|
1 /* -*- C++ -*- |
|
2 * |
|
3 * This file is a part of LEMON, a generic C++ optimization library |
|
4 * |
|
5 * Copyright (C) 2003-2007 |
|
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
|
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
|
8 * |
|
9 * Permission to use, modify and distribute this software is granted |
|
10 * provided that this copyright notice appears in all copies. For |
|
11 * precise terms see the accompanying LICENSE file. |
|
12 * |
|
13 * This software is provided "AS IS" with no warranty of any kind, |
|
14 * express or implied, and with no claim as to its suitability for any |
|
15 * purpose. |
|
16 * |
|
17 */ |
|
18 |
|
19 #ifndef LEMON_NETWORK_SIMPLEX_H |
|
20 #define LEMON_NETWORK_SIMPLEX_H |
|
21 |
|
22 /// \ingroup min_cost_flow |
|
23 /// |
|
24 /// \file |
|
25 /// \brief The network simplex algorithm for finding a minimum cost |
|
26 /// flow. |
|
27 |
|
28 #include <limits> |
|
29 #include <lemon/smart_graph.h> |
|
30 #include <lemon/graph_utils.h> |
|
31 |
|
32 /// \brief The pivot rule used in the algorithm. |
|
33 #define EDGE_BLOCK_PIVOT |
|
34 //#define FIRST_ELIGIBLE_PIVOT |
|
35 //#define BEST_ELIGIBLE_PIVOT |
|
36 //#define CANDIDATE_LIST_PIVOT |
|
37 //#define SORTED_LIST_PIVOT |
|
38 |
|
39 /// \brief State constant for edges at their lower bounds. |
|
40 #define LOWER 1 |
|
41 /// \brief State constant for edges in the spanning tree. |
|
42 #define TREE 0 |
|
43 /// \brief State constant for edges at their upper bounds. |
|
44 #define UPPER -1 |
|
45 |
|
46 #ifdef EDGE_BLOCK_PIVOT |
|
47 /// \brief Number of blocks for the "Edge Block" pivot rule. |
|
48 #define BLOCK_NUM 100 |
|
49 /// \brief Lower bound for the number of edges to use "Edge Block" |
|
50 // pivot rule instead of "First Eligible" pivot rule. |
|
51 #define MIN_BOUND 1000 |
|
52 #endif |
|
53 |
|
54 #ifdef CANDIDATE_LIST_PIVOT |
|
55 #include <list> |
|
56 /// \brief The maximum length of the edge list for the |
|
57 /// "Candidate List" pivot rule. |
|
58 #define LIST_LENGTH 100 |
|
59 /// \brief The maximum number of minor iterations between two major |
|
60 /// itarations. |
|
61 #define MINOR_LIMIT 50 |
|
62 #endif |
|
63 |
|
64 #ifdef SORTED_LIST_PIVOT |
|
65 #include <deque> |
|
66 #include <algorithm> |
|
67 /// \brief The maximum length of the edge list for the |
|
68 /// "Sorted List" pivot rule. |
|
69 #define LIST_LENGTH 500 |
|
70 #define LOWER_DIV 4 |
|
71 #endif |
|
72 |
|
73 //#define _DEBUG_ITER_ |
|
74 |
|
75 namespace lemon { |
|
76 |
|
77 /// \addtogroup min_cost_flow |
|
78 /// @{ |
|
79 |
|
80 /// \brief Implementation of the network simplex algorithm for |
|
81 /// finding a minimum cost flow. |
|
82 /// |
|
83 /// \ref lemon::NetworkSimplex "NetworkSimplex" implements the |
|
84 /// network simplex algorithm for finding a minimum cost flow. |
|
85 /// |
|
86 /// \param Graph The directed graph type the algorithm runs on. |
|
87 /// \param LowerMap The type of the lower bound map. |
|
88 /// \param CapacityMap The type of the capacity (upper bound) map. |
|
89 /// \param CostMap The type of the cost (length) map. |
|
90 /// \param SupplyMap The type of the supply map. |
|
91 /// |
|
92 /// \warning |
|
93 /// - Edge capacities and costs should be nonnegative integers. |
|
94 /// However \c CostMap::Value should be signed type. |
|
95 /// - Supply values should be integers. |
|
96 /// - \c LowerMap::Value must be convertible to |
|
97 /// \c CapacityMap::Value and \c CapacityMap::Value must be |
|
98 /// convertible to \c SupplyMap::Value. |
|
99 /// |
|
100 /// \author Peter Kovacs |
|
101 |
|
102 template < typename Graph, |
|
103 typename LowerMap = typename Graph::template EdgeMap<int>, |
|
104 typename CapacityMap = LowerMap, |
|
105 typename CostMap = typename Graph::template EdgeMap<int>, |
|
106 typename SupplyMap = typename Graph::template NodeMap |
|
107 <typename CapacityMap::Value> > |
|
108 class NetworkSimplex |
|
109 { |
|
110 typedef typename LowerMap::Value Lower; |
|
111 typedef typename CapacityMap::Value Capacity; |
|
112 typedef typename CostMap::Value Cost; |
|
113 typedef typename SupplyMap::Value Supply; |
|
114 |
|
115 typedef SmartGraph SGraph; |
|
116 typedef typename SGraph::Node Node; |
|
117 typedef typename SGraph::NodeIt NodeIt; |
|
118 typedef typename SGraph::Edge Edge; |
|
119 typedef typename SGraph::EdgeIt EdgeIt; |
|
120 typedef typename SGraph::InEdgeIt InEdgeIt; |
|
121 typedef typename SGraph::OutEdgeIt OutEdgeIt; |
|
122 |
|
123 typedef typename SGraph::template EdgeMap<Lower> SLowerMap; |
|
124 typedef typename SGraph::template EdgeMap<Capacity> SCapacityMap; |
|
125 typedef typename SGraph::template EdgeMap<Cost> SCostMap; |
|
126 typedef typename SGraph::template NodeMap<Supply> SSupplyMap; |
|
127 typedef typename SGraph::template NodeMap<Cost> SPotentialMap; |
|
128 |
|
129 typedef typename SGraph::template NodeMap<int> IntNodeMap; |
|
130 typedef typename SGraph::template NodeMap<bool> BoolNodeMap; |
|
131 typedef typename SGraph::template NodeMap<Node> NodeNodeMap; |
|
132 typedef typename SGraph::template NodeMap<Edge> EdgeNodeMap; |
|
133 typedef typename SGraph::template EdgeMap<int> IntEdgeMap; |
|
134 |
|
135 typedef typename Graph::template NodeMap<Node> NodeRefMap; |
|
136 typedef typename Graph::template EdgeMap<Edge> EdgeRefMap; |
|
137 |
|
138 public: |
|
139 |
|
140 /// \brief The type of the flow map. |
|
141 typedef typename Graph::template EdgeMap<Capacity> FlowMap; |
|
142 /// \brief The type of the potential map. |
|
143 typedef typename Graph::template NodeMap<Cost> PotentialMap; |
|
144 |
|
145 protected: |
|
146 |
|
147 /// \brief Map adaptor class for handling reduced edge costs. |
|
148 class ReducedCostMap : public MapBase<Edge, Cost> |
|
149 { |
|
150 private: |
|
151 |
|
152 const SGraph &gr; |
|
153 const SCostMap &cost_map; |
|
154 const SPotentialMap &pot_map; |
|
155 |
|
156 public: |
|
157 |
|
158 typedef typename MapBase<Edge, Cost>::Value Value; |
|
159 typedef typename MapBase<Edge, Cost>::Key Key; |
|
160 |
|
161 ReducedCostMap( const SGraph &_gr, |
|
162 const SCostMap &_cm, |
|
163 const SPotentialMap &_pm ) : |
|
164 gr(_gr), cost_map(_cm), pot_map(_pm) {} |
|
165 |
|
166 Value operator[](const Key &e) const { |
|
167 return cost_map[e] - pot_map[gr.source(e)] + pot_map[gr.target(e)]; |
|
168 } |
|
169 |
|
170 }; //class ReducedCostMap |
|
171 |
|
172 protected: |
|
173 |
|
174 /// \brief The directed graph the algorithm runs on. |
|
175 SGraph graph; |
|
176 /// \brief The original graph. |
|
177 const Graph &graph_ref; |
|
178 /// \brief The original lower bound map. |
|
179 const LowerMap *lower; |
|
180 /// \brief The capacity map. |
|
181 SCapacityMap capacity; |
|
182 /// \brief The cost map. |
|
183 SCostMap cost; |
|
184 /// \brief The supply map. |
|
185 SSupplyMap supply; |
|
186 /// \brief The reduced cost map. |
|
187 ReducedCostMap red_cost; |
|
188 /// \brief The sum of supply values equals zero. |
|
189 bool valid_supply; |
|
190 |
|
191 /// \brief The edge map of the current flow. |
|
192 SCapacityMap flow; |
|
193 /// \brief The edge map of the found flow on the original graph. |
|
194 FlowMap flow_result; |
|
195 /// \brief The potential node map. |
|
196 SPotentialMap potential; |
|
197 /// \brief The potential node map on the original graph. |
|
198 PotentialMap potential_result; |
|
199 |
|
200 /// \brief Node reference for the original graph. |
|
201 NodeRefMap node_ref; |
|
202 /// \brief Edge reference for the original graph. |
|
203 EdgeRefMap edge_ref; |
|
204 |
|
205 /// \brief The depth node map of the spanning tree structure. |
|
206 IntNodeMap depth; |
|
207 /// \brief The parent node map of the spanning tree structure. |
|
208 NodeNodeMap parent; |
|
209 /// \brief The pred_edge node map of the spanning tree structure. |
|
210 EdgeNodeMap pred_edge; |
|
211 /// \brief The thread node map of the spanning tree structure. |
|
212 NodeNodeMap thread; |
|
213 /// \brief The forward node map of the spanning tree structure. |
|
214 BoolNodeMap forward; |
|
215 /// \brief The state edge map. |
|
216 IntEdgeMap state; |
|
217 |
|
218 |
|
219 #ifdef EDGE_BLOCK_PIVOT |
|
220 /// \brief The size of blocks for the "Edge Block" pivot rule. |
|
221 int block_size; |
|
222 #endif |
|
223 #ifdef CANDIDATE_LIST_PIVOT |
|
224 /// \brief The list of candidate edges for the "Candidate List" |
|
225 /// pivot rule. |
|
226 std::list<Edge> candidates; |
|
227 /// \brief The number of minor iterations. |
|
228 int minor_count; |
|
229 #endif |
|
230 #ifdef SORTED_LIST_PIVOT |
|
231 /// \brief The list of candidate edges for the "Sorted List" |
|
232 /// pivot rule. |
|
233 std::deque<Edge> candidates; |
|
234 #endif |
|
235 |
|
236 // Root node of the starting spanning tree. |
|
237 Node root; |
|
238 // The entering edge of the current pivot iteration. |
|
239 Edge in_edge; |
|
240 // Temporary nodes used in the current pivot iteration. |
|
241 Node join, u_in, v_in, u_out, v_out; |
|
242 Node right, first, second, last; |
|
243 Node stem, par_stem, new_stem; |
|
244 // The maximum augment amount along the cycle in the current pivot |
|
245 // iteration. |
|
246 Capacity delta; |
|
247 |
|
248 public : |
|
249 |
|
250 /// \brief General constructor of the class (with lower bounds). |
|
251 /// |
|
252 /// General constructor of the class (with lower bounds). |
|
253 /// |
|
254 /// \param _graph The directed graph the algorithm runs on. |
|
255 /// \param _lower The lower bounds of the edges. |
|
256 /// \param _capacity The capacities (upper bounds) of the edges. |
|
257 /// \param _cost The cost (length) values of the edges. |
|
258 /// \param _supply The supply values of the nodes (signed). |
|
259 NetworkSimplex( const Graph &_graph, |
|
260 const LowerMap &_lower, |
|
261 const CapacityMap &_capacity, |
|
262 const CostMap &_cost, |
|
263 const SupplyMap &_supply ) : |
|
264 graph_ref(_graph), lower(&_lower), capacity(graph), cost(graph), |
|
265 supply(graph), flow(graph), flow_result(_graph), potential(graph), |
|
266 potential_result(_graph), depth(graph), parent(graph), |
|
267 pred_edge(graph), thread(graph), forward(graph), state(graph), |
|
268 node_ref(graph_ref), edge_ref(graph_ref), |
|
269 red_cost(graph, cost, potential) |
|
270 { |
|
271 // Checking the sum of supply values |
|
272 Supply sum = 0; |
|
273 for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n) |
|
274 sum += _supply[n]; |
|
275 if (!(valid_supply = sum == 0)) return; |
|
276 |
|
277 // Copying graph_ref to graph |
|
278 copyGraph(graph, graph_ref) |
|
279 .edgeMap(cost, _cost) |
|
280 .nodeRef(node_ref) |
|
281 .edgeRef(edge_ref) |
|
282 .run(); |
|
283 |
|
284 // Removing nonzero lower bounds |
|
285 for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e) { |
|
286 capacity[edge_ref[e]] = _capacity[e] - _lower[e]; |
|
287 } |
|
288 for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n) { |
|
289 Supply s = _supply[n]; |
|
290 for (typename Graph::InEdgeIt e(graph_ref, n); e != INVALID; ++e) |
|
291 s += _lower[e]; |
|
292 for (typename Graph::OutEdgeIt e(graph_ref, n); e != INVALID; ++e) |
|
293 s -= _lower[e]; |
|
294 supply[node_ref[n]] = s; |
|
295 } |
|
296 } |
|
297 |
|
298 /// \brief General constructor of the class (without lower bounds). |
|
299 /// |
|
300 /// General constructor of the class (without lower bounds). |
|
301 /// |
|
302 /// \param _graph The directed graph the algorithm runs on. |
|
303 /// \param _capacity The capacities (upper bounds) of the edges. |
|
304 /// \param _cost The cost (length) values of the edges. |
|
305 /// \param _supply The supply values of the nodes (signed). |
|
306 NetworkSimplex( const Graph &_graph, |
|
307 const CapacityMap &_capacity, |
|
308 const CostMap &_cost, |
|
309 const SupplyMap &_supply ) : |
|
310 graph_ref(_graph), lower(NULL), capacity(graph), cost(graph), |
|
311 supply(graph), flow(graph), flow_result(_graph), potential(graph), |
|
312 potential_result(_graph), depth(graph), parent(graph), |
|
313 pred_edge(graph), thread(graph), forward(graph), state(graph), |
|
314 node_ref(graph_ref), edge_ref(graph_ref), |
|
315 red_cost(graph, cost, potential) |
|
316 { |
|
317 // Checking the sum of supply values |
|
318 Supply sum = 0; |
|
319 for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n) |
|
320 sum += _supply[n]; |
|
321 if (!(valid_supply = sum == 0)) return; |
|
322 |
|
323 // Copying graph_ref to graph |
|
324 copyGraph(graph, graph_ref) |
|
325 .edgeMap(capacity, _capacity) |
|
326 .edgeMap(cost, _cost) |
|
327 .nodeMap(supply, _supply) |
|
328 .nodeRef(node_ref) |
|
329 .edgeRef(edge_ref) |
|
330 .run(); |
|
331 } |
|
332 |
|
333 /// \brief Simple constructor of the class (with lower bounds). |
|
334 /// |
|
335 /// Simple constructor of the class (with lower bounds). |
|
336 /// |
|
337 /// \param _graph The directed graph the algorithm runs on. |
|
338 /// \param _lower The lower bounds of the edges. |
|
339 /// \param _capacity The capacities (upper bounds) of the edges. |
|
340 /// \param _cost The cost (length) values of the edges. |
|
341 /// \param _s The source node. |
|
342 /// \param _t The target node. |
|
343 /// \param _flow_value The required amount of flow from node \c _s |
|
344 /// to node \c _t (i.e. the supply of \c _s and the demand of |
|
345 /// \c _t). |
|
346 NetworkSimplex( const Graph &_graph, |
|
347 const LowerMap &_lower, |
|
348 const CapacityMap &_capacity, |
|
349 const CostMap &_cost, |
|
350 typename Graph::Node _s, |
|
351 typename Graph::Node _t, |
|
352 typename SupplyMap::Value _flow_value ) : |
|
353 graph_ref(_graph), lower(&_lower), capacity(graph), cost(graph), |
|
354 supply(graph), flow(graph), flow_result(_graph), potential(graph), |
|
355 potential_result(_graph), depth(graph), parent(graph), |
|
356 pred_edge(graph), thread(graph), forward(graph), state(graph), |
|
357 node_ref(graph_ref), edge_ref(graph_ref), |
|
358 red_cost(graph, cost, potential) |
|
359 { |
|
360 // Copying graph_ref to graph |
|
361 copyGraph(graph, graph_ref) |
|
362 .edgeMap(cost, _cost) |
|
363 .nodeRef(node_ref) |
|
364 .edgeRef(edge_ref) |
|
365 .run(); |
|
366 |
|
367 // Removing nonzero lower bounds |
|
368 for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e) { |
|
369 capacity[edge_ref[e]] = _capacity[e] - _lower[e]; |
|
370 } |
|
371 for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n) { |
|
372 Supply s = 0; |
|
373 if (n == _s) s = _flow_value; |
|
374 if (n == _t) s = -_flow_value; |
|
375 for (typename Graph::InEdgeIt e(graph_ref, n); e != INVALID; ++e) |
|
376 s += _lower[e]; |
|
377 for (typename Graph::OutEdgeIt e(graph_ref, n); e != INVALID; ++e) |
|
378 s -= _lower[e]; |
|
379 supply[node_ref[n]] = s; |
|
380 } |
|
381 valid_supply = true; |
|
382 } |
|
383 |
|
384 /// \brief Simple constructor of the class (without lower bounds). |
|
385 /// |
|
386 /// Simple constructor of the class (without lower bounds). |
|
387 /// |
|
388 /// \param _graph The directed graph the algorithm runs on. |
|
389 /// \param _capacity The capacities (upper bounds) of the edges. |
|
390 /// \param _cost The cost (length) values of the edges. |
|
391 /// \param _s The source node. |
|
392 /// \param _t The target node. |
|
393 /// \param _flow_value The required amount of flow from node \c _s |
|
394 /// to node \c _t (i.e. the supply of \c _s and the demand of |
|
395 /// \c _t). |
|
396 NetworkSimplex( const Graph &_graph, |
|
397 const CapacityMap &_capacity, |
|
398 const CostMap &_cost, |
|
399 typename Graph::Node _s, |
|
400 typename Graph::Node _t, |
|
401 typename SupplyMap::Value _flow_value ) : |
|
402 graph_ref(_graph), lower(NULL), capacity(graph), cost(graph), |
|
403 supply(graph, 0), flow(graph), flow_result(_graph), potential(graph), |
|
404 potential_result(_graph), depth(graph), parent(graph), |
|
405 pred_edge(graph), thread(graph), forward(graph), state(graph), |
|
406 node_ref(graph_ref), edge_ref(graph_ref), |
|
407 red_cost(graph, cost, potential) |
|
408 { |
|
409 // Copying graph_ref to graph |
|
410 copyGraph(graph, graph_ref) |
|
411 .edgeMap(capacity, _capacity) |
|
412 .edgeMap(cost, _cost) |
|
413 .nodeRef(node_ref) |
|
414 .edgeRef(edge_ref) |
|
415 .run(); |
|
416 supply[node_ref[_s]] = _flow_value; |
|
417 supply[node_ref[_t]] = -_flow_value; |
|
418 valid_supply = true; |
|
419 } |
|
420 |
|
421 /// \brief Returns a const reference to the flow map. |
|
422 /// |
|
423 /// Returns a const reference to the flow map. |
|
424 /// |
|
425 /// \pre \ref run() must be called before using this function. |
|
426 const FlowMap& flowMap() const { |
|
427 return flow_result; |
|
428 } |
|
429 |
|
430 /// \brief Returns a const reference to the potential map (the dual |
|
431 /// solution). |
|
432 /// |
|
433 /// Returns a const reference to the potential map (the dual |
|
434 /// solution). |
|
435 /// |
|
436 /// \pre \ref run() must be called before using this function. |
|
437 const PotentialMap& potentialMap() const { |
|
438 return potential_result; |
|
439 } |
|
440 |
|
441 /// \brief Returns the total cost of the found flow. |
|
442 /// |
|
443 /// Returns the total cost of the found flow. The complexity of the |
|
444 /// function is \f$ O(e) \f$. |
|
445 /// |
|
446 /// \pre \ref run() must be called before using this function. |
|
447 Cost totalCost() const { |
|
448 Cost c = 0; |
|
449 for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e) |
|
450 c += flow_result[e] * cost[edge_ref[e]]; |
|
451 return c; |
|
452 } |
|
453 |
|
454 /// \brief Runs the algorithm. |
|
455 /// |
|
456 /// Runs the algorithm. |
|
457 /// |
|
458 /// \return \c true if a feasible flow can be found. |
|
459 bool run() { |
|
460 return init() && start(); |
|
461 } |
|
462 |
|
463 protected: |
|
464 |
|
465 /// \brief Extends the underlaying graph and initializes all the |
|
466 /// node and edge maps. |
|
467 bool init() { |
|
468 if (!valid_supply) return false; |
|
469 |
|
470 // Initializing state and flow maps |
|
471 for (EdgeIt e(graph); e != INVALID; ++e) { |
|
472 flow[e] = 0; |
|
473 state[e] = LOWER; |
|
474 } |
|
475 |
|
476 // Adding an artificial root node to the graph |
|
477 root = graph.addNode(); |
|
478 parent[root] = INVALID; |
|
479 pred_edge[root] = INVALID; |
|
480 depth[root] = supply[root] = potential[root] = 0; |
|
481 |
|
482 // Adding artificial edges to the graph and initializing the node |
|
483 // maps of the spanning tree data structure |
|
484 Supply sum = 0; |
|
485 Node last = root; |
|
486 Edge e; |
|
487 Cost max_cost = std::numeric_limits<Cost>::max() / 4; |
|
488 for (NodeIt u(graph); u != INVALID; ++u) { |
|
489 if (u == root) continue; |
|
490 thread[last] = u; |
|
491 last = u; |
|
492 parent[u] = root; |
|
493 depth[u] = 1; |
|
494 sum += supply[u]; |
|
495 if (supply[u] >= 0) { |
|
496 e = graph.addEdge(u, root); |
|
497 flow[e] = supply[u]; |
|
498 forward[u] = true; |
|
499 potential[u] = max_cost; |
|
500 } else { |
|
501 e = graph.addEdge(root, u); |
|
502 flow[e] = -supply[u]; |
|
503 forward[u] = false; |
|
504 potential[u] = -max_cost; |
|
505 } |
|
506 cost[e] = max_cost; |
|
507 capacity[e] = std::numeric_limits<Capacity>::max(); |
|
508 state[e] = TREE; |
|
509 pred_edge[u] = e; |
|
510 } |
|
511 thread[last] = root; |
|
512 |
|
513 #ifdef EDGE_BLOCK_PIVOT |
|
514 // Initializing block_size for the edge block pivot rule |
|
515 int edge_num = countEdges(graph); |
|
516 block_size = edge_num > MIN_BOUND ? edge_num / BLOCK_NUM + 1 : 1; |
|
517 #endif |
|
518 #ifdef CANDIDATE_LIST_PIVOT |
|
519 minor_count = 0; |
|
520 #endif |
|
521 |
|
522 return sum == 0; |
|
523 } |
|
524 |
|
525 #ifdef FIRST_ELIGIBLE_PIVOT |
|
526 /// \brief Finds entering edge according to the "First Eligible" |
|
527 /// pivot rule. |
|
528 bool findEnteringEdge(EdgeIt &next_edge) { |
|
529 for (EdgeIt e = next_edge; e != INVALID; ++e) { |
|
530 if (state[e] * red_cost[e] < 0) { |
|
531 in_edge = e; |
|
532 next_edge = ++e; |
|
533 return true; |
|
534 } |
|
535 } |
|
536 for (EdgeIt e(graph); e != next_edge; ++e) { |
|
537 if (state[e] * red_cost[e] < 0) { |
|
538 in_edge = e; |
|
539 next_edge = ++e; |
|
540 return true; |
|
541 } |
|
542 } |
|
543 return false; |
|
544 } |
|
545 #endif |
|
546 |
|
547 #ifdef BEST_ELIGIBLE_PIVOT |
|
548 /// \brief Finds entering edge according to the "Best Eligible" |
|
549 /// pivot rule. |
|
550 bool findEnteringEdge() { |
|
551 Cost min = 0; |
|
552 for (EdgeIt e(graph); e != INVALID; ++e) { |
|
553 if (state[e] * red_cost[e] < min) { |
|
554 min = state[e] * red_cost[e]; |
|
555 in_edge = e; |
|
556 } |
|
557 } |
|
558 return min < 0; |
|
559 } |
|
560 #endif |
|
561 |
|
562 #ifdef EDGE_BLOCK_PIVOT |
|
563 /// \brief Finds entering edge according to the "Edge Block" |
|
564 /// pivot rule. |
|
565 bool findEnteringEdge(EdgeIt &next_edge) { |
|
566 if (block_size == 1) { |
|
567 // Performing first eligible selection |
|
568 for (EdgeIt e = next_edge; e != INVALID; ++e) { |
|
569 if (state[e] * red_cost[e] < 0) { |
|
570 in_edge = e; |
|
571 next_edge = ++e; |
|
572 return true; |
|
573 } |
|
574 } |
|
575 for (EdgeIt e(graph); e != next_edge; ++e) { |
|
576 if (state[e] * red_cost[e] < 0) { |
|
577 in_edge = e; |
|
578 next_edge = ++e; |
|
579 return true; |
|
580 } |
|
581 } |
|
582 return false; |
|
583 } else { |
|
584 // Performing edge block selection |
|
585 Cost curr, min = 0; |
|
586 EdgeIt min_edge(graph); |
|
587 int cnt = 0; |
|
588 for (EdgeIt e = next_edge; e != INVALID; ++e) { |
|
589 if ((curr = state[e] * red_cost[e]) < min) { |
|
590 min = curr; |
|
591 min_edge = e; |
|
592 } |
|
593 if (++cnt == block_size) { |
|
594 if (min < 0) break; |
|
595 cnt = 0; |
|
596 } |
|
597 } |
|
598 if (!(min < 0)) { |
|
599 for (EdgeIt e(graph); e != next_edge; ++e) { |
|
600 if ((curr = state[e] * red_cost[e]) < min) { |
|
601 min = curr; |
|
602 min_edge = e; |
|
603 } |
|
604 if (++cnt == block_size) { |
|
605 if (min < 0) break; |
|
606 cnt = 0; |
|
607 } |
|
608 } |
|
609 } |
|
610 in_edge = min_edge; |
|
611 if ((next_edge = ++min_edge) == INVALID) |
|
612 next_edge = EdgeIt(graph); |
|
613 return min < 0; |
|
614 } |
|
615 } |
|
616 #endif |
|
617 |
|
618 #ifdef CANDIDATE_LIST_PIVOT |
|
619 /// \brief Functor class for removing non-eligible edges from the |
|
620 /// candidate list. |
|
621 class RemoveFunc |
|
622 { |
|
623 private: |
|
624 const IntEdgeMap &st; |
|
625 const ReducedCostMap &rc; |
|
626 public: |
|
627 RemoveFunc(const IntEdgeMap &_st, const ReducedCostMap &_rc) : |
|
628 st(_st), rc(_rc) {} |
|
629 bool operator()(const Edge &e) { |
|
630 return st[e] * rc[e] >= 0; |
|
631 } |
|
632 }; |
|
633 |
|
634 /// \brief Finds entering edge according to the "Candidate List" |
|
635 /// pivot rule. |
|
636 bool findEnteringEdge() { |
|
637 static RemoveFunc remove_func(state, red_cost); |
|
638 typedef typename std::list<Edge>::iterator ListIt; |
|
639 |
|
640 candidates.remove_if(remove_func); |
|
641 if (minor_count >= MINOR_LIMIT || candidates.size() == 0) { |
|
642 // Major iteration |
|
643 for (EdgeIt e(graph); e != INVALID; ++e) { |
|
644 if (state[e] * red_cost[e] < 0) { |
|
645 candidates.push_back(e); |
|
646 if (candidates.size() == LIST_LENGTH) break; |
|
647 } |
|
648 } |
|
649 if (candidates.size() == 0) return false; |
|
650 } |
|
651 |
|
652 // Minor iteration |
|
653 ++minor_count; |
|
654 Cost min = 0; |
|
655 for (ListIt it = candidates.begin(); it != candidates.end(); ++it) { |
|
656 if (state[*it] * red_cost[*it] < min) { |
|
657 min = state[*it] * red_cost[*it]; |
|
658 in_edge = *it; |
|
659 } |
|
660 } |
|
661 return true; |
|
662 } |
|
663 #endif |
|
664 |
|
665 #ifdef SORTED_LIST_PIVOT |
|
666 /// \brief Functor class to compare edges during sort of the |
|
667 /// candidate list. |
|
668 class SortFunc |
|
669 { |
|
670 private: |
|
671 const IntEdgeMap &st; |
|
672 const ReducedCostMap &rc; |
|
673 public: |
|
674 SortFunc(const IntEdgeMap &_st, const ReducedCostMap &_rc) : |
|
675 st(_st), rc(_rc) {} |
|
676 bool operator()(const Edge &e1, const Edge &e2) { |
|
677 return st[e1] * rc[e1] < st[e2] * rc[e2]; |
|
678 } |
|
679 }; |
|
680 |
|
681 /// \brief Finds entering edge according to the "Sorted List" |
|
682 /// pivot rule. |
|
683 bool findEnteringEdge() { |
|
684 static SortFunc sort_func(state, red_cost); |
|
685 |
|
686 // Minor iteration |
|
687 while (candidates.size() > 0) { |
|
688 in_edge = candidates.front(); |
|
689 candidates.pop_front(); |
|
690 if (state[in_edge] * red_cost[in_edge] < 0) return true; |
|
691 } |
|
692 |
|
693 // Major iteration |
|
694 Cost curr, min = 0; |
|
695 for (EdgeIt e(graph); e != INVALID; ++e) { |
|
696 if ((curr = state[e] * red_cost[e]) < min / LOWER_DIV) { |
|
697 candidates.push_back(e); |
|
698 if (curr < min) min = curr; |
|
699 if (candidates.size() >= LIST_LENGTH) break; |
|
700 } |
|
701 } |
|
702 if (candidates.size() == 0) return false; |
|
703 sort(candidates.begin(), candidates.end(), sort_func); |
|
704 return true; |
|
705 } |
|
706 #endif |
|
707 |
|
708 /// \brief Finds the join node. |
|
709 Node findJoinNode() { |
|
710 // Finding the join node |
|
711 Node u = graph.source(in_edge); |
|
712 Node v = graph.target(in_edge); |
|
713 while (u != v) { |
|
714 if (depth[u] == depth[v]) { |
|
715 u = parent[u]; |
|
716 v = parent[v]; |
|
717 } |
|
718 else if (depth[u] > depth[v]) u = parent[u]; |
|
719 else v = parent[v]; |
|
720 } |
|
721 return u; |
|
722 } |
|
723 |
|
724 /// \brief Finds the leaving edge of the cycle. Returns \c true if |
|
725 /// the leaving edge is not the same as the entering edge. |
|
726 bool findLeavingEdge() { |
|
727 // Initializing first and second nodes according to the direction |
|
728 // of the cycle |
|
729 if (state[in_edge] == LOWER) { |
|
730 first = graph.source(in_edge); |
|
731 second = graph.target(in_edge); |
|
732 } else { |
|
733 first = graph.target(in_edge); |
|
734 second = graph.source(in_edge); |
|
735 } |
|
736 delta = capacity[in_edge]; |
|
737 bool result = false; |
|
738 Capacity d; |
|
739 Edge e; |
|
740 |
|
741 // Searching the cycle along the path form the first node to the |
|
742 // root node |
|
743 for (Node u = first; u != join; u = parent[u]) { |
|
744 e = pred_edge[u]; |
|
745 d = forward[u] ? flow[e] : capacity[e] - flow[e]; |
|
746 if (d < delta) { |
|
747 delta = d; |
|
748 u_out = u; |
|
749 u_in = first; |
|
750 v_in = second; |
|
751 result = true; |
|
752 } |
|
753 } |
|
754 // Searching the cycle along the path form the second node to the |
|
755 // root node |
|
756 for (Node u = second; u != join; u = parent[u]) { |
|
757 e = pred_edge[u]; |
|
758 d = forward[u] ? capacity[e] - flow[e] : flow[e]; |
|
759 if (d <= delta) { |
|
760 delta = d; |
|
761 u_out = u; |
|
762 u_in = second; |
|
763 v_in = first; |
|
764 result = true; |
|
765 } |
|
766 } |
|
767 return result; |
|
768 } |
|
769 |
|
770 /// \brief Changes flow and state edge maps. |
|
771 void changeFlows(bool change) { |
|
772 // Augmenting along the cycle |
|
773 if (delta > 0) { |
|
774 Capacity val = state[in_edge] * delta; |
|
775 flow[in_edge] += val; |
|
776 for (Node u = graph.source(in_edge); u != join; u = parent[u]) { |
|
777 flow[pred_edge[u]] += forward[u] ? -val : val; |
|
778 } |
|
779 for (Node u = graph.target(in_edge); u != join; u = parent[u]) { |
|
780 flow[pred_edge[u]] += forward[u] ? val : -val; |
|
781 } |
|
782 } |
|
783 // Updating the state of the entering and leaving edges |
|
784 if (change) { |
|
785 state[in_edge] = TREE; |
|
786 state[pred_edge[u_out]] = |
|
787 (flow[pred_edge[u_out]] == 0) ? LOWER : UPPER; |
|
788 } else { |
|
789 state[in_edge] = -state[in_edge]; |
|
790 } |
|
791 } |
|
792 |
|
793 /// \brief Updates thread and parent node maps. |
|
794 void updateThreadParent() { |
|
795 Node u; |
|
796 v_out = parent[u_out]; |
|
797 |
|
798 // Handling the case when join and v_out coincide |
|
799 bool par_first = false; |
|
800 if (join == v_out) { |
|
801 for (u = join; u != u_in && u != v_in; u = thread[u]) ; |
|
802 if (u == v_in) { |
|
803 par_first = true; |
|
804 while (thread[u] != u_out) u = thread[u]; |
|
805 first = u; |
|
806 } |
|
807 } |
|
808 |
|
809 // Finding the last successor of u_in (u) and the node after it |
|
810 // (right) according to the thread index |
|
811 for (u = u_in; depth[thread[u]] > depth[u_in]; u = thread[u]) ; |
|
812 right = thread[u]; |
|
813 if (thread[v_in] == u_out) { |
|
814 for (last = u; depth[last] > depth[u_out]; last = thread[last]) ; |
|
815 if (last == u_out) last = thread[last]; |
|
816 } |
|
817 else last = thread[v_in]; |
|
818 |
|
819 // Updating stem nodes |
|
820 thread[v_in] = stem = u_in; |
|
821 par_stem = v_in; |
|
822 while (stem != u_out) { |
|
823 thread[u] = new_stem = parent[stem]; |
|
824 |
|
825 // Finding the node just before the stem node (u) according to |
|
826 // the original thread index |
|
827 for (u = new_stem; thread[u] != stem; u = thread[u]) ; |
|
828 thread[u] = right; |
|
829 |
|
830 // Changing the parent node of stem and shifting stem and |
|
831 // par_stem nodes |
|
832 parent[stem] = par_stem; |
|
833 par_stem = stem; |
|
834 stem = new_stem; |
|
835 |
|
836 // Finding the last successor of stem (u) and the node after it |
|
837 // (right) according to the thread index |
|
838 for (u = stem; depth[thread[u]] > depth[stem]; u = thread[u]) ; |
|
839 right = thread[u]; |
|
840 } |
|
841 parent[u_out] = par_stem; |
|
842 thread[u] = last; |
|
843 |
|
844 if (join == v_out && par_first) { |
|
845 if (first != v_in) thread[first] = right; |
|
846 } else { |
|
847 for (u = v_out; thread[u] != u_out; u = thread[u]) ; |
|
848 thread[u] = right; |
|
849 } |
|
850 } |
|
851 |
|
852 /// \brief Updates pred_edge and forward node maps. |
|
853 void updatePredEdge() { |
|
854 Node u = u_out, v; |
|
855 while (u != u_in) { |
|
856 v = parent[u]; |
|
857 pred_edge[u] = pred_edge[v]; |
|
858 forward[u] = !forward[v]; |
|
859 u = v; |
|
860 } |
|
861 pred_edge[u_in] = in_edge; |
|
862 forward[u_in] = (u_in == graph.source(in_edge)); |
|
863 } |
|
864 |
|
865 /// \brief Updates depth and potential node maps. |
|
866 void updateDepthPotential() { |
|
867 depth[u_in] = depth[v_in] + 1; |
|
868 potential[u_in] = forward[u_in] ? |
|
869 potential[v_in] + cost[pred_edge[u_in]] : |
|
870 potential[v_in] - cost[pred_edge[u_in]]; |
|
871 |
|
872 Node u = thread[u_in], v; |
|
873 while (true) { |
|
874 v = parent[u]; |
|
875 if (v == INVALID) break; |
|
876 depth[u] = depth[v] + 1; |
|
877 potential[u] = forward[u] ? |
|
878 potential[v] + cost[pred_edge[u]] : |
|
879 potential[v] - cost[pred_edge[u]]; |
|
880 if (depth[u] <= depth[v_in]) break; |
|
881 u = thread[u]; |
|
882 } |
|
883 } |
|
884 |
|
885 /// \brief Executes the algorithm. |
|
886 bool start() { |
|
887 // Processing pivots |
|
888 #ifdef _DEBUG_ITER_ |
|
889 int iter_num = 0; |
|
890 #endif |
|
891 #if defined(FIRST_ELIGIBLE_PIVOT) || defined(EDGE_BLOCK_PIVOT) |
|
892 EdgeIt next_edge(graph); |
|
893 while (findEnteringEdge(next_edge)) |
|
894 #else |
|
895 while (findEnteringEdge()) |
|
896 #endif |
|
897 { |
|
898 join = findJoinNode(); |
|
899 bool change = findLeavingEdge(); |
|
900 changeFlows(change); |
|
901 if (change) { |
|
902 updateThreadParent(); |
|
903 updatePredEdge(); |
|
904 updateDepthPotential(); |
|
905 } |
|
906 #ifdef _DEBUG_ITER_ |
|
907 ++iter_num; |
|
908 #endif |
|
909 } |
|
910 |
|
911 #ifdef _DEBUG_ITER_ |
|
912 t_iter.stop(); |
|
913 std::cout << "Network Simplex algorithm finished. " << iter_num |
|
914 << " pivot iterations performed."; |
|
915 #endif |
|
916 |
|
917 // Checking if the flow amount equals zero on all the |
|
918 // artificial edges |
|
919 for (InEdgeIt e(graph, root); e != INVALID; ++e) |
|
920 if (flow[e] > 0) return false; |
|
921 for (OutEdgeIt e(graph, root); e != INVALID; ++e) |
|
922 if (flow[e] > 0) return false; |
|
923 |
|
924 // Copying flow values to flow_result |
|
925 if (lower) { |
|
926 for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e) |
|
927 flow_result[e] = (*lower)[e] + flow[edge_ref[e]]; |
|
928 } else { |
|
929 for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e) |
|
930 flow_result[e] = flow[edge_ref[e]]; |
|
931 } |
|
932 // Copying potential values to potential_result |
|
933 for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n) |
|
934 potential_result[n] = potential[node_ref[n]]; |
|
935 |
|
936 return true; |
|
937 } |
|
938 |
|
939 }; //class NetworkSimplex |
|
940 |
|
941 ///@} |
|
942 |
|
943 } //namespace lemon |
|
944 |
|
945 #endif //LEMON_NETWORK_SIMPLEX_H |