COIN-OR::LEMON - Graph Library

Ticket #620: fp-nagamochi-ibaraki-89dd204d3d12.patch

File fp-nagamochi-ibaraki-89dd204d3d12.patch, 3.4 KB (added by Malte Schürks, 6 years ago)
  • lemon/nagamochi_ibaraki.h

    # HG changeset patch
    # User Malte SchÃŒrks <s6jnschu@uni-bonn.de>
    # Date 1549222758 -3600
    #      Sun Feb 03 20:39:18 2019 +0100
    # Node ID 89dd204d3d126f89c40f1a2a9e050dd9a6db68bb
    # Parent  8c567e298d7f3fad82cc66754f2fb6c4a420366b
    Fix infinite loops when using Nagamochi-Ibaraki on graphs with floating-point capacities
    
    diff --git a/lemon/nagamochi_ibaraki.h b/lemon/nagamochi_ibaraki.h
    a b  
    3030#include <lemon/maps.h>
    3131#include <lemon/radix_sort.h>
    3232#include <lemon/unionfind.h>
     33#include <lemon/tolerance.h>
    3334
    3435#include <cassert>
    3536
     
    9899    static Heap *createHeap(HeapCrossRef& r) {
    99100      return new Heap(r);
    100101    }
     102
     103    /// \brief The tolerance used by the algorithm
     104    ///
     105    /// The tolerance used by the algorithm to handle inexact computation.
     106    typedef lemon::Tolerance<Value> Tolerance;
    101107  };
    102108
    103109  /// \ingroup min_cut
     
    275281
    276282    typedef typename Graph::template NodeMap<bool> MinCutMap;
    277283    MinCutMap *_cut_map;
     284   
     285    typedef typename Traits::Tolerance Tolerance;
     286    Tolerance _tolerance;
    278287
    279288    void createStructures() {
    280289      if (!_nodes) {
     
    560569           n != INVALID; n = (*_nodes)[n].next) {
    561570        bool merged = false;
    562571        for (int a = (*_nodes)[n].first_arc; a != -1; a = _arcs[a].next) {
    563           if (!(_edges[a >> 1].cut < pmc)) {
     572          if (!_tolerance.less(_edges[a >> 1].cut, pmc)) {
    564573            if (!merged) {
    565574              for (int b = (*_nodes)[n].first_arc; b != -1; b = _arcs[b].next) {
    566575                (*_nodes)[_arcs[b].target].curr_arc = b;
  • test/nagamochi_ibaraki_test.cc

    diff --git a/test/nagamochi_ibaraki_test.cc b/test/nagamochi_ibaraki_test.cc
    a b  
    4040  "4\n"
    4141  "5\n"
    4242  "@edges\n"
    43   "     cap1 cap2 cap3\n"
    44   "0 1  1    1    1   \n"
    45   "0 2  2    2    4   \n"
    46   "1 2  4    4    4   \n"
    47   "3 4  1    1    1   \n"
    48   "3 5  2    2    4   \n"
    49   "4 5  4    4    4   \n"
    50   "2 3  1    6    6   \n";
     43  "     cap1 cap2 cap3 cap4\n"
     44  "0 1  1    1    1    1   \n"
     45  "0 2  2    2    4    1   \n"
     46  "1 2  4    4    4    1   \n"
     47  "3 4  1    1    1    1e-4\n"
     48  "3 5  2    2    4    1e-5\n"
     49  "4 5  4    4    4    1   \n"
     50  "2 3  1    6    6    1   \n";
    5151
    5252void checkNagamochiIbarakiCompile()
    5353{
     
    9595int main() {
    9696  SmartGraph graph;
    9797  SmartGraph::EdgeMap<int> cap1(graph), cap2(graph), cap3(graph);
     98  SmartGraph::EdgeMap<double> cap4(graph);
    9899  SmartGraph::NodeMap<bool> cut(graph);
    99100
    100101  istringstream input(lgf);
     
    102103    .edgeMap("cap1", cap1)
    103104    .edgeMap("cap2", cap2)
    104105    .edgeMap("cap3", cap3)
     106    .edgeMap("cap4", cap4)
    105107    .run();
    106108
    107109  {
     
    133135    ni.run();
    134136    ni.minCutMap(cut);
    135137
    136     ConstMap<SmartGraph::Edge, int> cap4(1);
     138    ConstMap<SmartGraph::Edge, int> cap5(1);
    137139    check(ni.minCutValue() == 1, "Wrong cut value");
    138     check(ni.minCutValue() == cutValue(graph, cap4, cut), "Wrong cut value");
     140    check(ni.minCutValue() == cutValue(graph, cap5, cut), "Wrong cut value");
     141  }
     142  {
     143    NagamochiIbaraki<SmartGraph, SmartGraph::EdgeMap<double>> ni(graph, cap4);
     144    ni.run();
     145    ni.minCutMap(cut);
     146
     147    Tolerance<double> tolerance;
     148    check(!tolerance.different(ni.minCutValue(), 1.1e-4), "Wrong cut value");
     149    check(!tolerance.different(ni.minCutValue(), cutValue(graph, cap4, cut)), "Wrong cut value");
    139150  }
    140151
    141152  return 0;