@Test public void testContractNode_directed_withWitness() { // 0 --> 1 --> 2 // \_________/ graph.edge(0, 1, 1, false); graph.edge(1, 2, 2, false); graph.edge(0, 2, 1, false); graph.freeze(); setMaxLevelOnAllNodes(); createNodeContractor().contractNode(1); checkNoShortcuts(); }
@Test public void testContractNode_directed_shortcutRequired_reverse() { // 0 <-- 1 <-- 2 final EdgeIteratorState edge1 = graph.edge(2, 1, 1, false); final EdgeIteratorState edge2 = graph.edge(1, 0, 2, false); graph.freeze(); setMaxLevelOnAllNodes(); createNodeContractor().contractNode(1); checkShortcuts(expectedShortcut(0, 2, edge1, edge2, false, true)); }
@Test public void testShortestPathLimit() { createExampleGraph(); DijkstraOneToMany algo = new DijkstraOneToMany(graph, weighting, traversalMode); setMaxLevelOnAllNodes(); algo.setEdgeFilter(createIgnoreNodeFilter(0)); algo.setWeightLimit(2); int endNode = algo.findEndNode(4, 1); // did not reach endNode assertNotEquals(1, endNode); }
private void checkNoShortcuts() { checkShortcuts(); }
/** * Queries the ch graph and checks if the graph's shortcuts match the given expected shortcuts. */ private void checkShortcuts(Shortcut... expectedShortcuts) { Set<Shortcut> expected = setOf(expectedShortcuts); if (expected.size() != expectedShortcuts.length) { fail("was given duplicate shortcuts"); } AllCHEdgesIterator iter = lg.getAllEdges(); Set<Shortcut> given = new HashSet<>(); while (iter.next()) { if (iter.isShortcut()) { given.add(new Shortcut( iter.getBaseNode(), iter.getAdjNode(), iter.getWeight(), iter.getDistance(), iter.isForward(encoder), iter.isBackward(encoder), iter.getSkippedEdge1(), iter.getSkippedEdge2())); } } assertEquals(expected, given); }
@Test public void testContractNode_directed_shortcutRequired() { // 0 --> 1 --> 2 final EdgeIteratorState edge1 = graph.edge(0, 1, 1, false); final EdgeIteratorState edge2 = graph.edge(1, 2, 2, false); graph.freeze(); setMaxLevelOnAllNodes(); createNodeContractor().contractNode(1); checkShortcuts(expectedShortcut(0, 2, edge1, edge2, true, false)); }
@Test public void testShortestPathSkipNode2() { createExampleGraph(); final double normalDist = new Dijkstra(graph, weighting, traversalMode).calcPath(4, 2).getDistance(); assertEquals(3, normalDist, 1e-5); DijkstraOneToMany algo = new DijkstraOneToMany(graph, weighting, traversalMode); setMaxLevelOnAllNodes(); algo.setEdgeFilter(createIgnoreNodeFilter(3)); algo.setWeightLimit(10); int nodeEntry = algo.findEndNode(4, 2); assertEquals(4, algo.getWeight(nodeEntry), 1e-5); nodeEntry = algo.findEndNode(4, 1); assertEquals(4, algo.getWeight(nodeEntry), 1e-5); }
@Test public void testContractNode_bidirected_shortcutsRequired() { // 0 -- 1 -- 2 final EdgeIteratorState edge1 = graph.edge(0, 1, 1, true); final EdgeIteratorState edge2 = graph.edge(1, 2, 2, true); graph.freeze(); setMaxLevelOnAllNodes(); createNodeContractor().contractNode(1); checkShortcuts(expectedShortcut(0, 2, edge2, edge1, true, true)); }
@Test public void testShortestPathSkipNode() { createExampleGraph(); final double normalDist = new Dijkstra(graph, weighting, traversalMode).calcPath(4, 2).getDistance(); DijkstraOneToMany algo = new DijkstraOneToMany(graph, weighting, traversalMode); CHGraph lg = graph.getGraph(CHGraph.class); setMaxLevelOnAllNodes(); algo.setEdgeFilter(createIgnoreNodeFilter(3)); algo.setWeightLimit(100); int nodeEntry = algo.findEndNode(4, 2); assertTrue(algo.getWeight(nodeEntry) > normalDist); algo.clear(); algo.setMaxVisitedNodes(1); nodeEntry = algo.findEndNode(4, 2); assertEquals(-1, nodeEntry); }
@Test public void testShortcutMergeBug() { // We refer to this real world situation http://www.openstreetmap.org/#map=19/52.71205/-1.77326 // assume the following graph: // // ---1---->----2-----3 // \--------/ // // where there are two roads from 1 to 2 and the directed road has a smaller weight // leading to two shortcuts sc1 (unidir) and sc2 (bidir) where the second should NOT be rejected due to the larger weight final EdgeIteratorState edge1to2bidirected = graph.edge(1, 2, 1, true); final EdgeIteratorState edge1to2directed = graph.edge(1, 2, 1, false); final EdgeIteratorState edge2to3 = graph.edge(2, 3, 1, true); graph.freeze(); setMaxLevelOnAllNodes(); NodeContractor nodeContractor = createNodeContractor(); nodeContractor.contractNode(2); checkShortcuts( expectedShortcut(1, 3, edge2to3, edge1to2bidirected, false, true), expectedShortcut(1, 3, edge1to2directed, edge2to3, true, false) ); }
@Test public void testDirectedGraph() { //5 6 7 // \|/ //4-3_1<-\ 10 // \_|/ // 0___2_11 graph.edge(0, 2, 2, true); graph.edge(10, 2, 2, true); graph.edge(11, 2, 2, true); // create a longer one directional edge => no longish one-dir shortcut should be created final EdgeIteratorState edge2to1bidirected = graph.edge(2, 1, 2, true); final EdgeIteratorState edge2to1directed = graph.edge(2, 1, 10, false); final EdgeIteratorState edge1to3 = graph.edge(1, 3, 2, true); graph.edge(3, 4, 2, true); graph.edge(3, 5, 2, true); graph.edge(3, 6, 2, true); graph.edge(3, 7, 2, true); graph.freeze(); setMaxLevelOnAllNodes(); // find all shortcuts if we contract node 1 NodeContractor nodeContractor = createNodeContractor(); nodeContractor.contractNode(1); checkShortcuts( expectedShortcut(2, 3, edge1to3, edge2to1bidirected, true, true), expectedShortcut(2, 3, edge2to1directed, edge1to3, true, false) ); }
sc6to4.setSkippedEdges(iter6to8.getEdge(), iter8to4.getEdge()); setMaxLevelOnAllNodes(); lg.setLevel(8, 8); Shortcut manualSc1 = expectedShortcut(1, 4, iter1to3, iter3to4, true, true); Shortcut manualSc2 = expectedShortcut(4, 6, iter4to5, iter5to6, true, false); Shortcut manualSc3 = expectedShortcut(4, 6, iter6to8, iter8to4, false, true); checkShortcuts(manualSc1, manualSc2, manualSc3); NodeContractor nodeContractor = createNodeContractor(); nodeContractor.contractNode(4); checkShortcuts(manualSc1, manualSc2, manualSc3, expectedShortcut(1, 6, sc1to4, sc4to6, true, false), expectedShortcut(1, 6, sc6to4, sc1to4, false, true) );