首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C++的A*算法求解n个难题

用C++的A*算法求解n个难题
EN

Stack Overflow用户
提问于 2011-10-18 04:04:17
回答 3查看 11.5K关注 0票数 0

我正在C++中实现C++,以解决n难题.

我试图在链接中实现伪代码。

总成本(F=H+G)计算是“成本取决于错误放置的瓷砖数量(启发式)+从初始状态(G)开始的步骤”。给出了AStar函数的算法。

问题是,我有一个无限循环的情况。我怎么才能解决这个问题?

PS:如果需要的话,我可以给出AStar中使用的其他函数的实现。

任何帮助都将不胜感激。

代码语言:javascript
复制
void AStar(const int size, int** puzzle)
{
int moveCount = 0;                                                                  // initialize G(n)
int**goalState = GoalState(size);                                                   // initialize  and assign goal state
int openListIndex = 0;                                                              // initialize open list index
vector<node> openList;                                                              // initialize open list
vector<node> closedList;                                                            // initialize closed list

node startNode;                                                                     // initialize start node
startNode.puzzleArray = puzzle;                                                     // assign start node's state
startNode.cost = moveCount + Heuristics(goalState,puzzle,size);                     // assign start node's cost

node goalNode;                                                                      // initialize goal node
goalNode.puzzleArray = goalState;                                                   // assign goal node's state

openList.push_back(startNode);                                                      // push start node to the open list

while (!openList.empty())                                                           // loop while open list is not empty
{
    node currentNode = CalculateLowestCost(&openList, &closedList);                 // initialize current node which has the lowest cost, pop it from open list, push it to the closed list
    int** currentState = currentNode.puzzleArray;                                   // initialize and assign current state array
    /*********************************************************************************************/
    if (GoalCheck(goalState, currentState, size)) break;                            // GOAL CHECK//
    /*********************************************************************************************/
    vector<char> successorDirectionList = CalculateSuccessor(size, currentState);   // initialize a char vector for the directions of the successors

    int**successor;                                                                 // initialize successor state
    node successorNode;                                                             // initialize successor node
    moveCount++;                                                                    // advance G(n)

    for (;!successorDirectionList.empty();)                                         // loop over the successor list
    {
        char direction = successorDirectionList.back();                             // take a direction from the list
        successorDirectionList.pop_back();                                          // remove that direction from the list
        successor = MoveBlank(currentState, size, direction);                       // assign successor state

        successorNode.puzzleArray = successor;                                      // assign successor node's state
        successorNode.cost = moveCount + Heuristics(goalState,currentState,size);   // assign successor node's cost

        //vector<node> stateCheckList = openList;                                   // copy the open list for the checking the nodes in that list

        bool flagOpen = false;
        bool flagClosed = false;
        int locationOpen = -1;
        int locationClosed = -1;

        for (int i=0; i<openList.size(); i++)
        {
            int** existing = openList[i].puzzleArray;
            int existingCost = openList[i].cost;

            if (StateCheck(successor, existing, size))
            {
                locationOpen = i;
                if (successorNode.cost > existingCost)
                {
                    flagOpen = true;
                    break;
                }
            }
        }
        if (flagOpen) continue;

        int** existingInOpen;
        if(locationOpen != -1) 
        {
            existingInOpen = openList[locationOpen].puzzleArray;
            openList.erase(openList.begin()+locationOpen);
        }

        for (int i=0; i<closedList.size(); i++)
        {
            int** existing = closedList[i].puzzleArray;
            int existingCost = closedList[i].cost;

            if (StateCheck(successor, existing, size))
            {
                locationClosed = i;
                if (successorNode.cost > existingCost)
                {
                    flagClosed = true;
                    break;
                }
            }
        }
        if (flagClosed) continue;

        int**existingInClosed;
        if(locationClosed != -1)
        {
            existingInClosed = closedList[locationClosed].puzzleArray;
            closedList.erase(closedList.begin()+locationClosed);
        }

        openList.push_back(successorNode);
    }    
}

}

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-20 08:39:34

由于循环的可能性,也就是将您带回到您已经访问过的状态的一系列移动,所以检查重复状态是很重要的(显然,树搜索不是问题)。我不太明白你在做什么检查这个,但这很可能是问题所在。在编写Haskell实现(details 这里这里)时,我遇到了类似的问题,问题归结为处理探索集的问题。做得对,一切都正常。(要解决4x4的难题仍然是一件偶然的事情,特别是如果你从状态空间中的目标开始很长一段时间,但这主要是因为A*的缺陷和我们处理可能发生的动作的天真方式。)

票数 1
EN

Stack Overflow用户

发布于 2013-09-07 06:59:10

是否从公开列表中删除所选择的状态?这是一个非常简单和编写良好的C#代码,也许它可以帮助您:http://geekbrothers.org/index.php/categories/computer/12-solve-8-puzzle-with-a和A*自动避免循环,因为它采取了您要考虑的步骤

票数 1
EN

Stack Overflow用户

发布于 2011-10-20 07:45:37

我还实现了一个n字谜(深度优先和*),它进入无限循环。这是因为下面的循环:上,左,下,右,上,左.我真的不知道是否有办法防止这样的事情(我能做的最大就是防止像左-右-左)这样的循环.通过记忆它最后的动作)。

不知道这是否是导致你循环的原因,最好的方法是在每次迭代中打印板,看看到底发生了什么;)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7802290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档