我目前正在研究一种模型,该模型模拟了在simpy中整个操作一天的交付过程。运送是由骑手进行的,他们一次只交付一个包裹。包裹需要在特定的时间窗口内交付。此外,该系统整天都在处理不断波动的需求。因此,我想调整现行制度的雇员人数,以配合每小时不断波动的需求。我把骑手建模成一种有一定能力的资源。在模拟运行过程中是否有可能调整资源的容量,或者是否有其他方法可以用我的系统对骑手进行建模?
我已经在simpy文档、示例或其他帖子中寻找了可能的解决方案。然而,我还没有成功。因此,对于任何建议或可能的解决方案,我将非常感激!提前谢谢你。
发布于 2022-05-31 01:45:02
使用存储而不是资源。资源有固定数量的资源。商店的工作方式有点像带有可选最大容量的列表的队列。若要减少存储中的数量,只需停止将对象放回存储区。
举个例子,我用一个类包装了一个商店来管理骑手的数量。
"""
Simple demo of a pool of riders delivering packages where the
number of riders can change over time
Idel riders are keep in a store that is wrapped in a class
to manage the number of riders
Programmer Michael R. Gibbs
"""
import simpy
import random
class Rider():
"""
quick class to track the riders that deliver packanges
"""
# tranks the next id to be assiend to a rider
next_id = 1
def __init__(self):
self.id = Rider.next_id
Rider.next_id += 1
class Pack():
"""
quick class to track the packanges
"""
# tranks the next id to be assiend to a pack
next_id = 1
def __init__(self):
self.id = Pack.next_id
Pack.next_id += 1
class RiderPool():
"""
Pool of riders where the number of riders can be changed
"""
def __init__(self, env, start_riders=10):
self.env = env
# tracks the number of ridres we need
self.target_cnt = start_riders
# tracks the number of riders we have
self.curr_cnt = start_riders
# the store idel riders
self.riders = simpy.Store(env)
# stores do not start with objects like resource pools do.
# need to add riders yourself as part of set up
self.riders.items = [Rider() for _ in range(start_riders)]
def add_rider(self):
"""
Add a rider to the pool
"""
self.target_cnt += 1
if self.curr_cnt < self.target_cnt:
# need to add a rider to the pool to get to the target
rider = Rider()
self.riders.put(rider)
self.curr_cnt += 1
print(f'{env.now:0.2f} rider {rider.id} added')
else:
# already have enough riders,
# must have tried to reduce the rider pool while all riders were busy
# In effect we are cancelling a previous remove rider call
print(f'{env.now:0.2f} keeping rider scheduled to be removed instead of adding')
def remove_rider(self):
"""
Remove a ridder from the pool
If all the riders are busy, the actual removal of a rider
will happen when a that rider finishes it current task and is
tried to be put/returned back into the pool
"""
self.target_cnt -= 1
if self.curr_cnt > self.target_cnt:
if len(self.riders.items) > 0:
# we have a idel rider that we can remove now
rider = yield self.riders.get()
self.curr_cnt -= 1
print(f'{env.now:0.2f} rider {rider.id} removed from store')
else:
# wait for a rider th be put back to the pool
pass
def get(self):
"""
Get a rider from the pool
returns a get request that can be yield to, not a rider
"""
rider_req = self.riders.get()
return rider_req
def put(self, rider):
"""
put a rider pack into the pool
"""
if self.curr_cnt <= self.target_cnt:
# still need the rider
self.riders.put(rider)
else:
# have tool many riders, do not add back to pool
self.curr_cnt -= 1
print(f'{env.now:0.2f} rider {rider.id} removed on return to pool')
def gen_packs(env, riders):
"""
generates the arrival of packages to be delivered by riders
"""
while True:
yield env.timeout(random.randint(1,4))
pack = Pack()
env.process(ship_pack(env, pack, riders))
def ship_pack(env, pack, riders):
"""
The process of a rider delivering a packages
"""
print(f'{env.now:0.2f} pack {pack.id} getting rider')
rider = yield riders.get()
print(f'{env.now:0.2f} pack {pack.id} has rider {rider.id}')
# trip time
yield env.timeout(random.randint(5,22))
riders.put(rider)
print(f'{env.now:0.2f} pack {pack.id} delivered')
def rider_sched(env, riders):
"""
Changes the number of riders in rider pool over time
"""
yield env.timeout(30)
# time to remove a few riders
print(f'{env.now:0.2f} -- reducing riders')
print(f'{env.now:0.2f} -- request queue len {len(riders.riders.get_queue)}')
print(f'{env.now:0.2f} -- rider store len {len(riders.riders.items)}')
for _ in range(5):
env.process(riders.remove_rider())
yield env.timeout(60)
# time to add back some riders
print(f'{env.now:0.2f} -- adding riders ')
for _ in range(2):
riders.add_rider()
# run the model
env = simpy.Environment()
riders = RiderPool(env, 10)
env.process(gen_packs(env, riders))
env.process(rider_sched(env, riders))
env.run(100)
print(f'{env.now:0.2f} -- end rider count {riders.target_cnt}')https://stackoverflow.com/questions/72439540
复制相似问题