SE450: Simulation: Active and Passive Objects [3/13] |
Agents act.
Agents know what they want to do.
One can model agents as finite automata.
Let's say I am implementing an airline reservation system. How do I do a simulation?
A passive view of a customer:
interface Customer { void addFlight(Flight f); void removeFlight(Flight f); }
A more active view:
public interface Agent { public void run(); } class Main { List<Agent> q = new List<Agent>(); for (i=0; i<numSimulated; i++) q.add(new SimulatedCustomer()); for (i=0; i<numHuman; i++) q.add(new HumanCustomer()); for (currentTime=0; currentTime<endTime; currentTime+=timeStep) for (Agent a : q) a.run(); }
If we think of customers as "subscribing" to a time service:
public interface Agent { public void run(); } public interface TimeServer { public long currentTime(); public void add(Agent thing); public void run(int duration); } class Main { TimeService q = TimeService (); for (i=0; i<numSimulated; i++) q.add(new SimulatedCustomer()); for (i=0; i<numHuman; i++) q.add(new HumanCustomer()); q.run(duration); }
With "sparse" time you use a priority queue:
class Main { TimeServer q = new TimeServer(); for (i=0; i<numSimulated; i++) q.enqueue(q.currentTime, new SimulatedCustomer()); for (i=0; i<numHuman; i++) q.enqueue(q.currentTime, new HumanCustomer()); q.run(duration); } public interface TimeServer { public long currentTime(); public void enqueue(long time, Agent thing); public void run(int duration); } public interface Agent { public void run(); } class SimulatedCustomer implements Agent { int state; SimulatedCustomer(TimeServer q) { ... } public void run() { switch (state) { case ... ... q.enqueue(q.currentTime + 500, this); break; ... } } } class HumanCustomer implements Agent { HumanCustomer(TimeServer q, UI ui) { ... } public void run() { // create a menu whose options end with: // q.enqueue(q.currentTime + 500, this); ... ui.displayMenu(menu); } }