COIN-OR::LEMON - Graph Library

Ticket #127: 0915721396dc.patch

File 0915721396dc.patch, 7.9 KB (added by Balazs Dezso, 11 years ago)
  • lemon/core.h

    # HG changeset patch
    # User Balazs Dezso <deba@inf.elte.hu>
    # Date 1216723993 -7200
    # Node ID 0915721396dcdb9490e648fbe2b93621ec303c4e
    # Parent  b6732e0d38c5c5e6b21123d8425a62591491e391
    Bug fix and interface change in DynArcLookUp (ticket #127)
    
    The bug fix is related to erase and lookup
    
    diff -r b6732e0d38c5 -r 0915721396dc lemon/core.h
    a b  
    11671167  ///Dynamic arc look up between given endpoints.
    11681168
    11691169  ///Using this class, you can find an arc in a digraph from a given
    1170   ///source to a given target in amortized time <em>O(log d)</em>,
     1170  ///source to a given target in amortized time <em>O(log</em>d<em>)</em>,
    11711171  ///where <em>d</em> is the out-degree of the source node.
    11721172  ///
    11731173  ///It is possible to find \e all parallel arcs between two nodes with
    1174   ///the \c findFirst() and \c findNext() members.
     1174  ///the \c operator() member.
    11751175  ///
    11761176  ///See the \ref ArcLookUp and \ref AllArcLookUp classes if your
    11771177  ///digraph is not changed so frequently.
     
    13801380        } else {
    13811381          _right.set(e, _right[arc]);
    13821382          _parent.set(_right[arc], e);
     1383          _parent.set(e, _parent[arc]);
    13831384
    13841385          if (_parent[arc] != INVALID) {
    13851386            if (_left[_parent[arc]] == arc) {
     
    13941395      }
    13951396    }
    13961397
    1397     Arc refreshRec(std::vector<Arc> &v,int a,int b)
     1398    Arc refreshRec(std::vector<Arc> &v, int a, int b)
    13981399    {
    1399       int m=(a+b)/2;
    1400       Arc me=v[m];
     1400      int m = (a + b) / 2;
     1401      Arc me = v[m];
    14011402      if (a < m) {
    1402         Arc left = refreshRec(v,a,m-1);
     1403        Arc left = refreshRec(v, a, m - 1);
    14031404        _left.set(me, left);
    14041405        _parent.set(left, me);
    14051406      } else {
    14061407        _left.set(me, INVALID);
    14071408      }
    14081409      if (m < b) {
    1409         Arc right = refreshRec(v,m+1,b);
     1410        Arc right = refreshRec(v, m + 1, b);
    14101411        _right.set(me, right);
    14111412        _parent.set(right, me);
    14121413      } else {
     
    14161417    }
    14171418
    14181419    void refresh() {
    1419       for(NodeIt n(_g);n!=INVALID;++n) {
     1420      for(NodeIt n(_g); n != INVALID; ++n) {
    14201421        std::vector<Arc> v;
    1421         for(OutArcIt e(_g,n);e!=INVALID;++e) v.push_back(e);
    1422         if(v.size()) {
     1422        for(OutArcIt a(_g, n); a != INVALID; ++a) v.push_back(a);
     1423        if (!v.empty()) {
    14231424          std::sort(v.begin(),v.end(),ArcLess(_g));
    1424           Arc head = refreshRec(v,0,v.size()-1);
     1425          Arc head = refreshRec(v, 0, v.size() - 1);
    14251426          _head.set(n, head);
    14261427          _parent.set(head, INVALID);
    14271428        }
     
    14991500
    15001501  public:
    15011502
     1503
    15021504    ///Find an arc between two nodes.
    15031505
    1504     ///Find an arc between two nodes in time <em>O(</em>log<em>d)</em>, where
    1505     /// <em>d</em> is the number of outgoing arcs of \c s.
     1506    ///Find an arc between two nodes.
    15061507    ///\param s The source node
    15071508    ///\param t The target node
    1508     ///\return An arc from \c s to \c t if there exists,
    1509     ///\ref INVALID otherwise.
    1510     Arc operator()(Node s, Node t) const
     1509    ///\param p The previous arc between \c s and \c t. It it is INVALID or
     1510    ///not given, the operator finds the first appropriate arc.
     1511    ///\return An arc from \c s to \c t after \c p or
     1512    ///\ref INVALID if there is no more.
     1513    ///
     1514    ///For example, you can count the number of arcs from \c u to \c v in the
     1515    ///following way.
     1516    ///\code
     1517    ///DynArcLookUp<ListDigraph> ae(g);
     1518    ///...
     1519    ///int n=0;
     1520    ///for(Arc e=ae(u,v);e!=INVALID;e=ae(u,v,e)) n++;
     1521    ///\endcode
     1522    ///
     1523    ///Finding the arcs take at most <em>O(</em>log<em>d)</em>
     1524    ///amortized time, specifically, the time complexity of the lookups
     1525    ///is equal to the optimal search tree implementation for the
     1526    ///current query distribution in a constant factor.
     1527    ///
     1528    ///\note This is a dynamic data structure, therefore the data
     1529    ///structure is updated after each graph alteration. However,
     1530    ///theoretically this data structure is faster than \c ArcLookUp
     1531    ///or AllEdgeLookup, but it often provides worse performance than
     1532    ///them.
     1533    ///
     1534    Arc operator()(Node s, Node t, Arc p = INVALID) const
    15111535    {
    1512       Arc a = _head[s];
    1513       while (true) {
    1514         if (_g.target(a) == t) {
     1536      if (p == INVALID) {
     1537        Arc a = _head[s];
     1538        if (a == INVALID) return INVALID;
     1539        Arc r = INVALID;
     1540        while (true) {
     1541          if (_g.target(a) < t) {
     1542            if (_right[a] == INVALID) {
     1543              const_cast<DynArcLookUp&>(*this).splay(a);
     1544              return r;
     1545            } else {
     1546              a = _right[a];
     1547            }
     1548          } else {
     1549            if (_g.target(a) == t) {
     1550              r = a;
     1551            }
     1552            if (_left[a] == INVALID) {
     1553              const_cast<DynArcLookUp&>(*this).splay(a);
     1554              return r;
     1555            } else {
     1556              a = _left[a];
     1557            }
     1558          }
     1559        }
     1560      } else {
     1561        Arc a = p;
     1562        if (_right[a] != INVALID) {
     1563          a = _right[a];
     1564          while (_left[a] != INVALID) {
     1565            a = _left[a];
     1566          }
    15151567          const_cast<DynArcLookUp&>(*this).splay(a);
    1516           return a;
    1517         } else if (t < _g.target(a)) {
    1518           if (_left[a] == INVALID) {
    1519             const_cast<DynArcLookUp&>(*this).splay(a);
     1568        } else {
     1569          while (_parent[a] != INVALID && _right[_parent[a]] ==  a) {
     1570            a = _parent[a];
     1571          }
     1572          if (_parent[a] == INVALID) {
    15201573            return INVALID;
    15211574          } else {
    1522             a = _left[a];
    1523           }
    1524         } else  {
    1525           if (_right[a] == INVALID) {
     1575            a = _parent[a];
    15261576            const_cast<DynArcLookUp&>(*this).splay(a);
    1527             return INVALID;
    1528           } else {
    1529             a = _right[a];
    15301577          }
    15311578        }
     1579        if (_g.target(a) == t) return a;
     1580        else return INVALID;
    15321581      }
    1533     }
    1534 
    1535     ///Find the first arc between two nodes.
    1536 
    1537     ///Find the first arc between two nodes in time
    1538     /// <em>O(</em>log<em>d)</em>, where <em>d</em> is the number of
    1539     /// outgoing arcs of \c s.
    1540     ///\param s The source node
    1541     ///\param t The target node
    1542     ///\return An arc from \c s to \c t if there exists, \ref INVALID
    1543     /// otherwise.
    1544     Arc findFirst(Node s, Node t) const
    1545     {
    1546       Arc a = _head[s];
    1547       Arc r = INVALID;
    1548       while (true) {
    1549         if (_g.target(a) < t) {
    1550           if (_right[a] == INVALID) {
    1551             const_cast<DynArcLookUp&>(*this).splay(a);
    1552             return r;
    1553           } else {
    1554             a = _right[a];
    1555           }
    1556         } else {
    1557           if (_g.target(a) == t) {
    1558             r = a;
    1559           }
    1560           if (_left[a] == INVALID) {
    1561             const_cast<DynArcLookUp&>(*this).splay(a);
    1562             return r;
    1563           } else {
    1564             a = _left[a];
    1565           }
    1566         }
    1567       }
    1568     }
    1569 
    1570     ///Find the next arc between two nodes.
    1571 
    1572     ///Find the next arc between two nodes in time
    1573     /// <em>O(</em>log<em>d)</em>, where <em>d</em> is the number of
    1574     /// outgoing arcs of \c s.
    1575     ///\param s The source node
    1576     ///\param t The target node
    1577     ///\return An arc from \c s to \c t if there exists, \ref INVALID
    1578     /// otherwise.
    1579 
    1580     ///\note If \c e is not the result of the previous \c findFirst()
    1581     ///operation then the amorized time bound can not be guaranteed.
    1582 #ifdef DOXYGEN
    1583     Arc findNext(Node s, Node t, Arc a) const
    1584 #else
    1585     Arc findNext(Node, Node t, Arc a) const
    1586 #endif
    1587     {
    1588       if (_right[a] != INVALID) {
    1589         a = _right[a];
    1590         while (_left[a] != INVALID) {
    1591           a = _left[a];
    1592         }
    1593         const_cast<DynArcLookUp&>(*this).splay(a);
    1594       } else {
    1595         while (_parent[a] != INVALID && _right[_parent[a]] ==  a) {
    1596           a = _parent[a];
    1597         }
    1598         if (_parent[a] == INVALID) {
    1599           return INVALID;
    1600         } else {
    1601           a = _parent[a];
    1602           const_cast<DynArcLookUp&>(*this).splay(a);
    1603         }
    1604       }
    1605       if (_g.target(a) == t) return a;
    1606       else return INVALID;
    16071582    }
    16081583
    16091584  };