基于python的M/M/m/∞/∞/FCFS的排队系统仿真

使用python模拟负指数分布的到达时间间隔以及服务时间
要是遇上跟我一节课的同学就不要用我这个代码啦hhh

import math
import random
import numpy as np
import matplotlib.pyplot as plt
def expntl(L):
    """
    negative exponential distribution
    return a double random number, L is the mean value
    """
    u = random.random()
    return -L * math.log(u)

# 参数初始化
Total_time = 20
lam = 4
mu = 3
N = 1000000  # 系统可容纳的队列最大长度
arr_mean = 1/lam
ser_mean = 1/mu
arr_num = int(Total_time*lam*2)  # 到达的顾客总数仿真
events = np.zeros((5, arr_num))
services = 2  # 系统中有两台服务器在提供服务

# 第0行为顾客的到达时间
# 第1行为顾客的服务时间
# 第2行为顾客的等待时间
# 第3行为顾客的离开时间
# 第4行为每个顾客的标志位

arr = np.array([expntl(arr_mean) for i in range(arr_num)])  # 产生每个顾客的到达间隔时间,累加后即得每个顾客的到达时间
events[0, :] = np.cumsum(arr)  # 得到每个顾客的到达时间
events[1, :] = np.array([expntl(ser_mean) for i in range(arr_num)])  # 产生每个顾客的服务时间
print(events.shape)
numbers = 2  # 该系统已经服务过的顾客的数量
member = [0, 1]  # 正在接受服务的顾客
# 用for循环产生每个顾客的等待时间
events[2, :2] = 0  # 前两个顾客的等待时间为0
events[3, 0] = events[0, 0] + events[1, 0]  # 计算前两个顾客的离开时间
events[3, 1] = events[0, 1] + events[1, 1]
events[4, :2] = 1  # 已经服务完的前两个顾客标志位置1

# 记录正在服务的两个顾客的离开时间
leave_time = np.array([events[3, 0], events[3, 1]])
ser_num = 0
# print(leave_time)

# print(events[:, :4])
for k in range(2, arr_num):
    # 首先判断是否第k个顾客的到达时间超出了总的仿真时间,是则跳出循环
    if events[0, k] >= Total_time:
        ser_num = k
        break
    else:  # 首先获取此顾客的到达时间并判断是否需要等待
        if events[0, k] <= np.min(leave_time):  # 需要等待
            events[2, k] = np.min(leave_time) - events[0, k]
            # 计算这个顾客的离开时间,为到达时间+等待时间+服务时间
            events[3, k] = sum(events[[0, 1, 2], k])
        else:  # 无需等待
            events[2, k] = 0
            # 计算这个顾客的离开时间,为到达时间+等待时间+服务时间
            events[3, k] = sum(events[[0, 1, 2], k])
        leave_time = np.array([np.max(leave_time), events[3, k]])
        numbers += 1  # 已经服务完的顾客数量加1
        events[4, k] = 1  # 标志位置1
# events_reverse = np.transpose(events)
# print(events_reverse[100:120, :])
# 画出所有顾客的到达时间

c = lam/mu
p = lam/(2*mu)
p0 = 1/(1+c+c**2/(2*(1-p)))
Lq = math.pow(services*p, services)*p*p0/(math.factorial(services)*math.pow(1-p, 2))
Ls = Lq + c
Ws = Ls/lam
Wq = Lq/lam
print("经公式计算所得的顾客的平均排队长为:", Lq)
print("经公式计算所得的顾客的平均队长为:", Ls)
print("经公式计算所得的顾客的平均逗留时间为:", Ws)
print("经公式计算所得的顾客的平均等待时间为:", Wq)
print("仿真所得的顾客的平均等待时间为:", np.mean(events[2, :ser_num]))
plt.figure(figsize=(14, 16))

