- Open RepastPy, if you don't already have it open. and load the Tutorial 2
project.
- Rename the model display name, model name and agent name and agent
group name to Tutorial 3, TutorialThreeModel,
TutorialThreeAgent and tutorialThreeNodes respectively. At this point you should know how to
do this. If not, follow the beginning steps for
tutorial 2.
- Save your project as tutorial3.sbp.

- Click on the Network Display component
in
the network component palette. Click on TutorialThreeModel.
You should see a new component added to the project tree. This
component will be labeled Network Display. Most components are added
the model component, although some may be added to the agent. See the
SimBuilder Component reference for what can be added
to what.
- Click on Network Display if it is not already highlighted to
display its properties.

- Choose circular from the Layout property.
The layout property defines how the network will be laid out on the
display. Circular will layout the nodes in a circle; Fruchman-Reingold
will layout the nodes according to the Fruchman-Reingold algorithm (a
"simulated annealing" type graph layout); Kamada-Kawai will layout the
nodes according to the Kamada-Kawai algorithm; and Random will layout the nodes
randomly. The Edit button can be used to set properties specific to each type
of graph layout.
That's it for adding a display. We'll now add some more complicated
agent behavior.
- Save your project. Its okay to overwrite your current save file.
- Click on TutorialThreeAgent.
- Add a new field to TutorialThreeAgent called wealth. It should
be of int type with a default value of 0, accessible but not a parameter.
By accessible, you are creating the get/set accessor methods for the
field, but not making it "probeable" via Repast.

- Click on the edit button of the actions property in
TutorialThreeAgent, and select the step method if it is not already
selected.
- Delete all the source code from the step action.
- Add the following to the step action.
if (self.getNumOutEdges()):
otherAgent = (TutorialThreeAgent)self.getRandomNodeOut()
otherWealth = otherAgent.getWealth()
if (otherWealth > self.wealth and otherWealth > 2):
self.wealth = self.wealth + 2
otherAgent.setWealth(otherWealth - 2)
else:
self.removeEdgesTo(otherAgent)
otherAgent.removeEdgesFrom(self)
self.makeRandomOutEdge(self.model.getAgentList(), DefaultDrawableEdge(), false)
else:
self.makeRandomOutEdge(self.model.getAgentList(), DefaultDrawableEdge(), false)
self.setNodeLabel(String.valueOf(self.wealth))
Make sure that the code is indented exactly as it is above. Here's the
same code with line numbers added for reference.
1. if (self.getNumOutEdges()):
2. otherAgent = (TutorialThreeAgent)self.getRandomNodeOut()
3. otherWealth = otherAgent.getWealth()
4. if (otherWealth > self.wealth and otherWealth > 2):
5. self.wealth = self.wealth + 2
6. otherAgent.setWealth(otherWealth - 2)
7. else:
8. self.removeEdgesTo(otherAgent)
9. otherAgent.removeEdgesFrom(self)
10. self.makeRandomOutEdge(self.model.getAgentList(), DefaultDrawableEdge(), false)
11.
12. else:
13. self.makeRandomOutEdge(self.model.getAgentList(), DefaultDrawableEdge(), false)
14.
15. self.setNodeLabel(String.valueOf(self.wealth))
Line one here checks that the current agent (the "self" agent) has out
edges. If so, then the indented code under the if statement is
executed. Line 2 gets another agent at the other end of one of self's
out edges, and stores that agent in a variable called otherAgent. The
"(TutorialThreeAgent)" is called a cast, and ensures that the node
returned from getRandomNodeOut will be treated by the compiler as a
TutorialThreeAgent. Line 3 gets the amount of wealth this other agent
has and stores that number in a variable called otherWealth. Line 4
tests that the other agent has more wealth than self and that this
amount of wealth is greater than 2. We test that the amount is greater
than two, so that wealth never falls below 0. If this test is true,
then line 5 and line 6 add two units of wealth to self, and remove 2
units from the other agent. Lines 8, 9 and 10 are executed if the test on
line 4 fails. Line 8 removes the edge to the other agent, and line 9
remove the edge from the other agent to self. Line 10 makes an edge at random
between self and an agent in the list of all the agents. self.model contains
this list and we get it by calling the
getAgentList method. The false argument ensures that we do not get any
self loops as the result. Line 13 gets executed if the test in line 1
fails. Line 13 is identical to line 10. The last line ensures that the
displayed label for self is updated to self's current wealth
amount. String.valueOf(...) returns the value of the self.wealth
parameter as a String (a list of text characters) suitable for a
label.
- Click OK to save your changes.
- Rename the labelMin and labelMax parameters in TutorialThreeModel
to wealthMin and wealthMax and set their respective default values to
10 and 20. You can do this directly in the fields table itself.

