zoukankan      html  css  js  c++  java
  • 多路电梯调度算法(二)

    输入:乘客请求事件,所有电梯状态

    输出:电梯命令

    其中,

    电梯状态

    电梯命令

    乘客请求事件

    最高层数

    添加电梯停时响应事件

    X楼上行请求

    剩余负载

    取消电梯停时响应事件

    X楼下行请求

    运行方向(上、下、静止)

    E电梯内有乘客请求去Y楼

    能否到达X楼

    开往X楼

     

    开往(静止时:上、下)

    设置开往方向(上、下)

     

    算法思想

    一、统计每层楼的“剩余负载”变化情况

    如果0、1层“剩余负载”的平均增量大于其它楼层,则是下班

    如果0、1层“剩余负载”的平均增量小于其它楼层,则是上班

    二、流程:

    a. 电梯按环形路线运行,向上至顶,再向下至底,再向上至顶,。。。

    b. 电梯停时,按a从近向远扫描,如果在某一站,有必要停的话(参考c,d),就开往那一站。

    c. 如果有乘客请求在E电梯的X层停,则标志E电梯需要在X层停。

    d. 如果有乘客请求上/下行,

           下班时,标志一个电梯需要在那停。

           上班时,标志所有电梯都需在那停。

    e. 如果c、d发生,执行b

    算法很简单,但模式识别思想很赞。

    算法很粗糙,可以有很多优化。比如,

    上班时,环形路线并不是最佳的,我们已经证明内线、外线的模式更佳。即是说,适当的时候可以拒绝去高层的请求。

    下班时,如何选择电梯 来响应乘客上/下行的请求。我们的方案很粗糙: 电梯ID==楼层*电梯总数/(楼层高度+1)。 更精细的方案是考虑电梯的“剩余负载”,或者更精细地根据楼层远近绑定电梯和楼层。

    但因为时间关系没有实现他们。有兴趣的读者可以尝试。

    相关工作

    按钮

    为了过滤重复请求,我们引入了“Button”(这更应该在电梯中实现)

    IButton
    -Press(ID)
    -UnPress(ID)
    -IsPressed(ID)
    -NotPressed(ID)

    每个电梯有个Button,记录需要停的楼层

    四个电梯共享一个Button,记录上行、下行的情况。

    最佳算法

    在没有新的外部请求的情况下,我们找得到了最佳调度算法

    (动态规划法)

    目标:让电梯里的人为零

    转移:电梯在任何状态下,只有两种选择,上行一层,或下行一层。这两个新的状态是当前状态的子问题。新状态下,电梯里的人可能减少。

    合并:如果当前在同一个楼层,并且电梯递里的乘客一样,则可以合并状态,取离开乘客平均等待时间最少的那个状态。

    可以证明,每一层,只有N种状态,于是,总共只有N*N种状态。算法有效

    但是电梯外部请求是不确定的,所以不存在最佳调度算法。于是,我们转向模式识别。

    模式识别

    实际上,电梯的外部请求有两种极端情况,

    上班时,大量乘客从一楼和地下一层进电梯

    下班时,大量乘客从一楼或地下一层出电梯

    这两种情况下最佳调度方式不太可能一样,所以上/下班的信息对调度会有很大帮助

    我们可以从 每一层的“剩余负载”变化,即每一层多少重量的人进出, 提取出上/下班信息。

    “剩余负载”更新是离散的,而且有毛刺。为了让上/下班信息稳定,我们增加了移动平均滤波器。

    移动平均滤器如此有用,以至于我一定要把代码贴出来。

    RateMeasurer
    1 public class RateMeasurer
    2 {
    3 private float[] m_Samples = null;
    4 private int m_LastUpdated = -1;
    5
    6 public RateMeasurer(int n_samples = 4)
    7 {
    8 m_Samples = new float[n_samples];
    9 for (int i = 0; i < n_samples; i++)
    10 m_Samples[i] = 0;
    11 }
    12
    13 public void Update(float rate)
    14 {
    15 if (m_LastUpdated < 0)
    16 {
    17 m_LastUpdated = 0;
    18 }
    19 m_Samples[m_LastUpdated] = rate;
    20 m_LastUpdated = (m_LastUpdated + 1) % m_Samples.Length;
    21 }
    22
    23 public float GetAverageRate()
    24 {
    25 float avg = 0.0F;
    26 int pos = 0;
    27 for (int i = 0; i < m_Samples.Length; i++)
    28 {
    29 avg += m_Samples[i];
    30 pos++;
    31 }
    32 if (pos > 0)
    33 return avg / pos;
    34 else
    35 return 0;
    36 }
    37
    38 }
    39  

    如果一楼和地下一层进的人很多,无疑是上班模式;

    如果一楼和地下一层出的人很多,无疑是下班模式。

    测试框架

    电梯系统还包括 电梯、乘客和楼。这部分工作由Sen Xiang完成。简单介绍下

    楼是顶层对象,包括一些电梯、一个调度器和一个计时器。

    初始化后,计时器开始计时,

    乘客:

    如果时间和乘客到达时间一致,乘客状态变为等待,并发送上/下行请求。

    如果电梯停在乘客所在楼层,并且开往方向与乘客的去向一致,则乘客进入电梯,乘客状态变为正在电梯中,并发送目的地请求。

    如果乘客所乘电梯停在目的,乘客状态变为到达。

    电梯:

    根据高度器的命令运行,并更新状态。

    电梯停时,发送电梯停信号。

    楼:

    只需要要提供楼层高度的信息。

    22032010(001)

    MicroTeam Hui

    CodingCrazy Hao

  • 相关阅读:
    Bluedroid介绍
    Android蓝牙介绍
    Android Bluetooth抓包
    Bluetooth LMP介绍
    Bluetooth Baseband介绍
    Bluetooth SDP介绍
    Bluetooth HFP介绍
    Bluetooth RFCOMM介绍
    Bluetooth L2CAP介绍
    Windows开发
  • 原文地址:https://www.cnblogs.com/MicroTeam/p/1904093.html
Copyright © 2011-2022 走看看