Ticket #127: 0915721396dc.patch
File 0915721396dc.patch, 7.9 KB (added by , 16 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 1167 1167 ///Dynamic arc look up between given endpoints. 1168 1168 1169 1169 ///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>, 1171 1171 ///where <em>d</em> is the out-degree of the source node. 1172 1172 /// 1173 1173 ///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. 1175 1175 /// 1176 1176 ///See the \ref ArcLookUp and \ref AllArcLookUp classes if your 1177 1177 ///digraph is not changed so frequently. … … 1380 1380 } else { 1381 1381 _right.set(e, _right[arc]); 1382 1382 _parent.set(_right[arc], e); 1383 _parent.set(e, _parent[arc]); 1383 1384 1384 1385 if (_parent[arc] != INVALID) { 1385 1386 if (_left[_parent[arc]] == arc) { … … 1394 1395 } 1395 1396 } 1396 1397 1397 Arc refreshRec(std::vector<Arc> &v, int a,int b)1398 Arc refreshRec(std::vector<Arc> &v, int a, int b) 1398 1399 { 1399 int m =(a+b)/2;1400 Arc me =v[m];1400 int m = (a + b) / 2; 1401 Arc me = v[m]; 1401 1402 if (a < m) { 1402 Arc left = refreshRec(v, a,m-1);1403 Arc left = refreshRec(v, a, m - 1); 1403 1404 _left.set(me, left); 1404 1405 _parent.set(left, me); 1405 1406 } else { 1406 1407 _left.set(me, INVALID); 1407 1408 } 1408 1409 if (m < b) { 1409 Arc right = refreshRec(v, m+1,b);1410 Arc right = refreshRec(v, m + 1, b); 1410 1411 _right.set(me, right); 1411 1412 _parent.set(right, me); 1412 1413 } else { … … 1416 1417 } 1417 1418 1418 1419 void refresh() { 1419 for(NodeIt n(_g); n!=INVALID;++n) {1420 for(NodeIt n(_g); n != INVALID; ++n) { 1420 1421 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()) { 1423 1424 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); 1425 1426 _head.set(n, head); 1426 1427 _parent.set(head, INVALID); 1427 1428 } … … 1499 1500 1500 1501 public: 1501 1502 1503 1502 1504 ///Find an arc between two nodes. 1503 1505 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. 1506 1507 ///\param s The source node 1507 1508 ///\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 1511 1535 { 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 } 1515 1567 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) { 1520 1573 return INVALID; 1521 1574 } else { 1522 a = _left[a]; 1523 } 1524 } else { 1525 if (_right[a] == INVALID) { 1575 a = _parent[a]; 1526 1576 const_cast<DynArcLookUp&>(*this).splay(a); 1527 return INVALID;1528 } else {1529 a = _right[a];1530 1577 } 1531 1578 } 1579 if (_g.target(a) == t) return a; 1580 else return INVALID; 1532 1581 } 1533 }1534 1535 ///Find the first arc between two nodes.1536 1537 ///Find the first arc between two nodes in time1538 /// <em>O(</em>log<em>d)</em>, where <em>d</em> is the number of1539 /// outgoing arcs of \c s.1540 ///\param s The source node1541 ///\param t The target node1542 ///\return An arc from \c s to \c t if there exists, \ref INVALID1543 /// otherwise.1544 Arc findFirst(Node s, Node t) const1545 {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 time1573 /// <em>O(</em>log<em>d)</em>, where <em>d</em> is the number of1574 /// outgoing arcs of \c s.1575 ///\param s The source node1576 ///\param t The target node1577 ///\return An arc from \c s to \c t if there exists, \ref INVALID1578 /// 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 DOXYGEN1583 Arc findNext(Node s, Node t, Arc a) const1584 #else1585 Arc findNext(Node, Node t, Arc a) const1586 #endif1587 {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;1607 1582 } 1608 1583 1609 1584 };