| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2863 人关注过本帖
标题:[分享](2) 银行业务模拟
只看楼主 加入收藏
gaominghui
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2007-9-8
收藏
 问题点数:0 回复次数:1 
[分享](2) 银行业务模拟

(2) 银行业务模拟(难度系数4)
[问题描述]
客户业务分为两种。第一种是申请从银行得到一笔资金,即取款或借款。第二种是向银行投入一笔资金,即存款或换款。银行有两个服务窗口,相应地有两个队列。客户到达银行后先派第一个队列。处理每一个客户业务时,如属于第一种,且申请超出银行现存资金总额而得不到满足的,则立即排入第二个队列等候,直到满足时才离开银行;否则业务处理完后立即离开银行。每接待完一个第二种业务的客户,则顺序检查和处理(如果可能)第二个队列中的客户,对能满足的申请者予以满足,不能满足者重新排到第二个队列的末尾。注意:在此检查过程中,一旦银行资金总额少于或等于刚才第一个队列中最后一个客户(第二种业务)被接待之前的数额,或者本次已将第二个队列检查或处理了一遍,就停止检查(因为此时已不可能还有满足者)转而继续接待第一个队列的客户。任何时刻都只开一个窗口。假设检查不需要时间。营业时间结束时所有客户立即离开银行。
  写一个上述银行业务的事件驱动模拟系统,通过模拟方法求出客户在银行内逗留的平均时间。
[基本要求]
利用动态存储结构实现模拟。
[测试数据]
一天营业开始银行拥有的款项10000(元),营业时间为600分钟。其他模拟的参量自定。注意测定两种极端情况:一是两个到达事件之间的间隔很短,而客户的交易时间很长;另一个正好相反,设置两个到达事件的间隔时间很长,而客户之间交易的时间很短。
[实现提示]
事件有两类:到达银行和离开银行。初始时银行现存资金总额为Total。开始营业后的第一个事件是客户到达,营业时间从0到Closetime。到达事件发生时随机地设置各客户的交易时间和距下一次到达时间之间的时间间隔。每个客户要办理的款项也是随机确定的,用负值和正值分别表示第一类和第二类业务。变量Total、CloseTime以及上述两个随机量的上下界均交互地从终端读入,作为模拟参数。
两个队列和一个事件表均要用动态的存储结构实现。注意弄清应该在什么条件下设置离开事件,以及第二个队列用怎样的存储结构实现可以获得较高的效率。注意:时间表是按照时间顺序有序的。





#include <iostream>
#include <string>
#include <time.h>
using namespace std;


int total; //初始时银行现存资金总额
int closeTime; //营业结束时间
int arriveTime; //两个到达事件之间的间隔上限
int dealTime; //客户之间交易的时间上限
int dealMoney = 5000; //交易额上限
int currentTime = 0; //当前时间
int totalTime = 0; //客户逗留总时间
int counter = 0; //客户总数
int number = 1; //初始客户序列号+


struct service
{

int num; //客户号
string type; //到达或离开
int beginTime;
int endTime;
int money; //正数为存款,负数为取款
service* next;

};


struct queue
{ //队列


service* head;
service* rear;

};

void push(queue &q,int d)
{// 插入元素d为Q的新的队尾元素
service* temp = new service;
temp->money = d;
temp->next = NULL;
if(NULL == q.head)
{//队列为空,初始化
q. head = temp;
q. rear = temp;
}//if
else
{//队列不为空,插入元素d
q. rear->next = temp;
q. rear = q.rear->next;
}//else


}


void pop(queue &q)
{// 若队列不空,出对列函数
service* temp;
temp = q. head;
if(NULL ==q. head->next)
q.head = q. rear =NULL;
else
q. head=q. head->next;
delete temp;

}
service* front(queue &q)
{//返回队首元素
return q. head;
}
service* back(queue &q)
{//返回队尾元素
return q. rear;
}

service* searchAndDel(queue &q,int m)
{//在对列中寻找可处理元素
service* sign = q. head; //标记头节点
service* temp;
while(NULL != q. head)
{
if((-(q. head->money)) <m)
{//队首元素可以处理
if(q. head==q.rear)
{
temp = q. head;
q. head = q. rear = NULL;
return temp;

}//if
else
{//队首元素出列
temp = q. head;
q. head = q. head->next; // 首节点后移一位,返回原首节点
return temp;
}//else

}//while
else
{//队首元首不能被处理
if(q. head == q. rear){}
else
{//首节点移到队列尾部
q. rear->next = q. head;
q. rear = q. rear->next;
q. head =q. head->next;
q. rear->next = NULL;
}//else
}//else
if(q. head == sign)//队列循环一周时停止
return NULL;

}

return NULL;

}


bool state =1; //用于判断是否有窗口在处理
int currentTimeOfDeal = 0;
int theArriveTime = 0;
queue eq; //事件队列
queue fq; //队列一
queue sq; //对列二
//初始化三个队列

