2015-02-05 48 views
0

我正在使用simpy模擬火車模擬,到目前爲止,單個列車實體已經取得了如下成功。Simpy地鐵模擬:如何解決排隊等候資源時的班列中斷故障?

列車進程是由平臺跟隨的部分。每個部分和平臺的資源爲1,以確保一次只有一列火車利用。

但是我無法找到一個方法來解決以下錯誤:

當我在第二個火車到模擬插件有偶爾的情況,其中一個火車等待不可用的資源,然後失敗在列車正在等待時發生。

我結束了一個中斷:中斷()錯誤。

有沒有解決這些資源故障隊列的方法?

任何幫助,非常感謝。

import random 
import simpy 
import numpy 

# Configure parameters for the model 
RANDOM_SEED = random.seed() # makes results repeatable 

T_MEAN_SECTION = 200.0 # journey time (seconds) 

DWELL_TIME = 30.0 # dwell time mean (seconds) 
DWELL_TIME_EXPO = 1/DWELL_TIME # for exponential distribution 

MTTF = 600.0 # mean time to failure (seconds) 
TTF_MEAN = 1/MTTF # for exponential distribution 

REPAIR_TIME = 120.0 # mean repair time for when failure occurs (seconds) 
REPAIR_TIME_EXPO = 1/REPAIR_TIME # for exponential distribution 

NUM_TRAINS = 2 # number of trains to simulate 

SIM_TIME_HOURS = 1 # sim time in hours 
SIM_TIME_DAYS = SIM_TIME_HOURS/18.0 # number of days to simulate 
SIM_TIME = 3600 * 18 * SIM_TIME_DAYS # sim time in seconds (this is used in the code below) 


# Defining the times for processes 
def Section(): # returns processing time for platform 7 Waterloo to 26 Bank 
    return T_MEAN_SECTION 

def Dwell(): # returns processing time for platform 25 Bank to platform 7 Waterloo 
    return random.expovariate(DWELL_TIME_EXPO) 

def time_to_failure(): # returns time until next failure 
    return random.expovariate(TTF_MEAN) 



# Defining the train 
class Train(object): 

    def __init__(self, env, name, repair): 
     self.env = env 
     self.name = name 
     self.trips_complete = 0 
     self.num_saf = 0 
     self.sum_saf = 0 
     self.broken = False 

    # Start "running" and "downtime_train" processes for the train 
     self.process = env.process(self.running(repair)) 
     env.process(self.downtime_train()) 


    def running(self, repair): 

     while True: 

      # request section A 
      request_SA = sectionA.request() 

########## SIM ERROR IF FAILURE OCCURS HERE ########### 
      yield request_SA 

      done_in_SA = Section()   
      while done_in_SA: 

       try: 
        # going on the trip 
        start = self.env.now 


        print('%s leaving platform at time %d') % (self.name, env.now) 

        # processing time 
        yield self.env.timeout(done_in_SA) 

        # releasing the section resource 
        sectionA.release(request_SA) 
        done_in_SA = 0 # Set to 0 to exit while loop 

       except simpy.Interrupt: 
        self.broken = True 
        delay = random.expovariate(REPAIR_TIME_EXPO) 
        print('Oh no! Something has caused a delay of %d seconds to %s at time %d') % (delay, self.name, env.now) 
        done_in_SA -= self.env.now - start # How much time left? 
        with repair.request(priority = 1) as request_D_SA: 
         yield request_D_SA 
         yield self.env.timeout(delay) 
        self.broken = False 
        print('Okay all good now, failure fixed on %s at time %d') % (self.name, env.now) 
        self.num_saf += 1 
        self.sum_saf += delay 



      # request platform A 
      request_PA = platformA.request() 

########## SIM ERROR IF FAILURE OCCURS HERE ########### 
      yield request_PA 

      done_in_PA = Dwell() 
      while done_in_PA: 

       try: 

        # platform process 
        start = self.env.now 


        print('%s arriving to platform A and opening doors at time %d') % (self.name, env.now) 
        yield self.env.timeout(done_in_PA) 
        print('%s closing doors, ready to depart platform A at %d\n') % (self.name, env.now) 
        # releasing the platform resource 
        platformA.release(request_PA) 
        done_in_PA = 0 # Set to 0 to exit while loop 

       except simpy.Interrupt: 
        self.broken = True 
        delay = random.expovariate(REPAIR_TIME_EXPO) 
        print('Oh no! Something has caused a delay of %d seconds to %s at time %d') % (delay, self.name, env.now) 
        done_in_PA -= self.env.now - start # How much time left? 
        with repair.request(priority = 1) as request_D_PA: 
         yield request_D_PA 
         yield self.env.timeout(delay) 
        self.broken = False 
        print('Okay all good now, failure fixed on %s at time %d') % (self.name, env.now) 
        self.num_saf += 1 
        self.sum_saf += delay 


     # Round trip is finished 

      self.trips_complete += 1 


# Defining the failure event   
    def downtime_train(self): 
     while True: 
      yield self.env.timeout(time_to_failure()) 
      if not self.broken: 
      # Only break the train if it is currently working 
       self.process.interrupt() 



# Setup and start the simulation 
print('Train trip simulator') 
random.seed(RANDOM_SEED) # Helps with reproduction 

# Create an environment and start setup process 
env = simpy.Environment() 

# Defining resources 
platformA = simpy.Resource(env, capacity = 1) 
sectionA = simpy.Resource(env, capacity = 1) 

repair = simpy.PreemptiveResource(env, capacity = 10) 

trains = [Train(env, 'Train %d' % i, repair) 
    for i in range(NUM_TRAINS)] 


# Execute 
env.run(until = SIM_TIME) 

回答

1

您的進程請求資源,並且從不釋放它。這就是爲什麼第二列火車會一直等待其成功的要求。在等待時,失敗過程似乎中斷了過程。這就是爲什麼你會得到一個錯誤。請閱讀guide to resources瞭解SimPy的資源如何工作,尤其是在完成後如何發佈資源。

+0

感謝您的回覆Stefan。然而,資源在試用時發佈:低於請求的地方。這似乎工作得很好,因爲列車在循環中很好地處理了這兩個過程......直到在其中一個列車上發生故障,如果它正在爲資源排隊。 – bobo 2015-02-05 20:40:13

+0

好吧,現在我可以看到您發佈請求的位置。問題仍然是列車在等待request_SA或request_PA時被故障過程中斷。例如,你可以使用'try ...包裝'yield request_SA',除了simpy.Interrupt:pass'來忽略它。 – 2015-02-06 08:24:59

+0

謝謝你完美的解決了這個問題! – bobo 2015-02-06 10:57:36