SugarScape

SugarScape is a model developed by Joshua Epstein and Robert Axtell (see references.)

In the first version hungry agents roam the countryside looking for sugar. As they roam, they burn sugar at a rate determined by their metabolism. If an agent burns up all of his sugar before he finds more, he dies. An agent's ability to spot sugar is determined by how far it can see. This is controlled by its vision attribute.

When an agent discovers a patch of sugar, he consumes it and resumes his search for more sugar. Eventually, the patch will grow more sugar at a rate determined by its growBack attribute.

By playing with these parameters-- metabolism, vision, and growBack-- users can gain insight into phenomena such as carrying capacity, distribution of wealth, seasonal migration, and resource consumption.

In version 2 agents have finite life times and the ability to mate. In this version users can also gaininsight into phenomena such as fertility, cultural dynamics, proto-history, even combat.

In version 3 a second commodity is introduced: spice. An agent rich in sugar but poor in spice can trade with an agent in the opposite situation. The number of units of spice equivalent to a unit of sugar fluctuates according to supply and demand. The model provides interesting insights into the performance of markets populated by rational agents versus markets populated by evolving agents.

In version 4, disease is added to the model. Users can study the transmission of disease, the effects on the economy, and disease control policies.

CNP SugarScape

CNP SugarScape is a version of SugarScape 1.0 described above, but with a twist. Instead of vision, turtles have a broadcast range. Following the Contract Net Protocol (CNP), turtles broadcast requests for proposals (rfp's). Patches that receive these requests may send proposals back to the turtle. The turtle selects the best proposal, and moves toward the patch to pick up the sugar.

Here is CNP SugarScape at initialization. Note that there are 100 turtles. Each has a random broadcast range (0 � 5 patches), a random metabolism (0 � 0.3), and a random initial endowment of energy (0% � 100%). The average energy is 50.29%.

After a short amount of time the population stabilizes at 39 turtles with an average energy of 26.53%. This is the environment's carrying capacity.

Design

Every turtle in SugarScape has a proposal queue, every patch has an rfp queue. Turtles place rfps in the rfp queues of nearby patches. An rfp contains a reference to the turtle that created it.

If a patch decides to respond to an rfp in its queue, it places a proposal in the proposal queue of the turtle that sent the original rfp. The proposal contains a reference back to the patch that created it.

Here it is as a class diagram:

Implementation

The Sugarscape model (ss.nlogo) is a good introduction to the NetLogo language. It is further analyzed in overview3.html.

 

 

 

 

Agent Attributes

Including the proposal queue, a turtle has six attributes:

turtles-own [
�� energy ���������� ; dead = 0% <= energy <= 100%
�� metabolism ������ ; rate sugar is burned by moving <= 0.3
�� proposal-queue �� ; patches put proposals here
�� broadcast-range ; how far can rfps be transmitted <= 5
�� hasProposal ����� ; = true if turtle has accepted a proposal
�� target����������� ; = the patch that made the accepted proposal
]

A patch has three attributes:

patches-own [
�� sugar ����������� ; = amount of sugar here <= 100%
�� grow-back ������� ; how fast sugar is replenished <= 5
�� rfp-queue�������� ; turtles put rfp's here
]

Agent Initialization

We begin with the standard initialization procedures:

to init-agents
�� ca
�� init-turtles
�� init-patches
�� repeat 5 [diffuse sugar .1]
end

to init-turtles
�� crt 100
�� ask turtles [init-turtle]
end

to init-patches
�� ask patches [init-patch]
end

A turtle is initialized with a random energy, metabolism, position, and broadcast range. The redness of the turtle reflects its energy level.

to init-turtle
�� set energy random 100
�� set metabolism random-float 0.3
�� set broadcast-range 5
�� set hasProposal false
�� set proposal-queue []
�� setxy random-xcor random-ycor
�� set color scale-color red energy 140 0
end

A patch is initialized with a random amount of sugar and a random grow back rate. The greenness of a patch reflects how much sugar is present.

to init-patch
�� set sugar random 100
�� set grow-back random 5
�� set rfp-queue []
�� set pcolor scale-color green sugar 140 0
end

Updating Agents

We begin with the usual machinery for updating agents:

to update-agents
�� update-turtles
�� update-patches
end

to update-patches
�� ask patches [update-patch]
end

to update-turtles
�� ask turtles [update-turtle]
end

A patch goes through cycles of making proposals and growing sugar:

to update-patch
�� make-proposals
�� grow-sugar
end

A turtle goes through cycles of making rfp's and seeking sugar:

to update-turtle
�� make-rfps
�� seek-sugar
end

Requesting and selecting proposals from patches

If a turtle has no proposal, it selects a proposal from its queue. If the queue is empty, the turtle broadcasts an rfp:

to make-rfps
�� if not hasProposal
����� [
�������� ifelse empty? proposal-queue
����������� [make-rfp]
����������� [select-proposal]
����� ]
end

A turtle sorts its proposal queue by distance and awards the contract to the nearest patch:

to select-proposal
�� set proposal-queue
����� sort-by [distance ?1 < distance ?2] proposal-queue
�� set target first proposal-queue
�� set hasProposal true
�� set proposal-queue []
end

A turtle "makes" and rfp simply by putting a reference to itself into the rfp queues of all nearby patches.

to make-rfp
�� locals [near]
�� set near patches in-radius broadcast-range
�� ask near [set rfp-queue lput myself rfp-queue]
end

Note the use of myself instead of self. In NetLogo self always refers to the agent executing a command, while myself refers to the agent asking for a command to be executed.

Seeking and consuming sugar

Each cycle a turtle advances one step toward its target. When it arrives, it consumes sugar. If a turtle has no target, it moves twice the distance of its broadcast range looking for new sources of sugar:

to seek-sugar
�� ifelse hasProposal
����� [
������ ��ifelse target = patch-here
����������� [consume-sugar target]
����������� [move-toward target 1]
����� ]
����� [move-toward one-of patches broadcast-range * 2]

end

A turtle converts sugar into equal amounts of energy:

to consume-sugar [p]
�� locals [old-energy]
�� set old-energy energy
�� set energy max (list (value-from p [sugar]) 100)
�� ask p [set sugar
����������� sugar - ((value-from myself [energy]) - old-energy)]
�� set hasProposal false
�� move-toward one-of patches 2 * broadcast-range
�� type self
print " has consumed sugar"
end

As a turtle moves, it consumes energy according to its metabolism rate:

to move-toward [goal steps]
�� face goal
�� fd steps
�� set energy (energy - energy * metabolism * steps)
�� set color scale-color red energy 140 0
if (energy <= 0)
�� [
����� type self
����� print " is dying"
����� die
�� ]
end

Making proposals and sugar

If a patch has sugar, it places a proposal, which is simply a reference to itself, into the proposal queue of every agent in its rfp queue provided that 1. the agent hasn't died and 2. the agent hasn't accepted a proposal from another patch:

to make-proposals
�� locals [candidate]
�� if (0 < sugar)
�� [
����� if (not empty? rfp-queue)
�������� [set candidate (first rfp-queue)]
����� while [not empty? rfp-queue and
����������������������� ((candidate = nobody) or
����������������������� (value-from candidate [hasProposal]))]
����� [
�������� set rfp-queue bf rfp-queue
�������� if (not empty? rfp-queue) [set candidate (first rfp-queue)]
����� ]
����� if not empty? rfp-queue
����� [
�� ������ask candidate
����������� [set proposal-queue (lput myself proposal-queue)]
�������� set rfp-queue bf rfp-queue
����� ]
��� ]
end

If sugar level is below 50, a patch incrementally adds a tiny bit of sugar on every cycle. Note the color being restored:

to grow-sugar
�� if sugar < 50
����� [ set sugar min (list 100 (sugar + grow-back)) ]
�� set pcolor scale-color green sugar 140 0
end

Gathering statistics

Here are a few simple statistics:

to-report avg-energy
�� locals [result]
�� ask turtles [set result result + energy]
�� report result / (count turtles)
end

to-report population
�� report count turtles
end