COIN-OR::LEMON - Graph Library

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


Ignore:
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • lemon/cycle_canceling.h

    r1013 r1003  
    3636#include <lemon/bellman_ford.h>
    3737#include <lemon/howard_mmc.h>
    38 #include <lemon/hartmann_orlin_mmc.h>
    3938
    4039namespace lemon {
     
    929928    // Execute the "Minimum Mean Cycle Canceling" method
    930929    void startMinMeanCycleCanceling() {
    931       typedef Path<StaticDigraph> SPath;
     930      typedef SimplePath<StaticDigraph> SPath;
    932931      typedef typename SPath::ArcIt SPathArcIt;
    933932      typedef typename HowardMmc<StaticDigraph, CostArcMap>
    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);
     933        ::template SetPath<SPath>::Create MMC;
    944934
    945935      SPath cycle;
    946       HwMmc hw_mmc(_sgr, _cost_map);
    947       hw_mmc.cycle(cycle);
     936      MMC mmc(_sgr, _cost_map);
     937      mmc.cycle(cycle);
    948938      buildResidualNetwork();
    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        
     939      while (mmc.findCycleMean() && mmc.cycleCost() < 0) {
     940        // Find the cycle
     941        mmc.findCycle();
     942
    967943        // Compute delta value
    968944        Value delta = INF;
     
    989965      const double LIMIT_FACTOR = 1.0;
    990966      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);
    997967
    998968      // Contruct auxiliary data vectors
     
    11681138          }
    11691139        } else {
    1170           typedef HowardMmc<StaticDigraph, CostArcMap> HwMmc;
    1171           typedef HartmannOrlinMmc<StaticDigraph, CostArcMap> HoMmc;
     1140          typedef HowardMmc<StaticDigraph, CostArcMap> MMC;
    11721141          typedef typename BellmanFord<StaticDigraph, CostArcMap>
    11731142            ::template SetDistMap<CostNodeMap>::Create BF;
    11741143
    11751144          // Set epsilon to the minimum cycle mean
    1176           Cost cycle_cost = 0;
    1177           int cycle_size = 1;
    11781145          buildResidualNetwork();
    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           }
     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();
    11941151
    11951152          // Compute feasible potentials for the current epsilon
  • lemon/howard_mmc.h

    r1012 r1002  
    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 
    169152  private:
    170153
     
    342325    }
    343326
    344     /// \brief Find the minimum cycle mean (or an upper bound).
     327    /// \brief Find the minimum cycle mean.
    345328    ///
    346329    /// This function finds the minimum mean cost of the directed
    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()) {
     330    /// cycles in the digraph.
     331    ///
     332    /// \return \c true if a directed cycle exists in the digraph.
     333    bool findCycleMean() {
    365334      // Initialize and find strongly connected components
    366335      init();
     
    368337
    369338      // Find the minimum cycle mean in the components
    370       int iter_count = 0;
    371       bool iter_limit_reached = false;
    372339      for (int comp = 0; comp < _comp_num; ++comp) {
    373340        // Find the minimum mean cycle in the current component
    374341        if (!buildPolicyGraph(comp)) continue;
    375342        while (true) {
    376           if (++iter_count > limit) {
    377             iter_limit_reached = true;
    378             break;
    379           }
    380343          findPolicyCycle();
    381344          if (!computeNodeDistances()) break;
    382345        }
    383 
    384346        // Update the best cycle (global minimum mean cycle)
    385347        if ( _curr_found && (!_best_found ||
     
    390352          _best_node = _curr_node;
    391353        }
    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       }
     354      }
     355      return _best_found;
    401356    }
    402357
  • test/min_mean_cycle_test.cc

    r1012 r877  
    111111                 int cost, int size) {
    112112  MMC alg(gr, lm);
    113   check(alg.findCycleMean(), "Wrong result");
     113  alg.findCycleMean();
    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");
    220213  }
    221214
Note: See TracChangeset for help on using the changeset viewer.