gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Small fixes related to BellmanFord (#51) - Add a missing #include. - Add a missing const keyword for negativeCycle(). - Test if negativeCycle() is const function.
0 2 0
default
2 files changed with 4 insertions and 1 deletions:
↑ Collapse diff ↑
Ignore white space 128 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_BELLMAN_FORD_H
20 20
#define LEMON_BELLMAN_FORD_H
21 21

	
22 22
/// \ingroup shortest_path
23 23
/// \file
24 24
/// \brief Bellman-Ford algorithm.
25 25

	
26
#include <lemon/list_graph.h>
26 27
#include <lemon/bits/path_dump.h>
27 28
#include <lemon/core.h>
28 29
#include <lemon/error.h>
29 30
#include <lemon/maps.h>
30 31
#include <lemon/path.h>
31 32

	
32 33
#include <limits>
33 34

	
34 35
namespace lemon {
35 36

	
36 37
  /// \brief Default OperationTraits for the BellmanFord algorithm class.
37 38
  ///  
38 39
  /// This operation traits class defines all computational operations
39 40
  /// and constants that are used in the Bellman-Ford algorithm.
40 41
  /// The default implementation is based on the \c numeric_limits class.
41 42
  /// If the numeric type does not have infinity value, then the maximum
42 43
  /// value is used as extremal infinity value.
43 44
  template <
44 45
    typename V, 
45 46
    bool has_inf = std::numeric_limits<V>::has_infinity>
46 47
  struct BellmanFordDefaultOperationTraits {
47 48
    /// \e
48 49
    typedef V Value;
49 50
    /// \brief Gives back the zero value of the type.
50 51
    static Value zero() {
51 52
      return static_cast<Value>(0);
52 53
    }
53 54
    /// \brief Gives back the positive infinity value of the type.
54 55
    static Value infinity() {
55 56
      return std::numeric_limits<Value>::infinity();
56 57
    }
57 58
    /// \brief Gives back the sum of the given two elements.
58 59
    static Value plus(const Value& left, const Value& right) {
59 60
      return left + right;
60 61
    }
61 62
    /// \brief Gives back \c true only if the first value is less than
62 63
    /// the second.
63 64
    static bool less(const Value& left, const Value& right) {
64 65
      return left < right;
65 66
    }
66 67
  };
67 68

	
68 69
  template <typename V>
69 70
  struct BellmanFordDefaultOperationTraits<V, false> {
70 71
    typedef V Value;
71 72
    static Value zero() {
72 73
      return static_cast<Value>(0);
73 74
    }
74 75
    static Value infinity() {
75 76
      return std::numeric_limits<Value>::max();
76 77
    }
77 78
    static Value plus(const Value& left, const Value& right) {
78 79
      if (left == infinity() || right == infinity()) return infinity();
79 80
      return left + right;
80 81
    }
81 82
    static bool less(const Value& left, const Value& right) {
82 83
      return left < right;
83 84
    }
84 85
  };
85 86
  
86 87
  /// \brief Default traits class of BellmanFord class.
87 88
  ///
88 89
  /// Default traits class of BellmanFord class.
89 90
  /// \param GR The type of the digraph.
... ...
@@ -714,129 +715,129 @@
714 715
    /// This function returns the 'previous arc' of the shortest path
715 716
    /// tree for node \c v, i.e. it returns the last arc of a
716 717
    /// shortest path from a root to \c v. It is \c INVALID if \c v
717 718
    /// is not reached from the root(s) or if \c v is a root.
718 719
    ///
719 720
    /// The shortest path tree used here is equal to the shortest path
720 721
    /// tree used in \ref predNode() and \predMap().
721 722
    ///
722 723
    /// \pre Either \ref run() or \ref init() must be called before
723 724
    /// using this function.
724 725
    Arc predArc(Node v) const { return (*_pred)[v]; }
725 726

	
726 727
    /// \brief Returns the 'previous node' of the shortest path tree for
727 728
    /// the given node.
728 729
    ///
729 730
    /// This function returns the 'previous node' of the shortest path
730 731
    /// tree for node \c v, i.e. it returns the last but one node of
731 732
    /// a shortest path from a root to \c v. It is \c INVALID if \c v
732 733
    /// is not reached from the root(s) or if \c v is a root.
733 734
    ///
734 735
    /// The shortest path tree used here is equal to the shortest path
735 736
    /// tree used in \ref predArc() and \predMap().
736 737
    ///
737 738
    /// \pre Either \ref run() or \ref init() must be called before
738 739
    /// using this function.
739 740
    Node predNode(Node v) const { 
740 741
      return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]); 
741 742
    }
