1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
#include <iostream>
#include <cstdlib>
#include <queue>
#include <fstream>
#include <ctime>
using namespace std;
// Input parameters
#define SIMULATION_TIME 0
#define ARRIVAL_RATE 1
#define MIN_SERVICE_TIME 2
#define MAX_SERVICE_TIME 3
#define MAX_LINE_SIZE 4
#define ANGRY_THRESHOLD 5
#define PARAMS_MAX 6
#define FILENAME "sim.txt"
// Or like this:
// const int SIMULATION_TIME = 0;
// Or make 6 variables:
// double SIMULATION_TIME = 0;
// Counters -- indexes into variable 'counters' below
#define CUSTOMERS_SERVICED 0
#define CUSTOMERS_LEAVING 1
#define AVERAGE_WAIT 2
#define AVERAGE_LINE 3
#define ANGRY_CUSTOMERS 4
#define COUNTERS_MAX 5
// Holds the current simulation parameters
double parameters[PARAMS_MAX];
double counters[COUNTERS_MAX];
// This is an example debug macro you can use to print
// things each time through the loop
#define DEBUGGING_ENABLED 1
#ifdef DEBUGGING_ENABLED
#define DEBUG(x) do { \
cerr << __FILE__ << ": " << __LINE__ << ": " << x << endl; \
} while (0)
#else
#define DEBUG(x)
#endif // DEBUGGING_ENABLED
// Return the service interval, between 'min'
// and 'max'.
int randomInt(int min, int max)
{
return (rand() % (max - min) + min);
}
// Returns TRUE if a customer arrived during this minute
bool randomChance(double prob)
{
double rv = rand() / (double(RAND_MAX) + 1);
return (rv < prob);
}
// Read the next simulation from the file. Return
// TRUE if one could be read, FALSE otherwise (eof).
bool readNextSim(fstream &f, double parameters[])
{
for (int i = 0; i < PARAMS_MAX; i++)
{
string tmp;
getline(f, tmp);
if (f.eof())
return false;
// Read in the next parameter
parameters[i] = atof(tmp.c_str());
}
for (int i = 0; i < 5; i++)
cout <<"Simulation Results #" << i + 1 << endl;
cout << "---------------------" << endl;
cout << "\t Overall simulation time: " << "\t" << parameters[SIMULATION_TIME] << endl;
cout << "\t Arrival rate: " << "\t\t\t" << parameters[ARRIVAL_RATE] << endl;
cout << "\t Minimum service time: " << "\t\t" << parameters[MIN_SERVICE_TIME] << endl;
cout << "\t Maximum service time: " << "\t\t" << parameters[MAX_SERVICE_TIME] << endl;
cout << "\t Maximum line size: " << "\t\t" << parameters[MAX_LINE_SIZE] << endl;
cout << "\t Angry threshold: " << "\t\t" << parameters[ANGRY_THRESHOLD] << endl;
return true;
}
int main()
{
fstream f(FILENAME);
// Seed the random number generator here
srand(time(0));
if (!f.good())
{
cout << "Invalid file." << endl;
return -1;
}
while (readNextSim(f, parameters))
{
// Run the next simulation
queue<int> line;
for (int i = 0; i < COUNTERS_MAX; i++)
counters[i] = 0;
// or:
// memset(counters, 0, COUNTERS_MAX * sizeof(double));
//int customersLeavingLineFull = 0;
int simTime = 0;
int currentCustomer = -1;
// Each time through this loop represents 1 minute passing.
// There needs to be code to handle everything that can happen
// in 1 minute:
// - Customer arriving (yes/no?)
// - Is the current customer finished
// - Possibly process the next person in line
// - Calculate simulation statistics along the way
while (simTime++ < parameters[SIMULATION_TIME])
{
// One iteration of the loop represents one
// minute of simulation time.
// Check to see if a customer arrived
// (if so, process, also see if the line is full)
bool arrived = randomChance(parameters[ARRIVAL_RATE]);
if (arrived)
{
// A customer arrived in this minute
if (currentCustomer == -1)
{
// No customer is currently at the cashier
int serviceTime = randomInt(parameters[MIN_SERVICE_TIME],
parameters[MAX_SERVICE_TIME]);
currentCustomer = simTime + serviceTime;
}
else
{
if (line.size() == parameters[MAX_LINE_SIZE])
{
// Count this customer as leaving because the line is too
// full
counters[CUSTOMERS_LEAVING]++;
}
else
{
line.push(simTime);
}
}
}
counters[AVERAGE_LINE] += line.size();
// Check to see if the current customer is done
// at the cashier. Also check if there is no customer
// at the cashier (in which the next customer goes to the
// cashier).
if (simTime == currentCustomer)
{
if (!line.empty())
{
int nextCustomerTimestamp = line.front();
int waitingTime = simTime - nextCustomerTimestamp;
// We need to include this in the average waiting times
if (waitingTime >= parameters[ANGRY_THRESHOLD])
counters[ANGRY_CUSTOMERS]++;
counters[AVERAGE_WAIT] += waitingTime;
// Set currentCustomer to the time when that customer
// will be done. Need to call randomInt().
int serviceTime = randomInt(parameters[MIN_SERVICE_TIME],
parameters[MAX_SERVICE_TIME]);
// This will give us a timestamp of when the current customer will
// be done.
currentCustomer = simTime + serviceTime;
line.pop();
counters[CUSTOMERS_SERVICED]++;
}
else
{
// The line is empty
counters[CUSTOMERS_SERVICED]++;
currentCustomer = -1;
}
}
}
// Print a summary of the simulation:
// counters
counters[AVERAGE_WAIT] /= counters[CUSTOMERS_SERVICED];
counters[AVERAGE_LINE] /= parameters[SIMULATION_TIME];
cout << endl;
cout << "\t Customers serviced: " << "\t\t" << counters[CUSTOMERS_SERVICED] << endl;
cout << "\t Customers leaving: " << "\t\t" << counters[CUSTOMERS_LEAVING] << endl;
cout << "\t Average time spent in line: " << "\t" << counters[AVERAGE_WAIT] << endl;
cout << "\t Average line length: " << "\t\t" << counters[AVERAGE_LINE] << endl;
cout << "\t Angry customers: " << "\t\t" << counters[ANGRY_CUSTOMERS] << endl;
cout << endl;
}
return 0;
}
|