2014-10-07 28 views
2

我一直有問題,我已經建立了模擬,我不知道如何解決它們。這個模擬的想法如下:需要SimPy仿真的可用性幫助

系統中共有10臺機器。當模擬開始時,6臺機器將開始工作,而其他4臺機器將作爲備件保存在庫存中。

要求是在系統中的任何時候,應該有6臺機器工作。當沒有總共6臺機器工作時,任何時間都會計爲停機時間。

經過一段時間的工作,6臺工作機器中的一臺將失敗。當發生這種故障事件時,我們將從庫存中取出1臺機器並將其添加到工作機組中,以便我們能夠滿足6臺機器同時工作的要求。

失敗的機器將被送到維修車間並在一段時間後進行修理。維修完成後,它將被移到庫存中,以便加入其他機器。

下一次6臺工作機中的另一臺出現故障時,將再次從庫存中取出1臺機器來更換故障機器。這意味着庫存內的機器數量將在整個模擬過程中不斷波動。在整個模擬過程中,我還需要清點內有多少臺機器,因此我添加了print語句來向我顯示。

總之,一臺機器將經歷以下循環: 開始工作 - >失敗 - >發送到維修車間 - >修理後,放入庫存 - >當另一臺機器發生故障時再次拉動操作 - >啓動工作 - >失敗..等

我在這個模擬中的另一個要求是,我需要知道機器1到10在任何時候。這樣我就可以跟蹤每臺機器的運動,例如,機器7何時發生故障,何時進入並離開修理車間,何時進入並離開庫存等。

此後仿真建立後,我將隨後改變最初的備件數量和修復時間,以研究這些因素如何影響操作可用性的水平。

我面臨的主要問題:

我無法單獨完成整個週期

我無法正確地進行建模我的備件庫存跟蹤每一個10臺機器。如果機器5-10在開始時處於運行狀態,當其中一臺機器出現故障時,下一行輸出應告訴我機器1已從庫存中取出(並開始運行)以替換故障機器。但是,我無法得到這樣的結果。

預先感謝您!

我已經包括了我的進步至今:

import simpy 
    import random 

    RANDOM_SEED = 42 
    NUM_SERVERS = 2 
    MTBF = 10 
    MTTR = 2 
    TOTAL_MACHINES = 10 
    TOTAL_SPARES = 4 
    TOTAL_WORKING = TOTAL_MACHINES - TOTAL_SPARES 
    SIM_TIME = 100 

    class Working(object): 
     def __init__ (self, env, num, repair_workshop, spares_inventory, downtime): 
      self.env = env 
      self.repair_workshop = repair_workshop 
      self.spares_inventory = spares_inventory 
      self.downtime = downtime 
      self.name = 'Machine %d' % (num + 1) 
      print('%s begins working %.2f' % (self.name, self.env.now)) 
      self.env.process(self.run()) 

     def run(self): 
      yield self.env.timeout(random.expovariate(1.0/MTBF)) 
      print('%s stops working %.2f' % (self.name, self.env.now)) 

      downtime_start = self.env.now 
      spare = yield self.spares_inventory.get(1) 
      self.downtime.append(self.env.now - downtime_start) 

      print('%s taken from inventory at %.2f' % (spare.name, self.env.now)) 
      print('%d inside inventory' % len(spares_inventory.items)) 

      with self.repair_workshop.request() as req: 
       yield req 
       print('%s starts repair %.2f' % (self.name, self.env.now)) 

       yield self.env.timeout(random.expovariate(1.0/MTTR)) 

       yield self.spares_inventory.put(1) 
       print('%s finishes repair at %.2f' % (self.name, self.env.now)) 

      print(' %d inside inventory' % len(spares_inventory.items)) 

    def main(): 
     env = simpy.Environment() 
     repair_workshop = simpy.Resource(env, capacity = NUM_SERVERS) 
     spares_inventory = simpy.Container(env, capacity = TOTAL_MACHINES, init = TOTAL_SPARES) 
     downtime = [] 
     working = [Working(env, i, repair_workshop, spares_inventory, downtime) for i in range(TOTAL_WORKING)] 

     env.run(SIM_TIME) 

     print('Total downtime for all machines throughout simulation time is %.2f hours' % sum(downtime)) 
     print('Operational Availability = %.2f percent' % ((SIM_TIME - sum(downtime)) * 100/(SIM_TIME))) 

    if __name__ == '__main__': 
     main() 

