You are on page 1of 74

Discrete Event Simulation

CS1316: Representing
Structure and Behavior

Story

Discrete event simulation

Simulation time != real time

A Queue

Different kinds of random


Straightening time

Key ideas:

A Queue is a queue, no matter how implemented.

Inserting it into the right place


Sorting it afterwards

Building a discrete event simulation

Graphics as the representation, not the real thing: The


Model and the View

Imagine the simulation

There are three Trucks that bring product from the


Factory.

Weve got five Distributors who pick up product from the


Factory with orders.

On average, they take 3 days to arrive.


Each truck brings somewhere between 10 and 20 products
all equally likely.
Usually they want from 5 to 25 products, all equally likely.

It takes the Distributors an average of 2 days to get back


to the market, and an average of 5 days to deliver the
products.
Question we might wonder: How much product gets sold
like this?

Dont use a Continuous


Simulation

We dont want to wait that number of days in real time.


We dont even care about every day.

Were dealing with different probability distributions.

There will certainly be timesteps (days) when nothing


happens of interest.
Some uniform, some normally distributed.

Things can get out of synch

A Truck may go back to the factory and get more product


before a Distributor gets back.
A Distributor may have to wait for multiple trucks to fulfill
orders (and other Distributors might end up waiting in line)

We use a Discrete Event


Simulation
We

dont simulate every moment


continuously.
We simulate discrete events.

Whats the difference?


No time loop
In

a discrete event simulation: There is


no time loop.

There are events that are scheduled.


At each run step, the next scheduled event
with the lowest time gets processed.

The current time is then that time, the time that that
event is supposed to occur.

Key:

We have to keep the list of


scheduled events sorted (in order)

Whats the difference?


Agents dont act()
In

a discrete event simulations, agents


dont act().

Instead, they wait for events to occur.


They schedule new events to correspond to
the next thing that theyre going to do.

Key:

Events get scheduled according to


different probabilities.

Whats the difference?


Agents get blocked

Agents cant do everything that they want to do.


If they want product (for example) and there isnt any,
they get blocked.

Many agents may get blocked awaiting the same


resource.

They cant schedule any new events until they get


unblocked.

More than one Distributor may be awaiting arrival of Trucks

Key: We have to keep track of the Distributors waiting in


line (in the queue)

Key Ideas

A Queue

A Queue is a queue, no matter how implemented.

Different kinds of random


Straightening time

Inserting it into the right place


Sorting it afterwards

Key idea #1:


Introducing a Queue
First-In-First-Out

List

First person in line is first person served


I got here
third!

This is the tail


of the queue

I got here
second!

I got here
first!

This is the
front or head
of the queue

First-in-First-out
New

items only get added to the tail.

Never in the middle


Items

only get removed from the head.

I got here
third!

This is the tail


of the queue

I got here
second!

I got here
first!

This is the
front or head
of the queue

As items leave, the head shifts


I got here
third!

I got here
second!

This is the tail


of the queue

Now, this is
the front or
head of the
queue

I got here
first! AND
NOW IM UP!

Served!

As new items come in, the tail


shifts

I got here
fourth!
Now, this is
the tail of the
queue

I got here
third!

I got here
second!

Now, this is
the front or
head of the
queue

What can we do with queues?


push(anObject):

Tack a new object onto


the tail of the queue
pop(): Pull the end (head) object off the
queue.
peek(): Get the head of the queue, but
dont remove it from the queue.
size(): Return the size of the queue

Building a Queue
> Queue line = new Queue();
> line.push("Fred");
> line.push("Mary");
> line.push("Jose");
> line.size()
3

Accessing a Queue
> line.peek()
"Fred"
> line.pop()
"Fred"
> line.peek()
"Mary"
> line.pop()
"Mary"
> line.peek()
"Jose"
> line.pop()
"Jose"
> line.pop()
java.util.NoSuchElementException:

We dont really
want to peek()
or pop() an
empty queue,
so we should
probably check
its size first.

