COIN-OR::LEMON - Graph Library

Ticket #436: 436-81d7e0a1b09d-cc-str-poly.patch

File 436-81d7e0a1b09d-cc-str-poly.patch, 4.7 KB (added by Peter Kovacs, 9 years ago)
  • lemon/cycle_canceling.h

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1328290438 -3600
    # Node ID 81d7e0a1b09d1fc9e217823ede77ca3810339ad4
    # Parent  ee2fe24de0158171e2cdacb5807d0a4daeb99d99
    Ensure strongly polynomial running time for CycleCanceling (#436)
    The number of iterations performed by Howard's algorithm is limited.
    If the limit is reached, a strongly polynomial implementation,
    HartmannOrlinMmc is executed to find a minimum mean cycle.
    Note that Howard's algorithm is usually much faster in practice
    than the other two minimum mean cycle algorithms currently
    implemented in LEMON.
    
    diff --git a/lemon/cycle_canceling.h b/lemon/cycle_canceling.h
    a b  
    3535#include <lemon/circulation.h>
    3636#include <lemon/bellman_ford.h>
    3737#include <lemon/howard_mmc.h>
     38#include <lemon/hartmann_orlin_mmc.h>
    3839
    3940namespace lemon {
    4041
     
    922923
    923924    // Execute the "Minimum Mean Cycle Canceling" method
    924925    void startMinMeanCycleCanceling() {
    925       typedef SimplePath<StaticDigraph> SPath;
     926      typedef Path<StaticDigraph> SPath;
    926927      typedef typename SPath::ArcIt SPathArcIt;
    927928      typedef typename HowardMmc<StaticDigraph, CostArcMap>
    928         ::template SetPath<SPath>::Create MMC;
     929        ::template SetPath<SPath>::Create HwMmc;
     930      typedef typename HartmannOrlinMmc<StaticDigraph, CostArcMap>
     931        ::template SetPath<SPath>::Create HoMmc;
     932
     933      const double HW_ITER_LIMIT_FACTOR = 0.25;
     934      const int HW_ITER_LIMIT_MIN_VALUE = 5;
     935
     936      const int hw_iter_limit =
     937          std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num),
     938                   HW_ITER_LIMIT_MIN_VALUE);
    929939
    930940      SPath cycle;
    931       MMC mmc(_sgr, _cost_map);
    932       mmc.cycle(cycle);
     941      HwMmc hw_mmc(_sgr, _cost_map);
     942      hw_mmc.cycle(cycle);
    933943      buildResidualNetwork();
    934       while (mmc.findCycleMean() && mmc.cycleCost() < 0) {
    935         // Find the cycle
    936         mmc.findCycle();
    937 
     944      while (true) {
     945       
     946        typename HwMmc::TerminationCause hw_tc =
     947            hw_mmc.findCycleMean(hw_iter_limit);
     948        if (hw_tc == HwMmc::ITERATION_LIMIT) {
     949          // Howard's algorithm reached the iteration limit, start a
     950          // strongly polynomial algorithm instead
     951          HoMmc ho_mmc(_sgr, _cost_map);
     952          ho_mmc.cycle(cycle);
     953          // Find a minimum mean cycle (Hartmann-Orlin algorithm)
     954          if (!(ho_mmc.findCycleMean() && ho_mmc.cycleCost() < 0)) break;
     955          ho_mmc.findCycle();
     956        } else {
     957          // Find a minimum mean cycle (Howard algorithm)
     958          if (!(hw_tc == HwMmc::OPTIMAL && hw_mmc.cycleCost() < 0)) break;
     959          hw_mmc.findCycle();
     960        }
     961       
    938962        // Compute delta value
    939963        Value delta = INF;
    940964        for (SPathArcIt a(cycle); a != INVALID; ++a) {
     
    959983      // Constants for the min mean cycle computations
    960984      const double LIMIT_FACTOR = 1.0;
    961985      const int MIN_LIMIT = 5;
     986      const double HW_ITER_LIMIT_FACTOR = 0.25;
     987      const int HW_ITER_LIMIT_MIN_VALUE = 5;
     988
     989      const int hw_iter_limit =
     990          std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num),
     991                   HW_ITER_LIMIT_MIN_VALUE);
    962992
    963993      // Contruct auxiliary data vectors
    964994      DoubleVector pi(_res_node_num, 0.0);
     
    11321162            }
    11331163          }
    11341164        } else {
    1135           typedef HowardMmc<StaticDigraph, CostArcMap> MMC;
     1165          typedef HowardMmc<StaticDigraph, CostArcMap> HwMmc;
     1166          typedef HartmannOrlinMmc<StaticDigraph, CostArcMap> HoMmc;
    11361167          typedef typename BellmanFord<StaticDigraph, CostArcMap>
    11371168            ::template SetDistMap<CostNodeMap>::Create BF;
    11381169
    11391170          // Set epsilon to the minimum cycle mean
     1171          Cost cycle_cost = 0;
     1172          int cycle_size = 1;
    11401173          buildResidualNetwork();
    1141           MMC mmc(_sgr, _cost_map);
    1142           mmc.findCycleMean();
    1143           epsilon = -mmc.cycleMean();
    1144           Cost cycle_cost = mmc.cycleCost();
    1145           int cycle_size = mmc.cycleSize();
     1174          HwMmc hw_mmc(_sgr, _cost_map);
     1175          if (hw_mmc.findCycleMean(hw_iter_limit) == HwMmc::ITERATION_LIMIT) {
     1176            // Howard's algorithm reached the iteration limit, start a
     1177            // strongly polynomial algorithm instead
     1178            HoMmc ho_mmc(_sgr, _cost_map);
     1179            ho_mmc.findCycleMean();
     1180            epsilon = -ho_mmc.cycleMean();
     1181            cycle_cost = ho_mmc.cycleCost();
     1182            cycle_size = ho_mmc.cycleSize();
     1183          } else {
     1184            // Set epsilon
     1185            epsilon = -hw_mmc.cycleMean();
     1186            cycle_cost = hw_mmc.cycleCost();
     1187            cycle_size = hw_mmc.cycleSize();
     1188          }
    11461189
    11471190          // Compute feasible potentials for the current epsilon
    11481191          for (int i = 0; i != int(_cost_vec.size()); ++i) {