From 2ed814911028dd27c8eaf4072e21f15e47b9da40 Mon Sep 17 00:00:00 2001 From: Berack96 Date: Sun, 16 Mar 2025 17:38:16 +0100 Subject: [PATCH] Rename runBuilder method to run in InteractiveConsole; update interactive console commands and tests for improved clarity and functionality --- .vscode/launch.json | 4 +- .../berack/upo/valpre/InteractiveConsole.java | 90 ++++++++++++++----- src/main/java/net/berack/upo/valpre/Main.java | 2 +- .../upo/valpre/sim/TestInteractions.java | 32 +++++-- 4 files changed, 96 insertions(+), 32 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c7f527a..2c02d94 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -55,10 +55,10 @@ }, { "type": "java", - "name": "Build Net", + "name": "Interactive Net Builder", "request": "launch", "mainClass": "net.berack.upo.valpre.Main", - "args": "net" + "args": "interactive" }, ] } \ No newline at end of file diff --git a/src/main/java/net/berack/upo/valpre/InteractiveConsole.java b/src/main/java/net/berack/upo/valpre/InteractiveConsole.java index bbf352a..6d1b2b1 100644 --- a/src/main/java/net/berack/upo/valpre/InteractiveConsole.java +++ b/src/main/java/net/berack/upo/valpre/InteractiveConsole.java @@ -1,9 +1,15 @@ package net.berack.upo.valpre; +import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.util.Scanner; +import java.util.concurrent.ExecutionException; import java.util.function.Function; + +import com.esotericsoftware.kryo.KryoException; + import net.berack.upo.valpre.rand.Distribution; import net.berack.upo.valpre.sim.Net; import net.berack.upo.valpre.sim.ServerNode; @@ -39,27 +45,18 @@ public class InteractiveConsole { /** * Run the interactive net builder. */ - public Net runBuilder() { + public Net run() { while (true) { try { var choice = choose(this.net + "\nChoose the next step to do:", - "Add a node", "Add a connection", "Save the net", "Load net", "Clear", "Exit"); + "Add a node", "Add a connection", "Save the net", "Load net", "Clear", "Run", "Exit"); switch (choice) { - case 1 -> { - var node = this.buildNode(); - this.net.addNode(node); - } - case 2 -> { - var source = ask("Enter the source node: "); - var target = ask("Enter the target node: "); - var weight = ask("Enter the weight: ", Double::parseDouble); - var sourceNode = this.net.getNode(source); - var targetNode = this.net.getNode(target); - this.net.addConnection(sourceNode, targetNode, weight); - } + case 1 -> this.buildNode(); + case 2 -> this.buildConnection(); case 3 -> this.net.save(ask("Enter the filename: ")); - case 4 -> this.net = Net.load(ask("Enter the filename: ")); + case 4 -> this.loadNet(); case 5 -> this.net = new Net(); + case 6 -> this.simpleRuns(); default -> { this.scanner.close(); return this.net; @@ -72,17 +69,15 @@ public class InteractiveConsole { } /** - * Build a node. - * - * @return the node + * Build a node as a source, terminal, queue, or queue with unavailable time. */ - private ServerNode buildNode() { + private void buildNode() { var choice = choose("Choose the type of node to create:", "Source", "Terminal", "Queue", "Queue with unavailable time"); var name = ask("Node name: "); var distribution = askDistribution("Service distribution"); - return switch (choice) { + var node = switch (choice) { case 1 -> ServerNode.Builder.source(name, distribution); case 2 -> { var limit = ask("Arrivals limit (0 for Int.Max): ", Integer::parseInt); @@ -101,6 +96,61 @@ public class InteractiveConsole { } default -> null; }; + + if (node != null) + this.net.addNode(node); + } + + /** + * Build a connection. + */ + private void buildConnection() { + var source = ask("Enter the source node: "); + var target = ask("Enter the target node: "); + var weight = ask("Enter the weight: ", Double::parseDouble); + var sourceNode = this.net.getNode(source); + var targetNode = this.net.getNode(target); + this.net.addConnection(sourceNode, targetNode, weight); + } + + /** + * Load a net from a file or from examples. + */ + private void loadNet() throws KryoException, IOException { + var choice = choose("Choose the type of net to load:", "From file", "From examples"); + this.net = switch (choice) { + case 1 -> Net.load(ask("Enter the filename: ")); + case 2 -> { + var choice2 = choose("Choose the example to load:", + "Example 1: Source -> Queue", + "Example 2: Source -> Queue -> Queue"); + yield switch (choice2) { + case 1 -> NetExamples.getNet1(); + case 2 -> NetExamples.getNet2(); + default -> null; + }; + } + default -> null; + }; + } + + /** + * Run the simulation with the net. + */ + private void simpleRuns() throws InterruptedException, ExecutionException, IOException { + var choice = choose("Choose what to do:", "100 Run", "1K Runs", "1K Runs + Plot"); + switch (choice) { + case 1 -> new SimulationBuilder(net).setMaxRuns(100).setParallel(true).run(); + case 2 -> new SimulationBuilder(net).setMaxRuns(1000).setParallel(true).run(); + case 3 -> { + var randName = "rand" + System.currentTimeMillis() + ".csv"; + new SimulationBuilder(net).setMaxRuns(1000).setParallel(true).setCsv(randName).run(); + new Plot(randName).show(); + new File(randName).delete(); + } + default -> { + } + } } /** diff --git a/src/main/java/net/berack/upo/valpre/Main.java b/src/main/java/net/berack/upo/valpre/Main.java index 120d2d1..8135468 100644 --- a/src/main/java/net/berack/upo/valpre/Main.java +++ b/src/main/java/net/berack/upo/valpre/Main.java @@ -31,7 +31,7 @@ public class Main { var plot = new Plot(csv); plot.show(); } - case "interactive" -> new InteractiveConsole().runBuilder(); + case "interactive" -> new InteractiveConsole().run(); default -> exit("Invalid program!"); } } catch (Exception e) { diff --git a/src/test/java/net/berack/upo/valpre/sim/TestInteractions.java b/src/test/java/net/berack/upo/valpre/sim/TestInteractions.java index 3b342a7..801c2f9 100644 --- a/src/test/java/net/berack/upo/valpre/sim/TestInteractions.java +++ b/src/test/java/net/berack/upo/valpre/sim/TestInteractions.java @@ -100,17 +100,17 @@ public class TestInteractions { public void netBuilderInteractive() { // Test the interactive console EXIT - var net = runInteraction("6"); + var net = runInteraction("7"); assertEquals("", net.toString()); // Test the interactive console ADD NODE - net = runInteraction("1", "1", "Source", "1", "1.0", "6"); + net = runInteraction("1", "1", "Source", "1", "1.0", "7"); assertEquals("Source[servers:1, queue:100, spawn:-1, Exponential(1.0)] -\n", net.toString()); - // Test the interactive console ADD SECOND NODE + // Test the interactive console ADD SECOND NODE net = runInteraction("1", "2", "Terminal", "1", "2.0", "500", "1", "3", "Queue", "5", "3.2", "0.6", "1", - "6"); + "7"); assertEquals("Terminal[servers:1, queue:100, spawn:500, Exponential(2.0)] -\n" + "Queue[servers:1, queue:100, spawn:0, Normal(3.2, 0.6)] -\n", net.toString()); @@ -118,7 +118,7 @@ public class TestInteractions { net = runInteraction("1", "1", "Source", "1", "2.0", "1", "3", "Queue", "5", "3.2", "0.6", "1", "2", "Source", "Queue", "1.0", - "6"); + "7"); assertEquals("Source[servers:1, queue:100, spawn:-1, Exponential(2.0)] -> Queue(1.0)\n" + "Queue[servers:1, queue:100, spawn:0, Normal(3.2, 0.6)] -\n", net.toString()); @@ -127,13 +127,27 @@ public class TestInteractions { "1", "3", "Queue", "5", "3.2", "0.6", "1", "2", "Source", "Queue", "1.0", "2", "Queue", "Queue", "1.0", - "5", "6"); + "5", "7"); assertEquals("", net.toString()); // Test the interactive console LOAD - net = runInteraction("4", "src/test/resources/example1.net", "6"); + net = runInteraction("4", "1", "src/test/resources/example1.net", "7"); assertEquals("Source[servers:1, queue:100, spawn:10000, Exponential(0.2222222222222222)] -> Queue(1.0)\n" - + "Queue[servers:1, queue:100, spawn:0, NormalBoxMuller(3.2, 0.6)] -\n", net.toString()); + + "Queue[servers:1, queue:100, spawn:0, NormalBoxMuller(3.2, 0.6)] -\n", + net.toString()); + + // Test the interactive console LOAD EXAMPLE 1 + net = runInteraction("4", "2", "1", "7"); + assertEquals("Source[servers:1, queue:100, spawn:10000, Exponential(0.2222222222222222)] -> Queue(1.0)\n" + + "Queue[servers:1, queue:100, spawn:0, NormalBoxMuller(3.2, 0.6)] -\n", + net.toString()); + + // 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" + + "Service2[servers:1, queue:100, spawn:0, Exponential(3.5), u:UnavailableTime(0.1, Exponential(10.0))] -\n", + net.toString()); } private static Net runInteraction(String... commands) { @@ -141,7 +155,7 @@ public class TestInteractions { var inputs = String.join("\n", commands); var bytes = inputs.getBytes(); var in = new ByteArrayInputStream(bytes); - return new InteractiveConsole(out, in).runBuilder(); + return new InteractiveConsole(out, in).run(); } /*