计算机仿真排队系统实验报告(附代码)
- 格式:docx
- 大小:19.66 KB
- 文档页数:12
计算机仿真实验报告第一题1.作业内容应用排队系统流程图,用C语言编制仿真程序,求解以下问题。
修理店只有一个修理工,来修理的顾客到达次数服从泊松分布,平均4人/h;修理时间服从指数分布,平均需6min。
试求(随机数发生器采用float lcgrand(int stream) ,种子stream 为自己学号的最后两位。
):①修理店空闲的概率;②店内有三个顾客的概率;③店内至少有一个顾客的概率;④在店内顾客的平均数;⑤顾客在店内的平均逗留时间;⑥顾客必须在店内消耗15分钟以上的概率。
统计量实现算法:①修理店空闲的概率;p1=1-area_server_status/sim_timearea_server_status:总服务时间(即修理工在这段仿真时间里非空闲时间)sim_time:总仿真时间用1减去非空闲概率,即为空闲概率。
②店内有三个顾客的概率;p2=Three_people_time/sim_time增加变量Three_people_time,即有三个顾客在店内的时间。
三个顾客在店里,也就是说一个顾客在理发,两个人在排队,此时,无论是来一个新的客人或者离开一个客人,都会破坏这种三个人的状态,所以我们每次要统计的,就是这种三个人的状态持续的时间。
因此,用到的是time_since_last_event这个变量,该变量用于统计两种状态(事件,包括离开和到来)之间的事件。
因此,在每次计算完time_since_last_even t之后,考察队伍中的人数是否为2,若为2,则把该段time_since_last_event加到Three_people_time中。
仿真结束时,用Three_people_time/总仿真时间,即为店内有三个顾客的概率。
③店内至少有一个顾客的概率;p3=p3=1-idle_time/sim_time增加变量idle_time,即店里空闲的概率(没有顾客),用1减去一个顾客都没有的概率,就是至少有一个顾客的概率。
判断店里空闲的方法是,如果当前有一个顾客来了,他不需要排队,就意味着这之前店里是空闲着的。
这里仍用到time_since_last_event,在这个客人来之前的这段时间店里空闲,因此把这个时间段加给idle_time,以此累加,最后得到总的空闲时间。
④在店内顾客的平均数;mean_customer=1.0*num_custs_delayed/sim_time在这里我计算的是店里平均每分钟的顾客数(包括等待的和正在理发的)。
num_cust_delay ed是在这段仿真时间里总共出现的顾客,除以仿真时间,就是店内顾客平均数。
⑤顾客在店内的平均逗留时间;mean_stay_time=(area_num_in_q+area_server_status)/(1.0*num_custs_delayed)对于任意一位顾客,他在店里逗留的时间=排队时间+理发时间。
area_num_in_q统计的是队列中的顾客等待的总时间,而area_server_status统计的是所有顾客理发的总时间,相加就是所有顾客在店里逗留的时间,除以顾客的人数,就是顾客平均逗留时间。
⑥顾客必须在店内消耗15分钟以上的概率。
p6=1.0*count15/num_custs_delayed增加变量count15,用于统计在店内消耗15分钟以上的顾客人数,再增加变量single_cust_t ime,用于统计单个顾客在店内消耗的时间。
这里有两种情况。
(1)不用排队。
那么该顾客在店里消耗的时间就是理发时间,即single_cust_time=time_n ext_event[2]-sim_time。
time_next_event[2]=sim_time+expon(mean_service)。
(2)要排队。
那么single_cust_time=delay+time_next_event[2]-sim_time。
delay是当前有一位顾客离开时,得到的下一位将要理发的顾客(即队首顾客)的等待时间。
每一位顾客到店里时都会有一个time_arrival[]将其抵达时刻记录下来,因此,轮到他时,用sim_time减去time_arrival[]就得到了他等待的时间。
等待时间加上理发时间,就是这位顾客在店里消耗的时间。
以上可计算出单个顾客在店里消耗的时间,与15分钟比较,若超过,加入count15中,count 15除以总人数,就是所求概率。
对原程序的修改点:去掉了文件操作,用提示输入的方式输入参数,可多次输入。
增加变量count15,Three_peop le_time,idle_time,single_cust_time。
作用见上面六小题具体算法。
代码:#include <stdio.h>#include <math.h>#include <stdlib.h>/*#include "lcgrand.h" Header file for random-number generator. */#define Q_LIMIT 100 /* Limit on queue length. */#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,count15;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,Three_people_time,idle_time,single_cust_time,time_since_last_eve nt;/* The following 3 declarations are for use of the random-number generatorlcgrand and the associated functions lcgrandst and lcgrandgt for seedmanagement. This file (named lcgrand.h) should be included in any programusing these functions by executing#include "lcgrand.h"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);int main() /* Main function. */{/* Specify the number of events for the timing function. */char choice;num_events = 2;while(1){printf("Start to simulate?(Y/N)");getchar();scanf("%c",&choice);if(choice=='N')exit(0);printf("\n\nPlease enter the interarrival time(min):");scanf("%f",&mean_interarrival);printf("\nPlease enter the serving time(min):");scanf("%f",&mean_service);printf("\nPlease enter the number of customer:");scanf("%d",&num_delays_required);/* Initialize the simulation. */initialize();/* Run the simulation while more delays are still needed. */ while (num_custs_delayed < num_delays_required) {/* 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();}return 0;}void initialize(void) /* Initialization function. */{/* Initialize the simulation clock. */sim_time = 0.0;/* Initialize the state variables. */server_status = IDLE;num_in_q = 0;time_last_event = 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;// Initialize the variables I addedThree_people_time = 0.0;idle_time = 0.0;count15 = 0;/* 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. */printf("\nEvent list empty at time %f", sim_time);exit(0);}/* 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); //compute when the next people arrive/* 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. */printf("\nOverflow of the array time_arrival at");printf(" time %f", sim_time);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; //record the time when this person arrived}else {/* Server is idle, so arriving customer has a delay of zero. (Thefollowing two statements are for program clarity and do not affectthe results of the simulation.) */delay = 0.0; //no need to waittotal_of_delays += delay;idle_time+=time_since_last_event;/* Increment the number of customers delayed, and make server busy. */++num_custs_delayed;server_status = BUSY;/* Schedule a departure (service completion). */time_next_event[2] = sim_time + expon(mean_service); //compute the serve time of this person(to know when he will leave)single_cust_time = time_next_event[2] - sim_time;if(single_cust_time>=15)count15++;}}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 thedeparture (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 inqueue. */--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]; //how long does this person wait in the queuetotal_of_delays += delay; //the total waiting-time of people in the queue/* Increment the number of customers delayed, and schedule departure. */++num_custs_delayed;time_next_event[2] = sim_time + expon(mean_service); //compute the serve time of this personsingle_cust_time = delay + time_next_event[2] - sim_time;if(single_cust_time>=15)count15++;/* 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]; //FIFO,after the firstperson's departure,the queue moves.}}void report(void) /* Report generator function. */{/* Compute and write estimates of desired measures of performance. */ float p1,p2,p3,p6,mean_customer,mean_stay_time;p1=1-area_server_status/sim_time;p2=Three_people_time/sim_time;p3=1-idle_time/sim_time;mean_customer=1.0*num_custs_delayed/sim_time;mean_stay_time=(area_num_in_q+area_server_status)/(1.0*num_custs_delayed);p6=1.0*count15/num_custs_delayed;printf("\n\nSingle-server queueing system\n\n");printf("Mean interarrival time%11.3f minutes\n\n",mean_interarrival);printf("Mean service time%16.3f minutes\n\n", mean_service);printf("Number of customers%14d\n\n", num_delays_required);printf("Here is the report:\n");printf("\n\n修理店空闲的概率为:%11.3f\n\n",p1);printf("\n\n店内有三个顾客的概率为:%11.3f\n\n",p2);printf("\n\n店内至少有一个顾客的概率为:%11.3f\n\n",p3);printf("\n\n在店内顾客的平均数为%11.3f 人每分钟\n\n",mean_customer);printf("\n\n顾客在店内的平均逗留时间为%11.3f 分钟\n\n",mean_stay_time);printf("\n\n顾客必须在店内消耗15分钟以上的概率为:%11.3f\n\n",p6);printf("Time simulation ended%12.3f minutes\n\n",sim_time);}void update_time_avg_stats(void) /* Update area accumulators for time-averagestatistics. */{/* Compute time since last event, and update last-event-time marker. */time_since_last_event = sim_time - time_last_event;//how much time past from the last event(arrive or departure)time_last_event = sim_time;//record the moment of last eventif(num_in_q==2)Three_people_time+=time_since_last_event;/* Update area under number-in-queue function. */area_num_in_q += num_in_q * time_since_last_event;//count the total waiting-time of people in the queue/* Update area under server-busy indicator function. */area_server_status += server_status * time_since_last_event;//count the total serving-time}float expon(float mean) /* Exponential variate generation function. */{/* Return an exponential random variate with mean "mean". */return -mean * log(lcgrand(3));}/* Prime modulus multiplicative linear congruential generatorZ[i] = (630360016 * Z[i-1]) (mod(pow(2,31) - 1)), based on Marse and Roberts'portable FORTRAN random-number generator UNIRAN. Multiple (100) streams aresupported, with seeds spaced 100,000 apart. Throughout, input argument "stream" must be an int giving the desired stream number. The header filelcgrand.h must be included in the calling program (#include "lcgrand.h")before using these functions.Usage: (Three functions)1. To obtain the next U(0,1) random number from stream "stream," executeu = lcgrand(stream);where lcgrand is a float function. The float variable u will contain thenext random number.2. To set the seed for stream "stream" to a desired value zset, executelcgrandst(zset, stream);where lcgrandst is a void function and zset must be a long set to thedesired seed, a number between 1 and 2147483646 (inclusive). Defaultseeds for all 100 streams are given in the code.3. To get the current (most recently used) integer in the sequence beinggenerated for stream "stream" into the long variable zget, executezget = 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, 281629770, 20006270,1280689831,2096730329,1933576050, 913566091, 246780520,1363774876, 604901985,1511192140,1259851944, 824064364, 150493284, 242708531, 75253171,1964472944,1202299975, 233217322,1911216000, 726370533, 403498145, 993232223,1103205531, 762430696,1922803170,1385516923, 76271663, 413682397, 726466604, 336157058,1432650381,1120463904, 595778810, 877722890,1046574445, 68911991,2088367019, 748545416, 622401386,2122378830, 640690903, 1774806513,2132545692,2079249579, 78130110, 852776735,1187867272, 1351423507,1645973084,1997049139, 922510944,2045512870, 898585771, 243649545,1004818771, 773686062, 403188473, 372279877,1901633463, 498067494,2087759558, 493157915, 597104727,1530940798,1814496276, 536444882,1663153658, 855503735, 67784357,1432404475, 619691088, 119025595, 880802310, 176192644,1116780070, 277854671,1366580350, 1142483975,2026948561,1053920743, 786262391,1792203830,1494667770, 1923011392,1433700034,1244184613,1147297105, 539712780,1545929719, 190641742,1645390429, 264907697, 620389253,1502074852, 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;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"stream" to zset. */{zrng[stream] = zset;}long lcgrandgt (int stream) /* Return the current zrng for stream "stream". */ {return zrng[stream];}。