00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 # ifndef BELLMAN_FORD_H
00045 # define BELLMAN_FORD_H
00046
00047 # include <tpl_dynListQueue.H>
00048 # include <tpl_graph.H>
00049
00050 namespace Aleph {
00051
00052
00053 # define NI(p) (static_cast<Bellman_Ford_Node_Info<GT, Distance>*>(NODE_COOKIE(p)))
00054 # define IDX(p) (NI(p)->idx)
00055 # define ACU(p) (NI(p)->acum)
00056 template <class GT, class Distance>
00057 struct Bellman_Ford_Node_Info
00058 {
00059 int idx;
00060 typename Distance::Distance_Type acum;
00061 };
00133 template <class GT, class Distance, class Compare, class Plus> inline
00134 bool bellman_ford_min_spanning_tree(GT & g,
00135 typename GT::Node * start_node,
00136 GT & tree)
00137 {
00138 if (not g.is_digraph())
00139 throw std::domain_error("Bellman-Ford algorithm only operates on digraphs");
00140 tree.clear_graph();
00141 DynArray<typename GT::Node*> pred;
00142 DynArray<typename GT::Arc*> arcs;
00143 {
00144 typename GT::Node_Iterator it(g);
00145
00146 for (int i = 0; it.has_current(); ++i, it.next())
00147 {
00148 typename GT::Node * p = it.get_current_node();
00149
00150 pred[i] = NULL;
00151 arcs[i] = NULL;
00152
00153 g.reset_bit(p, Aleph::Min);
00154
00155
00156 Bellman_Ford_Node_Info <GT, Distance> * ptr =
00157 new Bellman_Ford_Node_Info <GT, Distance>;
00158
00159 NODE_BITS(p).set_bit(Min, false);
00160 NODE_BITS(p).set_bit(Breadth_First, false);
00161 NODE_COOKIE(p) = ptr;
00162
00163
00164 ptr->idx = i;
00165 ptr->acum = Distance::Max_Distance;
00166 }
00167 }
00168 ACU(start_node) = Distance::Zero_Distance;
00169 g.reset_bit_arcs(Min);
00170 for (int i = 0, n = g.get_num_nodes() - 1; i < n; ++i)
00171
00172 for (typename GT::Arc_Iterator it(g); it.has_current(); it.next())
00173 {
00174 typename GT::Arc * arc = it.get_current_arc();
00175
00176 typename GT::Node * src = g.get_src_node(arc);
00177 typename GT::Node * tgt = g.get_tgt_node(arc);
00178
00179 const typename Distance::Distance_Type & dist = Distance () (arc);
00180
00181 const typename Distance::Distance_Type & acum_src = ACU(src);
00182
00183 typename Distance::Distance_Type & acum_tgt = ACU(tgt);
00184
00185 const typename Distance::Distance_Type sum = Plus () (acum_src, dist);
00186
00187 if (Compare() (sum, acum_tgt))
00188 {
00189 const int & idx = IDX(tgt);
00190
00191 pred[idx] = src;
00192 arcs[idx] = arc;
00193 acum_tgt = sum;
00194 }
00195 }
00196 bool ret_val = true;
00197
00198
00199 for (typename GT::Arc_Iterator it(g); it.has_current(); it.next())
00200 {
00201 typename GT::Arc * arc = it.get_current_arc();
00202
00203 typename GT::Node * src = g.get_src_node(arc);
00204 typename GT::Node * tgt = g.get_tgt_node(arc);
00205
00206 const typename Distance::Distance_Type & dist = Distance () (arc);
00207 const typename Distance::Distance_Type & acum_src = ACU(src);
00208 const typename Distance::Distance_Type & acum_tgt = ACU(tgt);
00209 const typename Distance::Distance_Type sum = Plus ()(acum_src, dist);
00210
00211 if (Compare() (sum, acum_tgt))
00212 {
00213 ret_val = false;
00214 break;
00215 }
00216 }
00217 if (not ret_val)
00218 {
00219 for (typename GT::Node_Iterator it(g); it.has_current(); it.next())
00220 delete NI(it.get_current_node());
00221
00222 return false;
00223 }
00224 for (int i = 0; i < g.get_num_nodes(); ++i)
00225 {
00226 typename GT::Arc * garc = arcs[i];
00227
00228 if (garc == NULL)
00229 continue;
00230
00231 typename GT::Node * gsrc = g.get_src_node(garc);
00232 typename GT::Node * tsrc = NULL;
00233 if (IS_NODE_VISITED(gsrc, Min))
00234 tsrc = static_cast<typename GT::Node*>(NODE_COOKIE(gsrc));
00235 else
00236 {
00237 NODE_BITS(gsrc).set_bit(Min, true);
00238
00239 delete NI(gsrc);
00240
00241 tsrc = tree.insert_node(gsrc->get_info());
00242 GT::map_nodes(gsrc, tsrc);
00243 }
00244
00245 typename GT::Node * gtgt = g.get_tgt_node(garc);
00246 typename GT::Node * ttgt = NULL;
00247 if (IS_NODE_VISITED(gtgt, Min))
00248 ttgt = static_cast<typename GT::Node*>(NODE_COOKIE(gtgt));
00249 else
00250 {
00251 NODE_BITS(gtgt).set_bit(Min, true);
00252
00253 delete NI(gtgt);
00254
00255 ttgt = tree.insert_node(gtgt->get_info());
00256 GT::map_nodes(gtgt, ttgt);
00257 }
00258
00259 typename GT::Arc * tarc = tree.insert_arc(tsrc, ttgt, garc->get_info());
00260 GT::map_arcs(garc, tarc);
00261 ARC_BITS(garc).set_bit(Min, true);
00262 }
00263
00264 return true;
00265 }
00266
00267 template <class GT> inline static
00268 void put_in_queue(DynListQueue<typename GT::Node*> & q, typename GT::Node * p)
00269 {
00270 q.put(p);
00271 NODE_BITS(p).set_bit(Breadth_First, true);
00272 }
00273
00274 template <class GT> inline static
00275 typename GT::Node * get_from_queue(DynListQueue<typename GT::Node*> & q)
00276 {
00277 typename GT::Node * p = q.get();
00278 NODE_BITS(p).set_bit(Breadth_First, false);
00279
00280 return p;
00281 }
00282
00283 template <class GT> inline static
00284 bool is_in_queue(typename GT::Node * p)
00285 {
00286 return IS_NODE_VISITED(p, Breadth_First);
00287 }
00288
00366 template <class GT, class Distance, class Compare, class Plus> inline
00367 bool q_bellman_ford_min_spanning_tree(GT & g,
00368 typename GT::Node * start_node,
00369 GT & tree)
00370 {
00371 if (not g.is_digraph())
00372 throw std::domain_error("Bellman-Ford algorithm only operates on digraphs");
00373 tree.clear_graph();
00374 DynArray<typename GT::Node*> pred;
00375 DynArray<typename GT::Arc*> arcs;
00376 {
00377 typename GT::Node_Iterator it(g);
00378
00379 for (int i = 0; it.has_current(); ++i, it.next())
00380 {
00381 typename GT::Node * p = it.get_current_node();
00382
00383 pred[i] = NULL;
00384 arcs[i] = NULL;
00385
00386 g.reset_bit(p, Aleph::Min);
00387
00388
00389 Bellman_Ford_Node_Info <GT, Distance> * ptr =
00390 new Bellman_Ford_Node_Info <GT, Distance>;
00391
00392 NODE_BITS(p).set_bit(Min, false);
00393 NODE_BITS(p).set_bit(Breadth_First, false);
00394 NODE_COOKIE(p) = ptr;
00395
00396
00397 ptr->idx = i;
00398 ptr->acum = Distance::Max_Distance;
00399 }
00400 }
00401 ACU(start_node) = Distance::Zero_Distance;
00402 g.reset_bit_arcs(Min);
00403 DynListQueue<typename GT::Node*> q;
00404 put_in_queue <GT> (q, start_node);
00405 for (int i = 0, n = (g.get_num_nodes() - 1)*g.get_num_arcs();
00406 (not q.is_empty()) and i < n;
00407 )
00408 {
00409 typename GT::Node * src = get_from_queue <GT> (q);
00410
00411
00412 for (typename GT::Node_Arc_Iterator it(src);
00413 it.has_current() and i < n;
00414 it.next(), ++i)
00415 {
00416 typename GT::Arc * arc = it.get_current_arc();
00417
00418 typename GT::Node * tgt = it.get_tgt_node();
00419
00420 const typename Distance::Distance_Type & acum_src = ACU(src);
00421
00422 const typename Distance::Distance_Type & w = Distance () (arc);
00423
00424 const typename Distance::Distance_Type sum_src = Plus () (acum_src, w);
00425
00426 typename Distance::Distance_Type & acum_tgt = ACU(tgt);
00427
00428
00429 if (Compare () (sum_src, acum_tgt))
00430 {
00431 const int & idx = IDX(tgt);
00432
00433 pred[idx] = src;
00434 arcs[idx] = arc;
00435 acum_tgt = sum_src;
00436
00437 if (not is_in_queue <GT> (tgt))
00438 put_in_queue <GT> (q, tgt);
00439 }
00440 }
00441 }
00442 bool ret_val = true;
00443
00444
00445 for (typename GT::Arc_Iterator it(g); it.has_current(); it.next())
00446 {
00447 typename GT::Arc * arc = it.get_current_arc();
00448
00449 typename GT::Node * src = g.get_src_node(arc);
00450 typename GT::Node * tgt = g.get_tgt_node(arc);
00451
00452 const typename Distance::Distance_Type & dist = Distance () (arc);
00453 const typename Distance::Distance_Type & acum_src = ACU(src);
00454 const typename Distance::Distance_Type & acum_tgt = ACU(tgt);
00455 const typename Distance::Distance_Type sum = Plus ()(acum_src, dist);
00456
00457 if (Compare() (sum, acum_tgt))
00458 {
00459 ret_val = false;
00460 break;
00461 }
00462 }
00463 if (not ret_val)
00464 {
00465 for (typename GT::Node_Iterator it(g); it.has_current(); it.next())
00466 delete NI(it.get_current_node());
00467
00468 return false;
00469 }
00470 for (int i = 0; i < g.get_num_nodes(); ++i)
00471 {
00472 typename GT::Arc * garc = arcs[i];
00473
00474 if (garc == NULL)
00475 continue;
00476
00477 typename GT::Node * gsrc = g.get_src_node(garc);
00478 typename GT::Node * tsrc = NULL;
00479 if (IS_NODE_VISITED(gsrc, Min))
00480 tsrc = static_cast<typename GT::Node*>(NODE_COOKIE(gsrc));
00481 else
00482 {
00483 NODE_BITS(gsrc).set_bit(Min, true);
00484
00485 delete NI(gsrc);
00486
00487 tsrc = tree.insert_node(gsrc->get_info());
00488 GT::map_nodes(gsrc, tsrc);
00489 }
00490
00491 typename GT::Node * gtgt = g.get_tgt_node(garc);
00492 typename GT::Node * ttgt = NULL;
00493 if (IS_NODE_VISITED(gtgt, Min))
00494 ttgt = static_cast<typename GT::Node*>(NODE_COOKIE(gtgt));
00495 else
00496 {
00497 NODE_BITS(gtgt).set_bit(Min, true);
00498
00499 delete NI(gtgt);
00500
00501 ttgt = tree.insert_node(gtgt->get_info());
00502 GT::map_nodes(gtgt, ttgt);
00503 }
00504
00505 typename GT::Arc * tarc = tree.insert_arc(tsrc, ttgt, garc->get_info());
00506 GT::map_arcs(garc, tarc);
00507 ARC_BITS(garc).set_bit(Min, true);
00508 }
00509
00510 return true;
00511 }
00512 template <class GT, class Distance> inline
00513 bool bellman_ford_min_spanning_tree(GT & g,
00514 typename GT::Node * start_node,
00515 GT & tree)
00516 {
00517 return bellman_ford_min_spanning_tree
00518 <GT, Distance, Aleph::less<typename Distance::Distance_Type>,
00519 Aleph::plus<typename Distance::Distance_Type> > (g, start_node, tree);
00520 }
00521
00522 template <class GT, class Distance> inline
00523 bool q_bellman_ford_min_spanning_tree(GT & g,
00524 typename GT::Node * start_node,
00525 GT & tree)
00526 {
00527 return q_bellman_ford_min_spanning_tree
00528 <GT, Distance, Aleph::less<typename Distance::Distance_Type>,
00529 Aleph::plus<typename Distance::Distance_Type> > (g, start_node, tree);
00530 }
00531
00532 # undef NI
00533 # undef IDX
00534 # undef ACU
00535 }
00536
00537 # endif // BELLMAN_FORD_H
00538