From 11e841e7ae2278fcdc92a116bf3ca3eca97cbec0 Mon Sep 17 00:00:00 2001
From: ethankelly <72452934+ethankelly@users.noreply.github.com>
Date: Sat, 27 Mar 2021 15:40:49 +0000
Subject: [PATCH] Runs on command line user input
---
.idea/artifacts/Equations_jar.xml | 10 +
Equations.txt | 50 ++++
src/META-INF/MANIFEST.MF | 3 +
src/io/github/ethankelly/Equations.java | 54 ----
src/io/github/ethankelly/Graph.java | 14 +-
src/io/github/ethankelly/GraphGenerator.java | 261 +++++++++++++++++--
src/io/github/ethankelly/Main.java | 70 ++---
7 files changed, 339 insertions(+), 123 deletions(-)
create mode 100644 .idea/artifacts/Equations_jar.xml
create mode 100644 Equations.txt
create mode 100644 src/META-INF/MANIFEST.MF
diff --git a/.idea/artifacts/Equations_jar.xml b/.idea/artifacts/Equations_jar.xml
new file mode 100644
index 0000000..cbd737f
--- /dev/null
+++ b/.idea/artifacts/Equations_jar.xml
@@ -0,0 +1,10 @@
+
+
+ $PROJECT_DIR$/out/artifacts/Equations_jar
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Equations.txt b/Equations.txt
new file mode 100644
index 0000000..30b8d72
--- /dev/null
+++ b/Equations.txt
@@ -0,0 +1,50 @@
+ *** Equations for an SIR model on a Toast Graph ***
+
+0: 0 1 1 1
+1: 1 0 1 0
+2: 1 1 0 1
+3: 1 0 1 0
+Numbers of equations of each size: [8, 10, 16, 8]
+
+[〈S3〉] = - β〈S3 I0〉- β〈S3 I2〉
+[〈S2〉] = - β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉
+[〈S1〉] = - β〈S1 I0〉- β〈S1 I2〉
+[〈S0〉] = - β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉
+[〈I3〉] = γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉
+[〈I2〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉
+[〈I1〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉
+[〈I0〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉
+[〈I3〉, 〈S2〉] = γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉
+[〈I3〉, 〈S0〉] = γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉
+[〈I2〉, 〈S3〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S3 I0〉- β〈S3 I2〉
+[〈I2〉, 〈S1〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S1 I0〉- β〈S1 I2〉
+[〈I2〉, 〈S0〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉
+[〈I1〉, 〈S2〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉
+[〈I1〉, 〈S0〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉
+[〈I0〉, 〈S3〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉- β〈S3 I0〉- β〈S3 I2〉
+[〈I0〉, 〈S2〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉
+[〈I0〉, 〈S1〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉- β〈S1 I0〉- β〈S1 I2〉
+[〈I3〉, 〈S0〉, 〈S2〉] = γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉
+[〈I3〉, 〈S0〉, 〈S1〉] = γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S1 I0〉- β〈S1 I2〉
+[〈I2〉, 〈S0〉, 〈S3〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S3 I0〉- β〈S3 I2〉
+[〈I2〉, 〈S0〉, 〈S1〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S1 I0〉- β〈S1 I2〉
+[〈I2〉, 〈I3〉, 〈S0〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉+ γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉
+[〈I1〉, 〈S2〉, 〈S3〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉- β〈S3 I0〉- β〈S3 I2〉
+[〈I1〉, 〈S0〉, 〈S3〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S3 I0〉- β〈S3 I2〉
+[〈I1〉, 〈S0〉, 〈S2〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉
+[〈I1〉, 〈I2〉, 〈S3〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S3 I0〉- β〈S3 I2〉
+[〈I1〉, 〈I2〉, 〈S0〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉
+[〈I0〉, 〈S2〉, 〈S3〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉- β〈S3 I0〉- β〈S3 I2〉
+[〈I0〉, 〈S1〉, 〈S2〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉- β〈S1 I0〉- β〈S1 I2〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉
+[〈I0〉, 〈I3〉, 〈S2〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉+ γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉
+[〈I0〉, 〈I2〉, 〈S3〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S3 I0〉- β〈S3 I2〉
+[〈I0〉, 〈I2〉, 〈S1〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S1 I0〉- β〈S1 I2〉
+[〈I0〉, 〈I1〉, 〈S2〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉+ γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉
+[〈I3〉, 〈S0〉, 〈S1〉, 〈S2〉] = γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S1 I0〉- β〈S1 I2〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉
+[〈I2〉, 〈I3〉, 〈S0〉, 〈S1〉] = γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉+ γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S1 I0〉- β〈S1 I2〉
+[〈I1〉, 〈S0〉, 〈S2〉, 〈S3〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉- β〈S3 I0〉- β〈S3 I2〉
+[〈I1〉, 〈I2〉, 〈S0〉, 〈S3〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉- β〈S3 I0〉- β〈S3 I2〉
+[〈I1〉, 〈I2〉, 〈I3〉, 〈S0〉] = γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉+ γ〈S3 I0〉+ γ〈S3 I2〉- γ〈I3〉- β〈S0 I1〉- β〈S0 I2〉- β〈S0 I3〉
+[〈I0〉, 〈S1〉, 〈S2〉, 〈S3〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉- β〈S1 I0〉- β〈S1 I2〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉- β〈S3 I0〉- β〈S3 I2〉
+[〈I0〉, 〈I1〉, 〈S2〉, 〈S3〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉+ γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉- β〈S2 I0〉- β〈S2 I1〉- β〈S2 I3〉- β〈S3 I0〉- β〈S3 I2〉
+[〈I0〉, 〈I1〉, 〈I2〉, 〈S3〉] = γ〈S0 I1〉+ γ〈S0 I2〉+ γ〈S0 I3〉- γ〈I0〉+ γ〈S1 I0〉+ γ〈S1 I2〉- γ〈I1〉+ γ〈S2 I0〉+ γ〈S2 I1〉+ γ〈S2 I3〉- γ〈I2〉- β〈S3 I0〉- β〈S3 I2〉
diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..edd213a
--- /dev/null
+++ b/src/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: io.github.ethankelly.Main
+
diff --git a/src/io/github/ethankelly/Equations.java b/src/io/github/ethankelly/Equations.java
index d33c33c..dfbb39c 100644
--- a/src/io/github/ethankelly/Equations.java
+++ b/src/io/github/ethankelly/Equations.java
@@ -78,58 +78,4 @@ public static List generateEquations(Tuple tuples) {
return equations;
}
-
- public static void main(String[] args) throws FileNotFoundException {
- PrintStream o = new PrintStream("TLTEquations.txt");
- System.setOut(o);
-
- char[] states = new char[]{'S', 'I', 'R', 'P'};
- // TRIANGLE
- Graph triangle = new Graph(3);
- triangle.addEdge(0, 1);
- triangle.addEdge(1, 2);
- triangle.addEdge(2, 0);
- Tuple triangleNE = new Tuple(triangle, states);
-
- System.out.println(" *** TRIANGLE GRAPH ***\n\n" + triangle + "Numbers of equations of each size: "
- + Arrays.toString(triangleNE.findNumbers(triangleNE.getTuples())) + "\n");
- Equations.generateEquations(triangleNE).forEach(System.out::println);
-
- // LOLLIPOP
- Graph lollipop = new Graph(4);
- lollipop.addEdge(0, 1);
- lollipop.addEdge(0, 2);
- lollipop.addEdge(0, 3);
- lollipop.addEdge(2, 3);
- Tuple lollipopNE = new Tuple(lollipop, states);
-
- System.out.println("\n *** LOLLIPOP GRAPH ***\n\n" + lollipop + "Numbers of equations of each size: "
- + Arrays.toString(lollipopNE.findNumbers(lollipopNE.getTuples())) + "\n");
- Equations.generateEquations(lollipopNE).forEach(System.out::println);
-
- // TOAST
- Graph toast = new Graph(4);
- toast.addEdge(0, 1);
- toast.addEdge(0, 2);
- toast.addEdge(0, 3);
- toast.addEdge(1, 2);
- toast.addEdge(2, 3);
- Tuple toastNE = new Tuple(toast, states);
-
- System.out.println("\n *** TOAST GRAPH ***\n\n" + toast + "Numbers of equations of each size: "
- + Arrays.toString(toastNE.findNumbers(toastNE.getTuples())) + "\n");
- Equations.generateEquations(toastNE).forEach(System.out::println);
-
- // Creating another File object that represents the disk file and assign to output stream
- PrintStream er = new PrintStream("ErdosRenyiTest.txt");
- System.setOut(er);
-
- // ERDOS-RENYI
- Graph erdosRenyi = GraphGenerator.erdosRenyi(5, 0.5);
- Tuple erdosRenyiNE = new Tuple(erdosRenyi, states);
-
- System.out.println(" *** ERDOS-RENYI GRAPH ***\n\n" + erdosRenyi + "Numbers of equations of each size: "
- + Arrays.toString(erdosRenyiNE.findNumbers(erdosRenyiNE.getTuples())) + "\n");
- Equations.generateEquations(erdosRenyiNE).forEach(System.out::println);
- }
}
diff --git a/src/io/github/ethankelly/Graph.java b/src/io/github/ethankelly/Graph.java
index 7feea65..9519210 100644
--- a/src/io/github/ethankelly/Graph.java
+++ b/src/io/github/ethankelly/Graph.java
@@ -23,6 +23,8 @@
* @author Ethan Kelly
*/
public class Graph {
+
+ private String name;
private int numVertices;
private int numEdges;
private boolean[][] adjMatrix;
@@ -33,10 +35,11 @@ public class Graph {
*
* @param numVertices the number of vertices to create in the graph.
*/
- public Graph(int numVertices) {
+ public Graph(int numVertices, String name) {
this.numVertices = numVertices;
this.adjMatrix = new boolean[numVertices][numVertices];
this.transmissionMatrix = new int[numVertices][numVertices];
+ this.name = name;
}
/**
@@ -244,4 +247,13 @@ public int[][] getTransmissionMatrix() {
public void setTransmissionMatrix(int[][] transmissionMatrix) {
this.transmissionMatrix = transmissionMatrix;
}
+
+ public Graph setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String getName() {
+ return this.name;
+ }
}
diff --git a/src/io/github/ethankelly/GraphGenerator.java b/src/io/github/ethankelly/GraphGenerator.java
index 03388c8..1777b9a 100644
--- a/src/io/github/ethankelly/GraphGenerator.java
+++ b/src/io/github/ethankelly/GraphGenerator.java
@@ -1,5 +1,10 @@
package io.github.ethankelly;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.InputMismatchException;
+import java.util.Scanner;
import java.util.stream.IntStream;
/**
@@ -20,7 +25,7 @@ public class GraphGenerator {
*/
public static Graph getToastGraph() {
// TOAST
- Graph toast = new Graph(4);
+ Graph toast = new Graph(4, "Toast");
toast.addEdge(0, 1);
toast.addEdge(0, 2);
toast.addEdge(0, 3);
@@ -34,7 +39,7 @@ public static Graph getToastGraph() {
*/
public static Graph getLollipopGraph() {
// LOLLIPOP
- Graph lollipop = new Graph(4);
+ Graph lollipop = new Graph(4, "Lollipop");
lollipop.addEdge(0, 1);
lollipop.addEdge(0, 2);
lollipop.addEdge(0, 3);
@@ -47,13 +52,233 @@ public static Graph getLollipopGraph() {
*/
public static Graph getTriangleGraph() {
// TRIANGLE
- Graph triangle = new Graph(3);
+ Graph triangle = new Graph(3, "Triangle");
triangle.addEdge(0, 1);
triangle.addEdge(1, 2);
triangle.addEdge(2, 0);
return triangle;
}
+ static String[] getUserInput() {
+ Scanner scan = new Scanner(System.in);
+ String[] arguments = new String[5];
+
+ getUserStates(scan, arguments);
+ getUserGraphSelection(scan, arguments);
+
+ System.out.println("Thanks! Generating equations now...");
+
+ scan.close();
+ return arguments;
+ }
+
+ private static void getUserGraphSelection(Scanner scan, String[] arguments) {
+ System.out.println("Now, select a graph. Type \"help\" to see the list of graphs that can be randomly generated.");
+
+ if (scan.nextLine().equalsIgnoreCase("help")) {
+ System.out.println("""
+ Enter any of the following currently available graph types for generation:
+ 1. Toast
+ 2. Triangle
+ 3. Lollipop
+ 4. Simple
+ 5. Erdős–Rényi
+ 6. Complete
+ 7. Bipartite
+ 8. Complete Bipartite
+ 9. Path
+ 10. Binary Tree
+ 11. Cycle
+ 12. Eulerian Path
+ 13. Eulerian Cycle
+ 14. Wheel
+ 15. Star
+ 16. Regular
+ 17. Tree
+ Please enter either the number corresponding to the desired graph type or the name of the graph.""");
+ }
+
+ try {
+ arguments[1] = scan.nextLine();
+ } catch (InputMismatchException e) {
+ System.out.println("You should have entered either an integer or graph name.");
+ e.printStackTrace();
+ }
+ // 1, 2 and 3 don't require further input
+ if (!arguments[1].equalsIgnoreCase("toast") &&
+ !arguments[1].equalsIgnoreCase("triangle") &&
+ !arguments[1].equalsIgnoreCase("lollipop") &&
+ !arguments[1].equals("1") && !arguments[1].equals("2") && !arguments[1].equals("3")) {
+ // 6, 9, 10, 11, 14, 15, 17 just need vertices
+ System.out.println("Please enter the desired number of vertices in your selected graph.");
+ try {
+ arguments[2] = scan.nextLine();
+ } catch (InputMismatchException e) {
+ System.out.println("You should have entered an integer number of vertices.");
+ e.printStackTrace();
+ }
+ // 7 and 8 need two sets of vertices
+ if (arguments[1].equalsIgnoreCase("bipartite") || arguments[1].equals("7") ||
+ arguments[1].equalsIgnoreCase("complete bipartite") || arguments[1].equals("8")) {
+ System.out.println("Please enter the number of vertices for the first partition.");
+ try {
+ arguments[2] = scan.nextLine();
+ } catch (InputMismatchException e) {
+ System.out.println("You should have entered an integer number of vertices.");
+ e.printStackTrace();
+ }
+ System.out.println("Please enter the number of vertices for the second partition.");
+ try {
+ arguments[3] = scan.nextLine();
+ } catch (InputMismatchException e) {
+ System.out.println("You should have entered an integer number of vertices.");
+ e.printStackTrace();
+ }
+ // 7 further needs a number of edges
+ if (arguments[1].equalsIgnoreCase("bipartite") || arguments[1].equals("7")) {
+ System.out.println("Please enter the desired number of edges in your selected graph.");
+ try {
+ arguments[4] = scan.nextLine();
+ } catch (InputMismatchException e) {
+ System.out.println("You should have entered an integer number of edges.");
+ e.printStackTrace();
+ }
+ }
+ // 4, 12 and 13 need vertices and edges
+ } else if (arguments[1].equalsIgnoreCase("simple") || arguments[1].equals("4") ||
+ arguments[1].equalsIgnoreCase("eulerian path") || arguments[1].equals("12") ||
+ arguments[1].equalsIgnoreCase("eulerian cycle") || arguments[1].equals("13")) {
+ System.out.println("Please enter the desired number of edges in your selected graph.");
+ try {
+ arguments[3] = scan.nextLine();
+ } catch (InputMismatchException e) {
+ System.out.println("You should have entered an integer number of edges.");
+ e.printStackTrace();
+ }
+ // 16 needs a value for k
+ } else if (arguments[1].equalsIgnoreCase("regular") || arguments[1].equals("16")) {
+ System.out.println("Please enter the value of k for the k-regular graph.");
+ try {
+ arguments[3] = scan.nextLine();
+ } catch (InputMismatchException e) {
+ System.out.println("You should have entered an integer number.");
+ e.printStackTrace();
+ }
+ } else if (arguments[1].equalsIgnoreCase("erdos renyi") ||
+ arguments[1].equalsIgnoreCase("erdős rényi") || arguments[1].equals("5")) {
+ System.out.println("Please enter a probability for the Erdős-Rényi graph.");
+ try {
+ arguments[3] = scan.nextLine();
+ } catch (InputMismatchException e) {
+ System.out.println("You should have entered a decimal number.");
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private static void getUserStates(Scanner scan, String[] arguments) {
+ System.out.println("""
+
+ *** COMPARTMENTAL GRAPH MODEL EQUATIONS GENERATOR ***
+
+ Welcome to the Equations Generation program. This software generates the full system of differential
+ equations required to describe a particular compartmental model of disease on a specified graph. A text
+ file will be generated in the same directory as you are running this software from. If you choose to run
+ the jar again, this text file will be overwritten unless you move it elsewhere or delete it.
+
+ To begin, please enter the states required in the model. Currently, this can be either of:
+ * SIR
+ * SIRP
+ where S represents Susceptible, I is Infected, R is Recovered and P is Protected.""");
+ try {
+ arguments[0] = scan.nextLine();
+ } catch (InputMismatchException e) {
+ System.out.println("You should have entered characters representing the required states.");
+ e.printStackTrace();
+ }
+ }
+
+ static Graph getGraph(String[] args) {
+ Graph graph;
+ switch (args[1].toLowerCase()) {
+ case "1", "toast" -> graph = getToastGraph();
+ case "2", "triangle" -> graph = getTriangleGraph();
+ case "3", "lollipop" -> graph = getLollipopGraph();
+ case "4", "simple" -> {
+ // Requires number of vertices and number of edges
+ int[] parsed = parseIntegers(new String[] {args[2], args[3]});
+ graph = simple(parsed[0], parsed[1]);
+ }
+ case "5", "erdos renyi", "erdős rényi", "er" -> {
+ // Requires number of vertices and a probability
+ int numVertices = parseIntegers(new String[] {args[2]})[0];
+ double p = parseDoubles(new String[] {args[3]})[0];
+ graph = erdosRenyi(numVertices, p);
+ }
+ case "6", "complete" -> graph = complete(parseIntegers(new String[] {args[2]})[0]);
+ case "7", "bipartite" -> {
+ // Requires 2 numbers of vertices and a number of edges
+ int[] parsed = parseIntegers(new String[] {args[2], args[3], args[4]});
+ graph = bipartite(parsed[0], parsed[1], parsed[2]);
+ }
+ case "8", "complete bipartite" -> {
+ // Requires 2 numbers of vertices
+ int[] parsed = parseIntegers(new String[] {args[2], args[3]});
+ graph = completeBipartite(parsed[0], parsed[1]);
+ }
+ case "9", "path" -> graph = path(parseIntegers(new String[] {args[2]})[0]);
+ case "10", "binary tree" -> graph = binaryTree(parseIntegers(new String[] {args[2]})[0]);
+ case "11", "cycle" -> graph = cycle(parseIntegers(new String[] {args[2]})[0]);
+ case "12", "eulerian path" -> {
+ // Requires number of vertices and number of edges
+ int[] parsed = parseIntegers(new String[] {args[2], args[3]});
+ graph = eulerianPath(parsed[0], parsed[1]);
+ }
+ case "13", "eulerian cycle" -> {
+ // Requires number of vertices and number of edges
+ int[] parsed = parseIntegers(new String[] {args[2], args[3]});
+ graph = eulerianCycle(parsed[0], parsed[1]);
+ }
+ case "14", "wheel" -> graph = wheel(parseIntegers(new String[] {args[2]})[0]);
+ case "15", "star" -> graph = star(parseIntegers(new String[] {args[2]})[0]);
+ case "16", "regular" -> {
+ // Requires number of vertices and value of k
+ int[] parsed = parseIntegers(new String[] {args[2], args[3]});
+ graph = regular(parsed[0], parsed[1]);
+ }
+ case "17", "tree" -> graph = tree(parseIntegers(new String[] {args[2]})[0]);
+ default -> throw new IllegalStateException("Unexpected graph type: " + args[1].toLowerCase());
+ }
+ return graph;
+ }
+
+ public static int[] parseIntegers(String[] args) {
+ int[] toReturn = new int[args.length];
+ for (int i = 0; i < args.length; i++) {
+ try {
+ toReturn[i] = Integer.parseInt(args[i]);
+ } catch (NumberFormatException e) {
+ System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
+ System.out.println("Could not parse integer: " + e);
+ }
+ }
+ return toReturn;
+ }
+
+ public static double[] parseDoubles(String[] args) {
+ double[] toReturn = new double[args.length];
+ for (int i = 0; i < args.length; i++) {
+ try {
+ toReturn[i] = Double.parseDouble(args[i]);
+ } catch (NumberFormatException e) {
+ System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
+ System.out.println("Could not parse double: " + e);
+ }
+ }
+ return toReturn;
+ }
+
/**
* The Edge class is used to represent an edge as a pair of vertex locations (v, w) where v < w, between which the
* edge exists.
@@ -110,7 +335,7 @@ public int compareTo(Edge that) {
public static Graph simple(int numVertices, int numEdges) {
assert numEdges <= numVertices * (numVertices - 1) / 2 : "Too many edges.";
assert numEdges >= 0 : "Too few edges.";
- Graph g = new Graph(numVertices);
+ Graph g = new Graph(numVertices, "Simple");
g.setNumEdges(0);
Set set = new Set<>();
while (g.getNumEdges() < numEdges) {
@@ -137,7 +362,7 @@ public static Graph simple(int numVertices, int numEdges) {
*/
public static Graph erdosRenyi(int numVertices, double probability) {
assert !(probability < 0.0) && !(probability > 1.0) : "Probability must be between 0 and 1";
- Graph g = new Graph(numVertices);
+ Graph g = new Graph(numVertices, "Erdős–Rényi");
for (int v = 0; v < numVertices; v++)
for (int w = v + 1; w < numVertices; w++)
if (StdRandom.bernoulli(probability))
@@ -153,7 +378,7 @@ public static Graph erdosRenyi(int numVertices, double probability) {
* @return the complete graph on the given number of vertices.
*/
public static Graph complete(int numVertices) {
- return erdosRenyi(numVertices, 1.0);
+ return erdosRenyi(numVertices, 1.0).setName("Complete");
}
/**
@@ -167,7 +392,7 @@ public static Graph complete(int numVertices) {
* @return a complete bipartite graph on {@code numVer1} and {@code numVer2} vertices.
*/
public static Graph completeBipartite(int numVer1, int numVer2) {
- return bipartite(numVer1, numVer2, numVer1 * numVer2);
+ return bipartite(numVer1, numVer2, numVer1 * numVer2).setName("Complete Bipartite");
}
/**
@@ -184,7 +409,7 @@ public static Graph completeBipartite(int numVer1, int numVer2) {
public static Graph bipartite(int numVer1, int numVer2, int numEdges) {
assert numEdges <= numVer1 * numVer2 : "Too many edges";
assert numEdges >= 0 : "Too few edges";
- Graph g = new Graph(numVer1 + numVer2);
+ Graph g = new Graph(numVer1 + numVer2, "Bipartite");
int[] vertices = IntStream.range(0, numVer1 + numVer2).toArray();
StdRandom.shuffle(vertices);
@@ -217,7 +442,7 @@ public static Graph bipartite(int numVer1, int numVer2, double probability) {
assert !(probability < 0.0) && !(probability > 1.0) : "Probability must be between 0 and 1";
int[] vertices = IntStream.range(0, numVer1 + numVer2).toArray();
StdRandom.shuffle(vertices);
- Graph G = new Graph(numVer1 + numVer2);
+ Graph G = new Graph(numVer1 + numVer2, "Bipartite");
for (int i = 0; i < numVer1; i++)
for (int j = 0; j < numVer2; j++)
if (StdRandom.bernoulli(probability))
@@ -233,7 +458,7 @@ public static Graph bipartite(int numVer1, int numVer2, double probability) {
* @return a path graph on {@code numVertices} vertices
*/
public static Graph path(int numVertices) {
- Graph g = new Graph(numVertices);
+ Graph g = new Graph(numVertices, "Path");
// Generate an array: [0, 1, ..., numVertices] and randomly shuffle it.
int[] vertices = IntStream.range(0, numVertices).toArray();
StdRandom.shuffle(vertices);
@@ -253,7 +478,7 @@ public static Graph path(int numVertices) {
* @return a complete binary tree graph on {@code numVertices} vertices
*/
public static Graph binaryTree(int numVertices) {
- Graph g = new Graph(numVertices);
+ Graph g = new Graph(numVertices, "Binary Tree");
// Generate an array: [0, 1, ..., numVertices] and randomly shuffle it.
int[] vertices = IntStream.range(0, numVertices).toArray();
StdRandom.shuffle(vertices);
@@ -273,7 +498,7 @@ public static Graph binaryTree(int numVertices) {
* @return a cycle graph on {@code numVertices} vertices.
*/
public static Graph cycle(int numVertices) {
- Graph g = new Graph(numVertices);
+ Graph g = new Graph(numVertices, "Cycle");
// Generate an array: [0, 1, ..., numVertices] and randomly shuffle it.
int[] vertices = IntStream.range(0, numVertices).toArray();
StdRandom.shuffle(vertices);
@@ -299,7 +524,7 @@ public static Graph eulerianPath(int numVertices, int numEdges) {
// Catch incorrect input of number of edges or vertices
assert numEdges >= 0 : "negative number of edges";
assert numVertices > 0 : "An Eulerian path must have at least one vertex";
- Graph g = new Graph(numVertices);
+ Graph g = new Graph(numVertices, "Eulerian Path");
// Fill an array of length equal to the number of edges with uniformly random values
int[] vertices = IntStream.range(0, numEdges + 1).map(i -> StdRandom.uniform(numVertices)).toArray();
// Connect consecutive (i, i+1) vertices
@@ -319,7 +544,7 @@ public static Graph eulerianPath(int numVertices, int numEdges) {
public static Graph eulerianCycle(int numVertices, int numEdges) {
assert numEdges > 0 : "An Eulerian cycle must have at least one edge";
assert numVertices > 0 : "An Eulerian cycle must have at least one vertex";
- Graph G = new Graph(numVertices);
+ Graph G = new Graph(numVertices, "Eulerian Cycle");
// Fill an array of length equal to the number of edges with uniformly random values
int[] vertices = IntStream.range(0, numEdges).map(i -> StdRandom.uniform(numVertices)).toArray();
// Connect consecutive (i, i+1) vertices
@@ -339,7 +564,7 @@ public static Graph eulerianCycle(int numVertices, int numEdges) {
*/
public static Graph wheel(int numVertices) {
assert numVertices > 1 : "Number of vertices must be at least 2";
- Graph g = new Graph(numVertices);
+ Graph g = new Graph(numVertices, "Wheel");
// Generate an array: [0, 1, ..., numVertices] and randomly shuffle it.
int[] vertices = IntStream.range(0, numVertices).toArray();
StdRandom.shuffle(vertices);
@@ -364,7 +589,7 @@ public static Graph wheel(int numVertices) {
*/
public static Graph star(int numVertices) {
assert numVertices > 0 : "Number of vertices must be at least 1";
- Graph g = new Graph(numVertices);
+ Graph g = new Graph(numVertices, "Star");
// Generate an array: [0, 1, ..., numVertices] and randomly shuffle it.
int[] vertices = IntStream.range(0, numVertices).toArray();
StdRandom.shuffle(vertices);
@@ -387,7 +612,7 @@ public static Graph star(int numVertices) {
*/
public static Graph regular(int numVertices, int k) {
assert numVertices * k % 2 == 0 : "Number of vertices * k must be even";
- Graph g = new Graph(numVertices);
+ Graph g = new Graph(numVertices, k + "-Regular");
// Create k copies of each vertex
int[] vertices = new int[numVertices * k];
@@ -412,7 +637,7 @@ public static Graph regular(int numVertices, int k) {
* @return a uniformly random tree on {@code numVertices} vertices.
*/
public static Graph tree(int numVertices) {
- Graph g = new Graph(numVertices);
+ Graph g = new Graph(numVertices, "Tree");
if (numVertices == 1) return g;
diff --git a/src/io/github/ethankelly/Main.java b/src/io/github/ethankelly/Main.java
index 83189eb..1f84dd1 100644
--- a/src/io/github/ethankelly/Main.java
+++ b/src/io/github/ethankelly/Main.java
@@ -1,61 +1,31 @@
package io.github.ethankelly;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Arrays;
public class Main {
- /**
- * Takes command-line args to generate equations for a compartmental model on a specified graph.
- *
- * @param args command-line args
- * @throws FileNotFoundException if the files cannot be written to.
- */
- public static void main(String[] args) throws FileNotFoundException {
- // Creating a File object that represents the disk file and assign to output stream
- PrintStream o = new PrintStream("data/Tuples.txt");
- System.setOut(o);
+ /**
+ * Takes command-line args to generate equations for a compartmental model on a specified graph.
+ *
+ * @param args command-line args
+ * @throws FileNotFoundException if the files cannot be written to.
+ */
+ public static void main(String[] args) throws FileNotFoundException {
+ String[] arguments = GraphGenerator.getUserInput();
+ char[] states = arguments[0].toUpperCase().toCharArray();
+ Graph graph = GraphGenerator.getGraph(arguments);
+ Tuple tuples = new Tuple(graph, states);
- char[] states = args[0].toUpperCase().toCharArray();
- Graph graph;
- Tuple tuples;
+ // Creating a File object that represents the disk file and assign to output stream
+ PrintStream o = new PrintStream(new FileOutputStream("Equations.txt"));
+ System.setOut(o);
+ System.out.println(" *** Equations for an " + arguments[0].toUpperCase() + " model on a " + graph.getName()
+ + " Graph ***\n\n" + graph + "Numbers of equations of each size: "
+ + Arrays.toString(tuples.findNumbers(tuples.getTuples())) + "\n");
+ Equations.generateEquations(tuples).forEach(System.out::println);
+ }
- switch(args[1].toLowerCase()) {
- case "toast" -> {
- graph = GraphGenerator.getToastGraph();
- tuples = new Tuple(graph, states);
- }
- case "triangle" -> {
- graph = GraphGenerator.getTriangleGraph();
- tuples = new Tuple(graph, states);
- }
- case "lollipop" -> {
- graph = GraphGenerator.getLollipopGraph();
- tuples = new Tuple(graph, states);
- }
- case "erdos-renyi" -> {
- int numVertices = 0;
- try {
- numVertices = Integer.parseInt(args[1]);
- } catch (NumberFormatException e) {
- System.out.println("Second argument should have been an integer");
- }
-
- double p = 0;
- try {
- p = Double.parseDouble(args[2]);
- } catch (NumberFormatException e) {
- System.out.println("Third argument should have been a double");
- }
- graph = GraphGenerator.erdosRenyi(numVertices, p);
- tuples = new Tuple(graph, states);
- }
- default -> throw new IllegalStateException("Unexpected value: " + args[1].toLowerCase());
- }
-
- System.out.println(" *** " + args[1].toUpperCase() + " GRAPH ***\n\n" + graph +
- "Numbers of equations of each size: " + Arrays.toString(tuples.findNumbers(tuples.getTuples())) + "\n");
- tuples.getTuples().forEach(System.out::println);
- }
}