Hefery 的个人网站

Hefery's Personal Website

Contact:hefery@126.com
  menu
73 文章
0 浏览
1 当前访客
ღゝ◡╹)ノ❤️

M/M/S-混合制排队Matlab实现

M/M/S-混合制排队Matlab实现

%=======================================================================
% M/M/S-混合制排队系统
% 组成:
%    顾客:服从指数分布
%    服务台:多服务台,服务时间服从指数分布
%    服务机制:混合制(损失制、等待制)
%    服务规则:先到先服务(FCFS)
%
% 算法:计算机仿真(事件步长法)
%
% 输入参数:
%    totalNum_client:顾客总人数
%    lambda:单位时间顾客到达数
%    mu:单个服务台单位时间接待顾客数
%    num_serviceTable:服务台数量
%    maxNum_waitedQueue:单行等待顾客的最大排队容量
%
% 输出参数:
%    Pbusy:排队系统繁忙的概率
%    meaWait_peo:平均等待队长  
%    meaWait_time:平均等待时间
%    mean_peo:系统中平均总乘客数
%    lost_peo:损失的乘客数
%=======================================================================

% 清空工作区变量、清屏
clear
clc

% 初始化排队系统参数
totalNum_client = 100;    % 顾客总人数
lambda = 9;               % 单位时间顾客到达数
mu = 2;                   % 单个服务台单位时间接待顾客数
num_serviceTable = 4;     % 服务台数量
maxNum_waitedQueue = 10; % 单行等待顾客的最大排队容量

% 存储每位顾客的信息 (7*total_num_client 矩阵)
list_client = zeros(7, totalNum_client);  
% 产生指数分布的顾客到达时间间隔
list_client(1,:) = exprnd(1/lambda, 1, totalNum_client);  
list_client(1,:) = cumsum(list_client(1,:));            
list_client(2,:) = exprnd(1/mu, 1, totalNum_client); 
% 1.顾客到达时间
% 2.服务台顾客的服务时间
% 3.顾客等待时间
% 4.顾客离开时间
% 5.顾客到达时排队系统当前的人数(包括正在被服务的)
% 6.系统中正在等待中的人数
% 7.该顾客是否直接离开 (1;直接离开,0:排队等待)
pro_client = [];  % 储存每个顾客到达时在系统中总人数的序号

% 计算每个顾客到达时系统的队长
for i = 1:totalNum_client
    % 统计顾客到来时还在系统中的顾客的序号
    % 若顾客的离开时间>到达时间,则认为顾客还在排队系统中
    curPro_client = find(list_client(4,pro_client) > list_client(1,i));  
    % 更新当前系统中顾客的序号
    pro_client = pro_client(curPro_client);  
    % 统计排队系统中总顾客数
    num_queue = length(curPro_client);  
    % 损失制:若排队顾客数量超过单行总顾客数,则该顾客损失
    % 单行总顾客数 = 单行排队容量max_num_waitedQueue + 正在被服务的顾客数(即服务台数量)
    if( num_queue >= maxNum_waitedQueue + num_serviceTable )  
        list_client(2:7,i) = [0; 0; list_client(1,i); num_queue; num_queue-num_serviceTable; 1];
        continue
    else if( num_queue < num_serviceTable )  % 无人排队等待,则等待时间为0
            list_client(3:6,i) = [0, sum(list_client(1:3,i)), num_queue, 0];
            pro_client = [pro_client,i];  % 将当前顾客加入到系统
        else  % 有人排队
            leaveTime_client = sort(list_client(4, pro_client));  % 排序:正在排队系统中顾客的离开时间
            % 排队等待的顾客 = 顾客到来时还在系统中的人的序号cur_pro_client - 服务台数量num_serviceTable
            list_client(3,i) = leaveTime_client(end - num_serviceTable + 1) - list_client(1,i);  
            % 此时,顾客的等待时间 = 当前系统中倒数第num_serviceTable(服务台数量)个离开的顾客的时间 - 该顾客的到达时间
            list_client(4:6,i) = [sum(list_client(1:3,i)); num_queue; num_queue-num_serviceTable];
            pro_client = [pro_client,i];  % 将当前的顾客加入到系统
        end
    end
end

% 计算时间范围内排队系统的队长变化
list_time = zeros(4, 2*totalNum_client);
% 1.时间
% 2.对应时间的总人数
% 3.对应时间正在排队的人数
% 4.是否繁忙(1:繁忙 0:不繁忙)

