001    package aima.search.framework;
002    
003    import aima.search.framework.Search;
004    import aima.search.framework.GraphSearch;
005    import aima.search.framework.TreeSearch;
006    import aima.search.framework.QueueSearch;
007    import aima.search.informed.AStarEvaluationFunction;
008    import aima.search.informed.AStarSearch;
009    import aima.search.informed.GreedyBestFirstSearch;
010    import aima.search.informed.HillClimbingSearch;
011    import aima.search.informed.RecursiveBestFirstSearch;
012    import aima.search.uninformed.BreadthFirstSearch;
013    import aima.search.uninformed.DepthFirstSearch;
014    import aima.search.uninformed.IterativeDeepeningSearch;
015    import aima.search.uninformed.UniformCostSearch;
016    
017    /**
018     * Useful factory for configuring search objects. Implemented
019     * as a singleton.
020     * @author R. Lunde
021     */ 
022    public class SearchFactory {
023    
024            /** Search strategy: Depth first search. */
025            public final static int DF_SEARCH = 0;
026            /** Search strategy: Depth first search. */
027            public final static int BF_SEARCH = 1;
028            /** Search strategy: Iterative deepening search. */
029            public final static int ID_SEARCH = 2;
030            /** Search strategy: Uniform cost search. */
031            public final static int UC_SEARCH = 3;
032            /** Search strategy: Greedy best first search. */
033            public final static int GBF_SEARCH = 4;
034            /** Search strategy: A* search. */
035            public final static int ASTAR_SEARCH = 5;
036            /** Search strategy: Recursive best first search. */
037            public final static int RBF_SEARCH = 6;
038            /** Search strategy: Hill climbing search. */
039            public final static int HILL_SEARCH = 7;
040    
041            /** Search mode: tree search. */
042            public final static int TREE_SEARCH = 0;
043            /** Search mode: graph search. */
044            public final static int GRAPH_SEARCH = 1;
045            
046            /** Contains the only existing instance. */
047            private static SearchFactory instance;
048            /** Invisible constructor. */
049            private SearchFactory() {};
050            
051            /** Provides access to the factory. Implemented with lazy instantiation. */
052            public static SearchFactory getInstance() {
053                    if (instance == null)
054                            instance = new SearchFactory();
055                    return instance;
056            }
057            
058            /**
059             * Returns the names of all search strategies, which are supported
060             * by this factory. The indices correspond to the parameter values
061             * of method {@link #createSearch(int, int)}.
062             */ 
063            public String[] getSearchStrategyNames() {
064                    return new String[]{
065                                    "Depth First", "Breadth First", "Iterative Deepening",
066                                    "Uniform Cost", "Greedy Best First", "A*",
067                                    "Recursive Best First", "Hill Climbing"};
068            }
069            
070            /**
071             * Returns the names of all search modes, which are supported
072             * by this factory. The indices correspond to the parameter values
073             * of method {@link #createSearch(int, int)}.
074             */ 
075            public String[] getSearchModeNames() {
076                    return new String[]{"Tree Search", "Graph Search"};
077            }
078            
079            /**
080             * Creates a search instance.
081             * @param strategy search strategy. See static constants.
082             * @param mode     search mode: {@link #TREE_SEARCH} or {@link #GRAPH_SEARCH}
083             * 
084             */
085            public Search createSearch(int strategy, int mode) {
086                    QueueSearch qs = null;
087                    Search result = null;
088                    switch(mode) {
089                    case TREE_SEARCH: qs = new TreeSearch(); break;
090                    case GRAPH_SEARCH: qs = new GraphSearch();
091                    }
092                    switch (strategy) {
093                            case DF_SEARCH:
094                                    result = new DepthFirstSearch(qs); break;
095                            case BF_SEARCH:
096                                    result = new BreadthFirstSearch(qs); break;
097                            case ID_SEARCH:
098                                    result = new IterativeDeepeningSearch(); break;
099                            case UC_SEARCH:
100                                    result = new UniformCostSearch(qs); break;
101                            case GBF_SEARCH:
102                                    result = new GreedyBestFirstSearch(qs); break;
103                            case ASTAR_SEARCH:
104                                    result = new AStarSearch(qs); break;
105                            case RBF_SEARCH:
106                                    result = new RecursiveBestFirstSearch(new AStarEvaluationFunction()); break;
107                            case HILL_SEARCH:
108                                    result = new HillClimbingSearch(); break;
109                    }
110                    return result;
111            }
112    }