'' @(#) law105.sim 2/25/86
''Flexible manufacturing system model
''An Introduction to Simulation Using SIMSCRIPT II.5, Chapter 5
PREAMBLE

   PROCESSES INCLUDE ARRIVAL.GENERATOR, JOB, AND REPORT

   RESOURCES 

      EVERY TRANSPORTER HAS A TP.LOCATION AND A TP.SPEED
      DEFINE TP.LOCATION AS AN INTEGER VARIABLE
      DEFINE TP.SPEED AS A REAL VARIABLE

      EVERY WORK.STATION HAS A WS.DELAY.IN.QUEUE, A WS.NUM.MACHINES,
         AND A WS.NUM.MACH.WORKING
      DEFINE WS.DELAY.IN.QUEUE AS A REAL VARIABLE
      DEFINE WS.NUM.MACHINES AND WS.NUM.MACH.WORKING AS INTEGER 
	 VARIABLES

   PERMANENT ENTITIES

      EVERY JOB.TYPE HAS A JB.DELAY.IN.QUEUE, A JB.TRANSPORTER.DELAY,
         AND OWNS A JB.ROUTING
      DEFINE JB.DELAY.IN.QUEUE AND JB.TRANSPORTER.DELAY AS REAL VARIABLES
      DEFINE JB.ROUTING AS A FIFO SET

   TEMPORARY ENTITIES

      EVERY TASK HAS A TK.MEAN.SERVICE.TIME, A TK.WORK.STATION,
         AND BELONGS TO A JB.ROUTING
      DEFINE TK.MEAN.SERVICE.TIME AS A REAL VARIABLE
      DEFINE TK.WORK.STATION AS AN INTEGER VARIABLE

   DEFINE MEAN.INTERARRIVAL.TIME AND SIM.LENGTH AS REAL VARIABLES

   DEFINE IO.STATION AS AN INTEGER VARIABLE

   DEFINE .HOURS TO MEAN UNITS

   THE SYSTEM HAS A TYPE.DISTRIBUTION RANDOM STEP VARIABLE
   DEFINE TYPE.DISTRIBUTION AS AN INTEGER, STREAM 9 VARIABLE

   DEFINE DISTANCE AS A REAL, 2-DIMENSIONAL ARRAY

   TALLY MEAN.JB.DELAY.IN.Q AS THE MEAN OF JB.DELAY.IN.QUEUE

   TALLY MEAN.JB.TRANSPORTER.DELAY AS THE MEAN OF JB.TRANSPORTER.DELAY

   TALLY MEAN.WS.DELAY.IN.Q AS THE MEAN OF WS.DELAY.IN.QUEUE

   ACCUMULATE AVG.NUM.IN.STATION.Q AS THE AVERAGE OF N.Q.WORK.STATION

   ACCUMULATE AVG.NUM.MACH.OCCUPIED AS THE AVERAGE OF N.X.WORK.STATION 

   ACCUMULATE AVG.NUM.MACH.WORKING AS THE AVERAGE OF WS.NUM.MACH.WORKING 

   ACCUMULATE UTIL.TRANSPORTER AS THE AVERAGE OF N.X.TRANSPORTER

END ''PREAMBLE
MAIN    use 1 for input

   write as  /, "Test LAW105 - Flexible manufacturing system", /
   CALL READ.DATA
   CALL INITIALIZE

   START SIMULATION
   write as  /, /, "End of Test LAW105", /

END ''MAIN
ROUTINE READ.DATA

   DEFINE I, J, AND NUM.TASKS AS INTEGER VARIABLES

   CREATE EVERY TRANSPORTER(1)
   LET U.TRANSPORTER(1) = 1
   READ TP.SPEED(1)

   READ N.WORK.STATION
   CREATE EVERY WORK.STATION
   FOR EACH WORK.STATION
   DO
      READ WS.NUM.MACHINES(WORK.STATION)
      LET U.WORK.STATION(WORK.STATION) = WS.NUM.MACHINES(WORK.STATION)
   LOOP
   LET IO.STATION = N.WORK.STATION + 1

   READ TYPE.DISTRIBUTION AND N.JOB.TYPE
   CREATE EVERY JOB.TYPE
   FOR EACH JOB.TYPE
   DO
      READ NUM.TASKS
      FOR I = 1 TO NUM.TASKS
      DO
         CREATE A TASK
         READ TK.MEAN.SERVICE.TIME(TASK) AND TK.WORK.STATION(TASK)
         FILE THIS TASK IN JB.ROUTING(JOB.TYPE)
      LOOP
   LOOP

   READ MEAN.INTERARRIVAL.TIME AND SIM.LENGTH

   RESERVE DISTANCE(*,*) AS IO.STATION BY IO.STATION
   READ DISTANCE

   PRINT 6 LINES THUS
 


FLEXIBLE MANUFACTURING SYSTEM -- INPUT PARAMETERS
-------------------------------------------------

   SKIP 3 LINES

   PRINT 7 LINES WITH SIM.LENGTH, TP.SPEED(1), AND MEAN.INTERARRIVAL.TIME
      THUS

LENGTH OF SIMULATION  *****.** HOURS

TRANSPORTER SPEED     *****.** FEET PER SECOND

JOB INTERARRIVAL TIMES ARE EXPONENTIAL WITH MEAN ***.** HOURS

   SKIP 3 LINES

   FOR EACH JOB.TYPE
   DO
      PRINT 9 LINES WITH JOB.TYPE THUS

JOB TYPE ** ROUTING:
--------------------



STATION     MEAN SERVICE TIME (IN HOURS)
-------     ----------------------------

      FOR EACH TASK IN JB.ROUTING(JOB.TYPE)
         PRINT 3 LINES WITH TK.WORK.STATION(TASK) AND  
            TK.MEAN.SERVICE.TIME(TASK) THUS      

     **                         *****.**

      SKIP 3 LINES
   LOOP

   PRINT 9 LINES THUS

DISTRIBUTION FUNCTION OF JOB TYPES:
-----------------------------------



TYPE     CUMULATIVE PROBABILITY
----     ----------------------

   FOR EACH RANDOM.E IN TYPE.DISTRIBUTION 
      PRINT 3 LINES WITH IVALUE.A(RANDOM.E) AND PROB.A(RANDOM.E) THUS

  **                       *.**

   SKIP 3 LINES

   PRINT 9 LINES THUS

MACHINE ALLOCATIONS:
--------------------



STATION     NUMBER OF MACHINES
-------     ------------------

   FOR EACH WORK.STATION 
      PRINT 3 LINES WITH WORK.STATION AND WS.NUM.MACHINES(WORK.STATION)
         THUS

     **                     **

   SKIP 3 LINES

   PRINT 4 LINES WITH IO.STATION THUS

DISTANCE MATRIX (DISTANCES IN FEET, STATION ** IS THE I/O STATION):
-------------------------------------------------------------------

   SKIP 3 LINES

   WRITE AS "STATION   "
   FOR I = 1 TO IO.STATION
      WRITE I AS I 6, S 4
   SKIP 2 LINES
   FOR I = 1 TO IO.STATION
   DO
      WRITE I AS S 5, I 2, S 6
      FOR J = 1 TO IO.STATION
         WRITE DISTANCE(I,J) AS D(5,1), S 5
      SKIP 2 LINES
   LOOP

   START NEW PAGE

END ''READ.DATA  
ROUTINE INITIALIZE

   LET TP.LOCATION(1) = IO.STATION

   ACTIVATE AN ARRIVAL.GENERATOR NOW
   ACTIVATE A REPORT IN SIM.LENGTH .HOURS

END ''INITIALIZE
PROCESS ARRIVAL.GENERATOR

   WHILE TIME.V < SIM.LENGTH
   DO
      WAIT EXPONENTIAL.F(MEAN.INTERARRIVAL.TIME,8) .HOURS
      ACTIVATE A JOB NOW
   LOOP

END ''ARRIVAL.GENERATOR
PROCESS JOB

   DEFINE TIME.OF.ARRIVAL, TIME.OF.REQUEST, TOTAL.DELAY.IN.QUEUE,
      TOTAL.TRANSPORTER.DELAY, AND TRAVEL.TIME AS REAL VARIABLES
   DEFINE CURRENT.STATION, JOB.TYPE, NEXT.STATION, AND TASK AS 
      INTEGER VARIABLES

   LET JOB.TYPE = TYPE.DISTRIBUTION
   LET TOTAL.DELAY.IN.QUEUE = 0
   LET TIME.OF.REQUEST = TIME.V
   
   REQUEST 1 TRANSPORTER(1)
   LET TRAVEL.TIME = DISTANCE(TP.LOCATION(1),IO.STATION)/ 
      (TP.SPEED(1) * 3600.0)
   WAIT TRAVEL.TIME .HOURS
   ADD (TIME.V - TIME.OF.REQUEST) TO TOTAL.TRANSPORTER.DELAY

   LET NEXT.STATION = TK.WORK.STATION(F.JB.ROUTING(JOB.TYPE))
   LET TRAVEL.TIME = DISTANCE(IO.STATION,NEXT.STATION)/
      (TP.SPEED(1) * 3600.0)
   WAIT TRAVEL.TIME .HOURS
   LET TP.LOCATION(1) = NEXT.STATION
   RELINQUISH 1 TRANSPORTER(1)

   FOR EACH TASK IN JB.ROUTING(JOB.TYPE)
   DO
      LET CURRENT.STATION = TK.WORK.STATION(TASK)
      LET TIME.OF.ARRIVAL = TIME.V
     
      REQUEST 1 UNIT OF WORK.STATION(CURRENT.STATION)
      LET WS.DELAY.IN.QUEUE(CURRENT.STATION) = TIME.V - TIME.OF.ARRIVAL
      ADD (TIME.V - TIME.OF.ARRIVAL) TO TOTAL.DELAY.IN.QUEUE
      ADD 1 TO WS.NUM.MACH.WORKING(CURRENT.STATION)
      WORK ERLANG.F(TK.MEAN.SERVICE.TIME(TASK),2,CURRENT.STATION) .HOURS 
      SUBTRACT 1 FROM WS.NUM.MACH.WORKING(CURRENT.STATION)
      LET TIME.OF.REQUEST = TIME.V

      REQUEST 1 TRANSPORTER(1)
      LET TRAVEL.TIME = DISTANCE(TP.LOCATION(1),CURRENT.STATION)/
         (TP.SPEED(1) * 3600.0)
      WAIT TRAVEL.TIME .HOURS
      ADD (TIME.V - TIME.OF.REQUEST) TO TOTAL.TRANSPORTER.DELAY
      RELINQUISH 1 UNIT OF WORK.STATION(CURRENT.STATION)
 
      IF TASK = L.JB.ROUTING(JOB.TYPE)
         LET NEXT.STATION = IO.STATION
      ELSE
         LET NEXT.STATION = TK.WORK.STATION(S.JB.ROUTING(TASK))
      ALWAYS
      LET TRAVEL.TIME = DISTANCE(CURRENT.STATION,NEXT.STATION)/
         (TP.SPEED(1) * 3600.0)
      WAIT TRAVEL.TIME .HOURS
      LET TP.LOCATION(1) = NEXT.STATION
      RELINQUISH 1 TRANSPORTER(1)
   LOOP

   LET JB.DELAY.IN.QUEUE(JOB.TYPE) = TOTAL.DELAY.IN.QUEUE
   LET JB.TRANSPORTER.DELAY(JOB.TYPE) = TOTAL.TRANSPORTER.DELAY

END ''JOB    
PROCESS REPORT

   DEFINE PROP.BLOCKED, PROP.IDLE, AND PROP.WORKING AS REAL VARIABLES

   PRINT 6 LINES THUS



SIMULATION RESULTS (ALL TIMES ARE IN HOURS)
-------------------------------------------

   SKIP 3 LINES
   
   PRINT 10 LINES THUS

JOB REPORT:
-----------



         AVERAGE TOTAL      AVERAGE TOTAL
TYPE     DELAY IN QUEUE     TRANSPORTER DELAY
----     --------------     -----------------

   FOR EACH JOB.TYPE
      PRINT 3 LINES WITH JOB.TYPE, MEAN.JB.DELAY.IN.Q(JOB.TYPE), AND
         MEAN.JB.TRANSPORTER.DELAY(JOB.TYPE) THUS

  **             ***.**                ***.**

   SKIP 3 LINES

   PRINT 10 LINES THUS

STATION REPORT:
---------------



           AVG NUM     AVG DELAY    PROP TIME    PROP TIME    PROP TIME
STATION    IN QUEUE    IN QUEUE     WORKING      BLOCKED      IDLE
-------    --------    ---------    ---------    ---------    ---------

   FOR EACH WORK.STATION
   DO
      LET PROP.WORKING = AVG.NUM.MACH.WORKING(WORK.STATION)/ 
         WS.NUM.MACHINES(WORK.STATION)
      LET PROP.IDLE = 1.0 - (AVG.NUM.MACH.OCCUPIED(WORK.STATION)/
         WS.NUM.MACHINES(WORK.STATION))
      LET PROP.BLOCKED = 1.0 - PROP.WORKING - PROP.IDLE

      PRINT 3 LINES WITH WORK.STATION, AVG.NUM.IN.STATION.Q(WORK.STATION),
         MEAN.WS.DELAY.IN.Q(WORK.STATION), PROP.WORKING, PROP.BLOCKED, AND
         PROP.IDLE THUS

     **      ***.**       ***.**        *.***        *.***        *.***

   LOOP

   SKIP 3 LINES

   PRINT 8 LINES WITH UTIL.TRANSPORTER(1) THUS

TRANSPORTER REPORT:
-------------------



UTILIZATION  *.***

''   TRACE

   STOP
 
END ''REPORT
