📄 simulation.java
字号:
/*
##############################################################################################################
Wal-Mart Checkout Simulation
By: Dustin Grimmeissen and Richard Anderson
-> Main Program and Functions
This is the core of the Wal-Mart simulation. This initializes the priority queue and then begins
generating new arrival and departure events and executing the next event. The program operates until
the variance of the custom waiting times falls within a certain error.
##############################################################################################################
*/
import java.util.Random;
import java.lang.Math;
public class Simulation implements Runnable
{
UI Interface;
int QueueNumber, ExpressNumber;
double ArrRate, RegServRate, ExpServRate;
//------------------------------------------------------------------------
// main - Initializes the Simulation and creates a User Interface
//------------------------------------------------------------------------
public static void main( String args[] )
{
Simulation App = new Simulation();
App.Interface = new UI(App);
App.Interface.Initialize();
}
//------------------------------------------------------------------------
// run - This is used to allow the UI to call ExecuteSimulation()
//------------------------------------------------------------------------
public void run()
{
ExecuteSimulation();
}
//------------------------------------------------------------------------
// setValues - This is used by the UI to pass the entered values into the
// main simulation program.
//------------------------------------------------------------------------
public void setValues(int NumQueues, int NumExpress, double ArrivalRate, double RegularLane, double ExpressLane)
{
QueueNumber = NumQueues;
ExpressNumber = NumExpress;
ArrRate = ArrivalRate;
RegServRate = RegularLane;
ExpServRate = ExpressLane;
}
//------------------------------------------------------------------------
// ExecuteSimulation - This function performs the entire process of the
// discrete time simulation. A priority queue is created
// along with a set of service lane queues based on the
// amount the user requested. The program does not store
// any calculations until 5,000 customers have already
// been process. After this, the simulation runs until
// the variance of total waiting times drops below an
// error value of 0.0000001.
//------------------------------------------------------------------------
public void ExecuteSimulation()
{
// Initialize all queues and variables to store data
// -------------------------------------------------
int NumberLanes = QueueNumber;
long CurrentTime = 0;
double ArrivalRate = ArrRate;
double RegularLane = RegServRate;
double ExpressLane = ExpServRate;
PriorityQueue PriQueue = new PriorityQueue();
Queue CheckoutLane[] = new Queue[NumberLanes];
for (int i = 0; i < NumberLanes-ExpressNumber; i++)
CheckoutLane[i] = new Queue(RegularLane);
for (int i = NumberLanes-ExpressNumber; i < NumberLanes; i++)
CheckoutLane[i] = new Queue(ExpressLane);
double TotalWait[] = new double[NumberLanes+1];
double TotalResponse[] = new double[NumberLanes+1];
double NumCustomers[] = new double[NumberLanes+1];
double PreviousWait = 0;
double CurrentWait = 0;
double CurrentAvg = 0;
double PreviousAvg = 0;
double DesiredError = 0.0000001;
double Error = 1;
// Generate Initial Arrival
// ------------------------
Customer FirstCustomer = new Customer (1);
PriQueue.enqueue(FirstCustomer, 1, 1);
// Begin simulation process
// -------------------------
while (Error >= DesiredError)
{
Event NextEvent = PriQueue.dequeue();
int Lane;
long Priority;
CurrentTime = NextEvent.getPriority();
// Check To See If Current Event Is Arrival Or Departure
if (NextEvent.getType() == 1)
{
Lane = ChooseLane(NumberLanes);
if (CheckoutLane[Lane].getSize() == 0)
{
Priority = CurrentTime + ExpVar(CheckoutLane[Lane].getRate());
NextEvent.EventCustomer.BeginService(CurrentTime);
PriQueue.enqueue(NextEvent.EventCustomer, Priority, 2);
}
NextEvent.EventCustomer.setLane(Lane);
CheckoutLane[Lane].enqueue(NextEvent.EventCustomer);
PrintLanes(CheckoutLane, NumberLanes);
Priority = CurrentTime + ExpVar(ArrivalRate);
Customer NextArrival = new Customer(Priority);
PriQueue.enqueue(NextArrival, Priority, 1);
}
else
{
Lane = NextEvent.EventCustomer.getLane();
Customer DepartCustomer = CheckoutLane[Lane].dequeue();
DepartCustomer.EndService(CurrentTime);
NumCustomers[NumberLanes]++;
if (NumCustomers[NumberLanes] > 5000)
{
NumCustomers[Lane]++;
PreviousWait = TotalWait[NumberLanes];
CurrentWait = (DepartCustomer.getServiceStartTime() - DepartCustomer.getArrivalTime());
TotalWait[NumberLanes] += CurrentWait;
TotalWait[Lane] += CurrentWait;
TotalResponse[NumberLanes] += (DepartCustomer.getDepartureTime() - DepartCustomer.getArrivalTime());
TotalResponse[Lane] += (DepartCustomer.getDepartureTime() - DepartCustomer.getArrivalTime());
}
if (NumCustomers[NumberLanes] > 5002)
{
CurrentAvg = TotalWait[NumberLanes]/(NumCustomers[NumberLanes]-5000.0);
PreviousAvg = PreviousWait/(NumCustomers[NumberLanes]-5001.0);
if ((((CurrentAvg+PreviousAvg) > 0) && ((CurrentAvg-PreviousAvg) != 0)) || (Error < 0.0001))
Error = Math.abs((CurrentAvg-PreviousAvg)/(CurrentAvg+PreviousAvg));
}
if (CheckoutLane[Lane].getSize() > 0)
{
Priority = CurrentTime + ExpVar(CheckoutLane[Lane].getRate());
Customer NextDepart = DepartCustomer.NextInLine;
NextDepart.BeginService(CurrentTime);
PriQueue.enqueue(NextDepart, Priority, 2);
}
PrintLanes(CheckoutLane, NumberLanes);
}
}
NumCustomers[NumberLanes] -= 5000.0;
Interface.FinishSimulation(NumCustomers, TotalWait, TotalResponse, ArrivalRate, CheckoutLane, NumberLanes);
}
//------------------------------------------------------------------------
// ExpVar - This function is passed a value of Lamda and uses the inverse
// transformation of the CDF to generate an exponential random
// variable.
//------------------------------------------------------------------------
public static long ExpVar(double Lamda)
{
long x = 0;
Random randNumber = new Random();
double u, Variate;
while( x == 0 )
{
u = randNumber.nextDouble();
Variate = (-1)*(1/Lamda)*(Math.log(u));
x = Math.round(Variate);
}
return x;
}
//------------------------------------------------------------------------
// ChooseLane - Assigns which checkout lane a customer chooses based on an
// even probability for each lane.
//------------------------------------------------------------------------
public static int ChooseLane(int Lanes)
{
Random randNumber = new Random();
int x = randNumber.nextInt(99);
return ((x+1)%Lanes);
}
//------------------------------------------------------------------------
// ChooseLane - Passes a current picture of each lain to the UI so that it
// can be displayed on the screen.
//------------------------------------------------------------------------
public void PrintLanes(Queue theLanes[], int Lanes)
{
String PrintString = new String("");
for (int i = 0; i < Lanes; i++)
{
PrintString += "Queue " + (i+1) + ": ";
for (int j = 0; j < theLanes[i].getSize(); j++)
{
PrintString += "*";
}
PrintString += "\n";
}
Interface.setProcessText(PrintString);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -