Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 846b33ad43 | |||
|
|
40751f40c2 | ||
| 039cc1104c | |||
|
|
158976bb71 | ||
| f8f7f72eea | |||
| 37e0b57c36 | |||
| 44cf714840 | |||
| 719c6b353a | |||
| 4b9c40f894 | |||
| 78dcac0a56 | |||
| 57c9dd9733 | |||
| 3844a46379 | |||
| e48bddf94d | |||
| 8f30f07c36 | |||
| e4df5dab73 |
11
.vscode/launch.json
vendored
@@ -4,6 +4,13 @@
|
|||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "NetExamples",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "net.berack.upo.valpre.NetExamples",
|
||||||
|
"projectName": "valpre"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "java",
|
"type": "java",
|
||||||
"name": "Run1k Simple",
|
"name": "Run1k Simple",
|
||||||
@@ -23,7 +30,7 @@
|
|||||||
"name": "Run Incremental",
|
"name": "Run Incremental",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"mainClass": "net.berack.upo.valpre.Main",
|
"mainClass": "net.berack.upo.valpre.Main",
|
||||||
"args": "simulation -net src/test/resources/example2.net -runs 1000 -i \"[Service1:throughput=0.98:0.01],[Service2:utilization=0.98:0.01],[Service2:unavailable=0.98:0.01]\""
|
"args": "simulation -net src/test/resources/example2.net -runs 1000 -indices \"[Service1:throughput=0.98:0.01],[Service2:utilization=0.98:0.01],[Service2:unavailable=0.98:0.01]\""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "java",
|
"type": "java",
|
||||||
@@ -52,6 +59,6 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"mainClass": "net.berack.upo.valpre.Main",
|
"mainClass": "net.berack.upo.valpre.Main",
|
||||||
"args": "interactive"
|
"args": "interactive"
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
151
README.md
@@ -1,87 +1,118 @@
|
|||||||
# Valutazione delle Prestazioni
|
# Valutazione delle Prestazioni
|
||||||
|
|
||||||
Il progetto riguarda un simulatore ad eventi discreti.
|
Questo progetto consiste in un simulatore ad eventi discreti. Il simulatore è stato inizialmente sviluppato seguendo il materiale del libro [Discrete-Event System Simulation](https://www.pearson.com/en-us/subject-catalog/p/discrete-event-system-simulation/P200000003161/9780136062127) (Capitolo 4), per poi essere personalizzato e profondamente modificato.
|
||||||
Il simulatore è iniziato con il lavoro trovato sul libro di testo [Discrete-Event System Simulation](https://www.pearson.com/en-us/subject-catalog/p/discrete-event-system-simulation/P200000003161/9780136062127) al Capitolo 4, per poi esser personalizzato e modificato radicalmente.
|
|
||||||
|
|
||||||
Il risultato è la creazione in una libreria per la simulazione di eventi discreti nella quale si può scegliera la topologia e la quantità di nodi nella rete da simulare.
|
Il risultato finale è una libreria per la simulazione di eventi discreti, che consente di configurare la topologia e il numero di nodi della rete da simulare.
|
||||||
|
|
||||||
Questa libreria è stata confrontata con il tool [JMT](https://jmt.sourceforge.net/Download.html) e le reti usate per fare il confronto si possono trovare sotto [le risorse del main](https://github.com/Berack96/upo-valpre/tree/main/src/main/resources).
|
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> Il JAR risultante che si trova nelle [Releases](https://github.com/Berack96/upo-valpre/releases).\
|
> Il file JAR generato è disponibile nella sezione [Releases](https://github.com/Berack96/upo-valpre/releases).\
|
||||||
> La versione di Java usata è la 23 (precisamente la [23.0.1](https://www.oracle.com/java/technologies/javase/jdk23-archive-downloads.html)).
|
> La libreria è stata sviluppata utilizzando Java 23, versione [23.0.1](https://www.oracle.com/java/technologies/javase/jdk23-archive-downloads.html).
|
||||||
|
|
||||||
---
|
## Comandi Jar
|
||||||
### Comandi Jar
|
|
||||||
|
|
||||||
Il JAR viene invocato tramite il classico comando java: `java -jar upo-valpre.jar` al quale si aggiungono vari argomenti successivi in base a cosa si vuole fare:
|
Il file JAR può essere eseguito tramite il comando standard `java -jar upo-valpre.jar`, seguito da specifici argomenti in base all'operazione desiderata:
|
||||||
|
|
||||||
* `java -jar upo-valpre.jar interactive`\
|
* `java -jar upo-valpre.jar interactive`\
|
||||||
Usato per avviare una sessione interattiva per la creazione di una rete. Da usare se la rete è relativamente breve da descrivere, altrimenti è più comodo usare il codice della libreria per la generazione della rete.\
|
Avvia una sessione interattiva per creare una rete. Questa modalità è consigliata per reti di dimensioni ridotte; per reti più complesse, è preferibile utilizzare il codice della libreria per generare la rete.\
|
||||||
Una volta scelta la rete è necessario salvarla in un file per la successiva simulazione e analisi.
|
Una volta configurata la rete, è necessario salvarla in un file per eseguire simulazioni e analisi successive.
|
||||||
|
|
||||||
* `java -jar upo-valpre.jar simulation -net <file> [other]`\
|
* `java -jar upo-valpre.jar simulation -net <file> [other]`\
|
||||||
Usato per avviare una simulazione della rete. Nel caso la rete non abbia eventuali limiti nella generazione di arrivi, viene restituito un errore.
|
Esegue una simulazione della rete specificata. Se la rete non include limiti per la generazione degli arrivi, verrà restituito un errore. Gli argomenti disponibili per personalizzare la simulazione includono:
|
||||||
Esistono vari tipi di argomenti per scegliere come fare la simulazione:
|
* `-runs <N>`: Esegue la simulazione N volte.
|
||||||
* `-runs <N>` per fare la simulazione N volte
|
* `-seed <value>`: Imposta un seed iniziale per la generazione casuale.
|
||||||
* `-seed <value>` per dare un seed iniziale scelto
|
* `-i <confidences>`: Specifica gli indici di terminazione delle simulazioni basati sugli intervalli di confidenza. Ignora l'opzione `-p` se attiva. Formato:\
|
||||||
* `-i <confidences>` per scegliere gli indici di terminazione delle run di simulazione quando l'intervallo di confidenza associato è raggiunto. Viene ignorato il comando -p se questa opzione è attiva. Il formato da usare è\
|
|
||||||
**\[nodo:statistica=confidenza:errore%\];\[..\]**
|
**\[nodo:statistica=confidenza:errore%\];\[..\]**
|
||||||
* `-csv <file>` per salvare i risultati delle run in un file csv
|
* `-csv <file>`: Salva i risultati delle simulazioni in un file CSV.
|
||||||
* `-p` per fare le simulazioni in parallelo (ovvero su più thread)
|
* `-p`: Esegue simulazioni in parallelo (su più thread).
|
||||||
* `-end <criteria>` per scegliere quando la simulazione finisce nel caso non ci siano dei source limitati nella creazione di arrivi. La tipologia di fine simulazione la si può trovare dentro `EndCriteria` (ovvero MaxArrivals, MaxDepartures, MaxTime) e la formattazione da usare per passare il parametro è la seguente:\
|
* `-end <criteria>`: Definisce i criteri di terminazione della simulazione per reti senza limiti di arrivi. I criteri disponibili sono definiti in `EndCriteria` (MaxArrivals, MaxDepartures, MaxTime). Formato:\
|
||||||
**\[tipo:param1,..,paramN\];\[..\]**
|
**\[tipo:param1,..,paramN\];\[..\]**
|
||||||
|
|
||||||
* `java -jar upo-valpre.jar plot -csv <file>`\
|
* `java -jar upo-valpre.jar plot -csv <file>`\
|
||||||
Mostra (con un ambiente grafico) una finestra nella quale si può scegliere quale nodo vedere e ogni statistica associata ad esso. Di seguito un'immagine di esempio:\
|
Avvia un'interfaccia grafica per visualizzare i risultati. È possibile selezionare un nodo e analizzare le statistiche associate. Esempio di visualizzazione:\
|
||||||

|

|
||||||
|
|
||||||
---
|
## Classi Interne
|
||||||
### Classi Interne
|
|
||||||
|
|
||||||
Esistono molteplici classi interne che vengono usate per supportare la simulazione e/o mostrare i risultati. In generale le classi dentro il percorso [net.berack.upo.valpre](src/main/java/net/berack/upo/valpre) sono usate per l'utilizzo del jar e quindi non sono essenziali per la simulazione.
|
Il progetto include diverse classi interne per supportare la simulazione e la visualizzazione dei risultati. Le classi nel package [net.berack.upo.valpre](src/main/java/net/berack/upo/valpre) sono principalmente utili per l'uso del JAR e non sono essenziali per la simulazione. Le classi principali per la simulazione si trovano nei seguenti package:
|
||||||
I percorsi che invece sono direttamente responsabili per la simulazione sono:
|
|
||||||
- [net.berack.upo.valpre.rand](src/main/java/net/berack/upo/valpre/rand) All'interno del quale si possono trovare:
|
|
||||||
- **Rng** che viene usato per il calcolo di numeri pseudo-casuali tramite un seed iniziale e la generazione di molteplici stream di generazione di numeri casuali
|
|
||||||
- **Distribution** interfaccia usata per la generazione di un numero casuale di una distribuzione. In questo file esistono molteplici classi interne che implementano l'interfaccia; per esempio: Exponential, Normal, Uniform
|
|
||||||
- [net.berack.upo.valpre.sim](src/main/java/net/berack/upo/valpre/sim) Package che contiene tutte le parti utili alla simulazione; per esempio la creazione della rete o la simulazione si più thread:
|
|
||||||
- **Net** che viene usato per rappresentare una rete da simulare.
|
|
||||||
- **ServerNode** che viene usato per rappresentare un singolo nodo della rete.
|
|
||||||
- **Event** che viene usato per rappresentare un evento della simulazione.
|
|
||||||
- **EndCriteria** interfaccia che viene implementata dalle classi interne usata per controllare se e quando la simulazione debba finire.
|
|
||||||
- **Simulation** e **SimulationMultiple** che vengono usate per far partire la simulazione; la versione multiple serve ad organizzare molteplici simulazioni su più thread o su un singolo core.
|
|
||||||
- [net.berack.upo.valpre.sim.stats](src/main/java/net/berack/upo/valpre/sim/stats) Package che contiene tutte le classi utili per la raccolta e l'analisi statistica dei vari valori generati dalla simulazione:
|
|
||||||
- **Result** il risultato di una run e la sua classe interna **Result.Summary** che contiene molteplici risultati di run già analizzati.
|
|
||||||
- **NodeStats** contiene indici statistici di un nodo e la sua classe interna **NodeStats.Summary** che contiene molteplici indici statistici già analizzati.
|
|
||||||
- **ConsoleTable** utile per mostrare i risultati in console sottoforma di tabella
|
|
||||||
- **CsvResult** utile per la lettura/scrittura dei risultati in formato csv
|
|
||||||
|
|
||||||
---
|
- [net.berack.upo.valpre.rand](src/main/java/net/berack/upo/valpre/rand): Contiene:
|
||||||
### Esempi
|
- **Rng**: Generatore di numeri pseudo-casuali con supporto per stream multipli.
|
||||||
|
- **Distribution**: Interfaccia per la generazione di numeri casuali secondo diverse distribuzioni (es. Exponential, Normal, Uniform).
|
||||||
|
|
||||||
Nel jar sono presenti già 2 reti per fare degli esperimenti e/o testare se il tool funziona correttamente. Per poter vedere una run usando questi esempi basta far partire il tool in modalità interattiva e scegliere di caricare gli esempi.\
|
- [net.berack.upo.valpre.sim](src/main/java/net/berack/upo/valpre/sim): Include:
|
||||||
|
- **Net**: Rappresenta una rete da simulare.
|
||||||
|
- **ServerNode**: Modella un singolo nodo della rete.
|
||||||
|
- **Event**: Rappresenta un evento della simulazione.
|
||||||
|
- **EndCriteria**: Interfaccia per definire i criteri di terminazione della simulazione.
|
||||||
|
- **Simulation** e **SimulationMultiple**: Avviano la simulazione; la seconda consente l'esecuzione su più thread.
|
||||||
|
|
||||||
|
- [net.berack.upo.valpre.sim.stats](src/main/java/net/berack/upo/valpre/sim/stats): Contiene classi per l'analisi statistica:
|
||||||
|
- **Result**: Rappresenta i risultati di una simulazione.
|
||||||
|
- **NodeStats**: Contiene statistiche relative ai nodi.
|
||||||
|
- **ConsoleTable**: Mostra i risultati in formato tabellare.
|
||||||
|
- **CsvResult**: Gestisce la lettura/scrittura dei risultati in formato CSV.
|
||||||
|
|
||||||
|
## Esempi
|
||||||
|
|
||||||
|
Il JAR include due reti di esempio utili per esperimenti o per verificare il corretto funzionamento del tool. Per eseguire una simulazione con questi esempi, avviare il tool in modalità interattiva e caricare gli esempi:\
|
||||||
`java -jar upo-valpre.jar interactive`
|
`java -jar upo-valpre.jar interactive`
|
||||||
|
|
||||||
##### Primo esempio
|
Oltre ad una verifica semplice che il tool funzioni, sono stati condotti ulteriori esperimenti sulle due reti di esempio, modificando progressivamente il numero di clienti nel sistema e variando la distribuzione di servizio di un nodo, mantenendo invariata la media (μ). Ogni esperimento è stato eseguito con un campione di 1000 simulazioni. I risultati dettagliati sono disponibili a questo [link](https://docs.google.com/spreadsheets/d/1yM1fvlpc2mIIpRe8M7_ry8m3DC3ZxNA204mM60O2hoQ/edit?usp=sharing) nei fogli colorati di verde (net1_incremental, net2_incremental, pivot1, pivot2).\
|
||||||
|
Le distribuzioni usate hanno tutte la stessa media μ e sono state create con questi parametri:
|
||||||
|
- Normale(μ, 0.6)
|
||||||
|
- Uniforme(μ - (μ\*0.1), μ + (μ\*0.1))
|
||||||
|
- Esponenziale(1/μ)
|
||||||
|
- Erlang(5, 5/μ)
|
||||||
|
- Iperesponenziale(p=\[0.5, 0.5\], e=\[1/(μ\*0.5), 1/(μ\*1.5)\])
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Primo esempio
|
||||||
\
|
\
|
||||||
Il primo è `example1`; è una rete composta da una fonte di clienti (Source) che arrivano con tasso esponenziale (λ=0.222 e quindi media 4.5) e un centro di servizio (Queue) con tasso di servizio distribuito come una normale (μ=3.2, σ=0.6).\
|
`example1` è una rete con una fonte di clienti (Source) che arrivano con tasso esponenziale (λ=0.222, media 4.5) e un centro di servizio (Queue) con tasso di servizio distribuito come una normale (μ=3.2, σ=0.6).\
|
||||||
Se si effettua una simulazione si vedranno i risultati sulla console in questo modo:
|
Esempio di risultati in console:\
|
||||||

|

|
||||||
|
|
||||||
Il tool JMT con la stessa rete produce i seguenti risultati che sono molto simili a quelli prodotti dalla libreria:\
|
Risultati grafici con incertezza:\
|
||||||
Queue Response Time = 7.3022 con un range [7.1456, 7.4589]\
|

|
||||||
Queue Throughput = 0.2226 con un range [0.2182, 0.2271]\
|
|
||||||
Queue Utilization = 0.7111 con un range [0.6959, 0.7262]
|
|
||||||
|
|
||||||
##### Secondo esempio
|
Modificando la distribuzione di servizio del nodo "Queue", si osservano variazioni nei valori medi della coda, del tempo di attesa e del tempo di risposta, mentre l'utilizzo e il throughput rimangono invariati.\
|
||||||
|

|
||||||
|
|
||||||
|
Di seguito si può vedere il cambiamento del tempo medio di attesa, il numero medio della coda e l'utilizzazione al variare del numero di clienti nel sistema.\
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Secondo esempio
|
||||||
\
|
\
|
||||||
Il secondo esempio è `example2`; è una rete composta da una fonte di clienti (Source) che arrivano con tasso esponenziale (λ=1.5 e quindi media 0.666), un centro di servizio (Service1) con tasso di servizio distribuito come una esponenziale (λ=2.0 e quindi media 0.5) e un altro centro di servizio (Service2) con tasso di servizio distribuito come una esponenziale (λ=3.5 e quindi media 0.2857) e con un tempo di indisponibilità che viene attivato con probabilità 10% e distribuito con una eseponenziale (λ=10.0 e quindi media 0.1)\
|
`example2` è una rete con una fonte di clienti (Source) che arrivano con tasso esponenziale (λ=1.5, media 0.666), un centro di servizio (Service1) con tasso esponenziale (λ=2.0, media 0.5) e un altro centro di servizio (Service2) con tasso esponenziale (λ=3.5, media 0.2857) e un tempo di indisponibilità distribuito esponenzialmente (λ=10.0, media 0.1) con probabilità 10%.\
|
||||||
Se si effettua una simulazione si vedranno i risultati sulla console in questo modo:
|
Esempio di risultati in console:\
|
||||||

|

|
||||||
|
|
||||||
Il tool JMT con la stessa rete produce i seguenti risultati che sono molto simili a quelli prodotti dalla libreria:\
|
Risultati grafici con incertezza:\
|
||||||
Service1 Response Time ~ 1.9866\
|

|
||||||
Busy2 Response Time ~ 0.2825\
|
|
||||||
Queue2 Response Time ~ 0.2279\
|
Anche in questo caso, modificando la distribuzione di servizio del nodo "Service2", si osservano variazioni nei valori medi della coda e del tempo di attesa, mentre l'utilizzo e il throughput rimangono invariati.\
|
||||||
Service1 Utilization ~ 0.7488\
|

|
||||||
Calibration Number of Customers ~ 0.0150\
|
|
||||||
Busy2 Number of Customers ~ 0.4279\
|
Una particolarità di questa rete è il basso valore atteso per il tempo di servizio. Questo, in concomitanza con il resample in caso di valori negativi, fa si di aumentare la media della Distribuzione Normale. Nei grafici seguenti è stata inclusa la Normale solo nell'ultimo per mostrare la differenza rispetto le altre distribuzioni.\
|
||||||
Throughput ~ 1.5000
|

|
||||||
|
|
||||||
|
## Confronto con JMT
|
||||||
|
|
||||||
|
Il tool JMT con le stesse reti di base (ovvero senza cambiare la Distribuzione) ottiene risultati simili al simulatore. Le reti usate per fare il confronto si possono trovare dentro la cartella delle [risorse di test](src/test/resources). I risultati ottenuti dal simulatore e da JMT si possono trovare al seguente [link](https://docs.google.com/spreadsheets/d/1yM1fvlpc2mIIpRe8M7_ry8m3DC3ZxNA204mM60O2hoQ/edit?usp=sharing) nei fogli colorati di blu (example1, example2, Riassunto) oppure direttamente dalla seguente tabella:\
|
||||||
|

|
||||||
|
|
||||||
|
Si possono notare due note messe nella tabella che servono ad indicare da dove vengono presi alcuni dati: La response, l'utilization% e l'unavailable% di Service2.\
|
||||||
|
Infatti essi si possono derivare da alcuni dati presenti dentro il simulatore JMT:
|
||||||
|
- Response: è il totale dato da Queue2 + Busy2 dato che il primo indica l'attesa della coda, mentre il secondo indica il tempo medio di servizio.
|
||||||
|
- Utilization%: è il valore preso dal numero medio di customer di Busy2. In questo caso indica proprio quanto la stazione (essendo single server) è occupata.
|
||||||
|
- Unavailable%: è il valore preso dal numero medio di customer di Calibration. In questo caso indica proprio quanto la stazione (essendo single server) è ferma e non può servire i clienti.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Per quanto riguarda il confronto con l'aumentare dei clienti nel sistema, JMT non permette di fermare la simulazione una volta elaborati N clienti, perciò è stata solo modificata la distribuzione e sono stati salvati i dati. Il risultato è la seguente tabella:\
|
||||||
|

|
||||||
|
|
||||||
|
Notare che, le osservazioni precedenti per la rete2, valgono anche in questo caso per il calcolo del tempo di risposta.
|
||||||
|
Before Width: | Height: | Size: 13 KiB |
BIN
image/README/1742150755381.png
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
image/README/1742556358341.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
image/README/1742632017987.png
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
image/README/1744786768084.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
image/README/1744786814771.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
image/README/1744793029362.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
image/README/1744966407854.png
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
image/README/1745009420186.png
Normal file
|
After Width: | Height: | Size: 81 KiB |
5
pom.xml
@@ -41,5 +41,10 @@
|
|||||||
<artifactId>jfreechart</artifactId>
|
<artifactId>jfreechart</artifactId>
|
||||||
<version>1.5.5</version>
|
<version>1.5.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.sourceforge.argparse4j</groupId>
|
||||||
|
<artifactId>argparse4j</artifactId>
|
||||||
|
<version>0.9.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -1,16 +1,15 @@
|
|||||||
package net.berack.upo.valpre;
|
package net.berack.upo.valpre;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import com.esotericsoftware.kryo.KryoException;
|
import com.esotericsoftware.kryo.KryoException;
|
||||||
|
|
||||||
import net.berack.upo.valpre.rand.Distribution;
|
import net.berack.upo.valpre.rand.Distribution;
|
||||||
|
import net.berack.upo.valpre.rand.Rng;
|
||||||
import net.berack.upo.valpre.sim.Net;
|
import net.berack.upo.valpre.sim.Net;
|
||||||
import net.berack.upo.valpre.sim.ServerNode;
|
import net.berack.upo.valpre.sim.ServerNode;
|
||||||
|
|
||||||
@@ -137,16 +136,17 @@ public class InteractiveConsole {
|
|||||||
/**
|
/**
|
||||||
* Run the simulation with the net.
|
* Run the simulation with the net.
|
||||||
*/
|
*/
|
||||||
private void simpleRuns() throws InterruptedException, ExecutionException, IOException {
|
private void simpleRuns() throws Exception {
|
||||||
var choice = choose("Choose what to do:", "100 Run", "1K Runs", "1K Runs + Plot");
|
var choice = choose("Choose what to do:", "100 Run", "1K Runs", "Run max 10K with confidence", "Back");
|
||||||
|
var seed = Rng.newSeed();
|
||||||
|
var csv = "run" + seed + ".csv";
|
||||||
switch (choice) {
|
switch (choice) {
|
||||||
case 1 -> new SimulationBuilder(net).setMaxRuns(100).setParallel(true).run();
|
case 1 -> new SimulationBuilder(net).setSeed(seed).setMaxRuns(100).setParallel(true).setCsv(csv).run();
|
||||||
case 2 -> new SimulationBuilder(net).setMaxRuns(1000).setParallel(true).run();
|
case 2 -> new SimulationBuilder(net).setSeed(seed).setMaxRuns(1000).setParallel(true).setCsv(csv).run();
|
||||||
case 3 -> {
|
case 3 -> {
|
||||||
var randName = "rand" + System.currentTimeMillis() + ".csv";
|
var indices = ask("Confidence indices with format [node:stat=confidence:relativeError];[..]\n");
|
||||||
new SimulationBuilder(net).setMaxRuns(1000).setParallel(true).setCsv(randName).run();
|
new SimulationBuilder(net).setSeed(seed).setMaxRuns(10000).parseConfidenceIndices(indices).setCsv(csv)
|
||||||
new Plot(randName).show();
|
.run();
|
||||||
new File(randName).delete();
|
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,95 +2,93 @@ package net.berack.upo.valpre;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.Arrays;
|
import net.sourceforge.argparse4j.ArgumentParsers;
|
||||||
import java.util.HashMap;
|
import net.sourceforge.argparse4j.impl.Arguments;
|
||||||
|
import net.sourceforge.argparse4j.inf.Namespace;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
private final static String NAME;
|
||||||
if (args.length == 0)
|
|
||||||
exit("No program specified!");
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the program, used for the help message.
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
var name = "valpre";
|
||||||
try {
|
try {
|
||||||
var program = args[0];
|
var uri = Main.class.getProtectionDomain().getCodeSource().getLocation().toURI();
|
||||||
var subArgs = Arrays.copyOfRange(args, 1, args.length);
|
name = new File(uri).getName();
|
||||||
switch (program) {
|
} catch (URISyntaxException e) {
|
||||||
|
}
|
||||||
|
NAME = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main method of the program. It parses the arguments and runs the
|
||||||
|
* simulation or the plotter.
|
||||||
|
*
|
||||||
|
* @param args the arguments to parse
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
var param = Main.getParameters(args);
|
||||||
|
var command = param.getString("command");
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
case "simulation" -> {
|
case "simulation" -> {
|
||||||
var param = Main.getParameters(program, subArgs);
|
new SimulationBuilder(param.getString("net"))
|
||||||
new SimulationBuilder(param.get("net"))
|
.setCsv(param.getString("csv"))
|
||||||
.setCsv(param.get("csv"))
|
.setMaxRuns(param.getInt("runs"))
|
||||||
.setMaxRuns(param.getOrDefault("runs", Integer::parseInt, 100))
|
.setSeed(param.getLong("seed"))
|
||||||
.setSeed(param.getOrDefault("seed", Long::parseLong, 0L))
|
.setParallel(param.getBoolean("p"))
|
||||||
.setParallel(param.get("p") != null)
|
.parseEndCriteria(param.getString("end"))
|
||||||
.parseEndCriteria(param.get("end"))
|
.parseConfidenceIndices(param.getString("indices"))
|
||||||
.parseConfidenceIndices(param.get("i"))
|
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
case "plot" -> {
|
case "plot" -> {
|
||||||
var param = Main.getParameters(program, subArgs);
|
var csv = param.getString("csv");
|
||||||
var csv = param.get("csv");
|
|
||||||
var plot = new Plot(csv);
|
var plot = new Plot(csv);
|
||||||
plot.show();
|
plot.show();
|
||||||
}
|
}
|
||||||
case "interactive" -> new InteractiveConsole().run();
|
case "interactive" -> new InteractiveConsole().run();
|
||||||
default -> exit("Invalid program!");
|
default -> throw new RuntimeException("Invalid program!"); // Should never happen
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
exit(e.getMessage());
|
System.err.println(e.getMessage());
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the parameters from the arguments.
|
|
||||||
*
|
|
||||||
* @param program the program to run
|
|
||||||
* @param args the arguments to parse
|
|
||||||
* @return the parameters
|
|
||||||
*/
|
|
||||||
private static Parameters getParameters(String program, String[] args) {
|
|
||||||
var arguments = new HashMap<String, Boolean>();
|
|
||||||
arguments.put("p", false);
|
|
||||||
arguments.put("seed", true);
|
|
||||||
arguments.put("runs", true);
|
|
||||||
arguments.put("net", true);
|
|
||||||
arguments.put("end", true);
|
|
||||||
arguments.put("csv", true);
|
|
||||||
arguments.put("i", true);
|
|
||||||
|
|
||||||
var descriptions = new HashMap<String, String>();
|
|
||||||
descriptions.put("p", "Add this if you want the simulation to use threads (one each run).");
|
|
||||||
descriptions.put("seed", "The seed of the simulation.");
|
|
||||||
descriptions.put("runs", "How many runs the simulator should run.");
|
|
||||||
descriptions.put("end", "When the simulation should end. Format is \"[ClassName:param1,..,paramN];[..]\"");
|
|
||||||
descriptions.put("net", "The file net to use. Use example1.net or example2.net for the provided ones.");
|
|
||||||
descriptions.put("i", "The confidence indices to use for the simulation. If active then p is ignored."
|
|
||||||
+ " Format is \"[node:stat=confidence:relativeError];[..]\"");
|
|
||||||
|
|
||||||
var csvDesc = switch (program) {
|
|
||||||
case "simulation" -> "The filename for saving every run statistics.";
|
|
||||||
case "plot" -> "The filename that contains the previous saved runs.";
|
|
||||||
default -> "";
|
|
||||||
};
|
|
||||||
descriptions.put("csv", csvDesc);
|
|
||||||
|
|
||||||
return Parameters.getArgsOrHelper(args, "-", arguments, descriptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exit the program with an error message.
|
|
||||||
*/
|
|
||||||
public static void exit(String message) {
|
|
||||||
try {
|
|
||||||
var uri = Main.class.getProtectionDomain().getCodeSource().getLocation().toURI();
|
|
||||||
var name = new File(uri).getName();
|
|
||||||
System.err.println(message);
|
|
||||||
System.out.println("Usage: java -jar " + name + ".jar [simulation|plot|interactive] [args]");
|
|
||||||
System.out.println("simulation args: -net <net> [-csv <csv>] [-runs <runs>] [-seed <seed>]"
|
|
||||||
+ "[-p] [-end <end>] [-i <indices>]");
|
|
||||||
System.out.println("plot args: -csv <csv>");
|
|
||||||
System.out.println("interactive: no args needed");
|
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the arguments of the program. It uses the argparse4j library to parse
|
||||||
|
* the arguments and return a Namespace object with the parsed arguments.
|
||||||
|
*
|
||||||
|
* @param args the arguments to parse
|
||||||
|
* @return a Namespace object with the parsed arguments
|
||||||
|
*/
|
||||||
|
private static Namespace getParameters(String[] args) {
|
||||||
|
var parser = ArgumentParsers.newFor(NAME).build()
|
||||||
|
.defaultHelp(true)
|
||||||
|
.description("Build a network simulation and/or plot the results of a simulation.");
|
||||||
|
var subparser = parser.addSubparsers().title("commands").description("valid commands").help("subcommand help");
|
||||||
|
|
||||||
|
var sim = subparser.addParser("simulation").help("Run a simulation of the network.");
|
||||||
|
sim.addArgument("-net").help("The file net to use.").required(true);
|
||||||
|
sim.addArgument("-csv").help("The filename for saving every run statistics.");
|
||||||
|
sim.addArgument("-runs").type(Integer.class).help("How many runs the simulator should run.").setDefault(100);
|
||||||
|
sim.addArgument("-seed").type(Long.class).help("The seed of the simulation.").setDefault(0L);
|
||||||
|
sim.addArgument("-p").action(Arguments.storeTrue()).help("Parallel (one thread each run).").setDefault(false);
|
||||||
|
sim.addArgument("-end").help("When the simulation should end. Format:\n\"[ClassName:param1,..,paramN];[..]\"");
|
||||||
|
sim.addArgument("-indices").help("The confidence indices to use for the simulation. If active -p is ignored."
|
||||||
|
+ " Format:\n\"[node:stat=confidence:relativeError];[..]\"");
|
||||||
|
|
||||||
|
var plot = subparser.addParser("plot").help("Plot the results of a simulation.");
|
||||||
|
plot.addArgument("-csv").help("The filename for the csv file to plot.").required(true);
|
||||||
|
|
||||||
|
var _ = subparser.addParser("interactive").help("Run the interactive console.");
|
||||||
|
// Interactive console does not need any arguments
|
||||||
|
|
||||||
|
var namespace = parser.parseArgsOrFail(args);
|
||||||
|
namespace.getAttrs().put("command", args[0]);
|
||||||
|
return namespace;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,14 @@
|
|||||||
package net.berack.upo.valpre;
|
package net.berack.upo.valpre;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import net.berack.upo.valpre.rand.Distribution;
|
import net.berack.upo.valpre.rand.Distribution;
|
||||||
import net.berack.upo.valpre.sim.Net;
|
import net.berack.upo.valpre.sim.Net;
|
||||||
import net.berack.upo.valpre.sim.ServerNode;
|
import net.berack.upo.valpre.sim.ServerNode;
|
||||||
|
import net.berack.upo.valpre.sim.SimulationMultiple;
|
||||||
|
import net.berack.upo.valpre.sim.stats.CsvResult;
|
||||||
|
import net.berack.upo.valpre.sim.stats.Result;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides two example networks.
|
* This class provides two example networks.
|
||||||
@@ -10,37 +16,111 @@ import net.berack.upo.valpre.sim.ServerNode;
|
|||||||
* The second network is composed of a terminal node and two queue nodes.
|
* The second network is composed of a terminal node and two queue nodes.
|
||||||
*/
|
*/
|
||||||
public final class NetExamples {
|
public final class NetExamples {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main method to test the networks.
|
||||||
|
* The first network will have the distribution changed but the mean will be the
|
||||||
|
* same. The second network will have the distribution changed but the mean will
|
||||||
|
* be the same. The results will be saved to a csv file.
|
||||||
|
*
|
||||||
|
* @param args not needed
|
||||||
|
* @throws Exception if the simulation fails or the file is not saved
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
var seed = 123456789L;
|
||||||
|
runNet(seed, 3.2, 1, "net1.csv", (spawn, dist) -> {
|
||||||
|
var name = dist.getClass().getSimpleName() + "_" + spawn;
|
||||||
|
return NetExamples.getNet1(spawn, name, dist);
|
||||||
|
});
|
||||||
|
runNet(seed, 1 / 3.5, 2, "net2.csv", (spawn, dist) -> {
|
||||||
|
var name = dist.getClass().getSimpleName() + "_" + spawn;
|
||||||
|
return NetExamples.getNet2(spawn, name, dist);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to test whatever network you input.
|
||||||
|
* The network will have the distribution changed but the mean will be the same.
|
||||||
|
* The bifunction requested is to get the network you want to test passing the
|
||||||
|
* spawn and the distribution with the same mean.
|
||||||
|
* The network will be tested with spawn totals of 1, 2, 5, 7, 10, 25, 50, 75,
|
||||||
|
* 100, 250, 500, 750, 1000, 1500, 2000.
|
||||||
|
* The results will be saved to a csv passed as argument.
|
||||||
|
*
|
||||||
|
* @param seed the seed for the simulation
|
||||||
|
* @param avg the mean of the distribution
|
||||||
|
* @param nodeToWatch the node to watch
|
||||||
|
* @param csv the file to save the results
|
||||||
|
* @param getNet the bifunction to get the network
|
||||||
|
* @throws Exception if the simulation fails or the file is not saved
|
||||||
|
*/
|
||||||
|
public static void runNet(long seed, double avg, int nodeToWatch, String csv,
|
||||||
|
BiFunction<Integer, Distribution, Net> getNet) throws Exception {
|
||||||
|
var build = new Result.Builder().seed(seed);
|
||||||
|
var spawnTotals = new int[] { 1, 2, 5, 7, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 1500, 2000 };
|
||||||
|
|
||||||
|
var normal = new Distribution.NormalBoxMuller(avg, 0.6);
|
||||||
|
var exponential = new Distribution.Exponential(1 / avg);
|
||||||
|
var erlang = new Distribution.Erlang(5, 5 / avg);
|
||||||
|
var uniform = new Distribution.Uniform(avg - (avg * 0.1), avg + (avg * 0.1));
|
||||||
|
var hyper = new Distribution.HyperExponential(
|
||||||
|
new double[] { 1 / (avg * 0.5), 1 / (avg * 1.5) },
|
||||||
|
new double[] { 0.5f, 0.5f });
|
||||||
|
|
||||||
|
for (var spawn : spawnTotals) {
|
||||||
|
System.out.println("Spawn: " + spawn);
|
||||||
|
var nets = new Net[] {
|
||||||
|
getNet.apply(spawn, normal),
|
||||||
|
getNet.apply(spawn, exponential),
|
||||||
|
getNet.apply(spawn, erlang),
|
||||||
|
getNet.apply(spawn, uniform),
|
||||||
|
getNet.apply(spawn, hyper),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var net : nets) {
|
||||||
|
var summary = new SimulationMultiple(net).runParallel(build.seed, 1000);
|
||||||
|
var name = net.getNode(nodeToWatch).name;
|
||||||
|
var stat = summary.getSummaryOf(name).average;
|
||||||
|
build.addNode(name, stat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = build.build();
|
||||||
|
new CsvResult(csv).saveResults(List.of(result));
|
||||||
|
System.out.println("Results saved to " + csv);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the first example network.
|
* Return the first example network.
|
||||||
* The net is composed of a terminal node and a queue node.
|
* The net is composed of a terminal node and a queue node.
|
||||||
* The terminal node generates 10000 jobs with an exponential distribution 4.5.
|
* The terminal node generates 10000 jobs with an exponential distribution 4.5.
|
||||||
* The queue node has a capacity of 1 and a service time of 3.2 with a standard
|
* The queue node has a capacity of 1 and a service time of 3.2 with a standard
|
||||||
* deviation of 0.6.
|
* deviation of 0.6.
|
||||||
* The terminal node is connected to the queue node with a probability of 1.0.
|
|
||||||
*
|
*
|
||||||
* @return the first example network
|
* @return the first example network
|
||||||
*/
|
*/
|
||||||
public static Net getNet1() {
|
public static Net getNet1() {
|
||||||
var exp0_22 = new Distribution.Exponential(1.0 / 4.5);
|
|
||||||
var norm3_2 = new Distribution.NormalBoxMuller(3.2, 0.6);
|
var norm3_2 = new Distribution.NormalBoxMuller(3.2, 0.6);
|
||||||
var spawn = 10000;
|
return getNet1(10000, "Queue", norm3_2);
|
||||||
return getNet1(spawn, exp0_22, norm3_2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the first example network.
|
* Return the first example network.
|
||||||
* The net is composed of a terminal node and a queue node.
|
* The net is composed of a terminal node and a queue node.
|
||||||
* The terminal node is connected to the queue node.
|
* The terminal node is connected to the queue node.
|
||||||
|
* The terminal node generates N jobs with an exponential distribution 4.5.
|
||||||
*
|
*
|
||||||
* @param spawn the number of jobs to generate
|
* @param spawn the number of jobs to generate
|
||||||
* @param source the distribution of the source node
|
* @param name the name of the queue node
|
||||||
* @param queue the distribution of the queue node
|
* @param queue the distribution of the queue node
|
||||||
* @return the first example network
|
* @return the first example network
|
||||||
*/
|
*/
|
||||||
public static Net getNet1(int spawn, Distribution source, Distribution queue) {
|
public static Net getNet1(int spawn, String name, Distribution queue) {
|
||||||
|
var source = new Distribution.Exponential(1.0 / 4.5);
|
||||||
|
|
||||||
var net1 = new Net();
|
var net1 = new Net();
|
||||||
net1.addNode(ServerNode.Builder.terminal("Source", spawn, source));
|
net1.addNode(ServerNode.Builder.terminal("Source", spawn, source));
|
||||||
net1.addNode(ServerNode.Builder.queue("Queue", 1, queue));
|
net1.addNode(ServerNode.Builder.queue(name, 1, queue));
|
||||||
net1.addConnection(0, 1, 1.0);
|
net1.addConnection(0, 1, 1.0);
|
||||||
return net1;
|
return net1;
|
||||||
}
|
}
|
||||||
@@ -59,13 +139,8 @@ public final class NetExamples {
|
|||||||
* @return the second example network
|
* @return the second example network
|
||||||
*/
|
*/
|
||||||
public static Net getNet2() {
|
public static Net getNet2() {
|
||||||
var exp1_5 = new Distribution.Exponential(1.5);
|
|
||||||
var exp2 = new Distribution.Exponential(2.0);
|
|
||||||
var exp3_5 = new Distribution.Exponential(3.5);
|
var exp3_5 = new Distribution.Exponential(3.5);
|
||||||
var exp10 = new Distribution.Exponential(10.0);
|
return getNet2(10000, "Service2", exp3_5);
|
||||||
var unExp = new Distribution.UnavailableTime(0.1, exp10);
|
|
||||||
var spawn = 10000;
|
|
||||||
return getNet2(spawn, exp1_5, exp2, exp3_5, unExp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,18 +150,20 @@ public final class NetExamples {
|
|||||||
* The first queue node is connected to the second queue node.
|
* The first queue node is connected to the second queue node.
|
||||||
*
|
*
|
||||||
* @param spawn the number of jobs to generate
|
* @param spawn the number of jobs to generate
|
||||||
* @param source the distribution of the source node
|
* @param name the name of the second queue node
|
||||||
* @param service1 the distribution of the first queue node
|
|
||||||
* @param service2 the distribution of the second queue node
|
* @param service2 the distribution of the second queue node
|
||||||
* @param unExp the distribution of the unavailable time
|
|
||||||
* @return the second example network
|
* @return the second example network
|
||||||
*/
|
*/
|
||||||
public static Net getNet2(int spawn, Distribution source, Distribution service1, Distribution service2,
|
public static Net getNet2(int spawn, String name, Distribution service2) {
|
||||||
Distribution unExp) {
|
var exp1_5 = new Distribution.Exponential(1.5);
|
||||||
|
var exp2 = new Distribution.Exponential(2.0);
|
||||||
|
var exp10 = new Distribution.Exponential(10.0);
|
||||||
|
var unExp = new Distribution.UnavailableTime(0.1, exp10);
|
||||||
|
|
||||||
var net3 = new Net();
|
var net3 = new Net();
|
||||||
net3.addNode(ServerNode.Builder.terminal("Source", spawn, source));
|
net3.addNode(ServerNode.Builder.terminal("Source", spawn, exp1_5));
|
||||||
net3.addNode(ServerNode.Builder.queue("Service1", 1, service1));
|
net3.addNode(ServerNode.Builder.queue("Service", 1, exp2));
|
||||||
net3.addNode(ServerNode.Builder.queue("Service2", 1, service2, unExp));
|
net3.addNode(ServerNode.Builder.queue(name, 1, service2, unExp));
|
||||||
net3.addConnection(0, 1, 1.0);
|
net3.addConnection(0, 1, 1.0);
|
||||||
net3.addConnection(1, 2, 1.0);
|
net3.addConnection(1, 2, 1.0);
|
||||||
return net3;
|
return net3;
|
||||||
|
|||||||
@@ -1,194 +0,0 @@
|
|||||||
package net.berack.upo.valpre;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class that helps with parsing the parameters passed as input in the console.
|
|
||||||
*/
|
|
||||||
public class Parameters {
|
|
||||||
private final Map<String, Boolean> arguments;
|
|
||||||
private final String prefix;
|
|
||||||
private Map<String, String> parameters;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new Parameters object with the specified prefix and arguments.
|
|
||||||
* The arguments can be with value, in that case in the map the boolean should
|
|
||||||
* be true, otherwise it is only an argument that is a flag
|
|
||||||
*
|
|
||||||
* @param prefix the prefix to be used
|
|
||||||
* @param arguments a map of arguments where the key is a string and if the
|
|
||||||
* boolean is true then the argument expect a value
|
|
||||||
* @throws IllegalArgumentException if the arguments map is null or empty
|
|
||||||
*/
|
|
||||||
public Parameters(String prefix, Map<String, Boolean> arguments) {
|
|
||||||
if (arguments == null || arguments.size() == 0)
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
this.arguments = arguments;
|
|
||||||
this.prefix = prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the size of the parameters.
|
|
||||||
*
|
|
||||||
* @return the size of the parameters
|
|
||||||
*/
|
|
||||||
public int size() {
|
|
||||||
return this.parameters.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value of the argument passed as input.
|
|
||||||
*
|
|
||||||
* @param key the key of the argument
|
|
||||||
* @return the value of the argument
|
|
||||||
*/
|
|
||||||
public String get(String key) {
|
|
||||||
if (this.parameters == null)
|
|
||||||
return null;
|
|
||||||
return this.parameters.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the value from the arguments or the default value if it is not present.
|
|
||||||
*
|
|
||||||
* @param key The key to get the value from.
|
|
||||||
* @param parse The function to parse the value.
|
|
||||||
* @param value The default value if the key is not present.
|
|
||||||
* @return The value from the arguments or the default value if it is not
|
|
||||||
* present.
|
|
||||||
*/
|
|
||||||
public <T> T getOrDefault(String key, Function<String, T> parse, T value) {
|
|
||||||
var arg = this.get(key);
|
|
||||||
return arg != null ? parse.apply(arg) : value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a string with the standard <arggument> <description> spaced enough
|
|
||||||
*
|
|
||||||
* @param eventualDescription the description for the argument, if not present
|
|
||||||
* the argument will be shown anyway/
|
|
||||||
* @return a string of arguments
|
|
||||||
*/
|
|
||||||
public String helper(Map<String, String> eventualDescription) {
|
|
||||||
var size = 0;
|
|
||||||
var parameters = new HashMap<String, String>();
|
|
||||||
|
|
||||||
for (var param : this.arguments.entrySet()) {
|
|
||||||
var string = this.prefix + param.getKey();
|
|
||||||
if (param.getValue())
|
|
||||||
string += " <value>";
|
|
||||||
|
|
||||||
parameters.put(param.getKey(), string);
|
|
||||||
size = Math.max(size, string.length());
|
|
||||||
}
|
|
||||||
size += 2; // spacing
|
|
||||||
|
|
||||||
var builder = new StringBuilder();
|
|
||||||
for (var param : parameters.entrySet()) {
|
|
||||||
var key = param.getKey();
|
|
||||||
var args = param.getValue();
|
|
||||||
|
|
||||||
builder.append(" ");
|
|
||||||
builder.append(args);
|
|
||||||
|
|
||||||
var desc = eventualDescription.get(key);
|
|
||||||
if (desc != null) {
|
|
||||||
builder.append(" ".repeat(size - args.length()));
|
|
||||||
builder.append(desc);
|
|
||||||
}
|
|
||||||
builder.append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the arguments passed and build a map of Argument --> Value that can
|
|
||||||
* be used to retrieve the information. In the case that the arguments are not
|
|
||||||
* in the correct format then an exception is thrown.
|
|
||||||
* To get the arguments use the {@link #get(String)} method.
|
|
||||||
*
|
|
||||||
* @param args the arguments in input
|
|
||||||
* @throws IllegalArgumentException if the arguments are not formatted correctly
|
|
||||||
* or if there is an unknown argument or there
|
|
||||||
* are not arguments in the input
|
|
||||||
*/
|
|
||||||
public void parse(String[] args) {
|
|
||||||
if (args == null || args.length == 0)
|
|
||||||
throw new IllegalArgumentException("No arguments passed");
|
|
||||||
|
|
||||||
var result = new HashMap<String, String>();
|
|
||||||
for (var i = 0; i < args.length; i += 1) {
|
|
||||||
var current = args[i];
|
|
||||||
var next = i + 1 < args.length ? args[i + 1] : null;
|
|
||||||
|
|
||||||
var updateI = this.parseSingle(current, next, result);
|
|
||||||
if (updateI)
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.parameters = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse one single argument and put it into the map.
|
|
||||||
*
|
|
||||||
* @param current the current argument
|
|
||||||
* @param next the next argument if present
|
|
||||||
* @param result the map where to insert the value
|
|
||||||
* @throws IllegalArgumentException if the arguments are not formatted correctly
|
|
||||||
* or if there is an unknown argument
|
|
||||||
* @return true if the next argument is used
|
|
||||||
*/
|
|
||||||
private boolean parseSingle(String current, String next, Map<String, String> result) {
|
|
||||||
if (!current.startsWith(this.prefix))
|
|
||||||
throw new IllegalArgumentException("Missing prefix [" + current + "]");
|
|
||||||
current = current.substring(this.prefix.length());
|
|
||||||
|
|
||||||
var value = this.arguments.get(current);
|
|
||||||
if (value != null) {
|
|
||||||
result.put(current, value ? next : "");
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
var finalSize = result.size() + current.length();
|
|
||||||
for (var letter : current.split(""))
|
|
||||||
if (this.arguments.get(letter) != null)
|
|
||||||
result.put(current, "");
|
|
||||||
|
|
||||||
if (finalSize != result.size())
|
|
||||||
throw new IllegalArgumentException("Unknown argument [" + current + "]");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the arguments passed and returns a map of Argument --> Value that can
|
|
||||||
* be used to retrieve the information. In the case that the arguments are not
|
|
||||||
* in the correct format then an exception is thrown and the helper is printed.
|
|
||||||
* If the arguments passed are 0 then the helper is printed.
|
|
||||||
*
|
|
||||||
* @param args the arguments in input
|
|
||||||
* @param prefix the prefix to be used
|
|
||||||
* @param arguments a map of arguments where the key is a string and if the
|
|
||||||
* boolean is true then the argument expect a value
|
|
||||||
* @param descriptions a map of descriptions for the arguments
|
|
||||||
* @throws IllegalArgumentException if the arguments are not formatted correctly
|
|
||||||
* or if there is an unknown argument
|
|
||||||
* @return a map of the values
|
|
||||||
*/
|
|
||||||
public static Parameters getArgsOrHelper(String[] args, String prefix, Map<String, Boolean> arguments,
|
|
||||||
Map<String, String> descriptions) {
|
|
||||||
|
|
||||||
var param = new Parameters(prefix, arguments);
|
|
||||||
try {
|
|
||||||
param.parse(args);
|
|
||||||
return param;
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
System.out.println(e.getMessage());
|
|
||||||
System.out.println(param.helper(descriptions));
|
|
||||||
throw new IllegalArgumentException("Invalid arguments");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -44,7 +44,7 @@ public class Plot {
|
|||||||
var results = new CsvResult(csv).loadResults();
|
var results = new CsvResult(csv).loadResults();
|
||||||
this.summary = new Result.Summary(results);
|
this.summary = new Result.Summary(results);
|
||||||
|
|
||||||
var nodes = this.summary.getNodes().toArray(new String[0]);
|
var nodes = this.summary.getNodes();
|
||||||
this.panelBarChart = new ChartPanel(null);
|
this.panelBarChart = new ChartPanel(null);
|
||||||
|
|
||||||
this.nodeComboBox = new JComboBox<>(nodes);
|
this.nodeComboBox = new JComboBox<>(nodes);
|
||||||
@@ -113,7 +113,7 @@ public class Plot {
|
|||||||
var frame = new JFrame("Graph of the Simulation");
|
var frame = new JFrame("Graph of the Simulation");
|
||||||
frame.add(rootPane);
|
frame.add(rootPane);
|
||||||
frame.setSize(800, 600);
|
frame.setSize(800, 600);
|
||||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,8 @@ public class Plot {
|
|||||||
|
|
||||||
var model = this.statList.getModel();
|
var model = this.statList.getModel();
|
||||||
var avg = summary.average;
|
var avg = summary.average;
|
||||||
var err = summary.calcError(0.95);
|
var err = summary.calcError(0.95)
|
||||||
|
.apply(val -> val / 2); // Done to get the error for the mean value
|
||||||
|
|
||||||
for (int i = 0; i < model.getSize(); i++) {
|
for (int i = 0; i < model.getSize(); i++) {
|
||||||
var entry = model.getElementAt(i);
|
var entry = model.getElementAt(i);
|
||||||
|
|||||||
@@ -131,4 +131,13 @@ public class Rng {
|
|||||||
var t = multiplier * (seed % Q) - R * (seed / Q);
|
var t = multiplier * (seed % Q) - R * (seed / Q);
|
||||||
return t > 0 ? t : (t + modulus);
|
return t > 0 ? t : (t + modulus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This creates a new seed based on the current time.
|
||||||
|
*
|
||||||
|
* @return a new seed
|
||||||
|
*/
|
||||||
|
public static long newSeed() {
|
||||||
|
return System.currentTimeMillis() % MODULUS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,209 +0,0 @@
|
|||||||
package net.berack.upo.valpre.rand;
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
* This is a Java library for generating random variates from six discrete
|
|
||||||
* distributions
|
|
||||||
*
|
|
||||||
* Generator Range (x) Mean Variance
|
|
||||||
*
|
|
||||||
* bernoulli(p) x = 0,1 p p*(1-p)
|
|
||||||
* binomial(n, p) x = 0,...,n n*p n*p*(1-p)
|
|
||||||
* equilikely(a, b) x = a,...,b (a+b)/2 ((b-a+1)*(b-a+1)-1)/12
|
|
||||||
* Geometric(p) x = 0,... p/(1-p) p/((1-p)*(1-p))
|
|
||||||
* pascal(n, p) x = 0,... n*p/(1-p) n*p/((1-p)*(1-p))
|
|
||||||
* poisson(m) x = 0,... m m
|
|
||||||
*
|
|
||||||
* and seven continuous distributions
|
|
||||||
*
|
|
||||||
* uniform(a, b) a < x < b (a + b)/2 (b - a)*(b - a)/12
|
|
||||||
* exponential(m) x > 0 m m*m
|
|
||||||
* erlang(n, b) x > 0 n*b n*b*b
|
|
||||||
* normal(m, s) all x m s*s
|
|
||||||
* logNormal(a, b) x > 0 see below
|
|
||||||
* chiSquare(n) x > 0 n 2*n
|
|
||||||
* student(n) all x 0 (n > 1) n/(n - 2) (n > 2)
|
|
||||||
*
|
|
||||||
* For the a Lognormal(a, b) random variable, the mean and variance are
|
|
||||||
*
|
|
||||||
* mean = exp(a + 0.5*b*b)
|
|
||||||
* variance = (exp(b*b) - 1) * exp(2*a + b*b)
|
|
||||||
*
|
|
||||||
* Name : Rvgs.java (Random Variate GeneratorS)
|
|
||||||
* Authors : Steve Park & Dave Geyer
|
|
||||||
* Translated by : Richard Dutton & Jun Wang
|
|
||||||
* Language : Java
|
|
||||||
* Latest Revision : 7-1-04
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
public class Rvgs {
|
|
||||||
|
|
||||||
private final Rng rng;
|
|
||||||
|
|
||||||
// public Rvgs() {
|
|
||||||
// this.rngs = new Rngs(Rng.DEFAULT);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public Rvgs(Rng rng) {
|
|
||||||
if (rng == null)
|
|
||||||
throw new NullPointerException();
|
|
||||||
this.rng = rng;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns 1 with probability p or 0 with probability 1 - p.
|
|
||||||
* NOTE: use 0.0 < p < 1.0
|
|
||||||
*/
|
|
||||||
public long bernoulli(double p) {
|
|
||||||
return ((this.rng.random() < (1.0 - p)) ? 0 : 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a binomial distributed integer between 0 and n inclusive.
|
|
||||||
* NOTE: use n > 0 and 0.0 < p < 1.0
|
|
||||||
*/
|
|
||||||
public long binomial(long n, double p) {
|
|
||||||
long i, x = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
x += bernoulli(p);
|
|
||||||
return (x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an equilikely distributed integer between a and b inclusive.
|
|
||||||
* NOTE: use a < b
|
|
||||||
*/
|
|
||||||
public long equilikely(long a, long b) {
|
|
||||||
return (a + (long) ((b - a + 1) * this.rng.random()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a geometric distributed non-negative integer.
|
|
||||||
* NOTE: use 0.0 < p < 1.0
|
|
||||||
*/
|
|
||||||
public long geometric(double p) {
|
|
||||||
return ((long) (Math.log(1.0 - this.rng.random()) / Math.log(p)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a Pascal distributed non-negative integer.
|
|
||||||
* NOTE: use n > 0 and 0.0 < p < 1.0
|
|
||||||
*/
|
|
||||||
public long pascal(long n, double p) {
|
|
||||||
long i, x = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
x += geometric(p);
|
|
||||||
return (x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a Poisson distributed non-negative integer.
|
|
||||||
* NOTE: use m > 0
|
|
||||||
*/
|
|
||||||
public long poisson(double m) {
|
|
||||||
double t = 0.0;
|
|
||||||
long x = 0;
|
|
||||||
|
|
||||||
while (t < m) {
|
|
||||||
t += exponential(1.0);
|
|
||||||
x++;
|
|
||||||
}
|
|
||||||
return (x - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a uniformly distributed real number between a and b.
|
|
||||||
* NOTE: use a < b
|
|
||||||
*/
|
|
||||||
public double uniform(double a, double b) {
|
|
||||||
return (a + (b - a) * this.rng.random());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an exponentially distributed positive real number.
|
|
||||||
* NOTE: use m > 0.0
|
|
||||||
*/
|
|
||||||
public double exponential(double m) {
|
|
||||||
return (-m * Math.log(1.0 - this.rng.random()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an Erlang distributed positive real number.
|
|
||||||
* NOTE: use n > 0 and b > 0.0
|
|
||||||
*/
|
|
||||||
public double erlang(long n, double b) {
|
|
||||||
long i;
|
|
||||||
double x = 0.0;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
x += exponential(b);
|
|
||||||
return (x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a normal (Gaussian) distributed real number.
|
|
||||||
* NOTE: use s > 0.0
|
|
||||||
*
|
|
||||||
* Uses a very accurate approximation of the normal idf due to Odeh & Evans,
|
|
||||||
* J. Applied Statistics, 1974, vol 23, pp 96-97.
|
|
||||||
*/
|
|
||||||
public double normal(double m, double s) {
|
|
||||||
final double p0 = 0.322232431088;
|
|
||||||
final double q0 = 0.099348462606;
|
|
||||||
final double p1 = 1.0;
|
|
||||||
final double q1 = 0.588581570495;
|
|
||||||
final double p2 = 0.342242088547;
|
|
||||||
final double q2 = 0.531103462366;
|
|
||||||
final double p3 = 0.204231210245e-1;
|
|
||||||
final double q3 = 0.103537752850;
|
|
||||||
final double p4 = 0.453642210148e-4;
|
|
||||||
final double q4 = 0.385607006340e-2;
|
|
||||||
double u, t, p, q, z;
|
|
||||||
|
|
||||||
u = this.rng.random();
|
|
||||||
if (u < 0.5)
|
|
||||||
t = Math.sqrt(-2.0 * Math.log(u));
|
|
||||||
else
|
|
||||||
t = Math.sqrt(-2.0 * Math.log(1.0 - u));
|
|
||||||
p = p0 + t * (p1 + t * (p2 + t * (p3 + t * p4)));
|
|
||||||
q = q0 + t * (q1 + t * (q2 + t * (q3 + t * q4)));
|
|
||||||
if (u < 0.5)
|
|
||||||
z = (p / q) - t;
|
|
||||||
else
|
|
||||||
z = t - (p / q);
|
|
||||||
return (m + s * z);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a lognormal distributed positive real number.
|
|
||||||
* NOTE: use b > 0.0
|
|
||||||
*/
|
|
||||||
public double logNormal(double a, double b) {
|
|
||||||
return (Math.exp(a + b * normal(0.0, 1.0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a chi-square distributed positive real number.
|
|
||||||
* NOTE: use n > 0
|
|
||||||
*/
|
|
||||||
public double chiSquare(long n) {
|
|
||||||
long i;
|
|
||||||
double z, x = 0.0;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
z = normal(0.0, 1.0);
|
|
||||||
x += z * z;
|
|
||||||
}
|
|
||||||
return (x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a student-t distributed real number.
|
|
||||||
* NOTE: use n > 0
|
|
||||||
*/
|
|
||||||
public double student(long n) {
|
|
||||||
return (normal(0.0, 1.0) / Math.sqrt(chiSquare(n) / n));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -146,5 +146,4 @@ public class SimulationMultiple {
|
|||||||
stream.println(); // remove last printed line
|
stream.println(); // remove last printed line
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,27 @@ public class ConsoleTable {
|
|||||||
* @throws NullPointerException if the array is null
|
* @throws NullPointerException if the array is null
|
||||||
*/
|
*/
|
||||||
public ConsoleTable(String... header) {
|
public ConsoleTable(String... header) {
|
||||||
var max = 0;
|
this(-1, header);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new table with the header passed as input.
|
||||||
|
* The table will have as many columns as the length of the header array.
|
||||||
|
* Each column will have the same size and will be the max length of all the
|
||||||
|
* headers string or the maxLen passed as input.
|
||||||
|
*
|
||||||
|
* @param maxLen the max length of the columns
|
||||||
|
* @param header an array of strings
|
||||||
|
* @throws NullPointerException if the array is null
|
||||||
|
*/
|
||||||
|
public ConsoleTable(int maxLen, String... header) {
|
||||||
|
var max = Math.max(0, maxLen);
|
||||||
for (var name : header)
|
for (var name : header)
|
||||||
max = Math.max(max, name.length());
|
max = Math.max(max, name.length());
|
||||||
|
|
||||||
this.columns = header.length;
|
this.columns = header.length;
|
||||||
this.maxLen = max + 2;
|
this.maxLen = max + 2;
|
||||||
this.border = ("+" + "═".repeat(maxLen)).repeat(header.length) + "+\n";
|
this.border = ("+" + "═".repeat(this.maxLen)).repeat(header.length) + "+\n";
|
||||||
this.builder.append(border);
|
this.builder.append(border);
|
||||||
this.addRow(header);
|
this.addRow(header);
|
||||||
}
|
}
|
||||||
@@ -45,11 +59,11 @@ public class ConsoleTable {
|
|||||||
|
|
||||||
for (var val : values) {
|
for (var val : values) {
|
||||||
var diff = maxLen - val.length();
|
var diff = maxLen - val.length();
|
||||||
var first = (int) Math.ceil(diff / 2.0);
|
var first = Math.max((int) Math.ceil(diff / 2.0), 0);
|
||||||
builder.append('║');
|
builder.append('║');
|
||||||
builder.append(" ".repeat(first));
|
builder.append(" ".repeat(first));
|
||||||
builder.append(val);
|
builder.append(val);
|
||||||
builder.append(" ".repeat(diff - first));
|
builder.append(" ".repeat(Math.max(diff - first, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.append("║\n");
|
builder.append("║\n");
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.berack.upo.valpre.sim.stats;
|
package net.berack.upo.valpre.sim.stats;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -36,6 +37,11 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
|||||||
this.stats = stats;
|
this.stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the stats of a node.
|
||||||
|
*
|
||||||
|
* @return the stats of a node
|
||||||
|
*/
|
||||||
public NodeStats getStat(String node) {
|
public NodeStats getStat(String node) {
|
||||||
for (var i = 0; i < this.nodes.length; i++)
|
for (var i = 0; i < this.nodes.length; i++)
|
||||||
if (this.nodes[i].equals(node))
|
if (this.nodes[i].equals(node))
|
||||||
@@ -45,7 +51,7 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return buildPrintable(this.seed, this.simulationTime, this.timeElapsedMS, this.nodes, this.stats);
|
return getResultString(this.seed, this.simulationTime, this.timeElapsedMS, this.nodes, this.stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -80,9 +86,8 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
|||||||
* @param stats the stats of each node
|
* @param stats the stats of each node
|
||||||
* @return a string representation of the result
|
* @return a string representation of the result
|
||||||
*/
|
*/
|
||||||
private static String buildPrintable(long seed, double simTime, double timeMS, String[] nodes, NodeStats[] stats) {
|
public static String getResultString(long seed, double simTime, double timeMS, String[] nodes, NodeStats[] stats) {
|
||||||
var size = (int) Math.ceil(Math.max(Math.log10(simTime), 1));
|
var size = (int) Math.ceil(Math.max(Math.log10(simTime), 1));
|
||||||
var iFormat = "%" + size + ".0f";
|
|
||||||
var fFormat = "%" + (size + 4) + ".3f";
|
var fFormat = "%" + (size + 4) + ".3f";
|
||||||
|
|
||||||
var builder = new StringBuilder();
|
var builder = new StringBuilder();
|
||||||
@@ -90,9 +95,35 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
|||||||
builder.append(String.format("Seed: \t%d\n", seed));
|
builder.append(String.format("Seed: \t%d\n", seed));
|
||||||
builder.append(String.format("Simulation: \t" + fFormat + "\n", simTime));
|
builder.append(String.format("Simulation: \t" + fFormat + "\n", simTime));
|
||||||
builder.append(String.format("Elapsed: \t" + fFormat + "ms\n", timeMS));
|
builder.append(String.format("Elapsed: \t" + fFormat + "ms\n", timeMS));
|
||||||
|
builder.append(getResultString(nodes, stats));
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
var table = new ConsoleTable("Node", "Departures", "Avg Queue", "Avg Wait", "Avg Response", "Throughput",
|
/**
|
||||||
"Utilization %", "Unavailable %", "Last Event");
|
* Create a string representation of the result. It only display the stats of
|
||||||
|
* each node in a table format.
|
||||||
|
*
|
||||||
|
* @param nodes the names of the nodes
|
||||||
|
* @param stats the stats of each node
|
||||||
|
* @return a string representation of the result
|
||||||
|
* @throws AssertionError if the nodes and stats do not match
|
||||||
|
*/
|
||||||
|
public static String getResultString(String[] nodes, NodeStats[] stats) {
|
||||||
|
assert nodes.length == stats.length;
|
||||||
|
|
||||||
|
var size = (int) Math.ceil(Math.max(Math.log10(stats[0].lastEventTime), 1));
|
||||||
|
var iFormat = "%" + size + ".0f";
|
||||||
|
var fFormat = "%" + (size + 4) + ".3f";
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
|
var maxNameLen = 0;
|
||||||
|
for (var i = 0; i < nodes.length; i++) {
|
||||||
|
var node = nodes[i];
|
||||||
|
maxNameLen = Math.max(node.length(), maxNameLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
var table = new ConsoleTable(maxNameLen, "Node", "Departures", "Avg Queue", "Avg Wait", "Avg Response",
|
||||||
|
"Throughput", "Utilization %", "Unavailable %", "Last Event");
|
||||||
|
|
||||||
for (var i = 0; i < nodes.length; i++) {
|
for (var i = 0; i < nodes.length; i++) {
|
||||||
var node = nodes[i];
|
var node = nodes[i];
|
||||||
@@ -206,12 +237,24 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the nodes of the summary.
|
* Gets a copy of the nodes of the summary.
|
||||||
*
|
*
|
||||||
* @return the nodes of the summary
|
* @return the nodes of the summary
|
||||||
*/
|
*/
|
||||||
public List<String> getNodes() {
|
public String[] getNodes() {
|
||||||
return List.of(this.nodes);
|
return Arrays.copyOf(this.nodes, this.nodes.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the statistics of the nodes of the summary.
|
||||||
|
*
|
||||||
|
* @return the statistics of the nodes of the summary
|
||||||
|
*/
|
||||||
|
public NodeStats[] getStats() {
|
||||||
|
var stats = new NodeStats[this.nodes.length];
|
||||||
|
for (var i = 0; i < this.nodes.length; i++)
|
||||||
|
stats[i] = this.stats[i].average;
|
||||||
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -239,11 +282,8 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
var stats = new NodeStats[this.nodes.length];
|
return getResultString(this.seed, this.avgSimulationTime, this.avgTimeElapsedMS, this.nodes,
|
||||||
for (var i = 0; i < this.nodes.length; i++)
|
this.getStats());
|
||||||
stats[i] = this.stats[i].average;
|
|
||||||
|
|
||||||
return buildPrintable(this.seed, this.avgSimulationTime, this.avgTimeElapsedMS, this.nodes, stats);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,4 +55,23 @@ public class TestRandom {
|
|||||||
|
|
||||||
assertTrue("Standard Dev must be less than [" + expected + "] -> [" + stdDev + "]", stdDev < expected);
|
assertTrue("Standard Dev must be less than [" + expected + "] -> [" + stdDev + "]", stdDev < expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMean() {
|
||||||
|
var rng = new Rng();
|
||||||
|
var normal = new Distribution.NormalBoxMuller(1 / 3.5, 0.6);
|
||||||
|
var mean = 0.0;
|
||||||
|
|
||||||
|
for (var i = 0; i < 100000; i++) {
|
||||||
|
var sample = Distribution.getPositiveSample(normal, rng);
|
||||||
|
mean = (mean * (i + 1) + sample) / (i + 2);
|
||||||
|
}
|
||||||
|
assertEquals(0.6, mean, 0.01);
|
||||||
|
|
||||||
|
for (var i = 0; i < 100000; i++) {
|
||||||
|
var sample = Math.max(0, normal.sample(rng));
|
||||||
|
mean = (mean * (i + 1) + sample) / (i + 2);
|
||||||
|
}
|
||||||
|
assertEquals(0.41, mean, 0.01);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,8 +144,8 @@ public class TestInteractions {
|
|||||||
|
|
||||||
// Test the interactive console LOAD EXAMPLE 2
|
// Test the interactive console LOAD EXAMPLE 2
|
||||||
net = runInteraction("4", "2", "2", "7");
|
net = runInteraction("4", "2", "2", "7");
|
||||||
assertEquals("Source[servers:1, queue:100, spawn:10000, Exponential(1.5)] -> Service1(1.0)\n"
|
assertEquals("Source[servers:1, queue:100, spawn:10000, Exponential(1.5)] -> Service(1.0)\n"
|
||||||
+ "Service1[servers:1, queue:100, spawn:0, Exponential(2.0)] -> Service2(1.0)\n"
|
+ "Service[servers:1, queue:100, spawn:0, Exponential(2.0)] -> Service2(1.0)\n"
|
||||||
+ "Service2[servers:1, queue:100, spawn:0, Exponential(3.5), u:UnavailableTime(0.1, Exponential(10.0))] -\n",
|
+ "Service2[servers:1, queue:100, spawn:0, Exponential(3.5), u:UnavailableTime(0.1, Exponential(10.0))] -\n",
|
||||||
net.toString());
|
net.toString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
|
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
|
||||||
<archive xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="example3.jsimg" timestamp="Thu Mar 13 12:37:25 CET 2025" xsi:noNamespaceSchemaLocation="Archive.xsd">
|
<archive xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="example2.jsimg" timestamp="Wed Apr 02 14:09:03 CEST 2025" xsi:noNamespaceSchemaLocation="Archive.xsd">
|
||||||
<sim disableStatisticStop="false" logDecimalSeparator="," logDelimiter=";" logPath="C:\Users\giaco\JMT" logReplaceMode="0" maxEvents="-1" maxSamples="100000000" name="example3.jsimg" polling="1.0" xsi:noNamespaceSchemaLocation="SIMmodeldefinition.xsd">
|
<sim disableStatisticStop="false" logDecimalSeparator="," logDelimiter=";" logPath="C:\Users\giaco\JMT" logReplaceMode="0" maxEvents="-1" maxSamples="100000000" name="example2.jsimg" polling="1.0" xsi:noNamespaceSchemaLocation="SIMmodeldefinition.xsd">
|
||||||
<userClass name="Class1" priority="0" referenceSource="Source 1" softDeadline="0.0" type="open"/>
|
<userClass name="Class1" priority="0" referenceSource="Source 1" softDeadline="0.0" type="open"/>
|
||||||
<userClass customers="1" name="Class2" priority="0" referenceSource="IdleServer2" softDeadline="0.0" type="closed"/>
|
<userClass customers="1" name="Class2" priority="0" referenceSource="IdleServer2" softDeadline="0.0" type="closed"/>
|
||||||
<node name="Service1">
|
<node name="Service1">
|
||||||
@@ -853,13 +853,13 @@
|
|||||||
</parameter>
|
</parameter>
|
||||||
</section>
|
</section>
|
||||||
</node>
|
</node>
|
||||||
<measure alpha="0.02" name="System Throughput" nodeType="" precision="0.01" referenceNode="" referenceUserClass="" type="System Throughput" verbose="false"/>
|
<measure alpha="0.02" name="Class1_System Throughput" nodeType="" precision="0.01" referenceNode="" referenceUserClass="Class1" type="System Throughput" verbose="false"/>
|
||||||
<measure alpha="0.02" name="Service1_Class1_Utilization" nodeType="station" precision="0.01" referenceNode="Service1" referenceUserClass="Class1" type="Utilization" verbose="false"/>
|
<measure alpha="0.02" name="Service1_Class1_Utilization" nodeType="station" precision="0.01" referenceNode="Service1" referenceUserClass="Class1" type="Utilization" verbose="false"/>
|
||||||
<measure alpha="0.02" name="Calibration_Class2_Number of Customers" nodeType="station" precision="0.01" referenceNode="Calibration" referenceUserClass="Class2" type="Number of Customers" verbose="false"/>
|
<measure alpha="0.02" name="Busy2_Number of Customers" nodeType="station" precision="0.01" referenceNode="Busy2" referenceUserClass="" type="Number of Customers" verbose="false"/>
|
||||||
<measure alpha="0.02" name="Busy2_Class1_Number of Customers" nodeType="station" precision="0.01" referenceNode="Busy2" referenceUserClass="Class1" type="Number of Customers" verbose="false"/>
|
<measure alpha="0.02" name="Calibration_Number of Customers" nodeType="station" precision="0.01" referenceNode="Calibration" referenceUserClass="" type="Number of Customers" verbose="false"/>
|
||||||
<measure alpha="0.01" name="Service1_Class1_Response Time" nodeType="station" precision="0.03" referenceNode="Service1" referenceUserClass="Class1" type="Response Time" verbose="false"/>
|
<measure alpha="0.01" name="Service1_Class1_Response Time" nodeType="station" precision="0.03" referenceNode="Service1" referenceUserClass="Class1" type="Response Time" verbose="false"/>
|
||||||
<measure alpha="0.01" name="Queue2_Response Time" nodeType="station" precision="0.03" referenceNode="Queue2" referenceUserClass="" type="Response Time" verbose="false"/>
|
|
||||||
<measure alpha="0.01" name="Busy2_Response Time" nodeType="station" precision="0.03" referenceNode="Busy2" referenceUserClass="" type="Response Time" verbose="false"/>
|
<measure alpha="0.01" name="Busy2_Response Time" nodeType="station" precision="0.03" referenceNode="Busy2" referenceUserClass="" type="Response Time" verbose="false"/>
|
||||||
|
<measure alpha="0.01" name="Queue2_Response Time" nodeType="station" precision="0.03" referenceNode="Queue2" referenceUserClass="" type="Response Time" verbose="false"/>
|
||||||
<connection source="Service1" target="Queue2"/>
|
<connection source="Service1" target="Queue2"/>
|
||||||
<connection source="Queue2" target="StartService2"/>
|
<connection source="Queue2" target="StartService2"/>
|
||||||
<connection source="Busy2" target="Service2"/>
|
<connection source="Busy2" target="Service2"/>
|
||||||
@@ -923,78 +923,75 @@
|
|||||||
<position angle="0.0" rotate="true" x="505.0" y="328.0"/>
|
<position angle="0.0" rotate="true" x="505.0" y="328.0"/>
|
||||||
</station>
|
</station>
|
||||||
</jmodel>
|
</jmodel>
|
||||||
<results elapsedTime="36465" logDecimalSeparator="," logDelimiter=";" pollingInterval="1.0" xsi:noNamespaceSchemaLocation="Results.xsd">
|
<results elapsedTime="22985" logDecimalSeparator="," logDelimiter=";" pollingInterval="1.0" xsi:noNamespaceSchemaLocation="Results.xsd">
|
||||||
<measure alpha="0.98" analyzedSamples="163840" discardedSamples="20" finalValue="4.5232841623024065" name="System Throughput" nodeType="" precision="0.01" referenceClass="" referenceStation="" state="1" type="16">
|
<measure alpha="0.98" analyzedSamples="163840" discardedSamples="60" finalValue="1.501221406545825" name="Class1_System Throughput" nodeType="" precision="0.01" referenceClass="Class1" referenceStation="" state="1" type="16">
|
||||||
<sample lastIntervalAvgValue="4.504801490858249" lowerBound="4.458882972372562" meanValue="4.529318694858492" simulationTime="21776.09828070597" upperBound="4.602015440763236"/>
|
<sample lastIntervalAvgValue="1.5106622983340463" lowerBound="1.468486049955798" meanValue="1.50631035481992" simulationTime="13876.695025167392" upperBound="1.546134682461421"/>
|
||||||
<sample lastIntervalAvgValue="4.5282972183892385" lowerBound="4.482148935563637" meanValue="4.5232841623024065" simulationTime="36299.65908694518" upperBound="4.56518142536432"/>
|
<sample lastIntervalAvgValue="1.4986167692697017" lowerBound="1.4786226101201805" meanValue="1.5021490600601366" simulationTime="64253.81714744975" upperBound="1.5264362760056998"/>
|
||||||
|
<sample lastIntervalAvgValue="1.5036451787298382" lowerBound="1.4886800249805132" meanValue="1.501221406545825" simulationTime="109105.4889075181" upperBound="1.5139758930959133"/>
|
||||||
</measure>
|
</measure>
|
||||||
<measure alpha="0.98" analyzedSamples="163840" discardedSamples="645" finalValue="0.7488388343771116" name="Service1_Class1_Utilization" nodeType="station" precision="0.01" referenceClass="Class1" referenceStation="Service1" state="1" type="6">
|
<measure alpha="0.98" analyzedSamples="327680" discardedSamples="65" finalValue="0.7471951139971086" name="Service1_Class1_Utilization" nodeType="station" precision="0.01" referenceClass="Class1" referenceStation="Service1" state="1" type="6">
|
||||||
<sample lastIntervalAvgValue="0.7535064165853067" lowerBound="0.7347511898562679" meanValue="0.7554442760158694" simulationTime="21775.473427065597" upperBound="0.7761373621754709"/>
|
<sample lastIntervalAvgValue="0.7580797914843828" lowerBound="0.7284349220101368" meanValue="0.758341372366939" simulationTime="13876.28919854346" upperBound="0.7882478227237412"/>
|
||||||
<sample lastIntervalAvgValue="0.7445105711875073" lowerBound="0.7407212322280543" meanValue="0.7498037610368465" simulationTime="70354.5805071057" upperBound="0.7588862898456388"/>
|
<sample lastIntervalAvgValue="0.7437399633757887" lowerBound="0.7338157319545954" meanValue="0.7479059359761921" simulationTime="64255.194361328504" upperBound="0.7619961399977889"/>
|
||||||
<sample lastIntervalAvgValue="0.7586119497689925" lowerBound="0.7431437478710194" meanValue="0.7488388343771116" simulationTime="87689.27209134017" upperBound="0.7545339208832038"/>
|
<sample lastIntervalAvgValue="0.7481274953188917" lowerBound="0.7385472374512729" meanValue="0.7465206013494042" simulationTime="112954.31879089898" upperBound="0.7544939652475355"/>
|
||||||
|
<sample lastIntervalAvgValue="0.7484087729914563" lowerBound="0.7385472374512729" meanValue="0.7465206013494042" simulationTime="161441.3383818988" upperBound="0.7544939652475355"/>
|
||||||
|
<sample lastIntervalAvgValue="0.7449583611117644" lowerBound="0.7410310642295588" meanValue="0.7471951139971086" simulationTime="174394.58870580947" upperBound="0.7533591637646584"/>
|
||||||
</measure>
|
</measure>
|
||||||
<measure alpha="0.98" analyzedSamples="491520" discardedSamples="0" finalValue="0.01502196751515807" name="Calibration_Class2_Number of Customers" nodeType="station" precision="0.01" referenceClass="Class2" referenceStation="Calibration" state="1" type="0">
|
<measure alpha="0.98" analyzedSamples="491520" discardedSamples="20" finalValue="0.4285284158768284" name="Busy2_Number of Customers" nodeType="station" precision="0.01" referenceClass="" referenceStation="Busy2" state="1" type="0">
|
||||||
<sample lastIntervalAvgValue="0.015451188703979256" lowerBound="0.0138424705098969" meanValue="0.016187964221642762" simulationTime="21766.73812642876" upperBound="0.018533457933388627"/>
|
<sample lastIntervalAvgValue="0.4327278274081417" lowerBound="0.4209685663151158" meanValue="0.43604958177996045" simulationTime="13876.695025167392" upperBound="0.4511305972448051"/>
|
||||||
<sample lastIntervalAvgValue="0.015316511373736548" lowerBound="0.014374715697260619" meanValue="0.015190946165135149" simulationTime="70348.82214008998" upperBound="0.016007176633009677"/>
|
<sample lastIntervalAvgValue="0.4277717437256055" lowerBound="0.4246046190172446" meanValue="0.4316330740668569" simulationTime="64255.194361328504" upperBound="0.4386615291164692"/>
|
||||||
<sample lastIntervalAvgValue="0.014810176107958328" lowerBound="0.014499838877632499" meanValue="0.015141505665220153" simulationTime="116227.31778632166" upperBound="0.015783172452807807"/>
|
<sample lastIntervalAvgValue="0.4275252965369865" lowerBound="0.42421446359628734" meanValue="0.428573485460139" simulationTime="112953.74188414749" upperBound="0.4329325073239907"/>
|
||||||
<sample lastIntervalAvgValue="0.015015931438824447" lowerBound="0.014499838877632499" meanValue="0.015141505665220153" simulationTime="161897.14230721688" upperBound="0.015783172452807807"/>
|
<sample lastIntervalAvgValue="0.4283866284569466" lowerBound="0.42421446359628734" meanValue="0.428573485460139" simulationTime="161441.69294713807" upperBound="0.4329325073239907"/>
|
||||||
<sample lastIntervalAvgValue="0.015097088641949937" lowerBound="0.014672164221681517" meanValue="0.015083679994612001" simulationTime="207688.88837590834" upperBound="0.015495195767542486"/>
|
<sample lastIntervalAvgValue="0.4302070978372558" lowerBound="0.42484998277284614" meanValue="0.4285284158768284" simulationTime="203719.94497095025" upperBound="0.43220684898081063"/>
|
||||||
<sample lastIntervalAvgValue="0.014829921937192552" lowerBound="0.014672164221681517" meanValue="0.015083679994612001" simulationTime="254149.67477199846" upperBound="0.015495195767542486"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014911973968486553" lowerBound="0.014672164221681517" meanValue="0.015083679994612001" simulationTime="300536.84517320833" upperBound="0.015495195767542486"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014699223664444459" lowerBound="0.014672164221681517" meanValue="0.015083679994612001" simulationTime="346691.52494638273" upperBound="0.015495195767542486"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014988018919497652" lowerBound="0.014672164221681517" meanValue="0.015083679994612001" simulationTime="392753.7815057624" upperBound="0.015495195767542486"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015390467280069639" lowerBound="0.014692057017720115" meanValue="0.014950192945317558" simulationTime="439015.40235724894" upperBound="0.015208328872915"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014723468291279457" lowerBound="0.014692057017720115" meanValue="0.014950192945317558" simulationTime="486023.41708038445" upperBound="0.015208328872915"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014990332429956269" lowerBound="0.014692057017720115" meanValue="0.014950192945317558" simulationTime="532345.2338903961" upperBound="0.015208328872915"/>
|
|
||||||
<sample lastIntervalAvgValue="0.01512892277644804" lowerBound="0.014692057017720115" meanValue="0.014950192945317558" simulationTime="577743.0321701578" upperBound="0.015208328872915"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015375427409931423" lowerBound="0.014692057017720115" meanValue="0.014950192945317558" simulationTime="622253.6586889254" upperBound="0.015208328872915"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015155014689754675" lowerBound="0.014692057017720115" meanValue="0.014950192945317558" simulationTime="668163.390439792" upperBound="0.015208328872915"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014967893805991304" lowerBound="0.014692057017720115" meanValue="0.014950192945317558" simulationTime="713612.4515839645" upperBound="0.015208328872915"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015093515945500144" lowerBound="0.014692057017720115" meanValue="0.014950192945317558" simulationTime="758075.1986095438" upperBound="0.015208328872915"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015240038896880059" lowerBound="0.014692057017720115" meanValue="0.014950192945317558" simulationTime="803122.8063282591" upperBound="0.015208328872915"/>
|
|
||||||
<sample lastIntervalAvgValue="0.01494197253142771" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="846994.9182424243" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015316224307781281" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="892371.1869919545" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015287557414606176" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="937841.2147936824" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014828449374704704" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="979320.4534554591" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015367428881752852" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1021517.3855445393" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015373844504018285" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1066479.3541446298" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015144042405280125" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1113069.7105294534" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015033483433153087" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1158935.8798971626" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.01488156398436712" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1205086.0006715988" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015054286820852658" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1250896.7860750651" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015051541315634832" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1296770.221482743" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014784450606072117" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1343326.8851068765" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014812454176986678" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1389252.9730239573" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015088702324276122" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1434795.9813835449" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014886542332539013" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1480835.7958693986" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014979218892753306" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1526224.9871218654" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014506037996704546" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1569533.926212085" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.014851578281992977" lowerBound="0.01487607320311706" meanValue="0.015039710794825883" simulationTime="1611240.7532581263" upperBound="0.015203348386534707"/>
|
|
||||||
<sample lastIntervalAvgValue="0.015113421688025146" lowerBound="0.014903824682028551" meanValue="0.01502196751515807" simulationTime="1638481.7111367544" upperBound="0.015140110348287588"/>
|
|
||||||
</measure>
|
</measure>
|
||||||
<measure alpha="0.98" analyzedSamples="327680" discardedSamples="280" finalValue="0.42790781788223825" name="Busy2_Class1_Number of Customers" nodeType="station" precision="0.01" referenceClass="Class1" referenceStation="Busy2" state="1" type="0">
|
<measure alpha="0.98" analyzedSamples="327680" discardedSamples="160" finalValue="0.014924666640854697" name="Calibration_Number of Customers" nodeType="station" precision="0.01" referenceClass="" referenceStation="Calibration" state="1" type="0">
|
||||||
<sample lastIntervalAvgValue="0.4270037257849655" lowerBound="0.419757623740597" meanValue="0.43104459763105024" simulationTime="21776.09828070597" upperBound="0.4423315715215035"/>
|
<sample lastIntervalAvgValue="0.014296267465728714" lowerBound="0.011322752016847876" meanValue="0.014850303903029771" simulationTime="13874.061196402345" upperBound="0.018377855789211667"/>
|
||||||
<sample lastIntervalAvgValue="0.4276599741209307" lowerBound="0.4223922092995258" meanValue="0.42701287609912386" simulationTime="70354.67479538477" upperBound="0.4316335428987219"/>
|
<sample lastIntervalAvgValue="0.014868345345791742" lowerBound="0.013988219806503858" meanValue="0.014827742149762239" simulationTime="64253.42721042049" upperBound="0.015667264493020618"/>
|
||||||
<sample lastIntervalAvgValue="0.4268697539498743" lowerBound="0.4223922092995258" meanValue="0.42701287609912386" simulationTime="116227.22182050864" upperBound="0.4316335428987219"/>
|
<sample lastIntervalAvgValue="0.014812215932949374" lowerBound="0.014092261369804996" meanValue="0.014674223347077174" simulationTime="112953.02447111536" upperBound="0.015256185324349353"/>
|
||||||
<sample lastIntervalAvgValue="0.4314156316385907" lowerBound="0.42440678200176163" meanValue="0.42790781788223825" simulationTime="135859.83926632564" upperBound="0.4314088537627149"/>
|
<sample lastIntervalAvgValue="0.014559361071869054" lowerBound="0.014247388150725647" meanValue="0.014709234534974254" simulationTime="161433.99304923858" upperBound="0.015171080919222861"/>
|
||||||
|
<sample lastIntervalAvgValue="0.014995041507434526" lowerBound="0.014247388150725647" meanValue="0.014709234534974254" simulationTime="208953.24224685304" upperBound="0.015171080919222861"/>
|
||||||
|
<sample lastIntervalAvgValue="0.014949846023837393" lowerBound="0.014247388150725647" meanValue="0.014709234534974254" simulationTime="257841.91701157822" upperBound="0.015171080919222861"/>
|
||||||
|
<sample lastIntervalAvgValue="0.015408671090531872" lowerBound="0.014497445222088935" meanValue="0.01488811143629382" simulationTime="307232.2999839692" upperBound="0.015278777650498704"/>
|
||||||
|
<sample lastIntervalAvgValue="0.014666101118067975" lowerBound="0.014497445222088935" meanValue="0.01488811143629382" simulationTime="356122.65243281063" upperBound="0.015278777650498704"/>
|
||||||
|
<sample lastIntervalAvgValue="0.014751113494851873" lowerBound="0.014497445222088935" meanValue="0.01488811143629382" simulationTime="404635.01388552965" upperBound="0.015278777650498704"/>
|
||||||
|
<sample lastIntervalAvgValue="0.014672454292437586" lowerBound="0.014497445222088935" meanValue="0.01488811143629382" simulationTime="453685.40696788987" upperBound="0.015278777650498704"/>
|
||||||
|
<sample lastIntervalAvgValue="0.015094578158137126" lowerBound="0.014497445222088935" meanValue="0.01488811143629382" simulationTime="502604.4424242108" upperBound="0.015278777650498704"/>
|
||||||
|
<sample lastIntervalAvgValue="0.0147073503392127" lowerBound="0.014627249197317147" meanValue="0.014870847342668999" simulationTime="551597.2510570573" upperBound="0.01511444548802085"/>
|
||||||
|
<sample lastIntervalAvgValue="0.014849138821895225" lowerBound="0.014627249197317147" meanValue="0.014870847342668999" simulationTime="600424.9280403093" upperBound="0.01511444548802085"/>
|
||||||
|
<sample lastIntervalAvgValue="0.015292616237036798" lowerBound="0.014627249197317147" meanValue="0.014870847342668999" simulationTime="649308.6124621176" upperBound="0.01511444548802085"/>
|
||||||
|
<sample lastIntervalAvgValue="0.014377886778078027" lowerBound="0.014627249197317147" meanValue="0.014870847342668999" simulationTime="698192.541974876" upperBound="0.01511444548802085"/>
|
||||||
|
<sample lastIntervalAvgValue="0.01497014247619875" lowerBound="0.014627249197317147" meanValue="0.014870847342668999" simulationTime="746741.2640130178" upperBound="0.01511444548802085"/>
|
||||||
|
<sample lastIntervalAvgValue="0.014858699882670481" lowerBound="0.014627249197317147" meanValue="0.014870847342668999" simulationTime="795533.0825674769" upperBound="0.01511444548802085"/>
|
||||||
|
<sample lastIntervalAvgValue="0.01517207994251526" lowerBound="0.014627249197317147" meanValue="0.014870847342668999" simulationTime="844151.4035294583" upperBound="0.01511444548802085"/>
|
||||||
|
<sample lastIntervalAvgValue="0.014861073878907496" lowerBound="0.014627249197317147" meanValue="0.014870847342668999" simulationTime="892762.1492607896" upperBound="0.01511444548802085"/>
|
||||||
|
<sample lastIntervalAvgValue="0.015266432294084805" lowerBound="0.014627249197317147" meanValue="0.014870847342668999" simulationTime="941109.1109068348" upperBound="0.01511444548802085"/>
|
||||||
|
<sample lastIntervalAvgValue="0.014682845962729731" lowerBound="0.014627249197317147" meanValue="0.014870847342668999" simulationTime="989071.5846569396" upperBound="0.01511444548802085"/>
|
||||||
|
<sample lastIntervalAvgValue="0.014978189055859124" lowerBound="0.014627249197317147" meanValue="0.014870847342668999" simulationTime="1037509.0030904149" upperBound="0.01511444548802085"/>
|
||||||
|
<sample lastIntervalAvgValue="0.015254413177080007" lowerBound="0.014627249197317147" meanValue="0.014870847342668999" simulationTime="1086040.183054915" upperBound="0.01511444548802085"/>
|
||||||
|
<sample lastIntervalAvgValue="0.014605848518467818" lowerBound="0.014782350210118329" meanValue="0.014924666640854697" simulationTime="1096716.662202565" upperBound="0.015066983071591065"/>
|
||||||
</measure>
|
</measure>
|
||||||
<measure alpha="0.99" analyzedSamples="409600" discardedSamples="0" finalValue="1.986564381173249" name="Service1_Class1_Response Time" nodeType="station" precision="0.03" referenceClass="Class1" referenceStation="Service1" state="1" type="2">
|
<measure alpha="0.99" analyzedSamples="778240" discardedSamples="3005" finalValue="2.0114910663794854" name="Service1_Class1_Response Time" nodeType="station" precision="0.03" referenceClass="Class1" referenceStation="Service1" state="1" type="2">
|
||||||
<sample lastIntervalAvgValue="2.0599179672889827" lowerBound="1.8264644916233692" meanValue="2.099179305259092" simulationTime="21775.473427065597" upperBound="2.371894118894815"/>
|
<sample lastIntervalAvgValue="1.94831588313056" lowerBound="1.569602317070396" meanValue="1.8932003606330974" simulationTime="13876.28919854346" upperBound="2.2167984041957984"/>
|
||||||
<sample lastIntervalAvgValue="1.96682860504446" lowerBound="1.9213379061986726" meanValue="2.006465003671471" simulationTime="70354.5805071057" upperBound="2.0915921011442693"/>
|
<sample lastIntervalAvgValue="1.96702004144991" lowerBound="1.8378967552023229" meanValue="2.0265293538191256" simulationTime="64255.194361328504" upperBound="2.215161952435928"/>
|
||||||
<sample lastIntervalAvgValue="2.031093718502449" lowerBound="1.9213379061986726" meanValue="2.006465003671471" simulationTime="116228.33156832606" upperBound="2.0915921011442693"/>
|
<sample lastIntervalAvgValue="1.9583792326739768" lowerBound="1.8419491796060967" meanValue="1.9467177321899223" simulationTime="112954.31879089898" upperBound="2.051486284773748"/>
|
||||||
<sample lastIntervalAvgValue="1.9061317473170853" lowerBound="1.9199753971000892" meanValue="1.9869801546284203" simulationTime="161903.31510042533" upperBound="2.0539849121567513"/>
|
<sample lastIntervalAvgValue="1.9920863680624197" lowerBound="1.8815084714201606" meanValue="1.9586531713516644" simulationTime="161441.3383818988" upperBound="2.0357978712831684"/>
|
||||||
<sample lastIntervalAvgValue="1.9192841262686469" lowerBound="1.9199753971000892" meanValue="1.9869801546284203" simulationTime="207689.00729111172" upperBound="2.0539849121567513"/>
|
<sample lastIntervalAvgValue="2.08577509641053" lowerBound="1.8815084714201606" meanValue="1.9586531713516644" simulationTime="208959.31741758634" upperBound="2.0357978712831684"/>
|
||||||
<sample lastIntervalAvgValue="2.042724611382815" lowerBound="1.9199753971000892" meanValue="1.9869801546284203" simulationTime="254151.00098901935" upperBound="2.0539849121567513"/>
|
<sample lastIntervalAvgValue="2.013680282601994" lowerBound="1.8815084714201606" meanValue="1.9586531713516644" simulationTime="257854.98823458815" upperBound="2.0357978712831684"/>
|
||||||
<sample lastIntervalAvgValue="2.0996528378344155" lowerBound="1.9315234682839908" meanValue="1.986564381173249" simulationTime="272849.5832034668" upperBound="2.041605294062507"/>
|
<sample lastIntervalAvgValue="1.9655282858960066" lowerBound="1.9488991331825811" meanValue="2.011806401261866" simulationTime="307242.539402015" upperBound="2.0747136693411505"/>
|
||||||
|
<sample lastIntervalAvgValue="2.0760998968280298" lowerBound="1.9488991331825811" meanValue="2.011806401261866" simulationTime="356127.94247851" upperBound="2.0747136693411505"/>
|
||||||
|
<sample lastIntervalAvgValue="2.033177821938796" lowerBound="1.9488991331825811" meanValue="2.011806401261866" simulationTime="404638.22271664144" upperBound="2.0747136693411505"/>
|
||||||
|
<sample lastIntervalAvgValue="1.999037798158856" lowerBound="1.9488991331825811" meanValue="2.011806401261866" simulationTime="453687.12732063007" upperBound="2.0747136693411505"/>
|
||||||
|
<sample lastIntervalAvgValue="1.9448319477916651" lowerBound="1.9488991331825811" meanValue="2.011806401261866" simulationTime="502604.22743246035" upperBound="2.0747136693411505"/>
|
||||||
|
<sample lastIntervalAvgValue="2.1072909204942096" lowerBound="1.9670740207786732" meanValue="2.0114910663794854" simulationTime="520010.72527265665" upperBound="2.0559081119802975"/>
|
||||||
</measure>
|
</measure>
|
||||||
<measure alpha="0.99" analyzedSamples="163840" discardedSamples="0" finalValue="0.22788167369085163" name="Queue2_Response Time" nodeType="station" precision="0.03" referenceClass="" referenceStation="Queue2" state="1" type="2">
|
<measure alpha="0.99" analyzedSamples="51200" discardedSamples="20" finalValue="0.2857712799507223" name="Busy2_Response Time" nodeType="station" precision="0.03" referenceClass="" referenceStation="Busy2" state="1" type="2">
|
||||||
<sample lastIntervalAvgValue="0.2212951698650024" lowerBound="0.2027105687474914" meanValue="0.2242909119463804" simulationTime="21776.00795157667" upperBound="0.2458712551452694"/>
|
<sample lastIntervalAvgValue="0.28644908123102863" lowerBound="0.2722201556987353" meanValue="0.28601168477942707" simulationTime="13876.695025167392" upperBound="0.2998032138601188"/>
|
||||||
<sample lastIntervalAvgValue="0.2278950422330009" lowerBound="0.2153447485921806" meanValue="0.2245708961594881" simulationTime="70354.5805071057" upperBound="0.2337970437267956"/>
|
<sample lastIntervalAvgValue="0.28510476832868925" lowerBound="0.2816272949130171" meanValue="0.2857712799507223" simulationTime="33841.364358874554" upperBound="0.28991526498842757"/>
|
||||||
<sample lastIntervalAvgValue="0.22956698889225155" lowerBound="0.22151463053572565" meanValue="0.22788167369085163" simulationTime="109254.34303629368" upperBound="0.23424871684597762"/>
|
|
||||||
</measure>
|
</measure>
|
||||||
<measure alpha="0.99" analyzedSamples="35840" discardedSamples="65" finalValue="0.28347770862779204" name="Busy2_Response Time" nodeType="station" precision="0.03" referenceClass="" referenceStation="Busy2" state="1" type="2">
|
<measure alpha="0.99" analyzedSamples="225280" discardedSamples="565" finalValue="0.23183614777687678" name="Queue2_Response Time" nodeType="station" precision="0.03" referenceClass="" referenceStation="Queue2" state="1" type="2">
|
||||||
<sample lastIntervalAvgValue="0.28436573286403344" lowerBound="0.2760999612224342" meanValue="0.2875318764129495" simulationTime="21776.09828070597" upperBound="0.29896379160346487"/>
|
<sample lastIntervalAvgValue="0.23921408959189303" lowerBound="0.19954877885417566" meanValue="0.2302254387533936" simulationTime="13876.695025167392" upperBound="0.26090209865261155"/>
|
||||||
<sample lastIntervalAvgValue="0.2821039263923575" lowerBound="0.2784439934828284" meanValue="0.28347770862779204" simulationTime="23986.594552011404" upperBound="0.2885114237727557"/>
|
<sample lastIntervalAvgValue="0.22855069519234839" lowerBound="0.21936484900427225" meanValue="0.23297066183042345" simulationTime="64255.194361328504" upperBound="0.24657647465657465"/>
|
||||||
|
<sample lastIntervalAvgValue="0.23258007884898674" lowerBound="0.22085652239964554" meanValue="0.23127995842533797" simulationTime="112953.74188414749" upperBound="0.2417033944510304"/>
|
||||||
|
<sample lastIntervalAvgValue="0.2332468297868342" lowerBound="0.22496715167829837" meanValue="0.23183614777687678" simulationTime="150286.67327611792" upperBound="0.2387051438754552"/>
|
||||||
</measure>
|
</measure>
|
||||||
</results>
|
</results>
|
||||||
</archive>
|
</archive>
|
||||||