#include #include #include // *** Tiempo de proceso del dispositivo: NORMAL(m,d) #define NORMAL_MEAN 3.2 #define NORMAL_DESV 0.6 // *** Tiempo de llegadas: EXPONENCIAL(m) #define EXPONENTIAL_MEAN 4.5 // *** Número máximo de elementos en la cola #define QUEUE_SIZE 101 // *** Número de unidades que se procesan #define UNITS 1000 // *** Tiempo máximo de proceso #define MAX_TIME 7.0 // *** Número de eventos diferentes #define EVENT_TYPES 2 // *** Indica la inexistencia de evento #define NO_EVENT 1000000 //*** Reloj de simulación float simulationTime; //*** Tiempo de utilización del dispositivo float busyTime; //*** Tiempo de respuesta acumulado float responseTime; //*** Momento en el que sucedió el último evento float lastEventTime; //*** Momento de llegadas de unidades a la cola float queue[QUEUE_SIZE]; //*** Momento de sucesión de los próximos eventos. [0]: entrada, [1]: salida float events[EVENT_TYPES]; // *** Tipo del siguiente evento int nextEvent; // *** Número de unidades en la cola int unitsInQueue; // *** Número máximo de unidades en la cola int maxQueueOccupation; // *** Número total de unidades procesadas int unitsTotal; // *** Número de unidades procesadas por encima del tiempo máximo int unitsInMaxTime; // *** Indica si el dispositivo está o no ocupado bool busyDevice; float exponential(float fmean) { float r = 1.*random()/RAND_MAX;; return -fmean*log(r); } float normal(float mean, float sigma){ double rone = 1.*random()/RAND_MAX; double rtwo = 1.*random()/RAND_MAX; double zone = sqrt(-2*log(rone))*sin(2*M_PI*rtwo); return (float) zone*sigma+mean; } void initialize() { // Reloj de simulación a cero simulationTime = 0; // Las condiciones iniciales indican que el sistema está vacío y por // tanto el dispositivo libre. busyDevice = false; // No se ha producido ningún evento previo lastEventTime = 0; // Inicialización de las variables que almacenan los datos estadísticos busyTime = 0; responseTime = 0; unitsInQueue = 0; maxQueueOccupation = 0; unitsTotal = 0; unitsInMaxTime = 0; // Se planifica el primer evento de llegada y se inicializa a un tiempo // elevado el de salida con el fin de no ser elegido events[0] = simulationTime + exponential(EXPONENTIAL_MEAN); events[1] = NO_EVENT; } void time_advance() { float fmin; int i; nextEvent = 0; fmin = events[nextEvent]; for(i = 1; i < EVENT_TYPES; i++){ if (events[i] < fmin) { fmin = events[i]; nextEvent = i; } } simulationTime = events[nextEvent]; } void llegada( ) { // Determina si el servidor está ocupado if (!busyDevice) { // Actualiza el estado y almacena el tiempo de // de llegada para el siguiente cliente busyDevice = true; queue[0] = simulationTime; // Genera un tiempo de servicio y prepara el // evento de salida events[1] = simulationTime + normal(NORMAL_MEAN, NORMAL_DESV); // Actualiza estadistica LastEventTime para ver la // ocupacion del servidor lastEventTime = simulationTime; } else { unitsInQueue++; // Actualiza el estado y almacena el tiempo de // llegada para el siguiente cliente if (unitsInQueue > QUEUE_SIZE ){ printf("DESBORDAMIENTO DE LA COLA \n"); exit(0); } else { if (unitsInQueue > maxQueueOccupation) maxQueueOccupation = unitsInQueue; } queue[unitsInQueue] = simulationTime; // Actualiza estadísticas busyTime= busyTime + simulationTime - lastEventTime; lastEventTime = simulationTime; } // Genera un tiempo entre llegadas y planifica el siguiente evento events[0] = simulationTime + exponential(EXPONENTIAL_MEAN); } void salida( ) { // Actualiza estadísticas acumulativas b,s,nd y f busyTime = busyTime + simulationTime - lastEventTime; float rt = simulationTime - queue[0]; responseTime = responseTime + rt; unitsTotal++; if (rt > MAX_TIME) unitsInMaxTime++; // Comprueba el estado de la cola de espera if (unitsInQueue == 0){ // No hay clientes en la cola-> servidor inactivo y // tiempo de salida muy alto para no ser elegido busyDevice = false; events[1] = NO_EVENT; }else{ // Cada cliente en cola avanza una posicion for(int i=0; i