gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Fix gcc-4.3 compilation errors and warnings
0 6 0
default
6 files changed with 13 insertions and 12 deletions:
↑ Collapse diff ↑
Ignore white space 6 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_BEZIER_H
20 20
#define LEMON_BEZIER_H
21 21

	
22 22
///\ingroup misc
23 23
///\file
24 24
///\brief Classes to compute with Bezier curves.
25 25
///
26 26
///Up to now this file is used internally by \ref graph_to_eps.h
27 27

	
28 28
#include<lemon/dim2.h>
29 29

	
30 30
namespace lemon {
31 31
  namespace dim2 {
32 32

	
33 33
class BezierBase {
34 34
public:
35
  typedef Point<double> Point;
35
  typedef lemon::dim2::Point<double> Point;
36 36
protected:
37 37
  static Point conv(Point x,Point y,double t) {return (1-t)*x+t*y;}
38 38
};
39 39

	
40 40
class Bezier1 : public BezierBase
41 41
{
42 42
public:
43 43
  Point p1,p2;
44 44

	
45 45
  Bezier1() {}
46 46
  Bezier1(Point _p1, Point _p2) :p1(_p1), p2(_p2) {}
47 47
  
48 48
  Point operator()(double t) const
49 49
  {
50 50
    //    return conv(conv(p1,p2,t),conv(p2,p3,t),t);
51 51
    return conv(p1,p2,t);
52 52
  }
53 53
  Bezier1 before(double t) const
54 54
  {
55 55
    return Bezier1(p1,conv(p1,p2,t));
56 56
  }
57 57
  
58 58
  Bezier1 after(double t) const
59 59
  {
60 60
    return Bezier1(conv(p1,p2,t),p2);
61 61
  }
62 62

	
63 63
  Bezier1 revert() const { return Bezier1(p2,p1);}
64 64
  Bezier1 operator()(double a,double b) const { return before(b).after(a/b); }
65 65
  Point grad() const { return p2-p1; }
66 66
  Point norm() const { return rot90(p2-p1); }
67 67
  Point grad(double) const { return grad(); }
68 68
  Point norm(double t) const { return rot90(grad(t)); }
69 69
};
70 70

	
71 71
class Bezier2 : public BezierBase
72 72
{
73 73
public:
74 74
  Point p1,p2,p3;
75 75

	
76 76
  Bezier2() {}
77 77
  Bezier2(Point _p1, Point _p2, Point _p3) :p1(_p1), p2(_p2), p3(_p3) {}
78 78
  Bezier2(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,.5)), p3(b.p2) {}
79 79
  Point operator()(double t) const
80 80
  {
81 81
    //    return conv(conv(p1,p2,t),conv(p2,p3,t),t);
82 82
    return ((1-t)*(1-t))*p1+(2*(1-t)*t)*p2+(t*t)*p3;
83 83
  }
84 84
  Bezier2 before(double t) const
85 85
  {
86 86
    Point q(conv(p1,p2,t));
87 87
    Point r(conv(p2,p3,t));
88 88
    return Bezier2(p1,q,conv(q,r,t));
89 89
  }
90 90
  
91 91
  Bezier2 after(double t) const
92 92
  {
93 93
    Point q(conv(p1,p2,t));
94 94
    Point r(conv(p2,p3,t));
95 95
    return Bezier2(conv(q,r,t),r,p3);
96 96
  }
97 97
  Bezier2 revert() const { return Bezier2(p3,p2,p1);}
98 98
  Bezier2 operator()(double a,double b) const { return before(b).after(a/b); }
99 99
  Bezier1 grad() const { return Bezier1(2.0*(p2-p1),2.0*(p3-p2)); }
100 100
  Bezier1 norm() const { return Bezier1(2.0*rot90(p2-p1),2.0*rot90(p3-p2)); }
101 101
  Point grad(double t) const { return grad()(t); }
102 102
  Point norm(double t) const { return rot90(grad(t)); }
103 103
};
104 104

	
105 105
class Bezier3 : public BezierBase
106 106
{
107 107
public:
108 108
  Point p1,p2,p3,p4;
109 109

	
110 110
  Bezier3() {}
111 111
  Bezier3(Point _p1, Point _p2, Point _p3, Point _p4)
112 112
    : p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}
113 113
  Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)), 
114 114
			      p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {}
115 115
  Bezier3(const Bezier2 &b) : p1(b.p1), p2(conv(b.p1,b.p2,2.0/3.0)),
116 116
			      p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {}
117 117
  
118 118
  Point operator()(double t) const 
119 119
    {
120 120
      //    return Bezier2(conv(p1,p2,t),conv(p2,p3,t),conv(p3,p4,t))(t);
121 121
      return ((1-t)*(1-t)*(1-t))*p1+(3*t*(1-t)*(1-t))*p2+
122 122
	(3*t*t*(1-t))*p3+(t*t*t)*p4;
123 123
    }
124 124
  Bezier3 before(double t) const
125 125
    {
126 126
      Point p(conv(p1,p2,t));
127 127
      Point q(conv(p2,p3,t));
128 128
      Point r(conv(p3,p4,t));
129 129
      Point a(conv(p,q,t));
130 130
      Point b(conv(q,r,t));
131 131
      Point c(conv(a,b,t));
132 132
      return Bezier3(p1,p,a,c);
133 133
    }
134 134
  
135 135
  Bezier3 after(double t) const
136 136
    {
137 137
      Point p(conv(p1,p2,t));
138 138
      Point q(conv(p2,p3,t));
139 139
      Point r(conv(p3,p4,t));
140 140
      Point a(conv(p,q,t));
141 141
      Point b(conv(q,r,t));
142 142
      Point c(conv(a,b,t));
143 143
      return Bezier3(c,b,r,p4);
144 144
    }
145 145
  Bezier3 revert() const { return Bezier3(p4,p3,p2,p1);}
146 146
  Bezier3 operator()(double a,double b) const { return before(b).after(a/b); }
147 147
  Bezier2 grad() const { return Bezier2(3.0*(p2-p1),3.0*(p3-p2),3.0*(p4-p3)); }
148 148
  Bezier2 norm() const { return Bezier2(3.0*rot90(p2-p1),
149 149
				  3.0*rot90(p3-p2),
150 150
				  3.0*rot90(p4-p3)); }
151 151
  Point grad(double t) const { return grad()(t); }
152 152
  Point norm(double t) const { return rot90(grad(t)); }
153 153

	
154 154
  template<class R,class F,class S,class D>
155 155
  R recSplit(F &_f,const S &_s,D _d) const 
156 156
  {
157 157
    const Point a=(p1+p2)/2;
158 158
    const Point b=(p2+p3)/2;
159 159
    const Point c=(p3+p4)/2;
160 160
    const Point d=(a+b)/2;
161 161
    const Point e=(b+c)/2;
162 162
    const Point f=(d+e)/2;
163 163
    R f1=_f(Bezier3(p1,a,d,e),_d);
164 164
    R f2=_f(Bezier3(e,d,c,p4),_d);
165 165
    return _s(f1,f2);
166 166
  }
167 167
  
168 168
};
169 169

	
170 170

	
171 171
} //END OF NAMESPACE dim2
172 172
} //END OF NAMESPACE lemon
173 173

	
174 174
#endif // LEMON_BEZIER_H
Ignore white space 6 line context
1 1

	
2 2
/* -*- C++ -*-
3 3
 *
4 4
 * This file is a part of LEMON, a generic C++ optimization library
5 5
 *
6 6
 * Copyright (C) 2003-2008
7 7
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
8 8
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 9
 *
10 10
 * Permission to use, modify and distribute this software is granted
11 11
 * provided that this copyright notice appears in all copies. For
12 12
 * precise terms see the accompanying LICENSE file.
13 13
 *
14 14
 * This software is provided "AS IS" with no warranty of any kind,
15 15
 * express or implied, and with no claim as to its suitability for any
16 16
 * purpose.
17 17
 *
18 18
 */
