0

我正在 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)
4

1 回答 1

1

Your processes request a resource and never release it. That’s why the second trains waits forever for its request to succeed. While it is waiting, the failure process seems to interrupt the process. That’s why you get an error. Please read the guide to resources to understand how SimPy’s resources work and, especially, how to release a resource when you are done.

于 2015-02-05T19:25:46.697 回答