File indexing completed on 2025-08-03 08:19:39
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <GTL/maxflow_pp.h>
0010
0011 #include <cstdlib>
0012 #include <iostream>
0013 #include <cassert>
0014
0015 #ifdef __GTL_MSVCC
0016 # ifdef _DEBUG
0017 # ifndef SEARCH_MEMORY_LEAKS_ENABLED
0018 # error SEARCH NOT ENABLED
0019 # endif
0020 # define new DEBUG_NEW
0021 # undef THIS_FILE
0022 static char THIS_FILE[] = __FILE__;
0023 # endif
0024 #endif
0025
0026 __GTL_BEGIN_NAMESPACE
0027
0028 maxflow_pp::maxflow_pp()
0029 {
0030 max_graph_flow = 0.0;
0031 set_vars_executed = false;
0032 }
0033
0034
0035 maxflow_pp::~maxflow_pp()
0036 {
0037 }
0038
0039
0040 void maxflow_pp::set_vars(const edge_map<double>& edge_capacity)
0041 {
0042 this->edge_capacity = edge_capacity;
0043 artif_source_target = true;
0044 max_graph_flow = 0.0;
0045 set_vars_executed = true;
0046 }
0047
0048
0049 void maxflow_pp::set_vars(const edge_map<double>& edge_capacity,
0050 const node& net_source, const node& net_target)
0051 {
0052 this->edge_capacity = edge_capacity;
0053 this->net_source = net_source;
0054 this->net_target = net_target;
0055 artif_source_target = false;
0056 max_graph_flow = 0.0;
0057 set_vars_executed = true;
0058 }
0059
0060
0061 int maxflow_pp::check(graph& G)
0062 {
0063 if (!set_vars_executed)
0064 {
0065 return(GTL_ERROR);
0066 }
0067 graph::edge_iterator edge_it = G.edges_begin();
0068 graph::edge_iterator edges_end = G.edges_end();
0069 while (edge_it != edges_end)
0070 {
0071 if (edge_capacity[*edge_it] < 0)
0072 {
0073 return(GTL_ERROR);
0074 }
0075 ++edge_it;
0076 }
0077
0078 if ((G.number_of_nodes() <= 1) || (!G.is_connected()) || (G.is_undirected()))
0079 {
0080 return(GTL_ERROR);
0081 }
0082 if (artif_source_target)
0083 {
0084 bool source_found = false;
0085 bool target_found = false;
0086 graph::node_iterator node_it = G.nodes_begin();
0087 graph::node_iterator nodes_end = G.nodes_end();
0088 while (node_it != nodes_end)
0089 {
0090 if ((*node_it).indeg() == 0)
0091 {
0092 source_found = true;
0093 }
0094 if ((*node_it).outdeg() == 0)
0095 {
0096 target_found = true;
0097 }
0098 ++node_it;
0099 }
0100 if (!(source_found && target_found))
0101 {
0102 return(GTL_ERROR);
0103 }
0104 }
0105 else
0106 {
0107 if (net_source == net_target)
0108 {
0109 return(GTL_ERROR);
0110 }
0111 }
0112 return(GTL_OK);
0113 }
0114
0115
0116 int maxflow_pp::run(graph& G)
0117 {
0118
0119 if (artif_source_target)
0120 {
0121 create_artif_source_target(G);
0122 }
0123 prepare_run(G);
0124
0125 double flow_value = 0;
0126 node min_tp_node;
0127 while(leveling(G) == TARGET_FROM_SOURCE_REACHABLE)
0128 {
0129 hide_unreachable_nodes(G);
0130 min_throughput_node(G, min_tp_node, flow_value);
0131 push(G, min_tp_node, flow_value);
0132 pull(G, min_tp_node, flow_value);
0133 comp_rem_net(G);
0134 }
0135
0136 restore_graph(G);
0137 return(GTL_OK);
0138 }
0139
0140
0141 double maxflow_pp::get_max_flow(const edge& e) const
0142 {
0143 return(edge_max_flow[e]);
0144 }
0145
0146
0147 double maxflow_pp::get_max_flow() const
0148 {
0149 return(max_graph_flow);
0150 }
0151
0152
0153 double maxflow_pp::get_rem_cap(const edge& e) const
0154 {
0155 return(edge_capacity[e] - edge_max_flow[e]);
0156 }
0157
0158
0159 void maxflow_pp::reset()
0160 {
0161 }
0162
0163
0164 void maxflow_pp::create_artif_source_target(graph& G)
0165 {
0166 net_source = G.new_node();
0167 net_target = G.new_node();
0168 edge e;
0169 graph::node_iterator node_it = G.nodes_begin();
0170 graph::node_iterator nodes_end = G.nodes_end();
0171 while (node_it != nodes_end)
0172 {
0173 if (*node_it != net_source && (*node_it).indeg() == 0)
0174 {
0175 e = G.new_edge(net_source, *node_it);
0176 edge_capacity[e] = 1.0;
0177 node::out_edges_iterator out_edge_it = (*node_it).out_edges_begin();
0178 node::out_edges_iterator out_edges_end = (*node_it).out_edges_end();
0179 while (out_edge_it != out_edges_end)
0180 {
0181 edge_capacity[e] += edge_capacity[*out_edge_it];
0182 ++out_edge_it;
0183 }
0184 }
0185 if (*node_it != net_target && (*node_it).outdeg() == 0)
0186 {
0187 e = G.new_edge(*node_it, net_target);
0188 edge_capacity[e] = 1.0;
0189 node::in_edges_iterator in_edge_it = (*node_it).in_edges_begin();
0190 node::in_edges_iterator in_edges_end = (*node_it).in_edges_end();
0191 while (in_edge_it != in_edges_end)
0192 {
0193 edge_capacity[e] += edge_capacity[*in_edge_it];
0194 ++in_edge_it;
0195 }
0196 }
0197 ++node_it;
0198 }
0199 }
0200
0201
0202 void maxflow_pp::prepare_run(const graph& G)
0203 {
0204 flow_update.init(G, 0.0);
0205 edge_max_flow.init(G, 0.0);
0206 edge_org.init(G, true);
0207 back_edge_exists.init(G, false);
0208 max_graph_flow = 0.0;
0209 full_edges.clear();
0210 temp_unvisible_nodes.clear();
0211 temp_unvisible_edges.clear();
0212 }
0213
0214
0215 int maxflow_pp::leveling(graph& G)
0216 {
0217 bool source_target_con = false;
0218 node_map<int> level(G, -1);
0219 queue<node> next_nodes;
0220 next_nodes.push(net_source);
0221 level[net_source] = 0;
0222 node cur_node;
0223 while (!next_nodes.empty())
0224 {
0225 cur_node = next_nodes.front();
0226 next_nodes.pop();
0227 node::out_edges_iterator out_edge_it = cur_node.out_edges_begin();
0228 node::out_edges_iterator out_edges_end = cur_node.out_edges_end();
0229 while (out_edge_it != out_edges_end)
0230 {
0231 if (level[(*out_edge_it).target()] == -1)
0232 {
0233 if ((*out_edge_it).target() == net_target)
0234 {
0235 source_target_con = true;
0236 }
0237 level[(*out_edge_it).target()] = level[cur_node] + 1;
0238 next_nodes.push((*out_edge_it).target());
0239 ++out_edge_it;
0240 }
0241 else if (level[(*out_edge_it).target()] <= level[cur_node])
0242 {
0243 node::out_edges_iterator temp_it = out_edge_it;
0244 ++out_edge_it;
0245 temp_unvisible_edges.push_back(*temp_it);
0246 G.hide_edge(*temp_it);
0247 }
0248 else
0249 {
0250 ++out_edge_it;
0251 }
0252 }
0253 }
0254 if (source_target_con)
0255 {
0256 return(TARGET_FROM_SOURCE_REACHABLE);
0257 }
0258 else
0259 {
0260 return(TARGET_FROM_SOURCE_NOT_REACHABLE);
0261 }
0262 }
0263
0264
0265 void maxflow_pp::hide_unreachable_nodes(graph& G)
0266 {
0267 node_map<bool> reachable_from_net_source(G, false);
0268 node_map<bool> reachable_from_net_target(G, false);
0269 queue<node> next_nodes;
0270 node cur_node;
0271
0272 next_nodes.push(net_source);
0273 reachable_from_net_source[net_source] = true;
0274 while (!next_nodes.empty())
0275 {
0276 cur_node = next_nodes.front();
0277 next_nodes.pop();
0278 node::out_edges_iterator out_edge_it = cur_node.out_edges_begin();
0279 node::out_edges_iterator out_edges_end = cur_node.out_edges_end();
0280 while (out_edge_it != out_edges_end)
0281 {
0282 node next = (*out_edge_it).target();
0283 if (!reachable_from_net_source[next])
0284 {
0285 next_nodes.push(next);
0286 reachable_from_net_source[next] = true;
0287 }
0288 ++out_edge_it;
0289 }
0290 }
0291
0292 next_nodes.push(net_target);
0293 reachable_from_net_target[net_target] = true;
0294 while (!next_nodes.empty())
0295 {
0296 cur_node = next_nodes.front();
0297 next_nodes.pop();
0298 node::in_edges_iterator in_edge_it = cur_node.in_edges_begin();
0299 node::in_edges_iterator in_edges_end = cur_node.in_edges_end();
0300 while (in_edge_it != in_edges_end)
0301 {
0302 node next = (*in_edge_it).source();
0303 if (!reachable_from_net_target[next])
0304 {
0305 next_nodes.push(next);
0306 reachable_from_net_target[next] = true;
0307 }
0308 ++in_edge_it;
0309 }
0310 }
0311
0312 graph::node_iterator node_it = G.nodes_begin();
0313 graph::node_iterator nodes_end = G.nodes_end();
0314 while (node_it != nodes_end)
0315 {
0316 if ((!reachable_from_net_source[*node_it]) ||
0317 (!reachable_from_net_target[*node_it]))
0318 {
0319 graph::node_iterator temp_it = node_it;
0320 ++node_it;
0321 temp_unvisible_nodes.push_back(*temp_it);
0322 store_temp_unvisible_edges(*temp_it);
0323 G.hide_node(*temp_it);
0324 }
0325 else
0326 {
0327 ++node_it;
0328 }
0329 }
0330 }
0331
0332
0333 void maxflow_pp::store_temp_unvisible_edges(const node& cur_node)
0334 {
0335 node::in_edges_iterator in_it = cur_node.in_edges_begin();
0336 node::in_edges_iterator in_edges_end = cur_node.in_edges_end();
0337 while (in_it != in_edges_end)
0338 {
0339 temp_unvisible_edges.push_back(*in_it);
0340 ++in_it;
0341 }
0342 node::out_edges_iterator out_it = cur_node.out_edges_begin();
0343 node::out_edges_iterator out_edges_end = cur_node.out_edges_end();
0344 while (out_it != out_edges_end)
0345 {
0346 temp_unvisible_edges.push_back(*out_it);
0347 ++out_it;
0348 }
0349 }
0350
0351
0352 void maxflow_pp::min_throughput_node(const graph& G, node& min_tp_node,
0353 double& flow_value)
0354 {
0355 min_tp_node = net_source;
0356 flow_value = comp_min_throughput(min_tp_node);
0357
0358 graph::node_iterator node_it = G.nodes_begin();
0359 graph::node_iterator nodes_end = G.nodes_end();
0360 double cur_tp;
0361 while (node_it != nodes_end)
0362 {
0363 cur_tp = comp_min_throughput(*node_it);
0364 if (cur_tp < flow_value)
0365 {
0366 min_tp_node = *node_it;
0367 flow_value = cur_tp;
0368 }
0369 ++node_it;
0370 }
0371 }
0372
0373
0374 double maxflow_pp::comp_min_throughput(const node cur_node) const
0375 {
0376 double in_flow = 0.0;
0377 double out_flow = 0.0;
0378 node::in_edges_iterator in_it = cur_node.in_edges_begin();
0379 node::in_edges_iterator in_edges_end = cur_node.in_edges_end();
0380 while (in_it != in_edges_end)
0381 {
0382 in_flow += edge_capacity[*in_it] - edge_max_flow[*in_it];
0383 ++in_it;
0384 }
0385 node::out_edges_iterator out_it = cur_node.out_edges_begin();
0386 node::out_edges_iterator out_edges_end = cur_node.out_edges_end();
0387 while (out_it != out_edges_end)
0388 {
0389 out_flow += edge_capacity[*out_it] - edge_max_flow[*out_it];
0390 ++out_it;
0391 }
0392 if (cur_node == net_source)
0393 {
0394 return(out_flow);
0395 }
0396 if (cur_node == net_target)
0397 {
0398 return(in_flow);
0399 }
0400 return(in_flow < out_flow ? in_flow : out_flow);
0401 }
0402
0403
0404 void maxflow_pp::get_sp_ahead(const graph& G, const node& start_node,
0405 node_map<edge>& last_edge)
0406 {
0407 queue<node> next_nodes;
0408 node_map<bool> visited(G, false);
0409 next_nodes.push(start_node);
0410 visited[start_node] = true;
0411
0412 node cur_node;
0413 while (!next_nodes.empty())
0414 {
0415 cur_node = next_nodes.front();
0416 next_nodes.pop();
0417
0418 node::out_edges_iterator out_edge_it = cur_node.out_edges_begin();
0419 node::out_edges_iterator out_edges_end = cur_node.out_edges_end();
0420 while (out_edge_it != out_edges_end)
0421 {
0422 node next = (*out_edge_it).target();
0423 if (!visited[next])
0424 {
0425 last_edge[next] = *out_edge_it;
0426 if (next == net_target)
0427 {
0428 return;
0429 }
0430 next_nodes.push(next);
0431 visited[next] = true;
0432 }
0433 ++out_edge_it;
0434 }
0435 }
0436 }
0437
0438
0439 void maxflow_pp::get_sp_backwards(const graph& G, const node& start_node,
0440 node_map<edge>& prev_edge)
0441 {
0442 queue<node> next_nodes;
0443 node_map<bool> visited(G, false);
0444 next_nodes.push(start_node);
0445 visited[start_node] = true;
0446
0447 node cur_node;
0448 while (!next_nodes.empty())
0449 {
0450 cur_node = next_nodes.front();
0451 next_nodes.pop();
0452
0453 node::in_edges_iterator in_edge_it = cur_node.in_edges_begin();
0454 node::in_edges_iterator in_edges_end = cur_node.in_edges_end();
0455 while (in_edge_it != in_edges_end)
0456 {
0457 node next = (*in_edge_it).source();
0458 if (!visited[next])
0459 {
0460 prev_edge[next] = *in_edge_it;
0461 if (next == net_source)
0462 {
0463 return;
0464 }
0465 next_nodes.push(next);
0466 visited[next] = true;
0467 }
0468 ++in_edge_it;
0469 }
0470 }
0471 }
0472
0473
0474 void maxflow_pp::push(graph& G, const node& start_node, const double flow_value)
0475 {
0476 node_map<edge> last_edge;
0477 double cur_flow = flow_value;
0478 double min_value = 0.0;
0479
0480 if (start_node == net_target)
0481 {
0482 return;
0483 }
0484 do
0485 {
0486 get_sp_ahead(G, start_node, last_edge);
0487 min_value = extra_charge_ahead(start_node, last_edge);
0488 if (min_value > cur_flow)
0489 {
0490 min_value = cur_flow;
0491 }
0492 node cur_node = net_target;
0493 do
0494 {
0495 if (edge_org[last_edge[cur_node]])
0496 {
0497 edge_max_flow[last_edge[cur_node]] += min_value;
0498 if (back_edge_exists[last_edge[cur_node]])
0499 {
0500 flow_update[back_edge[last_edge[cur_node]]] += min_value;
0501 }
0502 }
0503 else
0504 {
0505 edge_capacity[last_edge[cur_node]] -= min_value;
0506 flow_update[back_edge[last_edge[cur_node]]] += min_value;
0507 }
0508 if (edge_capacity[last_edge[cur_node]] <=
0509 edge_max_flow[last_edge[cur_node]])
0510 {
0511 full_edges.push_back(last_edge[cur_node]);
0512 G.hide_edge(last_edge[cur_node]);
0513 }
0514 cur_node = last_edge[cur_node].source();
0515 }
0516 while (cur_node != start_node);
0517 cur_flow -= min_value;
0518 if (cur_flow < 1e-015)
0519 {
0520 cur_flow = 0.0;
0521 }
0522 } while (cur_flow > 0.0);
0523 }
0524
0525
0526 void maxflow_pp::pull(graph& G, const node& start_node, const double flow_value)
0527 {
0528 node_map<edge> prev_edge;
0529 double cur_flow = flow_value;
0530 double min_value = 0.0;
0531
0532 if (start_node == net_source)
0533 {
0534 return;
0535 }
0536 do
0537 {
0538 get_sp_backwards(G, start_node, prev_edge);
0539 min_value = extra_charge_backwards(start_node, prev_edge);
0540 if (min_value > cur_flow)
0541 {
0542 min_value = cur_flow;
0543 }
0544 node cur_node = net_source;
0545 do
0546 {
0547 if (edge_org[prev_edge[cur_node]])
0548 {
0549 edge_max_flow[prev_edge[cur_node]] += min_value;
0550 if (back_edge_exists[prev_edge[cur_node]])
0551 {
0552 flow_update[back_edge[prev_edge[cur_node]]] += min_value;
0553 }
0554 }
0555 else
0556 {
0557 edge_capacity[prev_edge[cur_node]] -= min_value;
0558 flow_update[back_edge[prev_edge[cur_node]]] += min_value;
0559 }
0560 if (edge_capacity[prev_edge[cur_node]] <=
0561 edge_max_flow[prev_edge[cur_node]])
0562 {
0563 full_edges.push_back(prev_edge[cur_node]);
0564 G.hide_edge(prev_edge[cur_node]);
0565 }
0566 cur_node = prev_edge[cur_node].target();
0567 }
0568 while (cur_node != start_node);
0569 cur_flow -= min_value;
0570 if (cur_flow < 1e-015)
0571 {
0572 cur_flow = 0.0;
0573 }
0574 } while (cur_flow > 0.0);
0575 }
0576
0577
0578 void maxflow_pp::comp_rem_net(graph& G)
0579 {
0580
0581 graph::edge_iterator edge_it = G.edges_begin();
0582 graph::edge_iterator edges_end = G.edges_end();
0583 while (edge_it != edges_end)
0584 {
0585 single_edge_update(G, *edge_it);
0586 ++edge_it;
0587 }
0588 list<edge>::iterator list_it = full_edges.begin();
0589 list<edge>::iterator list_end = full_edges.end();
0590 while (list_it != list_end)
0591 {
0592 G.restore_edge(*list_it);
0593 if (flow_update[*list_it] > 0.0)
0594 {
0595 single_edge_update(G, *list_it);
0596 list<edge>::iterator temp_it = list_it;
0597 ++list_it;
0598 full_edges.erase(temp_it);
0599 }
0600 else
0601 {
0602 if (!back_edge_exists[*list_it])
0603 {
0604 create_back_edge(G, *list_it);
0605 edge_capacity[back_edge[*list_it]] = edge_max_flow[*list_it];
0606 }
0607 G.hide_edge(*list_it);
0608 ++list_it;
0609 }
0610 }
0611
0612
0613
0614 list<node>::iterator temp_un_node_it = temp_unvisible_nodes.begin();
0615 list<node>::iterator temp_un_nodes_end = temp_unvisible_nodes.end();
0616 while (temp_un_node_it != temp_un_nodes_end)
0617 {
0618 G.restore_node(*temp_un_node_it);
0619 ++temp_un_node_it;
0620 }
0621 list<edge>::iterator temp_un_edge_it = temp_unvisible_edges.begin();
0622 list<edge>::iterator temp_un_edges_end = temp_unvisible_edges.end();
0623 while (temp_un_edge_it != temp_un_edges_end)
0624 {
0625 G.restore_edge(*temp_un_edge_it);
0626 if (flow_update[*temp_un_edge_it] > 0.0)
0627 {
0628 single_edge_update(G, *temp_un_edge_it);
0629 }
0630 ++temp_un_edge_it;
0631 }
0632 temp_unvisible_nodes.clear();
0633 temp_unvisible_edges.clear();
0634 }
0635
0636
0637 void maxflow_pp::single_edge_update(graph& G, edge cur_edge)
0638 {
0639 if(edge_org[cur_edge])
0640 {
0641 edge_max_flow[cur_edge] -= flow_update[cur_edge];
0642 flow_update[cur_edge] = 0.0;
0643 if (!back_edge_exists[cur_edge])
0644 {
0645 if (edge_max_flow[cur_edge] > 0.0)
0646 {
0647 create_back_edge(G, cur_edge);
0648 edge_capacity[back_edge[cur_edge]] = edge_max_flow[cur_edge];
0649 }
0650 }
0651 }
0652 else
0653 {
0654 edge_capacity[cur_edge] += flow_update[cur_edge];
0655 flow_update[cur_edge] = 0.0;
0656 }
0657 }
0658
0659
0660 double maxflow_pp::extra_charge_ahead(const node& start_node,
0661 const node_map<edge>& last_edge) const
0662 {
0663 node cur_node = net_target;
0664 double min_value = edge_capacity[last_edge[cur_node]]
0665 - edge_max_flow[last_edge[cur_node]];
0666 double cur_capacity;
0667
0668 do
0669 {
0670 cur_capacity = edge_capacity[last_edge[cur_node]]
0671 - edge_max_flow[last_edge[cur_node]];
0672 if (cur_capacity < min_value) min_value = cur_capacity;
0673 cur_node = last_edge[cur_node].source();
0674 }
0675 while (cur_node != start_node);
0676 return(min_value);
0677 }
0678
0679
0680 double maxflow_pp::extra_charge_backwards(const node& start_node, const node_map<edge>& prev_edge) const
0681 {
0682 node cur_node = net_source;
0683 double min_value = edge_capacity[prev_edge[cur_node]]
0684 - edge_max_flow[prev_edge[cur_node]];
0685 double cur_capacity;
0686
0687 do
0688 {
0689 cur_capacity = edge_capacity[prev_edge[cur_node]]
0690 - edge_max_flow[prev_edge[cur_node]];
0691 if (cur_capacity < min_value) min_value = cur_capacity;
0692 cur_node = prev_edge[cur_node].target();
0693 }
0694 while (cur_node != start_node);
0695 return(min_value);
0696 }
0697
0698
0699 void maxflow_pp::create_back_edge(graph& G, const edge& org_edge)
0700 {
0701 edge be = G.new_edge(org_edge.target(), org_edge.source());
0702 edge_org[be] = false;
0703 edges_not_org.push_back(be);
0704 back_edge[org_edge] = be;
0705 back_edge[be] = org_edge;
0706 edge_max_flow[be] = 0.0;
0707 edge_capacity[be] = 0.0;
0708 back_edge_exists[org_edge] = true;
0709 back_edge_exists[be] = true;
0710 flow_update[be] = 0.0;
0711 }
0712
0713
0714 void maxflow_pp::comp_max_flow(const graph& G)
0715 {
0716 max_graph_flow = 0.0;
0717
0718 node::out_edges_iterator out_edge_it = net_source.out_edges_begin();
0719 node::out_edges_iterator out_edges_end = net_source.out_edges_end();
0720 while (out_edge_it != out_edges_end)
0721 {
0722 max_graph_flow += edge_max_flow[*out_edge_it];
0723 ++out_edge_it;
0724 }
0725 }
0726
0727
0728 void maxflow_pp::restore_graph(graph& G)
0729 {
0730 G.restore_graph();
0731 while (!edges_not_org.empty())
0732 {
0733 G.del_edge(edges_not_org.front());
0734 edges_not_org.pop_front();
0735 }
0736 comp_max_flow(G);
0737 if (artif_source_target)
0738 {
0739 G.del_node(net_source);
0740 G.del_node(net_target);
0741 }
0742 }
0743
0744 __GTL_END_NAMESPACE
0745
0746
0747
0748