Search code examples
pythonsimpy

"Weighting" the amount of a SimPy Resource to use for a process


I would like to send orders to a Resource in SimPy, which specify a quantity of products that the Resource would manufacture.

My issue is that when I send an order of 100 quantity, the resource is only utilized for the 1 order rather than utilized for the 100 quantity. Is there a way to model this in SimPy?

I understand how to use Containers and Stores rather than a Resource Resource, but for my larger application I would like this to be a resource since different product inventory levels would be stored in Container levels. This resource would be shared among multiple products.

Here is the mocked up simple example for my question above. Thanks! If I could add plan_for_hour_x as the parameter for processing_capacity.request(plan_for_hour_x), that would solve my problem, but that does not seem to be possible.

import simpy
env = simpy.Environment()
processing_capacity_per_hour = simpy.Resource(env, capacity=1000)
DEMAND_IN_HOUR_1 = 100

def production_plan(env, processing_capacity, plan_for_hour_x): 
    yield env.timeout(1)
    print(f'The current time is {env.now}')
    with processing_capacity.request() as req:
        yield req
        print(f'Resources in use 1: {processing_capacity.count}')
        yield env.timeout(1)
            
env.process(production_plan(env, 
                            processing_capacity_per_hour, 
                            DEMAND_IN_HOUR_1))
env.run(until=5)
print(f'The ending time is {env.now}')

>>> The current time is 1
>>> Resources in use 1: 1
>>> The ending time is 5

Solution

  • If you are trying to seize 100 resources in one grab then do this

    import simpy
    from simpy.events import AllOf
    env = simpy.Environment()
    processing_capacity_per_hour = simpy.Resource(env, capacity=1000)
    DEMAND_IN_HOUR_1 = 100
    
    def production_plan(env, processing_capacity, plan_for_hour_x): 
        yield env.timeout(1)
        print(f'The current time is {env.now}')
    
        req_list = [processing_capacity.request() for _ in range(plan_for_hour_x)]
        
        yield AllOf(env, req_list)
        print(f'Resources in use: {processing_capacity.count}')
        yield env.timeout(1)
    
        for req in req_list:
            processing_capacity.release(req)
    
        print(f'Resources in use: {processing_capacity.count}')
                
    env.process(production_plan(env, 
                                processing_capacity_per_hour, 
                                DEMAND_IN_HOUR_1))
    env.run(until=5)
    print(f'The ending time is {env.now}')
    

    this will print

    The current time is 1
    Resources in use: 100
    Resources in use: 0
    The ending time is 5
    

    but it sounds like a container might be a better choice over a resource