排队论经典程序MM1代码

更新时间:2024-04-10 10:16:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

修理店仿真报告

一.问题:

① ② ③ ④ ⑤ ⑥

修理店空闲的概率; 店内有三个顾客的概率;

店内至少有一个顾客的概率; 在店内顾客的平均数;

顾客在店内的平均逗留时间;

顾客必须在店内消耗15分钟以上的概率。

二.求解问题的方法: ①修理店空闲的概率:

(sim_time-area_server_status) / sim_time); ②店内有三个顾客的概率:

area_3_in_q/sim_time);

③店内至少有一个顾客的概率:

abv_1/sim_time);

④在店内顾客的平均数:

area_num_in_h/sim_time);

⑤顾客在店内的平均逗留时间:

(total_of_delays+total_of_server)/ num_custs_delayed );

⑥顾客必须在店内消耗15分钟以上概率:

abv_15/num_custs_delayed);

三。求解过程中计算统计量的方法:

① area_server_status += server_status * time_since_last_event; ② //店内有三个顾客的概率 if(server_status == BUSY)

//服务台忙,则有队列中有两个顾客 if(num_in_q == 2)

area_3_in_q += time_since_last_event; ③ //店内至少有一个顾客的概率

if(server_status == BUSY)

//服务台忙,则店内至少有

一个顾客

abv_1 += time_since_last_event;

④ //在店内顾客的平均数

if(server_status == BUSY)

//服务台忙,总的顾客数为

排队顾客数加一

area_num_in_h += (num_in_q+1) * time_since_last_event;

⑤ total_of_server += time_next_event[2]-sim_time;//总的服务时间加一个服务时间为新的服务总时间

delay = sim_time - time_arrival[1];//排队时间=当前时间-这个人来的时间

total_of_delays += delay;

⑥ //离开时总的消耗时间大于15,必须在店内消耗15分钟以上的顾客数加一

if((delay+time_next_event[2]-sim_time)>15) abv_15++;

//到达时总的服务时间大于15,必须在店内消耗15分钟以上的顾客数加一

if((time_next_event[2]-sim_time)>15) abv_15++;

程序代码:

/* External definitions for single-server queueing system. */

#include #include

/*#include \ Header file for random-number generator. */

#define Q_LIMIT 100 /* Limit on queue length.队伍最长100人 */ #define BUSY 1 /* Mnemonics for server's being busy 忙碌状态*/

#define IDLE 0 /* and idle.空闲状态 */

int next_event_type, //下一个事件类型 num_custs_delayed, //已模拟的顾客数 num_delays_required, //模拟的顾客数 num_events,//事件数 num_in_q, //队列中的顾客数

server_status;//服务状态

float area_num_in_q,//有顾客的时间

area_server_status,//总的服务时间 mean_interarrival,//平均顾客到达时间间隔 mean_service,//平均服务时间 sim_time, //模拟时间

time_arrival[Q_LIMIT + 1], //到来的时间 time_last_event, //上一个事件的时间 time_next_event[3],//下一个事件的时间

total_of_delays; //总的排队时间

//////////////////////////////////////////////////////////////////////////////////// //添加的变量 float abv_15,

//15分钟以上的顾客数量 //所有顾客的总的服务时间

//有3个顾客的时间

total_of_server, area_3_in_q, abv_1,

//至少有一个顾客的时间 //顾客总数

area_num_in_h;

//////////////////////////////////////////////////////////////////////////////////// FILE *infile, *outfile;

/* The following 3 declarations are for use of the random-number generator

lcgrand and the associated functions lcgrandst and lcgrandgt for seed management. This file (named lcgrand.h) should be included in any

program

using these functions by executing #include \ before referencing the functions. */

float lcgrand(int stream);

void lcgrandst(long zset, int stream); long lcgrandgt(int stream);

void initialize(void); void timing(void); void arrive(void); void depart(void); void report(void);

void update_time_avg_stats(void); float expon(float mean);

