#include #include #include #include #define MAXQUEUE 4 /* use a small value for testing */ typedef enum action { ARRIVE, DEPART } Action; typedef enum bool { TRUE, FALSE } Boolean; typedef struct plane { int id; /* identification number of airplane*/ int tm; /* time of arrival in queue */ } Plane; typedef Plane QueueEntry; typedef struct queue { int count; /* number of airplanes in the queue */ int front; /* front of the queue */ int rear; /* rear of the queue */ QueueEntry entry[MAXQUEUE]; } Queue; Boolean QueueEmpty(Queue *q) { return q->count <= 0; } Boolean QueueFull(Queue *q) { return q->count >= MAXQUEUE; } void CreateQueue(Queue *q) { q->count = q->front = 0; q->rear = -1; } void Append(QueueEntry x, Queue *q) { if (QueueFull(q)) printf("Cannot append an entry to a full queue."); else { q->count++; q->rear=(q->rear + 1) % MAXQUEUE; q->entry[q->rear]=x; } } void Serve(QueueEntry *x, Queue *q) { if (QueueEmpty(q)) printf("Cannot serve from an empty queue."); else { q->count--; *x=q->entry[q->front]; q->front=(q->front + 1) % MAXQUEUE; } } int QueueSize(Queue *q) { return q->count; } void Randomize(void) { srand((unsigned int) (time(NULL) % 10000)); } int PoissonRandom(double expectedvalue) { int n = 0; /* counter of iterations */ double limit; /* e^-v, where v is the expected value */ double x; /* pseudorandom number */ limit = exp(-expectedvalue); x = rand() / (double) 32767; while (x > limit) { n++; x *= rand() / (double)32767; } return n; } Boolean UserSaysYes(void) { int c; printf(" (y,n)? "); do { while ((c = getchar()) == '\n') ; /* Ignore new line character. */ if (c == 'y' || c == 'Y' || c == 'n' || c == 'N') return (c == 'y' || c == 'Y'); printf("Please respond by typing one of the letters y or n\n"); } while (1); } void Start(int *endtime, double *expectarrive, double *expectdepart) { Boolean ok; printf("This program simulates an airport with only one runway.\n" "One plane can land or depart in each unit of time.\n" "Up to %d planes can be waiting to land or take off " "at any time.\n", MAXQUEUE); printf("How many units of time will the simulation run? "); scanf("%d", endtime); Randomize(); /* Initialize random number generation. */ do { printf("Expected number of arrivals per unit time(real number)? "); scanf("%lf", expectarrive); printf("Expected number of departures per unit time? "); scanf("%lf", expectdepart); if (*expectarrive < 0.0 || *expectdepart < 0.0) { printf("These numbers must be nonnegative.\n"); ok = FALSE; } else if (*expectarrive + *expectdepart > 1.0) { printf("The airport will become saturated. " "Read new numbers? "); ok = !UserSaysYes(); /* If user says yes, repeat loop. */ } else ok = TRUE; } while (ok == FALSE); } void NewPlane(Plane *p, int *nplanes, int curtime, Action kind) { (*nplanes)++; p->id = *nplanes; p->tm = curtime; switch(kind) { case ARRIVE: printf(" Plane %3d ready to land.\n", *nplanes); break; case DEPART: printf(" Plane %3d ready to take off.\n", *nplanes); break; } } void Refuse(Plane p, int *nrefuse, Action kind) { switch(kind) { case ARRIVE: printf(" Plane %3d directed to another airport.\n", p.id); break; case DEPART: printf(" Plane %3d told to try later.\n", p.id); break; } (*nrefuse)++; } void Land(Plane p, int curtime, int *nland, int *landwait) { int wait; wait = curtime - p.tm; printf("%3d : Plane %3d landed; in queue %d units.\n", curtime, p.id, wait); (*nland)++; *landwait += wait; } void Fly(Plane p, int curtime, int *ntakeoff, int *takeoffwait) { int wait; wait = curtime - p.tm; printf("%3d : Plane %3d took off; in queue %d units.\n", curtime, p.id, wait); (*ntakeoff)++; *takeoffwait += wait; } void Idle(int curtime, int *idletime) { printf("%3d : Runway is idle.\n", curtime); (*idletime)++; } void Conclude(int nplanes, int nland, int ntakeoff, int nrefuse, int landwait, int takeoffwait, int idletime, int endtime, Queue *pt, Queue *pl) { printf("Simulation has concluded after %d units.\n", endtime); printf("Total number of planes processed: %3d\n", nplanes); printf(" Number of planes landed: %3d\n", nland); printf(" Number of planes taken off: %3d\n", ntakeoff); printf(" Number of planes refused use: %3d\n", nrefuse); printf(" Number left ready to land: %3d\n", QueueSize(pl)); printf(" Number left ready to take off: %3d\n", QueueSize(pt)); if (endtime > 0) printf(" Percentage of time runway idle: %6.2f\n", ((double) idletime / endtime) * 100.0); if (nland > 0) printf(" Average wait time to land: %6.2f\n", (double) landwait / nland); if (ntakeoff > 0) printf(" Average wait time to take off: %6.2f\n", (double) takeoffwait / ntakeoff); } void main(void) { Queue landing, takeoff; Queue *pl = &landing; Queue *pt = &takeoff; Plane plane; int curtime; /* current time; one unit = time for take off or landing */ int endtime; /* total number of time units to run */ double expectarrive;/* number of planes arriving in one unit */ double expectdepart;/* number of planes newly ready to take off */ int i; /* loop control variable */ int idletime; /* number of units when runway is idle */ int landwait; /* total waiting time for planes landed */ int nland; /* number of planes landed */ int nplanes; /* number of planes processed so far */ int nrefuse; /* number of planes refused use of airport */ int ntakeoff; /* number of planes taken off */ int pri; /* pseudo-random integer */ int takeoffwait;/* total waiting time for take off */ CreateQueue(pl); CreateQueue(pt); nplanes = nland = ntakeoff = nrefuse = 0; landwait = takeoffwait = idletime = 0; Start(&endtime, &expectarrive, &expectdepart); for (curtime = 1; curtime <= endtime; curtime++) { pri = PoissonRandom(expectarrive); for (i = 1; i <= pri; i++) {/* Add to landing queue. */ NewPlane(&plane, &nplanes, curtime, ARRIVE); if (QueueFull(pl)) Refuse(plane, &nrefuse, ARRIVE); else Append(plane, pl); } pri = PoissonRandom(expectdepart); for (i = 1; i <= pri; i++) {/* Add to takeoff queue. */ NewPlane(&plane, &nplanes, curtime, DEPART); if (QueueFull(pt)) Refuse(plane, &nrefuse, DEPART); else Append(plane, pt); } if (!QueueEmpty(pl)) { /* Bring plane to land. */ Serve(&plane, pl); Land(plane, curtime, &nland, &landwait); } else if (!QueueEmpty(pt)) { /* Allow plane to take off. */ Serve(&plane, pt); Fly(plane, curtime, &ntakeoff, &takeoffwait); } else Idle(curtime, &idletime); } Conclude(nplanes, nland, ntakeoff, nrefuse, landwait, takeoffwait, idletime, endtime, pt, pl); }