0

nパズルの問題A* algorithmを解決するためにC++で実装しています。このリンク に擬似コードを実装しようとしました。 総コスト(F = H + G)の計算は、「コストは、置き忘れたタイルの数(ヒューリスティック)+初期状態(G)からのステップに依存します」です。以下 に示す関数のアルゴリズム。

AStar

問題は、私が無限ループの状況にあることです。どうすればこれを解決できますか?

PS:必要に応じて、で使用される他の関数の実装を提供できますAStar

どんな助けでもいただければ幸いです。

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);
    }    
}

}

4

3 に答える 3

1

ループの可能性、つまり、すでにアクセスした状態に戻る一連の移動の可能性があるため、重複する状態をチェックすることが重要です(明らかにツリー検索の問題ではありません)。私はあなたがこれをチェックして何をしているのかを完全に追跡することはできませんが、それが問題の原因である可能性があります。Haskellの実装を書いているときに私はあなたと同じような問題を抱えていました(詳細はここここにあります)、そしてそれは探索されたセットを処理する問題に帰着しました。正しく理解すれば、すべてが機能します。(4x4パズルの解決策を得るのは、特に状態空間の目標から遠く離れた状態から開始する場合は、ちょっとした失敗の問題のままですが、それは主にA*の欠陥と素朴な方法にかかっています私たち'

于 2011-10-20T08:39:34.367 に答える
1

開いているリストから選択した状態を削除しますか?これは非常に簡単でよく書かれたC#コードであり、おそらくあなたを助けることができます:http: //geekbrothers.org/index.php/categories/computer/12-solve-8-puzzle-with-a そしてA*も自動的にそれはあなたが考慮に入れる動きをとったのでループを避けてください

于 2013-09-07T06:59:10.303 に答える
0

また、nパズル(深さ優先探索とa *)の実装を行い、無限ループに入りました。これは、次のループが原因で発生しました:上、左、下、右、上、左...そのようなことを防ぐ方法があるかどうかは本当にわかりません(私ができる最大のことは、左右のようなループを防ぐことでした-左...最後の動きを思い出して)。

これがループの原因であるかどうかわからない場合、最善の方法は、すべての反復でボードを印刷して、実際に何が起こっているかを確認することです;)

于 2011-10-20T07:45:37.070 に答える