Refinement Zero

Let's construct a NetLogo model of Page's standing ovation model. First a simple description:

  1. an audience sits in an auditorium
  2. a performance takes place
  3. the performance has some actual, absolute quality level, say, between 0 and 10.
  4. each member of the audience compares her perception of the performance to her "standard"
  5. if performance exceeds standard, she stands and claps
  6. with each passing click of the tock, audience members assess whether or not people around them are standing, and…
  7. …stand up (or stay standing) if the majority ARE standing but sit down (or stay seated) if majority are not standing.

Details we are ignoring for now:
does everyone perceive the quality "accurately"?
does everyone have the same standard?
how much of the rest of the audience does each audience member pay attention to

Here is a first take:

  1. set up the audience
  2. performance takes place
  3. each audience member reacts to performance
  4. each audience member reacts to audience members around them
  5. repeat step 4 until no more changes

Implement in code

Write empty procedures called

setup
performance_happens
react_to_performance
react_to_each_other

to setup
print "SETUP"
end

to performance_happens
print "PERFORMANCE HAPPENS"
end

to react_to_performance
print "REACT TO PERFORMANCE"
end

to react_to_each_other
print "REACT TO EACH OTHER"
end

Before we continue, let's put buttons on the interface for each of these actions. When you are done, test each of the buttons.

Refinement 1: setting up the auditorium and the audience

The grid of patches is numbered like a coordinate system in geometry. Patch 0,0 is at the center and the pxcor's of the patches increase as we go up and decrease as we go down. The pycors behave similarly with negative pycor's to the left and positive pycor's to the right.

Let's make our auditorium go from pxcor -10 to pxcor +10 (21 columns of patches) and similarly from pycor -10 to +10. All told the means we'll have 21x21= 441 patches. We'll symbolize the auditorium by making the patches white. We can do this by asking all the patches that are within the bounds just described to set their pcolor to white:

ask patches [if (pxcor > -10 and pxcor < 10 and pycor > -10 and pycor < 10) [set pcolor white]]

We'll see in a minute that there may be simpler ways to say the same thing, but for now, code and test.

Now that we have an auditorium, we want to fill it with an audience, one per seat. We can do this by asking each of the auditorium patches to "sprout" one turtle. The command for this is simply sprout 1. We can put this inside the square brackets where we ask the patches to turn white.

ask patches [if (pxcor > -10 and pxcor < 10 and pycor > -10 and pycor < 10) [set pcolor white sprout 1]]

Code this and test it. Notice that the audience members are looking every which way? Let's get their attention and have them looking toward the front (top) of the room. To do this, we'll tell the new turtles to set their heading as soon as they come into existence but putting a bracketed command right after the sprout command. When we say

sprout n [commands]


it means that a patch will generate n turtles and each of those turtles will execute commands as soon it is "born." Let's have them face forward and turn red. The former is accomplished by setting their "heading" variable (it's a built in variable that all turtles have).

ask patches [if (pxcor > -10 and pxcor < 10 and pycor > -10 and pycor < 10) [set pcolor white sprout 1 [set color red set heading 0]]]

Refinement 2: giving the agents some properties

What characteristics or properties do we want our audience members to have? Each one has a seat location, a threshold or standard of performance, and each one is either standing or not. In NetLogo we give agents properties using the -own command. For example, to give our audience members these characteristics we could use

turtles-own [row seat threshold standing]

where row and seat will be numbers running from -10 to +10, threshold is some number against which the performance will be compared, and standing is 0 if the agent is sitting and 1 if standing.

We also want a variable to store the value of the performance so all the turtles can "see" it and react to it. In NetLogo we can create a variable that all the agents in the system have access to with the command globals []. Here's how we would use it here:

globals [performance]

Both of these commands go at the top of our code. Thus, refinement 2 will look like this:

globals [performance]
turtles-own [row seat threshold standing]

to setup
print "SETUP"
ca
ask patches [if (pxcor > -10 and pxcor < 10 and pycor > -10 and pycor < 10)
[set pcolor white sprout 1 [set color red set heading 0]]]
end

to performance_happens
print "PERFORMANCE HAPPENS"
end

to react_to_performance
print "REACT TO PERFORMANCE"
end

to react_to_each_other
print "REACT TO EACH OTHER"
end

Refinement 3: Let the turtles react!

Since we have a global variable for the performance value we are almost ready to implement the turtles' reaction to the performance. But first we need to set each turtle's threshold AND we need to make the performance happen.

