A RePast Tutorial by John T. Murphy, University of Arizona & Arizona State University (contact)
At the moment we have agents who are born and age; we count them as dead when their 'stepsToLive' goes below zero, but they're not really dead, and stepsToLive just keeps dropping. We need a routine to have agents actually die and be removed from the simulation.
Along side that, to avoid depression, we can also provide the happier routine through which new agents are born.
The die routine must do the following:
Once these are done, no more pointers to this agent object exist, and the memory will be reallocated when the next garbage collection event occurs (this is usually automatic- it can be added as a scheduled event, but we will not do that for this demonstration).
To achieve this, we add a 'reapDeadAgents()' method to the model, and include that in the schedule object by making it a part of the CarryModelStep execute() method. We also need a 'removeAgentAt()' method for the space object.
We create the reapDeadAgents() method so that it returns a count of the agents who died. We then create that same number of agents anew to have agents being 'reborn'
The code modifications are:
// CarryDropModel
package demo;
import java.awt.Color;
import java.util.ArrayList;
import uchicago.src.sim.engine.BasicAction;
import uchicago.src.sim.engine.Schedule;
import uchicago.src.sim.engine.SimInit;
import uchicago.src.sim.engine.SimModelImpl;
import uchicago.src.sim.gui.DisplaySurface;
import uchicago.src.sim.gui.ColorMap;
import uchicago.src.sim.gui.Object2DDisplay;
import uchicago.src.sim.gui.Value2DDisplay;
import uchicago.src.sim.util.SimUtilities;
public class CarryDropModel extends SimModelImpl {
// Default Values
private static final int NUMAGENTS = 100;
private static final int WORLDXSIZE = 40;
private static final int WORLDYSIZE = 40;
private static final int TOTALMONEY = 1000;
private static final int AGENT_MIN_LIFESPAN = 30;
private static final int AGENT_MAX_LIFESPAN = 50;
private int numAgents = NUMAGENTS;
private int worldXSize = WORLDXSIZE;
private int worldYSize = WORLDYSIZE;
private int money = TOTALMONEY;
private int agentMinLifespan = AGENT_MIN_LIFESPAN;
private int agentMaxLifespan = AGENT_MAX_LIFESPAN;
private Schedule schedule;
private CarryDropSpace cdSpace;
private ArrayList agentList;
private DisplaySurface displaySurf;
public String getName(){
return "Carry And Drop";
}
public void setup(){
System.out.println("Running setup");
cdSpace = null;
agentList = new ArrayList();
schedule = new Schedule(1);
if (displaySurf != null){
displaySurf.dispose();
}
displaySurf = null;
displaySurf = new DisplaySurface(this, "Carry Drop Model Window 1");
registerDisplaySurface("Carry Drop Model Window 1", displaySurf);
}
public void begin(){
buildModel();
buildSchedule();
buildDisplay();
displaySurf.display();
}
public void buildModel(){
System.out.println("Running BuildModel");
cdSpace = new CarryDropSpace(worldXSize, worldYSize);
cdSpace.spreadMoney(money);
for(int i = 0; i < numAgents; i++){
addNewAgent();
}
for(int i = 0; i < agentList.size(); i++){
CarryDropAgent cda = (CarryDropAgent)agentList.get(i);
cda.report();
}
}
public void buildSchedule(){
System.out.println("Running BuildSchedule");
class CarryDropStep extends BasicAction {
public void execute() {
SimUtilities.shuffle(agentList);
for(int i =0; i < agentList.size(); i++){
CarryDropAgent cda = (CarryDropAgent)agentList.get(i);
cda.step();
}
int deadAgents = reapDeadAgents();
for(int i =0; i < deadAgents; i++){
addNewAgent();
}
displaySurf.updateDisplay();
}
}
schedule.scheduleActionBeginning(0, new CarryDropStep());
class CarryDropCountLiving extends BasicAction {
public void execute(){
countLivingAgents();
}
}
schedule.scheduleActionAtInterval(10, new CarryDropCountLiving());
}
public void buildDisplay(){
System.out.println("Running BuildDisplay");
ColorMap map = new ColorMap();
for(int i = 1; i<16; i++){
map.mapColor(i, new Color((int)(i * 8 + 127), 0, 0));
}
map.mapColor(0, Color.white);
Value2DDisplay displayMoney =
new Value2DDisplay(cdSpace.getCurrentMoneySpace(), map);
Object2DDisplay displayAgents = new Object2DDisplay(cdSpace.getCurrentAgentSpace());
displayAgents.setObjectList(agentList);
displaySurf.addDisplayable(displayMoney, "Money");
displaySurf.addDisplayable(displayAgents, "Agents");
}
private void addNewAgent(){
CarryDropAgent a = new CarryDropAgent(agentMinLifespan, agentMaxLifespan);
agentList.add(a);
cdSpace.addAgent(a);
}
private int reapDeadAgents(){
int count = 0;
for(int i = (agentList.size() - 1); i >= 0 ; i--){
CarryDropAgent cda = (CarryDropAgent)agentList.get(i);
if(cda.getStepsToLive() < 1){
cdSpace.removeAgentAt(cda.getX(), cda.getY());
cdSpace.spreadMoney(cda.getMoney());
agentList.remove(i);
count++;
}
}
return count;
}
private int countLivingAgents(){
int livingAgents = 0;
for(int i = 0; i < agentList.size(); i++){
CarryDropAgent cda = (CarryDropAgent)agentList.get(i);
if(cda.getStepsToLive() > 0) livingAgents++;
}
System.out.println("Number of living agents is: " + livingAgents);
return livingAgents;
}
public Schedule getSchedule(){
return schedule;
}
public String[] getInitParam(){
String[] initParams = { "NumAgents", "WorldXSize", "WorldYSize", "Money", "AgentMinLifespan", "AgentMaxLifespan"};
return initParams;
}
public int getNumAgents(){
return numAgents;
}
public void setNumAgents(int na){
numAgents = na;
}
public int getWorldXSize(){
return worldXSize;
}
public void setWorldXSize(int wxs){
worldXSize = wxs;
}
public int getWorldYSize(){
return worldYSize;
}
public void setWorldYSize(int wys){
worldYSize = wys;
}
public int getMoney() {
return money;
}
public void setMoney(int i) {
money = i;
}
public int getAgentMaxLifespan() {
return agentMaxLifespan;
}
public int getAgentMinLifespan() {
return agentMinLifespan;
}
public void setAgentMaxLifespan(int i) {
agentMaxLifespan = i;
}
public void setAgentMinLifespan(int i) {
agentMinLifespan = i;
}
public static void main(String[] args) {
SimInit init = new SimInit();
CarryDropModel model = new CarryDropModel();
init.loadModel(model, "", false);
}
}
// CarryDropAgent
package demo;
import java.awt.Color;
import uchicago.src.sim.gui.Drawable;
import uchicago.src.sim.gui.SimGraphics;
public class CarryDropAgent implements Drawable{
private int x;
private int y;
private int money;
private int stepsToLive;
private static int IDNumber = 0;
private int ID;
public CarryDropAgent(int minLifespan, int maxLifespan){
x = -1;
y = -1;
money = 0;
stepsToLive =
(int)((Math.random() * (maxLifespan - minLifespan)) + minLifespan);
IDNumber++;
ID = IDNumber;
}
public void setXY(int newX, int newY){
x = newX;
y = newY;
}
public String getID(){
return "A-" + ID;
}
public int getMoney(){
return money;
}
public int getStepsToLive(){
return stepsToLive;
}
public void report(){
System.out.println(getID() +
" at " +
x + ", " + y +
" has " +
getMoney() + " dollars" +
" and " +
getStepsToLive() + " steps to live.");
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public void draw(SimGraphics G){
if(stepsToLive > 10)
G.drawFastRoundRect(Color.green);
else
G.drawFastRoundRect(Color.blue);
}
public void step(){
stepsToLive--;
}
}
// CarryDropSpace
package demo;
import uchicago.src.sim.space.Object2DGrid;
public class CarryDropSpace {
private Object2DGrid moneySpace;
private Object2DGrid agentSpace;
public CarryDropSpace(int xSize, int ySize){
moneySpace = new Object2DGrid(xSize, ySize);
agentSpace = new Object2DGrid(xSize, ySize);
for(int i = 0; i < xSize; i++){
for(int j = 0; j < ySize; j++){
moneySpace.putObjectAt(i,j,new Integer(0));
}
}
}
public void spreadMoney(int money){
// Randomly place money in moneySpace
for(int i = 0; i < money; i++){
// Choose coordinates
int x = (int)(Math.random()*(moneySpace.getSizeX()));
int y = (int)(Math.random()*(moneySpace.getSizeY()));
// Get the value of the object at those coordinates
int currentValue = getMoneyAt(x, y);
// Replace the Integer object with another one with the new value
moneySpace.putObjectAt(x,y,new Integer(currentValue + 1));
}
}
public int getMoneyAt(int x, int y){
int i;
if(moneySpace.getObjectAt(x,y)!= null){
i = ((Integer)moneySpace.getObjectAt(x,y)).intValue();
}
else{
i = 0;
}
return i;
}
public Object2DGrid getCurrentMoneySpace(){
return moneySpace;
}
public Object2DGrid getCurrentAgentSpace(){
return agentSpace;
}
public boolean isCellOccupied(int x, int y){
boolean retVal = false;
if(agentSpace.getObjectAt(x, y)!=null) retVal = true;
return retVal;
}
public boolean addAgent(CarryDropAgent agent){
boolean retVal = false;
int count = 0;
int countLimit = 10 * agentSpace.getSizeX() * agentSpace.getSizeY();
while((retVal==false) && (count < countLimit)){
int x = (int)(Math.random()*(agentSpace.getSizeX()));
int y = (int)(Math.random()*(agentSpace.getSizeY()));
if(isCellOccupied(x,y) == false){
agentSpace.putObjectAt(x,y,agent);
agent.setXY(x,y);
retVal = true;
}
count++;
}
return retVal;
}
public void removeAgentAt(int x, int y){
agentSpace.putObjectAt(x, y, null);
}
}
When you run this code and step through it, the model is created, agents are green for a while, then turn blue and the disappear. For each one that disappears, however, another one appears. If you press 'play' you will see that the number of agents living, as reported every 10 timesteps, never changes.
Previous: Displays and Schedules
Next: Agents Learn Their Place
Go to Table of Contents
A RePast Tutorial by John T. Murphy, University of Arizona & Arizona State University (contact)