Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
maxflow_sap.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file maxflow_sap.cpp
1 /* This software is distributed under the GNU Lesser General Public License */
2 //==========================================================================
3 //
4 // maxflow_sap.cpp
5 //
6 //==========================================================================
7 // $Id: maxflow_sap.cpp,v 1.6 2001/11/07 13:58:10 pick Exp $
8 
9 #include <GTL/maxflow_sap.h>
10 #include <cstdlib>
11 #include <iostream>
12 #include <cassert>
13 
14 #ifdef __GTL_MSVCC
15 # ifdef _DEBUG
16 # ifndef SEARCH_MEMORY_LEAKS_ENABLED
17 # error SEARCH NOT ENABLED
18 # endif
19 # define new DEBUG_NEW
20 # undef THIS_FILE
21  static char THIS_FILE[] = __FILE__;
22 # endif // _DEBUG
23 #endif // __GTL_MSVCC
24 
26 
28 {
29  max_graph_flow = 0.0;
30  set_vars_executed = false;
31 }
32 
33 
35 {
36 }
37 
38 
39 void maxflow_sap::set_vars(const edge_map<double>& edge_capacity)
40 {
41  this->edge_capacity = edge_capacity;
42  artif_source_target = true;
43  max_graph_flow = 0.0;
44  set_vars_executed = true;
45 }
46 
47 
48 void maxflow_sap::set_vars(const edge_map<double>& edge_capacity,
49  const node& net_source, const node& net_target)
50 {
51  this->edge_capacity = edge_capacity;
52  this->net_source = net_source;
53  this->net_target = net_target;
54  artif_source_target = false;
55  max_graph_flow = 0.0;
56  set_vars_executed = true;
57 }
58 
59 
61 {
62  if (!set_vars_executed)
63  {
64  return(GTL_ERROR);
65  }
66  graph::edge_iterator edge_it = G.edges_begin();
67  graph::edge_iterator edges_end = G.edges_end();
68  while (edge_it != edges_end)
69  {
70  if (edge_capacity[*edge_it] < 0)
71  {
72  return(GTL_ERROR);
73  }
74  ++edge_it;
75  }
76  // G.is_acyclic may be false
77  if ((G.number_of_nodes() <= 1) || (!G.is_connected())
78  || (G.is_undirected()))
79  {
80  return(GTL_ERROR);
81  }
83  {
84  bool source_found = false;
85  bool target_found = false;
86  graph::node_iterator node_it = G.nodes_begin();
87  graph::node_iterator nodes_end = G.nodes_end();
88  while (node_it != nodes_end)
89  {
90  if ((*node_it).indeg() == 0)
91  {
92  source_found = true;
93  }
94  if ((*node_it).outdeg() == 0)
95  {
96  target_found = true;
97  }
98  ++node_it;
99  }
100  if (!(source_found && target_found))
101  {
102  return(GTL_ERROR);
103  }
104  }
105  else
106  {
107  if (net_source == net_target)
108  {
109  return(GTL_ERROR);
110  }
111  }
112  return(GTL_OK); // everything ok
113 }
114 
115 
117 {
118  // init
120  {
122  }
123  bool go_on = true;
124  node_map<edge> last_edge(G);
125  node cur_node;
126  int number_of_nodes = G.number_of_nodes();
127  vector<int> numb(number_of_nodes, 0);
128  prepare_run(G);
129 
130  comp_dist_labels(G, numb);
131  cur_node = net_source;
132 
133  while (go_on)
134  {
135  if (has_an_admissible_arc(cur_node))
136  {
137  advance(cur_node, last_edge);
138  if (cur_node == net_target)
139  {
140  augment(G, last_edge);
141  cur_node = net_source;
142  }
143  }
144  else // only inadmissible edges
145  {
146  go_on = retreat(number_of_nodes, cur_node, last_edge, numb);
147  }
148  }
149 
150  restore_graph(G);
151  return(GTL_OK);
152 }
153 
154 
155 double maxflow_sap::get_max_flow(const edge& e) const
156 {
157  return(edge_max_flow[e]);
158 }
159 
160 
162 {
163  return(max_graph_flow);
164 }
165 
166 
167 double maxflow_sap::get_rem_cap(const edge& e) const
168 {
169  return(edge_capacity[e] - edge_max_flow[e]);
170 }
171 
172 
174 {
175  max_graph_flow = 0.0;
176  set_vars_executed = false;
177 }
178 
179 
181 {
182  net_source = G.new_node();
183  net_target = G.new_node();
184  edge e;
185  graph::node_iterator node_it = G.nodes_begin();
186  graph::node_iterator nodes_end = G.nodes_end();
187  while (node_it != nodes_end)
188  {
189  if (*node_it != net_source && (*node_it).indeg() == 0)
190  {
191  e = G.new_edge(net_source, *node_it);
192  edge_capacity[e] = 1.0; // 1.0 prevents e from hiding
193  node::out_edges_iterator out_edge_it =
194  (*node_it).out_edges_begin();
195  node::out_edges_iterator out_edges_end =
196  (*node_it).out_edges_end();
197  while (out_edge_it != out_edges_end)
198  {
199  edge_capacity[e] += edge_capacity[*out_edge_it];
200  ++out_edge_it;
201  }
202  }
203  if (*node_it != net_target && (*node_it).outdeg() == 0)
204  {
205  e = G.new_edge(*node_it, net_target);
206  edge_capacity[e] = 1.0; // 1.0 prevents e from hiding
207  node::in_edges_iterator in_edge_it =
208  (*node_it).in_edges_begin();
209  node::in_edges_iterator in_edges_end =
210  (*node_it).in_edges_end();
211  while (in_edge_it != in_edges_end)
212  {
213  edge_capacity[e] += edge_capacity[*in_edge_it];
214  ++in_edge_it;
215  }
216  }
217  ++node_it;
218  }
219 }
220 
221 
223 {
224  edge_max_flow.init(G, 0.0);
225  edge_org.init(G, true);
226  back_edge_exists.init(G, false);
227  max_graph_flow = 0.0;
228 }
229 
230 
231 void maxflow_sap::comp_dist_labels(const graph& G, vector<int>& numb)
232 {
233  queue<node> next_nodes;
234  node_map<bool> visited(G, false);
235  next_nodes.push(net_target);
236  visited[net_target] = true;
237  dist_label[net_target] = 0;
238  numb[0] = 1; // only one sink
239  node cur_node;
240 
241  while (!next_nodes.empty())
242  {
243  cur_node = next_nodes.front();
244  next_nodes.pop();
245  node::in_edges_iterator in_edge_it = cur_node.in_edges_begin();
246  node::in_edges_iterator in_edges_end = cur_node.in_edges_end();
247  while (in_edge_it != in_edges_end)
248  {
249  node next = (*in_edge_it).source();
250  if (!visited[next])
251  {
252  next_nodes.push(next);
253  visited[next] = true;
254  dist_label[next] = dist_label[cur_node] + 1;
255  ++numb[dist_label[next]];
256  }
257  ++in_edge_it;
258  }
259  }
260 }
261 
262 
264 {
265  node::out_edges_iterator out_edge_it = cur_node.out_edges_begin();
266  node::out_edges_iterator out_edges_end = cur_node.out_edges_end();
267  while (out_edge_it != out_edges_end)
268  {
269  if (dist_label[cur_node] == dist_label[(*out_edge_it).target()] + 1)
270  {
271  return true;
272  }
273  ++out_edge_it;
274  }
275  return false;
276 }
277 
278 
279 void maxflow_sap::advance(node& cur_node, node_map<edge>& last_edge)
280 {
281  node::out_edges_iterator out_edge_it = cur_node.out_edges_begin();
282  node::out_edges_iterator out_edges_end = cur_node.out_edges_end();
283  while (out_edge_it != out_edges_end)
284  {
285  if (dist_label[cur_node] == dist_label[(*out_edge_it).target()] + 1)
286  {
287  last_edge[(*out_edge_it).target()] = *out_edge_it;
288  cur_node = (*out_edge_it).target();
289  }
290  ++out_edge_it;
291  }
292 }
293 
294 
295 void maxflow_sap::augment(graph& G, const node_map<edge>& last_edge)
296 {
297  double additional_flow = free_capacity(last_edge);
298  node cur_node = net_target;
299 
300  do
301  {
302  if (edge_org[last_edge[cur_node]])
303  // shortest path runs over a org. edge
304  {
305  if (!back_edge_exists[last_edge[cur_node]]) // create back edge
306  {
307  create_back_edge(G, last_edge[cur_node]);
308  }
309  edge_max_flow[last_edge[cur_node]] += additional_flow;
310  G.restore_edge(back_edge[last_edge[cur_node]]);
311  edge_capacity[back_edge[last_edge[cur_node]]] +=
312  additional_flow;
313  }
314  else // shortest path runs over a inserted back edge
315  {
316  edge oe = back_edge[last_edge[cur_node]];
317  G.restore_edge(oe);
318  edge_max_flow[oe] -= additional_flow;
319  edge_capacity[last_edge[cur_node]] -= additional_flow;
320  }
321  if (edge_capacity[last_edge[cur_node]] <=
322  edge_max_flow[last_edge[cur_node]])
323  {
324  G.hide_edge(last_edge[cur_node]);
325  }
326  cur_node = last_edge[cur_node].source();
327  }
328  while (cur_node != net_source);
329 }
330 
331 
332 bool maxflow_sap::retreat(const int number_of_nodes,
333  node& cur_node,
334  const node_map<edge>& last_edge,
335  vector<int>& numb)
336 {
337  --numb[dist_label[cur_node]];
338  if (numb[dist_label[cur_node]] == 0)
339  {
340  return false;
341  }
342  else
343  {
344  dist_label[cur_node] =
345  min_neighbour_label(number_of_nodes, cur_node) + 1;
346  ++numb[dist_label[cur_node]];
347  if (cur_node != net_source)
348  {
349  cur_node = last_edge[cur_node].source();
350  }
351  return true;
352  }
353 }
354 
355 
356 int maxflow_sap::min_neighbour_label(const int number_of_nodes,
357  const node cur_node) const
358 {
359  int min_value = number_of_nodes; // if no out edge exists
360 
361  node::out_edges_iterator out_edge_it = cur_node.out_edges_begin();
362  node::out_edges_iterator out_edges_end = cur_node.out_edges_end();
363  while (out_edge_it != out_edges_end)
364  {
365  if (min_value > dist_label[(*out_edge_it).target()])
366  {
367  min_value = dist_label[(*out_edge_it).target()];
368  }
369  ++out_edge_it;
370  }
371  return min_value;
372 }
373 
374 
375 double maxflow_sap::free_capacity(const node_map<edge>& last_edge) const
376 {
377  node cur_node = net_target;
378  double min_value =
379  edge_capacity[last_edge[cur_node]] -
380  edge_max_flow[last_edge[cur_node]];
381  double cur_capacity;
382 
383  do
384  {
385  cur_capacity =
386  edge_capacity[last_edge[cur_node]] -
387  edge_max_flow[last_edge[cur_node]];
388 
389  if (cur_capacity < min_value)
390  {
391  min_value = cur_capacity;
392  }
393  cur_node = last_edge[cur_node].source();
394  }
395  while (cur_node != net_source);
396  return(min_value);
397 }
398 
399 
400 void maxflow_sap::create_back_edge(graph& G, const edge& org_edge)
401 {
402  edge be = G.new_edge(org_edge.target(), org_edge.source());
403  edge_org[be] = false;
404  edges_not_org.push_back(be);
405  back_edge[org_edge] = be;
406  back_edge[be] = org_edge;
407  edge_max_flow[be] = 0.0;
408  edge_capacity[be] = 0.0;
409  back_edge_exists[org_edge] = true;
410  back_edge_exists[be] = true; // a back edge always has a org. edge
411 }
412 
413 
415 {
416  max_graph_flow = 0.0;
417 
420  while (out_edge_it != out_edges_end)
421  {
422  max_graph_flow += edge_max_flow[*out_edge_it];
423  ++out_edge_it;
424  }
425 }
426 
427 
429 {
430  G.restore_graph(); // hidden edges can not be deleted!
431  while (!edges_not_org.empty())
432  {
433  G.del_edge(edges_not_org.front());
434  edges_not_org.pop_front();
435  }
436  comp_max_flow(G);
438  {
439  G.del_node(net_source);
440  G.del_node(net_target);
441  }
442 }
443 
445 
446 //--------------------------------------------------------------------------
447 // end of file
448 //--------------------------------------------------------------------------