COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/network_simplex.h @ 2457:8c791ee69a45

Last change on this file since 2457:8c791ee69a45 was 2457:8c791ee69a45, checked in by Balazs Dezso, 17 years ago

Improvments in min cost flow algorithms

  • improved cycle cancelling
File size: 27.4 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 FIRST_ELIGIBLE_PIVOT
34//#define BEST_ELIGIBLE_PIVOT
35#define EDGE_BLOCK_PIVOT
36//#define CANDIDATE_LIST_PIVOT
37//#define SORTED_LIST_PIVOT
38
39//#define _DEBUG_ITER_
40
41
42/// \brief State constant for edges at their lower bounds.
43#define LOWER   1
44/// \brief State constant for edges in the spanning tree.
45#define TREE    0
46/// \brief State constant for edges at their upper bounds.
47#define UPPER   -1
48
49#ifdef EDGE_BLOCK_PIVOT
50  /// \brief Number of blocks for the "Edge Block" pivot rule.
51  #define BLOCK_NUM             100
52  /// \brief Lower bound for the size of blocks.
53  #define MIN_BLOCK_SIZE        10
54#endif
55
56#ifdef CANDIDATE_LIST_PIVOT
57  #include <list>
58  /// \brief The maximum length of the edge list for the
59  /// "Candidate List" pivot rule.
60  #define LIST_LENGTH           100
61  /// \brief The maximum number of minor iterations between two major
62  /// itarations.
63  #define MINOR_LIMIT           10
64#endif
65
66#ifdef SORTED_LIST_PIVOT
67  #include <deque>
68  #include <algorithm>
69  /// \brief The maximum length of the edge list for the
70  /// "Sorted List" pivot rule.
71  #define LIST_LENGTH           500
72  #define LOWER_DIV             3
73#endif
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      graph.reserveNode(countNodes(graph_ref) + 1);
279      graph.reserveEdge(countEdges(graph_ref) + countNodes(graph_ref));
280      copyGraph(graph, graph_ref)
281        .edgeMap(cost, _cost)
282        .nodeRef(node_ref)
283        .edgeRef(edge_ref)
284        .run();
285
286      // Removing nonzero lower bounds
287      for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e) {
288        capacity[edge_ref[e]] = _capacity[e] - _lower[e];
289      }
290      for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n) {
291        Supply s = _supply[n];
292        for (typename Graph::InEdgeIt e(graph_ref, n); e != INVALID; ++e)
293          s += _lower[e];
294        for (typename Graph::OutEdgeIt e(graph_ref, n); e != INVALID; ++e)
295          s -= _lower[e];
296        supply[node_ref[n]] = s;
297      }
298    }
299
300    /// \brief General constructor of the class (without lower bounds).
301    ///
302    /// General constructor of the class (without lower bounds).
303    ///
304    /// \param _graph The directed graph the algorithm runs on.
305    /// \param _capacity The capacities (upper bounds) of the edges.
306    /// \param _cost The cost (length) values of the edges.
307    /// \param _supply The supply values of the nodes (signed).
308    NetworkSimplex( const Graph &_graph,
309                    const CapacityMap &_capacity,
310                    const CostMap &_cost,
311                    const SupplyMap &_supply ) :
312      graph_ref(_graph), lower(NULL), capacity(graph), cost(graph),
313      supply(graph), flow(graph), flow_result(_graph), potential(graph),
314      potential_result(_graph), depth(graph), parent(graph),
315      pred_edge(graph), thread(graph), forward(graph), state(graph),
316      node_ref(graph_ref), edge_ref(graph_ref),
317      red_cost(graph, cost, potential)
318    {
319      // Checking the sum of supply values
320      Supply sum = 0;
321      for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n)
322        sum += _supply[n];
323      if (!(valid_supply = sum == 0)) return;
324
325      // Copying graph_ref to graph
326      copyGraph(graph, graph_ref)
327        .edgeMap(capacity, _capacity)
328        .edgeMap(cost, _cost)
329        .nodeMap(supply, _supply)
330        .nodeRef(node_ref)
331        .edgeRef(edge_ref)
332        .run();
333    }
334
335    /// \brief Simple constructor of the class (with lower bounds).
336    ///
337    /// Simple constructor of the class (with lower bounds).
338    ///
339    /// \param _graph The directed graph the algorithm runs on.
340    /// \param _lower The lower bounds of the edges.
341    /// \param _capacity The capacities (upper bounds) of the edges.
342    /// \param _cost The cost (length) values of the edges.
343    /// \param _s The source node.
344    /// \param _t The target node.
345    /// \param _flow_value The required amount of flow from node \c _s
346    /// to node \c _t (i.e. the supply of \c _s and the demand of
347    /// \c _t).
348    NetworkSimplex( const Graph &_graph,
349                    const LowerMap &_lower,
350                    const CapacityMap &_capacity,
351                    const CostMap &_cost,
352                    typename Graph::Node _s,
353                    typename Graph::Node _t,
354                    typename SupplyMap::Value _flow_value ) :
355      graph_ref(_graph), lower(&_lower), capacity(graph), cost(graph),
356      supply(graph), flow(graph), flow_result(_graph), potential(graph),
357      potential_result(_graph), depth(graph), parent(graph),
358      pred_edge(graph), thread(graph), forward(graph), state(graph),
359      node_ref(graph_ref), edge_ref(graph_ref),
360      red_cost(graph, cost, potential)
361    {
362      // Copying graph_ref to graph
363      copyGraph(graph, graph_ref)
364        .edgeMap(cost, _cost)
365        .nodeRef(node_ref)
366        .edgeRef(edge_ref)
367        .run();
368
369      // Removing nonzero lower bounds
370      for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e) {
371        capacity[edge_ref[e]] = _capacity[e] - _lower[e];
372      }
373      for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n) {
374        Supply s = 0;
375        if (n == _s) s =  _flow_value;
376        if (n == _t) s = -_flow_value;
377        for (typename Graph::InEdgeIt e(graph_ref, n); e != INVALID; ++e)
378          s += _lower[e];
379        for (typename Graph::OutEdgeIt e(graph_ref, n); e != INVALID; ++e)
380          s -= _lower[e];
381        supply[node_ref[n]] = s;
382      }
383      valid_supply = true;
384    }
385
386    /// \brief Simple constructor of the class (without lower bounds).
387    ///
388    /// Simple constructor of the class (without lower bounds).
389    ///
390    /// \param _graph The directed graph the algorithm runs on.
391    /// \param _capacity The capacities (upper bounds) of the edges.
392    /// \param _cost The cost (length) values of the edges.
393    /// \param _s The source node.
394    /// \param _t The target node.
395    /// \param _flow_value The required amount of flow from node \c _s
396    /// to node \c _t (i.e. the supply of \c _s and the demand of
397    /// \c _t).
398    NetworkSimplex( const Graph &_graph,
399                    const CapacityMap &_capacity,
400                    const CostMap &_cost,
401                    typename Graph::Node _s,
402                    typename Graph::Node _t,
403                    typename SupplyMap::Value _flow_value ) :
404      graph_ref(_graph), lower(NULL), capacity(graph), cost(graph),
405      supply(graph, 0), flow(graph), flow_result(_graph), potential(graph),
406      potential_result(_graph), depth(graph), parent(graph),
407      pred_edge(graph), thread(graph), forward(graph), state(graph),
408      node_ref(graph_ref), edge_ref(graph_ref),
409      red_cost(graph, cost, potential)
410    {
411      // Copying graph_ref to graph
412      copyGraph(graph, graph_ref)
413        .edgeMap(capacity, _capacity)
414        .edgeMap(cost, _cost)
415        .nodeRef(node_ref)
416        .edgeRef(edge_ref)
417        .run();
418      supply[node_ref[_s]] =  _flow_value;
419      supply[node_ref[_t]] = -_flow_value;
420      valid_supply = true;
421    }
422
423    /// \brief Returns a const reference to the flow map.
424    ///
425    /// Returns a const reference to the flow map.
426    ///
427    /// \pre \ref run() must be called before using this function.
428    const FlowMap& flowMap() const {
429      return flow_result;
430    }
431
432    /// \brief Returns a const reference to the potential map (the dual
433    /// solution).
434    ///
435    /// Returns a const reference to the potential map (the dual
436    /// solution).
437    ///
438    /// \pre \ref run() must be called before using this function.
439    const PotentialMap& potentialMap() const {
440      return potential_result;
441    }
442
443    /// \brief Returns the total cost of the found flow.
444    ///
445    /// Returns the total cost of the found flow. The complexity of the
446    /// function is \f$ O(e) \f$.
447    ///
448    /// \pre \ref run() must be called before using this function.
449    Cost totalCost() const {
450      Cost c = 0;
451      for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e)
452        c += flow_result[e] * cost[edge_ref[e]];
453      return c;
454    }
455
456    /// \brief Runs the algorithm.
457    ///
458    /// Runs the algorithm.
459    ///
460    /// \return \c true if a feasible flow can be found.
461    bool run() {
462      return init() && start();
463    }
464
465  protected:
466
467    /// \brief Extends the underlaying graph and initializes all the
468    /// node and edge maps.
469    bool init() {
470      if (!valid_supply) return false;
471
472      // Initializing state and flow maps
473      for (EdgeIt e(graph); e != INVALID; ++e) {
474        flow[e] = 0;
475        state[e] = LOWER;
476      }
477
478      // Adding an artificial root node to the graph
479      root = graph.addNode();
480      parent[root] = INVALID;
481      pred_edge[root] = INVALID;
482      depth[root] = 0;
483      supply[root] = 0;
484      potential[root] = 0;
485
486      // Adding artificial edges to the graph and initializing the node
487      // maps of the spanning tree data structure
488      Supply sum = 0;
489      Node last = root;
490      Edge e;
491      Cost max_cost = std::numeric_limits<Cost>::max() / 4;
492      for (NodeIt u(graph); u != INVALID; ++u) {
493        if (u == root) continue;
494        thread[last] = u;
495        last = u;
496        parent[u] = root;
497        depth[u] = 1;
498        sum += supply[u];
499        if (supply[u] >= 0) {
500          e = graph.addEdge(u, root);
501          flow[e] = supply[u];
502          forward[u] = true;
503          potential[u] = max_cost;
504        } else {
505          e = graph.addEdge(root, u);
506          flow[e] = -supply[u];
507          forward[u] = false;
508          potential[u] = -max_cost;
509        }
510        cost[e] = max_cost;
511        capacity[e] = std::numeric_limits<Capacity>::max();
512        state[e] = TREE;
513        pred_edge[u] = e;
514      }
515      thread[last] = root;
516
517#ifdef EDGE_BLOCK_PIVOT
518      // Initializing block_size for the edge block pivot rule
519      int edge_num = countEdges(graph);
520      block_size = edge_num >= BLOCK_NUM * MIN_BLOCK_SIZE ?
521                   edge_num / BLOCK_NUM : MIN_BLOCK_SIZE;
522#endif
523#ifdef CANDIDATE_LIST_PIVOT
524      minor_count = 0;
525#endif
526
527      return sum == 0;
528    }
529
530#ifdef FIRST_ELIGIBLE_PIVOT
531    /// \brief Finds entering edge according to the "First Eligible"
532    /// pivot rule.
533    bool findEnteringEdge(EdgeIt &next_edge) {
534      for (EdgeIt e = next_edge; e != INVALID; ++e) {
535        if (state[e] * red_cost[e] < 0) {
536          in_edge = e;
537          next_edge = ++e;
538          return true;
539        }
540      }
541      for (EdgeIt e(graph); e != next_edge; ++e) {
542        if (state[e] * red_cost[e] < 0) {
543          in_edge = e;
544          next_edge = ++e;
545          return true;
546        }
547      }
548      return false;
549    }
550#endif
551
552#ifdef BEST_ELIGIBLE_PIVOT
553    /// \brief Finds entering edge according to the "Best Eligible"
554    /// pivot rule.
555    bool findEnteringEdge() {
556      Cost min = 0;
557      for (EdgeIt e(graph); e != INVALID; ++e) {
558        if (state[e] * red_cost[e] < min) {
559          min = state[e] * red_cost[e];
560          in_edge = e;
561        }
562      }
563      return min < 0;
564    }
565#endif
566
567#ifdef EDGE_BLOCK_PIVOT
568    /// \brief Finds entering edge according to the "Edge Block"
569    /// pivot rule.
570    bool findEnteringEdge(EdgeIt &next_edge) {
571      // Performing edge block selection
572      Cost curr, min = 0;
573      EdgeIt min_edge(graph);
574      int cnt = 0;
575      for (EdgeIt e = next_edge; e != INVALID; ++e) {
576        if ((curr = state[e] * red_cost[e]) < min) {
577          min = curr;
578          min_edge = e;
579        }
580        if (++cnt == block_size) {
581          if (min < 0) break;
582          cnt = 0;
583        }
584      }
585      if (!(min < 0)) {
586        for (EdgeIt e(graph); e != next_edge; ++e) {
587          if ((curr = state[e] * red_cost[e]) < min) {
588            min = curr;
589            min_edge = e;
590          }
591          if (++cnt == block_size) {
592            if (min < 0) break;
593            cnt = 0;
594          }
595        }
596      }
597      in_edge = min_edge;
598      if ((next_edge = ++min_edge) == INVALID)
599        next_edge = EdgeIt(graph);
600      return min < 0;
601    }
602#endif
603
604#ifdef CANDIDATE_LIST_PIVOT
605    /// \brief Functor class for removing non-eligible edges from the
606    /// candidate list.
607    class RemoveFunc
608    {
609    private:
610      const IntEdgeMap &st;
611      const ReducedCostMap &rc;
612    public:
613      RemoveFunc(const IntEdgeMap &_st, const ReducedCostMap &_rc) :
614        st(_st), rc(_rc) {}
615      bool operator()(const Edge &e) {
616        return st[e] * rc[e] >= 0;
617      }
618    };
619
620    /// \brief Finds entering edge according to the "Candidate List"
621    /// pivot rule.
622    bool findEnteringEdge() {
623      static RemoveFunc remove_func(state, red_cost);
624      typedef typename std::list<Edge>::iterator ListIt;
625
626      candidates.remove_if(remove_func);
627      if (minor_count >= MINOR_LIMIT || candidates.size() == 0) {
628        // Major iteration
629        for (EdgeIt e(graph); e != INVALID; ++e) {
630          if (state[e] * red_cost[e] < 0) {
631            candidates.push_back(e);
632            if (candidates.size() == LIST_LENGTH) break;
633          }
634        }
635        if (candidates.size() == 0) return false;
636      }
637
638      // Minor iteration
639      ++minor_count;
640      Cost min = 0;
641      for (ListIt it = candidates.begin(); it != candidates.end(); ++it) {
642        if (state[*it] * red_cost[*it] < min) {
643          min = state[*it] * red_cost[*it];
644          in_edge = *it;
645        }
646      }
647      return true;
648    }
649#endif
650
651#ifdef SORTED_LIST_PIVOT
652    /// \brief Functor class to compare edges during sort of the
653    /// candidate list.
654    class SortFunc
655    {
656    private:
657      const IntEdgeMap &st;
658      const ReducedCostMap &rc;
659    public:
660      SortFunc(const IntEdgeMap &_st, const ReducedCostMap &_rc) :
661        st(_st), rc(_rc) {}
662      bool operator()(const Edge &e1, const Edge &e2) {
663        return st[e1] * rc[e1] < st[e2] * rc[e2];
664      }
665    };
666
667    /// \brief Finds entering edge according to the "Sorted List"
668    /// pivot rule.
669    bool findEnteringEdge() {
670      static SortFunc sort_func(state, red_cost);
671
672      // Minor iteration
673      while (candidates.size() > 0) {
674        in_edge = candidates.front();
675        candidates.pop_front();
676        if (state[in_edge] * red_cost[in_edge] < 0) return true;
677      }
678
679      // Major iteration
680      Cost curr, min = 0;
681      for (EdgeIt e(graph); e != INVALID; ++e) {
682        if ((curr = state[e] * red_cost[e]) < min / LOWER_DIV) {
683          candidates.push_back(e);
684          if (curr < min) min = curr;
685          if (candidates.size() == LIST_LENGTH) break;
686        }
687      }
688      if (candidates.size() == 0) return false;
689      sort(candidates.begin(), candidates.end(), sort_func);
690      in_edge = candidates.front();
691      candidates.pop_front();
692      return true;
693    }
694#endif
695
696    /// \brief Finds the join node.
697    Node findJoinNode() {
698      // Finding the join node
699      Node u = graph.source(in_edge);
700      Node v = graph.target(in_edge);
701      while (u != v) {
702        if (depth[u] == depth[v]) {
703          u = parent[u];
704          v = parent[v];
705        }
706        else if (depth[u] > depth[v]) u = parent[u];
707        else v = parent[v];
708      }
709      return u;
710    }
711
712    /// \brief Finds the leaving edge of the cycle. Returns \c true if
713    /// the leaving edge is not the same as the entering edge.
714    bool findLeavingEdge() {
715      // Initializing first and second nodes according to the direction
716      // of the cycle
717      if (state[in_edge] == LOWER) {
718        first = graph.source(in_edge);
719        second  = graph.target(in_edge);
720      } else {
721        first = graph.target(in_edge);
722        second  = graph.source(in_edge);
723      }
724      delta = capacity[in_edge];
725      bool result = false;
726      Capacity d;
727      Edge e;
728
729      // Searching the cycle along the path form the first node to the
730      // root node
731      for (Node u = first; u != join; u = parent[u]) {
732        e = pred_edge[u];
733        d = forward[u] ? flow[e] : capacity[e] - flow[e];
734        if (d < delta) {
735          delta = d;
736          u_out = u;
737          u_in = first;
738          v_in = second;
739          result = true;
740        }
741      }
742      // Searching the cycle along the path form the second node to the
743      // root node
744      for (Node u = second; u != join; u = parent[u]) {
745        e = pred_edge[u];
746        d = forward[u] ? capacity[e] - flow[e] : flow[e];
747        if (d <= delta) {
748          delta = d;
749          u_out = u;
750          u_in = second;
751          v_in = first;
752          result = true;
753        }
754      }
755      return result;
756    }
757
758    /// \brief Changes flow and state edge maps.
759    void changeFlows(bool change) {
760      // Augmenting along the cycle
761      if (delta > 0) {
762        Capacity val = state[in_edge] * delta;
763        flow[in_edge] += val;
764        for (Node u = graph.source(in_edge); u != join; u = parent[u]) {
765          flow[pred_edge[u]] += forward[u] ? -val : val;
766        }
767        for (Node u = graph.target(in_edge); u != join; u = parent[u]) {
768          flow[pred_edge[u]] += forward[u] ? val : -val;
769        }
770      }
771      // Updating the state of the entering and leaving edges
772      if (change) {
773        state[in_edge] = TREE;
774        state[pred_edge[u_out]] =
775          (flow[pred_edge[u_out]] == 0) ? LOWER : UPPER;
776      } else {
777        state[in_edge] = -state[in_edge];
778      }
779    }
780
781    /// \brief Updates thread and parent node maps.
782    void updateThreadParent() {
783      Node u;
784      v_out = parent[u_out];
785
786      // Handling the case when join and v_out coincide
787      bool par_first = false;
788      if (join == v_out) {
789        for (u = join; u != u_in && u != v_in; u = thread[u]) ;
790        if (u == v_in) {
791          par_first = true;
792          while (thread[u] != u_out) u = thread[u];
793          first = u;
794        }
795      }
796
797      // Finding the last successor of u_in (u) and the node after it
798      // (right) according to the thread index
799      for (u = u_in; depth[thread[u]] > depth[u_in]; u = thread[u]) ;
800      right = thread[u];
801      if (thread[v_in] == u_out) {
802        for (last = u; depth[last] > depth[u_out]; last = thread[last]) ;
803        if (last == u_out) last = thread[last];
804      }
805      else last = thread[v_in];
806
807      // Updating stem nodes
808      thread[v_in] = stem = u_in;
809      par_stem = v_in;
810      while (stem != u_out) {
811        thread[u] = new_stem = parent[stem];
812
813        // Finding the node just before the stem node (u) according to
814        // the original thread index
815        for (u = new_stem; thread[u] != stem; u = thread[u]) ;
816        thread[u] = right;
817
818        // Changing the parent node of stem and shifting stem and
819        // par_stem nodes
820        parent[stem] = par_stem;
821        par_stem = stem;
822        stem = new_stem;
823
824        // Finding the last successor of stem (u) and the node after it
825        // (right) according to the thread index
826        for (u = stem; depth[thread[u]] > depth[stem]; u = thread[u]) ;
827        right = thread[u];
828      }
829      parent[u_out] = par_stem;
830      thread[u] = last;
831
832      if (join == v_out && par_first) {
833        if (first != v_in) thread[first] = right;
834      } else {
835        for (u = v_out; thread[u] != u_out; u = thread[u]) ;
836        thread[u] = right;
837      }
838    }
839
840    /// \brief Updates pred_edge and forward node maps.
841    void updatePredEdge() {
842      Node u = u_out, v;
843      while (u != u_in) {
844        v = parent[u];
845        pred_edge[u] = pred_edge[v];
846        forward[u] = !forward[v];
847        u = v;
848      }
849      pred_edge[u_in] = in_edge;
850      forward[u_in] = (u_in == graph.source(in_edge));
851    }
852
853    /// \brief Updates depth and potential node maps.
854    void updateDepthPotential() {
855      depth[u_in] = depth[v_in] + 1;
856      potential[u_in] = forward[u_in] ?
857        potential[v_in] + cost[pred_edge[u_in]] :
858        potential[v_in] - cost[pred_edge[u_in]];
859
860      Node u = thread[u_in], v;
861      while (true) {
862        v = parent[u];
863        if (v == INVALID) break;
864        depth[u] = depth[v] + 1;
865        potential[u] = forward[u] ?
866          potential[v] + cost[pred_edge[u]] :
867          potential[v] - cost[pred_edge[u]];
868        if (depth[u] <= depth[v_in]) break;
869        u = thread[u];
870      }
871    }
872
873    /// \brief Executes the algorithm.
874    bool start() {
875      // Processing pivots
876#ifdef _DEBUG_ITER_
877      int iter_num = 0;
878#endif
879#if defined(FIRST_ELIGIBLE_PIVOT) || defined(EDGE_BLOCK_PIVOT)
880      EdgeIt next_edge(graph);
881      while (findEnteringEdge(next_edge))
882#else
883      while (findEnteringEdge())
884#endif
885      {
886        join = findJoinNode();
887        bool change = findLeavingEdge();
888        changeFlows(change);
889        if (change) {
890          updateThreadParent();
891          updatePredEdge();
892          updateDepthPotential();
893        }
894#ifdef _DEBUG_ITER_
895        ++iter_num;
896#endif
897      }
898
899#ifdef _DEBUG_ITER_
900      std::cout << "Network Simplex algorithm finished. " << iter_num
901                << " pivot iterations performed." << std::endl;
902#endif
903
904      // Checking if the flow amount equals zero on all the
905      // artificial edges
906      for (InEdgeIt e(graph, root); e != INVALID; ++e)
907        if (flow[e] > 0) return false;
908      for (OutEdgeIt e(graph, root); e != INVALID; ++e)
909        if (flow[e] > 0) return false;
910
911      // Copying flow values to flow_result
912      if (lower) {
913        for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e)
914          flow_result[e] = (*lower)[e] + flow[edge_ref[e]];
915      } else {
916        for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e)
917          flow_result[e] = flow[edge_ref[e]];
918      }
919      // Copying potential values to potential_result
920      for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n)
921        potential_result[n] = potential[node_ref[n]];
922
923      return true;
924    }
925
926  }; //class NetworkSimplex
927
928  ///@}
929
930} //namespace lemon
931
932#endif //LEMON_NETWORK_SIMPLEX_H
Note: See TracBrowser for help on using the repository browser.