[OO] 第二单元 电梯优化策略

电梯优化策略

架构

UML类图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rjTJwMdU-1586954031048)(F:\JACQUES\Academic\Courses\OO\研讨课\20200415\new_structure_UML.png)

  • 采用架构为三类线程分配器与控制器分离

请求处理流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mIxMm7eM-1586954031051)(F:\JACQUES\Academic\Courses\OO\研讨课\20200415\pipeline_process.png)]

优化策略

强测结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1gFiAlgC-1586954031054)(F:\JACQUES\Academic\Courses\OO\研讨课\20200415\result_strong.png)]

请求拆分策略

策略概述

  • 拆分与分配独立,无需在拆分时考虑电梯的实时状态

  • 使用静态Floyed预处理求最短路

  • 无向图中边的定义为:

    F i F j R ( F i , F j ) g ( F i , F j ) = F i F j \forall F_i \forall F_j \quad R(F_i, F_j)\leadsto g(F_i,F_j)=|F_i-F_j|

    F i F j ! R ( F i , F j ) g ( F i , F j ) = I N F \forall F_i \forall F_j \quad !R(F_i, F_j) \leadsto g(F_i,F_j)=INF

    其中 R R 为三类电梯总的可达性矩阵,且 R ( F i , F j ) = R A ( F i , F j ) R B ( F i , F j ) R C ( F i , F j ) R(F_i,F_j)=R_A(F_i,F_j)|R_B(F_i,F_j)|R_C(F_i,F_j)

  • 换乘的花费定义

    d p ( F i , F j ) d p ( F i , F k ) + g ( F k , F j ) + 1 dp(F_i, F_j) \sim dp(F_i, F_k)+g(F_k, F_j)+1

    即定义换乘花费为 1 1

  • 以不同电梯花费相关的值作为边权不同,主要考虑点在于拆分器分配器的行为匹配

    如果拆分器认为应该把任务MA电梯处理,但分配器进行分配时发现A电梯已经满载距离起始楼层太远,而将任务M分配给了另外的电梯,这样反而相对最好的情况相差太大

    上述定义的拆分策略不是最优,但相对来说平均性能较好

  • 静态在于针对A,B,C三类电梯建图,新增电梯不需要修改

实现细节

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RR7jIpgc-1586954031059)(F:\JACQUES\Academic\Courses\OO\研讨课\20200415\Floyed.png)]

  • 中间点k的循环一定要在最外层!

  • 否则dist(i,j)的确定不会因为更多的路径更新而更新,即以i->j->k的顺序枚举时,最后一次更新dist(i,j)后的值不是最优

  • 通过trace跟踪当前dist(i,j)最短路上的上一个节点来获取路径,即拆分后的任务,简洁一点可以用递归

  • 存储数据结构采用单链表,构建HashMappersonID作为key,每个人一个单链表,任务节点定义如下

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KXajchld-1586954031062)(F:\JACQUES\Academic\Courses\OO\研讨课\20200415\mission_def_list.png)]

  • 查找较为方便高效

控制器策略

策略概述

  • 注意到对于每一个电梯的每个时刻可能的决策空间只有向上向下两种,这对枚举策略很友好

  • 借鉴启发式搜索中的估价函数贪心地选取估价函数中最优的策略

  • 最重要的是如何选取估价函数h*(state),需要保证估价函数与真实情况十分相近,其中最优的真实情况h(state)是估价函数的下界,即 h ( s t a t e ) h ( s t a t e ) h(state)\le h^*(state)

  • h(state)无法通过较短时间获取,需要暴力搜索不可取

  • 估价函数 h ( s t a t e ) h^*(state) 一种可能的定义为

    当前状态的电梯使用LOOK策略到电梯运行结束还需要的耗时(针对第一次作业)

实现细节

  • 定义模拟器类,调用Simulator.simulate(…)根据当前状态获得LOOK运行至结束的花费,作为估价函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bfCZzODJ-1586954031064)(F:\JACQUES\Academic\Courses\OO\研讨课\20200415\simulator.png)]

  • 需要注意模拟器的修改需要clone一下,避免对原电梯状态进行改变

分配器策略

策略概述

  • 对于多个电梯,控制器仅仅解决了单个电梯给定任务集后的最佳调度

  • 同样采取枚举策略,尝试将当前待分配任务分别加入到每个电梯进行枚举,将所有电梯运行时间的最大值作为估计函数(针对第二次作业),即

    h ( s t a t e ) = m a x ( r u n t i m e C o s t ( E i ) ) h^*(state) = max(runtimeCost(E_i))

    其中, E i E_i 定义为按照state规定的加入当前任务后的电梯

  • 最后将 a r g m i n ( h ( s t a t e ) ) argmin(h^*(state)) 作为最终决策应用到实际电梯中进行分配

  • 对于第三次作业的评价指标加入了等待时间之和,只需要按照指导书性能值的配比修改估价函数的计算方式就行了,其他不需要改变

  • 由于 s t a g e ( T 1 + T 2 ) s t a g e T 1 + s t a g e T 2 \sum_{stage}(T_1+T_2)\ne \sum_{stage}T_1+\sum_{stage}T_2 ,所以估价函数应在最终决策时确定,模拟器返回一个runtimeCostwaitingCost的Pair

    h ( s t a t e ) = m a x ( r u n t i m e C o s t E i ) + w a i t i n g C o s t E i h^*(state)=max(runtimeCost_{E_i})+\sum waitingCost_{E_i}

实现细节

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EJ5ySqyK-1586954031065)(F:\JACQUES\Academic\Courses\OO\研讨课\20200415\decision_making.png)]

  • 其中初始值的设定使用了INT_MAX是为了防止使用LONG_MAX进行加法的意外溢出

其他优化

  • 拆分后的任务如果第一阶段已经完成了才通知分配第二阶段,会造成电梯等待的浪费,即电梯等待楼层与接客楼层太远
  • 分配第一阶段任务后,新增一个操作,选一个电梯的等待楼层设置为第二阶段的起始位置
  • 循环链表管理当前分配到哪个电梯,继续寻找下一题个Waiting状态的电梯进行等待楼层设置
  • 如果遍历一圈了都没空,就设置当前这个电梯等待楼层为第二阶段起点
  • 平均下来等待楼层能够较为分散,且每个电梯任务量较平均
原创文章 152 获赞 15 访问量 6万+

猜你喜欢

转载自blog.csdn.net/ourfutr2330/article/details/105543822