Hello,CSDN的各位小伙伴们,拖更了几年后,又重新开始记录这段时间准备学习的东西啦!最近博主在学习 SimPy 的相关知识,发现国内关于 SimPy 的介绍还是相对较少,且缺乏系统性,因此博主打算用1~2周的时间,边学边记,打算从 SimPy 官方给出的几个例子出发分析 SimPy 的使用场景和用法,希望能和大家互勉!那废话不多说,我们直接开始吧!今天要学习的例程是 Bank Renege
例程背景
这个example最初的流程是这样的:有一个银行,银行里面只有一个柜台 (Counter),众多顾客以一个随机时间到达银行,柜台一次只能服务一个用户,并会消耗一定的服务时间。抵达银行的顾客如果发现柜台有人,则需要排队等候。而每一个顾客的等待时间是有限制的,如果超过一定的时间后还没有轮到自己,那么该顾客就会离开。我们的目的就是用 SimPy 对这个流程进行建模。
例程代码分析
首先自然是导入一些必要的模块,这里不再赘述
import simpy
import random
接下来我们定义一些仿真相关的参数:
RANDOM_SEED = 2024 # 随机种子
NUM_OF_CUSTOMERS = 5 # 仿真过程中顾客的总数量
INTERVAL_CUSTOMERS = 10.0 # 每个顾客的到达时间大致相差10s
MIN_PATIENCE = 1 # 顾客的最小允许等待时间
MAX_PATIENCE = 3 # 顾客的最大允许等待时间
下面是整个仿真的关键部分:我们首先来定义单个用户的行为。即在用户到达银行后,他的一些行为。用户到达银行后,先会看counter资源是否空闲,如果空闲,则直接开始使用柜台一段时间,用完柜台后释放柜台资源。如果柜台正在被占用,那么用户就会等待,如果在允许的时间内等到了空闲的counter,那么就开始使用;否则用户将离开。
我们来看看这部分代码怎么写的:
def customer(env, name, counter, time_in_bank):
"""
定义用户的行为 (排队等待,使用柜台,离开等)
:param env: 仿真环境
:param name: 用户的标识号
:param counter: 柜台资源
:param time_in_bank: 用户使用柜台的时间
:return:
"""
arrival_time = env.now # 用户抵达银行的时间
print('Customer: ', name, ' arrive the bank at: ', arrival_time)
with counter.request() as req:
patience = random.uniform(MIN_PATIENCE, MAX_PATIENCE) # 定义该用户的允许等待时间
results = yield req | env.timeout(patience)
waiting_time = env.now - arrival_time # 该用户的等待时间
if req in results:
# 说明用户等到了counter
print('Customer: ', name, ' is ready to use the counter at: ', env.now)
tib = random.expovariate(1.0 / time_in_bank) # 用户使用柜台的时间
yield env.timeout(tib)
print('Customer: ', name, ' finished at: ', env.now)
else:
# 说明等待时间超过了用户的最大允许等