#include "stdafx.h"
#include "BankObj.h"
CBank:: CBank()
{
}
CBank:: ~CBank()
{
POSITION pos;
CCounter* pCounter;
CCustomer* pCustmor;
CEvent* pEvent;
pos = m_CounterList.GetHeadPosition();
while(pos != NULL)
{
pCounter = (CCounter*)m_CounterList.GetNext(pos);
pCounter->m_CustomerQueue.RemoveAll();
delete pCounter;
}
m_CounterList.RemoveAll();
pos = m_CustomerList.GetHeadPosition();
while(pos != NULL)
{
pCustmor = (CCustomer*)m_CustomerList.GetNext(pos);
delete pCustmor;
}
m_CustomerList.RemoveAll();
pos = m_EventList.GetHeadPosition();
while(pos != NULL)
{
pEvent = (CEvent*)m_EventList.GetNext(pos);
delete pEvent;
}
m_EventList.RemoveAll();
}
/*********** 银行系统初始设置 ******************/
void CBank:: InitBank(int countnum)
{
int i;
POSITION pos;
CCounter* pCounter;
CCustomer* pCustmor;
CEvent* pEvent;
pos = m_CounterList.GetHeadPosition();
while(pos != NULL)
{
pCounter = (CCounter*)m_CounterList.GetNext(pos);
pCounter->m_CustomerQueue.RemoveAll();
delete pCounter;
}
m_CounterList.RemoveAll();
pos = m_CustomerList.GetHeadPosition();
while(pos != NULL)
{
pCustmor = (CCustomer*)m_CustomerList.GetNext(pos);
delete pCustmor;
}
m_CustomerList.RemoveAll();
pos = m_EventList.GetHeadPosition();
while(pos != NULL)
{
pEvent = (CEvent*)m_EventList.GetNext(pos);
delete pEvent;
}
m_EventList.RemoveAll();
m_CountNum = countnum;
for( i =0;i< m_CountNum;i++ )
{
pCounter = new CCounter;
pCounter->m_ID = i+1;
m_CounterList.AddTail(pCounter);
}
m_SimuTime = 0;
m_ServerdCustmorNum = 0;
m_AvgWaitLength =0;
m_TotalWaitTime = 0;
m_AvgWaitTime =0;
m_WorkTimeLength = 28800; //秒,9:00-17:00
}
/************** 银行模拟仿真主控函数**************/
void CBank:: Simulation()
{
CEvent* pEvent;
//生成第一个到达顾客并安排其到达事件
GenerateNewCustomer(m_SimuTime);
while ( m_SimuTime <= m_WorkTimeLength )
{
pEvent = GetMinTimeEvent(); //选择最小时间事件,并将事件指针从事件表中remove掉
m_SimuTime = pEvent->m_OccurTime; // 推进模拟时钟
switch ( pEvent->m_Type ) //处理发生的事件
{
case ARRIVE: //顾客到达事件
CustomerArrive(pEvent->m_pCustmor);
break;
case LEAVE: //顾客离去事件
CustomerDepart(pEvent->m_pCustmor,pEvent->m_pCounter);
break;
}
delete pEvent;
}
SimuDataReport();
}
/************ 到达事件处理 *************
参数:pCustmor 指向到达顾客的指针 */
void CBank:: CustomerArrive(CCustomer* pCustmor)
{
CCounter* pCounter;
CEvent* pEvent;
// 生成下一个到达顾客并安排其到达事件
GenerateNewCustomer( pCustmor->m_ArriveTime );
// 选择服务台
pCounter = SelectCounter();
if(pCounter->m_Status == FREE ) //接受服务
{
pCounter->m_Status = WORKING;
//安排其离去事件
pCustmor->m_ServedTime = pCustmor->m_ArriveTime;
pCustmor->m_DepartTime = pCustmor->m_ServedTime + GetRand(SERVICE);
pEvent = new CEvent;
pEvent->m_pCustmor = pCustmor;
pEvent->m_OccurTime = pCustmor->m_DepartTime;
pEvent->m_pCounter = pCounter;
pEvent->m_Type = LEAVE;
m_EventList.AddTail(pEvent);
}
pCounter->m_QueLength++;
pCounter->m_CustomerQueue.AddTail(pCustmor);
ComputSimuData();
}
/******* 离去事件处理 *************
参数:pCustmor 指向到达顾客的指针 ,pCounter 指向离去柜台的指针 */
void CBank:: CustomerDepart(CCustomer* pCustmor, CCounter* pCounter)
{
CEvent* pEvent;
CCustomer* pNextCustmor;
pCounter->m_QueLength --;
pCounter->m_CustomerQueue.RemoveHead();
if(pCounter->m_QueLength > 0 ) //队列非空
{
pNextCustmor = (CCustomer* )pCounter->m_CustomerQueue.GetHead();
//安排下一顾客及其离去事件
pNextCustmor->m_ServedTime = pCustmor->m_DepartTime;
pNextCustmor->m_DepartTime = pNextCustmor->m_ServedTime + GetRand(SERVICE);
pEvent = new CEvent;
pEvent->m_pCustmor = pNextCustmor;
pEvent->m_OccurTime = pNextCustmor->m_DepartTime;
pEvent->m_pCounter = pCounter;
pEvent->m_Type = LEAVE;
m_EventList.AddTail(pEvent);
}
else pCounter->m_Status = FREE;
ComputSimuData();
//换队处理
CheckandJockey( pCounter );
}
/******* 察看换队及其处理 *************
参数:pToCounter 指向目标柜台的指针 */
void CBank::CheckandJockey( CCounter* pToCounter)
{
CCounter* pFromCounter;
CCustomer* pCustmor;
CEvent* pEvent;
//选择将换队的顾客及所在队列
if((pFromCounter = SelectJockeyCounter( pToCounter ))== NULL ) return;
if( pFromCounter->m_CustomerQueue.IsEmpty( )) return;
pCustmor = ( CCustomer* )pFromCounter->m_CustomerQueue.RemoveTail();
if(pToCounter->m_Status == FREE ) //接受服务
{
pToCounter->m_Status = WORKING;
//安排其离去事件
pCustmor->m_ServedTime = m_SimuTime;
pCustmor->m_DepartTime = pCustmor->m_ServedTime + GetRand(SERVICE);
pEvent = new CEvent;
pEvent->m_pCustmor = pCustmor;
pEvent->m_OccurTime = pCustmor->m_DepartTime;
pEvent->m_pCounter = pToCounter;
pEvent->m_Type = LEAVE;
m_EventList.AddTail(pEvent);
}
pToCounter->m_QueLength++;
pToCounter->m_CustomerQueue.AddTail(pCustmor);
ComputSimuData();
}
/* ***** 产生新的到达顾客并安排到达事件 *********
参数: Curtime:当前顾客到达时间 */
void CBank:: GenerateNewCustomer( float Curtime )
{
CCustomer* pCustmor;
CEvent* pEvent;
m_ServerdCustmorNum++;
pCustmor = new CCustomer;
pCustmor->m_ID = m_ServerdCustmorNum;
pCustmor->m_ArriveTime = Curtime + GetRand(ARRIVE);
m_CustomerList.AddTail(pCustmor);
pEvent = new CEvent;
pEvent->m_pCustmor = pCustmor;
pEvent->m_OccurTime = pCustmor->m_ArriveTime;
pEvent->m_pCounter = NULL;
pEvent->m_Type = ARRIVE;
m_EventList.AddTail(pEvent);
}
/* **** 顾客到达后根据一定的规则选择服务台
返回值:所选择的柜台指针 ******** */
CCounter* CBank:: SelectCounter()
{
return NULL;
}
/* **** 从事件表中选择最小时间事件,注意:将所选事件指针从事件表中remove掉
返回值:指向所选事件的指针 *********/
CEvent* CBank:: GetMinTimeEvent()
{
return NULL;
}
/* **** 根据一定规则选择需要进行换队的柜台
返回值:指向所选柜台的指针,没有换队需求时返回NULL *********/
CCounter* CBank:: SelectJockeyCounter(CCounter* pTocounter)
{
return NULL;
}
/* **** 根据一定的递推统计算法计算仿真指标 *****/
void CBank:: ComputSimuData()
{
}
/***** 获取所需的随机数 ********
参数: type随机数类型 返回值:DOUBLE型随机数*/
float CBank:: GetRand(int type)
{
return 0;
}
/***** 仿真结果输出 *********/
void CBank:: SimuDataReport()
{
}