mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-27 14:21:48 +01:00
K-shorest path algorithm to support UC1, it can be used by other modules as well.
Change-Id: I736ec55c6211a505d6cf43ab22e1197fdb86ecf3
This commit is contained in:
parent
e0f804aa3f
commit
0d0ef61cd5
@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.onlab.graph;
|
||||
|
||||
import java.util.ArrayList;
|
||||
//import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
//import java.util.Map;
|
||||
//import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
|
||||
//import org.apache.commons.lang3.tuple.Pair;
|
||||
//import org.onlab.graph.AbstractGraphPathSearch.DefaultResult;
|
||||
|
||||
/**
|
||||
* K-shortest-path graph search algorithm capable of finding not just one,
|
||||
* but K shortest paths with descending order between the source and destinations.
|
||||
*/
|
||||
|
||||
public class KshortestPathSearch<V extends Vertex, E extends Edge<V>> {
|
||||
|
||||
// Define class variables.
|
||||
private Graph<V, E> immutableGraph;
|
||||
private MutableGraph<V, E> mutableGraph;
|
||||
private List<List<E>> pathResults = new ArrayList<List<E>>();
|
||||
private List<List<E>> pathCandidates = new ArrayList<List<E>>();
|
||||
private V source;
|
||||
private V sink;
|
||||
private int numK = 0;
|
||||
private EdgeWeight<V, E> weight = null;
|
||||
// private PriorityQueue<List<E>> pathCandidates = new PriorityQueue<List<E>>();
|
||||
|
||||
// Initialize the graph.
|
||||
public KshortestPathSearch(Graph<V, E> graph) {
|
||||
immutableGraph = graph;
|
||||
mutableGraph = new MutableAdjacencyListsGraph(graph.getVertexes(),
|
||||
graph.getEdges());
|
||||
}
|
||||
|
||||
public List<List<E>> search(V src,
|
||||
V dst,
|
||||
EdgeWeight<V, E> wei,
|
||||
int k) {
|
||||
|
||||
weight = wei;
|
||||
source = src;
|
||||
sink = dst;
|
||||
numK = k;
|
||||
// pathCandidates = new PriorityQueue<List<E>>();
|
||||
|
||||
pathResults.clear();
|
||||
pathCandidates.clear();
|
||||
|
||||
// Double check the parameters
|
||||
checkArguments(immutableGraph, src, dst, numK);
|
||||
|
||||
// DefaultResult result = new DefaultResult(src, dst);
|
||||
|
||||
searchKShortestPaths();
|
||||
|
||||
return pathResults;
|
||||
}
|
||||
|
||||
private void checkArguments(Graph<V, E> graph, V src, V dst, int k) {
|
||||
if (graph == null) {
|
||||
throw new NullPointerException("graph is null");
|
||||
}
|
||||
if (!graph.getVertexes().contains(src)) {
|
||||
throw new NullPointerException("source node does not exist");
|
||||
}
|
||||
if (!graph.getVertexes().contains(dst)) {
|
||||
throw new NullPointerException("target node does not exist");
|
||||
}
|
||||
if (k <= 0) {
|
||||
throw new NullPointerException("K is negative or 0");
|
||||
}
|
||||
if (weight == null) {
|
||||
throw new NullPointerException("the cost matrix is null");
|
||||
}
|
||||
}
|
||||
|
||||
private void searchKShortestPaths() {
|
||||
// Step 1: find the shortest path.
|
||||
List<E> shortestPath = searchShortestPath(immutableGraph, source, sink);
|
||||
// no path exists, exit.
|
||||
if (shortestPath == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 2: update the results.
|
||||
pathResults.add(shortestPath);
|
||||
// pathCandidates.add(shortestPath);
|
||||
|
||||
// Step 3: find the other K-1 paths.
|
||||
while (/*pathCandidates.size() > 0 &&*/pathResults.size() < numK) {
|
||||
// 3.1 the spur node ranges from the first node to the last node in the previous k-shortest path.
|
||||
List<E> lastPath = pathResults.get(pathResults.size() - 1);
|
||||
for (int i = 0; i < lastPath.size(); i++) {
|
||||
// 4.1 convert the graph into mutable.
|
||||
convertGraph();
|
||||
// 4.2 transform the graph.
|
||||
List<E> rootPath = createSpurNode(lastPath, i);
|
||||
transformGraph(rootPath);
|
||||
// 4.3 find the deviation node.
|
||||
V devNode;
|
||||
devNode = getDevNode(rootPath);
|
||||
List<E> spurPath;
|
||||
// 4.4 find the shortest path in the transformed graph.
|
||||
spurPath = searchShortestPath(mutableGraph, devNode, sink);
|
||||
// 4.5 update the path candidates.
|
||||
if (spurPath != null) {
|
||||
// totalPath = rootPath + spurPath;
|
||||
rootPath.addAll(spurPath);
|
||||
pathCandidates.add(rootPath);
|
||||
}
|
||||
}
|
||||
// 3.2 if there is no spur path, exit.
|
||||
if (pathCandidates.size() == 0) {
|
||||
break;
|
||||
}
|
||||
// 3.3 add the path into the results.
|
||||
addPathResult();
|
||||
}
|
||||
}
|
||||
|
||||
private List<E> searchShortestPath(Graph<V, E> graph, V src, V dst) {
|
||||
// Determine the shortest path from the source to the destination by using the Dijkstra algorithm.
|
||||
DijkstraGraphSearch dijkstraAlg = new DijkstraGraphSearch();
|
||||
Set<Path> paths = dijkstraAlg.search(graph, src, dst, weight).paths();
|
||||
Iterator<Path> itr = paths.iterator();
|
||||
if (!itr.hasNext()) {
|
||||
return null;
|
||||
}
|
||||
// return the first shortest path only.
|
||||
return (List<E>) itr.next().edges();
|
||||
}
|
||||
|
||||
private void convertGraph() {
|
||||
// clear the mutableGraph first
|
||||
if (mutableGraph != null) {
|
||||
((MutableAdjacencyListsGraph) mutableGraph).clear();
|
||||
}
|
||||
|
||||
// create a immutableGraph
|
||||
Set<E> copyEa = immutableGraph.getEdges();
|
||||
Set<V> copyVa = immutableGraph.getVertexes();
|
||||
for (V vertex : copyVa) {
|
||||
mutableGraph.addVertex(vertex);
|
||||
}
|
||||
for (E edge : copyEa) {
|
||||
mutableGraph.addEdge(edge);
|
||||
}
|
||||
}
|
||||
|
||||
private V getDevNode(List<E> path) {
|
||||
V srcA;
|
||||
V dstB;
|
||||
|
||||
if (path.size() == 0) {
|
||||
return source;
|
||||
}
|
||||
|
||||
E temp1 = path.get(path.size() - 1);
|
||||
srcA = temp1.src();
|
||||
dstB = temp1.dst();
|
||||
|
||||
if (path.size() == 1) {
|
||||
if (srcA.equals(source)) {
|
||||
return dstB;
|
||||
} else {
|
||||
return srcA;
|
||||
}
|
||||
} else {
|
||||
E temp2 = path.get(path.size() - 2);
|
||||
if (srcA.equals(temp2.src()) || srcA.equals(temp2.dst())) {
|
||||
return dstB;
|
||||
} else {
|
||||
return srcA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<E> createSpurNode(List<E> path, int n) {
|
||||
List<E> root = new ArrayList<E>();
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
root.add(path.get(i));
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
private void transformGraph(List<E> rootPath) {
|
||||
List<E> prePath;
|
||||
//remove edges
|
||||
for (int i = 0; i < pathResults.size(); i++) {
|
||||
prePath = pathResults.get(i);
|
||||
if (prePath.size() == 1) {
|
||||
mutableGraph.removeEdge(prePath.get(0));
|
||||
} else if (comparePath(rootPath, prePath)) {
|
||||
for (int j = 0; j <= rootPath.size(); j++) {
|
||||
mutableGraph.removeEdge(prePath.get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < pathCandidates.size(); i++) {
|
||||
prePath = pathCandidates.get(i);
|
||||
if (prePath.size() == 1) {
|
||||
mutableGraph.removeEdge(prePath.get(0));
|
||||
} else if (comparePath(rootPath, prePath)) {
|
||||
for (int j = 0; j <= rootPath.size(); j++) {
|
||||
mutableGraph.removeEdge(prePath.get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rootPath.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//remove nodes
|
||||
List<V> nodes = new ArrayList<V>();
|
||||
nodes.add(source);
|
||||
V pre = source;
|
||||
V srcA;
|
||||
V dstB;
|
||||
for (int i = 0; i < rootPath.size() - 1; i++) {
|
||||
E temp = rootPath.get(i);
|
||||
srcA = temp.src();
|
||||
dstB = temp.dst();
|
||||
|
||||
if (srcA.equals(pre)) {
|
||||
nodes.add(dstB);
|
||||
pre = dstB;
|
||||
} else {
|
||||
nodes.add(srcA);
|
||||
pre = srcA;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
mutableGraph.removeVertex(nodes.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean comparePath(List<E> path1, List<E> path2) {
|
||||
if (path1.size() > path2.size()) {
|
||||
return false;
|
||||
}
|
||||
if (path1.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < path1.size(); i++) {
|
||||
if (path1.get(i) != path2.get(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void addPathResult() {
|
||||
List<E> sp;
|
||||
sp = pathCandidates.get(0);
|
||||
for (int i = 1; i < pathCandidates.size(); i++) {
|
||||
if (sp.size() > pathCandidates.get(i).size()) {
|
||||
sp = pathCandidates.get(i);
|
||||
}
|
||||
}
|
||||
pathResults.add(sp);
|
||||
// Log.info(sp.toString());
|
||||
pathCandidates.remove(sp);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,147 @@
|
||||
package org.onlab.graph;
|
||||
|
||||
import static com.google.common.base.MoreObjects.toStringHelper;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
public class MutableAdjacencyListsGraph<V extends Vertex, E extends Edge<V>>
|
||||
implements MutableGraph<V, E> {
|
||||
private Set<V> vertexes = new HashSet<V>();
|
||||
private Set<E> edges = new HashSet<E>();
|
||||
|
||||
private SetMultimap<V, E> sources = HashMultimap.create();
|
||||
private SetMultimap<V, E> destinations = HashMultimap.create();
|
||||
|
||||
/**
|
||||
* Creates a graph comprising of the specified vertexes and edges.
|
||||
*
|
||||
* @param vertexes set of graph vertexes
|
||||
* @param edges set of graph edges
|
||||
*/
|
||||
public MutableAdjacencyListsGraph(Set<V> vertex, Set<E> edge) {
|
||||
vertexes.addAll(vertex);
|
||||
edges.addAll(edge);
|
||||
for (E e : edge) {
|
||||
sources.put(e.src(), e);
|
||||
vertexes.add(e.src());
|
||||
destinations.put(e.dst(), e);
|
||||
vertexes.add(e.dst());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> getVertexes() {
|
||||
return vertexes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<E> getEdges() {
|
||||
return edges;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<E> getEdgesFrom(V src) {
|
||||
return sources.get(src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<E> getEdgesTo(V dst) {
|
||||
return destinations.get(dst);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof MutableAdjacencyListsGraph) {
|
||||
MutableAdjacencyListsGraph that = (MutableAdjacencyListsGraph) obj;
|
||||
return this.getClass() == that.getClass() &&
|
||||
Objects.equals(this.vertexes, that.vertexes) &&
|
||||
Objects.equals(this.edges, that.edges);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(vertexes, edges);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this)
|
||||
.add("vertexes", vertexes)
|
||||
.add("edges", edges)
|
||||
.toString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addVertex(V vertex) {
|
||||
if (vertexes != null) {
|
||||
if (!vertexes.contains(vertex)) {
|
||||
vertexes.add(vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeVertex(V vertex) {
|
||||
// TODO Auto-generated method stub
|
||||
if (vertexes != null && edges != null) {
|
||||
if (vertexes.contains(vertex)) {
|
||||
vertexes.remove(vertex);
|
||||
Set<E> srcEdgesList = sources.get(vertex);
|
||||
Set<E> dstEdgesList = destinations.get(vertex);
|
||||
edges.removeAll(srcEdgesList);
|
||||
edges.removeAll(dstEdgesList);
|
||||
sources.remove(vertex, srcEdgesList);
|
||||
sources.remove(vertex, dstEdgesList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEdge(E edge) {
|
||||
if (edges != null) {
|
||||
if (!edges.contains(edge)) {
|
||||
edges.add(edge);
|
||||
sources.put(edge.src(), edge);
|
||||
destinations.put(edge.dst(), edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEdge(E edge) {
|
||||
if (edges != null) {
|
||||
if (edges.contains(edge)) {
|
||||
edges.remove(edge);
|
||||
sources.remove(edge.src(), edge);
|
||||
destinations.remove(edge.dst(), edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Graph<V, E> toImmutable() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the graph.
|
||||
*/
|
||||
public void clear() {
|
||||
edges.clear();
|
||||
vertexes.clear();
|
||||
sources.clear();
|
||||
destinations.clear();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.onlab.graph;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.of;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
//import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class KshortestPathSearchTest extends BreadthFirstSearchTest {
|
||||
|
||||
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
|
||||
|
||||
@Test
|
||||
public void noPath() {
|
||||
graph = new AdjacencyListsGraph<>(of(A, B, C, D),
|
||||
of(new TestEdge(A, B, 1),
|
||||
new TestEdge(B, A, 1),
|
||||
new TestEdge(C, D, 1),
|
||||
new TestEdge(D, C, 1)));
|
||||
KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
|
||||
List<List<TestEdge>> result = gs.search(A, D, weight, 1);
|
||||
List<Path> paths = new ArrayList<>();
|
||||
Iterator<List<TestEdge>> itr = result.iterator();
|
||||
while (itr.hasNext()) {
|
||||
System.out.println(itr.next().toString());
|
||||
}
|
||||
assertEquals("incorrect paths count", 0, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2Path() {
|
||||
graph = new AdjacencyListsGraph<>(of(A, B, C, D),
|
||||
of(new TestEdge(A, B, 1),
|
||||
new TestEdge(B, A, 1),
|
||||
new TestEdge(B, D, 1),
|
||||
new TestEdge(D, B, 1),
|
||||
new TestEdge(A, C, 1),
|
||||
new TestEdge(C, A, 1),
|
||||
new TestEdge(C, D, 1),
|
||||
new TestEdge(D, C, 1)));
|
||||
KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
|
||||
List<List<TestEdge>> result = gs.search(A, D, weight, 2);
|
||||
List<Path> paths = new ArrayList<>();
|
||||
Iterator<List<TestEdge>> itr = result.iterator();
|
||||
while (itr.hasNext()) {
|
||||
System.out.println(itr.next().toString());
|
||||
}
|
||||
assertEquals("incorrect paths count", 2, result.size());
|
||||
// assertEquals("printing the paths", outContent.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3Path() {
|
||||
graph = new AdjacencyListsGraph<>(of(A, B, C, D),
|
||||
of(new TestEdge(A, B, 1),
|
||||
new TestEdge(B, A, 1),
|
||||
new TestEdge(A, D, 1),
|
||||
new TestEdge(D, A, 1),
|
||||
new TestEdge(B, D, 1),
|
||||
new TestEdge(D, B, 1),
|
||||
new TestEdge(A, C, 1),
|
||||
new TestEdge(C, A, 1),
|
||||
new TestEdge(C, D, 1),
|
||||
new TestEdge(D, C, 1)));
|
||||
KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
|
||||
List<List<TestEdge>> result = gs.search(A, D, weight, 3);
|
||||
List<Path> paths = new ArrayList<>();
|
||||
Iterator<List<TestEdge>> itr = result.iterator();
|
||||
while (itr.hasNext()) {
|
||||
System.out.println(itr.next().toString());
|
||||
}
|
||||
assertEquals("incorrect paths count", 3, result.size());
|
||||
// assertEquals("printing the paths", outContent.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test4Path() {
|
||||
graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F),
|
||||
of(new TestEdge(A, B, 1),
|
||||
new TestEdge(B, A, 1),
|
||||
new TestEdge(A, C, 1),
|
||||
new TestEdge(C, A, 1),
|
||||
new TestEdge(B, D, 1),
|
||||
new TestEdge(D, B, 1),
|
||||
new TestEdge(C, E, 1),
|
||||
new TestEdge(E, C, 1),
|
||||
new TestEdge(D, F, 1),
|
||||
new TestEdge(F, D, 1),
|
||||
new TestEdge(F, E, 1),
|
||||
new TestEdge(E, F, 1),
|
||||
new TestEdge(C, D, 1),
|
||||
new TestEdge(D, C, 1)));
|
||||
KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
|
||||
List<List<TestEdge>> result = gs.search(A, F, weight, 4);
|
||||
List<Path> paths = new ArrayList<>();
|
||||
Iterator<List<TestEdge>> itr = result.iterator();
|
||||
while (itr.hasNext()) {
|
||||
System.out.println(itr.next().toString());
|
||||
}
|
||||
assertEquals("incorrect paths count", 4, result.size());
|
||||
// assertEquals("printing the paths", outContent.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test6Path() {
|
||||
graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F),
|
||||
of(new TestEdge(A, B, 1),
|
||||
new TestEdge(B, A, 1),
|
||||
new TestEdge(A, C, 1),
|
||||
new TestEdge(C, A, 1),
|
||||
new TestEdge(B, D, 1),
|
||||
new TestEdge(D, B, 1),
|
||||
new TestEdge(B, C, 1),
|
||||
new TestEdge(C, B, 1),
|
||||
new TestEdge(D, E, 1),
|
||||
new TestEdge(E, D, 1),
|
||||
new TestEdge(C, E, 1),
|
||||
new TestEdge(E, C, 1),
|
||||
new TestEdge(D, F, 1),
|
||||
new TestEdge(F, D, 1),
|
||||
new TestEdge(E, F, 1),
|
||||
new TestEdge(F, E, 1)));
|
||||
KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
|
||||
List<List<TestEdge>> result = gs.search(A, F, weight, 6);
|
||||
List<Path> paths = new ArrayList<>();
|
||||
Iterator<List<TestEdge>> itr = result.iterator();
|
||||
while (itr.hasNext()) {
|
||||
System.out.println(itr.next().toString());
|
||||
}
|
||||
assertEquals("incorrect paths count", 6, result.size());
|
||||
// assertEquals("printing the paths", outContent.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dualEdgePath() {
|
||||
graph = new AdjacencyListsGraph<>(of(A, B, C, D, E, F, G, H),
|
||||
of(new TestEdge(A, B, 1), new TestEdge(A, C, 3),
|
||||
new TestEdge(B, D, 2), new TestEdge(B, C, 1),
|
||||
new TestEdge(B, E, 4), new TestEdge(C, E, 1),
|
||||
new TestEdge(D, H, 5), new TestEdge(D, E, 1),
|
||||
new TestEdge(E, F, 1), new TestEdge(F, D, 1),
|
||||
new TestEdge(F, G, 1), new TestEdge(F, H, 1),
|
||||
new TestEdge(A, E, 3), new TestEdge(B, D, 1)));
|
||||
KshortestPathSearch<TestVertex, TestEdge> gs = new KshortestPathSearch<TestVertex, TestEdge>(graph);
|
||||
List<List<TestEdge>> result = gs.search(A, G, weight, 6);
|
||||
List<Path> paths = new ArrayList<>();
|
||||
Iterator<List<TestEdge>> itr = result.iterator();
|
||||
while (itr.hasNext()) {
|
||||
System.out.println(itr.next().toString());
|
||||
}
|
||||
assertEquals("incorrect paths count", 6, result.size());
|
||||
// assertEquals("printing the paths", outContent.toString());
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() throws Exception {
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// System.setOut(new PrintStream(outContent));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
// System.setOut(null);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user