2017-11-25 24 views
-2

A *経路探索アルゴリズムの最後の部分を2D配列に実装する際に問題があります。 https://www.raywenderlich.com/4946/introduction-to-a-pathfinding のチュートリアルを使用しています。最後には、擬似コードがあります。私はこのコードを最後まで辿ることができました。私のコードと擬似コードとの違いは、すべてのノードのすべてのG、H、F値をあらかじめ計算しておくことです。これが、最後のステップを実装する際に問題がある理由です。A *経路探索アルゴリズムの実装

[openList add:originalSquare]; // start by adding the original position to the open list 
do { 
currentSquare = [openList squareWithLowestFScore]; // Get the square with the lowest F score 

[closedList add:currentSquare]; // add the current square to the closed list 
[openList remove:currentSquare]; // remove it to the open list 

if ([closedList contains:destinationSquare]) { // if we added the destination to the closed list, we've found a path 
    // PATH FOUND 
    break; // break the loop 
} 

adjacentSquares = [currentSquare walkableAdjacentSquares]; // Retrieve all its walkable adjacent squares 

foreach (aSquare in adjacentSquares) { 

    if ([closedList contains:aSquare]) { // if this adjacent square is already in the closed list ignore it 
     continue; // Go to the next adjacent square 
    } 

    if (![openList contains:aSquare]) { // if its not in the open list 

     // compute its score, set the parent 
     [openList add:aSquare]; // and add it to the open list 

    } else { // if its already in the open list 

     // test if using the current G score make the aSquare F score lower, if yes update the parent because it means its a better path 

    } 
} 

} while(![openList isEmpty]); // Continue until there is no more available square in the open list (which means there is no path) 

このチュートリアルではObjective-Cで書かれていますが、私の実装はC++で書かれています。すでにたくさん助けになるelseステートメント内に入る必要があります何のため

AStarPath AStarSearch::calculatePath() 
{ 
    if (!wasInit) 
    { 
     throw "AStarSearch::calculatePath(): A* Search was not initialized!\n"; 
    } 
    /*Create open and closed lists*/ 
    std::vector<AStarNode*> openList; 
    std::vector<AStarNode*> closedList; 

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

    do 
    { 
     /*Get square with lowest F score in the open list*/ 
     AStarNode* currentNode = openList[0]; 
     for (int index = 0; index < openList.size(); ++index) 
     { 
      if (openList[index]->getF() < currentNode->getF()) 
       currentNode = openList[index]; 
     } 

     /*Remove the current node from the open list, add it to the closed list*/ 
     std::remove(openList.begin(), openList.end(), currentNode); 
     closedList.push_back(currentNode); 

     /*Check if the destination is in the closed list*/ 
     if (std::find(closedList.begin(), closedList.end(), endNode) != closedList.end()); 
     { 
      /*Found a path, break the loop*/ 
      break; 
     } 

     /*Find walkable and adjacent nodes*/ 
     std::vector<AStarNode*> walkableAdjacent = getWalkableAdjacentNodes(currentNode->getX(), currentNode->getY()); 
     for (std::vector<AStarNode*>::iterator it = walkableAdjacent.begin(); it != walkableAdjacent.end(); ++it) 
     { 
      /*Skip the node if it is in the closed list*/ 
      if (std::find(closedList.begin(), closedList.end(), *it) != closedList.end()) 
      { 
       /*Skip to next node*/ 
       continue; 
      } 
      /*If the node is not in the open list, set it's parent and add it to the open list*/ 
      if (std::find(openList.begin(), openList.end(), *it) != closedList.end()) 
      { 
       /*Set the parent to the current node*/ 
       (*it)->setParent(currentNode); 
       /*Add the node to the open list*/ 
       openList.push_back(*it); 
      } 
      /*If the node is in the open list*/ 
      else 
      { 
       //This is the part I'm having trouble with 
      } 
     } 

    } while (!openList.empty()); 
} 

擬似コード: はここに私のcalculatePath機能です。

編集:私はelseステートメントの中にこれを書いたとき、私は修正アム:

/*Check if the node has a better G value than the current node*/ 
if ((*it)->getG() < currentNode->getG()) 
{ 
    /*Do I have to set a parent here?*/ 
} 

編集2:私は、私の質問はdownvotesを得ている参照してください。誰かが私が間違っていることを教えてもらえますか?そうすれば、自分自身を修正し、必要に応じてより多くの情報を与えたり、次の質問から学ぶことができます。

+0

大きな問題は、 'openList.erase(it);'が 'it'を無効にすることです。このループを 'std :: remove(openList.begin()、openList.end()、currentNode);に置き換えてください。 – molbdnilo

+0

これを変更しますが、Visual Studioで入力したら、 :ベクトル< stuff>をconst char * – MivVG

+0

私はstd :: removeの参照を探しました。これは文字列のためであり、ベクトルのためではありません。 – MivVG

答えて

0

私はすべてのGとFの値を事前に計算しているので、else文でそれらを更新することに意味がないので、空にしておくことができます。

関連する問題