Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
158976bb71 | ||
| f8f7f72eea | |||
| 37e0b57c36 | |||
| 44cf714840 | |||
| 719c6b353a | |||
| 4b9c40f894 | |||
| 78dcac0a56 | |||
| 57c9dd9733 | |||
| 3844a46379 | |||
| e48bddf94d | |||
| 8f30f07c36 | |||
| e4df5dab73 | |||
|
|
68687fa595 | ||
|
|
9b51562469 | ||
| e11bb3f419 | |||
| 2ed8149110 | |||
| f4d3262cb7 | |||
| 60ef40c0ab | |||
| 6cb87be89b | |||
| cd3ff3b699 | |||
| 1687154c62 | |||
| 76adc91a43 | |||
| 744df75d41 | |||
| 8fe2f9d781 | |||
| 611e14e6fa | |||
| 121d4cd44a | |||
| c2b9d350aa | |||
| 1cab669fd9 | |||
| 64e135810a | |||
| fbd1fab9fb | |||
| e97703e23a | |||
| 3a769d6ae3 | |||
| 6b3b5fea2f | |||
| f0d9c59350 | |||
| 65e8f378f5 | |||
| cb8b2d2913 | |||
| 2331e42e55 | |||
| d7bf804313 | |||
| 762a1d1d0a | |||
| f5d70140d7 |
32
.vscode/launch.json
vendored
@@ -4,61 +4,61 @@
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "java",
|
||||
"name": "NetExamples",
|
||||
"request": "launch",
|
||||
"mainClass": "net.berack.upo.valpre.NetExamples",
|
||||
"projectName": "valpre"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Run1k Simple",
|
||||
"request": "launch",
|
||||
"mainClass": "net.berack.upo.valpre.Main",
|
||||
"args": "simulation -net example1.net -runs 1000 -p"
|
||||
"args": "simulation -net src/test/resources/example1.net -runs 1000 -p"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Run1k Complex",
|
||||
"request": "launch",
|
||||
"mainClass": "net.berack.upo.valpre.Main",
|
||||
"args": "simulation -net example2.net -runs 1000 -p"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Run1k Complex EXP",
|
||||
"request": "launch",
|
||||
"mainClass": "net.berack.upo.valpre.Main",
|
||||
"args": "simulation -net example3.net -runs 1000 -p"
|
||||
"args": "simulation -net src/test/resources/example2.net -runs 1000 -p"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Run Incremental",
|
||||
"request": "launch",
|
||||
"mainClass": "net.berack.upo.valpre.Main",
|
||||
"args": "simulation -net example3.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",
|
||||
"name": "Run10",
|
||||
"request": "launch",
|
||||
"mainClass": "net.berack.upo.valpre.Main",
|
||||
"args": "simulation -net example1.net -runs 10 -seed 2007539552"
|
||||
"args": "simulation -net src/test/resources/example1.net -runs 10 -seed 2007539552"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Plot Simple",
|
||||
"request": "launch",
|
||||
"mainClass": "net.berack.upo.valpre.Main",
|
||||
"args": "plot -csv example1.csv"
|
||||
"args": "plot -csv src/test/resources/example1.csv"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Plot Complex",
|
||||
"request": "launch",
|
||||
"mainClass": "net.berack.upo.valpre.Main",
|
||||
"args": "plot -csv example2.csv"
|
||||
"args": "plot -csv src/test/resources/example2.csv"
|
||||
},
|
||||
{
|
||||
"type": "java",
|
||||
"name": "Build Net",
|
||||
"name": "Interactive Net Builder",
|
||||
"request": "launch",
|
||||
"mainClass": "net.berack.upo.valpre.Main",
|
||||
"args": "net"
|
||||
},
|
||||
"args": "interactive"
|
||||
}
|
||||
]
|
||||
}
|
||||
84
README.md
@@ -9,11 +9,11 @@ Il risultato è la creazione in una libreria per la simulazione di eventi discre
|
||||
> Il JAR risultante che si trova nelle [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)).
|
||||
|
||||
### 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:
|
||||
|
||||
* `java -jar upo-valpre.jar net`\
|
||||
* `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.\
|
||||
Una volta scelta la rete è necessario salvarla in un file per la successiva simulazione e analisi.
|
||||
* `java -jar upo-valpre.jar simulation -net <file> [other]`\
|
||||
@@ -21,33 +21,93 @@ Usato per avviare una simulazione della rete. Nel caso la rete non abbia eventua
|
||||
Esistono vari tipi di argomenti per scegliere come fare la simulazione:
|
||||
* `-runs <N>` per fare la simulazione N volte
|
||||
* `-seed <value>` per dare un seed iniziale scelto
|
||||
* `-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%\];\[..\]**
|
||||
* `-csv <file>` per salvare i risultati delle run in un file csv
|
||||
* `-p` per fare le simulazioni in parallelo (ovvero 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:\
|
||||
**\[Tipo1:param1,..,paramN\];\[..\];\[TipoN:param1,..,paramN\]**
|
||||
**\[tipo:param1,..,paramN\];\[..\]**
|
||||
* `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:\
|
||||

|
||||
|
||||
Esistono dei file prefatti per vedere eventuali simulazioni che, nel caso vengano passati come parametri, automaticamente vengono usati:
|
||||
* `example1.net`, `example2.net` e `example3.net` per `simulation -net`
|
||||
* `example1.csv`, `example2.csv` e `example3.csv` per `plot -csv`
|
||||
## 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](https://github.com/Berack96/upo-valpre/tree/main/src/main/java/net/berack/upo/valpre) sono usate per l'utilizzo del jar e quindi non sono essenziali per la simulazione.
|
||||
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.
|
||||
I percorsi che invece sono direttamente responsabili per la simulazione sono:
|
||||
- [net.berack.upo.valpre.rand](https://github.com/Berack96/upo-valpre/tree/main/src/main/java/net/berack/upo/valpre/rand) All'interno del quale si possono trovare:
|
||||
- [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](https://github.com/Berack96/upo-valpre/tree/main/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.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](https://github.com/Berack96/upo-valpre/tree/main/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:
|
||||
- [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
|
||||
|
||||
## Esempi
|
||||
|
||||
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.\
|
||||
`java -jar upo-valpre.jar interactive`\
|
||||
Questa libreria è stata confrontata con il tool [JMT](https://jmt.sourceforge.net/Download.html); le reti usate per fare il confronto si possono trovare sotto [le risorse del test](src/test/resources) e in esse ci sono anche i risultati ottenuti dalle run.\
|
||||
Inoltre in alcune istanze state modificate le due reti di esempio in modo da mostrare cosa succede con l'aumento del numero di clienti nel sistema e cambiando la distribuzione di servizio di un nodo. Ogni valore ottenuto ha un sample di 1000 simulazioni. I risultati possono essere presi dal seguente [link](https://docs.google.com/spreadsheets/d/1yM1fvlpc2mIIpRe8M7_ry8m3DC3ZxNA204mM60O2hoQ/edit?usp=sharing)\
|
||||
Le distribuzioni usate hanno tutte la stessa media μ:
|
||||
- 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).\
|
||||
Se si effettua una simulazione si vedranno i risultati sulla console in questo modo:\
|
||||

|
||||
|
||||
O se si utilizza la parte grafica si possono vedere i risultati della Queue con l'incertezza:\
|
||||

|
||||
|
||||
Il tool JMT con la stessa rete produce i seguenti risultati che sono molto simili a quelli prodotti dalla libreria:
|
||||
```
|
||||
Response Time (Queue) 7.3022 con range [7.1456, 7.4589]
|
||||
Throughput (Queue) 0.2226 con range [0.2182, 0.2271]
|
||||
Utilization (Queue) 0.7111 con range [0.6959, 0.7262]
|
||||
```
|
||||
|
||||
Successivamente ho cambiato la distribuzione di servizio usata dal nodo "Queue".\
|
||||
Come si può notare l'utilizzo e il throughput rimangono pressochè invariati tra le varie distribuzioni, ma convergono con l'aumentare dei clienti.\
|
||||
I valori che cambiano sono il **numero medio della coda**, il **tempo medio di attesa** e, di conseguenza, anche il **tempo medio di risposta**.\
|
||||
\
|
||||
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)\
|
||||
Se si effettua una simulazione si vedranno i risultati sulla console in questo modo:\
|
||||

|
||||
|
||||
O se si utilizza la parte grafica si possono vedere i risultati del Service2 con l'incertezza:\
|
||||

|
||||
|
||||
Il tool JMT con la stessa rete produce i seguenti risultati che sono molto simili a quelli prodotti dalla libreria:
|
||||
```
|
||||
Response Time (Service1) 2.0115 con range [1.9671, 2.0559]
|
||||
Response Time (Busy2) 0.2858 con range [0.2816, 0.2899]
|
||||
Response Time (Queue2) 0.2318 con range [0.2250, 0.2387]
|
||||
Utilization (Service1) 0.7472 con range [0.7410, 0.7534]
|
||||
Number of Customers (Busy2) 0.4285 con range [0.4248, 0.4322]
|
||||
Number of Customers (Calibration) 0.0149 con range [0.0148, 0.0151]
|
||||
Throughput del Sistema 1.5094 con range [1.5005, 1.5183]
|
||||
```
|
||||
|
||||
Successivamente ho cambiato la distribuzione di servizio usata dal nodo "Service2".\
|
||||
Anche in questo caso l'utilizzo e il throughput rimangono pressochè invariati e convergono con l'aumentare dei clienti nel sistema, ma cambiano il **numero medio della coda** e il **tempo medio di attesa**.\
|
||||
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.\
|
||||

|
||||
|
||||
BIN
image/README/1741860064265.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
image/README/1741862486547.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
image/README/1741862746304.png
Normal file
|
After Width: | Height: | Size: 902 B |
BIN
image/README/1741863043733.png
Normal file
|
After Width: | Height: | Size: 1.1 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 |
29
pom.xml
@@ -13,30 +13,6 @@
|
||||
<maven.compiler.target>23</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- Compilazione Java con Maven -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>23</source>
|
||||
<target>23</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Maven plugin per eseguire l'applicazione JavaFX -->
|
||||
<plugin>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-maven-plugin</artifactId>
|
||||
<version>0.0.8</version>
|
||||
<configuration>
|
||||
<mainClass>net.berack.upo.valpre.Main</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
@@ -65,5 +41,10 @@
|
||||
<artifactId>jfreechart</artifactId>
|
||||
<version>1.5.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.argparse4j</groupId>
|
||||
<artifactId>argparse4j</artifactId>
|
||||
<version>0.9.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
267
src/main/java/net/berack/upo/valpre/InteractiveConsole.java
Normal file
@@ -0,0 +1,267 @@
|
||||
package net.berack.upo.valpre;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Scanner;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.esotericsoftware.kryo.KryoException;
|
||||
|
||||
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.ServerNode;
|
||||
|
||||
/**
|
||||
* Interactive net builder. This class allows the user to build a net by adding
|
||||
* nodes and connections. The user can also save the net to a file.
|
||||
*/
|
||||
public class InteractiveConsole {
|
||||
|
||||
private Net net = new Net();
|
||||
private final PrintStream out;
|
||||
private final Scanner scanner;
|
||||
|
||||
/**
|
||||
* Create a new interactive net builder. Uses System.in and System.out.
|
||||
*/
|
||||
public InteractiveConsole() {
|
||||
this(System.out, System.in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new interactive net builder.
|
||||
*
|
||||
* @param out the output stream
|
||||
* @param in the input stream
|
||||
*/
|
||||
public InteractiveConsole(PrintStream out, InputStream in) {
|
||||
this.out = out;
|
||||
this.scanner = new Scanner(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the interactive net builder.
|
||||
*/
|
||||
public Net run() {
|
||||
while (true) {
|
||||
try {
|
||||
var choice = choose(this.net + "\nChoose the next step to do:",
|
||||
"Add a node", "Add a connection", "Save the net", "Load net", "Clear", "Run", "Exit");
|
||||
switch (choice) {
|
||||
case 1 -> this.buildNode();
|
||||
case 2 -> this.buildConnection();
|
||||
case 3 -> this.net.save(ask("Enter the filename: "));
|
||||
case 4 -> this.loadNet();
|
||||
case 5 -> this.net = new Net();
|
||||
case 6 -> this.simpleRuns();
|
||||
default -> {
|
||||
this.scanner.close();
|
||||
return this.net;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a node as a source, terminal, queue, or queue with unavailable time.
|
||||
*/
|
||||
private void buildNode() {
|
||||
var choice = choose("Choose the type of node to create:", "Source", "Terminal", "Queue",
|
||||
"Queue with unavailable time");
|
||||
var name = ask("Node name: ");
|
||||
var distribution = askDistribution("Service distribution");
|
||||
|
||||
var node = switch (choice) {
|
||||
case 1 -> ServerNode.Builder.source(name, distribution);
|
||||
case 2 -> {
|
||||
var limit = ask("Arrivals limit (0 for Int.Max): ", Integer::parseInt);
|
||||
if (limit <= 0)
|
||||
limit = Integer.MAX_VALUE;
|
||||
yield ServerNode.Builder.terminal(name, limit, distribution);
|
||||
}
|
||||
case 3 -> {
|
||||
var servers = ask("Number of servers: ", Integer::parseInt);
|
||||
yield ServerNode.Builder.queue(name, servers, distribution, null);
|
||||
}
|
||||
case 4 -> {
|
||||
var servers = ask("Number of servers: ", Integer::parseInt);
|
||||
var unavailable = askDistribution("Unavailable distribution");
|
||||
yield ServerNode.Builder.queue(name, servers, distribution, unavailable);
|
||||
}
|
||||
default -> null;
|
||||
};
|
||||
|
||||
if (node != null)
|
||||
this.net.addNode(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a connection.
|
||||
*/
|
||||
private void buildConnection() {
|
||||
var source = ask("Enter the source node: ");
|
||||
var target = ask("Enter the target node: ");
|
||||
var weight = ask("Enter the weight: ", Double::parseDouble);
|
||||
var sourceNode = this.net.getNode(source);
|
||||
var targetNode = this.net.getNode(target);
|
||||
this.net.addConnection(sourceNode, targetNode, weight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a net from a file or from examples.
|
||||
*/
|
||||
private void loadNet() throws KryoException, IOException {
|
||||
var choice = choose("Choose the type of net to load:", "From file", "From examples");
|
||||
this.net = switch (choice) {
|
||||
case 1 -> Net.load(ask("Enter the filename: "));
|
||||
case 2 -> {
|
||||
var choice2 = choose("Choose the example to load:",
|
||||
"Example 1: Source -> Queue",
|
||||
"Example 2: Source -> Queue -> Queue");
|
||||
yield switch (choice2) {
|
||||
case 1 -> NetExamples.getNet1();
|
||||
case 2 -> NetExamples.getNet2();
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the simulation with the net.
|
||||
*/
|
||||
private void simpleRuns() throws Exception {
|
||||
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) {
|
||||
case 1 -> new SimulationBuilder(net).setSeed(seed).setMaxRuns(100).setParallel(true).setCsv(csv).run();
|
||||
case 2 -> new SimulationBuilder(net).setSeed(seed).setMaxRuns(1000).setParallel(true).setCsv(csv).run();
|
||||
case 3 -> {
|
||||
var indices = ask("Confidence indices with format [node:stat=confidence:relativeError];[..]\n");
|
||||
new SimulationBuilder(net).setSeed(seed).setMaxRuns(10000).parseConfidenceIndices(indices).setCsv(csv)
|
||||
.run();
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the user for a distribution.
|
||||
*
|
||||
* @return the distribution
|
||||
*/
|
||||
private Distribution askDistribution(String ask) {
|
||||
var choice = choose(ask + ":", "Exponential", "Uniform", "Erlang",
|
||||
"UnavailableTime", "Normal", "NormalBoxMuller", "None");
|
||||
|
||||
return switch (choice) {
|
||||
case 1 -> {
|
||||
var lambda = ask("Lambda: ", Double::parseDouble);
|
||||
yield new Distribution.Exponential(lambda);
|
||||
}
|
||||
case 2 -> {
|
||||
var min = ask("Min: ", Double::parseDouble);
|
||||
var max = ask("Max: ", Double::parseDouble);
|
||||
yield new Distribution.Uniform(min, max);
|
||||
}
|
||||
case 3 -> {
|
||||
var k = ask("K: ", Integer::parseInt);
|
||||
var lambda = ask("Lambda: ", Double::parseDouble);
|
||||
yield new Distribution.Erlang(k, lambda);
|
||||
}
|
||||
case 4 -> {
|
||||
var probability = ask("Probability: ", Double::parseDouble);
|
||||
var unavailable = askDistribution("Unavailable distribution");
|
||||
yield new Distribution.UnavailableTime(probability, unavailable);
|
||||
}
|
||||
case 5 -> {
|
||||
var mean = ask("Mean: ", Double::parseDouble);
|
||||
var stdDev = ask("Standard deviation: ", Double::parseDouble);
|
||||
yield new Distribution.Normal(mean, stdDev);
|
||||
}
|
||||
case 6 -> {
|
||||
var mean = ask("Mean: ", Double::parseDouble);
|
||||
var stdDev = ask("Standard deviation: ", Double::parseDouble);
|
||||
yield new Distribution.NormalBoxMuller(mean, stdDev);
|
||||
}
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the user a question.
|
||||
*
|
||||
* @param ask the question to ask
|
||||
* @return the answer
|
||||
*/
|
||||
private String ask(String ask) {
|
||||
return ask(ask, Function.identity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the user a question.
|
||||
*
|
||||
* @param ask the question to ask
|
||||
* @param parser the parser to use
|
||||
* @param defaultValue the default value
|
||||
* @return the answer
|
||||
*/
|
||||
private <T> T ask(String ask, Function<String, T> parser) {
|
||||
var totalRows = ask.chars().filter(ch -> ch == '\n').count();
|
||||
|
||||
var ask2 = "\033[" + totalRows + "A" + ask;
|
||||
var first = true;
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
this.out.print(first ? ask : ask2);
|
||||
var line = this.scanner.nextLine();
|
||||
first = false;
|
||||
|
||||
try {
|
||||
var value = parser.apply(line);
|
||||
return value;
|
||||
} catch (Exception e) {
|
||||
this.out.print("\033[A\033[K"); // clear the line
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return null; // normally when the scanner is closed
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the user to choose an option.
|
||||
*
|
||||
* @param ask the question to ask
|
||||
* @param options the options to choose from
|
||||
* @return the choice
|
||||
*/
|
||||
private int choose(String ask, String... options) {
|
||||
var builder = new StringBuilder();
|
||||
builder.append(ask).append("\n");
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
builder.append(i + 1).append(". ").append(options[i]).append("\n");
|
||||
}
|
||||
builder.append("> ");
|
||||
|
||||
var string = builder.toString();
|
||||
var choice = 0;
|
||||
choice = ask(string, val -> {
|
||||
var x = Integer.parseInt(val);
|
||||
if (x < 1 || x > options.length)
|
||||
throw new NumberFormatException(); // retry the question
|
||||
return x;
|
||||
});
|
||||
|
||||
return choice;
|
||||
}
|
||||
}
|
||||
@@ -2,98 +2,93 @@ package net.berack.upo.valpre;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import net.sourceforge.argparse4j.ArgumentParsers;
|
||||
import net.sourceforge.argparse4j.impl.Arguments;
|
||||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
if (args.length == 0)
|
||||
exit("No program specified!");
|
||||
private final static String NAME;
|
||||
|
||||
/**
|
||||
* The name of the program, used for the help message.
|
||||
*/
|
||||
static {
|
||||
var name = "valpre";
|
||||
try {
|
||||
var program = args[0];
|
||||
var subArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||
switch (program) {
|
||||
var uri = Main.class.getProtectionDomain().getCodeSource().getLocation().toURI();
|
||||
name = new File(uri).getName();
|
||||
} 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" -> {
|
||||
var param = Main.getParameters(program, subArgs);
|
||||
new SimulationBuilder(param.get("net"))
|
||||
.setCsv(param.get("csv"))
|
||||
.setMaxRuns(param.getOrDefault("runs", Integer::parseInt, 100))
|
||||
.setSeed(param.getOrDefault("seed", Long::parseLong, 0L))
|
||||
.setParallel(param.get("p") != null)
|
||||
.parseEndCriteria(param.get("end"))
|
||||
.parseConfidenceIndices(param.get("i"))
|
||||
new SimulationBuilder(param.getString("net"))
|
||||
.setCsv(param.getString("csv"))
|
||||
.setMaxRuns(param.getInt("runs"))
|
||||
.setSeed(param.getLong("seed"))
|
||||
.setParallel(param.getBoolean("p"))
|
||||
.parseEndCriteria(param.getString("end"))
|
||||
.parseConfidenceIndices(param.getString("indices"))
|
||||
.run();
|
||||
}
|
||||
case "plot" -> {
|
||||
var param = Main.getParameters(program, subArgs);
|
||||
var csv = param.get("csv");
|
||||
var csv = param.getString("csv");
|
||||
var plot = new Plot(csv);
|
||||
plot.show();
|
||||
}
|
||||
case "net" -> {
|
||||
var net = new NetBuilderInteractive();
|
||||
net.run();
|
||||
}
|
||||
default -> exit("Invalid program!");
|
||||
case "interactive" -> new InteractiveConsole().run();
|
||||
default -> throw new RuntimeException("Invalid program!"); // Should never happen
|
||||
}
|
||||
} catch (Exception e) {
|
||||
exit(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|net] [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("net args: none");
|
||||
System.err.println(e.getMessage());
|
||||
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,186 +0,0 @@
|
||||
package net.berack.upo.valpre;
|
||||
|
||||
import java.util.function.Function;
|
||||
import net.berack.upo.valpre.rand.Distribution;
|
||||
import net.berack.upo.valpre.sim.Net;
|
||||
import net.berack.upo.valpre.sim.ServerNode;
|
||||
|
||||
public class NetBuilderInteractive {
|
||||
|
||||
private final Net net = new Net();
|
||||
|
||||
/**
|
||||
* Run the interactive net builder.
|
||||
*
|
||||
* @param args the arguments
|
||||
*/
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
var choice = choose("Choose the next step to do:",
|
||||
"Add a node", "Add a connection", "Print Nodes", "Save the net", "Exit");
|
||||
switch (choice) {
|
||||
case 1 -> {
|
||||
var node = this.buildNode();
|
||||
this.net.addNode(node);
|
||||
}
|
||||
case 2 -> {
|
||||
var source = ask("Enter the source node: ");
|
||||
var target = ask("Enter the target node: ");
|
||||
var weight = ask("Enter the weight: ", Double::parseDouble, 0.0);
|
||||
var sourceNode = this.net.getNode(source);
|
||||
var targetNode = this.net.getNode(target);
|
||||
this.net.addConnection(sourceNode, targetNode, weight);
|
||||
}
|
||||
case 3 -> this.printNodes();
|
||||
case 4 -> this.net.save(ask("Enter the filename: "));
|
||||
case 5 -> System.exit(0);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the nodes in the net.
|
||||
*/
|
||||
private void printNodes() {
|
||||
var builder = new StringBuilder();
|
||||
builder.append("Nodes:\n");
|
||||
for (var i = 0; i < this.net.size(); i++) {
|
||||
var name = this.net.getNode(i).name;
|
||||
builder.append(name).append(" -> ");
|
||||
|
||||
for (var connection : this.net.getChildren(i)) {
|
||||
var child = this.net.getNode(connection.index);
|
||||
builder.append(child.name).append("(").append(connection.weight).append("), ");
|
||||
}
|
||||
|
||||
builder.delete(builder.length() - 2, builder.length());
|
||||
builder.append("\n");
|
||||
}
|
||||
System.out.print(builder.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a node.
|
||||
*
|
||||
* @return the node
|
||||
*/
|
||||
private ServerNode buildNode() {
|
||||
var choice = choose("Choose the type of node to create:", "Source", "Queue");
|
||||
var name = ask("Node name: ");
|
||||
var distribution = askDistribution("Service distribution");
|
||||
|
||||
return switch (choice) {
|
||||
case 1 -> {
|
||||
var limit = ask("Arrivals limit (0 for Int.Max): ", Integer::parseInt, 1);
|
||||
if (limit <= 0)
|
||||
limit = Integer.MAX_VALUE;
|
||||
yield ServerNode.Builder.sourceLimited(name, limit, distribution);
|
||||
}
|
||||
case 2 -> {
|
||||
var servers = ask("Number of servers: ", Integer::parseInt, 1);
|
||||
var unavailable = askDistribution("Unavailable distribution");
|
||||
yield ServerNode.Builder.queue(name, servers, distribution, unavailable);
|
||||
}
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the user for a distribution.
|
||||
*
|
||||
* @return the distribution
|
||||
*/
|
||||
public static Distribution askDistribution(String ask) {
|
||||
var choice = choose(ask + ":", "Exponential", "Uniform", "Erlang",
|
||||
"UnavailableTime", "Normal", "NormalBoxMuller", "None");
|
||||
|
||||
return switch (choice) {
|
||||
case 1 -> {
|
||||
var lambda = ask("Lambda: ", Double::parseDouble, 1.0);
|
||||
yield new Distribution.Exponential(lambda);
|
||||
}
|
||||
case 2 -> {
|
||||
var min = ask("Min: ", Double::parseDouble, 0.0);
|
||||
var max = ask("Max: ", Double::parseDouble, 1.0);
|
||||
yield new Distribution.Uniform(min, max);
|
||||
}
|
||||
case 3 -> {
|
||||
var k = ask("K: ", Integer::parseInt, 1);
|
||||
var lambda = ask("Lambda: ", Double::parseDouble, 1.0);
|
||||
yield new Distribution.Erlang(k, lambda);
|
||||
}
|
||||
case 4 -> {
|
||||
var probability = ask("Probability: ", Double::parseDouble, 0.0);
|
||||
var unavailable = askDistribution("Unavailable distribution");
|
||||
yield new Distribution.UnavailableTime(probability, unavailable);
|
||||
}
|
||||
case 5 -> {
|
||||
var mean = ask("Mean: ", Double::parseDouble, 0.0);
|
||||
var stdDev = ask("Standard deviation: ", Double::parseDouble, 1.0);
|
||||
yield new Distribution.Normal(mean, stdDev);
|
||||
}
|
||||
case 6 -> {
|
||||
var mean = ask("Mean: ", Double::parseDouble, 0.0);
|
||||
var stdDev = ask("Standard deviation: ", Double::parseDouble, 1.0);
|
||||
yield new Distribution.NormalBoxMuller(mean, stdDev);
|
||||
}
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the user a question.
|
||||
*
|
||||
* @param ask the question to ask
|
||||
* @return the answer
|
||||
*/
|
||||
private static String ask(String ask) {
|
||||
return ask(ask, Function.identity(), "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the user a question.
|
||||
*
|
||||
* @param ask the question to ask
|
||||
* @param parser the parser to use
|
||||
* @param defaultValue the default value
|
||||
* @return the answer
|
||||
*/
|
||||
private static <T> T ask(String ask, Function<String, T> parser, T defaultValue) {
|
||||
System.out.print(ask);
|
||||
try {
|
||||
var line = System.console().readLine();
|
||||
return parser.apply(line);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Invalid input: " + e.getMessage());
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the user to choose an option.
|
||||
*
|
||||
* @param ask the question to ask
|
||||
* @param options the options to choose from
|
||||
* @return the choice
|
||||
*/
|
||||
private static int choose(String ask, String... options) {
|
||||
var builder = new StringBuilder();
|
||||
builder.append(ask).append("\n");
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
builder.append(i + 1).append(". ").append(options[i]).append("\n");
|
||||
}
|
||||
builder.append("> ");
|
||||
|
||||
var string = builder.toString();
|
||||
var choice = 0;
|
||||
while (choice < 1 || choice > options.length)
|
||||
choice = ask(string, Integer::parseInt, 0);
|
||||
|
||||
return choice;
|
||||
}
|
||||
}
|
||||
171
src/main/java/net/berack/upo/valpre/NetExamples.java
Normal file
@@ -0,0 +1,171 @@
|
||||
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.sim.Net;
|
||||
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.
|
||||
* The first network is composed of a terminal node and a queue node.
|
||||
* The second network is composed of a terminal node and two queue nodes.
|
||||
*/
|
||||
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.
|
||||
* 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 queue node has a capacity of 1 and a service time of 3.2 with a standard
|
||||
* deviation of 0.6.
|
||||
*
|
||||
* @return the first example network
|
||||
*/
|
||||
public static Net getNet1() {
|
||||
var norm3_2 = new Distribution.NormalBoxMuller(3.2, 0.6);
|
||||
return getNet1(10000, "Queue", norm3_2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first example network.
|
||||
* The net is composed of a terminal node and a 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 name the name of the queue node
|
||||
* @param queue the distribution of the queue node
|
||||
* @return the first example network
|
||||
*/
|
||||
public static Net getNet1(int spawn, String name, Distribution queue) {
|
||||
var source = new Distribution.Exponential(1.0 / 4.5);
|
||||
|
||||
var net1 = new Net();
|
||||
net1.addNode(ServerNode.Builder.terminal("Source", spawn, source));
|
||||
net1.addNode(ServerNode.Builder.queue(name, 1, queue));
|
||||
net1.addConnection(0, 1, 1.0);
|
||||
return net1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the second example network.
|
||||
* The net is composed of a terminal node and two queue nodes.
|
||||
* The terminal node generates 10000 jobs with an exponential distribution 1.5.
|
||||
* The first queue node has a capacity of 1 and a service time of 2.0.
|
||||
* The second queue node has a capacity of 1 and a service time of 3.5.
|
||||
* The second queue node has an unavailable time of 0.1 with an exponential
|
||||
* distribution of 10.0.
|
||||
* The terminal node is connected to the first queue node.
|
||||
* The first queue node is connected to the second queue node.
|
||||
*
|
||||
* @return the second example network
|
||||
*/
|
||||
public static Net getNet2() {
|
||||
var exp3_5 = new Distribution.Exponential(3.5);
|
||||
return getNet2(10000, "Service2", exp3_5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the second example network.
|
||||
* The net is composed of a terminal node and two queue nodes.
|
||||
* The terminal node is connected to the first queue node.
|
||||
* The first queue node is connected to the second queue node.
|
||||
*
|
||||
* @param spawn the number of jobs to generate
|
||||
* @param name the name of the second queue node
|
||||
* @param service2 the distribution of the second queue node
|
||||
* @return the second example network
|
||||
*/
|
||||
public static Net getNet2(int spawn, String name, Distribution service2) {
|
||||
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();
|
||||
net3.addNode(ServerNode.Builder.terminal("Source", spawn, exp1_5));
|
||||
net3.addNode(ServerNode.Builder.queue("Service", 1, exp2));
|
||||
net3.addNode(ServerNode.Builder.queue(name, 1, service2, unExp));
|
||||
net3.addConnection(0, 1, 1.0);
|
||||
net3.addConnection(1, 2, 1.0);
|
||||
return net3;
|
||||
}
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
package net.berack.upo.valpre;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file or the example file if it is present.
|
||||
*
|
||||
* @param file the file to get
|
||||
* @return the file or the example file
|
||||
* @throws FileNotFoundException if the file is not found
|
||||
*/
|
||||
public static InputStream getFileOrExample(String file) throws FileNotFoundException {
|
||||
if (file == null)
|
||||
return null;
|
||||
|
||||
if (file.startsWith("example")) {
|
||||
var resource = Parameters.class.getClassLoader().getResourceAsStream(file);
|
||||
if (resource != null)
|
||||
return resource;
|
||||
}
|
||||
return new FileInputStream(file);
|
||||
}
|
||||
}
|
||||
@@ -41,15 +41,10 @@ public class Plot {
|
||||
* @throws IOException if anything happens while reading the file
|
||||
*/
|
||||
public Plot(String csv) throws IOException {
|
||||
var stream = Parameters.getFileOrExample(csv);
|
||||
if (stream == null)
|
||||
throw new IllegalArgumentException("CSV file needed!");
|
||||
var results = CsvResult.loadResults(stream);
|
||||
stream.close();
|
||||
|
||||
var results = new CsvResult(csv).loadResults();
|
||||
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.nodeComboBox = new JComboBox<>(nodes);
|
||||
@@ -118,7 +113,7 @@ public class Plot {
|
||||
var frame = new JFrame("Graph of the Simulation");
|
||||
frame.add(rootPane);
|
||||
frame.setSize(800, 600);
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
frame.setVisible(true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.berack.upo.valpre;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import com.esotericsoftware.kryo.KryoException;
|
||||
|
||||
@@ -13,6 +14,7 @@ import net.berack.upo.valpre.sim.EndCriteria.MaxTime;
|
||||
import net.berack.upo.valpre.sim.Net;
|
||||
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 is responsible for running the simulation. It parses the arguments
|
||||
@@ -35,10 +37,8 @@ public class SimulationBuilder {
|
||||
*/
|
||||
public SimulationBuilder(String netFile) throws IOException {
|
||||
try {
|
||||
var file = Parameters.getFileOrExample(netFile);
|
||||
this.net = Net.load(file);
|
||||
this.net = Net.load(netFile);
|
||||
this.confidences = new ConfidenceIndices(this.net);
|
||||
file.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new IllegalArgumentException("Net file needed!");
|
||||
} catch (KryoException e) {
|
||||
@@ -230,23 +230,38 @@ public class SimulationBuilder {
|
||||
* @throws ExecutionException If the simulation has an error.
|
||||
* @throws IOException If the CSV file has a problem.
|
||||
*/
|
||||
public void run() throws InterruptedException, ExecutionException, IOException {
|
||||
public Result.Summary run() throws InterruptedException, ExecutionException, IOException {
|
||||
return this.run(System.out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the simulation with the given parameters.
|
||||
* At the end it prints the results and saves them to a CSV file if requested.
|
||||
*
|
||||
* @param out the output stream to print the results
|
||||
* @throws InterruptedException If the simulation is interrupted.
|
||||
* @throws ExecutionException If the simulation has an error.
|
||||
* @throws IOException If the CSV file has a problem.
|
||||
*/
|
||||
public Result.Summary run(PrintStream out) throws InterruptedException, ExecutionException, IOException {
|
||||
var nano = System.nanoTime();
|
||||
var sim = new SimulationMultiple(this.net);
|
||||
var summary = switch (this.type) {
|
||||
case Incremental -> sim.runIncremental(this.seed, this.runs, this.confidences, this.endCriteria);
|
||||
case Incremental -> sim.runIncremental(this.seed, this.runs, out, this.confidences, this.endCriteria);
|
||||
case Parallel -> sim.runParallel(this.seed, this.runs, this.endCriteria);
|
||||
case Normal -> sim.run(this.seed, this.runs, this.endCriteria);
|
||||
};
|
||||
nano = System.nanoTime() - nano;
|
||||
|
||||
System.out.print(summary);
|
||||
System.out.println("Final time " + nano / 1e6 + "ms");
|
||||
out.print(summary);
|
||||
out.println("Final time " + nano / 1e6 + "ms");
|
||||
|
||||
if (csv != null) {
|
||||
new CsvResult(this.csv).saveResults(summary.getRuns());
|
||||
System.out.println("Data saved to " + this.csv);
|
||||
out.println("Data saved to " + this.csv);
|
||||
}
|
||||
|
||||
return summary;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,6 +32,36 @@ public interface Distribution {
|
||||
return sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the distribution.
|
||||
* In case the distribution is null, an empty string is returned.
|
||||
*
|
||||
* @param distribution The distribution to represent.
|
||||
* @return A string representation of the distribution.
|
||||
* @throws IllegalArgumentException if the field cannot be accessed
|
||||
* @throws IllegalAccessException if the field cannot be accessed
|
||||
*/
|
||||
public static String toString(Distribution distribution) throws IllegalArgumentException, IllegalAccessException {
|
||||
if (distribution == null)
|
||||
return "";
|
||||
|
||||
var builder = new StringBuilder();
|
||||
var dist = distribution.getClass();
|
||||
|
||||
builder.append(dist.getSimpleName()).append('(');
|
||||
for (var param : dist.getFields()) {
|
||||
var paramValue = param.get(distribution);
|
||||
var str = paramValue instanceof Distribution
|
||||
? toString((Distribution) paramValue)
|
||||
: paramValue;
|
||||
|
||||
builder.append(str).append(", ");
|
||||
}
|
||||
|
||||
builder.delete(builder.length() - 2, builder.length()).append(')');
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an exponential distribution.
|
||||
*/
|
||||
|
||||
@@ -131,4 +131,13 @@ public class Rng {
|
||||
var t = multiplier * (seed % Q) - R * (seed / Q);
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,11 +23,7 @@ public class Event implements Comparable<Event> {
|
||||
|
||||
@Override
|
||||
public int compareTo(Event other) {
|
||||
if (this.time < other.time)
|
||||
return -1;
|
||||
if (this.time == other.time)
|
||||
return 0;
|
||||
return 1;
|
||||
return Double.compare(this.time, other.time);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,7 +75,6 @@ public final class Net implements Iterable<ServerNode> {
|
||||
* @param weight The probability of the child node.
|
||||
* @throws IndexOutOfBoundsException if one of the two nodes are not in the net
|
||||
* @throws IllegalArgumentException if the weight is negative or zero
|
||||
* @throws IllegalArgumentException if the child is a source node
|
||||
*/
|
||||
public void addConnection(int parent, int child, double weight) {
|
||||
if (weight <= 0)
|
||||
@@ -85,9 +84,6 @@ public final class Net implements Iterable<ServerNode> {
|
||||
if (parent < 0 || child < 0 || parent > max || child > max)
|
||||
throw new IndexOutOfBoundsException("One of the nodes does not exist");
|
||||
|
||||
if (this.servers.get(child).spawnArrivals > 0)
|
||||
throw new IllegalArgumentException("Can't connect to a source node");
|
||||
|
||||
var list = this.connections.get(parent);
|
||||
list.removeIf(conn -> conn.index == child);
|
||||
list.add(new Connection(child, weight));
|
||||
@@ -170,14 +166,13 @@ public final class Net implements Iterable<ServerNode> {
|
||||
for (var conn : list)
|
||||
sum += conn.weight;
|
||||
|
||||
var newOne = new Connection[list.size()];
|
||||
for (var i = 0; i < list.size(); i++) {
|
||||
var conn = list.get(i);
|
||||
var newOne = new ArrayList<Connection>();
|
||||
for (var conn : list) {
|
||||
var newWeight = conn.weight / sum;
|
||||
newOne[i] = new Connection(conn.index, newWeight);
|
||||
newOne.add(new Connection(conn.index, newWeight));
|
||||
}
|
||||
|
||||
this.connections.set(node, List.of(newOne));
|
||||
this.connections.set(node, newOne);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,6 +244,56 @@ public final class Net implements Iterable<ServerNode> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of the net passed as input.
|
||||
* The new net will have the same nodes and connections.
|
||||
*
|
||||
* @param net the net to copy
|
||||
* @return a new Net object
|
||||
*/
|
||||
public static Net copyOf(Net net) {
|
||||
var newNet = new Net();
|
||||
|
||||
for (var index = 0; index < net.size(); index++) {
|
||||
var node = net.servers.get(index);
|
||||
var conn = net.connections.get(index);
|
||||
conn = new ArrayList<>(conn);
|
||||
|
||||
newNet.indices.put(node, index);
|
||||
newNet.servers.add(node);
|
||||
newNet.connections.add(conn);
|
||||
}
|
||||
|
||||
return newNet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
var builder = new StringBuilder();
|
||||
try {
|
||||
for (var node : this.servers) {
|
||||
builder.append(node)
|
||||
.append(" -> ");
|
||||
|
||||
for (var child : this.getChildren(this.indices.get(node))) {
|
||||
var childNode = this.servers.get(child.index);
|
||||
builder.append(childNode.name)
|
||||
.append("(")
|
||||
.append(child.weight)
|
||||
.append("), ");
|
||||
}
|
||||
|
||||
builder.delete(builder.length() - 2, builder.length())
|
||||
.append("\n");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A Static inner class used to represent the connection of a node
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,7 @@ public class ServerNode {
|
||||
/**
|
||||
* Creates a generic node with the given name and distribution.
|
||||
* The servers number must be 1 or higher; if lower will be put to 1.
|
||||
* The spawn number must be 0 or higher; if lower will be put to 0.
|
||||
* The spawn number must be 0 or higher; if lower will be put to -1 (infinite).
|
||||
* The queue number must be equal or higher than the servers number; if lower
|
||||
* will be put to the servers number.
|
||||
* The service distribution can't be null, otherwise an exception is thrown.
|
||||
@@ -37,7 +37,7 @@ public class ServerNode {
|
||||
if (servers <= 0)
|
||||
servers = 1;
|
||||
if (spawn < 0)
|
||||
spawn = 0;
|
||||
spawn = -1;
|
||||
if (queue < servers)
|
||||
queue = servers;
|
||||
|
||||
@@ -71,6 +71,28 @@ public class ServerNode {
|
||||
return Distribution.getPositiveSample(this.unavailable, rng);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
var build = new StringBuilder()
|
||||
.append(this.name)
|
||||
.append("[servers:")
|
||||
.append(this.maxServers)
|
||||
.append(", queue:")
|
||||
.append(this.maxQueue)
|
||||
.append(", spawn:")
|
||||
.append(this.spawnArrivals)
|
||||
.append(", ")
|
||||
.append(Distribution.toString(this.service));
|
||||
if (this.unavailable != null)
|
||||
build.append(", u:").append(Distribution.toString(this.unavailable));
|
||||
return build.append(']').toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof ServerNode))
|
||||
@@ -183,26 +205,27 @@ public class ServerNode {
|
||||
|
||||
/**
|
||||
* Creates a source node with the given name and distribution.
|
||||
* It swpawns infinite arrivals (Integer.MAX_VALUE).
|
||||
* It swpawns infinite arrivals (-1).
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param distribution The distribution of the inter-arrival times.
|
||||
* @return The created source node.
|
||||
*/
|
||||
public static ServerNode source(String name, Distribution distribution) {
|
||||
return new Builder(name, distribution).spawn(Integer.MAX_VALUE).build();
|
||||
return new Builder(name, distribution).spawn(-1).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a source node with the given name, distribution, and number of
|
||||
* Creates a terminal node with the given name, distribution, and number of
|
||||
* arrivals to spawn.
|
||||
* Once it has finished spawning the arrivals, it will not spawn anymore.
|
||||
*
|
||||
* @param name The name of the node.
|
||||
* @param service The distribution of the inter-arrival times.
|
||||
* @param spawnArrivals The number of arrivals to spawn.
|
||||
* @return The created source node.
|
||||
*/
|
||||
public static ServerNode sourceLimited(String name, int spawnArrivals, Distribution service) {
|
||||
public static ServerNode terminal(String name, int spawnArrivals, Distribution service) {
|
||||
return new Builder(name, service).spawn(spawnArrivals).build();
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ public class ServerNodeState {
|
||||
* @return True if the node should spawn an arrival, false otherwise.
|
||||
*/
|
||||
public boolean shouldSpawnArrival() {
|
||||
return this.node.spawnArrivals > this.stats.numArrivals;
|
||||
return this.node.spawnArrivals < 0 || this.node.spawnArrivals > this.stats.numArrivals;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,6 +158,23 @@ public class ServerNodeState {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random child based on the weights of the children and the random number
|
||||
* generator passed as input
|
||||
*
|
||||
* @param rng the random number generator
|
||||
* @return the index of the child or -1 if no child is selected
|
||||
*/
|
||||
public int getRandomChild(Rng rng) {
|
||||
var random = rng.random();
|
||||
for (var child : this.children) {
|
||||
random -= child.weight;
|
||||
if (random <= 0)
|
||||
return child.index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an arrival event to a child node based on the node and the time passed
|
||||
* as input
|
||||
@@ -168,12 +185,7 @@ public class ServerNodeState {
|
||||
* otherwise
|
||||
*/
|
||||
public Event spawnArrivalToChild(double time, Rng rng) {
|
||||
var random = rng.random();
|
||||
for (var child : this.children) {
|
||||
random -= child.weight;
|
||||
if (random <= 0)
|
||||
return Event.newArrival(child.index, time);
|
||||
}
|
||||
return null;
|
||||
var child = this.getRandomChild(rng);
|
||||
return child > -1 ? Event.newArrival(child, time) : null;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package net.berack.upo.valpre.sim;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
@@ -98,8 +97,13 @@ public final class Simulation {
|
||||
case DEPARTURE -> {
|
||||
state.updateDeparture(time);
|
||||
|
||||
// Spawn unavailability if has unavailable time
|
||||
this.addToFel(state.spawnUnavailableIfPossible(time, this.rng));
|
||||
|
||||
// Spawn departure if has requests and server is available
|
||||
this.addToFel(state.spawnDepartureIfPossible(time, this.rng));
|
||||
|
||||
// Spawn arrival to self if is source node
|
||||
this.addToFel(state.spawnArrivalIfPossilbe(time));
|
||||
|
||||
// Spawn arrival to child node if queue is not full otherwise drop
|
||||
@@ -151,7 +155,7 @@ public final class Simulation {
|
||||
* @return a list of future events.
|
||||
*/
|
||||
public List<Event> getFutureEventList() {
|
||||
return new ArrayList<>(this.fel);
|
||||
return List.copyOf(this.fel);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.berack.upo.valpre.sim;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executors;
|
||||
@@ -99,16 +100,21 @@ public class SimulationMultiple {
|
||||
* Run the simulation multiple times with the given seed and end criteria. The
|
||||
* simulation runs will stop when the relative error of the confidence index is
|
||||
* less than the given value.
|
||||
* The results are printed on the console.
|
||||
* The results are printed on the PrintStream.
|
||||
*
|
||||
* @param seed The seed to use for the random number generator.
|
||||
* @param criterias The criteria to determine when to end the simulation. If
|
||||
* null then the simulation will run until there are no more
|
||||
* events.
|
||||
* @param seed The seed to use for the random number generator.
|
||||
* @param runs The maximum number of runs to perform.
|
||||
* @param stream The PrintStream to print the results.
|
||||
* @param confidences The confidence indices to use to determine when to stop
|
||||
* the simulation.
|
||||
* @param criterias The criteria to determine when to end the simulation. If
|
||||
* null then the simulation will run until there are no more
|
||||
* events.
|
||||
* @return The statistics the network.
|
||||
* @throws IllegalArgumentException If the confidence is not set.
|
||||
*/
|
||||
public Result.Summary runIncremental(long seed, int runs, ConfidenceIndices confidences, EndCriteria... criterias) {
|
||||
public Result.Summary runIncremental(long seed, int runs, PrintStream stream, ConfidenceIndices confidences,
|
||||
EndCriteria... criterias) {
|
||||
if (confidences == null)
|
||||
throw new IllegalArgumentException("Confidence must be not null");
|
||||
|
||||
@@ -116,7 +122,8 @@ public class SimulationMultiple {
|
||||
var results = new Result.Summary(rng.getSeed(), nodes);
|
||||
var output = new StringBuilder();
|
||||
var stop = false;
|
||||
for (int i = 0; !stop; i++) {
|
||||
|
||||
for (int i = 0; !stop && runs > i; i++) {
|
||||
var sim = new Simulation(this.net, rng, criterias);
|
||||
var result = sim.run();
|
||||
results.add(result);
|
||||
@@ -132,12 +139,11 @@ public class SimulationMultiple {
|
||||
var oneSting = String.join("], [", errString);
|
||||
|
||||
output.append('[').append(oneSting).append("]");
|
||||
System.out.print(output);
|
||||
stream.print(output);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(); // remove last printed line
|
||||
stream.println(); // remove last printed line
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,13 +21,27 @@ public class ConsoleTable {
|
||||
* @throws NullPointerException if the array is null
|
||||
*/
|
||||
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)
|
||||
max = Math.max(max, name.length());
|
||||
|
||||
this.columns = header.length;
|
||||
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.addRow(header);
|
||||
}
|
||||
@@ -45,11 +59,11 @@ public class ConsoleTable {
|
||||
|
||||
for (var val : values) {
|
||||
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(" ".repeat(first));
|
||||
builder.append(val);
|
||||
builder.append(" ".repeat(diff - first));
|
||||
builder.append(" ".repeat(Math.max(diff - first, 0)));
|
||||
}
|
||||
|
||||
builder.append("║\n");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.berack.upo.valpre.sim.stats;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -36,6 +37,11 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
||||
this.stats = stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stats of a node.
|
||||
*
|
||||
* @return the stats of a node
|
||||
*/
|
||||
public NodeStats getStat(String node) {
|
||||
for (var i = 0; i < this.nodes.length; i++)
|
||||
if (this.nodes[i].equals(node))
|
||||
@@ -45,7 +51,7 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
||||
|
||||
@Override
|
||||
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
|
||||
@@ -80,9 +86,8 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
||||
* @param stats the stats of each node
|
||||
* @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 iFormat = "%" + size + ".0f";
|
||||
var fFormat = "%" + (size + 4) + ".3f";
|
||||
|
||||
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("Simulation: \t" + fFormat + "\n", simTime));
|
||||
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++) {
|
||||
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
|
||||
*/
|
||||
public List<String> getNodes() {
|
||||
return List.of(this.nodes);
|
||||
public String[] getNodes() {
|
||||
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
|
||||
public String toString() {
|
||||
var stats = new NodeStats[this.nodes.length];
|
||||
for (var i = 0; i < this.nodes.length; i++)
|
||||
stats[i] = this.stats[i].average;
|
||||
|
||||
return buildPrintable(this.seed, this.avgSimulationTime, this.avgTimeElapsedMS, this.nodes, stats);
|
||||
return getResultString(this.seed, this.avgSimulationTime, this.avgTimeElapsedMS, this.nodes,
|
||||
this.getStats());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,4 +55,23 @@ public class TestRandom {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
187
src/test/java/net/berack/upo/valpre/sim/TestInteractions.java
Normal file
@@ -0,0 +1,187 @@
|
||||
package net.berack.upo.valpre.sim;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import net.berack.upo.valpre.InteractiveConsole;
|
||||
import net.berack.upo.valpre.rand.Distribution;
|
||||
|
||||
public class TestInteractions {
|
||||
|
||||
@Test
|
||||
public void distributionToString() throws Exception {
|
||||
var exp = new Distribution.Exponential(1.0);
|
||||
assertEquals("Exponential(1.0)", Distribution.toString(exp));
|
||||
|
||||
var uniform = new Distribution.Uniform(0.0, 1.0);
|
||||
assertEquals("Uniform(0.0, 1.0)", Distribution.toString(uniform));
|
||||
|
||||
var erlang = new Distribution.Erlang(2, 1.0);
|
||||
assertEquals("Erlang(2, 1.0)", Distribution.toString(erlang));
|
||||
|
||||
var normal = new Distribution.Normal(3.2, 0.6);
|
||||
assertEquals("Normal(3.2, 0.6)", Distribution.toString(normal));
|
||||
|
||||
var normalBoxMuller = new Distribution.NormalBoxMuller(3.2, 0.6);
|
||||
assertEquals("NormalBoxMuller(3.2, 0.6)", Distribution.toString(normalBoxMuller));
|
||||
|
||||
var unavailable = new Distribution.UnavailableTime(0.1, exp);
|
||||
assertEquals("UnavailableTime(0.1, Exponential(1.0))", Distribution.toString(unavailable));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nodeToString() {
|
||||
var exp = new Distribution.Exponential(1.0);
|
||||
var normal = new Distribution.Normal(3.2, 0.6);
|
||||
var unavailable = new Distribution.UnavailableTime(0.1, exp);
|
||||
|
||||
var node = new ServerNode.Builder("Source", exp).build();
|
||||
assertEquals("Source[servers:1, queue:100, spawn:0, Exponential(1.0)]", node.toString());
|
||||
|
||||
node = new ServerNode.Builder("Queue", normal).build();
|
||||
assertEquals("Queue[servers:1, queue:100, spawn:0, Normal(3.2, 0.6)]", node.toString());
|
||||
|
||||
node = new ServerNode.Builder("Queue", normal).queue(10).servers(5).spawn(100).build();
|
||||
assertEquals("Queue[servers:5, queue:10, spawn:100, Normal(3.2, 0.6)]", node.toString());
|
||||
|
||||
node = new ServerNode.Builder("Queue", normal).queue(10).servers(5).spawn(100).unavailable(unavailable).build();
|
||||
assertEquals(
|
||||
"Queue[servers:5, queue:10, spawn:100, Normal(3.2, 0.6), u:UnavailableTime(0.1, Exponential(1.0))]",
|
||||
node.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void netToString() {
|
||||
var net = new Net();
|
||||
assertEquals("", net.toString());
|
||||
|
||||
var node1 = new ServerNode.Builder("Source", new Distribution.Exponential(1)).build();
|
||||
net.addNode(node1);
|
||||
assertEquals(node1 + " -\n", net.toString());
|
||||
|
||||
var node2 = new ServerNode.Builder("Server", new Distribution.Normal(3.2, 0.6)).build();
|
||||
net.addNode(node2);
|
||||
assertEquals(node1 + " -\n" + node2 + " -\n", net.toString());
|
||||
|
||||
net.addConnection(0, 1, 1.0);
|
||||
assertEquals(node1 + " -> Server(1.0)\n" + node2 + " -\n", net.toString());
|
||||
|
||||
var node3 = new ServerNode.Builder("Server2", new Distribution.Normal(4.1, 0.1)).build();
|
||||
net.addNode(node3);
|
||||
assertEquals(node1 + " -> Server(1.0)\n" + node2 + " -\n" + node3 + " -\n", net.toString());
|
||||
|
||||
net.addConnection(0, 2, 1.0);
|
||||
net.normalizeWeights();
|
||||
assertEquals(node1 + " -> Server(0.5), Server2(0.5)\n" + node2 + " -\n" + node3 + " -\n", net.toString());
|
||||
|
||||
net.addConnection(1, 2, 1.0);
|
||||
assertEquals(node1 + " -> Server(0.5), Server2(0.5)\n"
|
||||
+ node2 + " -> Server2(1.0)\n"
|
||||
+ node3 + " -\n",
|
||||
net.toString());
|
||||
|
||||
var const0 = new Distribution.Uniform(0, 0);
|
||||
var unavailable = new Distribution.UnavailableTime(0.1, new Distribution.Exponential(1));
|
||||
var other = ServerNode.Builder.queue("Other", 1, const0, unavailable);
|
||||
net.addNode(other);
|
||||
assertEquals(node1 + " -> Server(0.5), Server2(0.5)\n"
|
||||
+ node2 + " -> Server2(1.0)\n"
|
||||
+ node3 + " -\n"
|
||||
+ other + " -\n",
|
||||
net.toString());
|
||||
}
|
||||
|
||||
@Test(timeout = 1000)
|
||||
public void netBuilderInteractive() {
|
||||
|
||||
// Test the interactive console EXIT
|
||||
var net = runInteraction("7");
|
||||
assertEquals("", net.toString());
|
||||
|
||||
// Test the interactive console ADD NODE
|
||||
net = runInteraction("1", "1", "Source", "1", "1.0", "7");
|
||||
assertEquals("Source[servers:1, queue:100, spawn:-1, Exponential(1.0)] -\n", net.toString());
|
||||
|
||||
// Test the interactive console ADD SECOND NODE
|
||||
net = runInteraction("1", "2", "Terminal", "1", "2.0", "500",
|
||||
"1", "3", "Queue", "5", "3.2", "0.6", "1",
|
||||
"7");
|
||||
assertEquals("Terminal[servers:1, queue:100, spawn:500, Exponential(2.0)] -\n"
|
||||
+ "Queue[servers:1, queue:100, spawn:0, Normal(3.2, 0.6)] -\n", net.toString());
|
||||
|
||||
// Test the interactive console ADD CONNECTION
|
||||
net = runInteraction("1", "1", "Source", "1", "2.0",
|
||||
"1", "3", "Queue", "5", "3.2", "0.6", "1",
|
||||
"2", "Source", "Queue", "1.0",
|
||||
"7");
|
||||
assertEquals("Source[servers:1, queue:100, spawn:-1, Exponential(2.0)] -> Queue(1.0)\n"
|
||||
+ "Queue[servers:1, queue:100, spawn:0, Normal(3.2, 0.6)] -\n", net.toString());
|
||||
|
||||
// Test the interactive console CLEAR
|
||||
net = runInteraction("1", "1", "Source", "1", "2.0",
|
||||
"1", "3", "Queue", "5", "3.2", "0.6", "1",
|
||||
"2", "Source", "Queue", "1.0",
|
||||
"2", "Queue", "Queue", "1.0",
|
||||
"5", "7");
|
||||
assertEquals("", net.toString());
|
||||
|
||||
// Test the interactive console LOAD
|
||||
net = runInteraction("4", "1", "src/test/resources/example1.net", "7");
|
||||
assertEquals("Source[servers:1, queue:100, spawn:10000, Exponential(0.2222222222222222)] -> Queue(1.0)\n"
|
||||
+ "Queue[servers:1, queue:100, spawn:0, NormalBoxMuller(3.2, 0.6)] -\n",
|
||||
net.toString());
|
||||
|
||||
// Test the interactive console LOAD EXAMPLE 1
|
||||
net = runInteraction("4", "2", "1", "7");
|
||||
assertEquals("Source[servers:1, queue:100, spawn:10000, Exponential(0.2222222222222222)] -> Queue(1.0)\n"
|
||||
+ "Queue[servers:1, queue:100, spawn:0, NormalBoxMuller(3.2, 0.6)] -\n",
|
||||
net.toString());
|
||||
|
||||
// Test the interactive console LOAD EXAMPLE 2
|
||||
net = runInteraction("4", "2", "2", "7");
|
||||
assertEquals("Source[servers:1, queue:100, spawn:10000, Exponential(1.5)] -> Service(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",
|
||||
net.toString());
|
||||
}
|
||||
|
||||
private static Net runInteraction(String... commands) {
|
||||
var out = new PrintStream(OutputStream.nullOutputStream());
|
||||
var inputs = String.join("\n", commands);
|
||||
var bytes = inputs.getBytes();
|
||||
var in = new ByteArrayInputStream(bytes);
|
||||
return new InteractiveConsole(out, in).run();
|
||||
}
|
||||
|
||||
/*
|
||||
* An interaction example is like this:
|
||||
* 1. Add a node
|
||||
* - Choose the type of node to create:
|
||||
* - 1. Source
|
||||
* - 2. Queue
|
||||
* - 3. Queue with unavailable time
|
||||
* - Node name: Name
|
||||
* - Arrivals limit (0 for Int.Max) / Number of servers: 1
|
||||
* - Choose the type of service distribution:
|
||||
* - - 1. Exponential
|
||||
* - - 2. Uniform
|
||||
* - - 3. Erlang
|
||||
* - - 4. UnavailableTime
|
||||
* - - 5. Normal
|
||||
* - - 6. NormalBoxMuller
|
||||
* - - 7. None
|
||||
* 2. Add a connection
|
||||
* - Enter the source node: Source
|
||||
* - Enter the target node: Queue
|
||||
* - Enter the weight: 1.0
|
||||
* 3. Save the net
|
||||
* 4. Load net
|
||||
* 5. Clear
|
||||
* 6. Exit
|
||||
*/
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashSet;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
@@ -11,61 +13,26 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
import com.esotericsoftware.kryo.KryoException;
|
||||
|
||||
import net.berack.upo.valpre.NetExamples;
|
||||
import net.berack.upo.valpre.SimulationBuilder;
|
||||
import net.berack.upo.valpre.rand.Distribution;
|
||||
import net.berack.upo.valpre.rand.Rng;
|
||||
import net.berack.upo.valpre.sim.stats.CsvResult;
|
||||
import net.berack.upo.valpre.sim.stats.NodeStats;
|
||||
|
||||
public class TestSaveExamplesNet {
|
||||
|
||||
private static final Distribution exp0_22 = new Distribution.Exponential(1.0 / 4.5);
|
||||
private static final Distribution exp2 = new Distribution.Exponential(2.0);
|
||||
private static final Distribution exp1_5 = new Distribution.Exponential(1.5);
|
||||
private static final Distribution exp3_5 = new Distribution.Exponential(3.5);
|
||||
private static final Distribution exp10 = new Distribution.Exponential(10.0);
|
||||
|
||||
private static final Distribution norm3_2 = new Distribution.NormalBoxMuller(3.2, 0.6);
|
||||
private static final Distribution norm4_2 = new Distribution.NormalBoxMuller(4.2, 0.6);
|
||||
|
||||
private static final Distribution unNorm = new Distribution.UnavailableTime(0.2, norm4_2);
|
||||
private static final Distribution unExp = new Distribution.UnavailableTime(0.1, exp10);
|
||||
|
||||
private static final int spawn = 10000;
|
||||
private static final String path = "src/main/resources/example%d.%s";
|
||||
private static final String path = "src/test/resources/example%d.%s";
|
||||
private static final String netFile1 = path.formatted(1, "net");
|
||||
private static final String netFile2 = path.formatted(2, "net");
|
||||
private static final String netFile3 = path.formatted(3, "net");
|
||||
private static final String csv1 = path.formatted(1, "csv");
|
||||
private static final String csv2 = path.formatted(2, "csv");
|
||||
private static final String csv3 = path.formatted(3, "csv");
|
||||
|
||||
private static final Net net1 = new Net();
|
||||
private static final Net net2 = new Net();
|
||||
private static final Net net3 = new Net();
|
||||
static {
|
||||
net1.addNode(ServerNode.Builder.sourceLimited("Source", spawn, exp0_22));
|
||||
net1.addNode(ServerNode.Builder.queue("Queue", 1, norm3_2));
|
||||
net1.addConnection(0, 1, 1.0);
|
||||
|
||||
net2.addNode(ServerNode.Builder.sourceLimited("Source", spawn, exp0_22));
|
||||
net2.addNode(ServerNode.Builder.queue("Queue", 1, norm3_2));
|
||||
net2.addNode(ServerNode.Builder.queue("Queue Wait", 1, norm3_2, unNorm));
|
||||
net2.addConnection(0, 1, 1.0);
|
||||
net2.addConnection(1, 2, 1.0);
|
||||
|
||||
net3.addNode(ServerNode.Builder.sourceLimited("Source", spawn, exp1_5));
|
||||
net3.addNode(ServerNode.Builder.queue("Service1", 1, exp2));
|
||||
net3.addNode(ServerNode.Builder.queue("Service2", 1, exp3_5, unExp));
|
||||
net3.addConnection(0, 1, 1.0);
|
||||
net3.addConnection(1, 2, 1.0);
|
||||
}
|
||||
private static final Net net1 = NetExamples.getNet1();
|
||||
private static final Net net2 = NetExamples.getNet2();
|
||||
|
||||
@BeforeAll
|
||||
public void saveAll() throws IOException {
|
||||
net1.save(netFile1);
|
||||
net2.save(netFile2);
|
||||
net3.save(netFile3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -85,20 +52,6 @@ public class TestSaveExamplesNet {
|
||||
public void loadExample2() throws KryoException, IOException {
|
||||
var sim = new Simulation(Net.load(netFile2), new Rng());
|
||||
var res = sim.run();
|
||||
var time = 45417.0;
|
||||
var maxErr = time / 1000.0;
|
||||
|
||||
assertEquals(Rng.DEFAULT, res.seed);
|
||||
assertEquals(time, res.simulationTime, maxErr);
|
||||
testNode(res.getStat("Source"), 10000, time, 1.0, 4.5, 0.0, 0.0);
|
||||
testNode(res.getStat("Queue"), 10000, time, 2.6, 7.2, 4.0, 0.0);
|
||||
testNode(res.getStat("Queue Wait"), 10000, time, 5.8, 22.3, 19.1, 8497.7);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadExample3() throws KryoException, IOException {
|
||||
var sim = new Simulation(Net.load(netFile3), new Rng());
|
||||
var res = sim.run();
|
||||
var time = 6736.0;
|
||||
var maxErr = time / 1000.0;
|
||||
|
||||
@@ -153,33 +106,26 @@ public class TestSaveExamplesNet {
|
||||
@Test
|
||||
@AfterAll
|
||||
public void multiSimulation1() throws Exception {
|
||||
new SimulationBuilder(net1)
|
||||
.setCsv(csv1)
|
||||
.setMaxRuns(1000)
|
||||
.setSeed(2007539552L)
|
||||
.setParallel(true)
|
||||
.run();
|
||||
try (var newOut = new PrintStream(OutputStream.nullOutputStream())) {
|
||||
new SimulationBuilder(net1)
|
||||
.setCsv(csv1)
|
||||
.setMaxRuns(1000)
|
||||
.setSeed(2007539552L)
|
||||
.setParallel(true)
|
||||
.run(newOut);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@AfterAll
|
||||
public void multiSimulation2() throws Exception {
|
||||
new SimulationBuilder(net2)
|
||||
.setCsv(csv2)
|
||||
.setMaxRuns(1000)
|
||||
.setSeed(2007539552L)
|
||||
.setParallel(true)
|
||||
.run();
|
||||
}
|
||||
|
||||
@Test
|
||||
@AfterAll
|
||||
public void multiSimulation3() throws Exception {
|
||||
new SimulationBuilder(net3)
|
||||
.setCsv(csv3)
|
||||
.setMaxRuns(1000)
|
||||
.setSeed(2007539552L)
|
||||
.setParallel(true)
|
||||
.run();
|
||||
try (var newOut = new PrintStream(OutputStream.nullOutputStream())) {
|
||||
new SimulationBuilder(net2)
|
||||
.setCsv(csv2)
|
||||
.setMaxRuns(1000)
|
||||
.setSeed(2007539552L)
|
||||
.setParallel(true)
|
||||
.run(newOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
@@ -23,7 +24,7 @@ public class TestSimulation {
|
||||
private static final ServerNode node0;
|
||||
private static final ServerNode node1;
|
||||
static {
|
||||
node0 = ServerNode.Builder.sourceLimited("First", 0, const1);
|
||||
node0 = ServerNode.Builder.terminal("First", 0, const1);
|
||||
node1 = ServerNode.Builder.queue("Second", 1, const1);
|
||||
|
||||
simpleNet = new Net();
|
||||
@@ -56,10 +57,10 @@ public class TestSimulation {
|
||||
node = ServerNode.Builder.source("Source", const1);
|
||||
assertEquals("Source", node.name);
|
||||
assertEquals(1, node.maxServers);
|
||||
assertEquals(Integer.MAX_VALUE, node.spawnArrivals);
|
||||
assertEquals(-1, node.spawnArrivals);
|
||||
assertEquals(1.0, node.getServiceTime(null), DELTA);
|
||||
|
||||
node = ServerNode.Builder.sourceLimited("Source", 50, const1);
|
||||
node = ServerNode.Builder.terminal("Source", 50, const1);
|
||||
assertEquals("Source", node.name);
|
||||
assertEquals(1, node.maxServers);
|
||||
assertEquals(50, node.spawnArrivals);
|
||||
@@ -196,7 +197,7 @@ public class TestSimulation {
|
||||
@Test
|
||||
public void nodeStatsUpdates() {
|
||||
var net = new Net();
|
||||
net.addNode(ServerNode.Builder.sourceLimited("Source", 50, const1));
|
||||
net.addNode(ServerNode.Builder.terminal("Source", 50, const1));
|
||||
net.addNode(node1);
|
||||
net.addConnection(0, 1, 1.0);
|
||||
|
||||
@@ -393,13 +394,23 @@ public class TestSimulation {
|
||||
|
||||
@Test
|
||||
public void simulation() {
|
||||
var start = System.nanoTime();
|
||||
assertThrows(NullPointerException.class, () -> new Simulation(null, rigged));
|
||||
assertThrows(NullPointerException.class, () -> new Simulation(simpleNet, null));
|
||||
|
||||
var sim = new Simulation(simpleNet, rigged);
|
||||
assertTrue(sim.hasEnded());
|
||||
assertEquals(0, sim.getEventsProcessed());
|
||||
assertEquals(0.0, sim.getTime(), DELTA);
|
||||
var fel = sim.getFutureEventList();
|
||||
assertEquals(0, fel.size());
|
||||
|
||||
var start = System.nanoTime();
|
||||
sim = new Simulation(simpleNet, rigged);
|
||||
// knowing that it takes time to allocate the object
|
||||
// we can use the average time
|
||||
var endAllocation = System.nanoTime();
|
||||
var time = (endAllocation + start) / 2;
|
||||
var diff = 0.5e-6 * (endAllocation - start); // getting the error margin in ms
|
||||
var diff = 1e-6 * (endAllocation - start); // getting the error margin in ms
|
||||
|
||||
assertTrue(sim.hasEnded());
|
||||
assertEquals(0, sim.getEventsProcessed());
|
||||
@@ -410,7 +421,7 @@ public class TestSimulation {
|
||||
assertEquals(0, sim.getNodeState(node0.name).numServerUnavailable);
|
||||
assertEquals(0, sim.getNodeState(node1.name).numServerBusy);
|
||||
assertEquals(0, sim.getNodeState(node1.name).numServerUnavailable);
|
||||
var fel = sim.getFutureEventList();
|
||||
fel = sim.getFutureEventList();
|
||||
assertEquals(0, fel.size());
|
||||
|
||||
sim.addToFel(Event.newArrival(0, sim.getTime()));
|
||||
@@ -489,6 +500,8 @@ public class TestSimulation {
|
||||
assertEquals(0, sim.getNodeState(node1.name).numServerUnavailable);
|
||||
fel = sim.getFutureEventList();
|
||||
assertEquals(0, fel.size());
|
||||
final var s = sim;
|
||||
assertThrows(NullPointerException.class, () -> s.processNextEvent());
|
||||
|
||||
var elapsed = (double) (System.nanoTime() - time);
|
||||
var result = sim.endSimulation();
|
||||
@@ -529,7 +542,7 @@ public class TestSimulation {
|
||||
@Test
|
||||
public void simulationStats() {
|
||||
var net = new Net();
|
||||
net.addNode(ServerNode.Builder.sourceLimited("Source", 50, const1));
|
||||
net.addNode(ServerNode.Builder.terminal("Source", 50, const1));
|
||||
|
||||
var sim = new Simulation(net, rigged);
|
||||
var result = sim.run();
|
||||
@@ -581,7 +594,7 @@ public class TestSimulation {
|
||||
@Test
|
||||
public void simulationDrop() {
|
||||
var net = new Net();
|
||||
net.addNode(ServerNode.Builder.sourceLimited("Source", 50, const1));
|
||||
net.addNode(ServerNode.Builder.terminal("Source", 50, const1));
|
||||
net.addNode(new ServerNode.Builder("Queue", _ -> 2.0).queue(20).build());
|
||||
net.addConnection(0, 1, 1.0);
|
||||
|
||||
|
||||
146
src/test/resources/example1.jsimg
Normal file
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
|
||||
<archive xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="example1.jsimg" timestamp="Thu Mar 13 11:14:34 CET 2025" xsi:noNamespaceSchemaLocation="Archive.xsd">
|
||||
<sim disableStatisticStop="false" logDecimalSeparator="," logDelimiter=";" logPath="C:\Users\giaco\JMT\" logReplaceMode="0" maxEvents="-1" maxSamples="1000000" name="example1.jsimg" polling="1.0" xsi:noNamespaceSchemaLocation="SIMmodeldefinition.xsd">
|
||||
<userClass name="Class1" priority="0" referenceSource="Source " softDeadline="0.0" type="open"/>
|
||||
<node name="Source ">
|
||||
<section className="RandomSource">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.ServiceStrategy" name="ServiceStrategy">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.ServiceStrategies.ServiceTimeStrategy" name="ServiceTimeStrategy">
|
||||
<subParameter classPath="jmt.engine.random.Exponential" name="Exponential"/>
|
||||
<subParameter classPath="jmt.engine.random.ExponentialPar" name="distrPar">
|
||||
<subParameter classPath="java.lang.Double" name="lambda">
|
||||
<value>0.2222222222222222</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="ServiceTunnel"/>
|
||||
<section className="Router">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.RoutingStrategy" name="RoutingStrategy">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.RoutingStrategies.RandomStrategy" name="Random"/>
|
||||
</parameter>
|
||||
</section>
|
||||
</node>
|
||||
<node name="Sink">
|
||||
<section className="JobSink"/>
|
||||
</node>
|
||||
<node name="Queue">
|
||||
<classSoftDeadlines>
|
||||
<softDeadline>0.0</softDeadline>
|
||||
</classSoftDeadlines>
|
||||
<quantumSize>
|
||||
<quantaSize>0.0</quantaSize>
|
||||
</quantumSize>
|
||||
<quantumSwitchoverTime>
|
||||
<quantumSwitchoverTime>0.0</quantumSwitchoverTime>
|
||||
</quantumSwitchoverTime>
|
||||
<section className="Queue">
|
||||
<parameter classPath="java.lang.Integer" name="size">
|
||||
<value>-1</value>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.String" name="dropStrategies">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropStrategy">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter classPath="jmt.engine.NetStrategies.QueueGetStrategies.FCFSstrategy" name="FCFSstrategy"/>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.QueuePutStrategy" name="QueuePutStrategy">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="TailStrategy"/>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Server">
|
||||
<parameter classPath="java.lang.Integer" name="maxJobs">
|
||||
<value>1</value>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="numberOfVisits">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="numberOfVisits">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.ServiceStrategy" name="ServiceStrategy">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.ServiceStrategies.ServiceTimeStrategy" name="ServiceTimeStrategy">
|
||||
<subParameter classPath="jmt.engine.random.Normal" name="Normal"/>
|
||||
<subParameter classPath="jmt.engine.random.NormalPar" name="distrPar">
|
||||
<subParameter classPath="java.lang.Double" name="mean">
|
||||
<value>3.2</value>
|
||||
</subParameter>
|
||||
<subParameter classPath="java.lang.Double" name="standardDeviation">
|
||||
<value>0.6000000000000001</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="classParallelism">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="serverParallelism">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.String" name="serverNames">
|
||||
<subParameter classPath="java.lang.String" name="serverTypesNames">
|
||||
<value>Queue - Server Type 1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="serversPerServerType">
|
||||
<subParameter classPath="java.lang.Integer" name="serverTypesNumOfServers">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Object" name="serverCompatibilities">
|
||||
<subParameter array="true" classPath="java.lang.Boolean" name="serverTypesCompatibilities">
|
||||
<subParameter classPath="java.lang.Boolean" name="compatibilities">
|
||||
<value>true</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter classPath="java.lang.String" name="schedulingPolicy">
|
||||
<value>ALIS (Assign Longest Idle Server)</value>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Router">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.RoutingStrategy" name="RoutingStrategy">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.RoutingStrategies.RandomStrategy" name="Random"/>
|
||||
</parameter>
|
||||
</section>
|
||||
</node>
|
||||
<measure alpha="0.01" name="Queue_Class1_Response Time" nodeType="station" precision="0.03" referenceNode="Queue" referenceUserClass="Class1" type="Response Time" verbose="false"/>
|
||||
<measure alpha="0.01" name="Queue_Class1_Utilization" nodeType="station" precision="0.03" referenceNode="Queue" referenceUserClass="Class1" type="Utilization" verbose="false"/>
|
||||
<measure alpha="0.01" name="Queue_Class1_Throughput" nodeType="station" precision="0.03" referenceNode="Queue" referenceUserClass="Class1" type="Throughput" verbose="false"/>
|
||||
<connection source="Source " target="Queue"/>
|
||||
<connection source="Queue" target="Sink"/>
|
||||
</sim>
|
||||
<jmodel xsi:noNamespaceSchemaLocation="JModelGUI.xsd">
|
||||
<userClass color="#FF0000FF" name="Class1"/>
|
||||
<station name="Source ">
|
||||
<position angle="0.0" rotate="false" x="73.0" y="139.0"/>
|
||||
</station>
|
||||
<station name="Sink">
|
||||
<position angle="0.0" rotate="false" x="354.0" y="139.0"/>
|
||||
</station>
|
||||
<station name="Queue">
|
||||
<position angle="0.0" rotate="false" x="191.0" y="136.0"/>
|
||||
</station>
|
||||
</jmodel>
|
||||
<results elapsedTime="932" logDecimalSeparator="," logDelimiter=";" pollingInterval="1.0" xsi:noNamespaceSchemaLocation="Results.xsd">
|
||||
<measure alpha="0.99" analyzedSamples="245760" discardedSamples="390" finalValue="7.30224421202774" name="Queue_Class1_Response Time" nodeType="station" precision="0.03" referenceClass="Class1" referenceStation="Queue" state="1" type="2">
|
||||
<sample lastIntervalAvgValue="7.171346385053164" lowerBound="6.925342616994286" meanValue="7.2654952908722095" simulationTime="349360.1710046531" upperBound="7.6056479647501325"/>
|
||||
<sample lastIntervalAvgValue="7.340886944129393" lowerBound="7.145587638668616" meanValue="7.30224421202774" simulationTime="1105542.162869484" upperBound="7.458900785386865"/>
|
||||
</measure>
|
||||
<measure alpha="0.99" analyzedSamples="56320" discardedSamples="1755" finalValue="0.7110892727677632" name="Queue_Class1_Utilization" nodeType="station" precision="0.03" referenceClass="Class1" referenceStation="Queue" state="1" type="6">
|
||||
<sample lastIntervalAvgValue="0.7121434625959978" lowerBound="0.6959357730746889" meanValue="0.7110892727677632" simulationTime="202809.54195132584" upperBound="0.7262427724608376"/>
|
||||
<sample lastIntervalAvgValue="0.7121434625959978" lowerBound="0.6959357730746889" meanValue="0.7110892727677632" simulationTime="202809.54195132584" upperBound="0.7262427724608376"/>
|
||||
</measure>
|
||||
<measure alpha="0.99" analyzedSamples="51200" discardedSamples="180" finalValue="0.22256617058473832" name="Queue_Class1_Throughput" nodeType="station" precision="0.03" referenceClass="Class1" referenceStation="Queue" state="1" type="5">
|
||||
<sample lastIntervalAvgValue="0.22277397312289457" lowerBound="0.21822871906729738" meanValue="0.22256617058473832" simulationTime="230637.3553415772" upperBound="0.22707953845333897"/>
|
||||
<sample lastIntervalAvgValue="0.22277397312289457" lowerBound="0.21822871906729738" meanValue="0.22256617058473832" simulationTime="230637.3553415772" upperBound="0.22707953845333897"/>
|
||||
</measure>
|
||||
</results>
|
||||
</archive>
|
||||
997
src/test/resources/example2.jsimg
Normal file
@@ -0,0 +1,997 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
|
||||
<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="example2.jsimg" polling="1.0" xsi:noNamespaceSchemaLocation="SIMmodeldefinition.xsd">
|
||||
<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"/>
|
||||
<node name="Service1">
|
||||
<classSoftDeadlines>
|
||||
<softDeadline>0.0</softDeadline>
|
||||
<softDeadline>0.0</softDeadline>
|
||||
</classSoftDeadlines>
|
||||
<quantumSize>
|
||||
<quantaSize>0.0</quantaSize>
|
||||
</quantumSize>
|
||||
<quantumSwitchoverTime>
|
||||
<quantumSwitchoverTime>0.0</quantumSwitchoverTime>
|
||||
</quantumSwitchoverTime>
|
||||
<section className="Queue">
|
||||
<parameter classPath="java.lang.Integer" name="size">
|
||||
<value>-1</value>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.String" name="dropStrategies">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropStrategy">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropStrategy">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter classPath="jmt.engine.NetStrategies.QueueGetStrategies.FCFSstrategy" name="FCFSstrategy"/>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.QueuePutStrategy" name="QueuePutStrategy">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="TailStrategy"/>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="TailStrategy"/>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Server">
|
||||
<parameter classPath="java.lang.Integer" name="maxJobs">
|
||||
<value>1</value>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="numberOfVisits">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="numberOfVisits">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="numberOfVisits">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.ServiceStrategy" name="ServiceStrategy">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.ServiceStrategies.ServiceTimeStrategy" name="ServiceTimeStrategy">
|
||||
<subParameter classPath="jmt.engine.random.Exponential" name="Exponential"/>
|
||||
<subParameter classPath="jmt.engine.random.ExponentialPar" name="distrPar">
|
||||
<subParameter classPath="java.lang.Double" name="lambda">
|
||||
<value>2.0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.ServiceStrategies.ServiceTimeStrategy" name="ServiceTimeStrategy">
|
||||
<subParameter classPath="jmt.engine.random.Exponential" name="Exponential"/>
|
||||
<subParameter classPath="jmt.engine.random.ExponentialPar" name="distrPar">
|
||||
<subParameter classPath="java.lang.Double" name="lambda">
|
||||
<value>1.0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="classParallelism">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="serverParallelism">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="serverParallelism">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.String" name="serverNames">
|
||||
<subParameter classPath="java.lang.String" name="serverTypesNames">
|
||||
<value>Service1 - Server Type 1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="serversPerServerType">
|
||||
<subParameter classPath="java.lang.Integer" name="serverTypesNumOfServers">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Object" name="serverCompatibilities">
|
||||
<subParameter array="true" classPath="java.lang.Boolean" name="serverTypesCompatibilities">
|
||||
<subParameter classPath="java.lang.Boolean" name="compatibilities">
|
||||
<value>true</value>
|
||||
</subParameter>
|
||||
<subParameter classPath="java.lang.Boolean" name="compatibilities">
|
||||
<value>true</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter classPath="java.lang.String" name="schedulingPolicy">
|
||||
<value>ALIS (Assign Longest Idle Server)</value>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Router">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.RoutingStrategy" name="RoutingStrategy">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.RoutingStrategies.RandomStrategy" name="Random"/>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.RoutingStrategies.RandomStrategy" name="Random"/>
|
||||
</parameter>
|
||||
</section>
|
||||
</node>
|
||||
<node name="Queue2">
|
||||
<section className="Storage">
|
||||
<parameter classPath="java.lang.Integer" name="totalCapacity">
|
||||
<value>-1</value>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="capacities">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="capacity">
|
||||
<value>-1</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="capacity">
|
||||
<value>-1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.String" name="dropRules">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropRule">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropRule">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter classPath="jmt.engine.NetStrategies.QueueGetStrategies.FCFSstrategy" name="getStrategy"/>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.QueuePutStrategy" name="putStrategies">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="putStrategy"/>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="putStrategy"/>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="ServiceTunnel"/>
|
||||
<section className="Linkage"/>
|
||||
</node>
|
||||
<node name="Busy2">
|
||||
<section className="Storage">
|
||||
<parameter classPath="java.lang.Integer" name="totalCapacity">
|
||||
<value>-1</value>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="capacities">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="capacity">
|
||||
<value>-1</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="capacity">
|
||||
<value>-1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.String" name="dropRules">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropRule">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropRule">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter classPath="jmt.engine.NetStrategies.QueueGetStrategies.FCFSstrategy" name="getStrategy"/>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.QueuePutStrategy" name="putStrategies">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="putStrategy"/>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="putStrategy"/>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="ServiceTunnel"/>
|
||||
<section className="Linkage"/>
|
||||
</node>
|
||||
<node name="IdleServer2">
|
||||
<section className="Storage">
|
||||
<parameter classPath="java.lang.Integer" name="totalCapacity">
|
||||
<value>-1</value>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="capacities">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="capacity">
|
||||
<value>-1</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="capacity">
|
||||
<value>-1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.String" name="dropRules">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropRule">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropRule">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter classPath="jmt.engine.NetStrategies.QueueGetStrategies.FCFSstrategy" name="getStrategy"/>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.QueuePutStrategy" name="putStrategies">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="putStrategy"/>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="putStrategy"/>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="ServiceTunnel"/>
|
||||
<section className="Linkage"/>
|
||||
</node>
|
||||
<node name="CheckCalibration">
|
||||
<section className="Storage">
|
||||
<parameter classPath="java.lang.Integer" name="totalCapacity">
|
||||
<value>-1</value>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="capacities">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="capacity">
|
||||
<value>-1</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="capacity">
|
||||
<value>-1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.String" name="dropRules">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropRule">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropRule">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter classPath="jmt.engine.NetStrategies.QueueGetStrategies.FCFSstrategy" name="getStrategy"/>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.QueuePutStrategy" name="putStrategies">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="putStrategy"/>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="putStrategy"/>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="ServiceTunnel"/>
|
||||
<section className="Linkage"/>
|
||||
</node>
|
||||
<node name="StartService2">
|
||||
<section className="Enabling">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="enablingConditions">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="enablingCondition">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="enablingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="enablingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>Queue2</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="enablingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="enablingEntry">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="enablingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="enablingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>IdleServer2</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="enablingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="enablingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="enablingEntry">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="inhibitingConditions">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="inhibitingCondition">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="inhibitingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="inhibitingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>Queue2</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="inhibitingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="inhibitingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="inhibitingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="inhibitingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>IdleServer2</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="inhibitingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="inhibitingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="inhibitingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Timing">
|
||||
<parameter array="true" classPath="java.lang.String" name="modeNames">
|
||||
<subParameter classPath="java.lang.String" name="modeName">
|
||||
<value>Mode1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="numbersOfServers">
|
||||
<subParameter classPath="java.lang.Integer" name="numberOfServers">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.ServiceStrategy" name="timingStrategies">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.ServiceStrategies.ZeroServiceTimeStrategy" name="timingStrategy"/>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="firingPriorities">
|
||||
<subParameter classPath="java.lang.Integer" name="firingPriority">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Double" name="firingWeights">
|
||||
<subParameter classPath="java.lang.Double" name="firingWeight">
|
||||
<value>1.0</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Firing">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="firingOutcomes">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="firingOutcome">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="firingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="firingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>Busy2</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="firingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="firingEntry">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="firingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
</node>
|
||||
<node name="Service2">
|
||||
<section className="Enabling">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="enablingConditions">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="enablingCondition">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="enablingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="enablingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>Busy2</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="enablingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="enablingEntry">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="enablingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="inhibitingConditions">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="inhibitingCondition">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="inhibitingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="inhibitingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>Busy2</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="inhibitingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="inhibitingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="inhibitingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Timing">
|
||||
<parameter array="true" classPath="java.lang.String" name="modeNames">
|
||||
<subParameter classPath="java.lang.String" name="modeName">
|
||||
<value>Mode1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="numbersOfServers">
|
||||
<subParameter classPath="java.lang.Integer" name="numberOfServers">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.ServiceStrategy" name="timingStrategies">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.ServiceStrategies.ServiceTimeStrategy" name="timingStrategy">
|
||||
<subParameter classPath="jmt.engine.random.Exponential" name="Exponential"/>
|
||||
<subParameter classPath="jmt.engine.random.ExponentialPar" name="distrPar">
|
||||
<subParameter classPath="java.lang.Double" name="lambda">
|
||||
<value>3.5</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="firingPriorities">
|
||||
<subParameter classPath="java.lang.Integer" name="firingPriority">
|
||||
<value>-1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Double" name="firingWeights">
|
||||
<subParameter classPath="java.lang.Double" name="firingWeight">
|
||||
<value>1.0</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Firing">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="firingOutcomes">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="firingOutcome">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="firingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="firingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>CheckCalibration</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="firingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="firingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="firingEntry">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="firingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>Sink 2</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="firingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="firingEntry">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="firingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
</node>
|
||||
<node name="StartCalibration">
|
||||
<section className="Enabling">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="enablingConditions">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="enablingCondition">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="enablingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="enablingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>CheckCalibration</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="enablingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="enablingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="enablingEntry">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="inhibitingConditions">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="inhibitingCondition">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="inhibitingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="inhibitingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>CheckCalibration</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="inhibitingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="inhibitingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="inhibitingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Timing">
|
||||
<parameter array="true" classPath="java.lang.String" name="modeNames">
|
||||
<subParameter classPath="java.lang.String" name="modeName">
|
||||
<value>Mode1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="numbersOfServers">
|
||||
<subParameter classPath="java.lang.Integer" name="numberOfServers">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.ServiceStrategy" name="timingStrategies">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.ServiceStrategies.ZeroServiceTimeStrategy" name="timingStrategy"/>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="firingPriorities">
|
||||
<subParameter classPath="java.lang.Integer" name="firingPriority">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Double" name="firingWeights">
|
||||
<subParameter classPath="java.lang.Double" name="firingWeight">
|
||||
<value>0.1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Firing">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="firingOutcomes">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="firingOutcome">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="firingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="firingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>Calibration</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="firingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="firingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="firingEntry">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
</node>
|
||||
<node name="Sink 2">
|
||||
<section className="JobSink"/>
|
||||
</node>
|
||||
<node name="EndService">
|
||||
<section className="Enabling">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="enablingConditions">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="enablingCondition">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="enablingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="enablingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>CheckCalibration</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="enablingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="enablingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="enablingEntry">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="inhibitingConditions">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="inhibitingCondition">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="inhibitingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="inhibitingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>CheckCalibration</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="inhibitingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="inhibitingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="inhibitingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Timing">
|
||||
<parameter array="true" classPath="java.lang.String" name="modeNames">
|
||||
<subParameter classPath="java.lang.String" name="modeName">
|
||||
<value>Mode1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="numbersOfServers">
|
||||
<subParameter classPath="java.lang.Integer" name="numberOfServers">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.ServiceStrategy" name="timingStrategies">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.ServiceStrategies.ZeroServiceTimeStrategy" name="timingStrategy"/>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="firingPriorities">
|
||||
<subParameter classPath="java.lang.Integer" name="firingPriority">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Double" name="firingWeights">
|
||||
<subParameter classPath="java.lang.Double" name="firingWeight">
|
||||
<value>0.9</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Firing">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="firingOutcomes">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="firingOutcome">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="firingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="firingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>IdleServer2</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="firingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="firingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="firingEntry">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
</node>
|
||||
<node name="Calibration">
|
||||
<section className="Storage">
|
||||
<parameter classPath="java.lang.Integer" name="totalCapacity">
|
||||
<value>-1</value>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="capacities">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="capacity">
|
||||
<value>-1</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="capacity">
|
||||
<value>-1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.String" name="dropRules">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropRule">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.String" name="dropRule">
|
||||
<value>drop</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter classPath="jmt.engine.NetStrategies.QueueGetStrategies.FCFSstrategy" name="getStrategy"/>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.QueuePutStrategy" name="putStrategies">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="putStrategy"/>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.QueuePutStrategies.TailStrategy" name="putStrategy"/>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="ServiceTunnel"/>
|
||||
<section className="Linkage"/>
|
||||
</node>
|
||||
<node name="Source 1">
|
||||
<section className="RandomSource">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.ServiceStrategy" name="ServiceStrategy">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.ServiceStrategies.ServiceTimeStrategy" name="ServiceTimeStrategy">
|
||||
<subParameter classPath="jmt.engine.random.Exponential" name="Exponential"/>
|
||||
<subParameter classPath="jmt.engine.random.ExponentialPar" name="distrPar">
|
||||
<subParameter classPath="java.lang.Double" name="lambda">
|
||||
<value>1.5</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.ServiceStrategies.ServiceTimeStrategy" name="ServiceTimeStrategy">
|
||||
<value>null</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="ServiceTunnel"/>
|
||||
<section className="Router">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.RoutingStrategy" name="RoutingStrategy">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.RoutingStrategies.RandomStrategy" name="Random"/>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="jmt.engine.NetStrategies.RoutingStrategies.RandomStrategy" name="Random"/>
|
||||
</parameter>
|
||||
</section>
|
||||
</node>
|
||||
<node name="PerformCalibration">
|
||||
<section className="Enabling">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="enablingConditions">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="enablingCondition">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="enablingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="enablingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>Calibration</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="enablingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="enablingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="enablingEntry">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="inhibitingConditions">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="inhibitingCondition">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="inhibitingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="inhibitingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>Calibration</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="inhibitingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="inhibitingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="inhibitingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Timing">
|
||||
<parameter array="true" classPath="java.lang.String" name="modeNames">
|
||||
<subParameter classPath="java.lang.String" name="modeName">
|
||||
<value>Mode1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="numbersOfServers">
|
||||
<subParameter classPath="java.lang.Integer" name="numberOfServers">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.ServiceStrategy" name="timingStrategies">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.ServiceStrategies.ServiceTimeStrategy" name="timingStrategy">
|
||||
<subParameter classPath="jmt.engine.random.Exponential" name="Exponential"/>
|
||||
<subParameter classPath="jmt.engine.random.ExponentialPar" name="distrPar">
|
||||
<subParameter classPath="java.lang.Double" name="lambda">
|
||||
<value>10.0</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Integer" name="firingPriorities">
|
||||
<subParameter classPath="java.lang.Integer" name="firingPriority">
|
||||
<value>-1</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
<parameter array="true" classPath="java.lang.Double" name="firingWeights">
|
||||
<subParameter classPath="java.lang.Double" name="firingWeight">
|
||||
<value>1.0</value>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
<section className="Firing">
|
||||
<parameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="firingOutcomes">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionMatrix" name="firingOutcome">
|
||||
<subParameter array="true" classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="firingVectors">
|
||||
<subParameter classPath="jmt.engine.NetStrategies.TransitionUtilities.TransitionVector" name="firingVector">
|
||||
<subParameter classPath="java.lang.String" name="stationName">
|
||||
<value>IdleServer2</value>
|
||||
</subParameter>
|
||||
<subParameter array="true" classPath="java.lang.Integer" name="firingEntries">
|
||||
<refClass>Class1</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="firingEntry">
|
||||
<value>0</value>
|
||||
</subParameter>
|
||||
<refClass>Class2</refClass>
|
||||
<subParameter classPath="java.lang.Integer" name="firingEntry">
|
||||
<value>1</value>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</subParameter>
|
||||
</parameter>
|
||||
</section>
|
||||
</node>
|
||||
<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="Busy2_Number of Customers" nodeType="station" precision="0.01" referenceNode="Busy2" referenceUserClass="" 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="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="Queue2" target="StartService2"/>
|
||||
<connection source="Busy2" target="Service2"/>
|
||||
<connection source="IdleServer2" target="StartService2"/>
|
||||
<connection source="CheckCalibration" target="StartCalibration"/>
|
||||
<connection source="CheckCalibration" target="EndService"/>
|
||||
<connection source="StartService2" target="Busy2"/>
|
||||
<connection source="Service2" target="CheckCalibration"/>
|
||||
<connection source="Service2" target="Sink 2"/>
|
||||
<connection source="StartCalibration" target="Calibration"/>
|
||||
<connection source="EndService" target="IdleServer2"/>
|
||||
<connection source="Calibration" target="PerformCalibration"/>
|
||||
<connection source="Source 1" target="Service1"/>
|
||||
<connection source="PerformCalibration" target="IdleServer2"/>
|
||||
<preload>
|
||||
<stationPopulations stationName="IdleServer2">
|
||||
<classPopulation population="1" refClass="Class2"/>
|
||||
</stationPopulations>
|
||||
</preload>
|
||||
</sim>
|
||||
<jmodel xsi:noNamespaceSchemaLocation="JModelGUI.xsd">
|
||||
<userClass color="#FF0000FF" name="Class1"/>
|
||||
<userClass color="#FFFF0000" name="Class2"/>
|
||||
<station name="Service1">
|
||||
<position angle="0.0" rotate="false" x="130.0" y="200.0"/>
|
||||
</station>
|
||||
<station name="Queue2">
|
||||
<position angle="0.0" rotate="false" x="277.0" y="203.0"/>
|
||||
</station>
|
||||
<station name="Busy2">
|
||||
<position angle="0.0" rotate="false" x="560.0" y="203.0"/>
|
||||
</station>
|
||||
<station name="IdleServer2">
|
||||
<position angle="0.0" rotate="true" x="411.0" y="328.0"/>
|
||||
</station>
|
||||
<station name="CheckCalibration">
|
||||
<position angle="0.0" rotate="false" x="738.0" y="203.0"/>
|
||||
</station>
|
||||
<station name="StartService2">
|
||||
<position angle="0.0" rotate="false" x="394.0" y="203.0"/>
|
||||
</station>
|
||||
<station name="Service2">
|
||||
<position angle="0.0" rotate="false" x="635.0" y="203.0"/>
|
||||
</station>
|
||||
<station name="StartCalibration">
|
||||
<position angle="0.0" rotate="true" x="739.0" y="328.0"/>
|
||||
</station>
|
||||
<station name="Sink 2">
|
||||
<position angle="0.0" rotate="false" x="753.0" y="113.0"/>
|
||||
</station>
|
||||
<station name="EndService">
|
||||
<position angle="0.0" rotate="false" x="877.0" y="328.0"/>
|
||||
</station>
|
||||
<station name="Calibration">
|
||||
<position angle="0.0" rotate="true" x="638.0" y="328.0"/>
|
||||
</station>
|
||||
<station name="Source 1">
|
||||
<position angle="0.0" rotate="false" x="28.0" y="203.0"/>
|
||||
</station>
|
||||
<station name="PerformCalibration">
|
||||
<position angle="0.0" rotate="true" x="505.0" y="328.0"/>
|
||||
</station>
|
||||
</jmodel>
|
||||
<results elapsedTime="22985" logDecimalSeparator="," logDelimiter=";" pollingInterval="1.0" xsi:noNamespaceSchemaLocation="Results.xsd">
|
||||
<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="1.5106622983340463" lowerBound="1.468486049955798" meanValue="1.50631035481992" simulationTime="13876.695025167392" upperBound="1.546134682461421"/>
|
||||
<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 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.7580797914843828" lowerBound="0.7284349220101368" meanValue="0.758341372366939" simulationTime="13876.28919854346" upperBound="0.7882478227237412"/>
|
||||
<sample lastIntervalAvgValue="0.7437399633757887" lowerBound="0.7338157319545954" meanValue="0.7479059359761921" simulationTime="64255.194361328504" upperBound="0.7619961399977889"/>
|
||||
<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 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.4327278274081417" lowerBound="0.4209685663151158" meanValue="0.43604958177996045" simulationTime="13876.695025167392" upperBound="0.4511305972448051"/>
|
||||
<sample lastIntervalAvgValue="0.4277717437256055" lowerBound="0.4246046190172446" meanValue="0.4316330740668569" simulationTime="64255.194361328504" upperBound="0.4386615291164692"/>
|
||||
<sample lastIntervalAvgValue="0.4275252965369865" lowerBound="0.42421446359628734" meanValue="0.428573485460139" simulationTime="112953.74188414749" upperBound="0.4329325073239907"/>
|
||||
<sample lastIntervalAvgValue="0.4283866284569466" lowerBound="0.42421446359628734" meanValue="0.428573485460139" simulationTime="161441.69294713807" upperBound="0.4329325073239907"/>
|
||||
<sample lastIntervalAvgValue="0.4302070978372558" lowerBound="0.42484998277284614" meanValue="0.4285284158768284" simulationTime="203719.94497095025" upperBound="0.43220684898081063"/>
|
||||
</measure>
|
||||
<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.014296267465728714" lowerBound="0.011322752016847876" meanValue="0.014850303903029771" simulationTime="13874.061196402345" upperBound="0.018377855789211667"/>
|
||||
<sample lastIntervalAvgValue="0.014868345345791742" lowerBound="0.013988219806503858" meanValue="0.014827742149762239" simulationTime="64253.42721042049" upperBound="0.015667264493020618"/>
|
||||
<sample lastIntervalAvgValue="0.014812215932949374" lowerBound="0.014092261369804996" meanValue="0.014674223347077174" simulationTime="112953.02447111536" upperBound="0.015256185324349353"/>
|
||||
<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 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="1.94831588313056" lowerBound="1.569602317070396" meanValue="1.8932003606330974" simulationTime="13876.28919854346" upperBound="2.2167984041957984"/>
|
||||
<sample lastIntervalAvgValue="1.96702004144991" lowerBound="1.8378967552023229" meanValue="2.0265293538191256" simulationTime="64255.194361328504" upperBound="2.215161952435928"/>
|
||||
<sample lastIntervalAvgValue="1.9583792326739768" lowerBound="1.8419491796060967" meanValue="1.9467177321899223" simulationTime="112954.31879089898" upperBound="2.051486284773748"/>
|
||||
<sample lastIntervalAvgValue="1.9920863680624197" lowerBound="1.8815084714201606" meanValue="1.9586531713516644" simulationTime="161441.3383818988" upperBound="2.0357978712831684"/>
|
||||
<sample lastIntervalAvgValue="2.08577509641053" lowerBound="1.8815084714201606" meanValue="1.9586531713516644" simulationTime="208959.31741758634" upperBound="2.0357978712831684"/>
|
||||
<sample lastIntervalAvgValue="2.013680282601994" lowerBound="1.8815084714201606" meanValue="1.9586531713516644" simulationTime="257854.98823458815" upperBound="2.0357978712831684"/>
|
||||
<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 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.28644908123102863" lowerBound="0.2722201556987353" meanValue="0.28601168477942707" simulationTime="13876.695025167392" upperBound="0.2998032138601188"/>
|
||||
<sample lastIntervalAvgValue="0.28510476832868925" lowerBound="0.2816272949130171" meanValue="0.2857712799507223" simulationTime="33841.364358874554" upperBound="0.28991526498842757"/>
|
||||
</measure>
|
||||
<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.23921408959189303" lowerBound="0.19954877885417566" meanValue="0.2302254387533936" simulationTime="13876.695025167392" upperBound="0.26090209865261155"/>
|
||||
<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>
|
||||
</results>
|
||||
</archive>
|
||||