Dear all,
I am using Python and Simpy for a simulation. In the simulation jobs are processed by resources. Some jobs require a single resource, other jobs require multiple resources at the same time. I would like to retrieve (get / request) multiple resources at the same time. I've asked a similar question on
stack overflow, but received no response.
In the example below resources are requested sequentially. As a consequence, job 3 is started before job 2 at time 5 even though job 2 could have started at time 4 because resource 2 became available at time 4.
I am trying to achieved the desired sequence [1, 3, 2, 4].
I am able achieve the desired sequence by prioritizing jobs which request fewer resources (e.g. priority=len(resources_required)). However, that would mean that jobs which require fewer resources get prioritized over jobs which require more resources even if these jobs were generated earlier. I am looking for a solution which preserves the first-come, first served (fcfs) sequence. I only want to prioritize the job that requires fewer resources if jobs that were generated earlier still have to wait for other resources.
I thought about delaying the requests, as suggested
here, but I don't know how to go about this.
Thanks,
nkz
Code:
import simpy
import random
def source(env, jobs):
count = 0
for i in jobs:
env.process(job(env, count, i))
yield env.timeout(1)
count += 1
def job(env, count, resources_required):
print('job: {} requests resources: {} at time: {}'.format(count, resources_required, env.now))
resources_needed = []
for i in resources_required:
for j in resources:
if i == j['id']:
resources_needed.append(j['resource'].request())
yield env.all_of(resources_needed)
print('job: {} retrieved resources: {} at time: {}'.format(count, resources_required, env.now))
yield env.timeout(4)
for i in resources_needed:
i.resource.release(i)
print('job: {} released resources: {} completed at time: {}'.format(count, resources_required, env.now))
sequence.append(count)
env = simpy.Environment()
resources = []
capacity = 1
for i in range(5):
resource = {
'id': i,
'resource': simpy.PriorityResource(env, capacity=capacity)
}
resources.append(resource)
jobs = [
[2],
[0],
[2, 0],
[2]
]
sequence = []
random.seed(1234567890)
env.process(source(env, jobs))
env.run(until=50)
print('...')
print('current sequence: {}'.format(sequence))
Output:
job: 0 requests resources: [2] at time: 0
job: 0 retrieved resources: [2] at time: 0
job: 1 requests resources: [0] at time: 1
job: 1 retrieved resources: [0] at time: 1
job: 2 requests resources: [2, 0] at time: 2
job: 3 requests resources: [2] at time: 3
job: 0 released resources: [2] completed at time: 4
job: 1 released resources: [0] completed at time: 5
job: 2 retrieved resources: [2, 0] at time: 5
job: 2 released resources: [2, 0] completed at time: 9
job: 3 retrieved resources: [2] at time: 9
job: 3 released resources: [2] completed at time: 13
...
current sequence: [0, 1, 2, 3]
...
desired sequence: [0, 1, 3, 2]