Skip to content

Instantly share code, notes, and snippets.

@EgidioCaprino
Last active January 21, 2021 20:34
Show Gist options
  • Save EgidioCaprino/e8c79a32c80c502e0acdd78323112130 to your computer and use it in GitHub Desktop.
Save EgidioCaprino/e8c79a32c80c502e0acdd78323112130 to your computer and use it in GitHub Desktop.
Metodi e linguaggi di simulazione
PROCEDURE simulatore BEGIN
<variabili di stato (stato_unita_1, stato_unita_2, stato_unita_3)>
<variabili di carico (t_arrivo[j], t_uscita[j] per tutti i job)>
<calendario eventi (t_arrivo, t_fine_servizio_1, t_fine_servizio_2, t_fine_servizio_3, t_fine_simulazione)>
<code (coda_1 di tipo LIFO, coda_2 di tipo RAND, coda_3 di tipo FIFO)>
<clock>
* Data in input dal progettista. Possibili valori: stabilizzazione, statistica *
<variabile per identificare la fase: fase_simulazione>
<indice del run: n>
<indice del job all'interno del run: j>
<numero run di stabilizzazione: p> * In input dal progettista *
<numero di osservazioni per ogni run: n0> * In input dal progettista *
<osservazioni_stabilizzazione> * Array bidimensionale per tutte le osservazioni di tutti i run *
<gordon_e, gordon_s2> * Stimatori di Gordon per la media e la varianza da 1 a n0 *
* Ogni run statistico ha lunghezza variabile; qui si suppone tra 50 e 100 *
<lunghezza_run_statistici[p]>
<osservazioni_statistiche[p]> * media delle osservazioni di ogni run statistico *
<somma_osservazioni_statistiche> * variabile di appoggio *
<invoca procedura inizializzazione>
<invoca procedura sequenziatore>
END
PROCEDURE inizializzazione BEGIN
<inizializza i generatori pseudocasuali>
* Imposta i centri come liberi *
stato_unita_1 := IDLE
stato_unita_2 := IDLE
stato_unita_3 := IDLE
<inizializza le code come vuote>
* Imposta tutti i tempi degli eventi a infinito *
t_arrivo = +∞
t_fine_servizio_1 = +∞
t_fine_servizio_2 = +∞
t_fine_servizio_3 = +∞
t_fine_simulazione = +∞
n := 1
j := 1
<inizializza valori in input dal progettista: fase_simulazione, p, n0>
// @todo va bene usare lo stesso p per la fase di stabilizzazione e statistica?
osservazioni_stabilizzazione := array[p][n0]
gordon_e := array[n0]
gordon_s2 := array[n0]
lunghezza_run_statistici := array[p]
FOR <indice_run := 1 TO p> DO BEGIN
<estrai un valore pseudocasuale dal generatore uniforme in [50, 100] in lunghezza_run_temp>
lunghezza_run_statistici[indice_run] := lunghezza_run_temp
END
osservazioni_statistiche := array[p]
somma_osservazioni_statistiche := 0
* Prevedi il primo tempo di arrivo *
<estrai un valore pseudocasuale dal generatore 2-erlangiano in t_arrivo_temp>
t_arrivo := clock + t_arrivo_temp
END
PROCEDURE sequenziatore BEGIN
WHILE <clock < t_fine_simulazione> DO THEN BEGIN
<seleziona da calendario il prossimo evento: t_evento_x, dove x è il tipo di evento>
* Avanza il clock fino al prossimo evento *
clock := t_evento_x
<esegui la routine relativa all'evento x>
END
END
PROCEDURE arrivo BEGIN
* Prevedi il prossimo arrivo *
<estraggo un valore pseudocasuale dal generatore 2-erlangiano in t_arrivo_temp>
t_arrivo := clock + t_arrivo_temp
* Salva il tempo di arrivo di questo job *
t_arrivo[j] := clock
* Routing verso prossimo centro *
<estrai un valore pseudocasuale dal generatore uniforme in [0,1] in prob_routing_temp>
IF <prob_routing_temp <= 0.8> THEN BEGIN
IF <stato_unita_1 = IDLE> THEN BEGIN
<il job corrente occupa il centro 1>
stato_unita_1 := BUSY
<estrai un valore pseudocasuale dal generatore 2-erlangiano in t_fine_servizio_1_temp>
<t_fine_servizio_1 := clock + t_fine_servizio_1_temp>
END ELSE BEGIN
<inserisci il job corrente in testa alla coda_1>
END
END
ELSE IF <prob_routing_temp <= 0.9> THEN BEGIN
IF <stato_unita_2 = IDLE> THEN BEGIN
<il job corrente occupa il centro 2>
stato_unita_2 := BUSY
<estrai un valore pseudocasuale dal generatore iperesponenziale in t_fine_servizio_2_temp>
<t_fine_servizio_2 := clock + t_fine_servizio_2_temp>
END ELSE BEGIN
<estrai un valore pseudocasuale dal generatore uniforme in [1, lunghezza(coda_2) + 1] in t_indice_coda_2_temp>
<inserisci il job corrente nella coda_2 alla posizione t_indice_coda_2_temp, spostando tutti i job se occupata>
END
END ELSE BEGIN
IF <stato_unita_3 = IDLE> THEN BEGIN
<il job corrente occupa il centro 3>
stato_unita_3 := BUSY
<estrai un valore pseudocasuale dal generatore iperesponenziale in t_fine_servizio_3_temp>
<t_fine_servizio_3 := clock + t_fine_servizio_3_temp>
END ELSE BEGIN
<inserisci il job corrente in coda alla coda_3>
END
END
END
PROCEDURE fine_servizio_1 BEGIN
<termina servizio per il job corrente>
* Routing verso prossimo centro o verso l'uscita dal sistema *
<estrai un valore pseudocasuale dal generatore uniforme [0,1] in routing_temp>
IF <routing_temp <= 0.6> THEN BEGIN
* Indirizza il job verso il centro 3 *
IF <stato_unita_3 = IDLE> THEN BEGIN
<il job corrente occupa il centro 3>
stato_unita_3 := BUSY
<estrai un valore pseudocasuale dal generatore iperesponenziale in t_fine_servizio_3_temp>
<t_fine_servizio_3 := clock + t_fine_servizio_3_temp>
END ELSE BEGIN
<inserisci il job corrente in coda alla coda_3>
END
END ELSE BEGIN
* Il job esce dal sistema *
t_uscita[j] := clock
<invoca procedura osservazione>
END
* Inserisci nel centro il prossimo job, se presente *
IF <lunghezza(coda_1) = 0> THEN BEGIN
stato_unita_1 := IDLE
t_fine_servizio_1 := +∞
END ELSE BEGIN
<estrai il job in testa alla coda_1 e inseriscilo nel centro 1>
stato_unita_1 := BUSY
<estrai un valore pseudocasuale dal generatore 2-erlangiano in t_fine_servizio_1_temp>
<t_fine_servizio_1 := clock + t_fine_servizio_1_temp>
END
END
PROCEDURE fine_servizio_2 BEGIN
<termina servizio per il job corrente>
* Il job esce dal sistema *
t_uscita[j] := clock
<invoca procedura osservazione>
* Inserisci nel centro il prossimo job, se presente *
IF <lunghezza(coda_2) = 0> THEN BEGIN
stato_unita_2 := IDLE
t_fine_servizio_2 := +∞
END ELSE BEGIN
<estrai il job in testa alla coda_2 e inseriscilo nel centro 2>
stato_unita_2 := BUSY
<estrai un valore pseudocasuale dal generatore iperesponenziale in t_fine_servizio_2_temp>
<t_fine_servizio_2 := clock + t_fine_servizio_2_temp>
END
END
PROCEDURE fine_servizio_3 BEGIN
<termina servizio per il job corrente>
* Il job esce dal sistema *
t_uscita[j] := clock
<invoca procedura osservazione>
* Inserisci nel centro il prossimo job, se presente *
IF <lunghezza(coda_3) = 0> THEN BEGIN
stato_unita_3 := IDLE
t_fine_servizio_3 := +∞
END ELSE BEGIN
<estrai il job in testa alla coda_3 e inseriscilo nel centro 3>
stato_unita_3 := BUSY
<estrai un valore pseudocasuale dal generatore iperesponenziale in t_fine_servizio_3_temp>
<t_fine_servizio_3 := clock + t_fine_servizio_3_temp>
END
END
PROCEDURE osservazione BEGIN
osservazione := t_uscita[j] - t_arrivo[j]
IF <fase_simulazione = stabilizzazione> THEN BEGIN
osservazioni_stabilizzazione[j][n] := osservazione
* Se si sta eseguendo l'ultimo run, si può iniziare a calcolare gli stimatori di Gordon *
IF <j = p> THEN ELSE
gordon_e_temp := 0
FOR <indice_run := 1 TO p> DO BEGIN
gordon_e_temp_n := 0
FOR <indice_osservazione := 1 TO n> DO BEGIN
gordon_e_temp_n := gordon_e_temp_n + osservazioni_stabilizzazione[indice_run][indice_osservazione]
END
gordon_e_temp := gordon_e_temp + (gordon_e_temp_n / n)
END
gordon_e[n] := gordon_e_temp / p
gordon_s2_temp := 0
FOR <indice_run := 1 TO p> DO BEGIN
gordon_s2_temp_n := 0
FOR <indice_osservazione := 1 TO n> DO BEGIN
gordon_s2_temp_n := gordon_s2_temp_n + osservazioni_stabilizzazione[indice_run][indice_osservazione]
END
gordon_s2_temp := gordon_s2_temp + (gordon_s2_temp_n - gordon_e[n])^2
END
gordon_s2[n] := gordon_s2_temp / (p - 1)
IF <n = n0> THEN BEGIN
* Raggiunta la fine delle fase di stabilizzazione *
t_fine_simulazione := clock + 1
<salva lo stato di equilibrio del sistema>
END ELSE BEGIN
n := n + 1
END
END ELSEIF <n = n0> BEGIN
* Raggiunta la fine del run corrente, passa al run successivo *
j := j + 1
n := 1
<ripristina lo stato del sistema necessario ad eseguire il nuovo run>
END ELSE BEGIN
n := n + 1
END
END ELSE BEGIN * Fase statistica *
IF <n = lunghezza_run_statistici[j]> THEN BEGIN
somma_osservazioni_statistiche := somma_osservazioni_statistiche + osservazione
IF <n = lunghezza_run_statistici[j]> THEN BEGIN
osservazioni_statistiche[j] = somma_osservazioni_statistiche / lunghezza_run_statistici[j]
IF <j = p> THEN BEGIN
t_fine_simulazione := clock + 1
END ELSE BEGIN
somma_osservazioni_statistiche := 0
j := j + 1
n := 0
<ripristina lo stato di equilibrio ottenuto dopo la fase di stabilizzazione>
END
END
END ELSE BEGIN
* Passa alla prossima osservazione *
n := n + 1
END
END
END
PROCEDURE fine_simulazione BEGIN
IF <fase_simulazione = stabilizzazione> THEN BEGIN
* Stampa i grafici dell'andamento delle medie e delle varianze di Gordon al crescere delle osservazioni n *
<plot(gordon_e)>
<plot(gordon_s2)>
END ELSE BEGIN
* Fase statistica *
<calcola la media campionaria Ū delle medie in osservazioni_statistiche[] dei p run>
<calcola la media campionaria ñ delle lunghezze dei p run in lunghezza_run_statistici[]>
<crea campione di vettori (z_1, ..., z_p) formato dalle coppie (u_j, n_j)>
<calcola media Ẑ del campione di vettori>
<calcola la matrice di covarianza del campione da cui il valore s>
<calcola f=Ū/ñ e d=s/(ñ*√p)
* Intervallo di confidenza al 90% del livello di confidenza u_ɑ/2 = 1,96 *
<min := f - (d * 1,96)>
<max := f + (d * 1,96)>
<stampa intervallo di confidenza al 95%>
END
<arresta il programma di simulazione>
END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment