While trying to run the code for 24 Tile puzzle and above, the code executes for a very long time (Greater than 3 minutes) (It runs pretty quick for 8 Tile puzzle). The code can be found below.
while (openQueue.isEmpty() == false) {
State queueHead = openQueue.remove();
openMap.remove(queueHead.hashCode());
closedMap.put(queueHead.hashCode(), queueHead);
State queueHeadState = queueHead;
if (Constants.debug) {
System.out.println("Popped State");
HeuristicSolverUtility.printState(queueHead);
}
// If reached goal state . Termination condition.
if (queueHead.equals(goalState)) {
break;
} else {
List<Action> listOfPossibleActions = queueHeadState
.getPossibleActions();
Iterator<Action> actIter = listOfPossibleActions.iterator();
while (actIter.hasNext()) {
// Here it performs Tile UP, DOWN, LEFT and RIGHT operations
Action actionOnState = actIter.next();
StateP newState = actionOnState.applyTo(queueHeadState);
newState.setHeuristicCost((double) ManhattanDistance
.calculate(newState));
newState.setParent(queueHead);
newState.setAction(actionOnState);
if (!closedMap.containsKey(newState.hashCode()) && !openMap.containsKey(newState.hashCode())) {
openQueue.offer(newState);
openMap.put(newState.hashCode(), newState);
} else if (openMap.containsKey(newState.hashCode())) {
System.out.println("State found in Open Map");
State stateFetchedFromOpenMap = openMap.get(newState.hashCode());
if (stateFetchedFromOpenMap.getPathCost() > newState.getPathCost()) {
openMap.remove(stateFetchedFromOpenMap.hashCode());
openMap.put(newState.hashCode(), newState);
openQueue.remove(stateFetchedFromOpenMap);
openQueue.add(newState);
}
}
}
}
}
This is my hashcode :
@Override
public int hashCode() {
return Arrays.hashCode(allCells);
}
And this is the code for Priority Queue comparator :-
public static class HeuristicComparator implements Comparator<State> {
public int compare(State o1, State o2) {
Double result;
result = o1.getKey() - o2.getKey();
if (result == 0.0) {
// Ties among minimal f values are resolved in favor of the
// deepest node in the search tree
// i.e. the closest node to the goal
result = (double) (o2.getPathCost() - o1.getPathCost());
}
if (result > 0.0) {
return 1;
}
return -1;
}
}
I am not sure why does it take so long for my A* implementation to compute for 24 tile puzzle and up. How can I optimize my code to compute faster, also is there any bug that is causing it to take so long?
If you are interested in the entire code, it can be found here
As Turing85 has mentioned, this is an NP-complete problem, so it's unlikely that you will have a fast runtime.
I would suggest that you can do the following:
I know this is an old question, but I just had the same problem.
Apparently, Arrays.hashCode(allCells); is really really slow, and using another hash code can make the algorithm run much faster.
Try this answer for alternative hash.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With