Update README and refactor EndCriteria and Simulation classes for improved clarity and functionality

This commit is contained in:
2025-02-04 11:30:25 +01:00
parent 2d5f43bbc9
commit 173dee884f
3 changed files with 62 additions and 24 deletions

View File

@@ -21,6 +21,8 @@ Esistono vari tipi di argomenti per scegliere come fare la simulazione:
* `-seed <value>` per dare un seed iniziale scelto * `-seed <value>` per dare un seed iniziale scelto
* `-csv <file>` per salvare i risultati delle run in un file csv * `-csv <file>` per salvare i risultati delle run in un file csv
* `-p` per fare le simulazioni in parallelo (ovvero su più thread) * `-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]`
* `java -jar upo-valpre.jar plot -csv <file>`\ * `java -jar upo-valpre.jar plot -csv <file>`\
Mostra (con un ambiente grafico) una finestra nella quale si può scegliere quale nodo vedere e ogni statistica associata ad esso. Di seguito un'immagine di esempio: 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:
![1738603552417](image/README/1738603552417.png) ![1738603552417](image/README/1738603552417.png)
@@ -40,10 +42,10 @@ I percorsi che invece sono direttamente responsabili per la simulazione sono:
- **Net** che viene usato per rappresentare una rete da simulare. - **Net** che viene usato per rappresentare una rete da simulare.
- **ServerNode** che viene usato per rappresentare un singolo nodo della rete. - **ServerNode** che viene usato per rappresentare un singolo nodo della rete.
- **Event** che viene usato per rappresentare un evento della simulazione. - **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. - **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 si più thread o su un singolo core. - **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](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. - **Result** il risultato di una run e la sua controparte **ResultSummary** che contiene molteplici risultati di run già analizzati.
- **Statistics** un singolo valore di indici statistici di un nodo e la sua controparte **StatisticsSummary** che contiene molteplici risultati già analizzati. - **Statistics** contiene indici statistici di un nodo e la sua controparte **StatisticsSummary** che contiene molteplici indici statistici già analizzati.
- **ConsoleTable** utile per mostrare i risultati in console sottoforma di tabella - **ConsoleTable** utile per mostrare i risultati in console sottoforma di tabella
- **CsvResult** utile per la lettura/scrittura di risultati in formato csv - **CsvResult** utile per la lettura/scrittura dei risultati in formato csv

View File

@@ -73,7 +73,7 @@ public interface EndCriteria {
@Override @Override
public boolean shouldEnd(Simulation run) { public boolean shouldEnd(Simulation run) {
return run.getNode(nodeName).stats.numArrivals >= this.maxArrivals; return run.getNodeState(nodeName).stats.numArrivals >= this.maxArrivals;
} }
} }
@@ -99,7 +99,7 @@ public interface EndCriteria {
@Override @Override
public boolean shouldEnd(Simulation run) { public boolean shouldEnd(Simulation run) {
return run.getNode(nodeName).stats.numDepartures >= this.maxDepartures; return run.getNodeState(nodeName).stats.numDepartures >= this.maxDepartures;
} }
} }

View File

@@ -1,7 +1,9 @@
package net.berack.upo.valpre.sim; package net.berack.upo.valpre.sim;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.PriorityQueue; import java.util.PriorityQueue;
@@ -13,14 +15,16 @@ import net.berack.upo.valpre.sim.stats.Statistics;
* Process an entire run of the simulation. * Process an entire run of the simulation.
*/ */
public final class Simulation { public final class Simulation {
public final Rng rng;
public final long timeStartedNano;
public final EndCriteria[] criterias;
public final long seed;
private final Net net; private final Net net;
private final Map<String, NodeState> states; private final Map<String, NodeState> states;
private final PriorityQueue<Event> fel; private final PriorityQueue<Event> fel;
private final EndCriteria[] criterias; private double time = 0.0d;
private final long timeStartedNano; private long eventProcessed = 0;
private final long seed;
private final Rng rng;
private double time;
/** /**
* Creates a new run of the simulation with the given nodes and random number * Creates a new run of the simulation with the given nodes and random number
@@ -31,30 +35,28 @@ public final class Simulation {
* @param criterias when the simulation has to end. * @param criterias when the simulation has to end.
*/ */
public Simulation(Net net, Rng rng, EndCriteria... criterias) { public Simulation(Net net, Rng rng, EndCriteria... criterias) {
this.timeStartedNano = System.nanoTime();
this.net = net; this.net = net;
this.states = new HashMap<>(); this.states = new HashMap<>();
this.fel = new PriorityQueue<>(); this.fel = new PriorityQueue<>();
this.criterias = criterias; this.criterias = criterias;
this.timeStartedNano = System.nanoTime();
this.seed = rng.getSeed(); this.seed = rng.getSeed();
this.rng = rng; this.rng = rng;
this.time = 0.0d;
// check for ending criteria in simulation
boolean hasLimit = false; boolean hasLimit = false;
for (var node : net) for (var node : net) {
// check for ending criteria in simulation
if (node.spawnArrivals != Integer.MAX_VALUE) if (node.spawnArrivals != Integer.MAX_VALUE)
hasLimit = true; hasLimit = true;
if (!hasLimit && (criterias == null || criterias.length == 0)) // Initial arrivals (if spawned)
throw new IllegalArgumentException("At least one end criteria is needed!");
// Initial arrivals (if spawned)
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);
}); }
if (!hasLimit && (criterias == null || criterias.length == 0))
throw new IllegalArgumentException("At least one end criteria is needed!");
} }
/** /**
@@ -74,12 +76,17 @@ public final class Simulation {
* You should check if the simulation has ended before calling this method. * You should check if the simulation has ended before calling this method.
* *
* @see #hasEnded() * @see #hasEnded()
* @throws NullPointerException if there are no more events to process.
*/ */
public void processNextEvent() { public void processNextEvent() {
var event = fel.poll(); var event = fel.poll();
if (event == null)
throw new NullPointerException("No more events to process!");
var node = event.node; var node = event.node;
var state = this.states.get(node.name); var state = this.states.get(node.name);
this.time = event.time; this.time = event.time;
this.eventProcessed += 1;
switch (event.type) { switch (event.type) {
case AVAILABLE -> { case AVAILABLE -> {
@@ -136,12 +143,41 @@ public final class Simulation {
} }
/** /**
* Get the node state requested by the name passed as a string. * Get the number of events processed.
*
* @return the number of events processed.
*/
public long getEventsProcessed() {
return this.eventProcessed;
}
/**
* Get the list of future events.
* This method returns a copy of the list, so the original list is not modified.
*
* @return a list of future events.
*/
public List<Event> getFutureEventList() {
return new ArrayList<>(this.fel);
}
/**
* Get the node requested by the name passed as a string.
* *
* @param node the name of the node * @param node the name of the node
* @return the node * @return the node
*/ */
public NodeState getNode(String node) { public ServerNode getNode(String node) {
return this.net.getNode(node);
}
/**
* Get the node state requested by the name passed as a string.
*
* @param node the name of the node
* @return the current state of the node
*/
public NodeState getNodeState(String node) {
return this.states.get(node); return this.states.get(node);
} }