/* * Copyright 2012 Odysseus Software GmbH * * Licensed 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 de.odysseus.ithaka.digraph; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.junit.Assert; import org.junit.Test; public class DigraphsTest { @Test public void testEmptyDigraph() { Digraph<?,?> empty = Digraphs.emptyDigraph(); Assert.assertEquals(0, empty.getEdgeCount()); Assert.assertEquals(0, empty.getVertexCount()); Assert.assertTrue(empty.isAcyclic()); } @Test(expected=UnsupportedOperationException.class) public void testUnmodifiableDigraph() { Digraph<Integer,Object> digraph = Digraphs.unmodifiableDigraph(new MapDigraph<Integer,Object>()); digraph.put(1, 2, 3); } @Test public void testTopsort() { SimpleDigraph<Integer> g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(2, 3); g.add(3, 4); g.add(1, 3); g.add(2, 4); assert g.isAcyclic(); int n = 0; int v = 0; for (int w : Digraphs.topsort(g, false)) { Assert.assertTrue(v < w); v = w; n++; } Assert.assertEquals(g.getVertexCount(), n); } @Test public void testClosure() { SimpleDigraph<Integer> g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(2, 3); g.add(3, 2); g.add(3, 4); Set<Integer> c; c = Digraphs.closure(g, 1); Assert.assertEquals(4, c.size()); c = Digraphs.closure(g, 2); Assert.assertEquals(3, c.size()); Assert.assertFalse(c.contains(1)); c = Digraphs.closure(g, 3); Assert.assertEquals(3, c.size()); Assert.assertFalse(c.contains(1)); c = Digraphs.closure(g, 4); Assert.assertEquals(1, c.size()); Assert.assertTrue(c.contains(4)); } @Test public void testIsAcyclic() { SimpleDigraph<Integer> g; g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(2, 3); g.add(3, 4); g.add(1, 3); g.add(2, 4); Assert.assertTrue(Digraphs.isAcyclic(g)); g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(2, 3); g.add(3, 2); g.add(3, 4); Assert.assertFalse(Digraphs.isAcyclic(g)); } @Test public void testIsStronglyConnected() { SimpleDigraph<Integer> g; g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(2, 3); g.add(3, 4); g.add(1, 3); g.add(2, 4); Assert.assertFalse(Digraphs.isStronglyConnected(g)); g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(2, 3); g.add(3, 4); g.add(4, 2); g.add(3, 1); Assert.assertTrue(Digraphs.isStronglyConnected(g)); } @Test public void testIsEquivalent() { WeightedDigraph<Integer> g1; WeightedDigraph<Integer> g2; g1 = new WeightedDigraphAdapter<Integer>(); g1.add(0); g1.put(1, 2, 1); g1.put(2, 3, 2); g1.put(3, 4, 3); g1.put(1, 3, 4); g1.put(2, 4, 5); g2 = g1; Assert.assertTrue(Digraphs.isEquivalent(g1, g2, false)); Assert.assertTrue(Digraphs.isEquivalent(g1, g2, true)); g2 = new WeightedDigraphAdapter<Integer>(); g2.add(0); g2.put(1, 2, 1); g2.put(2, 3, 2); g2.put(3, 4, 3); g2.put(1, 3, 4); g2.put(2, 4, 5); Assert.assertTrue(Digraphs.isEquivalent(g1, g2, false)); Assert.assertTrue(Digraphs.isEquivalent(g2, g1, false)); Assert.assertTrue(Digraphs.isEquivalent(g1, g2, true)); Assert.assertTrue(Digraphs.isEquivalent(g2, g1, true)); g2.remove(0); Assert.assertFalse(Digraphs.isEquivalent(g1, g2, false)); Assert.assertFalse(Digraphs.isEquivalent(g2, g1, false)); Assert.assertFalse(Digraphs.isEquivalent(g1, g2, true)); Assert.assertFalse(Digraphs.isEquivalent(g2, g1, true)); g2.add(0); Assert.assertTrue(Digraphs.isEquivalent(g1, g2, false)); Assert.assertTrue(Digraphs.isEquivalent(g2, g1, false)); Assert.assertTrue(Digraphs.isEquivalent(g1, g2, true)); Assert.assertTrue(Digraphs.isEquivalent(g2, g1, true)); g2.remove(2, 3); Assert.assertFalse(Digraphs.isEquivalent(g1, g2, false)); Assert.assertFalse(Digraphs.isEquivalent(g2, g1, false)); Assert.assertFalse(Digraphs.isEquivalent(g1, g2, true)); Assert.assertFalse(Digraphs.isEquivalent(g2, g1, true)); g2.put(2, 3, 2); Assert.assertTrue(Digraphs.isEquivalent(g1, g2, false)); Assert.assertTrue(Digraphs.isEquivalent(g2, g1, false)); Assert.assertTrue(Digraphs.isEquivalent(g1, g2, true)); Assert.assertTrue(Digraphs.isEquivalent(g2, g1, true)); g2.put(2, 3, 0); Assert.assertTrue(Digraphs.isEquivalent(g1, g2, false)); Assert.assertTrue(Digraphs.isEquivalent(g2, g1, false)); Assert.assertFalse(Digraphs.isEquivalent(g1, g2, true)); Assert.assertFalse(Digraphs.isEquivalent(g2, g1, true)); g2.put(2, 3, null); Assert.assertTrue(Digraphs.isEquivalent(g1, g2, false)); Assert.assertTrue(Digraphs.isEquivalent(g2, g1, false)); Assert.assertFalse(Digraphs.isEquivalent(g1, g2, true)); Assert.assertFalse(Digraphs.isEquivalent(g2, g1, true)); } @Test public void testIsReachable() { SimpleDigraph<Integer> g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(2, 3); g.add(3, 2); g.add(3, 4); Assert.assertTrue(Digraphs.isReachable(g, 1, 1)); Assert.assertTrue(Digraphs.isReachable(g, 1, 2)); Assert.assertTrue(Digraphs.isReachable(g, 1, 3)); Assert.assertTrue(Digraphs.isReachable(g, 1, 4)); Assert.assertTrue(Digraphs.isReachable(g, 2, 2)); Assert.assertTrue(Digraphs.isReachable(g, 2, 3)); Assert.assertTrue(Digraphs.isReachable(g, 2, 4)); Assert.assertTrue(Digraphs.isReachable(g, 3, 2)); Assert.assertTrue(Digraphs.isReachable(g, 3, 3)); Assert.assertTrue(Digraphs.isReachable(g, 3, 4)); Assert.assertTrue(Digraphs.isReachable(g, 4, 4)); Assert.assertFalse(Digraphs.isReachable(g, 2, 1)); Assert.assertFalse(Digraphs.isReachable(g, 3, 1)); Assert.assertFalse(Digraphs.isReachable(g, 4, 1)); Assert.assertFalse(Digraphs.isReachable(g, 4, 2)); Assert.assertFalse(Digraphs.isReachable(g, 4, 3)); } @Test public void testDfs() { SimpleDigraph<Integer> g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(2, 3); g.add(3, 2); g.add(3, 4); Set<Integer> discovered = new HashSet<Integer>(); List<Integer> finished = new ArrayList<Integer>(); Digraphs.dfs(g, 1, discovered, finished); Assert.assertTrue(discovered.size() == 4); Assert.assertTrue(finished.size() == 4); Assert.assertEquals(4, finished.get(0).intValue()); Assert.assertEquals(3, finished.get(1).intValue()); Assert.assertEquals(2, finished.get(2).intValue()); Assert.assertEquals(1, finished.get(3).intValue()); } @Test public void testDfs2() { SimpleDigraph<Integer> g = new SimpleDigraphAdapter<Integer>(); g.add(2, 1); g.add(2, 3); g.add(3, 2); g.add(3, 4); Set<Integer> discovered = new HashSet<Integer>(); List<Integer> finished = new ArrayList<Integer>(); Digraphs.dfs2(g, 1, discovered, finished); Assert.assertTrue(discovered.size() == 4); Assert.assertTrue(finished.size() == 4); Assert.assertEquals(4, finished.get(0).intValue()); Assert.assertEquals(3, finished.get(1).intValue()); Assert.assertEquals(2, finished.get(2).intValue()); Assert.assertEquals(1, finished.get(3).intValue()); } @Test public void testScc() { SimpleDigraph<Integer> g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(2, 1); g.add(1, 3); g.add(3, 4); g.add(4, 2); g.add(3, 5); List<Set<Integer>> components = Digraphs.scc(g); Assert.assertEquals(2, components.size()); if (components.get(0).size() == 1) { Set<Integer> tmp = components.get(0); components.set(0, components.get(1)); components.set(1, tmp); } Assert.assertEquals(4, components.get(0).size()); Assert.assertEquals(1, components.get(1).size()); Assert.assertTrue(components.get(1).contains(5)); } @Test public void testWcc() { SimpleDigraph<Integer> g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(1, 3); g.add(4, 2); g.add(5, 6); List<Set<Integer>> components = Digraphs.wcc(g); Assert.assertEquals(2, components.size()); if (components.get(0).size() == 1) { Set<Integer> tmp = components.get(0); components.set(0, components.get(1)); components.set(1, tmp); } Assert.assertEquals(4, components.get(0).size()); Assert.assertEquals(2, components.get(1).size()); Assert.assertTrue(components.get(1).contains(5)); Assert.assertTrue(components.get(1).contains(6)); } @Test public void testReverse() { SimpleDigraph<Integer> g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(1, 3); g.add(4, 2); g.add(5, 6); g.add(7); SimpleDigraph<Integer> r = g.reverse(); Assert.assertEquals(7, r.getVertexCount()); Assert.assertEquals(4, r.getEdgeCount()); Assert.assertTrue(r.contains(2, 1)); Assert.assertTrue(r.contains(3, 1)); Assert.assertTrue(r.contains(2, 4)); Assert.assertTrue(r.contains(6, 5)); } @Test public void testSubgraph() { SimpleDigraph<Integer> g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(1, 3); g.add(4, 2); g.add(5, 6); g.add(7); Set<Integer> nodes = new HashSet<Integer>(); nodes.add(1); nodes.add(2); nodes.add(3); nodes.add(7); SimpleDigraph<Integer> s = g.subgraph(nodes); Assert.assertEquals(4, s.getVertexCount()); Assert.assertEquals(2, s.getEdgeCount()); Assert.assertTrue(s.contains(1, 2)); Assert.assertTrue(s.contains(1, 3)); } @Test public void testPartition() { SimpleDigraph<Integer> g = new SimpleDigraphAdapter<Integer>(); g.add(1, 2); g.add(2, 1); g.add(1, 3); g.add(1, 4); g.add(3, 4); g.add(4, 2); g.add(3, 5); List<Set<Integer>> sets = new ArrayList<Set<Integer>>(); Set<Integer> set = new HashSet<Integer>(); set.add(1); set.add(2); sets.add(set); set = new HashSet<Integer>(); set.add(3); set.add(4); sets.add(set); set = new HashSet<Integer>(); set.add(5); sets.add(set); DigraphFactory<WeightedDigraphAdapter<SimpleDigraph<Integer>>> f1 = WeightedDigraphAdapter.<SimpleDigraph<Integer>>getAdapterFactory(MapDigraph.<SimpleDigraph<Integer>,Integer>getDefaultDigraphFactory()); DigraphFactory<SimpleDigraphAdapter<Integer>> f2 = SimpleDigraphAdapter.<Integer>getAdapterFactory(MapDigraph.<Integer,Boolean>getDefaultDigraphFactory()); EdgeCumulator<SimpleDigraph<Integer>, Integer, Boolean> c = new EdgeCumulator<SimpleDigraph<Integer>, Integer, Boolean>() { @Override public Integer add(SimpleDigraph<Integer> s, SimpleDigraph<Integer> t, Integer c, Boolean e) { return c == null ? 1 : c + 1; } }; WeightedDigraph<SimpleDigraph<Integer>> p = Digraphs.<Integer,Boolean,SimpleDigraph<Integer>,WeightedDigraph<SimpleDigraph<Integer>>,Integer>partition(g, sets, f1, f2, c); Assert.assertEquals(3, p.getVertexCount()); Assert.assertEquals(3, p.getEdgeCount()); SimpleDigraph<Integer> s1 = null, s2 = null, s3 = null; for (SimpleDigraph<Integer> s : p.vertices()) { if (s.contains(1) && s.contains(2)) { Assert.assertEquals(2, s.getVertexCount()); Assert.assertEquals(2, s.getEdgeCount()); Assert.assertTrue(s.contains(1, 2)); Assert.assertTrue(s.contains(2, 1)); s1 = s; } if (s.contains(3) && s.contains(4)) { Assert.assertEquals(2, s.getVertexCount()); Assert.assertEquals(1, s.getEdgeCount()); Assert.assertTrue(s.contains(3, 4)); s2 = s; } if (s.contains(5)) { Assert.assertEquals(1, s.getVertexCount()); Assert.assertEquals(0, s.getEdgeCount()); s3 = s; } } Assert.assertTrue(s1 != s2 && s1 != s3 && s2 != s3 && s1 != null && s2 != null && s3 != null); Assert.assertEquals(2, p.get(s1, s2).intValue()); Assert.assertEquals(1, p.get(s2, s1).intValue()); Assert.assertEquals(1, p.get(s2, s3).intValue()); } }