Coding a RePast S model (Non-Groovy way)
Before I write about how to write a RePast S model from scratch, the non-groovy way, let me write something that will lead to the details. Any model needs to know what is has – model descriptor, and how it is – scenario descriptor.
Model descriptors consists of agent definition – java classes, networks, space, grids etc., relation ships between them, watching and watcher triggers, schedule methods etc. Scenario descriptors tell you what the model has. It would say that the grid from the model descriptor is 2D or 3D. It would also tell you from where the agents are loaded – from the scenario loader or some class context loader. It also has charts etc i.e logging information for the model.
So what do you basically need to create a RePast S model ?
1. Define a Model – the Agents, the relationship between agents (which method to schedule when, which agent keeps an eyes on another etc.)
2. Define the Context. RePast S has a default context that spares you from writing a Context class but I will write here to illustrate. Define geometry of the model. Add the agents to that geometry. This is essentially the scenario part.
3. Load the model and run it.
Let us go through each of these steps.
1. Defining the model.
Assuming familiarity with Eclipse, load the Eclipse and create RePast S project
and name it GasNodeModel. Create an Agent GasNodeAgent, GasNodeGrid, GasNetwork. The GasNodeGrid will tell the model where the Agent GasNode is going to reside and The GasNetwork will define the interconnection between these agents. Take a look at the Scenario.xml in the directory where model.score lies.
Let me write the agent GasNodeAgent with parameter Pressure and measuredPressure, much the same from the tutorial.
package gasnodemodel; import repast.simphony.engine.schedule.ScheduledMethod; import repast.simphony.engine.watcher.Watch; import repast.simphony.engine.watcher.WatcherTriggerSchedule; import repast.simphony.parameter.Parameter; import repast.simphony.ui.probe.ProbeID; /** * @author shefali * */ public class GasNodeAgent { @Parameter (displayName = "Node Pressure", usageName = "pressure") public double getPressure() { return this.pressure; } public void setPressure(double pressure) { this.pressure = pressure; } private double pressure = 300; @Parameter (displayName = "Measured Pressure", usageName = "measuredPressure") public double getMeasuredPressure() { return this.measuredPressure; } public void setMeasuredPressure(double measuredPressure) { this.measuredPressure = measuredPressure; } private double measuredPressure = 0; @Watch( watcheeClassName = "gasnodemodel.GasNodeAgent", watcheeFieldNames = "pressure", query = "linked_from", whenToTrigger = WatcherTriggerSchedule.LATER, scheduleTriggerDelta = 10d, triggerCondition = "$watchee.getPressure()<200") public void changePressure(gasnodemodel.GasNodeAgent watchedNode) { setPressure(watchedNode.getPressure()); } @ScheduledMethod( start = 1d, interval = 1d, shuffle = true ) public void measurePressure() { double x = 0; int num = 0; for (int i=0;i<10;i++) { x = x+pressure + Math.random(); num++; } setMeasuredPressure(x/num); } @ProbeID() public String toString() { return "GasNode"; } }
Run your model. Build Displays. It goes all well! That’s all you need to make a non-groovy model.
But what if my model agents are fixed ? Yeap, lets create a context. Quite the one in SimpleHappy.
2. Define the Context.
Let me write a GasNodeContext class.
package gasnodemodel; import repast.simphony.context.Context; import repast.simphony.context.space.graph.NetworkFactoryFinder; import repast.simphony.context.space.grid.GridFactoryFinder; import repast.simphony.dataLoader.ContextBuilder; import repast.simphony.space.grid.StickyBorders; import repast.simphony.space.graph.Network; import repast.simphony.space.grid.GridBuilderParameters; import repast.simphony.space.grid.RandomGridAdder; /** * @author shefali */ public class GasNodeContext implements ContextBuilder<GasNodeAgent> { private int gasNodes = 3; public Context<GasNodeAgent> build(Context<GasNodeAgent> context) { Network<GasNodeAgent> network = NetworkFactoryFinder.createNetworkFactory(null).createNetwork("GasNetwork", context, true); GridFactoryFinder.createGridFactory(null).createGrid("GasNodeGrid", context, GridBuilderParameters.singleOccupancy2D(new RandomGridAdder<GasNodeAgent>(), new StickyBorders(), 30, 30)); GasNodeAgent gasnode = new GasNodeAgent(); context.add(gasnode); GasNodeAgent prev = gasnode; GasNodeAgent agent = null; for (int i = 0; i < gasNodes - 1; i++) { agent = new GasNodeAgent(); context.add(agent); network.addEdge(prev, agent); prev = agent; } network.addEdge(agent, gasnode); return context; } public int getNumNodes() { return gasNodes; } public void setNumNodes(int numNodes) { this.gasNodes = numNodes; } }
Lets run it. It wont work. If you look on the left pane the data loader is Score Context Builder, RePast`s default. It determines where to load data from, from scenario.xml. Let go back to this scenario.xml. It will have an element:
<repast.simphony.dataLoader.engine.ScoreDataLoaderAction context=”GasNodeModel” file=”repast.simphony.dataLoader.engine.ScoreDataLoaderAction_0.xml” />
You would need to change one last thing to get those ‘fixed’ agents in your display. Change the above line to:
<repast.simphony.dataLoader.engine.ClassNameDataLoaderAction context=“GasNodeModel” file=“repast.simphony.dataLoader.engine.ClassNameDataLoaderAction_0.xml” />
Create a file named repast.simphony.dataLoader.engine.ClassNameDataLoaderAction_0.xml in gasnodemodel.rs directory and add the line:
<string>gasnodemodel.GasNodeContext</string>
The RePast S runtime system needs to know from where to load agents, and in what to load agents. That’s what scenario.xml tells the model.
Happy creating POJO Agents !!
About this entry
You’re currently reading “Coding a RePast S model (Non-Groovy way),” an entry on Technical Musings
- Published:
- May 6, 2008 / 9:23 am
- Category:
- Agent-Based Systems, RePast S
- Tags:

1 Comment
Jump to comment form | comments rss [?] | trackback uri [?]