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
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 # ifndef BELLMAN_FORD_H
00063 # define BELLMAN_FORD_H
00064
00065 # include <tpl_dynListQueue.H>
00066 # include <tpl_avl.H>
00067 # include <tpl_graph_utils.H>
00068 # include <Tarjan.H>
00069
00070 namespace Aleph {
00071 # define NI(p) (static_cast<Bellman_Ford_Node_Info<GT, Distance>*>(NODE_COOKIE(p)))
00072 # define IDX(p) (NI(p)->idx)
00073 # define ACU(p) (NI(p)->acum)
00074
00075 template <class GT, class Distance> struct Bellman_Ford_Node_Info
00076 {
00077 int idx;
00078 typename Distance::Distance_Type acum;
00079 };
00150 template <class GT, class Distance,
00151 class Compare = Aleph::less<typename Distance::Distance_Type>,
00152 class Plus = Aleph::plus<typename Distance::Distance_Type>,
00153 class SA = Default_Show_Arc<GT> > inline
00154 bool bellman_ford_min_spanning_tree(GT & g, typename GT::Node * start_node,
00155 GT & tree)
00156 {
00157 if (not g.is_digraph())
00158 throw std::domain_error("Bellman-Ford algorithm only operates on digraphs");
00159 clear_graph(tree);
00160 DynArray<typename GT::Node*> pred(g.get_num_nodes());
00161 DynArray<typename GT::Arc*> arcs(g.get_num_nodes());
00162 {
00163 typename GT::Node_Iterator it(g);
00164 for (int i = 0; it.has_current(); ++i, it.next())
00165 {
00166 pred[i] = NULL;
00167 arcs[i] = NULL;
00168 typename GT::Node * p = it.get_current_node();
00169 g.reset_bit(p, Aleph::Min);
00170 Bellman_Ford_Node_Info <GT, Distance> * ptr =
00171 new Bellman_Ford_Node_Info <GT, Distance>;
00172 ptr->idx = i;
00173 ptr->acum = Distance::Max_Distance;
00174 NODE_BITS(p).set_bit(Min, false);
00175 NODE_BITS(p).set_bit(Breadth_First, false);
00176 NODE_COOKIE(p) = ptr;
00177 }
00178 }
00179 ACU(start_node) = Distance::Zero_Distance;
00180 g.reset_bit_arcs(Min);
00181 for (int i = 0, n = g.get_num_nodes() - 1; i < n; ++i)
00182 for (Arc_Iterator<GT, SA> it(g); it.has_current(); it.next())
00183 {
00184 typename GT::Arc * arc = it.get_current_arc();
00185 typename GT::Node * src = g.get_src_node(arc);
00186 typename GT::Node * tgt = g.get_tgt_node(arc);
00187 const typename Distance::Distance_Type & acum_src = ACU(src);
00188 if (acum_src == Distance::Max_Distance)
00189 continue;
00190
00191 const typename Distance::Distance_Type & dist = Distance () (arc);
00192 typename Distance::Distance_Type & acum_tgt = ACU(tgt);
00193 const typename Distance::Distance_Type sum = Plus () (acum_src, dist);
00194 if (Compare () (sum, acum_tgt))
00195 {
00196 const int & idx = IDX(tgt);
00197 pred[idx] = src;
00198 arcs[idx] = arc;
00199 acum_tgt = sum;
00200 }
00201 }
00202 bool negative_cycle = false;
00203
00204 for (Arc_Iterator<GT, SA> it(g); it.has_current(); it.next())
00205 {
00206 typename GT::Arc * arc = it.get_current_arc();
00207 typename GT::Node * src = g.get_src_node(arc);
00208 const typename Distance::Distance_Type & acum_src = ACU(src);
00209 if (acum_src == Distance::Max_Distance)
00210 continue;
00211
00212 typename GT::Node * tgt = g.get_tgt_node(arc);
00213 const typename Distance::Distance_Type & dist = Distance () (arc);
00214 typename Distance::Distance_Type & acum_tgt = ACU(tgt);
00215 const typename Distance::Distance_Type sum = Plus ()(acum_src, dist);
00216
00217 if (Compare () (sum, acum_tgt))
00218 {
00219 negative_cycle = true;
00220 const int & idx = IDX(tgt);
00221 pred[idx] = src;
00222 arcs[idx] = arc;
00223 acum_tgt = sum;
00224 }
00225 }
00226
00227
00228 for (Node_Iterator<GT> it(g); it.has_current(); it.next())
00229 {
00230 typename GT::Node * p = it.get_current_node();
00231 delete NI(p);
00232 NODE_COOKIE(p) = NULL;
00233 }
00234
00235 if (negative_cycle)
00236
00237
00238 {
00239
00240 for (Node_Iterator<GT> it(g); it.has_current(); it.next())
00241 {
00242 typename GT::Node * p = it.get_current_node();
00243 delete NI(p);
00244 NODE_COOKIE(p) = NULL;
00245 }
00246 return true;
00247 }
00248
00249 for (int i = 0; i < g.get_num_nodes(); ++i)
00250 {
00251 typename GT::Arc * garc = arcs[i];
00252 if (garc == NULL)
00253 continue;
00254
00255 typename GT::Node * gsrc = g.get_src_node(garc);
00256 typename GT::Node * tsrc = NULL;
00257 if (IS_NODE_VISITED(gsrc, Min))
00258 tsrc = mapped_node<GT> (gsrc);
00259 else
00260 {
00261 NODE_BITS(gsrc).set_bit(Min, true);
00262 delete NI(gsrc);
00263 tsrc = tree.insert_node(gsrc->get_info());
00264 GT::map_nodes(gsrc, tsrc);
00265 }
00266
00267 typename GT::Node * gtgt = g.get_tgt_node(garc);
00268 typename GT::Node * ttgt = NULL;
00269 if (IS_NODE_VISITED(gtgt, Min))
00270 ttgt = mapped_node<GT> (gtgt);
00271 else
00272 {
00273 NODE_BITS(gtgt).set_bit(Min, true);
00274 delete NI(gtgt);
00275 ttgt = tree.insert_node(gtgt->get_info());
00276 GT::map_nodes(gtgt, ttgt);
00277 }
00278 typename GT::Arc * tarc = tree.insert_arc(tsrc, ttgt, garc->get_info());
00279 GT::map_arcs(garc, tarc);
00280 ARC_BITS(garc).set_bit(Min, true);
00281 }
00282 return false;
00283 }
00284
00285 template <class GT> inline static
00286 void put_in_queue(DynListQueue<typename GT::Node*> & q, typename GT::Node * p)
00287 {
00288 q.put(p);
00289 NODE_BITS(p).set_bit(Breadth_First, true);
00290 }
00291 template <class GT> inline static typename GT::Node *
00292 get_from_queue(DynListQueue<typename GT::Node*> & q)
00293 {
00294 typename GT::Node * p = q.get();
00295 NODE_BITS(p).set_bit(Breadth_First, false);
00296 return p;
00297 }
00298 template <class GT> inline static bool is_in_queue(typename GT::Node * p)
00299 {
00300 return IS_NODE_VISITED(p, Breadth_First);
00301 }
00302
00382 template <class GT, class Distance,
00383 class Compare = Aleph::less<typename Distance::Distance_Type>,
00384 class Plus = Aleph::plus<typename Distance::Distance_Type>,
00385 class SA = Default_Show_Arc<GT> > inline
00386 bool q_bellman_ford_min_spanning_tree(GT & g, typename GT::Node * start_node,
00387 GT & tree)
00388 {
00389 if (not g.is_digraph())
00390 throw std::domain_error("Bellman-Ford algorithm only operates on digraphs");
00391 clear_graph(tree);
00392 DynArray<typename GT::Node*> pred(g.get_num_nodes());
00393 DynArray<typename GT::Arc*> arcs(g.get_num_nodes());
00394 {
00395 typename GT::Node_Iterator it(g);
00396 for (int i = 0; it.has_current(); ++i, it.next())
00397 {
00398 pred[i] = NULL;
00399 arcs[i] = NULL;
00400 typename GT::Node * p = it.get_current_node();
00401 g.reset_bit(p, Aleph::Min);
00402 Bellman_Ford_Node_Info <GT, Distance> * ptr =
00403 new Bellman_Ford_Node_Info <GT, Distance>;
00404 ptr->idx = i;
00405 ptr->acum = Distance::Max_Distance;
00406 NODE_BITS(p).set_bit(Min, false);
00407 NODE_BITS(p).set_bit(Breadth_First, false);
00408 NODE_COOKIE(p) = ptr;
00409 }
00410 }
00411 ACU(start_node) = Distance::Zero_Distance;
00412 g.reset_bit_arcs(Min);
00413 DynListQueue<typename GT::Node*> q;
00414 typename GT::Node __sentinel;
00415 typename GT::Node * sentinel = &__sentinel;
00416 put_in_queue <GT> (q, sentinel);
00417 put_in_queue <GT> (q, start_node);
00418 for (int i = 0, n = g.get_num_nodes() - 1; not q.is_empty(); )
00419 {
00420 typename GT::Node * src = get_from_queue <GT> (q);
00421 if (src == sentinel)
00422 if (i++ == n)
00423 break;
00424 else
00425 put_in_queue <GT> (q, sentinel);
00426
00427
00428 for (Node_Arc_Iterator<GT, SA> it(src); it.has_current(); it.next())
00429 {
00430 typename GT::Arc * arc = it.get_current_arc();
00431 const typename Distance::Distance_Type & acum_src = ACU(src);
00432 if (acum_src == Distance::Max_Distance)
00433 continue;
00434
00435 typename GT::Node * tgt = it.get_tgt_node();
00436 const typename Distance::Distance_Type & w = Distance () (arc);
00437 const typename Distance::Distance_Type sum_src =
00438 Plus () (acum_src, w);
00439 typename Distance::Distance_Type & acum_tgt = ACU(tgt);
00440 if (Compare () (sum_src, acum_tgt))
00441 {
00442 const int & idx = IDX(tgt);
00443 pred[idx] = src;
00444 arcs[idx] = arc;
00445 acum_tgt = sum_src;
00446 if (not is_in_queue <GT> (tgt))
00447 put_in_queue <GT> (q, tgt);
00448 }
00449 }
00450 }
00451 bool negative_cycle = false;
00452
00453 for (Arc_Iterator<GT, SA> it(g); it.has_current(); it.next())
00454 {
00455 typename GT::Arc * arc = it.get_current_arc();
00456 typename GT::Node * src = g.get_src_node(arc);
00457 const typename Distance::Distance_Type & acum_src = ACU(src);
00458 if (acum_src == Distance::Max_Distance)
00459 continue;
00460
00461 typename GT::Node * tgt = g.get_tgt_node(arc);
00462 const typename Distance::Distance_Type & dist = Distance () (arc);
00463 typename Distance::Distance_Type & acum_tgt = ACU(tgt);
00464 const typename Distance::Distance_Type sum = Plus ()(acum_src, dist);
00465
00466 if (Compare () (sum, acum_tgt))
00467 {
00468 negative_cycle = true;
00469 const int & idx = IDX(tgt);
00470 pred[idx] = src;
00471 arcs[idx] = arc;
00472 acum_tgt = sum;
00473 }
00474 }
00475
00476
00477 for (Node_Iterator<GT> it(g); it.has_current(); it.next())
00478 {
00479 typename GT::Node * p = it.get_current_node();
00480 delete NI(p);
00481 NODE_COOKIE(p) = NULL;
00482 }
00483
00484 if (negative_cycle)
00485
00486
00487 {
00488
00489 for (Node_Iterator<GT> it(g); it.has_current(); it.next())
00490 {
00491 typename GT::Node * p = it.get_current_node();
00492 delete NI(p);
00493 NODE_COOKIE(p) = NULL;
00494 }
00495 return true;
00496 }
00497
00498 for (int i = 0; i < g.get_num_nodes(); ++i)
00499 {
00500 typename GT::Arc * garc = arcs[i];
00501 if (garc == NULL)
00502 continue;
00503
00504 typename GT::Node * gsrc = g.get_src_node(garc);
00505 typename GT::Node * tsrc = NULL;
00506 if (IS_NODE_VISITED(gsrc, Min))
00507 tsrc = mapped_node<GT> (gsrc);
00508 else
00509 {
00510 NODE_BITS(gsrc).set_bit(Min, true);
00511 delete NI(gsrc);
00512 tsrc = tree.insert_node(gsrc->get_info());
00513 GT::map_nodes(gsrc, tsrc);
00514 }
00515
00516 typename GT::Node * gtgt = g.get_tgt_node(garc);
00517 typename GT::Node * ttgt = NULL;
00518 if (IS_NODE_VISITED(gtgt, Min))
00519 ttgt = mapped_node<GT> (gtgt);
00520 else
00521 {
00522 NODE_BITS(gtgt).set_bit(Min, true);
00523 delete NI(gtgt);
00524 ttgt = tree.insert_node(gtgt->get_info());
00525 GT::map_nodes(gtgt, ttgt);
00526 }
00527 typename GT::Arc * tarc = tree.insert_arc(tsrc, ttgt, garc->get_info());
00528 GT::map_arcs(garc, tarc);
00529 ARC_BITS(garc).set_bit(Min, true);
00530 }
00531 return false;
00532 }
00591 template <class GT, class Distance,
00592 class Compare = Aleph::less<typename Distance::Distance_Type>,
00593 class Plus = Aleph::plus<typename Distance::Distance_Type>,
00594 class SA = Default_Show_Arc<GT> >
00595 class Bellman_Ford_Min_Spanning_Tree
00596 {
00597 public:
00598
00615 bool operator () (GT & g, typename GT::Node * start_node, GT & tree)
00616 {
00617 return bellman_ford_min_spanning_tree <GT, Distance, Compare, Plus, SA>
00618 (g, start_node, tree);
00619 }
00620 };
00621
00680 template <class GT, class Distance,
00681 class Compare = Aleph::less<typename Distance::Distance_Type>,
00682 class Plus = Aleph::plus<typename Distance::Distance_Type>,
00683 class SA = Default_Show_Arc<GT> >
00684 class Q_Bellman_Ford_Min_Spanning_Tree
00685 {
00686 public:
00687
00704 bool operator () (GT & g, typename GT::Node * start_node, GT & tree)
00705 {
00706 return q_bellman_ford_min_spanning_tree <GT, Distance, Compare, Plus, SA>
00707 (g, start_node, tree);
00708 }
00709
00718 inline bool
00719 has_negative_cycle(GT & g, typename GT::Node * s, Path<GT> & path) const;
00720 };
00763 template <class GT>
00764 bool search_cycle(GT & g, DynArray<typename GT::Node *> & pred,
00765 DynArray<typename GT::Arc *> & arcs, Path<GT> & cycle)
00766 {
00767 const size_t & n = pred.size();
00768 DynMapAvlTree<typename GT::Node*, typename GT::Node*> nodes_table;
00769 GT aux;
00770 for (int i = 0; i < n; ++i)
00771 {
00772 typename GT::Node * p = pred.access(i);
00773 if (p == NULL or NODE_COOKIE(p) != NULL)
00774 continue;
00775
00776 typename GT::Node * q = aux.insert_node(p->get_info());
00777 GT::map_nodes(p, q);
00778 nodes_table.insert(q, p);
00779 }
00780
00781 for (int i = 0; i < n; ++i)
00782 {
00783 typename GT::Arc * a = arcs.access(i);
00784 if (a == NULL or ARC_COOKIE(a) != NULL)
00785 continue;
00786
00787 typename GT::Node * gsrc = g.get_src_node(a);
00788 typename GT::Node * gtgt = g.get_tgt_node(a);
00789 if (NODE_COOKIE(gsrc) == NULL or NODE_COOKIE(gtgt) == NULL)
00790 continue;
00791
00792 typename GT::Node * aux_src = mapped_node<GT> (gsrc);
00793 typename GT::Node * aux_tgt = mapped_node<GT> (gtgt);
00794 aux.insert_arc(aux_src, aux_tgt);
00795 }
00796 Path<GT> path;
00797 if (not Compute_Cycle_In_Digraph <GT> () (aux, path))
00798 return false;
00799
00800 cycle.set_graph(g);
00801
00802 for (typename Path<GT>::Iterator it(path); it.has_current(); it.next())
00803 cycle.append(nodes_table[it.get_current_node()]);
00804
00805 return true;
00806 }
00807
00829 template <class GT>
00830 class Search_Cycle
00831 {
00832 public:
00833
00852 bool operator () (GT & g,
00853 DynArray<typename GT::Node *> & pred,
00854 DynArray<typename GT::Arc *> & arcs,
00855 Path<GT> & cycle) const
00856 {
00857 return search_cycle <GT> (g, pred, arcs, cycle);
00858 }
00859 };
00860
00906 template <class GT, class Distance,
00907 class Compare = Aleph::less<typename Distance::Distance_Type>,
00908 class Plus = Aleph::plus<typename Distance::Distance_Type>,
00909 class SA = Default_Show_Arc<GT> > inline
00910 bool bellman_ford_negative_cycle(GT & g, typename GT::Node * start_node,
00911 Path<GT> & cycle)
00912 {
00913 GT tree;
00914 if (not g.is_digraph())
00915 throw std::domain_error("Bellman-Ford algorithm only operates on digraphs");
00916 clear_graph(tree);
00917 DynArray<typename GT::Node*> pred(g.get_num_nodes());
00918 DynArray<typename GT::Arc*> arcs(g.get_num_nodes());
00919 {
00920 typename GT::Node_Iterator it(g);
00921 for (int i = 0; it.has_current(); ++i, it.next())
00922 {
00923 pred[i] = NULL;
00924 arcs[i] = NULL;
00925 typename GT::Node * p = it.get_current_node();
00926 g.reset_bit(p, Aleph::Min);
00927 Bellman_Ford_Node_Info <GT, Distance> * ptr =
00928 new Bellman_Ford_Node_Info <GT, Distance>;
00929 ptr->idx = i;
00930 ptr->acum = Distance::Max_Distance;
00931 NODE_BITS(p).set_bit(Min, false);
00932 NODE_BITS(p).set_bit(Breadth_First, false);
00933 NODE_COOKIE(p) = ptr;
00934 }
00935 }
00936 ACU(start_node) = Distance::Zero_Distance;
00937 g.reset_bit_arcs(Min);
00938 for (int i = 0, n = g.get_num_nodes() - 1; i < n; ++i)
00939 for (Arc_Iterator<GT, SA> it(g); it.has_current(); it.next())
00940 {
00941 typename GT::Arc * arc = it.get_current_arc();
00942 typename GT::Node * src = g.get_src_node(arc);
00943 typename GT::Node * tgt = g.get_tgt_node(arc);
00944 const typename Distance::Distance_Type & acum_src = ACU(src);
00945 if (acum_src == Distance::Max_Distance)
00946 continue;
00947
00948 const typename Distance::Distance_Type & dist = Distance () (arc);
00949 typename Distance::Distance_Type & acum_tgt = ACU(tgt);
00950 const typename Distance::Distance_Type sum = Plus () (acum_src, dist);
00951 if (Compare () (sum, acum_tgt))
00952 {
00953 const int & idx = IDX(tgt);
00954 pred[idx] = src;
00955 arcs[idx] = arc;
00956 acum_tgt = sum;
00957 }
00958 }
00959 bool negative_cycle = false;
00960
00961 for (Arc_Iterator<GT, SA> it(g); it.has_current(); it.next())
00962 {
00963 typename GT::Arc * arc = it.get_current_arc();
00964 typename GT::Node * src = g.get_src_node(arc);
00965 const typename Distance::Distance_Type & acum_src = ACU(src);
00966 if (acum_src == Distance::Max_Distance)
00967 continue;
00968
00969 typename GT::Node * tgt = g.get_tgt_node(arc);
00970 const typename Distance::Distance_Type & dist = Distance () (arc);
00971 typename Distance::Distance_Type & acum_tgt = ACU(tgt);
00972 const typename Distance::Distance_Type sum = Plus ()(acum_src, dist);
00973
00974 if (Compare () (sum, acum_tgt))
00975 {
00976 negative_cycle = true;
00977 const int & idx = IDX(tgt);
00978 pred[idx] = src;
00979 arcs[idx] = arc;
00980 acum_tgt = sum;
00981 }
00982 }
00983
00984
00985 for (Node_Iterator<GT> it(g); it.has_current(); it.next())
00986 {
00987 typename GT::Node * p = it.get_current_node();
00988 delete NI(p);
00989 NODE_COOKIE(p) = NULL;
00990 }
00991
00992 if (not negative_cycle)
00993 return false;
00994
00995 Search_Cycle <GT> () (g, pred, arcs, cycle);
00996
00997 return true;
00998 }
01046 template <class GT, class Distance,
01047 class Compare = Aleph::less<typename Distance::Distance_Type>,
01048 class Plus = Aleph::plus<typename Distance::Distance_Type>,
01049 class SA = Default_Show_Arc<GT> > inline
01050 bool bellman_ford_negative_cycle(GT & g,
01051 typename GT::Node * start_node,
01052 GT & tree,
01053 Path<GT> & cycle)
01054 {
01055 if (not g.is_digraph())
01056 throw std::domain_error("Bellman-Ford algorithm only operates on digraphs");
01057 clear_graph(tree);
01058 DynArray<typename GT::Node*> pred(g.get_num_nodes());
01059 DynArray<typename GT::Arc*> arcs(g.get_num_nodes());
01060 {
01061 typename GT::Node_Iterator it(g);
01062 for (int i = 0; it.has_current(); ++i, it.next())
01063 {
01064 pred[i] = NULL;
01065 arcs[i] = NULL;
01066 typename GT::Node * p = it.get_current_node();
01067 g.reset_bit(p, Aleph::Min);
01068 Bellman_Ford_Node_Info <GT, Distance> * ptr =
01069 new Bellman_Ford_Node_Info <GT, Distance>;
01070 ptr->idx = i;
01071 ptr->acum = Distance::Max_Distance;
01072 NODE_BITS(p).set_bit(Min, false);
01073 NODE_BITS(p).set_bit(Breadth_First, false);
01074 NODE_COOKIE(p) = ptr;
01075 }
01076 }
01077 ACU(start_node) = Distance::Zero_Distance;
01078 g.reset_bit_arcs(Min);
01079 DynListQueue<typename GT::Node*> q;
01080 typename GT::Node __sentinel;
01081 typename GT::Node * sentinel = &__sentinel;
01082 put_in_queue <GT> (q, sentinel);
01083 put_in_queue <GT> (q, start_node);
01084 for (int i = 0, n = g.get_num_nodes() - 1; not q.is_empty(); )
01085 {
01086 typename GT::Node * src = get_from_queue <GT> (q);
01087 if (src == sentinel)
01088 if (i++ == n)
01089 break;
01090 else
01091 put_in_queue <GT> (q, sentinel);
01092
01093
01094 for (Node_Arc_Iterator<GT, SA> it(src); it.has_current(); it.next())
01095 {
01096 typename GT::Arc * arc = it.get_current_arc();
01097 const typename Distance::Distance_Type & acum_src = ACU(src);
01098 if (acum_src == Distance::Max_Distance)
01099 continue;
01100
01101 typename GT::Node * tgt = it.get_tgt_node();
01102 const typename Distance::Distance_Type & w = Distance () (arc);
01103 const typename Distance::Distance_Type sum_src =
01104 Plus () (acum_src, w);
01105 typename Distance::Distance_Type & acum_tgt = ACU(tgt);
01106 if (Compare () (sum_src, acum_tgt))
01107 {
01108 const int & idx = IDX(tgt);
01109 pred[idx] = src;
01110 arcs[idx] = arc;
01111 acum_tgt = sum_src;
01112 if (not is_in_queue <GT> (tgt))
01113 put_in_queue <GT> (q, tgt);
01114 }
01115 }
01116 }
01117 bool negative_cycle = false;
01118
01119 for (Arc_Iterator<GT, SA> it(g); it.has_current(); it.next())
01120 {
01121 typename GT::Arc * arc = it.get_current_arc();
01122 typename GT::Node * src = g.get_src_node(arc);
01123 const typename Distance::Distance_Type & acum_src = ACU(src);
01124 if (acum_src == Distance::Max_Distance)
01125 continue;
01126
01127 typename GT::Node * tgt = g.get_tgt_node(arc);
01128 const typename Distance::Distance_Type & dist = Distance () (arc);
01129 typename Distance::Distance_Type & acum_tgt = ACU(tgt);
01130 const typename Distance::Distance_Type sum = Plus ()(acum_src, dist);
01131
01132 if (Compare () (sum, acum_tgt))
01133 {
01134 negative_cycle = true;
01135 const int & idx = IDX(tgt);
01136 pred[idx] = src;
01137 arcs[idx] = arc;
01138 acum_tgt = sum;
01139 }
01140 }
01141
01142 for (Node_Iterator<GT> it(g); it.has_current(); it.next())
01143 {
01144 typename GT::Node * p = it.get_current_node();
01145 delete NI(p);
01146 NODE_COOKIE(p) = NULL;
01147 }
01148
01149 if (not negative_cycle)
01150
01151 for (Node_Iterator<GT> it(g); it.has_current(); it.next())
01152 {
01153 typename GT::Node * p = it.get_current_node();
01154 delete NI(p);
01155 NODE_COOKIE(p) = NULL;
01156 }
01157 {
01158 for (int i = 0; i < g.get_num_nodes(); ++i)
01159 {
01160 typename GT::Arc * garc = arcs[i];
01161 if (garc == NULL)
01162 continue;
01163
01164 typename GT::Node * gsrc = g.get_src_node(garc);
01165 typename GT::Node * tsrc = NULL;
01166 if (IS_NODE_VISITED(gsrc, Min))
01167 tsrc = static_cast<typename GT::Node*>(NODE_COOKIE(gsrc));
01168 else
01169 {
01170 NODE_BITS(gsrc).set_bit(Min, true);
01171 delete NI(gsrc);
01172 tsrc = tree.insert_node(gsrc->get_info());
01173 GT::map_nodes(gsrc, tsrc);
01174 }
01175
01176 typename GT::Node * gtgt = g.get_tgt_node(garc);
01177 typename GT::Node * ttgt = NULL;
01178 if (IS_NODE_VISITED(gtgt, Min))
01179 ttgt = static_cast<typename GT::Node*>(NODE_COOKIE(gtgt));
01180 else
01181 {
01182 NODE_BITS(gtgt).set_bit(Min, true);
01183 delete NI(gtgt);
01184 ttgt = tree.insert_node(gtgt->get_info());
01185 GT::map_nodes(gtgt, ttgt);
01186 }
01187
01188 typename GT::Arc * tarc = tree.insert_arc(tsrc, ttgt, garc->get_info());
01189 GT::map_arcs(garc, tarc);
01190 ARC_BITS(garc).set_bit(Min, true);
01191 }
01192 return false;
01193 }
01194
01195 Search_Cycle <GT> () (g, pred, arcs, cycle);
01196
01197 return true;
01198 }
01253 template <class GT, class Distance,
01254 class Compare = Aleph::less<typename Distance::Distance_Type>,
01255 class Plus = Aleph::plus<typename Distance::Distance_Type>,
01256 class SA = Default_Show_Arc<GT> > inline
01257 bool bellman_ford_negative_cycle(GT & g, Path<GT> & cycle)
01258 {
01259 DynDlist<DynDlist<typename GT::Node*> > blocks;
01260
01261 Tarjan_Connected_Components <GT, SA> () (g, blocks);
01262
01263
01264 for (typename DynDlist<DynDlist<typename GT::Node*> >::Iterator
01265 it(blocks); it.has_current(); it.next())
01266 {
01267 DynDlist<typename GT::Node*> & block = it.get_current();
01268 if (block.size() == 1)
01269 continue;
01270
01271 typename GT::Node * src = block.get_first();
01272 if (bellman_ford_negative_cycle<GT,Distance,Compare,Plus,SA>
01273 (g, src, cycle))
01274 return true;
01275 }
01276 return false;
01277 }
01316 template <class GT, class Distance,
01317 class Compare = Aleph::less<typename Distance::Distance_Type>,
01318 class Plus = Aleph::plus<typename Distance::Distance_Type>,
01319 class SA = Default_Show_Arc<GT> >
01320 class Bellman_Ford_Negative_Cycle
01321 {
01322 public:
01323
01334 bool operator () (GT & g, typename GT::Node * s, Path<GT> & path) const
01335 {
01336 return bellman_ford_negative_cycle <GT, Distance, Compare, Plus, SA>
01337 (g, s, path);
01338 }
01339
01353 bool
01354 operator () (GT & g, typename GT::Node * s, GT & tree, Path<GT> & path) const
01355 {
01356 return bellman_ford_negative_cycle <GT, Distance, Compare, Plus, SA>
01357 (g, s, tree, path);
01358 }
01359
01379 bool
01380 operator () (GT & g, Path<GT> & cycle) const
01381 {
01382 return
01383 bellman_ford_negative_cycle <GT, Distance, Compare, Plus, SA> (g, cycle);
01384 }
01385 };
01386
01387 template <class GT, class Distance, class Compare, class Plus, class SA>
01388 bool Q_Bellman_Ford_Min_Spanning_Tree
01389 <GT, Distance, Compare, Plus, SA>::
01390 has_negative_cycle(GT & g, typename GT::Node * s, Path<GT> & path) const
01391 {
01392 return bellman_ford_negative_cycle <GT, Distance, Compare, Plus, SA>
01393 (g, s, path);
01394 }
01395
01396 # undef NI
01397 # undef IDX
01398 # undef ACU
01399 }
01400
01401 # endif // BELLMAN_FORD_H