19 19

	
20 20
#ifndef LEMON_BITS_TRAITS_H
21 21
#define LEMON_BITS_TRAITS_H
22 22

	
23 23
#include <lemon/bits/utility.h>
24 24

	
25 25
///\file
26 26
///\brief Traits for graphs and maps
27 27
///
28 28

	
29 29
namespace lemon {
30 30
  template <typename _Graph, typename _Item>
31 31
  class ItemSetTraits {};
32 32
  
33 33

	
34 34
  template <typename Graph, typename Enable = void>
35 35
  struct NodeNotifierIndicator {
36 36
    typedef InvalidType Type;
37 37
  };
38 38
  template <typename Graph>
39 39
  struct NodeNotifierIndicator<
40 40
    Graph, 
41 41
    typename enable_if<typename Graph::NodeNotifier::Notifier, void>::type
42 42
  > { 
43 43
    typedef typename Graph::NodeNotifier Type;
44 44
  };
45 45

	
46 46
  template <typename _Graph>
47 47
  class ItemSetTraits<_Graph, typename _Graph::Node> {
48 48
  public:
49 49
    
50 50
    typedef _Graph Graph;
51 51

	
52 52
    typedef typename Graph::Node Item;
53 53
    typedef typename Graph::NodeIt ItemIt;
54 54

	
55 55
    typedef typename NodeNotifierIndicator<Graph>::Type ItemNotifier;
56 56

	
57 57
    template <typename _Value>
58 58
    class Map : public Graph::template NodeMap<_Value> {
59 59
    public:
60 60
      typedef typename Graph::template NodeMap<_Value> Parent; 
61 61
      typedef typename Graph::template NodeMap<_Value> Type; 
62 62
      typedef typename Parent::Value Value;
63 63

	
64 64
      Map(const Graph& _digraph) : Parent(_digraph) {}
65 65
      Map(const Graph& _digraph, const Value& _value) 
66 66
	: Parent(_digraph, _value) {}
67 67

	
68 68
     };
69 69

	
70 70
  };
71 71

	
72 72
  template <typename Graph, typename Enable = void>
73 73
  struct ArcNotifierIndicator {
74 74
    typedef InvalidType Type;
75 75
  };
76 76
  template <typename Graph>
77 77
  struct ArcNotifierIndicator<
78 78
    Graph, 
79 79
    typename enable_if<typename Graph::ArcNotifier::Notifier, void>::type
80 80
  > { 
81 81
    typedef typename Graph::ArcNotifier Type;
82 82
  };
83 83

	
84 84
  template <typename _Graph>
85 85
  class ItemSetTraits<_Graph, typename _Graph::Arc> {
86 86
  public:
87 87
    
88 88
    typedef _Graph Graph;
89 89

	
90 90
    typedef typename Graph::Arc Item;
91 91
    typedef typename Graph::ArcIt ItemIt;
92 92

	
93 93
    typedef typename ArcNotifierIndicator<Graph>::Type ItemNotifier;
94 94

	
95 95
    template <typename _Value>
96 96
    class Map : public Graph::template ArcMap<_Value> {
97 97
    public:
98 98
      typedef typename Graph::template ArcMap<_Value> Parent; 
99 99
      typedef typename Graph::template ArcMap<_Value> Type; 
100 100
      typedef typename Parent::Value Value;
101 101

	
102 102
      Map(const Graph& _digraph) : Parent(_digraph) {}
103 103
      Map(const Graph& _digraph, const Value& _value) 
104 104
	: Parent(_digraph, _value) {}
105 105
    };
106 106

	
107 107
  };
108 108

	
109 109
  template <typename Graph, typename Enable = void>
110 110
  struct EdgeNotifierIndicator {
111 111
    typedef InvalidType Type;
112 112
  };
113 113
  template <typename Graph>
114 114
  struct EdgeNotifierIndicator<
115 115
    Graph, 
116 116
    typename enable_if<typename Graph::EdgeNotifier::Notifier, void>::type
117 117
  > { 
118 118
    typedef typename Graph::EdgeNotifier Type;
119 119
  };
120 120

	
121 121
  template <typename _Graph>
122 122
  class ItemSetTraits<_Graph, typename _Graph::Edge> {
123 123
  public:
124 124
    
125 125
    typedef _Graph Graph;
126 126

	
127 127
    typedef typename Graph::Edge Item;
128 128
    typedef typename Graph::EdgeIt ItemIt;
129 129

	
130 130
    typedef typename EdgeNotifierIndicator<Graph>::Type ItemNotifier;
131 131

	
132 132
    template <typename _Value>
133 133
    class Map : public Graph::template EdgeMap<_Value> {
134 134
    public:
135 135
      typedef typename Graph::template EdgeMap<_Value> Parent; 
136 136
      typedef typename Graph::template EdgeMap<_Value> Type; 
137 137
      typedef typename Parent::Value Value;
138 138

	
139 139
      Map(const Graph& _digraph) : Parent(_digraph) {}
140 140
      Map(const Graph& _digraph, const Value& _value) 
141 141
	: Parent(_digraph, _value) {}
142 142
    };
143 143

	
144 144
  };
145 145

	
146 146
  template <typename Map, typename Enable = void>
147 147
  struct MapTraits {
148 148
    typedef False ReferenceMapTag;
149 149

	
150 150
    typedef typename Map::Key Key;
151 151
    typedef typename Map::Value Value;
152 152

	
153
    typedef const Value ConstReturnValue;
154
    typedef const Value ReturnValue;
153
    typedef Value ConstReturnValue;
154
    typedef Value ReturnValue;
155 155
  };
156 156

	
157 157
  template <typename Map>
158 158
  struct MapTraits<
159 159
    Map, typename enable_if<typename Map::ReferenceMapTag, void>::type > 
160 160
  {
161 161
    typedef True ReferenceMapTag;
162 162
    
163 163
    typedef typename Map::Key Key;
164 164
    typedef typename Map::Value Value;
165 165

	
166 166
    typedef typename Map::ConstReference ConstReturnValue;
167 167
    typedef typename Map::Reference ReturnValue;
168 168

	
169 169
    typedef typename Map::ConstReference ConstReference; 
170 170
    typedef typename Map::Reference Reference;
171 171
 };
172 172

	
173 173
  template <typename MatrixMap, typename Enable = void>
174 174
  struct MatrixMapTraits {
175 175
    typedef False ReferenceMapTag;
176 176

	
177 177
    typedef typename MatrixMap::FirstKey FirstKey;
178 178
    typedef typename MatrixMap::SecondKey SecondKey;
179 179
    typedef typename MatrixMap::Value Value;
180 180

	
181
    typedef const Value ConstReturnValue;
182
    typedef const Value ReturnValue;
181
    typedef Value ConstReturnValue;
182
    typedef Value ReturnValue;
183 183
  };
184 184

	
185 185
  template <typename MatrixMap>
186 186
  struct MatrixMapTraits<
187 187
    MatrixMap, typename enable_if<typename MatrixMap::ReferenceMapTag, 
188 188
                                  void>::type > 
189 189
  {
190 190
    typedef True ReferenceMapTag;
191 191
    
192 192
    typedef typename MatrixMap::FirstKey FirstKey;
193 193
    typedef typename MatrixMap::SecondKey SecondKey;
194 194
    typedef typename MatrixMap::Value Value;
195 195

	
196 196
    typedef typename MatrixMap::ConstReference ConstReturnValue;
197 197
    typedef typename MatrixMap::Reference ReturnValue;
198 198

	
199 199
    typedef typename MatrixMap::ConstReference ConstReference; 
200 200
    typedef typename MatrixMap::Reference Reference;
201 201
 };
202 202

	
203 203
  // Indicators for the tags
204 204

	
205 205
  template <typename Graph, typename Enable = void>
206 206
  struct NodeNumTagIndicator {
207 207
    static const bool value = false;
208 208
  };
209 209

	
210 210
  template <typename Graph>
211 211
  struct NodeNumTagIndicator<
212 212
    Graph, 
213 213
    typename enable_if<typename Graph::NodeNumTag, void>::type
214 214
  > {
215 215
    static const bool value = true;
216 216
  };
217 217

	
218 218
  template <typename Graph, typename Enable = void>
219 219
  struct EdgeNumTagIndicator {
220 220
    static const bool value = false;
221 221
  };
222 222

	
223 223
  template <typename Graph>
224 224
  struct EdgeNumTagIndicator<
225 225
    Graph, 
226 226
    typename enable_if<typename Graph::EdgeNumTag, void>::type
227 227
  > {
228 228
    static const bool value = true;
229 229
  };
230 230

	
231 231
  template <typename Graph, typename Enable = void>
232 232
  struct FindEdgeTagIndicator {
233 233
    static const bool value = false;
234 234
  };
235 235

	
236 236
  template <typename Graph>
237 237
  struct FindEdgeTagIndicator<
238 238
    Graph, 
239 239
    typename enable_if<typename Graph::FindEdgeTag, void>::type
240 240
  > {
241 241
    static const bool value = true;
242 242
  };
243 243

	
244 244
  template <typename Graph, typename Enable = void>
245 245
  struct UndirectedTagIndicator {
246 246
    static const bool value = false;
247 247
  };
248 248

	
249 249
  template <typename Graph>
250 250
  struct UndirectedTagIndicator<
251 251
    Graph, 
252 252
    typename enable_if<typename Graph::UndirectedTag, void>::type
253 253
  > {
254 254
    static const bool value = true;
255 255
  };
256 256

	
257 257
  template <typename Graph, typename Enable = void>
258 258
  struct BuildTagIndicator {
259 259
    static const bool value = false;
260 260
  };
261 261

	
262 262
  template <typename Graph>
263 263
  struct BuildTagIndicator<
264 264
    Graph, 
265 265
    typename enable_if<typename Graph::BuildTag, void>::type
266 266
  > {
267 267
    static const bool value = true;
268 268
  };
269 269

	
270 270
}
271 271

	
272 272
#endif
Ignore white space 1536 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_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
#include <limits>
26 27
#include <lemon/list_graph.h>
27 28
#include <lemon/bin_heap.h>
28 29
#include <lemon/bits/path_dump.h>
29 30
#include <lemon/bits/invalid.h>
30 31
#include <lemon/error.h>
31 32
#include <lemon/maps.h>
32 33

	
33 34
namespace lemon {
34 35

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

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

	
77 78
  ///Default traits class of Dijkstra class.
78 79
  ///\tparam GR Digraph type.
79 80
  ///\tparam LM Type of length map.
80 81
  template<class GR, class LM>
81 82
  struct DijkstraDefaultTraits
82 83
  {
83 84
    ///The digraph type the algorithm runs on. 
84 85
    typedef GR Digraph;
85 86
    ///The type of the map that stores the arc lengths.
86 87

	
87 88
    ///The type of the map that stores the arc lengths.
88 89
    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
89 90
    typedef LM LengthMap;
90 91
    //The type of the length of the arcs.
91 92
    typedef typename LM::Value Value;
92 93
    /// Operation traits for Dijkstra algorithm.
93 94

	
94 95
    /// It defines the used operation by the algorithm.
95 96
    /// \see DijkstraDefaultOperationTraits
96 97
    typedef DijkstraDefaultOperationTraits<Value> OperationTraits;
97 98
    /// The cross reference type used by heap.
98 99

	
99 100

	
100 101
    /// The cross reference type used by heap.
101 102
    /// Usually it is \c Digraph::NodeMap<int>.
102 103
    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
103 104
    ///Instantiates a HeapCrossRef.
104 105

	
105 106
    ///This function instantiates a \c HeapCrossRef. 
106 107
    /// \param G is the digraph, to which we would like to define the 
107 108
    /// HeapCrossRef.
108 109
    static HeapCrossRef *createHeapCrossRef(const GR &G) 
109 110
    {
110 111
      return new HeapCrossRef(G);
111 112
    }
112 113
    
113 114
    ///The heap type used by Dijkstra algorithm.
114 115

	
115 116
    ///The heap type used by Dijkstra algorithm.
116 117
    ///
117 118
    ///\sa BinHeap
118 119
    ///\sa Dijkstra
119 120
    typedef BinHeap<typename LM::Value, HeapCrossRef, std::less<Value> > Heap;
120 121

	
121 122
    static Heap *createHeap(HeapCrossRef& R) 
122 123
    {
123 124
      return new Heap(R);
124 125
    }
125 126

	
126 127
    ///\brief The type of the map that stores the last
127 128
    ///arcs of the shortest paths.
128 129
    /// 
129 130
    ///The type of the map that stores the last
130 131
    ///arcs of the shortest paths.
131 132
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
132 133
    ///
133 134
    typedef typename Digraph::template NodeMap<typename GR::Arc> PredMap;
134 135
    ///Instantiates a PredMap.
135 136
 
136 137
    ///This function instantiates a \c PredMap. 
137 138
    ///\param G is the digraph, to which we would like to define the PredMap.
138 139
    ///\todo The digraph alone may be insufficient for the initialization
139 140
    static PredMap *createPredMap(const GR &G) 
140 141
    {
141 142
      return new PredMap(G);
142 143
    }
143 144

	
144 145
    ///The type of the map that stores whether a nodes is processed.
145 146
 
146 147
    ///The type of the map that stores whether a nodes is processed.
147 148
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
148 149
    ///By default it is a NullMap.
149 150
    ///\todo If it is set to a real map,
150 151
    ///Dijkstra::processed() should read this.
151 152
    ///\todo named parameter to set this type, function to read and write.
152 153
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
153 154
    ///Instantiates a ProcessedMap.
154 155
 
155 156
    ///This function instantiates a \c ProcessedMap. 
156 157
    ///\param g is the digraph, to which
157 158
    ///we would like to define the \c ProcessedMap
158 159
#ifdef DOXYGEN
159 160
    static ProcessedMap *createProcessedMap(const GR &g)
160 161
#else
161 162
    static ProcessedMap *createProcessedMap(const GR &)
162 163
#endif
163 164
    {
164 165
      return new ProcessedMap();
165 166
    }
166 167
    ///The type of the map that stores the dists of the nodes.
167 168
 
168 169
    ///The type of the map that stores the dists of the nodes.
169 170
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
170 171
    ///
171 172
    typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
172 173
    ///Instantiates a DistMap.
173 174
 
174 175
    ///This function instantiates a \ref DistMap. 
175 176
    ///\param G is the digraph, to which we would like to define the \ref DistMap
176 177
    static DistMap *createDistMap(const GR &G)
177 178
    {
178 179
      return new DistMap(G);
179 180
    }
180 181
  };
181 182
  
182 183
  ///%Dijkstra algorithm class.
183 184
  
184 185
  /// \ingroup shortest_path
185 186
  ///This class provides an efficient implementation of %Dijkstra algorithm.
186 187
  ///The arc lengths are passed to the algorithm using a
187 188
  ///\ref concepts::ReadMap "ReadMap",
188 189
  ///so it is easy to change it to any kind of length.
189 190
  ///
190 191
  ///The type of the length is determined by the
191 192
  ///\ref concepts::ReadMap::Value "Value" of the length map.
192 193
  ///
193 194
  ///It is also possible to change the underlying priority heap.
194 195
  ///
195 196
  ///\tparam GR The digraph type the algorithm runs on. The default value
196 197
  ///is \ref ListDigraph. The value of GR is not used directly by
197 198
  ///Dijkstra, it is only passed to \ref DijkstraDefaultTraits.
198 199
  ///\tparam LM This read-only ArcMap determines the lengths of the
199 200
  ///arcs. It is read once for each arc, so the map may involve in
200 201
  ///relatively time consuming process to compute the arc length if
201 202
  ///it is necessary. The default map type is \ref
202 203
  ///concepts::Digraph::ArcMap "Digraph::ArcMap<int>".  The value
203 204
  ///of LM is not used directly by Dijkstra, it is only passed to \ref
204 205
  ///DijkstraDefaultTraits.  
205 206
  ///\tparam TR Traits class to set
206 207
  ///various data types used by the algorithm.  The default traits
207 208
  ///class is \ref DijkstraDefaultTraits
208 209
  ///"DijkstraDefaultTraits<GR,LM>".  See \ref
209 210
  ///DijkstraDefaultTraits for the documentation of a Dijkstra traits
210 211
  ///class.
211 212

	
212 213
#ifdef DOXYGEN
213 214
  template <typename GR, typename LM, typename TR>
214 215
#else
215 216
  template <typename GR=ListDigraph,
216 217
	    typename LM=typename GR::template ArcMap<int>,
217 218
	    typename TR=DijkstraDefaultTraits<GR,LM> >
218 219
#endif
219 220
  class Dijkstra {
220 221
  public:
221 222
    /**
222 223
     * \brief \ref Exception for uninitialized parameters.
223 224
     *
224 225
     * This error represents problems in the initialization
225 226
     * of the parameters of the algorithms.
226 227
     */
227 228
    class UninitializedParameter : public lemon::UninitializedParameter {
228 229
    public:
229 230
      virtual const char* what() const throw() {
230 231
	return "lemon::Dijkstra::UninitializedParameter";
231 232
      }
232 233
    };
233 234

	
234 235
    typedef TR Traits;
235 236
    ///The type of the underlying digraph.
236 237
    typedef typename TR::Digraph Digraph;
237 238
    ///\e
238 239
    typedef typename Digraph::Node Node;
239 240
    ///\e
240 241
    typedef typename Digraph::NodeIt NodeIt;
241 242
    ///\e
242 243
    typedef typename Digraph::Arc Arc;
243 244
    ///\e
244 245
    typedef typename Digraph::OutArcIt OutArcIt;
245 246
    
246 247
    ///The type of the length of the arcs.
247 248
    typedef typename TR::LengthMap::Value Value;
248 249
    ///The type of the map that stores the arc lengths.
249 250
    typedef typename TR::LengthMap LengthMap;
250 251
    ///\brief The type of the map that stores the last
251 252
    ///arcs of the shortest paths.
252 253
    typedef typename TR::PredMap PredMap;
253 254
    ///The type of the map indicating if a node is processed.
254 255
    typedef typename TR::ProcessedMap ProcessedMap;
255 256
    ///The type of the map that stores the dists of the nodes.
256 257
    typedef typename TR::DistMap DistMap;
257 258
    ///The cross reference type used for the current heap.
258 259
    typedef typename TR::HeapCrossRef HeapCrossRef;
259 260
    ///The heap type used by the dijkstra algorithm.
260 261
    typedef typename TR::Heap Heap;
261 262
    ///The operation traits.
262 263
    typedef typename TR::OperationTraits OperationTraits;
263 264
  private:
264 265
    /// Pointer to the underlying digraph.
265 266
    const Digraph *G;
266 267
    /// Pointer to the length map
267 268
    const LengthMap *length;
268 269
    ///Pointer to the map of predecessors arcs.
269 270
    PredMap *_pred;
270 271
    ///Indicates if \ref _pred is locally allocated (\c true) or not.
271 272
    bool local_pred;
272 273
    ///Pointer to the map of distances.
273 274
    DistMap *_dist;
274 275
    ///Indicates if \ref _dist is locally allocated (\c true) or not.
275 276
    bool local_dist;
276 277
    ///Pointer to the map of processed status of the nodes.
277 278
    ProcessedMap *_processed;
278 279
    ///Indicates if \ref _processed is locally allocated (\c true) or not.
279 280
    bool local_processed;
280 281
    ///Pointer to the heap cross references.
281 282
    HeapCrossRef *_heap_cross_ref;
282 283
    ///Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not.
283 284
    bool local_heap_cross_ref;
284 285
    ///Pointer to the heap.
285 286
    Heap *_heap;
286 287
    ///Indicates if \ref _heap is locally allocated (\c true) or not.
287 288
    bool local_heap;
288 289

	
289 290
    ///Creates the maps if necessary.
290 291
    
291 292
    ///\todo Better memory allocation (instead of new).
292 293
    void create_maps() 
293 294
    {
294 295
      if(!_pred) {
295 296
	local_pred = true;
296 297
	_pred = Traits::createPredMap(*G);
297 298
      }
298 299
      if(!_dist) {
299 300
	local_dist = true;
300 301
	_dist = Traits::createDistMap(*G);
301 302
      }
302 303
      if(!_processed) {
303 304
	local_processed = true;
304 305
	_processed = Traits::createProcessedMap(*G);
305 306
      }
306 307
      if (!_heap_cross_ref) {
307 308
	local_heap_cross_ref = true;
308 309
	_heap_cross_ref = Traits::createHeapCrossRef(*G);
309 310
      }
310 311
      if (!_heap) {
311 312
	local_heap = true;
312 313
	_heap = Traits::createHeap(*_heap_cross_ref);
313 314
      }
314 315
    }
315 316
    
316 317
  public :
317 318

	
318 319
    typedef Dijkstra Create;
319 320
 
320 321
    ///\name Named template parameters
321 322

	
322 323
    ///@{
323 324

	
324 325
    template <class T>
325 326
    struct DefPredMapTraits : public Traits {
326 327
      typedef T PredMap;
327 328
      static PredMap *createPredMap(const Digraph &)
328 329
      {
329 330
	throw UninitializedParameter();
330 331
      }
331 332
    };
332 333
    ///\ref named-templ-param "Named parameter" for setting PredMap type
333 334

	
334 335
    ///\ref named-templ-param "Named parameter" for setting PredMap type
335 336
    ///
336 337
    template <class T>
337 338
    struct DefPredMap 
338 339
      : public Dijkstra< Digraph,	LengthMap, DefPredMapTraits<T> > {
339 340
      typedef Dijkstra< Digraph,	LengthMap, DefPredMapTraits<T> > Create;
340 341
    };
341 342
    
342 343
    template <class T>
343 344
    struct DefDistMapTraits : public Traits {
344 345
      typedef T DistMap;
345 346
      static DistMap *createDistMap(const Digraph &)
346 347
      {
347 348
	throw UninitializedParameter();
348 349
      }
349 350
    };
350 351
    ///\ref named-templ-param "Named parameter" for setting DistMap type
351 352

	
352 353
    ///\ref named-templ-param "Named parameter" for setting DistMap type
353 354
    ///
354 355
    template <class T>
355 356
    struct DefDistMap 
356 357
      : public Dijkstra< Digraph, LengthMap, DefDistMapTraits<T> > { 
357 358
      typedef Dijkstra< Digraph, LengthMap, DefDistMapTraits<T> > Create;
358 359
    };
359 360
    
360 361
    template <class T>
361 362
    struct DefProcessedMapTraits : public Traits {
362 363
      typedef T ProcessedMap;
363 364
      static ProcessedMap *createProcessedMap(const Digraph &G) 
364 365
      {
365 366
	throw UninitializedParameter();
366 367
      }
367 368
    };
368 369
    ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
369 370

	
370 371
    ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
371 372
    ///
372 373
    template <class T>
373 374
    struct DefProcessedMap 
374 375
      : public Dijkstra< Digraph,	LengthMap, DefProcessedMapTraits<T> > { 
375 376
      typedef Dijkstra< Digraph,	LengthMap, DefProcessedMapTraits<T> > Create;
376 377
    };
377 378
    
378 379
    struct DefDigraphProcessedMapTraits : public Traits {
379 380
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
380 381
      static ProcessedMap *createProcessedMap(const Digraph &G) 
381 382
      {
382 383
	return new ProcessedMap(G);
383 384
      }
384 385
    };
385 386
    ///\brief \ref named-templ-param "Named parameter"
386 387
    ///for setting the ProcessedMap type to be Digraph::NodeMap<bool>.
387 388
    ///
388 389
    ///\ref named-templ-param "Named parameter"
389 390
    ///for setting the ProcessedMap type to be Digraph::NodeMap<bool>.
390 391
    ///If you don't set it explicitely, it will be automatically allocated.
391 392
    template <class T>
392 393
    struct DefProcessedMapToBeDefaultMap 
393 394
      : public Dijkstra< Digraph, LengthMap, DefDigraphProcessedMapTraits> {
394 395
      typedef Dijkstra< Digraph, LengthMap, DefDigraphProcessedMapTraits> Create;
395 396
    };
396 397

	
397 398
    template <class H, class CR>
398 399
    struct DefHeapTraits : public Traits {
399 400
      typedef CR HeapCrossRef;
400 401
      typedef H Heap;
401 402
      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
402 403
	throw UninitializedParameter();
403 404
      }
404 405
      static Heap *createHeap(HeapCrossRef &) 
405 406
      {
406 407
	throw UninitializedParameter();
407 408
      }
408 409
    };
409 410
    ///\brief \ref named-templ-param "Named parameter" for setting
410 411
    ///heap and cross reference type
411 412
    ///
412 413
    ///\ref named-templ-param "Named parameter" for setting heap and cross 
413 414
    ///reference type
414 415
    ///
415 416
    template <class H, class CR = typename Digraph::template NodeMap<int> >
416 417
    struct DefHeap
417 418
      : public Dijkstra< Digraph,	LengthMap, DefHeapTraits<H, CR> > { 
418 419
      typedef Dijkstra< Digraph,	LengthMap, DefHeapTraits<H, CR> > Create;
419 420
    };
420 421

	
421 422
    template <class H, class CR>
422 423
    struct DefStandardHeapTraits : public Traits {
423 424
      typedef CR HeapCrossRef;
424 425
      typedef H Heap;
425 426
      static HeapCrossRef *createHeapCrossRef(const Digraph &G) {
426 427
	return new HeapCrossRef(G);
427 428
      }
428 429
      static Heap *createHeap(HeapCrossRef &R) 
429 430
      {
430 431
	return new Heap(R);
431 432
      }
432 433
    };
433 434
    ///\brief \ref named-templ-param "Named parameter" for setting
434 435
    ///heap and cross reference type with automatic allocation
435 436
    ///
436 437
    ///\ref named-templ-param "Named parameter" for setting heap and cross 
437 438
    ///reference type. It can allocate the heap and the cross reference 
438 439
    ///object if the cross reference's constructor waits for the digraph as 
439 440
    ///parameter and the heap's constructor waits for the cross reference.
440 441
    template <class H, class CR = typename Digraph::template NodeMap<int> >
441 442
    struct DefStandardHeap
442 443
      : public Dijkstra< Digraph,	LengthMap, DefStandardHeapTraits<H, CR> > { 
443 444
      typedef Dijkstra< Digraph,	LengthMap, DefStandardHeapTraits<H, CR> > 
444 445
      Create;
445 446
    };
446 447

	
447 448
    template <class T>
448 449
    struct DefOperationTraitsTraits : public Traits {
449 450
      typedef T OperationTraits;
450 451
    };
451 452
    
452 453
    /// \brief \ref named-templ-param "Named parameter" for setting 
453 454
    /// OperationTraits type
454 455
    ///
455 456
    /// \ref named-templ-param "Named parameter" for setting OperationTraits
456 457
    /// type
457 458
    template <class T>
458 459
    struct DefOperationTraits
459 460
      : public Dijkstra<Digraph, LengthMap, DefOperationTraitsTraits<T> > {
460 461
      typedef Dijkstra<Digraph, LengthMap, DefOperationTraitsTraits<T> >
461 462
      Create;
462 463
    };
463 464
    
464 465
    ///@}
465 466

	
466 467

	
467 468
  protected:
468 469

	
469 470
    Dijkstra() {}
470 471

	
471 472
  public:      
472 473
    
473 474
    ///Constructor.
474 475
    
475 476
    ///\param _G the digraph the algorithm will run on.
476 477
    ///\param _length the length map used by the algorithm.
477 478
    Dijkstra(const Digraph& _G, const LengthMap& _length) :
478 479
      G(&_G), length(&_length),
479 480
      _pred(NULL), local_pred(false),
480 481
      _dist(NULL), local_dist(false),
481 482
      _processed(NULL), local_processed(false),
482 483
      _heap_cross_ref(NULL), local_heap_cross_ref(false),
483 484
      _heap(NULL), local_heap(false)
484 485
    { }
485 486
    
486 487
    ///Destructor.
487 488
    ~Dijkstra() 
488 489
    {
489 490
      if(local_pred) delete _pred;
490 491
      if(local_dist) delete _dist;
491 492
      if(local_processed) delete _processed;
492 493
      if(local_heap_cross_ref) delete _heap_cross_ref;
493 494
      if(local_heap) delete _heap;
494 495
    }
495 496

	
496 497
    ///Sets the length map.
497 498

	
498 499
    ///Sets the length map.
499 500
    ///\return <tt> (*this) </tt>
500 501
    Dijkstra &lengthMap(const LengthMap &m) 
501 502
    {
502 503
      length = &m;
503 504
      return *this;
504 505
    }
505 506

	
506 507
    ///Sets the map storing the predecessor arcs.
507 508

	
508 509
    ///Sets the map storing the predecessor arcs.
509 510
    ///If you don't use this function before calling \ref run(),
510 511
    ///it will allocate one. The destuctor deallocates this
511 512
    ///automatically allocated map, of course.
512 513
    ///\return <tt> (*this) </tt>
513 514
    Dijkstra &predMap(PredMap &m) 
514 515
    {
515 516
      if(local_pred) {
516 517
	delete _pred;
517 518
	local_pred=false;
518 519
      }
519 520
      _pred = &m;
520 521
      return *this;
521 522
    }
522 523

	
523 524
    ///Sets the map storing the distances calculated by the algorithm.
524 525

	
525 526
    ///Sets the map storing the distances calculated by the algorithm.
526 527
    ///If you don't use this function before calling \ref run(),
527 528
    ///it will allocate one. The destuctor deallocates this
528 529
    ///automatically allocated map, of course.
529 530
    ///\return <tt> (*this) </tt>
530 531
    Dijkstra &distMap(DistMap &m) 
531 532
    {
532 533
      if(local_dist) {
533 534
	delete _dist;
534 535
	local_dist=false;
535 536
      }
536 537
      _dist = &m;
537 538
      return *this;
538 539
    }
539 540

	
540 541
    ///Sets the heap and the cross reference used by algorithm.
541 542

	
542 543
    ///Sets the heap and the cross reference used by algorithm.
543 544
    ///If you don't use this function before calling \ref run(),
544 545
    ///it will allocate one. The destuctor deallocates this
545 546
    ///automatically allocated heap and cross reference, of course.
546 547
    ///\return <tt> (*this) </tt>
547 548
    Dijkstra &heap(Heap& hp, HeapCrossRef &cr)
548 549
    {
549 550
      if(local_heap_cross_ref) {
550 551
	delete _heap_cross_ref;
551 552
	local_heap_cross_ref=false;
552 553
      }
553 554
      _heap_cross_ref = &cr;
554 555
      if(local_heap) {
555 556
	delete _heap;
556 557
	local_heap=false;
557 558
      }
558 559
      _heap = &hp;
559 560
      return *this;
560 561
    }
561 562

	
562 563
  private:
563 564
    void finalizeNodeData(Node v,Value dst)
564 565
    {
565 566
      _processed->set(v,true);
566 567
      _dist->set(v, dst);
567 568
    }
568 569

	
569 570
  public:
570 571

	
571 572
    typedef PredMapPath<Digraph, PredMap> Path;
572 573

	
573 574
    ///\name Execution control
574 575
    ///The simplest way to execute the algorithm is to use
575 576
    ///one of the member functions called \c run(...).
576 577
    ///\n
577 578
    ///If you need more control on the execution,
578 579
    ///first you must call \ref init(), then you can add several source nodes
579 580
    ///with \ref addSource().
580 581
    ///Finally \ref start() will perform the actual path
581 582
    ///computation.
582 583

	
583 584
    ///@{
584 585

	
585 586
    ///Initializes the internal data structures.
586 587

	
587 588
    ///Initializes the internal data structures.
588 589
    ///
589 590
    void init()
590 591
    {
591 592
      create_maps();
592 593
      _heap->clear();
593 594
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
594 595
	_pred->set(u,INVALID);
595 596
	_processed->set(u,false);
596 597
	_heap_cross_ref->set(u,Heap::PRE_HEAP);
597 598
      }
598 599
    }
