离散事件模拟---银行业务模拟c++实现

来源:互联网 发布:windows msg 编辑:程序博客网 时间:2024/04/30 11:03

 

 

// 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;
}