diff --git a/.gitignore b/.gitignore
index 9122c96..0fb3b56 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,5 +25,6 @@ replay_pid*
# mine
+target/*
pdf/*
*.csv
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
index d2fb8bc..30215a4 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -6,31 +6,24 @@
"configurations": [
{
"type": "java",
- "name": "Run1k Rand",
+ "name": "Run1k Simple",
"request": "launch",
"mainClass": "net.berack.upo.valpre.Main",
- "args": "-runs 1000 -p -seed 0"
+ "args": "-net example1.net -runs 1000 -p -seed 0"
},
{
"type": "java",
- "name": "Run1k save",
+ "name": "Run1k Complex",
"request": "launch",
"mainClass": "net.berack.upo.valpre.Main",
- "args": "-runs 1000 -p -csv result.csv"
- },
- {
- "type": "java",
- "name": "Run1k",
- "request": "launch",
- "mainClass": "net.berack.upo.valpre.Main",
- "args": "-runs 1000 -p"
+ "args": "-net example2.net -runs 1000 -p -seed 0"
},
{
"type": "java",
"name": "Run10",
"request": "launch",
"mainClass": "net.berack.upo.valpre.Main",
- "args": "-runs 10"
+ "args": "-net example1.net -runs 10"
},
]
}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index c9b6055..1ea74b4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,5 +31,10 @@
commons-math3
3.6.1
+
+ com.esotericsoftware
+ kryo
+ 5.6.2
+
\ No newline at end of file
diff --git a/src/main/java/net/berack/upo/valpre/Main.java b/src/main/java/net/berack/upo/valpre/Main.java
index a72ae64..67e923c 100644
--- a/src/main/java/net/berack/upo/valpre/Main.java
+++ b/src/main/java/net/berack/upo/valpre/Main.java
@@ -3,10 +3,8 @@ package net.berack.upo.valpre;
import java.util.HashMap;
import java.util.Map;
-import net.berack.upo.valpre.rand.Distribution;
-import net.berack.upo.valpre.sim.SimulationMultiple;
import net.berack.upo.valpre.sim.Net;
-import net.berack.upo.valpre.sim.ServerNode;
+import net.berack.upo.valpre.sim.SimulationMultiple;
public class Main {
public static void main(String[] args) throws Exception {
@@ -25,11 +23,17 @@ public class Main {
csv = arguments.get("csv");
var parallel = arguments.containsKey("p");
- var net = moreComplexNet();
+ var file = arguments.get("net");
+ if (file == null)
+ throw new IllegalArgumentException("Net file needed! Use -net ");
+ if (file.startsWith("example"))
+ file = Main.class.getClassLoader().getResource(file).getPath();
+
// var maxDepartures = new EndSimulationCriteria.MaxDepartures("Queue", total);
// var maxTime = new EndSimulationCriteria.MaxTime(1000.0);
/// Run multiple simulations
+ var net = Net.load(file);
var nano = System.nanoTime();
var sim = new SimulationMultiple(net);
var results = parallel ? sim.runParallel(seed, runs) : sim.run(seed, runs);
@@ -45,44 +49,12 @@ public class Main {
}
}
- public static Net simpleNet() {
- var lambda = 1.0 / 4.5;
- var mu = 3.2;
- var sigma = 0.6;
- var total = 10000;
-
- var distrExp = new Distribution.Exponential(lambda);
- var distrNorm = new Distribution.NormalBoxMuller(mu, sigma);
-
- // Build the network
- var net = new Net();
- net.addNode(ServerNode.createLimitedSource("Source", distrExp, total));
- net.addNode(ServerNode.createQueue("Queue", 1, distrNorm));
- net.addConnection(0, 1, 1.0);
- net.normalizeWeights();
-
- return net;
- }
-
- public static Net moreComplexNet() {
- var net = simpleNet();
- var distrNorm = new Distribution.NormalBoxMuller(3.2, 0.6);
- var distrNorm2 = new Distribution.NormalBoxMuller(4.2, 0.6);
- var distrUnav = new Distribution.UnavailableTime(0.2, distrNorm2);
-
- // Build the network
- net.addNode(ServerNode.createQueue("Queue Wait", 1, distrNorm, distrUnav));
- net.addConnection(1, 2, 1.0);
- net.normalizeWeights();
-
- return net;
- }
-
public static Map parseParameters(String[] args) {
var arguments = new HashMap();
arguments.put("p", false);
arguments.put("seed", true);
arguments.put("runs", true);
+ arguments.put("net", true);
arguments.put("csv", true);
var param = new Parameters("-", arguments);
@@ -90,10 +62,12 @@ public class Main {
return param.parse(args);
} catch (IllegalArgumentException e) {
var descriptions = new HashMap();
- descriptions.put("p", "Add this if you want the simulation to use threads (one each run)");
- descriptions.put("seed", "The seed of the simulation");
- descriptions.put("runs", "How many runs the simulator should run");
- descriptions.put("csv", "The filename for saving every run statistics");
+ descriptions.put("p", "Add this if you want the simulation to use threads (one each run).");
+ descriptions.put("seed", "The seed of the simulation.");
+ descriptions.put("runs", "How many runs the simulator should run.");
+ descriptions.put("net",
+ "The net to use. It should be a file. Use example1.net or example2.net for the provided ones.");
+ descriptions.put("csv", "The filename for saving every run statistics.");
System.out.println(e.getMessage());
System.out.println(param.helper(descriptions));
diff --git a/src/main/java/net/berack/upo/valpre/sim/Net.java b/src/main/java/net/berack/upo/valpre/sim/Net.java
index 0802f0a..8bf8842 100644
--- a/src/main/java/net/berack/upo/valpre/sim/Net.java
+++ b/src/main/java/net/berack/upo/valpre/sim/Net.java
@@ -1,10 +1,20 @@
package net.berack.upo.valpre.sim;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.function.Consumer;
+import org.objenesis.strategy.StdInstantiatorStrategy;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.KryoException;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+
import net.berack.upo.valpre.rand.Rng;
/**
@@ -218,6 +228,41 @@ public final class Net {
this.servers.stream().forEach(consumer);
}
+ /**
+ * Save the current net to a file.
+ * The resulting file is saved with Kryo.
+ *
+ * @param file the name of the file
+ * @throws FileNotFoundException if the path doesn't exist
+ */
+ public void save(String file) throws FileNotFoundException {
+ var kryo = new Kryo();
+ kryo.setRegistrationRequired(false);
+
+ try (var out = new Output(new FileOutputStream(file))) {
+ kryo.writeClassAndObject(out, this);
+ }
+ }
+
+ /**
+ * Load the net from the file passed as input.
+ * The net will be the same as the one saved.
+ *
+ * @param file the file to load
+ * @return a new Net object
+ * @throws KryoException if the file saved is not a net
+ * @throws FileNotFoundException if the file is not found
+ */
+ public static Net load(String file) throws KryoException, FileNotFoundException {
+ var kryo = new Kryo();
+ kryo.setRegistrationRequired(false);
+ kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
+
+ try (var in = new Input(new FileInputStream(file))) {
+ return (Net) kryo.readClassAndObject(in);
+ }
+ }
+
/**
* A static inner class used to represent the connection between two nodes
*/
diff --git a/src/main/resources/example1.net b/src/main/resources/example1.net
new file mode 100644
index 0000000..f8e0fd8
Binary files /dev/null and b/src/main/resources/example1.net differ
diff --git a/src/main/resources/example2.net b/src/main/resources/example2.net
new file mode 100644
index 0000000..0428cd6
Binary files /dev/null and b/src/main/resources/example2.net differ