Creating as many events as needed in Simpy simulation

Viewed 195

I am working on a python simulation using Simpy but I am having somewhat of a brick wall. The simulation has an arrival process and a shipping process. The goal is to ship as many orders as they arrive and not leave orders waiting. This code gives me a process that ships more orders than they arrive.

class LC:
    def __init__(self,env):
        self.dispatch=simpy.Container(env,capacity=100000, init=0)
        self.costs=simpy.Container(env, capacity=100000, init=0)
        self.shipment_count=simpy.Container(env,capacity=10000, init=0)
        self.orders=simpy.Container(env,capacity=10000,init=0)
def shipping(env, ship):
    while True:
        #yield env.timeout(i)
        print('Shipment was sent at %d' % (env.now))
        time,weight=get_weight_n_time() ####other function that assigns weight and time of shipment
        if weight <=35:
            cost=get_cost(weight,0)###other function that calculates costs 
        else:
            cost=get_cost(weight,1)
        yield env.timeout(time)
        print ('Shipment of %d kgs where delivered after %d days with cost of $ %d' %(weight,time,cost))
        yield ship.dispatch.put(weight)
        yield ship.orders.get(1)
        yield ship.costs.put(cost)
        yield ship.shipment_count.put(1)

def arrival (env,ship):
    while True:
        print('Order arrived at %d'%(env.now))
        yield ship.orders.put(1)
        yield env.timeout(1)
        

def shipment_gen(env,ship):
    
        env.process(arrival(env,ship))
        num_trucks=5
        for i in range(num_trucks):
           env.process(shipping(env,ship))
           yield env.timeout(0)
        
env = simpy.Environment()
ship=LC(env)
env.process(shipment_gen(env,ship))    
env.run(until=100)

when I add a variable to determine weather or not to make a shipment based in the # of orders then the shipment process does not occur

class LC:
    def __init__(self,env):
        self.dispatch=simpy.Container(env,capacity=100000, init=0)
        self.costs=simpy.Container(env, capacity=100000, init=0)
        self.shipment_count=simpy.Container(env,capacity=10000, init=0)
        self.orders=simpy.Container(env,capacity=10000,init=0)
        self.order=0
def shipping(env, ship):
    while True:
        #yield env.timeout(i)
        print('Shipment was sent at %d' % (env.now))
        time,weight=get_weight_n_time()
        if weight <=35:
            cost=get_cost(weight,0)
        else:
            cost=get_cost(weight,1)
        yield env.timeout(time)
        print ('Shipment of %d kgs where delivered after %d days with cost of $ %d' %(weight,time,cost))
        yield ship.dispatch.put(weight)
        yield ship.orders.get(1)
        yield ship.costs.put(cost)
        yield ship.shipment_count.put(1)

def arrival (env,ship):
    while True:
        print('Order arrived at %d'%(env.now))
        yield ship.orders.put(1)
        yield env.timeout(1)
        ship.order+=1
        

def shipment_gen(env,ship):
    
        env.process(arrival(env,ship))
        # if ship.orders.level >0:
        #     num_trucks=get_number_trucks(ship)
        # else:
        #     num_trucks=get_number_trucks(ship)
        num_trucks=5
        for i in range(num_trucks):
            if ship.order>0:
                env.process(shipping(env,ship))
                yield env.timeout(0)
                ship.order-=1
            else:
                print('-')
env = simpy.Environment()
ship=LC(env)
env.process(shipment_gen(env,ship))    
env.run(until=100)
2 Answers

You do not need to add extra ship.order in the class. The container has the information about the number of orders(ship.orders.level).So delete the ship.order and delete the loop in shipment_gen ,your code will be executed normally. By using of multi-thread,the multi-process is realized by Simpy. If you add extra variable in the ship class,it may lead to errors.

do you want to move your

yield ship.orders.get(1)

line to the top of the function so your truck waits for a order to arrive before it does anything else?

also shipment_gen is doing its if statement at time 0, but your order counter is not =+1 till time 1 so at time 0 your order counter is still 0 so your if will always do the else

Related