The threshold can be set in the setup procedure when the audience members are created. For now, let's set all the turtles to the same threshold, say, 6.

to setup
print "SETUP"
ca
ask patches [if (pxcor > -10 and pxcor < 10 and pycor > -10 and pycor < 10)
[set pcolor white sprout 1 [set color red set heading 0 set threshold 6 ]]]
end

and we can insert a "random" performance in the corresponding procedure:

to performance_happens
set performance random 10 ;; each run of the model starts with a random performance "level"
print "PERFORMANCE HAPPENS"
end

And finally, let's implement the react-to-performance procedure. What do we want to tell each turtle to do? IF the performance is over the threshold, she should stand. What does standing mean? Let's say we have no idea yet. And so we'll just black box it by creating a procedure called STAND:

to stand
print "TURTLE STOOD"
end

and then we can write the react_to_performance like this

to react_to_performance
if (performance > threshold) [stand]
end

When we check this out it looks OK but then we go back to the interface and some parts are highlighted in red. Something is wrong. The problem is that we have written the react_to_performance as a turtle procedure. That is, it is a verb that turtles do. When we create buttons we have to tell NetLogo whether the command relates to turtles, patches, or the whole system (the "observer"). Right click and edit the two "react" buttons and change them to turtle commands.

Now click "setup" and then "performance happens" and then "react to performance." What do you see? You might want to enlarge the command center and repeat it a few times to see what is going on.

Why Keep Ourselves in the Dark?

It's frustrating not knowing what the performance was like, is it not? Our agents supposedly know, but we do not. Let's fix this by installing a monitor or two.

In the interface to the "button" pull-down and select "Monitor." Create a monitor and tell it to report the value of the variable "performance." And then create another and tell it to report the count of turtles who are standing (count turtles with [standing = 1]):

netlogo-monitor-standing.png

Refinement the Next - Actually Standing

Our "how many are standing" monitor is useless unless we change the turtles' standing variable when they stand. Now let's make the agents actually do something when they stand. How about the change their shape to a circle and turn blue? We'll add this code to the stand procedure and we'll comment out the print command so that it does not distract us

to stand
set shape "circle" set color blue set standing 1
;;print "Turtle Stood"
end

Now run it a few times to verify that we can see what's going on.

Not Very Interesting

If every turtle has the same threshold then they either all stand or all do not stand. Not so interesting. Let's try a variation. How about if we give the turtles random thresholds (not changing thresholds, but each turtle has a different threshold).

**Stop and Think: Where might we insert code to give each turtle a random threshold (say, between 1 and 10)?

**Stop and Think: If you click "react to performance" repeatedly, what do you expect will happen? Try it? Why does this happen? What happens if we click "performance happens" again?

Adding "Interaction" to Our Model

Next we want our turtles to pay attention to the turtles around them. First we'll look only at our immediate neighbors.

To make life easier, let's give each one a list of neighbors - we'll add this to the variables the turtles "own." And then, in setup, we'll call a procedure to "identify my neighbors":

to identify-my-neighbors
print "identifying neighbors"
end

We will fill in this blackbox with a new command. All the internal parentheses are not necessary, but we'll use them here to make the syntax more visible. "TURTLE-SET" is a command that takes turtle numbers and turns them into a "set of turtles" for commands that operate on a thing we call an "agent set." The TURTLES-AT command takes an offset X and offset Y and reports the set of turtles found at that location relative to the turtle who is carrying out the command.

to identify-my-neighbors
set my-neighbors (turtle-set (turtles-at -1 0) (turtles-at -1 1) (turtles-at 0 1) (turtles-at 1 1) (turtles-at 1 0) )
end

Stop and Think: Do you see what set of turtles get put into each turtles "my-neighbors" variable? Inspect a few to confirm.

Now that turtles know who their neighbors are, they can assess how many are standing. Let's say our rule is "stand if more than half your neighbors are standing.

if (count my-neighbors with [standing = 1] > (count my-neighbors) / 2) [stand]

But what if they are not? How would we implement the rule of "and if you are standing and (not enough of) your neighbors are not you should sit down?

Start by writing a blackbox procedure called "sitdown" and then put the additional logic in the react-to-each-other procedure. Note how NetLogo does If-Then-Else.

File nameFile typeSize
SO_model05.nlogoASCII English text11.95 kBInfo
SO_model06.nlogoASCII English text12.02 kBInfo