⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mm2.cpp

📁 队列事件驱动仿真
💻 CPP
字号:
 
  /******* M/M/1  main program   **********/
#include "stdio.h"
#include "math.h"

int NEVNTS,NEXT,NIQ,NUMCUS,STATUS1,STATUS2,TOTCUS,maxq=0;
float MODEl,ANIQ,MARRVT,MSERVT,TIME,TLEVNT,TOTDEL,maxqt=0;
float TNE[3],TARRVL[100];

double random(float type)
{ static double x,z;
  float RAND;
  if(type<=0) z=1.0;
  x=z;
  x=65539*x+1743251541;
  x=fmod(x,2147483638);
  z=x;
  RAND=(float)x/2147483638;
  return RAND;
 }

float expondep(float RMEAN)
{ float RANDE,U;
  U=(float)random(TIME);
  RANDE=(float)(-RMEAN*log(U));
  return RANDE;
}

float exponarr(float MARRVT)
{ float RANDA,U;
  U=(float)random(TIME);
  RANDA=(float)(-MARRVT*log(U));
  return RANDA;
}

void main()
{ void init(),timing(),arrive(),depart(),report();
  NEVNTS=2;   /* 两种事件类型:  到达,离开 */
  printf("\n输入平均到达间隔:"); scanf("%f",&MARRVT);   /* 到达间隔均值 */
  printf("\n输入平均服务时间:"); scanf("%f",&MSERVT);   /* 平均服务时间  */
  printf("\n输入顾客总数:\n"); scanf("%d",&TOTCUS);	    /* 顾客总数 */
  init();
  while (NUMCUS<TOTCUS)
  { timing();
    if(NEXT==1)      //  NEXT为1: 将产生到达事件
     { arrive(); 
	   if(maxq<NIQ) maxq=NIQ;
     }
    if(NEXT==2)      //  NEXT为2: 将产生离开事件
     { depart(); 
	   if(maxq<NIQ) maxq=NIQ; 
     }
  }
  report();
}

void init()
{ TIME=0;     /* 仿真钟 */
  STATUS1=0;   /* 服务器状态: 0闲,1忙  */
  STATUS2=0;
  NIQ=0;      /* 队长  */
  TLEVNT=0;   /* 前一事件时间  */
  NUMCUS=0;   /* 已服务的顾客数  */
  TOTDEL=0;   /* 排队时间总和  */
  ANIQ=0;     /* 队长积分值 */
  TNE[1]=TIME+exponarr(MARRVT);   /* 类型I,到达事件发生时间  */
  TNE[2]=1.0e10;
  return;
}

void timing()		// 推进时钟到下一最早事件
{ int i;
  float RMIN=1.0e10;   /*  下一事件最早发生时间设为无穷大  */
  NEXT=0;
  for(i=1;i<=NEVNTS;i++)  // 找出下一个最早发生事件
    if (TNE[i]<=RMIN)
    { RMIN=TNE[i]; 
	  NEXT=i;            //  事件代号next: 0为错误,1为到达,2为离开
	}
  if (NEXT<=0) printf("event list empty  next=%d\n",NEXT);
  else TIME=TNE[NEXT]; 	// 始终定到下一事件
}

void arrive()
{ float DELAY;
  TNE[1]=TIME+exponarr(MARRVT);       // 服务时间为现时间+服务时间 
  if(STATUS1==1&&STATUS2==1)                       // 服务状态:0闲,1忙
  { ANIQ=ANIQ+NIQ*(TIME-TLEVNT);      // 对长积分
	if(maxqt<TIME-TLEVNT) maxqt=TIME-TLEVNT;  // 最大排队时间
    TLEVNT=TIME;                      // 前一事件发生时间变为当前时间
    NIQ=NIQ+1;                        // 对长+1
    if(NIQ<=100) TARRVL[NIQ]=TIME;    // 第i个顾客到达时间
    else printf("overflow of the arry tarrvl"); // 对长大于100超界 
    return;
  }
  else if(STATUS1==0)
			{ DELAY=0;
			  TOTDEL=TOTDEL+DELAY;              //  客户等待积分时间
              NUMCUS=NUMCUS+1;                  //  客户+1
              STATUS1=1;                         //  服务状态: 0闲,1忙
              TNE[2]=TIME+expondep(MSERVT);        //  服务时间为现时间+服务间隔
              return;
  }
        else
			{ DELAY=0;
			  TOTDEL=TOTDEL+DELAY;              //  客户等待积分时间
              NUMCUS=NUMCUS+1;                  //  客户+1
              STATUS2=1;                         //  服务状态: 0闲,1忙
              TNE[2]=TIME+expondep(MSERVT);        //  服务时间为现时间+服务间隔
              return;
		}

}

void depart()
{ float expon();
  int i,i1;
  float DELAY;
  if(NIQ>0)                           // 对长大于0
   { ANIQ=ANIQ+NIQ*(TIME-TLEVNT);     // TLEVNT 前一事件发生时间
     TLEVNT=TIME;
     NIQ=NIQ-1;                       //  对长 -1
     DELAY=TIME-TARRVL[1];
     TOTDEL=TOTDEL+DELAY;
     NUMCUS=NUMCUS+1;
     TNE[2]=TIME+expondep(MSERVT);
     if(NIQ!=0)
     for(i=1;i<=NIQ;i++)
     { i1=i+1;
       TARRVL[i]=TARRVL[i1];
     }
   }
  else
   { STATUS1=0;
     STATUS2=0;
     TNE[2]=1.0e10;
   }
  return;
}

void report()
{ float AVGNIQ,AVGDEL;
  printf("===SINGLE-SERVER QUEUEING SYSTEM===\n");
  printf("平均到达间隔: %6.2f 分钟\n",MARRVT);
  printf("平均服务时间: %6.2f 分钟\n",MSERVT);
  printf("最大顾客数:   %d人\n",TOTCUS);
  AVGDEL=TOTDEL/NUMCUS;
  AVGNIQ=ANIQ/TIME;
  printf("平均排队时间:%6.3f 分钟\n",AVGDEL);
  printf("最大排队时间:%6.3f 分钟\n",maxqt);
  printf("平均排队人数:%6.3f人\n",AVGNIQ);
  printf("最大排队人数:%d人\n",maxq);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -