diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2017-02-09 11:50:31 -0500 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2017-02-09 11:50:31 -0500 |
| commit | d2af58b0f68ebfbba2be7e7679efec6c8c0af12f (patch) | |
| tree | 2b16fbf014db350126e8c1b5f081312276f85f62 /BJC-Utils2/src/main/java/bjc/utils/graph | |
| parent | 187e1815488e3c1ed22e7592f304e632cffefb82 (diff) | |
Update
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/graph')
| -rw-r--r-- | BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java | 101 | ||||
| -rw-r--r-- | BJC-Utils2/src/main/java/bjc/utils/graph/Edge.java | 32 | ||||
| -rw-r--r-- | BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java | 142 |
3 files changed, 132 insertions, 143 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java b/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java index ff9103e..2f6d91a 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java @@ -37,22 +37,22 @@ public class AdjacencyMap<T> { } // Create the adjacency map - AdjacencyMap<Integer> adjacencyMap; + AdjacencyMap<Integer> adjacency; - try (Scanner inputSource = new Scanner(stream)) { - inputSource.useDelimiter("\n"); + try (Scanner input = new Scanner(stream)) { + input.useDelimiter("\n"); - int numVertices; + int vertexCount; - String possibleVertices = inputSource.next(); + String possible = input.next(); try { // First, read in number of vertices - numVertices = Integer.parseInt(possibleVertices); + vertexCount = Integer.parseInt(possible); } catch (NumberFormatException nfex) { InputMismatchException imex = new InputMismatchException( "The first line must contain the number of vertices. " - + possibleVertices + + possible + " is not a valid number"); imex.initCause(nfex); @@ -60,45 +60,44 @@ public class AdjacencyMap<T> { throw imex; } - if (numVertices <= 0) { + if (vertexCount <= 0) { throw new InputMismatchException( "The number of vertices must be greater than 0"); } IList<Integer> vertices = new FunctionalList<>(); - FuncUtils.doTimes(numVertices, - (vertexNo) -> vertices.add(vertexNo)); + FuncUtils.doTimes(vertexCount, (vertexNo) -> vertices.add(vertexNo)); - adjacencyMap = new AdjacencyMap<>(vertices); + adjacency = new AdjacencyMap<>(vertices); IHolder<Integer> row = new Identity<>(0); - inputSource.forEachRemaining((strang) -> { - readRow(adjacencyMap, numVertices, row, strang); + input.forEachRemaining((strang) -> { + readRow(adjacency, vertexCount, row, strang); }); } - return adjacencyMap; + return adjacency; } - private static void readRow(AdjacencyMap<Integer> adjacencyMap, - int numVertices, IHolder<Integer> row, String strang) { + private static void readRow(AdjacencyMap<Integer> adjacency, + int vertexCount, IHolder<Integer> row, String strang) { String[] parts = strang.split(" "); - if (parts.length != numVertices) { + if (parts.length != vertexCount) { throw new InputMismatchException( - "Must specify a weight for all " + numVertices + "Must specify a weight for all " + vertexCount + " vertices"); } int column = 0; for (String part : parts) { - int columnWeight; + int weight; try { - columnWeight = Integer.parseInt(part); + weight = Integer.parseInt(part); } catch (NumberFormatException nfex) { InputMismatchException imex = new InputMismatchException( "" + part + " is not a valid weight."); @@ -108,7 +107,7 @@ public class AdjacencyMap<T> { throw imex; } - adjacencyMap.setWeight(row.getValue(), column, columnWeight); + adjacency.setWeight(row.getValue(), column, weight); column++; } @@ -119,7 +118,7 @@ public class AdjacencyMap<T> { /** * The backing storage of the map */ - private IMap<T, IMap<T, Integer>> adjacencyMap = new FunctionalMap<>(); + private IMap<T, IMap<T, Integer>> adjacency = new FunctionalMap<>(); /** * Create a new map from a set of vertices @@ -133,13 +132,13 @@ public class AdjacencyMap<T> { } vertices.forEach(vertex -> { - IMap<T, Integer> vertexRow = new FunctionalMap<>(); + IMap<T, Integer> row = new FunctionalMap<>(); - vertices.forEach(targetVertex -> { - vertexRow.put(targetVertex, 0); + vertices.forEach(target -> { + row.put(target 0); }); - adjacencyMap.put(vertex, vertexRow); + adjacency.put(vertex, row); }); } @@ -151,9 +150,9 @@ public class AdjacencyMap<T> { public boolean isDirected() { IHolder<Boolean> result = new Identity<>(true); - adjacencyMap.forEach((key, value) -> { - value.forEach((targetKey, targetValue) -> { - int inverseValue = adjacencyMap.get(targetKey).get(key); + adjacency.forEach((sourceKey, sourceValue) -> { + sourceValue.forEach((targetKey, targetValue) -> { + int inverseValue = adjacency.get(targetKey).get(sourceKey); if (targetValue != inverseValue) { result.replace(false); @@ -167,31 +166,31 @@ public class AdjacencyMap<T> { /** * Set the weight of an edge * - * @param sourceVertex + * @param source * The source node of the edge - * @param targetVertex + * @param target * The target node of the edge - * @param edgeWeight + * @param weight * The weight of the edge */ - public void setWeight(T sourceVertex, T targetVertex, int edgeWeight) { - if (sourceVertex == null) { + public void setWeight(T source, T target int weight) { + if (source == null) { throw new NullPointerException( "Source vertex must not be null"); - } else if (targetVertex == null) { + } else if (target== null) { throw new NullPointerException( "Target vertex must not be null"); } - if (!adjacencyMap.containsKey(sourceVertex)) { + if (!adjacency.containsKey(source)) { throw new IllegalArgumentException("Source vertex " - + sourceVertex + " isn't present in map"); - } else if (!adjacencyMap.containsKey(targetVertex)) { + + source + " isn't present in map"); + } else if (!adjacency.containsKey(target) { throw new IllegalArgumentException("Target vertex " - + targetVertex + " isn't present in map"); + + target+ " isn't present in map"); } - adjacencyMap.get(sourceVertex).put(targetVertex, edgeWeight); + adjacency.get(source).put(target weight); } /** @@ -200,33 +199,33 @@ public class AdjacencyMap<T> { * @return The new representation of this graph */ public Graph<T> toGraph() { - Graph<T> returnedGraph = new Graph<>(); + Graph<T> ret = new Graph<>(); - adjacencyMap.forEach((key, value) -> { - value.forEach((targetKey, targetValue) -> { - returnedGraph.addEdge(key, targetKey, targetValue, true); + adjacency.forEach((sourceKey, sourceValue) -> { + sourceValue.forEach((targetKey, targetValue) -> { + ret.addEdge(sourceKey, targetKey, targetValue, true); }); }); - return returnedGraph; + return ret; } /** * Convert an adjacency map back into a stream * - * @param outputSink + * @param sink * The stream to convert to */ - public void toStream(OutputStream outputSink) { - if (outputSink == null) { + public void toStream(OutputStream sink) { + if (sink == null) { throw new NullPointerException( "Output source must not be null"); } - PrintStream outputPrinter = new PrintStream(outputSink); + PrintStream outputPrinter = new PrintStream(sink); - adjacencyMap.forEach((key, value) -> { - value.forEach((targetKey, targetValue) -> { + adjacency.forEach((sourceKey, sourceValue) -> { + sourceValue.forEach((targetKey, targetValue) -> { outputPrinter.printf("%d", targetValue); }); diff --git a/BJC-Utils2/src/main/java/bjc/utils/graph/Edge.java b/BJC-Utils2/src/main/java/bjc/utils/graph/Edge.java index fa34083..2ad4132 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/graph/Edge.java +++ b/BJC-Utils2/src/main/java/bjc/utils/graph/Edge.java @@ -9,12 +9,12 @@ package bjc.utils.graph; * The type of the nodes in the graph */ public class Edge<T> { - /** + /* * The distance from initial to terminal node */ private final int distance; - /** + /* * The initial and terminal nodes of this edge */ private final T source, target; @@ -22,32 +22,27 @@ public class Edge<T> { /** * Create a new edge with set parameters * - * @param initialNode + * @param initial * The initial node of the edge - * @param terminalNode + * @param terminal * The terminal node of the edge * @param distance * The distance between initial and terminal edge */ - public Edge(T initialNode, T terminalNode, int distance) { - if (initialNode == null) { + public Edge(T initial, T terminal, int distance) { + if (initial == null) { throw new NullPointerException( "Initial node must not be null"); - } else if (terminalNode == null) { + } else if (terminal == null) { throw new NullPointerException( "Terminal node must not be null"); } - this.source = initialNode; - this.target = terminalNode; + this.source = initial; + this.target = terminal; this.distance = distance; } - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ @Override public boolean equals(Object obj) { if (this == obj) { @@ -57,7 +52,6 @@ public class Edge<T> { } else if (getClass() != obj.getClass()) { return false; } else { - Edge<?> other = (Edge<?>) obj; if (distance != other.distance) { @@ -108,20 +102,18 @@ public class Edge<T> { return target; } - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ @Override public int hashCode() { final int prime = 31; + int result = 1; + result = prime * result + distance; result = prime * result + ((source == null) ? 0 : source.hashCode()); result = prime * result + ((target == null) ? 0 : target.hashCode()); + return result; } diff --git a/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java b/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java index 68d0ef1..66fe580 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java +++ b/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java @@ -49,55 +49,55 @@ public class Graph<T> { /** * The backing representation of the graph */ - private final IMap<T, IMap<T, Integer>> backingGraph; + private final IMap<T, IMap<T, Integer>> backing; /** * Create a new graph */ public Graph() { - backingGraph = new FunctionalMap<>(); + backing = new FunctionalMap<>(); } /** * Add a edge to the graph * - * @param sourceVertex + * @param source * The source vertex for this edge - * @param targetVertex + * @param target * The target vertex for this edge * @param distance * The distance from the source vertex to the target vertex * @param directed * Whether or not */ - public void addEdge(T sourceVertex, T targetVertex, int distance, + public void addEdge(T source, T target, int distance, boolean directed) { // Can't add edges with a null source or target - if (sourceVertex == null) { + if (source == null) { throw new NullPointerException( "The source vertex cannot be null"); - } else if (targetVertex == null) { + } else if (target == null) { throw new NullPointerException( "The target vertex cannot be null"); } // Initialize adjacency list for vertices if necessary - if (!backingGraph.containsKey(sourceVertex)) { - backingGraph.put(sourceVertex, + if (!backing.containsKey(source)) { + backing.put(source, new FunctionalMap<T, Integer>()); } // Add the edge to the graph - backingGraph.get(sourceVertex).put(targetVertex, distance); + backing.get(source).put(target, distance); // Handle possible directed edges if (!directed) { - if (!backingGraph.containsKey(targetVertex)) { - backingGraph.put(targetVertex, + if (!backing.containsKey(target)) { + backing.put(target, new FunctionalMap<T, Integer>()); } - backingGraph.get(targetVertex).put(sourceVertex, distance); + backing.get(target).put(source, distance); } } @@ -105,25 +105,25 @@ public class Graph<T> { * Execute an action for all edges of a specific vertex matching * conditions * - * @param sourceVertex + * @param source * The vertex to test edges for - * @param edgeMatcher + * @param matcher * The conditions an edge must match - * @param edgeAction + * @param action * The action to execute for matching edges */ - public void forAllEdgesMatchingAt(T sourceVertex, - BiPredicate<T, Integer> edgeMatcher, - BiConsumer<T, Integer> edgeAction) { - if (edgeMatcher == null) { + public void forAllEdgesMatchingAt(T source, + BiPredicate<T, Integer> matcher, + BiConsumer<T, Integer> action) { + if (matcher == null) { throw new NullPointerException("Matcher must not be null"); - } else if (edgeAction == null) { + } else if (action == null) { throw new NullPointerException("Action must not be null"); } - getEdges(sourceVertex).forEach((targetVertex, vertexWeight) -> { - if (edgeMatcher.test(targetVertex, vertexWeight)) { - edgeAction.accept(targetVertex, vertexWeight); + getEdges(source).forEach((target, weight) -> { + if (matcher.test(target, weight)) { + action.accept(target, weight); } }); } @@ -139,12 +139,12 @@ public class Graph<T> { // Can't find edges for a null source if (source == null) { throw new NullPointerException("The source cannot be null."); - } else if (!backingGraph.containsKey(source)) { + } else if (!backing.containsKey(source)) { throw new IllegalArgumentException( "Vertex " + source + " is not in graph"); } - return backingGraph.get(source); + return backing.get(source); } /** @@ -153,67 +153,65 @@ public class Graph<T> { * @return The initial vertex of the graph */ public T getInitial() { - return backingGraph.keyList().first(); + return backing.keyList().first(); } /** - * Uses Prim's algorothm to calculate a MST for the graph. If the graph - * is non-connected, this will lead to unpredictable results. + * Uses Prim's algorothm to calculate a MST for the graph. + * + * If the graph is non-connected, this will lead to unpredictable results. * * @return a list of edges that constitute the MST */ public List<Edge<T>> getMinimumSpanningTree() { // Set of all of the currently available edges - Queue<Edge<T>> availableEdges = new PriorityQueue<>(10, - (leftEdge, rightEdge) -> leftEdge.getDistance() - - rightEdge.getDistance()); + Queue<Edge<T>> available = new PriorityQueue<>(10, + (left, right) -> left.getDistance() - right.getDistance()); // The MST of the graph - List<Edge<T>> minimumEdges = new ArrayList<>(); + List<Edge<T>> minimums = new ArrayList<>(); // The set of all of the visited vertices. - Set<T> visitedVertexes = new HashSet<>(); + Set<T> visited = new HashSet<>(); // Start at the initial vertex and visit it - IHolder<T> sourceVertex = new Identity<>(getInitial()); + IHolder<T> source = new Identity<>(getInitial()); - visitedVertexes.add(sourceVertex.getValue()); + visited.add(source.getValue()); // Make sure we visit all the nodes - while (visitedVertexes.size() != getVertexCount()) { + while (visited.size() != getVertexCount()) { // Grab all edges adjacent to the provided edge - forAllEdgesMatchingAt(sourceVertex.getValue(), - (targetVertex, vertexWeight) -> { - return !visitedVertexes.contains(targetVertex); - }, (targetVertex, vertexWeight) -> { - availableEdges.add(new Edge<>( - sourceVertex.unwrap(vertex -> vertex), - targetVertex, vertexWeight)); + forAllEdgesMatchingAt(source.getValue(), + (target, weight) -> { + return !visited.contains(target); + }, (target, weight) -> { + available.add(new Edge<>( + source.unwrap(vertex -> vertex), + target, weight)); }); // Get the edge with the minimum distance - IHolder<Edge<T>> minimumEdge = new Identity<>( - availableEdges.poll()); + IHolder<Edge<T>> minimum = new Identity<>(available.poll()); // Only consider edges where we haven't visited the target of // the edge - while (visitedVertexes.contains(minimumEdge.getValue())) { - minimumEdge.transform((edge) -> availableEdges.poll()); + while (visited.contains(minimum.getValue())) { + minimum.transform((edge) -> available.poll()); } // Add it to our MST - minimumEdges.add(minimumEdge.getValue()); + minimums.add(minimum.getValue()); // Advance to the next node - sourceVertex.transform((vertex) -> minimumEdge - .unwrap(edge -> edge.getTarget())); + source.transform((vertex) -> minimum.unwrap(edge -> edge.getTarget())); // Visit this node - visitedVertexes.add(sourceVertex.getValue()); + visited.add(source.getValue()); } - return minimumEdges; + return minimums; } /** @@ -222,7 +220,7 @@ public class Graph<T> { * @return A count of the vertices in this graph */ public int getVertexCount() { - return backingGraph.getSize(); + return backing.getSize(); } /** @@ -231,39 +229,39 @@ public class Graph<T> { * @return A unmodifiable set of all the vertices in the graph. */ public IList<T> getVertices() { - return backingGraph.keyList(); + return backing.keyList(); } /** * Remove the edge starting at the source and ending at the target * - * @param sourceVertex + * @param source * The source vertex for the edge - * @param targetVertex + * @param target * The target vertex for the edge */ - public void removeEdge(T sourceVertex, T targetVertex) { + public void removeEdge(T source, T target) { // Can't remove things w/ null vertices - if (sourceVertex == null) { + if (source == null) { throw new NullPointerException( "The source vertex cannot be null"); - } else if (targetVertex == null) { + } else if (target == null) { throw new NullPointerException( "The target vertex cannot be null"); } // Can't remove if one vertice doesn't exists - if (!backingGraph.containsKey(sourceVertex)) { + if (!backing.containsKey(source)) { throw new NoSuchElementException( - "vertex " + sourceVertex + " does not exist."); + "vertex " + source + " does not exist."); } - if (!backingGraph.containsKey(targetVertex)) { + if (!backing.containsKey(target)) { throw new NoSuchElementException( - "vertex " + targetVertex + " does not exist."); + "vertex " + target + " does not exist."); } - backingGraph.get(sourceVertex).remove(targetVertex); + backing.get(source).remove(target); // Uncomment this to turn the graph undirected // graph.get(target).remove(source); @@ -275,15 +273,15 @@ public class Graph<T> { * @return A adjacency map representing this graph */ public AdjacencyMap<T> toAdjacencyMap() { - AdjacencyMap<T> adjacencyMap = new AdjacencyMap<>( - backingGraph.keyList()); + AdjacencyMap<T> adjacency = new AdjacencyMap<>( + backing.keyList()); - backingGraph.forEach((key, value) -> { - value.forEach((targetKey, targetValue) -> { - adjacencyMap.setWeight(key, targetKey, targetValue); + backing.forEach((sourceKey, sourceValue) -> { + sourceValue.forEach((targetKey, targetValue) -> { + adjacency.setWeight(sourceKey, targetKey, targetValue); }); }); - return adjacencyMap; + return adjacency; } -}
\ No newline at end of file +} |