742 743
    
743 744
    /// \brief Returns a const reference to the node map that stores the
744 745
    /// distances of the nodes.
745 746
    ///
746 747
    /// Returns a const reference to the node map that stores the distances
747 748
    /// of the nodes calculated by the algorithm.
748 749
    ///
749 750
    /// \pre Either \ref run() or \ref init() must be called before
750 751
    /// using this function.
751 752
    const DistMap &distMap() const { return *_dist;}
752 753
 
753 754
    /// \brief Returns a const reference to the node map that stores the
754 755
    /// predecessor arcs.
755 756
    ///
756 757
    /// Returns a const reference to the node map that stores the predecessor
757 758
    /// arcs, which form the shortest path tree (forest).
758 759
    ///
759 760
    /// \pre Either \ref run() or \ref init() must be called before
760 761
    /// using this function.
761 762
    const PredMap &predMap() const { return *_pred; }
762 763
 
763 764
    /// \brief Checks if a node is reached from the root(s).
764 765
    ///
765 766
    /// Returns \c true if \c v is reached from the root(s).
766 767
    ///
767 768
    /// \pre Either \ref run() or \ref init() must be called before
768 769
    /// using this function.
769 770
    bool reached(Node v) const {
770 771
      return (*_dist)[v] != OperationTraits::infinity();
771 772
    }
772 773

	
773 774
    /// \brief Gives back a negative cycle.
774 775
    ///    
775 776
    /// This function gives back a directed cycle with negative total
776 777
    /// length if the algorithm has already found one.
777 778
    /// Otherwise it gives back an empty path.
778
    lemon::Path<Digraph> negativeCycle() {
779
    lemon::Path<Digraph> negativeCycle() const {
779 780
      typename Digraph::template NodeMap<int> state(*_gr, -1);
780 781
      lemon::Path<Digraph> cycle;
781 782
      for (int i = 0; i < int(_process.size()); ++i) {
782 783
        if (state[_process[i]] != -1) continue;
783 784
        for (Node v = _process[i]; (*_pred)[v] != INVALID;
784 785
             v = _gr->source((*_pred)[v])) {
785 786
          if (state[v] == i) {
786 787
            cycle.addFront((*_pred)[v]);
787 788
            for (Node u = _gr->source((*_pred)[v]); u != v;
788 789
                 u = _gr->source((*_pred)[u])) {
789 790
              cycle.addFront((*_pred)[u]);
790 791
            }
791 792
            return cycle;
792 793
          }
793 794
          else if (state[v] >= 0) {
794 795
            break;
795 796
          }
796 797
          state[v] = i;
797 798
        }
798 799
      }
799 800
      return cycle;
800 801
    }
801 802
    
802 803
    ///@}
803 804
  };
804 805
 
805 806
  /// \brief Default traits class of bellmanFord() function.
806 807
  ///
807 808
  /// Default traits class of bellmanFord() function.
808 809
  /// \tparam GR The type of the digraph.
809 810
  /// \tparam LEN The type of the length map.
810 811
  template <typename GR, typename LEN>