void arrive()
{/*"到达"函数 随机产生顾客,进入队列一
产生到达事件 进入事件队列*/

push(fq,(rand()% (2*dealMoney) -dealMoney)); //随机产生顾客加入第一队列
back(fq)->beginTime = currentTime;
back(fq)->num = number;
push(eq,(back(fq)->money)); //将产生事件加入事件队列
back(eq)->beginTime = currentTime;
back(eq)->type = "到达";
back(eq)->num = number;

++number;

}

void putMoney()
{ //存款函数
total += front(fq)->money; //更新资金总额
push(eq,front(fq)->money); //加入事件队列 离开
back(eq)->type = "离开";
back(eq)->num = front(fq)->num;
back(eq)->endTime = (front(fq)->beginTime + rand()%dealTime +1);
++counter; //更新客户总数
totalTime += (back(eq)->endTime - front(fq)->beginTime); //更新逗留时间
pop(fq); //删除第一队列第一个业务
currentTimeOfDeal = back(eq)->endTime;
state =0;

}


void getMoney()
{//取款函数
if( (-fq.head->money) > total )
{//资金短缺 加入第二队列
push( sq,front(fq)->money );
back(sq)->beginTime = front(fq)->beginTime;
back(sq)->num = front(fq)->num;
pop(fq);
}//if
else
{
total += back(fq)->money;
push(eq,front(fq)->money); //加入事件队列 离开
back(eq)->type = "离开";
back(eq)->num = front(fq)->num;
back(eq)->endTime = (front(fq)->beginTime + rand()%dealTime +1);
back(eq)->beginTime = 0;
currentTimeOfDeal = back(eq)->endTime;
++counter; //更新客户总数
totalTime += ( back(eq)->endTime - back(fq)->beginTime ); //更新逗留时间
pop(fq); //删除第一队列第一个业务
state =0;

}//else

}
service* temped ;
int randomTemp;
void findAndDeal()
{//在对列中寻找可处理元素,对其进行处理
while( (temped= searchAndDel(sq,total))&&NULL != temped )
{//查找可处理取款



total += temped->money; //更新资金总额
push(eq,temped->money); //加入事件队列训 离开
back(eq)->type = "离开";
back(eq)->num = temped->num;
randomTemp = rand()%dealTime +1;
back(eq)->endTime = currentTime + randomTemp ;
currentTimeOfDeal += randomTemp;
++counter; //更新客户总数
totalTime += ( back(eq)->endTime - temped->beginTime ); //更新逗留时间
delete temped; //删除节点
temped = NULL;


}

state = 0;
}

int main()
{
printf(" ********************************************\n");
printf(" 欢迎进入银行模拟系统\n");
printf(" ********************************************\n");
printf("1.开始模拟 0.退出\n");
int n;
scanf("%d",&n);
while(n==1)
{
srand(time(NULL)); //初始化随机函数
printf("输入银行的初始存款:\n");
scanf("%d",&total);
printf("输入银行的营业时间:\n");
scanf("%d",&closeTime);
printf("输入最大到达时间间隔:\n");
scanf("%d",&arriveTime);
printf("输入最大的处理时间:\n");
scanf("%d",&dealTime);

theArriveTime +=rand()%arriveTime + 1; //首次到达时间
while(currentTime < closeTime)
{
++currentTime;
if( currentTimeOfDeal < currentTime ) currentTimeOfDeal = currentTime ;
if( currentTimeOfDeal == currentTime ) state = 1;
if( currentTime == theArriveTime ) //到达事件
{
arrive();
theArriveTime +=rand()%arriveTime +1;
}//if
if( 1 == state && NULL != fq.head)
{
if(fq.head->money >= 0)
{
putMoney();
findAndDeal();
}//if
else
getMoney();
}//if


}



cout <<endl<< "客户序列"<<"\t" <<"事件类型"<<"\t\t"<<" 时间"<<"\t"<<" 处理金额"<<endl;

while( NULL != eq.head) //清除事件队列
{
if(eq.head->type=="离开")
cout << eq.head->num<<"\t\t"<<eq.head->type<<"\t\t"<<"\t\t"<<eq.head->endTime<<"\t\t"<<eq.head->money<<endl;
if(eq.head->type=="到达")
cout << eq.head->num<<"\t\t"<<eq.head->type<<"\t\t"<<"\t\t"<<eq.head->beginTime<<"\t\t"<<eq.head->money<<endl;
pop(eq);
}
cout << "未处理客户:" <<""<<endl;
while( NULL != fq.head)
{
totalTime += ( closeTime - fq.head->beginTime ); //更新结束时第一队列中未处理的客户

cout <<fq.head->num <<" "<<endl ;
++counter;
pop(fq);

}//while

cout <<"客户逗留平均时间为: " << totalTime/counter <<endl;
cout<<"银行当前余额:"<<total<<endl;
break;
}//while(n==1)
return 0;


}//maim()

搜索更多相关主题的帖子: 银行业务 队列 客户 模拟 系数 
2007-09-15 09:20
xiangcaoleyuan
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2008-11-19
收藏
得分:0 
程序是怎么理解的????两种业务和交易时间是如何联系的??????
2008-11-19 21:17
快速回复:[分享](2) 银行业务模拟
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.048271 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved