aboutsummaryrefslogtreecommitdiff
path: root/src/dk.biks.bachelorizer/dk/biks/bachelorizer/Combi.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/dk.biks.bachelorizer/dk/biks/bachelorizer/Combi.java')
-rw-r--r--src/dk.biks.bachelorizer/dk/biks/bachelorizer/Combi.java105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/dk.biks.bachelorizer/dk/biks/bachelorizer/Combi.java b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/Combi.java
new file mode 100644
index 0000000..78a1ee0
--- /dev/null
+++ b/src/dk.biks.bachelorizer/dk/biks/bachelorizer/Combi.java
@@ -0,0 +1,105 @@
+// SPDX-FileCopyrightText: 2025 Jonas Smedegaard <dr@jones.dk>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package dk.biks.bachelorizer;
+
+import java.util.Collection;
+import java.util.Set;
+
+import com.example.portfolio3.AdjListGraph;
+import com.example.portfolio3.Graph;
+import com.example.portfolio3.GraphAlgorithms;
+import com.example.portfolio3.MatrixGraph;
+import com.example.portfolio3.Vertex;
+
+/// Combi - static sample dataset of course combinations
+///
+/// Slurps and parses data from upstream-provided comma-separated file.
+///
+/// @version 0.0.1
+/// @see <https://moodle.ruc.dk/mod/assign/view.php?id=523186>
+public final class Combi {
+
+ /// data about combinations as a Graph
+ private Graph g;
+
+ /// Default constructor
+ ///
+ /// @param path path to data file
+ private Combi(final String path) {
+
+ // read into temporary graph to resolve vertice count
+ //
+ // use Adjacency List Representation:
+ // * cheap to bootstrap (done once)
+ // * simple to count vertices (done once): O(1)
+ Graph _g = new AdjListGraph();
+ GraphAlgorithms.readGraph(_g, path);
+ Integer _vertice_count = _g.vertices().size();
+
+ // read into final graph
+ //
+ // use Adjacency Matrix Representation:
+ // * expensive to bootstrap (done once)
+ // * simple to add edges but needs vertice count
+ // * simple to get edges (done repeatedly): O(1)
+ //
+ // TODO: avoid reading and parsing file twice
+ Graph g = new MatrixGraph(_vertice_count);
+ GraphAlgorithms.readGraph(g, path);
+
+ // ensure the graph is connected
+ isConnected(g);
+
+ GraphAlgorithms.printGraph(g);
+
+ // release temporary variables for garbage collection
+ _g = null;
+ _vertice_count = null;
+ }
+
+ /// JVM entry point
+ ///
+ /// @param args command-line arguments
+ public static void main(final String[] args) {
+
+ // first argument, if provided, is the data file path;
+ // else use upstream named file in current directory.
+ String path = (args.length > 0)
+ ? args[0]
+ : "combi.txt";
+
+ Combi combi = new Combi(path);
+ }
+
+ /// utility function to check that a graph is connected
+ ///
+ /// If check fails, throw an unchecked exception,
+ /// since it occurs at runtime and is unrecoverable.
+ ///
+ /// Time complexity of the operation is O(n²)
+ /// where n is the amount of vertices,
+ /// since visitDepthFirst() recurses out-edges of all vertices.
+ ///
+ /// @param g Graph to inspect
+ /// @throws IllegalArgumentException
+ /// https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html
+ public static void isConnected(Graph g) {
+
+ // collect all vertices in the graph
+ Collection<Vertex> c = g.vertices();
+
+ // pick a random vertice in the graph
+ Vertex v = g.vertices().iterator().next();
+
+ // collect the set of visitable vertices
+ Set<Vertex> visited = GraphAlgorithms.visitDepthFirst(
+ g, v);
+
+ // throw exception if not all vertices were visited
+ if (visited.size() != c.size()) {
+ throw new IllegalArgumentException(
+ "graph is not connected");
+ }
+ }
+}