Lets take a few first steps with our modeling frameworks. We
will be fairly brief , limiting ourselves to simple "kicking the tires"
and writing a hello world in each ABM system (here is the RePast First Steps).
Our goal is to gain a feel for what each system is capable of so that
we can make intelligent decisions on which one to use for a given
task. Note: most images below
can be clicked on for a full size image.
| To download NetLogo, go to their web site,
downloading the package for your system. As of this writing, the
version is 1.2. During the download you can join the mail list,
which I recommend. The package will include considerable
browser-based documentation in the docs/ directory for fast
viewing. I show the results of downloading "Other Java-enabled
platform" to the
right. The NetLogo.jar is double clickable, starting the
application. Specific downloads are available for Mac and
Windows. The NetLogoLite.jar file is used for exporting your models to the web, like this example. |
|
Now lets try a few simple commands. To do this, we'll select
New in the File menu to get an empty new model. This presents
just two items: the graphics window and the command center. The
graphics window shows the patches and turtles, while the command center
lets you type in commands, helpful for experimenting to see how they
work.
The command center accepts commands in three contexts: commands for the global Observer, or for commands sent to all of the individual Turtles or Patches as a group. You choose which sort of command you want via the small drop down menu. In the image below left we show the patches being selected. The center image shows the result of one command: "set pcolor (pxcor + pycor)" which simply sets the color (a number between 0 and 140) to the sum of the x and y coordinates. Note that, because the command is going to all of the patches, the entire Graphics Window is changed. Silly but illustrative! We then switch to Observer mode and reset the display and create 36 turtles with these two commands: "clear-patches" and "create-turtles 36". We then switch to Turtle mode, and do "set heading who * 10" and "forward 15" which turns the turtles in all directions ("who" is the number of the turtle from 0 to 35) and then has them move forward 15 units, resulting in the image on the right.
|
|
|
| Programs are run using a very
simple Logo-like
language,
along with an easy to use GUI for building sliders, buttons, and
graphs. To understand this a bit further, we'll use the
(excellent!) documentation that came with the download. The index
page is to the right. Use your browser to look at the doc/index.html
that came with your system.
Take some time to browse through the documentation. The
three
tutorial modules are quite good as are the three reference
sections. Look at the Interface Guide .. it will show you all the
visible components in a model, and explain how they are used.
Then look at the Programming Guide .. it will guide you through all of
the NetLogo language features. Finally, the Primitives Dictionary
gives detailed information on every language primitive. It will
be your constant companion as you write models! |
|
| We can model this in NetLogo by
having the buttons be turtles placed
randomly on the graphic window. Each tick we will chose a pair of
buttons, connecting them together and changing their color to be the
same. At the end of each turn we will find the largest cluster,
posting its size.
Before we start, you can try the
model in your browser, and browse the source
code. As we begin programming, use your "Open File" menu to open
the docs/index.html
that came with your NetLogo download, and click on the Primitives
Dictionary, so that you can look up the NetLogo language keywords as we
use them. On my system, it looks
like this. |
|
We will build our model in four phases, in order to make learning a
simple, step-by-step process.
From the File menu chose "New". This will give us a "blank" new
model with an empty graphics window and a command center. Use the
File menu's Save command to save the model on your disk in a convenient
place. We'll use the name Buttons, which is stored with the
extension ".nlogo" automatically. Ours looks
like this.
Click on the Procedures tab where the model program is built. It will look like this. It has one line:
; add model procedures here
The ";" begins a comment which goes to the end of the
line. We'll delete this and begin by building the buttons
agents. Our first phase simply builds 500 turtles (buttons) and
randomly places them on the screen. The source
file is here and looks like this, where we've added line numbers
for reference:
1 globals [buttons] ; Global variables
2 to setup ; Initializes model for new run.
3 set-default-shape turtles "circle" ; Turtles are circles
4 clear-all ; Reset turtles and patches
5 set buttons 500 ; Set number of buttons to 500
6 create-turtles (buttons) ; Create "buttons" number of turtles
7 ask turtles [setup-turtles] ; Initialize each turtle
8 end
9 to setup-turtles ; Called for each turtle during setup
10 setxy random screen-size-x random screen-size-y ; Set our x,y randomly
11 end
| To run the current code, click
on the Interface tab. We have
not built a GUI yet so will have to use the Command Center like we did
in the "Kicking the Tires" introduction above. Make sure the
type-in area of the Command Center is in "Observer" mode (i.e. the left
of the type-in area shows "O >"). A small drop-down menu is used to change between
Observer, Turtle, and Patches, see the introduction above. Click in the type-in area to the right of the "O >" symbol
and
type "setup". You can do this several times, getting a new random
set of buttons each time. |
|
Line 1 declares the global variable, "buttons", the number of buttons for this run of the model. Note that it is not declared as an integer variable, which it happens to be. NetLogo dynamically types variables as needed. And indeed, you can have the same variable be a string, a list, an integer and so on during the execution of the program. Look up "globals" in the NetLogo Primitives Dictionary by clicking on the "G" Alphabetical index, or by scrolling primitives frame, or by searching to the word "globals" using your browser's "Find". Also note the comments at the end of the line: everything past a ";" is a comment, just like C/C++ "//" comments or the shell's "#" comments.
| Lines 2 and 8 ("to" and "end")
enclose the definition of the
procedure "setup". Line 3 sets the shape of the turtles to be
circles rather than the default arrow-like shape. Line 4
initializes the system by killing all existing turtles, resetting all
globals, and clearing the patches and plots. This lets us re-run
the model multiple times. Line 5 sets the global "buttons"
to be 500. Line 6 creates that number of turtles.
Line 7 then causes the procedure on line 9 to be called for each
turtle. For each of the commands above, there is an entry
in the Primitives Dictionary in the documentation. To the right
we show the "clear-all" entry. The "ca" in the banner tells us
that we can use ca as an abbreviation for clear-all. The eye-ball
tells us that it executes in the observer context (as discussed in the
Command Center above). If you have any doubt how a command works,
just look it up! |
|
| The "ask" command is special: it executes the command in each individual turtle's context. This exposes variables like "color, xcor" which can be set, and "who", which cannot be changed. The documentation contains special entries for
these variables. To the right we show the entry for
turtles. You can also check the variables for patches.
There are also predefined variables for constants like "red" , "pi",
and so on. |
|
Just as Lines 2 and 8 enclose the procedure "setup", lines 9 and 11
enclose the procedure "setup-turtles". Line 10 is our first
compound command which contains three simple commands, two instances of
the "random" command and one instance of the "setxy" command.
Calling "random integer-variable" returns a number between 0 and
(integer-variable - 1). The "setxy" command takes two variables
and sets the turtle's xcor and ycor (coordinate) values to these two
numbers. Note that Logo typically uses these compound commands,
much like Lisp and other sophisticated recursive languages.
| The "setxy" statement
introduces us to the coordinate system used by
the turtles and patches. This is discussed in Tutorial #1 in the
Changing Graphics Window Settings section. The origin, x=0, y=0,
is in the center of the patches. This causes NetLogo to have the
screen-size-x and screen-size-y to be an odd number of cells.
But in the setxy command, we use screen-size which is
twice the edge length plus one for the center! This works because
NetLogo wraps the coordinates around the edges. So when an X
coordinate is one greater than the right edge, it really on the far
left edge. This means the NetLogo modeling space is actually a
torus. This is common in modeling frameworks. A similar style is applied to colors. Colors go from 0-140 as discussed in Tutorial #2 in the Working With Colors section. If you set a color beyond the 140 colors, they wrap as well. Thus color 150 is the same as color 10. This lets us use colors equal to the "who" number of the turtles without error. |
|
1 globals [buttons] ; Global variables
2 turtles-own [group] ; Each turtle has "group" as a variable
3 to setup ; Initializes model for new run.
4 set-default-shape turtles "circle" ; Turtles are circles
5 clear-all ; Reset turtles and patches
6 set buttons 500 ; Set number of buttons to 500
7 create-turtles (buttons) ; Create "buttons" number of turtles
8 ask turtles [setup-turtles] ; Initialize each turtle
9 end
10 to setup-turtles ; Called for each turtle during setup
11 set group who ; Initialize "group" ins var to ID built-in
12 setxy random screen-size-x random screen-size-y ; Set our x,y randomly
13 end
14 to go ; Step the model once
15 locals [g1 g2] ; This procedure has some temp local variables
16 set g1 group-of turtle random buttons ; g1 & g2 are two group values
17 set g2 group-of turtle random buttons ; chosen from two random turtles
18 ask turtles [joinClusters g1 g2] ; Merge group g1 with group g2
19 end
20 to joinClusters [g1 g2] ; Convert group g1 turtles into g2 turtles
21 if (group = g1) [set group g2 set color color-of turtle g2]
22 end
Line 2 adds a new variable, "group", to each turtle, using the
"turtles-own" command. This is initialized in line 11, inside our
earlier "setup-turtles" procedure, to be the value of the turtle's
"who" variable. Recall "who" is automatically assigned to turtles
and cannot be changed. Thus each turtle starts out in a group of
one, itself. This means there are no threads yet tied between any
of the turtles. These two lines are the only changes to our
earlier procedures. The other changes are to add the "go" and
"joinClusters" procedures.
As before, lines 14, 19, 20 and 22 enclose our two new procedures
using "to" and "end" pairs. At line 15, the "go" procedure uses the
"locals" primitive to declare two local variables. Local
variables are only "visible" within the defining procedure and are thus
temporary to the execution of the procedure. Line 16 is a compound
command, using the "set", "-of", "turtle", and "random"
primitives. The execution is from right to left. First,
"random buttons" returns an integer between 0 and buttons-1.
Next, the "turtle" primitive uses this to return the turtle who's ID
("who" value) is equal to that random number. Next, the
"group-of" command returns the "group" variable's value of that
particular turtle. (Look at the -of primitive in the Primitives
Dictionary, under "O".) Finally, the "set" command stores the
result in the "g1" local variable. Line 17 simply repeats this
for a second time to get a second group value, "g2", to use.
Whew! These three lines could have been written:
locals [g1 who1 t1 g2 who2 t2]
set who1 random buttons
set t1 turtle who1
set g1 group-of t1
set who2 random buttons
set t2 turtle who2
set g2 group-of t2
But as you become more adapt at NetLogo, you'll find the terse form
far easier to read and understand.
Line 18 in the "go" procedure asks each turtle to execute the
command: "joinClusters g1 g2". JoinClusters is the first
procedure we have created with arguments passed to it (g1 &
g2). The task of "joinClusters" is to make every turtle in group
g1 become a g2 member by setting its group value to g2 and its color to
be the same as all the turtles of g2. It does this with a single
line with several parts. It is easier to understand rewritten as
follows:
if (group = g1) [
set group g2
set color color-of turtle g2
]
The "if" primitive takes a boolean (true/false) expression and if
it evaluates to true, executes the supplied procedure. The ()'s
are not necessary but improve readability. Note that "a = b" does
not mean "set a to b" but "does a equal b". The first line of the
if statement's procedure simply sets the group variable of the turtle
to be g2. The second statement is a compound statement: turtle g2
returns the turtle who's ID ("who" value) is g2. We then set the
color of the current turtle to be the color of turtle g2. This is
a bit subtle: "turtle g2" is guaranteed to be in the g2 group because
of the way we initialized the groups to be turtle IDs. Thus its
color is the color of the g2 group. Actually, we could just as
simply set the merged group colors to be "red" or some other
value. We are simply trying to make all the turtles in groups g1
and g2 to look alike.
| When you commented out the two lines above, it left NetLogo not knowing about the "buttons" variable which tells us how many buttons to use. When you click to leave the Procedures tab, or you click the compile icon, NetLogo finds the error, and automatically opens the Error tab, with the error highlighted in blue, and explained in yellow. You can still go the Interface tab, but to help you remember you're in an error state, both the Procedures tab and Errors tab will be highlighted red. | |
|
So how do we fix the
error? NetLogo's sliders both declare a
global variable and set its value .. exactly the two lines we commented
out. To make our own slider, go to the Interface tab and click the
slider control as shown on the right. |
|
After creating the slider, it can be moved and resized by selecting
it: click in the white part of the window and drag over the
slider. By then clicking on the edit icon, you can also edit the
parameters you set up when you made the slider initially.
At this point, you can run the program as you did in Phase 2: using
the Command Center for entering "setup" and "go" commands, while using
the slider to control the number of buttons used. The rest of
this section will add two buttons to replace this use of the Command
Center
| First, we'll add a NetLogo
button to call "setup". To do this,
in the Interface Tab, click the Button icon, and with the cross-hair
cursor, click where you want to place the "setup" button. Put
"setup" in the resulting dialog's code box. This will default to
being the display name as well. Each click will re-initialize the
buttons. Similarly, create a "go" button, with the additional step of checking the "Forever" check box, causing it to repeat indefinitely (until the stop command above). We can now run the model easily without the command center. |
|
Next, we'll generate graphical data for the simulation.
1 globals [ClusterSz ticks] ; Global variables
2 turtles-own [group] ; Each turtle has "group" as a variable
3 to setup ; Initializes model for new run.
4 set-default-shape turtles "circle" ; Turtles are circles
5 clear-all ; Reset turtles and patches
6 set ticks 0 ; Initialize ticks global to 0
7 set ClusterSz 1 ; Initialize ClusterSz global to 1
8 set-plot-y-range 0 buttons ; Set Y axis to be 0 .. "buttons" tall
9 create-turtles (buttons) ; Create "buttons" number of turtles
10 ask turtles [setup-turtles] ; Initialize each turtle
11 end
12 to setup-turtles ; Called for each turtle during setup
13 set group who ; Initialize "group" ins var to ID built-in
14 setxy random screen-size-x random screen-size-y ; Set our x,y randomly
15 end
16 to go ; Step the model once
17 locals [g1 g2 thisClusterSz] ; This procedure has some temp local variables
18 set g1 group-of turtle random buttons ; g1 & g2 are two group values
19 set g2 group-of turtle random buttons ; chosen from two random turtles
20 ask turtles [joinClusters g1 g2] ; Merge group g1 with group g2
21 set thisClusterSz (count turtles with [group = g2]) ; Calculate merged size
22 set ClusterSz (max list ClusterSz thisClusterSz) ; Update global max size
23 plot ClusterSz ; Plot current max cluster size
24 set ticks (ticks + 1) ; Keep track of number of steps
25 if (ClusterSz = buttons) [stop] ; Stop if we have one huge cluster
26 end
27 to joinClusters [g1 g2] ; Convert group g1 turtles into g2 turtles
28 if (group = g1) [set group g2 set color color-of turtle g2]
29 end
Line 1 adds two global variables we will use to monitor the simulation: "clusterSz" and "ticks". ClusterSz is the number of buttons in the largest group of buttons. We initialize this to 1 in line 7. Ticks is the number of times we've run the "go" procedure. We initialize this to 0 in line 6. Line 8 initializes the plot we are about to build to have the Y axis go from 0 to buttons, the size of the largest cluster when all buttons are connected to each other.
Lines 21-25 manage clusterSz and ticks in the go procedure.
Line 21 sets a local variable, "thisClusterSz", to be the size of the
newly merged two groups of buttons. The phrase "turtles with
[group = g2] returns the set of turtles who's group variable is
g2. The "count" primitive returns the number of turtles in this
set, which is used to set the value of thisClusterSz. The global
variable clusterSz is then set to the maximum value of itself and the
local thisClusterSz. Line 23 adds the new value of ClusterSz to the
plot. Line 24 simply increments the "ticks" global
variable. Finally, line 25 halts the program when we've reached
the point where all the buttons are in the same group.
| To create the ClusterSz
display, click on the Monitor icon, then
clicking where you want to place the display. In the resulting
dialog, enter "ClusterSz" in the "reporter" box. (A Reporter in NetLogo
is any value or procedure returning a value). Similarly create the "ticks" monitor
which shows how many times the simulation "go" procedure has been run. |
|