如何在SimPy模拟流程中设置营业前的初始排队队列?
在SimPy银行排队模拟中添加初始队列的实现方法
当然可以在SimPy模拟中创建初始队列。针对你提出的银行9:00营业时已有20位顾客等待的需求,只需要在模拟启动阶段直接生成指定数量的初始顾客进程,再保留原有的随机到达逻辑处理后续顾客即可。
修改思路
- 定义初始顾客数量参数,在模拟启动时(对应银行开门时间,即
env.now=0)批量创建这些顾客并启动他们的排队流程,不需要等待到达间隔。 - 调整后续顾客的编号逻辑,避免和初始顾客重复。
- 保留原有的多队列选择、服务时间逻辑,确保初始顾客和后续顾客的行为一致。
修改后的完整代码
""" Bank with multiple queues and initial customers example Covers: - Resources: Resource - Iterating processes - Initial queue setup Scenario: A multi-counter bank with 20 initial customers waiting at opening time, plus random customer arrivals afterwards. Based on the program bank10.py from TheBank tutorial of SimPy 2. (KGM) Modified to support initial queue """ from simpy import * import random initial_customers = 20 # 开门时已等待的顾客数量 followup_customers = 30 # 后续到达的顾客数量 maxTime = 400.0 # 模拟总时长(分钟) timeInBank = 20.0 # 平均服务时长(分钟) arrivalMean = 10.0 # 后续顾客平均到达间隔(分钟) seed = 12345 # 随机种子 def Customer(env, name, counters): arrive = env.now Qlength = [NoInSystem(counters[i]) for i in range(len(counters))] print("%7.4f %s: 到达,各队列人数:%s" % (env.now, name, Qlength)) # 选择最短的队列(优先空队列) choice = Qlength.index(min(Qlength)) with counters[choice].request() as req: # 等待叫号 yield req wait = env.now - arrive print('%7.4f %s: 等待时长 %6.3f 分钟' % (env.now, name, wait)) # 生成随机服务时长 tib = random.expovariate(1.0 / timeInBank) yield env.timeout(tib) print('%7.4f %s: 办理完成' % (env.now, name)) def NoInSystem(R): """计算资源R中的总顾客数(排队+正在办理)""" return max([0, len(R.put_queue) + len(R.users)]) def Source(env, start_number, number, interval, counters): """生成后续到达的顾客,编号从start_number开始""" for i in range(start_number, start_number + number): c = Customer(env, f'顾客{i:02d}', counters) env.process(c) # 生成下一位顾客的到达间隔(指数分布) t = random.expovariate(1.0 / interval) yield env.timeout(t) # 初始化并启动模拟 print('带初始队列的多柜台银行模拟') random.seed(seed) env = Environment() # 创建两个柜台资源 counters = [Resource(env), Resource(env)] # 生成初始顾客(开门时直接到达) for i in range(initial_customers): env.process(Customer(env, f'初始顾客{i:02d}', counters)) # 启动后续顾客生成进程,从编号20开始 env.process(Source(env, initial_customers, followup_customers, arrivalMean, counters)) # 运行模拟 env.run(until=maxTime)
关键修改说明
- 初始顾客生成:在模拟启动时,通过循环直接创建20个
Customer进程并启动,这些顾客会在env.now=0(对应9:00)时立刻进入队列选择逻辑,形成初始等待队列。 - 编号区分:初始顾客命名为「初始顾客XX」,后续顾客从编号20开始命名为「顾客XX」,避免混淆。
- 队列选择优化:用
Qlength.index(min(Qlength))简化了原有的队列选择逻辑,效果和原代码一致,更简洁。 - 参数拆分:把原
maxNumber拆分为initial_customers和followup_customers,更清晰区分初始和后续顾客数量。
时间对应说明
模拟中的时间0对应银行开门的9:00,时间单位为分钟,maxTime=400即模拟银行营业400分钟(约6小时40分钟)的场景。
内容的提问来源于stack exchange,提问作者Andrea Ciufo
相关产品推荐
相关产品推荐

