Readme
- Refactor simulation handling and improve net iteration methods
This commit is contained in:
7
.vscode/launch.json
vendored
7
.vscode/launch.json
vendored
@@ -25,13 +25,6 @@
|
|||||||
"mainClass": "net.berack.upo.valpre.Main",
|
"mainClass": "net.berack.upo.valpre.Main",
|
||||||
"args": "simulation -net example1.net -runs 10"
|
"args": "simulation -net example1.net -runs 10"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "java",
|
|
||||||
"name": "Run10",
|
|
||||||
"request": "launch",
|
|
||||||
"mainClass": "net.berack.upo.valpre.Main",
|
|
||||||
"args": "simulation -net example1.net -runs 10"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "java",
|
"type": "java",
|
||||||
"name": "Plot Simple",
|
"name": "Plot Simple",
|
||||||
|
|||||||
51
README.md
51
README.md
@@ -1,2 +1,49 @@
|
|||||||
# upo-valpre
|
# Valutazione delle Prestazioni
|
||||||
valutazione delle prestazioni (principalemnte Reti di code e di Petri)
|
|
||||||
|
Il progetto riguarda un simulatore ad eventi discreti.
|
||||||
|
Il simulatore è iniziato con il lavoro trovato sul libro di testo [Discrete-Event System Simulation](https://www.pearson.com/en-us/subject-catalog/p/discrete-event-system-simulation/P200000003161/9780136062127) al Capitolo 4, per poi esser personalizzato e modificato radicalmente.
|
||||||
|
|
||||||
|
Il risultato è la creazione in una libreria per la simulazione di eventi discreti nella quale si può scegliera la topologia e la quantità di nodi nella rete da simulare.
|
||||||
|
|
||||||
|
Per fare ciò si può usare il JAR risultante che si trova nelle [Releases](https://github.com/Berack96/upo-valpre/releases).
|
||||||
|
|
||||||
|
### 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`\
|
||||||
|
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]`\
|
||||||
|
Usato per avviare una simulazione della rete. Nel caso la rete non abbia eventuali limiti nella generazione di arrivi, viene restituito un errore.
|
||||||
|
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
|
||||||
|
* `-csv <file>` per salvare i risultati delle run in un file csv
|
||||||
|
* `-p` per fare le simulazioni in parallelo (ovvero su più thread)
|
||||||
|
* `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:
|
||||||
|
* `example1.net` e `example2.net` per `simulation -net`
|
||||||
|
* `example1.csv` e `example2.csv` per `plot -csv`
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
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:
|
||||||
|
- **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** 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 la simulazione debba finire.
|
||||||
|
- **Simulation** e **SimulationMultiple** che vengono usate per far partire la simulazione; la versione multiple serve ad organizzare molteplici simulazioni si 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:
|
||||||
|
- **Result** un singolo risultato e la sua controparte **ResultSummary** che contiene molteplici risultati già analizzati.
|
||||||
|
- **Statistics** un singolo valore di indici statistici di un nodo e la sua controparte **StatisticsSummary** che contiene molteplici risultati già analizzati.
|
||||||
|
- **ConsoleTable** utile per mostrare i risultati in console sottoforma di tabella
|
||||||
|
- **CsvResult** utile per la lettura/scrittura di risultati in formato csv
|
||||||
|
|||||||
BIN
image/README/1738603552417.png
Normal file
BIN
image/README/1738603552417.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
@@ -18,7 +18,7 @@ public class Main {
|
|||||||
var param = Main.getParameters(program, subArgs);
|
var param = Main.getParameters(program, subArgs);
|
||||||
switch (program) {
|
switch (program) {
|
||||||
case "simulation" -> {
|
case "simulation" -> {
|
||||||
new Simulation(param.get("net"))
|
new SimulationBuilder(param.get("net"))
|
||||||
.setCsv(param.get("csv"))
|
.setCsv(param.get("csv"))
|
||||||
.setRuns(param.getOrDefault("runs", Integer::parseInt, 100))
|
.setRuns(param.getOrDefault("runs", Integer::parseInt, 100))
|
||||||
.setSeed(param.getOrDefault("seed", Long::parseLong, 2007539552L))
|
.setSeed(param.getOrDefault("seed", Long::parseLong, 2007539552L))
|
||||||
|
|||||||
@@ -142,7 +142,9 @@ public class Plot {
|
|||||||
var columnKey = String.format("%.3f", columnVal);
|
var columnKey = String.format("%.3f", columnVal);
|
||||||
dataset.addValue(frequency[i], "Frequency", columnKey);
|
dataset.addValue(frequency[i], "Frequency", columnKey);
|
||||||
}
|
}
|
||||||
this.panelBarChart.getChart().getCategoryPlot().setDataset(dataset);
|
var chart = this.panelBarChart.getChart();
|
||||||
|
chart.getCategoryPlot().setDataset(dataset);
|
||||||
|
chart.setTitle(stat + " distribution");
|
||||||
|
|
||||||
var model = this.statList.getModel();
|
var model = this.statList.getModel();
|
||||||
for (int i = 0; i < model.getSize(); i++) {
|
for (int i = 0; i < model.getSize(); i++) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import net.berack.upo.valpre.sim.stats.CsvResult;
|
|||||||
* This class is responsible for running the simulation. It parses the arguments
|
* This class is responsible for running the simulation. It parses the arguments
|
||||||
* and runs the simulation with the given parameters.
|
* and runs the simulation with the given parameters.
|
||||||
*/
|
*/
|
||||||
public class Simulation {
|
public class SimulationBuilder {
|
||||||
private String csv;
|
private String csv;
|
||||||
private int runs;
|
private int runs;
|
||||||
private long seed;
|
private long seed;
|
||||||
@@ -28,7 +28,7 @@ public class Simulation {
|
|||||||
* @param netFile the net file to load
|
* @param netFile the net file to load
|
||||||
* @throws IOException if the file has a problem
|
* @throws IOException if the file has a problem
|
||||||
*/
|
*/
|
||||||
public Simulation(String netFile) throws IOException {
|
public SimulationBuilder(String netFile) throws IOException {
|
||||||
try {
|
try {
|
||||||
var file = Parameters.getFileOrExample(netFile);
|
var file = Parameters.getFileOrExample(netFile);
|
||||||
this.net = Net.load(file);
|
this.net = Net.load(file);
|
||||||
@@ -46,7 +46,7 @@ public class Simulation {
|
|||||||
* @param net the net
|
* @param net the net
|
||||||
* @throws IllegalArgumentException if the net is null
|
* @throws IllegalArgumentException if the net is null
|
||||||
*/
|
*/
|
||||||
public Simulation(Net net) {
|
public SimulationBuilder(Net net) {
|
||||||
if (net == null)
|
if (net == null)
|
||||||
throw new IllegalArgumentException("Net needed!");
|
throw new IllegalArgumentException("Net needed!");
|
||||||
this.net = net;
|
this.net = net;
|
||||||
@@ -59,7 +59,7 @@ public class Simulation {
|
|||||||
* @throws IllegalArgumentException if the runs are less than 1
|
* @throws IllegalArgumentException if the runs are less than 1
|
||||||
* @return this simulation
|
* @return this simulation
|
||||||
*/
|
*/
|
||||||
public Simulation setRuns(int runs) {
|
public SimulationBuilder setRuns(int runs) {
|
||||||
if (runs <= 0)
|
if (runs <= 0)
|
||||||
throw new IllegalArgumentException("Runs must be greater than 0!");
|
throw new IllegalArgumentException("Runs must be greater than 0!");
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ public class Simulation {
|
|||||||
* @param seed the seed
|
* @param seed the seed
|
||||||
* @return this simulation
|
* @return this simulation
|
||||||
*/
|
*/
|
||||||
public Simulation setSeed(long seed) {
|
public SimulationBuilder setSeed(long seed) {
|
||||||
this.seed = seed;
|
this.seed = seed;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ public class Simulation {
|
|||||||
* @param parallel if the simulation should run in parallel
|
* @param parallel if the simulation should run in parallel
|
||||||
* @return this simulation
|
* @return this simulation
|
||||||
*/
|
*/
|
||||||
public Simulation setParallel(boolean parallel) {
|
public SimulationBuilder setParallel(boolean parallel) {
|
||||||
this.parallel = parallel;
|
this.parallel = parallel;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -96,7 +96,7 @@ public class Simulation {
|
|||||||
* @param csv the CSV file
|
* @param csv the CSV file
|
||||||
* @return this simulation
|
* @return this simulation
|
||||||
*/
|
*/
|
||||||
public Simulation setCsv(String csv) {
|
public SimulationBuilder setCsv(String csv) {
|
||||||
this.csv = csv;
|
this.csv = csv;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -110,7 +110,7 @@ public class Simulation {
|
|||||||
* @return this simulation
|
* @return this simulation
|
||||||
* @throws IllegalArgumentException if the criteria are null
|
* @throws IllegalArgumentException if the criteria are null
|
||||||
*/
|
*/
|
||||||
public Simulation setEndCriteria(EndCriteria... criterias) {
|
public SimulationBuilder setEndCriteria(EndCriteria... criterias) {
|
||||||
if (criterias == null)
|
if (criterias == null)
|
||||||
throw new IllegalArgumentException("End criteria cannot be null!");
|
throw new IllegalArgumentException("End criteria cannot be null!");
|
||||||
this.endCriteria = criterias;
|
this.endCriteria = criterias;
|
||||||
@@ -7,8 +7,8 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import org.objenesis.strategy.StdInstantiatorStrategy;
|
import org.objenesis.strategy.StdInstantiatorStrategy;
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ import net.berack.upo.valpre.rand.Rng;
|
|||||||
* connections between nodes. In order to start a simulation, at least one node
|
* connections between nodes. In order to start a simulation, at least one node
|
||||||
* must be a Source or must generate at least one event to be processed.
|
* must be a Source or must generate at least one event to be processed.
|
||||||
*/
|
*/
|
||||||
public final class Net {
|
public final class Net implements Iterable<ServerNode> {
|
||||||
private final List<ServerNode> servers = new ArrayList<>();
|
private final List<ServerNode> servers = new ArrayList<>();
|
||||||
private final HashMap<ServerNode, Integer> indices = new HashMap<>();
|
private final HashMap<ServerNode, Integer> indices = new HashMap<>();
|
||||||
private final List<List<Connection>> connections = new ArrayList<>();
|
private final List<List<Connection>> connections = new ArrayList<>();
|
||||||
@@ -220,16 +220,6 @@ public final class Net {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply a consumer to all the nodes. The implementation uses a stream and for
|
|
||||||
* this reason you should consider to make thread safe the consumer.
|
|
||||||
*
|
|
||||||
* @param consumer a function that takes in input a ServerNode
|
|
||||||
*/
|
|
||||||
public void forEachNode(Consumer<ServerNode> consumer) {
|
|
||||||
this.servers.stream().forEach(consumer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the current net to a file.
|
* Save the current net to a file.
|
||||||
* The resulting file is saved with Kryo.
|
* The resulting file is saved with Kryo.
|
||||||
@@ -304,4 +294,9 @@ public final class Net {
|
|||||||
this.weight = weight;
|
this.weight = weight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<ServerNode> iterator() {
|
||||||
|
return this.servers.iterator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,17 @@ public final class Simulation {
|
|||||||
this.rng = rng;
|
this.rng = rng;
|
||||||
this.time = 0.0d;
|
this.time = 0.0d;
|
||||||
|
|
||||||
|
// check for ending criteria in simulation
|
||||||
|
boolean hasLimit = false;
|
||||||
|
for (var node : net)
|
||||||
|
if (node.spawnArrivals != Integer.MAX_VALUE)
|
||||||
|
hasLimit = true;
|
||||||
|
|
||||||
|
if (!hasLimit && (criterias == null || criterias.length == 0))
|
||||||
|
throw new IllegalArgumentException("At least one end criteria is needed!");
|
||||||
|
|
||||||
// Initial arrivals (if spawned)
|
// Initial arrivals (if spawned)
|
||||||
net.forEachNode(node -> {
|
net.forEach(node -> {
|
||||||
this.states.put(node.name, new NodeState());
|
this.states.put(node.name, new NodeState());
|
||||||
if (node.shouldSpawnArrival(0))
|
if (node.shouldSpawnArrival(0))
|
||||||
this.addArrival(node);
|
this.addArrival(node);
|
||||||
@@ -152,7 +161,7 @@ public final class Simulation {
|
|||||||
* on the given node, and the delay is determined by the node's service
|
* on the given node, and the delay is determined by the node's service
|
||||||
* distribution.
|
* distribution.
|
||||||
*
|
*
|
||||||
* @param node The node to create the event for.
|
* @param node The node to create the event for.
|
||||||
* @param state The current state of the node
|
* @param state The current state of the node
|
||||||
*/
|
*/
|
||||||
public void addDepartureIfPossible(ServerNode node, NodeState state) {
|
public void addDepartureIfPossible(ServerNode node, NodeState state) {
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public class TestSimulation {
|
|||||||
var nodes = new HashSet<ServerNode>();
|
var nodes = new HashSet<ServerNode>();
|
||||||
nodes.add(node);
|
nodes.add(node);
|
||||||
nodes.add(node1);
|
nodes.add(node1);
|
||||||
net.forEachNode(n -> assertTrue(nodes.contains(n)));
|
net.forEach(n -> assertTrue(nodes.contains(n)));
|
||||||
|
|
||||||
net.addConnection(0, 1, 1.0);
|
net.addConnection(0, 1, 1.0);
|
||||||
var conn = net.getChildren(0);
|
var conn = net.getChildren(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user