此處 特地感謝 lsj 霸霸提出的這一神奇思路,我只是把這個想法變爲現實。java
很慚愧,只作了一點一點微小的工做(端起茶杯)算法
ALS 在處理大多數狀況的時候效果明顯差於 Look ,可是ALS,在面對安全
1-FROM-1-TO-3性能
2-FROM--2-TO-3優化
3-FROM-10-TO-15ui
這種狀況的時候,反而會由於它 先來先選 的沙雕策略比 Look 折返路程更少。this
貪心算法在面對精心構造的數據的時候可能會被來回 放風箏 這是 墜痛苦的 。spa
指導書最開始並無禁止互測經過針對對方算法構造一個極具針對性的數據點。線程
我的見解是,針對一個多數狀況下較優的算法,經過一個很極端的例子,去卡爆對方性能,獲取hack分數code
是有點缺德的。同時這個所謂的Bug還難以修復。
開發這個多策略的 初心 是防止本身的程序出如今極端狀況下慢於純ALS的狀況。
第二次和第三次做業當中,個人一些優化算法,可能在某些狀況下出現負優化,因而我須要根據判斷
優化先後的字符串長度取捨本次的優化。 因而lsj julao提出能不能在此處根據時間取捨優化,並初步提出了
多電梯並行的操做。
多策略能夠理解爲一種在 算法選擇 層面的貪心,總體思路以下
public class ElevatorSystem { public static void main(String[] args) { GlobalPermission permission = new GlobalPermission(); Rail rail0 = new Rail(16,3); Rail rail1 = new Rail(16,3); Rail rail2 = new Rail(16,3); Dispatcher dispatcher0 = new Dispatcher(rail0,permission); Dispatcher dispatcher1 = new Dispatcher(rail1,permission); Dispatcher dispatcher2 = new Dispatcher(rail2,permission); dispatcher0.addSillyElevator(); dispatcher1.addLookElevator(); dispatcher2.addAlsElevator(); ArrayList<Elevator> elevators0 = dispatcher0.getElevators(); ArrayList<Elevator> elevators1 = dispatcher1.getElevators(); ArrayList<Elevator> elevators2 = dispatcher2.getElevators(); TimableOutput.initStartTimestamp(); permission.systemStart(); Thread elevator0 = new Thread(elevators0.get(0)); Thread elevator1 = new Thread(elevators1.get(0)); Thread elevator2 = new Thread(elevators2.get(0)); elevator0.start(); elevator1.start(); elevator2.start(); ElevatorInput elevatorInput = new ElevatorInput(System.in); while (true) { PersonRequest request = elevatorInput.nextPersonRequest(); if (request == null) { permission.systemQuit(); try { elevatorInput.close(); } catch (Exception e) { e.printStackTrace(); } break; } try { // 每拿到一個新的請求,把這個請求給每一個電梯各分配一次 dispatcher0.getBuffer().put(request); dispatcher1.getBuffer().put(request); dispatcher2.getBuffer().put(request); } catch (Exception e) { e.printStackTrace(); } } } }
我把緩衝區以及最後的帶鎖輸出方法封裝到了一個OutputHelper類中,每一個電梯都自帶一個OutputHelper對象
public class OutputHelper { private static boolean hasOuput = false; private ByteArrayOutputStream storeStream = new ByteArrayOutputStream(); private PrintStream stream = new PrintStream(storeStream); public static synchronized void output(OutputHelper helper) { if (!hasOuput) { helper.finalOutput(); hasOuput = true; } } public void println(String string) { TimableOutput.println(string,stream); } public void finalOutput() { Scanner scanner = new Scanner(storeStream.toString()); while (scanner.hasNextLine()) { System.out.println(scanner.nextLine()); } } }
public void run() { dispatcher.updateRequests(); while (this.hasMoreWork()) { dispatcher.updateRequests(); ElevatorOrder order = getOrderAndUpdateBuffer(); dispatcher.updateRequests(); executeOrder(order); } // 任務執行完畢,開始輸出 OutputHelper.output(helper); // 輸出! System.err.println(scheduler); // 輸出「優勝者」的信息,便於統計算法性能 System.exit(0); // 暴力關程序 }
根據本人利用err流輸出的統計信息,在強測數據中,本人的高分數據點(95+)的最優策略包含了本人使用的三種算法,可見這種多策略對性能的提高是很大的。
固然,在這裏我必須得膜那些用單策略可是性能分高於個人dalao,三個算法比不過對方一個算法,哭哭。
此方法出自shh,可是他摸了,沒去實現,哭哭。
這裏大概講一下shh的思路。
咱們以前所說的多策略都是每一個線程給定一個算法,而後取最優。
若是遇到一下這種狀況,這個方法的效果可能會大打折扣
那麼這樣子看來,咱們的多策略仍是不夠
因而,shh提出了根據每固定執行步數給各個算法打個分,而後調整算法的操做。
(反正我是不會實現的,哭哭)
前文咱們提到,多策略在其中一個線程由於bug而陷入長時間沒法運行的狀態時,通常不會輸出錯誤。
由於那個bug線程一直摸魚,沒法輸出,就會使得正確執行的線程能夠輸出。
那麼,這就帶來另外一個問題 若是一個線程由於Bug,執行錯誤地線程最早結束,那麼輸出將會是錯誤的。
這裏,咱們就能夠把本身評測機的評測模塊加進來,對咱們本身的輸出結果進行檢驗。
若是是正確的輸出,則正常輸出並結束程序,若是不是正確數據則等待下一個能夠輸出的線程,直到等到第一個正確的輸出。
此外若是擔憂本身電梯出現異常
的問題,能夠try-catch一下,若是有異常就失去輸出的權力。
這樣,就能夠大幅度下降本身程序出錯的機率~
在第三次做業中,我須要統計爲三部電梯選擇合適的控制算法。
因而我經過根據三部電梯的任務特徵生成針對性數據,經過運行多策略電梯統計各個策略的效果。
最後根據統計結果爲三部電梯的調度策略作出調整。