Add launch configuration for NetExamples; enhance NetExamples class with main method and improved network creation; refactor Result class for better stats handling
This commit is contained in:
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
@@ -4,6 +4,13 @@
|
|||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "NetExamples",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "net.berack.upo.valpre.NetExamples",
|
||||||
|
"projectName": "valpre"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "java",
|
"type": "java",
|
||||||
"name": "Run1k Simple",
|
"name": "Run1k Simple",
|
||||||
@@ -52,6 +59,6 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"mainClass": "net.berack.upo.valpre.Main",
|
"mainClass": "net.berack.upo.valpre.Main",
|
||||||
"args": "interactive"
|
"args": "interactive"
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
package net.berack.upo.valpre;
|
package net.berack.upo.valpre;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import net.berack.upo.valpre.rand.Distribution;
|
import net.berack.upo.valpre.rand.Distribution;
|
||||||
import net.berack.upo.valpre.sim.Net;
|
import net.berack.upo.valpre.sim.Net;
|
||||||
import net.berack.upo.valpre.sim.ServerNode;
|
import net.berack.upo.valpre.sim.ServerNode;
|
||||||
|
import net.berack.upo.valpre.sim.SimulationMultiple;
|
||||||
|
import net.berack.upo.valpre.sim.stats.Result;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides two example networks.
|
* This class provides two example networks.
|
||||||
@@ -10,37 +14,64 @@ import net.berack.upo.valpre.sim.ServerNode;
|
|||||||
* The second network is composed of a terminal node and two queue nodes.
|
* The second network is composed of a terminal node and two queue nodes.
|
||||||
*/
|
*/
|
||||||
public final class NetExamples {
|
public final class NetExamples {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main method to test the example networks.
|
||||||
|
* It runs the fist network and prints the results.
|
||||||
|
* The network will have the distribution changed but the mean will be the same.
|
||||||
|
*
|
||||||
|
* @param args not needed
|
||||||
|
* @throws ExecutionException if the execution fails
|
||||||
|
* @throws InterruptedException if the execution is interrupted
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws InterruptedException, ExecutionException {
|
||||||
|
var avg1 = 3.2;
|
||||||
|
var seed = 0l;
|
||||||
|
|
||||||
|
var nets = new Net[] {
|
||||||
|
getNet1("Normal", new Distribution.NormalBoxMuller(avg1, 0.6)),
|
||||||
|
getNet1("Exponential", new Distribution.Exponential(1 / avg1)),
|
||||||
|
getNet1("Erlang", new Distribution.Erlang(5, 5 / avg1)),
|
||||||
|
getNet1("Uniform", new Distribution.Uniform(avg1 - 1, avg1 + 1))
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var net : nets) {
|
||||||
|
var summary = new SimulationMultiple(net).runParallel(seed, 1000);
|
||||||
|
var table = Result.getResultString(summary.getNodes(), summary.getStats());
|
||||||
|
System.out.println(table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the first example network.
|
* Return the first example network.
|
||||||
* The net is composed of a terminal node and a queue node.
|
* The net is composed of a terminal node and a queue node.
|
||||||
* The terminal node generates 10000 jobs with an exponential distribution 4.5.
|
* The terminal node generates 10000 jobs with an exponential distribution 4.5.
|
||||||
* The queue node has a capacity of 1 and a service time of 3.2 with a standard
|
* The queue node has a capacity of 1 and a service time of 3.2 with a standard
|
||||||
* deviation of 0.6.
|
* deviation of 0.6.
|
||||||
* The terminal node is connected to the queue node with a probability of 1.0.
|
|
||||||
*
|
*
|
||||||
* @return the first example network
|
* @return the first example network
|
||||||
*/
|
*/
|
||||||
public static Net getNet1() {
|
public static Net getNet1() {
|
||||||
var exp0_22 = new Distribution.Exponential(1.0 / 4.5);
|
|
||||||
var norm3_2 = new Distribution.NormalBoxMuller(3.2, 0.6);
|
var norm3_2 = new Distribution.NormalBoxMuller(3.2, 0.6);
|
||||||
var spawn = 10000;
|
return getNet1("Queue", norm3_2);
|
||||||
return getNet1(spawn, exp0_22, norm3_2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the first example network.
|
* Return the first example network.
|
||||||
* The net is composed of a terminal node and a queue node.
|
* The net is composed of a terminal node and a queue node.
|
||||||
* The terminal node is connected to the queue node.
|
* The terminal node is connected to the queue node.
|
||||||
|
* The terminal node generates 10000 jobs with an exponential distribution 4.5.
|
||||||
*
|
*
|
||||||
* @param spawn the number of jobs to generate
|
* @param queue the distribution of the queue node
|
||||||
* @param source the distribution of the source node
|
|
||||||
* @param queue the distribution of the queue node
|
|
||||||
* @return the first example network
|
* @return the first example network
|
||||||
*/
|
*/
|
||||||
public static Net getNet1(int spawn, Distribution source, Distribution queue) {
|
public static Net getNet1(String name, Distribution queue) {
|
||||||
|
var spawn = 10000;
|
||||||
|
var source = new Distribution.Exponential(1.0 / 4.5);
|
||||||
|
|
||||||
var net1 = new Net();
|
var net1 = new Net();
|
||||||
net1.addNode(ServerNode.Builder.terminal("Source", spawn, source));
|
net1.addNode(ServerNode.Builder.terminal("Source", spawn, source));
|
||||||
net1.addNode(ServerNode.Builder.queue("Queue", 1, queue));
|
net1.addNode(ServerNode.Builder.queue(name, 1, queue));
|
||||||
net1.addConnection(0, 1, 1.0);
|
net1.addConnection(0, 1, 1.0);
|
||||||
return net1;
|
return net1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class Plot {
|
|||||||
var results = new CsvResult(csv).loadResults();
|
var results = new CsvResult(csv).loadResults();
|
||||||
this.summary = new Result.Summary(results);
|
this.summary = new Result.Summary(results);
|
||||||
|
|
||||||
var nodes = this.summary.getNodes().toArray(new String[0]);
|
var nodes = this.summary.getNodes();
|
||||||
this.panelBarChart = new ChartPanel(null);
|
this.panelBarChart = new ChartPanel(null);
|
||||||
|
|
||||||
this.nodeComboBox = new JComboBox<>(nodes);
|
this.nodeComboBox = new JComboBox<>(nodes);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.berack.upo.valpre.sim.stats;
|
package net.berack.upo.valpre.sim.stats;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -36,6 +37,11 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
|||||||
this.stats = stats;
|
this.stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the stats of a node.
|
||||||
|
*
|
||||||
|
* @return the stats of a node
|
||||||
|
*/
|
||||||
public NodeStats getStat(String node) {
|
public NodeStats getStat(String node) {
|
||||||
for (var i = 0; i < this.nodes.length; i++)
|
for (var i = 0; i < this.nodes.length; i++)
|
||||||
if (this.nodes[i].equals(node))
|
if (this.nodes[i].equals(node))
|
||||||
@@ -45,7 +51,7 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return buildPrintable(this.seed, this.simulationTime, this.timeElapsedMS, this.nodes, this.stats);
|
return getResultString(this.seed, this.simulationTime, this.timeElapsedMS, this.nodes, this.stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -80,9 +86,8 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
|||||||
* @param stats the stats of each node
|
* @param stats the stats of each node
|
||||||
* @return a string representation of the result
|
* @return a string representation of the result
|
||||||
*/
|
*/
|
||||||
private static String buildPrintable(long seed, double simTime, double timeMS, String[] nodes, NodeStats[] stats) {
|
public static String getResultString(long seed, double simTime, double timeMS, String[] nodes, NodeStats[] stats) {
|
||||||
var size = (int) Math.ceil(Math.max(Math.log10(simTime), 1));
|
var size = (int) Math.ceil(Math.max(Math.log10(simTime), 1));
|
||||||
var iFormat = "%" + size + ".0f";
|
|
||||||
var fFormat = "%" + (size + 4) + ".3f";
|
var fFormat = "%" + (size + 4) + ".3f";
|
||||||
|
|
||||||
var builder = new StringBuilder();
|
var builder = new StringBuilder();
|
||||||
@@ -90,6 +95,26 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
|||||||
builder.append(String.format("Seed: \t%d\n", seed));
|
builder.append(String.format("Seed: \t%d\n", seed));
|
||||||
builder.append(String.format("Simulation: \t" + fFormat + "\n", simTime));
|
builder.append(String.format("Simulation: \t" + fFormat + "\n", simTime));
|
||||||
builder.append(String.format("Elapsed: \t" + fFormat + "ms\n", timeMS));
|
builder.append(String.format("Elapsed: \t" + fFormat + "ms\n", timeMS));
|
||||||
|
builder.append(getResultString(nodes, stats));
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 table = new ConsoleTable("Node", "Departures", "Avg Queue", "Avg Wait", "Avg Response", "Throughput",
|
var table = new ConsoleTable("Node", "Departures", "Avg Queue", "Avg Wait", "Avg Response", "Throughput",
|
||||||
"Utilization %", "Unavailable %", "Last Event");
|
"Utilization %", "Unavailable %", "Last Event");
|
||||||
@@ -206,12 +231,24 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the nodes of the summary.
|
* Gets a copy of the nodes of the summary.
|
||||||
*
|
*
|
||||||
* @return the nodes of the summary
|
* @return the nodes of the summary
|
||||||
*/
|
*/
|
||||||
public List<String> getNodes() {
|
public String[] getNodes() {
|
||||||
return List.of(this.nodes);
|
return Arrays.copyOf(this.nodes, this.nodes.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the statistics of the nodes of the summary.
|
||||||
|
*
|
||||||
|
* @return the statistics of the nodes of the summary
|
||||||
|
*/
|
||||||
|
public NodeStats[] getStats() {
|
||||||
|
var stats = new NodeStats[this.nodes.length];
|
||||||
|
for (var i = 0; i < this.nodes.length; i++)
|
||||||
|
stats[i] = this.stats[i].average;
|
||||||
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -239,11 +276,8 @@ public class Result implements Iterable<Entry<String, NodeStats>> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
var stats = new NodeStats[this.nodes.length];
|
return getResultString(this.seed, this.avgSimulationTime, this.avgTimeElapsedMS, this.nodes,
|
||||||
for (var i = 0; i < this.nodes.length; i++)
|
this.getStats());
|
||||||
stats[i] = this.stats[i].average;
|
|
||||||
|
|
||||||
return buildPrintable(this.seed, this.avgSimulationTime, this.avgTimeElapsedMS, this.nodes, stats);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user