COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/network_simplex.h @ 2441:d8d6ab871608

Last change on this file since 2441:d8d6ab871608 was 2440:c9218405595b, checked in by Balazs Dezso, 17 years ago

Various min cost flow solvers

Patch from Peter Kovacs

File size: 27.6 KB
Line 
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
75namespace 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
102template < 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
Note: See TracBrowser for help on using the repository browser.