599 600
    
600 601
    ///Adds a new source node.
601 602

	
602 603
    ///Adds a new source node to the priority heap.
603 604
    ///
604 605
    ///The optional second parameter is the initial distance of the node.
605 606
    ///
606 607
    ///It checks if the node has already been added to the heap and
607 608
    ///it is pushed to the heap only if either it was not in the heap
608 609
    ///or the shortest path found till then is shorter than \c dst.
609 610
    void addSource(Node s,Value dst=OperationTraits::zero())
610 611
    {
611 612
      if(_heap->state(s) != Heap::IN_HEAP) {
612 613
	_heap->push(s,dst);
613 614
      } else if(OperationTraits::less((*_heap)[s], dst)) {
614 615
	_heap->set(s,dst);
615 616
	_pred->set(s,INVALID);
616 617
      }
617 618
    }
618 619
    
619 620
    ///Processes the next node in the priority heap
620 621

	
621 622
    ///Processes the next node in the priority heap.
622 623
    ///
623 624
    ///\return The processed node.
624 625
    ///
625 626
    ///\warning The priority heap must not be empty!
626 627
    Node processNextNode()
627 628
    {
628 629
      Node v=_heap->top(); 
629 630
      Value oldvalue=_heap->prio();
630 631
      _heap->pop();
631 632
      finalizeNodeData(v,oldvalue);
632 633
      
633 634
      for(OutArcIt e(*G,v); e!=INVALID; ++e) {
634 635
	Node w=G->target(e); 
635 636
	switch(_heap->state(w)) {
636 637
	case Heap::PRE_HEAP:
637 638
	  _heap->push(w,OperationTraits::plus(oldvalue, (*length)[e])); 
638 639
	  _pred->set(w,e);
639 640
	  break;
640 641
	case Heap::IN_HEAP:
641 642
	  {
642 643
	    Value newvalue = OperationTraits::plus(oldvalue, (*length)[e]);
643 644
	    if ( OperationTraits::less(newvalue, (*_heap)[w]) ) {
644 645
	      _heap->decrease(w, newvalue); 
645 646
	      _pred->set(w,e);
646 647
	    }
647 648
	  }
648 649
	  break;
649 650
	case Heap::POST_HEAP:
650 651
	  break;
651 652
	}
652 653
      }
653 654
      return v;
654 655
    }
655 656

	
656 657
    ///Next node to be processed.
657 658
    
658 659
    ///Next node to be processed.
659 660
    ///
660 661
    ///\return The next node to be processed or INVALID if the priority heap
661 662
    /// is empty.
662 663
    Node nextNode()
663 664
    { 
664 665
      return !_heap->empty()?_heap->top():INVALID;
665 666
    }
666 667
 
667 668
    ///\brief Returns \c false if there are nodes
668 669
    ///to be processed in the priority heap
669 670
    ///
670 671
    ///Returns \c false if there are nodes
671 672
    ///to be processed in the priority heap
672 673
    bool emptyQueue() { return _heap->empty(); }
673 674
    ///Returns the number of the nodes to be processed in the priority heap
674 675

	
675 676
    ///Returns the number of the nodes to be processed in the priority heap
676 677
    ///
677 678
    int queueSize() { return _heap->size(); }
678 679
    
679 680
    ///Executes the algorithm.
680 681

	
681 682
    ///Executes the algorithm.
682 683
    ///
683 684
    ///\pre init() must be called and at least one node should be added
684 685
    ///with addSource() before using this function.
685 686
    ///
686 687
    ///This method runs the %Dijkstra algorithm from the root node(s)
687 688
    ///in order to
688 689
    ///compute the
689 690
    ///shortest path to each node. The algorithm computes
690 691
    ///- The shortest path tree.
691 692
    ///- The distance of each node from the root(s).
692 693
    ///
693 694
    void start()
694 695
    {
695 696
      while ( !_heap->empty() ) processNextNode();
696 697
    }
697 698
    
698 699
    ///Executes the algorithm until \c dest is reached.
699 700

	
700 701
    ///Executes the algorithm until \c dest is reached.
701 702
    ///
702 703
    ///\pre init() must be called and at least one node should be added
703 704
    ///with addSource() before using this function.
704 705
    ///
705 706
    ///This method runs the %Dijkstra algorithm from the root node(s)
706 707
    ///in order to
707 708
    ///compute the
708 709
    ///shortest path to \c dest. The algorithm computes
709 710
    ///- The shortest path to \c  dest.
710 711
    ///- The distance of \c dest from the root(s).
711 712
    ///
712 713
    void start(Node dest)
713 714
    {
714 715
      while ( !_heap->empty() && _heap->top()!=dest ) processNextNode();
715 716
      if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
716 717
    }
717 718
    
718 719
    ///Executes the algorithm until a condition is met.
719 720

	
720 721
    ///Executes the algorithm until a condition is met.
721 722
    ///
722 723
    ///\pre init() must be called and at least one node should be added
723 724
    ///with addSource() before using this function.
724 725
    ///
725 726
    ///\param nm must be a bool (or convertible) node map. The algorithm
726 727
    ///will stop when it reaches a node \c v with <tt>nm[v]</tt> true.
727 728
    ///
728 729
    ///\return The reached node \c v with <tt>nm[v]</tt> true or
729 730
    ///\c INVALID if no such node was found.
730 731
    template<class NodeBoolMap>
731 732
    Node start(const NodeBoolMap &nm)
732 733
    {
733 734
      while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
734 735
      if ( _heap->empty() ) return INVALID;
735 736
      finalizeNodeData(_heap->top(),_heap->prio());
736 737
      return _heap->top();
737 738
    }
738 739
    
739 740
    ///Runs %Dijkstra algorithm from node \c s.
740 741
    
741 742
    ///This method runs the %Dijkstra algorithm from a root node \c s
742 743
    ///in order to
743 744
    ///compute the
744 745
    ///shortest path to each node. The algorithm computes
745 746
    ///- The shortest path tree.
746 747
    ///- The distance of each node from the root.
747 748
    ///
748 749
    ///\note d.run(s) is just a shortcut of the following code.
749 750
    ///\code
750 751
    ///  d.init();
751 752
    ///  d.addSource(s);
752 753
    ///  d.start();
753 754
    ///\endcode
754 755
    void run(Node s) {
755 756
      init();
756 757
      addSource(s);
757 758
      start();
758 759
    }
759 760
    
760 761
    ///Finds the shortest path between \c s and \c t.
761 762
    
762 763
    ///Finds the shortest path between \c s and \c t.
763 764
    ///
764 765
    ///\return The length of the shortest s---t path if there exists one,
765 766
    ///0 otherwise.
766 767
    ///\note Apart from the return value, d.run(s) is
767 768
    ///just a shortcut of the following code.
768 769
    ///\code
769 770
    ///  d.init();
770 771
    ///  d.addSource(s);
771 772
    ///  d.start(t);
772 773
    ///\endcode
773 774
    Value run(Node s,Node t) {
774 775
      init();
775 776
      addSource(s);
776 777
      start(t);
777 778
      return (*_pred)[t]==INVALID?OperationTraits::zero():(*_dist)[t];
778 779
    }
779 780
    
780 781
    ///@}
781 782

	
782 783
    ///\name Query Functions
783 784
    ///The result of the %Dijkstra algorithm can be obtained using these
784 785
    ///functions.\n
785 786
    ///Before the use of these functions,
786 787
    ///either run() or start() must be called.
787 788
    
788 789
    ///@{
