Python 您所在的位置:网站首页 排队模型数学建模 Python

Python

2024-06-29 14:06| 来源: 网络整理| 查看: 265

数模准备过程中,写了这种运筹学仿真的代码,虽然自己选了C题没有用到,但考虑到市面上存在的仿真代码较少,聊以为分享。

文档介绍

本文档使用了Python的离散事件仿真库对于排队论模型进行了仿真

仿真的主要目的是提供个性化定制,如对分布的设定,对排队规则的设定等。通过蒙特卡洛模拟得到复杂规则下难以得到的数值解。

本文档提供了:

基础排队模型仿真

Erlang分布实现

通用分布函数适配器

工具库

库依赖

代码语言:javascript复制from numpy.random import * from simpy import *

高阶函数随机数生成器

输入:分布函数,单一参数(多参数请柯里化) 输出:随机数

代码语言:javascript复制def rng(dis,param): """random number generator""" def generate(): return dis(lam=param,size=1)[0] return generate

Erlang分布函数:

输入:阶数

输出:k阶erlang分布函数

代码语言:javascript复制def erlang(k): """由k个指数分布拟合""" def exp2erlang(lam,size): res=[] for n in range(size): k_poisson= exponential(lam/k,size=k) sum=0 for x in k_poisson: sum = sum + x res.append(sum) return res return exp2erlang

测试,计算分布期望

代码语言:javascript复制x=rng(erlang(10),10) sum=0 for i in range(10000): sum= sum+x() print(sum/10000)

结果为9.99565983119657,说明函数正确

FIFO队列模型代码语言:javascript复制#典型银行模型:FIFO def bankSample(X,Y,Z,A,B,EX): """ 银行排队服务例子 情景: 一个柜台对客户进行服务, 服务耗时, 客户等候过长会离开柜台 %X 表示时间间隔分布 %Y 表示服务时间的分布 %Z 表示服务台的个数 %A 表示系统的容量,此处特殊化为客户的耐心时间分布 %B 表示顾客数 %以上参数必须有界,受到计算机精度限制,可以使用大常数近似无穷 %C 表示服务规则,请修改函数 %EX 传递了银行储蓄额的分布 """ #加入随机种子是为了对比模型的变化 seed(2) def source(env, number, interval,counter): """生成客户""" for i in range(number): c = customer(env, '客户%04d' % i, counter, time_in_bank=Y(),account=EX()) env.process(c) yield env.timeout(interval) #成功服务的客户 SUCC=0 #成功客户等待时间 WAIT=0 #成功客户逗留时间 STAY=0 #业务额 AMT=0 def customer(env, name, counter, time_in_bank,account): nonlocal WAIT nonlocal SUCC nonlocal STAY nonlocal AMT """顾客服务与离开仿真""" arrive = env.now #print('%7.4f %s: 到达' % (arrive, name)) with counter.request() as req: patience = A() # 直到到达或者失去耐心 results = yield req | env.timeout(patience) wait = env.now - arrive if req in results: # 到达 WAIT=WAIT+wait STAY=STAY+time_in_bank AMT= AMT + account #print('%7.4f %s:等待%6.3f' % (env.now, name, wait)) yield env.timeout(time_in_bank) SUCC=SUCC+1 #print('%7.4f %s:服务完成' % (env.now, name)) else: # We reneged pass #print('%7.4f %s:等待%6.3f后离开' % (env.now, name, wait)) # 初始化环境 print('排队问题仿真') env = Environment() # 开始协程 counter = Resource(env, capacity=Z) env.process(source(env, B, X(), counter)) env.run() print("总服务人数:{0:n}人".format(SUCC)) print("总营业额:{0:n}元".format(AMT)) print("总计失去: {0:n}名客户".format(B-SUCC)) print("损失率为: {0:n}%".format((B-SUCC)/B*100)) print("平均等待时间:{0:n}".format(WAIT/SUCC) ) print("平均耗费时间:{0:n}".format(STAY/SUCC) )

我们以下列参数作为输入

代码语言:javascript复制#间隔分布 X=rng(erlang(3),3) #服务时间分布 Y=rng(erlang(3),10) #耐心时间分布 A=rng(erlang(3),3) #业务额分布正态 def normaltocurry(s): def normalcurry(lam,size): return normal(lam,s,size=size) return normalcurry EX=rng(normaltocurry(200),1000) bankSample(X,Y,3,A,1000,EX)

输出的结果为:

排队问题仿真

总服务人数:417人

总营业额:409903元

总计失去: 583名客户

损失率为: 58.3%

平均等待时间:1.8828

平均耗费时间:10.0787

营业额优先队列模型

然后,我们转变一下模型,变成营业额越高越优先的队列

代码语言:javascript复制#银行模型·ELite:优先队列 def eliteBankSample(X,Y,Z,A,B,EX): """ 银行排队服务例子 情景: 一个柜台对客户进行服务, 服务耗时, 客户等候过长会离开柜台 %X 表示时间间隔分布 %Y 表示服务时间的分布 %Z 表示服务台的个数 %A 表示系统的容量,此处特殊化为客户的耐心时间分布 %B 表示顾客数 %以上参数必须有界,受到计算机精度限制,可以使用大常数近似无穷 %C 表示服务规则,请修改函数 %EX 传递了银行储蓄额的分布 """ #加入随机种子是为了对比模型的变化 seed(2) def source(env, number, interval,counter): """生成客户""" for i in range(number): c = customer(env, '客户%04d' % i, counter, time_in_bank=Y(),account=EX()) env.process(c) yield env.timeout(interval) #成功服务的客户 SUCC=0 #成功客户等待时间 WAIT=0 #成功客户逗留时间 STAY=0 #业务额 AMT=0 def customer(env, name, counter, time_in_bank,account): nonlocal WAIT nonlocal SUCC nonlocal STAY nonlocal AMT """顾客服务与离开仿真""" arrive = env.now #print('%7.4f %s: 到达' % (arrive, name)) #以业绩作为优先级,priority越小,优先级越大, with counter.request(priority = 1/account) as req: patience = A() # 直到到达或者失去耐心 results = yield req | env.timeout(patience) wait = env.now - arrive if req in results: # 到达 WAIT=WAIT+wait STAY=STAY+time_in_bank AMT= AMT + account #print('%7.4f %s:等待%6.3f' % (env.now, name, wait)) yield env.timeout(time_in_bank) SUCC=SUCC+1 #print('%7.4f %s:服务完成' % (env.now, name)) else: # We reneged pass #print('%7.4f %s:等待%6.3f后离开' % (env.now, name, wait)) # 初始化环境 print('排队问题仿真') env = Environment() # 开始协程 counter = PriorityResource(env, capacity=Z) env.process(source(env, B, X(), counter)) env.run() print("总服务人数:{0:n}人".format(SUCC)) print("总营业额:{0:n}元".format(AMT)) print("总计失去: {0:n}名客户".format(B-SUCC)) print("损失率为: {0:n}%".format((B-SUCC)/B*100)) print("平均等待时间:{0:n}".format(WAIT/SUCC) ) print("平均耗费时间:{0:n}".format(STAY/SUCC) )

以相同的参数测试

结果为:

排队问题仿真 总服务人数:432人 总营业额:450145元 总计失去: 568名客户 损失率为: 56.8% 平均等待时间:1.28862 平均耗费时间:9.69799



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有