gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 2 0
merge default
0 files changed with 1 insertions and 24 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
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_DIJKSTRA_H
20 20
#define LEMON_DIJKSTRA_H
21 21

	
22 22
///\ingroup shortest_path
23 23
///\file
24 24
///\brief Dijkstra algorithm.
25 25

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

	
35 35
namespace lemon {
36 36

	
37 37
  /// \brief Default operation traits for the Dijkstra algorithm class.
38 38
  ///
39 39
  /// This operation traits class defines all computational operations and
40 40
  /// constants which are used in the Dijkstra algorithm.
41 41
  template <typename Value>
42 42
  struct DijkstraDefaultOperationTraits {
43 43
    /// \brief Gives back the zero value of the type.
44 44
    static Value zero() {
45 45
      return static_cast<Value>(0);
46 46
    }
47 47
    /// \brief Gives back the sum of the given two elements.
48 48
    static Value plus(const Value& left, const Value& right) {
49 49
      return left + right;
50 50
    }
51 51
    /// \brief Gives back true only if the first value is less than the second.
52 52
    static bool less(const Value& left, const Value& right) {
53 53
      return left < right;
54 54
    }
55 55
  };
56 56

	
57
  /// \brief Widest path operation traits for the Dijkstra algorithm class.
58
  ///
59
  /// This operation traits class defines all computational operations and
60
  /// constants which are used in the Dijkstra algorithm for widest path
61
  /// computation.
62
  ///
63
  /// \see DijkstraDefaultOperationTraits
64
  template <typename Value>
65
  struct DijkstraWidestPathOperationTraits {
66
    /// \brief Gives back the maximum value of the type.
67
    static Value zero() {
68
      return std::numeric_limits<Value>::max();
69
    }
70
    /// \brief Gives back the minimum of the given two elements.
71
    static Value plus(const Value& left, const Value& right) {
72
      return std::min(left, right);
73
    }
74
    /// \brief Gives back true only if the first value is less than the second.
75
    static bool less(const Value& left, const Value& right) {
76
      return left < right;
77
    }
78
  };
79

	
80 57
  ///Default traits class of Dijkstra class.
81 58

	
82 59
  ///Default traits class of Dijkstra class.
83 60
  ///\tparam GR The type of the digraph.
84 61
  ///\tparam LM The type of the length map.
85 62
  template<class GR, class LM>
86 63
  struct DijkstraDefaultTraits
87 64
  {
88 65
    ///The type of the digraph the algorithm runs on.
89 66
    typedef GR Digraph;
90 67

	
91 68
    ///The type of the map that stores the arc lengths.
92 69

	
93 70
    ///The type of the map that stores the arc lengths.
94 71
    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
95 72
    typedef LM LengthMap;
96 73
    ///The type of the length of the arcs.
97 74
    typedef typename LM::Value Value;
98 75

	
99 76
    /// Operation traits for Dijkstra algorithm.
100 77

	
101 78
    /// This class defines the operations that are used in the algorithm.
102 79
    /// \see DijkstraDefaultOperationTraits
103 80
    typedef DijkstraDefaultOperationTraits<Value> OperationTraits;
104 81

	
105 82
    /// The cross reference type used by the heap.
106 83

	
107 84
    /// The cross reference type used by the heap.
108 85
    /// Usually it is \c Digraph::NodeMap<int>.
109 86
    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
110 87
    ///Instantiates a \ref HeapCrossRef.
111 88

	
112 89
    ///This function instantiates a \ref HeapCrossRef.
113 90
    /// \param g is the digraph, to which we would like to define the
114 91
    /// \ref HeapCrossRef.
115 92
    static HeapCrossRef *createHeapCrossRef(const Digraph &g)
116 93
    {
117 94
      return new HeapCrossRef(g);
118 95
    }
119 96

	
120 97
    ///The heap type used by the Dijkstra algorithm.
121 98

	
122 99
    ///The heap type used by the Dijkstra algorithm.
123 100
    ///
124 101
    ///\sa BinHeap
125 102
    ///\sa Dijkstra
126 103
    typedef BinHeap<typename LM::Value, HeapCrossRef, std::less<Value> > Heap;
127 104
    ///Instantiates a \ref Heap.
128 105

	
129 106
    ///This function instantiates a \ref Heap.
130 107
    static Heap *createHeap(HeapCrossRef& r)
131 108
    {
132 109
      return new Heap(r);
133 110
    }
134 111

	
135 112
    ///\brief The type of the map that stores the predecessor
136 113
    ///arcs of the shortest paths.
137 114
    ///
138 115
    ///The type of the map that stores the predecessor
139 116
    ///arcs of the shortest paths.
140 117
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
141 118
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
142 119
    ///Instantiates a PredMap.
143 120

	
144 121
    ///This function instantiates a PredMap.
145 122
    ///\param g is the digraph, to which we would like to define the
146 123
    ///PredMap.
147 124
    static PredMap *createPredMap(const Digraph &g)
148 125
    {
149 126
      return new PredMap(g);
150 127
    }
151 128

	
152 129
    ///The type of the map that indicates which nodes are processed.
153 130

	
154 131
    ///The type of the map that indicates which nodes are processed.
155 132
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
156 133
    ///By default it is a NullMap.
157 134
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
158 135
    ///Instantiates a ProcessedMap.
159 136

	
160 137
    ///This function instantiates a ProcessedMap.
161 138
    ///\param g is the digraph, to which
162 139
    ///we would like to define the ProcessedMap
163 140
#ifdef DOXYGEN
164 141
    static ProcessedMap *createProcessedMap(const Digraph &g)
165 142
#else
166 143
    static ProcessedMap *createProcessedMap(const Digraph &)
167 144
#endif
168 145
    {
169 146
      return new ProcessedMap();
170 147
    }
171 148

	
172 149
    ///The type of the map that stores the distances of the nodes.
173 150

	
174 151
    ///The type of the map that stores the distances of the nodes.
175 152
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
Ignore white space 192 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
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
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/smart_graph.h>
21 21
#include <lemon/list_graph.h>
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/dijkstra.h>
24 24
#include <lemon/path.h>
25 25
#include <lemon/bin_heap.h>
26 26

	
27 27
#include "graph_test.h"
28 28
#include "test_tools.h"
29 29

	
30 30
using namespace lemon;
31 31

	
32 32
char test_lgf[] =
33 33
  "@nodes\n"
34 34
  "label\n"
35 35
  "0\n"
36 36
  "1\n"
37 37
  "2\n"
38 38
  "3\n"
39 39
  "4\n"
40 40
  "@arcs\n"
41 41
  "     label length\n"
42 42
  "0 1  0     1\n"
43 43
  "1 2  1     1\n"
44 44
  "2 3  2     1\n"
45 45
  "0 3  4     5\n"
46 46
  "0 3  5     10\n"
47 47
  "0 3  6     7\n"
48 48
  "4 2  7     1\n"
49 49
  "@attributes\n"
50 50
  "source 0\n"
51 51
  "target 3\n";
52 52

	
53 53
void checkDijkstraCompile()
54 54
{
55 55
  typedef int VType;
56 56
  typedef concepts::Digraph Digraph;
57 57
  typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
58 58
  typedef Dijkstra<Digraph, LengthMap> DType;
59 59
  typedef Digraph::Node Node;
60 60
  typedef Digraph::Arc Arc;
61 61

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

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

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

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

	
97 97
    dijkstra_test.run(s);
98 98
    dijkstra_test.run(s,t);
99 99

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

	
107 107
}
108 108

	
109 109
void checkDijkstraFunctionCompile()
110 110
{
111 111
  typedef int VType;
112 112
  typedef concepts::Digraph Digraph;
113 113
  typedef Digraph::Arc Arc;
114 114
  typedef Digraph::Node Node;
115 115
  typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
116 116

	
117 117
  Digraph g;
118 118
  bool b;
119 119
  dijkstra(g,LengthMap()).run(Node());
120 120
  b=dijkstra(g,LengthMap()).run(Node(),Node());
121 121
  dijkstra(g,LengthMap())
122 122
    .predMap(concepts::ReadWriteMap<Node,Arc>())
123 123
    .distMap(concepts::ReadWriteMap<Node,VType>())
124 124
    .processedMap(concepts::WriteMap<Node,bool>())
125 125
    .run(Node());
126 126
  b=dijkstra(g,LengthMap())
127 127
    .predMap(concepts::ReadWriteMap<Node,Arc>())
128 128
    .distMap(concepts::ReadWriteMap<Node,VType>())
129 129
    .processedMap(concepts::WriteMap<Node,bool>())
130 130
    .path(concepts::Path<Digraph>())
131 131
    .dist(VType())
132 132
    .run(Node(),Node());
133 133
}
134 134

	
135 135
template <class Digraph>
136 136
void checkDijkstra() {
137 137
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
138 138
  typedef typename Digraph::template ArcMap<int> LengthMap;
139 139

	
140 140
  Digraph G;
141 141
  Node s, t;
142 142
  LengthMap length(G);
143 143

	
144 144
  std::istringstream input(test_lgf);
145 145
  digraphReader(G, input).
146 146
    arcMap("length", length).
147 147
    node("source", s).
148 148
    node("target", t).
149 149
    run();
150 150

	
151 151
  Dijkstra<Digraph, LengthMap>
152 152
        dijkstra_test(G, length);
153 153
  dijkstra_test.run(s);
154 154

	
155 155
  check(dijkstra_test.dist(t)==3,"Dijkstra found a wrong path.");
156 156

	
157 157
  Path<Digraph> p = dijkstra_test.path(t);
158 158
  check(p.length()==3,"path() found a wrong path.");
159 159
  check(checkPath(G, p),"path() found a wrong path.");
160 160
  check(pathSource(G, p) == s,"path() found a wrong path.");
161 161
  check(pathTarget(G, p) == t,"path() found a wrong path.");
162 162

	
163 163
  for(ArcIt e(G); e!=INVALID; ++e) {
164 164
    Node u=G.source(e);
165 165
    Node v=G.target(e);
166 166
    check( !dijkstra_test.reached(u) ||
167 167
           (dijkstra_test.dist(v) - dijkstra_test.dist(u) <= length[e]),
168 168
           "Wrong output. dist(target)-dist(source)-arc_length=" <<
169 169
           dijkstra_test.dist(v) - dijkstra_test.dist(u) - length[e]);
170 170
  }
171 171

	
172 172
  for(NodeIt v(G); v!=INVALID; ++v) {
173 173
    if (dijkstra_test.reached(v)) {
174 174
      check(v==s || dijkstra_test.predArc(v)!=INVALID, "Wrong tree.");
175 175
      if (dijkstra_test.predArc(v)!=INVALID ) {
176 176
        Arc e=dijkstra_test.predArc(v);
177 177
        Node u=G.source(e);
178 178
        check(u==dijkstra_test.predNode(v),"Wrong tree.");
179 179
        check(dijkstra_test.dist(v) - dijkstra_test.dist(u) == length[e],
180 180
              "Wrong distance! Difference: " <<
181 181
              std::abs(dijkstra_test.dist(v)-dijkstra_test.dist(u)-length[e]));
182 182
      }
183 183
    }
184 184
  }
185 185

	
186 186
  {
187 187
    NullMap<Node,Arc> myPredMap;
188 188
    dijkstra(G,length).predMap(myPredMap).run(s);
0 comments (0 inline)