main() /* Main function. */ {

/* Open input and output files. */

infile = fopen(\ \ outfile = fopen(\

/* Specify the number of events for the timing function. */

num_events = 2;//两种事件

/* Read input parameters. */

fscanf(infile, \ &num_delays_required);

/* Write report heading and input parameters. 输出*/

fprintf(outfile, \ fprintf(outfile, \ mean_interarrival); fprintf(outfile, mean_service); fprintf(outfile, num_delays_required);

\

of

customersd\\n\\n\

\

service

time.3f

minutes\\n\\n\

/* Initialize the simulation.初始化仿真 */

initialize();//初始化

/* Run the simulation while more delays are still needed.没服务完,仿真继续 */

while (num_custs_delayed < num_delays_required) {//当已服务顾客数小于1000时

/* Determine the next event. 确定下一事件*/

timing();

/* Update time-average statistical accumulators.时间记录更新 */

update_time_avg_stats();

/* Invoke the appropriate event function. 根据事件的不同,调用不同的函数*/

switch (next_event_type) { case 1:

arrive();//到达 break; case 2:

depart();//离开 break; } }

/* Invoke the report generator and end the simulation. */

report();

fclose(infile); fclose(outfile);

return 0; }

void initialize(void) /* Initialization function. */ {

/* Initialize the simulation clock. 仿真时间置为0*/

sim_time = 0.0;

/* Initialize the state variables.最开始状态初始化 */

server_status = IDLE;//服务空闲

num_in_q = 0; //队伍里无人排队

time_last_event = 0.0; //上一个事件的时间,最开始肯定是0开始

/* Initialize the statistical counters. */

num_custs_delayed = 0; //已经服务的人数 total_of_delays = 0.0;//总的排队时间 area_num_in_q = 0.0;//有顾客的时间 area_server_status = 0.0;//总的服务时间 ///////////////////////////////////////////////////////////////////////////////// //添加的变量的初始化

area_3_in_q = 0.0;//有3个顾客的时间 abv_1 = 0.0;//有顾客的时间

area_num_in_h = 0.0;//顾客的总数

total_of_server = 0.0;//所有顾客的所有的服务的时间 abv_15

= 0.0;//消耗15分钟以上的顾客数

/////////////////////////////////////////////////////////////////////////////////

/* Initialize event list. 初始化事件列表 Since no customers are present, the departure

(service completion) event is eliminated from consideration. 无顾客存在和离开*/

time_next_event[1] = sim_time + expon(mean_interarrival);//下一事件是来的时间

time_next_event[2] = 1.0e+30; //下一事件是离开的时间 }

void timing(void) /* Timing function. */ {

int i;

float min_time_next_event = 1.0e+29; //像指针一样的对于当前服务的人来说下一个事件的时间

next_event_type = 0;

/* Determine the event type of the next event to occur.接下来将要发生的事件的类型 */

for (i = 1; i <= num_events; ++i) if (time_next_event[i] < min_time_next_event) {//下一事件是来的时间跟离开时间比较

min_time_next_event = time_next_event[i]; next_event_type = i; }

/* Check to see whether the event list is empty. */

if (next_event_type == 0) {

/* The event list is empty, so stop the simulation. 无事件,停止仿真过程*/

fprintf(outfile, \ exit(1);

}

/* The event list is not empty, so advance the simulation clock. 有事件,进行仿真过程*/

sim_time

=

min_time_next_event;

//仿真的时间就是当前事件的时间 }

void arrive(void) /* Arrival event function. */ {

float delay;

/* Schedule next arrival.计划下一次的到来 */

time_next_event[1] = sim_time + expon(mean_interarrival);

/* Check to see whether server is busy. 检测是否在服务状态*/

if (server_status == BUSY) {

/* Server is busy, so increment number of customers in queue. 在服务则排队多一人*/

++num_in_q;

/* Check to see whether an overflow condition exists. 检测人数是否超出*/

if (num_in_q > Q_LIMIT) {

/* The queue has overflowed, so stop the simulation. */

fprintf(outfile, \ fprintf(outfile, \ exit(2); }

/* There is still room in the queue, so store the time of arrival of the

arriving customer at the (new) end of time_arrival. 队列中仍有空间时,记录新到达的时间*/

time_arrival[num_in_q] = sim_time;//在这个时间的时候有这么多的排队人数,用于计算3顾客的问题 }

else { //服务空闲的状况

/* Server is idle, so arriving customer has a delay of zero. (The

following two statements are for program clarity and do not affect

the results of the simulation.) */

delay = 0.0;

total_of_delays += delay; //总的排队时间

/* Increment the number of customers delayed, and make server busy. */

++num_custs_delayed; //已经模拟的顾客数加1

server_status = BUSY; //人到来,服务开始

/* Schedule a departure (service completion). 服务完成*/

time_next_event[2] = sim_time + expon(mean_service);//这个人离开的时间为现在时间+服务时间

///////////////////////////////////////////////////////////////////////////////// //总的服务时间加上当前服务时间,更新总的服务时间

total_of_server += time_next_event[2]-sim_time;//总的服务时间

加一个服务时间为新的服务总时间

//总的服务时间大于15,必须在店内消耗15分钟以上的顾客数加一

if((time_next_event[2]-sim_time)>15)//如果这个人服务时间超

过15分钟则耗费15分钟人数加1

abv_15++;

///////////////////////////////////////////////////////////////////////////////// } }

void depart(void) /* Departure event function. 讨论离开事件*/ {

int i; float delay;

/* Check to see whether the queue is empty.检测队列是否为空 */

if (num_in_q == 0) {

/* The queue is empty so make the server idle and eliminate the departure (service completion) event from consideration. 队列空,服务空闲*/

server_status = IDLE;

time_next_event[2] = 1.0e+30; //离开的时间无限大(无人离开) }

else {

/* The queue is nonempty, so decrement the number of customers in

queue. 有人离开,队列人数减少*/

--num_in_q;

/* Compute the delay of the customer who is beginning service

and update

the total delay accumulator. */

delay = sim_time - time_arrival[1];//排队时间=当前时间-这个人来的时间

total_of_delays += delay;

/* Increment the number of customers delayed, and schedule departure.已经服务人数+1 */

++num_custs_delayed; //服务人数加1

time_next_event[2] = sim_time + expon(mean_service);//当前接受服务的人的离开时间

///////////////////////////////////////////////////////////////////////////////// //总的服务时间加上当前服务时间,更新总的服务时间

total_of_server += time_next_event[2]-sim_time;

//总的消耗时间大于15,必须在店内消耗15分钟以上的顾客数加一

if((delay+time_next_event[2]-sim_time)>15)

abv_15++;

/////////////////////////////////////////////////////////////////////////////////

/* Move each customer in queue (if any) up one place.有人离开,队列前移 */

for (i = 1; i <= num_in_q; ++i)

time_arrival[i] = time_arrival[i + 1];//人的到达时间也前移 } }

void report(void) /* Report generator function. */ {

/* Compute and write estimates of desired measures of performance. */

fprintf(outfile, \ total_of_delays / num_custs_delayed); fprintf(outfile, \ area_num_in_q / sim_time); fprintf(outfile, \ area_server_status / sim_time);

fprintf(outfile, \

printf(\统计量:\\n\

////////////////////////////////////////////////////////////////////////

//总时间减去服务台忙的时间除以总时间,得到服务台空闲的概率

printf(\①修理店空闲的概率:$.3f\\n\

(sim_time-area_server_status) / sim_time);

printf(\②店内有三个顾客的概率: .3f\\n\

area_3_in_q/sim_time);

printf(\③店内至少有一个顾客的概率:.3f\\n\

abv_1/sim_time);

printf(\④在店内顾客的平均数:".3f\\n\

area_num_in_h/sim_time);

printf(\⑤顾客在店内的平均逗留时间:.3f\\n\

(total_of_delays+total_of_server)/ num_custs_delayed );

printf(\⑥顾客必须在店内消耗15分钟以上概率:%8.3f\\n\\n\

abv_15/num_custs_delayed);

printf(\仿真时间:.3f minutes\\n\\n\////////////////////////////////////////////////////////////////////// }

void update_time_avg_stats(void) /* Update area accumulators for

time-average

statistics.更新时间平均时间统计 */ {

float time_since_last_event;

/* Compute time since last event, and update last-event-time marker.上个事件到现在的时间并更新最后事件的标记 */

time_since_last_event = sim_time - time_last_event;//两个事件的时间差

time_last_event = sim_time;

/* Update area under number-in-queue function. 有顾客的时间=队列中的人数*时间差*/

area_num_in_q += num_in_q * time_since_last_event;

/* Update area under server-busy indicator function. 总的服务时间=所有时间差相加*/

area_server_status += server_status * time_since_last_event;

///////////////////////////////////////////////////////////////////////////////// //店内有三个顾客的概率

if(server_status == BUSY)

//服务台忙,则有队列中有两个

顾客

if(num_in_q == 2)

area_3_in_q += time_since_last_event;

//服务台空闲,则有队列中有三

//if(server_status == IDLE)

个顾客

// if(num_in_q == 3) //

area_3_in_q += time_since_last_event;

//店内至少有一个顾客的概率

if(server_status == BUSY)

//服务台忙,则店内至少有一个

顾客

abv_1 += time_since_last_event;

//服务台空闲,则有队列中至少

//if(server_status == IDLE)

有一个顾客

// if(num_in_q>0) //

abv_1 += time_since_last_event;

//在店内顾客的平均数

if(server_status == BUSY)

//服务台忙,总的顾客数为排队

顾客数加一

area_num_in_h += (num_in_q+1) * time_since_last_event;

//服务台空闲,总的顾客数为排

//if(server_status == IDLE)

队顾客数

// area_num_in_h += num_in_q * time_since_last_event;

///////////////////////////////////////////////////////////////////////////////// }

float expon(float mean) /* Exponential variate generation function. */ {

/* Return an exponential random variate with mean \

return -mean * log(lcgrand(10));//自己学号的后两位 }

/* Prime modulus multiplicative linear congruential generator

Z[i] = (630360016 * Z[i-1]) (mod(pow(2,31) - 1)), based on Marse and Roberts'

portable FORTRAN random-number generator UNIRAN. Multiple

(100) streams are

supported, with seeds spaced 100,000 apart. Throughout, input argument

\must be an int giving the desired stream number. The header file

lcgrand.h must be included in the calling program (#include \

before using these functions.

Usage: (Three functions)

1. To obtain the next U(0,1) random number from stream \execute

u = lcgrand(stream);

where lcgrand is a float function. The float variable u will contain the

next random number.

2. To set the seed for stream \ lcgrandst(zset, stream);

where lcgrandst is a void function and zset must be a long set to the

desired seed, a number between 1 and 2147483646 (inclusive). Default

seeds for all 100 streams are given in the code.

3. To get the current (most recently used) integer in the sequence being

generated for stream \ zget = lcgrandgt(stream); where lcgrandgt is a long function. */

/* Define the constants. */

#define MODLUS 2147483647 #define MULT1 24112 #define MULT2 26143

/* Set the default seeds for all 100 streams. */

static long zrng[] = { 1, 1973272912,

20006270,1280689831,2096730329,1933576050,

281629770,

913566091,

604901985,1511192140,1259851944, 824064364,

150493284,

246780520,1363774876,

242708531,

75253171,1964472944,1202299975, 233217322,1911216000, 993232223,1103205531,

762430696,1922803170,1385516923, 726466604,

336157058,1432650381,1120463904, 877722890,1046574445, 68911991,2088367019, 640690903,

1774806513,2132545692,2079249579, 852776735,1187867272,

1351423507,1645973084,1997049139, 898585771,

243649545,1004818771, 372279877,1901633463, 498067494,2087759558,

597104727,1530940798,1814496276, 536444882,1663153658, 619691088,

855503735,

67784357,1432404475,

493157915,

773686062,

403188473,

922510944,2045512870,

78130110,

748545416,

622401386,2122378830,

595778810,

76271663,

413682397,

726370533,

403498145,

119025595,

277854671,1366580350,

880802310, 176192644,1116780070,

1142483975,2026948561,1053920743, 786262391,1792203830,1494667770,

1923011392,1433700034,1244184613,1147297105, 539712780,1545929719, 190641742,1645390429, 927711160,

364849192,2049576050, 638580085, 547070247 };

/* Generate the next random number. */

float lcgrand(int stream) {

long zi, lowprd, hi31;

zi = zrng[stream];

lowprd = (zi & 65535) * MULT1;

hi31 = (zi >> 16) * MULT1 + (lowprd >> 16); zi = ((lowprd & 65535) - MODLUS) + ((hi31 & 32767) << 16) + (hi31 >> 15); if (zi < 0) zi += MODLUS;

264907697,

620389253,1502074852,

lowprd = (zi & 65535) * MULT2;

hi31 = (zi >> 16) * MULT2 + (lowprd >> 16); zi = ((lowprd & 65535) - MODLUS) + ((hi31 & 32767) << 16) + (hi31 >> 15); if (zi < 0) zi += MODLUS; zrng[stream] = zi;

return (zi >> 7 | 1) / 16777216.0; }

void lcgrandst (long zset, int stream) /* Set the current zrng for stream \{

zrng[stream] = zset; }

long lcgrandgt (int stream) /* Return the current zrng for stream \*/ {

return zrng[stream]; }

本文来源:https://www.bwwdw.com/article/mw3r.html

Top