789 790

	
790 791
    ///Gives back the shortest path.
791 792
    
792 793
    ///Gives back the shortest path.
793 794
    ///\pre The \c t should be reachable from the source.
Ignore white space 6 line context
... ...
@@ -250,997 +250,998 @@
250 250

	
251 251
  static const int INTERPOL_PREC;
252 252
  static const double A4HEIGHT;
253 253
  static const double A4WIDTH;
254 254
  static const double A4BORDER;
255 255

	
256 256
  bool dontPrint;
257 257

	
258 258
public:
259 259
  ///Node shapes
260 260

	
261 261
  ///Node shapes
262 262
  ///
263 263
  enum NodeShapes { 
264 264
    /// = 0
265 265
    ///\image html nodeshape_0.png
266 266
    ///\image latex nodeshape_0.eps "CIRCLE shape (0)" width=2cm
267 267
    CIRCLE=0, 
268 268
    /// = 1
269 269
    ///\image html nodeshape_1.png
270 270
    ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
271 271
    ///
272 272
    SQUARE=1, 
273 273
    /// = 2
274 274
    ///\image html nodeshape_2.png
275 275
    ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm
276 276
    ///
277 277
    DIAMOND=2,
278 278
    /// = 3
279 279
    ///\image html nodeshape_3.png
280 280
    ///\image latex nodeshape_2.eps "MALE shape (4)" width=2cm
281 281
    ///
282 282
    MALE=3,
283 283
    /// = 4
284 284
    ///\image html nodeshape_4.png
285 285
    ///\image latex nodeshape_2.eps "FEMALE shape (4)" width=2cm
286 286
    ///
287 287
    FEMALE=4
288 288
  };
289 289

	
290 290
private:
291 291
  class arcLess {
292 292
    const Graph &g;
293 293
  public:
294 294
    arcLess(const Graph &_g) : g(_g) {}
295 295
    bool operator()(Arc a,Arc b) const 
296 296
    {
297 297
      Node ai=std::min(g.source(a),g.target(a));
298 298
      Node aa=std::max(g.source(a),g.target(a));
299 299
      Node bi=std::min(g.source(b),g.target(b));
300 300
      Node ba=std::max(g.source(b),g.target(b));
301 301
      return ai<bi ||
302 302
	(ai==bi && (aa < ba || 
303 303
		    (aa==ba && ai==g.source(a) && bi==g.target(b))));
304 304
    }
305 305
  };
306 306
  bool isParallel(Arc e,Arc f) const
307 307
  {
308 308
    return (g.source(e)==g.source(f)&&
309 309
	    g.target(e)==g.target(f)) ||
310 310
      (g.source(e)==g.target(f)&&
311 311
       g.target(e)==g.source(f));
312 312
  }
313 313
  template<class TT>
314 314
  static std::string psOut(const dim2::Point<TT> &p) 
315 315
    {
316 316
      std::ostringstream os;	
317 317
      os << p.x << ' ' << p.y;
318 318
      return os.str();
319 319
    }
320 320
  static std::string psOut(const Color &c) 
321 321
    {
322 322
      std::ostringstream os;	
323 323
      os << c.red() << ' ' << c.green() << ' ' << c.blue();
324 324
      return os.str();
325 325
    }
326 326
  
327 327
public:
328 328
  GraphToEps(const T &t) : T(t), dontPrint(false) {};
329 329
  
330 330
  template<class X> struct CoordsTraits : public T {
331 331
  typedef X CoordsMapType;
332 332
    const X &_coords;
333 333
    CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
334 334
  };
335 335
  ///Sets the map of the node coordinates
336 336

	
337 337
  ///Sets the map of the node coordinates.
338 338
  ///\param x must be a node map with dim2::Point<double> or
339 339
  ///\ref dim2::Point "dim2::Point<int>" values. 
340 340
  template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
341 341
    dontPrint=true;
342 342
    return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
343 343
  }
344 344
  template<class X> struct NodeSizesTraits : public T {
345 345
    const X &_nodeSizes;
346 346
    NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
347 347
  };
348 348
  ///Sets the map of the node sizes
349 349

	
350 350
  ///Sets the map of the node sizes
351 351
  ///\param x must be a node map with \c double (or convertible) values. 
352 352
  template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
353 353
  {
354 354
    dontPrint=true;
355 355
    return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
356 356
  }
357 357
  template<class X> struct NodeShapesTraits : public T {
358 358
    const X &_nodeShapes;
359 359
    NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
360 360
  };
361 361
  ///Sets the map of the node shapes
362 362

	
363 363
  ///Sets the map of the node shapes.
364 364
  ///The available shape values
365 365
  ///can be found in \ref NodeShapes "enum NodeShapes".
366 366
  ///\param x must be a node map with \c int (or convertible) values. 
367 367
  ///\sa NodeShapes
368 368
  template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
369 369
  {
370 370
    dontPrint=true;
371 371
    return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x));
372 372
  }
373 373
  template<class X> struct NodeTextsTraits : public T {
374 374
    const X &_nodeTexts;
375 375
    NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
376 376
  };
377 377
  ///Sets the text printed on the nodes
378 378

	
379 379
  ///Sets the text printed on the nodes
380 380
  ///\param x must be a node map with type that can be pushed to a standard
381 381
  ///ostream. 
382 382
  template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
383 383
  {
384 384
    dontPrint=true;
385 385
    _showNodeText=true;
386 386
    return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
387 387
  }
388 388
  template<class X> struct NodePsTextsTraits : public T {
389 389
    const X &_nodePsTexts;
390 390
    NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {}
391 391
  };
392 392
  ///Inserts a PostScript block to the nodes
393 393

	
394 394
  ///With this command it is possible to insert a verbatim PostScript
395 395
  ///block to the nodes.
396 396
  ///The PS current point will be moved to the centre of the node before
397 397
  ///the PostScript block inserted.
398 398
  ///
399 399
  ///Before and after the block a newline character is inserted so you
400 400
  ///don't have to bother with the separators.
401 401
  ///
402 402
  ///\param x must be a node map with type that can be pushed to a standard
403 403
  ///ostream.
404 404
  ///
405 405
  ///\sa nodePsTextsPreamble()
406 406
  template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
407 407
  {
408 408
    dontPrint=true;
409 409
    _showNodePsText=true;
410 410
    return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
411 411
  }
412 412
  template<class X> struct ArcWidthsTraits : public T {
413 413
    const X &_arcWidths;
414 414
    ArcWidthsTraits(const T &t,const X &x) : T(t), _arcWidths(x) {}
415 415
  };
416 416
  ///Sets the map of the arc widths
417 417

	
418 418
  ///Sets the map of the arc widths
419 419
  ///\param x must be an arc map with \c double (or convertible) values. 
420 420
  template<class X> GraphToEps<ArcWidthsTraits<X> > arcWidths(const X &x)
421 421
  {
422 422
    dontPrint=true;
423 423
    return GraphToEps<ArcWidthsTraits<X> >(ArcWidthsTraits<X>(*this,x));
424 424
  }
425 425

	
426 426
  template<class X> struct NodeColorsTraits : public T {
427 427
    const X &_nodeColors;
428 428
    NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
429 429
  };
430 430
  ///Sets the map of the node colors
431 431

	
432 432
  ///Sets the map of the node colors
433 433
  ///\param x must be a node map with \ref Color values.
434 434
  ///
435 435
  ///\sa Palette
436 436
  template<class X> GraphToEps<NodeColorsTraits<X> >
437 437
  nodeColors(const X &x)
438 438
  {
439 439
    dontPrint=true;
440 440
    return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
441 441
  }
442 442
  template<class X> struct NodeTextColorsTraits : public T {
443 443
    const X &_nodeTextColors;
444 444
    NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {}
445 445
  };
446 446
  ///Sets the map of the node text colors
447 447

	
448 448
  ///Sets the map of the node text colors
449 449
  ///\param x must be a node map with \ref Color values. 
450 450
  ///
451 451
  ///\sa Palette
452 452
  template<class X> GraphToEps<NodeTextColorsTraits<X> >
453 453
  nodeTextColors(const X &x)
454 454
  {
455 455
    dontPrint=true;
456 456
    _nodeTextColorType=CUST_COL;
457 457
    return GraphToEps<NodeTextColorsTraits<X> >
458 458
      (NodeTextColorsTraits<X>(*this,x));
459 459
  }
460 460
  template<class X> struct ArcColorsTraits : public T {
461 461
    const X &_arcColors;
462 462
    ArcColorsTraits(const T &t,const X &x) : T(t), _arcColors(x) {}
463 463
  };
464 464
  ///Sets the map of the arc colors
465 465

	
466 466
  ///Sets the map of the arc colors
467 467
  ///\param x must be an arc map with \ref Color values. 
468 468
  ///
469 469
  ///\sa Palette
470 470
  template<class X> GraphToEps<ArcColorsTraits<X> >
471 471
  arcColors(const X &x)
472 472
  {
473 473
    dontPrint=true;
474 474
    return GraphToEps<ArcColorsTraits<X> >(ArcColorsTraits<X>(*this,x));
475 475
  }
476 476
  ///Sets a global scale factor for node sizes
477 477

	
478 478
  ///Sets a global scale factor for node sizes.
479 479
  /// 
480 480
  /// If nodeSizes() is not given, this function simply sets the node
481 481
  /// sizes to \c d.  If nodeSizes() is given, but
482 482
  /// autoNodeScale() is not, then the node size given by
483 483
  /// nodeSizes() will be multiplied by the value \c d.
484 484
  /// If both nodeSizes() and autoNodeScale() are used, then the
485 485
  /// node sizes will be scaled in such a way that the greatest size will be
486 486
  /// equal to \c d.
487 487
  /// \sa nodeSizes()
488 488
  /// \sa autoNodeScale()
489 489
  GraphToEps<T> &nodeScale(double d=.01) {_nodeScale=d;return *this;}
490 490
  ///Turns on/off the automatic node width scaling.
491 491

	
492 492
  ///Turns on/off the automatic node width scaling.
493 493
  ///
494 494
  ///\sa nodeScale()
495 495
  ///
496 496
  GraphToEps<T> &autoNodeScale(bool b=true) {
497 497
    _autoNodeScale=b;return *this;
498 498
  }
499 499

	
500 500
  ///Turns on/off the absolutematic node width scaling.
501 501

	
502 502
  ///Turns on/off the absolutematic node width scaling.
503 503
  ///
504 504
  ///\sa nodeScale()
505 505
  ///
506 506
  GraphToEps<T> &absoluteNodeSizes(bool b=true) {
507 507
    _absoluteNodeSizes=b;return *this;
508 508
  }
509 509

	
510 510
  ///Negates the Y coordinates.
511 511

	
512 512
  ///Negates the Y coordinates.
513 513
  ///
514 514
  GraphToEps<T> &negateY(bool b=true) {
515 515
    _negY=b;return *this;
516 516
  }
517 517

	
518 518
  ///Turn on/off pre-scaling
519 519

	
520 520
  ///By default graphToEps() rescales the whole image in order to avoid
521 521
  ///very big or very small bounding boxes.
522 522
  ///
523 523
  ///This (p)rescaling can be turned off with this function.
524 524
  ///
525 525
  GraphToEps<T> &preScale(bool b=true) {
526 526
    _preScale=b;return *this;
527 527
  }
528 528

	
529 529
  ///Sets a global scale factor for arc widths
530 530

	
531 531
  /// Sets a global scale factor for arc widths.
532 532
  ///
533 533
  /// If arcWidths() is not given, this function simply sets the arc
534 534
  /// widths to \c d.  If arcWidths() is given, but
535 535
  /// autoArcWidthScale() is not, then the arc withs given by
536 536
  /// arcWidths() will be multiplied by the value \c d.
537 537
  /// If both arcWidths() and autoArcWidthScale() are used, then the
538 538
  /// arc withs will be scaled in such a way that the greatest width will be
539 539
  /// equal to \c d.
540 540
  GraphToEps<T> &arcWidthScale(double d=.003) {_arcWidthScale=d;return *this;}
541 541
  ///Turns on/off the automatic arc width scaling.
542 542

	
543 543
  ///Turns on/off the automatic arc width scaling.
544 544
  ///
545 545
  ///\sa arcWidthScale()
546 546
  ///
547 547
  GraphToEps<T> &autoArcWidthScale(bool b=true) {
548 548
    _autoArcWidthScale=b;return *this;
549 549
  }
550 550
  ///Turns on/off the absolutematic arc width scaling.
551 551

	
552 552
  ///Turns on/off the absolutematic arc width scaling.
553 553
  ///
554 554
  ///\sa arcWidthScale()
555 555
  ///
556 556
  GraphToEps<T> &absoluteArcWidths(bool b=true) {
557 557
    _absoluteArcWidths=b;return *this;
558 558
  }
559 559
  ///Sets a global scale factor for the whole picture
560 560

	
561 561
  ///Sets a global scale factor for the whole picture
562 562
  ///
563 563

	
564 564
  GraphToEps<T> &scale(double d) {_scale=d;return *this;}
565 565
  ///Sets the width of the border around the picture
566 566

	
567 567
  ///Sets the width of the border around the picture
568 568
  ///
569 569
  GraphToEps<T> &border(double b=10) {_xBorder=_yBorder=b;return *this;}
570 570
  ///Sets the width of the border around the picture
571 571

	
572 572
  ///Sets the width of the border around the picture
573 573
  ///
574 574
  GraphToEps<T> &border(double x, double y) {
575 575
    _xBorder=x;_yBorder=y;return *this;
576 576
  }
577 577
  ///Sets whether to draw arrows
578 578

	
579 579
  ///Sets whether to draw arrows
580 580
  ///
581 581
  GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
582 582
  ///Sets the length of the arrowheads
583 583

	
584 584
  ///Sets the length of the arrowheads
585 585
  ///
586 586
  GraphToEps<T> &arrowLength(double d=1.0) {_arrowLength*=d;return *this;}
587 587
  ///Sets the width of the arrowheads
588 588

	
589 589
  ///Sets the width of the arrowheads
590 590
  ///
591 591
  GraphToEps<T> &arrowWidth(double d=.3) {_arrowWidth*=d;return *this;}
592 592
  
593 593
  ///Scales the drawing to fit to A4 page
594 594

	
595 595
  ///Scales the drawing to fit to A4 page
596 596
  ///
597 597
  GraphToEps<T> &scaleToA4() {_scaleToA4=true;return *this;}
598 598
  
599 599
  ///Enables parallel arcs
600 600

	
601 601
  ///Enables parallel arcs
602 602
  GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
603 603
  
604 604
  ///Sets the distance 
605 605
  
606 606
  ///Sets the distance 
607 607
  ///
608 608
  GraphToEps<T> &parArcDist(double d) {_parArcDist*=d;return *this;}
609 609
  
610 610
  ///Hides the arcs
611 611
  
612 612
  ///Hides the arcs
613 613
  ///
614 614
  GraphToEps<T> &hideArcs(bool b=true) {_showArcs=!b;return *this;}
615 615
  ///Hides the nodes
616 616
  
617 617
  ///Hides the nodes
618 618
  ///
619 619
  GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
620 620
  
621 621
  ///Sets the size of the node texts
622 622
  
623 623
  ///Sets the size of the node texts
624 624
  ///
625 625
  GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
626 626

	
627 627
  ///Sets the color of the node texts to be different from the node color
628 628

	
629 629
  ///Sets the color of the node texts to be as different from the node color
630 630
  ///as it is possible
631 631
  ///
632 632
  GraphToEps<T> &distantColorNodeTexts()
633 633
  {_nodeTextColorType=DIST_COL;return *this;}
634 634
  ///Sets the color of the node texts to be black or white and always visible.
635 635

	
636 636
  ///Sets the color of the node texts to be black or white according to
637 637
  ///which is more 
