gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Improvements related to BFS/DFS/Dijkstra (ticket #96) - Add run(s,t) function to BfsVisit. - Modify run(s,t) functions in the class interfaces to return bool value. - Bug fix in Dijkstra::start(t) function. - Improve Dijkstra::currentDist(). - Extend test files to check named class template parameters. - Doc improvements.
0 6 0
default
6 files changed with 195 insertions and 89 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -607,11 +607,11 @@
607 607
    ///Executes the algorithm until the given target node is reached.
608 608
    ///
609 609
    ///This method runs the %BFS algorithm from the root node(s)
610
    ///in order to compute the shortest path to \c dest.
610
    ///in order to compute the shortest path to \c t.
611 611
    ///
612 612
    ///The algorithm computes
613
    ///- the shortest path to \c dest,
614
    ///- the distance of \c dest from the root(s).
613
    ///- the shortest path to \c t,
614
    ///- the distance of \c t from the root(s).
615 615
    ///
616 616
    ///\pre init() must be called and at least one root node should be
617 617
    ///added with addSource() before using this function.
... ...
@@ -623,10 +623,10 @@
623 623
    ///    b.processNextNode(t, reach);
624 624
    ///  }
625 625
    ///\endcode
626
    void start(Node dest)
626
    void start(Node t)
627 627
    {
628 628
      bool reach = false;
629
      while ( !emptyQueue() && !reach ) processNextNode(dest, reach);
629
      while ( !emptyQueue() && !reach ) processNextNode(t, reach);
630 630
    }
631 631

	
632 632
    ///Executes the algorithm until a condition is met.
... ...
@@ -664,7 +664,7 @@
664 664
      return rnode;
665 665
    }
666 666

	
667
    ///Runs the algorithm from the given node.
667
    ///Runs the algorithm from the given source node.
668 668

	
669 669
    ///This method runs the %BFS algorithm from node \c s
670 670
    ///in order to compute the shortest path to each node.
... ...
@@ -688,10 +688,10 @@
688 688
    ///Finds the shortest path between \c s and \c t.
689 689

	
690 690
    ///This method runs the %BFS algorithm from node \c s
691
    ///in order to compute the shortest path to \c t.
691
    ///in order to compute the shortest path to node \c t
692
    ///(it stops searching when \c t is processed).
692 693
    ///
693
    ///\return The length of the shortest <tt>s</tt>--<tt>t</tt> path,
694
    ///if \c t is reachable form \c s, \c 0 otherwise.
694
    ///\return \c true if \c t is reachable form \c s.
695 695
    ///
696 696
    ///\note Apart from the return value, <tt>b.run(s,t)</tt> is just a
697 697
    ///shortcut of the following code.
... ...
@@ -700,11 +700,11 @@
700 700
    ///  b.addSource(s);
701 701
    ///  b.start(t);
702 702
    ///\endcode
703
    int run(Node s,Node t) {
703
    bool run(Node s,Node t) {
704 704
      init();
705 705
      addSource(s);
706 706
      start(t);
707
      return reached(t) ? _curr_dist : 0;
707
      return reached(t);
708 708
    }
709 709

	
710 710
    ///Runs the algorithm to visit all nodes in the digraph.
... ...
@@ -1621,11 +1621,11 @@
1621 1621
    /// Executes the algorithm until the given target node is reached.
1622 1622
    ///
1623 1623
    /// This method runs the %BFS algorithm from the root node(s)
1624
    /// in order to compute the shortest path to \c dest.
1624
    /// in order to compute the shortest path to \c t.
1625 1625
    ///
1626 1626
    /// The algorithm computes
1627
    /// - the shortest path to \c dest,
1628
    /// - the distance of \c dest from the root(s).
1627
    /// - the shortest path to \c t,
1628
    /// - the distance of \c t from the root(s).
1629 1629
    ///
1630 1630
    /// \pre init() must be called and at least one root node should be
1631 1631
    /// added with addSource() before using this function.
... ...
@@ -1637,9 +1637,9 @@
1637 1637
    ///     b.processNextNode(t, reach);
1638 1638
    ///   }
1639 1639
    /// \endcode
1640
    void start(Node dest) {
1640
    void start(Node t) {
1641 1641
      bool reach = false;
1642
      while ( !emptyQueue() && !reach ) processNextNode(dest, reach);
1642
      while ( !emptyQueue() && !reach ) processNextNode(t, reach);
1643 1643
    }
1644 1644

	
1645 1645
    /// \brief Executes the algorithm until a condition is met.
... ...
@@ -1677,7 +1677,7 @@
1677 1677
      return rnode;
1678 1678
    }
1679 1679

	
1680
    /// \brief Runs the algorithm from the given node.
1680
    /// \brief Runs the algorithm from the given source node.
1681 1681
    ///
1682 1682
    /// This method runs the %BFS algorithm from node \c s
1683 1683
    /// in order to compute the shortest path to each node.
... ...
@@ -1698,6 +1698,28 @@
1698 1698
      start();
1699 1699
    }
