COIN-OR::LEMON - Graph Library

Changes in / [1011:9a6c9d4ee77b:1014:bc726f4892c7] in lemon-main


Ignore:
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • lemon/cycle_canceling.h

    r1003 r1013  
    3636#include <lemon/bellman_ford.h>
    3737#include <lemon/howard_mmc.h>
     38#include <lemon/hartmann_orlin_mmc.h>
    3839
    3940namespace lemon {
     
    928929    // Execute the "Minimum Mean Cycle Canceling" method
    929930    void startMinMeanCycleCanceling() {
    930       typedef SimplePath<StaticDigraph> SPath;
     931      typedef Path<StaticDigraph> SPath;
    931932      typedef typename SPath::ArcIt SPathArcIt;
    932933      typedef typename HowardMmc<StaticDigraph, CostArcMap>
    933         ::template SetPath<SPath>::Create MMC;
     934        ::template SetPath<SPath>::Create HwMmc;
     935      typedef typename HartmannOrlinMmc<StaticDigraph, CostArcMap>
     936        ::template SetPath<SPath>::Create HoMmc;
     937
     938      const double HW_ITER_LIMIT_FACTOR = 1.0;
     939      const int HW_ITER_LIMIT_MIN_VALUE = 5;
     940
     941      const int hw_iter_limit =
     942          std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num),
     943                   HW_ITER_LIMIT_MIN_VALUE);
    934944
    935945      SPath cycle;
    936       MMC mmc(_sgr, _cost_map);
    937       mmc.cycle(cycle);
     946      HwMmc hw_mmc(_sgr, _cost_map);
     947      hw_mmc.cycle(cycle);
    938948      buildResidualNetwork();
    939       while (mmc.findCycleMean() && mmc.cycleCost() < 0) {
    940         // Find the cycle
    941         mmc.findCycle();
    942 
     949      while (true) {
     950       
     951        typename HwMmc::TerminationCause hw_tc =
     952            hw_mmc.findCycleMean(hw_iter_limit);
     953        if (hw_tc == HwMmc::ITERATION_LIMIT) {
     954          // Howard's algorithm reached the iteration limit, start a
     955          // strongly polynomial algorithm instead
     956          HoMmc ho_mmc(_sgr, _cost_map);
     957          ho_mmc.cycle(cycle);
     958          // Find a minimum mean cycle (Hartmann-Orlin algorithm)
     959          if (!(ho_mmc.findCycleMean() && ho_mmc.cycleCost() < 0)) break;
     960          ho_mmc.findCycle();
     961        } else {
     962          // Find a minimum mean cycle (Howard algorithm)
     963          if (!(hw_tc == HwMmc::OPTIMAL && hw_mmc.cycleCost() < 0)) break;
     964          hw_mmc.findCycle();
     965        }
     966       
    943967        // Compute delta value
    944968        Value delta = INF;
     
    965989      const double LIMIT_FACTOR = 1.0;
    966990      const int MIN_LIMIT = 5;
     991      const double HW_ITER_LIMIT_FACTOR = 1.0;
     992      const int HW_ITER_LIMIT_MIN_VALUE = 5;
     993
     994      const int hw_iter_limit =
     995          std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num),
     996                   HW_ITER_LIMIT_MIN_VALUE);
    967997
    968998      // Contruct auxiliary data vectors
     
    11381168          }
    11391169        } else {
    1140           typedef HowardMmc<StaticDigraph, CostArcMap> MMC;
     1170          typedef HowardMmc<StaticDigraph, CostArcMap> HwMmc;
     1171          typedef HartmannOrlinMmc<StaticDigraph, CostArcMap> HoMmc;
    11411172          typedef typename BellmanFord<StaticDigraph, CostArcMap>
    11421173            ::template SetDistMap<CostNodeMap>::Create BF;
    11431174
    11441175          // Set epsilon to the minimum cycle mean
     1176          Cost cycle_cost = 0;
     1177          int cycle_size = 1;
    11451178          buildResidualNetwork();
    1146           MMC mmc(_sgr, _cost_map);
    1147           mmc.findCycleMean();
    1148           epsilon = -mmc.cycleMean();
    1149           Cost cycle_cost = mmc.cycleCost();
    1150           int cycle_size = mmc.cycleSize();
     1179          HwMmc hw_mmc(_sgr, _cost_map);
     1180          if (hw_mmc.findCycleMean(hw_iter_limit) == HwMmc::ITERATION_LIMIT) {
     1181            // Howard's algorithm reached the iteration limit, start a
     1182            // strongly polynomial algorithm instead
     1183            HoMmc ho_mmc(_sgr, _cost_map);
     1184            ho_mmc.findCycleMean();
     1185            epsilon = -ho_mmc.cycleMean();
     1186            cycle_cost = ho_mmc.cycleCost();
     1187            cycle_size = ho_mmc.cycleSize();
     1188          } else {
     1189            // Set epsilon
     1190            epsilon = -hw_mmc.cycleMean();
     1191            cycle_cost = hw_mmc.cycleCost();
     1192            cycle_size = hw_mmc.cycleSize();
     1193          }
    11511194
    11521195          // Compute feasible potentials for the current epsilon
  • lemon/howard_mmc.h

    r1002 r1012  
    150150    typedef TR Traits;
    151151
     152    /// \brief Constants for the causes of search termination.
     153    ///
     154    /// Enum type containing constants for the different causes of search
     155    /// termination. The \ref findCycleMean() function returns one of
     156    /// these values.
     157    enum TerminationCause {
     158     
     159      /// No directed cycle can be found in the digraph.
     160      NO_CYCLE = 0,
     161   
     162      /// Optimal solution (minimum cycle mean) is found.
     163      OPTIMAL = 1,
     164
     165      /// The iteration count limit is reached.
     166      ITERATION_LIMIT
     167    };
     168
    152169  private:
    153170
     
    325342    }
    326343
    327     /// \brief Find the minimum cycle mean.
     344    /// \brief Find the minimum cycle mean (or an upper bound).
    328345    ///
    329346    /// This function finds the minimum mean cost of the directed
    330     /// cycles in the digraph.
    331     ///
    332     /// \return \c true if a directed cycle exists in the digraph.
    333     bool findCycleMean() {
     347    /// cycles in the digraph (or an upper bound for it).
     348    ///
     349    /// By default, the function finds the exact minimum cycle mean,
     350    /// but an optional limit can also be specified for the number of
     351    /// iterations performed during the search process.
     352    /// The return value indicates if the optimal solution is found
     353    /// or the iteration limit is reached. In the latter case, an
     354    /// approximate solution is provided, which corresponds to a directed
     355    /// cycle whose mean cost is relatively small, but not necessarily
     356    /// minimal.
     357    ///
     358    /// \param limit  The maximum allowed number of iterations during
     359    /// the search process. Its default value implies that the algorithm
     360    /// runs until it finds the exact optimal solution.
     361    ///
     362    /// \return The termination cause of the search process.
     363    /// For more information, see \ref TerminationCause.
     364    TerminationCause findCycleMean(int limit = std::numeric_limits<int>::max()) {
    334365      // Initialize and find strongly connected components
    335366      init();
     
    337368
    338369      // Find the minimum cycle mean in the components
     370      int iter_count = 0;
     371      bool iter_limit_reached = false;
    339372      for (int comp = 0; comp < _comp_num; ++comp) {
    340373        // Find the minimum mean cycle in the current component
    341374        if (!buildPolicyGraph(comp)) continue;
    342375        while (true) {
     376          if (++iter_count > limit) {
     377            iter_limit_reached = true;
     378            break;
     379          }
    343380          findPolicyCycle();
    344381          if (!computeNodeDistances()) break;
    345382        }
     383
    346384        // Update the best cycle (global minimum mean cycle)
    347385        if ( _curr_found && (!_best_found ||
     
    352390          _best_node = _curr_node;
    353391        }
    354       }
    355       return _best_found;
     392       
     393        if (iter_limit_reached) break;
     394      }
     395
     396      if (iter_limit_reached) {
     397        return ITERATION_LIMIT;
     398      } else {
     399        return _best_found ? OPTIMAL : NO_CYCLE;
     400      }
    356401    }
    357402
  • test/min_mean_cycle_test.cc

    r877 r1012  
    111111                 int cost, int size) {
    112112  MMC alg(gr, lm);
    113   alg.findCycleMean();
     113  check(alg.findCycleMean(), "Wrong result");
    114114  check(alg.cycleMean() == static_cast<double>(cost) / size,
    115115        "Wrong cycle mean");
     
    211211    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
    212212    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
     213   
     214    // Howard with iteration limit
     215    HowardMmc<GR, IntArcMap> mmc(gr, l1);
     216    check((mmc.findCycleMean(2) == HowardMmc<GR, IntArcMap>::ITERATION_LIMIT),
     217      "Wrong termination cause");
     218    check((mmc.findCycleMean(4) == HowardMmc<GR, IntArcMap>::OPTIMAL),
     219      "Wrong termination cause");
    213220  }
    214221
Note: See TracChangeset for help on using the changeset viewer.