1

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)
Riccardo Bucco
  • 13,980
  • 4
  • 22
  • 50
nesquess
  • 39
  • 4

2 Answers2

1

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.

superman
  • 231
  • 2
  • 3
0

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

Michael
  • 1,671
  • 2
  • 4
  • 8