1700 1700

	
1701
    /// \brief Finds the shortest path between \c s and \c t.
1702
    ///
1703
    /// This method runs the %BFS algorithm from node \c s
1704
    /// in order to compute the shortest path to node \c t
1705
    /// (it stops searching when \c t is processed).
1706
    ///
1707
    /// \return \c true if \c t is reachable form \c s.
1708
    ///
1709
    /// \note Apart from the return value, <tt>b.run(s,t)</tt> is just a
1710
    /// shortcut of the following code.
1711
    ///\code
1712
    ///   b.init();
1713
    ///   b.addSource(s);
1714
    ///   b.start(t);
1715
    ///\endcode
1716
    bool run(Node s,Node t) {
1717
      init();
1718
      addSource(s);
1719
      start(t);
1720
      return reached(t);
1721
    }
1722

	
1701 1723
    /// \brief Runs the algorithm to visit all nodes in the digraph.
1702 1724
    ///
1703 1725
    /// This method runs the %BFS algorithm in order to
Ignore white space 6 line context
... ...
@@ -558,17 +558,17 @@
558 558
    ///Executes the algorithm until the given target node is reached.
559 559
    ///
560 560
    ///This method runs the %DFS algorithm from the root node
561
    ///in order to compute the DFS path to \c dest.
561
    ///in order to compute the DFS path to \c t.
562 562
    ///
563 563
    ///The algorithm computes
564
    ///- the %DFS path to \c dest,
565
    ///- the distance of \c dest from the root in the %DFS tree.
564
    ///- the %DFS path to \c t,
565
    ///- the distance of \c t from the root in the %DFS tree.
566 566
    ///
567 567
    ///\pre init() must be called and a root node should be
568 568
    ///added with addSource() before using this function.
569
    void start(Node dest)
569
    void start(Node t)
570 570
    {
571
      while ( !emptyQueue() && G->target(_stack[_stack_head])!=dest )
571
      while ( !emptyQueue() && G->target(_stack[_stack_head])!=t )
572 572
        processNextArc();
573 573
    }
574 574

	
... ...
@@ -598,7 +598,7 @@
598 598
      return emptyQueue() ? INVALID : _stack[_stack_head];
599 599
    }
600 600

	
601
    ///Runs the algorithm from the given node.
601
    ///Runs the algorithm from the given source node.
602 602

	
603 603
    ///This method runs the %DFS algorithm from node \c s
604 604
    ///in order to compute the DFS path to each node.
... ...
@@ -622,10 +622,10 @@
622 622
    ///Finds the %DFS path between \c s and \c t.
623 623

	
624 624
    ///This method runs the %DFS algorithm from node \c s
625
    ///in order to compute the DFS path to \c t.
625
    ///in order to compute the DFS path to node \c t
626
    ///(it stops searching when \c t is processed)
626 627
    ///
627
    ///\return The length of the <tt>s</tt>--<tt>t</tt> DFS path,
628
    ///if \c t is reachable form \c s, \c 0 otherwise.
628
    ///\return \c true if \c t is reachable form \c s.
629 629
    ///
630 630
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is
631 631
    ///just a shortcut of the following code.
... ...
@@ -634,11 +634,11 @@
634 634
    ///  d.addSource(s);
635 635
    ///  d.start(t);
636 636
    ///\endcode
637
    int run(Node s,Node t) {
637
    bool run(Node s,Node t) {
638 638
      init();
639 639
      addSource(s);
640 640
      start(t);
641
      return reached(t)?_stack_head+1:0;
641
      return reached(t);
642 642
    }
643 643

	
644 644
    ///Runs the algorithm to visit all nodes in the digraph.
... ...
@@ -1526,16 +1526,16 @@
1526 1526
    /// Executes the algorithm until the given target node is reached.
1527 1527
    ///
1528 1528
    /// This method runs the %DFS algorithm from the root node
1529
    /// in order to compute the DFS path to \c dest.
1529
    /// in order to compute the DFS path to \c t.
1530 1530
    ///
1531 1531
    /// The algorithm computes
1532
    /// - the %DFS path to \c dest,
1533
    /// - the distance of \c dest from the root in the %DFS tree.
1532
    /// - the %DFS path to \c t,
1533
    /// - the distance of \c t from the root in the %DFS tree.
1534 1534
    ///
1535 1535
    /// \pre init() must be called and a root node should be added
1536 1536
    /// with addSource() before using this function.
1537
    void start(Node dest) {
1538
      while ( !emptyQueue() && _digraph->target(_stack[_stack_head]) != dest )
1537
    void start(Node t) {
1538
      while ( !emptyQueue() && _digraph->target(_stack[_stack_head]) != t )
1539 1539
        processNextArc();
1540 1540
    }
1541 1541

	
... ...
@@ -1564,7 +1564,7 @@
1564 1564
      return emptyQueue() ? INVALID : _stack[_stack_head];
1565 1565
    }
1566 1566

	
1567
    /// \brief Runs the algorithm from the given node.
1567
    /// \brief Runs the algorithm from the given source node.
1568 1568
    ///
1569 1569
    /// This method runs the %DFS algorithm from node \c s.
1570 1570
    /// in order to compute the DFS path to each node.
... ...
@@ -1588,10 +1588,10 @@
1588 1588
    /// \brief Finds the %DFS path between \c s and \c t.
1589 1589

	
1590 1590
    /// This method runs the %DFS algorithm from node \c s
1591
    /// in order to compute the DFS path to \c t.
1591
    /// in order to compute the DFS path to node \c t
1592
    /// (it stops searching when \c t is processed).
1592 1593
    ///
1593
    /// \return The length of the <tt>s</tt>--<tt>t</tt> DFS path,
1594
    /// if \c t is reachable form \c s, \c 0 otherwise.
1594
    /// \return \c true if \c t is reachable form \c s.
1595 1595
    ///
1596 1596
    /// \note Apart from the return value, <tt>d.run(s,t)</tt> is
1597 1597
    /// just a shortcut of the following code.
... ...
@@ -1600,11 +1600,11 @@
1600 1600
    ///   d.addSource(s);
1601 1601
    ///   d.start(t);
1602 1602
    ///\endcode
1603
    int run(Node s,Node t) {
1603
    bool run(Node s,Node t) {
1604 1604
      init();
1605 1605
      addSource(s);
1606 1606
      start(t);
1607
      return reached(t)?_stack_head+1:0;
1607
      return reached(t);
1608 1608
    }
1609 1609

	
1610 1610
    /// \brief Runs the algorithm to visit all nodes in the digraph.
Ignore white space 6 line context
... ...
@@ -728,23 +728,26 @@
728 728
      while ( !emptyQueue() ) processNextNode();
729 729
    }
730 730

	
731
    ///Executes the algorithm until the given target node is reached.
731
    ///Executes the algorithm until the given target node is processed.
732 732

	
733
    ///Executes the algorithm until the given target node is reached.
733
    ///Executes the algorithm until the given target node is processed.
734 734
    ///
735 735
    ///This method runs the %Dijkstra algorithm from the root node(s)
736
    ///in order to compute the shortest path to \c dest.
736
    ///in order to compute the shortest path to \c t.
737 737
    ///
738 738
    ///The algorithm computes
739
    ///- the shortest path to \c dest,
740
    ///- the distance of \c dest from the root(s).
739
    ///- the shortest path to \c t,
740
    ///- the distance of \c t from the root(s).
741 741
    ///
742 742
    ///\pre init() must be called and at least one root node should be
743 743
    ///added with addSource() before using this function.
744
    void start(Node dest)
744
    void start(Node t)
745 745
    {
746
      while ( !_heap->empty() && _heap->top()!=dest ) processNextNode();
747
      if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
746
      while ( !_heap->empty() && _heap->top()!=t ) processNextNode();
747
      if ( !_heap->empty() ) {
748
        finalizeNodeData(_heap->top(),_heap->prio());
749
        _heap->pop();
750
      }
748 751
    }
749 752

	
750 753
    ///Executes the algorithm until a condition is met.
... ...
@@ -772,7 +775,7 @@
772 775
      return _heap->top();
773 776
    }
774 777

	
775
    ///Runs the algorithm from the given node.
778
    ///Runs the algorithm from the given source node.
776 779

	
777 780
    ///This method runs the %Dijkstra algorithm from node \c s
778 781
    ///in order to compute the shortest path to each node.
... ...
@@ -796,10 +799,10 @@
796 799
    ///Finds the shortest path between \c s and \c t.
797 800

	
798 801
    ///This method runs the %Dijkstra algorithm from node \c s
799
    ///in order to compute the shortest path to \c t.
802
    ///in order to compute the shortest path to node \c t
803
    ///(it stops searching when \c t is processed).