Recall that you edit fields by bringing up the fields editor
and then clicking on the field you want to edit in the
fields table. For example, to edit the name of the labelMax
parameter, click on labelMax in the fields table, delete the
text and type in wealthMax. Do the same to edit the default
value.
We now have a range of wealth from a minimum of 10 to a maximum of
20. What we want to do now is assign some value from this range to
the wealth parameter of each agent. This kind of
assignment is done is the model's initAgent's method. So,
- Bring up the actions editor to edit the initAgents action. (Click
on the edit button for TutorialThreeModel's action property, and
select the initAgents action if it is not already selected.)
- Replace the references to labelMin, labelMax and the variable i
in the line
i = Random.uniform.nextIntFromTo(self.labelMin, self.labelMax)
with wealthMin, wealthMax and wealth respectively. The line should now
look like
wealth = Random.uniform.nextIntFromTo(self.wealthMin, self.wealthMax)
This will assign a random integer from the range defined by
self.wealthMin and self.wealthMax to the variable wealth. Replacing i
with wealth is not necessary here, but it does give a clearer idea of
what this random integer will be used for.
Beneath this newly edited line, add
agent.setWealth(wealth)
This will set the agent's wealth to the value of the wealth
variable. When you created the wealth field for
TutorialThreeAgent and marked it as accessible, RepastPy silently created getWealth and setWealth
accessor methods for you. You use the setWeath method to set the
wealth value and the getWealth value to get the value.
Edit the line
agent.setNodeLabel("id - " + i)
to read
agent.setNodeLabel(String.valueOf(wealth))
This sets the label of the node to the text value of the value of the
wealth variable.
Lastly replace the reference to TutorialTwoAgent in the for loop
header to TutorialThreeAgent and tutorialTwoNodes with tutorialThreeNodes,
just as you did in the second iteration
of the tutorial. The entire action source should now read:
for agent as TutorialThreeAgent in self.tutorialThreeNodes:
wealth = Random.uniform.nextIntFromTo(self.wealthMin, self.wealthMax)
agent.setWealth(wealth)
agent.setNodeLabel(String.valueOf(wealth))
Click OK to save your changes.
- Save and compile.
- Run the simulation.
When you click the run button on the RePast toolbar, you should see a
circular display of the network with the wealth displayed on each
node. However, the wealth label and the links do not change while the
simluation is running, although given the code you have just written,
they should.
In this case, the simulation is running correctly, wealth is being
altered and links are being created a destroyed, but the display is
not updating to show the changes. We need to edit the
Network Display Component for this to work.
- Exit the RePast simulation and click on the Network Display
component. Then click on the schedule property's edit button. This
will bring up the schedule editor.

RepastPy allows you to schedule components actions to execute at
certain times in the simulation. Recall that when you run a RePast
simulation the tick count on the toolbar increase by one for each
iteration of the simulation. You can schedule component actions
against these ticks with the schedule editor.
In our case, we'd like to update the display every iteration of the
simulation, that is, at every tick. So,
- Select the update_display action from the combo box of actions in
the schedule editor.
The actions box lists the actions available for scheduling, some of
these may be user defined via the actions property and some may be
internally defined by the component. The two listed here are
internally defined by the Network Display component.
- Select EVERY_TICK from the execution combo box and make sure that
the tick text area reads 1.
The execution combo box lists the types of execution you can use to
schedule your action. These types are
- EVERY_TICK -- the specified action executes every tick beginning at
the tick specificed in the tick box.
- AT A SINGLE TICK -- the specified action executes once at the tick
specificed in the tick box.
- AT INTERVAL -- the specified action executes at the interval
specified by the tick box (e.g. every three ticks).
- AT END -- the specified action executes at the end of the RePast
simulation, that is, when the stop button is pressed. The tick box is
ignored in this case.
- AT PAUSE -- the specified action executes at a pause in the RePast
simulation, that is, when the pause button is pressed, or when the
step button is pressed (step runs a single iteration and then
pauses). The tick box is ignored in this case.
The execute last check box is available for the AT INTERVAL and AT A
SINGLE TICK types. Checking execute last check box ensures that the
specified action will execute after any regularly scheduled
actions. So for example, if action x is scheduled to execute every
tick beginning at 1, and action y is scheduled to execute only at tick
3, and has execute last checked then y will execute after x at tick 3.
The master schedule property in the model component gives you a view
of all the scheduled actions in relation to each other. You can edit
their relative order there.
- Click the add button to add the action execution to the table.
To delete an action execution click on it in the table and click the
delete button.
<
There is no way to edit actions other than deleting them and re-adding
them.
- Click OK to register your changes with the component.
- Save and compile.
- Run the RePast simulation.
The wealth of each node will change a bit a first and then settle
down as nodes begin to swap wealth back and forth.
The projects directory contains several more sample models. They are
good examples of how to create more complicated RepsatPy models.