隨着Stefan的幫助下,我已經修改了我的腳本:

class Working(object): 

     def __init__ (self, env, num, repair_workshop, spares_inventory, downtime, machine): 
      self.env = env 
      self.repair_workshop = repair_workshop 
      self.spares_inventory = spares_inventory 
      self.downtime = downtime 
      self.machine = machine 
      self.name = ('Machine %d' % (num + 1)) 
      print('%s begins working %.2f' % (self.name, self.env.now)) 
      self.env.process(self.run()) 

     def run(self): 
      yield self.env.timeout(random.expovariate(1.0/MTBF)) 
      print('%s stops working %.2f' % (self.name, self.env.now)) 

      downtime_start = self.env.now 
      spare = yield self.spares_inventory.get(1) 
      self.downtime.append(self.env.now - downtime_start) 

      print('%s taken from inventory at %.2f' % (spare.name, self.env.now)) 
      print('%d inside inventory' % len(spares_inventory.items)) 

      with self.repair_workshop.request() as req: 
       yield req 
       print('%s starts repair %.2f' % (self.name, self.env.now)) 

       yield self.env.timeout(random.expovariate(1.0/MTTR)) 

       yield self.spares_inventory.put(1) 
       print('%s finishes repair at %.2f' % (self.name, self.env.now)) 

      print(' %d inside inventory' % len(spares_inventory.items)) 

    def main(): 
     env = simpy.Environment() 
     repair_workshop = simpy.Resource(env, capacity = NUM_SERVERS) 
     downtime = [] 

     machines = [object() for i in range(TOTAL_MACHINES)] 
     working, spares = machines[:TOTAL_WORKING], machines[TOTAL_WORKING:] 
     spares_inventory = simpy.Store(env, capacity = TOTAL_MACHINES) 
     spares_inventory.items = spares 
     working = [Working(env, i, repair_workshop, spares_inventory, downtime, machine) for i, machine in enumerate(working)] 

     env.run(SIM_TIME) 

     print('Total downtime for all machines throughout simulation time is %.2f hours' % sum(downtime)) 
     print('Operational Availability = %.2f percent' % ((SIM_TIME - sum(downtime)) * 100/(SIM_TIME))) 

    if __name__ == '__main__': 
     main() 

這是我收到的回溯:

Traceback (most recent call last): 
    File "/Users/Scripts/8oct1.py", line 70, in <module> main() 
    File "/Users/Scripts/8oct1.py", line 64, in main env.run(SIM_TIME) 
    File "/Library/Python/2.7/site-packages/simpy/core.py", line 120, in run self.step() 
    File "/Library/Python/2.7/site-packages/simpy/core.py", line 213, in step raise event._value 
    TypeError: __init__() takes exactly 2 arguments (3 given) 
+0

那麼你究竟面臨的問題是什麼? – 2014-10-07 18:31:55

+0

@stefan抱歉讓我離開,這真是我的愚蠢!我已經將問題添加到文本正文中。謝謝! – Craig 2014-10-08 01:30:54

回答

2

您可以使用Store而不是Container。通過Store,您可以爲您的機器使用可區分的對象,這將允許您通過仿真追蹤他們的方式。

例如,

machines = [object() for i in range(TOTAL_MACHINES)] 
working, spares = machines[:TOTAL_WORKING], machines[TOTAL_WORKING:] 
spares_inventory = Store(env, capacity=TOTAL_MACHINES) 
spares_inventory.items = spares 
working = [Working(env, i, machine) for i, machine in enumerate(working)] 

當然,代替object還使用(命名)元組,普通整數或最適合於表示一臺機器的任何其他對象。

+0

您好Stefan,我在我的代碼中實現了上述對main()的更改,但我似乎仍然收到以下錯誤:TypeError:__init __()只需2個參數(給定3);你能幫忙嗎?謝謝! – Craig 2014-10-10 10:39:48

+0

模擬最初幾行運行平穩,但是這個錯誤出現在打印語句'引擎x停止工作'之後。 – Craig 2014-10-10 10:45:58

+0

您能否提供完整的堆棧跟蹤? – 2014-10-11 10:59:30