800 804
    ///
801
    ///\return The length of the shortest <tt>s</tt>--<tt>t</tt> path,
802
    ///if \c t is reachable form \c s, \c 0 otherwise.
805
    ///\return \c true if \c t is reachable form \c s.
803 806
    ///
804 807
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is just a
805 808
    ///shortcut of the following code.
... ...
@@ -808,11 +811,11 @@
808 811
    ///  d.addSource(s);
809 812
    ///  d.start(t);
810 813
    ///\endcode
811
    Value run(Node s,Node t) {
814
    bool run(Node s,Node t) {
812 815
      init();
813 816
      addSource(s);
814 817
      start(t);
815
      return (*_pred)[t]==INVALID?OperationTraits::zero():(*_dist)[t];
818
      return (*_heap_cross_ref)[t] == Heap::POST_HEAP;
816 819
    }
817 820

	
818 821
    ///@}
... ...
@@ -908,7 +911,7 @@
908 911

	
909 912
    ///Returns \c true if \c v is processed, i.e. the shortest
910 913
    ///path to \c v has already found.
911
    ///\pre Either \ref run() or \ref start()
914
    ///\pre Either \ref run() or \ref init()
912 915
    ///must be called before using this function.
913 916
    bool processed(Node v) const { return (*_heap_cross_ref)[v] ==
914 917
                                          Heap::POST_HEAP; }
... ...
@@ -917,8 +920,12 @@
917 920

	
918 921
    ///Returns the current distance of a node from the root(s).
919 922
    ///It may be decreased in the following processes.
920
    ///\pre \c v should be reached but not processed.
921
    Value currentDist(Node v) const { return (*_heap)[v]; }
923
    ///\pre Either \ref run() or \ref init()
924
    ///must be called before using this function and
925
    ///node \c v must be reached but not necessarily processed.
926
    Value currentDist(Node v) const {
927
      return processed(v) ? (*_dist)[v] : (*_heap)[v];
928
    }
922 929

	
923 930
    ///@}
924 931
  };
Ignore white space 6 line context
... ...
@@ -54,27 +54,52 @@
54 54
{
55 55
  typedef concepts::Digraph Digraph;
56 56
  typedef Bfs<Digraph> BType;
57
  typedef Digraph::Node Node;
58
  typedef Digraph::Arc Arc;
57 59

	
58 60
  Digraph G;
59
  Digraph::Node n;
60
  Digraph::Arc e;
61
  Node s, t;
62
  Arc e;
61 63
  int l;
62 64
  bool b;
63 65
  BType::DistMap d(G);
64 66
  BType::PredMap p(G);
67
  Path<Digraph> pp;
65 68

	
66
  BType bfs_test(G);
69
  {
70
    BType bfs_test(G);
67 71

	
68
  bfs_test.run(n);
72
    bfs_test.run(s);
73
    bfs_test.run(s,t);
74
    bfs_test.run();
69 75

	
70
  l  = bfs_test.dist(n);
71
  e  = bfs_test.predArc(n);
72
  n  = bfs_test.predNode(n);
73
  d  = bfs_test.distMap();
74
  p  = bfs_test.predMap();
75
  b  = bfs_test.reached(n);
76
    l  = bfs_test.dist(t);
77
    e  = bfs_test.predArc(t);
78
    s  = bfs_test.predNode(t);
79
    b  = bfs_test.reached(t);
80
    d  = bfs_test.distMap();
81
    p  = bfs_test.predMap();
82
    pp = bfs_test.path(t);
83
  }
84
  {
85
    BType
86
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
87
      ::SetDistMap<concepts::ReadWriteMap<Node,int> >
88
      ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
89
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
90
      ::SetStandardProcessedMap
91
      ::Create bfs_test(G);
76 92

	
77
  Path<Digraph> pp = bfs_test.path(n);
93
    bfs_test.run(s);
94
    bfs_test.run(s,t);
95
    bfs_test.run();
96

	
97
    l  = bfs_test.dist(t);
98
    e  = bfs_test.predArc(t);
99
    s  = bfs_test.predNode(t);
100
    b  = bfs_test.reached(t);
101
    pp = bfs_test.path(t);
102
  }
78 103
}
79 104

	
80 105
void checkBfsFunctionCompile()
Ignore white space 6 line context
... ...
@@ -56,27 +56,52 @@
56 56
{
57 57
  typedef concepts::Digraph Digraph;
58 58
  typedef Dfs<Digraph> DType;
59
  typedef Digraph::Node Node;
60
  typedef Digraph::Arc Arc;
59 61

	
60 62
  Digraph G;
61
  Digraph::Node n;
62
  Digraph::Arc e;
63
  Node s, t;
64
  Arc e;
63 65
  int l;
64 66
  bool b;
65 67
  DType::DistMap d(G);
66 68
  DType::PredMap p(G);
69
  Path<Digraph> pp;
67 70

	
68
  DType dfs_test(G);
71
  {
72
    DType dfs_test(G);
69 73

	
70
  dfs_test.run(n);
74
    dfs_test.run(s);
75
    dfs_test.run(s,t);
76
    dfs_test.run();
71 77

	
72
  l  = dfs_test.dist(n);
73
  e  = dfs_test.predArc(n);
74
  n  = dfs_test.predNode(n);
75
  d  = dfs_test.distMap();
76
  p  = dfs_test.predMap();
77
  b  = dfs_test.reached(n);
78
    l  = dfs_test.dist(t);
79
    e  = dfs_test.predArc(t);
80
    s  = dfs_test.predNode(t);
81
    b  = dfs_test.reached(t);
82
    d  = dfs_test.distMap();
83
    p  = dfs_test.predMap();
84
    pp = dfs_test.path(t);
85
  }
86
  {
87
    DType
88
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
89
      ::SetDistMap<concepts::ReadWriteMap<Node,int> >
90
      ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
91
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
92
      ::SetStandardProcessedMap
93
      ::Create dfs_test(G);
78 94

	
79
  Path<Digraph> pp = dfs_test.path(n);
95
    dfs_test.run(s);
96
    dfs_test.run(s,t);
97
    dfs_test.run();
98

	
99
    l  = dfs_test.dist(t);
100
    e  = dfs_test.predArc(t);
101
    s  = dfs_test.predNode(t);
102
    b  = dfs_test.reached(t);
103
    pp = dfs_test.path(t);
104
  }
80 105
}
81 106

	
82 107
void checkDfsFunctionCompile()
Ignore white space 6 line context
... ...
@@ -22,6 +22,7 @@
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/dijkstra.h>
24 24
#include <lemon/path.h>
25
#include <lemon/bin_heap.h>
25 26

	
26 27
#include "graph_test.h"
27 28
#include "test_tools.h"
... ...
@@ -55,28 +56,54 @@
55 56
  typedef concepts::Digraph Digraph;
