事件驱动仿真

时间:2022-10-04 20:01:17

Overview: For this assignment, you must write a C++ program that simulates a line of customers at a bank. Your program must compute statistics to describe the length of time that customers are required to wait for service. This problem resembles many physical systems that make use of queues. Examples include communication networks, highway traffic, and assembly lines in factories.
Objectives: The main goals of this assignment are to gain experience in using queues and the Standard Template Library (STL), and in modeling real-world systems.
Program specifications: Write a C++ program that implements an event-driven simulation of a line of customers at a bank, similar to the description in Chapter 13 of the textbook. Each customer enters a queue, waits until reaching the front of the queue, performs a transaction with a teller (bank employee), and then leaves the bank. You may assume that the bank has only one queue and one teller.
A list of arrival events will be provided to your program from an input text file, similar to the following:
20 5
22 4
23 2
30 3
Each line of text represents a single bank customer, and contains a pair of integers. The first number is the arrival time, which is when that customer entered the bank queue; this is specified in minutes relative to the time when the bank opened for business at t = 0. The second number on each line is the transaction time, which is the amount of time (also in minutes) required for that customer’s transaction. You may assume that the file’s events are sorted in ascending order of arrival time.
The main goal of the program is to determine when departure events occur (i.e., when customers leave the bank), and compute statistics based on the length of time that customers spend in the bank. Your program needs to maintain a queue of customers, and an event list. As described in the textbook and lecture notes, the event list is an ADT that 1) keeps track of arrival and departure events that will occur but have not yet occurred, and 2) contains at most one arrival event and one departure event.
The output of the program should be sent to a text file. This output should provide a trace of events, along with statistics for the entire simulation run. For the input file shown above, the output should resemble the following:
1
Spring 2015
t = 0: Simulation begins
t = 20: Arrival event
t = 22: Arrival event
t = 23: Arrival event
t = 25: Departure event
t = 29: Departure event
t = 30: Arrival event
t = 31: Departure event
t = 34: Departure event
Total number of customers = 4
Average amount of time in the bank = 6.0 minutes
Maximum amount of time in the bank = 8.0 minutes
Average amount of time waiting = 2.5 minutes
Maximum amount of time waiting = 6.0 minutes
Maximum length of line = 3 customers
In the program’s output, the “amount of time in the bank” should include a customer’s transaction and waiting times. The “amount of time waiting” should not include a customer’s transaction time. The “length of line” should include the customer who is engaged in a transaction.
You must use an STL queue to represent your line (i.e., queue) of customers. Use an ADT for your event list, either by selecting one from the STL (e.g., using the STL list container) or by implementing your own. The choice of ADT for the event list is up to you.
Your program should be invoked using the command line as follows:
simulate input_file output_file
Here, simulate is the name of your executable program, and input_file and output_file are the names of the input and output text files, respectively.
Exception handling: Your implementation should use try/throw/catch to handle the following exceptions:
1. If input/output files are not provided on the command line, or the input file does not exist.
2. If new returns NULL when allocating memory.
3. If the content of the input file is not in the expected format.

//arrivalfile1.txt
20 5
22 4
23 2
30 3

//arrivalfile2.txt
1 5
2 5
4 5
20 5
22 5
24 5
26 5
28 5
30 5
88 3

//arrivalfile3.txt
2 4
6 3
9 5
14 6
20 1



#ifndef SIMULATE_H_
#define SIMULATE_H_

#include <queue>
#include <fstream>
#include <iostream>

using namespace std;

#define MAX 100

//event class
enum EventType{ Arrival, Departure }; //event type

struct Customer
{
int arriveTime;
int transactionTime;
};

//extern queue<Customer> bankQueue;

class Event
{
public:
Event(int _time, EventType _eType, int _serviceTime=0)
{
time = _time;
eType = _eType;
serviceTime = _serviceTime;
}
Event(){};
int getTime() { return time; }
EventType getEType() {return eType;}
int getServiceTime() {return serviceTime;}
void printEvent();
private:
int time; //arrive/leave time
EventType eType; //event type
int serviceTime; //if arrive,add the service time
};

//event list
class EventList
{
private:
Event *events;
int count; //list length
public:
EventList()
{
events = new Event[MAX];
count = 0;
}
void AddEvent(Event evt); //add event to the list

Event DelEvent(); //The minimum time given top priority

bool isEmpty(){ return count == 0; } //isEmpty
bool isFull(){ return count == MAX; } //isFull
int length(){ return count; } //get the length
};


//data
extern EventList eList;
extern int totalNum ;
extern float sumTime;
extern float maxTime;
extern float maxWaitTime;
extern float sumWaitTime;
extern int maxLength ;

