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.
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:
{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...
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...
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.
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...).
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/...
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.
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...