Repast 2D Model Template
M.Schippling v0.2 6/6/6-06/21/06
http://www.etantdonnes.com/repast/demos/Template2D.html


Introduction

This is just about as simple a multi-agent model as can be made and still do something. I hacked up the uchicago.src.repastdemos.sugarscape files, changed the package to com.etantdonnes.repast.models.template2D to protect the innocent, shuffled some things around, removed all but the essential model specific code, and added/edited the comments. Perhaps the exercise was in reading the code, but at least these source files now form a minimal template set for this sort of model. Any model which uses a 2D torus consisting of a Space and a set of Agents that interact should be able to start from here without a lot of trouble.

To get everything see the Installation section below.

This specific model is just a set of agents that take random walks on a space which has been initialized to have areas that are not penetrable. The two rules are that agents can't occupy the same location in the space at the same time, and they can't invade any blocked areas of the space. As the agents wander they leave a trace in the space so we can see that, as Random Walk theory posits, they do indeed cover all the territory.

There are Graph and Histogram windows that plot some internal agent values. The Graph shows the total number of collisions over time, and the Histogram shows the distribution of move-directions for each step. They are examples of use, more than useful examples.

The model can also log data from each step to a file named Template_data.txt. Checking the writelog entry in the Settings window before starting a run will enable the log. Again this is more for illustrative purposes than to provide useful data.

Before, During, and After Pictures

The model display window, labeled Template, shows two overlayed fields and has three basic types of items. The fields are the Space and the Agents. The items are:

start  middle  later

Usage

{Click here for a downloaded demo,} -- sorry, this won't work until someone sends me instructions for signing applications -- or Install everything locally according to the instructions below. If you are running from an installed version you may double click on the T2DModel.jar file in the demos directory (on Windows at least) or crank up Repast and run Template from the File menu. The How to Run... and How to use the GUI pages in the Repast documentation describe the buttons and windows. Basically hit Play and watch the pretty pictures...

Repast Structure

The only thing Repast needs is a model class which extends SimModelImpl and implements a small number of abstract methods. In our case the class is T2DModel, which provides the following required methods:

Since this is an Object Oriented Paradigm, we have two other main classes:

While neither of these has a required function, they may implement the Drawable interface in order to have control over how they are displayed (actually the Space doesn't, but elements contained in the Space could...). As a convention they should each contain a step() method to localize behavior for each time tick. The step() methods should then be called from within model.step().

The source files are here:
Or you can download this whole caboodle in one zip:

Repast Startup

When Repast cranks up the T2DModel the following things happen:

Template Model Specifics

T2DSpace

The model arena comprises three Object2DTorus objects (see Why Tori?) which are created in T2DSpace(), these are containers for two dimensional matrices of individual model specific objects:

The initSpace is initialized in size and content from the template.pgm file. Its constructor parses the file, creates a matrix of the specified size, and populates it with Integer objects whose values are read from the matrix in the file. See Init File Format for some details. (Note that we could dispense with initSpace as it is only used to do the copy-initialization of currentSpace, but it was used in the canonical SugarSpace model so I just kept it this way in case an example was needed.)

The currentSpace is the actual working environment whose contents are displayed in the Template model window. Each Object2DTorus matrix location contains an Integer object. The Integers are initialized from the initSpace and the individual locations are incremented whenever an agent is moved. After each model step the content of the currentSpace matrix is displayed in the Template model window. The color of each display square is determined by a ColorMap created in T2DSpace.getSpaceDisplay(). (Note that instead of Integers, I could have created a new kind of object for the currentSpace entries. This object could simplify the incrementing of visit counts done in putAgent(), and implement the Drawable interface in order to avoid the whole ColorMap creation thing. But this is just an example, so YMMV).

The agentGrid is used to hold the position of each agent in the model. On each model step our T2DAgent objects are placed in the Object2DTorus matrix at their desired x,y positions, and any empty locations are set to null. The agentGrid serves two purposes: First it is a two-dimensional index to all the agents so we can find the agent at a certain location without searching through the whole list of agents; and Second, it is used to generate the agent display in the Template window. The Agent display is overlaid on the Space display so agents always show up on top. What is displayed for each agent is implemented in the T2DAgent.draw() Drawable interface.

The T2DSpace class also contains some model specific methods for moving agents around in the space:

For the most part these methods are generally useful. The model specific rules that prevent multiple occupancy and enforce blocked spacial locations are built into putAgent(), and can be easily dispensed with for other types of models. Since these methods manipulate spacial elements I put them in T2DSpace rather than in the Agent class (Rant: Or the model class where SugarSpace had them). This design decision is reasonably arbitrary...

T2DAgent

The agent object is very simple in the Template model. It contains it's own x,y position and a step() method that implements the random-walk behavior. It also implements the Drawable interface so the display code can use agent objects to make their own pictures in the Template window.  For example purposes there are some other variables with get/setters that are used to generate graphs and log information, but they are not germane to the actual agent function.

T2DModel

As described in the Repast Startup section above, T2DModel is the driver for the simulation. Between that section and comments in the code it should be fairly obvious (totally opaque) what is going on.

Aside from helper classes to collect data for graphs and logs, the only interesting modeling specific object in T2DModel is the agentList. This is an ArrayList that contains all the agents in the model. Since the Template model doesn't do dynamic agent create/destroy the list is not modified while the model is running, but it might just as well be, as in SugarScape. The point of the agentList is to give the step(), graph, and display methods something to iterate over without having to grind through the whole T2DSpace.agentGrid, which is assumed to be sparsely populated. There is even a special display interface, Object2DDisplay.setObjectList(), that allows the graphics code to use the agentList to speed up it's drawing using the Drawable interface in each T2DAgent. (Rant: As a matter of fact, since the Space matrices don't implement the List interface, this is the only (easy) way to do some of the step() and graph functions....Just try to make a histogram of the currentSpace and you'll see what I mean...).


Notes

Installation

Click here to download a zip file with all the source and chattel, including this file. Unzip this file into your Repast 3/Repast J directory tree. It will put some new files under the demos directory, including this file, demos/Template2D.html, and the source under demos/src/com/etantdonnes/...


Why Tori?

A torus is a donut, is a bagel for those of us on a diet. One of the nice things about donuts is that they have no edges. If you keep going right or left (around the circumference  ), or up or down (through the hole), you come back to where you were. If you have an environment that is a grid on a sheet of graph paper, you can map it into a torus by connecting the left and right, and top and bottom edges together -- it's not very practical as origami, but conceptually it works nicely. For modeling purposes this means that (with a little arithmetical trickery) there are no spacial boundaries to check, you never fall off the edge of your world, and you always have the same number of neighbors.


Init File Format

The template.pgm initialization file has a very strict, (Rant: And somewhat brain damaged) format which is implemented in Object2DGrid.init():

P2
50 50
4
0 0 0 ....
....

The lines must be in the specified order. Contrary to what is actually in the example file, there are no comments allowed, it just happens that, on the second and third lines, the parser ignores text after the expected fields:

Each of the content initialization values is converted to an Integer and stored in the appropriate Object2DGrid matrix location. In the Template model case, 0 means an empty square, -1 means a square where an agent may not go (obstacle), and anything else will pre-load a number-of-visits value. These meanings are defined by the model specific behavior in T2DSpace.putAgent() and T2DSpace.getSpaceDisplay(), and can be changed at will...