多服务台仿真实验

1 Python仿真

1.1 模型假设
  1. 顾客的到来随仿真时间的停止而停止;
  2. 排队长度有时间限制;
  3. 到达系统的顾客按先到先服务原则依次进入服务;
  4. 服务员在仿真过程中没有休假;
  5. 顾客到达时排成一队,当有服务台空闲时进入服务状态;
  6. 顾客到达间隔时间服从负指数分布;
  7. 顾客所需的服务时间服从负指数分布;
  8. 各服务台服务无相互影响且平均服务时间相同;

注:当顾客平均到达率为常数 λ \lambda λ的到达间隔服从指数分布时,单位时间内到达的顾客数 k k k服从泊松分布,即单位时间内到达 k k k位顾客的概率为
P k = λ k e − λ k ! P_k = \frac{\lambda^k e^{-\lambda }}{k!} Pk=k!λkeλ
指数分布函数
F ( x ; λ ) = { 1 − e − λ x , x ≥ 0 0 , x < 0 F(x;\lambda) = \begin{cases} 1 - e^{-\lambda x}&,&x \ge 0\\ 0&, &x<0 \end{cases} F(x;λ)={1eλx0,,x0x<0
期望值:

E ( x ) = 1 λ E(x) = \frac{1}{\lambda} E(x)=λ1

1.2 模型分析

排队系统构成
系统设计过程中,将排队过程分为到达过程,排队过程,服务过程三部分。

  1. 到达过程

    1)顾客到达间隔时间服从负指数分布。

    2)顾客单个到来,且相互独立。

  2. 排队过程
    1)顾客到达时 若所有服务台均被占用,则顾客均选择排队等候。

    2)顾客发服务次序采取先到先服务的原则。

    3)队列数为单列且有队长限制,顾客不会在排队过程中中途退出,但是顾客到达时若队列满则顾客会离开系统。

  3. 服务过程
    1)服务机构为多服务台并联型(包括单服务台),各服务台独立为不同顾客提供服务。

    2)服务采用先到先服务的原则,未设置服务优先级。

1.3 系统性能
  • 平均队列顾客数
  • 平均等待时间
  • 损失顾客数
  • 工作台利用率

排队模型

一般排队模型示意图
1.4 python仿真源码
1.4.1 系统输入数据
符号含义
S S S服务台个数上限(例:S=3,则分别输出服务台个数为1,2,3的系统性能)
k k k等待队列上限
u u u顾客到达时间间隔均值
v v v顾客服务时间均值
T T T仿真终止时间
1.4.2 初始化参数
def initialize():
    global num_in_q,num_record,sim_time,arrival_time_q,depart_time,begin_service_time,arrival_count,sim_time
    global lose_count,avg_wait_q,avg_wait_time,avg_stay_time,next_event_type,num_events,time_next_event,depart_time_q
    num_in_q = 0 #加油站车辆数
    num_record = [] #记录仿真钟每一刻的加油站车辆数
    sim_time = 0 #初始化仿真钟
    #顾客属性
    arrival_time_q = [] #所有顾客到达时间序列
    depart_time_q = [] #所有顾客离开时间序列
    depart_time = [float('inf')] #记录正在接受服务的车辆离开序列
    begin_service_time = [] #服务开始时间序列
    arrival_count = 0 #到达顾客数
    lose_count = 0   #损失顾客数
    avg_wait_q = 0  #平均等待队长
    avg_wait_time = 0   #平均等待时间
    avg_stay_time = 0 #平均逗留时间
    next_event_type = 2 #下一事件类型
    num_events = [0,1] #事件类型,0表示到达,1表示离去
    time_next_event = [0]*2
    time_next_event[0] = sim_time #初始化第位顾客0时刻到达
    time_next_event[1] = float('inf')#离开时间置为无穷大,后期随机生成
1.4.3 定时函数
流程图

定时函数

定时函数流程图
函数体
def timing():
    '''
    推进仿真钟,判断下一事件类型
    '''
    global sim_time,next_event_type,time_next_event,depart_time
    time_next_event[1] = min(depart_time)
    sim_time = min(time_next_event) #推进仿真钟
    next_event_type = time_next_event.index(sim_time) #判断下一事件类型
    if next_event_type == 1: #如果下一事件为离开事件则从临时离开事件表中删除该事件的时间
        depart_time.remove(time_next_event[1])
1.4.4 到达事件
流程图

在这里插入图片描述

