python建模仿真报告_Python|数学建模|排队论仿真

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

文档介绍

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

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

本文档提供了:

基础排队模型仿真

Erlang分布实现

通用分布函数适配器

工具库

库依赖

from numpy.random import *

from simpy import *

高阶函数随机数生成器

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

输出:随机数

def rng(dis,param):

"""random number generator"""

def generate():

return dis(lam=param,size=1)[0]

return generate

Erlang分布函数:

输入:阶数

输出:k阶erlang分布函数

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

测试,计算分布期望

x=rng(erlang(10),10)

sum=0

for i in range(10000):

sum= sum+x()

print(sum/10000)

结果为9.99565983119657,说明函数正确

FIFO队列模型

#典型银行模型: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) )

我们以下列参数作为输入

#间隔分布

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

营业额优先队列模型

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

#银行模型·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

总结

可以看出,在加入了上述充满着歧视与不公平的规则之后, 人均营业额上升,并且等待时间和耗费时间都有所下降 即:富人和银行获得了利益,富人节约了自己的时间,银行增加了业绩sjtuzwj/OperationalResearchModeling​github.com

内部含网络图/决策论等算法。

你可能感兴趣的:(python建模仿真报告)