Building a
Queue
import java.util.*; // LinkedList representation
/**
* Implements a simple queue
**/
public class Queue {
/** Where we'll store our elements */
public LinkedList elements;
/// Constructor
public Queue(){
elements = new LinkedList();
}

Queue methods
/// Methods
/** Push an object onto the Queue */
public void push(Object element){
elements.addFirst(element);
}
/** Peek at, but don't remove, top of queue */
public Object peek(){
return elements.getLast();}
/** Pop an object from the Queue */
public Object pop(){
Object toReturn = this.peek();
elements.removeLast();
return toReturn;
}
/** Return the size of a queue */
public int size() { return elements.size();}

Were using a linked


list to implement the
Queue.
The front of the
LinkedList is the tail.
The last of the
LinkedList is the
head.

A queue is a queue, no matter


what lies beneath.

Our description of the queue minus the


implementation is an example of an abstract
data type (ADT).

An abstract type is a description of the methods that a


data structure knows and what the methods do.

We can actually write programs that use the


abstract data type without specifying the
implementation.

There are actually many implementations that will


work for the given ADT.
Some are better than others.

Array-oriented Queue
/**
* Implements a simple queue
**/
public class Queue2 {
private static int ARRAYSIZE = 20;
/** Where we'll store our elements */
private Object[] elements;
/** The indices of the head and tail */
private int head;
private int tail;

Queue = array + head index +


tail index
/// Constructor
public Queue2(){
elements = new Object[ARRAYSIZE];
head = 0;
tail = 0;
}

Queue2
methods

As the queue gets


pushed and
popped, it moves
down the array.

/** Push an object onto the Queue */


public void push(Object element){
if ((tail + 1) >= ARRAYSIZE) {
System.out.println("Queue underlying implementation
failed");
}
else {
// Store at the tail,
// then increment to a new open position
elements[tail] = element;
tail++; } }
/** Peek at, but don't remove, top of queue */
public Object peek(){
return elements[head];}
/** Pop an object from the Queue */
public Object pop(){
Object toReturn = this.peek();
if (((head + 1) >= ARRAYSIZE) ||
(head > tail)) {
System.out.println("Queue underlying implementation
failed.");
return toReturn;
}
else {
// Increment the head forward, too.
head++;
return toReturn;}}
/** Return the size of a queue */
public int size() { return tail-head;}

Same methods,
same behavior
But can only handle up
to 20 elements in the
queue! Less if pushing
and popping. Could shift
elements to always
allow 20.
Not as good an
implementation as the
linked list
implementation. (But
uses less memory.)

Welcome to DrJava.
> Queue2 line = new Queue2();
> line.push("Mary")
> line.push("Kim")
> line.push("Ron")
> line.peek()
"Mary"
> line.pop()
"Mary"
> line.peek()
"Kim"
> line.size()
2
> line.pop()
"Kim"
> line.pop()
"Ron"

Key idea #2:

Different kinds of random


Weve

been dealing with uniform random


distributions up until now, but those are
the least likely random distribution in real
life.
How can we generate some other
distributions, including some that are
more realistic?

import java.util.*; // Need this for Random


import java.io.*; // For BufferedWriter

Visualizing
a uniform
distribution

public class GenerateUniform {


public static void main(String[] args) {
Random rng = new Random(); // Random Number Generator
BufferedWriter output=null; // file for writing
// Try to open the file
try {
// create a writer
output =
new BufferedWriter(new FileWriter("D:/cs1316/uniform.txt"));
} catch (Exception ex) {
System.out.println("Trouble opening the file.");
}
// Fill it with 500 numbers between 0.0 and 1.0, uniformly
distributed
for (int i=0; i < 500; i++){
try{
output.write("\t"+rng.nextFloat());
output.newLine();
} catch (Exception ex) {
System.out.println("Couldn't write the data!");
System.out.println(ex.getMessage());
}
}
// Close the file
try{
output.close();}
catch (Exception ex)
{System.out.println("Something went wrong closing the file");}

By writing out a
tab and the
integer, we dont
have to do the
string conversion.

}
}

How do we view a distribution?


A Histogram

Then graph the result

A Uniform Distribution

A Normal
Distribution
// Fill it with 500 numbers between -1.0 and 1.0, normally distributed
for (int i=0; i < 500; i++){
try{
output.write("\t"+rng.nextGaussian());
output.newLine();
} catch (Exception ex) {
System.out.println("Couldn't write the data!");
System.out.println(ex.getMessage());
}
}

Graphing the normal distribution

The end arent


actually high
the tails go
further.

How do we shift the distribution


where we want it?
// Fill it with 500 numbers with a mean of 5.0 and a
//larger spread, normally distributed
for (int i=0; i < 500; i++){
try{
output.write("\t"+((range * rng.nextGaussian())+mean));
output.newLine();
} catch (Exception ex) {
System.out.println("Couldn't write the data!");
System.out.println(ex.getMessage());
}
}
Multiply the random nextGaussian()
by the range you want, then add the
mean to shift it where you want it.

A new normal distribution

Key idea #3: Straightening Time


Straightening

time

Inserting it into the right place


Sorting it afterwards
Well

actually do these in reverse order:

Well add a new event, then sort it.


Then well insert it into the right place.

Exercising
an EventQueue

public class EventQueueExercisor {


public static void main(String[] args){
// Make an EventQueue
EventQueue queue = new EventQueue();
// Now, stuff it full of events, out of order.
SimEvent event = new SimEvent();
event.setTime(5.0);
queue.add(event);
event = new SimEvent();
event.setTime(2.0);
queue.add(event);

Were stuffing the EventQueue


with events whose times are out of
order.

event = new SimEvent();


event.setTime(7.0);
queue.add(event);
event = new SimEvent();
event.setTime(0.5);
queue.add(event);
event = new SimEvent();
event.setTime(1.0);
queue.add(event);
// Get the events back, hopefull in order!
for (int i=0; i < 5; i++) {
event = queue.pop();
System.out.println("Popped event
time:"+event.getTime());
}
}
}

If it works right, should look like


this:
Welcome to DrJava.
> java EventQueueExercisor
Popped event time:0.5
Popped event time:1.0
Popped event time:2.0
Popped event time:5.0
Popped event time:7.0

Implementing an EventQueue
import java.util.*;
/**
* EventQueue
* It's called an event "queue," but it's not really.
* Instead, it's a list (could be an array, could be a linked list)
* that always keeps its elements in time sorted order.
* When you get the nextEvent, you KNOW that it's the one
* with the lowest time in the EventQueue
**/
public class EventQueue {
private LinkedList elements;
/// Constructor
public EventQueue(){
elements = new LinkedList();
}

Mostly, its a queue


public SimEvent peek(){
return (SimEvent) elements.getFirst();}
public SimEvent pop(){
SimEvent toReturn = this.peek();
elements.removeFirst();
return toReturn;}
public int size(){return elements.size();}
public boolean empty(){return this.size()==0;}

Two options for add()


/**
* Add the event.
* The Queue MUST remain in order, from lowest time to
highest.
**/
public void add(SimEvent myEvent){
// Option one: Add then sort
elements.add(myEvent);
this.sort();
//Option two: Insert into order
//this.insertInOrder(myEvent);
}

There are lots of sorts!


Lots

of ways to keep things in order.

Some are faster best are O(n log n)


Some are slower theyre always O(n )
Some are O(n ) in the worst case, but on
2

average, theyre better than that.

Were

going to try an insertion sort

How an insertion sort works

Consider the event at some position (1..n)


Compare it to all the events before that
position backwardstowards 0.

If the comparison event time is LESS THAN the


considered event time, then shift the comparison
event down to make room.
Wherever we stop, thats where the considered event
goes.

Consider the next eventuntil done

Insertion
Sort
public void sort(){
// Perform an insertion sort
// For comparing to elements at smaller indices
SimEvent considered = null;
SimEvent compareEvent = null; // Just for use in
loop
// Smaller index we're comparing to
int compare;
// Start out assuming that position 0 is "sorted"
// When position==1, compare elements at
indices 0 and 1
// When position==2, compare at indices 0, 1,
and 2, etc.
for (int position=1; position < elements.size();
position++){
considered = (SimEvent) elements.get(position);
// Now, we look at "considered" versus the
elements
// less than "compare"
compare = position;

Trace this out to convince yourself it


works!

// While the considered event is greater than the


compared event ,
// it's in the wrong place, so move the
elements up one.
compareEvent = (SimEvent)
elements.get(compare-1);
while (compareEvent.getTime() >
considered.getTime()) {
elements.set(compare,elements.get(compar
e-1));
compare = compare-1;
// If we get to the end of the array, stop
if (compare <= 0) {break;}
// else get ready for the next time through
the loop
else {compareEvent = (SimEvent)
elements.get(compare-1);}
}
// Wherever we stopped, this is where
"considered" belongs
elements.set(compare,considered);
} // for all positions 1 to the end
} // end of sort()

Useful Links on Sorting


http://ciips.ee.uwa.edu.au/~morris/Year2

/PLDS210/sorting.html
http://www.cs.ubc.ca/spider/harrison/Jav
a/sorting-demo.html
http://www.cs.brockport.edu/cs/java/apps/
sorters/insertsort.html
Recommended

These include animations that help to


see how its all working

Option #2: Put it in the right


place
/**
* Add the event.
* The Queue MUST remain in order, from lowest time to
highest.
**/
public void add(SimEvent myEvent){
// Option one: Add then sort
//elements.add(myEvent);
//this.sort();
//Option two: Insert into order
this.insertInOrder(myEvent);
}

Again, trace it out to convince


yourself that it works!

insertInOrder()
/**
* Put thisEvent into elements, assuming
* that it's already in order.
**/
public void insertInOrder(SimEvent
thisEvent){
SimEvent comparison = null;
// Have we inserted yet?
boolean inserted = false;
for (int i=0; i < elements.size(); i++){
comparison = (SimEvent)
elements.get(i);

// Assume elements from 0..i are less than


thisEvent
// If the element time is GREATER,
insert here and
// shift the rest down
if (thisEvent.getTime() <
comparison.getTime()) {
//Insert it here
inserted = true;
elements.add(i,thisEvent);
break; // We can stop the search loop
}
} // end for
// Did we get through the list without
finding something
// greater? Must be greater than any
currently there!
if (!inserted) {
// Insert it at the end
elements.addLast(thisEvent);}
}

Finally: A Discrete Event


Simulation
Now,

we can assemble queues, different


kinds of random, and a sorted
EventQueue to create a discrete event
simulation.

Running a DESimulation
Welcome to DrJava.
> FactorySimulation fs = new
FactorySimulation();
> fs.openFrames("D:/temp/");
> fs.run(25.0)

What we see (not much)

The detail tells the story


Time:
1.7078547183397625
Time:
1.7078547183397625
>>> Timestep: 1
Time:
1.727166341118611
Time:
1.727166341118611
>>> Timestep: 1
Time:
1.8778754913001443
Time:
1.8778754913001443
>>> Timestep: 1
Time:
1.889475045031698
Time:
1.889475045031698
>>> Timestep: 1
Time:
3.064560375192933
Time:
3.064560375192933
>>> Timestep: 3
Time:
3.444420374970288
Time:
3.444420374970288
Time:
3.444420374970288
>>> Timestep: 3
Time:
3.8869697922832698
Time:
3.8869697922832698
Time:
3.8869697922832698
>>> Timestep: 3
Time:
4.095930381479024
>>> Timestep: 4
Time:
4.572840072576855
Time:
4.572840072576855
Time:
4.572840072576855

Distributor: 0
Distributor: 0

Arrived at warehouse
is blocking

Distributor: 3
Distributor: 3

Arrived at warehouse
is blocking

Distributor: 4
Distributor: 4

Arrived at warehouse
is blocking

Distributor: 2
Distributor: 2

Arrived at warehouse
is blocking

Distributor: 1
Distributor: 1

Arrived at warehouse
is blocking

Notice that
time 2 never
occurs!

Truck: 2
Arrived at warehouse with load
13
Distributor: 0
unblocked!
Distributor: 0
Gathered product for orders of

11

Truck: 0
Arrived at warehouse with load
18
Distributor: 3
unblocked!
Distributor: 3
Gathered product for orders of

12

Distributor: 0

Arrived at market

Truck: 1
Arrived at warehouse with load
20
Distributor: 4
unblocked!
Distributor: 4
Gathered product for orders of

19

What questions we can answer

How long do distributors wait?

How much product sits in the warehouse?

Subtract the time that they unblock from the time that
they block
At each time a distributor leaves, figure out how much
is left in the warehouse.

How long does the line get at the warehouse?

At each block, count the size of the queue.

Try it!

Can we move more product by having more


distributors or more trucks?

How DESimulation works

FactorySimulation: Extend a few


classes

DESimulation: Sets the Stage


DESimulation

calls setUp to create


agents and schedule the first events.
It provides log for writing things out to
the console and a text file.
When it run()s, it processes each event
in the event queue and tells the
corresponding agent to process a
particular message.

What a DESimulation does:


// While we're not yet at the stop time,
// and there are more events to process
while ((now < stopTime) && (!events.empty())) {
topEvent = events.pop();
// Whatever event is next, that time is now
now = topEvent.getTime();
// Let the agent now that its event has occurred
topAgent = topEvent.getAgent();
topAgent.processEvent(topEvent.getMessage());
// repaint the world to show the movement
// IF there is a world
if (world != null) {
world.repaint();}
// Do the end of step processing
this.endStep((int) now);
}

As long as there are


events in the queue,
and were not at the
stopTime:
Grab an event.
Make its time now
Process the event.

Whats an Event (SimEvent)?


/**
* SimulationEvent (SimEvent) -- an event that occurs in a simulation,
* like a truck arriving at a factory, or a salesperson leaving the
* market
**/
public class SimEvent{
/// Fields ///
/** When does this event occur? */
public double time;

Its a time, an
Agent, and an
integer that the
Agent will
understand as a
message

/** To whom does it occur? Who should be informed when it occurred? */


public DEAgent whom;
/** What is the event? We'll use integers to represent the meaning
* of the event -- the "message" of the event.
* Each agent will know the meaning of the integer for themselves.
**/
public int message;

DEAgent: Process events, block


if needed

DEAgents define the constants for messages:


What will be the main events for this agent?
If the agent needs a resource, it asks to see if
its available, and if not, it blocks itself.
It will be told to unblock when its ready.
Agents are responsible for scheduling their
OWN next event!

An Example: A Truck
/**
* Truck -- delivers product from Factory
* to Warehouse.
**/
public class Truck extends DEAgent {
/////// Constants for Messages
public static final int FACTORY_ARRIVE = 0;
public static final int WAREHOUSE_ARRIVE = 1;
////// Fields /////
/**
* Amount of product being carried
**/
public int load;

How Trucks start


/**
* Set up the truck
* Start out at the factory
**/
public void init(Simulation thisSim){
// Do the default init
super.init(thisSim);
this.setPenDown(false); // Pen up
this.setBodyColor(Color.green); // Let green deliver!

The truck gets a load,


then schedules itself
to arrive at the
Warehouse.

// Show the truck at the factory


this.moveTo(30,350);
// Load up at the factory, and set off for the warehouse
load = this.newLoad();
((DESimulation) thisSim).addEvent(
new SimEvent(this,tripTime(),WAREHOUSE_ARRIVE));
}

tripTime() uses the normal


distribution
/** A trip distance averages 3 days */
public double tripTime(){
double delay = randNumGen.nextGaussian()+3;
if (delay < 1)
// Must take at least one day
{return 1.0+((DESimulation) simulation).getTime();}
else {return delay+((DESimulation) simulation).getTime();}
}

newLoad() uses uniform


/** A new load is between 10 and 20 on a
uniform distribution */
public int newLoad(){
return 10+randNumGen.nextInt(11);
}

How a Truck processes Events


/**
* Process an event.
* Default is to do nothing with it.
**/
public void processEvent(int message){
switch(message){
case FACTORY_ARRIVE:
// Show the truck at the factory
((DESimulation) simulation).log(this.getName()+"\t Arrived at factory");
this.moveTo(30,350);
// Load up at the factory, and set off for the warehouse
load = this.newLoad();
((DESimulation) simulation).addEvent(
new SimEvent(this,tripTime(),WAREHOUSE_ARRIVE));
break;

Truck Arriving at the Warehouse


case WAREHOUSE_ARRIVE:
// Show the truck at the warehouse
((DESimulation) simulation).log(this.getName()+"\t Arrived at
warehouse with load \t"+load);
this.moveTo(50,50);
// Unload product -- takes zero time (unrealistic!)
((FactorySimulation) simulation).getProduct().add(load);
load = 0;
// Head back to factory
((DESimulation) simulation).addEvent(
new SimEvent(this,tripTime(),FACTORY_ARRIVE));
break;

What Resources do

They keep track of what amount they have


available (of whatever the resource is).
They keep a queue of agents that are blocked
on this resource.
They can add to the resource, or have it
consume(d).

When more resource comes in, the head of the queue


gets asked if its enough. If so, it can unblock.

How Resources alert agents


/**
* Add more produced resource.
* Is there enough to unblock the first
* Agent in the Queue?
**/
public void add(int production) {
amount = amount + production;
if (!blocked.empty()){
// Ask the next Agent in the queue if it can be unblocked
DEAgent topOne = (DEAgent) blocked.peek();
// Is it ready to run given this resource?
if (topOne.isReady(this)) {
// Remove it from the queue
topOne = (DEAgent) blocked.pop();
// And tell it its unblocked
topOne.unblocked(this);
}
}
}

An example blocking agent:


Distributor
/**
* Distributor -- takes orders from Market to Warehouse,
* fills them, and returns with product.
**/
public class Distributor extends DEAgent {
/////// Constants for Messages
public static final int MARKET_ARRIVE = 0;
public static final int MARKET_LEAVE = 1;
public static final int WAREHOUSE_ARRIVE = 2;
/** AmountOrdered so-far */
int amountOrdered;

Distributors start in the Market


public void init(Simulation thisSim){
//First, do the normal stuff
super.init(thisSim);
this.setPenDown(false); // Pen up
this.setBodyColor(Color.blue); // Go Blue!
// Show the distributor in the market
this.moveTo(600,460); // At far right
// Get the orders, and set off for the warehouse
amountOrdered = this.newOrders();
((DESimulation) thisSim).addEvent(
new SimEvent(this,tripTime(),WAREHOUSE_ARRIVE));
}

Distributors have 3 events


Arrive

in Market: Schedule how long itll


take to deliver.
Leave Market: Schedule arrive at the
Factory
Arrive at Warehouse: Is there enough
product available? If not, block and wait
for trucks to bring enough product.

Processing Distributor Events


/**
* Process an event.
* Default is to do nothing with it.
**/
public void processEvent(int message){
switch(message){
case MARKET_ARRIVE:
// Show the distributor at the market, far left
((DESimulation) simulation).log(this.getName()+"\t Arrived at
market");
this.moveTo(210,460);
// Schedule time to deliver
((DESimulation) simulation).addEvent(
new SimEvent(this,timeToDeliver(),MARKET_LEAVE));
break;

Leaving the Market


case MARKET_LEAVE:
// Show the distributor at the market, far right
((DESimulation) simulation).log(this.getName()+"\t
Leaving market");
this.moveTo(600,460);
// Get the orders, and set off for the warehouse
amountOrdered = this.newOrders();
((DESimulation) simulation).addEvent(
new
SimEvent(this,tripTime(),WAREHOUSE_ARRIVE));
break;

Arriving at the Warehouse


case WAREHOUSE_ARRIVE:
// Show the distributor at the warehouse
((DESimulation) simulation).log(this.getName()+"\t Arrived at warehouse");
this.moveTo(600,50);
// Is there enough product available?
Resource warehouseProduct = ((FactorySimulation) simulation).getProduct();
if (warehouseProduct.amountAvailable() >= amountOrdered)
{
// Consume the resource for the orders
warehouseProduct.consume(amountOrdered); // Zero time to load?
((DESimulation) simulation).log(this.getName()+"\t Gathered product for orders of
\t"+amountOrdered);
// Schedule myself to arrive at the Market
((DESimulation) simulation).addEvent(
new SimEvent(this,tripTime(),MARKET_ARRIVE));
}
else {// We have to wait until more product arrives!
((DESimulation) simulation).log(this.getName()+"\t is blocking");
waitFor(((FactorySimulation) simulation).getProduct());}
break;

Is there enough product?


/** Are we ready to be unlocked? */
public boolean isReady(Resource res) {
// Is the amount in the factory more than our orders?
return ((FactorySimulation)
simulation).getProduct().amountAvailable() >=
amountOrdered;}

If so, well be unblocked


/**
* I've been unblocked!
* @param resource the desired resource
**/
public void unblocked(Resource resource){
super.unblocked(resource);
// Consume the resource for the orders
((DESimulation) simulation).log(this.getName()+"\t unblocked!");
resource.consume(amountOrdered); // Zero time to load?
((DESimulation) simulation).log(this.getName()+"\t Gathered product for orders
of \t"+amountOrdered);
// Schedule myself to arrive at the Market
((DESimulation) simulation).addEvent(
new SimEvent(this,tripTime(),MARKET_ARRIVE));
}

The Overall Factory Simulation


/**
* FactorySimulation -- set up the whole simulation,
* including creation of the Trucks and Distributors.
**/
public class FactorySimulation extends DESimulation {
private Resource product;
/**
* Accessor for factory
**/
public FactoryProduct getFactory(){return factory;}

Setting up
the
Factory
Simulation

public void setUp(){


// Let the world be setup
super.setUp();
// Give the world a reasonable background
FileChooser.setMediaPath("D:/cs1316/MediaSources/");
world.setPicture(new Picture(
FileChooser.getMediaPath("EconomyBackground.jpg"))
);
// Create a warehouse resource
product = new Resource(); //Track product
// Create three trucks
Truck myTruck = null;
for (int i=0; i<3; i++){
myTruck = new Truck(world,this);
myTruck.setName("Truck: "+i);}
// Create five Distributors
Distributor sales = null;
for (int i=0; i<5; i++){
sales = new Distributor(world,this);
sales.setName("Distributor: "+i);}
}

The Master Data Structure List:


We use almost everything here!
Queues:

For storing the agents waiting in

line.
EventQueues: For storing the events
scheduled to occur.
LinkedList: For storing all the agents.

You might also like