basic
Class AStarSearch<T>
java.lang.Object
core.Search<T>
core.DirectedSearch<T>
core.BestFirstSearch<T>
basic.AStarSearch<T>
- Type Parameters:
T
- the specific type of all elements of the search domain.
- All Implemented Interfaces:
- java.lang.Runnable
public class AStarSearch<T>
- extends BestFirstSearch<T>
The A* search algorithm is a heuristic search able
to solve any problem implementing the core.HeuristicProblem interface.
This search tries to expand those states at first
which are cheap to reach from the initial state and are most promising to reach a goal state.
To do this the core.HeuristicProblem#g(java.lang.Object) and core.HeuristicProblem#h(java.lang.Object) methods
are called for each state in order to approximate the overall costs needed
to reach a goal from the initial state.
This approximation for a state can be mathematically described with the following formula:
f(s) = g(s) + h(s)
Where g computes the path costs to reach state s and h estimates the costs needed to reach a goal.
This strategy grants completeness and a worst case time and space complexity
of O(b*^n)
(where b* is the effective branching factor and n the depth of the solution).
This search is able to generate optimal solutions whenever the following constraints hold
for all states s
in the search domain:
-
h(s) <= h(s') + cost(s,s')
for all successors s'
of state s
.
This constraint is called monotony and ensures that
the heuristic function h
is constantly falling.
-
h(s) <= g(t)
where t
is the nearest goal to state s
This constraint makes the heuristic function optimistic and
ensures that the best solution is found first.
In general this search should be used with enabled hashing and an updating queue.
(These are not the default values.)
Because in all cases where two or more paths from the initial state to an other state exists
you have to take care of updated states.
To cope with this situation you can select one of the following implementation patterns:
- Do not care:
If your search domain has constant path costs between each state and its successors,
you do not have to care about duplicates.
Because the first occurrence of a state s implies that each later occurrence of this state
has a greater sum of path costs. Thats why we can discard every state which has already been seen.
As a conclusion our search can now use the fast java.util.PriorityQueue and
the implicit duplicate handling mechanism.
Pros: Its probably the best solution.
Cons: Its only applicable for certain problems.
Example:
HeuristicProblem problem = new MyHeuristicProblem();
Search search = new AStarSearch(problem);
- Disable hashing:
A simple solution would be to create an A* search without hashing and without updating of the queue.
In this way all states will be inserted into the queue and ordered according to their current sum of path costs
without checking whether they have already been visited or not.
So if we revisit a state with lower path costs, we can simply add it again to the queue.
Because the queue will not update its elements the state with the lowest path costs will
be placed before its duplicates.
Pros: The major benefit of this solution is its simplicity and the fact that it uses the
fast java.util.PriorityQueue instead of the slow util.SortedQueue.
An other benefit is that you do not need to take care of duplicate states by your self.
Cons: If there exists no shortest path in the search domain, this solution
produces lots of unnecessary expansions of already expanded notes.
In fact this makes the search more space and time consuming.
Example:
HeuristicProblem problem = new MyHeuristicProblem();
Search search = new AStarSearch(problem, true, false);
-
User defined hashing:
Experienced users can create an A* search with custom hashing and with an updating queue.
The idea is that you keep track of all the visited states in a map,
where you can simply update each visited state whenever you found a better path.
You only have to make sure that the HeuristicProblem#expand(java.lang.Object) will only
return a list of states not visited before.
The util.SortedQueue implementation ensures, that the queue is updated whenever a state in it has changed.
(Please note that the sorted queue works slightly different, as described here!)
Pros: This solution saves lots of memory by prohibiting expansion of already visited states.
Further more it is a general solution applicable for all problems with alternative paths in the search space.
Cons: This solution is more time consuming because it must frequently update the queue
and the states itself.
In fact the util.SortedQueue is damn slow compared to the java.util.PriorityQueue.
Example:
class MyCustomProblem<T> extends MyHeuristicProblem<T>{
private Map<Integer,T> visited=new HashMap<Integer,T>();
public List expand(T state){
List result = new LinkedList();
for (T newState : super.expand(state) ){
oldState = visited.get( newState.hashCode() );
if (oldState == null){
result.add(newState);
visited.put(newState.hashCode(), newState);
}else{
update(oldState, newState);
}
}
return result;
}
public update(T oldState,T newState){
if ( g(oldState) > g(newState) ){
// update the state of the oldState Object
// ...
}
}
}
// ...
HeuristicProblem problem = new MyCustomProblem();
Search search = new AStarSearch(problem, false, false);
- Author:
- eden06
Constructor Summary |
AStarSearch(HeuristicProblem<T> problem)
Creates a new AStarSearch with the given problem. |
AStarSearch(HeuristicProblem<T> problem,
boolean update)
Create a new AStarSearch with the given problem
and a queue corresponding to the given update flag. |
AStarSearch(HeuristicProblem<T> problem,
boolean noHash,
boolean update)
Create a new AStarSearch with the given problem,
disabled hashing if the noHash flag is true
and a queue corresponding to the given update flag. |
Method Summary |
java.lang.Double |
f(T state)
This method estimates the costs to reach a goal state from the initial state
over the given state. |
Methods inherited from class java.lang.Object |
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
AStarSearch
public AStarSearch(HeuristicProblem<T> problem)
- Creates a new AStarSearch with the given problem.
The search will use implicit duplicate handling and no updating queue.
- Parameters:
problem
- the HeuristicProblem to be solved
AStarSearch
public AStarSearch(HeuristicProblem<T> problem,
boolean update)
- Create a new AStarSearch with the given problem
and a queue corresponding to the given update flag.
The search will also use implicit duplicate handling.
- Parameters:
problem
- the HeuristicProblem to be solvedupdate
- flag indicating whether the states in the queue should be updated or not.
AStarSearch
public AStarSearch(HeuristicProblem<T> problem,
boolean noHash,
boolean update)
- Create a new AStarSearch with the given problem,
disabled hashing if the noHash flag is true
and a queue corresponding to the given update flag.
- Parameters:
problem
- the HeuristicProblem to be solvednoHash
- flag indicating that duplicates should not be handledupdate
- flag indicating whether the states in the queue should be updated or not.
f
public java.lang.Double f(T state)
- This method estimates the costs to reach a goal state from the initial state
over the given state.
Note: This method uses the function core.HeuristicProblem#g(java.lang.Object)
and core.HeuristicProblem#h(java.lang.Object)to compute this estimation, and nothing else.
- Specified by:
f
in class BestFirstSearch<T>
- Parameters:
state
- to be evaluated
- Returns:
- the function value
- See Also:
BestFirstSearch.f(java.lang.Object)