電梯優化策略
架構
UML類圖
- 採用架構爲三類線程、分配器與控制器分離
請求處理流程
優化策略
強測結果
請求拆分策略
策略概述
-
拆分與分配獨立,無需在拆分時考慮電梯的實時狀態
-
使用靜態Floyed預處理求最短路
-
無向圖中邊的定義爲:
其中爲三類電梯總的可達性矩陣,且
-
換乘的花費定義:
即定義換乘花費爲
-
與以不同電梯花費相關的值作爲邊權不同,主要考慮點在於拆分器與分配器的行爲匹配
如果拆分器認爲應該把任務M給A電梯處理,但分配器進行分配時發現A電梯已經滿載或距離起始樓層太遠,而將任務M分配給了另外的電梯,這樣反而相對最好的情況相差太大
上述定義的拆分策略不是最優,但相對來說平均性能較好
-
靜態在於針對A,B,C三類電梯建圖,新增電梯不需要修改
實現細節
-
中間點k的循環一定要在最外層!
-
否則dist(i,j)的確定不會因爲更多的路徑更新而更新,即以i->j->k的順序枚舉時,最後一次更新dist(i,j)後的值不是最優的
-
通過trace跟蹤當前dist(i,j)最短路上的上一個節點來獲取路徑,即拆分後的任務,簡潔一點可以用遞歸找
-
存儲數據結構採用單鏈表,構建HashMap以personID作爲key,每個人一個單鏈表,任務節點定義如下
-
查找較爲方便高效
控制器策略
策略概述
-
注意到對於每一個電梯的每個時刻可能的決策空間只有向上與向下兩種,這對枚舉策略很友好
-
借鑑啓發式搜索中的估價函數,貪心地選取估價函數中最優的策略
-
最重要的是如何選取估價函數h*(state),需要保證估價函數與真實情況十分相近,其中最優的真實情況h(state)是估價函數的下界,即
-
但h(state)無法通過較短時間獲取,需要暴力搜索,不可取
-
估價函數一種可能的定義爲
當前狀態的電梯使用LOOK策略到電梯運行結束還需要的耗時(針對第一次作業)
實現細節
- 定義模擬器類,調用Simulator.simulate(…)根據當前狀態獲得LOOK運行至結束的花費,作爲估價函數
- 需要注意模擬器的修改需要clone一下,避免對原電梯狀態進行改變
分配器策略
策略概述
-
對於多個電梯,控制器僅僅解決了單個電梯給定任務集後的最佳調度
-
同樣採取枚舉策略,嘗試將當前待分配任務分別加入到每個電梯進行枚舉,將所有電梯運行時間的最大值作爲估計函數(針對第二次作業),即
其中,定義爲按照state規定的加入當前任務後的電梯
-
最後將作爲最終決策應用到實際電梯中進行分配
-
對於第三次作業的評價指標加入了等待時間之和,只需要按照指導書性能值的配比修改估價函數的計算方式就行了,其他不需要改變
-
由於,所以估價函數應在最終決策時確定,模擬器返回一個runtimeCost與waitingCost的Pair
實現細節
- 其中初始值的設定使用了INT_MAX是爲了防止使用LONG_MAX進行加法的意外溢出
其他優化
- 拆分後的任務如果第一階段已經完成了才通知分配第二階段,會造成電梯等待的浪費,即電梯等待樓層與接客樓層太遠
- 分配第一階段任務後,新增一個操作,選一個電梯的等待樓層設置爲第二階段的起始位置
- 用循環鏈表管理當前分配到哪個電梯,繼續尋找下一題個Waiting狀態的電梯進行等待樓層設置
- 如果遍歷一圈了都沒空,就設置當前這個電梯等待樓層爲第二階段起點
- 平均下來等待樓層能夠較爲分散,且每個電梯任務量較平均