自己动手C#模拟电梯的运行V1.0

电梯调度有很多种模式,参见http://www.cnblogs.com/jianyungsun/archive/2011/03/16/1986439.html

1.1先来先服务算法(FCFS)

先来先服务(FCFS-First Come First Serve)算法,是一种随即服务算法,它不仅仅没有对寻找楼层进行优化,也没有实时性的特征,它是一种最简单的电梯调度算法。它根据乘客请求乘坐电梯的先后次序进行调度。此算法的优点是公平、简单,且每个乘客的请求都能依次地得到处理,不会出现某一乘客的请求长期得不到满足的情况[12]。这种方法在载荷较轻松的环境下,性能尚可接受,但是在载荷较大的情况下,这种算法的性能就会严重下降,甚至恶化。人们之所以研究这种在载荷较大的情况下几乎不可用的算法,有两个原因:

(1)任何调度算法在请求队列长度为1时,请求速率极低或相邻请求的间隔为无穷大时使用先来先服务算法既对调度效率不会产生影响,而且实现这种算法极其简单。

(2)先来先服务算法可以作为衡量其他算法的标准。

1.2最短寻找楼层时间优先算法(SSTF)

最短寻找楼层时间优先(SSTF-Shortest Seek Time First) [14]算法,它注重电梯寻找楼层的优化。最短寻找楼层时间优先算法选择下一个服务对象的原则是最短寻找楼层的时间。这样请求队列中距当前能够最先到达的楼层的请求信号就是下一个服务对象。在重载荷的情况下,最短寻找楼层时间优先算法的平均响应时间较短,但响应时间的方差较大,原因是队列中的某些请求可能长时间得不到响应,出现所谓的“饿死”现象。

1.3扫描算法(SCAN)

扫描算法(SCAN)是一种按照楼层顺序依次服务请求,它让电梯在最底层和最顶层之间连续往返运行,在运行过程中响应处在于电梯运行方向相同的各楼层上的请求。它进行寻找楼层的优化,效率比较高,但它是一个非实时算法。扫描算法较好地解决了电梯移动的问题,在这个算法中,每个电梯响应乘客请求使乘客获得服务的次序是由其发出请求的乘客的位置与当前电梯位置之间的距离来决定的,所有的与电梯运行方向相同的乘客的请求在一次电向上运行或向下运行的过程中完成,免去了电梯频繁的来回移动[2]。

扫描算法的平均响应时间比最短寻找楼层时间优先算法长,但是响应时间方差比最短寻找楼层时间优先算法小,从统计学角度来讲,扫描算法要比最短寻找楼层时间优先算法稳定。

1.4 LOOK 算法

LOOK算法[18]是扫描算法的一种改进。对LOOK算法而言,电梯同样在最底层和最顶层之间运行。但当LOOK算法发现电梯所移动的方向上不再有请求时立即改变运行方向,而扫描算法则需要移动到最底层或者最顶层时才改变运行方向。

1.5 SAFT 算法

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();
        }
    }
}

运行结果:

时间: 2024-12-14 13:21:39

自己动手C#模拟电梯的运行V1.0的相关文章

自己动手写计算器v1.0

今天突发奇想,想着看了还几个设计模式了,倒不如写点东西来实践它们.发现计算器这种就比较合适,打算随着设计模式的学习,会对计算器不断的做改进. 包括功能的增加和算法的改进.初学者难免犯错,希望大家不吝指教. 计算器V1.0:主要实现了计算器最常见的加减乘除功能,同时还有一个特殊功能,例如:我们执行完1+2后,如果点击等号,会执行加法运算输出结果.但我们如果点击的是运算符(如-),那么不仅会执行加法运算,还会将-号放置到执行结果后,表示这次执行的将会是减法运算. 代码:Operator类负责使用简单

Servlet+AJAX实现的模拟电梯调度

需求产生: 大三下学期天天在学校的同一栋教学楼上课,每天要等四次电梯,有次等电梯无聊了,就想到电梯的运行逻辑该如何用程序来表达呢? 问题描述: 大学的那栋楼有21层,不过在页面中画21层有点密,所以只画了9层: 同时有三座电梯等待调度: 按钮分为楼层按钮和电梯内按钮,电梯内按钮有楼层数字和关门按钮: 运行的要求: 1.电梯空闲时,电梯内按钮被点击,对应按钮被点亮,需要按关门键自动运行到最近的楼层: 2.电梯正在运行过程中,电梯内按钮被点击,如果离电梯更近,需要自动更改电梯目的停靠楼层为新添加的请

