<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Stitch11752

      Unit 2 Summary

      Unit 2 Summary

      by Mike Liu


      代碼分析

      總的來看,本單元三次作業的架構沒有大的變化。

      主要的類(線程)有三個:主類(讀入線程)MainClass,電梯Elevator和電梯控制器Controller

      • 每個電梯線程均和一個控制器線程形成一一對應關系。
      • 主類負責讀入請求,并隨即決定將請求分配給某一部電梯,加入該電梯的控制器的請求隊列中。當輸入結束時,讀入線程即結束。
      • 控制器負責根據電梯的狀態來將請求送入/取出電梯。當電梯線程結束時,控制器才結束。
      • 電梯自動根據電梯內部的請求確定目標樓層并運行;當內部沒有請求時,自動從控制器處獲得一個目標樓層;每到達一層時,會自動根據電梯內部請求和控制器中已有的請求決定是否開門。只有當控制器中沒有請求且輸入已經結束時,電梯線程才結束。

      控制器中的請求隊列使用ConcurrentLinkedQueue儲存,每次電梯開門時即遍歷該隊列,將需要進電梯的請求從中移除并送入電梯。

      Homework 5

      Preview

      本次作業較為簡單,調度策略的核心在于電梯如何確定主請求。

      靜態分析

      • 方法分析

        Method CONTROL ev(G) LOC V v(G)
        Controller.Controller(Elevator) 0 1 4 13 1
        Controller.addRequest(PersonRequest) 0 1 4 19 1
        Controller.endInput() 0 1 4 11 1
        Controller.endRequest() 0 1 3 8 1
        Controller.feedPerson() 2 1 14 167 4
        Controller.getMainRequest(int) 6 4 29 528 9
        Controller.requestEnded() 0 1 3 24 2
        Controller.run() 6 1 24 166 7
        Controller.someoneToGetIn(int) 2 3 10 120 4
        Elevator.Elevator() 0 1 4 16 1
        Elevator.doorClose() 3 2 14 89 3
        Elevator.doorOpen() 3 2 15 99 3
        Elevator.endService() 0 1 3 8 1
        Elevator.getController() 0 1 3 8 1
        Elevator.getFloor() 0 1 3 8 1
        Elevator.getHead() 0 1 3 8 1
        Elevator.getIn(PersonRequest) 0 1 5 46 1
        Elevator.getMainRequest() 6 1 24 292 9
        Elevator.getMainRequestFromController(boolean) 7 1 25 322 13
        Elevator.getOffAll() 3 1 16 202 5
        Elevator.goOneFloor() 3 2 16 133 5
        Elevator.isOpen() 0 1 3 15 1
        Elevator.run() 2 1 11 79 5
        Elevator.serviceEnded() 0 1 3 8 1
        Elevator.someoneToGetOff() 2 3 8 51 3
        MainClass.main(String[]) 3 3 15 99 3
      • 類分析

        Class CBO DIT LCOM LOC NOAC OCavg
        Controller 3 2 1 101 7 2.33
        Elevator 2 2 1 169 14 2.31
        MainClass 2 1 1 17 1 3
      • 類圖

        hw5

      設計策略

      可以看出,復雜度主要體現在電梯的getMainRequest函數;該函數是第一次作業調度策略的核心。

      • 當電梯內部有請求時,該函數取出電梯內請求隊列中到達樓層距當前樓層最遠的一個作為主請求;
      • 當電梯內部無請求時,該函數通過getMainRequestFromController流程,調用控制器的Controller.getMainRequest函數,從控制器獲得一個目標樓層。當控制器中無請求時,電梯線程進行wait,直到控制器中有新的請求,或所有輸入結束。

      Homework 6

      Preview

      本次作業加入了多部電梯,核心在于請求的分配。

      靜態分析

      • 方法分析

        Method CONTROL ev(G) LOC V v(G)
        Controller.Controller(Elevator) 0 1 4 13 1
        Controller.addRequest(PersonRequest) 0 1 4 19 1
        Controller.calcWeight(PersonRequest) 3 1 19 436 6
        Controller.endInput() 0 1 4 11 1
        Controller.endRequest() 0 1 3 8 1
        Controller.feedPerson() 4 4 17 185 5
        Controller.getMainRequest(int) 6 4 29 528 9
        Controller.requestEnded() 0 1 3 24 2
        Controller.run() 6 1 24 166 7
        Controller.someoneToGetIn(int) 2 3 10 120 4
        Elevator.Elevator(String) 0 1 5 28 1
        Elevator.doorClose() 3 2 15 105 3
        Elevator.doorOpen() 3 2 15 105 3
        Elevator.endService() 0 1 3 8 1
        Elevator.getController() 0 1 3 8 1
        Elevator.getFloor() 0 1 3 8 1
        Elevator.getHead() 0 1 3 8 1
        Elevator.getIn(PersonRequest) 1 2 8 99 2
        Elevator.getMainRequest() 6 1 24 292 9
        Elevator.getMainRequestFromController(boolean) 7 1 25 322 13
        Elevator.getNumOfPerson() 0 1 3 11 1
        Elevator.getOffAll() 3 1 18 247 5
        Elevator.goOneFloor() 3 2 16 208 7
        Elevator.isFull() 0 1 3 19 1
        Elevator.isOpen() 0 1 3 15 1
        Elevator.run() 4 3 13 109 7
        Elevator.serviceEnded() 0 1 3 8 1
        Elevator.someoneToGetOff() 2 3 8 51 3
        MainClass.main(String[]) 10 5 40 668 9

        RequestComparator類中只包含了一些用來比較兩個請求的靜態方法,此處不列。

      • 類分析

        Class CBO DIT LCOM LOC NOAC OCavg
        Controller 4 2 1 123 8 2.7
        Elevator 2 2 1 187 16 2.39
        MainClass 2 1 1 42 1 8
        RequestComparator 1 1 3 44 9 1.67
      • 類圖

        hw6

      設計策略

      可以看出,本次作業相較上一次,主類(讀入線程)的復雜度有了很大提升,因為其負責了請求的分配。

      由于是多部電梯,且每部電梯有載客量限制,因此分配主要考慮的因素主要有兩點:一是當前電梯及其控制器中已有的請求數,二是新請求捎帶其他請求/被其他請求捎帶的能力。

      綜上所述,本次作業采用了加權隨機的分配策略,具體策略如下:

      • 每讀入一個新的請求,根據該請求為每個電梯計算一個權重\(weight\):該權重最大值為1000,由兩部分組成:其中已有請求數\(numWeight\)貢獻70%,可稍帶/被捎帶的能力\(coverageWeight\)貢獻30%。
      • 已有請求數貢獻的權重\(numWeight = 700\times2^{-totnum/9}\) ,其中 \(totnum\) 為電梯及其控制器中當前已有的請求數之和。
      • 可稍帶/被捎帶的能力貢獻的權重
        \(coverageWeight = 300\times\begin{cases}1, \text{當前請求起止于電梯當前層到目標層之間,且同向}\\0.75, \text{當前請求起于電梯當前層到目標層之間,且同向}\\0.5, \text{當前請求起止于電梯目標層之后,且同向}\\0.5\times2^{-diff/3},\text{其他 其中diff為當前目標層與請求起始層的樓層差絕對值}\end{cases}\)
        RequestComparator類中的靜態方法即是來完成對不同情況的判斷。

      得到每個電梯的權重后,用隨機數決定將請求分配給哪部電梯;被分配到的概率和權重成正比例關系。決定后,隨即將該請求加入對應電梯的控制器的請求隊列。

      之所以采用隨機策略,主要出于兩點考慮:一是權重計算本身并不精確,沒有用數據進行測試,只是憑感覺;二是調度時間本身受到很多不確定性因素影響,即使權重最高也不一定最優,因此用隨機的方式避免一些最壞情況發生。非常遺憾,由于本次作業出現了其他致命錯誤,導致強測全部WA,沒有能夠驗證該策略的效果。

      Homework 7

      Preview

      第三次作業的核心是停層限制和換乘;因此核心是完成對請求的拆分,其余機制和功能不變。為了便于拆分請求,引入了自定義的請求類MyRequest,封裝了PersonRequest原有的接口,增添了對前驅/后繼請求的引用,以及對請求的激活功能。

      靜態分析

      • 方法分析

        Method CONTROL ev(G) LOC V v(G)
        Controller.Controller(Elevator) 0 1 4 13 1
        Controller.addRequest(MyRequest) 0 1 4 19 1
        Controller.calcWeight(MyRequest) 3 1 19 436 6
        Controller.endInput() 0 1 4 11 1
        Controller.endRequest() 0 1 3 8 1
        Controller.feedPerson() 7 5 20 254 7
        Controller.getMainRequest(int) 8 5 30 567 10
        Controller.requestEnded() 0 1 3 24 2
        Controller.run() 6 1 24 166 7
        Controller.someoneToGetIn(int) 2 3 9 124 5
        Elevator.Elevator(String,String) 9 2 28 247 5
        Elevator.doorClose() 3 2 15 105 3
        Elevator.doorOpen() 3 2 15 105 3
        Elevator.endService() 0 1 3 8 1
        Elevator.getController() 0 1 3 8 1
        Elevator.getFloor() 0 1 3 8 1
        Elevator.getHead() 0 1 3 8 1
        Elevator.getIn(MyRequest) 1 2 8 99 2
        Elevator.getMainRequest() 7 1 25 332 10
        Elevator.getMainRequestFromController(boolean) 7 1 25 322 13
        Elevator.getNumOfPerson() 0 1 3 11 1
        Elevator.getOffAll() 3 1 20 269 5
        Elevator.getType() 0 1 1 11 1
        Elevator.goOneFloor() 3 2 16 208 7
        Elevator.isFull() 0 1 3 19 1
        Elevator.isOpen() 0 1 3 15 1
        Elevator.run() 4 3 13 137 8
        Elevator.serviceEnded() 0 1 3 8 1
        Elevator.someoneToGetOff() 3 4 9 102 5
        MainClass.main(String[]) 14 8 54 894 13
        MyRequest.Link(MyRequest,MyRequest) 0 1 4 25 1
        MyRequest.MyRequest(PersonRequest,String) 0 1 4 11 1
        MyRequest.activate() 1 1 4 30 1
        MyRequest.activateNext() 1 2 4 26 2
        MyRequest.getFromFloor() 0 1 3 15 1
        MyRequest.getPersonId() 0 1 3 15 1
        MyRequest.getToFloor() 0 1 3 15 1
        MyRequest.getVia() 0 1 1 4 1
        MyRequest.getViaType() 0 1 1 11 1
        MyRequest.isActive() 0 1 3 15 1
        MyRequest.setVia(Elevator) 0 1 1 8 1
      • 類分析

        Class CBO DIT LCOM LOC NOAC OCavg
        Controller 5 2 1 126 8 3
        Elevator 3 2 2 227 17 2.63
        MainClass 4 1 1 56 1 12
        MyRequest 5 1 3 38 10 1.09
        RequestComparator 2 1 3 44 9 1.67
        RequestSplitter 3 1 1 262 1 4
        RequestSplitter.Node 1 1 0 13 0 1
      • 類圖

        hw7

        總的來說,本單元各線程分工比較明確,在類的設計上沒有特別的注意點。

      設計策略

      1. 換乘拆分

        • 用圖的思想,將每一層和每類型電梯在每一層的停靠點作為圖的結點,進出電梯、電梯上下運行的過程作為圖的邊。

        • 為了最大限度地減少換乘,將表示電梯上下運行的邊長度設為實際運行需要的時間,將從樓層進出電梯的邊長度設為一個很大的值。

        • 將每一層視為起點,分別跑一次SPFA,求出到其他各層的最短路徑。若無需換乘,則只求出需乘坐的電梯型號;若需要換乘(本題目中最多換乘一次),則求出兩次需乘坐的電梯型號和換乘樓層。

        該部分其實可以內嵌在Java程序中進行。但由于用Java描述算法過于臃腫,且為了減少不必要的CPU開銷,本次作業書寫了額外的C++代碼用于執行SPFA算法最短路并打表,并將打表結果轉化為Java語句,寫入了RequestSplitter類的static域。

      2. 請求設計

        MyRequest中封裝了PersonRequest,并且存儲了前驅請求prev和后繼請求next的引用。當一個初始請求被拆分成兩個新請求時,調用MyRequest.Link方法分別設置兩個請求的nextprev為對方。

        • 當一個請求的prev不為null時,表示該請求的前驅請求尚未完成,現在不能調度。
        • 當一個請求的prevnull時,表示該請求的前驅請求已完成或沒有前驅請求,現在可以調度。
        • 當一個請求的next不為null時,表示該請求有后繼請求;該請求結束(出電梯)后,將后繼請求的prev置為null,使得后繼請求可以被調度。

        這樣,只需要在調度器中添加判斷條件(當前請求是否有前驅請求)即可,其余皆可繼承之前的作業。

      功能設計與性能設計

      從功能角度來看,由于第一次作業的架構就具有很好的一般性,導致電梯系統的兼容性很強:只需要做好請求的分配即可,無需調整整體的架構。這樣的好處在后兩次迭代中也顯現出了優勢,每次迭代修改的代碼量很少。這樣即使后期有更多功能需求,也便于擴展;只需要修改上層的邏輯。

      從性能角度來看,由于必須在請求讀入時就確定分配方案,調度機制不能機動地考慮到實時的情況,只能根據預定的方案和目前電梯的狀況來進行分配,顯然缺乏一些靈活性,且不是性能最優解。當然,可以通過后期修改參數來調整分配策略,使性能不斷優化;也可以設置不同的參數,來適應不同工作情況。

      總體來說,本單元作業更傾向于功能設計,犧牲了部分性能。但還可以增加一些附加機制,如將已進入控制器的請求重新分配等,來提高性能。以及,由于寫第一次作業時對多線程還不夠熟悉,一些同步關系比較混亂,基礎架構還存在提升的空間;尤其是電梯線程和控制器線程的配合,還可以有更好的解決方法。


      時序圖

      seq


      Bug分析

      Homework 5

      強測和互測中均未出現bug。

      Homework 6

      本次作業中出現了一個bug,導致強測所有測試點WA。

      在主類(讀入線程)中,同時使用了Scanner(System.in)讀入電梯個數和ElevatorInput(System.in)讀入電梯請求,產生了緩沖區沖突。

      在中測時,由于同時進行評測的進程較少,讀入線程被及時調度:Scanner讀取第一個整數時,后續請求還未被輸入,此時Scanner只取走這個整數到緩沖區;之后的請求被ElevatorInput取走,運行正常。

      在強測時,由于同時進行評測的進程較多,觀察到第一條輸出的時間戳往往為數秒之后,說明讀入線程未被及時調度:Scanner讀取第一個整數時,后續請求已經被輸入,此時Scanner為了提高讀入效率,將請求也取入了緩沖區;當ElevatorInput讀入時,就取不到Scanner緩沖區中的前幾個請求,導致了程序錯誤。

      事后我也和助教討論了這一bug,提出了我的一些關于評測的疑問,不過我們的助教似乎不太擅長回答問題。其實我們曾經就遇到過類似的情況,比如cinscanf慢,是因為cin要保持某種和scanf的同步,來使得兩種輸入可以同時使用而不出現錯誤;可以理解為二者用這種同步來保證不會將輸入被不正當地取入緩沖區。如果用std::ios::sync_with_stdio(false)來關閉同步,cin就和scanf速度相當,但不能混合使用。

      Homework 7

      強測全部通過;由于上一次作業沒有進入互測,導致了一些可能是遺留的bug,在本次互測中體現出來。

      1. 電梯開門運行邏輯不嚴密,在某些情況下到達目標層后不開門,導致卡住不動。
      2. 調度器每執行一次循環中的feedPerson動作就必然喚醒一次電梯,導致電梯在暫時沒有請求時不斷wait - 被喚醒 - wait - 被喚醒……;更改后,只有在的確有人被feed入電梯的情況下才喚醒電梯,否則不喚醒。

      由于采用了隨機策略,在某些情況下復現bug有一定的難度。調試時,主要采用了分時段手動輸入+print輸出的方法,主要查找線程等待與喚醒相關的部分,十分有效。


      心得體會

      第一次接觸到多線程編程,有很多概念需要重新理解。編程思路也和單線程編程有很大的區別:提前的架構設計非常重要,因為后期迭代開發時重構帶來的成本過高,設計時必須想清楚協作邏輯,留下良好的兼容性。

      除了多線程編程思想之外,也是用一次強測爆0的成本意識到了一些問題,比如輸入輸出涉及的一些原理。

      總之,多線程編程的思維量大幅度提升,需要考慮的問題也增多;要掌握這項技術還需要多加練習。

      posted on 2020-04-18 13:10  Stitch11752  閱讀(155)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 在线国产你懂的| 午夜在线不卡| 少妇高潮潮喷到猛进猛出小说| 视频一区视频二区视频三| 亚洲午夜福利网在线观看| 亚洲人妻av伦理| 国产在线精品中文字幕| 天堂v亚洲国产v第一次 | 五家渠市| 欧美日韩精品一区二区视频| 亚洲av免费成人在线| 国产精品一区在线蜜臀| 亚洲精品综合网在线8050影院| 欧美黑人性暴力猛交在线视频| 人妻少妇精品无码专区| 亚洲日韩日本中文在线| 国产午夜精品福利在线观看| 国产高清自产拍av在线| 亚洲精国产一区二区三区| 在线高清免费不卡全码| 一本之道高清乱码少妇| 色综合国产一区二区三区| 成全影视大全在线观看| 精品无码久久久久国产电影| 兰坪| 久女女热精品视频在线观看| 激情在线网| 精品视频一区二区| 激情综合网激情五月激情| 国产麻花豆剧传媒精品mv在线 | 少妇被日自拍黄色三级网络| 欧美丰满熟妇xxxx性| 国产欧美综合在线观看第十页| 女同亚洲精品一区二区三| 国产桃色在线成免费视频| 久久夜色撩人精品国产av| 渭源县| 亚洲色一色噜一噜噜噜| 爱色精品视频一区二区| 欧美在线一区二区三区精品| 久久人人97超碰人人澡爱香蕉|