home *** CD-ROM | disk | FTP | other *** search
- PROGRAM Airort(Input, Output);
- (********************************************************)
- (* Pre-Cond: The user must supply the number of time *)
- (* intervals, the arrival and departure *)
- (* rates per time interval. *)
- (* Post-Cond: The program performs a random simulation *)
- (* of the airport, showing the summary of *)
- (* various statistics and the log of run *)
- (* use. *)
- (* From Kruse, out of PRB 1/31/91 *)
- (********************************************************)
-
- (*****************************************)
- (* Alejo Alamillo COSC 055 *)
- (* Spring 1991 Assignment Airport *)
- (*****************************************)
-
-
-
- CONST QueueSize = 5;
- TYPE PlaneRecType = RECORD
- ID,
- TimeOnQ: Integer;
- END;
- QueueEntry = PlaneRecType; (* Alias for QueuePack *)
-
- QueueType = RECORD (* Array implementation *)
- Count,
- Front,
- Rear: Integer;
- Entry: ARRAY[0..QueueSize] OF QueueEntry;
- END;
- VAR LandingQ,
- TakeoffQ: Queuetype;
- CurrentPlane: PlaneRecType;
- BackLog: Boolean;
- Counter,
- CurrentTime,
- EndTime,
- Seed,
- NumberOfPlanes,
- NumberOfLandings,
- NumberOfTakeoffs,
- NumberRefused,
- TotalLandingWait,
- TotalTakeoffWait,
- MaximumLandingWait,
- MaximumTakeoffWait,
- Idletime,
- IdletimeLand,
- IdletimeTakeoff: Integer;
-
- (*****************************************************************)
-
- ExpectedArrivals,
- ExpectedDepartures: Real;
-
- (*********************************************************)
- (* QUEUEPACK routines follow: *)
- (*********************************************************)
-
- (***********************************************)
- (* Pre-Cond: None *)
- (* Post-Cond: An empty Q has been created *)
- (***********************************************)
- PROCEDURE CreateQ( VAR Q: QueueType);
- BEGIN
- WITH Q DO
- BEGIN
- Count:= 0;
- Front:= 1;
- Rear:= 0;
- END;
- END;
- (***********************************************)
- (* Pre-Cond: The Queue has been created. *)
- (* Post-Cond: Obvious. *)
- (***********************************************)
- FUNCTION FullQ(VAR Q: QueueType): Boolean;
- BEGIN
- IF ((Q.Rear + 2) MOD QueueSize = (Q.Front MOD QueueSize) ) THEN
- FullQ:= True
- ELSE
- FullQ:= False;
- END;
-
- FUNCTION EmptyQ( VAR Q: QueueType): Boolean;
- BEGIN
- IF ((Q.Rear + 1) MOD QueueSize = (Q.Front MOD QueueSize)) THEN
- EmptyQ:= True
- ELSE
- EmptyQ:= False;
- END;
-
- (***********************************************)
- (* Pre-Cond: Q has been created *)
- (* Post-Cond: Item has been added at the *)
- (* rear of the Q *)
- (***********************************************)
- PROCEDURE Append(VAR Q: QueueType; NewItem: QueueEntry);
- BEGIN
- WITH Q DO
- BEGIN
- IF (not FullQ(Q)) THEN
- BEGIN
- Rear:= (Rear MOD QueueSize) + 1;
- Entry[Rear]:= NewItem;
- END
- ELSE
- Writeln('ERROR--Q overflow');
- END;
- END;
- (**************************************************)
- (* Pre-Cond: Q has been created *)
- (* Post-Cond: The first item on the Q hs been *)
- (* removed and copied to ItemFromQ *)
- (**************************************************)
- PROCEDURE Serve(VAR Q: QueueType; VAR ItemFromQ: QueueEntry);
- BEGIN
- WITH Q DO
- BEGIN
- IF (not EmptyQ(Q)) THEN
- BEGIN
- Count:= Count - 1;
- ItemFromQ:= Entry[Front];
- Front:= (Front MOD QueueSize) + 1;
- END
- ELSE
- Writeln('ERROR--Attempt to serve an empty Q');
- END;
- END;
- (*******************************************************)
- (* Random function *)
- (* Pre-Cond: a seed has been initialized *)
- (* Post-Cond: Random is a uniformly distributed R V *)
- (* and a new Seed has been generated. *)
- (*******************************************************)
- FUNCTION Random(VAR Seed: Integer): Real;
- CONST Modulus = 65536;
- Multiplier = 25173;
- Increment = 13849;
- BEGIN
- Seed:= ((Multiplier*Seed) + Increment) MOD Modulus;
- Random:= Seed/Modulus;
- END;
- (************************************************************)
- (* Pre-Cond: An expected value and a Seed have been pre-set *)
- (* Post-Cond: An integer in the range: 0... is generated *)
- (* with a poisson distribution *)
- (************************************************************)
- FUNCTION Poisson(ExpectedValue: Real): Integer;
- VAR Limit,
- Product: Real;
- Count: Integer;
- BEGIN
- Count:= 0;
- Limit:= Exp(-ExpectedValue); (* Exponential function *)
- Product:= Random(Seed);
-
- WHILE (Product > Limit) DO
- BEGIN
- Count:= Count + 1;
- Product:= Product*Random(Seed);
- END; (*** WHILE ***)
-
- Poisson:= Count;
- END;
- (******************** End of QueuePack ******************)
- (***********************************************************)
- (* Pre-Cond: None. *)
- (* Post- Cond: All variables are initialized *)
- (***********************************************************)
- PROCEDURE Initialize;
- VAR GoodInput: Boolean;
- BEGIN
- BackLog := False;
- NumberOfPlanes:= 0;
- NumberofLandings:= 0;
- NumberOfTakeoffs:= 0;
- NumberRefused:= 0;
- TotalLandingWait:= 0;
- TotalTakeoffWait:= 0;
- Idletime:= 0;
- CurrentTime:=0;
- Writeln('This program simulates the activity at an airport with');
- Writeln('two runways. Two planes can land or takeoff ');
- Writeln('in each time interval of the simulation');
- Writeln; Write('How many time periods in the simulation? ');
- Readln(EndTime);
- Writeln;
- Write('Enter a seed integer for the random function: ');
- Readln(Seed);
- Writeln;
-
- REPEAT
- Write('Enter the expected number of arrivals and departures--');
- Readln(ExpectedArrivals, ExpectedDepartures); Writeln;
- IF ((ExpectedArrivals + ExpectedDepartures) >= 2.0) THEN
- Writeln('These must be positive real numbers with total less than 1 ')
- ELSE (* Lest the Queues overflow regularly *)
- GoodInput:= True;
- UNTIL GoodInput;
- END; (**************** Initialize *****************************)
- (*******************************************************************)
- (* Pre-Cond: None. *)
- (* Post-Cond: Processes a plane attempting to access a full queue *)
- (*******************************************************************)
- PROCEDURE Refuse(CurrentPlane: PlaneRecType; VAR NumberRefused: Integer);
- BEGIN
- Writeln('Queue is full, plane delayed');
- NumberRefused:= NumberRefused + 1;
- END;
- (******************************************************************)
- (* Pre-Cond: None. *)
- (* Post-Cond: Revises data for landing CurrentPlane *)
- (******************************************************************)
- PROCEDURE Land(CurrentPlane: PlaneRecType;
- CurrentTime: Integer;
- VAR NumberLanded,
- TotalLandingWait,
- MaximumLandingWait: Integer);
- VAR WaitingTIme: Integer;
- BEGIN
- WaitingTime:= CurrentTime - CurrentPlane.TimeOnQ;
- TotalLandingWait:= TotalLandingWait + WaitingTime;
- If (WaitingTime > MaximumLandingWait) THEN
- MaximumLandingWait:= WaitingTime;
- NumberofLandings:= NumberofLandings + 1;
- Write('Plane #',CurrentPlane.ID:0,' landed at ',CurrentTime:0);
- END;
- (*****************************************************************)
- (* Pre-Cond: None. *)
- (* Post-Cond: Process a plane which is taking off. *)
- (*****************************************************************)
- PROCEDURE Takeoff(CurrentPlane: PlaneRecType;
- CurrentTime: Integer;
- VAR NumberLanded,
- TotalLandingWait,
- MaximumLandingWait: Integer);
- VAR WaitingTime: Integer;
- BEGIN
- WaitingTime:= CurrentTime - CurrentPlane.TimeOnQ;
- TotalTakeoffWait:= TotalTakeoffWait + WaitingTime;
- If (WaitingTime > MaximumTakeoffWait) THEN
- MaximumTakeoffWait:= WaitingTime;
- NumberofTakeoffs:= NumberofTakeoffs + 1;
- Write('Plane #',CurrentPlane.ID:0,' took off at ',CurrentTime:0);
- END;
- (*****************************************************************)
- (* Pre-Cond: None. *)
- (* Post-Cond: Updates variables for idle period *)
- (*****************************************************************)
- PROCEDURE IdleL(CurrentTime: Integer; VAR IdleTimeLand: Integer);
- BEGIN
- IdleTimeLand:= IdleTimeLand + 1;
- Writeln('Runway L is idle at ',CurrentTime:0);
- END;
- (*****************************************************************)
- (* Pre-Cond: None. *)
- (* Post-Cond: Updates variables for idle period *)
- (*****************************************************************)
- PROCEDURE IdleT(CurrentTime: Integer; VAR IdleTimeTakeoff: Integer);
- BEGIN
- IdleTimeTakeoff:= IdleTimeTakeoff + 1;
- Writeln('Runway T is Idle at ',CurrentTime:0);
- END;
- (*****************************************************************)
- (* Pre-Cond: None. *)
- (* Post-Cond: Writes out a summary of the activity. *)
- (*****************************************************************)
- PROCEDURE Conclude(
- VAR LandingQ,
- TakeoffQ: Queuetype;
- VAR CurrentPlane: PlaneRecType;
- EndTime,
- NumberOfPlanes,
- NumberofLandings,
- NumberOfTakeoffs,
- NumberRefused,
- TotalLandingWait,
- TotalTakeoffWait,
- MaximumLandingWait,
- MaximumTakeoffWait,
- Idletime: Integer);
-
- BEGIN
- Writeln;
- IF CurrentTime <= EndTime THEN
- Writeln('Simulation has concluded after ',EndTime:0,' units.')
- ELSE
- Writeln('Simulation has concluded after ',CurrentTime:0,' units.');
- Writeln('Total number of planes: ',NumberofPlanes:0);
- Writeln(' Number of planes landed: ',NumberofLandings:0);
- Writeln(' Number of planes taking off: ',NumberofTakeoffs:0);
- Writeln('Number of planes turned away: ',NumberRefused:0);
- Writeln;
- Writeln(' LANDING WAIT TAKEOFF WAIT');
- Writeln('Avg. Max. Avg. Max.');
- Writeln;
- IF (NumberofLandings = 0) OR (NumberofTakeoffs = 0) THEN
- Writeln( 'ZERO DIV')
- ELSE
- BEGIN
- Write(TotalLandingWait/NumberofLandings:2:2, MaximumLandingWait:4);
- Writeln(TotalTakeoffWait/NumberofTakeoffs:20:2, MaximumTakeoffWait:4);
- END;
- Writeln;
- Writeln('Percentage of time idle on T: ',IdletimeTakeoff/EndTime*100:2:2);
- Writeln;
- Writeln('Percentage of time idle on L: ',IdletimeLand/EndTime*100:2:2);
- Writeln;
- Write('Percentage of time idle: ');
- Writeln(((IdletimeLand+IdletimeTakeoff)/EndTime*100)/2:2:2);
- Writeln;
- END;
- (*****************************************************************)
- (********************* MAIN ************************************)
- (*****************************************************************)
- BEGIN
- Initialize; (* Many global variables *)
- CreateQ(LandingQ);
- CreateQ(TakeoffQ);
-
- FOR CurrentTime := 1 to EndTime DO (* Main Loop of Simulation *)
- BEGIN
- FOR Counter:= 1 TO Poisson(ExpectedArrivals) DO (* Process arrivals *)
- BEGIN (* onto Landing queue *)
- NumberofPlanes:= NumberofPlanes + 1;
- CurrentPlane.ID:= NumberofPlanes;
- CurrentPlane.TimeonQ:= CurrentTime;
- IF FullQ(LandingQ) THEN
- BEGIN
- Refuse(CurrentPlane, NumberRefused);
- BackLog := True;
- END
- ELSE
- Append(LandingQ, CurrentPlane);
- END;
-
- FOR Counter:= 1 TO Poisson(ExpectedDepartures) DO (* Process Departures *)
- BEGIN (* onto Takeoff queue *)
- NumberofPlanes:= NumberofPlanes + 1;
- CurrentPlane.ID:= NumberofPlanes;
- CurrentPlane.TimeonQ:= CurrentTime;
- IF FullQ(TakeoffQ) THEN
- Refuse(Currentplane, NumberRefused)
- ELSE
- Append(TakeoffQ, CurrentPlane);
- END;
- IF BackLog AND EmptyQ(LandingQ) THEN
- BackLog := False;
-
- IF BackLog AND not EmptyQ(LandingQ) THEN
- BEGIN (* First priority to *)
- Serve(LandingQ, CurrentPlane); (* planes waiting to land. *)
- Land(CurrentPlane, CurrentTime, NumberofLandings,
- TotalLandingWait, MaximumLandingWait);
- Writeln(' on runway L'); (* Landing on runway L *)
- IF not EmptyQ(LandingQ) THEN
- BEGIN
- Serve(LandingQ, CurrentPlane);
- Land(CurrentPlane, CurrentTime, NumberofLandings,
- TotalLandingWait, MaximumLandingWait);
- Writeln(' on runway T');
- END
- ELSE
- BEGIN
- BackLog := False;
- IdleL(CurrentTime, IdleTimeLand);
- END;
- END
- ELSE
- {===============================================================}
- IF not EmptyQ(LandingQ) THEN
- BEGIN
- Serve(LandingQ, CurrentPlane);
- Land(CurrentPlane, CurrentTime, NumberofLandings,
- TotalLandingWait, MaximumLandingWait);
- Writeln(' on runway L');
- IF not EmptyQ(TakeoffQ) THEN
- BEGIN
- Serve(TakeoffQ, CurrentPlane);
- Takeoff(CurrentPlane, CurrentTime, NumberofTakeoffs,
- TotalTakeoffWait, MaximumTakeoffWait);
- Writeln(' on runway T');
- END
- ELSE
- BEGIN
- IF not EmptyQ(LandingQ) THEN
- BEGIN
- Serve(LandingQ, CurrentPlane);
- Land(CurrentPlane, CurrentTime, NumberofLandings,
- TotalLandingWait, MaximumLandingWait);
- Writeln(' on runway T')
- END
- ELSE
- BEGIN
- IdleT(CurrentTime, IdleTimeTakeoff);
- END;
- END;
- END
- ELSE
- IF not EmptyQ(TakeoffQ) THEN
- BEGIN
- Serve(TakeoffQ, CurrentPlane);
- Takeoff(CurrentPlane, CurrentTime, NumberofTakeoffs,
- TotalTakeoffWait, MaximumTakeoffWait);
- Writeln(' on runway L');
- IF not EmptyQ(TakeoffQ) THEN
- BEGIN
- Serve(TakeoffQ, CurrentPlane);
- Takeoff(CurrentPlane, CurrentTime, NumberofTakeoffs,
- TotalTakeoffWait, MaximumTakeoffWait);
- Writeln(' on runway T');
- END
- ELSE
- BEGIN
- IdleL(CurrentTime, IdleTimeLand);
- IdleT(CurrentTime, IdleTimeTakeoff);
- END;
- END
- ELSE
- BEGIN
- IdleL(CurrentTime, IdleTimeLand);
- IdleT(CurrentTime, IdleTimeTakeoff);
- END;
-
- END; (************* FOR LOOP ************)
-
-
-
-
- Conclude( (* Write summary statistics *)
- LandingQ,
- TakeoffQ,
- CurrentPlane,
- EndTime,
- NumberOfPlanes,
- NumberofLandings,
- NumberOfTakeoffs,
- NumberRefused,
- TotalLandingWait,
- TotalTakeoffWait,
- MaximumLandingWait,
- MaximumTakeoffWait,
- Idletime);
- END.
-