主流区块链技术特点及Fabric V0.6&V1.0版本特点

声明:文章内容来源于网络. 一.主流区块链技术特点 二.Hyperledger的fabric V0.6总体架构: 对应的0.6版本的运行时架构: 0.6版本的架构特点是: 结构简单: 应用-成员管理-Peer的三角形关系,主要业务功能全部集中于Peer节点:    架构问题:由于peer节点承担了太多的功能,所以带来扩展性.可维护性.安全性.业务隔离等方面的诸多问题,所以0.6版本在推出后,并没有大规模被行业使用,只是在一些零星的案例中进行业务验证: 三.Hyperledger的fabric V

003-主流区块链技术特点及Hyperledger的fabric V1.0

一.最新的1.0运行时架构: 1.0 架构要点: 分拆Peer的功能,将Blockchain的数据维护和共识服务进行分离,共识服务从Peer节点中完全分离出来,独立为Orderer节点提供共识服务: 基于新的架构,实现多通道(channel)的结构,实现了更为灵活的业务适应性(业务隔离.安全性等方面) 支持更强的配置功能和策略管理功能,进一步增强系统的灵活性和适应性: 1.0版本架构目标: 1.chaincode信任的灵活性:支持多个ordering服务节点,增强共识的容错能力和对抗ordere

接口性能测试方案 白皮书 V1.0

一. 性能测试术语解释 1. 响应时间 响应时间即从应用系统发出请求开始,到客户端接收到最后一个字节数据为止所消耗的时间.响应时间按软件的特点再可以细分,如对于一个 C/S 软件的响应时间可以细分为网络传输时间.应用服务器处理时间.数据库服务器处理时间.另外客户端自身也存在着解析时间.界面绘制呈现时间等. 响应时间主要站在客户端角度来看的一个性能指标,它是用户最关心.并且容易感知到的一个性能指标. 2. 吞吐率 吞吐率指单位时间内系统处理用户的请求数,从业务角度看,吞吐率可以用每秒请求数.每秒事

最新:百度春节抢百万游戏--汤圆向前冲--辅助工具v1.0.0.2

https://www.cnblogs.com/Charltsing/p/ADBJumpTY.html 联系QQ:564955427 汤圆向前冲辅助工具 因为手残,用以前微信跳一跳的辅助工具改了一下,手工跳. 1.如果是xp sp3或者windows7 sp1,请百度下载安装.net 4.0或更高版本 2.本程序自带ADB,无需自行安装.想自己下载的用下面的链接,下载之后将ADB相关的三个文件放到本程序同一目录下 adb工具包最新2017Google官方版下载https://dl.google.

Windows环境下Android Studio v1.0安装教程

Windows环境下Android Studio v1.0安装教程 Windows环境下Android Studio v1.0安装教程 准备工具 JDK安装包. 要求:JDK 7以及以上版本. Android Studio安装文件. Windows: exe(包含SDK) (813 MB) exe(不包含SDK) (250 MB) zip (235 MB) Mac dmg (234 MB) zip (233 MB) Linux: zip (233 MB) 说明: 32位系统和64位系统是同一个安

【转】Windows环境下Android Studio v1.0安装教程

原文网址:http://ask.android-studio.org/?/article/9 http://android-studio.org/index.php/docs/experience/158-androidstudio-v1-0-win-install Windows环境下Android Studio v1.0安装教程 准备工具 JDK安装包.要求:JDK 7以及以上版本. Android Studio安装文件. Windows:exe(包含SDK) (813 MB)exe(不包含

效率飞速提高Four Dimension Technologies GeoTools v17.0 1CD+AutoHook.2017.v1.0.3.00 1CD

效率飞速提高Four Dimension Technologies GeoTools v17.0 1CD+AutoHook.2017.v1.0.3.00 1CD GeoTools v12.18 1CD     GeoTools写的是测绘.GIS用户心中最初但现在有这个程序它是有用的,只是任何AutoCAD用户相关的足够的命令.GeoTools现在是几乎所有的AutoCAD用户有用.它解决了很多常见的问题和地图生产的要求和编辑AutoCAD是地理数据的一个非常方便的工具捕获(GIS底图).处理.转