638 638
  ///different from the node color
639 639
  ///
640 640
  GraphToEps<T> &distantBWNodeTexts()
641 641
  {_nodeTextColorType=DIST_BW;return *this;}
642 642

	
643 643
  ///Gives a preamble block for node Postscript block.
644 644
  
645 645
  ///Gives a preamble block for node Postscript block.
646 646
  ///
647 647
  ///\sa nodePsTexts()
648 648
  GraphToEps<T> & nodePsTextsPreamble(const char *str) {
649 649
    _nodePsTextsPreamble=str ;return *this;
650 650
  }
651 651
  ///Sets whether the the graph is undirected
652 652

	
653 653
  ///Sets whether the the graph is undirected.
654 654
  ///
655 655
  ///This setting is the default for undirected graphs.
656 656
  ///
657 657
  ///\sa directed()
658 658
   GraphToEps<T> &undirected(bool b=true) {_undirected=b;return *this;}
659 659

	
660 660
  ///Sets whether the the graph is directed
661 661

	
662 662
  ///Sets whether the the graph is directed.
663 663
  ///Use it to show the edges as a pair of directed ones.
664 664
  ///
665 665
  ///This setting is the default for digraphs.
666 666
  ///
667 667
  ///\sa undirected()
668 668
  GraphToEps<T> &directed(bool b=true) {_undirected=!b;return *this;}
669 669
  
670 670
  ///Sets the title.
671 671

	
672 672
  ///Sets the title of the generated image,
673 673
  ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
674 674
  ///the EPS file.
675 675
  GraphToEps<T> &title(const std::string &t) {_title=t;return *this;}
676 676
  ///Sets the copyright statement.
677 677

	
678 678
  ///Sets the copyright statement of the generated image,
679 679
  ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
680 680
  ///the EPS file.
681 681
  GraphToEps<T> &copyright(const std::string &t) {_copyright=t;return *this;}
682 682

	
683 683
protected:
684 684
  bool isInsideNode(dim2::Point<double> p, double r,int t) 
685 685
  {
686 686
    switch(t) {
687 687
    case CIRCLE:
688 688
    case MALE:
689 689
    case FEMALE:
690 690
      return p.normSquare()<=r*r;
691 691
    case SQUARE:
692 692
      return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
693 693
    case DIAMOND:
694 694
      return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r;
695 695
    }
696 696
    return false;
697 697
  }
698 698

	
699 699
public:
700 700
  ~GraphToEps() { }
701 701
  
702 702
  ///Draws the graph.
703 703

	
704 704
  ///Like other functions using
705 705
  ///\ref named-templ-func-param "named template parameters",
706 706
  ///this function calls the algorithm itself, i.e. in this case
707 707
  ///it draws the graph.
708 708
  void run() {
709 709
    //\todo better 'epsilon' would be nice here.
710 710
    const double EPSILON=1e-9;
711 711
    if(dontPrint) return;
712 712
    
713 713
    _graph_to_eps_bits::_NegY<typename T::CoordsMapType>
714 714
      mycoords(_coords,_negY);
715 715

	
716 716
    os << "%!PS-Adobe-2.0 EPSF-2.0\n";
717 717
    if(_title.size()>0) os << "%%Title: " << _title << '\n';
718 718
     if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n';
719 719
//        << "%%Copyright: XXXX\n"
720 720
    os << "%%Creator: LEMON, graphToEps()\n";
721 721

	
722 722
    {    
723 723
#ifndef WIN32 
724 724
      timeval tv;
725 725
      gettimeofday(&tv, 0);
726 726

	
727 727
      char cbuf[26];
728 728
      ctime_r(&tv.tv_sec,cbuf);
729 729
      os << "%%CreationDate: " << cbuf;
730 730
#else
731 731
      SYSTEMTIME time;
732 732
      char buf1[11], buf2[9], buf3[5];
733 733
      
734 734
      GetSystemTime(&time);
735 735
      if (GetDateFormat(LOCALE_USER_DEFAULT, 0, &time, 
736 736
			"ddd MMM dd", buf1, 11) &&
737 737
	  GetTimeFormat(LOCALE_USER_DEFAULT, 0, &time, 
738 738
			"HH':'mm':'ss", buf2, 9) &&
739 739
	  GetDateFormat(LOCALE_USER_DEFAULT, 0, &time, 
740 740
				"yyyy", buf3, 5)) {
741 741
	os << "%%CreationDate: " << buf1 << ' ' 
742 742
	   << buf2 << ' ' << buf3 << std::endl;
743 743
      }	  
744 744
#endif
745 745
    }
746 746

	
747 747
    if (_autoArcWidthScale) {
748 748
      double max_w=0;
749 749
      for(ArcIt e(g);e!=INVALID;++e)
750 750
	max_w=std::max(double(_arcWidths[e]),max_w);
751 751
      ///\todo better 'epsilon' would be nice here.
752 752
      if(max_w>EPSILON) {
753 753
	_arcWidthScale/=max_w;
754 754
      }
755 755
    }
756 756

	
757 757
    if (_autoNodeScale) {
758 758
      double max_s=0;
759 759
      for(NodeIt n(g);n!=INVALID;++n)
760 760
	max_s=std::max(double(_nodeSizes[n]),max_s);
761 761
      ///\todo better 'epsilon' would be nice here.
762 762
      if(max_s>EPSILON) {
763 763
	_nodeScale/=max_s;
764 764
      }
765 765
    }
766 766

	
767 767
    double diag_len = 1;
768 768
    if(!(_absoluteNodeSizes&&_absoluteArcWidths)) {
769 769
      dim2::BoundingBox<double> bb;
770 770
      for(NodeIt n(g);n!=INVALID;++n) bb.add(mycoords[n]);
771 771
      if (bb.empty()) {
772 772
	bb = dim2::BoundingBox<double>(dim2::Point<double>(0,0));
773 773
      }
774 774
      diag_len = std::sqrt((bb.bottomLeft()-bb.topRight()).normSquare());
775 775
      if(diag_len<EPSILON) diag_len = 1;
776 776
      if(!_absoluteNodeSizes) _nodeScale*=diag_len;
777 777
      if(!_absoluteArcWidths) _arcWidthScale*=diag_len;
778 778
    }
779 779
    
780 780
    dim2::BoundingBox<double> bb;
781 781
    for(NodeIt n(g);n!=INVALID;++n) {
782 782
      double ns=_nodeSizes[n]*_nodeScale;
783 783
      dim2::Point<double> p(ns,ns);
784 784
      switch(_nodeShapes[n]) {
785 785
      case CIRCLE:
786 786
      case SQUARE:
787 787
      case DIAMOND:
788 788
	bb.add(p+mycoords[n]);
789 789
	bb.add(-p+mycoords[n]);
790 790
	break;
791 791
      case MALE:
792 792
	bb.add(-p+mycoords[n]);
793 793
	bb.add(dim2::Point<double>(1.5*ns,1.5*std::sqrt(3.0)*ns)+mycoords[n]);
794 794
	break;
795 795
      case FEMALE:
796 796
	bb.add(p+mycoords[n]);
797 797
	bb.add(dim2::Point<double>(-ns,-3.01*ns)+mycoords[n]);
798 798
	break;
799 799
      }
800 800
    }
801 801
    if (bb.empty()) {
802 802
      bb = dim2::BoundingBox<double>(dim2::Point<double>(0,0));
803 803
    }
804 804
    
805 805
    if(_scaleToA4)
806 806
      os <<"%%BoundingBox: 0 0 596 842\n%%DocumentPaperSizes: a4\n";
807 807
    else {
808 808
      if(_preScale) {
809 809
	//Rescale so that BoundingBox won't be neither to big nor too small.
810 810
	while(bb.height()*_scale>1000||bb.width()*_scale>1000) _scale/=10;
811 811
	while(bb.height()*_scale<100||bb.width()*_scale<100) _scale*=10;
812 812
      }
813 813
      
814 814
      os << "%%BoundingBox: "
815 815
	 << int(floor(bb.left()   * _scale - _xBorder)) << ' '
816 816
	 << int(floor(bb.bottom() * _scale - _yBorder)) << ' '
817 817
	 << int(ceil(bb.right()  * _scale + _xBorder)) << ' '
818 818
	 << int(ceil(bb.top()    * _scale + _yBorder)) << '\n';
819 819
    }
820 820
    
821 821
    os << "%%EndComments\n";
822 822
    
823 823
    //x1 y1 x2 y2 x3 y3 cr cg cb w
824 824
    os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
825 825
       << "      4 2 roll 1 index 1 index curveto stroke } bind def\n";
826 826
    os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
827 827
    //x y r
828 828
    os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def\n";
829 829
    //x y r
830 830
    os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
831 831
       << "      2 index 1 index sub 2 index 2 index add lineto\n"
832 832
       << "      2 index 1 index sub 2 index 2 index sub lineto\n"
833 833
       << "      2 index 1 index add 2 index 2 index sub lineto\n"
834 834
       << "      closepath pop pop pop} bind def\n";
835 835
    //x y r
836 836
    os << "/di { newpath 2 index 1 index add 2 index moveto\n"
837 837
       << "      2 index             2 index 2 index add lineto\n"
838 838
       << "      2 index 1 index sub 2 index             lineto\n"
839 839
       << "      2 index             2 index 2 index sub lineto\n"
840 840
       << "      closepath pop pop pop} bind def\n";
841 841
    // x y r cr cg cb
842 842
    os << "/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill\n"
843 843
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
844 844
       << "   } bind def\n";
845 845
    os << "/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill\n"
846 846
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div sq fill\n"
847 847
       << "   } bind def\n";
848 848
    os << "/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill\n"
849 849
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div di fill\n"
850 850
       << "   } bind def\n";
851 851
    os << "/nfemale { 0 0 0 setrgbcolor 3 index "
852 852
       << _nodeBorderQuotient/(1+_nodeBorderQuotient)
853 853
       << " 1.5 mul mul setlinewidth\n"
854 854
       << "  newpath 5 index 5 index moveto "
855 855
       << "5 index 5 index 5 index 3.01 mul sub\n"
856 856
       << "  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto\n"
857 857
       << "  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke\n"
858 858
       << "  5 index 5 index 5 index c fill\n"
859 859
       << "  setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
860 860
       << "  } bind def\n";
861 861
    os << "/nmale {\n"
862 862
       << "  0 0 0 setrgbcolor 3 index "
863 863
       << _nodeBorderQuotient/(1+_nodeBorderQuotient)
864 864
       <<" 1.5 mul mul setlinewidth\n"
865 865
       << "  newpath 5 index 5 index moveto\n"
866 866
       << "  5 index 4 index 1 mul 1.5 mul add\n"
867 867
       << "  5 index 5 index 3 sqrt 1.5 mul mul add\n"
868 868
       << "  1 index 1 index lineto\n"
869 869
       << "  1 index 1 index 7 index sub moveto\n"
870 870
       << "  1 index 1 index lineto\n"
871 871
       << "  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto\n"
872 872
       << "  stroke\n"
873 873
       << "  5 index 5 index 5 index c fill\n"
874 874
       << "  setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
875 875
       << "  } bind def\n";
876 876
    
877 877

	
878 878
    os << "/arrl " << _arrowLength << " def\n";
879 879
    os << "/arrw " << _arrowWidth << " def\n";
880 880
    // l dx_norm dy_norm
881 881
    os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
882 882
    //len w dx_norm dy_norm x1 y1 cr cg cb
883 883
    os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def\n"
884 884
       << "       /w exch def /len exch def\n"
885 885
      //	 << "       0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
886 886
       << "       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
887 887
       << "       len w sub arrl sub dx dy lrl\n"
888 888
       << "       arrw dy dx neg lrl\n"
889 889
       << "       dx arrl w add mul dy w 2 div arrw add mul sub\n"
890 890
       << "       dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
891 891
       << "       dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
892 892
       << "       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
893 893
       << "       arrw dy dx neg lrl\n"
894 894
       << "       len w sub arrl sub neg dx dy lrl\n"
895 895
       << "       closepath fill } bind def\n";
896 896
    os << "/cshow { 2 index 2 index moveto dup stringwidth pop\n"
897 897
       << "         neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n";
898 898

	
899 899
    os << "\ngsave\n";
900 900
    if(_scaleToA4)
901 901
      if(bb.height()>bb.width()) {
902 902
	double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.height(),
903 903
		  (A4WIDTH-2*A4BORDER)/bb.width());
904 904
	os << ((A4WIDTH -2*A4BORDER)-sc*bb.width())/2 + A4BORDER << ' '
905 905
	   << ((A4HEIGHT-2*A4BORDER)-sc*bb.height())/2 + A4BORDER
906 906
	   << " translate\n"
907 907
	   << sc << " dup scale\n"
908 908
	   << -bb.left() << ' ' << -bb.bottom() << " translate\n";
909 909
      }
910 910
      else {
911 911
	//\todo Verify centering
912 912
	double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.width(),
913 913
		  (A4WIDTH-2*A4BORDER)/bb.height());
914 914
	os << ((A4WIDTH -2*A4BORDER)-sc*bb.height())/2 + A4BORDER << ' '
915 915
	   << ((A4HEIGHT-2*A4BORDER)-sc*bb.width())/2 + A4BORDER 
916 916
	   << " translate\n"
917 917
	   << sc << " dup scale\n90 rotate\n"
918 918
	   << -bb.left() << ' ' << -bb.top() << " translate\n";	
919 919
	}
920 920
    else if(_scale!=1.0) os << _scale << " dup scale\n";
921 921
    
