27 # ifndef BELLMAN_FORD_H 28 # define BELLMAN_FORD_H 30 # include <tpl_dynListQueue.H> 31 # include <tpl_dynSetTree.H> 32 # include <tpl_graph_utils.H> 37 template <
class GT,
class Distance>
struct Bellman_Ford_Node_Info
40 typename Distance::Distance_Type acum;
55 typedef typename Distance::Distance_Type Distance_Type;
57 using Node =
typename GT::Node;
58 using Arc =
typename GT::Arc;
65 struct Ni :
public Sni
70 Distance_Type & acum(Node * p) noexcept
75 int & idx(Node * p) noexcept
82 const Distance_Type Inf;
89 void init_simple(Node * start)
91 typename GT::Node_Iterator it(g);
92 for (
int i = 0; it.has_curr(); ++i, it.next_ne())
94 auto p = it.get_curr_ne();
95 g.reset_bit(p, Aleph::Spanning_Tree);
98 NODE_BITS(p).set_bit(Spanning_Tree,
false);
106 void init_with_indexes(Node * start)
108 arcs.
reserve(g.get_num_nodes());
109 typename GT::Node_Iterator it(g);
110 for (
int i = 0; it.has_curr(); ++i, it.next_ne())
113 auto p = it.get_curr_ne();
114 g.reset_bit(p, Aleph::Spanning_Tree);
118 NODE_BITS(p).set_bit(Spanning_Tree,
false);
119 NODE_BITS(p).set_bit(Depth_First,
false);
130 template <
class Info_Type>
131 void uninit() noexcept
133 for (
typename GT::Node_Iterator it(g); it.has_curr(); it.next_ne())
135 auto p = it.get_curr_ne();
141 bool check_painted_arcs() noexcept
144 for (Ait<GT, SA> it(g, sa); it.has_curr(); it.next_ne())
148 return num_arcs == g.get_num_nodes() - 1 or num_arcs == g.get_num_nodes();
153 Bellman_Ford(
const GT & __g, Distance d = Distance(), SA __sa = SA())
154 : g(const_cast<GT&>(__g)), Inf(std::numeric_limits<Distance_Type>::max()),
155 painted(
false), sa(__sa), dist(d)
162 void relax_arcs() noexcept
164 const size_t & n = g.vsize();
165 for (
int i = 0; i < n - 1; ++i)
166 for (Ait<GT, SA> it(g, sa); it.has_curr(); it.next_ne())
168 auto arc = it.get_curr_ne();
169 auto src = g.get_src_node(arc);
170 const auto & acum_src = acum(src);
174 auto tgt = it.get_tgt_node_ne();
176 auto sum = acum_src + w;
177 auto & acum_tgt = acum(tgt);
180 const auto & index = idx(tgt);
200 NODE_BITS(ret).set_bit(Depth_First,
false);
206 for (NAit<GT, SA> it(src, sa); it.has_curr(); it.next_ne())
208 auto arc = it.get_curr_ne();
209 auto src = g.get_src_node(arc);
210 const auto & acum_src = acum(src);
214 auto tgt = g.get_tgt_node(arc);
216 auto sum = acum_src + w;
217 auto & acum_tgt = acum(tgt);
220 const auto & index = idx(tgt);
223 put_in_queue(q, tgt);
228 void paint_tree() noexcept
230 const auto & n = g.vsize();
231 for (
int i = 0; i < n; ++i)
237 ARC_BITS(arc).set_bit(Aleph::Spanning_Tree,
true);
238 auto src = (Node*) arc->src_node;
239 auto tgt = (Node*) arc->tgt_node;
240 NODE_BITS(src).set_bit(Aleph::Spanning_Tree,
true);
241 NODE_BITS(tgt).set_bit(Aleph::Spanning_Tree,
true);
243 NODE_BITS(s).set_bit(Aleph::Spanning_Tree,
true);
245 assert(check_painted_arcs());
250 bool last_relax_and_prepare_check_negative_cycle() noexcept
252 bool negative_cycle =
false;
253 for (Ait<GT, SA> it(g, sa); it.has_curr(); it.next_ne())
255 auto arc = it.get_curr_ne();
256 auto src = g.get_src_node(arc);
257 auto & acum_src = acum(src);
261 auto tgt = g.get_tgt_node(arc);
263 auto & acum_tgt = acum(tgt);
264 auto sum = acum_src + d;
267 negative_cycle =
true;
268 const auto & index = idx(tgt);
273 return negative_cycle;
276 bool last_relax_and_test_negative_cycle() noexcept
278 for (Ait<GT, SA> it(g, sa); it.has_curr(); it.next_ne())
280 auto arc = it.get_curr_ne();
281 auto src = g.get_src_node(arc);
282 auto & acum_src = acum(src);
286 auto tgt = g.get_tgt_node(arc);
288 auto & acum_tgt = acum(tgt);
289 auto sum = acum_src + d;
296 void link_cookies_and_free(
typename GT::Node * s) noexcept
301 const auto & n = g.vsize();
302 for (
int i = 0; i < n; ++i)
308 auto tgt = g.get_tgt_node(arc);
330 init_with_indexes(start);
333 bool negative_cycle = last_relax_and_prepare_check_negative_cycle();
335 link_cookies_and_free(s);
337 return negative_cycle;
354 init_with_indexes(start);
356 const auto & n = g.get_num_nodes();
361 Node * sentinel = &__sentinel;
364 put_in_queue(q, sentinel);
366 for (
size_t i = 0; not q.
is_empty(); )
368 auto src = get_from_queue(q);
374 put_in_queue(q, sentinel);
380 bool negative_cycle = last_relax_and_prepare_check_negative_cycle();
382 link_cookies_and_free(s);
384 return negative_cycle;
389 Node * create_dummy_node()
391 s =
const_cast<GT&
>(g).insert_node(
typename GT::Node_Type());
392 for (
typename GT::Node_Iterator it(g); it.has_curr(); it.next_ne())
394 auto p = it.get_curr_ne();
397 auto a =
const_cast<GT&
>(g).insert_arc(s, p);
398 Distance::set_zero(a);
403 template <
class Info_Type>
404 void remove_dummy_node(Node * p)
407 const_cast<GT&
>(g).remove_node(p);
417 init_with_indexes(start);
422 bool negative_cycle = last_relax_and_test_negative_cycle();
425 return negative_cycle;
428 bool has_negative_cycle()
431 auto ret = has_negative_cycle(s);
432 remove_dummy_node<Ni>(s);
439 Path<GT> search_negative_cycle_on_partial_graph()
441 GT aux = build_spanning_tree<GT>(
arcs);
445 for (
typename GT::Node_Iterator it(aux); it.has_curr(); it.next_ne())
447 auto p = it.get_curr_ne();
479 init_with_indexes(start);
482 bool negative_cycle = last_relax_and_prepare_check_negative_cycle();
483 if (not negative_cycle)
485 link_cookies_and_free(s);
489 Path<GT> ret = search_negative_cycle_on_partial_graph();
491 WARNING(
"Serious inconsistency. Bellman-Ford algorithm has detected\n" 492 "a negative cycle, but Tarjan algorithm executed on partial\n" 493 "graph has not found such cycle\n\n" 494 "Be very careful, this is provably a bug");
496 link_cookies_and_free(s);
507 auto start = create_dummy_node();
508 auto ret_val = test_negative_cycle(start);
509 remove_dummy_node<Ni>(start);
556 tuple<Path<GT>,
size_t>
559 init_with_indexes(start);
561 const auto & n = g.get_num_nodes();
564 Node * sentinel = &__sentinel;
566 put_in_queue(q, sentinel);
568 double threshold = it_factor*n;
574 auto src = get_from_queue(q);
580 put_in_queue(q, sentinel);
583 ret = search_negative_cycle_on_partial_graph();
586 link_cookies_and_free(s);
587 return make_tuple(std::forward<
Path<GT>>(ret), i);
596 bool negative_cycle = last_relax_and_prepare_check_negative_cycle();
599 ret = search_negative_cycle_on_partial_graph();
601 WARNING(
"Serious inconsistency. Bellman-Ford algorithm has detected\n" 602 "a negative cycle, but Tarjan algorithm executed on partial\n" 603 "graph has not found such cycle\n\n" 604 "Be very careful, this provably is a bug");
607 link_cookies_and_free(s);
608 return make_tuple(std::forward<
Path<GT>>(ret), i);
627 init_with_indexes(start);
629 const auto & n = g.get_num_nodes();
632 Node * sentinel = &__sentinel;
634 put_in_queue(q, sentinel);
637 for (
size_t i = 0; not q.
is_empty(); )
639 auto src = get_from_queue(q);
645 put_in_queue(q, sentinel);
651 bool negative_cycle = last_relax_and_prepare_check_negative_cycle();
654 ret = search_negative_cycle_on_partial_graph();
656 WARNING(
"Serious inconsistency. Bellman-Ford algorithm has detected\n" 657 "a negative cycle, but Tarjan algorithm executed on partial\n" 658 "graph has not found such cycle\n\n" 659 "Be very careful, this provably is a bug");
662 link_cookies_and_free(s);
677 tuple<Path<GT>,
size_t> search_negative_cycle(
double it_factor,
680 auto start = create_dummy_node();
681 auto ret_val = search_negative_cycle(start, it_factor, step);
682 remove_dummy_node<Ni>(start);
691 auto start = create_dummy_node();
692 auto ret_val = search_negative_cycle(start);
693 remove_dummy_node<Ni>(start);
726 if (not painted and with_map)
727 throw std::domain_error(
"Spanning tree has not been painted");
732 for (
typename GT::Node_Iterator it(g); it.has_curr(); it.next_ne())
734 auto gp = it.get_curr_ne();
735 auto tp = tree.insert_node(gp->get_info());
739 for (
typename GT::Node_Iterator it(g); it.has_curr(); it.next_ne())
741 auto gtgt = it.get_curr_ne();
746 auto garc_ptr = g.arcs(gsrc).find_ptr([gsrc, gtgt] (Arc * a)
748 return a->src_node == gsrc and a->tgt_node == gtgt;
750 assert(garc_ptr and
IS_ARC_VISITED(*garc_ptr, Aleph::Spanning_Tree));
751 auto garc = *garc_ptr;
752 assert(garc->src_node == gsrc and garc->tgt_node == gtgt);
753 auto tsrc_ptr = table.
search(gsrc);
754 auto ttgt_ptr = table.
search(gtgt);
755 assert(tsrc_ptr and ttgt_ptr);
756 auto tarc = tree.insert_arc(tsrc_ptr->second, ttgt_ptr->second,
766 bool test_negative_cycle(
typename GT::Node * s,
Path<GT> & cycle)
768 cycle = test_negative_cycle(s);
772 bool test_negative_cycle(
Path<GT> & cycle)
774 cycle = test_negative_cycle();
778 Distance_Type get_min_path(
typename GT::Node * end,
Path<GT> & path)
781 throw std::domain_error(
"Graph has not previously painted");
783 return Aleph::get_min_path<GT, Distance>(s, end, path);
802 init_with_indexes(s);
804 const auto & n = g.get_num_nodes();
809 Node * sentinel = &__sentinel;
812 put_in_queue(q, sentinel);
814 bool negative_cycle =
false;
815 for (
int i = 0; not q.
is_empty() and not negative_cycle; )
817 auto src = get_from_queue(q);
823 put_in_queue(q, sentinel);
829 negative_cycle = last_relax_and_prepare_check_negative_cycle();
830 remove_dummy_node<Ni>(s);
835 if (not negative_cycle)
836 for (
auto it = g.get_node_it(); it.has_curr(); it.next_ne())
838 auto p = it.get_curr_ne();
846 throw domain_error(
"negative cycles detected");
889 Distance & d, SA & sa)
const 892 test_negative_cycle(path);
895 bool operator () (
const GT & g,
Path<GT> & path,
896 Distance && d = Distance(), SA && sa = SA())
const 899 test_negative_cycle(path);
912 bool operator () (
const GT & g,
typename GT::Node * s,
913 Path<GT> & path, Distance & d, SA & sa)
const 916 test_negative_cycle(s, path);
919 bool operator () (
const GT & g,
typename GT::Node * s,
920 Path<GT> & path, Distance && d = Distance(),
921 SA && sa = SA())
const 924 test_negative_cycle(s, path);
927 Path<GT> operator () (
const GT & g,
typename GT::Node * s,
928 Distance & d, SA & sa,
double it_factor = 0.7)
const 931 search_negative_cycle(s, it_factor);
934 Path<GT> operator () (
const GT & g,
typename GT::Node * s,
935 Distance && d = Distance(), SA && sa = SA(),
936 double it_factor = 0.7)
const 939 search_negative_cycle(s, it_factor);
942 Path<GT> operator () (
const GT & g, Distance & d, SA & sa,
943 double it_factor = 0.7)
const 946 search_negative_cycle(it_factor);
950 operator () (
const GT & g, Distance && d = Distance(), SA && sa = SA(),
951 double it_factor = 0.7)
const 954 search_negative_cycle(it_factor);
964 # endif // BELLMAN_FORD_H Path< GT > test_negative_cycle()
Definition: Bellman_Ford.H:505
void reserve(const size_t l, const size_t r)
Definition: tpl_dynArray.H:998
void clear_graph(GT &g) noexcept
Definition: tpl_graph.H:3463
Definition: tpl_graph.H:1225
Definition: Bellman_Ford.H:877
Pair * insert(const Key &key, const Data &data)
Definition: tpl_dynMapTree.H:112
void cut(const size_t new_dim=0)
Definition: tpl_dynArray.H:1104
bool has_current_node() const noexcept
Return true if the iterator has a current node.
Definition: tpl_graph.H:3243
#define NODE_COOKIE(p)
Definition: aleph-graph.H:333
bool is_empty() const noexcept
rioReturn true if this is empty
Definition: tpl_dynListQueue.H:112
bool faster_paint_spanning_tree(Node *start)
Definition: Bellman_Ford.H:352
void for_each(Operation &operation) noexcept(noexcept(operation))
Definition: htlist.H:589
Definition: tpl_dynMapTree.H:62
#define IS_NODE_VISITED(p, bit)
Definition: aleph-graph.H:327
Definition: tpl_dynListQueue.H:50
void map_arcs(typename GTS::Arc *p, typename GTT::Arc *q) noexcept
Definition: tpl_graph.H:3445
#define IS_ARC_VISITED(p, bit)
Definition: aleph-graph.H:360
tuple< Path< GT >, size_t > search_negative_cycle(Node *start, double it_factor, const size_t step)
Definition: Bellman_Ford.H:557
Definition: tpl_graph.H:53
DynList< typename GT::Arc * > arcs(typename GT::Node *p, SA sa=SA())
Definition: tpl_graph.H:1893
void map_nodes(typename GTS::Node *p, typename GTT::Node *q) noexcept
Definition: tpl_graph.H:3419
Definition: Bellman_Ford.H:53
Definition: tpl_graph.H:1063
Path< GT > search_negative_cycle(Node *start)
Definition: Bellman_Ford.H:625
void append_directed(Node *p)
Definition: tpl_graph.H:2880
DynMapTree< Node *, Distance_Type > compute_nodes_weights()
Definition: Bellman_Ford.H:798
Pair * search(const Key &key) const noexcept
Definition: tpl_dynMapTree.H:214
Definition: tpl_graph.H:1796
#define NODE_BITS(p)
Definition: aleph-graph.H:305
bool has_negative_cycle(Node *start)
Definition: Bellman_Ford.H:415
DynArray< Arc * > extract_mim_spanning_tree()
Definition: Bellman_Ford.H:708
Definition: tpl_graph_utils.H:1753
bool paint_spanning_tree(Node *start)
Definition: Bellman_Ford.H:328
void build_tree(GT &tree, bool with_map=true)
Definition: Bellman_Ford.H:724
bool is_empty() const noexcept
Return true if the path is empty.
Definition: tpl_graph.H:2758
#define ARC_BITS(p)
Definition: aleph-graph.H:351
Definition: tpl_dynArray.H:159
T get()
Definition: tpl_dynListQueue.H:165
Definition: tpl_graph.H:1177
Path< GT > test_negative_cycle(Node *start)
Definition: Bellman_Ford.H:477
Definition: tpl_graph.H:3135
T & put(const T &data)
The type of element.
Definition: tpl_dynListQueue.H:125