电梯调度有很多种模式,参见http://www.cnblogs.com/jianyungsun/archive/2011/03/16/1986439.html
先来先服务(FCFS-First Come First Serve)算法,是一种随即服务算法,它不仅仅没有对寻找楼层进行优化,也没有实时性的特征,它是一种最简单的电梯调度算法。它根据乘客请求乘坐电梯的先后次序进行调度。此算法的优点是公平、简单,且每个乘客的请求都能依次地得到处理,不会出现某一乘客的请求长期得不到满足的情况[12]。这种方法在载荷较轻松的环境下,性能尚可接受,但是在载荷较大的情况下,这种算法的性能就会严重下降,甚至恶化。人们之所以研究这种在载荷较大的情况下几乎不可用的算法,有两个原因:
(1)任何调度算法在请求队列长度为1时,请求速率极低或相邻请求的间隔为无穷大时使用先来先服务算法既对调度效率不会产生影响,而且实现这种算法极其简单。
(2)先来先服务算法可以作为衡量其他算法的标准。
1.2最短寻找楼层时间优先算法(SSTF)
最短寻找楼层时间优先(SSTF-Shortest Seek Time First) [14]算法,它注重电梯寻找楼层的优化。最短寻找楼层时间优先算法选择下一个服务对象的原则是最短寻找楼层的时间。这样请求队列中距当前能够最先到达的楼层的请求信号就是下一个服务对象。在重载荷的情况下,最短寻找楼层时间优先算法的平均响应时间较短,但响应时间的方差较大,原因是队列中的某些请求可能长时间得不到响应,出现所谓的“饿死”现象。
扫描算法(SCAN)是一种按照楼层顺序依次服务请求,它让电梯在最底层和最顶层之间连续往返运行,在运行过程中响应处在于电梯运行方向相同的各楼层上的请求。它进行寻找楼层的优化,效率比较高,但它是一个非实时算法。扫描算法较好地解决了电梯移动的问题,在这个算法中,每个电梯响应乘客请求使乘客获得服务的次序是由其发出请求的乘客的位置与当前电梯位置之间的距离来决定的,所有的与电梯运行方向相同的乘客的请求在一次电向上运行或向下运行的过程中完成,免去了电梯频繁的来回移动[2]。
扫描算法的平均响应时间比最短寻找楼层时间优先算法长,但是响应时间方差比最短寻找楼层时间优先算法小,从统计学角度来讲,扫描算法要比最短寻找楼层时间优先算法稳定。
1.4 LOOK 算法
LOOK算法[18]是扫描算法的一种改进。对LOOK算法而言,电梯同样在最底层和最顶层之间运行。但当LOOK算法发现电梯所移动的方向上不再有请求时立即改变运行方向,而扫描算法则需要移动到最底层或者最顶层时才改变运行方向。
SATF(Shortest Access Time First)[15,19]算法与SSTF算法的思想类似,唯一的区别就是SATF算法将SSTF算法中的寻找楼层时间改成了访问时间。这是因为电梯技术发展到今天,寻找楼层的时间已经有了很大地改进,但是电梯的运行当中等待乘客上梯时间却不是人为可以控制。SATF算法考虑到了电梯运行过程中乘客上梯时间的影响。
上面是常见的电梯调度模式,这里我们写的是第二种模式,这是一个简化的版本。
运行原理:电梯会将目前所有的请求中最高的楼层请求查出来,通过与电梯所在楼层进行对比,确定电梯的运行方向,是向上运行(方法getRequest1)或者是向下运行(方法getRequest),同时每到一层都会执行下面的操作:
1.这层是否有人请求,如果有,那么要求设置目的层。
2.确定这层是某个请求的目的层,如果是,就将相应的请求归零。
缺陷:将请求单纯简化为层数,其实实际中还会出现请求的方向,这个下次再解决,还有其他的一些。
代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 电梯调度算法 { struct elevatorRequest { public int start; public int end; public int rFlag; } class elevator { public static int count = 0; public static int now = 0; elevatorRequest[] sRequest = new elevatorRequest[12]; public static int runNow = 0; public void run() { while (count > 0) { getRequest(); getRequest1(); } } public void setDirect() { int max = 0; int ns = count; if (ns != 0) { max = sRequest[0].start; int i = 0; while (ns > 0) { if (max < sRequest[i].end || max < sRequest[i].start) { max = sRequest[i].end > sRequest[i].start ? sRequest[i].end : sRequest[i].start; } } if(max>runNow) { getRequest(); } else { getRequest1(); } } } public void getRequest1() { if (count > 0) { Console.WriteLine("电梯开始方向运行"); for (int i = 11; i >= 0; i--) { Console.WriteLine("-----" + i + "----"); int j = isEnd(i); if (j != 0) { Console.WriteLine("完成了从" + sRequest[j].start + "层到" + sRequest[j].end + "的请求"); runNow = i; count--; sRequest[j].start = 0; sRequest[j].end = 0; } } if (count == 0) { Console.WriteLine("请求执行完毕,电梯停止运行"); Console.WriteLine("电梯停留在" + runNow + "层"); } } else { Console.WriteLine("请求执行完毕,电梯停止运行"); Console.WriteLine("电梯停留在" + runNow + "层"); } } public void getRequest() { if (count > 0) { //int next = getNextFloor(); for (int i = 0; i < 12; i++) { Console.WriteLine("-----" + i + "----"); if (sRequest[i].start != 0) { Console.WriteLine("响应了" + i + "层的请求"); Console.WriteLine("请输入要去的楼层"); int e; string str = Console.ReadLine(); e = Convert.ToInt32(str); setRequest(i, e); } int j = isEnd(i); if (j != 0) { Console.WriteLine("完成了从" + sRequest[j].start + "层到" + sRequest[j].end + "的请求"); runNow = i; count--; sRequest[j].start = 0; sRequest[j].end = 0; } } if (count == 0) { Console.WriteLine("请求执行完毕,电梯停止运行"); Console.WriteLine("电梯停留在" + runNow + "层"); } } else { Console.WriteLine("请求执行完毕,电梯停止运行"); Console.WriteLine("电梯停留在" + runNow + "层"); } } public int isEnd(int i) { for (int j = 0; j < 12; j++) { if (i == sRequest[j].end) { return j; } } return 0; } public int getNextFloor() { int min = sRequest[0].start - runNow > 0 ? (sRequest[0].start - runNow) : (runNow - sRequest[0].start); for (int i = 0; i < now; i++) { if (min > sRequest[i].start - runNow) { min = sRequest[i].start - runNow; } } return min + runNow; } public void setRequest(int i, int e) { sRequest[i].end = e; if (i > e) { sRequest[i].rFlag = 0; } else { sRequest[i].rFlag = 1; } } public void setRequest(int s) { count++; sRequest[s].start = s; } public void show() { for (int i = 0; i < 12; i++) { if (sRequest[i].end != 0) { string s = ""; if (sRequest[i].rFlag > 0) { s = "上"; } else { s = "下"; } Console.WriteLine("我要从" + sRequest[i].start + "层到" + sRequest[i].end + "层,方向向" + s); } } } } class Program { static void Main(string[] args) { elevator es = new elevator(); es.setRequest(1); es.setRequest(10); es.setRequest(7); es.run(); es.show(); es.setRequest(9); es.setRequest(4); es.run(); Console.ReadKey(); } } }
运行结果: