一、背景: (结对成员:杨世超和李夏蕾)
电梯名称 |
停靠层数 |
乘客限制 |
重量限制 |
1 |
所有楼层 |
10 |
800 kg |
2 |
所有楼层 |
10 |
800 kg |
3 |
所有楼层 |
20 |
1600 kg |
4 |
所有楼层 |
20 |
2000 kg |
二、结对开发要求
每一对学生将设计一套接口和类定义这样一种算法提供者可以提供他/她实现“电梯调度程序”类。避免出现 “公共汽车”最坏情况的算法。该算法把电梯作为总线,它从底部到顶部,停在每一层楼,打开门,让人们进出,然后把门关上,继续前进。之后到达顶层,它会下去。该算法能够满足所有的要求,但它显然不是最快的算法。
三、评分指南
评估所有乘客的“平均总旅行时间”在同一个测试用例,越低越好。如果你的表现低于“总线”的解决方案,你得到0分;如果您的程序不能提供任何乘客到正确的目的地,你得到0分。
一个关于电梯调度提示:当总重量在45公斤的最小限制,或乘客的数量已经在最大,电梯不需要更多的外部请求停止。电梯调度程序不知道有多少乘客等待每层,它不知道有多少乘客将出现。这与现实世界的情况是一样的。
四、需求分析
1. 客户(上楼、下楼)信息的输入
用户将其将要上楼、下楼的信息输入,系统按要求做即能够将该请求输入,并分享到各层。
2. 当前电梯的状态显示。
3. 客户要求信息的存储,以便于电梯的运作。
4. 电梯的限重报警。
五、设计思路
1.首先检查是否有完成的任务,如果有,就从该电梯任务列表中去掉这个已经完成的任务。
2.然后检查电梯是否还有未完成的任务:
(1)如果有,就去完成,秉承的规则是如果电梯之前是在向上走,那就完成任务列表最开头的任务,如果电梯向下走就完成任务列表最末尾的任务(任务列表中的任务按照任务的楼层从高到低排序)
3. 当电梯在运行时,我们希望电梯所接客人的位置,能够和电梯运行方向相同,那么电梯就可以停靠在客人所在的位置,这样可以从整体上提高电梯的运行效率。
4.如果该电梯的任务列表中所有任务都完成。检查一下所有的乘客请求:
(1)如果当前所有的乘客请求为0个,那么电梯不动。
(2)如果有请求,那么按照以下优先级顺序来选择加入新的任务
若乘客的目标位置与电梯的运行方向相同,则首先响应。若相反,则需要等待响应。在响应之前,要判断一下电梯的载重,如果电梯已不能够再承载70kg(平均体重)就忽略这个任务,若进入电梯的人数超过了限重,则电梯会发出报警信号。
5.一号到四号电梯分别负责0-5层,6-10层,11-15层,16-20层。各个电梯内部,只涉及停靠的楼层按钮并且能显示电梯所在的楼层数。当没有任务时他们分别停在3层,8层,13层,18层。
6.电梯外部只设置向上,向下按钮,和显示电梯到达的楼层功能(最底层只有向上按钮,最高层只有向下按钮),当按了向上或向下按钮,电梯到达此楼层后会停止,门自动打开。
六、工作安排
2014-3-9我们一起到学校春晖楼实地考察电梯的运转情况,考察完之后,我们就在自习室开始设计电梯调度算法。我们在网上也寻找了一些关于电梯设计的资料。最终设计出了上述电梯调度算法。
2014-3-11今天我正好到省二院去看望亲戚,借这个机会正好测试了一下电梯的性能。电梯关门或者开门的时间大约为4s,根据进出电梯的人数不同,电梯从开关门到开始启动的时间也不同,大概就是20s。在电梯从初始位置一直到目的位置中途不停的话,电梯上下一层楼大概需要5s.
经过几天的奋斗,电梯终于能运转了,我和李夏蕾分工如下:3-13我负责查阅调度算法,李夏蕾负责界面设计;3-15我们实现了单个电梯的上下移动;3-16我们共同用多线程控制4个电梯。
我们的设计目的就是综合调度4个电梯,核心思想是响应的层数与4个电梯所在层数进行比较,从而得出用哪一个电梯最合适。
核心算法:
private void diaodu(int[] a)//判断用哪一个电梯 { int i, j, x, y, q = 1, L, sub, small; int[] d=new int[5]; for (i = 0; i < f - 1; i++) //排序 { for (j = 0; j < f - 1 - i; j++) { if (a[j] > a[j + 1]) { x = a[j]; a[j] = a[j + 1]; a[j + 1] = x; } } } y = this.label1.Location.Y; Console.WriteLine("第一层"); for (j = 0; j < 21; j++) { if (((y - b[j]) < 5&&(y - b[j])>=0) || ((y - b[j]) > -5&&(y - b[j])<0) ) { d[1] = j; break; } } y = this.label3.Location.Y; Console.WriteLine(y); for (j = 0; j < 21; j++) { if (((y - b[j]) < 5 && (y - b[j]) >=0) || ((y - b[j]) > -5 && (y - b[j]) < 0)) { d[2] = j; break; } } y = this.label4.Location.Y; for (j = 0; j < 21; j++) { if (((y - b[j]) < 5 && (y - b[j]) >= 0) || ((y - b[j]) > -5 && (y - b[j]) < 0)) { d[3] = j; break; } } y = this.label5.Location.Y; // Console.WriteLine(y); for (j = 0; j < 21; j++) { if (((y - b[j]) < 5 && (y - b[j]) >= 0) || ((y - b[j]) > -5 && (y - b[j]) < 0)) { d[4]= j; break; } } //选择最佳电梯. flag =d[1]; L = 1; if (d[1] - a[0] >=0) { small = d[1] - a[0]; } else { small = a[0] - d[1]; } for (i = 1; i < 5; i++) { if (d[i] - a[0] >=0) { sub = d[i] - a[0]; } else {sub= a[0] - d[i]; } if (small >sub) { small = sub; flag = d[i]; L = i; } } if (L==1) { dianti1 = flag;//电梯所在层。 th1 = a[0]; if (th1 >= dianti1) { k1 = th1 - dianti1; } else { k1 = dianti1 - th1; } this.timer1.Interval = 500; this.timer1.Enabled = true; } if (L == 2) { dianti2 = flag; th2 = a[0]; if (th2 >= dianti2) { k2 = th2 - dianti2; } else { k2 = dianti2 - th2; } this.timer2.Interval = 500; this.timer2.Enabled = true; } if (L == 3) { dianti3 = flag; th3 = a[0]; if (th3>= dianti3) { k3 = th3 - dianti3; } else { k3 = dianti3 - th3; } this.timer3.Interval = 500; this.timer3.Enabled = true; } if (L == 4) { dianti4 = flag; th4 = a[0]; if (th4 >= dianti4) { k4 = th4 - dianti4; } else { k4 = dianti4 - th4; } this.timer4.Interval = 500; this.timer4.Enabled = true; } } public void start1()//电梯1 { int step = 21; if ((th1 - dianti1) > 0) { this.label1.Location = new Point(this.label1.Location.X, this.label1.Location.Y - step); k1--; if(k1==0) { this.timer1.Enabled =false; } } else { this.label1.Location = new Point(this.label1.Location.X, this.label1.Location.Y + step); k1--; if (k1 == 0) { this.timer1.Enabled = false; } } } public void start2()//电梯2 { int step = 21; if ((th2 - dianti2) > 0) { this.label3.Location = new Point(this.label3.Location.X, this.label3.Location.Y - step); k2--; if (k2 == 0) { this.timer2.Enabled = false; } } else { this.label3.Location = new Point(this.label3.Location.X, this.label3.Location.Y + step); k2--; if (k2 == 0) { this.timer2.Enabled = false; } } } public void start3()//电梯3 { int step = 21; if ((th3 - dianti3) > 0) { this.label4.Location = new Point(this.label4.Location.X, this.label4.Location.Y - step); k3--; if (k3 == 0) { this.timer3.Enabled = false; } } else { this.label4.Location = new Point(this.label4.Location.X, this.label4.Location.Y + step); k3--; if (k3 == 0) { this.timer3.Enabled = false; } } } public void start4()//电梯4 { int step = 21; if ((th4 - dianti4) > 0) { this.label5.Location = new Point(this.label5.Location.X, this.label5.Location.Y - step); k4--; if (k4 == 0) { this.timer4.Enabled = false; } } else { this.label5.Location = new Point(this.label5.Location.X, this.label5.Location.Y + step); k4--; if (k4 == 0) { this.timer4.Enabled = false; } } }