数据结构电话客户服务模拟_第1页
数据结构电话客户服务模拟_第2页
数据结构电话客户服务模拟_第3页
数据结构电话客户服务模拟_第4页
数据结构电话客户服务模拟_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

客户效劳模拟问题描述一个模拟时钟提供接听效劳的时间〔以分钟记〕,然后这个时钟将循环的自增一〔分钟〕直到到达指定时间为止。在时钟的每个“时刻”,就会执行一次检查来看看当前的效劳是否已经完成了,如果是,这个从队列中删除,模拟效劳将从队列中取出下一个〔如果有的话〕继续开始。同时还需要执行一个检查来判断是否有一个新的到达。如果是将其到达时间记录下来,并为其产生一个随机效劳时间,这个效劳时间也被记录下来,然后这个被放入队列中,当客户效劳人员空闲时,按照先来先效劳的方式处理这个队列。当时钟到达指定时间时,不会再接听新的,但是效劳将继续,直到队列中所有都得到处理为止。当完成上述功能以后,将记录最正确方案,记录客服人员信息,通过桶存储方式来记录和查询信息。根本要求〔1〕程序需要的初始数据包括:客户效劳人员的人数,时间限制,的到达速率,平均效劳时间,客服人员编号,客服人员姓名。〔2〕程序产生的结果包括:处理的数,每个的平均等待时间,效劳总时间,限制时间内接听数。三、工具/准备工作在开始做课程设计工程前,应回忆或复习相关内容。需要一台计算机,期中安装有VisualC++6.0、VisualC++2005、VisualC++2005Express、Dev-C++或MinGWDeveloperStudio之一的集成开发环境。分析与实现由于要计算客户的等待时间,并且每个客户都有接受效劳所需的时间,为实现这些功能,对客户加上当前接受效劳的时间,具体客户结构类型和效劳人员类型如下://效劳人员类型structTelephoneServerType{ charseverNumber[18]; //效劳人员编号 charseverName[16]; //效劳人员姓名 boolisEmpty; //是否为空 intobjServerTotalTime;//效劳总时间 intobjTelephoneOfLimit;//限制时间内接听数};//客户类型structCustomerType{unsignedintarrivalTime;//客户到达时刻 unsignedintduration;//客户接受效劳所需的时间 unsignedintcurServiceTime;//当前接受效劳的时间};//效劳人员类型structServerType{ intserverTotalTime;//效劳总时间 inttelephoneOfLimit;//限制时间内接听数};为了模拟计时,在客户效劳模拟类中增加表示当前时间的变量curTime,此处时间单位为分钟,为更好地模拟,使用泊松随机数,为模拟客户随机打进,需要知道客户到达率〔平均每分钟打进人数〕,为模拟客户接受效劳的时间,需要知道平均效劳时间,为存储效劳人员信息,需要创造一个文本,将基桶写入文件中,具体客户效劳模拟类声明如下:template<intm,intb>TelephoneServer<m,b>::TelephoneServer()//操作结果:初始化效劳人员信息{ //初始化数据成员 curTime=0;//当前时间初值为0 totalWaitingTime=0;//总等待时间初值为0numOfCalls=0;//处理的数初值为0//获得模拟参数 cout<<"输入客户人员的人数(请输入数字):"; cin>>numOfCustomerServiceStaffs;//输入客户人员的人数 cout<<"输入时间限制(请输入数字):"; cin>>limitTime;//不再接受新的时间 intcallsPerHour;//每小时数 cout<<"输入每小时数(请输入数字):"; cin>>callsPerHour;//输入每小时数 arrivalRate=callsPerHour/60.0;//转换为每分钟数 cout<<"输入平均效劳时间(请输入数字):"; cin>>averageServiceTime;//输入平均效劳时间//分配动态存储空间 callsWaitingQueue=newLinkQueue<CustomerType>[numOfCustomerServiceStaffs];//为客服等待队列数组分配存储空间 customerServed=newCustomerType[numOfCustomerServiceStaffs];//为客服人员正在效劳的客户分配存储空间servers=newServerType[numOfCustomerServiceStaffs];//为效劳人员分配存储空间//初始化客服人员正在效劳的客户 for(inti=0;i<numOfCustomerServiceStaffs;i++) {//初始化每个客服人员正在效劳的客户 customerServed[i].curServiceTime=customerServed[i].duration=0;//表示还没有人接受效劳servers[i].serverTotalTime=servers[i].telephoneOfLimit=0;//表示还没有工作 }//设置随机数种子 SetRandSeed();//以当前时间值为随机数种子 ifstreamiFile("telph.dat"); //建立输入文件 if(iFile.fail()) { //翻开文件失败,表示不存在文件 ofstreamoFile("telph.dat"); //建立输出文件 if(oFile.fail())throw("翻开文件失败!"); //抛出异常 oFile.close(); //关闭文件 } else { //存在文件 iFile.close(); //关闭文件 } hashFile.open("telph.dat",ios::in|ios::out|ios::binary); //以读写方式翻开文件 if(hashFile.fail())throw("翻开文件失败!"); //抛出异常 hashFile.seekg(0,ios::end); //定位到文件尾 intbucketNum=hashFile.tellg()/sizeof(BucketType); //桶数 if(bucketNum<b) { //桶数不于基桶数,说明文件不完整或已被破坏,应初始化基桶 BucketTypebucket; intpos; //临时变量 for(pos=0;pos<m;pos++) { //初始化基桶 bucket.records[pos].isEmpty=true; //空记录 bucket.next=-1; //无溢出 } hashFile.clear(); //去除标志 hashFile.seekg(0,ios::beg); //定位到文件头 for(pos=0;pos<b;pos++) { //写基桶到文件中 hashFile.write((char*)&bucket,sizeof(BucketType));//写入基桶 } }}类TelephoneServer的Service〔〕辅助函数为客户效劳人员效劳当前的,如果当前客户接受效劳的时间还未到达客户效劳所需的时间,那么继续在为客户提供效劳,否那么如有客户在等待效劳,那么从等待队列中取出新客户进行效劳,并更新总客户等待时间,具体实现如下:template<intm,intb>voidTelephoneServer<m,b>::Service()//操作结果:效劳当前〔如有〕{ for(inti=0;i<numOfCustomerServiceStaffs;i++) {//处理每个客服工作人员提供的效劳 if(customerServed[i].curServiceTime<customerServed[i].duration) {//未到达客户接受效劳所需的时间,正在为客户提供效劳 customerServed[i].curServiceTime++;//增加客户接受效劳的时间 } else {//已到达客户接受效劳所需的时间,为下一客户提供效劳 if(!callsWaitingQueue[i].Empty()) {//有客户在等待 callsWaitingQueue[i].OutQueue(customerServed[i]);//从等待队列中取出新客户进行效劳 totalWaitingTime+=curTime-customerServed[i].arrivalTime;//更新总客户等待时间 } } }}类TelephoneServer的CheckForNewCall〔〕辅助函数用于生成当前时间打进的人数,对每个打进的客户,将其插入最短的客服等待队列中,具体实现如下:template<intm,intb>voidTelephoneServer<m,b>::CheckForNewCall()//操作结果:检查是否有新,如果有,那么将添加到队列{ intcalls=GetPoissionRand(arrivalRate);//当前打进的人数 for(inti=1;i<=calls;i++) {//第i个 CustomerTypecustomer;//客户customer.arrivalTime=curTime;//客户到达时间 customer.duration=GetPoissionRand(averageServiceTime);//客户接受效劳所需的时间 customer.curServiceTime=0;//当前接受效劳的时间 intpos=MinLengthCallWaitingQueue();//最短客服等待队列的位置callsWaitingQueue[pos].InQueue(customer);//客户插入等待队列 numOfCalls++;//处理的数 }}类TelephoneServer的Display〔〕辅助函数用于在模拟的最后显示处理的总数和每个的平均等待时间,具体实现如下:template<intm,intb>voidTelephoneServer<m,b>::Display()//操作结果:显示模拟结果{ cout<<"处理的总数:"<<numOfCalls<<endl; cout<<"平均等待时间:"<<GetTheAverageServiceTimet()<<endl<<endl;}类TelephoneServer的Run〔〕方法实现模拟客户效劳,当为到达时间限制时,首先检查是否有新,如果有,那么将添加到队列,然后客户效劳人员再对当前客户进行效劳,最后增加时间;当已到达时间限制时,不再检查是否有新,但客户效劳人员还要对当前客户进行效劳,并增加时间,具体实现如下:template<intm,intb>voidTelephoneServer<m,b>::Run()//操作结果:模拟客户效劳{ while(curTime<limitTime) {//未到达时间限制,可检查新 CheckForNewCall();//检查是否有新,如果有,那么将添加到队列 Service();//进行效劳 curTime++;//增加时间 } while(MinLengthCallWaitingQueue()>0) {//在客服等待队列中还有客户在等待效劳 Service();//进行效劳 curTime++;//增加时间 } Display();}类TelephoneServer中Hash(constcharseverNumber[18])辅助函数用于生成散列函数值,具体实现如下:template<intm,intb>longTelephoneServer<m,b>::Hash(constcharseverNumber[18])//操作结果:返回散列函数值{ longh=0; //散列函数值 for(intpos=0;pos<(int)strlen(severNumber);pos++) { //依次处理各数字字符 h=(h*10+severNumber[pos]-'0')%b; } returnh; //返回散列函数值}类TelephoneServer中LocateHelp(constBucketType&bucket,charseverNumber[18])辅助函数用于记录效劳人员编号在桶中的位置,具体实现如下:template<intm,intb>intTelephoneServer<m,b>::LocateHelp(constBucketType&bucket,charseverNumber[18])//操作结果:返回效劳人员编号severNumber在桶bucket中的位置{ for(intpos=0;pos<m;pos++) { //依次比拟桶中各效劳人员信息存储记录 if(!bucket.records[pos].isEmpty&& strcmp(bucket.records[pos].severNumber,severNumber)==0)returnpos;//定位成功 } return-1; //定位失败}类TelephoneServer中Locate(BucketType&bucket,long&offset,int&pos,charseverNumber[18])辅助函数用于定位效劳人员编号所在的桶,以及在桶中的位置和桶在文件中的位置,具体实现如下:template<intm,intb>voidTelephoneServer<m,b>::Locate(BucketType&bucket,long&offset, int&pos,charseverNumber[18])//操作结果:定位效劳人员编号severNumber所在的桶bucket,在桶中的位置pos,桶在文件// 中的位置位置offset{ longh=Hash(severNumber); //散列函数值 offset=sizeof(BucketType)*h; //桶在文件中的位置 hashFile.clear(); //去除标志 hashFile.seekg(offset,ios::beg); //文件定位 hashFile.read((char*)&bucket,sizeof(BucketType)); //读取基桶 pos=LocateHelp(bucket,severNumber); //定位效劳人员信息存储记录在桶中的位置 if(pos==-1)offset=bucket.next; //溢出桶的位置 while(pos==-1&&offset!=-1) { //继续在溢出桶中查找 hashFile.clear(); //去除标志 hashFile.seekg(offset,ios::beg); //文件定位 hashFile.read((char*)&bucket,sizeof(BucketType)); //读到基桶 pos=LocateHelp(bucket,severNumber); //定位效劳人员信息存储记录在桶中的位置 if(pos==-1)offset=bucket.next; //后继溢出桶的位置 }}类TelephoneServer中LocateEmptyRecordHelp(constBucketType&bucket)辅助函数用于获得空记录的位置,具体实现如下:template<intm,intb>intTelephoneServer<m,b>::LocateEmptyRecordHelp(constBucketType&bucket)//操作结果:返回空记录位位置{ for(intpos=0;pos<m;pos++) { //依次比拟桶中各效劳人员信息存储记录 if(bucket.records[pos].isEmpty)returnpos; //定位成功 } return-1; //定位失败}类TelephoneServer中LocateEmptyRecord(BucketType&bucket,long&offset,int&pos,charseverNumber[18])辅助函数用于效劳人员编号所在具有空记录的桶,以及桶中空记录的位置,和桶在文件中的位置,具体实现如下:template<intm,intb>voidTelephoneServer<m,b>::LocateEmptyRecord(BucketType&bucket,long&offset, int&pos,charseverNumber[18])//操作结果:定位效劳人员编号severNumber所在的具有空记录的桶bucket,桶中的空记录位置pos,桶// 在文件中的位置位置offset{ longh=Hash(severNumber); //散列函数值 offset=sizeof(BucketType)*h; //桶在文件中的位置 hashFile.clear(); //去除标志 hashFile.seekg(offset,ios::beg); //文件定位 hashFile.read((char*)&bucket,sizeof(BucketType)); //读到基桶 pos=LocateEmptyRecordHelp(bucket); //定位桶中空记录的位置 if(pos==-1)offset=bucket.next; //溢出桶的位置 while(pos==-1&&offset!=-1) { //继续在溢出桶中查找 hashFile.clear(); //去除标志 hashFile.seekg(offset,ios::beg); //文件定位 hashFile.read((char*)&bucket,sizeof(BucketType)); //读到基桶 pos=LocateEmptyRecordHelp(bucket); //定位桶中空记录的位置 if(pos==-1)offset=bucket.next; //后继溢出桶的位置 }}类TelephoneServer中Input()辅助函数用于输入记录并且将数据写入通过桶写入到文件中,具体实现如下:template<intm,intb>voidTelephoneServer<m,b>::Input()//操作结果:输入记录{ TelephoneServerTypetelph;//效劳人员信息存储记录 telph.isEmpty=false; //标记 cout<<"输入效劳人员编号:"; cin>>telph.severNumber; cout<<"输入效劳人员姓名:"; cin>>telph.severName;telph.objServerTotalTime=GetTheServerTotalTime();telph.objTelephoneOfLimit=GetTheTelephoneOfLimit(); BucketTypebucket; //桶 longoffset; //桶在文件中的相应位置 intpos; //效劳人员信息存储记录在桶中的位置 Locate(bucket,offset,pos,telph.severNumber); //定位效劳人员信息存储记录的位置 if(pos!=-1) { //定位成功 cout<<"编号已在散列文件中!"<<endl; } else { //定位失败 LocateEmptyRecord(bucket,offset,pos,telph.severNumber);//定位空记录位置 if(pos!=-1) { //找到空记录 bucket.records[pos]=telph; //将效劳人员信息存储记录赋值给bucket.records[pos] hashFile.clear(); //去除标志 hashFile.seekg(offset,ios::beg); //定位文件 hashFile.write((char*)&bucket,sizeof(BucketType));//写桶 } else { hashFile.clear(); //去除标志 hashFile.seekg(0,ios::end); //定位到文件尾 bucket.next=hashFile.tellg(); //后继溢出桶位置 hashFile.clear(); //去除标志 hashFile.seekg(offset,ios::beg); //定位文件 hashFile.write((char*)&bucket,sizeof(BucketType));//写桶 offset=bucket.next; //新溢出桶在文件中的位置 for(pos=1;pos<m;pos++) { //设置空记录 bucket.records[pos].isEmpty=true; } pos=0; //效劳人员信息存储记录的位置 bucket.records[pos]=telph; //将效劳人员信息存储记录赋值给bucket.records[pos] hashFile.clear(); //去除标志 hashFile.seekg(offset,ios::beg); //定位文件 hashFile.write((char*)&bucket,sizeof(BucketType));//写桶 } }}类TelephoneServer中Serach()辅助函数用于查找客服人员的信息,通过输入客服人员编号获得其在文件中的位置并显示在屏幕上,具体实现如下:template<intm,intb>voidTelephoneServer<m,b>::Serach()//操作结果:查找记录{ charseverNumber[18]; //效劳人员编号 cout<<"输入效劳人员编号:"; cin>>severNumber; BucketTypebucket; //桶 longoffset; //桶在文件中的相应位置 intpos; //效劳人员信息存储记录在桶中的位置 Locate(bucket,offset,pos,severNumber);//定位效劳人员信息存储记录的=-1) if(pos==-1) { //定位失败 cout<<"查找失败!"<<endl; } else { hashFile.clear(); //去除标志 hashFile.seekg(offset,ios::beg); //定位文件 hashFile.read((char*)&

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论