【问题标题】:Inventory simulation using SimPy使用 SimPy 进行库存模拟
【发布时间】:2020-06-04 08:39:02
【问题描述】:

我想知道我在 SimPy 代码上做错了什么?当我更改 interarrivalTime_DR > 1.5 时,代码被挂起。如果我更改 interarrivalTime_DR

有人可以帮忙吗?

    import simpy
    import numpy as np
    import random
    import math

    class P:
        externalToDRMean = 1/2
        DRorderLotSize = 10
        externalToBUMean = 5/60
        BUorderLotSize = 20
        BU_Q = 100
        DR_Q = 20
        ROP_BU = 20+(200/30)*7
        ROP_DR = 10+(150/30)*`
        BU_LT = 7 
        DR_LT = 2
        simulationTimeMax = 1 * 30


    class S:
        Inv = None
        DRwaits = []
        BUwaits = []
        nBUCustomers = 0
        nDRCustomers = 0
        BU_Dem_day = list(np.repeat(0, P.simulationTimeMax))
        DR_Dem_day = list(np.repeat(0, P.simulationTimeMax))

    class Inventory:

        def __init__(self, env):
            self.env = env
            self.SP_inv = simpy.Container(env, init = 10000)
            self.BU_inv = simpy.Container(env, init = P.ROP_BU)
            self.DR_inv = simpy.Container(env, init = P.ROP_DR)
            self.mon_procBU = env.process(self.monitor_BU_inv(env))
            self.mon_procDR = env.process(self.monitor_DR_inv(env))

        def monitor_BU_inv(self, env):
            while True:
                #print(f"BU_Inv level:{self.BU_inv.level}")
                if self.BU_inv.level <= P.ROP_BU:
                    print("Time {0}: BU inventory reached ROP: BU places replenishment order to Supply".format(self.env.now))
                    yield self.SP_inv.get(P.BU_Q)
                    print("Time {0}: Supply fills BU replenishment request".format(self.env.now))
                    yield self.env.timeout(P.BU_LT)
                    print("Time {0}: BU replenishment inventory arrives".format(self.env.now))
                    yield self.BU_inv.put(P.BU_Q)
                    print("Time {0}: BU replenishment order is added to inventory".format(self.env.now))
                    yield self.env.timeout(1)

        def monitor_DR_inv(self, env):
            while True:
                if self.DR_inv.level <= P.ROP_DR:
                    print("Time {0}: DR inventory reached ROP: DR places replenishment order to BU".format(self.env.now))
                    yield self.BU_inv.get(P.DR_Q)
                    print("Time {0}: BU fills DR replenishment request".format(self.env.now))
                    yield self.env.timeout(P.DR_LT)
                    print("Time {0}: DR replenishment inventory arrives from BU".format(self.env.now))
                    yield self.DR_inv.put(P.DR_Q)
                    print("Time {0}: DR replenishment order is added to inventory".format(self.env.now)) 
                    yield self.env.timeout(1)

    class DRCustomer(object):

        def __init__(self, env, name = ''):
            self.env = env
            self.action = self.env.process(self.ordertoDR())
            if (name==''):
                self.name = 'RandomDRCustomer' + str(random.randint(100))
            else:
                self.name = name

        def DRorderToBU(self):
            print("Time {1}: DR places order to BU to fill order for {0}".format(self.name, self.env.now))
            yield S.Inv.BU_inv.get(P.DRorderLotSize)
            yield self.env.timeout(P.DR_LT)
            yield S.Inv.DR_inv.put(P.DRorderLotSize)

        def ordertoDR(self):
            startTime_DR = self.env.now
            j = math.floor(self.env.now)
            S.DR_Dem_day[j] += 1
            print("Time {1}: {0} places order to DR".format(self.name, self.env.now))
            if S.Inv.DR_inv.level < P.DRorderLotSize:
                self.env.process( self.DRorderToBU() )
            yield S.Inv.DR_inv.get(P.DRorderLotSize)
            print("Time {1}: {0} receives order from DR".format(self.name, self.env.now ))
            waitTime_DR = self.env.now - startTime_DR
            print("{0} had to wait {1} days".format(self.name, waitTime_DR))
            S.DRwaits.append( waitTime_DR )

     class BUCustomer(object):

         def __init__(self, env, name = ''):
             self.env = env
             self.action = self.env.process( self.ordertoBU() )
             if (name == ''):
                 self.name = 'RandomBUCustomer' + str(random.randint(100))
             else:
                 self.name = name

         def BUorderToSupply(self):
             print("Time {1}: BU places order to Supplier to fill order for {0}".format(self.name, self.env.now))
             yield S.Inv.SP_inv.get(P.BUorderLotSize)
             yield self.env.timeout(P.BU_LT)
             yield S.Inv.BU_inv.put(P.BUorderLotSize)

         def ordertoBU(self):
             startTime_BU = self.env.now
             i = math.floor(self.env.now)
             S.BU_Dem_day[i] += 1
             print("Time {1}: {0} places order to BU".format(self.name, self.env.now))
             print(f"****** {S.Inv.BU_inv.level} ---- {P.BUorderLotSize}")
             if S.Inv.BU_inv.level < P.BUorderLotSize:
                 self.env.process( self.BUorderToSupply() )
             yield S.Inv.BU_inv.get(P.BUorderLotSize)
             print("Time {1}: {0} receives order".format(self.name, self.env.now))
             waitTime_BU = self.env.now - startTime_BU
             print("{0} had to wait {1} days".format(self.name, waitTime_BU ))
             S.BUwaits.append( waitTime_BU )

    class DROrderProcessor(object):

        def __init__(self, env, DRlambda):
            self.env = env
            self.action = env.process(self.DREntrance())
            self.lam = DRlambda

        def DREntrance(self):
            while True:
                interarrivalTime_DR = 1.6#np.random.exponential(1/P.externalToDRMean)
                print(f"interarrivalTime_DR:  {interarrivalTime_DR}")
                print()
                yield self.env.timeout( interarrivalTime_DR )
                c = DRCustomer(self.env, name = "DRCustomer {0}".format(S.nDRCustomers))
                S.nDRCustomers += 1

    class BUOrderProcessor(object):

        def __init__(self, env, BUlambda):
            self.env = env
            self.action = env.process(self.BUEntrance())
            self.lam = BUlambda

        def BUEntrance(self):
            while True:
                interarrivalTime_BU = 1#np.random.exponential(1/P.externalToBUMean)
                yield self.env.timeout( interarrivalTime_BU )
                c = BUCustomer(self.env, name = "BUCustomer {0}".format(S.nBUCustomers))
                S.nBUCustomers += 1

    randomSeed=123
    random.seed(randomSeed)
    S.DRwaits = []
    S.BUwaits = []
    envr = simpy.Environment()
    BU = BUOrderProcessor(envr, BUlambda = P.externalToBUMean)
    DR = DROrderProcessor(envr, DRlambda = P.externalToDRMean)
    S.Inv = Inventory(envr)
    envr.run(until = P.simulationTimeMax)

【问题讨论】:

  • 请编辑您的问题;删除“xxxx”并添加有关您的程序的全部内容的更多详细信息。否则,其他人很难理解代码。解释一下,程序的正确行为是什么......以及如果它的行为不符合预期会发生什么。
  • 我正在尝试模拟来自dc.etsu.edu/cgi/viewcontent.cgi?article=4651&context=etd 的库存流。在我运行代码后,程序运行了一些模拟并在 interarrivalTime_DR 为 1.6 及以上时挂起。但是当 interarrivalTime_DR 低于 1.5 时工作正常。

标签: simulation inventory simpy


【解决方案1】:

函数def monitor_BU_inv(self, env)def monitor_DR_inv(self, env) 中最后一行的缩进不正确。 yield self.env.timeout(1) 行不应在 if-statement 内,以避免当 if-statement 评估为 false 时出现无限循环。

def monitor_BU_inv(self, env):
     while True:
         if self.BU_inv.level <= P.ROP_BU:
             print("Time {0}: BU inv...".format(self.env.now))
             yield self.SP_inv.get(P.BU_Q)
             print("Time {0}: Supply fills BU ...".format(self.env.now))
             yield self.env.timeout(P.BU_LT)
             print("Time {0}: BU replenishment...".format(self.env.now))
             yield self.BU_inv.put(P.BU_Q)
             print("Time {0}: BU replenishment ...".format(self.env.now))
          yield self.env.timeout(1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-03
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-12
    相关资源
    最近更新 更多