到达函数流程图
函数体
def arrive(s,k,u,v):
    '''
    推进事件的到达
    '''
    global arrival_time_q,arrival_count,time_next_event,begin_service_time
    global num_in_q,lose_count,depart_time,num_record
    arrival_time_q.append(sim_time) #记录到达事件
    arrival_count += 1 #累加到达顾客数
    #生成下一顾客到达事件
    time_next_event[0] = sim_time + np.random.exponential(u)#到达时间间隔为均值为u的指数分布随机数
    #分析到达事件对系统状态的影响
    if num_in_q < s: #有服务台空闲
        num_in_q += 1 #更新队列人数
        num_record.append(num_in_q) #记录系统内的人数
        begin_service_time.append(sim_time) #记录服务开始的时间
        #产生新的顾客离开事件
        service_time = np.random.exponential(v) #生成该事件的服务时间为均值为v的指数分布随机数
        depart_time.append(sim_time + service_time) #添加到离开事件列表
    elif num_in_q < s + k :#所有服务台忙,但排队的人还未满
        num_in_q += 1 #更新顾客数
        num_record.append(num_in_q) #记录系统内的人数
    else:
        lose_count += 1 #如果队列满了则该客户会选择其他的加油站,此时要删除该事件的到达时间
        arrival_time_q.pop()
1.4.5 离开事件
流程图

离开事件

离开函数流程图
函数体
def depart(s,v):
    '''
    推进事件的离开
    '''
    global depart_time_q,num_in_q,begin_service_time,depart_time,num_record
    #安排下一离开事件
    if num_in_q > s :
        begin_service_time.append(sim_time) #记录服务开始时间
        service_time = np.random.exponential(v) #生成服务时间
        depart_time.append(sim_time + service_time) #记录该事件的离开时间
    #记录当前离开事件
    num_in_q -= 1 #更新并记录系统中的顾客数
    num_record.append(num_in_q)
    depart_time_q.append(sim_time) #记录顾客的离开时间
1.4.6 更新函数
def update(s):
    '''
    更新系统指标
    '''
    global avg_wait_time,lose_count,record,avg_num_in_q
    end_service_num = len(depart_time_q) #已结束服务顾客数
    #平均等待时间
    avg_wait_time = np.mean(np.array(begin_service_time[0:end_service_num]) - np.array(arrival_time_q[0:end_service_num]))
    #平均等待队列人数(这里用的仿真时间为在设置的仿真结束时间前最后一位顾客的离开时间)
    avg_num_in_q = avg_wait_time * end_service_num / depart_time_q[-1]
    #工作台利用率
    use_ratio = sum(np.array(depart_time_q) - np.array(begin_service_time[0:end_service_num]))/(s * depart_time_q[-1])
    record = [avg_num_in_q,avg_wait_time,lose_count,use_ratio]
    return record
1.4.7 主函数
流程图

主函数

主函数流程图
函数体
def main(S,k,u,v,T) : 
    '''
    S:输入服务台个数,k:队列上限,u:到达时间间隔均值,v:服务时间均值,T:仿真结束时间
    输出各项指标:平均队列人数,平均等待时间,损失顾客数,工作台利用率
    '''
    global record_s
    for s in range(1,S + 1):
        initialize()
        while sim_time  <= T :
            timing() #判断事件类型
            if next_event_type == 0 :
                arrive(s,k,u,v)
            else:
                depart(s,v)
        record_s.append(update(s)) #仿真结束计算统计计数

2 仿真结果分析

2.1 系统输入
  • S = 10 S = 10 S=10、分析服务台个数从1到10的情况下系统各项指标。
  • k = 10 k = 10 k=10、系统中的等待顾客数不能超过10个。
  • u = [ 2 , 4 , 6 , 8 , 10 ] u = [2,4,6,8,10] u=[2,4,6,8,10]、分析顾客到达时间间隔均值由小到大,即模拟系统所处位置的顾客流量大小,探讨不同顾客流下的系统指标。
  • v = 5 v = 5 v=5、顾客服务时间均值。
  • T = 1440 T=1440 T=1440、仿真终止时间为一天即1440分钟。
  • N = 100 N=100 N=100、每一个 u u u做100次重复实验,系统指标取其均值。
2.2 结果分析
2.2.1 平均队列顾客数

在这里插入图片描述

image-20200608120710834

