/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.graph.traverse.standard; import java.util.HashMap; import java.util.Map; import junit.framework.TestCase; import org.geotools.graph.GraphTestUtil; import org.geotools.graph.build.GraphBuilder; import org.geotools.graph.build.basic.BasicGraphBuilder; import org.geotools.graph.path.AStarShortestPathFinder; import org.geotools.graph.path.Path; import org.geotools.graph.structure.GraphVisitor; import org.geotools.graph.structure.Graphable; import org.geotools.graph.structure.Node; import org.geotools.graph.traverse.GraphTraversal; import org.geotools.graph.traverse.basic.BasicGraphTraversal; import org.geotools.graph.traverse.basic.CountingWalker; import org.geotools.graph.traverse.standard.AStarIterator.AStarNode; public class AStarIteratorTest extends TestCase{ public GraphBuilder m_builder; public AStarIteratorTest(String name) { super(name); } protected void setUp() throws Exception { super.setUp(); m_builder = createBuilder(); } /** Test 0: * Graph with no bifurcations. 100 nodes. * G = 1 for all edges * H = TargetsID - currentID * Expected: * 1. Every node should be visited * 2. ParentID = SonsID - 1 * */ public void test_0() { final int nnodes = 100; Node[] ends = GraphTestUtil.buildNoBifurcations(builder(), nnodes); CountingWalker walker = new CountingWalker(); final AStarIterator iterator = createIterator(ends[0],ends[ends.length-1]); BasicGraphTraversal traversal = new BasicGraphTraversal( builder().getGraph(), walker, iterator ); traversal.init(); traversal.traverse(); GraphVisitor visitor = new GraphVisitor() { public int visit(Graphable component) { assertTrue(component.isVisited()); if (component.getID() == 0) assertNull(iterator.getParent((Node) component)); else assertTrue(component.getID() == iterator.getParent((Node)component).getID() + 1); return 0; } }; builder().getGraph().visitNodes(visitor); assertTrue(walker.getCount() == nnodes); } /** * Create a graph with no bifurcations and start a traversal from start * node, then suspend, and resume. <BR> * <BR> * Expected: After suspend: * 1. Nodes from 0 to suspend node should be visted, others not. * * After resume: * 1. Next node visited should have id suspend node id + 1 * 2. Every node should have a parent with id node id + 1 */ public void test_1() { int nnodes = 100; Node[] ends = GraphTestUtil.buildNoBifurcations(builder(), nnodes); final int suspend = 50; CountingWalker walker = new CountingWalker() { int m_mode = 0; public int visit(Graphable element, GraphTraversal traversal) { super.visit(element, traversal); if (m_mode == 0) { if (element.getID() == suspend) { m_mode++; return(GraphTraversal.SUSPEND); } } else if (m_mode == 1) { assertTrue(element.getID() == suspend+1); m_mode++; } return(GraphTraversal.CONTINUE); } }; final AStarIterator iterator = createIterator(ends[0],ends[ends.length-1]); BasicGraphTraversal traversal = new BasicGraphTraversal( builder().getGraph(), walker, iterator ); traversal.init(); traversal.traverse(); GraphVisitor visitor = new GraphVisitor() { public int visit(Graphable component) { if (component.getID() <= suspend) assertTrue(component.isVisited()); else assertTrue(!component.isVisited()); return 0; } }; builder().getGraph().visitNodes(visitor); assertTrue(walker.getCount() == nnodes-suspend+1); //resume traversal.traverse(); visitor = new GraphVisitor() { public int visit(Graphable component) { assertTrue(component.isVisited()); if (component.getID() == 0) assertNull(iterator.getParent((Node)component)); else assertTrue( iterator.getParent((Node)component).getID() == component.getID() - 1 ); return 0; } }; builder().getGraph().visitNodes(visitor); assertTrue(walker.getCount() == nnodes); } /** * Create a balanced binary tree and do a normal traversal starting at root. * <BR> * <BR> * Expected: 1. #nodes_visited <= #nodes * 2. The parent of each node should be the same as * the parent of the tree. * 3. G = depth. * H = infinity if the target is not in any subtree of this node or * depth difference between target node and current node otherwise. * @throws WrongPathException * */ public void test_3() { int k = 4; Object[] obj = GraphTestUtil.buildPerfectBinaryTree(builder(), k); final Node root = (Node)obj[0]; final HashMap map = (HashMap) obj[1]; HashMap rmap = new HashMap(); Map.Entry[] set = new Map.Entry[map.size()]; map.entrySet().toArray(set); for (int i = 0; i < set.length; i++) { rmap.put(set[i].getValue(), set[i].getKey()); } final HashMap hashmap = rmap; class Factory { public AStarIterator.AStarFunctions createFunctions(Node target) { return ( new AStarIterator.AStarFunctions(target) { public double cost(AStarNode n1, AStarNode n2){ return 1; } public double h(Node n){ String dest = hashmap.get(this.getDest()).toString(); String current = hashmap.get(n).toString(); if (dest.startsWith(current)) { // n under dest dest=dest.replaceAll("\\D", ""); current = current.replaceAll("\\D", ""); return dest.length()-current.length(); } else { return Double.POSITIVE_INFINITY; } } } ); } } Factory f = new Factory(); AStarShortestPathFinder walker = new AStarShortestPathFinder(builder().getGraph(),root,((Node) map.get("0.1.0.1")), f.createFunctions(((Node) map.get("0.1.0.1")))); walker.calculate(); MyVisitor visitor = new MyVisitor(); builder().getGraph().visitNodes(visitor); //#1 assertTrue(visitor.count > 0); assertTrue(visitor.count < map.size() + 1); Path p = null; try { p = walker.getPath(); } catch (Exception e) { e.printStackTrace(); } p.getEdges(); assertTrue(p.size() == 4); // #2 for (int j = 0; j < p.size() - 1; j++) { Node n = (Node) p.get(j); Node parent = (Node) p.get(j + 1); String n_id = rmap.get(n).toString(); String parent_id = rmap.get(parent).toString(); assertTrue(n_id.startsWith(parent_id)); } } private class MyVisitor implements GraphVisitor { public int count = 0; public int visit(Graphable component) { if (component.isVisited()) { count++; } return 0; } } protected GraphBuilder createBuilder() { return(new BasicGraphBuilder()); } protected GraphBuilder builder() { return(m_builder); } protected AStarIterator createIterator(Node source, Node target) { return ( new AStarIterator(source, new AStarIterator.AStarFunctions(target) { public double cost(AStarNode n1, AStarNode n2){ return 1; } public double h(Node n){ return (getDest().getID()-n.getID()); } }) ); } }