Professional Documents
Culture Documents
public class DemoProblem implements GoalTest { //A state in DemoProblem contains only a integer to represent its ID public int m_val = 0;
/* There maybe many states, but we have only 3 actions named FIRST, SECOND, and THIRD to be able to applied to states */ public static Action FIRST = new DynamicAction("FIRST"); public static Action SECOND = new DynamicAction("SECOND"); public static Action THIRD = new DynamicAction("THIRD"); public DemoProblem(){ m_val = 0; } /* Return true if the input state statisfies the goal condition. Otherwise, return false */ public boolean isGoalState(Object state) { DemoProblem astate = (DemoProblem)state; if(astate.m_val == 11) return true; else return false; }
In order to solve a problem, we separate its discription and the algorithm for solving. In this example, DemoProblem has a state space as a tree in the following figure. o Start state is <0> o Goal state is <11> We can use any algorithm in the library , e.g., Breadth-First-Search, to start from the state state and find the goal state. Start State
0
10
11
12
Goal State
Step 3: Add inner class EPActionsFunction to DemoProblem: In AIMA Library, Interface ActionsFunction defines a function called actions. The purpose of this function is to get all of the actions THAT can be applied to the input state. In our demo, all of the three actions defined in DemoProblem are able to be applied at any node of the tree, see the figure above. Each node has three children generated by the three actions.
private static class EPActionsFunction implements ActionsFunction {
public Set<Action> actions(Object state) { Set<Action> actions = new LinkedHashSet<Action>(); actions.add(DemoProblem.FIRST); actions.add(DemoProblem.SECOND); actions.add(DemoProblem.THIRD); return actions; } }
Step 4: Add inner class EPResultFunction to DemoProblem: In AIMA Library, Interface ResultFunction defines a function called results. The purpose of this function is to get all of the children THAT can be obtained when we apply the input action a to the input state s. In this demo, we describe the tree shown in the figure above in this function.
private static class EPResultFunction implements ResultFunction { public Object result(Object s, Action a) { DemoProblem state = (DemoProblem)s; if(state.m_val == 0){ if(DemoProblem.FIRST.equals(a)){ System.out.println("" + 1); return new DemoProblem(1); } if(DemoProblem.SECOND.equals(a)){ System.out.println("" + 2); return new DemoProblem(2); } if(DemoProblem.THIRD.equals(a)){ System.out.println("" + 3); return new DemoProblem(3); } } if(state.m_val == 1){ if(DemoProblem.FIRST.equals(a)){ System.out.println("" + 4); return new DemoProblem(4); } if(DemoProblem.SECOND.equals(a)){ System.out.println("" + 5); return new DemoProblem(5); } if(DemoProblem.THIRD.equals(a)){ System.out.println("" + 6); return new DemoProblem(6); } } if(state.m_val == 2){ if(DemoProblem.FIRST.equals(a)){ System.out.println("" + 7); return new DemoProblem(7); } if(DemoProblem.SECOND.equals(a)){ System.out.println("" + 8); return new DemoProblem(8); }
if(DemoProblem.THIRD.equals(a)){ System.out.println("" + 9); return new DemoProblem(9); } } if(state.m_val == 3){ if(DemoProblem.FIRST.equals(a)){ System.out.println("" + 10); return new DemoProblem(10); } if(DemoProblem.SECOND.equals(a)){ System.out.println("" + 11); return new DemoProblem(11); } if(DemoProblem.THIRD.equals(a)){ System.out.println("" + 12); return new DemoProblem(12); } } // The Action is not understood or is a NoOp // the result will be the current state. return s;
} }
Step 5: Add the following functions to class DemoProblem in order to support the ability of selecting actions for each state and the result of applying an action to a state in DemoProblem.
private static ActionsFunction _actionsFunction = null; private static ResultFunction _resultFunction = null; public static ActionsFunction getActionsFunction() { if (null == _actionsFunction) { _actionsFunction = new EPActionsFunction(); } return _actionsFunction; } public static ResultFunction getResultFunction() { if (null == _resultFunction) { _resultFunction = new EPResultFunction(); } return _resultFunction; }
Step 7: Solve DemoProblem by Breadth-First-Search in AIMA Library. Create a class called BFSearch in package search as follows:
package search;
import java.util.List; import import import import import import aima.core.agent.Action; aima.core.search.framework.Problem; aima.core.search.framework.Search; aima.core.search.framework.SearchAgent; aima.core.search.framework.TreeSearch; aima.core.search.uninformed.BreadthFirstSearch;
public class BFSearch { public static void main(String args[]) { try{ //(1)Create a problem object Problem problem = new Problem(new DemoProblem(0), DemoProblem.getActionsFunction(), DemoProblem.getResultFunction(), new DemoProblem(0)); //(2)Create an algorithm object, BreadthFirstSearch Search search = new BreadthFirstSearch( new TreeSearch()); //(3)Create an object to solve the problem by the algorithm SearchAgent agent = new SearchAgent(problem, search); //(4)Get the solution path List<Action> actions = agent.getActions(); //(5)Print the path if you need for(Action a: actions){ System.out.println(a.toString()); } } catch(Exception e){ System.out.println(e.toString()); }
} }
III. Exercises.
1. Change the goal state in the tree above, then compile and run. 2. Change the structure of the tree above to any tree that you need. Remember to specify start state, goal state, how many actions we can apply to a state, how many state that we can obtain if we apply an action to a state. 3. Use Depth-First-Search and Other search strategies to the probem above. 4. Describe the 8-puzzle game.