diff options
Diffstat (limited to 'base/src/main/java/bjc/utils/graph')
| -rw-r--r-- | base/src/main/java/bjc/utils/graph/AdjacencyMap.java | 47 | ||||
| -rw-r--r-- | base/src/main/java/bjc/utils/graph/Edge.java | 33 | ||||
| -rw-r--r-- | base/src/main/java/bjc/utils/graph/Graph.java | 62 |
3 files changed, 60 insertions, 82 deletions
diff --git a/base/src/main/java/bjc/utils/graph/AdjacencyMap.java b/base/src/main/java/bjc/utils/graph/AdjacencyMap.java index e046fb5..978b21d 100644 --- a/base/src/main/java/bjc/utils/graph/AdjacencyMap.java +++ b/base/src/main/java/bjc/utils/graph/AdjacencyMap.java @@ -6,12 +6,12 @@ import java.io.PrintStream; import java.util.InputMismatchException; import java.util.Scanner; -import bjc.data.IHolder; +import bjc.data.Holder; import bjc.data.Identity; import bjc.funcdata.FunctionalList; import bjc.funcdata.FunctionalMap; -import bjc.funcdata.IList; -import bjc.funcdata.IMap; +import bjc.funcdata.ListEx; +import bjc.funcdata.MapEx; import bjc.utils.funcutils.FuncUtils; /** @@ -32,8 +32,7 @@ public class AdjacencyMap<T> { * @return An adjacency map defined by the text */ public static AdjacencyMap<Integer> fromStream(final InputStream stream) { - if (stream == null) - throw new NullPointerException("Input source must not be null"); + if (stream == null) throw new NullPointerException("Input source must not be null"); /* Create the adjacency map. */ AdjacencyMap<Integer> adjacency; @@ -60,17 +59,16 @@ public class AdjacencyMap<T> { throw imex; } - if (vertexCount <= 0) - throw new InputMismatchException( + if (vertexCount <= 0) throw new InputMismatchException( "The number of vertices must be greater than 0"); - final IList<Integer> vertices = new FunctionalList<>(); + final ListEx<Integer> vertices = new FunctionalList<>(); FuncUtils.doTimes(vertexCount, vertexNo -> vertices.add(vertexNo)); adjacency = new AdjacencyMap<>(vertices); - final IHolder<Integer> row = new Identity<>(0); + final Holder<Integer> row = new Identity<>(0); input.forEachRemaining(strang -> { readRow(adjacency, vertexCount, row, strang); @@ -82,7 +80,7 @@ public class AdjacencyMap<T> { /* Read a row of edges. */ private static void readRow(final AdjacencyMap<Integer> adjacency, - final int vertexCount, final IHolder<Integer> row, final String strang) { + final int vertexCount, final Holder<Integer> row, final String strang) { final String[] parts = strang.split(" "); if (parts.length != vertexCount) { @@ -117,7 +115,7 @@ public class AdjacencyMap<T> { } /** The backing storage of the map */ - private final IMap<T, IMap<T, Integer>> adjacency = new FunctionalMap<>(); + private final MapEx<T, MapEx<T, Integer>> adjacency = new FunctionalMap<>(); /** * Create a new map from a set of vertices @@ -125,12 +123,11 @@ public class AdjacencyMap<T> { * @param vertices * The set of vertices to create a map from */ - public AdjacencyMap(final IList<T> vertices) { - if (vertices == null) - throw new NullPointerException("Vertices must not be null"); + public AdjacencyMap(final ListEx<T> vertices) { + if (vertices == null) throw new NullPointerException("Vertices must not be null"); vertices.forEach(vertex -> { - final IMap<T, Integer> row = new FunctionalMap<>(); + final MapEx<T, Integer> row = new FunctionalMap<>(); vertices.forEach(target -> { row.put(target, 0); @@ -146,15 +143,13 @@ public class AdjacencyMap<T> { * @return Whether or not the graph is directed */ public boolean isDirected() { - final IHolder<Boolean> result = new Identity<>(true); + final Holder<Boolean> result = new Identity<>(true); adjacency.forEach((sourceKey, sourceValue) -> { sourceValue.forEach((targetKey, targetValue) -> { - final int inverseValue = adjacency.get(targetKey).get(sourceKey); + final int inverseValue = adjacency.get(targetKey).get().get(sourceKey).get(); - if (targetValue != inverseValue) { - result.replace(false); - } + if (targetValue != inverseValue) result.replace(false); }); }); @@ -172,11 +167,8 @@ public class AdjacencyMap<T> { * The weight of the edge. */ public void setWeight(final T source, final T target, final int weight) { - if (source == null) { - throw new NullPointerException("Source vertex must not be null"); - } else if (target == null) { - throw new NullPointerException("Target vertex must not be null"); - } + if (source == null) throw new NullPointerException("Source vertex must not be null"); + else if (target == null) throw new NullPointerException("Target vertex must not be null"); if (!adjacency.containsKey(source)) { String msg = String.format("Source vertex %s isn't present in map", source); @@ -188,7 +180,7 @@ public class AdjacencyMap<T> { throw new IllegalArgumentException(msg); } - adjacency.get(source).put(target, weight); + adjacency.get(source).get().put(target, weight); } /** @@ -215,8 +207,7 @@ public class AdjacencyMap<T> { * The stream to convert to. */ public void toStream(final OutputStream sink) { - if (sink == null) - throw new NullPointerException("Output source must not be null"); + if (sink == null) throw new NullPointerException("Output source must not be null"); final PrintStream outputPrinter = new PrintStream(sink); diff --git a/base/src/main/java/bjc/utils/graph/Edge.java b/base/src/main/java/bjc/utils/graph/Edge.java index fe3d891..b48fcd0 100644 --- a/base/src/main/java/bjc/utils/graph/Edge.java +++ b/base/src/main/java/bjc/utils/graph/Edge.java @@ -28,11 +28,8 @@ public class Edge<T> { * The distance between initial and terminal edge. */ public Edge(final T initial, final T terminal, final int distance) { - if (initial == null) { - throw new NullPointerException("Initial node must not be null"); - } else if (terminal == null) { - throw new NullPointerException("Terminal node must not be null"); - } + if (initial == null) throw new NullPointerException("Initial node must not be null"); + else if (terminal == null) throw new NullPointerException("Terminal node must not be null"); this.source = initial; this.target = terminal; @@ -41,27 +38,23 @@ public class Edge<T> { @Override public boolean equals(final Object obj) { - if (this == obj) - return true; - else if (obj == null) - return false; - else if (getClass() != obj.getClass()) - return false; + if (this == obj) return true; + else if (obj == null) return false; + else if (getClass() != obj.getClass()) return false; else { final Edge<?> other = (Edge<?>) obj; - if (distance != other.distance) + if (distance != other.distance) { return false; - else if (source == null) { - if (other.source != null) - return false; - } else if (!source.equals(other.source)) + } else if (source == null) { + if (other.source != null) return false; + } else if (!source.equals(other.source)) { return false; - else if (target == null) { - if (other.target != null) - return false; - } else if (!target.equals(other.target)) + } else if (target == null) { + if (other.target != null) return false; + } else if (!target.equals(other.target)) { return false; + } return true; } diff --git a/base/src/main/java/bjc/utils/graph/Graph.java b/base/src/main/java/bjc/utils/graph/Graph.java index 8ff5647..f32e07f 100644 --- a/base/src/main/java/bjc/utils/graph/Graph.java +++ b/base/src/main/java/bjc/utils/graph/Graph.java @@ -10,11 +10,11 @@ import java.util.Set; import java.util.function.BiConsumer; import java.util.function.BiPredicate; -import bjc.data.IHolder; +import bjc.data.Holder; import bjc.data.Identity; import bjc.funcdata.FunctionalMap; -import bjc.funcdata.IList; -import bjc.funcdata.IMap; +import bjc.funcdata.ListEx; +import bjc.funcdata.MapEx; /** * A directed weighted graph, where the vertices have some arbitrary label. @@ -47,7 +47,7 @@ public class Graph<T> { } /** The backing representation of the graph. */ - private final IMap<T, IMap<T, Integer>> backing; + private final MapEx<T, MapEx<T, Integer>> backing; /** Create a new empty graph. */ public Graph() { @@ -72,19 +72,14 @@ public class Graph<T> { public void addEdge(final T source, final T target, final int distance, final boolean directed) { /* Can't add edges with a null source or target. */ - if (source == null) { - throw new NullPointerException("The source vertex cannot be null"); - } else if (target == null) { - throw new NullPointerException("The target vertex cannot be null"); - } + if (source == null) throw new NullPointerException("The source vertex cannot be null"); + else if (target == null) throw new NullPointerException("The target vertex cannot be null"); /* Initialize adjacency list for vertices if necessary. */ - if (!backing.containsKey(source)) { - backing.put(source, new FunctionalMap<T, Integer>()); - } + if (!backing.containsKey(source)) backing.put(source, new FunctionalMap<T, Integer>()); /* Add the edge to the graph. */ - backing.get(source).put(target, distance); + backing.get(source).get().put(target, distance); /* Handle possible directed edges. */ if (!directed) { @@ -92,7 +87,7 @@ public class Graph<T> { backing.put(target, new FunctionalMap<T, Integer>()); } - backing.get(target).put(source, distance); + backing.get(target).get().put(source, distance); } } @@ -110,16 +105,11 @@ public class Graph<T> { */ public void forAllEdgesMatchingAt(final T source, final BiPredicate<T, Integer> matcher, final BiConsumer<T, Integer> action) { - if (matcher == null) { - throw new NullPointerException("Matcher must not be null"); - } else if (action == null) { - throw new NullPointerException("Action must not be null"); - } + if (matcher == null) throw new NullPointerException("Matcher must not be null"); + else if (action == null) throw new NullPointerException("Action must not be null"); getEdges(source).forEach((target, weight) -> { - if (matcher.test(target, weight)) { - action.accept(target, weight); - } + if (matcher.test(target, weight)) action.accept(target, weight); }); } @@ -130,14 +120,15 @@ public class Graph<T> { * The vertex to use as a source. * @return All of the edges with the specified vertex as a source. */ - public IMap<T, Integer> getEdges(final T source) { + public MapEx<T, Integer> getEdges(final T source) { /* Can't find edges for a null source. */ - if (source == null) + if (source == null) { throw new NullPointerException("The source cannot be null."); - else if (!backing.containsKey(source)) + } else if (!backing.containsKey(source)) { throw new IllegalArgumentException("Vertex " + source + " is not in graph"); + } - return backing.get(source); + return backing.get(source).get(); } /** @@ -168,7 +159,7 @@ public class Graph<T> { final Set<T> visited = new HashSet<>(); /* Start at the initial vertex and visit it */ - final IHolder<T> source = new Identity<>(getInitial()); + final Holder<T> source = new Identity<>(getInitial()); visited.add(source.getValue()); @@ -176,14 +167,17 @@ public class Graph<T> { while (visited.size() != getVertexCount()) { /* Grab all edges adjacent to the provided edge. */ - forAllEdgesMatchingAt(source.getValue(), (target, weight) -> !visited.contains(target), (target, weight) -> { - final T vert = source.unwrap(vertex -> vertex); + forAllEdgesMatchingAt(source.getValue(), + (target, weight) -> !visited.contains(target), + (target, weight) -> { + final T vert = source.unwrap(vertex -> vertex); - available.add(new Edge<>(vert, target, weight)); - }); + available.add(new Edge<>(vert, target, weight)); + } + ); /* Get the edge with the minimum distance. */ - final IHolder<Edge<T>> minimum = new Identity<>(available.poll()); + final Holder<Edge<T>> minimum = new Identity<>(available.poll()); /* * Only consider edges where we haven't visited the target of the edge. @@ -219,7 +213,7 @@ public class Graph<T> { * * @return A unmodifiable set of all the vertices in the graph. */ - public IList<T> getVertices() { + public ListEx<T> getVertices() { return backing.keyList(); } @@ -253,7 +247,7 @@ public class Graph<T> { throw new NoSuchElementException(msg); } - backing.get(source).remove(target); + backing.get(source).get().remove(target); /* * Uncomment this to turn the graph undirected |
