计算机仿真实验报告学号:2013214926
班级:机设13-3班
姓名:田启军
指导老师:翟华
日期2016年4月12日单服务员单队列系统仿真实验
实验要求及实验报告
一.实验要求及目的
通过实验了解离散事件系统仿真一般过程,了解离散事件系统中典型的单服务.单队列系统的仿真一般过程,并理解单服务.单队列系统的流程过程,能画出流程图,了解不同分布随机数的计算机实现过程,了解事件扫描法在离散事件系统中的应用。
同学能在参考源程序的基础上,独立编写C源程序,或其他高级语言程序,能正确理解程序含义,能正确计算仿真结果,并对结果进行分析。
二.实验报告
1.给出RAND()子程序输出的10个数据,以及对应的符合正态分布和指数分布的随机数。
1 2 3 4 5 RAND() 0.979553 0.664057 0.504250 0.527916 0.193561 NORMAL 2.9767 2.4904 3.0001 2.6499 3.2569 EXPENT() 0.2066 4.0939 6.3882 6.8468 16.4216
6 7 8 9 10 RAND() 0.959777 0.683238 0.084337 0.162432 0.080400 NORMAL 2.9658 4.5799 3.7783 1.6343 6.6180 EXPENT() 0.4105 3.8091 24.7294 18.1749 25.2074
2.分别输入下列三组数据,给出相应的计算结果(包括服务员
忙度、平均服务时间、平均到达间隔时间、顾客在系统中平均时间、顾客在队列中平均时间、系统中平均顾客数、队列中平均顾客数、停留4个时间单位以上的顾客比例等),并加以文字说明。(1)输入数据为:
MIAT=10, MSVT=5,SIGMA=2,TIME=100
miat=10.000000,msvt=5.000000,sigma=2.000000,time=100.000000 rho=0.482677,mq=2.000000,pc=0.454545,clock=114.048820
nd=11.000000,amts=4.362051,amta=9.973741
lq=1.026730,l=1.509407,wq=10.645217,w=3.600372
(2)输入数据为:
MIAT=10, MSVT=3,SIGMA=1,TIME=100
miat=10.000000,msvt=3.000000,sigma=1.000000,time=100.000000 rho=0.242204,mq=1.000000,pc=0.111111,clock=108.105759
nd=9.000000,amts=2.909301,amta=11.269994
lq=0.682092,l=0.924297,wq=8.193123,w=2.863684
(3)输入数据为:
MIAT=10, MSVT=30,SIGMA=2,TIME=100
miat=10.000000,msvt=30.00000,sigma=2.000000,time=100.000000 rho=0.998272,mq=8.000000,pc=1.000000,clock=119.530281
nd=4.000000,amts=29.953489,amta=9.972269
lq=5.037513,l=6.035784,wq=150.533829,w=15.594049
三.实验内容
在C语言环境下,输入C语言程序:
#include "stdio.h"
#include "math.h"
FILE * fp;
float seed;
int sstop,ip;
float miat,msvt,svt;
float tval,tlq,tmen;
float sigma,time,lqt,lst,tle;
float wkst[100];
float b,mq,s,f,nd,ts,is,ta,ia,clock,fel[3];
int imevt,numevs;
rptgen() //报告生成子程序
{ float rho,w,pc,amts,amta,lq,l,wq;
rho=b/clock;
w=s/nd;
pc=f/nd;
amts=ts/is;
amta=ta/ia;
lq=tlq/clock;
l=tmen/clock;
wq=tlq/nd;
if((fp=fopen("fz22","wb"))==NULL)
{printf("cannot open file\n");
}
printf("time=%f\n",time);
fprintf(fp,"miat=%f,msvt=%f,sigma=%f,time=%f\n",miat,msvt,sigma,time); fprintf(fp,"rho=%f,mq=%f,pc=%f,clock=%f\n",rho,mq,pc,clock);
fprintf(fp,"nd=%f,amts=%f,amta=%f\n",nd,amts,amta);
fprintf(fp,"lq=%f,l=%f,wq=%f,w=%f\n",lq,l,wq,w);
}
float rand() //随机数生成子程序
{float a,c,m;
float rand1;
a=25173.0;
c=13849.0;
m=65535.0;
seed=(seed*a+c)-m*(int)((seed*a+c)/m);
if(seed==0.0) seed=1.0;
rand1=seed/m;
return rand1;
}
float normal(ex,stdx) //正态分布随机数生成子程序float ex,stdx;
{float sum,x;
int i;
float r;
sum=0.0;
for(i=1;i<=12;i++)
{r=rand();
sum=sum+r;}
x=stdx*(sum-6.0)+ex;
return x;
}
float expent(ex) //指数分布随机数生成子程序float ex;
{float r,x;
r=rand();
printf("r=%f",r);
x=-ex*log(r);
return x;
}
initlz() //系统初始化子程序
{float aat;
clock=0.0; //置仿真时钟为0.0
imevt=0; //假定系统在时间0为空闲
lqt=0.0; //置以下各统计量初值为0
lst=0.0;
tle=0.0;
b=0.0;
mq=0.0;
s=0.0;
f=0.0;
nd=0.0;
ts=0.0;
is=0.0;
ta=0.0;
ia=0.0;
tlq=0.0;
tmen=0.0;
aat=expent(miat);
fel[1]=clock+aat; //产生第一次到达,并安排在FEL(1)
fel[2]=1.0e+30; //置FEL(2)为无穷大,表示系统空闲时,不会发生离开事件
}
timadv() //时间推进子程序
{ float fmin;
int i;
fmin=1.0e+29;
imevt=0;
for (i=1;i<=numevs;i++) //搜索FEL以找出下一事件
{
if(fel[i]>=fmin) continue;
fmin=fel[i];
imevt=i;
}
if(imevt>0) //判断有无将来事件
{clock=fel[imevt]; //设定仿真时钟为下一事件时间,事件将在时间FEL(IMEVT)发生tval=clock-tle;
tlq=tlq+lqt*tval;
tmen=tmen+(lqt+lst)*tval;
}
else
{
rptgen(); //若将来事件为空,调用报告子程序
sstop=1;
}
}
arrvl() //到达事件子程序
{
float aat,svt;
if(lst==1.0) goto loop2; //检查服务员是否被占
lst=1.0; //若服务员空闲,修改系统状态并记录新的顾客的到达时间
wkst[ip]=clock;
svt=normal(msvt,sigma); //为新到达顾客产生服务时间并安排离开事件
fel[2]=clock+svt;
ts=ts+svt;
is=is+1.0; //修改累积统计量
tle=clock;
if(lqt>mq)mq=lqt;
goto loop3;
loop2: lqt=lqt+1.0; //若服务员被占,修改系统状态,记录新的顾客到达时间及系统中顾客数ip=lqt+lst;
if(ip>100) goto loop4; //现设系统容量为100人,若超过即给出报告
wkst[ip]=clock;
b=b+(clock-tle); //修改累积统计量
tle=clock;
if(lqt>mq) mq=lqt;
loop3: aat=expent(miat); //产生一个到达时间间隔并安排下一到达事件
ta=ta+aat;
ia=ia+1.0;
fel[1]=clock+aat;
goto loop31;
loop4: printf("overflow in array wkst");
rptgen();
sstop=1;
loop31:
}
dpart() //离开事件子程序
{ int i,i1;
float rt,svt;
b=b+(clock-tle); //修改累积统计量
tle=clock;
rt=clock-wkst[ip];
s=s+rt;
nd=nd+1.0;
if(rt>=4.0)f=f+1.0; //记录(累计)停留时间大于等于4的顾客数
if(lqt>1.0) //检查队列空否
{
for(i=1;i<=lqt;i++)
{i1=i+1; //此时至少有一个顾客在队列中,使每个顾客向前移动一个位置wkst[i]=wkst[i1];
}
lqt=lqt-1.0; //队列中的顾客数减1
svt=normal(msvt,sigma,svt); //对将被服务的顾客产生一个新的服务,时间且安排下一个
//离开事件
fel[2]=clock+svt;
}
else
{ //队列空,服务员空闲,下一离开事件置在无穷大时间
lst=0.0;
fel[2]=1.0e+30;}
}
main() //主程序
{
ip=0;
seed=2.0; //输入随机数种子
miat=10.0; //
msvt=3.0;
sigma=1.0;
time=100.0;
numevs=2; //确定事件总数为2
initlz(); //调用初始化子程序
sstop=0; //程序终止变量,sstop=0,程序循环,sstop=1,程序终止loop: timadv(); //调用时间推进子程序
if(sstop==1) goto loopp; //判断sstop=1,程序终止
if (imevt==1) //IMEVT=1为到达,IMEVT=2为离开
{arrvl(); //调用到达事件子程序
if(sstop==1) goto loopp; //判断sstop=1,程序终止
goto loop; //程序循环执行
}
if (imevt==2) dpart();` //调用离开事件子程序
if (clock