Aleph-w  1.9
General library for algorithms and data structures
tpl_net.H
1 
2 /* Aleph-w
3 
4  / \ | | ___ _ __ | |__ __ __
5  / _ \ | |/ _ \ '_ \| '_ \ ____\ \ /\ / / Data structures & Algorithms
6  / ___ \| | __/ |_) | | | |_____\ V V / version 1.9b
7  /_/ \_\_|\___| .__/|_| |_| \_/\_/ https://github.com/lrleon/Aleph-w
8  |_|
9 
10  This file is part of Aleph-w library
11 
12  Copyright (c) 2002-2018 Leandro Rabindranath Leon & Alejandro Mujica
13 
14  This program is free software: you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful, but
20  WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27 # ifndef TPL_NET_H
28 # define TPL_NET_H
29 
30 # include <limits>
31 # include <set>
32 
33 # include <tpl_dynDlist.H>
34 # include <tpl_dynListStack.H>
35 # include <tpl_dynBinHeap.H>
36 # include <tpl_dynSetTree.H>
37 # include <tpl_dynSetHash.H>
38 # include <tpl_random_queue.H>
39 # include <tpl_graph_utils.H>
40 # include <tpl_find_path.H>
41 # include <graph-traverse.H>
42 
43 
44 
45 using namespace Aleph;
46 
47 namespace Aleph {
48 
49  template <typename Arc_Info, typename Flow_Type>
50 struct Net_Arc_Info : public Arc_Info
51 {
53  Flow_Type cap;
54 
56  Flow_Type flow;
57 
58  Net_Arc_Info() noexcept(std::is_nothrow_constructible<Arc_Info>::value) {}
59 
60  Net_Arc_Info(const Arc_Info & info, Flow_Type __cap, Flow_Type __flow)
61  noexcept(noexcept(Arc_Info(info)))
62  : Arc_Info(info), cap(__cap), flow(__flow)
63  {
64  // empty
65  }
66 };
67 
81  template <typename Arc_Info, typename F_Type = double>
82 struct Net_Arc : public Graph_Aarc<Arc_Info> // Tipo que representa el flujo
83 {
84  using Base = Graph_Aarc<Arc_Info>;
85 
86  using Flow_Type = F_Type;
87 
89  Flow_Type cap = 0;
90 
92  Flow_Type flow = 0;
93 
97  bool check_arc() const noexcept { return flow >= 0 and flow <= cap; }
98 
99  Net_Arc(const Arc_Info & info)
100  noexcept(noexcept(Base(info)))
101  : Base(info) { /* empty */ }
102 
103  Net_Arc(const Net_Arc & arc)
104  noexcept(noexcept(Base(arc.arc_info)))
105  : Base(arc.arc_info), cap(arc.cap), flow(arc.flow)
106  {
107  // empty
108  }
109 
110  Net_Arc() { /* empty */ }
111 
112  Net_Arc & operator = (const Net_Arc & arc)
113  noexcept(std::is_nothrow_copy_assignable<Arc_Info>::value)
114  {
115  if (this == &arc)
116  return *this;
117 
118  *(Base*) this = arc;
119  cap = arc.cap;
120  flow = arc.flow;
121 
122  return *this;
123  }
124 };
125 
126 
127 template <class Net>
128 bool is_residual(typename Net::Node * src, typename Net::Arc * a) noexcept
129 {
130  assert(a->src_node == src or a->tgt_node == src);
131  return a->tgt_node == src;
132 }
133 
138  template <class Net>
139 struct Net_Filt
140 {
141  typename Net::Node * p = nullptr;
142 
143  void * cookie = nullptr;
144 
145  void set_cookie(void * __cookie) noexcept { cookie = __cookie; }
146 
147  Net_Filt(typename Net::Node * s = nullptr) noexcept
148  : p(s) { /* empty */ }
149 
150  bool operator () (typename Net::Arc * a) const noexcept
151  {
152  assert(p);
153  assert(a->src_node == p or a->tgt_node == p);
154  auto src = (typename Net::Node*) a->src_node;
155  if (src == p)
156  return a->cap - a->flow > 0; // normal arc
157 
158  assert(is_residual<Net>(p, a));
159  return a->flow > 0; // residual arc
160  }
161 
162  bool operator () (const Net &, typename Net::Arc * arc) noexcept
163  {
164  return (*this)(arc);
165  }
166 
167  typename Net::Node* get_node(typename Net::Arc * a) const noexcept
168  {
169  assert(p);
170  assert(a->src_node == p or a->tgt_node == p);
171  return (typename Net::Node*) (a->src_node == p ? a->tgt_node : a->src_node);
172  }
173 };
174 
175 
176 template <class Net>
178 
179 template <class Net, class Show_Arc = Dft_Show_Arc<Net>>
180 using Net_Iterator =
182 
183 
189 template <class Net>
190 typename Net::Flow_Type
191 remaining_flow(typename Net::Node * src, typename Net::Arc * a) noexcept
192 {
193  return is_residual<Net>(src, a) ? a->flow : a->cap - a->flow;
194 }
195 
196 template <typename Node_Info = Empty_Class>
198 
199 
214  template <class NodeT = Net_Node<Empty_Class>,
215  class ArcT = Net_Arc<Empty_Class, double>>
216 struct Net_Graph : public Array_Graph<NodeT, ArcT>
217 {
218  using Net = Net_Graph<NodeT, ArcT>;
219 
220  using Base = Array_Graph<NodeT, ArcT>;
221 
222  using Base::Base;
223 
224  using Graph = Base;
225 
227  using Arc = ArcT;
228 
230  using Node = NodeT;
231 
233  using Flow_Type = typename Arc::Flow_Type;
234 
236  using Node_Type = typename Node::Node_Type;
237 
239  using Arc_Type = typename Arc::Arc_Type;
240 
241  mutable Flow_Type Infinity;
242 
244  DynList<Arc*> out_arcs(Node * p) const noexcept
245  {
246  return Aleph::out_arcs<Net_Graph>(p);
247  }
248 
249  // Nodos a los cuales se les accede desde p
250  DynList<Node*> out_nodes(Node * p) const noexcept
251  {
252  return out_pairs<Net_Graph>(p).template maps<Node*>
253  ([] (const ArcPair<Net_Graph> & p) { return get<1>(p); });
254  }
255 
256  // Arcos que llegan a p
257  DynList<Arc*> in_arcs(Node * p) const noexcept
258  {
259  return Aleph::in_arcs<Net_Graph>(p);
260  }
261 
262  // Nodos desde los cuales se llega a p
263  DynList<Node*> in_nodes(Node * p) const noexcept
264  {
265  return in_pairs<Net_Graph>(p).template maps<Node*>
266  ([] (const ArcPair<Net_Graph> & p) { return get<1>(p); });
267  }
268 
270  Flow_Type get_in_cap(Node * node) const noexcept
271  {
272  Flow_Type sum = 0.0;
273  for (__In_Iterator<Net_Graph> it(node); it.has_curr(); it.next_ne())
274  sum += it.get_curr_ne()->cap;
275  return sum;
276  }
277 
279  Flow_Type get_out_cap(Node * node) const noexcept
280  {
281  Flow_Type sum = 0.0;
282  for (__Out_Iterator<Net_Graph> it(node); it.has_curr(); it.next_ne())
283  sum += it.get_curr_ne()->cap;
284  return sum;
285  }
286 
289  size_t get_in_degree(Node * p) const noexcept
290  {
291  return this->in_degree(p);
292  }
293 
296  size_t get_out_degree(Node * p) const noexcept
297  {
298  return this->out_degree(p);
299  }
300 
302  Flow_Type get_out_flow(Node * node) const noexcept
303  {
304  Flow_Type sum = 0;
305  for (__Out_Iterator<Net_Graph> it(node); it.has_curr(); it.next_ne())
306  sum += it.get_curr_ne()->flow;
307  return sum;
308  }
309 
311  Flow_Type get_in_flow(Node * node) const noexcept
312  {
313  Flow_Type sum = 0;
314  for (__In_Iterator<Net_Graph> it(node); it.has_curr(); it.next_ne())
315  sum += it.get_curr_ne()->flow;
316  return sum;
317  }
318 
320  bool is_source(Node * node) noexcept { return src_nodes.contains(node); }
321 
323  bool is_sink(Node * node) noexcept { return sink_nodes.contains(node); }
324 
326  bool is_single_source() const noexcept { return src_nodes.size() == 1; }
327 
329  bool is_single_sink() const noexcept { return sink_nodes.size() == 1; }
330 
334  bool is_connected(Node * p) const noexcept
335  {
336  return get_in_degree(p) != 0 or get_out_degree(p) != 0;
337  }
338 
341  bool check_node(Node * node) noexcept
342  {
343  if (not is_connected(node))
344  return false;
345 
346  auto out_flow = get_out_flow(node);
347  auto in_flow = get_in_flow(node);
348 
349  if (is_sink(node))
350  return out_flow == 0 and in_flow >= 0;
351 
352  if (is_source(node))
353  return in_flow == 0 and out_flow >= 0;
354 
355  return out_flow == in_flow;
356  }
357 
358 private:
359 
360  DynSetTree<Node*> src_nodes;
361  DynSetTree<Node*> sink_nodes;
362 
363 public:
364 
366  const DynSetTree<Node*> & get_src_nodes() const noexcept { return src_nodes; }
367 
369  const DynSetTree<Node*> & get_sink_nodes() const noexcept
370  {
371  return sink_nodes;
372  }
373 
374 public:
375 
380  {
381  if (src_nodes.size() == 1)
382  return;
383 
384  if (src_nodes.size() == 0)
385  throw std::domain_error("network has not source node (it has cicles)");
386 
387  Node * super_source = insert_node();
388  src_nodes.for_each([super_source, this] (Node * p)
389  {
390  insert_arc(super_source, p, get_out_cap(p));
391  });
392 
393  with_super_source = true;
394  }
395 
398  void unmake_super_source() noexcept
399  {
400  if (not with_super_source)
401  return;
402 
403  assert(src_nodes.size() == 1);
404 
405  remove_node(src_nodes.get_item());
406  with_super_source = false;
407  }
408 
413  {
414  if (sink_nodes.size() == 1)
415  return;
416 
417  if (sink_nodes.size() == 0)
418  throw std::domain_error("network has not sink node (it has cicles)");
419 
420  Node * super_sink = insert_node();
421  sink_nodes.for_each([super_sink, this] (Node * p)
422  {
423  insert_arc(p, super_sink, get_in_cap(p));
424  });
425  with_super_sink = true;
426  }
427 
430  void unmake_super_sink() noexcept
431  {
432  if (not with_super_sink)
433  return;
434 
435  assert(sink_nodes.size() == 1);
436 
437  remove_node(sink_nodes.get_item());
438  with_super_sink = false;
439  }
440 
444  {
445  make_super_source();
446  try
447  {
448  make_super_sink();
449  }
450  catch (std::bad_alloc)
451  {
452  unmake_super_source();
453  }
454  }
455 
460  {
461  unmake_super_source();
462  unmake_super_sink();
463  }
464 
466  Node * get_source() const { return src_nodes.get_item(); }
467 
469  Node * get_sink() const { return sink_nodes.get_item(); }
470 
481  Node * insert_node(const Node_Type & node_info)
482  {
483  auto p = Graph::insert_node(node_info);
484  try
485  {
486  src_nodes.insert(p);
487  try
488  {
489  sink_nodes.insert(p);
490  return p;
491  }
492  catch (bad_alloc)
493  {
494  src_nodes.remove(p);
495  Graph::remove_node(p);
496  throw;
497  }
498  }
499  catch (bad_alloc)
500  {
501  Graph::remove_node(p);
502  throw; // propagar excepción
503  }
504  }
505 
508  Node * insert_node(Node_Type && info = Node_Type())
509  {
510  return insert_node(info);
511  }
512 
513  template <typename ...Args>
514  Node * emplace_node(Args && ... args)
515  {
516  return insert_node(Node_Type(args...));
517  }
518 
519 
520 
532  Node * insert_node(Node * p)
533  {
534  Graph::insert_node(p);
535  try
536  {
537  src_nodes.insert(p);
538  try
539  {
540  sink_nodes.insert(p);
541  return p;
542  }
543  catch (bad_alloc)
544  {
545  src_nodes.remove(p);
546  Graph::remove_node(p);
547  throw;
548  }
549  }
550  catch (bad_alloc)
551  {
552  Graph::remove_node(p);
553  throw; // propagar excepción
554  }
555  }
556 
575  Arc * insert_arc(Node * src_node, Node * tgt_node,
576  const Flow_Type & cap, const Flow_Type & flow,
577  const typename Arc::Arc_Type & arc_info = Arc_Type())
578  { // inserción en clase base
579  auto arc = Graph::insert_arc(src_node, tgt_node, arc_info);
580 
581  src_nodes.remove(tgt_node); // actualización de source/sink
582  sink_nodes.remove(src_node);
583 
584  arc->cap = cap; // ajuste capacidad y flujo de arco
585  arc->flow = flow;
586 
587  if (not arc->check_arc())
588  throw std::overflow_error("flow is greater than capacity");
589 
590  return arc;
591  }
592 
593  template <typename ...Args>
594  Arc * emplace_arc(Node * src_node, Node * tgt_node,
595  const Flow_Type & cap, const Flow_Type & flow,
596  Args && ... args)
597  {
598  return insert_arc(src_node, tgt_node, cap, flow, Arc_Type(args...));
599  }
600 
617  Arc * connect_arc(Arc * arc)
618  {
619  Graph::connect_arc(arc);
620 
621  auto src = this->get_src_node(arc);
622  auto tgt = this->get_tgt_node(arc);
623 
624  src_nodes.remove(tgt); // elimina destino de src_nodes
625  sink_nodes.remove(src); // elimina fuente de sink_nodes
626 
627  return arc;
628  }
629 
647  Arc * insert_arc(Node * src_node, Node * tgt_node, const Flow_Type & cap)
648  {
649  return insert_arc(src_node, tgt_node, cap, 0, Arc_Type());
650  }
651 
669  Arc * insert_arc(Node * src_node, Node * tgt_node,
670  const typename Arc::Arc_Type & arc_info = Arc_Type())
671  {
672  return insert_arc(src_node, tgt_node, 0, 0, arc_info);
673  }
674 
676  virtual void remove_arc(Arc * arc)
677  {
678  auto src = this->get_src_node(arc);
679  auto tgt = this->get_tgt_node(arc);
680  if (get_in_degree(tgt) == 1)
681  src_nodes.insert(tgt); // tgt deviene un nodo fuente
682 
683  Graph::remove_arc(arc); // eliminar en clase base
684 
685  if (get_out_degree(src) == 0)
686  sink_nodes.insert(src); // src deviene un nodo sumidero
687  }
688 
700  void disconnect_arc(Arc * arc) noexcept
701  {
702  auto src = this->get_src_node(arc);
703  auto tgt = this->get_tgt_node(arc);
704  if (get_in_degree(tgt) == 1)
705  src_nodes.insert(tgt); // tgt deviene un nodo fuente
706 
707  Graph::disconnect_arc(arc); // desconeción en clase base
708 
709  if (get_out_degree(src) == 0)
710  sink_nodes.insert(src); // src deviene un nodo sumidero
711  }
712 
714  virtual void remove_node(Node * p) noexcept
715  {
716  Graph::remove_node(p); // eliminación en clase base
717  src_nodes.remove(p);
718  sink_nodes.remove(p);
719  }
720 
723  Net_Graph(const Net_Graph & net)
724  : Array_Graph<NodeT, ArcT>::Array_Graph(),
725  Infinity(numeric_limits<typename Arc::Flow_Type>::max()),
726  with_super_source(net.with_super_source),
727  with_super_sink(net.with_super_sink)
728  {
729  copy_graph(*this, net, false); // copia sin mapear
730 
731  using Pair = std::pair<typename Net_Graph::Arc*, typename Net_Graph::Arc*>;
732  zip(this->arcs(), net.arcs()).for_each([] (const Pair & p)
733  {
734  auto atgt = p.first;
735  auto asrc = p.second;
736  atgt->cap = asrc->cap;
737  atgt->flow = asrc->flow;
738  });
739  }
740 
742  void set_cap(Arc * arc, const Flow_Type & cap)
743  {
744  if (cap < arc->flow)
745  throw std::out_of_range("capacity value is smaller than flow");
746 
747  arc->cap = cap;
748  }
749 
752  void set_flow(Arc * arc, const Flow_Type & flow)
753  {
754  if (flow > arc->cap)
755  throw std::out_of_range("flow value is greater than capacity");
756 
757  arc->flow = flow;
758  }
759 
761  const Flow_Type & get_flow(Arc * arc) const noexcept { return arc->flow; }
762 
764  const Flow_Type & get_cap(Arc * arc) const noexcept { return arc->cap; }
765 
766  void reset() noexcept
767  {
768  for (Arc_Iterator<Net_Graph> it(*this); it.has_curr(); it.next_ne())
769  it.get_curr_ne()->flow = 0;
770  }
771 
785  {
786  return this->nodes().all([this] (Node * p) { return check_node(p); }) and
787  this->arcs().all([] (Arc * a) { return a->check_arc(); }) and
788  get_out_flow(get_source()) == get_in_flow(get_sink());
789  }
790 
795  {
796  assert(get_in_flow(get_source()) == get_out_flow(get_sink()));
797  return get_out_flow(get_source());
798  }
799 
802 
805 
806  Net_Graph()
807  : Infinity(numeric_limits<typename Arc::Flow_Type>::max()),
808  with_super_source(false), with_super_sink(false)
809  { /* empty */ }
810 
811  friend ostream & operator << (ostream & s, const Path<Net_Graph> & path)
812  {
813  if (path.is_empty())
814  return s << "Path is Empty";
815 
816  const Net_Graph & net = path.get_graph();
817  typename Path<Net_Graph>::Iterator it(path);
818  s << it.get_current_node()->get_info();
819  for (; it.has_current_arc(); it.next_ne())
820  {
821  typename Net_Graph::Arc * a = it.get_current_arc_ne();
822  s << "(" << a->cap << "," << a->flow << ")"
823  << net.get_connected_node(a, it.get_current_node_ne())-> get_info();
824  }
825  return s;
826  }
827 };
828 
833 template <class Net>
834 using Parc = tuple<typename Net::Arc*, bool>; // 2do campo dice si normal
835 
844 template <class Net>
845 using SemiPath = tuple<bool, typename Net::Flow_Type, DynList<Parc<Net>>>;
846 
847 template <class Net>
848 inline void print(const DynList<Parc<Net>> & sp)
849 {
850  if (sp.is_empty())
851  {
852  cout << "Semi path is Empty";
853  return;
854  }
855 
856  for (typename DynList<Parc<Net>>::Iterator it(sp); it.has_curr();
857  it.next_ne())
858  {
859  const Parc<Net> & pa = it.get_curr_ne();
860  auto a = get<0>(pa);
861  auto s = (typename Net::Node *) a->src_node;
862  auto t = (typename Net::Node *) a->tgt_node;
863  cout << s->get_info() << "(" << a->flow << "," << a->cap << ")"
864  << t->get_info() << " " << (get<1>(pa) ? "Normal" : "Reduced")
865  << endl;
866  }
867 }
868 
894  template <class Net>
895 typename Net::Flow_Type increase_flow(Net & net, const Path<Net> & path)
896 {
897  typename Net::Flow_Type slack = net.Infinity; // eslabón mínimo
898  using Tuple = tuple<typename Net::Node*, typename Net::Arc*>;
899 
900  // calcular el eslabón mínimo del camino de aumento
901  for (typename Path<Net>::Iterator it(path); it.has_current_arc();
902  it.next_ne())
903  {
904  Tuple t = it.get_tuple_ne();
905  auto p = get<0>(t);
906  auto arc = get<1>(t);
907  const auto w = remaining_flow<Net>(p, arc);
908  if (w < slack)
909  slack = w;
910  }
911 
912  // aumentar el flujo de la red por el camino de aumento
913  for (typename Path<Net>::Iterator it(path); it.has_current_arc(); it.next_ne())
914  {
915  auto t = it.get_tuple_ne();
916  auto p = get<0>(t);
917  auto arc = get<1>(t);
918 
919  if (is_residual<Net>(p, arc))
920  arc->flow -= slack;
921  else
922  arc->flow += slack;
923 
924  assert(arc->check_arc());
925  }
926 
927  return slack;
928 }
929 
930 
946  template <class Net>
947 void increase_flow(Net & net,
948  const DynList<Parc<Net>> & semi_path,
949  const typename Net::Flow_Type slack)
950 {
951  // aumentar el flujo de la red por el camino de aumento
952  for (typename DynList<Parc<Net>>::Iterator it(semi_path); it.has_curr();
953  it.next_ne())
954  {
955  auto p = it.get_curr_ne();
956  auto arc = get<0>(p);
957  if (get<1>(p)) // es arco de normal?
958  arc->flow += slack;
959  else
960  arc->flow -= slack;
961 
962  assert(arc->check_arc());
963  }
964  assert(net.check_network());
965 }
966 
982  template <class Net>
983 void decrease_flow(Net & net, const DynList<Parc<Net>> & semi_path,
984  typename Net::Flow_Type slack)
985 {
986  increase_flow(net, semi_path, slack);
987 }
988 
989 
995  template <class Net, template <typename T> class Q>
997 {
998  const Net & net;
999 
1000  // returna nodo end si se encuentra un camino
1001  typename Net::Node * search(typename Net::Node* start,
1002  typename Net::Node* end,
1003  typename Net::Flow_Type min_slack)
1004  {
1005  using Itor = Net_Iterator<Net>;
1006  net.reset_nodes();
1007  net.reset_arcs();
1008 
1009  start->set_state(Processed);
1010  Q<typename Net::Arc*> q;
1011  for (Itor it(start); it.has_curr(); it.next_ne())
1012  {
1013  auto a = it.get_curr_ne();
1014  if (remaining_flow<Net>(start, a) < min_slack)
1015  continue;
1016  auto tgt = net.get_connected_node(a, start);
1017  tgt->set_state(Processing);
1018  a->set_state(Processing);
1019  q.put(a);
1020  }
1021 
1022  typename Net::Node * curr = nullptr;
1023  while (not q.is_empty())
1024  {
1025  auto arc = q.get();
1026  assert(arc->state() == Processing);
1027  arc->set_state(Processed);
1028 
1029  auto s = net.get_src_node(arc);
1030  auto t = net.get_tgt_node(arc);
1031 
1032  if (s->state() == Processed and t->state() == Processed)
1033  continue;
1034 
1035  curr = s->state() == Processed ? t : s;
1036  assert(curr->state() == Processing);
1037  curr->set_state(Processed);
1038  NODE_COOKIE(curr) = net.get_connected_node(arc, curr);
1039 
1040  if (curr == end)
1041  return curr;
1042 
1043  for (Itor it(curr); it.has_curr(); it.next_ne())
1044  {
1045  auto a = it.get_curr_ne();
1046  if (remaining_flow<Net>(curr, a) < min_slack)
1047  continue;
1048  a->set_state(Processing);
1049 
1050  auto tgt = net.get_connected_node(a, curr);
1051  if (tgt->state() == Processed)
1052  continue;
1053 
1054  if (tgt->state() != Processed)
1055  {
1056  q.put(a);
1057  tgt->set_state(Processing);
1058  }
1059  else
1060  a->set_state(Processed);
1061  }
1062  } // end while
1063 
1064  return nullptr;
1065  }
1066 
1067  Path<Net> find(typename Net::Node * start, typename Net::Node * end,
1068  const typename Net::Flow_Type & min_slack = 0.0)
1069  {
1070  auto curr = search(start, end, min_slack);
1071 
1072  Path<Net> ret(net);
1073  if (not curr)
1074  return ret;
1075 
1076  assert(curr == end);
1077 
1078  while (curr != start)
1079  {
1080  ret.insert(curr);
1081  curr = (typename Net::Node*) NODE_COOKIE(curr);
1082  }
1083  ret.insert(start);
1084 
1085  return ret;
1086  }
1087 
1088  SemiPath<Net> find_path(typename Net::Node * start,
1089  typename Net::Node * end,
1090  typename Net::Flow_Type min_slack = 0.0)
1091  {
1092  auto t = search(start, end, min_slack);
1093  if (not t)
1094  return make_tuple(false, 0, DynList<Parc<Net>>());
1095 
1096  assert(t == end);
1097 
1098  DynList<Parc<Net>> semi_path;
1099  auto m = std::numeric_limits<typename Net::Flow_Type>::max();
1100  while (t != start)
1101  {
1102  auto s = (typename Net::Node*) NODE_COOKIE(t);
1103  auto a_ptr = net.arcs(t).find_ptr([s, t] (typename Net::Arc * a)
1104  {
1105  return ((a->src_node == s and a->tgt_node == t) or
1106  (a->src_node == t and a->tgt_node == s));
1107  });
1108  assert(a_ptr);
1109  auto a = *a_ptr;
1110  bool normal = a->tgt_node == t;
1111  auto slack = normal ? a->cap - a->flow : a->flow;
1112  m = std::min(m, slack);
1113  semi_path.insert(make_tuple(a, normal));
1114  t = s;
1115  }
1116 
1117  return make_tuple(true, m, move(semi_path));
1118  }
1119 
1120 public:
1121 
1123  SemiPath<Net> find_aum_path(typename Net::Flow_Type min_slack = 0.0)
1124  {
1125  return find_path(net.get_source(), net.get_sink(), min_slack);
1126  }
1127 
1129  SemiPath<Net> find_dec_path(typename Net::Flow_Type min_slack = 0.0)
1130  {
1131  return find_path(net.get_sink(), net.get_source(), min_slack);
1132  }
1133 
1134  Find_Aumenting_Path(const Net & __g) : net(__g)
1135  {
1136  // empty
1137  }
1138 
1139  Path<Net> operator () (typename Net::Node * start,
1140  typename Net::Node * end,
1141  typename Net::Flow_Type min_slack = 0)
1142  {
1143  return find(start, end, min_slack);
1144  }
1145 
1146  SemiPath<Net> operator () (typename Net::Flow_Type min_slack = 0)
1147  {
1148  return find_aum_path(min_slack);
1149  }
1150 
1151  typename Net::Flow_Type
1152  semi_path(typename Net::Node * start,
1153  typename Net::Node * end,
1154  DynList<Parc<Net>> & semi_path,
1155  const typename Net::Flow_Type & min_slack = 0)
1156  {
1157  return find_semi_path(start, end, semi_path, min_slack);
1158  }
1159 };
1160 
1161 
1162 template <class Net>
1164 
1165 
1166 template <class Net>
1168 
1169 
1181 template <class Net, template <typename T> class Q>
1183  const typename Net::Flow_Type & min_slack)
1184 {
1185  auto s = net.get_source();
1186  auto t = net.get_sink();
1187  return Find_Aumenting_Path<Net, Q> (net) (s, t, min_slack);
1188 }
1189 
1190 
1199 template <class Net>
1201  const typename Net::Flow_Type & min_slack)
1202 {
1203  return find_aumenting_path<Net, DynListStack> (net, min_slack);
1204 }
1205 
1206 
1215 template <class Net>
1217  const typename Net::Flow_Type & min_slack)
1218 {
1219  return find_aumenting_path<Net, DynListQueue> (net, min_slack);
1220 }
1221 
1222 
1238 template <class Net, template <typename T> class Q>
1240  const typename Net::Flow_Type & slack)
1241 {
1242  return Find_Aumenting_Path<Net, Q> (net). find_aum_path(slack);
1243 }
1244 
1245 
1258 template <class Net>
1261  const typename Net::Flow_Type & slack)
1262 {
1263  return find_aumenting_semi_path<Net, DynListStack> (net, slack);
1264 }
1265 
1266 
1279 template <class Net>
1282  const typename Net::Flow_Type & slack)
1283 {
1284  return find_aumenting_semi_path<Net, DynListQueue> (net, slack);
1285 }
1286 
1287 
1303 template <class Net, template <typename T> class Q>
1305 find_decrementing_path(const Net & net,
1306  const typename Net::Flow_Type & slack)
1307 {
1308  return Find_Aumenting_Path<Net, Q>(net).find_dec_path(slack);
1309 }
1310 
1311 
1320 template <class Net>
1323  const typename Net::Flow_Type & slack)
1324 {
1325  return find_decrementing_path<Net, DynListStack> (net, slack);
1326 }
1327 
1328 
1337 template <class Net>
1340  const typename Net::Flow_Type & slack)
1341 {
1342  return find_decrementing_path<Net, DynListQueue> (net, slack);
1343 }
1344 
1345 
1346 // Residual node for using is preflow-push algorithms
1347 template <class Net>
1348 struct PP_Res_Node : public Net_Node<Empty_Class>
1349 {
1350  using Base = Net_Node<Empty_Class>;
1351  using Base::Base;
1352 
1353  typename Net::Flow_Type in_flow;
1354  typename Net::Flow_Type out_flow;
1355 };
1356 
1357 template <class Net>
1358 struct __Res_Arc : public Net_Arc<Empty_Class, typename Net::Flow_Type>
1359 {
1361  using Base::Base;
1362 
1363  typename Net::Arc * img = nullptr; // nullptr indicates residual arc
1364  __Res_Arc * dup = nullptr;
1365 
1366  bool is_residual() const { return img == nullptr; }
1367 };
1368 
1369 
1370 template <class Net>
1371 using AP_Res_Net = Array_Digraph<Net_Node<Empty_Class>, __Res_Arc<Net>>;
1372 
1373  // Residual net for preflow-push algorithms
1374 template <class Net>
1375 using PP_Res_Net = Array_Digraph<PP_Res_Node<Net>, __Res_Arc<Net>>;
1376 
1377 // precondition: a->src and a->tgt are mapped to residual net
1378 template <class Net> inline
1379 void create_residual_arc(const Net & net, PP_Res_Net<Net> & rnet,
1380  typename Net::Arc * a)
1381 {
1382  using Rnet = PP_Res_Net<Net>;
1383  auto s = net.get_src_node(a);
1384  auto t = net.get_tgt_node(a);
1385 
1386  assert(NODE_COOKIE(s) and NODE_COOKIE(t));
1387 
1388  auto src = (typename Rnet::Node*) NODE_COOKIE(s);
1389  auto tgt = (typename Rnet::Node*) NODE_COOKIE(t);
1390 
1391  auto arc = rnet.insert_arc(src, tgt);
1392  auto dup = rnet.insert_arc(tgt, src);
1393 
1394  arc->img = a; // mark it as not residual
1395  arc->cap = a->cap;
1396  arc->flow = a->flow;
1397  arc->dup = dup;
1398 
1399  dup->cap = arc->cap;
1400  dup->flow = arc->cap - arc->flow;
1401  dup->dup = arc;
1402 }
1403 
1404 template <class Rnet>
1405 struct Res_F
1406 {
1407  Res_F(typename Rnet::Node *) noexcept {}
1408  Res_F() noexcept {}
1409 
1410  bool operator () (typename Rnet::Arc * a) const
1411  {
1412  return a->cap > a->flow;
1413  }
1414 };
1415 
1416 template <class Net> inline
1417 tuple<PP_Res_Net<Net>, typename PP_Res_Net<Net>::Node*,
1418  typename PP_Res_Net<Net>::Node*>
1419 preflow_create_residual_net(Net & net)
1420 {
1421  using Rnet = PP_Res_Net<Net>;
1422  net.reset_nodes();
1423  Rnet rnet;
1424 
1425  for (typename Net::Node_Iterator it(net); it.has_curr(); it.next_ne())
1426  {
1427  auto p = it.get_curr_ne();
1428  auto q = rnet.insert_node();
1429  q->in_flow = net.get_in_flow(p);
1430  q->out_flow = net.get_out_flow(p);
1431  map_nodes<typename Rnet::Node, typename Net::Node>(q, p);
1432  }
1433 
1434  for (typename Net::Arc_Iterator it(net); it.has_curr(); it.next_ne())
1435  create_residual_arc(net, rnet, it.get_curr_ne());
1436 
1437  return make_tuple(std::move(rnet),
1438  (typename Rnet::Node*) NODE_COOKIE(net.get_source()),
1439  (typename Rnet::Node*) NODE_COOKIE(net.get_sink()));
1440 }
1441 
1442 template <class Rnet> inline
1443 void update_flow(const Rnet & rnet)
1444 {
1445  for (typename Rnet::Arc_Iterator it(rnet); it.has_curr(); it.next_ne())
1446  {
1447  auto arc = it.get_curr_ne();
1448  auto img = arc->img;
1449  if (img == nullptr)
1450  continue;
1451  img->flow = arc->flow;
1452  }
1453 }
1454 
1474 template <class Net,
1475  template <class> class Find_Path>
1476 typename Net::Flow_Type aumenting_path_maximum_flow(Net & net)
1477 {
1478  if (not (net.is_single_source() and net.is_single_sink()))
1479  throw std::domain_error("Network is not single source and single sink");
1480 
1481  while (true) // mientras exista un camino de aumento
1482  {
1483  SemiPath<Net> semi_path = Find_Path<Net> (net) ();
1484  if (not get<0>(semi_path))
1485  break;
1486 
1487  increase_flow <Net> (net, get<2>(semi_path), get<1>(semi_path));
1488  }
1489 
1490  return net.get_out_flow(net.get_source());
1491 }
1492 
1493 
1517 template <class Net>
1518 typename Net::Flow_Type ford_fulkerson_maximum_flow(Net & net)
1519 {
1520  return aumenting_path_maximum_flow <Net, Find_Aumenting_Path_DFS> (net);
1521 }
1522 
1523 
1529 template <class Net>
1531 {
1539  typename Net::Flow_Type operator () (Net & net) const
1540  {
1541  return ford_fulkerson_maximum_flow(net);
1542  }
1543 };
1544 
1560 template <class Net>
1561 typename Net::Flow_Type edmonds_karp_maximum_flow(Net & net)
1562 {
1563  return aumenting_path_maximum_flow <Net, Find_Aumenting_Path_BFS> (net);
1564 }
1565 
1566 
1572 template <class Net>
1574 {
1582  typename Net::Flow_Type operator () (Net & net) const
1583  {
1584  return edmonds_karp_maximum_flow<Net>(net);
1585  }
1586 };
1587 
1588  template <class Net> static inline
1589 bool is_node_active(const Net & net, typename Net::Node * p)
1590 {
1591  return net.get_in_flow(p) != net.get_out_flow(p);
1592 }
1593 
1594 template <class Rnet> static inline
1595 bool is_node_active(typename Rnet::Node * p)
1596 {
1597  return p->in_flow != p->out_flow;
1598 }
1599 
1600 
1601  template <class Net> static inline
1602 long & node_height(typename Net::Node * p) { return NODE_COUNTER(p); }
1603 
1604 
1605  template <class Net> static inline
1606 void init_height_in_nodes(Net & net)
1607 {
1609  exec(net.get_sink(), [&net] (typename Net::Node * p, typename Net::Arc * a)
1610  {
1611  if (a)
1612  node_height<Net>(p) = node_height<Net>(net.get_tgt_node(a)) + 1;
1613  return true;
1614  });
1615 }
1616 
1617 
1618  template <class Q_Type> static inline
1619 void put_in_active_queue(Q_Type & q, typename Q_Type::Item_Type & p)
1620 {
1621  if (NODE_BITS(p).get_bit(Aleph::Maximum_Flow))
1622  return; // the node is already into the queue
1623  NODE_BITS(p).set_bit(Aleph::Maximum_Flow, true);
1624  q.put(p);
1625 }
1626 
1627 
1628  template <class Q_Type> static inline
1629 typename Q_Type::Item_Type get_from_active_queue(Q_Type & q)
1630 {
1631  auto p = q.get();
1632  assert(NODE_BITS(p).get_bit(Aleph::Maximum_Flow));
1633  NODE_BITS(p).set_bit(Aleph::Maximum_Flow, false);
1634  return p;
1635 }
1636 
1637 
1638  template <class Q_Type> static inline
1639 void remove_from_active_queue(Q_Type & q, typename Q_Type::Item_Type & p)
1640 {
1641  assert(NODE_BITS(p).get_bit(Aleph::Maximum_Flow));
1642  NODE_BITS(p).set_bit(Aleph::Maximum_Flow, false);
1643  q.remove(p);
1644 }
1645 
1646 
1681 template <class Net, class Q_Type> typename Net::Flow_Type
1683 {
1684  if (not (net.is_single_source() and net.is_single_sink()))
1685  throw std::domain_error("Network is not single source and single sink");
1686 
1687  net.reset_nodes(); // especially assures that counters are in zero
1688  init_height_in_nodes(net); // set height to minimum distance in nodes to sink
1689 
1690  auto source = net.get_source();
1691  auto sink = net.get_sink();
1692  node_height<Net>(source) = net.vsize(); // except the source
1693  const auto Max = numeric_limits<long>::max();
1694 
1695  using Itor = __Net_Iterator<Net>;
1696  Q_Type q;
1697  for (Itor it(source); it.has_curr(); it.next_ne()) // initial preflow
1698  {
1699  auto arc = it.get_curr_ne();
1700  arc->flow = arc->cap; // saturate arc
1701  auto tgt = net.get_tgt_node(arc);
1702  put_in_active_queue(q, tgt);
1703  }
1704 
1705  while (not q.is_empty()) // while there are active nodes
1706  {
1707  auto src = get_from_active_queue(q);
1708  auto excess = net.get_in_flow(src) - net.get_out_flow(src);
1709  long m = Max;
1710  bool was_eligible_arc = false;
1711  for (Itor it(src); it.has_curr() and excess > 0; it.next_ne())
1712  {
1713  auto arc = it.get_curr_ne();
1714  auto tgt = net.get_connected_node(arc, src);
1715  if (node_height<Net>(src) != node_height<Net>(tgt) + 1)
1716  {
1717  m = std::min(m, node_height<Net>(tgt));
1718  continue;
1719  }
1720 
1721  was_eligible_arc = true;
1722  typename Net::Flow_Type flow_to_push;
1723  if (is_residual<Net>(src, arc))
1724  {
1725  flow_to_push = std::min(arc->flow, excess);
1726  arc->flow -= flow_to_push;
1727  }
1728  else
1729  {
1730  flow_to_push = std::min(arc->cap - arc->flow, excess);
1731  arc->flow += flow_to_push;
1732  }
1733  excess -= flow_to_push;
1734  if (tgt != source and tgt != sink)
1735  {
1736  assert(is_node_active(net, tgt));
1737  put_in_active_queue(q, tgt);
1738  }
1739  }
1740 
1741  if (excess > 0) // is src still active
1742  {
1743  if (not was_eligible_arc)
1744  node_height<Net>(src) = m + 1;
1745  put_in_active_queue(q, src);
1746  }
1747  }
1748 
1749  assert(net.check_network());
1750 
1751  return net.flow_value();
1752 }
1753 
1754 
1755 template <class Rnet> inline
1756 void init_height_in_nodes(Rnet & rnet, typename Rnet::Node * sink)
1757 {
1759  exec(sink, [&rnet] (typename Rnet::Node * p, typename Rnet::Arc * a)
1760  {
1761  if (a)
1762  node_height<Rnet>(p) = node_height<Rnet>(rnet.get_src_node(a)) + 1;
1763  return true;
1764  });
1765 }
1766 
1767 
1795 template <class Net> typename Net::Flow_Type
1797 {
1798  using Node = typename Net::Node;
1800  <Net, DynListQueue<Node*>>(net);
1801 }
1802 
1808 template <class Net>
1810 {
1824  typename Net::Flow_Type
1825  operator () (Net & net) const
1826  {
1827  return fifo_preflow_maximum_flow(net);
1828  }
1829 };
1830 
1831 
1832  template <class Net>
1833 struct Compare_Height
1834 {
1835  bool operator () (typename Net::Node * n1, typename Net::Node * n2) const
1836  {
1837  return node_height<Net>(n1) > node_height<Net>(n2);
1838  }
1839 };
1840 
1872 template <class Net> typename Net::Flow_Type
1874 {
1875  using Node = typename Net::Node;
1878 }
1879 
1885  template <class Net>
1887 {
1900  typename Net::Flow_Type operator () (Net & net) const
1901  {
1902  return heap_preflow_maximum_flow(net);
1903  }
1904 };
1905 
1932  template <class Net> typename Net::Flow_Type
1934 {
1935  using Node = typename Net::Node;
1936  return generic_preflow_vertex_push_maximum_flow<Net, Random_Set<Node*>>(net);
1937 }
1938 
1939 
1945  template <class Net>
1947 {
1960  typename Net::Flow_Type operator () (Net & net) const
1961  {
1962  return random_preflow_maximum_flow(net);
1963  }
1964 };
1965 
1966 
1999 template <class Net, template <class> class Maxflow>
2000 typename Net::Flow_Type min_cut(Net & net,
2005 {
2006  Maxflow <Net> () (net); // calcula flujo máximo
2007 
2008  typename Net::Node * source = net.get_source();
2009 
2010  // Recorre en profundidad la red residual desde source. Todo lo
2011  // alcanzable pertenece a vs y por tanto es insertado
2013  (source, [&vs] (typename Net::Node * p)
2014  {
2015  vs.insert(p); return true;
2016  });
2017 
2018  // Calcula vt por el complemento
2019  const size_t size_vt = net.get_num_nodes() - vs.size();
2020  for (Node_Iterator<Net> it(net); it.has_curr() and
2021  vt.size() < size_vt; it.next_ne())
2022  {
2023  auto p = it.get_curr_ne();
2024  if (p->state() == Unprocessed)
2025  vt.insert(p);
2026  }
2027 
2028  for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
2029  {
2030  auto arc = it.get_curr_ne();
2031  if (arc->flow == 0) // ¿candidato a arco de retroceso?
2032  if (vt.contains(net.get_src_node(arc)) and // ¿de vt hacia vs?
2033  vs.contains(net.get_tgt_node(arc)) > 0)
2034  {
2035  cutt.insert(arc);
2036  continue;
2037  }
2038 
2039  if (arc->flow == arc->cap) // ¿candidato a arco de cruce?
2040  if (vs.contains(net.get_src_node(arc)) and // ¿de vs hacia vt?
2041  vt.contains(net.get_tgt_node(arc)) > 0)
2042  cuts.insert(arc);
2043  }
2044 
2045  return net.flow_value();
2046 }
2047 
2048 
2063  template <class Net,
2064  template <class> class Maxflow = Heap_Preflow_Maximum_Flow>
2065 struct Min_Cut
2066 {
2080  typename Net::Flow_Type operator () (Net & net,
2085  {
2086  return min_cut <Net, Maxflow> (net, vs, vt, cuts, cutt);
2087  }
2088 };
2089 
2090 
2091 } // end namespace Aleph
2092 
2093 # endif // TPL_NET_H
bool is_connected(Node *p) const noexcept
Definition: tpl_net.H:334
SemiPath< Net > find_decrementing_path(const Net &net, const typename Net::Flow_Type &slack)
Definition: tpl_net.H:1305
void make_super_source()
Definition: tpl_net.H:379
Flow_Type flow
valor de flujo
Definition: tpl_net.H:92
Definition: tpl_net.H:1809
Definition: tpl_agraph.H:691
Definition: tpl_graph.H:1225
Definition: tpl_agraph.H:301
bool is_single_source() const noexcept
Retorna true si la red es de un solo fuente.
Definition: tpl_net.H:326
Net::Flow_Type heap_preflow_maximum_flow(Net &net)
Definition: tpl_net.H:1873
SemiPath< Net > find_dec_path(typename Net::Flow_Type min_slack=0.0)
Encuentra un camino de decremento de al menos un slack.
Definition: tpl_net.H:1129
Flow_Type cap
valor de capacidad
Definition: tpl_net.H:89
const DynSetTree< Node * > & get_src_nodes() const noexcept
Retorna el conjunto de nodos fuente que contiene la red.
Definition: tpl_net.H:366
Node * get_connected_node(Arc *arc, Node *node) const noexcept
Definition: graph-dry.H:488
size_t get_in_degree(Node *p) const noexcept
Definition: tpl_net.H:289
const unsigned char Processing
#define NODE_COOKIE(p)
Definition: aleph-graph.H:333
Net::Flow_Type edmonds_karp_maximum_flow(Net &net)
Definition: tpl_net.H:1561
void set_flow(Arc *arc, const Flow_Type &flow)
Definition: tpl_net.H:752
void decrease_flow(Net &net, const DynList< Parc< Net >> &semi_path, typename Net::Flow_Type slack)
Definition: tpl_net.H:983
Flow_Type get_in_cap(Node *node) const noexcept
Retorna la capacidad total de entrada del nodo node.
Definition: tpl_net.H:270
Definition: tpl_net.H:139
bool is_sink(Node *node) noexcept
Retorna true si node es sumidero.
Definition: tpl_net.H:323
size_t remove(const Key &key)
Definition: tpl_dynSetTree.H:327
Node * get_current_node() const
Definition: tpl_graph.H:3159
Net_Graph(const Net_Graph &net)
Definition: tpl_net.H:723
Definition: tpl_net.H:996
void insert(Arc *arc)
Definition: tpl_graph.H:2951
Arc * insert_arc(Node *src_node, Node *tgt_node, const Flow_Type &cap, const Flow_Type &flow, const typename Arc::Arc_Type &arc_info=Arc_Type())
Definition: tpl_net.H:575
void for_each(Operation &operation) noexcept(noexcept(operation))
Definition: htlist.H:589
void make_super_nodes()
Definition: tpl_net.H:443
tuple< typename Net::Arc *, bool > Parc
Definition: tpl_net.H:834
void make_super_sink()
Definition: tpl_net.H:412
size_t get_out_degree(Node *p) const noexcept
Definition: tpl_net.H:296
Definition: tpl_net.H:82
Definition: tpl_net.H:216
SemiPath< Net > find_aumenting_semi_path(const Net &net, const typename Net::Flow_Type &slack)
Definition: tpl_net.H:1239
bool is_source(Node *node) noexcept
Retorna true si node es fuente.
Definition: tpl_net.H:320
Flow_Type get_out_cap(Node *node) const noexcept
Retorna la capacidad total de salida del nodo node.
Definition: tpl_net.H:279
Definition: tpl_graph.H:1693
size_t out_degree(typename GT::Node *p, SA sa=SA())
Definition: tpl_graph.H:1976
Definition: graph-traverse.H:42
Node * get_sink() const
Retorna un nodo sumidero de la red.
Definition: tpl_net.H:469
SemiPath< Net > find_aum_path(typename Net::Flow_Type min_slack=0.0)
Encuentra un camino de aumento de al menos un slack.
Definition: tpl_net.H:1123
Definition: tpl_dynListQueue.H:50
void unmake_super_nodes()
Definition: tpl_net.H:459
bool check_arc() const noexcept
Definition: tpl_net.H:97
Net::Flow_Type random_preflow_maximum_flow(Net &net)
Definition: tpl_net.H:1933
DynList< typename GT::Node * > out_nodes(typename GT::Node *p, SA sa=SA())
Definition: tpl_graph.H:1829
Net::Flow_Type aumenting_path_maximum_flow(Net &net)
Definition: tpl_net.H:1476
size_t in_degree(typename GT::Node *p, SA sa=SA())
Definition: tpl_graph.H:1948
void copy_graph(GT &gtgt, const GT &gsrc, const bool cookie_map=false)
Definition: tpl_graph.H:3482
const unsigned char Unprocessed
virtual void remove_arc(Arc *arc)
Elimina de la red el arco arc.
Definition: tpl_net.H:676
#define NODE_COUNTER(p)
Definition: aleph-graph.H:311
T & insert(const T &item)
Definition: htlist.H:1400
const Flow_Type & get_flow(Arc *arc) const noexcept
retorna el valor de capacidad del arco.
Definition: tpl_net.H:761
Net::Flow_Type remaining_flow(typename Net::Node *src, typename Net::Arc *a) noexcept
Definition: tpl_net.H:191
const unsigned char Processed
SemiPath< Net > find_aumenting_semi_path_dfs(const Net &net, const typename Net::Flow_Type &slack)
Definition: tpl_net.H:1260
SemiPath< Net > find_aumenting_semi_path_bfs(const Net &net, const typename Net::Flow_Type &slack)
Definition: tpl_net.H:1281
bool check_network()
Definition: tpl_net.H:784
Definition: tpl_dynBinHeap.H:55
Flow_Type get_in_flow(Node *node) const noexcept
Retorna el valor de flujo de entrada del nodo.
Definition: tpl_net.H:311
Definition: tpl_graph.H:53
Node * insert_node(Node *p)
Definition: tpl_net.H:532
bool with_super_source
true si a la red se le ha añadido un supra fuente.
Definition: tpl_net.H:801
Definition: tpl_agraph.H:43
const Key & get_item() const
Retorna un elemento cualquiera del conjunto.
Definition: tpl_dynSetTree.H:524
DynList< typename GT::Arc * > arcs(typename GT::Node *p, SA sa=SA())
Definition: tpl_graph.H:1893
typename Arc::Flow_Type Flow_Type
Tipo que representa la capacidad y el flujo.
Definition: tpl_net.H:233
Definition: ah-comb.H:35
void unmake_super_sink() noexcept
Definition: tpl_net.H:430
tuple< bool, typename Net::Flow_Type, DynList< Parc< Net > >> SemiPath
Definition: tpl_net.H:845
ArcT Arc
Tipo de arco.
Definition: tpl_net.H:227
void increase_flow(Net &net, const DynList< Parc< Net >> &semi_path, const typename Net::Flow_Type slack)
Definition: tpl_net.H:947
Arc * insert_arc(Node *src_node, Node *tgt_node, const Flow_Type &cap)
Definition: tpl_net.H:647
bool with_super_sink
true si a la red se le ha añadido un supra sumidero.
Definition: tpl_net.H:804
virtual void remove_node(Node *p) noexcept
Elimina un nodo de una red de flujo junto con todos sus arcos.
Definition: tpl_net.H:714
Path< Net > find_aumenting_path_dfs(const Net &net, const typename Net::Flow_Type &min_slack)
Definition: tpl_net.H:1200
Net::Flow_Type min_cut(Net &net, DynSetTree< typename Net::Node *> &vs, DynSetTree< typename Net::Node *> &vt, DynList< typename Net::Arc *> &cuts, DynList< typename Net::Arc *> &cutt)
Definition: tpl_net.H:2000
void next_ne() noexcept
Definition: tpl_dynDlist.H:433
Flow_Type flow_value() const
Definition: tpl_net.H:794
Container< Arc * > arcs() const
Definition: graph-dry.H:2109
void set_cap(Arc *arc, const Flow_Type &cap)
Coloca valor de capacidad a un arco.
Definition: tpl_net.H:742
tuple< __Graph_Arc *, __Graph_Node *> ArcPair
Pair of arc and node (topologically related)
Definition: graph-dry.H:2553
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
Definition: graph-dry.H:447
#define NODE_BITS(p)
Definition: aleph-graph.H:305
Definition: tpl_net.H:2065
const size_t & size() const
Retorna la cardinalidad del conjunto.
Definition: tpl_dynSetTree.H:502
Arc * insert_arc(Node *src_node, Node *tgt_node, const typename Arc::Arc_Type &arc_info=Arc_Type())
Definition: tpl_net.H:669
Node * insert_node(const Node_Type &node_info)
Definition: tpl_net.H:481
Definition: tpl_net.H:1530
bool check_node(Node *node) noexcept
Definition: tpl_net.H:341
Net::Flow_Type ford_fulkerson_maximum_flow(Net &net)
Definition: tpl_net.H:1518
Definition: tpl_dynSetTree.H:61
bool is_single_sink() const noexcept
Retorna true si la red es de un solo sumidero.
Definition: tpl_net.H:329
const DynSetTree< Node * > & get_sink_nodes() const noexcept
Retorna el conjunto de nodos sumidero que contiene la red.
Definition: tpl_net.H:369
Definition: tpl_graph.H:1270
GT::Arc * get_curr_ne() const noexcept
Definition: tpl_graph.H:1734
Path< Net > find_aumenting_path(const Net &net, const typename Net::Flow_Type &min_slack)
Definition: tpl_net.H:1182
void reset_nodes() const
Definition: graph-dry.H:630
const Flow_Type & get_cap(Arc *arc) const noexcept
Retorna el valor de flujo de un arco.
Definition: tpl_net.H:764
DynList< Arc * > out_arcs(Node *p) const noexcept
Arcos que salen desde p.
Definition: tpl_net.H:244
SemiPath< Net > find_decrementing_path_dfs(const Net &net, const typename Net::Flow_Type &slack)
Definition: tpl_net.H:1322
typename GT::Out_Iterator __Out_Iterator
Definition: tpl_graph.H:1780
void disconnect_arc(Arc *arc) noexcept
Definition: tpl_net.H:700
SemiPath< Net > find_decrementing_path_bfs(const Net &net, const typename Net::Flow_Type &slack)
Definition: tpl_net.H:1339
Definition: ahDry.H:41
Definition: filter_iterator.H:68
Arc * connect_arc(Arc *arc)
Definition: tpl_net.H:617
Definition: tpl_net.H:1886
typename GT::In_Iterator __In_Iterator
Definition: tpl_graph.H:1788
Node * get_source() const
Retorna un nodo fuente de la red.
Definition: tpl_net.H:466
__Graph_Arc * insert_arc(__Graph_Node *src, __Graph_Node *tgt, const Arc_Type &arc_info)
Definition: graph-dry.H:899
void unmake_super_source() noexcept
Definition: tpl_net.H:398
Flow_Type get_out_flow(Node *node) const noexcept
Retorna el valor de flujo de salida del nodo.
Definition: tpl_net.H:302
Net::Flow_Type fifo_preflow_maximum_flow(Net &net)
Definition: tpl_net.H:1796
bool has_current_arc() const noexcept
Definition: tpl_graph.H:3237
Definition: tpl_graph.H:3135
Node * insert_node(Node_Type &&info=Node_Type())
Definition: tpl_net.H:508
DynList< typename GT::Arc * > in_arcs(typename GT::Node *p, SA sa=SA())
Definition: tpl_graph.H:1878
Net::Flow_Type generic_preflow_vertex_push_maximum_flow(Net &net)
Definition: tpl_net.H:1682
Key * insert(const Key &key)
Definition: tpl_dynSetTree.H:195
Path< Net > find_aumenting_path_bfs(const Net &net, const typename Net::Flow_Type &min_slack)
Definition: tpl_net.H:1216
Definition: tpl_net.H:1946
DynList< typename GT::Node * > in_nodes(typename GT::Node *p, SA sa=SA())
Definition: tpl_graph.H:1846
Definition: tpl_net.H:1573

Leandro Rabindranath León