//function
void ReadData(char *fileName); //read data from file


#endif



#include "simulate.h"
#include <fstream>

//add event to the list
void EventList::AddEvent(Event evt)
{
if (!isFull())
{
events[count] = evt;
count++;
}
}


//The minimum time given top priority
Event EventList::DelEvent()
{
if (!isEmpty())
{
int min = events[0].getTime();
int minindex = 0;

for (int i = 1; i < count; i++)
{
if (events[i].getTime() < min)
{
min = events[i].getTime();
minindex = i;
}
}
if (events[minindex].getEType() == Arrival) //departurn first,arrival second
for (int i = 0; i < count; i++)
if (events[i].getTime() == events[minindex].getTime() && events[i].getEType() == Departure) minindex = i;
Event et = events[minindex];
events[minindex] = events[count - 1];
count--;
return et;
}
else
throw("delete error");
}



//read data from file
void ReadData(char *fileName)
{
fstream in;
in.open(fileName);
if (!in)
{
throw("can not open the file.");
}
int i = 0, temp1 = 0, temp2 = 0;
while (!in.eof())
{
totalNum++;
in >> temp1 >> temp2;
Event ev(temp1, Arrival, temp2);
eList.AddEvent(ev);
//cout << temp1 << " " << temp2 << endl;
}
in.close();
}

#include <iostream>
#include "simulate.h"


using namespace std;

queue<Customer> bankQueue;
EventList eList;
int totalNum = 0;
float sumTime = 0;
float maxTime = 0;
float maxWaitTime = 0;
float sumWaitTime = 0;
int maxLength = 0;


int main()
{
fstream out;
out.open("output.txt");
if (!out)
{
throw("can not open the file.");
}
int currentTime = 0;
out<<"t = 0: Simulation begins" << endl; //write data to file
ReadData("arrivalfile2.txt");
int flag = 1;
while (!eList.isEmpty())
{
Event tempE = eList.DelEvent();
if (flag == 1)
{
flag = 0;
currentTime = tempE.getTime();
}
if (tempE.getEType() == Arrival) //Process arrival event
{
if (currentTime >= tempE.getTime())
currentTime = tempE.getTime();
out << "t = " << currentTime << ": Arrival event" << endl;
bool atFront = bankQueue.empty();
bankQueue.push({ tempE.getTime(), tempE.getServiceTime() });//insert customer int teller queue
if (atFront)
{
int departureTime = currentTime + tempE.getServiceTime(); //get the departureTime
Event ev(departureTime, Departure);
eList.AddEvent(ev);
}
currentTime = currentTime + tempE.getServiceTime();
int size = bankQueue.size();
if (size > maxLength) maxLength = size; //get the max size of queue
}
else //Process departure event
{
if (currentTime >= tempE.getTime())
currentTime = tempE.getTime();
out << "t = " << currentTime << ": Departure event" << endl;

/*figure the time*/
Customer cusTime = bankQueue.front();
float bankTime = (float) (currentTime - cusTime.arriveTime);
float waitTime = bankTime - cusTime.transactionTime;
sumTime += bankTime;
if (bankTime > maxTime) maxTime = bankTime;
sumWaitTime += waitTime;
if (waitTime > maxWaitTime) maxWaitTime = waitTime;
/*figure time end*/

bankQueue.pop(); //delete the front customer
if (!bankQueue.empty())
{
Customer nowCustomer = bankQueue.front();
int departureTime = currentTime + nowCustomer.transactionTime; //get the departureTime
Event ev(departureTime, Departure);
eList.AddEvent(ev);
currentTime = currentTime + nowCustomer.transactionTime;
}
else
{
flag = 1;
}

}
}
out << endl;
out << "Total number of customers = " << totalNum << endl;
out << "Average amount of time in the bank = " << sumTime / totalNum << " minutes" <<endl;
out << "Maximum amount of time in the bank = " << maxTime << " minutes" << endl;
out << "Average amount of time waiting = " << sumWaitTime / totalNum << " minutes" << endl;
out << "Maximum amount of time waiting = " << maxWaitTime <<" minutes" << endl;
out << "Maximum length of line = " << maxLength <<" customers"<< endl;
out.close();
return 0;
}


事件驱动仿真

事件驱动仿真

事件驱动仿真



最后谈下收货吧,以前看过c++ primer plus上关于银行的模拟,是关于优先队列的,原先看书只是一带而过,没有自己敲下,后来碰到这个作业,比书上更为复杂,不仅要求自己写优先队列,还要求掌握优先队列的使用,更复杂的是要进行事件驱动的模拟,其中参考的资料是国外的课件,不得不说,国外的课件做的真好,出的题目很有针对性,总之做完获益匪浅。