2010-10-28 160 views
2

的分配如下:加油站模擬:如何模擬隨機出現的汽車?

加油站由2個泵。每個泵都有一定數量的燃油可以分配。汽車到達隨機時間間隔,並嘗試使用兩個泵中的一個:

- 如果泵可用,並且有燃料,該車立即允許使用它。每輛車需要一定數量的燃料(隨機數),並且必須等待與該燃料量成比例的時間。例如,一輛汽車可能需要6加侖汽油,並將使用該泵3秒,另一輛汽車可能需要10加侖,並將使用該泵5秒鐘等。當汽車加油時,它會離開,另一輛汽車可以使用泵。在給汽車加油後,泵中的燃油量會相應地調整。
- 如果兩臺泵當前正在使用,則到達的車輛將等待,直到兩臺泵中的一臺可用。
- 如果一個泵的燃油用完,它必須等待油罐車提供更多燃油。油輪定期到達(但不是太頻繁),並將兩臺泵充滿。雖然油輪正在維修泵,但沒有汽車可以使用泵。 忘了補充說明

第一部分:您必須提交符合上述規格的詳細設計。您的設計必須使用Java線程。您必須指定您將使用的線程數量和類型,以及這些線程將如何同步。您可以用僞代碼編寫項目的這個階段。這是爲了幫助你理解各個部分將如何結合在一起。第二部分:您必須使用Java線程和適當的同步方法提交您的設計的完整實現。您的實施必須根據上述規格進行仔細測試。


我想知道。我如何使用Java線程模擬隨機進入的汽車?
我很失落,並提前感謝您的幫助。

+2

正在使用多個線程的要求?我認爲使用線程並不是一個好的情況,但是如果目標是學習如何使用線程,那麼這種批評並不適用。 – CodesInChaos 2010-10-28 20:27:52

+0

是的,我想我需要使用幾個線程。 – Luron 2010-10-28 20:46:32

+0

是的,我同意,線程不是一個好的情況。但那只是爲了學習。 – Matt 2010-10-28 20:55:52

回答

12

創建一個汽車工廠類,吐出一車被添加到出院並隨機休息一段時間。

像所有的學生,你可能會發現這個問題是有點勢不可擋。這是如果你不開始把它分解成你可以處理的更小的塊。想想整體設計並開始實施它的小部分。

例如,這是一個排隊理論問題。他們可能是汽車,銀行人員或任何與隊列互動的人。不要擔心汽車或加油站的細節。這是你的問題:

  1. 你有一條線,一端添加新條目,另一端將它們關閉。它被稱爲出隊數據結構。請閱讀。查看您是否可以編寫(或重用)Java Dequeue類。完全理解它。寫一個小驅動程序添加到一端,並從另一端刪除。
  2. 一旦你有了這些,你需要編寫類創建新的條目添加到出列和其他刪除它們。簡單地通過寫入以固定間隔工作的加法器/去除器開始。你應該看到的是,如果加法器和去除器具有完全相同的接口,則排隊等待的條目數量不會改變。如果加法器的運行速度比卸妝器快,則該線應該填滿。如果卸妝者比加工者工作得更快,你永遠不會有備份。確保你的簡單課程表現出這種行爲。
  3. 添加隨機位並開始仿真。您需要查看排隊條目數量隨時間變化的情況。
  4. 現在添加多行。你想看看如何添加更多的線改變動態。
+0

Thread.currentThread()。sleep(1000) – Dlongnecker 2010-10-28 14:26:38

+0

1000不是隨機的;這是每秒一次。 – duffymo 2010-10-28 14:26:57

+0

我可以做隨機r = new Random(); Thread.currentThread()。睡眠(r.nextInt(100000)) – Luron 2010-10-28 14:30:03

3

如果你有固定的時間間隔汽車在該區間到達數爲Poisson分佈。

兩輛汽車之間的時間具有probabilitydensity成正比EXP(-t/TAU)其中的tau描述汽車到達的頻率。所以你需要弄清楚如何創建指數分佈的隨機數。