分析:

  • 在同样数量的服务台数下,系统中的平均等待队列顾客数随着顾客到达时间间隔均值的增大而减小。
  • 在顾客到达时间间隔均值相同的情况下,在某一服务台个M数前,随着服务台个数的增加,系统中的平均顾客数减小。若服务台的个数超过这个M值,即使增加服台的数量,对系统内的平均等待队列顾客数也影响不大。原因在于,此时影响平均等待队列顾客数的决定因素是到达时间间隔均值。
  • 此外,从图中可见当 v = 5 v=5 v=5(即:顾客的平均服务时间为5)时,服务台的个数由1个增加到两个对系统中平均队列顾客数的改善最大(通过斜率看出)
2.2.2 平均等待时间

在这里插入图片描述

image-20200608120809855

分析:

  • 在同样数量的服务台数下,系统中顾客的平均等待时间随着顾客到达时间间隔均值的增大而减小。
  • 在顾客到达时间间隔均值相同的情况下,在某一服务台个数M前,随着服务台个数的增加,系统中的顾客平均等待时间减小。若服务台的个数超过这个M值,即使增加服台的数量,对系统内的顾客平均等待时间也影响不大。原因同上(2.2.1)
  • 此外,从图中可见当 v = 5 v=5 v=5(即:顾客的平均服务时间为5)时,服务台的个数由1个增加到两个对系统中顾客平均等待时间的改善最大(通过斜率看出)
2.2.3 损失顾客数

在这里插入图片描述

在这里插入图片描述

分析:

  • 在同样数量的服务台数下,系统损失的顾客数随着顾客到达时间间隔均值的增大而减小。
  • 在顾客到达时间间隔均值相同的情况下,在某一服务台个数M前,随着服务台个数的增加,系统损失的顾客数减小。若服务台的个数超过这个M值,即使增加服台的数量,对系统损失的顾客数也影响不大。原因同上(2.2.1)
  • 从图中可见当 v = 5 v=5 v=5(即:顾客的平均服务时间为5)时,服务台的个数由1个增加到两个对系统损失顾客数的改善最大(通过斜率看出)
2.2.4 服务台利用率

在这里插入图片描述

在这里插入图片描述

分析:

  • 在同样数量的服务台数下,系统中服务台的利用率随着顾客到达时间间隔均值的增大而减小。
  • 在顾客到达时间间隔均值相同的情况下,系统中服务台的利用率随着服务台数量的增加而减小。
  • 虽然服务台由1个增加到两个在一定程度上降低了服务台的利用率,但是对于系统内的工作人员来说,给与一定的弹性休息时间是很有必要的。
2.3 结论

是否需要更多的工作台则需要根据服务中心所处地理位置的顾客流量来决定。若顾客流量很大(意味着在仿真系统中的顾客到达间隔时间 u u u就越小),就很有必要再新增新的工作台。

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
以下是一个简单的单服务台排队模型代码,使用 Python 实现: ```python import random class Queue: def __init__(self): self.items = [] def is_empty(self): return not self.items def enqueue(self, item): self.items.append(item) def dequeue(self): return self.items.pop(0) class Customer: def __init__(self, arrival_time): self.arrival_time = arrival_time self.service_time = random.randint(1, 5) class Server: def __init__(self): self.current_customer = None self.time_left = 0 def is_free(self): return not self.current_customer def start_service(self, customer): self.current_customer = customer self.time_left = customer.service_time def end_service(self): customer = self.current_customer self.current_customer = None self.time_left = 0 return customer def simulate(num_customers, avg_arrival_time): queue = Queue() server = Server() total_wait_time = 0 num_served = 0 current_time = 0 for i in range(num_customers): arrival_time = current_time + random.expovariate(1.0 / avg_arrival_time) customer = Customer(arrival_time) queue.enqueue(customer) while not queue.is_empty() or not server.is_free(): if not server.is_free(): server.time_left -= 1 if server.time_left == 0: customer = server.end_service() total_wait_time += current_time - customer.arrival_time num_served += 1 if not queue.is_empty(): if server.is_free(): customer = queue.dequeue() server.start_service(customer) else: next_customer = queue.items[0] if next_customer.arrival_time < current_time + server.time_left: customer = queue.dequeue() total_wait_time += current_time - customer.arrival_time num_served += 1 server.start_service(customer) current_time += 1 avg_wait_time = total_wait_time / num_served print("Num served = {}, avg wait time = {:.2f} minutes".format(num_served, avg_wait_time)) if __name__ == "__main__": simulate(100, 2.0) ``` 该代码使用了队列和随机数生成器等基础知识,模拟了一段时间内单服务台的顾客排队情况,并输出了服务的数量和平均等待时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值