922 922
    if(_showArcs) {
923 923
      os << "%Arcs:\ngsave\n";      
924 924
      if(_enableParallel) {
925 925
	std::vector<Arc> el;
926 926
	for(ArcIt e(g);e!=INVALID;++e)
927 927
	  if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
928 928
	     &&g.source(e)!=g.target(e))
929 929
	    el.push_back(e);
930 930
	std::sort(el.begin(),el.end(),arcLess(g));
931 931
	
932 932
	typename std::vector<Arc>::iterator j;
933 933
	for(typename std::vector<Arc>::iterator i=el.begin();i!=el.end();i=j) {
934 934
	  for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ;
935 935

	
936 936
	  double sw=0;
937 937
	  for(typename std::vector<Arc>::iterator e=i;e!=j;++e)
938 938
	    sw+=_arcWidths[*e]*_arcWidthScale+_parArcDist;
939 939
	  sw-=_parArcDist;
940 940
	  sw/=-2.0;
941 941
	  dim2::Point<double>
942 942
	    dvec(mycoords[g.target(*i)]-mycoords[g.source(*i)]);
943 943
	  double l=std::sqrt(dvec.normSquare()); 
944 944
	  //\todo better 'epsilon' would be nice here.
945 945
	  dim2::Point<double> d(dvec/std::max(l,EPSILON));
946 946
 	  dim2::Point<double> m;
947 947
// 	  m=dim2::Point<double>(mycoords[g.target(*i)]+mycoords[g.source(*i)])/2.0;
948 948

	
949 949
//  	  m=dim2::Point<double>(mycoords[g.source(*i)])+
950 950
// 	    dvec*(double(_nodeSizes[g.source(*i)])/
951 951
// 	       (_nodeSizes[g.source(*i)]+_nodeSizes[g.target(*i)]));
952 952

	
953 953
 	  m=dim2::Point<double>(mycoords[g.source(*i)])+
954 954
	    d*(l+_nodeSizes[g.source(*i)]-_nodeSizes[g.target(*i)])/2.0;
955 955

	
956 956
	  for(typename std::vector<Arc>::iterator e=i;e!=j;++e) {
957 957
	    sw+=_arcWidths[*e]*_arcWidthScale/2.0;
958 958
	    dim2::Point<double> mm=m+rot90(d)*sw/.75;
959 959
	    if(_drawArrows) {
960 960
	      int node_shape;
961 961
	      dim2::Point<double> s=mycoords[g.source(*e)];
962 962
	      dim2::Point<double> t=mycoords[g.target(*e)];
963 963
	      double rn=_nodeSizes[g.target(*e)]*_nodeScale;
964 964
	      node_shape=_nodeShapes[g.target(*e)];
965 965
	      dim2::Bezier3 bez(s,mm,mm,t);
966 966
	      double t1=0,t2=1;
967 967
	      for(int ii=0;ii<INTERPOL_PREC;++ii)
968 968
		if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t2=(t1+t2)/2;
969 969
		else t1=(t1+t2)/2;
970 970
	      dim2::Point<double> apoint=bez((t1+t2)/2);
971 971
	      rn = _arrowLength+_arcWidths[*e]*_arcWidthScale;
972 972
	      rn*=rn;
973 973
	      t2=(t1+t2)/2;t1=0;
974 974
	      for(int ii=0;ii<INTERPOL_PREC;++ii)
975 975
		if((bez((t1+t2)/2)-apoint).normSquare()>rn) t1=(t1+t2)/2;
976 976
		else t2=(t1+t2)/2;
977 977
	      dim2::Point<double> linend=bez((t1+t2)/2);	      
978 978
	      bez=bez.before((t1+t2)/2);
979 979
// 	      rn=_nodeSizes[g.source(*e)]*_nodeScale;
980 980
// 	      node_shape=_nodeShapes[g.source(*e)];
981 981
// 	      t1=0;t2=1;
982 982
// 	      for(int i=0;i<INTERPOL_PREC;++i)
983 983
// 		if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t1=(t1+t2)/2;
984 984
// 		else t2=(t1+t2)/2;
985 985
// 	      bez=bez.after((t1+t2)/2);
986 986
	      os << _arcWidths[*e]*_arcWidthScale << " setlinewidth "
987 987
		 << _arcColors[*e].red() << ' '
988 988
		 << _arcColors[*e].green() << ' '
989 989
		 << _arcColors[*e].blue() << " setrgbcolor newpath\n"
990 990
		 << bez.p1.x << ' ' <<  bez.p1.y << " moveto\n"
991 991
		 << bez.p2.x << ' ' << bez.p2.y << ' '
992 992
		 << bez.p3.x << ' ' << bez.p3.y << ' '
993 993
		 << bez.p4.x << ' ' << bez.p4.y << " curveto stroke\n";
994 994
	      dim2::Point<double> dd(rot90(linend-apoint));
995 995
	      dd*=(.5*_arcWidths[*e]*_arcWidthScale+_arrowWidth)/
996 996
		std::sqrt(dd.normSquare());
997 997
	      os << "newpath " << psOut(apoint) << " moveto "
998 998
		 << psOut(linend+dd) << " lineto "
999 999
		 << psOut(linend-dd) << " lineto closepath fill\n";
1000 1000
	    }
1001 1001
	    else {
1002 1002
	      os << mycoords[g.source(*e)].x << ' '
1003 1003
		 << mycoords[g.source(*e)].y << ' '
1004 1004
		 << mm.x << ' ' << mm.y << ' '
1005 1005
		 << mycoords[g.target(*e)].x << ' '
1006 1006
		 << mycoords[g.target(*e)].y << ' '
1007 1007
		 << _arcColors[*e].red() << ' '
1008 1008
		 << _arcColors[*e].green() << ' '
1009 1009
		 << _arcColors[*e].blue() << ' '
1010 1010
		 << _arcWidths[*e]*_arcWidthScale << " lb\n";
1011 1011
	    }
1012 1012
	    sw+=_arcWidths[*e]*_arcWidthScale/2.0+_parArcDist;
1013 1013
	  }
1014 1014
	}
1015 1015
      }
1016 1016
      else for(ArcIt e(g);e!=INVALID;++e)
1017 1017
	if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
1018
	   &&g.source(e)!=g.target(e))
1018
	   &&g.source(e)!=g.target(e)) {
1019 1019
	  if(_drawArrows) {
1020 1020
	    dim2::Point<double> d(mycoords[g.target(e)]-mycoords[g.source(e)]);
1021 1021
	    double rn=_nodeSizes[g.target(e)]*_nodeScale;
1022 1022
	    int node_shape=_nodeShapes[g.target(e)];
1023 1023
	    double t1=0,t2=1;
1024 1024
	    for(int i=0;i<INTERPOL_PREC;++i)
1025 1025
	      if(isInsideNode((-(t1+t2)/2)*d,rn,node_shape)) t1=(t1+t2)/2;
1026 1026
	      else t2=(t1+t2)/2;
1027 1027
	    double l=std::sqrt(d.normSquare());
1028 1028
	    d/=l;
1029 1029
	    
1030 1030
	    os << l*(1-(t1+t2)/2) << ' '
1031 1031
	       << _arcWidths[e]*_arcWidthScale << ' '
1032 1032
	       << d.x << ' ' << d.y << ' '
1033 1033
	       << mycoords[g.source(e)].x << ' '
1034 1034
	       << mycoords[g.source(e)].y << ' '
1035 1035
	       << _arcColors[e].red() << ' '
1036 1036
	       << _arcColors[e].green() << ' '
1037 1037
	       << _arcColors[e].blue() << " arr\n";
1038
	  }
1038
	  } 
1039 1039
	  else os << mycoords[g.source(e)].x << ' '
1040 1040
		  << mycoords[g.source(e)].y << ' '
1041 1041
		  << mycoords[g.target(e)].x << ' '
1042 1042
		  << mycoords[g.target(e)].y << ' '
1043 1043
		  << _arcColors[e].red() << ' '
1044 1044
		  << _arcColors[e].green() << ' '
1045 1045
		  << _arcColors[e].blue() << ' '
1046 1046
		  << _arcWidths[e]*_arcWidthScale << " l\n";
1047
	}
1047 1048
      os << "grestore\n";
1048 1049
    }
1049 1050
    if(_showNodes) {
1050 1051
      os << "%Nodes:\ngsave\n";
1051 1052
      for(NodeIt n(g);n!=INVALID;++n) {
1052 1053
	os << mycoords[n].x << ' ' << mycoords[n].y << ' '
1053 1054
	   << _nodeSizes[n]*_nodeScale << ' '
1054 1055
	   << _nodeColors[n].red() << ' '
1055 1056
	   << _nodeColors[n].green() << ' '
1056 1057
	   << _nodeColors[n].blue() << ' ';
1057 1058
	switch(_nodeShapes[n]) {
1058 1059
	case CIRCLE:
1059 1060
	  os<< "nc";break;
1060 1061
	case SQUARE:
1061 1062
	  os<< "nsq";break;
1062 1063
	case DIAMOND:
1063 1064
	  os<< "ndi";break;
1064 1065
	case MALE:
1065 1066
	  os<< "nmale";break;
1066 1067
	case FEMALE:
1067 1068
	  os<< "nfemale";break;
1068 1069
	}
1069 1070
	os<<'\n';
1070 1071
      }
1071 1072
      os << "grestore\n";
1072 1073
    }
1073 1074
    if(_showNodeText) {
1074 1075
      os << "%Node texts:\ngsave\n";
1075 1076
      os << "/fosi " << _nodeTextSize << " def\n";
1076 1077
      os << "(Helvetica) findfont fosi scalefont setfont\n";
1077 1078
      for(NodeIt n(g);n!=INVALID;++n) {
1078 1079
	switch(_nodeTextColorType) {
1079 1080
	case DIST_COL:
1080 1081
	  os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
1081 1082
	  break;
1082 1083
	case DIST_BW:
1083 1084
	  os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
1084 1085
	  break;
1085 1086
	case CUST_COL:
1086 1087
	  os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
1087 1088
	  break;
1088 1089
	default:
1089 1090
	  os << "0 0 0 setrgbcolor\n";
1090 1091
	}
1091 1092
	os << mycoords[n].x << ' ' << mycoords[n].y
1092 1093
	   << " (" << _nodeTexts[n] << ") cshow\n";
1093 1094
      }
1094 1095
      os << "grestore\n";
1095 1096
    }
1096 1097
    if(_showNodePsText) {
1097 1098
      os << "%Node PS blocks:\ngsave\n";
1098 1099
      for(NodeIt n(g);n!=INVALID;++n)
1099 1100
	os << mycoords[n].x << ' ' << mycoords[n].y
1100 1101
	   << " moveto\n" << _nodePsTexts[n] << "\n";
1101 1102
      os << "grestore\n";
1102 1103
    }
1103 1104
    
1104 1105
    os << "grestore\nshowpage\n";
1105 1106

	
1106 1107
    //CleanUp:
1107 1108
    if(_pleaseRemoveOsStream) {delete &os;}
1108 1109
  }
1109 1110

	
1110 1111
  ///\name Aliases
1111 1112
  ///These are just some aliases to other parameter setting functions.
1112 1113

	
1113 1114
  ///@{
1114 1115

	
1115 1116
  ///An alias for arcWidths()
1116 1117

	
1117 1118
  ///An alias for arcWidths()
1118 1119
  ///
1119 1120
  template<class X> GraphToEps<ArcWidthsTraits<X> > edgeWidths(const X &x)
1120 1121
  {
1121 1122
    return arcWidths(x);
1122 1123
  }
1123 1124

	
1124 1125
  ///An alias for arcColors()
1125 1126

	
1126 1127
  ///An alias for arcColors()
1127 1128
  ///
1128 1129
  template<class X> GraphToEps<ArcColorsTraits<X> >
1129 1130
  edgeColors(const X &x)
1130 1131
  {
1131 1132
    return arcColors(x);
1132 1133
  }
1133 1134

	
1134 1135
  ///An alias for arcWidthScale()
1135 1136

	
1136 1137
  ///An alias for arcWidthScale()
1137 1138
  ///
1138 1139
  GraphToEps<T> &edgeWidthScale(double d) {return arcWidthScale(d);}
1139 1140

	
1140 1141
  ///An alias for autoArcWidthScale()
1141 1142

	
1142 1143
  ///An alias for autoArcWidthScale()
1143 1144
  ///
1144 1145
  GraphToEps<T> &autoEdgeWidthScale(bool b=true)
1145 1146
  {
1146 1147
    return autoArcWidthScale(b);
1147 1148
  }
1148 1149
  
1149 1150
  ///An alias for absoluteArcWidths()
1150 1151

	
1151 1152
  ///An alias for absoluteArcWidths()
1152 1153
  ///
1153 1154
  GraphToEps<T> &absoluteEdgeWidths(bool b=true)
1154 1155
  {
1155 1156
    return absoluteArcWidths(b);
1156 1157
  }
1157 1158
  
1158 1159
  ///An alias for parArcDist()
1159 1160

	
1160 1161
  ///An alias for parArcDist()
1161 1162
  ///
1162 1163
  GraphToEps<T> &parEdgeDist(double d) {return parArcDist(d);}
1163 1164
  
1164 1165
  ///An alias for hideArcs()
1165 1166
  
1166 1167
  ///An alias for hideArcs()
1167 1168
  ///
1168 1169
  GraphToEps<T> &hideEdges(bool b=true) {return hideArcs(b);}
1169 1170

	
1170 1171
  ///@}
1171 1172
};
1172 1173

	
1173 1174
template<class T>
1174 1175
const int GraphToEps<T>::INTERPOL_PREC = 20;
1175 1176
template<class T>
1176 1177
const double GraphToEps<T>::A4HEIGHT = 841.8897637795276;
1177 1178
template<class T>
1178 1179
const double GraphToEps<T>::A4WIDTH  = 595.275590551181;
1179 1180
template<class T>
1180 1181
const double GraphToEps<T>::A4BORDER = 15;
1181 1182

	
1182 1183

	
1183 1184
///Generates an EPS file from a graph
1184 1185

	
1185 1186
///\ingroup eps_io
1186 1187
///Generates an EPS file from a graph.
1187 1188
///\param g is a reference to the graph to be printed
1188 1189
///\param os is a reference to the output stream.
1189 1190
///By default it is <tt>std::cout</tt>
1190 1191
///
1191 1192
///This function also has a lot of
1192 1193
///\ref named-templ-func-param "named parameters",
1193 1194
///they are declared as the members of class \ref GraphToEps. The following
1194 1195
///example shows how to use these parameters.
1195 1196
///\code
1196 1197
/// graphToEps(g,os).scale(10).coords(coords)
1197 1198
///              .nodeScale(2).nodeSizes(sizes)
1198 1199
///              .arcWidthScale(.4).run();
1199 1200
///\endcode
1200 1201
///\warning Don't forget to put the \ref GraphToEps::run() "run()"
1201 1202
///to the end of the parameter list.
1202 1203
///\sa GraphToEps
1203 1204
///\sa graphToEps(G &g, const char *file_name)
1204 1205
template<class G>
1205 1206
GraphToEps<DefaultGraphToEpsTraits<G> > 
1206 1207
graphToEps(G &g, std::ostream& os=std::cout)
1207 1208
{
1208 1209
  return 
1209 1210
    GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
1210 1211
}
1211 1212
 
1212 1213
///Generates an EPS file from a graph
1213 1214

	
1214 1215
///\ingroup eps_io
1215 1216
///This function does the same as
1216 1217
///\ref graphToEps(G &g,std::ostream& os)
1217 1218
///but it writes its output into the file \c file_name
1218 1219
///instead of a stream.
1219 1220
///\sa graphToEps(G &g, std::ostream& os)
1220 1221
template<class G>
1221 1222
GraphToEps<DefaultGraphToEpsTraits<G> > 
1222 1223
graphToEps(G &g,const char *file_name)
1223 1224
{
1224 1225
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1225 1226
    (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name),true));
1226 1227
}
1227 1228

	
1228 1229
///Generates an EPS file from a graph
1229 1230

	
1230 1231
///\ingroup eps_io
1231 1232
///This function does the same as
1232 1233
///\ref graphToEps(G &g,std::ostream& os)
1233 1234
///but it writes its output into the file \c file_name
1234 1235
///instead of a stream.
1235 1236
///\sa graphToEps(G &g, std::ostream& os)
1236 1237
template<class G>
1237 1238
GraphToEps<DefaultGraphToEpsTraits<G> > 
1238 1239
graphToEps(G &g,const std::string& file_name)
1239 1240
{
1240 1241
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1241 1242
    (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name.c_str()),true));
