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 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_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
Ignore white space 768 line context
... ...
@@ -634,613 +634,614 @@
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
    ///
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)