從P(T)= C * EXP(-t/TAU)的概率密度我們整合P(T)= 1-EXP(-t/TAU)的累積概率分佈。因此反轉該函數得到t = -tau * ln(1-P(t))。所以,如果你生成一個編號u 0和1之間均勻分佈的,你可以得到一個正確分佈T作爲T = -tau * LN(1-U)

+0

泊松分佈絕對是你想要的。 – 2010-10-28 14:30:29

+0

泊松分佈與解決OP問題有關嗎?即'我如何使用Java線程來模擬車輛以隨機間隔進入?' – 2010-10-28 14:50:47

+0

對於一個班級練習,我會從「隨機」生成數字的統一分佈開始。一旦這個工作,爲額外的信用去泊松。 – Qwerky 2010-10-28 14:52:00

0

您可以使用同一種汽車來源。你可以建立一些時間間隔,例如隨機偏差。

1

我可以通過一個線程看到你要去的地方,但除非這是一個圖形模擬,你希望人們能夠看到它實時運行,否則你並不需要它。否則,只需跟蹤時間表。在任何時間點知道接下來會發生什麼事件: A)卡車到達。 B)汽車到達。 C)汽車離開。

我想你會跟蹤這些事情需要多長時間,所以只需簡單地模擬事件的發生即可。每次到達時,新車到達的時間將由您決定的隨機時間。

相信我,它會讓你的生活變得簡單易行。

+0

忘記添加***第一部分:您必須提交符合上述規格的詳細設計。您的設計必須使用Java線程。*您必須指定您將使用的線程數量和類型,以及這些線程將如何同步。您可以用僞代碼編寫項目的這個階段。這是爲了幫助你理解各個部分將如何結合在一起。 **第二部分:您必須使用Java線程和適當的同步方法提交您的設計的完整實現。您的實施必須根據上述規格進行仔細測試。 – Luron 2010-10-28 14:25:14

+0

那麼,如果它是關於使用Java線程的練習,則應該這樣做。但是,要知道,在任何實際情況下,這不適用於線程。 – Neil 2010-10-29 09:23:28

0

您可以使用線程安全PriorityBlockingQueue來創建事件隊列。

基本上,汽車到達,油輪到達,汽車進入泵和汽車退出泵都是事件。其中每一個都具有發生順序,您爲每個事件插入一個「Event」對象,並帶有時間戳。您可以安排,以便PriorityBlockingQueue使用時間戳對事件進行排序。

最初,您爲汽車抵達生產者線程和罐車抵達生產者線程啓動線程。汽車到達線程將put()一個CarArrivalEvent到隊列中,然後休眠一段隨機時間。油輪螺紋也是這樣,但是put() TankerArrivalEvent代替。

加油站有兩個泵,每個都由消費者線代表。每個泵的螺紋將會在一個CarArrivalEvent中,然後睡眠一段時間以填充汽車。對於TankerArrivalEvent您也是這樣做的。

0

請勿使用泊松分佈。 Poission會給你「在接下來的X分鐘內到達的人數」。它不會給你「到下一次到達的時間」。

WITE小while循環,像這樣::

public int getTimeTillNextCar() { 
    PROBABILITY = .001; 
    int timeTillNextCar = 0; 
    while(rand.nextDouble() > PROBABILITY) { 
     timeTillNextCar++; 
    } 
    } 

很顯然,我只是假設你正在使用謹慎的時間。然而,這是可能的(有些人會認爲更好)使用指數的單個抽籤。這將更有效率。但是,使用這種方法會使代碼「骯髒」,有些人可能不喜歡/理解。

Remeber,泊松分佈從計數多少伯努利平局是當p是非常小的,n是中等大成功的給定的n平到達。如果n太大,則Possion分佈將收斂到正態分佈。

對於設計的其餘部分...

Thread_A應增加汽車的隊列(請務必使用一個線程安全的隊列類)

