COIN-OR::LEMON - Graph Library

Ticket #438: 438-ee2fe24de015-howard-limit.patch

File 438-ee2fe24de015-howard-limit.patch, 4.4 KB (added by Peter Kovacs, 8 years ago)
  • lemon/howard_mmc.h

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1328290203 -3600
    # Node ID ee2fe24de0158171e2cdacb5807d0a4daeb99d99
    # Parent  cfbabca1b4e9b8d4ce408f853db728509d020110
    Optional iteration limit in HowardMmc (#438)
    
    diff --git a/lemon/howard_mmc.h b/lemon/howard_mmc.h
    a b  
    149149    /// The \ref HowardMmcDefaultTraits "traits class" of the algorithm
    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(int) function returns one of
     156    /// these values.
     157    enum TerminationCause {
     158   
     159      /// Optimal solution (minimum cycle mean) is found.
     160      OPTIMAL,
     161     
     162      /// No directed cycle can be found in the digraph.
     163      NO_CYCLE,
     164
     165      /// The iteration count limit is reached.
     166      ITERATION_LIMIT
     167    };
     168
    152169  private:
    153170
    154171    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
     
    330347    /// cycles in the digraph.
    331348    ///
    332349    /// \return \c true if a directed cycle exists in the digraph.
     350    ///
     351    /// \note <tt>mmc.findCycleMean()</tt> is just a shortcut of the
     352    /// following code.
     353    /// \code
     354    ///   return mmc.findCycleMean(-1) == mmc.OPTIMAL;
     355    /// \endcode
    333356    bool findCycleMean() {
     357      return findCycleMean(-1) == OPTIMAL;
     358    }
     359
     360    /// \brief Find the minimum cycle mean.
     361    ///
     362    /// This function finds the minimum mean cost of the directed
     363    /// cycles in the digraph or at least an upper bound for it.
     364    /// At most the given number of iterations are performed during
     365    /// the search process. The return value indicates if the optimal
     366    /// solution is found or the iteration limit is reached.
     367    /// In the latter case, an approximate solution can be obtained
     368    /// using the query functions.
     369    /// Such an approximate solution corresponds to a directed cycle
     370    /// whose mean cost is relatively small, but not necessarily
     371    /// minimal.
     372    ///
     373    /// \param limit  The maximum allowed number of iterations duirng
     374    /// the search process. Negative values mean that this limitation
     375    /// is disabled, i.e. the algorithm runs until it finds the exact
     376    /// optimal solution.
     377    ///
     378    /// \return The termination cause of the search process.
     379    /// For more information, see \ref TerminationCause.
     380    TerminationCause findCycleMean(int limit) {
    334381      // Initialize and find strongly connected components
    335382      init();
    336383      findComponents();
     384     
     385      // Check iteration limit
     386      if (limit < 0) limit = std::numeric_limits<int>::max();
    337387
    338388      // Find the minimum cycle mean in the components
     389      int iter_count = 0;
     390      bool iter_limit = false;
    339391      for (int comp = 0; comp < _comp_num; ++comp) {
    340392        // Find the minimum mean cycle in the current component
    341393        if (!buildPolicyGraph(comp)) continue;
    342394        while (true) {
     395          if (++iter_count > limit) {
     396            iter_limit = true;
     397            break;
     398          }
    343399          findPolicyCycle();
    344400          if (!computeNodeDistances()) break;
    345401        }
     402
    346403        // Update the best cycle (global minimum mean cycle)
    347404        if ( _curr_found && (!_best_found ||
    348405             _curr_cost * _best_size < _best_cost * _curr_size) ) {
     
    351408          _best_size = _curr_size;
    352409          _best_node = _curr_node;
    353410        }
     411       
     412        if (iter_limit) break;
    354413      }
    355       return _best_found;
     414
     415      if (iter_limit) {
     416        return ITERATION_LIMIT;
     417      } else {
     418        return _best_found ? OPTIMAL : NO_CYCLE;
     419      }
    356420    }
    357421
    358422    /// \brief Find a minimum mean directed cycle.
  • test/min_mean_cycle_test.cc

    diff --git a/test/min_mean_cycle_test.cc b/test/min_mean_cycle_test.cc
    a b  
    210210    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
    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
    215222  return 0;