1242 1243
}
1243 1244

	
1244 1245
} //END OF NAMESPACE LEMON
1245 1246

	
1246 1247
#endif // LEMON_GRAPH_TO_EPS_H
Ignore white space 6 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_LIST_GRAPH_H
20 20
#define LEMON_LIST_GRAPH_H
21 21

	
22 22
///\ingroup graphs
23 23
///\file
24 24
///\brief ListDigraph, ListGraph classes.
25 25

	
26 26
#include <lemon/bits/graph_extender.h>
27 27

	
28 28
#include <vector>
29 29
#include <list>
30 30

	
31 31
namespace lemon {
32 32

	
33 33
  class ListDigraphBase {
34 34

	
35 35
  protected:
36 36
    struct NodeT {
37 37
      int first_in, first_out;
38 38
      int prev, next;
39 39
    };
40 40
 
41 41
    struct ArcT {
42 42
      int target, source;
43 43
      int prev_in, prev_out;
44 44
      int next_in, next_out;
45 45
    };
46 46

	
47 47
    std::vector<NodeT> nodes;
48 48

	
49 49
    int first_node;
50 50

	
51 51
    int first_free_node;
52 52

	
53 53
    std::vector<ArcT> arcs;
54 54

	
55 55
    int first_free_arc;
56 56
    
57 57
  public:
58 58
    
59 59
    typedef ListDigraphBase Digraph;
60 60
    
61 61
    class Node {
62 62
      friend class ListDigraphBase;
63 63
    protected:
64 64

	
65 65
      int id;
66 66
      explicit Node(int pid) { id = pid;}
67 67

	
68 68
    public:
69 69
      Node() {}
70 70
      Node (Invalid) { id = -1; }
71 71
      bool operator==(const Node& node) const {return id == node.id;}
72 72
      bool operator!=(const Node& node) const {return id != node.id;}
73 73
      bool operator<(const Node& node) const {return id < node.id;}
74 74
    };
75 75

	
76 76
    class Arc {
77 77
      friend class ListDigraphBase;
78 78
    protected:
79 79

	
80 80
      int id;
81 81
      explicit Arc(int pid) { id = pid;}
82 82

	
83 83
    public:
84 84
      Arc() {}
85 85
      Arc (Invalid) { id = -1; }
86 86
      bool operator==(const Arc& arc) const {return id == arc.id;}
87 87
      bool operator!=(const Arc& arc) const {return id != arc.id;}
88 88
      bool operator<(const Arc& arc) const {return id < arc.id;}
89 89
    };
90 90

	
91 91

	
92 92

	
93 93
    ListDigraphBase()
94 94
      : nodes(), first_node(-1),
95 95
	first_free_node(-1), arcs(), first_free_arc(-1) {}
96 96

	
97 97
    
98 98
    int maxNodeId() const { return nodes.size()-1; } 
99 99
    int maxArcId() const { return arcs.size()-1; }
100 100

	
101 101
    Node source(Arc e) const { return Node(arcs[e.id].source); }
102 102
    Node target(Arc e) const { return Node(arcs[e.id].target); }
103 103

	
104 104

	
105 105
    void first(Node& node) const { 
106 106
      node.id = first_node;
107 107
    }
108 108

	
109 109
    void next(Node& node) const {
110 110
      node.id = nodes[node.id].next;
111 111
    }
112 112

	
113 113

	
114 114
    void first(Arc& arc) const { 
115 115
      int n;
116 116
      for(n = first_node; 
117 117
	  n!=-1 && nodes[n].first_in == -1; 
118
	  n = nodes[n].next);
118
	  n = nodes[n].next) {}
119 119
      arc.id = (n == -1) ? -1 : nodes[n].first_in;
120 120
    }
121 121

	
122 122
    void next(Arc& arc) const {
123 123
      if (arcs[arc.id].next_in != -1) {
124 124
	arc.id = arcs[arc.id].next_in;
125 125
      } else {
126 126
	int n;
127 127
	for(n = nodes[arcs[arc.id].target].next;
128
	  n!=-1 && nodes[n].first_in == -1; 
129
	  n = nodes[n].next);
128
	    n!=-1 && nodes[n].first_in == -1; 
129
	    n = nodes[n].next) {}
130 130
	arc.id = (n == -1) ? -1 : nodes[n].first_in;
131 131
      }      
132 132
    }
133 133

	
134 134
    void firstOut(Arc &e, const Node& v) const {
135 135
      e.id = nodes[v.id].first_out;
136 136
    }
137 137
    void nextOut(Arc &e) const {
138 138
      e.id=arcs[e.id].next_out;
139 139
    }
140 140

	
141 141
    void firstIn(Arc &e, const Node& v) const {
142 142
      e.id = nodes[v.id].first_in;
143 143
    }
144 144
    void nextIn(Arc &e) const {
145 145
      e.id=arcs[e.id].next_in;
146 146
    }
147 147

	
148 148
    
149 149
    static int id(Node v) { return v.id; }
150 150
    static int id(Arc e) { return e.id; }
151 151

	
152 152
    static Node nodeFromId(int id) { return Node(id);}
153 153
    static Arc arcFromId(int id) { return Arc(id);}
154 154

	
155 155
    bool valid(Node n) const { 
156 156
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && 
157 157
	nodes[n.id].prev != -2;
158 158
    }
159 159

	
160 160
    bool valid(Arc a) const { 
161 161
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && 
162 162
	arcs[a.id].prev_in != -2;
163 163
    }
164 164

	
165 165
    Node addNode() {     
166 166
      int n;
167 167
      
168 168
      if(first_free_node==-1) {
169 169
	n = nodes.size();
170 170
	nodes.push_back(NodeT());
171 171
      } else {
172 172
	n = first_free_node;
173 173
	first_free_node = nodes[n].next;
174 174
      }
175 175
      
176 176
      nodes[n].next = first_node;
177 177
      if(first_node != -1) nodes[first_node].prev = n;
178 178
      first_node = n;
179 179
      nodes[n].prev = -1;
180 180
      
181 181
      nodes[n].first_in = nodes[n].first_out = -1;
182 182
      
183 183
      return Node(n);
184 184
    }
185 185
    
186 186
    Arc addArc(Node u, Node v) {
187 187
      int n;      
188 188

	
189 189
      if (first_free_arc == -1) {
190 190
	n = arcs.size();
191 191
	arcs.push_back(ArcT());
192 192
      } else {
193 193
	n = first_free_arc;
194 194
	first_free_arc = arcs[n].next_in;
195 195
      }
196 196
      
197 197
      arcs[n].source = u.id; 
198 198
      arcs[n].target = v.id;
199 199

	
200 200
      arcs[n].next_out = nodes[u.id].first_out;
201 201
      if(nodes[u.id].first_out != -1) {
202 202
	arcs[nodes[u.id].first_out].prev_out = n;
203 203
      }
204 204
      
205 205
      arcs[n].next_in = nodes[v.id].first_in;
206 206
      if(nodes[v.id].first_in != -1) {
207 207
	arcs[nodes[v.id].first_in].prev_in = n;
208 208
      }
209 209
      
210 210
      arcs[n].prev_in = arcs[n].prev_out = -1;
211 211
	
212 212
      nodes[u.id].first_out = nodes[v.id].first_in = n;
213 213

	
214 214
      return Arc(n);
215 215
    }
216 216
    
217 217
    void erase(const Node& node) {
218 218
      int n = node.id;
219 219
      
220 220
      if(nodes[n].next != -1) {
221 221
	nodes[nodes[n].next].prev = nodes[n].prev;
222 222
      }
223 223
      
224 224
      if(nodes[n].prev != -1) {
225 225
	nodes[nodes[n].prev].next = nodes[n].next;
226 226
      } else {
227 227
	first_node = nodes[n].next;
228 228
      }
229 229
      
230 230
      nodes[n].next = first_free_node;
231 231
      first_free_node = n;
232 232
      nodes[n].prev = -2;
233 233

	
234 234
    }
235 235
    
236 236
    void erase(const Arc& arc) {
237 237
      int n = arc.id;
238 238
      
239 239
      if(arcs[n].next_in!=-1) {
240 240
	arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
241 241
      }
242 242

	
243 243
      if(arcs[n].prev_in!=-1) {
244 244
	arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
245 245
      } else {
246 246
	nodes[arcs[n].target].first_in = arcs[n].next_in;
247 247
      }
248 248

	
249 249
      
250 250
      if(arcs[n].next_out!=-1) {
251 251
	arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
252 252
      } 
253 253

	
254 254
      if(arcs[n].prev_out!=-1) {
255 255
	arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
256 256
      } else {
257 257
	nodes[arcs[n].source].first_out = arcs[n].next_out;
258 258
      }
259 259
      
260 260
      arcs[n].next_in = first_free_arc;
261 261
      first_free_arc = n;
262 262
      arcs[n].prev_in = -2;
263 263
    }
264 264

	
265 265
    void clear() {
266 266
      arcs.clear();
267 267
      nodes.clear();
268 268
      first_node = first_free_node = first_free_arc = -1;
269 269
    }
270 270

	
271 271
  protected:
272 272
    void changeTarget(Arc e, Node n) 
273 273
    {
274 274
      if(arcs[e.id].next_in != -1)
275 275
	arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
276 276
      if(arcs[e.id].prev_in != -1)
277 277
	arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
278 278
      else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
279 279
      if (nodes[n.id].first_in != -1) {
280 280
	arcs[nodes[n.id].first_in].prev_in = e.id;
281 281
      }
282 282
      arcs[e.id].target = n.id;
283 283
      arcs[e.id].prev_in = -1;
284 284
      arcs[e.id].next_in = nodes[n.id].first_in;
285 285
      nodes[n.id].first_in = e.id;
286 286
    }
287 287
    void changeSource(Arc e, Node n) 
288 288
    {
289 289
      if(arcs[e.id].next_out != -1)
290 290
	arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
291 291
      if(arcs[e.id].prev_out != -1)
292 292
	arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
293 293
      else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
294 294
      if (nodes[n.id].first_out != -1) {
295 295
	arcs[nodes[n.id].first_out].prev_out = e.id;
296 296
      }
297 297
      arcs[e.id].source = n.id;
298 298
      arcs[e.id].prev_out = -1;
299 299
      arcs[e.id].next_out = nodes[n.id].first_out;
300 300
      nodes[n.id].first_out = e.id;
301 301
    }
302 302

	
303 303
  };
304 304

	
305 305
  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
306 306

	
307 307
  /// \addtogroup graphs
308 308
  /// @{
309 309

	
310 310
  ///A general directed graph structure. 
311 311

	
312 312
  ///\ref ListDigraph is a simple and fast <em>directed graph</em> 
313 313
  ///implementation based on static linked lists that are stored in 
314 314
  ///\c std::vector structures.   
315 315
  ///
316 316
  ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
317 317
  ///also provides several useful additional functionalities.
318 318
  ///Most of the member functions and nested classes are documented
319 319
  ///only in the concept class.
320 320
  ///
321 321
  ///An important extra feature of this digraph implementation is that
322 322
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
323 323
  ///
324 324
  ///\sa concepts::Digraph
