00001 #ifndef ASTARDIJKSTRA_H
00002 #define ASTARDIJKSTRA_H
00003
00004 #include <Structs/Trees/priorityQueue.h>
00005 #include <Utilities/geographic.h>
00006
00007
00020 template<class GraphType>
00021 class AStarDijkstra
00022 {
00023 public:
00024 typedef typename GraphType::NodeIterator NodeIterator;
00025 typedef typename GraphType::NodeDescriptor NodeDescriptor;
00026 typedef typename GraphType::EdgeIterator EdgeIterator;
00027 typedef typename GraphType::SizeType SizeType;
00028 typedef unsigned int WeightType;
00029 typedef PriorityQueue< WeightType, NodeIterator, HeapStorage> PriorityQueueType;
00030
00037 AStarDijkstra( GraphType& graph, unsigned int* timestamp):G(graph),m_timestamp(timestamp)
00038 {
00039 }
00040
00047 bool hasFeasiblePotentials( const typename GraphType::NodeIterator& t)
00048 {
00049 NodeIterator u,v,lastNode;
00050 EdgeIterator e,lastEdge;
00051
00052 WeightType potential_u, potential_v;
00053 int reducedCost;
00054
00055 for( u = G.beginNodes(), lastNode = G.endNodes(); u != lastNode; ++u)
00056 {
00057 for( e = G.beginEdges(u), lastEdge = G.endEdges(u); e != lastEdge; ++e)
00058 {
00059 v = G.target(e);
00060 potential_u = euclideanDistance( u->x, u->y, t->x, t->y);
00061 potential_v = euclideanDistance( v->x, v->y, t->x, t->y);
00062 reducedCost = e->weight - potential_u + potential_v;
00063 if( reducedCost < 0)
00064 {
00065 return false;
00066 }
00067 }
00068 }
00069 return true;
00070 }
00071
00079 WeightType runQuery( const typename GraphType::NodeIterator& s, const typename GraphType::NodeIterator& t)
00080 {
00081 NodeIterator u,v,lastNode;
00082 EdgeIterator e,lastEdge;
00083
00084 WeightType potential_u, potential_v;
00085 WeightType reducedCost;
00086
00087 assert(hasFeasiblePotentials(t));
00088
00089 pq.clear();
00090 ++(*m_timestamp);
00091 s->dist = 0;
00092 s->timestamp = (*m_timestamp);
00093 s->pred = G.nilNodeDescriptor();
00094
00095 pq.insert( s->dist, s, &(s->pqitem));
00096
00097 while( !pq.empty())
00098 {
00099 u = pq.minItem();
00100 pq.popMin();
00101 if( u == t) break;
00102
00103 potential_u = euclideanDistance( u->x, u->y, t->x, t->y);
00104 for( e = G.beginEdges(u), lastEdge = G.endEdges(u); e != lastEdge; ++e)
00105 {
00106 v = G.target(e);
00107 potential_v = euclideanDistance( v->x, v->y, t->x, t->y);
00108 reducedCost = e->weight + potential_v - potential_u;
00109
00110 if( v->timestamp < (*m_timestamp))
00111 {
00112 v->pred = u->getDescriptor();
00113 v->timestamp = (*m_timestamp);
00114
00115 pq.insert( u->dist + reducedCost, v, &(v->pqitem));
00116 v->dist = u->dist + reducedCost;
00117 }
00118 else if( v->dist > u->dist + reducedCost )
00119 {
00120 v->pred = u->getDescriptor();
00121
00122 pq.decrease( u->dist + reducedCost, &(v->pqitem));
00123 v->dist = u->dist + reducedCost;
00124 }
00125 }
00126 }
00127
00128 u = t;
00129 t->dist = 0;
00130 while( u->pred != G.nilNodeDescriptor())
00131 {
00132 v = G.getNodeIterator(u->pred);
00133 e = G.getEdgeIterator( v , u);
00134 t->dist += e->weight;
00135 u = v;
00136 }
00137 return t->dist;
00138 }
00139
00140 private:
00141 GraphType& G;
00142 unsigned int* m_timestamp;
00143 PriorityQueueType pq;
00144 };
00145
00146 #endif//ASTARDIJKSTRA_H
00147