56 57
  typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
57 58
  typedef Dijkstra<Digraph, LengthMap> DType;
59
  typedef Digraph::Node Node;
60
  typedef Digraph::Arc Arc;
58 61

	
59 62
  Digraph G;
60
  Digraph::Node n;
61
  Digraph::Arc e;
63
  Node s, t;
64
  Arc e;
62 65
  VType l;
63 66
  bool b;
64 67
  DType::DistMap d(G);
65 68
  DType::PredMap p(G);
66 69
  LengthMap length;
70
  Path<Digraph> pp;
67 71

	
68
  DType dijkstra_test(G,length);
72
  {
73
    DType dijkstra_test(G,length);
69 74

	
70
  dijkstra_test.run(n);
75
    dijkstra_test.run(s);
76
    dijkstra_test.run(s,t);
71 77

	
72
  l  = dijkstra_test.dist(n);
73
  e  = dijkstra_test.predArc(n);
74
  n  = dijkstra_test.predNode(n);
75
  d  = dijkstra_test.distMap();
76
  p  = dijkstra_test.predMap();
77
  b  = dijkstra_test.reached(n);
78
    l  = dijkstra_test.dist(t);
79
    e  = dijkstra_test.predArc(t);
80
    s  = dijkstra_test.predNode(t);
81
    b  = dijkstra_test.reached(t);
82
    d  = dijkstra_test.distMap();
83
    p  = dijkstra_test.predMap();
84
    pp = dijkstra_test.path(t);
85
  }
86
  {
87
    DType
88
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
89
      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
90
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
91
      ::SetStandardProcessedMap
92
      ::SetOperationTraits<DijkstraWidestPathOperationTraits<VType> >
93
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
94
      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
95
      ::Create dijkstra_test(G,length);
78 96

	
79
  Path<Digraph> pp = dijkstra_test.path(n);
97
    dijkstra_test.run(s);
98
    dijkstra_test.run(s,t);
99

	
100
    l  = dijkstra_test.dist(t);
101
    e  = dijkstra_test.predArc(t);
102
    s  = dijkstra_test.predNode(t);
103
    b  = dijkstra_test.reached(t);
104
    pp = dijkstra_test.path(t);
105
  }
106

	
80 107
}
81 108

	
82 109
void checkDijkstraFunctionCompile()
0 comments (0 inline)