325 325

	
326 326
  class ListDigraph : public ExtendedListDigraphBase {
327 327
  private:
328 328
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
329 329
    
330 330
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
331 331
    ///
332 332
    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
333 333
    ///\brief Assignment of ListDigraph to another one is \e not allowed.
334 334
    ///Use copyDigraph() instead.
335 335

	
336 336
    ///Assignment of ListDigraph to another one is \e not allowed.
337 337
    ///Use copyDigraph() instead.
338 338
    void operator=(const ListDigraph &) {}
339 339
  public:
340 340

	
341 341
    typedef ExtendedListDigraphBase Parent;
342 342

	
343 343
    /// Constructor
344 344
    
345 345
    /// Constructor.
346 346
    ///
347 347
    ListDigraph() {}
348 348

	
349 349
    ///Add a new node to the digraph.
350 350
    
351 351
    ///Add a new node to the digraph.
352 352
    ///\return the new node.
353 353
    Node addNode() { return Parent::addNode(); }
354 354

	
355 355
    ///Add a new arc to the digraph.
356 356
    
357 357
    ///Add a new arc to the digraph with source node \c s
358 358
    ///and target node \c t.
359 359
    ///\return the new arc.
360 360
    Arc addArc(const Node& s, const Node& t) { 
361 361
      return Parent::addArc(s, t); 
362 362
    }
363 363

	
364 364
    /// Node validity check
365 365

	
366 366
    /// This function gives back true if the given node is valid,
367 367
    /// ie. it is a real node of the graph.  
368 368
    ///
369 369
    /// \warning A Node pointing to a removed item
370 370
    /// could become valid again later if new nodes are
371 371
    /// added to the graph.
372 372
    bool valid(Node n) const { return Parent::valid(n); }
373 373

	
374 374
    /// Arc validity check
375 375

	
376 376
    /// This function gives back true if the given arc is valid,
377 377
    /// ie. it is a real arc of the graph.  
378 378
    ///
379 379
    /// \warning An Arc pointing to a removed item
380 380
    /// could become valid again later if new nodes are
381 381
    /// added to the graph.
382 382
    bool valid(Arc a) const { return Parent::valid(a); }
383 383

	
384 384
    /// Change the target of \c e to \c n
385 385

	
386 386
    /// Change the target of \c e to \c n
387 387
    ///
388 388
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
389 389
    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
390 390
    ///invalidated.
391 391
    ///
392 392
    ///\warning This functionality cannot be used together with the Snapshot
393 393
    ///feature.
394 394
    void changeTarget(Arc e, Node n) { 
395 395
      Parent::changeTarget(e,n); 
396 396
    }
397 397
    /// Change the source of \c e to \c n
398 398

	
399 399
    /// Change the source of \c e to \c n
400 400
    ///
401 401
    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s referencing
402 402
    ///the changed arc remain valid. However <tt>OutArcIt</tt>s are
403 403
    ///invalidated.
404 404
    ///
405 405
    ///\warning This functionality cannot be used together with the Snapshot
406 406
    ///feature.
407 407
    void changeSource(Arc e, Node n) { 
408 408
      Parent::changeSource(e,n);
409 409
    }
410 410

	
411 411
    /// Invert the direction of an arc.
412 412

	
413 413
    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
414 414
    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
415 415
    ///invalidated.
416 416
    ///
417 417
    ///\warning This functionality cannot be used together with the Snapshot
418 418
    ///feature.
419 419
    void reverseArc(Arc e) {
420 420
      Node t=target(e);
421 421
      changeTarget(e,source(e));
422 422
      changeSource(e,t);
423 423
    }
424 424

	
425 425
    /// Reserve memory for nodes.
426 426

	
427 427
    /// Using this function it is possible to avoid the superfluous memory
428 428
    /// allocation: if you know that the digraph you want to build will
429 429
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
430 430
    /// then it is worth reserving space for this amount before starting
431 431
    /// to build the digraph.
432 432
    /// \sa reserveArc
433 433
    void reserveNode(int n) { nodes.reserve(n); };
434 434

	
435 435
    /// Reserve memory for arcs.
436 436

	
437 437
    /// Using this function it is possible to avoid the superfluous memory
438 438
    /// allocation: if you know that the digraph you want to build will
439 439
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
440 440
    /// then it is worth reserving space for this amount before starting
441 441
    /// to build the digraph.
442 442
    /// \sa reserveNode
443 443
    void reserveArc(int m) { arcs.reserve(m); };
444 444

	
445 445
    ///Contract two nodes.
446 446

	
447 447
    ///This function contracts two nodes.
448 448
    ///Node \p b will be removed but instead of deleting
449 449
    ///incident arcs, they will be joined to \p a.
450 450
    ///The last parameter \p r controls whether to remove loops. \c true
451 451
    ///means that loops will be removed.
452 452
    ///
453 453
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
454 454
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
455 455
    ///may be invalidated.
456 456
    ///
457 457
    ///\warning This functionality cannot be used together with the Snapshot
458 458
    ///feature.
459 459
    void contract(Node a, Node b, bool r = true) 
460 460
    {
461 461
      for(OutArcIt e(*this,b);e!=INVALID;) {
462 462
	OutArcIt f=e;
463 463
	++f;
464 464
	if(r && target(e)==a) erase(e);
465 465
	else changeSource(e,a);
466 466
	e=f;
467 467
      }
468 468
      for(InArcIt e(*this,b);e!=INVALID;) {
469 469
	InArcIt f=e;
470 470
	++f;
471 471
	if(r && source(e)==a) erase(e);
472 472
	else changeTarget(e,a);
473 473
	e=f;
474 474
      }
475 475
      erase(b);
476 476
    }
477 477

	
478 478
    ///Split a node.
479 479

	
480 480
    ///This function splits a node. First a new node is added to the digraph,
481 481
    ///then the source of each outgoing arc of \c n is moved to this new node.
482 482
    ///If \c connect is \c true (this is the default value), then a new arc
483 483
    ///from \c n to the newly created node is also added.
484 484
    ///\return The newly created node.
485 485
    ///
486 486
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
487 487
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
488 488
    ///be invalidated.  
489 489
    ///
490 490
    ///\warning This functionality cannot be used together with the
491 491
    ///Snapshot feature.
492 492
    ///
493 493
    ///\todo It could be implemented in a bit faster way.
494 494
    Node split(Node n, bool connect = true) {
495 495
      Node b = addNode();
496 496
      for(OutArcIt e(*this,n);e!=INVALID;) {
497 497
 	OutArcIt f=e;
498 498
	++f;
499 499
	changeSource(e,b);
500 500
	e=f;
501 501
      }
502 502
      if (connect) addArc(n,b);
503 503
      return b;
504 504
    }
505 505
      
506 506
    ///Split an arc.
507 507

	
508 508
    ///This function splits an arc. First a new node \c b is added to
509 509
    ///the digraph, then the original arc is re-targeted to \c
510 510
    ///b. Finally an arc from \c b to the original target is added.
511 511
    ///
512 512
    ///\return The newly created node.
513 513
    ///
514 514
    ///\warning This functionality cannot be used together with the
515 515
    ///Snapshot feature.
516 516
    Node split(Arc e) {
517 517
      Node b = addNode();
518 518
      addArc(b,target(e));
519 519
      changeTarget(e,b);
520 520
      return b;
521 521
    }
522 522
      
523 523
    /// \brief Class to make a snapshot of the digraph and restore
524 524
    /// it later.
525 525
    ///
526 526
    /// Class to make a snapshot of the digraph and restore it later.
527 527
    ///
528 528
    /// The newly added nodes and arcs can be removed using the
529 529
    /// restore() function.
530 530
    ///
531 531
    /// \warning Arc and node deletions and other modifications (e.g.
532 532
    /// contracting, splitting, reversing arcs or nodes) cannot be 
533 533
    /// restored. These events invalidate the snapshot. 
534 534
    class Snapshot {
535 535
    protected:
536 536

	
537 537
      typedef Parent::NodeNotifier NodeNotifier;
538 538

	
539 539
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
540 540
      public:
541 541

	
542 542
        NodeObserverProxy(Snapshot& _snapshot)
543 543
          : snapshot(_snapshot) {}
544 544

	
545 545
        using NodeNotifier::ObserverBase::attach;
546 546
        using NodeNotifier::ObserverBase::detach;
547 547
        using NodeNotifier::ObserverBase::attached;
548 548
        
549 549
      protected:
550 550
        
551 551
        virtual void add(const Node& node) {
552 552
          snapshot.addNode(node);
553 553
        }
554 554
        virtual void add(const std::vector<Node>& nodes) {
555 555
          for (int i = nodes.size() - 1; i >= 0; ++i) {
556 556
            snapshot.addNode(nodes[i]);
557 557
          }
558 558
        }
559 559
        virtual void erase(const Node& node) {
560 560
          snapshot.eraseNode(node);
561 561
        }
562 562
        virtual void erase(const std::vector<Node>& nodes) {
563 563
          for (int i = 0; i < int(nodes.size()); ++i) {
564 564
            snapshot.eraseNode(nodes[i]);
565 565
          }
566 566
        }
567 567
        virtual void build() {
568 568
          Node node;
569 569
          std::vector<Node> nodes;
570 570
          for (notifier()->first(node); node != INVALID; 
571 571
               notifier()->next(node)) {
572 572
            nodes.push_back(node);
573 573
          }
574 574
          for (int i = nodes.size() - 1; i >= 0; --i) {
575 575
            snapshot.addNode(nodes[i]);
576 576
          }
577 577
        }
578 578
        virtual void clear() {
579 579
          Node node;
580 580
          for (notifier()->first(node); node != INVALID; 
581 581
               notifier()->next(node)) {
582 582
            snapshot.eraseNode(node);
583 583
          }
584 584
        }
585 585

	
586 586
        Snapshot& snapshot;
587 587
      };
588 588

	
589 589
      class ArcObserverProxy : public ArcNotifier::ObserverBase {
590 590
      public:
591 591

	
592 592
        ArcObserverProxy(Snapshot& _snapshot)
593 593
          : snapshot(_snapshot) {}
594 594

	
595 595
        using ArcNotifier::ObserverBase::attach;
596 596
        using ArcNotifier::ObserverBase::detach;
597 597
        using ArcNotifier::ObserverBase::attached;
598 598
        
599 599
      protected:
600 600

	
601 601
        virtual void add(const Arc& arc) {
602 602
          snapshot.addArc(arc);
603 603
        }
604 604
        virtual void add(const std::vector<Arc>& arcs) {
605 605
          for (int i = arcs.size() - 1; i >= 0; ++i) {
606 606
            snapshot.addArc(arcs[i]);
607 607
          }
608 608
        }
609 609
        virtual void erase(const Arc& arc) {
610 610
          snapshot.eraseArc(arc);
611 611
        }
612 612
        virtual void erase(const std::vector<Arc>& arcs) {
613 613
          for (int i = 0; i < int(arcs.size()); ++i) {
614 614
            snapshot.eraseArc(arcs[i]);
615 615
          }
616 616
        }
617 617
        virtual void build() {
618 618
          Arc arc;
619 619
          std::vector<Arc> arcs;
620 620
          for (notifier()->first(arc); arc != INVALID; 
621 621
               notifier()->next(arc)) {
622 622
            arcs.push_back(arc);
623 623
          }
624 624
          for (int i = arcs.size() - 1; i >= 0; --i) {
625 625
            snapshot.addArc(arcs[i]);
626 626
          }
627 627
        }
628 628
        virtual void clear() {
629 629
          Arc arc;
630 630
          for (notifier()->first(arc); arc != INVALID; 
631 631
               notifier()->next(arc)) {
632 632
            snapshot.eraseArc(arc);
633 633
          }
634 634
        }
635 635

	
636 636
        Snapshot& snapshot;
637 637
      };
638 638
      
639 639
      ListDigraph *digraph;
640 640

	
641 641
      NodeObserverProxy node_observer_proxy;
642 642
      ArcObserverProxy arc_observer_proxy;
643 643

	
644 644
      std::list<Node> added_nodes;
645 645
      std::list<Arc> added_arcs;
646 646

	
647 647

	
648 648
      void addNode(const Node& node) {
649 649
        added_nodes.push_front(node);        
650 650
      }
651 651
      void eraseNode(const Node& node) {
652 652
        std::list<Node>::iterator it = 
653 653
          std::find(added_nodes.begin(), added_nodes.end(), node);
654 654
        if (it == added_nodes.end()) {
655 655
          clear();
656 656
          arc_observer_proxy.detach();
657 657
          throw NodeNotifier::ImmediateDetach();
658 658
        } else {
659 659
          added_nodes.erase(it);
660 660
        }
661 661
      }
662 662

	
663 663
      void addArc(const Arc& arc) {
664 664
        added_arcs.push_front(arc);        
665 665
      }
666 666
      void eraseArc(const Arc& arc) {
667 667
        std::list<Arc>::iterator it = 
668 668
          std::find(added_arcs.begin(), added_arcs.end(), arc);
669 669
        if (it == added_arcs.end()) {
670 670
          clear();
671 671
          node_observer_proxy.detach(); 
672 672
          throw ArcNotifier::ImmediateDetach();
673 673
        } else {
674 674
          added_arcs.erase(it);
675 675
        }        
676 676
      }
677 677

	
678 678
      void attach(ListDigraph &_digraph) {
679 679
	digraph = &_digraph;
680 680
	node_observer_proxy.attach(digraph->notifier(Node()));
681 681
        arc_observer_proxy.attach(digraph->notifier(Arc()));
682 682
      }
683 683
            
684 684
      void detach() {
685 685
	node_observer_proxy.detach();
686 686
	arc_observer_proxy.detach();
687 687
      }
688 688

	
689 689
      bool attached() const {
690 690
        return node_observer_proxy.attached();
691 691
      }
692 692

	
693 693
      void clear() {
694 694
        added_nodes.clear();
695 695
        added_arcs.clear();        
696 696
      }
697 697

	
698 698
    public:
699 699

	
700 700
      /// \brief Default constructor.
701 701
      ///
702 702
      /// Default constructor.
703 703
      /// To actually make a snapshot you must call save().
704 704
      Snapshot() 
705 705
        : digraph(0), node_observer_proxy(*this), 
706 706
          arc_observer_proxy(*this) {}
707 707
      
708 708
      /// \brief Constructor that immediately makes a snapshot.
709 709
      ///      
710 710
      /// This constructor immediately makes a snapshot of the digraph.
711 711
      /// \param _digraph The digraph we make a snapshot of.
712 712
      Snapshot(ListDigraph &_digraph) 
713 713
        : node_observer_proxy(*this), 
714 714
          arc_observer_proxy(*this) {
715 715
	attach(_digraph);
716 716
      }
717 717
      
718 718
      /// \brief Make a snapshot.
719 719
      ///
720 720
      /// Make a snapshot of the digraph.
721 721
      ///
722 722
      /// This function can be called more than once. In case of a repeated
723 723
      /// call, the previous snapshot gets lost.
724 724
      /// \param _digraph The digraph we make the snapshot of.
725 725
      void save(ListDigraph &_digraph) {
726 726
        if (attached()) {
727 727
          detach();
728 728
          clear();
729 729
        }
730 730
        attach(_digraph);
731 731
      }
732 732
      
733 733
      /// \brief Undo the changes until the last snapshot.
734 734
      // 
735 735
      /// Undo the changes until the last snapshot created by save().
736 736
      void restore() {
737 737
	detach();
738 738
	for(std::list<Arc>::iterator it = added_arcs.begin(); 
739 739
            it != added_arcs.end(); ++it) {
740 740
	  digraph->erase(*it);
741 741
	}
742 742
	for(std::list<Node>::iterator it = added_nodes.begin(); 
743 743
            it != added_nodes.end(); ++it) {
744 744
	  digraph->erase(*it);
745 745
	}
746 746
        clear();
747 747
      }
748 748

	
749 749
      /// \brief Gives back true when the snapshot is valid.
750 750
      ///
751 751
      /// Gives back true when the snapshot is valid.
752 752
      bool valid() const {
753 753
        return attached();
754 754
      }
755 755
    };
756 756
    
757 757
  };
758 758

	
759 759
  ///@}
760 760

	
761 761
  class ListGraphBase {
762 762

	
763 763
  protected:
764 764

	
765 765
    struct NodeT {
766 766
      int first_out;
767 767
      int prev, next;
768 768
    };
769 769
 
770 770
    struct ArcT {
771 771
      int target;
772 772
      int prev_out, next_out;
773 773
    };
774 774

	
775 775
    std::vector<NodeT> nodes;
776 776

	
777 777
    int first_node;
778 778

	
779 779
    int first_free_node;
780 780

	
781 781
    std::vector<ArcT> arcs;
782 782

	
783 783
    int first_free_arc;
784 784
    
785 785
  public:
786 786
    
787 787
    typedef ListGraphBase Digraph;
788 788

	
789 789
    class Node;
790 790
    class Arc;
791 791
    class Edge;
792 792
    
793 793
    class Node {
794 794
      friend class ListGraphBase;
795 795
    protected:
796 796

	
797 797
      int id;
798 798
      explicit Node(int pid) { id = pid;}
799 799

	
800 800
    public:
801 801
      Node() {}
802 802
      Node (Invalid) { id = -1; }
803 803
      bool operator==(const Node& node) const {return id == node.id;}
804 804
      bool operator!=(const Node& node) const {return id != node.id;}
805 805
      bool operator<(const Node& node) const {return id < node.id;}
806 806
    };
807 807

	
808 808
    class Edge {
809 809
      friend class ListGraphBase;
810 810
    protected:
811 811

	
812 812
      int id;
813 813
      explicit Edge(int pid) { id = pid;}
814 814

	
815 815
    public:
816 816
      Edge() {}
817 817
      Edge (Invalid) { id = -1; }
818 818
      bool operator==(const Edge& edge) const {return id == edge.id;}
819 819
      bool operator!=(const Edge& edge) const {return id != edge.id;}
820 820
      bool operator<(const Edge& edge) const {return id < edge.id;}
821 821
    };
822 822

	
823 823
    class Arc {
824 824
      friend class ListGraphBase;
825 825
    protected:
826 826

	
827 827
      int id;
828 828
      explicit Arc(int pid) { id = pid;}
829 829

	
830 830
    public:
831 831
      operator Edge() const { return edgeFromId(id / 2); }
832 832

	
833 833
      Arc() {}
834 834
      Arc (Invalid) { id = -1; }
835 835
      bool operator==(const Arc& arc) const {return id == arc.id;}
836 836
      bool operator!=(const Arc& arc) const {return id != arc.id;}
837 837
      bool operator<(const Arc& arc) const {return id < arc.id;}
838 838
    };
839 839

	
840 840

	
841 841

	
842 842
    ListGraphBase()
843 843
      : nodes(), first_node(-1),
844 844
	first_free_node(-1), arcs(), first_free_arc(-1) {}
845 845

	
846 846
    
847 847
    int maxNodeId() const { return nodes.size()-1; } 
848 848
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
849 849
    int maxArcId() const { return arcs.size()-1; }
850 850

	
851 851
    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
852 852
    Node target(Arc e) const { return Node(arcs[e.id].target); }
853 853

	
854 854
    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
855 855
    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
856 856

	
857 857
    static bool direction(Arc e) {
858 858
      return (e.id & 1) == 1;
859 859
    }
860 860

	
861 861
    static Arc direct(Edge e, bool d) {
862 862
      return Arc(e.id * 2 + (d ? 1 : 0));
863 863
    }
864 864

	
865 865
    void first(Node& node) const { 
866 866
      node.id = first_node;
867 867
    }
868 868

	
869 869
    void next(Node& node) const {
870 870
      node.id = nodes[node.id].next;
871 871
    }
872 872

	
873 873
    void first(Arc& e) const { 
874 874
      int n = first_node;
875 875
      while (n != -1 && nodes[n].first_out == -1) {
876 876
        n = nodes[n].next;
877 877
      }
878 878
      e.id = (n == -1) ? -1 : nodes[n].first_out;
879 879
    }
880 880

	
881 881
    void next(Arc& e) const {
882 882
      if (arcs[e.id].next_out != -1) {
883 883
	e.id = arcs[e.id].next_out;
884 884
      } else {
885 885
	int n = nodes[arcs[e.id ^ 1].target].next;
886 886
        while(n != -1 && nodes[n].first_out == -1) {
887 887
          n = nodes[n].next;
888 888
        }
889 889
	e.id = (n == -1) ? -1 : nodes[n].first_out;
890 890
      }      
891 891
    }
892 892

	
893 893
    void first(Edge& e) const { 
894 894
      int n = first_node;
895 895
      while (n != -1) {
896 896
        e.id = nodes[n].first_out;
897 897
        while ((e.id & 1) != 1) {
Ignore white space 6 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_TEST_TEST_TOOLS_H
20 20
#define LEMON_TEST_TEST_TOOLS_H
21 21

	
22 22
///\ingroup misc
23 23
///\file
24 24
///\brief Some utilities to write test programs.
25 25

	
26 26
#include <iostream>
27
#include <stdlib.h>
27 28

	
28 29
///If \c rc is fail, writes an error message and exits.
29 30

	
30 31
///If \c rc is fail, writes an error message and exits.
31 32
///The error message contains the file name and the line number of the
32 33
///source code in a standard from, which makes it possible to go there
33 34
///using good source browsers like e.g. \c emacs.
34 35
///
35 36
///For example
36 37
///\code check(0==1,"This is obviously false.");\endcode will
37 38
///print something like this (and then exits).
38 39
///\verbatim file_name.cc:123: error: This is obviously false. \endverbatim
39
///
40
///\todo It should be in \c assert.h
41 40
#define check(rc, msg) \
42 41
  if(!(rc)) { \
43 42
    std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
44 43
    abort(); \
45 44
  } else { } \
46 45

	
47 46
#endif
0 comments (0 inline)