組員:蔡容玉 張丹丹
1 、背景
假設:該大樓有21層,從地面0 , 1 , ... 20 。地板0是地下停車場水平, 1樓是大堂的水平。大多數人都在/走出大樓通過這些2層。
2 、結對開發要求2.1 、每一對學生將設計一套接口和類定義這樣一種算法提供者可以提供他/她實現“電梯調度程序”類。2.2 避免出現 “公共汽車”最壞情況的算法。該算法把電梯作為總線,它從底部到頂部,停在每一層樓,打開門,讓人們進出,然后把門關上,繼續前進。之后到達頂層,它會下去。該算法能夠滿足所有的要求,但它顯然不是最快的算法。2.3 代碼要求:它具有生成0 (零)的代碼分析警告和錯誤。它必須是正確的。它要快。
一,概念設計
1.用戶界面設計
窗口方式:策略號二選一,用戶鍵盤輸入,屏幕輸出電梯運行情況以及未響應的請求,hint信息:用戶輸入指令的方式提示。
2.數據結構設計
2.1常量定義
#define N 3//電梯單層行動時間 #define M 5//電梯停靠樓層時的仿真時間 static int State=1;//電梯初始狀態(0停止 1上升 -1下降 -2空閑) static int size=0;//input數組中的元素個數 static Input input[1001];//記錄用戶的輸入請求 static int output[1001]={0};//儲存每個仿真時刻電梯狀態的數組 static int Time=1;//記錄當前的仿真時間 static Output position[1001];//記錄電梯的運行情況 static int go=0;//go=1表示GO鍵被按下,go=0表示GO鍵未被按下 static int strategy=1;//當前采用的策略號 static int t=0;//t=0表示getinput還不能走 2.2全局數據結構的定義 typedef struct{ int time; char order; int is_done; }Input;//main函數中儲存用戶指令的結構體數組 typedef struct{ int floor;//前一狀態的樓層 int statue;//此時間段內電梯的狀態(=0開門 =1上升 =-1下降 =2關門 =-2空閑) }Output;//main函數中記錄電梯輸出情況的結構體數組
3.函數說明 void getinput(void)//接收輸入 void state_d(void)//確定電梯狀態 void print_s(void)//輸出電梯狀態 void control(void)//確定下一個樓層 void time_control(void)//控制時間 int find(Input *,int,int,int,int [][20],int *)//查找請求序列中的下一個目標樓層 void Order(void)//打印剩余的指令 int newd(int [][20],int,int *,int)//確定新的運行方向 int finish(Input,int,int,int)//消除命令 int trans(char)//轉化為數字樓層 void clear(void);//清屏函數 void locate(int,int)//定位到第y行的第x列 int assist(int,int,int *,Input,int)//順便服務策略 int orders(int,Input,int,int,int *)//先來先服務策略 int ask(char)//判斷是否是重復的指令 void hint(void)//打印用戶輸入指令提示 int legal(char)//判斷輸入是否合法
詳細設計:
一.電梯配置 1. 2至20層每層有上下兩個按鈕,1層只有上行按鈕,20層只有下行按鈕。每層都有相應的指示燈,燈亮表示該按鈕已經被按下,如果該層的上行或者下行請求已經被響應,則指示燈滅。 2. 電梯內共有20個目標按鈕,表示有乘客要在該層下電梯。有指示燈指示按鈕是否被按下。乘客按按鈕導致按鈕指示燈亮,如果電梯已經在該層停靠則該按鈕指示燈滅。 3. 另有一啟動按鈕(GO)。當電梯停在某一樓層后,接受到GO信息就繼續運行。如果得不到GO信息,等待一段時間也自動繼續運行。 4. 電梯內設有方向指示燈表示當前電梯運行方向。 二.電梯運行的控制策略 順便服務策略:順便服務是一種最常見的簡單策略。這種策略在運行控制中所規定的安全前提下,一次將一個方向上的所有呼叫和目標全部完成。然后掉轉運行方向完成另外一個方向上的所有呼叫和目標。可以采用設定目標樓層的辦法來實現這個策略,即電梯向一個目標樓層運行,但這個樓層可以修改。
狀態轉換函數: void state_d()//確定電梯狀態 { position[Time].floor=output[Time]; if(output[Time+1]==output[Time])//下一個時刻和當前時刻的電梯層數相同(不移動) { int flag=0;//等待GO時間 go=0; position[Time].statue=0; while(go==0&&flag<=3)//GO鍵還沒有被按下 { clear(); print_s(); Order(); hint(); Sleep(3000); Time++; output[Time+1]=output[Time]; position[Time].floor=output[Time]; position[Time].statue=0; flag++; } position[Time].statue=2;//內部需求滿足后關上門 go=0; } else if(output[Time+1]==100*output[Time]||State==-2)//電梯處於空間狀態 { State=-2; output[Time+1]=output[Time]; position[Time].statue=-2; } else if(output[Time+1]>output[Time])//電梯要上升 { State=1; position[Time].statue=1; } else//電梯要下降 { State=-1; position[Time].statue=-1; } }
由於限制,只粘貼部分代碼:
int assist(int out[],int time,int *direction,Input in[],int in_size)//順便服務策略:0停止 1上升 -1下降 -2空閑 { int keyinfo[3][20]={0},floor=out[time]-1,d=-2;//存儲鍵盤輸入信息,[1][]內部請求,[2][]外部丄行請求,[0][]外部下行請求,[][n]n+1層,1被選,0未被選 int find(Input *,int,int,int,int[][20],int *); int newd(int[][20],int,int *,int); int finish(Input in[],int direction,int floor,int size); if(!find(in,in_size,time,floor,keyinfo,&d))//空 { *direction=-2; out[time+1]=100*out[time]; return -2;//置電梯於空閑狀態 } else//非空 { newd(keyinfo,floor,&*direction,d); if(keyinfo[1][floor]||(keyinfo[0][floor]&&*direction==-1)||(keyinfo[2][floor]&&*direction==1))//需要停靠 { out[time+1]=out[time];//下一時刻與上一時刻同一位置 keyinfo[1][floor]=0;//將該指令標記為"已執行" if(*direction==-2) keyinfo[0][floor]=keyinfo[2][floor]=0; else keyinfo[1+*direction][floor]=0; finish(in,*direction,floor,in_size); return 0;//0指需要暫停 } else//不需要停靠,電梯將要移動 { if(*direction==-2)//停一會兒 *direction=d;//新方向為最先指令所在方向(若無指令則不改變) if(*direction==-2) { out[time+1]=out[time];//下一時刻與上一時刻同一位置 return *direction;//不移動返回-2 } else//將要移動 { out[time+1]=out[time]+*direction; return *direction; }//向當前運行方向移動一層 } } }
int find(Input *in,int size,int curTime,int floor,int keyinfo[][20],int *d)//查找請求序列中的下一個目標樓層 { int i,j,empty=0;//0指空 for(i=1;i<=size;i++) if(!in[i].is_done&&in[i].time<=curTime) { int is_finished=0,ifFirst=1;//0指未完成指令,1指完成指令 for(j=0;j<27;j++) if(xiaoxie[j]==in[i].order) { if(!(j%20==floor&&curTime-1==in[i].time)) { keyinfo[j/20][j%20]=1; is_finished=1; empty=1; } if(ifFirst) if(j%20>floor) { *d=1; ifFirst=0; } else if(j%20<floor) { *d=-1; ifFirst=0; } break; } if(!is_finished) for(j=0;j<27;j++) if(daxie[j]==in[i].order) { if(!(j%20==floor&&curTime-1==in[i].time)) { keyinfo[j/20][j%20]=1; empty=1; } if(ifFirst) if(j%20>floor) { *d=1; ifFirst=0; } else if(j%20<floor) { *d=-1; ifFirst=0; } break; } } return empty; }
運行結果:
以上!謝謝!