00001 #pragma warning( disable : 4786 )
00002
00003 #include "astar.h"
00004 #include "debug/debug.h"
00005
00006 namespace Graph
00007 {
00008
00009
00010
00011
00012
00013
00014 void Astar::AddToOpenList( const int nodeNumber )
00015 {
00016 m_OpenList.insert( nodeNumber );
00017 }
00018
00019
00020
00021
00022
00023
00024 double Astar::GetCost( const int nodeNumber )
00025 {
00026 double returnMe = m_Costs[ nodeNumber ];
00027 return returnMe;
00028 }
00029
00030
00031
00032
00033
00034
00035 int Astar::GetNodeFromOpenList() const
00036 {
00037 int returnMe = *( m_OpenList.begin() );
00038 return returnMe;
00039 }
00040
00041
00042
00043
00044
00045
00046 std::vector< int > Astar::GetPath() const
00047 {
00048 return m_Path;
00049 }
00050
00051
00052
00053
00054
00055
00056 void Astar::MarkNodeCost( const int nodeNumber, const double cost )
00057 {
00058 m_Costs[ nodeNumber ] = cost;
00059 }
00060
00061
00062
00063
00064
00065
00066 bool Astar::OpenListIsEmpty() const
00067 {
00068 bool returnMe = m_OpenList.empty();
00069 return returnMe;
00070 }
00071
00072
00073
00074
00075
00076
00077 void Astar::ProcessAllNeighborsOfNode( const GraphBase& g, const int node )
00078 {
00079 double currentCost = GetCost( node );
00080
00081 std::vector< int > neighbors = g.GetNeighbors( node );
00082 int size = neighbors.size();
00083 int i;
00084 for( i = 0; i < size; ++i )
00085 {
00086 const int neighbor = neighbors[ i ];
00087 double currentNeighborCost = GetCost( neighbor );
00088 if( currentNeighborCost > currentCost + 1 )
00089 {
00090 MarkNodeCost( neighbor, currentCost + 1 );
00091 AddToOpenList( neighbor );
00092 }
00093 }
00094 }
00095
00096
00097
00098
00099
00100
00101 void Astar::RemoveNodeFromOpenList( const int nodeNum )
00102 {
00103 m_OpenList.erase( nodeNum );
00104 }
00105
00106
00107
00108
00109
00110
00111 void Astar::Search( const GraphBase& g, const int start, const int end )
00112 {
00113
00114
00115
00116 size_t numNodes = g.GetNumNodes();
00117 m_Costs.resize( numNodes, 10000.0 );
00118
00119
00120
00121
00122
00123 AddToOpenList( end );
00124 MarkNodeCost( end, 0.0 );
00125
00126 while( !OpenListIsEmpty() )
00127 {
00128 int node = GetNodeFromOpenList();
00129 RemoveNodeFromOpenList( node );
00130 ProcessAllNeighborsOfNode( g, node );
00131 }
00132
00133
00134
00135
00136 double startCost = GetCost( start );
00137 double endCost = GetCost( end );
00138 IJG_Assert( startCost < 10000.0 );
00139 IJG_Assert( endCost < 10000.0 );
00140
00141 if( startCost >= 10000.0 )
00142 {
00143 return;
00144 }
00145 if( endCost >= 10000.0 )
00146 {
00147 return;
00148 }
00149
00150
00151
00152
00153 m_Path.clear();
00154 m_Path.push_back( start );
00155
00156 int smallestNeighbor = SmallestNeighbor( g, start );
00157 while( smallestNeighbor != end )
00158 {
00159 m_Path.push_back( smallestNeighbor );
00160 smallestNeighbor = SmallestNeighbor( g, smallestNeighbor );
00161 }
00162 m_Path.push_back( end );
00163 }
00164
00165
00166
00167
00168
00169
00170 int Astar::SmallestNeighbor( const GraphBase& g, const int node )
00171 {
00172 std::vector< int > neighbors = g.GetNeighbors( node );
00173 int size = neighbors.size();
00174 int i;
00175
00176 int smallestNeighbor = neighbors[ 0 ];
00177 double smallestCost = m_Costs[ smallestNeighbor ];
00178 for( i = 1; i < size; ++i )
00179 {
00180 int neighbor = neighbors[ i ];
00181 double cost = m_Costs[ neighbor ];
00182 if( cost < smallestCost )
00183 {
00184 smallestCost = cost;
00185 smallestNeighbor = neighbor;
00186 }
00187 }
00188 return smallestNeighbor;
00189 }
00190
00191 }