Add new images and update README with network modifications; improve ConsoleTable formatting
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
package net.berack.upo.valpre;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -16,30 +18,79 @@ import net.berack.upo.valpre.sim.stats.Result;
|
||||
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.
|
||||
* 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 ExecutionException if the execution fails
|
||||
* @throws InterruptedException if the execution is interrupted
|
||||
* @throws Exception if the simulation fails or the file is not saved
|
||||
*/
|
||||
public static void main(String[] args) throws InterruptedException, ExecutionException {
|
||||
var avg1 = 3.2;
|
||||
var seed = 0l;
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
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))
|
||||
};
|
||||
/**
|
||||
* 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 };
|
||||
|
||||
for (var net : nets) {
|
||||
var summary = new SimulationMultiple(net).runParallel(seed, 1000);
|
||||
var table = Result.getResultString(summary.getNodes(), summary.getStats());
|
||||
System.out.println(table);
|
||||
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 });
|
||||
|
||||
System.out.println("Normal: " + normal.mean);
|
||||
System.out.println("Uniform: " + uniform.min + " - " + uniform.max);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,20 +104,21 @@ public final class NetExamples {
|
||||
*/
|
||||
public static Net getNet1() {
|
||||
var norm3_2 = new Distribution.NormalBoxMuller(3.2, 0.6);
|
||||
return getNet1("Queue", norm3_2);
|
||||
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 10000 jobs with an exponential distribution 4.5.
|
||||
* 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(String name, Distribution queue) {
|
||||
var spawn = 10000;
|
||||
public static Net getNet1(int spawn, String name, Distribution queue) {
|
||||
var source = new Distribution.Exponential(1.0 / 4.5);
|
||||
|
||||
var net1 = new Net();
|
||||
@@ -90,13 +142,8 @@ public final class NetExamples {
|
||||
* @return the second example network
|
||||
*/
|
||||
public static Net getNet2() {
|
||||
var exp1_5 = new Distribution.Exponential(1.5);
|
||||
var exp2 = new Distribution.Exponential(2.0);
|
||||
var exp3_5 = new Distribution.Exponential(3.5);
|
||||
var exp10 = new Distribution.Exponential(10.0);
|
||||
var unExp = new Distribution.UnavailableTime(0.1, exp10);
|
||||
var spawn = 10000;
|
||||
return getNet2(spawn, exp1_5, exp2, exp3_5, unExp);
|
||||
return getNet2(10000, "Service2", exp3_5);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,18 +153,20 @@ public final class NetExamples {
|
||||
* The first queue node is connected to the second queue node.
|
||||
*
|
||||
* @param spawn the number of jobs to generate
|
||||
* @param source the distribution of the source node
|
||||
* @param service1 the distribution of the first queue node
|
||||
* @param name the name of the second queue node
|
||||
* @param service2 the distribution of the second queue node
|
||||
* @param unExp the distribution of the unavailable time
|
||||
* @return the second example network
|
||||
*/
|
||||
public static Net getNet2(int spawn, Distribution source, Distribution service1, Distribution service2,
|
||||
Distribution unExp) {
|
||||
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, source));
|
||||
net3.addNode(ServerNode.Builder.queue("Service1", 1, service1));
|
||||
net3.addNode(ServerNode.Builder.queue("Service2", 1, service2, unExp));
|
||||
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;
|
||||
|
||||
@@ -49,7 +49,7 @@ public class ConsoleTable {
|
||||
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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,8 +144,8 @@ public class TestInteractions {
|
||||
|
||||
// Test the interactive console LOAD EXAMPLE 2
|
||||
net = runInteraction("4", "2", "2", "7");
|
||||
assertEquals("Source[servers:1, queue:100, spawn:10000, Exponential(1.5)] -> Service1(1.0)\n"
|
||||
+ "Service1[servers:1, queue:100, spawn:0, Exponential(2.0)] -> Service2(1.0)\n"
|
||||
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());
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user