Thread_A shoule做到這一點:
加車,
睡眠(getTimeTillNextCar()),
新增汽車,
睡眠(getTimeTillNextCar()),
加車,
睡眠(getTimeTillNextCar()),
等....

Thread_B和Thread_C應該採取汽車從隊列:
Thread_B(和C)應該這樣做:
get_car_off_queue,
睡眠(car.getFuelingTime(),
get_car_off_queue,
睡眠(car.getFuelingTime(), 等等

+1

如果你有代表泵兩個線程,那麼它不符合規範的問題 - 這個問題說:「如果一個泵可用,並且有燃料,該車立即允許使用它」。如果您沒有在RTOS中運行,那麼不能保證免費泵的線程將被安排並將汽車出列。 – 2010-10-28 20:26:13

+0

皮特Kirkham的,在大房子... – duffymo 2010-10-28 21:08:20

+0

@Pete - 沒錯,但是這是一個非常簡單的問題來解決。處理「無隊列」情況不會破壞這個通用設置。 – Ivan 2010-10-29 04:39:28

1

首先,由於沒有什麼或者您的OP也不其中指出,該系統是靠在牆上的時鐘,不要操作問題陳述的額外位我們假設它沒有。任何基於創建汽車之間睡10秒的東西都會在你測試它時讓你發瘋。創建一個簡單的界面,以提供時間進行模擬並與之對抗;如果你需要把它綁在牆上的時鐘,那麼你可以,但你也可以一樣快,你的機器會運行測試。其次,通常將模擬作爲事件運行會更好 - 汽車到達車站,汽車從排隊到泵,汽車離開泵,油罐車到達。通常基於時間的事件的優先級隊列起作用;當一輛汽車開始填充時,您將其事件添加到事件隊列中,並在將來使用時間戳。這是很多,更容易編寫邏輯不處理汽車是否有比與線程的優先級勾搭給定時間的油輪。由於您的任務要求您展示線程之間的某些同步,您可能需要運行汽車等待,汽車加油/油輪卸載作爲單獨線程的過程(在真實的軟件中,您不會,但更可能使用期貨和遺囑執行人,如果你想要並行執行,但我猜想這是一個教學任務,你需要證明的線程一些設計,而不是讓庫排序這一切了你)。

因此,對於每個時間片,你處理從隊列中的事件,等待所有事件處理完成,然後要求時鐘下一個節拍。快時鐘會立即返回一個時間戳下一秒,或掛鐘時鐘​​會等到的系統時間的下一秒。

由於您需要爲每個任務使用線程,因此您需要在每個時間片的開始和結束時同步這些任務,並且您需要同步或以其他方式確保排隊的事件安全入隊並在出現時間片完成。

所以任務是這樣的:

  • 進入汽車

    • 每一秒,確定車到達的數量。這將是一個泊松分佈。
    • 對於每個到達,發佈一個汽車到達事件(或發佈一個事件與汽車的數量) (或者,使用其他一些隨機機制;其他大多數方法只會導致一輛汽車一次到達,是不是經常放置在模型一個有用的限制)
  • 傳入油輪

    • 每一個(油船到貨週期)發佈每臺泵的油輪到達的事件
  • 等待汽車

    • 增量汽車等對汽車到達事件
  • 數量泵

    • 如果油輪已經來臨,設置油輪等待標誌
    • 如果泵是免費的,那麼
      • 如果油輪正在等待,如果泵有燃料並且任何汽車正在等待,減少汽車等待計數,發佈泵免費事件以便進行定時計時,則將油箱等待標誌,補油泵,後補泵免費事件作爲未來補油泵的時間
      • 。應填充車在未來

問題描述不清楚是否油輪必須等待兩個泵是免費的,纔可以開始填充它們,在這種情況下,你會需要添加另一個'油輪就緒'狀態。

如果這些任務位於不同的線程中,則需要手動同步各個計數器,或者使用java.util.concurrent.atomic中的原子值。