SimPy 中的可选资源
Optional resources within a SimPy
我正在使用 Simpy 进行离散事件模拟,但我遇到了一些问题,我最好将其描述为可选资源。上下文是我正在模拟将要执行的任务,并将需要一些资产(资源)来执行该任务。与大多数 SimPy 实施不同,任务需要在分配的时间开始,否则会失败,并且可能会接受较少的资源来启动任务。
例如,一个任务在时间 = t 时需要四辆车。在时间 t 只有三辆车可用,因此任务以三辆车开始,但结果较差。如果只有两辆或更少的车辆可用,任务将不会继续并被视为失败。
抱歉,此示例中缺少代码,我正在努力解决这个问题。任何帮助将不胜感激。
我使用容器来跟踪资源,但看看这是否是您想要的,请告诉我
"""
Demos checking the availability of resources befor taking resouces
Each agent has a first choice and second choice for seizing resources
if neither choice is avalale will not wait and skip getting resources
programmer: Michael R. Gibbs
"""
import simpy
import random
def eval(choice, containers):
"""
steps through each requirement and checks if there is enough resouces is available
returns True if there is enough, else returns False
"""
for k,v in choice.items():
if containers[k].level < v:
# not enough
return False
return True
def mission(env, id, firstChoice, secondChoice, startDelay, missingTime, containers):
"""
Sims agent checking if first or second choice of resouces is available
If so, will seize the resources, hold for a time, and then release the resouces
"""
choice = None # which choice to use
# wait for mission start
yield env.timeout(startDelay)
print()
print(f'{env.now} agent {id} is starting a mission')
x = [(k, v.level) for k, v in containers.items()]
print(f'available: {x}')
print(f'first choice {firstChoice}')
print(f'second choice {secondChoice}')
# evaluate the choices and see if either will work
if eval(firstChoice, containers):
choice = firstChoice
print(f'{env.now} agent {id} is going with first Choice')
else:
if eval(secondChoice,containers):
choice = secondChoice
print(f'{env.now} agent {id} is going with second Choice')
else:
print(f'{env.now} agent {id} is abort because not enough resources')
if choice is not None:
# found a choice that works
# seize the resouces, we checked that they are availale, so there should not be any queue time
for k,v in choice.items():
containers[k].get(v)
yield env.timeout(missingTime)
# return resouces
for k,v in choice.items():
containers[k].put(v)
print(f'{env.now} agent {id} has finished the mission ')
def build_choice():
"""
quick helper to generate random first and second choice requirements
(may not use all three resouces)
returns a dictionary of the requirements where key=type, value=how much
"""
choice = {}
while len(choice) == 0:
for k in ['A','B','C']:
v = random.randint(0,3)
if v > 0:
choice[k] = v
return choice
def gen_missions(env, containers):
"""
Generate a series of agents to seize the resources
"""
i = 0
while True:
i += 1 # id generator
firstChoice = build_choice()
secondChoice = build_choice()
env.process(mission(env,i,firstChoice,secondChoice,random.randint(1,4),random.randint(2,8),containers))
# put some time between agents
yield env.timeout(1)
env = simpy.Environment()
# load the resouces
containers = {}
containers['A'] = simpy.Container(env, init=10, capacity=10)
containers['B'] = simpy.Container(env, init=10, capacity=10)
containers['C'] = simpy.Container(env, init=10, capacity=10)
# start generating agents
env.process(gen_missions(env,containers))
env.run(100)
我正在使用 Simpy 进行离散事件模拟,但我遇到了一些问题,我最好将其描述为可选资源。上下文是我正在模拟将要执行的任务,并将需要一些资产(资源)来执行该任务。与大多数 SimPy 实施不同,任务需要在分配的时间开始,否则会失败,并且可能会接受较少的资源来启动任务。
例如,一个任务在时间 = t 时需要四辆车。在时间 t 只有三辆车可用,因此任务以三辆车开始,但结果较差。如果只有两辆或更少的车辆可用,任务将不会继续并被视为失败。
抱歉,此示例中缺少代码,我正在努力解决这个问题。任何帮助将不胜感激。
我使用容器来跟踪资源,但看看这是否是您想要的,请告诉我
"""
Demos checking the availability of resources befor taking resouces
Each agent has a first choice and second choice for seizing resources
if neither choice is avalale will not wait and skip getting resources
programmer: Michael R. Gibbs
"""
import simpy
import random
def eval(choice, containers):
"""
steps through each requirement and checks if there is enough resouces is available
returns True if there is enough, else returns False
"""
for k,v in choice.items():
if containers[k].level < v:
# not enough
return False
return True
def mission(env, id, firstChoice, secondChoice, startDelay, missingTime, containers):
"""
Sims agent checking if first or second choice of resouces is available
If so, will seize the resources, hold for a time, and then release the resouces
"""
choice = None # which choice to use
# wait for mission start
yield env.timeout(startDelay)
print()
print(f'{env.now} agent {id} is starting a mission')
x = [(k, v.level) for k, v in containers.items()]
print(f'available: {x}')
print(f'first choice {firstChoice}')
print(f'second choice {secondChoice}')
# evaluate the choices and see if either will work
if eval(firstChoice, containers):
choice = firstChoice
print(f'{env.now} agent {id} is going with first Choice')
else:
if eval(secondChoice,containers):
choice = secondChoice
print(f'{env.now} agent {id} is going with second Choice')
else:
print(f'{env.now} agent {id} is abort because not enough resources')
if choice is not None:
# found a choice that works
# seize the resouces, we checked that they are availale, so there should not be any queue time
for k,v in choice.items():
containers[k].get(v)
yield env.timeout(missingTime)
# return resouces
for k,v in choice.items():
containers[k].put(v)
print(f'{env.now} agent {id} has finished the mission ')
def build_choice():
"""
quick helper to generate random first and second choice requirements
(may not use all three resouces)
returns a dictionary of the requirements where key=type, value=how much
"""
choice = {}
while len(choice) == 0:
for k in ['A','B','C']:
v = random.randint(0,3)
if v > 0:
choice[k] = v
return choice
def gen_missions(env, containers):
"""
Generate a series of agents to seize the resources
"""
i = 0
while True:
i += 1 # id generator
firstChoice = build_choice()
secondChoice = build_choice()
env.process(mission(env,i,firstChoice,secondChoice,random.randint(1,4),random.randint(2,8),containers))
# put some time between agents
yield env.timeout(1)
env = simpy.Environment()
# load the resouces
containers = {}
containers['A'] = simpy.Container(env, init=10, capacity=10)
containers['B'] = simpy.Container(env, init=10, capacity=10)
containers['C'] = simpy.Container(env, init=10, capacity=10)
# start generating agents
env.process(gen_missions(env,containers))
env.run(100)