排队系统仿真实验报告
1 实验题目
考虑一个排队系统,顾客到达后若无空闲服务台则等待,否则接受服务后离开,仿真目的是统计服务台前的平均队长和服务台的忙闲程度,要求能利用离散事件仿真的方法对该系统进行仿真,系统的规则和参数自定。
2 实验原理
离散事件驱动的模型只在一些离散点上由事件改变其状态,故离散事件模型是由事件驱动的。
驱动某一模型的所有事件按其发生的时间先后构成一个序列,通常要求按时间先后顺序处理事件,而不能颠倒。
离散事件系统仿真的关键是按时间顺序确定这一序列。
除初始事件,事件序列中的事件不能在仿真前事先确定,而是在仿真进行中产生,离散事件系统仿真中一般采用事先策划事件的方式,即在仿真系统处理任何事件之前该事件必须已被策划。
确定事件发生的时间的方式有三类:直接方式、间接方式、混合方式。
从事件、活动、进程三个层次来组织事件即构成了处理离散事件模型的三种典型处理方法:事件调度法、活动扫描法、进程交互法。
本次实验针对排队系统采用事件调度法,仿真策略如图1所示:
图1事件调度法仿真排队系统流程图
3 仿真程序
#include<stdio.h>// 需要printf()函数
#include<stdlib.h>// 需要exit()函数和rand()函数
#include<math.h>// 需要log()函数
#define SIM_TIME 1.0e6 // 总的仿真时间
#define ARR_TIME 1.20 // 平均到达时间间隔
#define SERV_TIME 1.00 // 平均服务时间
double expntl(double x); // 生成参数为x的指数分布的函数的函数声明void main(void) // 主函数
{
double end_time = SIM_TIME; // 仿真总时间
double Ta = ARR_TIME; // 平均到达时间间隔
double Ts = SERV_TIME; // 平均服务时间
double time = 0.0; // 仿真时间
double t1 = 0.0; // 事件(到达)时间
double t2 = SIM_TIME; // 事件(离开)时间
unsigned int n = 0; // 系统中的顾客数
unsigned int c = 0; // 服务完的顾客数
double b = 0.0; // Total busy time
double s = 0.0; // 系统中顾客数目的范围
double tn = time; // 最后一次事件的时间变量double tb; // 最后一次服务开始的时间double x; // 通过率
double u; // 服务员的利用率
double l; // 系统中的平均队长
double w; // 平均等待时间
char vvv;
while (time < end_time)
{
if (t1 < t2) // 事件(到达)
{
time = t1;
s = s + n * (time - tn); // 更新s
n++;
tn = time;
t1 = time + expntl(Ta);
if (n == 1) //n为时的情况
{
tb = time;
t2 = time + expntl(Ts);
}
}
else// 事件(离开)
{
time = t2;
s = s + n * (time - tn);
n--;
tn = time;
c++; // 服务完的顾客数加
if (n > 0)
t2 = time + expntl(Ts);
else
{
t2 = SIM_TIME;
b = b + time - tb; // Update busy time sum if empty
}
}
}
x = c / time;
u = b / time; // 服务员利用率
l = s / time; // 系统的平均队长
w = l / x; // 平均等待时间
printf("=============================================================== \n"); printf("= *** 排队模型M/M/1仿真结果 ** = \n"); printf("=============================================================== \n"); printf("= 总的仿真时间为: %3.4f sec \n", end_time);
printf("= 输入变量: \n");
printf("= 平均到达时间间隔: %f sec \n", Ta);
printf("= 平均服务时间: %f sec \n", Ts);
printf("= 输出结果: \n");
printf("= 服务完顾客数: %ld 个 \n", c);
printf("= 系统通过率: %f 个/sec \n", x);
printf("= 服务员占用率: %f %% \n", 100.0*u);
printf("= 系统中顾客的平均队长:%f 个 \n", l);
printf("= 平均等待时间: %f sec \n", w);
printf("=============================================================== \n"); scanf(&vvv);}
double expntl(double x)
{ double z;
do//用来产生,之间的随机数
{
z = ((double) rand() / RAND_MAX);
}
while ((z == 0) || (z == 1));
return(-x * log(z));
}
4仿真结果
图2仿真结果。