00001
00002
00003
00004
00005
00006 #ifndef CAJUN_GRAPH_SEARCH_H
00007 #define CAJUN_GRAPH_SEARCH_H
00008
00009 #include "graph.H"
00010 #include <algorithm>
00011 #include <deque>
00012 #include <float.h>
00013
00014 namespace cajun
00015 {
00016 template <typename ID_T>
00017 class graph_search_t
00018 {
00020 class search_node_t
00021 {
00022 public:
00023 typename graph_t<ID_T>::vertex_t const *g_node;
00024 double m_cost;
00025 search_node_t *prev_s_node;
00026 bool operator < (search_node_t const &sn_) const
00027 {
00028 return (m_cost < sn_.m_cost);
00029 };
00030 bool operator == (search_node_t const &sn_) const
00031 {
00032 typename graph_t<ID_T>::vertex_t g1 = *g_node;
00033 typename graph_t<ID_T>::vertex_t g2 = *(sn_.g_node);
00034 return (g1 == g2);
00035 };
00036 search_node_t (typename graph_t<ID_T>::vertex_t const *g_node_) :
00037 g_node (g_node_), m_cost (FLT_MAX), prev_s_node (NULL){}
00038 double get_cost () { return m_cost; }
00039 void set_cost (double new_cost) { m_cost = new_cost; }
00040 };
00041
00042 class node_containter_t
00043 {
00044 search_node_t *m_node;
00045 public:
00046 bool operator < (node_containter_t const &nc_) const
00047 {
00048 return *m_node < *(nc_.node ());
00049 }
00050 bool operator == (node_containter_t const &nc_) const
00051 {
00052 return *m_node == nc_->m_node;
00053 }
00054 node_containter_t (search_node_t *node_)
00055 {
00056 m_node = node_;
00057 }
00058 search_node_t* const node () const
00059 { return m_node; }
00060 };
00061
00062 private:
00063 graph_t <ID_T> *m_graph;
00064
00065
00066
00067 std::vector<search_node_t *> m_all_nodes;
00068
00069 search_node_t* get_search_node (
00070 typename graph_t<ID_T>::vertex_t *node_)
00071 {
00072
00073 for (unsigned i=0; i < m_all_nodes.size (); i++)
00074 if (*(m_all_nodes [i]->g_node) == *node_)
00075 return m_all_nodes[i];
00076
00077
00078 search_node_t *sn = new search_node_t (node_);
00079 m_all_nodes.push_back (sn);
00080 return sn;
00081 }
00082
00085 bool update_cost (search_node_t *node_src_, search_node_t *node_dest_,
00086 typename graph_t<ID_T>::edge_t *edge_)
00087 {
00088 double edge_cost = edge_->cost ();
00089 double new_cost = node_src_->get_cost () + edge_cost;
00090 if (node_dest_->get_cost () <= new_cost)
00091 return false;
00092 node_dest_->set_cost (new_cost);
00093 node_dest_->prev_s_node = node_src_;
00094 return true;
00095 }
00100 void extract_path (std::deque<ID_T> &path_, search_node_t *last_node_)
00101 {
00102 search_node_t *node = last_node_;
00103 while (node != NULL)
00104 {
00105 path_.push_front ((node->g_node)->id ());
00106 node = node->prev_s_node;
00107 }
00108 }
00109
00112 void add_to_cont_list (
00113 search_node_t *node,
00114 std::deque<node_containter_t> &node_cont_list)
00115 {
00116 for (unsigned i=0; i < node_cont_list.size (); i++)
00117 if (*(node_cont_list[i].node ()) == *node)
00118 return;
00119
00120 node_cont_list.push_back (node_containter_t (node));
00121 }
00122
00123
00124 public:
00125 graph_search_t (graph_t<ID_T> *graph_) : m_graph (graph_)
00126 {}
00128 void print_graph ()
00129 {
00130 for (unsigned i =0; i< m_all_nodes.size (); i++)
00131 {
00132 search_node_t *node = m_all_nodes[i];
00133 search_node_t *p_node = node->prev_s_node;
00134
00135 printf (" cst=%.2lf (%d %d %d)",
00136 node->get_cost (),
00137 node->g_node->id ()[0],
00138 node->g_node->id ()[1],
00139 node->g_node->id ()[2]);
00140 if (p_node != NULL)
00141 printf ("\t (%d %d %d)\n",
00142 p_node->g_node->id ()[0],
00143 p_node->g_node->id ()[1],
00144 p_node->g_node->id ()[2]);
00145 else
00146 printf ("\n");
00147 }
00148 }
00149
00152 bool search_graph (typename graph_t<ID_T>::vertex_t *start_gn,
00153 typename graph_t<ID_T>::vertex_t *end_gn,
00154 std::deque<ID_T> &path_)
00155 {
00156 path_.clear ();
00157 search_node_t *start_node = new search_node_t (start_gn);
00158
00159 start_node->set_cost (0);
00160
00161 search_node_t *end_node = new search_node_t (end_gn);
00162
00163 std::deque<node_containter_t> node_cont_list;
00164
00165 node_containter_t start_nc (start_node);
00166
00167 node_cont_list.push_back (start_nc);
00168
00169 while (!node_cont_list.empty ())
00170 {
00171
00172 sort (node_cont_list.begin (), node_cont_list.end ());
00173
00174 search_node_t *node = node_cont_list.front ().node ();
00175 node_cont_list.pop_front ();
00176
00177 if (*node == *end_node)
00178 {
00179 extract_path (path_, node);
00180 clear_all_nodes ();
00181 return true;
00182 }
00183 typename graph_t<ID_T>::vertex_t const *g_node =
00184 node->g_node;
00185 for (unsigned i = 0; i < g_node->num_edges (); i++)
00186 {
00187 search_node_t *next_node =
00188 get_search_node ((g_node->edge (i))->get_vertex ());
00189
00190
00191
00192 if (update_cost (node, next_node, g_node->edge (i)))
00193 add_to_cont_list (next_node, node_cont_list);
00194 }
00195 }
00196
00197 print_graph ();
00198 printf ("FAILED FOR GRAPH SEARCH, here :\n");
00199 clear_all_nodes ();
00200
00201 return false;
00202 }
00203
00206 void clear_all_nodes ()
00207 {
00208 while (!m_all_nodes.empty ())
00209 {
00210 search_node_t *n = m_all_nodes.back ();
00211 m_all_nodes.pop_back ();
00212 delete (n);
00213 }
00214 }
00215 };
00216 };
00217
00218 #endif