basic
Class DepthLimitedSearch<T>

java.lang.Object
  extended by core.Search<T>
      extended by basic.DepthLimitedSearch<T>
Type Parameters:
T - the specific type of all elements in the search domain.
All Implemented Interfaces:
java.lang.Runnable

public class DepthLimitedSearch<T>
extends Search<T>

The depth limited search algorithm is a blind search able to solve any problem implementing the core.TreeProblem interface. Depth limited search is a subclass of core.Search because it uses recursion rather then the general search algorithm employed in core.DirectedSearch.

The depth limited search uses a recursive function to expand all states in the search tree. This function calls itself for each successor of the given state, and terminates only if a goal has been found, the depth limit is reached or all successors have been explored.
This strategy grants a time complexity of O(b^l) and a space complexity of O(b*l) (where b is the branching factor and l is the selected depth limit).
In contrast to other algorithms depth limited search is complete only if there is a solution s with problem.depth(s) < limit. The biggest problem now is to estimate the depth limit.
Despite the fact that this strategy can not generate optimal solutions, it can solve big problems in a memory saving way.
In general this algorithm is only applicable to search domains where you can estimate the depth of the solution in an appropriate way.
Note: You should prefer basic.IterativeDeepeningSearch whenever the depth limit can not be estimated.

To avoid duplicate states during the search a HashSet is used, which tries to hash all expanded states in order to inhibit further expansion. In detail there are two important rules for states of type T which allow proper hashing:

In some cases it is necessary to turn of the implicit duplicate handling mechanism. For example there are no duplicate states in the search domain, or special knowledge about the search domain makes customized duplicate handling more feasible.
The following example shows how to implement a duplicate handling mechanism and how to disable the implicit duplicate handling mechanism:
 
 class MyTreeProblem<T> extends TreeProblem<T>{
        private Set<Integer> visited=new HashSet<Integer>();
     
        public List expand(T state){
                List result = new LinkedList();
                for (T newState : super.expand(state) ){
                        if ( visited.add( newState.hashCode() ) ){
                                result.add(newState);
                        }
                }
                return result;
        }
     
 } 
 
 // ...
 
 TreeProblem problem = new MyTreeProblem();
 //Turn of the implicit duplicate handling mechanism
 Search search = new DepthLimitedSearch(problem, 1000, false);
 

Author:
eden06

Field Summary
protected  java.util.Set<T> hash
          holds the set used for duplicate handling
protected  int limit
          holds the depth limit used for this search
protected  TreeProblem<T> problem
          holds a reference to the problem to be solved
 
Fields inherited from class core.Search
neededSteps, result
 
Constructor Summary
DepthLimitedSearch(TreeProblem<T> problem, int limit)
          Create a new DepthLimitedSearch with the given problem, going down to the given limit.
DepthLimitedSearch(TreeProblem<T> problem, int limit, boolean noHash)
          Create a new DepthLimitedSearch with the given problem, going down to the given limit and disabled hashing if the noHash flag is true.
 
Method Summary
 int branchedNodes()
          This method returns the number of expanded nodes during the search.
protected  boolean canPrepare()
          This method checks if the given problem returns a valid initial state.
 int depthLimit()
          This method returns the depth to which the search domain will be explored
 TreeProblem<T> getProblem()
          This method returns the problem, with which this search has been created.
protected  void prepare()
          This method clears the hash used for duplicate handling to prepare it for a new search run.
protected  void search()
          This method looks for a goal in the search domain, by calling a recursive function which expands a state and calls itself for all successor states, until the depth limit is reached.
 
Methods inherited from class core.Search
finalize, getResult, initialize, initialized, neededSteps, run, running, stop
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

problem

protected TreeProblem<T> problem
holds a reference to the problem to be solved


limit

protected int limit
holds the depth limit used for this search


hash

protected java.util.Set<T> hash
holds the set used for duplicate handling

Constructor Detail

DepthLimitedSearch

public DepthLimitedSearch(TreeProblem<T> problem,
                          int limit)
Create a new DepthLimitedSearch with the given problem, going down to the given limit. The search will use implicit duplicate handling.

Parameters:
problem - the core.Poblem to be solved
limit - of the exploration depth

DepthLimitedSearch

public DepthLimitedSearch(TreeProblem<T> problem,
                          int limit,
                          boolean noHash)
Create a new DepthLimitedSearch with the given problem, going down to the given limit and disabled hashing if the noHash flag is true.

Parameters:
problem - the core.Poblem to be solved
limit - of the exploration depth
noHash - flag indicating that duplicates should not be handled
Method Detail

canPrepare

protected boolean canPrepare()
This method checks if the given problem returns a valid initial state.

Specified by:
canPrepare in class Search<T>
Returns:
true if the search can be prepared
See Also:
Search.canPrepare()

prepare

protected void prepare()
This method clears the hash used for duplicate handling to prepare it for a new search run.

Specified by:
prepare in class Search<T>
See Also:
Search.prepare()

search

protected void search()
This method looks for a goal in the search domain, by calling a recursive function which expands a state and calls itself for all successor states, until the depth limit is reached.
Note: A more accurate description is given in basic.DepthLimitedSearch.

Specified by:
search in class Search<T>
See Also:
Search.search()

branchedNodes

public final int branchedNodes()
This method returns the number of expanded nodes during the search. Note: This method is a alias for neededSteps() and has the same result.

Returns:
the number of expanded nodes

getProblem

public final TreeProblem<T> getProblem()
This method returns the problem, with which this search has been created.

Returns:
the problem to be solved

depthLimit

public final int depthLimit()
This method returns the depth to which the search domain will be explored

Returns:
the depth limit of this search