1 / 75

Discrete Event Simulation

Discrete Event Simulation. CS1316: Representing Structure and Behavior. Story. Discrete event simulation Simulation time != real time 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

celina
Download Presentation

Discrete Event Simulation

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Discrete Event Simulation CS1316: Representing Structure and Behavior

  2. Story • Discrete event simulation • Simulation time != real time • 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 • Building a discrete event simulation • Graphics as the representation, not the real thing: The Model and the View

  3. Imagine the simulation… • There are three Trucks that bring product from the Factory. • On average, they take 3 days to arrive. • Each truck brings somewhere between 10 and 20 products—all equally likely. • We’ve got five Distributors who pick up product from the Factory with orders. • 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?

  4. Don’t use a Continuous Simulation • We don’t want to wait that number of days in real time. • We don’t even care about every day. • There will certainly be timesteps (days) when nothing happens of interest. • We’re dealing with different probability distributions. • 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)

  5. We use a Discrete Event Simulation • We don’t simulate every moment continuously. • We simulate discrete events.

  6. What’s 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)

  7. What’s the difference?Agents don’t act() • In a discrete event simulations, agents don’t act(). • Instead, they wait for events to occur. • They schedule new events to correspond to the next thing that they’re going to do. • Key: Events get scheduled according to different probabilities.

  8. What’s the difference?Agents get blocked • Agents can’t do everything that they want to do. • If they want product (for example) and there isn’t any, they get blocked. • They can’t schedule any new events until they get unblocked. • Many agents may get blocked awaiting the same resource. • 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)

  9. 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

  10. Key idea #1: Introducing a Queue • First-In-First-Out List • First person in line is first person served I got here third! I got here second! I got here first! This is the tail of the queue This is the front or head of the queue

  11. 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! I got here second! I got here first! This is the tail of the queue This is the front or head of the queue

  12. As items leave, the head shifts I got here third! I got here second! I got here first! AND NOW I’M UP! Now, this is the front or head of the queue This is the tail of the queue Served!

  13. As new items come in, the tail shifts I got here fourth! I got here third! I got here second! Now, this is the tail of the queue Now, this is the front or head of the queue

  14. 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 don’t remove it from the queue. • size(): Return the size of the queue

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

  16. 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 don’t really want to peek() or pop() an empty queue, so we should probably check its size first.

  17. Building aQueue 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(); }

  18. 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();} We’re using a linked list to implement the Queue. The front of the LinkedList is the tail. The last of the LinkedList is the head.

  19. 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.

  20. 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;

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

  22. Queue2methods /** 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;} As the queue gets pushed and popped, it moves down the array.

  23. Same methods, same behavior 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" 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.)

  24. Key idea #2: Different kinds of random • We’ve 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?

  25. Visualizing a uniformdistribution import java.util.*; // Need this for Random import java.io.*; // For BufferedWriter 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 don’t have to do the string conversion.

  26. How do we view a distribution?A Histogram

  27. Then graph the result

  28. A Uniform Distribution

  29. A NormalDistribution // 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()); } }

  30. Graphing the normal distribution The end aren’t actually high—the tails go further.

  31. 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.

  32. A new normal distribution

  33. Key idea #3: Straightening Time • Straightening time • Inserting it into the right place • Sorting it afterwards • We’ll actually do these in reverse order: • We’ll add a new event, then sort it. • Then we’ll insert it into the right place.

  34. 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); 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()); } } } We’re stuffing the EventQueue with events whose times are out of order.

  35. 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

  36. 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(); }

  37. Mostly, it’s 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;}

  38. 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); }

  39. 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 – they’re always O(n2) • Some are O(n2) in the worst case, but on average, they’re better than that. • We’re going to try an insertion sort

  40. How an insertion sort works • Consider the event at some position (1..n) • Compare it to all the events before that position backwards—towards 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, that’s where the considered event goes. • Consider the next event…until done

  41. 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; // 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(compare-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() InsertionSort Trace this out to convince yourself it works!

  42. Useful Links on Sorting • http://ciips.ee.uwa.edu.au/~morris/Year2/PLDS210/sorting.html • http://www.cs.ubc.ca/spider/harrison/Java/sorting-demo.html • http://www.cs.brockport.edu/cs/java/apps/sorters/insertsort.html Recommended These include animations that help to see how it’s all working

  43. 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); }

  44. /** * 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);} } insertInOrder() Again, trace it out to convince yourself that it works!

  45. Finally: A Discrete Event Simulation • Now, we can assemble queues, different kinds of random, and a sorted EventQueue to create a discrete event simulation.

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

  47. What we see (not much)

  48. Time: 1.7078547183397625 Distributor: 0 Arrived at warehouse Time: 1.7078547183397625 Distributor: 0 is blocking >>> Timestep: 1 Time: 1.727166341118611 Distributor: 3 Arrived at warehouse Time: 1.727166341118611 Distributor: 3 is blocking >>> Timestep: 1 Time: 1.8778754913001443 Distributor: 4 Arrived at warehouse Time: 1.8778754913001443 Distributor: 4 is blocking >>> Timestep: 1 Time: 1.889475045031698 Distributor: 2 Arrived at warehouse Time: 1.889475045031698 Distributor: 2 is blocking >>> Timestep: 1 Time: 3.064560375192933 Distributor: 1 Arrived at warehouse Time: 3.064560375192933 Distributor: 1 is blocking >>> Timestep: 3 Time: 3.444420374970288 Truck: 2 Arrived at warehouse with load 13 Time: 3.444420374970288 Distributor: 0 unblocked! Time: 3.444420374970288 Distributor: 0 Gathered product for orders of 11 >>> Timestep: 3 Time: 3.8869697922832698 Truck: 0 Arrived at warehouse with load 18 Time: 3.8869697922832698 Distributor: 3 unblocked! Time: 3.8869697922832698 Distributor: 3 Gathered product for orders of 12 >>> Timestep: 3 Time: 4.095930381479024 Distributor: 0 Arrived at market >>> Timestep: 4 Time: 4.572840072576855 Truck: 1 Arrived at warehouse with load 20 Time: 4.572840072576855 Distributor: 4 unblocked! Time: 4.572840072576855 Distributor: 4 Gathered product for orders of 19 The detail tells the story Notice that time 2 never occurs!

  49. What questions we can answer • How long do distributors wait? • Subtract the time that they unblock from the time that they block • How much product sits in the warehouse? • 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. • Can we move more product by having more distributors or more trucks? • Try it!

  50. How DESimulation works

More Related