题目:基于医院分诊系统的排队策略一.需求分析说明1.问题的提出:近年来,随着医疗事业的发展,医院的规模不断扩大,科室门类划分的也越来越细,随之而来的是病人排队挂号和看病变的繁琐,等待时间变长,为此,需要制定一种良好的排队策略,减少病人的等待时间,提高医院的服务质量。
2.以下为主要的功能列表:(1)、进入医生窗口创建功能开始前,医院必须先创建医生窗口来确定现在有多少普通医生和专家医生在就诊,以方便是否满足病人的要求,可安排好是否有足够医生,以方便就诊。
(2)、进入策略一病人挂号功能病人选择该功能时,按照策略一,系统会记录为你挂号的号牌,并且会记录你的挂号的就诊级别。
当病人挂号完毕后,可以进入下一个功能,去选择你所需的医生就诊号,并且记录下医生就诊号(区分专家号和普通号)。
(3)、进入策略一模拟功能病人挂号和选择就诊号完毕后,进入候诊区进行等待,开始模拟策略一的就诊,记录每个病人的诊断时间,此时为保证对病人的透明度,可提前通知病人还需要等待的时间,时间为更加切合实际,采用每个病人单独随机产生。
根据在之前选择的就诊级别,医生会给此类病人就诊两次,以保证病人在现实用的健康保证。
(4)、进入策略二病人挂号功能病人选择该功能时,按照策略二,系统会记录为你挂号的号牌,并且会记录你的挂号的就诊级别。
当病人挂号完毕后,可以进入下一个功能,去选择你所需的医生就诊号,并且记录下医生就诊号(区分专家号和普通号)。
(5)、进入策略一模拟功能病人挂号后,病人挂号和选择就诊号完毕后,进入候诊区进行等待,规定一个固定容量的诊区候诊区和不限制容量的候诊区开始模拟策略二的就诊,记录每个病人的诊断时间,此时为保证对病人的透明度,可提前通知病人还需要等待的时间,时间为更加切合实际,采用每个病人单独随机产生。
根据在之前选择的就诊级别,医生会给此类病人就诊两次,以保证病人在现实用的健康保证。
(6)、进入策略一医生检查窗口选择该功能后,按照策略一的模拟记录的诊断信息,医生可查询是否还有病人还需就诊。
(7)、进入策略二医生检查窗口选择该功能后,按照策略二的模拟记录的诊断信息,医生可查询是否还有病人还需就诊和就诊区和候诊区是否有病人等待。
(8)、退出系统完成所有功能后,选择该功能可以退出该系统。
3.需求的分析:(1)、为了真实实现分诊的功能,在程序里面加入了功能列表菜单和一些选择提示。
(2)、该程序主要运用到链表和队列。
这个程序主要体现在链表的表头和表尾进行操作。
(3)、规定一个固定容量的候诊区进入策略一模拟功能,候诊区里的排队操作采用存储链表的头指针和尾指针。
可以按规定的规则进行模拟排队。
二.总体设计基本框架:1. 我们假设医院实行八小时工作制,一天工作八小时,即480分钟。
2. 医院门诊分为普通号和专家号,普通号一个可是有数为医生,专家号一个可是仅有一个医生,并且将普通好和专家号相互独立,以方便模拟。
3. 我们将病人分为A类和B类,对于A类病人,我们仅进行一次诊断,即用户挂号后进入队列,在进行一次诊断后即完成诊治。
B类病人需要进行两次诊断和一次检查,在完成一次诊断后,医生开出检查意见,病人进行检查,完成后病人需返回科室进行第二次诊断,在第二次完成后即完成诊治。
4. 虽然实际中在一定时间内病人的产生应该按照泊松分布,由于参数设定的困难,我们将病人的产生使用一般的随机数生成,同理,病人的诊治时间也使用确定的时间。
5. 实际中,每位医生每天接诊的人数是有一定限制的,尤其是专家门诊。
但考虑病人来源的数据无论自实际数据库,还是来自根据实际情况的随机模拟数据,各类病人的数量都对应了实际的各科室接诊病人的限制。
6. 对于由于到达时间过晚,部分病人将无法完成诊断,我们将忽略这部分病人。
两种策略的制定:一级分诊队列模式: 每个诊室队列只对应一个诊区候诊队列,我们将之记作Q,一般排队规则是:①刚完成挂号的病人,添加在Q的末尾;②按医嘱完成体检的病人,直接插入在Q的首部。
这种排队规则广泛应用于中小医院。
二级分诊队列模式: 每个诊室队列对应一个诊区候诊队列和一个候诊厅候诊队列,我们将前者记作Q1,后者记作Q2。
一般情况下,因为诊区空间限制,Q1的人数限制在2、3人左右;而候诊厅空间较大,所以对Q2的人数不作限制。
一般排队规则是:①刚完成挂号的病人,添加在Q2的末尾;②按医嘱完成体检的病人,直接插入在Q2的首部;③医师始终对Q1中的首位病人诊治,每位病人诊治结束时,若Q2不空,则Q2的首位病人脱离Q2,进入Q1的尾部。
这种排队规则广泛应用于大中型医院。
要实现的功能设计:功能菜单图片:三.详细设计病人的就诊操作主要做到挂号号码和医生就诊号码选择不会出现重复占用,很里安排就诊时间以及租到尽可能快的操作。
提高效率完成功能。
医生主要设立排队规则,例如,一个候诊区具有规定的候诊数量,不能太大,也不能太小医生对每个病人的诊断时间采用随机产生(程序对数据的需要,现实中看具体的诊断需要)医院主要是做病人和医生之间的就诊连接那一块,使得通过就诊号和挂号之间做到合理的对口,当然,主要是病人去选择自己所需的医生,对症就诊。
Link 类:定义链表类,函数中定义病人的挂号类型,挂号序列,和医生类型Queue 类:定义队列的头尾指针;定义队列的初始队列函数;定义队列的出队,入队函数;定义取对头函数和判断队列是否为空和输出的函数;定义友元类custom;Custom类:定义病人的随机产生和等待队列Doctor 类:定义医生的创建窗口函数;定义医生的普通医生和专家的类型;定义医生检查窗口;Manage 类:定义策略一和策略二的模拟信息函数;定义策略一和策略二的医生检查窗口函数;四.实现部分#include<iostream>#include<ctime>#include<time.h>#include<windows.h>#include<string>using namespace std;const int m=100;char stick[m];class link{public:string data;char stickxing;char xinghao;link *next;};class queue{public:link*front,*rear;void iniqueue(queue&s);void enqueue(queue&s,char x);void enqueue(queue&s,string x,char y);void enqueue1(queue&s,string x,char y);void dlqueue(queue&s);string gethead1(queue&s);char gethead2(queue&s);char gethead3(queue&s);int empty(queue&s);void print(queue&s);friend class custom;};void queue::iniqueue (queue&s){link *p;p=new link;p->next=NULL;s.front=p;s.rear=p;}void queue::enqueue(queue&s,char x){ link *p;string num;string num1;p=new link;if(x=='1'||x=='2')p->xinghao=x;else{cout<<"请输入病人挂号序号:num"<<endl;cin>>num;p->data=num;p->stickxing=x;cout<<"病人要挂普通号还是专家号:a(表示普通号) b(表示专家号)"<<endl;cin>>p->xinghao;}p->next=s.rear->next;s.rear->next=p;s.rear=p;}void queue::enqueue(queue&s,string x,char y) { link *p;string num;string num1;p=new link;if(y=='c'){p->data=x;p->stickxing=y;p->next=s.rear->next;s.rear->next=p;s.rear=p;}else if(y=='a'){p->data=x;p->stickxing=y;p->next=s.front->next;s.front->next=p;}}void queue::enqueue1(queue&s,string x,char y) { link *p;string num;string num1;p=new link;p->data=x;p->stickxing=y;p->next=s.rear->next;s.rear->next=p;s.rear=p;}string queue::gethead1(queue& s){if(s.front==s.rear)return NULL;elsereturn s.front->next->data;}char queue::gethead2(queue& s){if(s.front==s.rear)return NULL;elsereturn s.front->next->stickxing;}char queue::gethead3(queue& s){if(s.front==s.rear)return NULL;elsereturn s.front->next->xinghao;}void queue::dlqueue(queue&s){link *p;p=s.front->next;if(p->next==NULL){s.front->next=NULL;s.front=s.rear;}else s.front->next=p->next;delete p;}int queue::empty (queue&s){if(s.front==s.rear)return 1;elsereturn 0;}class custom{public:void productstick(int n);void makewaitlist(queue &custom1,int n);void makewaitlist1(queue &custom2,queue&Q,int n); };void custom::productstick (int n){char stickclass;int x;srand(time(NULL));for(int i=1;i<=n;i++){ x=int(rand())%2;if(x)stickclass='a';else stickclass='b';stick[i]=stickclass;}}void custom::makewaitlist(queue &custom1,int n){custom1.iniqueue(custom1);for(int i=1;i<=n;i++)custom1.enqueue(custom1,stick[i]);}void custom::makewaitlist1(queue&Q1,queue&Q2,int n){Q1.iniqueue(Q1);Q2.iniqueue(Q2);for(int i=1;i<=n;i++){ if(i<=2)Q1.enqueue(Q1,stick[i]);elseQ2.enqueue(Q2,stick[i]);}}class doctor{public:void proctordoctor(queue &doctoren);void servestick(queue &doctoren,queue&customque);void srvestickfinish(queue&doctoren,queue&customque);char jibei;};void doctor::proctordoctor (queue&doctoren){ char x;int n;doctoren.iniqueue(doctoren);cout<<"请输入普通医生和一个专家人数:n"<<endl;cin>>n;for(int i=1;i<=n;i++){ cout<<"请输入1表示普通医生,2表示一个专家"<<endl;cin>>x;jibei=x;doctoren.enqueue(doctoren,jibei);}}void doctor::servestick (queue &doctoren,queue&customque){ queue storage; int y;char ch;if(doctoren.empty(doctoren))cout<<"没有空闲医生可服务请等待:"<<endl;else{ string x2=customque.gethead1(customque);ch=doctoren.gethead3(doctoren);doctoren.dlqueue(doctoren);storage.iniqueue (storage);storage.enqueue(storage,ch);cout<<x2<<"号"<<"正在诊断之中:请耐心等待!:"<<endl;srand(time(NULL));y=int(rand());Sleep(3000+y);}}void doctor::srvestickfinish (queue&doctoren,queue&customque){ string x;x=customque.gethead1(customque);cout<<x<<"号"<<"病人诊断完成"<<endl;customque.dlqueue(customque);doctoren.enqueue(doctoren,jibei);}class manage{public:voidstrategy1(queue&customque,queue&doctorque,custom&customren,doctor&doctorman,queue&ch eckstick);voidstrategy2(queue&customque,queue&Q,queue&doctorque,custom&customren,doctor&doctorman, queue&checkstick);void doctorcheck(queue&checkstick,queue&customque);void doctorcheck1(queue&checkstick,queue&cQ2);int couttime();};int manage:: couttime(){ int x;time_t now_time;now_time = time(NULL);struct tm now = *localtime(&now_time);x=now.tm_sec;return x; }voidmanage::strategy1(queue&customque,queue&doctorque,custom&customren,doctor&doctorman,q ueue&checkstick){ string x;static int count1=0;int time1,time2;if(!customque.empty(customque)){ x=customque.gethead1(customque);time1=0;if(customque.gethead2(customque)=='a'||customque.gethead2(customque)=='c') {doctorman.servestick(doctorque,customque);doctorman.srvestickfinish(doctorque,customque);time2=couttime();cout<<"诊断花费"<<time2-time1<<"分钟"<<endl;count1=count1+(time2-time1);}else{doctorman.servestick(doctorque,customque);checkstick.enqueue(checkstick,x,'c');doctorman.srvestickfinish(doctorque,customque);time2=couttime();cout<<"诊断花费"<<time2-time1<<"分钟"<<endl;count1=count1+(time2-time1);}}else{ cout<<"策略一的花费总的时间为"<<count1<<"分钟"<<endl;cout<<"诊室区没有病人等待!"<<endl;}}voidmanage::strategy2(queue&Q1,queue&Q2,queue&doctorque,custom&customren1,doctor&doctor man,queue&checkstick){ string x,num1;char yy; static int count2=0;int time1,time2;if(!Q1.empty(Q1)){ x=Q1.gethead1(Q1);time1=0;if(Q1.gethead2(Q1)=='a'||Q1.gethead2(Q1)=='c'){doctorman.servestick(doctorque,Q1);doctorman.srvestickfinish(doctorque,Q1);time2=couttime();cout<<"诊断花费"<<time2-time1<<"分钟"<<endl;count2=count2+(time2-time1);}else{doctorman.servestick(doctorque,Q1);checkstick.enqueue(checkstick,x,'c');doctorman.srvestickfinish(doctorque,Q1);time2=couttime();cout<<"诊断花费"<<time2-time1<<"分钟"<<endl;count2=count2+(time2-time1);}}else if(!Q2.empty(Q2)){ cout<<"诊室区(Q1)没有病人等待! 请诊侯区(Q2)进入就诊:"<<endl;num1=Q2.gethead1(Q2);yy=Q2.gethead2(Q2);Q1.enqueue1(Q1,num1,yy);Q2.dlqueue(Q2);}else{ cout<<"策略二的花费总的时间为"<<count2<<"分钟"<<endl;cout<<"诊室区(Q1)和诊侯区(Q2)都没有病人等待!"<<endl;}}void manage::doctorcheck (queue&checkstick,queue&customque){ string x;if(!checkstick.empty(checkstick)){x=checkstick.gethead1(checkstick);cout<<x<<"号"<<"检查之中"<<endl;customque.enqueue1(customque,x,'a');Sleep(3000);cout<<x<<"号"<<"检查完成"<<endl;if(!checkstick.empty(checkstick))checkstick.dlqueue(checkstick);}else cout<<"没有病人要进行检查:"<<endl;}void manage::doctorcheck1(queue&checkstick,queue&Q2){ string x;if(!checkstick.empty(checkstick)){x=checkstick.gethead1(checkstick);cout<<x<<"号"<<"检查之中"<<endl;Q2.enqueue1(Q2,x,'a');Sleep(3000);cout<<x<<"号"<<"检查完成"<<endl;if(!checkstick.empty(checkstick))checkstick.dlqueue(checkstick); }else cout<<"没有病人要进行检查:"<<endl;}void main(){system("color A");queue Q1,Q2,customque,doctorque,checkstick,checkstick1;custom customren,customren1;doctor doctorman;manage g;int n;int w=1;checkstick.iniqueue(checkstick);checkstick1.iniqueue(checkstick1);while(w!=8){cout<<" ***********************************************"<<endl;cout<<" ** 基于医院排队分诊系统**"<<endl;cout<<" ** **"<<endl;cout<<" ** **"<<endl;cout<<" ** 1. 进入医生窗口创建**"<<endl;cout<<" ** 2. 进入策略一的病人挂号**"<<endl;cout<<" ** 3. 进入策略一模拟**"<<endl;cout<<" ** 4. 进入策略二的病人挂号**"<<endl;cout<<" ** 5. 进入策略二模拟**"<<endl;cout<<" ** 6. 进入策略一医生检查系统**"<<endl;cout<<" ** 7. 进入策略二医生检查系统**"<<endl;cout<<" ** 8. 退出系统**"<<endl;cout<<" ** **"<<endl;cout<<" ***********************************************"<<endl;cin>>w;switch(w){case 1:{ cout<<"医生窗口的生成:"<<endl;doctorman.proctordoctor(doctorque);Sleep(1000);system("cls");break;} case 2:{ cout<<"请输入要产生的人数:"<<endl;cin>>n;customren.productstick(n);cout<<"病人入队挂号"<<endl;customren.makewaitlist(customque,n);Sleep(1000);system("cls");break;} case 3:{ g.strategy1(customque,doctorque,customren,doctorman,checkstick);Sleep(6000);system("cls"); break;}case 4: { cout<<"请输入要产生的人数:"<<endl;cin>>n;customren.productstick(n);cout<<"病人入队挂号"<<endl;customren1.makewaitlist1(Q1,Q2,n);Sleep(1000);system("cls");break;}case 5:{g.strategy2(Q1,Q2,doctorque,customren1,doctorman,checkstick1);Sleep(8000);system("cls");break;}case 6:g.doctorcheck(checkstick,customque);Sleep(3000);system("cls");break;case 7:g.doctorcheck1(checkstick1,Q2);Sleep(3000);system("cls");break;}}system("cls");}五.程序测试主界面:功能一进入医生窗口创建:功能二进入策略一的病人挂号:功能三进入策略一模拟功能四进入策略二的病人挂号:功能五进入策略二模拟:功能六进入策略一医生检查系统:功能七进入策略一医生检查系统:六.总结通过将近一周的课程设计,感受颇深。