简体   繁体   English

解决滑动拼图拼图时的A *算法执行很长时间

[英]A* Algorithm while solving Sliding Tile puzzle executes for a very long time

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). 在尝试运行24 Tile puzzle及其以上代码的同时,代码执行了很长时间(大于3分钟)(对于8 Tile拼图,它运行得非常快)。 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 :- 这是Priority Queue比较器的代码: -

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. 我不确定为什么我的A *实现需要花费很长时间来计算24个拼图拼图。 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. 正如Turing85所提到的,这是一个NP完全问题,所以你不太可能有一个快速的运行时间。

I would suggest that you can do the following: 我建议您可以执行以下操作:

  1. Try to use different heuristic 尝试使用不同的启发式方法
  2. Try to use bidirectional search 尝试使用双向搜索

I know this is an old question, but I just had the same problem. 我知道这是一个老问题,但我遇到了同样的问题。

Apparently, Arrays.hashCode(allCells); 显然, 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. 尝试这个替代哈希的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM