#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>
#include <conio.h>
#define INFINITO 999
/* parametros a cambiar */
#define num_elementos 10
#define tamanio_grupos 5
#define fallos_grupo 4
#define num_servidores 2
#define parametro_servicio 0.001
#define error_relativo 0.1
#define numero_minimo_iteraciones 100
/* no olvidar introducir tambien las landas */
#define num_acontecimientos num_servidores+num_elementos
#define tamanio_sistema_reparacion num_elementos
/* [1] */ void inicializacion_estructuras(int sistema[num_elementos], int sistema_reparacion[tamanio_sistema_reparacion],
int copia_sistema_reparacion[tamanio_sistema_reparacion], float acontecimientos[num_acontecimientos],
float tasas_de_fallos[num_elementos], float landas[fallos_grupo]);
/* [2] */ float generar_aleatorio(char aleatorio, float tasas_de_fallos[num_elementos], int que_elemento);
/* [3] */ int primer_acontecimiento(float acontecimientos[num_acontecimientos], int funcionamiento_sistema);
/* [4] */ int colocar_componente(int sistema_reparacion[tamanio_sistema_reparacion], int que_elemento);
/* [5] */ void reducir_acontecimientos(float acontecimientos[num_acontecimientos], float cantidad_a_reducir, int funcionamiento_sistema);
/* [6] */ int comprobar_funcionamiento(int sistema[num_elementos], int posicion);
/* [7] */ int reordenar_sistema_reparacion(int sistema_reparacion[tamanio_sistema_reparacion], int siguiente_acontecimiento);
/* [8] */ void actualiza_landas(float tasas_de_fallos[num_elementos], int sistema[num_elementos], float landas[fallos_grupo]);
/* [9] */ void colocar_cola_prioridades(int sistema_reparacion[tamanio_sistema_reparacion], int copia_sistema_reparacion[tamanio_sistema_reparacion],
float tasas_de_fallos[num_elementos], float landas[fallos_grupo]);
/* [10] */void calcula_intervalo_error(float valor, int numero_muestras, float ic_izquierdo, float ic_derecho, float error_relativo);
main () /* PROGRAMA PRINCIPAL */
{
/* a introducir antes de la simulacion */
float landas[4] = {0.01,0.012,0.017,0.021};
/* variables */
int siguiente_acontecimiento, i, j, componentes_reparados, funcionamiento_sistema;
float reloj, cantidad_a_reducir;
int que_elemento, que_acontecimiento, posicion;
/* variables para la solucion */
float indisponibilidad, infiabilidad, error_infiabilidad, error_indisponibilidad;
float icizq_infiabilidad, icde_infiabilidad, icizq_indisponibilidad, icde_indisponibilidad;
int numero_muestras, contador_infiabilidad, contador_indisponibilidad, detectado_fallo;
srand(time(NULL)); /* cambia aleatorio */
/* creacion de estructuras*/
int sistema[num_elementos];
int sistema_reparacion[tamanio_sistema_reparacion];
int copia_sistema_reparacion[tamanio_sistema_reparacion];
float acontecimientos[num_acontecimientos];
float tasas_de_fallos[num_elementos];
error_infiabilidad = 100;
numero_muestras = 0; contador_infiabilidad = 0; contador_indisponibilidad = 0;
while (error_infiabilidad > error_relativo) /* Codicion de parada del error */
{
numero_muestras++;
detectado_fallo = 0;
/* inicializacion de estructuras */
inicializacion_estructuras(sistema, sistema_reparacion, copia_sistema_reparacion, acontecimientos, tasas_de_fallos, landas);
/* ========================= */
/* COMIENZO DE LA SIMULACION */
/* ========================= */
reloj = 0;
funcionamiento_sistema = 1; /* (1) El sistema funciona (0) El sistema no funciona */
componentes_reparados = 0; /* almacena el numero de componentes que han sido reparados */
while (reloj<100) /* Condicion de parada de cada muestra */
{
siguiente_acontecimiento=primer_acontecimiento(acontecimientos, funcionamiento_sistema); /* vemos que acontecimiento es el siguiente */
if (siguiente_acontecimiento < num_servidores) /* se produce salida de un servidor */
{
que_elemento = sistema_reparacion[siguiente_acontecimiento];
sistema[que_elemento-1] = 1; /* se pone el componente a funcionando */
reloj = reloj + acontecimientos[siguiente_acontecimiento]; /* actualizamos el reloj */
actualiza_landas(tasas_de_fallos, sistema, landas);
cantidad_a_reducir = acontecimientos[siguiente_acontecimiento]; /* almacenamos la cantidad que debemos restar a todos los acontecimientos */
componentes_reparados++; /* se incrementan los componentes reparados */
reducir_acontecimientos(acontecimientos, cantidad_a_reducir, funcionamiento_sistema); /* se decrementan los acontecimientos */
acontecimientos[siguiente_acontecimiento] = INFINITO; /* se pone el servidor de momento a INFINITO */
acontecimientos[num_servidores + que_elemento - 1] = generar_aleatorio('e', tasas_de_fallos, que_elemento); /* el componente arreglado empieza a estropearse, tiempo */
if (reordenar_sistema_reparacion(sistema_reparacion, siguiente_acontecimiento) == 1) /* si ha sido ocupado el servidor por otro mcomponente */
{acontecimientos[siguiente_acontecimiento] = generar_aleatorio('s', tasas_de_fallos, que_elemento);} /* generamos el tiempo de servicio */
if ((funcionamiento_sistema == 0) && (comprobar_funcionamiento(sistema, (que_elemento-1)) == 1)) /* si no funciona y con esa llegada se arregla el sistema */
{funcionamiento_sistema = 1;} /* se pone a que funciona */
}
else /* se produce una llegada al sistema de reparacion */
{
que_elemento = siguiente_acontecimiento-(num_servidores-1);
sistema[que_elemento-1] = 0; /* se pone el componente a estropeado, -1 pues empieza en 0 */
actualiza_landas(tasas_de_fallos, sistema, landas); /* a fallado un elemento, cambiamos las tasas de fallos */
reloj = reloj + acontecimientos[siguiente_acontecimiento]; /* actualizamos el reloj */
cantidad_a_reducir = acontecimientos[siguiente_acontecimiento];
reducir_acontecimientos(acontecimientos, cantidad_a_reducir, funcionamiento_sistema); /* reducimos los tiempos */
acontecimientos[siguiente_acontecimiento] = INFINITO; /* no puede volver a llegar, esta reparandose */
if (comprobar_funcionamiento(sistema, (que_elemento-1)) == 0) /* si con esa llegada se estropea el sistema */
{funcionamiento_sistema = 0;
detectado_fallo = 1; /* usado para la infiabilidad */
}
posicion = colocar_componente(sistema_reparacion, que_elemento); /* apilarle en el sistema de reparacion */
if (posicion < num_servidores) /* se ha colocado en un servidor */
{acontecimientos[posicion] = generar_aleatorio('s', tasas_de_fallos, que_elemento);}
if (!(sistema_reparacion[num_servidores+1] == 0)) /* si alemnos hay 2 componentesen la cola es necesario colocar por prioridades */
{colocar_cola_prioridades(sistema_reparacion, copia_sistema_reparacion, tasas_de_fallos, landas);}
}
} /* fin de la muestra */
if (funcionamiento_sistema == 0){contador_indisponibilidad++;} /* en el momento que sale, t=100 */
if (detectado_fallo == 1){contador_infiabilidad++;} /* si ha fallado en el transcurso de los 100, infiabilidad */
infiabilidad = contador_infiabilidad / numero_muestras;
indisponibilidad = contador_indisponibilidad / numero_muestras;
if (numero_muestras > numero_minimo_iteraciones) /* si lleva ya suficiente iteraciones */
{
calcula_intervalo_error(infiabilidad, numero_muestras, icizq_infiabilidad, icde_infiabilidad, error_infiabilidad);
calcula_intervalo_error(indisponibilidad, numero_muestras, icizq_indisponibilidad, icde_indisponibilidad, error_indisponibilidad);
}
} /* fin error suficientemente pequeño */
/* RESULTADOS */
printf("== Infiabilidad == \n");
printf("El valor es: ");printf("%f\n",infiabilidad);
printf("El IC de la infiabilidad es: (");printf("%f",icizq_infiabilidad);printf(" , ");printf("%f\n",icde_infiabilidad);
printf("El error de la infiabilidad es: ");printf("%f\n",error_infiabilidad);
printf("\n");
printf("== Indisponibilidad == \n");
printf("El valor es: ");printf("%f\n",indisponibilidad);
printf("El IC de la indisponibilidad es: (\n");printf("%f",icizq_indisponibilidad);printf(" , ");printf("%f\n",icde_indisponibilidad);
printf("El error de la indisponibilidad es: \n");printf("%f\n",error_indisponibilidad);
return(0);
}
/* =========================================================== */
/* ======================= FUNCIONES ========================= */
/* =========================================================== */
/* ======================== [ 1 ] ============================= */
void inicializacion_estructuras(int sistema[num_elementos], int sistema_reparacion[tamanio_sistema_reparacion],
int copia_sistema_reparacion[tamanio_sistema_reparacion], float acontecimientos[num_acontecimientos],
float tasas_de_fallos[num_elementos], float landas[fallos_grupo])
{/* funcion que inicializa las principales estructuras del simulador */
int i, j;
/* inicializamos a 1 el sistema */
for (i=0;i<num_elementos;i++){sistema[i] = 1;}
/* inicializamos a 0 el sistema de reparacion */
for (i=0;i<tamanio_sistema_reparacion;i++)
{
sistema_reparacion[i] = 0;
copia_sistema_reparacion[i] = 0;
}
/* inicializamos los acontecimientos de servidores */
for (i=0;i<num_servidores;i++)
{/* los servidores estan vacios */
acontecimientos[i] = INFINITO;
}
/* inicializamos las tasas de fallos de los componentes */
for (i=0;i<num_elementos;i++)
{
tasas_de_fallos[i] = landas[0];
}
/* inicializamos los acontecimientos de los componentes */
for (i=num_servidores;i<num_acontecimientos;i++)
{/* los componentes estan funcionando */
acontecimientos[i] = generar_aleatorio('e', tasas_de_fallos, 1);
}
}
/* ======================== [ 2 ] ============================= */
float generar_aleatorio(char aleatorio, float tasas_de_fallos[num_elementos], int que_elemento)
{ /* funcion que dvuelve un valor aleatorio e llegada s servicio */
float valor, numero_aleatorio, parametro;
if (aleatorio == 'e') /* es una llegada o entrada */
{
parametro = tasas_de_fallos[que_elemento-1];
numero_aleatorio = (rand()%100)/100.0; /* numero aleatorio real entre 0 y 1 */
numero_aleatorio = numero_aleatorio + 0.0001;
valor = (-1/parametro)*log(numero_aleatorio);
}
else /* es un tiempo de servicio */
{
numero_aleatorio = (rand()%100)/100.0; /* numero aleatorio real entre 0 y 1 */
numero_aleatorio = numero_aleatorio + 0.0001;
valor = (-1/parametro_servicio)*log(numero_aleatorio);
}
return(valor);
}
/* ======================== [ 3 ] ============================= */
int primer_acontecimiento(float acontecimientos[num_acontecimientos], int funcionamiento_sistema)
{ /* funcion que determina que valor es el mas pequeño de los acontecimientos */
float menor_tiempo;
int minima_posicion, i;
menor_tiempo = acontecimientos[0];
minima_posicion = 0;
for (i=1;i<num_acontecimientos;i++) /* se recorre todos los acontecimiento */
{
if ((funcionamiento_sistema == 1) || (i<num_servidores)) /* si funciona o no funciona pero es un servidor */
{
if (acontecimientos[i] < menor_tiempo) /* comparas */
{ /* actualizas */
minima_posicion = i;
menor_tiempo = acontecimientos[i];
}
}
}
return(minima_posicion);
}
/* ======================== [ 4 ] ============================= */
int colocar_componente(int sistema_reparacion[tamanio_sistema_reparacion], int que_elemento)
{ /* funcion que coloca al componente llegado en el sistema de reparacion */ /*hay sitio forzoso, sino no habria llegado */
int colocado, i;
colocado = 0;i = 0;
while(colocado == 0) /* mientras que no se coloque el componente */
{
if (sistema_reparacion[i] == 0) /* si esta vacía la posicion */
{ sistema_reparacion[i] = que_elemento;
colocado = 1;
}
else {i++;}
}
return(i); /* devuelve la posicion donde ha sido colocado */
}
/* ======================== [ 5 ] ============================= */
void reducir_acontecimientos(float acontecimientos[num_acontecimientos],float cantidad_a_reducir, int funcionamiento_sistema)
{ /* al ocurrir un acontecimiento, el resto debe disminuir en tiempo */
int i;
if (funcionamiento_sistema == 1) /* si el sistema funciona se reducen todos */
{
for (i=0;i<num_acontecimientos;i++)
{ /* reducimos todos menos los que son infinito */
if (!(acontecimientos[i] == INFINITO)){acontecimientos[i] = acontecimientos[i] - cantidad_a_reducir;}
}
}
else{ /* si el sistema no funciona no se reducen los tiempos de llegadas, solo los tiempos de servicio */
for (i=0;i<num_servidores;i++)
{
if (!(acontecimientos[i] == INFINITO)){acontecimientos[i] = acontecimientos[i] - cantidad_a_reducir;}
}
}
}
/* ======================== [ 6 ] ============================= */
int comprobar_funcionamiento(int sistema[num_elementos], int posicion)
{ /* funcion que comprueba si el sistema se ha estropeado */
int fallos_encontrados, i, j, funcionamiento_sistema;
funcionamiento_sistema = 1;
for (i=0;i<tamanio_grupos;i++) /* busca en los x grupos que rodean al elemento fallado */
{
fallos_encontrados = 0; /* funciona si no se demuestra lo contrario */
for (j=(posicion-i);j<((posicion-i)+tamanio_grupos);j++) /* dentro de un grupo comprueba todas las posiciones */
{
if ((j<num_elementos) && (j>-1)) /* primero mira si esa posición no se sale de los límites normales */
{
if (sistema[j] == 0){ fallos_encontrados++;} /* se ve si ese componente esta estropeado */
if (fallos_encontrados == fallos_grupo) {funcionamiento_sistema = 0;} /* se ha detectado el error */
}
}
}
return(funcionamiento_sistema);
}
/* ======================== [ 7 ] ============================= */
int reordenar_sistema_reparacion(int sistema_reparacion[tamanio_sistema_reparacion], int siguiente_acontecimiento)
{ /* devuelve 1 si se ha rellenado el servidor, 0 si no había componentes a colocar en el servidor */
/* si hay gente en cola es porque todos los demas estan ocupados */
int reocupado, i;
reocupado = 0;
if (!(sistema_reparacion[num_servidores] == 0)) /* si la primera posicion de la cola esta llena */
{ /* si no hay nadie esperando no hay que recolocar */
reocupado = 1;
sistema_reparacion[siguiente_acontecimiento] = sistema_reparacion[num_servidores]; /* se rellena el servidor */
i = num_servidores; /* vamos a ir adelantando el resto de posiciones */
while (!(sistema_reparacion[i] == 0) && (i < tamanio_sistema_reparacion))
{
sistema_reparacion[i] = sistema_reparacion[i+1]; /* el de antes igual al de despues */
i++;
}
}
else /* si no hay nadie en la cola se debe poner a 0 el servidor */
{
sistema_reparacion[siguiente_acontecimiento] = 0; /* se rellena el servidor */
}
return(reocupado);
}
/* ======================== [8] ============================= */
void actualiza_landas(float tasas_de_fallos[num_elementos], int sistema[num_elementos], float landas[fallos_grupo])
{
int contador,i;
contador = 0;
for (i=0;i<num_elementos;i++)
{ /* mira todos los elementos */
if (sistema[i] == 0){contador++;} /* si el elemento esta fallado incrementamos contador */
else{ /* si funciona hay que ponerle landa */
if (contador < fallos_grupo)
{
tasas_de_fallos[i] = landas[contador];
contador = 0;
}
else{tasas_de_fallos[i] = landas[fallos_grupo-1];}
}
}
}
/* ======================== [9] ============================= */
void colocar_cola_prioridades(int sistema_reparacion[tamanio_sistema_reparacion], int copia_sistema_reparacion[tamanio_sistema_reparacion],
float tasas_de_fallos[num_elementos], float landas[fallos_grupo])
{
int i, j, elemento, posicion_copia;
posicion_copia = num_servidores; /* para saber por donde va la copia */
for (i=0;i<fallos_grupo-1;i++) /* se recorre k-1 veces el sistema de reparacion */
{
for(j=num_servidores;j<tamanio_sistema_reparacion;j++) /* en cada pasada busca un landa y lo va metiendo a la copia */
{
elemento = sistema_reparacion[j]; /* si el elemento corrspone al landa que estamos recogiendo */
if (!(elemento == 0) && (tasas_de_fallos[elemento-1] > landas[fallos_grupo-i-2]))
{ /* lo metemos en la copia */
copia_sistema_reparacion[posicion_copia] = sistema_reparacion[j];
posicion_copia++;
sistema_reparacion[j] = 0;
}
}
}
for(j=num_servidores;j<tamanio_sistema_reparacion;j++) /* en cada pasada busca un landa y lo va metiendo a la copia */
{
elemento = sistema_reparacion[j]; /* especial para el landa menor */
if (!(elemento == 0) && (tasas_de_fallos[elemento-1] > 0))
{ /* lo metemos en la copia */
copia_sistema_reparacion[posicion_copia] = sistema_reparacion[j];
posicion_copia++;
sistema_reparacion[j] = 0;
}
}
/* hacemos el volcado final */
for(i=num_servidores;i<tamanio_sistema_reparacion;i++){sistema_reparacion[i] = copia_sistema_reparacion[i];}
}
/* ======================== [10] ============================= */
void calcula_intervalo_error(float valor, int numero_muestras, float ic_izquierdo, float ic_derecho, float error_relativo)
{ /* aplica las fórmulas del intervalo de confianza y error para la proporcion */
float general, superior, inferior;
inferior = sqrt numero_muestras; /* parte inferior de la ecuacion */
superior = sqrt (valor * (1 - valor)); /* parte superior de la ecuacion */
general = (1.96 * superior) / inferior; /* resultado de la division */
error_relativo = general / valor;
ic_izquierdo = valor - general;
ic_derecho = valor + general;
}