COIN-OR::LEMON - Graph Library

Ticket #638: 51691ae2d947.patch

File 51691ae2d947.patch, 7.8 KB (added by Balazs Dezso, 4 years ago)
  • lemon/matching.h

    # HG changeset patch
    # User Balazs Dezso <deba@google.com>
    # Date 1606764407 -3600
    #      Mon Nov 30 20:26:47 2020 +0100
    # Node ID 51691ae2d9473f9eca28f8a61645e4511b16ad43
    # Parent  8c567e298d7f3fad82cc66754f2fb6c4a420366b
    Factor out recursion from weighted matching algorithms
    
    Fixes:
    http://lemon.cs.elte.hu/trac/lemon/ticket/638
    
    diff -r 8c567e298d7f -r 51691ae2d947 lemon/matching.h
    a b  
    743743      int begin, end;
    744744      Value value;
    745745
    746       BlossomVariable(int _begin, int _end, Value _value)
    747         : begin(_begin), end(_end), value(_value) {}
     746      BlossomVariable(int _begin, Value _value)
     747          : begin(_begin), end(-1), value(_value) {}
    748748
    749749    };
    750750
     
    15211521      _tree_set->erase(blossom);
    15221522    }
    15231523
     1524    struct ExtractBlossomItem {
     1525      int blossom;
     1526      Node base;
     1527      Arc matching;
     1528      std::vector<int> closed;
     1529      ExtractBlossomItem(int _blossom, Node _base, Arc _matching)
     1530          : blossom(_blossom), base(_base), matching(_matching) {}
     1531    };
     1532
    15241533    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
    1525       if (_blossom_set->trivial(blossom)) {
    1526         int bi = (*_node_index)[base];
    1527         Value pot = (*_node_data)[bi].pot;
    1528 
    1529         (*_matching)[base] = matching;
    1530         _blossom_node_list.push_back(base);
    1531         (*_node_potential)[base] = pot;
    1532       } else {
    1533 
    1534         Value pot = (*_blossom_data)[blossom].pot;
    1535         int bn = _blossom_node_list.size();
    1536 
    1537         std::vector<int> subblossoms;
    1538         _blossom_set->split(blossom, std::back_inserter(subblossoms));
    1539         int b = _blossom_set->find(base);
    1540         int ib = -1;
    1541         for (int i = 0; i < int(subblossoms.size()); ++i) {
    1542           if (subblossoms[i] == b) { ib = i; break; }
     1534      std::vector<ExtractBlossomItem> stack;
     1535      stack.push_back(ExtractBlossomItem(blossom, base, matching));
     1536      while (!stack.empty()) {
     1537        if (_blossom_set->trivial(stack.back().blossom)) {
     1538          int bi = (*_node_index)[stack.back().base];
     1539          Value pot = (*_node_data)[bi].pot;
     1540
     1541          (*_matching)[stack.back().base] = stack.back().matching;
     1542          (*_node_potential)[stack.back().base] = pot;
     1543          _blossom_node_list.push_back(stack.back().base);
     1544          for (int i = 0; i < int(stack.back().closed.size()); ++i) {
     1545            _blossom_potential[stack.back().closed[i]].end = _blossom_node_list.size();
     1546          }
     1547          stack.pop_back();
     1548        } else {
     1549          Value pot = (*_blossom_data)[stack.back().blossom].pot;
     1550          int bn = _blossom_node_list.size();
     1551          stack.back().closed.push_back(_blossom_potential.size());
     1552          _blossom_potential.push_back(BlossomVariable(bn, pot));
     1553
     1554          std::vector<int> subblossoms;
     1555          _blossom_set->split(stack.back().blossom, std::back_inserter(subblossoms));
     1556          int b = _blossom_set->find(stack.back().base);
     1557          int ib = -1;
     1558          for (int i = 0; i < int(subblossoms.size()); ++i) {
     1559            if (subblossoms[i] == b) { ib = i; break; }
     1560          }
     1561
     1562          stack.back().blossom = subblossoms[ib];
     1563          for (int i = 1; i < int(subblossoms.size()); i += 2) {
     1564            int sb = subblossoms[(ib + i) % subblossoms.size()];
     1565            int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
     1566
     1567            Arc m = (*_blossom_data)[tb].next;
     1568            stack.push_back(ExtractBlossomItem(sb, _graph.target(m), _graph.oppositeArc(m)));
     1569            stack.push_back(ExtractBlossomItem(tb, _graph.source(m), m));
     1570          }
    15431571        }
    1544 
    1545         for (int i = 1; i < int(subblossoms.size()); i += 2) {
    1546           int sb = subblossoms[(ib + i) % subblossoms.size()];
    1547           int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
    1548 
    1549           Arc m = (*_blossom_data)[tb].next;
    1550           extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
    1551           extractBlossom(tb, _graph.source(m), m);
    1552         }
    1553         extractBlossom(subblossoms[ib], base, matching);
    1554 
    1555         int en = _blossom_node_list.size();
    1556 
    1557         _blossom_potential.push_back(BlossomVariable(bn, en, pot));
    15581572      }
    15591573    }
    15601574
     
    22162230      int begin, end;
    22172231      Value value;
    22182232
    2219       BlossomVariable(int _begin, int _end, Value _value)
    2220         : begin(_begin), end(_end), value(_value) {}
     2233      BlossomVariable(int _begin, Value _value)
     2234        : begin(_begin), value(_value) {}
    22212235
    22222236    };
    22232237
     
    29492963      _tree_set->erase(blossom);
    29502964    }
    29512965
     2966    struct ExtractBlossomItem {
     2967      int blossom;
     2968      Node base;
     2969      Arc matching;
     2970      std::vector<int> closed;
     2971      ExtractBlossomItem(int _blossom, Node _base, Arc _matching)
     2972          : blossom(_blossom), base(_base), matching(_matching) {}
     2973    };
     2974
    29522975    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
    2953       if (_blossom_set->trivial(blossom)) {
    2954         int bi = (*_node_index)[base];
    2955         Value pot = (*_node_data)[bi].pot;
    2956 
    2957         (*_matching)[base] = matching;
    2958         _blossom_node_list.push_back(base);
    2959         (*_node_potential)[base] = pot;
    2960       } else {
    2961 
    2962         Value pot = (*_blossom_data)[blossom].pot;
    2963         int bn = _blossom_node_list.size();
    2964 
    2965         std::vector<int> subblossoms;
    2966         _blossom_set->split(blossom, std::back_inserter(subblossoms));
    2967         int b = _blossom_set->find(base);
    2968         int ib = -1;
    2969         for (int i = 0; i < int(subblossoms.size()); ++i) {
    2970           if (subblossoms[i] == b) { ib = i; break; }
     2976      std::vector<ExtractBlossomItem> stack;
     2977      stack.push_back(ExtractBlossomItem(blossom, base, matching));
     2978      while (!stack.empty()) {
     2979        if (_blossom_set->trivial(stack.back().blossom)) {
     2980          int bi = (*_node_index)[stack.back().base];
     2981          Value pot = (*_node_data)[bi].pot;
     2982
     2983          (*_matching)[stack.back().base] = stack.back().matching;
     2984          (*_node_potential)[stack.back().base] = pot;
     2985          _blossom_node_list.push_back(stack.back().base);
     2986          for (int i = 0; i < int(stack.back().closed.size()); ++i) {
     2987            _blossom_potential[stack.back().closed[i]].end = _blossom_node_list.size();
     2988          }
     2989          stack.pop_back();
     2990        } else {
     2991          Value pot = (*_blossom_data)[stack.back().blossom].pot;
     2992          int bn = _blossom_node_list.size();
     2993          stack.back().closed.push_back(_blossom_potential.size());
     2994          _blossom_potential.push_back(BlossomVariable(bn, pot));
     2995
     2996          std::vector<int> subblossoms;
     2997          _blossom_set->split(stack.back().blossom, std::back_inserter(subblossoms));
     2998          int b = _blossom_set->find(stack.back().base);
     2999          int ib = -1;
     3000          for (int i = 0; i < int(subblossoms.size()); ++i) {
     3001            if (subblossoms[i] == b) { ib = i; break; }
     3002          }
     3003
     3004          stack.back().blossom = subblossoms[ib];
     3005          for (int i = 1; i < int(subblossoms.size()); i += 2) {
     3006            int sb = subblossoms[(ib + i) % subblossoms.size()];
     3007            int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
     3008
     3009            Arc m = (*_blossom_data)[tb].next;
     3010            stack.push_back(ExtractBlossomItem(sb, _graph.target(m), _graph.oppositeArc(m)));
     3011            stack.push_back(ExtractBlossomItem(tb, _graph.source(m), m));
     3012          }
    29713013        }
    2972 
    2973         for (int i = 1; i < int(subblossoms.size()); i += 2) {
    2974           int sb = subblossoms[(ib + i) % subblossoms.size()];
    2975           int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
    2976 
    2977           Arc m = (*_blossom_data)[tb].next;
    2978           extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
    2979           extractBlossom(tb, _graph.source(m), m);
    2980         }
    2981         extractBlossom(subblossoms[ib], base, matching);
    2982 
    2983         int en = _blossom_node_list.size();
    2984 
    2985         _blossom_potential.push_back(BlossomVariable(bn, en, pot));
    29863014      }
    29873015    }
    29883016