t_Leave(i)=t_Arrive(i)+Interval_Serve(i);
else
t_Leave(i)=t_Leave(i-1)+Interval_Serve(i);
end
LeaveNum(i)=i;
end
t_Wait=t_Leave-t_Arrive;%各顾客在系统中的等待时间
t_Wait_avg=mean(t_Wait);
t_Queue=t_Wait-Interval_Serve;%各顾客在系统中的排队时间
t_Queue_avg=mean(t_Queue);
Timepoint=[t_Arrive,t_Leave];%系统中顾客数随时间的变化
Timepoint=sort(Timepoint);
ArriveFlag=zeros(size(Timepoint));%到达时间标志
CusNum=zeros(size(Timepoint));
temp=2;
CusNum
(1)=1;
fori=2:
length(Timepoint)
if(temp<=length(t_Arrive))&&(Timepoint(i)==t_Arrive(temp))
CusNum(i)=CusNum(i-1)+1;
temp=temp+1;
ArriveFlag(i)=1;
else
CusNum(i)=CusNum(i-1)-1;
end
end
%系统中平均顾客数计算
Time_interval=zeros(size(Timepoint));
Time_interval
(1)=t_Arrive
(1);
fori=2:
length(Timepoint)
Time_interval(i)=Timepoint(i)-Timepoint(i-1);
end
CusNum_fromStart=[0CusNum];
CusNum_avg=sum(CusNum_fromStart.*[Time_interval0])/Timepoint(end);
QueLength=zeros(size(CusNum));
fori=1:
length(CusNum)
ifCusNum(i)>=2
QueLength(i)=CusNum(i)-1;
else
QueLength(i)=0;
end
end
QueLength_avg=sum([0QueLength].*[Time_interval0])/Timepoint(end);%系统平均等待队长
%仿真图
figure
(1);
set(1,'position',[0,0,1000,700]);
subplot(2,2,1);
title('各顾客到达时间和离去时间');
stairs([0ArriveNum],[0t_Arrive],'b');
holdon;
stairs([0LeaveNum],[0t_Leave],'y');
legend('到达时间','离去时间');
holdoff;
subplot(2,2,2);
stairs(Timepoint,CusNum,'b')
title('系统等待队长分布');
xlabel('时间');
ylabel('队长');
subplot(2,2,3);
title('各顾客在系统中的排队时间和等待时间');
stairs([0ArriveNum],[0t_Queue],'b');
holdon;
stairs([0LeaveNum],[0t_Wait],'y');
holdoff;
legend('排队时间','等待时间');
%仿真值与理论值比较
disp(['理论平均等待时间t_Wait_avg=',num2str(1/(Mu-Lambda))]);
disp(['理论平均排队时间t_Wait_avg=',num2str(Lambda/(Mu*(Mu-Lambda)))]);
disp(['理论系统中平均顾客数=',num2str(Lambda/(Mu-Lambda))]);
disp(['理论系统中平均等待队长=',num2str(Lambda*Lambda/(Mu*(Mu-Lambda)))]);
disp(['仿真平均等待时间t_Wait_avg=',num2str(t_Wait_avg)])
disp(['仿真平均排队时间t_Queue_avg=',num2str(t_Queue_avg)])
disp(['仿真系统中平均顾客数=',num2str(CusNum_avg)]);
disp(['仿真系统中平均等待队长=',num2str(QueLength_avg)]);
五、数据结构
1.仿真设计算法(主要函数)
利用负指数分布与泊松过程的关系,产生符合泊松过程的顾客流,产生符合负指数分布的随机变量作为每个顾客的服务时间:
Interval_Arrive=-log(rand(1,SimTotal))/Lambda;%到达时间间隔,结果与调用exprnd(1/Lambda,m)函数产生的结果相同
Interval_Serve=-log(rand(1,SimTotal))/Mu;%服务时间间隔
t_Arrive
(1)=Interval_Arrive
(1);%顾客到达时间
时间计算
t_Wait=t_Leave-t_Arrive;%各顾客在系统中的等待时间
t_Queue=t_Wait-Interval_Serve;%各顾客在系统中的排队时间
由事件来触发仿真时钟的不断推进。
每发生一次事件,记录下两次事件间隔的时间以及在该时间段内排队的人数:
Timepoint=[t_Arrive,t_Leave];%系统中顾客数变化
CusNum=zeros(size(Timepoint));
CusNum_avg=sum(CusNum_fromStart.*[Time_interval0])/Timepoint(end);%系统中平均顾客数计算
QueLength_avg=sum([0QueLength].*[Time_interval0])/Timepoint(end);%系统平均等待队长
2.算法的流程图
六、仿真结果分析
顾客的平均等待时间与顾客的平均等待队长,计算其方差如下:
从上表可以看出,通过这种模型和方法仿真的结果和理论值十分接近,增加仿真顾客数时,可以得到更理想的结果。
但由于变量定义的限制,在仿真时顾客总数超过1,500,000时会溢出。
证明使此静态仿真的思想对排队系统进行仿真是切实可行的。
实验结果截图如下(SimTotal分别为100、1000、10000、100000):
(仿真顾客总数为100000和1000000时,其图像与10000的区别很小)
七、遇到的问题及解决方法
1.在算法设计阶段对计算平均队长时对应的时间段不够清楚,重新画出状态转移图后,引入变量Timepoint用来返回按时间排序的到达和离开的时间点,从而得到正确的时间间隔内的CusNum,并由此计算出平均队长。
2.在刚开始进行仿真时仿真顾客数设置较小,得到的仿真结果与理论值相差巨大,进行改进后,得到的结果与理论值相差不大。
3.刚开始使用exprnd(Mu,m)产生负指数分布,但运行时报错,上网查找资料后找到替代方法:
改成Interval_Serve=-log(rand(1,SimTotal))/Mu;方法生成负指数分布,运行正常。
八、实验心得
通过本次实验我对M/M/1单窗口无限排队系统有了更深的认识,同时对MatLab编程语言更加熟悉,并了解到仿真在通信网中的重要作用。
此次实验我受益匪浅。