811 812
  struct BellmanFordWizardDefaultTraits {
812 813
    /// The type of the digraph the algorithm runs on. 
813 814
    typedef GR Digraph;
814 815

	
815 816
    /// \brief The type of the map that stores the arc lengths.
816 817
    ///
817 818
    /// The type of the map that stores the arc lengths.
818 819
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
819 820
    typedef LEN LengthMap;
820 821

	
821 822
    /// The type of the arc lengths.
822 823
    typedef typename LEN::Value Value;
823 824

	
824 825
    /// \brief Operation traits for Bellman-Ford algorithm.
825 826
    ///
826 827
    /// It defines the used operations and the infinity value for the
827 828
    /// given \c Value type.
828 829
    /// \see BellmanFordDefaultOperationTraits
829 830
    typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
830 831

	
831 832
    /// \brief The type of the map that stores the last
832 833
    /// arcs of the shortest paths.
833 834
    /// 
834 835
    /// The type of the map that stores the last arcs of the shortest paths.
835 836
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
836 837
    typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
837 838

	
838 839
    /// \brief Instantiates a \c PredMap.
839 840
    /// 
840 841
    /// This function instantiates a \ref PredMap.
841 842
    /// \param g is the digraph to which we would like to define the
842 843
    /// \ref PredMap.
Ignore white space 6 line context
... ...
@@ -35,164 +35,166 @@
35 35
  "1\n"
36 36
  "2\n"
37 37
  "3\n"
38 38
  "4\n"
39 39
  "@arcs\n"
40 40
  "    length\n"
41 41
  "0 1 3\n"
42 42
  "1 2 -3\n"
43 43
  "1 2 -5\n"
44 44
  "1 3 -2\n"
45 45
  "0 2 -1\n"
46 46
  "1 2 -4\n"
47 47
  "0 3 2\n"
48 48
  "4 2 -5\n"
49 49
  "2 3 1\n"
50 50
  "@attributes\n"
51 51
  "source 0\n"
52 52
  "target 3\n";
53 53

	
54 54

	
55 55
void checkBellmanFordCompile()
56 56
{
57 57
  typedef int Value;
58 58
  typedef concepts::Digraph Digraph;
59 59
  typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
60 60
  typedef BellmanFord<Digraph, LengthMap> BF;
61 61
  typedef Digraph::Node Node;
62 62
  typedef Digraph::Arc Arc;
63 63

	
64 64
  Digraph gr;
65 65
  Node s, t, n;
66 66
  Arc e;
67 67
  Value l;
68 68
  int k;
69 69
  bool b;
70 70
  BF::DistMap d(gr);
71 71
  BF::PredMap p(gr);
72 72
  LengthMap length;
73 73
  concepts::Path<Digraph> pp;
74 74

	
75 75
  {
76 76
    BF bf_test(gr,length);
77 77
    const BF& const_bf_test = bf_test;
78 78

	
79 79
    bf_test.run(s);
80 80
    bf_test.run(s,k);
81 81

	
82 82
    bf_test.init();
83 83
    bf_test.addSource(s);
84 84
    bf_test.addSource(s, 1);
85 85
    b = bf_test.processNextRound();
86 86
    b = bf_test.processNextWeakRound();
87 87

	
88 88
    bf_test.start();
89 89
    bf_test.checkedStart();
90 90
    bf_test.limitedStart(k);
91 91

	
92 92
    l  = const_bf_test.dist(t);
93 93
    e  = const_bf_test.predArc(t);
94 94
    s  = const_bf_test.predNode(t);
95 95
    b  = const_bf_test.reached(t);
96 96
    d  = const_bf_test.distMap();
97 97
    p  = const_bf_test.predMap();
98 98
    pp = const_bf_test.path(t);
99
    pp = const_bf_test.negativeCycle();
99 100
    
100 101
    for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {}
101 102
  }
102 103
  {
103 104
    BF::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
104 105
      ::SetDistMap<concepts::ReadWriteMap<Node,Value> >
105 106
      ::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
106 107
      ::Create bf_test(gr,length);
107 108

	
108 109
    LengthMap length_map;
109 110
    concepts::ReadWriteMap<Node,Arc> pred_map;
110 111
    concepts::ReadWriteMap<Node,Value> dist_map;
111 112
    
112 113
    bf_test
113 114
      .lengthMap(length_map)
114 115
      .predMap(pred_map)
115 116
      .distMap(dist_map);
116 117

	
117 118
    bf_test.run(s);
118 119
    bf_test.run(s,k);
119 120

	
120 121
    bf_test.init();
121 122
    bf_test.addSource(s);
122 123
    bf_test.addSource(s, 1);
123 124
    b = bf_test.processNextRound();
124 125
    b = bf_test.processNextWeakRound();
125 126

	
126 127
    bf_test.start();
127 128
    bf_test.checkedStart();
128 129
    bf_test.limitedStart(k);
129 130

	
130 131
    l  = bf_test.dist(t);
131 132
    e  = bf_test.predArc(t);
132 133
    s  = bf_test.predNode(t);
133 134
    b  = bf_test.reached(t);
134 135
    pp = bf_test.path(t);
136
    pp = bf_test.negativeCycle();
135 137
  }
136 138
}
137 139

	
138 140
void checkBellmanFordFunctionCompile()
139 141
{
140 142
  typedef int Value;
141 143
  typedef concepts::Digraph Digraph;
142 144
  typedef Digraph::Arc Arc;
143 145
  typedef Digraph::Node Node;
144 146
  typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
145 147

	
146 148
  Digraph g;
147 149
  bool b;
148 150
  bellmanFord(g,LengthMap()).run(Node());
149 151
  b = bellmanFord(g,LengthMap()).run(Node(),Node());
150 152
  bellmanFord(g,LengthMap())
151 153
    .predMap(concepts::ReadWriteMap<Node,Arc>())
152 154
    .distMap(concepts::ReadWriteMap<Node,Value>())
153 155
    .run(Node());
154 156
  b=bellmanFord(g,LengthMap())
155 157
    .predMap(concepts::ReadWriteMap<Node,Arc>())
156 158
    .distMap(concepts::ReadWriteMap<Node,Value>())
157 159
    .path(concepts::Path<Digraph>())
158 160
    .dist(Value())
159 161
    .run(Node(),Node());
160 162
}
161 163

	
162 164

	
163 165
template <typename Digraph, typename Value>
164 166
void checkBellmanFord() {
165 167
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
166 168
  typedef typename Digraph::template ArcMap<Value> LengthMap;
167 169

	
168 170
  Digraph gr;
169 171
  Node s, t;
170 172
  LengthMap length(gr);
171 173

	
172 174
  std::istringstream input(test_lgf);
173 175
  digraphReader(gr, input).
174 176
    arcMap("length", length).
175 177
    node("source", s).
176 178
    node("target", t).
177 179
    run();
178 180

	
179 181
  BellmanFord<Digraph, LengthMap>
180 182
    bf(gr, length);
181 183
  bf.run(s);
182 184
  Path<Digraph> p = bf.path(t);
183 185

	
184 186
  check(bf.reached(t) && bf.dist(t) == -1, "Bellman-Ford found a wrong path.");
185 187
  check(p.length() == 3, "path() found a wrong path.");
186 188
  check(checkPath(gr, p), "path() found a wrong path.");
187 189
  check(pathSource(gr, p) == s, "path() found a wrong path.");
188 190
  check(pathTarget(gr, p) == t, "path() found a wrong path.");
189 191
  
190 192
  ListPath<Digraph> path;
191 193
  Value dist;
192 194
  bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
193 195

	
194 196
  check(reached && dist == -1, "Bellman-Ford found a wrong path.");
195 197
  check(path.length() == 3, "path() found a wrong path.");
196 198
  check(checkPath(gr, path), "path() found a wrong path.");
197 199
  check(pathSource(gr, path) == s, "path() found a wrong path.");
198 200
  check(pathTarget(gr, path) == t, "path() found a wrong path.");
0 comments (0 inline)