Aleph-w  1.9
General library for algorithms and data structures
tpl_kgraph.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_KGRAPH_H
28 # define TPL_KGRAPH_H
29 
30 # include <Set.H>
31 # include <tpl_net.H>
32 
33 namespace Aleph {
34 
54 template <class GT,
55  template <class> class Max_Flow = Random_Preflow_Maximum_Flow,
56  class SA = Dft_Show_Arc<GT> >
57 long edge_connectivity(GT & g)
58 {
60  Net net;
61  typename Net::Node * source = nullptr;
62  long min_degree = numeric_limits<long>::max();
63  for (Node_Iterator<GT> it(g); it.has_curr(); it.next_ne())
64  {
65  auto p = it.get_curr_ne();
66  NODE_COOKIE(p) = net.insert_node();
67  if (g.get_num_arcs(p) < min_degree)
68  {
69  source = mapped_node<GT, Net> (p);
70  min_degree = g.get_num_arcs(p);
71  }
72  }
73 
74  if (min_degree <= 1)
75  return min_degree;
76 
77  for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
78  {
79  auto a = it.get_curr_ne();
80  auto src = mapped_node<GT, Net> (g.get_src_node(a));
81  auto tgt = mapped_node<GT, Net> (g.get_tgt_node(a));
82  if (src != source)
83  net.insert_arc(tgt, src, 1);
84  if (tgt != source)
85  net.insert_arc(src, tgt, 1);
86  }
87 
88  long min_k = min_degree;
89  for (Node_Iterator<Net> it(net); it.has_curr(); it.next_ne())
90  {
91  auto sink = it.get_curr_ne();
92  if (sink == source)
93  continue;
94 
95  DynDlist<typename Net::Arc*> from_sink_arcs;
96 
97  for (Node_Arc_Iterator<Net> it(sink); it.has_curr(); it.next_ne())
98  from_sink_arcs.append(it.get_curr_ne());
99 
101  it(from_sink_arcs); it.has_curr(); it.next_ne())
102  net.disconnect_arc(it.get_curr_ne());
103 
104  const typename Net::Flow_Type flow = Max_Flow <Net> () (net);
105  if (flow < min_k)
106  min_k = flow;
107 
108  while (not from_sink_arcs.is_empty())
109  net.connect_arc(from_sink_arcs.get());
110 
111  net.reset(); // colocar flujo en cero
112  }
113 
114  return min_k;
115 }
116 
133  template <class GT,
134  template <class> class Max_Flow = Heap_Preflow_Maximum_Flow>
136 {
137 public:
138 
149  long operator () (GT & g) { return edge_connectivity <GT, Max_Flow> (g); }
150 };
151 
152 
181  template <class GT,
182  template <class> class Max_Flow = Heap_Preflow_Maximum_Flow,
183  class SA = Dft_Show_Arc<GT> >
184 long compute_min_cut(GT & g,
188 {
190  Net net;
191  typename Net::Node * source = nullptr;
192  long min_degree = numeric_limits<long>::max();
193  for (Node_Iterator<GT> it(g); it.has_curr(); it.next_ne())
194  {
195  auto p = it.get_curr_ne();
196  auto q = net.insert_node();
197  GT::map_nodes (p, q);
198 
199  if (g.get_num_arcs(p) < min_degree)
200  {
201  source = mapped_node<GT, Net> (p);
202  min_degree = g.get_num_arcs(p);
203  }
204  }
205 
206  if (min_degree <= 1)
207  return min_degree;
208 
209  for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
210  {
211  auto a = it.get_curr_ne();
212  auto src = mapped_node<GT, Net>(g.get_src_node(a));
213  auto tgt = mapped_node<GT, Net>(g.get_tgt_node(a));
214  if (src != source)
215  {
216  auto arc = net.insert_arc(tgt, src, 1);
217  ARC_COOKIE(arc) = a;
218  }
219 
220  if (tgt != source)
221  {
222  auto arc = net.insert_arc(src, tgt, 1);
223  ARC_COOKIE(arc) = a;
224  }
225  }
226 
227  Aleph::set<typename Net::Node*> tmp_vs, tmp_vt;
228  DynDlist<typename Net::Arc*> tmp_cuts, tmp_cutt;
229  long min_k = numeric_limits<long>::max();
230  for (Node_Iterator<Net> it(net); it.has_curr(); it.next_ne())
231  {
232  auto sink = it.get_curr_ne();
233  if (sink == source)
234  continue;
235 
236  DynDlist<typename Net::Arc*> from_sink_arcs;
237 
238  for (Node_Arc_Iterator<Net> it(sink); it.has_curr(); it.next_ne())
239  from_sink_arcs.append(it.get_curr_ne());
240 
242  it(from_sink_arcs); it.has_curr(); it.next_ne())
243  net.disconnect_arc(it.get_curr_ne());
244 
247  const auto flow = Min_Cut <Net, Max_Flow> () (net, vs, vt, cuts, cutt);
248 
249  if (flow < min_k)
250  {
251  min_k = flow;
252  tmp_vs.swap(vs);
253  tmp_vt.swap(vt);
254  tmp_cuts.swap(cuts);
255  tmp_cutt.swap(cutt);
256  }
257 
258  net.reset(); // colocar flujo en cero
259 
260  while (not from_sink_arcs.is_empty())
261  net.connect_arc(from_sink_arcs.get());
262  }
263 
265  it = tmp_vs.begin(); it != tmp_vs.end(); it++)
266  l.insert(mapped_node <Net, GT> (*it));
267 
269  it = tmp_vt.begin(); it != tmp_vt.end(); it++)
270  r.insert(mapped_node <Net, GT> (*it));
271 
272  for (typename DynDlist<typename Net::Arc*>::Iterator it(tmp_cuts);
273  it.has_curr(); it.next_ne())
274  {
275  typename Net::Arc* arc = it.get_curr_ne();
276  cut.append(mapped_arc<Net, GT> (arc));
277  }
278 
279  return min_k;
280 }
281 
311  template <class GT,
312  template <class> class Max_Flow = Heap_Preflow_Maximum_Flow,
313  class SA = Dft_Show_Arc<GT> >
315 {
316 public:
317  long operator () (GT & g,
321  {
322  return compute_min_cut <GT, Max_Flow, SA> (g, l, r, cut);
323  }
324 };
325 
326 
338  template <class GT,
339  template <class> class Max_Flow = Random_Preflow_Maximum_Flow,
340  class SA = Dft_Show_Arc<GT> >
342 {
344  Net net;
345  for (Node_Iterator<GT> it(g); it.has_curr(); it.next_ne())
346  {
347  auto p = it.get_curr_ne();
348  NODE_COOKIE(p) = net.insert_node();
349  }
350 
351  for (Arc_Iterator<GT, SA> it(g); it.has_curr(); it.next_ne())
352  {
353  auto a = it.get_curr_ne();
354  auto src = mapped_node<GT,Net>(g.get_src_node(a));
355  auto tgt = mapped_node<GT,Net>(g.get_tgt_node(a));
356  net.insert_arc(tgt, src, 1);
357  net.insert_arc(src, tgt, 1);
358  }
359 
360  long min_k = g.get_num_nodes();
361  int i = 1;
362 
363  for (Node_Iterator<Net> k(net); k.has_curr() and i < min_k; k.next_ne(), i++)
364  {
365  auto source = k.get_curr_ne();
366  DynDlist<typename Net::Arc*> to_source_list;
367  for (Node_Arc_Iterator<Net> it(source); it.has_curr(); it.next_ne())
368  {
369  auto from_arc = it.get_curr_ne();
370  auto to_arc =
371  search_arc<Net>(net, net.get_tgt_node(from_arc), source);
372  assert(to_arc != nullptr);
373  assert(net.get_tgt_node(to_arc) == source);
374  to_source_list.append(to_arc);
375  }
376 
377  for (typename DynDlist<typename Net::Arc *>::Iterator it(to_source_list);
378  it.has_curr(); it.next_ne())
379  net.disconnect_arc(it.get_curr_ne());
380 
381  {
382  Node_Iterator<Net> j(k);
383  for (j.next(); j.has_curr(); j.next_ne())
384  {
385  auto sink = j.get_curr_ne();
386  if (search_arc <Net> (net, source, sink) != nullptr)
387  continue; // existe arco ==> ignórelo y avance a siguiente
388 
389  DynDlist<typename Net::Arc*> from_sink_arcs;
390 
391  for (Node_Arc_Iterator<Net> it(sink); it.has_curr(); it.next_ne())
392  from_sink_arcs.append(it.get_curr_ne());
393 
395  it(from_sink_arcs); it.has_curr(); it.next_ne())
396  net.disconnect_arc(it.get_curr_ne());
397  {
398  Net aux_net;
399  {
401  for (Node_Iterator<Net> it(net); it.has_curr(); it.next_ne())
402  {
403  auto p = it.get_curr_ne();
404  if (p == source or p == sink)
405  {
406  NODE_COOKIE(p) = aux_net.insert_node();
407  continue;
408  }
409 
410  auto ps = aux_net.insert_node(p->get_info());
411  auto pt = aux_net.insert_node(p->get_info());
412  map.insert(p, aux_net.insert_arc(ps, pt, 1));
413  }
414 
415  for (Arc_Iterator<Net> it(net); it.has_curr(); it.next_ne())
416  {
417  auto a = it.get_curr_ne();
418  auto nsrc = net.get_src_node(a);
419  auto ntgt = net.get_tgt_node(a);
420  typename Net::Node * asrc = nullptr;
421  typename Net::Node * atgt = nullptr;
422 
423  if (nsrc == source)
424  asrc = (typename Net::Node *) NODE_COOKIE(nsrc);
425  else
426  {
427  auto arc = map.find(nsrc);
428  asrc = aux_net.get_tgt_node(arc);
429  }
430 
431  if (ntgt == sink)
432  atgt = (typename Net::Node *) NODE_COOKIE(ntgt);
433  else
434  {
435  auto arc = map.find(ntgt);
436  atgt = aux_net.get_src_node(arc);
437  }
438  aux_net.insert_arc(asrc, atgt, 1);
439  }
440  } // fin de bloque que crea el mapeo
441 
442  const auto flow = Max_Flow <Net> () (aux_net);
443  if (flow < min_k)
444  min_k = flow;
445  }
446 
447  while (not from_sink_arcs.is_empty())
448  net.connect_arc(from_sink_arcs.get());
449 
450  net.reset(); // colocar flujo en cero
451  }
452 
453  while (not to_source_list.is_empty())
454  net.connect_arc(to_source_list.get());
455  }
456  }
457 
458  return min_k;
459 }
460 
461 
462 } // end namespace Aleph
463 
464 # endif // TPL_KGRAPH_H
Definition: tpl_graph.H:1225
void swap(DynDlist &l) noexcept
Definition: tpl_dynDlist.H:357
Pair * insert(const Key &key, const Type &data)
Definition: tpl_dynMapTree.H:112
#define NODE_COOKIE(p)
Definition: aleph-graph.H:333
Definition: tpl_dynDlist.H:51
Definition: tpl_net.H:82
Definition: tpl_net.H:216
void swap(set &c)
Definition: Set.H:476
#define ARC_COOKIE(p)
Definition: aleph-graph.H:366
Definition: tpl_dynDlist.H:413
long vertex_connectivity(GT &g)
Definition: tpl_kgraph.H:341
iterator end() const
Retorna un iterador posicionado al último elemento del conjunto.
Definition: Set.H:488
void map_nodes(typename GTS::Node *p, typename GTT::Node *q) noexcept
Definition: tpl_graph.H:3419
std::pair< iterator, bool > insert(const T &value)
Definition: Set.H:511
Definition: ah-comb.H:35
Definition: tpl_kgraph.H:314
Definition: tpl_graph.H:1063
void next()
Adelanta el iterador una posición.
Definition: filter_iterator.H:169
Definition: tpl_net.H:2065
Definition: tpl_dynMapTree.H:357
Definition: tpl_kgraph.H:135
iterator begin() const
Retorna un iterador posicionado al primer elemento del conjunto.
Definition: Set.H:482
Definition: tpl_graph.H:1270
Definition: Set.H:65
long operator()(GT &g)
Definition: tpl_kgraph.H:149
T get()
Definition: tpl_dynDlist.H:306
long edge_connectivity(GT &g)
Definition: tpl_kgraph.H:57
Definition: tpl_net.H:1886
Definition: Map.H:82
Definition: tpl_graph.H:1177
long compute_min_cut(GT &g, Aleph::set< typename GT::Node *> &l, Aleph::set< typename GT::Node *> &r, DynDlist< typename GT::Arc *> &cut)
Definition: tpl_kgraph.H:184
T & append(const T &item)
Definition: tpl_dynDlist.H:149
Definition: tpl_net.H:1946
Type & find(const Key &key)
Definition: tpl_dynMapTree.H:242

Leandro Rabindranath León