plt.subplot(211)
plt.plot(np.arange(k), events[0, :k], label='arrive time')
plt.plot(np.arange(k), events[3, :k], label='leave time')
plt.xlabel('t![在这里插入图片描述](https://img-blog.csdnimg.cn/7ebe8d32b4034166ad85e77d95fcd2e2.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6Zuq5a-76Iqx,size_15,color_FFFFFF,t_70,g_se,x_16#pic_center)
he number of customers')
plt.ylabel('Times')
plt.legend()
ax1 = plt.gca()
ax1.spines['right'].set_color('none')
ax1.spines['top'].set_color('none')
plt.subplot(212)
plt.plot(np.arange(k), events[2, :k], label='wait time')
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.show()

第一次写博客,研一某选修课的project,分享给大家,创作不易,点个赞哦
在这里插入图片描述
在这里插入图片描述
给大家附上matlab的代码和图片

clear
clc
%*****************************************
%初始化顾客源
%*****************************************

% =================================================================需要改的变量
%总仿真时间
Total_time = 10;
%队列最大长度
N = 10000000000;
%到达率与服务率
lambda = 10;
mu = 6;
% =================================================================需要改的变量

%平均到达时间与平均服务时间
arr_mean = 1/lambda;
ser_mean = 1/mu;
arr_num = round(Total_time*lambda*2);%设到达的顾客总数为200人
events = [];
%按负指数分布产生各顾客达到时间间隔
events(1,:) = exprnd(arr_mean,1,arr_num);
%各顾客的到达时刻等于时间间隔的累积和
events(1,:) = cumsum(events(1,:));
%按负指数分布产生各顾客服务时间
events(2,:) = exprnd(ser_mean,1,arr_num);
%计算仿真顾客人数,即到达时刻在仿真时间内的顾客数
len_sim = sum(events(1,:)<= Total_time);
%*****************************************
%计算第 1个顾客的信息
%*****************************************
%第 1个顾客进入系统后直接接受服务,无需等待
events(3,1) = 0;
%其离开时刻等于其到达时刻与服务时间之和
events(4,1) = events(1,1)+events(2,1);
%其肯定被系统接纳,此时系统内共有1个顾客,故标志位置1
events(5,1) = 1;
%其进入系统后,系统内已有成员序号为 1
member = [1];
for i = 2:arr_num
%如果第 i个顾客的到达时间超过了仿真时间,则跳出循环
    if events(1,i)>Total_time
        break;

    else
        number = sum(events(4,member) > events(1,i));
%如果系统已满,则系统拒绝第 i个顾客,其标志位置 0
    if number >= N+1
        events(5,i) = 0;
%如果系统为空,则第 i个顾客直接接受服务
    else
        if number == 0
%其等待时间为0
            events(3,i) = 0;
%其离开时刻等于到达时刻与服务时间之和
            events(4,i) = events(1,i)+events(2,i);
%其标志位置 1
            events(5,i) = 1;
            member = [member,i];
%如果系统有顾客正在接受服务,且系统等待队列未满,则 第 i个顾客进入系统

        else len_mem = length(member);
%其等待时间等于队列中前一个顾客的离开时刻减去其到达时刻
            events(3,i)=events(4,member(len_mem))-events(1,i);
%其离开时刻等于队列中前一个顾客的离开时刻加上其服务时间
            events(4,i)=events(4,member(len_mem))+events(2,i);
%标识位表示其进入系统后,系统内共有的顾客数
            events(5,i) = number+1;
            member = [member,i];
        end
    end

    end
end
%仿真结束时,进入系统的总顾客数
len_mem = length(member);

%*****************************************
%输出结果
%*****************************************
%绘制在仿真时间内,进入系统的所有顾客的到达时刻和离开时刻曲线图(stairs:绘制二维阶梯图)
stairs([0 events(1,member)],0:len_mem);
hold on;
stairs([0 events(4,member)],0:len_mem,'.-r');
legend('到达时间 ','离开时间 ');
hold off;
grid on;
%绘制在仿真时间内,进入系统的所有顾客的停留时间和等待时间曲线图(plot:绘制二维线性图)
figure;
plot(1:len_mem,events(3,member),'r-*',1: len_mem,events(2,member)+events(3,member),'k-');
legend('等待时间 ','停留时间 ');
grid on;

在这里插入图片描述
在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