Rename Statistics class to NodeStats and update references throughout the codebase

This commit is contained in:
2025-02-05 17:17:26 +01:00
parent 363b5ffee6
commit 1e6fea8af7
8 changed files with 43 additions and 22 deletions

View File

@@ -46,6 +46,6 @@ I percorsi che invece sono direttamente responsabili per la simulazione sono:
- **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:
- **Result** il risultato di una run e la sua controparte **ResultSummary** che contiene molteplici risultati di run già analizzati.
- **Statistics** contiene indici statistici di un nodo e la sua controparte **StatisticsSummary** che contiene molteplici indici statistici già analizzati.
- **NodeStats** 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
- **CsvResult** utile per la lettura/scrittura dei risultati in formato csv

View File

@@ -22,7 +22,7 @@ import org.jfree.data.category.DefaultCategoryDataset;
import net.berack.upo.valpre.sim.stats.CsvResult;
import net.berack.upo.valpre.sim.stats.ResultSummary;
import net.berack.upo.valpre.sim.stats.Statistics;
import net.berack.upo.valpre.sim.stats.NodeStats;
/**
* This class is used to plot the results of the simulation.
@@ -55,7 +55,7 @@ public class Plot {
this.nodeComboBox = new JComboBox<>(nodes);
this.nodeComboBox.addActionListener(_ -> update());
var order = Statistics.getOrderOfApply();
var order = NodeStats.getOrderOfApply();
var panels = new JListEntry[order.length];
for (int i = 0; i < order.length; i++)
panels[i] = new JListEntry(order[i]);

View File

@@ -9,7 +9,7 @@ import java.util.PriorityQueue;
import net.berack.upo.valpre.rand.Rng;
import net.berack.upo.valpre.sim.stats.Result;
import net.berack.upo.valpre.sim.stats.Statistics;
import net.berack.upo.valpre.sim.stats.NodeStats;
/**
* Process an entire run of the simulation.
@@ -126,7 +126,7 @@ public final class Simulation {
*/
public Result endSimulation() {
var elapsed = System.nanoTime() - this.timeStartedNano;
var nodes = new HashMap<String, Statistics>();
var nodes = new HashMap<String, NodeStats>();
for (var entry : this.states.entrySet())
nodes.put(entry.getKey(), entry.getValue().stats);
@@ -252,7 +252,7 @@ public final class Simulation {
public static class NodeState {
public int numServerBusy = 0;
public int numServerUnavailable = 0;
public final Statistics stats = new Statistics();
public final NodeStats stats = new NodeStats();
public final ArrayDeque<Double> queue = new ArrayDeque<>();
}
}

View File

@@ -38,7 +38,7 @@ public class CsvResult {
public void saveResults(Result[] results) throws IOException {
var builder = new StringBuilder();
builder.append("seed,node,");
builder.append(String.join(",", Statistics.getOrderOfApply()));
builder.append(String.join(",", NodeStats.getOrderOfApply()));
builder.append('\n');
try (var writer = new FileWriter(this.file)) {
@@ -76,7 +76,7 @@ public class CsvResult {
try (var scan = new Scanner(input)) {
var _ = scan.nextLine();
var nodes = new HashMap<String, Statistics>();
var nodes = new HashMap<String, NodeStats>();
var seed = 0L;
while (scan.hasNextLine()) {
@@ -106,7 +106,7 @@ public class CsvResult {
* @param stats the statistics to convert
* @return the CSV string
*/
public static String statsToCSV(Statistics stats) {
public static String statsToCSV(NodeStats stats) {
var builder = new StringBuilder();
stats.apply(val -> {
builder.append(val).append(",");
@@ -123,9 +123,9 @@ public class CsvResult {
* @param values the values to convert
* @return the statistics object
*/
public static Statistics statsFromCSV(String[] values) {
public static NodeStats statsFromCSV(String[] values) {
var i = new AtomicInteger(0);
var stats = new Statistics();
var stats = new NodeStats();
stats.apply(_ -> Double.parseDouble(values[i.getAndIncrement()]));
return stats;
}

View File

@@ -10,7 +10,7 @@ import java.util.function.Function;
* statistics are updated during simulation events, such as arrivals and
* departures, and can be used to analyze the net's behavior and performance.
*/
public class Statistics {
public class NodeStats {
public double numArrivals = 0.0d;
public double numDepartures = 0.0d;
public double maxQueueLength = 0.0d;
@@ -98,7 +98,7 @@ public class Statistics {
* @param func a function to apply
*/
public void apply(Function<Double, Double> func) {
Statistics.apply(this, this, this, (val1, _) -> func.apply(val1));
NodeStats.operation(this, this, this, (val1, _) -> func.apply(val1));
}
/**
@@ -109,8 +109,8 @@ public class Statistics {
* @param other
* @param func
*/
public void merge(Statistics other, BiFunction<Double, Double, Double> func) {
Statistics.apply(this, this, other, func);
public void merge(NodeStats other, BiFunction<Double, Double, Double> func) {
NodeStats.operation(this, this, other, func);
}
/**
@@ -124,6 +124,27 @@ public class Statistics {
"unavailable" };
}
/**
* Merges two sets of statistics into a new one.
* This method combines the statistics from two `Statistics` objects (`val1` and
* `val2`) and returns a new `Statistics` object with the merged results. The
* provided function is applied to each pair of corresponding statistics from
* `val1` and `val2` to compute the merged value. This is useful for merging or
* combining statistics from different sources (e.g., different simulation
* runs), allowing the creation of aggregated statistics.
*
* @param val1 The first `Statistics` object to merge.
* @param val2 The second `Statistics` object to merge.
* @param func The binary function that defines how to merge each pair of values
* from `val1` and `val2`. It takes two `Double` values (from `val1`
* and `val2`) and returns a new `Double` value.
*/
public static NodeStats merge(NodeStats val1, NodeStats val2, BiFunction<Double, Double, Double> func) {
var save = new NodeStats();
NodeStats.operation(save, val1, val2, func);
return save;
}
/**
* Applies a binary function to merge two sets of statistics into a third one.
* This method combines the statistics from two `Statistics` objects (`val1` and
@@ -140,7 +161,7 @@ public class Statistics {
* from `val1` and `val2`. It takes two `Double` values (from `val1`
* and `val2`) and returns a new `Double` value.
*/
public static void apply(Statistics save, Statistics val1, Statistics val2,
public static void operation(NodeStats save, NodeStats val1, NodeStats val2,
BiFunction<Double, Double, Double> func) {
save.numArrivals = func.apply(val1.numArrivals, val2.numArrivals);
save.numDepartures = func.apply(val1.numDepartures, val2.numDepartures);

View File

@@ -9,7 +9,7 @@ import java.util.Map;
* length, the busy time, and the response time.
*/
public class Result {
public final Map<String, Statistics> nodes;
public final Map<String, NodeStats> nodes;
public final long seed;
public final double simulationTime;
public final double timeElapsedMS;
@@ -23,7 +23,7 @@ public class Result {
* @param elapsed the real time elapsed while running the simulation in ms
* @param nodes all the stats collected by the simulation saved per node
*/
public Result(long seed, double time, double elapsed, Map<String, Statistics> nodes) {
public Result(long seed, double time, double elapsed, Map<String, NodeStats> nodes) {
this.seed = seed;
this.simulationTime = time;
this.timeElapsedMS = elapsed;

View File

@@ -129,11 +129,11 @@ public class ResultSummary {
*/
public static Map<String, Map<String, StatisticsSummary>> getSummary(Result[] runs) {
// Get the statistics of the nodes
var nodeStats = new HashMap<String, Statistics[]>();
var nodeStats = new HashMap<String, NodeStats[]>();
for (var i = 0; i < runs.length; i++) {
for (var entry : runs[i].nodes.entrySet()) {
var node = entry.getKey();
var stats = nodeStats.computeIfAbsent(node, _ -> new Statistics[runs.length]);
var stats = nodeStats.computeIfAbsent(node, _ -> new NodeStats[runs.length]);
stats[i] = entry.getValue();
}
}

View File

@@ -115,11 +115,11 @@ public class StatisticsSummary {
* @throws IllegalArgumentException if the fields of the statistics cannot be
* accessed
*/
public static Map<String, StatisticsSummary> getSummary(Statistics[] stats) throws IllegalArgumentException {
public static Map<String, StatisticsSummary> getSummary(NodeStats[] stats) throws IllegalArgumentException {
try {
var map = new HashMap<String, StatisticsSummary>();
for (var field : Statistics.class.getFields()) {
for (var field : NodeStats.class.getFields()) {
field.setAccessible(true);
var values = new double[stats.length];