summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/graph
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2017-02-09 11:50:31 -0500
committerbculkin2442 <bjculkin@mix.wvu.edu>2017-02-09 11:50:31 -0500
commitd2af58b0f68ebfbba2be7e7679efec6c8c0af12f (patch)
tree2b16fbf014db350126e8c1b5f081312276f85f62 /BJC-Utils2/src/main/java/bjc/utils/graph
parent187e1815488e3c1ed22e7592f304e632cffefb82 (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.java101
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/graph/Edge.java32
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java142
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
+}