Rename runBuilder method to run in InteractiveConsole; update interactive console commands and tests for improved clarity and functionality
This commit is contained in:
4
.vscode/launch.json
vendored
4
.vscode/launch.json
vendored
@@ -55,10 +55,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "java",
|
"type": "java",
|
||||||
"name": "Build Net",
|
"name": "Interactive Net Builder",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"mainClass": "net.berack.upo.valpre.Main",
|
"mainClass": "net.berack.upo.valpre.Main",
|
||||||
"args": "net"
|
"args": "interactive"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
package net.berack.upo.valpre;
|
package net.berack.upo.valpre;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.esotericsoftware.kryo.KryoException;
|
||||||
|
|
||||||
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;
|
||||||
@@ -39,27 +45,18 @@ public class InteractiveConsole {
|
|||||||
/**
|
/**
|
||||||
* Run the interactive net builder.
|
* Run the interactive net builder.
|
||||||
*/
|
*/
|
||||||
public Net runBuilder() {
|
public Net run() {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
var choice = choose(this.net + "\nChoose the next step to do:",
|
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) {
|
switch (choice) {
|
||||||
case 1 -> {
|
case 1 -> this.buildNode();
|
||||||
var node = this.buildNode();
|
case 2 -> this.buildConnection();
|
||||||
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 3 -> this.net.save(ask("Enter the filename: "));
|
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 5 -> this.net = new Net();
|
||||||
|
case 6 -> this.simpleRuns();
|
||||||
default -> {
|
default -> {
|
||||||
this.scanner.close();
|
this.scanner.close();
|
||||||
return this.net;
|
return this.net;
|
||||||
@@ -72,17 +69,15 @@ public class InteractiveConsole {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a node.
|
* Build a node as a source, terminal, queue, or queue with unavailable time.
|
||||||
*
|
|
||||||
* @return the node
|
|
||||||
*/
|
*/
|
||||||
private ServerNode buildNode() {
|
private void buildNode() {
|
||||||
var choice = choose("Choose the type of node to create:", "Source", "Terminal", "Queue",
|
var choice = choose("Choose the type of node to create:", "Source", "Terminal", "Queue",
|
||||||
"Queue with unavailable time");
|
"Queue with unavailable time");
|
||||||
var name = ask("Node name: ");
|
var name = ask("Node name: ");
|
||||||
var distribution = askDistribution("Service distribution");
|
var distribution = askDistribution("Service distribution");
|
||||||
|
|
||||||
return switch (choice) {
|
var node = switch (choice) {
|
||||||
case 1 -> ServerNode.Builder.source(name, distribution);
|
case 1 -> ServerNode.Builder.source(name, distribution);
|
||||||
case 2 -> {
|
case 2 -> {
|
||||||
var limit = ask("Arrivals limit (0 for Int.Max): ", Integer::parseInt);
|
var limit = ask("Arrivals limit (0 for Int.Max): ", Integer::parseInt);
|
||||||
@@ -101,6 +96,61 @@ public class InteractiveConsole {
|
|||||||
}
|
}
|
||||||
default -> null;
|
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 -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class Main {
|
|||||||
var plot = new Plot(csv);
|
var plot = new Plot(csv);
|
||||||
plot.show();
|
plot.show();
|
||||||
}
|
}
|
||||||
case "interactive" -> new InteractiveConsole().runBuilder();
|
case "interactive" -> new InteractiveConsole().run();
|
||||||
default -> exit("Invalid program!");
|
default -> exit("Invalid program!");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -100,17 +100,17 @@ public class TestInteractions {
|
|||||||
public void netBuilderInteractive() {
|
public void netBuilderInteractive() {
|
||||||
|
|
||||||
// Test the interactive console EXIT
|
// Test the interactive console EXIT
|
||||||
var net = runInteraction("6");
|
var net = runInteraction("7");
|
||||||
assertEquals("", net.toString());
|
assertEquals("", net.toString());
|
||||||
|
|
||||||
// Test the interactive console ADD NODE
|
// 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());
|
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",
|
net = runInteraction("1", "2", "Terminal", "1", "2.0", "500",
|
||||||
"1", "3", "Queue", "5", "3.2", "0.6", "1",
|
"1", "3", "Queue", "5", "3.2", "0.6", "1",
|
||||||
"6");
|
"7");
|
||||||
assertEquals("Terminal[servers:1, queue:100, spawn:500, Exponential(2.0)] -\n"
|
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());
|
+ "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",
|
net = runInteraction("1", "1", "Source", "1", "2.0",
|
||||||
"1", "3", "Queue", "5", "3.2", "0.6", "1",
|
"1", "3", "Queue", "5", "3.2", "0.6", "1",
|
||||||
"2", "Source", "Queue", "1.0",
|
"2", "Source", "Queue", "1.0",
|
||||||
"6");
|
"7");
|
||||||
assertEquals("Source[servers:1, queue:100, spawn:-1, Exponential(2.0)] -> Queue(1.0)\n"
|
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());
|
+ "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",
|
"1", "3", "Queue", "5", "3.2", "0.6", "1",
|
||||||
"2", "Source", "Queue", "1.0",
|
"2", "Source", "Queue", "1.0",
|
||||||
"2", "Queue", "Queue", "1.0",
|
"2", "Queue", "Queue", "1.0",
|
||||||
"5", "6");
|
"5", "7");
|
||||||
assertEquals("", net.toString());
|
assertEquals("", net.toString());
|
||||||
|
|
||||||
// Test the interactive console LOAD
|
// 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"
|
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) {
|
private static Net runInteraction(String... commands) {
|
||||||
@@ -141,7 +155,7 @@ public class TestInteractions {
|
|||||||
var inputs = String.join("\n", commands);
|
var inputs = String.join("\n", commands);
|
||||||
var bytes = inputs.getBytes();
|
var bytes = inputs.getBytes();
|
||||||
var in = new ByteArrayInputStream(bytes);
|
var in = new ByteArrayInputStream(bytes);
|
||||||
return new InteractiveConsole(out, in).runBuilder();
|
return new InteractiveConsole(out, in).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user