Aleph-w  1.9
General library for algorithms and data structures
Kruskal.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 KRUSKAL_H
28 # define KRUSKAL_H
29 
30 # include <ahFunction.H>
31 # include <tpl_agraph.H>
32 # include <tpl_graph_utils.H>
33 # include <tpl_test_acyclique.H>
34 # include <tpl_union.H>
35 
36 using namespace Aleph;
37 
38 namespace Aleph {
39 
40 
76  template <class GT,
77  class Distance = Dft_Dist<GT>,
78  class SA = Dft_Show_Arc<GT>>
80 {
81  Distance & dist;
82  SA sa;
83  bool painted;
84 
85 public:
86 
93  Kruskal_Min_Spanning_Tree(Distance && __dist = Distance(),
94  SA __sa = SA())
95  noexcept(std::is_nothrow_move_assignable<Distance>::value and
96  std::is_nothrow_move_assignable<SA>::value)
97  : dist(__dist), sa(__sa), painted(false)
98  {
99  /* empty */
100  }
101 
102  Kruskal_Min_Spanning_Tree(Distance & __dist, SA __sa = SA())
103  noexcept(std::is_nothrow_copy_assignable<Distance>::value and
104  std::is_nothrow_copy_assignable<SA>::value)
105  : dist(__dist), sa(__sa), painted(false)
106  {
107  /* empty */
108  }
109 
110 public:
111 
113  template <class G, class GT_SA>
114  struct Paint_Filt
115  {
116  GT_SA & sa;
117 
118  Paint_Filt(GT_SA & __sa)
119  noexcept(std::is_nothrow_copy_assignable<SA>::value)
120  : sa(__sa) { /* empty */ }
121 
122  bool operator () (typename G::Arc * a) const noexcept
123  {
124  if (not sa(a))
125  return false;
126 
127  return IS_ARC_VISITED(a, Aleph::Spanning_Tree);
128  }
129  };
130 
131 private:
132 
133  struct Init_Node
134  {
135  long count;
136 
137  Init_Node() noexcept : count(0) { /* empty */ }
138 
139  void operator () (const GT &, typename GT::Node * p) noexcept
140  {
141  NODE_COUNTER(p) = count++;
142  NODE_BITS(p).set_bit(Aleph::Spanning_Tree, false);
143  }
144  };
145 
146  static bool arc_is_in_tree(Fixed_Relation & tree, long i, long j) noexcept
147  {
148  return tree.are_connected(i, j);
149  }
150 
151 public:
152 
153  void paint_min_spanning_tree(const GT & g)
154  {
155  if (g.is_digraph())
156  throw std::domain_error("g is a digraph");
157 
158  g.reset_bit_arcs(Aleph::Spanning_Tree); // limpiar bits de marcado de arcos
159  Operate_On_Nodes<GT, Init_Node> () (g, Init_Node());
160 
161  typedef Distance_Compare<GT, Distance> DCMP;
162  DCMP comp(dist);
163  const_cast<GT&>(g).template sort_arcs<DCMP>(comp);
164  const size_t V = g.get_num_nodes();
165 
166  Fixed_Relation tree(V);
167 
168  // Recorrer arcos ordenados de g hasta que numero de arcos de
169  // tree sea igual al numero de nodos de g
170  for (Arc_Iterator <GT, SA> it(g, sa); tree.get_num_blocks() > 1 and
171  it.has_curr(); it.next_ne())
172  { // siguiente menor arco
173  auto arc = it.get_current_arc_ne();
174  long i = NODE_COUNTER(g.get_src_node(arc));
175  long j = NODE_COUNTER(g.get_tgt_node(arc));
176  if (arc_is_in_tree(tree, i, j))
177  continue;
178 
179  tree.join(i, j);
180  ARC_BITS(arc).set_bit(Aleph::Spanning_Tree, true);
181  }
182 
183  painted = true;
184  }
185 
186  void paint_min_spanning_tree(const GT & g, GT & tree)
187  {
188  paint_min_spanning_tree(g);
189  clear_graph(tree); // limpia grafo destino
190 
191  for (typename GT::Node_Iterator it(g); it.has_curr(); it.next_ne())
192  {
193  auto gp = it.get_curr_ne();
194  auto tp = tree.insert_node(gp->get_info());
195  GT::map_nodes(gp, tp);
196  }
197 
198  typedef Paint_Filt<GT, SA> F;
199  for (Arc_Iterator<GT, F> it(g, F(sa)); it.has_curr(); it.next_ne())
200  {
201  auto ga = it.get_current_arc_ne();
202  auto tsrc = mapped_node<GT>(g.get_src_node(ga));
203  auto ttgt = mapped_node<GT>(g.get_tgt_node(ga));
204  auto ta = tree.insert_arc(tsrc, ttgt, ga->get_info());
205  GT::map_arcs(ga, ta);
206  }
207  }
208 
209 public:
210 
222  void operator () (const GT & g, GT & tree)
223  {
224  paint_min_spanning_tree(g, tree);
225  }
226 
238  void operator () (const GT & g)
239  {
240  paint_min_spanning_tree(g);
241  }
242 };
243 
244 
245 } // end namespace Aleph
246 
247 # endif // KRUSKAL_H
void clear_graph(GT &g) noexcept
Definition: tpl_graph.H:3463
Definition: tpl_graph.H:1225
Definition: tpl_graph.H:2493
Definition: tpl_graph_utils.H:1618
Definition: tpl_union.H:52
#define NODE_COUNTER(p)
Definition: aleph-graph.H:311
void join(size_t i, size_t j) noexcept
Definition: tpl_union.H:139
void map_arcs(typename GTS::Arc *p, typename GTT::Arc *q) noexcept
Definition: tpl_graph.H:3445
size_t get_num_blocks() const noexcept
Definition: tpl_union.H:114
#define IS_ARC_VISITED(p, bit)
Definition: aleph-graph.H:360
Definition: Kruskal.H:79
void map_nodes(typename GTS::Node *p, typename GTT::Node *q) noexcept
Definition: tpl_graph.H:3419
Definition: ah-comb.H:35
bool are_connected(size_t i, size_t j) noexcept
Definition: tpl_union.H:128
Definition: tpl_graph.H:1063
#define NODE_BITS(p)
Definition: aleph-graph.H:305
Definition: tpl_graph_utils.H:1753
Filtro de arcos pintados por el algoritmo de Kruskal.
Definition: Kruskal.H:114
Kruskal_Min_Spanning_Tree(Distance &&__dist=Distance(), SA __sa=SA()) noexcept(std::is_nothrow_move_assignable< Distance >::value and std::is_nothrow_move_assignable< SA >::value)
Definition: Kruskal.H:93
#define ARC_BITS(p)
Definition: aleph-graph.H:351

Leandro Rabindranath León