/*

This software is under GPL terms.

*/


#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define N 100

float lambda;
float mu;

float interarrivo(void){
   float n=rand();
   return(-(1/lambda)*log(1-(n/32767)));
   }

float servizio(void){
   float n=rand();
   return(-(1/mu)*log(1-(n/32767)));
   }

main() {
float a,b[N],s[N],t,atemp,minb,mediacoda,mediautenti,numprove,tmax;
FILE*fp=fopen("testB.txt","a+");
int i,j,utenti,c,nmin,bo,f,assegnato;
/*Inizializzazione dei generatori casuali e delle variabili inserite dall'utente*/
srand(time(NULL));
printf("Inserisci il valore del tasso di servizio mu del sistema\n");
scanf("%f",&mu);
printf("Inserisci la massima durata di ogni prova\n");
scanf("%f",&tmax);
printf("Inserisci la precisione della variazione di lambda in termini di numero\ndi prove da eseguire\n");
scanf("%f",&numprove);
printf("Inserisci il numero di servitori del sistema\n");
scanf("%d",&c);
mu=mu/c;
lambda=mu/numprove;
fprintf(fp,"mu=%f durata=%f numprove=%f servitori=%f\n",mu,tmax,numprove,c);
printf("\nro | media utenti nel sistema | media utenti in coda | durata della prova\n");
fprintf(fp,"ro | media utenti nel sistema | media utenti in coda | numero campioni\n");
/*Ciclo che varia lambda per ogni prova effettuata*/
while(lambda<=mu){
   utenti=0;
   assegnato=0;
   a=0;
   t=0;
   i=0;
   atemp=0;
   mediacoda=0;
   mediautenti=0;
   for(j=c;j>0;j--) {b[j]=0; s[j]=0;}   
/*Ciclo operativo del programma*/
   while(t<tmax){
      bo=0;
      minb=b[c];
      nmin=c;
/*Ciclo per verificare se vi sono servitori liberi e in generale quale servitore 
  ha tempo di servizio inferiore*/
      for(j=c;j>0;j--){
         if (b[j]==0) bo=1;
         if (b[j]<minb) {nmin=j; minb=b[j];}
         }
/*Primo caso: tutti servitori occupati*/
      if(bo==0){
         if(assegnato==1&&(a-t<minb)) utenti++;
         atemp=0;
/*Calcolo degli arrivi durante il tempo di servizio del servitore che ha tempo di servizio 
  inferiore*/
         while((a-t)<minb){
            atemp=interarrivo();
            a=a+atemp;
            assegnato=1;
            utenti++;
            }
/*Spostamento dell'asse temporale e aggiornamento dei tempi di servizio in base al nuovo riferimento,
  aggiornamento anche del vettore che memorizza i tempi interarrivo per i singoli servitori*/  
         t=t+minb;
         if(atemp!=0) utenti--;    
         f=0;
         for(j=c;j>0;j--){
           s[j]=s[j]-minb;
            if(s[j]<=0) s[j]=0;
            else f++;
            b[j]=b[j]-minb;
            if (b[j]==0) utenti--;
            }    
/*Stampa del numero degli utenti nel sistema e in coda*/ 
         mediacoda=mediacoda+utenti-c+1;
         mediautenti=mediautenti+utenti-f;
         i++;
         }
/*Secondo caso: presenza di servitori liberi*/
      else {
/*Entrata in servizio di un servitore nel caso di utenti presenti in coda*/
         if((utenti-c+1)>0) {
            b[nmin]=servizio();
            s[nmin]=0;
            }
         else{
/*Calcolo del momento di entrata in servizio del servitore libero e del suo relativo futuro tempo 
  di servizio*/
            if (assegnato==0){ 
               atemp=interarrivo();
               a=a+atemp;
               }
            else assegnato=0;
            b[nmin]=a-t+servizio();
            s[nmin]=a-t;
            utenti++;
            }
         }
      }
/*Stampa delle medie*/ 
   printf("%f %f %f %d\n",lambda/mu,mediautenti/i,mediacoda/i,i);
   fprintf(fp,"%f %f %f %d\n",lambda/mu,mediautenti/i,mediacoda/i,i);
   lambda=lambda+(mu/numprove);
   }
fprintf(fp,"\n");
fclose(fp);
printf("\n\n\nPremere un tasto qualsiasi per uscire\n");
scanf("%*c");
scanf("%*c");
}