% 系统队长的变化必定发生在顾客到来或离去的时刻
% 排序:顾客的到来时间与离开时间
[list_time(1,:),idxs] = sort([list_client(1,:), list_client(4,:)]); 
% 第一位顾客到达,系统中人数开始变为 1,正在排队等待的为 0,系统不繁忙
list_time(2,1) = 1; 
for i = 2:2*totalNum_client    
    if idxs(i) <= totalNum_client  % 此时刻是有顾客到达
        list_time(2,i) = list_time(2,i-1)+1;
    else  % 此时刻有顾客离去
        list_time(2,i) = list_time(2,i-1) - 1;
    end
    % 判断是否繁忙(繁忙:所有的服务台全满)
    if list_time(2,i) >= num_serviceTable
        % 若繁忙则得出正在排队的人数,繁忙
        list_time(3:4,i) = [list_time(2,i)-num_serviceTable, 1];  
    end
end

% 计算各种统计指标(忽略首尾的非稳态过程)
all_peo = 0;
all_wait = 0;
busyTime = 0;
for i = 1:(2*totalNum_client-1)
    block = list_time(1,i+1) - list_time(1,i);     % 相邻两个“转变时刻”的时间间隔
    all_peo = all_peo + block * list_time(2,i);    % 每个时间段的总人数之和
    all_wait = all_wait + block * list_time(3,i);  % 每个时间段的等待人数之和
    busyTime = busyTime + block * list_time(4,i);  % 总繁忙时刻
end
Pbusy = busyTime / list_time(1,end);        % 系统繁忙的概率
mean_peo = all_peo / list_time(1,end);      % 系统中的平均总人数=每个时间段的总人数之和/总时间
meanWait_peo = all_wait / list_time(1,end); % 平均等待人数=每个时间段的等待人数之和/总时间
meanWait_time = sum(list_client(3,:)) / totalNum_client;  % 平均等待时间=每个人的等待时间之和/总人数
lost_peo = sum(list_client(7,:));           % 失去的顾客数
num_queue = find(list_client(7,:)==1);      % 失去的顾客的序号

% 每个顾客的到达时间和离开时间
figure
plot(1:totalNum_client, list_client(1,:), 1:totalNum_client, list_client(4,:), num_queue, list_client(1,num_queue), '*r');
title('顾客到达与离开时间')
% legend('到达时间 ','离开时间 ','损失的顾客');
% 各顾客等待时间与停留总时间
figure
plot(1:totalNum_client, list_client(3,:), 1:totalNum_client, sum(list_client(2:3,:)), num_queue,list_client(3,num_queue), '* r')
% legend('等待时间','停留总时间','损失的顾客',0)
title('各顾客等待时间与停留总时间')
xlabel('顾客');  ylabel('时间')
% 每个顾客到来时的系统总人数
figure
plot(1:totalNum_client, list_client(5,:), ':.', num_queue, list_client(5,num_queue), '*r')
% legend('每个顾客到来时的系统总人数','损失的顾客',0)
xlabel('顾客');  ylabel('系统总人数')
% 系统中总人数随时间的变化
figure
stairs(list_time(1,:), list_time(2,:));
hold on
plot(list_client(1,totalNum_client), list_time(2,idxs==totalNum_client), '.r', 'MarkerSize', 20);
title('系统中总人数随时间的变化')
if sum(list_client(7,:))
    plot([0,list_time(1,end)], [maxNum_waitedQueue + num_serviceTable, maxNum_waitedQueue + num_serviceTable],'--r')
    text(list_time(1,3), maxNum_waitedQueue + num_serviceTable, '系统最大容量')
end
% legend('人数','最后一个顾客到达',0)
xlabel('时间');  ylabel('人数')
fprintf('排队系统繁忙概率    =%.3f\n', Pbusy);
fprintf('平均等待队长        =%.3f\n', meanWait_peo);
fprintf('平均等待时间        =%.3f\n', meanWait_time);
fprintf('排队系统中平均总人数=%.3f\n', mean_peo);
fprintf('损失的顾客数        =%d\n',   lost_peo);
fprintf('损失率              =%.3f\n', lost_peo/totalNum_client);


标题:M/M/S-混合制排队Matlab实现
作者:Hefery
地址:http://hefery.icu/articles/2021/12/04/1638549165514.html