230 likes | 407 Views
The CarryDrop Model (Steps 19-24) : A RePast Tutorial by John Murphy. by Junjie Sun 8/16/2004 Department of Economics Iowa State University. What ’ s been done in Step 1-18. In CarryDropModel:
E N D
The CarryDrop Model (Steps 19-24) : A RePast Tutorial by John Murphy by Junjie Sun 8/16/2004 Department of Economics Iowa State University
What’s been done in Step 1-18 • In CarryDropModel: imports, private variables, setup(), begin( buildModel(), buildSchedule(), buildDisplay() ),addNewAgent(), get(), set(), main() • In CarryDropAgent: private variables, constructor, setXY(), • In CarryDropSpace: imports, private variables, constructor, spreadMoney(), getMoneyAt(), getCurrentMoneySpace(), IsCellOccupied(), addAgent()
Reporting (Step 19-1) • Providing a 'report' function that lists the values of the instance variables for a given object • Providing a unique 'ID' variable for each instance of an object • create a static variable that can be read by all instances of the class, and have the constructor increment it as a counter each time an agent is created.
'Report' function (Step 19-2) • In CarryDropModel: public void buildModel(){ … for(int i = 0; i < agentList.size(); i++){ CarryDropAgent cda = (CarryDropAgent)agentList.get(i); cda.report(); } } • In CarryDropAgent: 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."); }
Unique 'ID' variable (Step 19-3) • In CarryDropAgent: public class CarryDropAgent { … private static int IDNumber = 0; private int ID; public CarryDropAgent(int minLifeSpan, int maxLifeSpan){ … IDNumber++; ID = IDNumber; …} …}
Displaying Agents (Step 20-1) • Create an Object2DDisplay object, add the agent list to that Object2DDisplay object's list of objects, and add it to the display surface • When the objects are added to the display surface, order matters. Money space first and then agent space • Make the agents able to be drawn by implementing the 'Drawable' interface • 'get' methods for their x and y positions • 'draw' method that takes a 'SimGraphics' object as an argument
Codes for Displaying Agents (Step 20-2) -- Create an Object2DDisplay object, add it to the display surface, etc. • In CarryDropModel: import uchicago.src.sim.gui.Object2DDisplay; public void buildDisplay(){ … Value2DDisplay displayMoney = new Value2DDisplay(cdSpace.getCurrentMoneySpace( ), map); Object2DDisplay displayAgents = new Object2DDisplay(cdSpace.getCurrentAgentSpace()); displayAgents.setObjectList(agentList); displaySurf.addDisplayable(displayMoney, "Money"); displaySurf.addDisplayable(displayAgents, "Agents"); …}
Codes for Displaying Agents (Step 20-3) -- Make the agents able to be drawn by implementing 'Drawable' • In CarryDropAgent: import java.awt.Color; import uchicago.src.sim.gui.Drawable; import uchicago.src.sim.gui.SimGraphics; public class CarryDropAgent implements Drawable{ … public int getX(){ return x; } public int getY(){ return y; } public void draw(SimGraphics G){ G.drawFastRoundRect(Color.blue);}…} • In CarryDropSpace: public Object2DGrid getCurrentAgentSpace(){ return agentSpace; }
Adding a Schedule and Some Action (Step 21-1) - Motivation • At this point the model will load and run, but it won't do anything. We want to add actions to the model, so that it can be run through time without error reporting • Focus on a simple task: getting agents to 'age'. Once per timestep, the agents 'stepsToLive' variable should go down one • Ignore the implications of what will happen when 'stepsToLive' hits zero, just focus on how RePast uses a Schedule object to manage actions in the simulation.
Adding a Schedule and Some Action (Step 21-2) – Three things to do • Create a 'step' method in CarryDropAgent • Create the Schedule object in the 'setup' method; in this case we tell the object that we want it to run in timesteps with an interval of '1' • Specify what we want the Schedule object to do by creating an inner class 'CarryDropStep' and adding it to the Schedule object using one of RePast's built-in functions. These built in functions allow you to specify when the action defined by the inner class is executed.
Codes for creating a 'step' method and a Schedule object (Step 21-3) • In CarryDropAgent: public class CarryDropAgent implements Drawable{ … public void step(){ stepsToLive--; } } • In CarryDropModel: public void setup(){… schedule = new Schedule(1); …}
Codes for creating an inner class 'CarryDropStep' (Step 21-4) • In CarryDropModel: import uchicago.src.sim.engine.BasicAction; import uchicago.src.sim.util.SimUtilities; public void 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(); } } } schedule.scheduleActionBeginning(0, new CarryDropStep()); }
Notes on 'shuffle' and 'scheduleAction Beginning' routine (Step 21-5) • 'shuffle' routine makes use of another RePast built-in tool, SimUtilities, to shuffle ArrayLists. It requires you to add colt.jar to your project's build path • 'scheduleActionBeginning' routine creates a new instance of inner class, CarryDropStep, to add. (0) indicates that we want the action to be taken in the first timestep
Another Schedule Example (Step 22-1) • Motivation • Add another minor report function, for no other reason than to demonstrate another way to use the schedule object. • Two things to be added • A new method of the model class 'countLivingAgents' that counts the agents whose stepsToLive is above zero - that is, they are still 'alive' • A new inner class 'CarryDropCountLiving' that extends BasicAction and calls the new method. Note that this new inner class is paralleled to 'CarryDropStep' in Step 21
Codes for creating 'countLivingAgents' in CarryDropModel (Step 22-2) 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; }
Codes for 'CarryDropCountLiving' and how to add it to the Schedule object (Step 22-3) public void buildSchedule(){… class CarryDropCountLiving extends BasicAction { public void execute(){ countLivingAgents(); } } schedule.scheduleActionAtInterval(10, new CarryDropCountLiving()); } • Note that when adding the new CarryDropCountLiving object to the schedule object, we add it so that it is not executed every timestep, but rather is executed every 10th timestep.
Displays and Schedules (Step 23-1) • Updates to the display elements must be scheduled. This is done by adding a line to the CarryDropStep schedule item, in the execute() method. • In CarryDropModel, public void buildSchedule(){ System.out.println("Running BuildSchedule"); class CarryDropStep extends BasicAction { public void execute() {… displaySurf.updateDisplay(); } } …}
Displays and Schedules (Step 23-2) • Add one more element to our code: agents who have more than 10 steps left to live will be green, and agents who are nearing the end of their lives will turn blue • In CarryDropAgent, public void draw(SimGraphics G){ if(stepsToLive > 10) G.drawFastRoundRect(Color.green); else G.drawFastRoundRect(Color.blue); }
The Circle of Life: Agents Dying and Being Born (Step 24-1) - Motivation • 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 die routine to have agents actually die and be removed from the simulation. • On the other hand, to avoid population decreasing, we also need a newborn routine through which new agents are born.
The Circle of Life: Agents Dying and Being Born (Step 24-2) – Things to do • The die routine must do the following: • Remove the agent from the space object • Spread the agent's money across the space object • Remove the agent from the agent list • Add a 'reapDeadAgents()' method to the model • Add a 'removeAgentAt()' method to the space object • 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'
Codes for adding 'reapDeadAgents()' to the model (Step 24-3) • In CarryDropModel, 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; }
Codes for adding 'removeAgentAt()' to the space object and agent reborning (Step 24-4) • In CarryDropSpace, public void removeAgentAt(int x, int y){ agentSpace.putObjectAt(x, y, null); } • In CarryDropModel, public void buildSchedule(){… class CarryDropStep extends BasicAction { public void execute() {… int deadAgents = reapDeadAgents(); for(int i =0; i < deadAgents; i++){ addNewAgent(); } …} } …}
What’s been done in Step 1-24 • In CarryDropModel (extends SimModelImpl): imports (Java & RePast), private variables, setup(), begin( buildModel(), buildSchedule(), buildDisplay() ), private methods:addNewAgent(), reapDeadAgent(), countLivingAgents(), public access methods: get(), set(), public static void method: main() • In CarryDropAgent (implements Drawable): imports (Java & RePast), private variables, constructor, public access methods: get(), set() public utility methods: report(), draw(), step() • In CarryDropSpace: imports (RePast), private variables, constructor, public access methods: get(), set() public utility methods: spreadMoney(), IsCellOccupied(), addAgent(), removeAgentAt()