Python实现排队论——多坑位仿真(未使用仿真库,纯手写仿真)
Python实现排队论——多坑位仿真(未使⽤仿真库,纯⼿写仿真)
Python实现排队论-多坑位厕所
在⼀次偶然机会,接触到运筹学的排队论问题,于是简单尝试了⼀下硬撸代码,纯⼿打仿真,没有使⽤仿真库。建议⼤家可以学习Simpy 库,⽤以仿真。
⼀、案例:主要是基于“蒙特卡罗思想”,求解"单坑位"排队等待时间问题
场景:厕所排队问题
1、两场电影结束时间相隔较长,互不影响;
2、每场电影结束之后会有20个⼈想上厕所;
3、这20个⼈会在0到10分钟之内全部到达厕所;
4、每个⼈上厕所时间在1-3分钟之间
⾸先模拟最简单的情况,也就是厕所只有⼀个位置,不考虑两⼈共⽤的情况则每⼈必须等上⼀⼈出恭完毕⽅可进⾏。
分析:对于每个⼈都有如下⼏个参数:
到达时间 / 等待时间 / 开始上厕所时间 / 结束时间
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Dang
'''
Part1  设置随机值
'''
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
arrivingtime = np.random.uniform(0,10,size =20)
arrivingtime.sort()
workingtime = np.random.uniform(1,3,size =20)
# np.random.uniform 随机数:均匀分布的样本值
startingtime =[0for i in range(20)]
finishtime =[0for i in range(20)]
waitingtime =[0for i in range(20)]
emptytime =[0for i in range(20)]
# 开始时间都是0
print('arrivingtime\n',arrivingtime,'\n')
print('workingtime\n',workingtime,'\n')
print('startingtime\n',startingtime,'\n')
print('finishtime\n',finishtime,'\n')
print('waitingtime\n',waitingtime,'\n')
print('emptytime\n',emptytime,'\n')
'''
Part2  第⼀⼈上厕所时间
'''
startingtime[0]= arrivingtime[0]
# 第⼀个⼈之前没有⼈,所以开始时间 = 到达时间
finishtime[0]= startingtime[0]+ workingtime[0]
# 第⼀个⼈完成时间 = 开始时间 + “⼯作”时间
waitingtime[0]= startingtime[0]-arrivingtime[0]
# 第⼀个⼈不⽤等待
print(startingtime[0])
print(finishtime[0])
print(waitingtime[0])
print(waitingtime[0])
'''
Part3  第⼆⼈之后
'''
for i in range(1,len(arrivingtime)):
if finishtime[i-1]> arrivingtime[i]:
startingtime[i]= finishtime[i-1]
else:
startingtime[i]= arrivingtime[i]
emptytime[i]= arrivingtime[i]- finishtime[i-1]
# 判断:如果下⼀个⼈在上⼀个⼈完成之前到达,则开始时间 = 上⼀个⼈完成时间,# 否则开始时间 = 到达时间,且存在空闲时间 = 到达时间 - 上⼀个⼈完成时间
finishtime[i]= startingtime[i]+ workingtime[i]
waitingtime[i]= startingtime[i]- arrivingtime[i]
print('第%d个⼈:到达时间开始时间 “⼯作”时间完成时间等待时间\n'%i,
arrivingtime[i],
startingtime[i],
二十大开始时间workingtime[i],
finishtime[i],
waitingtime[i],
'\n')
print('arerage waiting time is %f'%np.mean(waitingtime))
"""
数据统计
"""
sns.set(style ='ticks',context ="notebook")
fig = plt.figure(figsize =(8,6))
arrivingtime,= plt.plot(arrivingtime,label ='arrivingtime')
startingtime,= plt.plot(startingtime,label ='startingtime')
workingtime,= plt.plot(workingtime,label ='workingtime')
finishtime,= plt.plot(finishtime,label ='finishtime')
waitingtime,= plt.plot(waitingtime,label ='waitingtime')
plt.title(("Queuing problem random simulation experiment").title())
plt.xlabel("Arriving Time(min)")
plt.ylabel("Total Time(min)")
plt.legend(handles=[arrivingtime,startingtime,workingtime,finishtime,waitingtime],
loc ='upper left')
plt.show()
输出结果如下:
以上为该⽹站内容:.
下⽂为我于上⽂基础上,继续推⼴到多坑位。
⼆、案例:主要是基于“蒙特卡罗思想”,求解"多坑位"排队等待时间问题
于⼀案例的基础假设上:
1.每个⼈不会插队
2.只有⼀条排队等待队列
3.不分男⼥厕所
4.假设从排队等待队列到坑位不需要花费时间
5.排队过程中不会有⼈放弃进⼊该厕所
6.排队讲究先来后到
7.每个⼈严格要求排队时间上厕所,忍耐时间⽆穷。
# -*- coding:utf-8 -*-
# Author:Xiangyang He
# Coding time: 10h
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns #⽤于合并绘图
#定义函数
class P():#建⽴要上厕所的⼈对象
def__init__(self,Num,A,WK,WT,ET,FS,ST,R):
self.Num = Num #编号
self.A = A #到达时间时间点
self.WT = WT #等待时间时间长度
self.WK = WK #“⼯作”时间时间长度
self.ET = ET #厕所⽆⼈空⽩时间时间长度
self.FS = FS #完成⼯作时间时间点
self.ST = ST #开始⼯作时间时间点
self.R = R #剩余时间时间长度
def toilet_which(toilet):#返回厕所队列中等待时间最短的索引
lt =[]
for i in toilet:
lt.append(i.R)
return lt.index(min(lt))
def toilet_minus_test(toilet,m):#
h =[]
for i in range(M):
if toilet[i]!=None:
h.append(toilet[i].R-m)
if min(h)<=0:
return True
else:
return False
def toilet_None(toilet):
return[i for i,x in enumerate(toilet)if x ==None]
def toilet_0(toilet,m):
return[i for i,x in enumerate(toilet)if x !=None and x.R <= m ] def Nature_minus(x,y):#⾃然数集中的减法
if x>y:
return x-y
else:
return0
#
N =200# item数量
M =12# 系统中处理item的个数
K =30
np.random.seed(2333)
WK = np.random.uniform(10,5,size = N)#⼯作时间随机⽣成
A = np.random.uniform(0,K,size = N)#item到达时间随机⽣成
A.sort()
y =[]
for i in range(0,N-1):
y.append(A[i+1]-A[i])
y = np.array(y)
Queue =[P(i,A[i],WK[i],0,0,0,0,0)for i in range(N)]#初始化Queue
#对toilet初始化
Queue[0].ST = Queue[0].A
Queue[0].WT =0
Queue[0].ET = Queue[0].A
Queue[0].R = Queue[0].WK
toilet =[Queue[0]]+[None for i in range(M-1)]
lt =[]#等待的队伍
for k in range(1,N):#item陆续进⼊处理器与等待队伍
m = y[k-1]
if toilet_minus_test(toilet,m):
#print("toilet",toilet,end="")
s =list(set((toilet_None(toilet)+ toilet_0(toilet,m)))) #print("这是关于A的Num",Queue[k].Num,"时刻为",Queue[k].A)
if len(lt)==0:
print("1,1",Queue[k].Num)
v = s[0]
for i in range(M):
if i == v and toilet[v]==None:
Queue[k].ET = Queue[k].A
Queue[k].ST = Queue[k].A
toilet[v]= Queue[k]
if i == v and toilet[v]!=None:
Queue[k].ET = m-toilet[v].R
Queue[k].ST = Queue[k].A
Queue[k].R = Queue[k].WK
toilet[v].FS = toilet[v].ST + toilet[v].WK
toilet[v].R =0
toilet[v]= Queue[k]
if i != v:
if toilet[i]!=None:
toilet[i].R = Nature_minus(toilet[i].R,m)
if toilet[i].R ==0:
toilet[i].FS = toilet[i].ST + toilet[i].WK
toilet[i]=None
else:
lt.append(Queue[k])
#print("1,0apend",Queue[k].Num)
for i in range(M):
if i in s :
if len(lt)>1:
toilet[i].FS = toilet[i].ST + toilet[i].WK
#print("前lt",lt[0].Num)
r = lt.pop(0)
#print("s",s)
#print("后lt",lt[0])
#print("第{}号厕所的{}完成".format(i,toilet[i].Num))
#print("取出",r.Num,"进⼊{}厕所".format(i))
r.ST = toilet[i].FS
r.ET =0
r.R = r.WK -(m-toilet[i].R)
toilet[i].R =0
toilet[i]= r
#if k == 10:
#print("ST",toilet[i].ST,toilet[i].Num,k)
if len(lt)==1:
toilet[i].FS = toilet[i].ST + toilet[i].WK
toilet[i].R =0
e = lt.pop(0)
e.ST = e.A
e.R = e.WK
toilet[i]= e
if len(lt)==0:
toilet[i].FS = toilet[i].ST + toilet[i].WK
toilet[i].R =0
toilet[i]=None
else:
toilet[i].R = Nature_minus(toilet[i].R,m)
else:
B =None in toilet
#if k ==2 :
#L = toilet[2]
#K = B
#print(toilet[2])
if B:
#print("0,1",Queue[k].Num)
v = toilet_None(toilet)
for i in range(M):
if i == v[0]:
Queue[k].ST = Queue[k].A
Queue[k].ET =0
Queue[k].R = Queue[k].WK
toilet[i]= Queue[k]
#if k==2:
#print("asjdhaskjdhasd")

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。