Jobshop Simulation Model
This file describes a JobShop simulation model which illustrates how the EAS-E
set processing software may be used in simulation programming. Sample inputs
and outputs from this model will be found in:
An EAS (entity attribute and set) description is in
The header files for the model are in:
The CPP files of the model are the following:
A zipped version of all these files can be downloaded from
General Description of Model
Each job in the JobShop model is of one or another “standard type”.
Sales--that is, new orders--of jobs of a standard type arrive according to an
exponential process whose mean time between arrivals is specified by the user.
Each job of the type is processed through a set of steps referred to as the “routing” of
the type. Each step of this routing is characterized by what machine group is
required; how much process time is required; and what is the priority of the
job at this step in the routing. At each step, the job needs one machine from
the specified machine group for “process-time” length.
The first line of the Input file reads
length of simulation (in decimal days): 100.0
The program skips over the text up to the colon. The text is for documentation
only. The program expects the LengthOfRun variable to appear after the colon.
Similarly with the remainder of the input file, text is for documentation
and colons mark the beginning of numbers which are expected in a fixed
Following the length of simulation, the Input routines read the number
of machine groups; the number of machines in each machine group; the
number of standard
job types; and, for each standard job type, the mean time between sales,
and the number of steps in its routing. Then, for each step in its
routing, it reads
the machine group required, the process time required, the priority of the
job at that step, and the number of jobs initially in the shop at that
The input file is processed by the ReadInputData() routine in the
The file JobShopOutputs.txt presents shop utilization and performance
reports. This includes the average, standard deviation and maximum
of queue size for each
machine group; the average, standard deviation and maximum number of idle
machines for each machine group; and the average, standard deviation
and maximum time
in shop for jobs of each standard type. These reports are produced by
While the simulation is running, the model writes the following information
to the screen:
a copy of the input data;
the message “start simulation”;
messages: “day 10”, “day 20”, …;
a message declaring end of simulation.
Main timing loop
In the routine Time_keeper::Simulate() in the file “Time_keeper.cpp, the
section of code following the comment “//Main Timing loop” can be
used as a pattern for any event driven simulation. The simulation contains one
entity (object) of type (class) time_keeper, namely the global object, Timer.
As noted in the JobShop EAS description, the time_keeper owns a set called Calendar.
See the events.h file for how this is told to C++. Note there that time_keeper
also has “methods” called Cause, Simulate and End _Simulation.
The Cause statement in the time_keeper file does little more than file a coming
onto the Calendar according to its time of occurrence.
The main routine, which gets control first, opens the Input and Output
files, invokes the ReadInputData routine and then Timer.Simulate(). Among
things, the ReadInputData causes--that is, files into the calendar of
first sale of each standard type, and end of process coming-event notices
for each job in process when the simulation starts. The main timing loop
the first coming event notice from the calendar, and then switches according
to event type. Each case in the switch calls on the appropriate event
routine. This switch can be modified to accommodate additional or other
an event driven simulation.
Accumulated and Tallied Variables
The Jobshop simulator includes classes called Accumulated_variable
and Tallied_variable. See the EAS description or the header file Accumulated_Tallied_Variables.h.
methods used by objects of these classes are located in the file Acc_Tal_Variables.cpp.
These classes and their methods may be used generally in simulation
models. As an example of the use of these classes note, in the file
JobShop.h, that class
Machine_Group has an attribute, Free_machines, declared to be an accumulated_variable.
To update the value of Free_machines one must use either the update or increment
methods of accumulated_variable. For example, the following coding is found
in the EndProcess::DispatchMachine() routine within the JobShopEntities.cpp
if (MGPtr Queue_size.Value()= = 0)
MGPtr Free_machine.Increment (1.0);
MGPtr Queue.size.Increment (-1.0);
In addition to updating value, the Increment and Update methods update
a time-weighted Sum and SumSq. They also note the minimum and maximum
values which the variable has taken on. The values of the arguments
to Update and Increment
are double; those to Increment may be positive or negative. The initial value
of an accululated_variable must be set by the Initialize method. This calls
on the reset method which, among other things, stores the current
value of SimTime
as the StartTime attribute of the Accumulated_variable. Thus, while accumulated
variables can be initialized before the start of the simulation, SimTime
must be set already.
The current value or the accumulated sum, sumSq, lastUpdateTime, startTime,
min and max can be accessed by public methods named Value(), Sum(),…,
as in the Time_keeper::EndSimulation() routine in the Time_keeper.cpp file.
Tallied variables are similar to accumulated variables except they
produce ordinary averages rather than time-weighted averages. See
their class definition.
With generic accumulate and update routines at our disposal, under
the control of a typical timing routine, other than the initialize
and report routines, not
much needs to be programmed to simulate the Jobshop. Specifically, the JobShopEntities.cpp
file contains the following short routines:
(a) Constructors which initialize machine_groups and jobs.
(b) The NewSale event routine. This causes the next occurrence
of a NewSale
and calls upon the AdvanceJob() routine to process the new
(c) The endOfProcessing() event routine. For the job step
just completed this
event routine disposes of the job being processed using
the AdvanceJob() routine and the machine doing the processing,
using the DispatchMachine()
(d) The AdvanceJob() routine proceeds depending on whether
the job is a
new job (place = = NULL) or an existing job. In the latter
case it proceeds depending on whether the last step in
the routing has or has not been completed.
(e) The DispatchMachine() routine proceeds according to
whether or not ther there is a job waiting for it in
See the routines themselves for details.