|
Alan Kaminsky
|
|
•
|
|
Department of Computer Science
|
|
•
|
|
Rochester Institute of Technology
|
|
•
|
|
4486 +
2220 =
6706
|
|
Home Page
|
Simulation Simplified
15. Priority Queues
Class edu.rit.sim.Simulation
//******************************************************************************
//
// File: Simulation.java
// Package: edu.rit.sim
// Unit: Class edu.rit.sim.Simulation
//
// This Java source file is copyright (C) 2011 by Alan Kaminsky. All rights
// reserved. For further information, contact the author, Alan Kaminsky, at
// ark@cs.rit.edu.
//
// This Java source file is part of the Parallel Java Library ("PJ"). PJ is free
// software; you can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// PJ is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// A copy of the GNU General Public License is provided in the file gpl.txt. You
// may also obtain a copy of the GNU General Public License on the World Wide
// Web at http://www.gnu.org/licenses/gpl.html.
//
//******************************************************************************
package edu.rit.sim;
/**
* Class Simulation provides a discrete event simulation. To write a discrete
* event simulation program:
* <OL TYPE=1>
* <P><LI>
* Create a Simulation object.
* <P><LI>
* Create one or more {@linkplain Event}s and add them to the simulation (by
* calling the <TT>doAt()</TT> or <TT>doAfter()</TT> methods).
* <P><LI>
* Run the simulation (by calling the <TT>run()</TT> method). The simulation
* performs events, by calling each event's <TT>perform()</TT> method, in order
* according to the events' simulation times, as returned by each event's
* <TT>time()</TT> method. Performing an event may cause further events to be
* created and added to the simulation.
* <P><LI>
* When there are no more events, the simulation is finished. At this point the
* simulation's <TT>run()</TT> method returns.
* </OL>
*
* @author Alan Kaminsky
* @version 29-Jul-2011
*/
public class Simulation
{
// Hidden data members.
// Minimum-priority queue of events. Uses a heap data structure. The entry
// at index 0 is a sentinel with time = 0.0.
private Event[] heap = new Event [1024];
// Number of entries in the heap (including the sentinel).
private int N = 1;
// Simulation time.
private double T = 0.0;
// Exported constructors.
/**
* Construct a new simulation.
*/
public Simulation()
{
heap[0] = new Event() { public void perform() { } };
heap[0].sim = this;
heap[0].time = 0.0;
}
// Exported operations.
/**
* Returns the current simulation time.
*
* @return Simulation time.
*/
public double time()
{
return T;
}
/**
* Schedule the given event to be performed at the given time in this
* simulation.
*
* @param t Simulation time for <TT>event</TT>.
* @param event Event to be performed.
*
* @exception IllegalArgumentException
* (unchecked exception) Thrown if <TT>t</TT> is less than the current
* simulation time.
* @exception NullPointerException
* (unchecked exception) Thrown if <TT>event</TT> is null.
*/
public void doAt
(double t,
Event event)
{
// Verify preconditions.
if (t < T)
{
throw new IllegalArgumentException
("Simulation.doAt(): t = "+t+" less than simulation time ="+T+
", illegal");
}
if (event == null)
{
throw new NullPointerException
("Simulation.doAt(): event = null");
}
// Set event fields.
event.sim = this;
event.time = t;
// Grow heap if necessary.
if (N == heap.length)
{
Event[] newheap = new Event [N + 1024];
System.arraycopy (heap, 0, newheap, 0, N);
heap = newheap;
}
// Insert event into heap in min-priority order.
heap[N] = event;
siftUp (N);
++ N;
}
/**
* Schedule the given event to be performed at a time <TT>dt</TT> in the
* future (at current simulation time + <TT>dt</TT>) in this simulation.
*
* @param dt Simulation time delta for <TT>event</TT>.
* @param event Event to be performed.
*
* @exception IllegalArgumentException
* (unchecked exception) Thrown if <TT>dt</TT> is less than zero.
* @exception NullPointerException
* (unchecked exception) Thrown if <TT>event</TT> is null.
*/
public void doAfter
(double dt,
Event event)
{
doAt (T + dt, event);
}
/**
* Run the simulation. At the start of the simulation, the simulation time
* is 0. The <TT>run()</TT> method returns when there are no more events.
*/
public void run()
{
while (N > 1)
{
// Extract minimum event from heap.
Event event = heap[1];
-- N;
heap[1] = heap[N];
heap[N] = null;
if (N > 1) siftDown (1);
// Advance simulation time and perform event.
T = event.time;
event.perform();
}
}
// Hidden operations.
/**
* Sift up the heap entry at the given index.
*
* @param c Index.
*/
private void siftUp
(int c)
{
double c_time = heap[c].time;
int p = c >> 1;
double p_time = heap[p].time;
while (c_time < p_time)
{
Event temp = heap[c];
heap[c] = heap[p];
heap[p] = temp;
c = p;
p = c >> 1;
p_time = heap[p].time;
}
}
/**
* Sift down the heap entry at the given index.
*
* @param p Index.
*/
private void siftDown
(int p)
{
double p_time = heap[p].time;
int lc = (p << 1);
double lc_time = lc < N ? heap[lc].time : Double.POSITIVE_INFINITY;
int rc = (p << 1) + 1;
double rc_time = rc < N ? heap[rc].time : Double.POSITIVE_INFINITY;
int c;
double c_time;
if (lc_time < rc_time)
{
c = lc;
c_time = lc_time;
}
else
{
c = rc;
c_time = rc_time;
}
while (c_time < p_time)
{
Event temp = heap[c];
heap[c] = heap[p];
heap[p] = temp;
p = c;
lc = (p << 1);
lc_time = lc < N ? heap[lc].time : Double.POSITIVE_INFINITY;
rc = (p << 1) + 1;
rc_time = rc < N ? heap[rc].time : Double.POSITIVE_INFINITY;
if (lc_time < rc_time)
{
c = lc;
c_time = lc_time;
}
else
{
c = rc;
c_time = rc_time;
}
}
}
}
|
Alan Kaminsky
|
|
•
|
|
Department of Computer Science
|
|
•
|
|
Rochester Institute of Technology
|
|
•
|
|
4486 +
2220 =
6706
|
|
Home Page
|
Copyright © 2011 Alan Kaminsky.
All rights reserved.
Last updated 31-Aug-2011.
Please send comments to ark@cs.rit.edu.