package uk.ac.rhul.cs.graph;
import static org.junit.Assert.*;
import com.sosnoski.util.array.IntArray;
import org.junit.BeforeClass;
import org.junit.Test;
import uk.ac.rhul.cs.utils.IteratorUtils;
public class DepthFirstSearchTest {
static Graph graph = null;
@BeforeClass
public static void setUpBefore() {
int[] edges = { 0, 1, 1, 3, 3, 4, 4, 6, 6, 5, 5, 3, 3, 2, 2, 0, 0, 3 };
double[] weights = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
graph = GraphFactory.createFromEdgeList(edges, weights);
}
@Test
public void testDepthFirstSearchConstructor() {
DepthFirstSearch dfs = new DepthFirstSearch(graph, 2);
assertEquals(graph, dfs.getGraph());
assertEquals(2, dfs.getSeedNode());
}
@Test
public void testIterator() {
DepthFirstSearch dfs = new DepthFirstSearch(graph, 0);
assertArrayEquals(new int[]{0, 1, 3, 4, 6, 5, 2}, dfs.toArray());
}
@Test
public void testDistancesAndParents() {
DepthFirstSearch dfs = new DepthFirstSearch(graph, 0);
DepthFirstSearchIterator iterator = dfs.iterator();
assertEquals(-1, iterator.getDistance());
assertEquals(-1, iterator.getParent());
// Visiting node 0
assertTrue(iterator.hasNext());
assertEquals(0, iterator.next().intValue());
assertEquals(0, iterator.getDistance());
assertEquals(-1, iterator.getParent());
// Visiting node 1
assertTrue(iterator.hasNext());
assertEquals(1, iterator.next().intValue());
assertEquals(1, iterator.getDistance());
assertEquals(0, iterator.getParent());
// Visiting node 3
assertTrue(iterator.hasNext());
assertEquals(3, iterator.next().intValue());
assertEquals(2, iterator.getDistance());
assertEquals(1, iterator.getParent());
// Visiting node 4
assertTrue(iterator.hasNext());
assertEquals(4, iterator.next().intValue());
assertEquals(3, iterator.getDistance());
assertEquals(3, iterator.getParent());
// Visiting node 6
assertTrue(iterator.hasNext());
assertEquals(6, iterator.next().intValue());
assertEquals(4, iterator.getDistance());
assertEquals(4, iterator.getParent());
// Visiting node 5
assertTrue(iterator.hasNext());
assertEquals(5, iterator.next().intValue());
assertEquals(5, iterator.getDistance());
assertEquals(6, iterator.getParent());
// Visiting node 2
assertTrue(iterator.hasNext());
assertEquals(2, iterator.next().intValue());
assertEquals(3, iterator.getDistance());
assertEquals(3, iterator.getParent());
// Did the traversal really end?
assertFalse(iterator.hasNext());
}
@Test
public void testHooks() {
DepthFirstSearchIteratorWithLoggingHooks iterator;
iterator = new DepthFirstSearchIteratorWithLoggingHooks(graph, 0);
IteratorUtils.exhaust(iterator);
assertArrayEquals(new int[] {0, 1, 3, 4, 6, 5, 10503, 105, 106, 104, 10305, 2,
10200, 102, 10300, 103, 101, 10002, 10003, 100},
iterator.log.toArray());
iterator = new DepthFirstSearchIteratorWithLoggingHooks(graph, 0, new int[] { 0, 1, 2, 3, 4 });
IteratorUtils.exhaust(iterator);
assertArrayEquals(new int[]{0, 1, 3, 4, 104, 2, 10200, 102, 10300, 103, 101, 10002, 10003, 100},
iterator.log.toArray());
}
@Test
public void testRestrictedIterator() {
DepthFirstSearch dfs = new DepthFirstSearch(graph, 0);
int[][] subsets = {
{ 0, 1, 3, 4, 5, 6 },
{ 0, 2, 4 },
{ 0, 4, 6 },
{ 0, 1, 2, 3, 4 }
};
int[][] results = {
{ 0, 1, 3, 4, 6, 5 },
{ 0, 2 },
{ 0 },
{ 0, 1, 3, 4, 2 }
};
for (int i = 0; i < subsets.length; i++) {
dfs.restrictToSubgraph(subsets[i]);
assertArrayEquals(dfs.toArray(), results[i]);
}
}
class DepthFirstSearchIteratorWithLoggingHooks extends DepthFirstSearchIterator {
public IntArray log = new IntArray();
public DepthFirstSearchIteratorWithLoggingHooks(Graph graph, int seedNode) {
this(graph, seedNode, null);
}
public DepthFirstSearchIteratorWithLoggingHooks(Graph graph, int seedNode, int[] subset) {
super(graph, seedNode, subset);
}
@Override
public void enterSubtreeHook(Item item) {
log.add(item.node);
}
@Override
public void exitSubtreeHook(Item item) {
log.add(item.node+100);
}
@Override
public void visitedNodeFoundHook(Item item, int neighbor, int neighborIndex) {
log.add(10000+item.node*100+neighbor);
}
}
}