/******************************************************************************* * Copyright (c) 2002 - 2010 IBM Corporation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package com.ibm.wala.core.tests.basic; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import junit.framework.Assert; import org.junit.Test; import com.ibm.wala.util.graph.INodeWithNumberedEdges; import com.ibm.wala.util.graph.NumberedGraph; import com.ibm.wala.util.graph.impl.DelegatingNumberedGraph; import com.ibm.wala.util.graph.traverse.FloydWarshall; import com.ibm.wala.util.graph.traverse.FloydWarshall.GetPath; import com.ibm.wala.util.graph.traverse.FloydWarshall.GetPaths; import com.ibm.wala.util.intset.IntSet; import com.ibm.wala.util.intset.IntSetUtil; import com.ibm.wala.util.intset.MutableIntSet; public class FloydWarshallTest { public static class Node implements INodeWithNumberedEdges { private final int number; private final MutableIntSet preds = IntSetUtil.make(); private final MutableIntSet succs = IntSetUtil.make(); @Override public int getGraphNodeId() { return number; } public Node(int number) { this.number = number; } @Override public void setGraphNodeId(int number) { throw new UnsupportedOperationException(); } @Override public IntSet getSuccNumbers() { return succs; } @Override public IntSet getPredNumbers() { return preds; } @Override public void addSucc(int n) { succs.add(n); } @Override public void addPred(int n) { preds.add(n); } @Override public void removeAllIncidentEdges() { throw new UnsupportedOperationException(); } @Override public void removeIncomingEdges() { throw new UnsupportedOperationException(); } @Override public void removeOutgoingEdges() { throw new UnsupportedOperationException(); } @Override public String toString() { return "["+number+"]"; } } private static NumberedGraph<Node> makeGraph() { NumberedGraph<Node> G = new DelegatingNumberedGraph<Node>(); for(int i = 0; i <= 8; i++) { G.addNode(new Node(i)); } G.addEdge(G.getNode(1),G.getNode(2)); G.addEdge(G.getNode(2),G.getNode(3)); G.addEdge(G.getNode(3),G.getNode(4)); G.addEdge(G.getNode(3),G.getNode(5)); G.addEdge(G.getNode(4),G.getNode(6)); G.addEdge(G.getNode(5),G.getNode(7)); G.addEdge(G.getNode(6),G.getNode(8)); G.addEdge(G.getNode(7),G.getNode(8)); G.addEdge(G.getNode(6),G.getNode(4)); G.addEdge(G.getNode(6),G.getNode(2)); return G; } private final NumberedGraph<Node> G = makeGraph(); private final int[][] shortestPaths = new int[][]{ {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE}, {Integer.MAX_VALUE, Integer.MAX_VALUE, 1, 2, 3, 3, 4, 4, 5}, {Integer.MAX_VALUE, Integer.MAX_VALUE, 4, 1, 2, 2, 3, 3, 4}, {Integer.MAX_VALUE, Integer.MAX_VALUE, 3, 4, 1, 1, 2, 2, 3}, {Integer.MAX_VALUE, Integer.MAX_VALUE, 2, 3, 2, 4, 1, 5, 2}, {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 1, 2}, {Integer.MAX_VALUE, Integer.MAX_VALUE, 1, 2, 1, 3, 2, 4, 1}, {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 1}, {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE} }; @Test public void TestPathLengths() { int[][] result = FloydWarshall.shortestPathLengths(G); Assert.assertTrue(result.length == shortestPaths.length); for(int i = 0; i < result.length; i++) { Assert.assertTrue(result[i].length == shortestPaths[i].length); for(int j = 0; j < result[i].length; j++) { Assert.assertTrue(result[i][j] == shortestPaths[i][j]); } } } @Test public void TestShortestPath() { GetPath<Node> result = FloydWarshall.allPairsShortestPath(G); Assert.assertEquals(result.getPath(G.getNode(1), G.getNode(3)), Collections.singletonList(G.getNode(2))); Assert.assertEquals(result.getPath(G.getNode(5), G.getNode(8)), Collections.singletonList(G.getNode(7))); Assert.assertEquals(result.getPath(G.getNode(1), G.getNode(7)), Arrays.asList(G.getNode(2),G.getNode(3),G.getNode(5))); Assert.assertEquals(result.getPath(G.getNode(1), G.getNode(6)), Arrays.asList(G.getNode(2),G.getNode(3),G.getNode(4))); } @Test public void TestShortestPaths() { GetPaths<Node> result = FloydWarshall.allPairsShortestPaths(G); Set<List<Node>> paths = new HashSet<List<Node>>(); paths.add(Arrays.asList(G.getNode(2),G.getNode(3),G.getNode(4),G.getNode(6))); paths.add(Arrays.asList(G.getNode(2),G.getNode(3),G.getNode(5),G.getNode(7))); Assert.assertEquals(result.getPaths(G.getNode(1), G.getNode(8)), paths); } }