// bankQueue.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <list>
#include <queue>
#include <iostream>
#include <ctime>
using namespace std;
typedef struct Event
{
int OccurTime; //事件发生时刻
int NType; //事件类型,0表示到达事件,1-4表示四个窗口的离开事件
bool operator<(Event a) //sort()函数调用函数指针,比较自定义类型
{
if (this->OccurTime <= a.OccurTime)
{
return true;
}
return false;
}
}Event,ElemType;
typedef struct
{
int ArriveTime; //到达时间
int Duration; //办理事务所需时间
}QElemType; //队列的数据元素类型
std::list<Event> ev; //事件列表
Event en; //事件
QElemType customer;
std::queue<QElemType> q[3];
int TotalTime = 0;
int CustomerNum = 0;
int CloseTime = 300;
void Init()
{
//设定第一个客户到达事件
en.OccurTime = 0;
en.NType = 0;
ev.push_back(en);
}
int RandNum()
{
int MIN = 4;
int MAX = 20;
srand((unsigned int )time(NULL));
return rand() % (MAX - MIN + 1);
}
int GetMinLengthQueue()
{
unsigned int min = q[0].size();
for (int i =1 ; i<3; i++)
{
if (q[i].size() < min)
{
min = i;
}
}
return min;
}
void CustomerArrived()
{
//处理客户到达事件
++CustomerNum;
int duraTime = RandNum();
int interTime = RandNum();
int t = en.OccurTime + interTime; // 下一客户到达时刻
if(t < CloseTime) //银行尚未关门
{
//插入事件列表
Event newCustomer;
newCustomer.NType = 0;
newCustomer.OccurTime = t;
ev.push_back(newCustomer);
ev.sort();
}
//求长度最短队列
int minQ = GetMinLengthQueue();
QElemType insert;
insert.ArriveTime = en.OccurTime;
insert.Duration = duraTime;
q[minQ].push(insert);
if (q[minQ].size() == 1)//
{
Event newCustomer;
newCustomer.NType = minQ;
newCustomer.OccurTime = en.OccurTime + duraTime;
ev.push_back(newCustomer);
ev.sort();
}
}
void CustomerLeaved()
{
int i = en.NType;
QElemType customer = q[i].front();
q[i].pop();
TotalTime += en.OccurTime - customer.ArriveTime;
if (!q[i].empty()) //
{
QElemType customer = q[i].front();
Event newCustomer;
newCustomer.NType = i;
newCustomer.OccurTime = en.OccurTime + customer.Duration;
ev.push_back(newCustomer);
ev.sort();
}
}
void Bank_Simulation()
{
Init();
while (!ev.empty())
{
std::list<Event>::iterator it = ev.begin();
en = *it;
if (en.NType == 0 )
{
CustomerArrived();
}
else
{
CustomerLeaved();
}
ev.erase(it);
}
cout<<TotalTime<<" "<<(float)TotalTime / CustomerNum<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Bank_Simulation();
system("pause");
return 0;
}