// world.cc: "model of the world" for CSC 270 simulation example // -- J. Clarke, March-June 1996 // // The first C++ version of this example attached these activities to // the classes defining the objects taking the actions: the car class // decided how much gas was needed, the arrival class decided when the // next arrival would take place, etc. That approach required the // random-number streams to be global variables; on the other hand, // it did not require global functions as this one does. // // The change back to this design, with a module grouping the random // processes together, was partly caused by dislike of the global variables, // and partly by a recognition that the representation of the "world" // needed to be kept together as much as the representation of the // aspects of objects like cars, arrivals, etc. #include #include "random.h" #include "world.h" // The random-number streams static randStream * arrivalStream; // auto arrival times static randStream * litreStream; // number of litres needed static randStream * balkingStream; // balking probability static randStream * serviceStream; // service times // Initialize the random-number streams: read a seed for each // and use it allocate a new stream. void worldsetup (FILE *fin, FILE *fout) { fprintf (fout, "and the following random number seeds:\n"); unsigned short seed; fscanf (fin, "%hu", &seed); fprintf (fout, " %hu", seed); arrivalStream = new randStream (seed); fscanf (fin, "%hu", &seed); fprintf (fout, " %hu", seed); litreStream = new randStream (seed); fscanf (fin, "%hu", &seed); fprintf (fout, " %hu", seed); balkingStream = new randStream (seed); fscanf (fin, "%hu", &seed); fprintf (fout, " %hu", seed); serviceStream = new randStream (seed); fputc ('\n', fout); } // The interarrival time of the next car is exponentially distributed. double interarrivalTime (void) { const int MEAN = 50; // seconds, because r is a rate in 1/sec, and this is 1/r return - MEAN * log (arrivalStream -> nextfloat()); } // The number of litres required by a car is uniform between 10 and 60. double numLitres (void) { return 10 + litreStream -> nextfloat() * 50; }; // The probability that a car leaves without buying gas (i.e., balks) // grows larger as the queue length gets larger, and grows smaller // when the car requries a greater number of litres of gas, such that: // (1) there is no balking if the queueLength is zero, and // (2) otherwise, the probability of *not* balking is // (40 + litres)/(25 * (3 + queueLength)) bool DoesCarBalk (double litres, int queueLength) { return queueLength > 0 && balkingStream -> nextfloat() > (40 + litres) / (25 * (3 + queueLength)); } // Determine how long the service will take. // // Service times will have a near Normal distribution, where the mean is 150 // seconds plus 1/2 second per litre, and the standard deviation is 30 seconds. // (It can be shown that the sum of 12 random numbers from the // uniform distribution on (0,1) has a near Normal distribution // with mean 6 and standard deviation 1.) double serviceTime(double litres) { double howLong = -6; for (int i = 1; i <= 12; i++) howLong += serviceStream -> nextfloat(); return 150 + 0.5 * litres + 30 * howLong; }