您的位置:首页 > 编程语言

系统排队仿真源代码

2013-05-02 23:13 295 查看
#include "stdafx.h"
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <queue>
#include <list>
#include <vector>

using namespace std;
const int Packet_Size=1000;
double lanmada=0.95; //到达间隔分布参数
double mu=1.0; //服务时间分布参数
int B=1; //标示系统容量
int Loss_Num=0; //记录到达的包的损失的数量
float EG=0; //总能量
double Service_Total_Time=0;

struct Event//事件
{
int id; //事件主体
double time;//事件发生时刻
int type; //事件类型

};
list < Event > eventtable;//事件表

struct Customer//顾客
{
double arrive;//到达时刻
double start;//开始服务时刻
double depart;//离开时刻

};
//vector< Customer > customer;//顾客数据集
Customer customer[Packet_Size];

queue< int > customerqueue;//排队情况
double t_idle=0;//空闲开始时刻
double s_idle=0;//累计空闲时间

//产生负指数分布的随机数
inline double exprand(double lanmada)
{
int rnd;
double r,x;

while(1)
{
rnd=rand();
if(rnd!=0 && rnd!=RAND_MAX)
break;
}
r=double(rnd)/RAND_MAX;

x=(-1/lanmada)*log(r);

return x;
}

void init()//仿真初始化
{
srand( time(NULL) );

Event event;
double t;
t=0;

event.id=0; //第一个时间的id是0,且事件类型是到达,时间的发生时刻是0;
event.type =0;
event.time =t;
eventtable.push_back(event); //将初始化事件进入时间链表

Loss_Num=0;
EG=0;
Service_Total_Time=0;

}

void insert(list<Event> &table ,Event event) //当发生顾客到达或离开时调用插入事件函数
{
list< Event >::iterator iter=table.begin(); //初始化事件迭代器

while( ((iter->time)< event.time) ) //循环到顾客到达这一事件的时刻
{
iter++;
if(iter==table.end()) //如果已经到了事件链表的最后一个事件则跳出
break;
}

table.insert(iter,event);
}

int arriveproc(int id,double t) //顾客到达程序
{
customer[id].arrive =t;
cout<<'['<<t<<']'<<' '<<"pkt"<<id<<' '<<"arrives"<<'.'<<"It finds "<<customerqueue.size()<<"packets "<<"in the queue!"<<endl;
if( id+1<=sizeof(customer)/sizeof(customer[0])-1/*customerqueue.size()!=0*/ )
{
//生产下个到达事件
Event nextevent;
nextevent.id =id+1;
nextevent.type =0;
nextevent.time =t+exprand(lanmada);
insert(eventtable,nextevent);
/*customerqueue.push(id);*/
}
if( (customerqueue.size()!=0)&&(customerqueue.size()<B) )
{
customerqueue.push(id);//排队
}
if(customerqueue.size()==B)
{
Loss_Num=Loss_Num+1;

}
if(customerqueue.size()==0)
{
customer[id].start =t; //如果顾客队列是空的,则新建一个事件,事件的id不变,
customer[id].depart =t+exprand(mu); // 事件的类型是1,事件的时间是当前事件+指数分布
s_idle=s_idle + (t-t_idle);//空闲结束 将此事件插入事件队列,并将此顾客进入顾客队列

Event event;
event.time=customer[id].depart;
event.type=1;
event.id=id;
insert(eventtable,event);
customerqueue.push(id);
}

return 0;

}

int departproc(int id,double t) //顾客离开程序
{
//int id0=customerqueue.front();
//if( id0==id)
EG=EG+(t-customer[id].arrive)/10.0;
cout<<'['<<t<<']'<<' '<<"pkt"<<id<<' '<<"departs"<<'.'<<"It spent "<<t-customer[id].arrive<<"us"<<' '<<"in the system and required "<<(t-customer[id].arrive)/10.0<<"mJ for DRAM refresh!"<<endl;
Service_Total_Time=Service_Total_Time+customer[id].depart-customer[id].start;
customerqueue.pop();

if( customerqueue.size()==0)
{
//空闲
t_idle=t;//记录空闲开始时刻
}
else
{
int id2=customerqueue.front(); //将顾客队列中最前面的顾客的开始时间设为t,离开时间设为
customer[id2].start=t; //t+指数分布
customer[id2].depart=t+exprand(mu);
Event event;
event.time=customer[id2].depart; //产生一个新的事件,此事件的事件是这个顾客离开的时间
event.type=1; //事件的类型是1,事件的id是顾客队列中最前面的顾客的id
event.id=id2; //将此事件插入事件队列
insert(eventtable,event);
}

return 0;
}

int main()
{
// TODO: Place code here.

double t;//仿真钟
double T;//仿真结束时间
Event event; //每次要处理的一个事件

//ifstream infile(ifile.c_str());
ofstream fout;
fout.open("out.txt",ios::ate);
if(!fout) cout<<"cannot open file"<<endl;
for(B=1;B<=10;B++)
{
init();
t=0;

while( eventtable.size()!=0 )
{
event=eventtable.front();
t=event.time;
eventtable.pop_front();
//cout<<"t="<<event.time<<"\ttype="<<event.type<<"\tid="<<event.id<<endl;
switch( event.type )
{
case 0: arriveproc(event.id,event.time);
break;
case 1: departproc(event.id,event.time);
break;
}

}

T=t;
//数据处理
/* double s=0,s1=0;
for(int i=0;i<sizeof(customer)/sizeof(customer[0]);i++)
{
s=s+(customer[i].depart -customer[i].arrive);
s1=s1+(customer[i].depart -customer[i].start);
}

s=s/(sizeof(customer)/sizeof(customer[0]));
s1=s1/(sizeof(customer)/sizeof(customer[0]));
*/
float L=Loss_Num/(Packet_Size-0.0);
float E=EG/(Packet_Size-Loss_Num); //平均能量
float Service_average_Time=Service_Total_Time/(Packet_Size-Loss_Num);//服务平均时间
cout<<"Loss_Num="<<Loss_Num<<endl; //损失的包数量
//fout<<"Loss_Num="<<Loss_Num<<endl;
cout<<"平均服务时间="<<Service_average_Time<<"us"<<endl;
//fout<<"平均服务时间="<<Service_average_Time<<endl;

cout<<"包损失率="<<L<<endl;
//fout<<"包损失率="<<L<<endl;
cout<<"每个包刷新平均能量="<<E<<"mJ"<<endl;
//fout<<"每个包刷新平均能量="<<E<<"mJ"<<endl;
cout<<"仿真开始时刻="<<0<<"us"<<endl;
//fout<<"仿真开始时刻="<<0<<"us"<<endl;
cout<<"仿真结束时刻="<<T<<"us"<<endl;
//fout<<"仿真结束时刻="<<T<<"us"<<endl;
cout<<endl;
//cout<<"系统空闲时间="<<s_idle<<endl;
//cout<<"空闲率="<<100*(s_idle/T)<<"%"<<endl;
cout<<endl;
//cout<<"平均停留时间(仿真值)="<<s<<endl;
//cout<<"平均服务时间(仿真值)="<<s1<<endl;
//cout<<endl;
//cout<<"平均停留时间(理论值)="<<1/(mu-lanmada)<<endl;

cout<<"平均服务时间(理论值)="<<1/mu<<"us"<<endl;
//fout<<"平均服务时间(理论值)="<<1/mu<<endl;
cout<<B<<endl;
fout<<L<<' '<<E<<';';

}

fout << flush;
fout.close();
return 0;
}专业程序代写大学生程序代写
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: