001    package aima.test.search.searches;
002    
003    import junit.framework.TestCase;
004    import aima.basic.BasicEnvironmentView;
005    import aima.search.framework.HeuristicFunction;
006    import aima.search.informed.AStarEvaluationFunction;
007    import aima.search.informed.RecursiveBestFirstSearch;
008    import aima.search.map.Map;
009    import aima.search.map.MapAgent;
010    import aima.search.map.MapEnvironment;
011    import aima.search.map.Point2D;
012    import aima.search.map.SimplifiedRoadMapOfPartOfRomania;
013    
014    /**
015     * @author Ciaran O'Reilly
016     * 
017     */
018    public class RecursiveBestFirstSearchTest extends TestCase {
019    
020            StringBuffer envChanges;
021    
022            Map aMap;
023    
024            RecursiveBestFirstSearch recursiveBestFirstSearch;
025    
026            HeuristicFunction heuristicFunction;
027    
028            @Override
029            public void setUp() {
030                    envChanges = new StringBuffer();
031    
032                    aMap = new SimplifiedRoadMapOfPartOfRomania();
033    
034                    recursiveBestFirstSearch = new RecursiveBestFirstSearch(
035                                    new AStarEvaluationFunction());
036    
037                    heuristicFunction = new HeuristicFunction() {
038                            public double getHeuristicValue(Object state) {
039                                    Point2D pt1 = aMap.getPosition((String) state);
040                                    Point2D pt2 = aMap.getPosition(SimplifiedRoadMapOfPartOfRomania.BUCHAREST);
041                                    return pt1.distance(pt2);
042                            }
043                    };
044            }
045    
046            public void testStartingAtGoal() {
047                    MapEnvironment me = new MapEnvironment(aMap);
048                    MapAgent ma = new MapAgent(me, recursiveBestFirstSearch,
049                                    new String[] { SimplifiedRoadMapOfPartOfRomania.BUCHAREST });
050                    ma.setHeuristicFunction(heuristicFunction);
051    
052                    me.addAgent(ma, SimplifiedRoadMapOfPartOfRomania.BUCHAREST);
053                    me.registerView(new BasicEnvironmentView() {
054                            @Override
055                            public void envChanged(String command) {
056                                    envChanges.append(command).append(":");
057                            }
058                    });
059                    me.stepUntilDone();
060    
061                    assertEquals(
062                                    "CurrentLocation=In(Bucharest), Goal=In(Bucharest):NoOP:METRIC[pathCost]=0.0:METRIC[maxRecursiveDepth]=0:METRIC[nodesExpanded]=0:NoOP:",
063                                    envChanges.toString());
064            }
065    
066            public void testExampleFromBookFigure4_6Page103() {
067                    MapEnvironment me = new MapEnvironment(aMap);
068                    MapAgent ma = new MapAgent(me, recursiveBestFirstSearch,
069                                    new String[] { SimplifiedRoadMapOfPartOfRomania.BUCHAREST });
070                    ma.setHeuristicFunction(heuristicFunction);
071    
072                    me.addAgent(ma, SimplifiedRoadMapOfPartOfRomania.ARAD);
073                    me.registerView(new BasicEnvironmentView() {
074                            @Override
075                            public void envChanged(String command) {
076                                    envChanges.append(command).append(":");
077                            }
078                    });
079                    me.stepUntilDone();
080    
081                    assertEquals(
082                                    "CurrentLocation=In(Arad), Goal=In(Bucharest):Sibiu:RimnicuVilcea:Pitesti:Bucharest:METRIC[pathCost]=418.0:METRIC[maxRecursiveDepth]=4:METRIC[nodesExpanded]=6:NoOP:",
083                                    envChanges.toString());
084            }
085    }