私はastarアルゴリズムのJustinHeyes-Jones実装を使用しています。私のヒューリスティック関数は、ユークリッド距離です。添付の図面(品質が悪いため申し訳ありません)には、特定の状況が示されています。ノード1からノード2に移動するとします。最短の方法はノードa --b --c --d--eを通過します。しかし、ユークリッドヒューリスティックを使用した段階的なAstarは、次のノードを通過する方法を提供します:a --b'--c'--d'--eそして私はこれがなぜ起こるのか理解しています。しかし、最短経路を返すようにするにはどうすればよいですか?!
実際のロードマップインポートのコード:
#include "search.h"
class ArcList;
class MapNode
{
public:
int x, y; // ���������� ����
MapNode();
MapNode(int X, int Y);
float Get_h( const MapNode & Goal_node );
bool GetNeighbours( AStarSearch<MapNode> *astarsearch, MapNode *parent_node );
bool IsSamePosition( const MapNode &rhs );
void PrintNodeInfo() const;
bool operator == (const MapNode & other) const;
void setArcList( ArcList * list );
private:
ArcList * list;
};
class Arc
{
public:
MapNode A1;
MapNode B1;
Arc(const MapNode & a, const MapNode & b);
};
class ArcList
{
public:
void setArcs( const std::vector<Arc> & arcs );
void addArc( const Arc & arc );
size_t size() const;
bool addNeighbours( AStarSearch<MapNode> * astarsearch, const MapNode & neighbour );
private :
std::vector<Arc> arcs;
};
std::vector <MapNode> FindPath(const MapNode & StartNode, const MapNode & GoalNode)
{
AStarSearch<MapNode> astarsearch;
astarsearch.SetStartAndGoalStates( StartNode, GoalNode );
unsigned int SearchState;
unsigned int SearchSteps = 0;
do
{
if ( SearchSteps % 100 == 0)
std::cout << "making step " << SearchSteps << endl;
SearchState = astarsearch.SearchStep();
SearchSteps++;
}
while ( SearchState == AStarSearch<MapNode>::SEARCH_STATE_SEARCHING );
std::vector<MapNode> S;
if ( SearchState == AStarSearch<MapNode>::SEARCH_STATE_SUCCEEDED )
{
int steps = 0;
for ( MapNode * node = astarsearch.GetSolutionStart(); node != 0; node = astarsearch.GetSolutionNext() )
{
S.push_back(*node);
// node->PrintNodeInfo();
}
astarsearch.FreeSolutionNodes();
}
else if ( SearchState == AStarSearch<MapNode>::SEARCH_STATE_FAILED )
{
throw " SEARCH_FAILED ";
}
return S;
}
関数FindPathは、結果ノードのベクトルを提供します。
addNeighboursメソッドは次のとおりです。
bool ArcList::addNeighbours( AStarSearch<MapNode> * astarsearch, const MapNode & target )
{
assert(astarsearch != 0);
bool found = false;
for (size_t i = 0; i < arcs.size(); i++ )
{
Arc arc = arcs.at(i);
if (arc.A1 == target)
{
found = true;
astarsearch->AddSuccessor( arc.B1 );
}
else if (arc.B1 == target )
{
found = true;
astarsearch->AddSuccessor( arc.A1 );
}
}
return found;
}
およびget_hメソッド:
float MapNode::Get_h( const MapNode & Goal_node )
{
float dx = x - Goal_node.x;
float dy = y - Goal_node.y;
return ( dx * dx + dy * dy );
}
正確な距離ではないことを私は知っています(ここでは平方根を取りません)-これは、評価時にいくつかのマシンリソースを節約するために行われます。