gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
1 109 73
merge default
3 files changed with 43618 insertions and 3481 deletions:
25
10
1
1
87
3
3
132
133
129
110
151
152
459
379
↑ Collapse diff ↑
Ignore white space 6 line context
1
SET(COIN_ROOT_DIR "" CACHE PATH "COIN root directory")
2

	
3
FIND_PATH(COIN_INCLUDE_DIR coin/CoinUtilsConfig.h
4
  HINTS ${COIN_ROOT_DIR}/include
5
)
6
FIND_LIBRARY(COIN_CBC_LIBRARY
7
  NAMES Cbc libCbc
8
  HINTS ${COIN_ROOT_DIR}/lib
9
)
10
FIND_LIBRARY(COIN_CBC_SOLVER_LIBRARY
11
  NAMES CbcSolver libCbcSolver
12
  HINTS ${COIN_ROOT_DIR}/lib
13
)
14
FIND_LIBRARY(COIN_CGL_LIBRARY
15
  NAMES Cgl libCgl
16
  HINTS ${COIN_ROOT_DIR}/lib
17
)
18
FIND_LIBRARY(COIN_CLP_LIBRARY
19
  NAMES Clp libClp
20
  HINTS ${COIN_ROOT_DIR}/lib
21
)
22
FIND_LIBRARY(COIN_COIN_UTILS_LIBRARY
23
  NAMES CoinUtils libCoinUtils
24
  HINTS ${COIN_ROOT_DIR}/lib
25
)
26
FIND_LIBRARY(COIN_OSI_LIBRARY
27
  NAMES Osi libOsi
28
  HINTS ${COIN_ROOT_DIR}/lib
29
)
30
FIND_LIBRARY(COIN_OSI_CBC_LIBRARY
31
  NAMES OsiCbc libOsiCbc
32
  HINTS ${COIN_ROOT_DIR}/lib
33
)
34
FIND_LIBRARY(COIN_OSI_CLP_LIBRARY
35
  NAMES OsiClp libOsiClp
36
  HINTS ${COIN_ROOT_DIR}/lib
37
)
38
FIND_LIBRARY(COIN_OSI_VOL_LIBRARY
39
  NAMES OsiVol libOsiVol
40
  HINTS ${COIN_ROOT_DIR}/lib
41
)
42
FIND_LIBRARY(COIN_VOL_LIBRARY
43
  NAMES Vol libVol
44
  HINTS ${COIN_ROOT_DIR}/lib
45
)
46

	
47
INCLUDE(FindPackageHandleStandardArgs)
48
FIND_PACKAGE_HANDLE_STANDARD_ARGS(COIN DEFAULT_MSG
49
  COIN_INCLUDE_DIR
50
  COIN_CBC_LIBRARY
51
  COIN_CBC_SOLVER_LIBRARY
52
  COIN_CGL_LIBRARY
53
  COIN_CLP_LIBRARY
54
  COIN_COIN_UTILS_LIBRARY
55
  COIN_OSI_LIBRARY
56
  COIN_OSI_CBC_LIBRARY
57
  COIN_OSI_CLP_LIBRARY
58
  COIN_OSI_VOL_LIBRARY
59
  COIN_VOL_LIBRARY
60
)
61

	
62
IF(COIN_FOUND)
63
  SET(COIN_INCLUDE_DIRS ${COIN_INCLUDE_DIR})
64
  SET(COIN_LIBRARIES "${COIN_CBC_LIBRARY};${COIN_CBC_SOLVER_LIBRARY};${COIN_CGL_LIBRARY};${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY};${COIN_OSI_LIBRARY};${COIN_OSI_CBC_LIBRARY};${COIN_OSI_CLP_LIBRARY};${COIN_OSI_VOL_LIBRARY};${COIN_VOL_LIBRARY}")
65
  SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY}")
66
  SET(COIN_CBC_LIBRARIES ${COIN_LIBRARIES})
67
ENDIF(COIN_FOUND)
68

	
69
MARK_AS_ADVANCED(
70
  COIN_INCLUDE_DIR
71
  COIN_CBC_LIBRARY
72
  COIN_CBC_SOLVER_LIBRARY
73
  COIN_CGL_LIBRARY
74
  COIN_CLP_LIBRARY
75
  COIN_COIN_UTILS_LIBRARY
76
  COIN_OSI_LIBRARY
77
  COIN_OSI_CBC_LIBRARY
78
  COIN_OSI_CLP_LIBRARY
79
  COIN_OSI_VOL_LIBRARY
80
  COIN_VOL_LIBRARY
81
)
82

	
83
IF(COIN_FOUND)
84
  SET(LEMON_HAVE_LP TRUE)
85
  SET(LEMON_HAVE_MIP TRUE)
86
  SET(LEMON_HAVE_CLP TRUE)
87
  SET(LEMON_HAVE_CBC TRUE)
88
ENDIF(COIN_FOUND)
Ignore white space 6 line context
1
SET(CPLEX_ROOT_DIR "" CACHE PATH "CPLEX root directory")
2

	
3
FIND_PATH(CPLEX_INCLUDE_DIR
4
  ilcplex/cplex.h
5
  PATHS "C:/ILOG/CPLEX91/include"
6
  PATHS "/opt/ilog/cplex91/include"
7
  HINTS ${CPLEX_ROOT_DIR}/include
8
)
9
FIND_LIBRARY(CPLEX_LIBRARY
10
  cplex91
11
  PATHS "C:/ILOG/CPLEX91/lib/msvc7/stat_mda"
12
  PATHS "/opt/ilog/cplex91/bin"
13
  HINTS ${CPLEX_ROOT_DIR}/bin
14
)
15

	
16
INCLUDE(FindPackageHandleStandardArgs)
17
FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPLEX DEFAULT_MSG CPLEX_LIBRARY CPLEX_INCLUDE_DIR)
18

	
19
FIND_PATH(CPLEX_BIN_DIR
20
  cplex91.dll
21
  PATHS "C:/ILOG/CPLEX91/bin/x86_win32"
22
)
23

	
24
IF(CPLEX_FOUND)
25
  SET(CPLEX_INCLUDE_DIRS ${CPLEX_INCLUDE_DIR})
26
  SET(CPLEX_LIBRARIES ${CPLEX_LIBRARY})
27
  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
28
    SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread")
29
  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
30
ENDIF(CPLEX_FOUND)
31

	
32
MARK_AS_ADVANCED(CPLEX_LIBRARY CPLEX_INCLUDE_DIR CPLEX_BIN_DIR)
33

	
34
IF(CPLEX_FOUND)
35
  SET(LEMON_HAVE_LP TRUE)
36
  SET(LEMON_HAVE_MIP TRUE)
37
  SET(LEMON_HAVE_CPLEX TRUE)
38
ENDIF(CPLEX_FOUND)
Ignore white space 6 line context
1
SET(GLPK_ROOT_DIR "" CACHE PATH "GLPK root directory")
2

	
3
SET(GLPK_REGKEY "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Glpk;InstallPath]")
4
GET_FILENAME_COMPONENT(GLPK_ROOT_PATH ${GLPK_REGKEY} ABSOLUTE)
5

	
6
FIND_PATH(GLPK_INCLUDE_DIR
7
  glpk.h
8
  PATHS ${GLPK_REGKEY}/include
9
  HINTS ${GLPK_ROOT_DIR}/include
10
)
11
FIND_LIBRARY(GLPK_LIBRARY
12
  glpk
13
  PATHS ${GLPK_REGKEY}/lib
14
  HINTS ${GLPK_ROOT_DIR}/lib
15
)
16

	
17
IF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY)
18
  FILE(READ ${GLPK_INCLUDE_DIR}/glpk.h GLPK_GLPK_H)
19

	
20
  STRING(REGEX MATCH "define[ ]+GLP_MAJOR_VERSION[ ]+[0-9]+" GLPK_MAJOR_VERSION_LINE "${GLPK_GLPK_H}")
21
  STRING(REGEX REPLACE "define[ ]+GLP_MAJOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MAJOR "${GLPK_MAJOR_VERSION_LINE}")
22

	
23
  STRING(REGEX MATCH "define[ ]+GLP_MINOR_VERSION[ ]+[0-9]+" GLPK_MINOR_VERSION_LINE "${GLPK_GLPK_H}")
24
  STRING(REGEX REPLACE "define[ ]+GLP_MINOR_VERSION[ ]+([0-9]+)" "\\1" GLPK_VERSION_MINOR "${GLPK_MINOR_VERSION_LINE}")
25

	
26
  SET(GLPK_VERSION_STRING "${GLPK_VERSION_MAJOR}.${GLPK_VERSION_MINOR}")
27

	
28
  IF(GLPK_FIND_VERSION)
29
    IF(GLPK_FIND_VERSION_COUNT GREATER 2)
30
      MESSAGE(SEND_ERROR "unexpected version string")
31
    ENDIF(GLPK_FIND_VERSION_COUNT GREATER 2)
32

	
33
    MATH(EXPR GLPK_REQUESTED_VERSION "${GLPK_FIND_VERSION_MAJOR}*100 + ${GLPK_FIND_VERSION_MINOR}")
34
    MATH(EXPR GLPK_FOUND_VERSION "${GLPK_VERSION_MAJOR}*100 + ${GLPK_VERSION_MINOR}")
35

	
36
    IF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
37
      SET(GLPK_PROPER_VERSION_FOUND FALSE)
38
    ELSE(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
39
      SET(GLPK_PROPER_VERSION_FOUND TRUE)
40
    ENDIF(GLPK_FOUND_VERSION LESS GLPK_REQUESTED_VERSION)
41
  ELSE(GLPK_FIND_VERSION)
42
    SET(GLPK_PROPER_VERSION_FOUND TRUE)
43
  ENDIF(GLPK_FIND_VERSION)
44
ENDIF(GLPK_INCLUDE_DIR AND GLPK_LIBRARY)
45

	
46
INCLUDE(FindPackageHandleStandardArgs)
47
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLPK DEFAULT_MSG GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_PROPER_VERSION_FOUND)
48

	
49
IF(GLPK_FOUND)
50
  SET(GLPK_INCLUDE_DIRS ${GLPK_INCLUDE_DIR})
51
  SET(GLPK_LIBRARIES ${GLPK_LIBRARY})
52
  SET(GLPK_BIN_DIR ${GLPK_ROOT_PATH}/bin)
53
ENDIF(GLPK_FOUND)
54

	
55
MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR)
56

	
57
IF(GLPK_FOUND)
58
  SET(LEMON_HAVE_LP TRUE)
59
  SET(LEMON_HAVE_MIP TRUE)
60
  SET(LEMON_HAVE_GLPK TRUE)
61
ENDIF(GLPK_FOUND)
Ignore white space 6 line context
1
SET(LEMON_INCLUDE_DIR "@CMAKE_INSTALL_PREFIX@/include" CACHE PATH "LEMON include directory")
2
SET(LEMON_INCLUDE_DIRS "${LEMON_INCLUDE_DIR}")
3

	
4
IF(UNIX)
5
  SET(LEMON_LIB_NAME "libemon.a")
6
ELSEIF(WIN32)
7
  SET(LEMON_LIB_NAME "lemon.lib")
8
ENDIF(UNIX)
9

	
10
SET(LEMON_LIBRARY "@CMAKE_INSTALL_PREFIX@/lib/${LEMON_LIB_NAME}" CACHE FILEPATH "LEMON library")
11
SET(LEMON_LIBRARIES "${LEMON_LIBRARY}")
12

	
13
MARK_AS_ADVANCED(LEMON_LIBRARY LEMON_INCLUDE_DIR)
Ignore white space 6 line context
1
%!PS-Adobe-3.0 EPSF-3.0
2
%%BoundingBox: 15 18 829 570
3
%%HiResBoundingBox: 15.1913 18.4493 828.078 569.438
4
%%Creator: Karbon14 EPS Exportfilter 0.5
5
%%CreationDate: (04/15/06 15:20:26)
6
%%For: (Balazs Dezso) ()
7
%%Title: ()
8

	
9
/N {newpath} def
10
/C {closepath} def
11
/m {moveto} def
12
/c {curveto} def
13
/l {lineto} def
14
/s {stroke} def
15
/f {fill} def
16
/w {setlinewidth} def
17
/d {setdash} def
18
/r {setrgbcolor} def
19
/S {gsave} def
20
/R {grestore} def
21

	
22
N
23
251.402 32.047 m
24
532.945 293.946 814.484 555.844 814.484 555.844 c
25
[] 0 d 1 0 0 r 3.92814 w s
26

	
27
N
28
749.012 32.047 m
29
742.465 293.946 735.918 555.844 735.918 555.844 c
30
[] 0 d 0 0 0 r 1.96407 w s
31

	
32
N
33
539.492 32.047 m
34
637.703 293.946 735.918 555.844 735.918 555.844 c
35
[] 0 d 0 0 0 r 1.96407 w s
36

	
37
N
38
172.832 32.047 m
39
454.375 293.946 735.918 555.844 735.918 555.844 c
40
[] 0 d 0 0 0 r 1.96407 w s
41

	
42
N
43
107.355 32.047 m
44
421.637 293.946 735.918 555.844 735.918 555.844 c
45
[] 0 d 1 0 0 r 3.92814 w s
46

	
47
N
48
644.25 555.844 m
49
696.633 293.946 749.012 32.047 749.012 32.047 c
50
[] 0 d 0 0 0 r 1.96407 w s
51

	
52
N
53
474.016 555.844 m
54
611.516 293.946 749.012 32.047 749.012 32.047 c
55
[] 0 d 1 0 0 r 3.92814 w s
56

	
57
N
58
683.535 32.047 m
59
663.894 293.946 644.25 555.844 644.25 555.844 c
60
[] 0 d 0 0 0 r 1.96407 w s
61

	
62
N
63
120.453 555.844 m
64
401.992 293.946 683.535 32.047 683.535 32.047 c
65
[] 0 d 0 0 0 r 1.96407 w s
66

	
67
N
68
28.7853 555.844 m
69
356.16 293.946 683.535 32.047 683.535 32.047 c
70
[] 0 d 1 0 0 r 3.92814 w s
71

	
72
N
73
539.492 32.047 m
74
546.039 293.946 552.586 555.844 552.586 555.844 c
75
[] 0 d 1 0 0 r 3.92814 w s
76

	
77
N
78
316.875 32.047 m
79
349.613 293.946 382.351 555.844 382.351 555.844 c
80
[] 0 d 1 0 0 r 3.92814 w s
81

	
82
N
83
107.355 32.047 m
84
244.855 293.946 382.351 555.844 382.351 555.844 c
85
[] 0 d 0 0 0 r 1.96407 w s
86

	
87
N
88
290.687 555.844 m
89
375.805 293.946 460.922 32.047 460.922 32.047 c
90
[] 0 d 1 0 0 r 3.92814 w s
91

	
92
N
93
120.453 555.844 m
94
290.687 293.946 460.922 32.047 460.922 32.047 c
95
[] 0 d 0 0 0 r 1.96407 w s
96

	
97
N
98
172.832 32.047 m
99
146.64 293.946 120.453 555.844 120.453 555.844 c
100
[] 0 d 1 0 0 r 3.92814 w s
101

	
102
N
103
15.6913 555.844 m
104
15.6913 555.844 l
105
15.6913 548.614 21.5553 542.75 28.7853 542.75 c
106
36.0163 542.75 41.8833 548.614 41.8833 555.844 c
107
41.8833 563.075 36.0163 568.938 28.7853 568.938 c
108
21.5553 568.938 15.6913 563.075 15.6913 555.844 c
109
15.6913 555.844 l
110
C
111
S 0 0 0 r f R
112

	
113
N
114
16.8833 555.844 m
115
16.8833 555.844 l
116
16.8833 549.27 22.2113 543.942 28.7853 543.942 c
117
35.3593 543.942 40.6913 549.27 40.6913 555.844 c
118
40.6913 562.418 35.3593 567.747 28.7853 567.747 c
119
22.2113 567.747 16.8833 562.418 16.8833 555.844 c
120
16.8833 555.844 l
121
C
122
S 1 0.5 1 r f R
123

	
124
N
125
107.355 555.844 m
126
107.355 555.844 l
127
107.355 548.614 113.223 542.75 120.453 542.75 c
128
127.683 542.75 133.547 548.614 133.547 555.844 c
129
133.547 563.075 127.683 568.938 120.453 568.938 c
130
113.223 568.938 107.355 563.075 107.355 555.844 c
131
107.355 555.844 l
132
C
133
S 0 0 0 r f R
134

	
135
N
136
108.547 555.844 m
137
108.547 555.844 l
138
108.547 549.27 113.879 543.942 120.453 543.942 c
139
127.027 543.942 132.355 549.27 132.355 555.844 c
140
132.355 562.418 127.027 567.747 120.453 567.747 c
141
113.879 567.747 108.547 562.418 108.547 555.844 c
142
108.547 555.844 l
143
C
144
S 1 0 1 r f R
145

	
146
N
147
199.019 555.844 m
148
199.019 555.844 l
149
199.019 548.614 204.887 542.75 212.117 542.75 c
150
219.348 542.75 225.211 548.614 225.211 555.844 c
151
225.211 563.075 219.348 568.938 212.117 568.938 c
152
204.887 568.938 199.019 563.075 199.019 555.844 c
153
199.019 555.844 l
154
C
155
S 0 0 0 r f R
156

	
157
N
158
200.211 555.844 m
159
200.211 555.844 l
160
200.211 549.27 205.543 543.942 212.117 543.942 c
161
218.691 543.942 224.019 549.27 224.019 555.844 c
162
224.019 562.418 218.691 567.747 212.117 567.747 c
163
205.543 567.747 200.211 562.418 200.211 555.844 c
164
200.211 555.844 l
165
C
166
S 1 0.5 1 r f R
167

	
168
N
169
277.59 555.844 m
170
277.59 555.844 l
171
277.59 548.614 283.457 542.75 290.687 542.75 c
172
297.918 542.75 303.781 548.614 303.781 555.844 c
173
303.781 563.075 297.918 568.938 290.687 568.938 c
174
283.457 568.938 277.59 563.075 277.59 555.844 c
175
277.59 555.844 l
176
C
177
S 0 0 0 r f R
178

	
179
N
180
278.781 555.844 m
181
278.781 555.844 l
182
278.781 549.27 284.113 543.942 290.687 543.942 c
183
297.262 543.942 302.59 549.27 302.59 555.844 c
184
302.59 562.418 297.262 567.747 290.687 567.747 c
185
284.113 567.747 278.781 562.418 278.781 555.844 c
186
278.781 555.844 l
187
C
188
S 1 0 1 r f R
189

	
190
N
191
369.258 555.844 m
192
369.258 555.844 l
193
369.258 548.614 375.121 542.75 382.351 542.75 c
194
389.582 542.75 395.445 548.614 395.445 555.844 c
195
395.445 563.075 389.582 568.938 382.351 568.938 c
196
375.121 568.938 369.258 563.075 369.258 555.844 c
197
369.258 555.844 l
198
C
199
S 0 0 0 r f R
200

	
201
N
202
370.445 555.844 m
203
370.445 555.844 l
204
370.445 549.27 375.777 543.942 382.351 543.942 c
205
388.926 543.942 394.258 549.27 394.258 555.844 c
206
394.258 562.418 388.926 567.747 382.351 567.747 c
207
375.777 567.747 370.445 562.418 370.445 555.844 c
208
370.445 555.844 l
209
C
210
S 1 0 1 r f R
211

	
212
N
213
460.922 555.844 m
214
460.922 555.844 l
215
460.922 548.614 466.785 542.75 474.016 542.75 c
216
481.246 542.75 487.109 548.614 487.109 555.844 c
217
487.109 563.075 481.246 568.938 474.016 568.938 c
218
466.785 568.938 460.922 563.075 460.922 555.844 c
219
460.922 555.844 l
220
C
221
S 0 0 0 r f R
222

	
223
N
224
462.113 555.844 m
225
462.113 555.844 l
226
462.113 549.27 467.441 543.942 474.016 543.942 c
227
480.59 543.942 485.922 549.27 485.922 555.844 c
228
485.922 562.418 480.59 567.747 474.016 567.747 c
229
467.441 567.747 462.113 562.418 462.113 555.844 c
230
462.113 555.844 l
231
C
232
S 1 0.5 1 r f R
233

	
234
N
235
539.492 555.844 m
236
539.492 555.844 l
237
539.492 548.614 545.355 542.75 552.586 542.75 c
238
559.816 542.75 565.68 548.614 565.68 555.844 c
239
565.68 563.075 559.816 568.938 552.586 568.938 c
240
545.355 568.938 539.492 563.075 539.492 555.844 c
241
539.492 555.844 l
242
C
243
S 0 0 0 r f R
244

	
245
N
246
540.683 555.844 m
247
540.683 555.844 l
248
540.683 549.27 546.012 543.942 552.586 543.942 c
249
559.16 543.942 564.492 549.27 564.492 555.844 c
250
564.492 562.418 559.16 567.747 552.586 567.747 c
251
546.012 567.747 540.683 562.418 540.683 555.844 c
252
540.683 555.844 l
253
C
254
S 1 0 1 r f R
255

	
256
N
257
631.156 555.844 m
258
631.156 555.844 l
259
631.156 548.614 637.019 542.75 644.25 542.75 c
260
651.48 542.75 657.348 548.614 657.348 555.844 c
261
657.348 563.075 651.48 568.938 644.25 568.938 c
262
637.019 568.938 631.156 563.075 631.156 555.844 c
263
631.156 555.844 l
264
C
265
S 0 0 0 r f R
266

	
267
N
268
632.348 555.844 m
269
632.348 555.844 l
270
632.348 549.27 637.676 543.942 644.25 543.942 c
271
650.824 543.942 656.156 549.27 656.156 555.844 c
272
656.156 562.418 650.824 567.747 644.25 567.747 c
273
637.676 567.747 632.348 562.418 632.348 555.844 c
274
632.348 555.844 l
275
C
276
S 1 0.5 1 r f R
277

	
278
N
279
722.82 555.844 m
280
722.82 555.844 l
281
722.82 548.614 728.687 542.75 735.918 542.75 c
282
743.149 542.75 749.012 548.614 749.012 555.844 c
283
749.012 563.075 743.149 568.938 735.918 568.938 c
284
728.687 568.938 722.82 563.075 722.82 555.844 c
285
722.82 555.844 l
286
C
287
S 0 0 0 r f R
288

	
289
N
290
724.012 555.844 m
291
724.012 555.844 l
292
724.012 549.27 729.344 543.942 735.918 543.942 c
293
742.492 543.942 747.82 549.27 747.82 555.844 c
294
747.82 562.418 742.492 567.747 735.918 567.747 c
295
729.344 567.747 724.012 562.418 724.012 555.844 c
296
724.012 555.844 l
297
C
298
S 1 0 1 r f R
299

	
300
N
301
801.391 555.844 m
302
801.391 555.844 l
303
801.391 548.614 807.254 542.75 814.484 542.75 c
304
821.715 542.75 827.578 548.614 827.578 555.844 c
305
827.578 563.075 821.715 568.938 814.484 568.938 c
306
807.254 568.938 801.391 563.075 801.391 555.844 c
307
801.391 555.844 l
308
C
309
S 0 0 0 r f R
310

	
311
N
312
802.582 555.844 m
313
802.582 555.844 l
314
802.582 549.27 807.91 543.942 814.484 543.942 c
315
821.059 543.942 826.387 549.27 826.387 555.844 c
316
826.387 562.418 821.059 567.747 814.484 567.747 c
317
807.91 567.747 802.582 562.418 802.582 555.844 c
318
802.582 555.844 l
319
C
320
S 1 0 1 r f R
321

	
322
N
323
15.6913 32.047 m
324
15.6913 32.047 l
325
15.6913 24.8165 21.5553 18.9493 28.7853 18.9493 c
326
36.0163 18.9493 41.8833 24.8165 41.8833 32.047 c
327
41.8833 39.2775 36.0163 45.1407 28.7853 45.1407 c
328
21.5553 45.1407 15.6913 39.2775 15.6913 32.047 c
329
15.6913 32.047 l
330
C
331
S 0 0 0 r f R
332

	
333
N
334
16.8833 32.047 m
335
16.8833 32.047 l
336
16.8833 25.4728 22.2113 20.1407 28.7853 20.1407 c
337
35.3593 20.1407 40.6913 25.4728 40.6913 32.047 c
338
40.6913 38.6212 35.3593 43.9493 28.7853 43.9493 c
339
22.2113 43.9493 16.8833 38.6212 16.8833 32.047 c
340
16.8833 32.047 l
341
C
342
S 0.5 0.5 1 r f R
343

	
344
N
345
94.2623 32.047 m
346
94.2623 32.047 l
347
94.2623 24.8165 100.125 18.9493 107.355 18.9493 c
348
114.586 18.9493 120.453 24.8165 120.453 32.047 c
349
120.453 39.2775 114.586 45.1407 107.355 45.1407 c
350
100.125 45.1407 94.2623 39.2775 94.2623 32.047 c
351
94.2623 32.047 l
352
C
353
S 0 0 0 r f R
354

	
355
N
356
95.4533 32.047 m
357
95.4533 32.047 l
358
95.4533 25.4728 100.781 20.1407 107.355 20.1407 c
359
113.93 20.1407 119.262 25.4728 119.262 32.047 c
360
119.262 38.6212 113.93 43.9493 107.355 43.9493 c
361
100.781 43.9493 95.4533 38.6212 95.4533 32.047 c
362
95.4533 32.047 l
363
C
364
S 0.5 0.5 1 r f R
365

	
366
N
367
159.734 32.047 m
368
159.734 32.047 l
369
159.734 24.8165 165.601 18.9493 172.832 18.9493 c
370
180.062 18.9493 185.926 24.8165 185.926 32.047 c
371
185.926 39.2775 180.062 45.1407 172.832 45.1407 c
372
165.601 45.1407 159.734 39.2775 159.734 32.047 c
373
159.734 32.047 l
374
C
375
S 0 0 0 r f R
376

	
377
N
378
160.926 32.047 m
379
160.926 32.047 l
380
160.926 25.4728 166.258 20.1407 172.832 20.1407 c
381
179.406 20.1407 184.734 25.4728 184.734 32.047 c
382
184.734 38.6212 179.406 43.9493 172.832 43.9493 c
383
166.258 43.9493 160.926 38.6212 160.926 32.047 c
384
160.926 32.047 l
385
C
386
S 0.5 0.5 1 r f R
387

	
388
N
389
238.305 32.047 m
390
238.305 32.047 l
391
238.305 24.8165 244.172 18.9493 251.402 18.9493 c
392
258.633 18.9493 264.496 24.8165 264.496 32.047 c
393
264.496 39.2775 258.633 45.1407 251.402 45.1407 c
394
244.172 45.1407 238.305 39.2775 238.305 32.047 c
395
238.305 32.047 l
396
C
397
S 0 0 0 r f R
398

	
399
N
400
239.496 32.047 m
401
239.496 32.047 l
402
239.496 25.4728 244.828 20.1407 251.402 20.1407 c
403
257.976 20.1407 263.305 25.4728 263.305 32.047 c
404
263.305 38.6212 257.976 43.9493 251.402 43.9493 c
405
244.828 43.9493 239.496 38.6212 239.496 32.047 c
406
239.496 32.047 l
407
C
408
S 0.5 0.5 1 r f R
409

	
410
N
411
303.781 32.047 m
412
303.781 32.047 l
413
303.781 24.8165 309.644 18.9493 316.875 18.9493 c
414
324.105 18.9493 329.973 24.8165 329.973 32.047 c
415
329.973 39.2775 324.105 45.1407 316.875 45.1407 c
416
309.644 45.1407 303.781 39.2775 303.781 32.047 c
417
303.781 32.047 l
418
C
419
S 0 0 0 r f R
420

	
421
N
422
304.973 32.047 m
423
304.973 32.047 l
424
304.973 25.4728 310.301 20.1407 316.875 20.1407 c
425
323.449 20.1407 328.781 25.4728 328.781 32.047 c
426
328.781 38.6212 323.449 43.9493 316.875 43.9493 c
427
310.301 43.9493 304.973 38.6212 304.973 32.047 c
428
304.973 32.047 l
429
C
430
S 0.5 0.5 1 r f R
431

	
432
N
433
382.351 32.047 m
434
382.351 32.047 l
435
382.351 24.8165 388.215 18.9493 395.445 18.9493 c
436
402.676 18.9493 408.543 24.8165 408.543 32.047 c
437
408.543 39.2775 402.676 45.1407 395.445 45.1407 c
438
388.215 45.1407 382.351 39.2775 382.351 32.047 c
439
382.351 32.047 l
440
C
441
S 0 0 0 r f R
442

	
443
N
444
383.543 32.047 m
445
383.543 32.047 l
446
383.543 25.4728 388.871 20.1407 395.445 20.1407 c
447
402.019 20.1407 407.351 25.4728 407.351 32.047 c
448
407.351 38.6212 402.019 43.9493 395.445 43.9493 c
449
388.871 43.9493 383.543 38.6212 383.543 32.047 c
450
383.543 32.047 l
451
C
452
S 0.5 0.5 1 r f R
453

	
454
N
455
447.828 32.047 m
456
447.828 32.047 l
457
447.828 24.8165 453.691 18.9493 460.922 18.9493 c
458
468.152 18.9493 474.016 24.8165 474.016 32.047 c
459
474.016 39.2775 468.152 45.1407 460.922 45.1407 c
460
453.691 45.1407 447.828 39.2775 447.828 32.047 c
461
447.828 32.047 l
462
C
463
S 0 0 0 r f R
464

	
465
N
466
449.016 32.047 m
467
449.016 32.047 l
468
449.016 25.4728 454.348 20.1407 460.922 20.1407 c
469
467.496 20.1407 472.824 25.4728 472.824 32.047 c
470
472.824 38.6212 467.496 43.9493 460.922 43.9493 c
471
454.348 43.9493 449.016 38.6212 449.016 32.047 c
472
449.016 32.047 l
473
C
474
S 0.5 0.5 1 r f R
475

	
476
N
477
526.394 32.047 m
478
526.394 32.047 l
479
526.394 24.8165 532.262 18.9493 539.492 18.9493 c
480
546.723 18.9493 552.586 24.8165 552.586 32.047 c
481
552.586 39.2775 546.723 45.1407 539.492 45.1407 c
482
532.262 45.1407 526.394 39.2775 526.394 32.047 c
483
526.394 32.047 l
484
C
485
S 0 0 0 r f R
486

	
487
N
488
527.586 32.047 m
489
527.586 32.047 l
490
527.586 25.4728 532.918 20.1407 539.492 20.1407 c
491
546.066 20.1407 551.394 25.4728 551.394 32.047 c
492
551.394 38.6212 546.066 43.9493 539.492 43.9493 c
493
532.918 43.9493 527.586 38.6212 527.586 32.047 c
494
527.586 32.047 l
495
C
496
S 0.5 0.5 1 r f R
497

	
498
N
499
591.871 32.047 m
500
591.871 32.047 l
501
591.871 24.8165 597.734 18.9493 604.965 18.9493 c
502
612.195 18.9493 618.062 24.8165 618.062 32.047 c
503
618.062 39.2775 612.195 45.1407 604.965 45.1407 c
504
597.734 45.1407 591.871 39.2775 591.871 32.047 c
505
591.871 32.047 l
506
C
507
S 0 0 0 r f R
508

	
509
N
510
593.062 32.047 m
511
593.062 32.047 l
512
593.062 25.4728 598.39 20.1407 604.965 20.1407 c
513
611.539 20.1407 616.871 25.4728 616.871 32.047 c
514
616.871 38.6212 611.539 43.9493 604.965 43.9493 c
515
598.39 43.9493 593.062 38.6212 593.062 32.047 c
516
593.062 32.047 l
517
C
518
S 0.5 0.5 1 r f R
519

	
520
N
521
670.441 32.047 m
522
670.441 32.047 l
523
670.441 24.8165 676.305 18.9493 683.535 18.9493 c
524
690.766 18.9493 696.633 24.8165 696.633 32.047 c
525
696.633 39.2775 690.766 45.1407 683.535 45.1407 c
526
676.305 45.1407 670.441 39.2775 670.441 32.047 c
527
670.441 32.047 l
528
C
529
S 0 0 0 r f R
530

	
531
N
532
671.633 32.047 m
533
671.633 32.047 l
534
671.633 25.4728 676.961 20.1407 683.535 20.1407 c
535
690.109 20.1407 695.441 25.4728 695.441 32.047 c
536
695.441 38.6212 690.109 43.9493 683.535 43.9493 c
537
676.961 43.9493 671.633 38.6212 671.633 32.047 c
538
671.633 32.047 l
539
C
540
S 0 0 1 r f R
541

	
542
N
543
735.918 32.047 m
544
735.918 32.047 l
545
735.918 24.8165 741.781 18.9493 749.012 18.9493 c
546
756.242 18.9493 762.106 24.8165 762.106 32.047 c
547
762.106 39.2775 756.242 45.1407 749.012 45.1407 c
548
741.781 45.1407 735.918 39.2775 735.918 32.047 c
549
735.918 32.047 l
550
C
551
S 0 0 0 r f R
552

	
553
N
554
737.105 32.047 m
555
737.105 32.047 l
556
737.105 25.4728 742.437 20.1407 749.012 20.1407 c
557
755.586 20.1407 760.914 25.4728 760.914 32.047 c
558
760.914 38.6212 755.586 43.9493 749.012 43.9493 c
559
742.437 43.9493 737.105 38.6212 737.105 32.047 c
560
737.105 32.047 l
561
C
562
S 0 0 1 r f R
563

	
564
N
565
801.391 32.047 m
566
801.391 32.047 l
567
801.391 24.8165 807.254 18.9493 814.484 18.9493 c
568
821.715 18.9493 827.578 24.8165 827.578 32.047 c
569
827.578 39.2775 821.715 45.1407 814.484 45.1407 c
570
807.254 45.1407 801.391 39.2775 801.391 32.047 c
571
801.391 32.047 l
572
C
573
S 0 0 0 r f R
574

	
575
N
576
802.582 32.047 m
577
802.582 32.047 l
578
802.582 25.4728 807.91 20.1407 814.484 20.1407 c
579
821.059 20.1407 826.387 25.4728 826.387 32.047 c
580
826.387 38.6212 821.059 43.9493 814.484 43.9493 c
581
807.91 43.9493 802.582 38.6212 802.582 32.047 c
582
802.582 32.047 l
583
C
584
S 0.5 0.5 1 r f R
585

	
586
%%EOF
1
%!PS-Adobe-2.0 EPSF-2.0
2
%%Creator: LEMON, graphToEps()
3
%%CreationDate: Tue Nov 15 16:51:43 2005
4
%%BoundingBox: 0 0 842 596
5
%%EndComments
6
/lb { setlinewidth setrgbcolor newpath moveto
7
      4 2 roll 1 index 1 index curveto stroke } bind def
8
/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
9
/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
10
/sq { newpath 2 index 1 index add 2 index 2 index add moveto
11
      2 index 1 index sub 2 index 2 index add lineto
12
      2 index 1 index sub 2 index 2 index sub lineto
13
      2 index 1 index add 2 index 2 index sub lineto
14
      closepath pop pop pop} bind def
15
/di { newpath 2 index 1 index add 2 index moveto
16
      2 index             2 index 2 index add lineto
17
      2 index 1 index sub 2 index             lineto
18
      2 index             2 index 2 index sub lineto
19
      closepath pop pop pop} bind def
20
/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
21
     setrgbcolor 1.1 div c fill
22
   } bind def
23
/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
24
     setrgbcolor 1.1 div sq fill
25
   } bind def
26
/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
27
     setrgbcolor 1.1 div di fill
28
   } bind def
29
/arrl 1 def
30
/arrw 0.3 def
31
/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
32
/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
33
       /w exch def /len exch def
34
       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
35
       len w sub arrl sub dx dy lrl
36
       arrw dy dx neg lrl
37
       dx arrl w add mul dy w 2 div arrw add mul sub
38
       dy arrl w add mul dx w 2 div arrw add mul add rlineto
39
       dx arrl w add mul neg dy w 2 div arrw add mul sub
40
       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
41
       arrw dy dx neg lrl
42
       len w sub arrl sub neg dx dy lrl
43
       closepath fill } bind def
44
/cshow { 2 index 2 index moveto dup stringwidth pop
45
         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
46

	
47
gsave
48
90 rotate
49
0 -842 translate
50
71.6378 15 translate
51
0.389093 dup scale
52
90 rotate
53
1197.47 -613.138 translate
54
%Edges:
55
gsave
56
513.857 -446.322 296.569 -487.43 79.2808 -528.539 0 0 0 2 lb
57
513.857 -446.322 575.52 -315.655 637.183 -184.989 0 0 0 2 lb
58
393.468 566.711 494.771 434.577 596.074 302.442 0 0 0 2 lb
59
393.468 566.711 155.625 579.925 -82.2171 593.138 0 0 0 2 lb
60
393.468 566.711 251.056 450.726 108.644 334.741 0 0 0 2 lb
61
869.153 52.8539 732.613 177.648 596.074 302.442 0 0 0 2 lb
62
869.153 52.8539 753.168 -66.0676 637.183 -184.989 0 0 0 2 lb
63
-82.2171 593.138 -91.0261 346.487 -99.8351 99.8351 0 0 0 2 lb
64
-663.61 546.157 -753.168 394.936 -842.726 243.715 0 0 0 2 lb
65
-663.61 546.157 -574.052 437.513 -484.494 328.869 0 0 0 2 lb
66
-1077.63 161.498 -960.178 202.606 -842.726 243.715 0 0 0 2 lb
67
-1077.63 161.498 -968.987 66.0674 -860.344 -29.3633 0 0 0 2 lb
68
-1177.47 -234.906 -1029.18 -381.722 -880.898 -528.539 0 0 0 2 lb
69
-1177.47 -234.906 -1018.91 -132.135 -860.344 -29.3633 0 0 0 2 lb
70
-880.898 -528.539 -744.359 -387.595 -607.82 -246.651 0 0 0 2 lb
71
-499.175 -499.175 -355.295 -475.685 -211.415 -452.194 0 0 0 2 lb
72
-499.175 -499.175 -553.498 -372.913 -607.82 -246.651 0 0 0 2 lb
73
-499.175 -499.175 -386.587 -315.087 -274 -131 0 0 0 2 lb
74
79.2808 -528.539 -66.0671 -490.366 -211.415 -452.194 0 0 0 2 lb
75
637.183 -184.989 421.363 -253.993 205.543 -322.996 0 0 0 2 lb
76
205.543 -322.996 162.966 -226.097 120.389 -129.198 0 0 0 2 lb
77
399.34 88.0898 259.865 -20.5541 120.389 -129.198 0 0 0 2 lb
78
399.34 88.0898 253.992 211.415 108.644 334.741 0 0 0 2 lb
79
-842.726 243.715 -471.281 171.775 -99.8351 99.8351 0 0 0 2 lb
80
-842.726 243.715 -558.363 56.3575 -274 -131 0 0 0 2 lb
81
-860.344 -29.3633 -734.082 -138.007 -607.82 -246.651 0 0 0 2 lb
82
-211.415 -452.194 -45.513 -290.696 120.389 -129.198 0 0 0 2 lb
83
-99.8351 99.8351 4.40445 217.288 108.644 334.741 0 0 0 2 lb
84
-99.8351 99.8351 -292.165 214.352 -484.494 328.869 0 0 0 2 lb
85
120.389 -129.198 -76.8055 -130.099 -274 -131 0 0 0 2 lb
86
grestore
87
%Nodes:
88
gsave
89
-274 -131 20 1 0 0 nc
90
-607.82 -246.651 20 1 0 0 nc
91
-484.494 328.869 20 0 0 1 nc
92
108.644 334.741 20 0 0 1 nc
93
120.389 -129.198 20 0 0 1 nc
94
-99.8351 99.8351 20 1 0 0 nc
95
-211.415 -452.194 20 1 0 0 nc
96
-860.344 -29.3633 20 0 0 1 nc
97
-842.726 243.715 20 0 0 1 nc
98
399.34 88.0898 20 1 0 0 nc
99
205.543 -322.996 20 1 0 0 nc
100
637.183 -184.989 20 0 0 1 nc
101
79.2808 -528.539 20 0 0 1 nc
102
-499.175 -499.175 20 0 0 1 nc
103
-880.898 -528.539 20 0 0 1 nc
104
-1177.47 -234.906 20 1 0 0 nc
105
-1077.63 161.498 20 1 0 0 nc
106
-663.61 546.157 20 1 0 0 nc
107
-82.2171 593.138 20 0 0 1 nc
108
596.074 302.442 20 0 0 1 nc
109
869.153 52.8539 20 1 0 0 nc
110
393.468 566.711 20 1 0 0 nc
111
513.857 -446.322 20 1 0 0 nc
112
grestore
113
grestore
114
showpage
1
%!PS-Adobe-2.0 EPSF-2.0
2
%%Creator: LEMON, graphToEps()
3
%%CreationDate: Fri Nov  4 13:47:12 2005
4
%%BoundingBox: 0 0 842 596
5
%%EndComments
6
/lb { setlinewidth setrgbcolor newpath moveto
7
      4 2 roll 1 index 1 index curveto stroke } bind def
8
/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
9
/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
10
/sq { newpath 2 index 1 index add 2 index 2 index add moveto
11
      2 index 1 index sub 2 index 2 index add lineto
12
      2 index 1 index sub 2 index 2 index sub lineto
13
      2 index 1 index add 2 index 2 index sub lineto
14
      closepath pop pop pop} bind def
15
/di { newpath 2 index 1 index add 2 index moveto
16
      2 index             2 index 2 index add lineto
17
      2 index 1 index sub 2 index             lineto
18
      2 index             2 index 2 index sub lineto
19
      closepath pop pop pop} bind def
20
/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
21
     setrgbcolor 1.1 div c fill
22
   } bind def
23
/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
24
     setrgbcolor 1.1 div sq fill
25
   } bind def
26
/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
27
     setrgbcolor 1.1 div di fill
28
   } bind def
29
/arrl 1 def
30
/arrw 0.3 def
31
/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
32
/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
33
       /w exch def /len exch def
34
       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
35
       len w sub arrl sub dx dy lrl
36
       arrw dy dx neg lrl
37
       dx arrl w add mul dy w 2 div arrw add mul sub
38
       dy arrl w add mul dx w 2 div arrw add mul add rlineto
39
       dx arrl w add mul neg dy w 2 div arrw add mul sub
40
       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
41
       arrw dy dx neg lrl
42
       len w sub arrl sub neg dx dy lrl
43
       closepath fill } bind def
44
/cshow { 2 index 2 index moveto dup stringwidth pop
45
         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
46

	
47
gsave
48
90 rotate
49
0 -842 translate
50
71.0944 15 translate
51
0.434694 dup scale
52
90 rotate
53
860.856 -588.349 translate
54
%Edges:
55
gsave
56
574.035 177.301 622.149 225.748 670.264 274.195 0 0 0 2 lb
57
694.579 115.483 682.421 194.839 670.264 274.195 0 0 0 2 lb
58
280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 0 2 lb
59
280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 0 2 lb
60
212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 0 2 lb
61
286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 0 2 lb
62
286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 0 2 lb
63
438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 0 2 lb
64
438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 0 2 lb
65
397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 0 2 lb
66
366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 0 2 lb
67
271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 0 2 lb
68
271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 0 2 lb
69
277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 0 2 lb
70
-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0 0 2 lb
71
-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0 2 lb
72
-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0 2 lb
73
-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0 2 lb
74
906.312 201.403 946.592 42.798 986.873 -115.807 0 0 0 2 lb
75
906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 0 2 lb
76
986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 0 2 lb
77
-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0 0 0 2 lb
78
422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 0 2 lb
79
422.945 521.129 376.371 417.911 329.797 314.692 0 0 0 2 lb
80
422.945 521.129 474.554 276.928 526.164 32.7279 0 0 0 2 lb
81
-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 0 2 lb
82
329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 0 2 lb
83
-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 0 2 lb
84
762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 0 2 lb
85
762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 0 2 lb
86
526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 0 2 lb
87
730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 0 2 lb
88
415.393 -289.516 173.71 -318.468 -67.9734 -347.42 0 0 0 2 lb
89
-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 0 2 lb
90
-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 0 2 lb
91
-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 0 2 lb
92
-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 0 2 lb
93
-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 0 2 lb
94
-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 0 2 lb
95
-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 0 2 lb
96
-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 0 2 lb
97
116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 0 2 lb
98
-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 0 2 lb
99
-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 0 2 lb
100
-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 0 2 lb
101
-180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 0 2 lb
102
-180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 0 2 lb
103
-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 0 2 lb
104
-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 0 2 lb
105
-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 0 2 lb
106
670.264 274.195 629.188 409.347 588.113 544.499 0 0 0 2 lb
107
670.264 274.195 797.466 341.771 924.667 409.347 0 0 0 2 lb
108
588.113 544.499 756.39 476.923 924.667 409.347 0 0 0 2 lb
109
-689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 0 2 lb
110
-689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 0 2 lb
111
grestore
112
%Nodes:
113
gsave
114
-567.302 43.6423 20 0 0 0 nc
115
-689.204 -237.261 20 0 0 0 nc
116
924.667 409.347 20 1 0 0 nc
117
588.113 544.499 20 1 0 0 nc
118
670.264 274.195 20 1 0 0 nc
119
-371.2 568.349 20 0 1 0 nc
120
-132.697 451.748 20 0 1 0 nc
121
-416.25 345.746 20 0 1 0 nc
122
-180.397 245.045 20 0 1 0 nc
123
-13.4452 133.743 20 0 1 0 nc
124
-262.548 107.243 20 0 1 0 nc
125
201.208 38.3422 20 0 1 0 nc
126
116.407 -173.66 20 0 1 0 nc
127
-26.6953 -19.9585 20 0 1 0 nc
128
-539.894 -262.64 20 0 0 1 nc
129
-323.543 -433.964 20 0 0 1 nc
130
-309.657 -57.9033 20 0 0 1 nc
131
-67.9734 -347.42 20 0 0 1 nc
132
415.393 -289.516 20 0 0 1 nc
133
730.084 -307.139 20 0 0 1 nc
134
526.164 32.7279 20 0 0 1 nc
135
762.812 -17.6227 20 0 0 1 nc
136
-67.9734 319.727 20 0 0 1 nc
137
329.797 314.692 20 0 0 1 nc
138
-5.03507 561.41 20 0 0 1 nc
139
422.945 521.129 20 0 0 1 nc
140
-470.779 158.605 20 0 0 1 nc
141
986.873 -115.807 20 0 0 1 nc
142
906.312 201.403 20 0 0 1 nc
143
-767.847 113.289 20 0 0 1 nc
144
-579.033 445.603 20 0 0 1 nc
145
-840.856 -246.718 20 0 0 1 nc
146
206.221 -205.967 20 1 1 0 nc
147
277.311 -252.33 20 1 1 0 nc
148
271.13 -175.058 20 1 1 0 nc
149
366.947 -110.15 20 1 1 0 nc
150
397.855 -196.694 20 1 1 0 nc
151
438.037 -88.514 20 1 1 0 nc
152
286.584 -48.3327 20 1 1 0 nc
153
212.403 -23.6057 20 1 1 0 nc
154
280.402 10.3938 20 1 1 0 nc
155
694.579 115.483 20 1 0 0 nc
156
574.035 177.301 20 1 0 0 nc
157
grestore
158
grestore
159
showpage
1
%!PS-Adobe-2.0 EPSF-2.0
2
%%Creator: LEMON, graphToEps()
3
%%CreationDate: Fri Nov  4 13:47:12 2005
4
%%BoundingBox: 0 0 842 596
5
%%EndComments
6
/lb { setlinewidth setrgbcolor newpath moveto
7
      4 2 roll 1 index 1 index curveto stroke } bind def
8
/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
9
/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
10
/sq { newpath 2 index 1 index add 2 index 2 index add moveto
11
      2 index 1 index sub 2 index 2 index add lineto
12
      2 index 1 index sub 2 index 2 index sub lineto
13
      2 index 1 index add 2 index 2 index sub lineto
14
      closepath pop pop pop} bind def
15
/di { newpath 2 index 1 index add 2 index moveto
16
      2 index             2 index 2 index add lineto
17
      2 index 1 index sub 2 index             lineto
18
      2 index             2 index 2 index sub lineto
19
      closepath pop pop pop} bind def
20
/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
21
     setrgbcolor 1.1 div c fill
22
   } bind def
23
/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
24
     setrgbcolor 1.1 div sq fill
25
   } bind def
26
/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
27
     setrgbcolor 1.1 div di fill
28
   } bind def
29
/arrl 1 def
30
/arrw 0.3 def
31
/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
32
/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
33
       /w exch def /len exch def
34
       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
35
       len w sub arrl sub dx dy lrl
36
       arrw dy dx neg lrl
37
       dx arrl w add mul dy w 2 div arrw add mul sub
38
       dy arrl w add mul dx w 2 div arrw add mul add rlineto
39
       dx arrl w add mul neg dy w 2 div arrw add mul sub
40
       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
41
       arrw dy dx neg lrl
42
       len w sub arrl sub neg dx dy lrl
43
       closepath fill } bind def
44
/cshow { 2 index 2 index moveto dup stringwidth pop
45
         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
46

	
47
gsave
48
90 rotate
49
0 -842 translate
50
71.0944 15 translate
51
0.434694 dup scale
52
90 rotate
53
860.856 -588.349 translate
54
%Edges:
55
gsave
56
574.035 177.301 622.149 225.748 670.264 274.195 1 0 0 2 lb
57
694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 2 lb
58
280.402 10.3938 246.402 -6.60595 212.403 -23.6057 0 0 1 2 lb
59
280.402 10.3938 283.493 -18.9695 286.584 -48.3327 0 0 1 2 lb
60
212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 0 0 1 2 lb
61
286.584 -48.3327 326.765 -79.2414 366.947 -110.15 0 0 1 2 lb
62
286.584 -48.3327 278.857 -111.695 271.13 -175.058 0 0 1 2 lb
63
438.037 -88.514 417.946 -142.604 397.855 -196.694 0 0 1 2 lb
64
438.037 -88.514 402.492 -99.332 366.947 -110.15 0 0 1 2 lb
65
397.855 -196.694 382.401 -153.422 366.947 -110.15 0 0 1 2 lb
66
366.947 -110.15 319.038 -142.604 271.13 -175.058 0 0 1 2 lb
67
271.13 -175.058 274.221 -213.694 277.311 -252.33 0 0 1 2 lb
68
271.13 -175.058 238.675 -190.512 206.221 -205.967 0 0 1 2 lb
69
277.311 -252.33 241.766 -229.149 206.221 -205.967 0 0 1 2 lb
70
-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 1 0 0 2 lb
71
-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 1 2 lb
72
-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 1 2 lb
73
-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 1 2 lb
74
906.312 201.403 946.592 42.798 986.873 -115.807 0 0 1 2 lb
75
906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0 1 2 lb
76
986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0 1 2 lb
77
-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 1 0 0 2 lb
78
422.945 521.129 208.955 541.269 -5.03507 561.41 0 0 1 2 lb
79
422.945 521.129 376.371 417.911 329.797 314.692 0 0 1 2 lb
80
422.945 521.129 474.554 276.928 526.164 32.7279 0 0 1 2 lb
81
-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0 0 1 2 lb
82
329.797 314.692 130.912 317.209 -67.9734 319.727 0 0 1 2 lb
83
-67.9734 319.727 229.095 176.227 526.164 32.7279 0 0 1 2 lb
84
762.812 -17.6227 644.488 7.5526 526.164 32.7279 0 0 1 2 lb
85
762.812 -17.6227 746.448 -162.381 730.084 -307.139 0 0 1 2 lb
86
526.164 32.7279 470.779 -128.394 415.393 -289.516 0 0 1 2 lb
87
730.084 -307.139 572.738 -298.327 415.393 -289.516 0 0 1 2 lb
88
415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0 0 2 lb
89
-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0 0 1 2 lb
90
-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0 0 1 2 lb
91
-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0 0 1 2 lb
92
-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0 0 1 2 lb
93
-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 0 0 1 2 lb
94
-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 0 0 1 2 lb
95
-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 0 0 1 2 lb
96
-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 0 0 1 2 lb
97
116.407 -173.66 158.808 -67.6589 201.208 38.3422 0 0 1 2 lb
98
-262.548 107.243 -137.997 120.493 -13.4452 133.743 0 0 1 2 lb
99
-262.548 107.243 -221.472 176.144 -180.397 245.045 0 0 1 2 lb
100
-13.4452 133.743 -96.9211 189.394 -180.397 245.045 0 0 1 2 lb
101
-180.397 245.045 -142.256 345.099 -132.697 451.748 0 0 1 2 lb
102
-180.397 245.045 -170.838 351.694 -132.697 451.748 0 0 1 2 lb
103
-416.25 345.746 -274.474 398.747 -132.697 451.748 0 0 1 2 lb
104
-416.25 345.746 -393.725 457.048 -371.2 568.349 0 0 1 2 lb
105
-132.697 451.748 -251.948 510.048 -371.2 568.349 0 0 1 2 lb
106
670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 2 lb
107
670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 2 lb
108
588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 2 lb
109
-689.204 -237.261 -614.799 -102.648 -567.302 43.6423 0 0 1 2 lb
110
-689.204 -237.261 -641.707 -90.9706 -567.302 43.6423 0 0 1 2 lb
111
grestore
112
%Nodes:
113
gsave
114
-567.302 43.6423 20 0 0 0 nc
115
-689.204 -237.261 20 0 0 0 nc
116
924.667 409.347 20 0 0 1 nc
117
588.113 544.499 20 0 0 1 nc
118
670.264 274.195 20 0 0 1 nc
119
-371.2 568.349 20 1 1 0 nc
120
-132.697 451.748 20 1 1 0 nc
121
-416.25 345.746 20 1 1 0 nc
122
-180.397 245.045 20 1 1 0 nc
123
-13.4452 133.743 20 1 1 0 nc
124
-262.548 107.243 20 1 1 0 nc
125
201.208 38.3422 20 1 1 0 nc
126
116.407 -173.66 20 1 1 0 nc
127
-26.6953 -19.9585 20 1 1 0 nc
128
-539.894 -262.64 20 0 0.5 0 nc
129
-323.543 -433.964 20 0 0.5 0 nc
130
-309.657 -57.9033 20 0 0.5 0 nc
131
-67.9734 -347.42 20 0 0.5 0 nc
132
415.393 -289.516 20 0.5 0 0 nc
133
730.084 -307.139 20 0.5 0 0 nc
134
526.164 32.7279 20 0.5 0 0 nc
135
762.812 -17.6227 20 0.5 0 0 nc
136
-67.9734 319.727 20 0.5 0 0 nc
137
329.797 314.692 20 0.5 0 0 nc
138
-5.03507 561.41 20 0.5 0 0 nc
139
422.945 521.129 20 0.5 0 0 nc
140
-470.779 158.605 20 0 1 1 nc
141
986.873 -115.807 20 0.5 0 0 nc
142
906.312 201.403 20 0.5 0 0 nc
143
-767.847 113.289 20 0 1 1 nc
144
-579.033 445.603 20 0 1 1 nc
145
-840.856 -246.718 20 1 0 1 nc
146
206.221 -205.967 20 0 0 0.5 nc
147
277.311 -252.33 20 0 0 0.5 nc
148
271.13 -175.058 20 0 0 0.5 nc
149
366.947 -110.15 20 0 0 0.5 nc
150
397.855 -196.694 20 0 0 0.5 nc
151
438.037 -88.514 20 0 0 0.5 nc
152
286.584 -48.3327 20 0 0 0.5 nc
153
212.403 -23.6057 20 0 0 0.5 nc
154
280.402 10.3938 20 0 0 0.5 nc
155
694.579 115.483 20 1 0 0 nc
156
574.035 177.301 20 0 1 0 nc
157
grestore
158
grestore
159
showpage
Ignore white space 6 line context
1
%!PS-Adobe-2.0 EPSF-2.0
2
%%Title: Grid undirected graph
3
%%Copyright: (C) 2006 LEMON Project
4
%%Creator: LEMON, graphToEps()
5
%%CreationDate: Fri Sep 29 11:55:56 2006
6
%%BoundingBox: 0 0 985 1144
7
%%EndComments
8
/lb { setlinewidth setrgbcolor newpath moveto
9
      4 2 roll 1 index 1 index curveto stroke } bind def
10
/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
11
/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
12
/sq { newpath 2 index 1 index add 2 index 2 index add moveto
13
      2 index 1 index sub 2 index 2 index add lineto
14
      2 index 1 index sub 2 index 2 index sub lineto
15
      2 index 1 index add 2 index 2 index sub lineto
16
      closepath pop pop pop} bind def
17
/di { newpath 2 index 1 index add 2 index moveto
18
      2 index             2 index 2 index add lineto
19
      2 index 1 index sub 2 index             lineto
20
      2 index             2 index 2 index sub lineto
21
      closepath pop pop pop} bind def
22
/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
23
     setrgbcolor 1.1 div c fill
24
   } bind def
25
/arrl 1 def
26
/arrw 0.3 def
27
/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
28
/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
29
       /w exch def /len exch def
30
       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
31
       len w sub arrl sub dx dy lrl
32
       arrw dy dx neg lrl
33
       dx arrl w add mul dy w 2 div arrw add mul sub
34
       dy arrl w add mul dx w 2 div arrw add mul add rlineto
35
       dx arrl w add mul neg dy w 2 div arrw add mul sub
36
       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
37
       arrw dy dx neg lrl
38
       len w sub arrl sub neg dx dy lrl
39
       closepath fill } bind def
40
/cshow { 2 index 2 index moveto dup stringwidth pop
41
         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
42

	
43
gsave
44
2 2 scale
45
50 40 translate
46
5.5000 5.5000 scale
47
% 1.14018 1.14018 translate
48
%Edges:
49
gsave
50
70 80 70 90 0 0 0 0.5000 l
51
70 70 70 80 0 0 0 0.5000 l
52
70 60 70 70 0 0 0 0.5000 l
53
70 50 70 60 0 0 0 0.5000 l
54
70 40 70 50 0 0 0 0.5000 l
55
70 30 70 40 0 0 0 0.5000 l
56
70 20 70 30 0 0 0 0.5000 l
57
70 10 70 20 0 0 0 0.5000 l
58
70 0 70 10 0 0 0 0.5000 l
59
60 80 60 90 0 0 0 0.5000 l
60
60 70 60 80 0 0 0 0.5000 l
61
60 60 60 70 0 0 0 0.5000 l
62
60 50 60 60 0 0 0 0.5000 l
63
60 40 60 50 0 0 0 0.5000 l
64
60 30 60 40 0 0 0 0.5000 l
65
60 20 60 30 0 0 0 0.5000 l
66
60 10 60 20 0 0 0 0.5000 l
67
60 0 60 10 0 0 0 0.5000 l
68
50 80 50 90 0 0 0 0.5000 l
69
50 70 50 80 0 0 0 0.5000 l
70
50 60 50 70 0 0 0 0.5000 l
71
50 50 50 60 0 0 0 0.5000 l
72
50 40 50 50 0 0 0 0.5000 l
73
50 30 50 40 0 0 0 0.5000 l
74
50 20 50 30 0 0 0 0.5000 l
75
50 10 50 20 0 0 0 0.5000 l
76
50 0 50 10 0 0 0 0.5000 l
77
40 80 40 90 0 0 0 0.5000 l
78
40 70 40 80 0 0 0 0.5000 l
79
40 60 40 70 0 0 0 0.5000 l
80
40 50 40 60 0 0 0 0.5000 l
81
40 40 40 50 0 0 0 0.5000 l
82
40 30 40 40 0 0 0 0.5000 l
83
40 20 40 30 0 0 0 0.5000 l
84
40 10 40 20 0 0 0 0.5000 l
85
40 0 40 10 0 0 0 0.5000 l
86
30 80 30 90 0 0 0 0.5000 l
87
30 70 30 80 0 0 0 0.5000 l
88
30 60 30 70 0 0 0 0.5000 l
89
30 50 30 60 0 0 0 0.5000 l
90
30 40 30 50 0 0 0 0.5000 l
91
30 30 30 40 0 0 0 0.5000 l
92
30 20 30 30 0 0 0 0.5000 l
93
30 10 30 20 0 0 0 0.5000 l
94
30 0 30 10 0 0 0 0.5000 l
95
20 80 20 90 0 0 0 0.5000 l
96
20 70 20 80 0 0 0 0.5000 l
97
20 60 20 70 0 0 0 0.5000 l
98
20 50 20 60 0 0 0 0.5000 l
99
20 40 20 50 0 0 0 0.5000 l
100
20 30 20 40 0 0 0 0.5000 l
101
20 20 20 30 0 0 0 0.5000 l
102
20 10 20 20 0 0 0 0.5000 l
103
20 0 20 10 0 0 0 0.5000 l
104
10 80 10 90 0 0 0 0.5000 l
105
10 70 10 80 0 0 0 0.5000 l
106
10 60 10 70 0 0 0 0.5000 l
107
10 50 10 60 0 0 0 0.5000 l
108
10 40 10 50 0 0 0 0.5000 l
109
10 30 10 40 0 0 0 0.5000 l
110
10 20 10 30 0 0 0 0.5000 l
111
10 10 10 20 0 0 0 0.5000 l
112
10 0 10 10 0 0 0 0.5000 l
113
0 80 0 90 0 0 0 0.5000 l
114
0 70 0 80 0 0 0 0.5000 l
115
0 60 0 70 0 0 0 0.5000 l
116
0 50 0 60 0 0 0 0.5000 l
117
0 40 0 50 0 0 0 0.5000 l
118
0 30 0 40 0 0 0 0.5000 l
119
0 20 0 30 0 0 0 0.5000 l
120
0 10 0 20 0 0 0 0.5000 l
121
0 0 0 10 0 0 0 0.5000 l
122
60 90 70 90 0 0 0 0.5000 l
123
60 80 70 80 0 0 0 0.5000 l
124
60 70 70 70 0 0 0 0.5000 l
125
60 60 70 60 0 0 0 0.5000 l
126
60 50 70 50 0 0 0 0.5000 l
127
60 40 70 40 0 0 0 0.5000 l
128
60 30 70 30 0 0 0 0.5000 l
129
60 20 70 20 0 0 0 0.5000 l
130
60 10 70 10 0 0 0 0.5000 l
131
60 0 70 0 0 0 0 0.5000 l
132
50 90 60 90 0 0 0 0.5000 l
133
50 80 60 80 0 0 0 0.5000 l
134
50 70 60 70 0 0 0 0.5000 l
135
50 60 60 60 0 0 0 0.5000 l
136
50 50 60 50 0 0 0 0.5000 l
137
50 40 60 40 0 0 0 0.5000 l
138
50 30 60 30 0 0 0 0.5000 l
139
50 20 60 20 0 0 0 0.5000 l
140
50 10 60 10 0 0 0 0.5000 l
141
50 0 60 0 0 0 0 0.5000 l
142
40 90 50 90 0 0 0 0.5000 l
143
40 80 50 80 0 0 0 0.5000 l
144
40 70 50 70 0 0 0 0.5000 l
145
40 60 50 60 0 0 0 0.5000 l
146
40 50 50 50 0 0 0 0.5000 l
147
40 40 50 40 0 0 0 0.5000 l
148
40 30 50 30 0 0 0 0.5000 l
149
40 20 50 20 0 0 0 0.5000 l
150
40 10 50 10 0 0 0 0.5000 l
151
40 0 50 0 0 0 0 0.5000 l
152
30 90 40 90 0 0 0 0.5000 l
153
30 80 40 80 0 0 0 0.5000 l
154
30 70 40 70 0 0 0 0.5000 l
155
30 60 40 60 0 0 0 0.5000 l
156
30 50 40 50 0 0 0 0.5000 l
157
30 40 40 40 0 0 0 0.5000 l
158
30 30 40 30 0 0 0 0.5000 l
159
30 20 40 20 0 0 0 0.5000 l
160
30 10 40 10 0 0 0 0.5000 l
161
30 0 40 0 0 0 0 0.5000 l
162
20 90 30 90 0 0 0 0.5000 l
163
20 80 30 80 0 0 0 0.5000 l
164
20 70 30 70 0 0 0 0.5000 l
165
20 60 30 60 0 0 0 0.5000 l
166
20 50 30 50 0 0 0 0.5000 l
167
20 40 30 40 0 0 0 0.5000 l
168
20 30 30 30 0 0 0 0.5000 l
169
20 20 30 20 0 0 0 0.5000 l
170
20 10 30 10 0 0 0 0.5000 l
171
20 0 30 0 0 0 0 0.5000 l
172
10 90 20 90 0 0 0 0.5000 l
173
10 80 20 80 0 0 0 0.5000 l
174
10 70 20 70 0 0 0 0.5000 l
175
10 60 20 60 0 0 0 0.5000 l
176
10 50 20 50 0 0 0 0.5000 l
177
10 40 20 40 0 0 0 0.5000 l
178
10 30 20 30 0 0 0 0.5000 l
179
10 20 20 20 0 0 0 0.5000 l
180
10 10 20 10 0 0 0 0.5000 l
181
10 0 20 0 0 0 0 0.5000 l
182
0 90 10 90 0 0 0 0.5000 l
183
0 80 10 80 0 0 0 0.5000 l
184
0 70 10 70 0 0 0 0.5000 l
185
0 60 10 60 0 0 0 0.5000 l
186
0 50 10 50 0 0 0 0.5000 l
187
0 40 10 40 0 0 0 0.5000 l
188
0 30 10 30 0 0 0 0.5000 l
189
0 20 10 20 0 0 0 0.5000 l
190
0 10 10 10 0 0 0 0.5000 l
191
0 0 10 0 0 0 0 0.5000 l
192
grestore
193
%Nodes:
194
gsave
195
70 90 1.4000 0 0 0 nc
196
70 80 1.4000 1 1 1 nc
197
70 70 1.4000 1 1 1 nc
198
70 60 1.4000 1 1 1 nc
199
70 50 1.4000 1 1 1 nc
200
70 40 1.4000 1 1 1 nc
201
70 30 1.4000 1 1 1 nc
202
70 20 1.4000 1 1 1 nc
203
70 10 1.4000 1 1 1 nc
204
70 0 1.4000 0 0 0 nc
205
60 90 1.4000 1 1 1 nc
206
60 80 1.4000 1 1 1 nc
207
60 70 1.4000 1 1 1 nc
208
60 60 1.4000 1 1 1 nc
209
60 50 1.4000 1 1 1 nc
210
60 40 1.4000 1 1 1 nc
211
60 30 1.4000 1 1 1 nc
212
60 20 1.4000 1 1 1 nc
213
60 10 1.4000 1 1 1 nc
214
60 0 1.4000 1 1 1 nc
215
50 90 1.4000 1 1 1 nc
216
50 80 1.4000 1 1 1 nc
217
50 70 1.4000 1 1 1 nc
218
50 60 1.4000 1 1 1 nc
219
50 50 1.4000 1 1 1 nc
220
50 40 1.4000 1 1 1 nc
221
50 30 1.4000 1 1 1 nc
222
50 20 1.4000 1 1 1 nc
223
50 10 1.4000 1 1 1 nc
224
50 0 1.4000 1 1 1 nc
225
40 90 1.4000 1 1 1 nc
226
40 80 1.4000 1 1 1 nc
227
40 70 1.4000 1 1 1 nc
228
40 60 1.4000 1 1 1 nc
229
40 50 1.4000 1 1 1 nc
230
40 40 1.4000 1 1 1 nc
231
40 30 1.4000 1 1 1 nc
232
40 20 1.4000 1 1 1 nc
233
40 10 1.4000 1 1 1 nc
234
40 0 1.4000 1 1 1 nc
235
30 90 1.4000 1 1 1 nc
236
30 80 1.4000 1 1 1 nc
237
30 70 1.4000 1 1 1 nc
238
30 60 1.4000 1 1 1 nc
239
30 50 1.4000 1 1 1 nc
240
30 40 1.4000 1 1 1 nc
241
30 30 1.4000 1 1 1 nc
242
30 20 1.4000 1 1 1 nc
243
30 10 1.4000 1 1 1 nc
244
30 0 1.4000 1 1 1 nc
245
20 90 1.4000 1 1 1 nc
246
20 80 1.4000 1 1 1 nc
247
20 70 1.4000 1 1 1 nc
248
20 60 1.4000 1 1 1 nc
249
20 50 1.4000 1 1 1 nc
250
20 40 1.4000 1 1 1 nc
251
20 30 1.4000 1 1 1 nc
252
20 20 1.4000 1 1 1 nc
253
20 10 1.4000 1 1 1 nc
254
20 0 1.4000 1 1 1 nc
255
10 90 1.4000 1 1 1 nc
256
10 80 1.4000 1 1 1 nc
257
10 70 1.4000 1 1 1 nc
258
10 60 1.4000 1 1 1 nc
259
10 50 1.4000 1 1 1 nc
260
10 40 1.4000 1 1 1 nc
261
10 30 1.4000 1 1 1 nc
262
10 20 1.4000 1 1 1 nc
263
10 10 1.4000 1 1 1 nc
264
10 0 1.4000 1 1 1 nc
265
0 90 1.4000 0 0 0 nc
266
0 80 1.4000 1 1 1 nc
267
0 70 1.4000 1 1 1 nc
268
0 60 1.4000 1 1 1 nc
269
0 50 1.4000 1 1 1 nc
270
0 40 1.4000 1 1 1 nc
271
0 30 1.4000 1 1 1 nc
272
0 20 1.4000 1 1 1 nc
273
0 10 1.4000 1 1 1 nc
274
0 0 1.4000 0 0 0 nc
275
grestore
276
gsave
277
/fosi 3.5 def
278
(Helvetica) findfont fosi scalefont setfont
279
0 0 0 setrgbcolor
280
0 95 ((0,height-1)) cshow
281
67 95 ((width-1,height-1)) cshow
282
0 -5 ((0,0)) cshow
283
70 -5 ((width-1,0)) cshow
284
grestore
285
grestore
286
showpage
1
%!PS-Adobe-2.0 EPSF-2.0
2
%%Creator: LEMON, graphToEps()
3
%%CreationDate: Fri Nov  4 13:47:12 2005
4
%%BoundingBox: 0 0 842 596
5
%%EndComments
6
/lb { setlinewidth setrgbcolor newpath moveto
7
      4 2 roll 1 index 1 index curveto stroke } bind def
8
/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
9
/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
10
/sq { newpath 2 index 1 index add 2 index 2 index add moveto
11
      2 index 1 index sub 2 index 2 index add lineto
12
      2 index 1 index sub 2 index 2 index sub lineto
13
      2 index 1 index add 2 index 2 index sub lineto
14
      closepath pop pop pop} bind def
15
/di { newpath 2 index 1 index add 2 index moveto
16
      2 index             2 index 2 index add lineto
17
      2 index 1 index sub 2 index             lineto
18
      2 index             2 index 2 index sub lineto
19
      closepath pop pop pop} bind def
20
/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
21
     setrgbcolor 1.1 div c fill
22
   } bind def
23
/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
24
     setrgbcolor 1.1 div sq fill
25
   } bind def
26
/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
27
     setrgbcolor 1.1 div di fill
28
   } bind def
29
/arrl 1 def
30
/arrw 0.3 def
31
/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
32
/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
33
       /w exch def /len exch def
34
       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
35
       len w sub arrl sub dx dy lrl
36
       arrw dy dx neg lrl
37
       dx arrl w add mul dy w 2 div arrw add mul sub
38
       dy arrl w add mul dx w 2 div arrw add mul add rlineto
39
       dx arrl w add mul neg dy w 2 div arrw add mul sub
40
       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
41
       arrw dy dx neg lrl
42
       len w sub arrl sub neg dx dy lrl
43
       closepath fill } bind def
44
/cshow { 2 index 2 index moveto dup stringwidth pop
45
         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
46

	
47
gsave
48
90 rotate
49
0 -842 translate
50
71.0944 15 translate
51
0.434694 dup scale
52
90 rotate
53
860.856 -588.349 translate
54
%Edges:
55
gsave
56
574.035 177.301 622.149 225.748 670.264 274.195 0 1 0 5 lb
57
694.579 115.483 682.421 194.839 670.264 274.195 1 0 0 5 lb
58
280.402 10.3938 246.402 -6.60595 212.403 -23.6057 1 1 0.5 5 lb
59
280.402 10.3938 283.493 -18.9695 286.584 -48.3327 1 1 0.5 5 lb
60
212.403 -23.6057 249.493 -35.9692 286.584 -48.3327 1 1 0.5 5 lb
61
286.584 -48.3327 326.765 -79.2414 366.947 -110.15 1 0.5 1 5 lb
62
286.584 -48.3327 278.857 -111.695 271.13 -175.058 1 0.5 1 5 lb
63
438.037 -88.514 417.946 -142.604 397.855 -196.694 0.5 0.5 1 5 lb
64
438.037 -88.514 402.492 -99.332 366.947 -110.15 0.5 0.5 1 5 lb
65
397.855 -196.694 382.401 -153.422 366.947 -110.15 0.5 0.5 1 5 lb
66
366.947 -110.15 319.038 -142.604 271.13 -175.058 1 0.5 1 5 lb
67
271.13 -175.058 274.221 -213.694 277.311 -252.33 0.5 1 1 5 lb
68
271.13 -175.058 238.675 -190.512 206.221 -205.967 0.5 1 1 5 lb
69
277.311 -252.33 241.766 -229.149 206.221 -205.967 0.5 1 1 5 lb
70
-840.856 -246.718 -804.351 -66.7145 -767.847 113.289 0 0.5 0 5 lb
71
-579.033 445.603 -673.44 279.446 -767.847 113.289 0 0 0.5 5 lb
72
-579.033 445.603 -524.906 302.104 -470.779 158.605 0 0 0.5 5 lb
73
-767.847 113.289 -619.313 135.947 -470.779 158.605 0 0 0.5 5 lb
74
906.312 201.403 946.592 42.798 986.873 -115.807 0 0.5 0.5 5 lb
75
906.312 201.403 834.562 91.8901 762.812 -17.6227 0 0.5 0.5 5 lb
76
986.873 -115.807 874.842 -66.7148 762.812 -17.6227 0 0.5 0.5 5 lb
77
-470.779 158.605 -390.218 50.3508 -309.657 -57.9033 0.5 0.5 0 5 lb
78
422.945 521.129 208.955 541.269 -5.03507 561.41 0.5 0 0.5 5 lb
79
422.945 521.129 376.371 417.911 329.797 314.692 0.5 0 0.5 5 lb
80
422.945 521.129 474.554 276.928 526.164 32.7279 0.5 0 0.5 5 lb
81
-5.03507 561.41 -36.5042 440.568 -67.9734 319.727 0.5 0 0.5 5 lb
82
329.797 314.692 130.912 317.209 -67.9734 319.727 0.5 0 0.5 5 lb
83
-67.9734 319.727 229.095 176.227 526.164 32.7279 0.5 0 0.5 5 lb
84
762.812 -17.6227 644.488 7.5526 526.164 32.7279 0.5 0.5 0.5 5 lb
85
762.812 -17.6227 746.448 -162.381 730.084 -307.139 0.5 0.5 0.5 5 lb
86
526.164 32.7279 470.779 -128.394 415.393 -289.516 0.5 0.5 0.5 5 lb
87
730.084 -307.139 572.738 -298.327 415.393 -289.516 0.5 0.5 0.5 5 lb
88
415.393 -289.516 173.71 -318.468 -67.9734 -347.42 1 0.5 0.5 5 lb
89
-67.9734 -347.42 -188.815 -202.662 -309.657 -57.9033 0.5 1 0.5 5 lb
90
-67.9734 -347.42 -195.758 -390.692 -323.543 -433.964 0.5 1 0.5 5 lb
91
-309.657 -57.9033 -424.775 -160.272 -539.894 -262.64 0.5 1 0.5 5 lb
92
-323.543 -433.964 -431.719 -348.302 -539.894 -262.64 0.5 1 0.5 5 lb
93
-26.6953 -19.9585 44.8558 -96.8093 116.407 -173.66 1 1 0 5 lb
94
-26.6953 -19.9585 87.2563 9.19185 201.208 38.3422 1 1 0 5 lb
95
-26.6953 -19.9585 -144.622 43.6422 -262.548 107.243 1 0 1 5 lb
96
-26.6953 -19.9585 -20.0703 56.8923 -13.4452 133.743 1 0 1 5 lb
97
116.407 -173.66 158.808 -67.6589 201.208 38.3422 1 1 0 5 lb
98
-262.548 107.243 -137.997 120.493 -13.4452 133.743 1 0 1 5 lb
99
-262.548 107.243 -221.472 176.144 -180.397 245.045 1 0 1 5 lb
100
-13.4452 133.743 -96.9211 189.394 -180.397 245.045 1 0 1 5 lb
101
-180.397 245.045 -140.307 344.649 -132.697 451.748 0 1 1 5 lb
102
-180.397 245.045 -172.787 352.144 -132.697 451.748 0 1 1 5 lb
103
-416.25 345.746 -274.474 398.747 -132.697 451.748 0.5 0 0 5 lb
104
-416.25 345.746 -393.725 457.048 -371.2 568.349 0.5 0 0 5 lb
105
-132.697 451.748 -251.948 510.048 -371.2 568.349 0.5 0 0 5 lb
106
670.264 274.195 629.188 409.347 588.113 544.499 0 0 1 5 lb
107
670.264 274.195 797.466 341.771 924.667 409.347 0 0 1 5 lb
108
588.113 544.499 756.39 476.923 924.667 409.347 0 0 1 5 lb
109
-689.204 -237.261 -612.964 -103.444 -567.302 43.6423 0 0 0 5 lb
110
-689.204 -237.261 -643.542 -90.1744 -567.302 43.6423 0 0 0 5 lb
111
grestore
112
%Nodes:
113
gsave
114
-567.302 43.6423 20 0 0 1 nc
115
-689.204 -237.261 20 0 0 1 nc
116
924.667 409.347 20 0 0 1 nc
117
588.113 544.499 20 0 0 1 nc
118
670.264 274.195 20 1 0 0 nc
119
-371.2 568.349 20 0 0 1 nc
120
-132.697 451.748 20 1 0 0 nc
121
-416.25 345.746 20 0 0 1 nc
122
-180.397 245.045 20 1 0 0 nc
123
-13.4452 133.743 20 0 0 1 nc
124
-262.548 107.243 20 0 0 1 nc
125
201.208 38.3422 20 0 0 1 nc
126
116.407 -173.66 20 0 0 1 nc
127
-26.6953 -19.9585 20 1 0 0 nc
128
-539.894 -262.64 20 0 0 1 nc
129
-323.543 -433.964 20 0 0 1 nc
130
-309.657 -57.9033 20 1 0 0 nc
131
-67.9734 -347.42 20 1 0 0 nc
132
415.393 -289.516 20 1 0 0 nc
133
730.084 -307.139 20 0 0 1 nc
134
526.164 32.7279 20 1 0 0 nc
135
762.812 -17.6227 20 1 0 0 nc
136
-67.9734 319.727 20 0 0 1 nc
137
329.797 314.692 20 0 0 1 nc
138
-5.03507 561.41 20 0 0 1 nc
139
422.945 521.129 20 0 0 1 nc
140
-470.779 158.605 20 1 0 0 nc
141
986.873 -115.807 20 0 0 1 nc
142
906.312 201.403 20 0 0 1 nc
143
-767.847 113.289 20 1 0 0 nc
144
-579.033 445.603 20 0 0 1 nc
145
-840.856 -246.718 20 0 0 1 nc
146
206.221 -205.967 20 0 0 1 nc
147
277.311 -252.33 20 0 0 1 nc
148
271.13 -175.058 20 1 0 0 nc
149
366.947 -110.15 20 1 0 0 nc
150
397.855 -196.694 20 0 0 1 nc
151
438.037 -88.514 20 0 0 1 nc
152
286.584 -48.3327 20 1 0 0 nc
153
212.403 -23.6057 20 0 0 1 nc
154
280.402 10.3938 20 0 0 1 nc
155
694.579 115.483 20 0 0 1 nc
156
574.035 177.301 20 0 0 1 nc
157
grestore
158
grestore
159
showpage
1
%!PS-Adobe-2.0 EPSF-2.0
2
%%Creator: LEMON, graphToEps()
3
%%CreationDate: Fri Nov  4 13:47:12 2005
4
%%BoundingBox: 0 0 842 596
5
%%EndComments
6
/lb { setlinewidth setrgbcolor newpath moveto
7
      4 2 roll 1 index 1 index curveto stroke } bind def
8
/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
9
/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
10
/sq { newpath 2 index 1 index add 2 index 2 index add moveto
11
      2 index 1 index sub 2 index 2 index add lineto
12
      2 index 1 index sub 2 index 2 index sub lineto
13
      2 index 1 index add 2 index 2 index sub lineto
14
      closepath pop pop pop} bind def
15
/di { newpath 2 index 1 index add 2 index moveto
16
      2 index             2 index 2 index add lineto
17
      2 index 1 index sub 2 index             lineto
18
      2 index             2 index 2 index sub lineto
19
      closepath pop pop pop} bind def
20
/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
21
     setrgbcolor 1.1 div c fill
22
   } bind def
23
/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
24
     setrgbcolor 1.1 div sq fill
25
   } bind def
26
/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
27
     setrgbcolor 1.1 div di fill
28
   } bind def
29
/arrl 10 def
30
/arrw 3 def
31
/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
32
/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
33
       /w exch def /len exch def
34
       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
35
       len w sub arrl sub dx dy lrl
36
       arrw dy dx neg lrl
37
       dx arrl w add mul dy w 2 div arrw add mul sub
38
       dy arrl w add mul dx w 2 div arrw add mul add rlineto
39
       dx arrl w add mul neg dy w 2 div arrw add mul sub
40
       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
41
       arrw dy dx neg lrl
42
       len w sub arrl sub neg dx dy lrl
43
       closepath fill } bind def
44
/cshow { 2 index 2 index moveto dup stringwidth pop
45
         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
46

	
47
gsave
48
90 rotate
49
0 -842 translate
50
77.1122 15 translate
51
0.585745 dup scale
52
90 rotate
53
695.963 -397.916 translate
54
%Edges:
55
gsave
56
2 setlinewidth 0 0 1 setrgbcolor newpath
57
218.178 27.2723 moveto
58
192.373 -40.1551 188.622 -49.9556 169.228 -100.631 curveto stroke
59
newpath 164.939 -111.838 moveto 165.492 -99.2013 lineto 172.964 -102.061 lineto closepath fill
60
2 setlinewidth 0 0 1 setrgbcolor newpath
61
44.8044 15.5841 moveto
62
119.293 20.6059 129.775 21.3125 186.25 25.1199 curveto stroke
63
newpath 198.223 25.927 moveto 186.519 21.1289 lineto 185.981 29.1108 lineto closepath fill
64
2 setlinewidth 1 0 0 setrgbcolor newpath
65
218.178 27.2723 moveto
66
285.395 -87.4449 290.763 -96.6058 348.102 -194.464 curveto stroke
67
newpath 354.169 -204.818 moveto 344.651 -196.487 lineto 351.554 -192.442 lineto closepath fill
68
2 setlinewidth 0 0 1 setrgbcolor newpath
69
157.79 -130.517 moveto
70
108.71 -67.0521 102.27 -58.7243 64.3804 -9.72954 curveto stroke
71
newpath 57.0394 -0.236898 moveto 67.5446 -7.28254 lineto 61.2162 -12.1765 lineto closepath fill
72
2 setlinewidth 1 0 0 setrgbcolor newpath
73
-105.193 -261.035 moveto
74
-35.6576 -132.801 -30.5923 -123.459 29.5506 -12.5464 curveto stroke
75
newpath 35.2708 -1.99743 moveto 33.0669 -14.4531 lineto 26.0343 -10.6397 lineto closepath fill
76
2 setlinewidth 0 0 1 setrgbcolor newpath
77
-465.576 -42.8564 moveto
78
-559.078 -25.5413 -569.47 -23.6169 -644.498 -9.72286 curveto stroke
79
newpath -656.297 -7.5378 moveto -643.77 -5.78973 lineto -645.226 -13.656 lineto closepath fill
80
2 setlinewidth 0 0 1 setrgbcolor newpath
81
-574.666 -153.893 moveto
82
-528.842 -107.252 -521.515 -99.794 -488.002 -65.683 curveto stroke
83
newpath -479.592 -57.123 moveto -485.149 -68.4863 lineto -490.856 -62.8797 lineto closepath fill
84
2 setlinewidth 1 0 0 setrgbcolor newpath
85
-490.901 120.777 moveto
86
-480.122 51.1328 -478.519 40.7713 -470.47 -11.2329 curveto stroke
87
newpath -468.635 -23.0917 moveto -474.423 -11.8447 lineto -466.517 -10.6212 lineto closepath fill
88
2 setlinewidth 0 0 1 setrgbcolor newpath
89
-675.963 -3.89604 moveto
90
-632.116 -68.8235 -626.228 -77.5422 -592.575 -127.374 curveto stroke
91
newpath -585.859 -137.319 moveto -595.89 -129.612 lineto -589.26 -125.135 lineto closepath fill
92
2 setlinewidth 0 0 1 setrgbcolor newpath
93
-490.901 120.777 moveto
94
-435.445 215.844 -430.107 224.995 -384.3 303.522 curveto stroke
95
newpath -378.253 313.887 moveto -380.845 301.507 lineto -387.755 305.537 lineto closepath fill
96
2 setlinewidth 0 0 1 setrgbcolor newpath
97
-266.879 114.933 moveto
98
-367.067 117.547 -377.642 117.822 -458.912 119.943 curveto stroke
99
newpath -470.908 120.255 moveto -458.807 123.941 lineto -459.016 115.944 lineto closepath fill
100
2 setlinewidth 0 0 1 setrgbcolor newpath
101
-368.176 331.163 moveto
102
-322.511 233.685 -318.018 224.095 -280.454 143.911 curveto stroke
103
newpath -275.364 133.044 moveto -284.076 142.214 lineto -276.832 145.608 lineto closepath fill
104
2 setlinewidth 1 0 0 setrgbcolor newpath
105
-266.879 114.933 moveto
106
-224.004 235.52 -220.448 245.52 -184.094 347.765 curveto stroke
107
newpath -180.074 359.072 moveto -180.325 346.425 lineto -187.863 349.105 lineto closepath fill
108
2 setlinewidth 0 0 1 setrgbcolor newpath
109
-251.294 -335.059 moveto
110
-189.25 -303.624 -179.902 -298.887 -133.738 -275.498 curveto stroke
111
newpath -123.034 -270.074 moveto -131.93 -279.066 lineto -135.546 -271.93 lineto closepath fill
112
2 setlinewidth 0 0 1 setrgbcolor newpath
113
-389.604 -136.361 moveto
114
-327.15 -226.083 -321.098 -234.777 -269.576 -308.795 curveto stroke
115
newpath -262.72 -318.644 moveto -272.859 -311.081 lineto -266.293 -306.51 lineto closepath fill
116
2 setlinewidth 1 0 0 setrgbcolor newpath
117
5.84406 175.322 moveto
118
-76.0754 267.926 -83.1051 275.873 -152.172 353.948 curveto stroke
119
newpath -160.122 362.936 moveto -149.176 356.598 lineto -155.168 351.298 lineto closepath fill
120
2 setlinewidth 0 0 1 setrgbcolor newpath
121
169.478 311.683 moveto
122
96.8003 251.119 88.6819 244.353 30.4273 195.808 curveto stroke
123
newpath 21.2086 188.126 moveto 27.8666 198.881 lineto 32.988 192.735 lineto closepath fill
124
2 setlinewidth 0 0 1 setrgbcolor newpath
125
342.851 111.037 moveto
126
263.766 202.563 256.831 210.589 190.4 287.47 curveto stroke
127
newpath 182.554 296.55 moveto 193.427 290.085 lineto 187.373 284.855 lineto closepath fill
128
2 setlinewidth 0 0 1 setrgbcolor newpath
129
5.84406 175.322 moveto
130
163.16 145.314 173.605 143.321 311.418 117.033 curveto stroke
131
newpath 323.205 114.784 moveto 310.668 113.104 lineto 312.167 120.962 lineto closepath fill
132
2 setlinewidth 0 0 1 setrgbcolor newpath
133
342.851 111.037 moveto
134
497.255 2.58683 505.964 -3.53033 643.932 -100.436 curveto stroke
135
newpath 653.752 -107.334 moveto 641.633 -103.71 lineto 646.231 -97.163 lineto closepath fill
136
2 setlinewidth 0 0 1 setrgbcolor newpath
137
364.28 -222.074 moveto
138
354.298 -66.9063 353.616 -56.2971 344.905 79.1029 curveto stroke
139
newpath 344.135 91.0781 moveto 348.897 79.3597 lineto 340.914 78.8461 lineto closepath fill
140
2 setlinewidth 0 0 1 setrgbcolor newpath
141
670.118 -118.829 moveto
142
528.037 -166.793 517.967 -170.192 394.599 -211.839 curveto stroke
143
newpath 383.229 -215.677 moveto 393.32 -208.049 lineto 395.878 -215.629 lineto closepath fill
144
2 setlinewidth 1 0 0 setrgbcolor newpath
145
-105.193 -261.035 moveto
146
118.401 -242.479 129.015 -241.598 332.39 -224.721 curveto stroke
147
newpath 344.348 -223.728 moveto 332.72 -228.707 lineto 332.059 -220.734 lineto closepath fill
148
2 setlinewidth 0 0 1 setrgbcolor newpath
149
-105.193 -261.035 moveto
150
-160.867 -161.176 -166.028 -151.918 -212.336 -68.858 curveto stroke
151
newpath -218.179 -58.3769 moveto -208.842 -66.9102 lineto -215.829 -70.8058 lineto closepath fill
152
2 setlinewidth 0 0 1 setrgbcolor newpath
153
-227.918 -40.9084 moveto
154
-298.35 -82.4884 -307.42 -87.8432 -362.048 -120.093 curveto stroke
155
newpath -372.381 -126.193 moveto -364.081 -116.648 lineto -360.014 -123.537 lineto closepath fill
156
grestore
157
%Nodes:
158
gsave
159
-389.604 -136.361 20 0 1 0 nc
160
-227.918 -40.9084 20 0 1 0 nc
161
-105.193 -261.035 20 0 1 0 nc
162
364.28 -222.074 20 1 1 0 nc
163
670.118 -118.829 20 1 1 0 nc
164
342.851 111.037 20 1 1 0 nc
165
5.84406 175.322 20 1 1 0 nc
166
169.478 311.683 20 1 1 0 nc
167
-173.374 377.916 20 1 0 1 nc
168
-251.294 -335.059 20 0 1 0 nc
169
-266.879 114.933 20 0 0 0 nc
170
-368.176 331.163 20 0 0 0 nc
171
-490.901 120.777 20 0 0 0 nc
172
-574.666 -153.893 20 1 0 0 nc
173
-675.963 -3.89604 20 1 0 0 nc
174
-465.576 -42.8564 20 1 0 0 nc
175
44.8044 15.5841 20 0 0 1 nc
176
157.79 -130.517 20 0 0 1 nc
177
218.178 27.2723 20 0 0 1 nc
178
grestore
179
grestore
180
showpage
Ignore white space 24576 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2009
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
namespace lemon {
20

	
21
/**
22
\page min_cost_flow Minimum Cost Flow Problem
23

	
24
\section mcf_def Definition (GEQ form)
25

	
26
The \e minimum \e cost \e flow \e problem is to find a feasible flow of
27
minimum total cost from a set of supply nodes to a set of demand nodes
28
in a network with capacity constraints (lower and upper bounds)
29
and arc costs.
30

	
31
Formally, let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$,
32
\f$upper: A\rightarrow\mathbf{R}\cup\{+\infty\}\f$ denote the lower and
33
upper bounds for the flow values on the arcs, for which
34
\f$lower(uv) \leq upper(uv)\f$ must hold for all \f$uv\in A\f$,
35
\f$cost: A\rightarrow\mathbf{R}\f$ denotes the cost per unit flow
36
on the arcs and \f$sup: V\rightarrow\mathbf{R}\f$ denotes the
37
signed supply values of the nodes.
38
If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
39
supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
40
\f$-sup(u)\f$ demand.
41
A minimum cost flow is an \f$f: A\rightarrow\mathbf{R}\f$ solution
42
of the following optimization problem.
43

	
44
\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
45
\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \geq
46
    sup(u) \quad \forall u\in V \f]
47
\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
48

	
49
The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
50
zero or negative in order to have a feasible solution (since the sum
51
of the expressions on the left-hand side of the inequalities is zero).
52
It means that the total demand must be greater or equal to the total
53
supply and all the supplies have to be carried out from the supply nodes,
54
but there could be demands that are not satisfied.
55
If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
56
constraints have to be satisfied with equality, i.e. all demands
57
have to be satisfied and all supplies have to be used.
58

	
59

	
60
\section mcf_algs Algorithms
61

	
62
LEMON contains several algorithms for solving this problem, for more
63
information see \ref min_cost_flow_algs "Minimum Cost Flow Algorithms".
64

	
65
A feasible solution for this problem can be found using \ref Circulation.
66

	
67

	
68
\section mcf_dual Dual Solution
69

	
70
The dual solution of the minimum cost flow problem is represented by
71
node potentials \f$\pi: V\rightarrow\mathbf{R}\f$.
72
An \f$f: A\rightarrow\mathbf{R}\f$ primal feasible solution is optimal
73
if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$ node potentials
74
the following \e complementary \e slackness optimality conditions hold.
75

	
76
 - For all \f$uv\in A\f$ arcs:
77
   - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
78
   - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
79
   - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
80
 - For all \f$u\in V\f$ nodes:
81
   - \f$\pi(u)<=0\f$;
82
   - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
83
     then \f$\pi(u)=0\f$.
84
 
85
Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc
86
\f$uv\in A\f$ with respect to the potential function \f$\pi\f$, i.e.
87
\f[ cost^\pi(uv) = cost(uv) + \pi(u) - \pi(v).\f]
88

	
89
All algorithms provide dual solution (node potentials), as well,
90
if an optimal flow is found.
91

	
92

	
93
\section mcf_eq Equality Form
94

	
95
The above \ref mcf_def "definition" is actually more general than the
96
usual formulation of the minimum cost flow problem, in which strict
97
equalities are required in the supply/demand contraints.
98

	
99
\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
100
\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) =
101
    sup(u) \quad \forall u\in V \f]
102
\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
103

	
104
However if the sum of the supply values is zero, then these two problems
105
are equivalent.
106
The \ref min_cost_flow_algs "algorithms" in LEMON support the general
107
form, so if you need the equality form, you have to ensure this additional
108
contraint manually.
109

	
110

	
111
\section mcf_leq Opposite Inequalites (LEQ Form)
112

	
113
Another possible definition of the minimum cost flow problem is
114
when there are <em>"less or equal"</em> (LEQ) supply/demand constraints,
115
instead of the <em>"greater or equal"</em> (GEQ) constraints.
116

	
117
\f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
118
\f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \leq
119
    sup(u) \quad \forall u\in V \f]
120
\f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
121

	
122
It means that the total demand must be less or equal to the 
123
total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
124
positive) and all the demands have to be satisfied, but there
125
could be supplies that are not carried out from the supply
126
nodes.
127
The equality form is also a special case of this form, of course.
128

	
129
You could easily transform this case to the \ref mcf_def "GEQ form"
130
of the problem by reversing the direction of the arcs and taking the
131
negative of the supply values (e.g. using \ref ReverseDigraph and
132
\ref NegMap adaptors).
133
However \ref NetworkSimplex algorithm also supports this form directly
134
for the sake of convenience.
135

	
136
Note that the optimality conditions for this supply constraint type are
137
slightly differ from the conditions that are discussed for the GEQ form,
138
namely the potentials have to be non-negative instead of non-positive.
139
An \f$f: A\rightarrow\mathbf{R}\f$ feasible solution of this problem
140
is optimal if and only if for some \f$\pi: V\rightarrow\mathbf{R}\f$
141
node potentials the following conditions hold.
142

	
143
 - For all \f$uv\in A\f$ arcs:
144
   - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
145
   - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
146
   - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
147
 - For all \f$u\in V\f$ nodes:
148
   - \f$\pi(u)>=0\f$;
149
   - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
150
     then \f$\pi(u)=0\f$.
151

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

	
19
#ifndef LEMON_ADAPTORS_H
20
#define LEMON_ADAPTORS_H
21

	
22
/// \ingroup graph_adaptors
23
/// \file
24
/// \brief Adaptor classes for digraphs and graphs
25
///
26
/// This file contains several useful adaptors for digraphs and graphs.
27

	
28
#include <lemon/core.h>
29
#include <lemon/maps.h>
30
#include <lemon/bits/variant.h>
31

	
32
#include <lemon/bits/graph_adaptor_extender.h>
33
#include <lemon/bits/map_extender.h>
34
#include <lemon/tolerance.h>
35

	
36
#include <algorithm>
37

	
38
namespace lemon {
39

	
40
#ifdef _MSC_VER
41
#define LEMON_SCOPE_FIX(OUTER, NESTED) OUTER::NESTED
42
#else
43
#define LEMON_SCOPE_FIX(OUTER, NESTED) typename OUTER::template NESTED
44
#endif
45

	
46
  template<typename DGR>
47
  class DigraphAdaptorBase {
48
  public:
49
    typedef DGR Digraph;
50
    typedef DigraphAdaptorBase Adaptor;
51

	
52
  protected:
53
    DGR* _digraph;
54
    DigraphAdaptorBase() : _digraph(0) { }
55
    void initialize(DGR& digraph) { _digraph = &digraph; }
56

	
57
  public:
58
    DigraphAdaptorBase(DGR& digraph) : _digraph(&digraph) { }
59

	
60
    typedef typename DGR::Node Node;
61
    typedef typename DGR::Arc Arc;
62

	
63
    void first(Node& i) const { _digraph->first(i); }
64
    void first(Arc& i) const { _digraph->first(i); }
65
    void firstIn(Arc& i, const Node& n) const { _digraph->firstIn(i, n); }
66
    void firstOut(Arc& i, const Node& n ) const { _digraph->firstOut(i, n); }
67

	
68
    void next(Node& i) const { _digraph->next(i); }
69
    void next(Arc& i) const { _digraph->next(i); }
70
    void nextIn(Arc& i) const { _digraph->nextIn(i); }
71
    void nextOut(Arc& i) const { _digraph->nextOut(i); }
72

	
73
    Node source(const Arc& a) const { return _digraph->source(a); }
74
    Node target(const Arc& a) const { return _digraph->target(a); }
75

	
76
    typedef NodeNumTagIndicator<DGR> NodeNumTag;
77
    int nodeNum() const { return _digraph->nodeNum(); }
78

	
79
    typedef ArcNumTagIndicator<DGR> ArcNumTag;
80
    int arcNum() const { return _digraph->arcNum(); }
81

	
82
    typedef FindArcTagIndicator<DGR> FindArcTag;
83
    Arc findArc(const Node& u, const Node& v, const Arc& prev = INVALID) const {
84
      return _digraph->findArc(u, v, prev);
85
    }
86

	
87
    Node addNode() { return _digraph->addNode(); }
88
    Arc addArc(const Node& u, const Node& v) { return _digraph->addArc(u, v); }
89

	
90
    void erase(const Node& n) { _digraph->erase(n); }
91
    void erase(const Arc& a) { _digraph->erase(a); }
92

	
93
    void clear() { _digraph->clear(); }
94

	
95
    int id(const Node& n) const { return _digraph->id(n); }
96
    int id(const Arc& a) const { return _digraph->id(a); }
97

	
98
    Node nodeFromId(int ix) const { return _digraph->nodeFromId(ix); }
99
    Arc arcFromId(int ix) const { return _digraph->arcFromId(ix); }
100

	
101
    int maxNodeId() const { return _digraph->maxNodeId(); }
102
    int maxArcId() const { return _digraph->maxArcId(); }
103

	
104
    typedef typename ItemSetTraits<DGR, Node>::ItemNotifier NodeNotifier;
105
    NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
106

	
107
    typedef typename ItemSetTraits<DGR, Arc>::ItemNotifier ArcNotifier;
108
    ArcNotifier& notifier(Arc) const { return _digraph->notifier(Arc()); }
109

	
110
    template <typename V>
111
    class NodeMap : public DGR::template NodeMap<V> {
112
      typedef typename DGR::template NodeMap<V> Parent;
113

	
114
    public:
115
      explicit NodeMap(const Adaptor& adaptor)
116
        : Parent(*adaptor._digraph) {}
117
      NodeMap(const Adaptor& adaptor, const V& value)
118
        : Parent(*adaptor._digraph, value) { }
119

	
120
    private:
121
      NodeMap& operator=(const NodeMap& cmap) {
122
        return operator=<NodeMap>(cmap);
123
      }
124

	
125
      template <typename CMap>
126
      NodeMap& operator=(const CMap& cmap) {
127
        Parent::operator=(cmap);
128
        return *this;
129
      }
130

	
131
    };
132

	
133
    template <typename V>
134
    class ArcMap : public DGR::template ArcMap<V> {
135
      typedef typename DGR::template ArcMap<V> Parent;
136

	
137
    public:
138
      explicit ArcMap(const DigraphAdaptorBase<DGR>& adaptor)
139
        : Parent(*adaptor._digraph) {}
140
      ArcMap(const DigraphAdaptorBase<DGR>& adaptor, const V& value)
141
        : Parent(*adaptor._digraph, value) {}
142

	
143
    private:
144
      ArcMap& operator=(const ArcMap& cmap) {
145
        return operator=<ArcMap>(cmap);
146
      }
147

	
148
      template <typename CMap>
149
      ArcMap& operator=(const CMap& cmap) {
150
        Parent::operator=(cmap);
151
        return *this;
152
      }
153

	
154
    };
155

	
156
  };
157

	
158
  template<typename GR>
159
  class GraphAdaptorBase {
160
  public:
161
    typedef GR Graph;
162

	
163
  protected:
164
    GR* _graph;
165

	
166
    GraphAdaptorBase() : _graph(0) {}
167

	
168
    void initialize(GR& graph) { _graph = &graph; }
169

	
170
  public:
171
    GraphAdaptorBase(GR& graph) : _graph(&graph) {}
172

	
173
    typedef typename GR::Node Node;
174
    typedef typename GR::Arc Arc;
175
    typedef typename GR::Edge Edge;
176

	
177
    void first(Node& i) const { _graph->first(i); }
178
    void first(Arc& i) const { _graph->first(i); }
179
    void first(Edge& i) const { _graph->first(i); }
180
    void firstIn(Arc& i, const Node& n) const { _graph->firstIn(i, n); }
181
    void firstOut(Arc& i, const Node& n ) const { _graph->firstOut(i, n); }
182
    void firstInc(Edge &i, bool &d, const Node &n) const {
183
      _graph->firstInc(i, d, n);
184
    }
185

	
186
    void next(Node& i) const { _graph->next(i); }
187
    void next(Arc& i) const { _graph->next(i); }
188
    void next(Edge& i) const { _graph->next(i); }
189
    void nextIn(Arc& i) const { _graph->nextIn(i); }
190
    void nextOut(Arc& i) const { _graph->nextOut(i); }
191
    void nextInc(Edge &i, bool &d) const { _graph->nextInc(i, d); }
192

	
193
    Node u(const Edge& e) const { return _graph->u(e); }
194
    Node v(const Edge& e) const { return _graph->v(e); }
195

	
196
    Node source(const Arc& a) const { return _graph->source(a); }
197
    Node target(const Arc& a) const { return _graph->target(a); }
198

	
199
    typedef NodeNumTagIndicator<Graph> NodeNumTag;
200
    int nodeNum() const { return _graph->nodeNum(); }
201

	
202
    typedef ArcNumTagIndicator<Graph> ArcNumTag;
203
    int arcNum() const { return _graph->arcNum(); }
204

	
205
    typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
206
    int edgeNum() const { return _graph->edgeNum(); }
207

	
208
    typedef FindArcTagIndicator<Graph> FindArcTag;
209
    Arc findArc(const Node& u, const Node& v,
210
                const Arc& prev = INVALID) const {
211
      return _graph->findArc(u, v, prev);
212
    }
213

	
214
    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
215
    Edge findEdge(const Node& u, const Node& v,
216
                  const Edge& prev = INVALID) const {
217
      return _graph->findEdge(u, v, prev);
218
    }
219

	
220
    Node addNode() { return _graph->addNode(); }
221
    Edge addEdge(const Node& u, const Node& v) { return _graph->addEdge(u, v); }
222

	
223
    void erase(const Node& i) { _graph->erase(i); }
224
    void erase(const Edge& i) { _graph->erase(i); }
225

	
226
    void clear() { _graph->clear(); }
227

	
228
    bool direction(const Arc& a) const { return _graph->direction(a); }
229
    Arc direct(const Edge& e, bool d) const { return _graph->direct(e, d); }
230

	
231
    int id(const Node& v) const { return _graph->id(v); }
232
    int id(const Arc& a) const { return _graph->id(a); }
233
    int id(const Edge& e) const { return _graph->id(e); }
234

	
235
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
236
    Arc arcFromId(int ix) const { return _graph->arcFromId(ix); }
237
    Edge edgeFromId(int ix) const { return _graph->edgeFromId(ix); }
238

	
239
    int maxNodeId() const { return _graph->maxNodeId(); }
240
    int maxArcId() const { return _graph->maxArcId(); }
241
    int maxEdgeId() const { return _graph->maxEdgeId(); }
242

	
243
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
244
    NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
245

	
246
    typedef typename ItemSetTraits<GR, Arc>::ItemNotifier ArcNotifier;
247
    ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
248

	
249
    typedef typename ItemSetTraits<GR, Edge>::ItemNotifier EdgeNotifier;
250
    EdgeNotifier& notifier(Edge) const { return _graph->notifier(Edge()); }
251

	
252
    template <typename V>
253
    class NodeMap : public GR::template NodeMap<V> {
254
      typedef typename GR::template NodeMap<V> Parent;
255

	
256
    public:
257
      explicit NodeMap(const GraphAdaptorBase<GR>& adapter)
258
        : Parent(*adapter._graph) {}
259
      NodeMap(const GraphAdaptorBase<GR>& adapter, const V& value)
260
        : Parent(*adapter._graph, value) {}
261

	
262
    private:
263
      NodeMap& operator=(const NodeMap& cmap) {
264
        return operator=<NodeMap>(cmap);
265
      }
266

	
267
      template <typename CMap>
268
      NodeMap& operator=(const CMap& cmap) {
269
        Parent::operator=(cmap);
270
        return *this;
271
      }
272

	
273
    };
274

	
275
    template <typename V>
276
    class ArcMap : public GR::template ArcMap<V> {
277
      typedef typename GR::template ArcMap<V> Parent;
278

	
279
    public:
280
      explicit ArcMap(const GraphAdaptorBase<GR>& adapter)
281
        : Parent(*adapter._graph) {}
282
      ArcMap(const GraphAdaptorBase<GR>& adapter, const V& value)
283
        : Parent(*adapter._graph, value) {}
284

	
285
    private:
286
      ArcMap& operator=(const ArcMap& cmap) {
287
        return operator=<ArcMap>(cmap);
288
      }
289

	
290
      template <typename CMap>
291
      ArcMap& operator=(const CMap& cmap) {
292
        Parent::operator=(cmap);
293
        return *this;
294
      }
295
    };
296

	
297
    template <typename V>
298
    class EdgeMap : public GR::template EdgeMap<V> {
299
      typedef typename GR::template EdgeMap<V> Parent;
300

	
301
    public:
302
      explicit EdgeMap(const GraphAdaptorBase<GR>& adapter)
303
        : Parent(*adapter._graph) {}
304
      EdgeMap(const GraphAdaptorBase<GR>& adapter, const V& value)
305
        : Parent(*adapter._graph, value) {}
306

	
307
    private:
308
      EdgeMap& operator=(const EdgeMap& cmap) {
309
        return operator=<EdgeMap>(cmap);
310
      }
311

	
312
      template <typename CMap>
313
      EdgeMap& operator=(const CMap& cmap) {
314
        Parent::operator=(cmap);
315
        return *this;
316
      }
317
    };
318

	
319
  };
320

	
321
  template <typename DGR>
322
  class ReverseDigraphBase : public DigraphAdaptorBase<DGR> {
323
    typedef DigraphAdaptorBase<DGR> Parent;
324
  public:
325
    typedef DGR Digraph;
326
  protected:
327
    ReverseDigraphBase() : Parent() { }
328
  public:
329
    typedef typename Parent::Node Node;
330
    typedef typename Parent::Arc Arc;
331

	
332
    void firstIn(Arc& a, const Node& n) const { Parent::firstOut(a, n); }
333
    void firstOut(Arc& a, const Node& n ) const { Parent::firstIn(a, n); }
334

	
335
    void nextIn(Arc& a) const { Parent::nextOut(a); }
336
    void nextOut(Arc& a) const { Parent::nextIn(a); }
337

	
338
    Node source(const Arc& a) const { return Parent::target(a); }
339
    Node target(const Arc& a) const { return Parent::source(a); }
340

	
341
    Arc addArc(const Node& u, const Node& v) { return Parent::addArc(v, u); }
342

	
343
    typedef FindArcTagIndicator<DGR> FindArcTag;
344
    Arc findArc(const Node& u, const Node& v,
345
                const Arc& prev = INVALID) const {
346
      return Parent::findArc(v, u, prev);
347
    }
348

	
349
  };
350

	
351
  /// \ingroup graph_adaptors
352
  ///
353
  /// \brief Adaptor class for reversing the orientation of the arcs in
354
  /// a digraph.
355
  ///
356
  /// ReverseDigraph can be used for reversing the arcs in a digraph.
357
  /// It conforms to the \ref concepts::Digraph "Digraph" concept.
358
  ///
359
  /// The adapted digraph can also be modified through this adaptor
360
  /// by adding or removing nodes or arcs, unless the \c GR template
361
  /// parameter is set to be \c const.
362
  ///
363
  /// \tparam DGR The type of the adapted digraph.
364
  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
365
  /// It can also be specified to be \c const.
366
  ///
367
  /// \note The \c Node and \c Arc types of this adaptor and the adapted
368
  /// digraph are convertible to each other.
369
  template<typename DGR>
370
#ifdef DOXYGEN
371
  class ReverseDigraph {
372
#else
373
  class ReverseDigraph :
374
    public DigraphAdaptorExtender<ReverseDigraphBase<DGR> > {
375
#endif
376
    typedef DigraphAdaptorExtender<ReverseDigraphBase<DGR> > Parent;
377
  public:
378
    /// The type of the adapted digraph.
379
    typedef DGR Digraph;
380
  protected:
381
    ReverseDigraph() { }
382
  public:
383

	
384
    /// \brief Constructor
385
    ///
386
    /// Creates a reverse digraph adaptor for the given digraph.
387
    explicit ReverseDigraph(DGR& digraph) {
388
      Parent::initialize(digraph);
389
    }
390
  };
391

	
392
  /// \brief Returns a read-only ReverseDigraph adaptor
393
  ///
394
  /// This function just returns a read-only \ref ReverseDigraph adaptor.
395
  /// \ingroup graph_adaptors
396
  /// \relates ReverseDigraph
397
  template<typename DGR>
398
  ReverseDigraph<const DGR> reverseDigraph(const DGR& digraph) {
399
    return ReverseDigraph<const DGR>(digraph);
400
  }
401

	
402

	
403
  template <typename DGR, typename NF, typename AF, bool ch = true>
404
  class SubDigraphBase : public DigraphAdaptorBase<DGR> {
405
    typedef DigraphAdaptorBase<DGR> Parent;
406
  public:
407
    typedef DGR Digraph;
408
    typedef NF NodeFilterMap;
409
    typedef AF ArcFilterMap;
410

	
411
    typedef SubDigraphBase Adaptor;
412
  protected:
413
    NF* _node_filter;
414
    AF* _arc_filter;
415
    SubDigraphBase()
416
      : Parent(), _node_filter(0), _arc_filter(0) { }
417

	
418
    void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
419
      Parent::initialize(digraph);
420
      _node_filter = &node_filter;
421
      _arc_filter = &arc_filter;      
422
    }
423

	
424
  public:
425

	
426
    typedef typename Parent::Node Node;
427
    typedef typename Parent::Arc Arc;
428

	
429
    void first(Node& i) const {
430
      Parent::first(i);
431
      while (i != INVALID && !(*_node_filter)[i]) Parent::next(i);
432
    }
433

	
434
    void first(Arc& i) const {
435
      Parent::first(i);
436
      while (i != INVALID && (!(*_arc_filter)[i]
437
                              || !(*_node_filter)[Parent::source(i)]
438
                              || !(*_node_filter)[Parent::target(i)]))
439
        Parent::next(i);
440
    }
441

	
442
    void firstIn(Arc& i, const Node& n) const {
443
      Parent::firstIn(i, n);
444
      while (i != INVALID && (!(*_arc_filter)[i]
445
                              || !(*_node_filter)[Parent::source(i)]))
446
        Parent::nextIn(i);
447
    }
448

	
449
    void firstOut(Arc& i, const Node& n) const {
450
      Parent::firstOut(i, n);
451
      while (i != INVALID && (!(*_arc_filter)[i]
452
                              || !(*_node_filter)[Parent::target(i)]))
453
        Parent::nextOut(i);
454
    }
455

	
456
    void next(Node& i) const {
457
      Parent::next(i);
458
      while (i != INVALID && !(*_node_filter)[i]) Parent::next(i);
459
    }
460

	
461
    void next(Arc& i) const {
462
      Parent::next(i);
463
      while (i != INVALID && (!(*_arc_filter)[i]
464
                              || !(*_node_filter)[Parent::source(i)]
465
                              || !(*_node_filter)[Parent::target(i)]))
466
        Parent::next(i);
467
    }
468

	
469
    void nextIn(Arc& i) const {
470
      Parent::nextIn(i);
471
      while (i != INVALID && (!(*_arc_filter)[i]
472
                              || !(*_node_filter)[Parent::source(i)]))
473
        Parent::nextIn(i);
474
    }
475

	
476
    void nextOut(Arc& i) const {
477
      Parent::nextOut(i);
478
      while (i != INVALID && (!(*_arc_filter)[i]
479
                              || !(*_node_filter)[Parent::target(i)]))
480
        Parent::nextOut(i);
481
    }
482

	
483
    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
484
    void status(const Arc& a, bool v) const { _arc_filter->set(a, v); }
485

	
486
    bool status(const Node& n) const { return (*_node_filter)[n]; }
487
    bool status(const Arc& a) const { return (*_arc_filter)[a]; }
488

	
489
    typedef False NodeNumTag;
490
    typedef False ArcNumTag;
491

	
492
    typedef FindArcTagIndicator<DGR> FindArcTag;
493
    Arc findArc(const Node& source, const Node& target,
494
                const Arc& prev = INVALID) const {
495
      if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
496
        return INVALID;
497
      }
498
      Arc arc = Parent::findArc(source, target, prev);
499
      while (arc != INVALID && !(*_arc_filter)[arc]) {
500
        arc = Parent::findArc(source, target, arc);
501
      }
502
      return arc;
503
    }
504

	
505
  public:
506

	
507
    template <typename V>
508
    class NodeMap 
509
      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>, 
510
	      LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
511
      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
512
	LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
513

	
514
    public:
515
      typedef V Value;
516

	
517
      NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
518
        : Parent(adaptor) {}
519
      NodeMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor, const V& value)
520
        : Parent(adaptor, value) {}
521

	
522
    private:
523
      NodeMap& operator=(const NodeMap& cmap) {
524
        return operator=<NodeMap>(cmap);
525
      }
526

	
527
      template <typename CMap>
528
      NodeMap& operator=(const CMap& cmap) {
529
        Parent::operator=(cmap);
530
        return *this;
531
      }
532
    };
533

	
534
    template <typename V>
535
    class ArcMap 
536
      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
537
	      LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
538
      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, ch>,
539
        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
540

	
541
    public:
542
      typedef V Value;
543

	
544
      ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor)
545
        : Parent(adaptor) {}
546
      ArcMap(const SubDigraphBase<DGR, NF, AF, ch>& adaptor, const V& value)
547
        : Parent(adaptor, value) {}
548

	
549
    private:
550
      ArcMap& operator=(const ArcMap& cmap) {
551
        return operator=<ArcMap>(cmap);
552
      }
553

	
554
      template <typename CMap>
555
      ArcMap& operator=(const CMap& cmap) {
556
        Parent::operator=(cmap);
557
        return *this;
558
      }
559
    };
560

	
561
  };
562

	
563
  template <typename DGR, typename NF, typename AF>
564
  class SubDigraphBase<DGR, NF, AF, false>
565
    : public DigraphAdaptorBase<DGR> {
566
    typedef DigraphAdaptorBase<DGR> Parent;
567
  public:
568
    typedef DGR Digraph;
569
    typedef NF NodeFilterMap;
570
    typedef AF ArcFilterMap;
571

	
572
    typedef SubDigraphBase Adaptor;
573
  protected:
574
    NF* _node_filter;
575
    AF* _arc_filter;
576
    SubDigraphBase()
577
      : Parent(), _node_filter(0), _arc_filter(0) { }
578

	
579
    void initialize(DGR& digraph, NF& node_filter, AF& arc_filter) {
580
      Parent::initialize(digraph);
581
      _node_filter = &node_filter;
582
      _arc_filter = &arc_filter;      
583
    }
584

	
585
  public:
586

	
587
    typedef typename Parent::Node Node;
588
    typedef typename Parent::Arc Arc;
589

	
590
    void first(Node& i) const {
591
      Parent::first(i);
592
      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
593
    }
594

	
595
    void first(Arc& i) const {
596
      Parent::first(i);
597
      while (i!=INVALID && !(*_arc_filter)[i]) Parent::next(i);
598
    }
599

	
600
    void firstIn(Arc& i, const Node& n) const {
601
      Parent::firstIn(i, n);
602
      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextIn(i);
603
    }
604

	
605
    void firstOut(Arc& i, const Node& n) const {
606
      Parent::firstOut(i, n);
607
      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextOut(i);
608
    }
609

	
610
    void next(Node& i) const {
611
      Parent::next(i);
612
      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
613
    }
614
    void next(Arc& i) const {
615
      Parent::next(i);
616
      while (i!=INVALID && !(*_arc_filter)[i]) Parent::next(i);
617
    }
618
    void nextIn(Arc& i) const {
619
      Parent::nextIn(i);
620
      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextIn(i);
621
    }
622

	
623
    void nextOut(Arc& i) const {
624
      Parent::nextOut(i);
625
      while (i!=INVALID && !(*_arc_filter)[i]) Parent::nextOut(i);
626
    }
627

	
628
    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
629
    void status(const Arc& a, bool v) const { _arc_filter->set(a, v); }
630

	
631
    bool status(const Node& n) const { return (*_node_filter)[n]; }
632
    bool status(const Arc& a) const { return (*_arc_filter)[a]; }
633

	
634
    typedef False NodeNumTag;
635
    typedef False ArcNumTag;
636

	
637
    typedef FindArcTagIndicator<DGR> FindArcTag;
638
    Arc findArc(const Node& source, const Node& target,
639
                const Arc& prev = INVALID) const {
640
      if (!(*_node_filter)[source] || !(*_node_filter)[target]) {
641
        return INVALID;
642
      }
643
      Arc arc = Parent::findArc(source, target, prev);
644
      while (arc != INVALID && !(*_arc_filter)[arc]) {
645
        arc = Parent::findArc(source, target, arc);
646
      }
647
      return arc;
648
    }
649

	
650
    template <typename V>
651
    class NodeMap 
652
      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
653
          LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> {
654
      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>, 
655
        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, NodeMap<V>)> Parent;
656

	
657
    public:
658
      typedef V Value;
659

	
660
      NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
661
        : Parent(adaptor) {}
662
      NodeMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor, const V& value)
663
        : Parent(adaptor, value) {}
664

	
665
    private:
666
      NodeMap& operator=(const NodeMap& cmap) {
667
        return operator=<NodeMap>(cmap);
668
      }
669

	
670
      template <typename CMap>
671
      NodeMap& operator=(const CMap& cmap) {
672
        Parent::operator=(cmap);
673
        return *this;
674
      }
675
    };
676

	
677
    template <typename V>
678
    class ArcMap 
679
      : public SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
680
          LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> {
681
      typedef SubMapExtender<SubDigraphBase<DGR, NF, AF, false>,
682
        LEMON_SCOPE_FIX(DigraphAdaptorBase<DGR>, ArcMap<V>)> Parent;
683

	
684
    public:
685
      typedef V Value;
686

	
687
      ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor)
688
        : Parent(adaptor) {}
689
      ArcMap(const SubDigraphBase<DGR, NF, AF, false>& adaptor, const V& value)
690
        : Parent(adaptor, value) {}
691

	
692
    private:
693
      ArcMap& operator=(const ArcMap& cmap) {
694
        return operator=<ArcMap>(cmap);
695
      }
696

	
697
      template <typename CMap>
698
      ArcMap& operator=(const CMap& cmap) {
699
        Parent::operator=(cmap);
700
        return *this;
701
      }
702
    };
703

	
704
  };
705

	
706
  /// \ingroup graph_adaptors
707
  ///
708
  /// \brief Adaptor class for hiding nodes and arcs in a digraph
709
  ///
710
  /// SubDigraph can be used for hiding nodes and arcs in a digraph.
711
  /// A \c bool node map and a \c bool arc map must be specified, which
712
  /// define the filters for nodes and arcs.
713
  /// Only the nodes and arcs with \c true filter value are
714
  /// shown in the subdigraph. The arcs that are incident to hidden
715
  /// nodes are also filtered out.
716
  /// This adaptor conforms to the \ref concepts::Digraph "Digraph" concept.
717
  ///
718
  /// The adapted digraph can also be modified through this adaptor
719
  /// by adding or removing nodes or arcs, unless the \c GR template
720
  /// parameter is set to be \c const.
721
  ///
722
  /// \tparam DGR The type of the adapted digraph.
723
  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
724
  /// It can also be specified to be \c const.
725
  /// \tparam NF The type of the node filter map.
726
  /// It must be a \c bool (or convertible) node map of the
727
  /// adapted digraph. The default type is
728
  /// \ref concepts::Digraph::NodeMap "DGR::NodeMap<bool>".
729
  /// \tparam AF The type of the arc filter map.
730
  /// It must be \c bool (or convertible) arc map of the
731
  /// adapted digraph. The default type is
732
  /// \ref concepts::Digraph::ArcMap "DGR::ArcMap<bool>".
733
  ///
734
  /// \note The \c Node and \c Arc types of this adaptor and the adapted
735
  /// digraph are convertible to each other.
736
  ///
737
  /// \see FilterNodes
738
  /// \see FilterArcs
739
#ifdef DOXYGEN
740
  template<typename DGR, typename NF, typename AF>
741
  class SubDigraph {
742
#else
743
  template<typename DGR,
744
           typename NF = typename DGR::template NodeMap<bool>,
745
           typename AF = typename DGR::template ArcMap<bool> >
746
  class SubDigraph :
747
    public DigraphAdaptorExtender<SubDigraphBase<DGR, NF, AF, true> > {
748
#endif
749
  public:
750
    /// The type of the adapted digraph.
751
    typedef DGR Digraph;
752
    /// The type of the node filter map.
753
    typedef NF NodeFilterMap;
754
    /// The type of the arc filter map.
755
    typedef AF ArcFilterMap;
756

	
757
    typedef DigraphAdaptorExtender<SubDigraphBase<DGR, NF, AF, true> >
758
      Parent;
759

	
760
    typedef typename Parent::Node Node;
761
    typedef typename Parent::Arc Arc;
762

	
763
  protected:
764
    SubDigraph() { }
765
  public:
766

	
767
    /// \brief Constructor
768
    ///
769
    /// Creates a subdigraph for the given digraph with the
770
    /// given node and arc filter maps.
771
    SubDigraph(DGR& digraph, NF& node_filter, AF& arc_filter) {
772
      Parent::initialize(digraph, node_filter, arc_filter);
773
    }
774

	
775
    /// \brief Sets the status of the given node
776
    ///
777
    /// This function sets the status of the given node.
778
    /// It is done by simply setting the assigned value of \c n
779
    /// to \c v in the node filter map.
780
    void status(const Node& n, bool v) const { Parent::status(n, v); }
781

	
782
    /// \brief Sets the status of the given arc
783
    ///
784
    /// This function sets the status of the given arc.
785
    /// It is done by simply setting the assigned value of \c a
786
    /// to \c v in the arc filter map.
787
    void status(const Arc& a, bool v) const { Parent::status(a, v); }
788

	
789
    /// \brief Returns the status of the given node
790
    ///
791
    /// This function returns the status of the given node.
792
    /// It is \c true if the given node is enabled (i.e. not hidden).
793
    bool status(const Node& n) const { return Parent::status(n); }
794

	
795
    /// \brief Returns the status of the given arc
796
    ///
797
    /// This function returns the status of the given arc.
798
    /// It is \c true if the given arc is enabled (i.e. not hidden).
799
    bool status(const Arc& a) const { return Parent::status(a); }
800

	
801
    /// \brief Disables the given node
802
    ///
803
    /// This function disables the given node in the subdigraph,
804
    /// so the iteration jumps over it.
805
    /// It is the same as \ref status() "status(n, false)".
806
    void disable(const Node& n) const { Parent::status(n, false); }
807

	
808
    /// \brief Disables the given arc
809
    ///
810
    /// This function disables the given arc in the subdigraph,
811
    /// so the iteration jumps over it.
812
    /// It is the same as \ref status() "status(a, false)".
813
    void disable(const Arc& a) const { Parent::status(a, false); }
814

	
815
    /// \brief Enables the given node
816
    ///
817
    /// This function enables the given node in the subdigraph.
818
    /// It is the same as \ref status() "status(n, true)".
819
    void enable(const Node& n) const { Parent::status(n, true); }
820

	
821
    /// \brief Enables the given arc
822
    ///
823
    /// This function enables the given arc in the subdigraph.
824
    /// It is the same as \ref status() "status(a, true)".
825
    void enable(const Arc& a) const { Parent::status(a, true); }
826

	
827
  };
828

	
829
  /// \brief Returns a read-only SubDigraph adaptor
830
  ///
831
  /// This function just returns a read-only \ref SubDigraph adaptor.
832
  /// \ingroup graph_adaptors
833
  /// \relates SubDigraph
834
  template<typename DGR, typename NF, typename AF>
835
  SubDigraph<const DGR, NF, AF>
836
  subDigraph(const DGR& digraph,
837
             NF& node_filter, AF& arc_filter) {
838
    return SubDigraph<const DGR, NF, AF>
839
      (digraph, node_filter, arc_filter);
840
  }
841

	
842
  template<typename DGR, typename NF, typename AF>
843
  SubDigraph<const DGR, const NF, AF>
844
  subDigraph(const DGR& digraph,
845
             const NF& node_filter, AF& arc_filter) {
846
    return SubDigraph<const DGR, const NF, AF>
847
      (digraph, node_filter, arc_filter);
848
  }
849

	
850
  template<typename DGR, typename NF, typename AF>
851
  SubDigraph<const DGR, NF, const AF>
852
  subDigraph(const DGR& digraph,
853
             NF& node_filter, const AF& arc_filter) {
854
    return SubDigraph<const DGR, NF, const AF>
855
      (digraph, node_filter, arc_filter);
856
  }
857

	
858
  template<typename DGR, typename NF, typename AF>
859
  SubDigraph<const DGR, const NF, const AF>
860
  subDigraph(const DGR& digraph,
861
             const NF& node_filter, const AF& arc_filter) {
862
    return SubDigraph<const DGR, const NF, const AF>
863
      (digraph, node_filter, arc_filter);
864
  }
865

	
866

	
867
  template <typename GR, typename NF, typename EF, bool ch = true>
868
  class SubGraphBase : public GraphAdaptorBase<GR> {
869
    typedef GraphAdaptorBase<GR> Parent;
870
  public:
871
    typedef GR Graph;
872
    typedef NF NodeFilterMap;
873
    typedef EF EdgeFilterMap;
874

	
875
    typedef SubGraphBase Adaptor;
876
  protected:
877

	
878
    NF* _node_filter;
879
    EF* _edge_filter;
880

	
881
    SubGraphBase()
882
      : Parent(), _node_filter(0), _edge_filter(0) { }
883

	
884
    void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
885
      Parent::initialize(graph);
886
      _node_filter = &node_filter;
887
      _edge_filter = &edge_filter;
888
    }
889

	
890
  public:
891

	
892
    typedef typename Parent::Node Node;
893
    typedef typename Parent::Arc Arc;
894
    typedef typename Parent::Edge Edge;
895

	
896
    void first(Node& i) const {
897
      Parent::first(i);
898
      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
899
    }
900

	
901
    void first(Arc& i) const {
902
      Parent::first(i);
903
      while (i!=INVALID && (!(*_edge_filter)[i]
904
                            || !(*_node_filter)[Parent::source(i)]
905
                            || !(*_node_filter)[Parent::target(i)]))
906
        Parent::next(i);
907
    }
908

	
909
    void first(Edge& i) const {
910
      Parent::first(i);
911
      while (i!=INVALID && (!(*_edge_filter)[i]
912
                            || !(*_node_filter)[Parent::u(i)]
913
                            || !(*_node_filter)[Parent::v(i)]))
914
        Parent::next(i);
915
    }
916

	
917
    void firstIn(Arc& i, const Node& n) const {
918
      Parent::firstIn(i, n);
919
      while (i!=INVALID && (!(*_edge_filter)[i]
920
                            || !(*_node_filter)[Parent::source(i)]))
921
        Parent::nextIn(i);
922
    }
923

	
924
    void firstOut(Arc& i, const Node& n) const {
925
      Parent::firstOut(i, n);
926
      while (i!=INVALID && (!(*_edge_filter)[i]
927
                            || !(*_node_filter)[Parent::target(i)]))
928
        Parent::nextOut(i);
929
    }
930

	
931
    void firstInc(Edge& i, bool& d, const Node& n) const {
932
      Parent::firstInc(i, d, n);
933
      while (i!=INVALID && (!(*_edge_filter)[i]
934
                            || !(*_node_filter)[Parent::u(i)]
935
                            || !(*_node_filter)[Parent::v(i)]))
936
        Parent::nextInc(i, d);
937
    }
938

	
939
    void next(Node& i) const {
940
      Parent::next(i);
941
      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
942
    }
943

	
944
    void next(Arc& i) const {
945
      Parent::next(i);
946
      while (i!=INVALID && (!(*_edge_filter)[i]
947
                            || !(*_node_filter)[Parent::source(i)]
948
                            || !(*_node_filter)[Parent::target(i)]))
949
        Parent::next(i);
950
    }
951

	
952
    void next(Edge& i) const {
953
      Parent::next(i);
954
      while (i!=INVALID && (!(*_edge_filter)[i]
955
                            || !(*_node_filter)[Parent::u(i)]
956
                            || !(*_node_filter)[Parent::v(i)]))
957
        Parent::next(i);
958
    }
959

	
960
    void nextIn(Arc& i) const {
961
      Parent::nextIn(i);
962
      while (i!=INVALID && (!(*_edge_filter)[i]
963
                            || !(*_node_filter)[Parent::source(i)]))
964
        Parent::nextIn(i);
965
    }
966

	
967
    void nextOut(Arc& i) const {
968
      Parent::nextOut(i);
969
      while (i!=INVALID && (!(*_edge_filter)[i]
970
                            || !(*_node_filter)[Parent::target(i)]))
971
        Parent::nextOut(i);
972
    }
973

	
974
    void nextInc(Edge& i, bool& d) const {
975
      Parent::nextInc(i, d);
976
      while (i!=INVALID && (!(*_edge_filter)[i]
977
                            || !(*_node_filter)[Parent::u(i)]
978
                            || !(*_node_filter)[Parent::v(i)]))
979
        Parent::nextInc(i, d);
980
    }
981

	
982
    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
983
    void status(const Edge& e, bool v) const { _edge_filter->set(e, v); }
984

	
985
    bool status(const Node& n) const { return (*_node_filter)[n]; }
986
    bool status(const Edge& e) const { return (*_edge_filter)[e]; }
987

	
988
    typedef False NodeNumTag;
989
    typedef False ArcNumTag;
990
    typedef False EdgeNumTag;
991

	
992
    typedef FindArcTagIndicator<Graph> FindArcTag;
993
    Arc findArc(const Node& u, const Node& v,
994
                const Arc& prev = INVALID) const {
995
      if (!(*_node_filter)[u] || !(*_node_filter)[v]) {
996
        return INVALID;
997
      }
998
      Arc arc = Parent::findArc(u, v, prev);
999
      while (arc != INVALID && !(*_edge_filter)[arc]) {
1000
        arc = Parent::findArc(u, v, arc);
1001
      }
1002
      return arc;
1003
    }
1004

	
1005
    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
1006
    Edge findEdge(const Node& u, const Node& v,
1007
                  const Edge& prev = INVALID) const {
1008
      if (!(*_node_filter)[u] || !(*_node_filter)[v]) {
1009
        return INVALID;
1010
      }
1011
      Edge edge = Parent::findEdge(u, v, prev);
1012
      while (edge != INVALID && !(*_edge_filter)[edge]) {
1013
        edge = Parent::findEdge(u, v, edge);
1014
      }
1015
      return edge;
1016
    }
1017

	
1018
    template <typename V>
1019
    class NodeMap 
1020
      : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
1021
          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
1022
      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
1023
        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
1024

	
1025
    public:
1026
      typedef V Value;
1027

	
1028
      NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
1029
        : Parent(adaptor) {}
1030
      NodeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
1031
        : Parent(adaptor, value) {}
1032

	
1033
    private:
1034
      NodeMap& operator=(const NodeMap& cmap) {
1035
        return operator=<NodeMap>(cmap);
1036
      }
1037

	
1038
      template <typename CMap>
1039
      NodeMap& operator=(const CMap& cmap) {
1040
        Parent::operator=(cmap);
1041
        return *this;
1042
      }
1043
    };
1044

	
1045
    template <typename V>
1046
    class ArcMap 
1047
      : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
1048
          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
1049
      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
1050
        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
1051

	
1052
    public:
1053
      typedef V Value;
1054

	
1055
      ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
1056
        : Parent(adaptor) {}
1057
      ArcMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
1058
        : Parent(adaptor, value) {}
1059

	
1060
    private:
1061
      ArcMap& operator=(const ArcMap& cmap) {
1062
        return operator=<ArcMap>(cmap);
1063
      }
1064

	
1065
      template <typename CMap>
1066
      ArcMap& operator=(const CMap& cmap) {
1067
        Parent::operator=(cmap);
1068
        return *this;
1069
      }
1070
    };
1071

	
1072
    template <typename V>
1073
    class EdgeMap 
1074
      : public SubMapExtender<SubGraphBase<GR, NF, EF, ch>,
1075
        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
1076
      typedef SubMapExtender<SubGraphBase<GR, NF, EF, ch>, 
1077
        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
1078

	
1079
    public:
1080
      typedef V Value;
1081

	
1082
      EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor)
1083
        : Parent(adaptor) {}
1084

	
1085
      EdgeMap(const SubGraphBase<GR, NF, EF, ch>& adaptor, const V& value)
1086
        : Parent(adaptor, value) {}
1087

	
1088
    private:
1089
      EdgeMap& operator=(const EdgeMap& cmap) {
1090
        return operator=<EdgeMap>(cmap);
1091
      }
1092

	
1093
      template <typename CMap>
1094
      EdgeMap& operator=(const CMap& cmap) {
1095
        Parent::operator=(cmap);
1096
        return *this;
1097
      }
1098
    };
1099

	
1100
  };
1101

	
1102
  template <typename GR, typename NF, typename EF>
1103
  class SubGraphBase<GR, NF, EF, false>
1104
    : public GraphAdaptorBase<GR> {
1105
    typedef GraphAdaptorBase<GR> Parent;
1106
  public:
1107
    typedef GR Graph;
1108
    typedef NF NodeFilterMap;
1109
    typedef EF EdgeFilterMap;
1110

	
1111
    typedef SubGraphBase Adaptor;
1112
  protected:
1113
    NF* _node_filter;
1114
    EF* _edge_filter;
1115
    SubGraphBase() 
1116
	  : Parent(), _node_filter(0), _edge_filter(0) { }
1117

	
1118
    void initialize(GR& graph, NF& node_filter, EF& edge_filter) {
1119
      Parent::initialize(graph);
1120
      _node_filter = &node_filter;
1121
      _edge_filter = &edge_filter;
1122
    }
1123

	
1124
  public:
1125

	
1126
    typedef typename Parent::Node Node;
1127
    typedef typename Parent::Arc Arc;
1128
    typedef typename Parent::Edge Edge;
1129

	
1130
    void first(Node& i) const {
1131
      Parent::first(i);
1132
      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
1133
    }
1134

	
1135
    void first(Arc& i) const {
1136
      Parent::first(i);
1137
      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
1138
    }
1139

	
1140
    void first(Edge& i) const {
1141
      Parent::first(i);
1142
      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
1143
    }
1144

	
1145
    void firstIn(Arc& i, const Node& n) const {
1146
      Parent::firstIn(i, n);
1147
      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextIn(i);
1148
    }
1149

	
1150
    void firstOut(Arc& i, const Node& n) const {
1151
      Parent::firstOut(i, n);
1152
      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextOut(i);
1153
    }
1154

	
1155
    void firstInc(Edge& i, bool& d, const Node& n) const {
1156
      Parent::firstInc(i, d, n);
1157
      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d);
1158
    }
1159

	
1160
    void next(Node& i) const {
1161
      Parent::next(i);
1162
      while (i!=INVALID && !(*_node_filter)[i]) Parent::next(i);
1163
    }
1164
    void next(Arc& i) const {
1165
      Parent::next(i);
1166
      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
1167
    }
1168
    void next(Edge& i) const {
1169
      Parent::next(i);
1170
      while (i!=INVALID && !(*_edge_filter)[i]) Parent::next(i);
1171
    }
1172
    void nextIn(Arc& i) const {
1173
      Parent::nextIn(i);
1174
      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextIn(i);
1175
    }
1176

	
1177
    void nextOut(Arc& i) const {
1178
      Parent::nextOut(i);
1179
      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextOut(i);
1180
    }
1181
    void nextInc(Edge& i, bool& d) const {
1182
      Parent::nextInc(i, d);
1183
      while (i!=INVALID && !(*_edge_filter)[i]) Parent::nextInc(i, d);
1184
    }
1185

	
1186
    void status(const Node& n, bool v) const { _node_filter->set(n, v); }
1187
    void status(const Edge& e, bool v) const { _edge_filter->set(e, v); }
1188

	
1189
    bool status(const Node& n) const { return (*_node_filter)[n]; }
1190
    bool status(const Edge& e) const { return (*_edge_filter)[e]; }
1191

	
1192
    typedef False NodeNumTag;
1193
    typedef False ArcNumTag;
1194
    typedef False EdgeNumTag;
1195

	
1196
    typedef FindArcTagIndicator<Graph> FindArcTag;
1197
    Arc findArc(const Node& u, const Node& v,
1198
                const Arc& prev = INVALID) const {
1199
      Arc arc = Parent::findArc(u, v, prev);
1200
      while (arc != INVALID && !(*_edge_filter)[arc]) {
1201
        arc = Parent::findArc(u, v, arc);
1202
      }
1203
      return arc;
1204
    }
1205

	
1206
    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
1207
    Edge findEdge(const Node& u, const Node& v,
1208
                  const Edge& prev = INVALID) const {
1209
      Edge edge = Parent::findEdge(u, v, prev);
1210
      while (edge != INVALID && !(*_edge_filter)[edge]) {
1211
        edge = Parent::findEdge(u, v, edge);
1212
      }
1213
      return edge;
1214
    }
1215

	
1216
    template <typename V>
1217
    class NodeMap 
1218
      : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
1219
          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> {
1220
      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
1221
        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, NodeMap<V>)> Parent;
1222

	
1223
    public:
1224
      typedef V Value;
1225

	
1226
      NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
1227
        : Parent(adaptor) {}
1228
      NodeMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
1229
        : Parent(adaptor, value) {}
1230

	
1231
    private:
1232
      NodeMap& operator=(const NodeMap& cmap) {
1233
        return operator=<NodeMap>(cmap);
1234
      }
1235

	
1236
      template <typename CMap>
1237
      NodeMap& operator=(const CMap& cmap) {
1238
        Parent::operator=(cmap);
1239
        return *this;
1240
      }
1241
    };
1242

	
1243
    template <typename V>
1244
    class ArcMap 
1245
      : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
1246
          LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> {
1247
      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
1248
        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, ArcMap<V>)> Parent;
1249

	
1250
    public:
1251
      typedef V Value;
1252

	
1253
      ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
1254
        : Parent(adaptor) {}
1255
      ArcMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
1256
        : Parent(adaptor, value) {}
1257

	
1258
    private:
1259
      ArcMap& operator=(const ArcMap& cmap) {
1260
        return operator=<ArcMap>(cmap);
1261
      }
1262

	
1263
      template <typename CMap>
1264
      ArcMap& operator=(const CMap& cmap) {
1265
        Parent::operator=(cmap);
1266
        return *this;
1267
      }
1268
    };
1269

	
1270
    template <typename V>
1271
    class EdgeMap 
1272
      : public SubMapExtender<SubGraphBase<GR, NF, EF, false>,
1273
        LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> {
1274
      typedef SubMapExtender<SubGraphBase<GR, NF, EF, false>, 
1275
	LEMON_SCOPE_FIX(GraphAdaptorBase<GR>, EdgeMap<V>)> Parent;
1276

	
1277
    public:
1278
      typedef V Value;
1279

	
1280
      EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor)
1281
        : Parent(adaptor) {}
1282

	
1283
      EdgeMap(const SubGraphBase<GR, NF, EF, false>& adaptor, const V& value)
1284
        : Parent(adaptor, value) {}
1285

	
1286
    private:
1287
      EdgeMap& operator=(const EdgeMap& cmap) {
1288
        return operator=<EdgeMap>(cmap);
1289
      }
1290

	
1291
      template <typename CMap>
1292
      EdgeMap& operator=(const CMap& cmap) {
1293
        Parent::operator=(cmap);
1294
        return *this;
1295
      }
1296
    };
1297

	
1298
  };
1299

	
1300
  /// \ingroup graph_adaptors
1301
  ///
1302
  /// \brief Adaptor class for hiding nodes and edges in an undirected
1303
  /// graph.
1304
  ///
1305
  /// SubGraph can be used for hiding nodes and edges in a graph.
1306
  /// A \c bool node map and a \c bool edge map must be specified, which
1307
  /// define the filters for nodes and edges.
1308
  /// Only the nodes and edges with \c true filter value are
1309
  /// shown in the subgraph. The edges that are incident to hidden
1310
  /// nodes are also filtered out.
1311
  /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
1312
  ///
1313
  /// The adapted graph can also be modified through this adaptor
1314
  /// by adding or removing nodes or edges, unless the \c GR template
1315
  /// parameter is set to be \c const.
1316
  ///
1317
  /// \tparam GR The type of the adapted graph.
1318
  /// It must conform to the \ref concepts::Graph "Graph" concept.
1319
  /// It can also be specified to be \c const.
1320
  /// \tparam NF The type of the node filter map.
1321
  /// It must be a \c bool (or convertible) node map of the
1322
  /// adapted graph. The default type is
1323
  /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
1324
  /// \tparam EF The type of the edge filter map.
1325
  /// It must be a \c bool (or convertible) edge map of the
1326
  /// adapted graph. The default type is
1327
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
1328
  ///
1329
  /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
1330
  /// adapted graph are convertible to each other.
1331
  ///
1332
  /// \see FilterNodes
1333
  /// \see FilterEdges
1334
#ifdef DOXYGEN
1335
  template<typename GR, typename NF, typename EF>
1336
  class SubGraph {
1337
#else
1338
  template<typename GR,
1339
           typename NF = typename GR::template NodeMap<bool>,
1340
           typename EF = typename GR::template EdgeMap<bool> >
1341
  class SubGraph :
1342
    public GraphAdaptorExtender<SubGraphBase<GR, NF, EF, true> > {
1343
#endif
1344
  public:
1345
    /// The type of the adapted graph.
1346
    typedef GR Graph;
1347
    /// The type of the node filter map.
1348
    typedef NF NodeFilterMap;
1349
    /// The type of the edge filter map.
1350
    typedef EF EdgeFilterMap;
1351

	
1352
    typedef GraphAdaptorExtender<SubGraphBase<GR, NF, EF, true> >
1353
      Parent;
1354

	
1355
    typedef typename Parent::Node Node;
1356
    typedef typename Parent::Edge Edge;
1357

	
1358
  protected:
1359
    SubGraph() { }
1360
  public:
1361

	
1362
    /// \brief Constructor
1363
    ///
1364
    /// Creates a subgraph for the given graph with the given node
1365
    /// and edge filter maps.
1366
    SubGraph(GR& graph, NF& node_filter, EF& edge_filter) {
1367
      initialize(graph, node_filter, edge_filter);
1368
    }
1369

	
1370
    /// \brief Sets the status of the given node
1371
    ///
1372
    /// This function sets the status of the given node.
1373
    /// It is done by simply setting the assigned value of \c n
1374
    /// to \c v in the node filter map.
1375
    void status(const Node& n, bool v) const { Parent::status(n, v); }
1376

	
1377
    /// \brief Sets the status of the given edge
1378
    ///
1379
    /// This function sets the status of the given edge.
1380
    /// It is done by simply setting the assigned value of \c e
1381
    /// to \c v in the edge filter map.
1382
    void status(const Edge& e, bool v) const { Parent::status(e, v); }
1383

	
1384
    /// \brief Returns the status of the given node
1385
    ///
1386
    /// This function returns the status of the given node.
1387
    /// It is \c true if the given node is enabled (i.e. not hidden).
1388
    bool status(const Node& n) const { return Parent::status(n); }
1389

	
1390
    /// \brief Returns the status of the given edge
1391
    ///
1392
    /// This function returns the status of the given edge.
1393
    /// It is \c true if the given edge is enabled (i.e. not hidden).
1394
    bool status(const Edge& e) const { return Parent::status(e); }
1395

	
1396
    /// \brief Disables the given node
1397
    ///
1398
    /// This function disables the given node in the subdigraph,
1399
    /// so the iteration jumps over it.
1400
    /// It is the same as \ref status() "status(n, false)".
1401
    void disable(const Node& n) const { Parent::status(n, false); }
1402

	
1403
    /// \brief Disables the given edge
1404
    ///
1405
    /// This function disables the given edge in the subgraph,
1406
    /// so the iteration jumps over it.
1407
    /// It is the same as \ref status() "status(e, false)".
1408
    void disable(const Edge& e) const { Parent::status(e, false); }
1409

	
1410
    /// \brief Enables the given node
1411
    ///
1412
    /// This function enables the given node in the subdigraph.
1413
    /// It is the same as \ref status() "status(n, true)".
1414
    void enable(const Node& n) const { Parent::status(n, true); }
1415

	
1416
    /// \brief Enables the given edge
1417
    ///
1418
    /// This function enables the given edge in the subgraph.
1419
    /// It is the same as \ref status() "status(e, true)".
1420
    void enable(const Edge& e) const { Parent::status(e, true); }
1421

	
1422
  };
1423

	
1424
  /// \brief Returns a read-only SubGraph adaptor
1425
  ///
1426
  /// This function just returns a read-only \ref SubGraph adaptor.
1427
  /// \ingroup graph_adaptors
1428
  /// \relates SubGraph
1429
  template<typename GR, typename NF, typename EF>
1430
  SubGraph<const GR, NF, EF>
1431
  subGraph(const GR& graph, NF& node_filter, EF& edge_filter) {
1432
    return SubGraph<const GR, NF, EF>
1433
      (graph, node_filter, edge_filter);
1434
  }
1435

	
1436
  template<typename GR, typename NF, typename EF>
1437
  SubGraph<const GR, const NF, EF>
1438
  subGraph(const GR& graph, const NF& node_filter, EF& edge_filter) {
1439
    return SubGraph<const GR, const NF, EF>
1440
      (graph, node_filter, edge_filter);
1441
  }
1442

	
1443
  template<typename GR, typename NF, typename EF>
1444
  SubGraph<const GR, NF, const EF>
1445
  subGraph(const GR& graph, NF& node_filter, const EF& edge_filter) {
1446
    return SubGraph<const GR, NF, const EF>
1447
      (graph, node_filter, edge_filter);
1448
  }
1449

	
1450
  template<typename GR, typename NF, typename EF>
1451
  SubGraph<const GR, const NF, const EF>
1452
  subGraph(const GR& graph, const NF& node_filter, const EF& edge_filter) {
1453
    return SubGraph<const GR, const NF, const EF>
1454
      (graph, node_filter, edge_filter);
1455
  }
1456

	
1457

	
1458
  /// \ingroup graph_adaptors
1459
  ///
1460
  /// \brief Adaptor class for hiding nodes in a digraph or a graph.
1461
  ///
1462
  /// FilterNodes adaptor can be used for hiding nodes in a digraph or a
1463
  /// graph. A \c bool node map must be specified, which defines the filter
1464
  /// for the nodes. Only the nodes with \c true filter value and the
1465
  /// arcs/edges incident to nodes both with \c true filter value are shown
1466
  /// in the subgraph. This adaptor conforms to the \ref concepts::Digraph
1467
  /// "Digraph" concept or the \ref concepts::Graph "Graph" concept
1468
  /// depending on the \c GR template parameter.
1469
  ///
1470
  /// The adapted (di)graph can also be modified through this adaptor
1471
  /// by adding or removing nodes or arcs/edges, unless the \c GR template
1472
  /// parameter is set to be \c const.
1473
  ///
1474
  /// \tparam GR The type of the adapted digraph or graph.
1475
  /// It must conform to the \ref concepts::Digraph "Digraph" concept
1476
  /// or the \ref concepts::Graph "Graph" concept.
1477
  /// It can also be specified to be \c const.
1478
  /// \tparam NF The type of the node filter map.
1479
  /// It must be a \c bool (or convertible) node map of the
1480
  /// adapted (di)graph. The default type is
1481
  /// \ref concepts::Graph::NodeMap "GR::NodeMap<bool>".
1482
  ///
1483
  /// \note The \c Node and <tt>Arc/Edge</tt> types of this adaptor and the
1484
  /// adapted (di)graph are convertible to each other.
1485
#ifdef DOXYGEN
1486
  template<typename GR, typename NF>
1487
  class FilterNodes {
1488
#else
1489
  template<typename GR,
1490
           typename NF = typename GR::template NodeMap<bool>,
1491
           typename Enable = void>
1492
  class FilterNodes :
1493
    public DigraphAdaptorExtender<
1494
      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >,
1495
                     true> > {
1496
#endif
1497
    typedef DigraphAdaptorExtender<
1498
      SubDigraphBase<GR, NF, ConstMap<typename GR::Arc, Const<bool, true> >, 
1499
                     true> > Parent;
1500

	
1501
  public:
1502

	
1503
    typedef GR Digraph;
1504
    typedef NF NodeFilterMap;
1505

	
1506
    typedef typename Parent::Node Node;
1507

	
1508
  protected:
1509
    ConstMap<typename Digraph::Arc, Const<bool, true> > const_true_map;
1510

	
1511
    FilterNodes() : const_true_map() {}
1512

	
1513
  public:
1514

	
1515
    /// \brief Constructor
1516
    ///
1517
    /// Creates a subgraph for the given digraph or graph with the
1518
    /// given node filter map.
1519
    FilterNodes(GR& graph, NF& node_filter) 
1520
      : Parent(), const_true_map()
1521
    {
1522
      Parent::initialize(graph, node_filter, const_true_map);
1523
    }
1524

	
1525
    /// \brief Sets the status of the given node
1526
    ///
1527
    /// This function sets the status of the given node.
1528
    /// It is done by simply setting the assigned value of \c n
1529
    /// to \c v in the node filter map.
1530
    void status(const Node& n, bool v) const { Parent::status(n, v); }
1531

	
1532
    /// \brief Returns the status of the given node
1533
    ///
1534
    /// This function returns the status of the given node.
1535
    /// It is \c true if the given node is enabled (i.e. not hidden).
1536
    bool status(const Node& n) const { return Parent::status(n); }
1537

	
1538
    /// \brief Disables the given node
1539
    ///
1540
    /// This function disables the given node, so the iteration
1541
    /// jumps over it.
1542
    /// It is the same as \ref status() "status(n, false)".
1543
    void disable(const Node& n) const { Parent::status(n, false); }
1544

	
1545
    /// \brief Enables the given node
1546
    ///
1547
    /// This function enables the given node.
1548
    /// It is the same as \ref status() "status(n, true)".
1549
    void enable(const Node& n) const { Parent::status(n, true); }
1550

	
1551
  };
1552

	
1553
  template<typename GR, typename NF>
1554
  class FilterNodes<GR, NF,
1555
                    typename enable_if<UndirectedTagIndicator<GR> >::type> :
1556
    public GraphAdaptorExtender<
1557
      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 
1558
                   true> > {
1559

	
1560
    typedef GraphAdaptorExtender<
1561
      SubGraphBase<GR, NF, ConstMap<typename GR::Edge, Const<bool, true> >, 
1562
                   true> > Parent;
1563

	
1564
  public:
1565

	
1566
    typedef GR Graph;
1567
    typedef NF NodeFilterMap;
1568

	
1569
    typedef typename Parent::Node Node;
1570

	
1571
  protected:
1572
    ConstMap<typename GR::Edge, Const<bool, true> > const_true_map;
1573

	
1574
    FilterNodes() : const_true_map() {}
1575

	
1576
  public:
1577

	
1578
    FilterNodes(GR& graph, NodeFilterMap& node_filter) :
1579
      Parent(), const_true_map() {
1580
      Parent::initialize(graph, node_filter, const_true_map);
1581
    }
1582

	
1583
    void status(const Node& n, bool v) const { Parent::status(n, v); }
1584
    bool status(const Node& n) const { return Parent::status(n); }
1585
    void disable(const Node& n) const { Parent::status(n, false); }
1586
    void enable(const Node& n) const { Parent::status(n, true); }
1587

	
1588
  };
1589

	
1590

	
1591
  /// \brief Returns a read-only FilterNodes adaptor
1592
  ///
1593
  /// This function just returns a read-only \ref FilterNodes adaptor.
1594
  /// \ingroup graph_adaptors
1595
  /// \relates FilterNodes
1596
  template<typename GR, typename NF>
1597
  FilterNodes<const GR, NF>
1598
  filterNodes(const GR& graph, NF& node_filter) {
1599
    return FilterNodes<const GR, NF>(graph, node_filter);
1600
  }
1601

	
1602
  template<typename GR, typename NF>
1603
  FilterNodes<const GR, const NF>
1604
  filterNodes(const GR& graph, const NF& node_filter) {
1605
    return FilterNodes<const GR, const NF>(graph, node_filter);
1606
  }
1607

	
1608
  /// \ingroup graph_adaptors
1609
  ///
1610
  /// \brief Adaptor class for hiding arcs in a digraph.
1611
  ///
1612
  /// FilterArcs adaptor can be used for hiding arcs in a digraph.
1613
  /// A \c bool arc map must be specified, which defines the filter for
1614
  /// the arcs. Only the arcs with \c true filter value are shown in the
1615
  /// subdigraph. This adaptor conforms to the \ref concepts::Digraph
1616
  /// "Digraph" concept.
1617
  ///
1618
  /// The adapted digraph can also be modified through this adaptor
1619
  /// by adding or removing nodes or arcs, unless the \c GR template
1620
  /// parameter is set to be \c const.
1621
  ///
1622
  /// \tparam DGR The type of the adapted digraph.
1623
  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
1624
  /// It can also be specified to be \c const.
1625
  /// \tparam AF The type of the arc filter map.
1626
  /// It must be a \c bool (or convertible) arc map of the
1627
  /// adapted digraph. The default type is
1628
  /// \ref concepts::Digraph::ArcMap "DGR::ArcMap<bool>".
1629
  ///
1630
  /// \note The \c Node and \c Arc types of this adaptor and the adapted
1631
  /// digraph are convertible to each other.
1632
#ifdef DOXYGEN
1633
  template<typename DGR,
1634
           typename AF>
1635
  class FilterArcs {
1636
#else
1637
  template<typename DGR,
1638
           typename AF = typename DGR::template ArcMap<bool> >
1639
  class FilterArcs :
1640
    public DigraphAdaptorExtender<
1641
      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >,
1642
                     AF, false> > {
1643
#endif
1644
    typedef DigraphAdaptorExtender<
1645
      SubDigraphBase<DGR, ConstMap<typename DGR::Node, Const<bool, true> >, 
1646
                     AF, false> > Parent;
1647

	
1648
  public:
1649

	
1650
    /// The type of the adapted digraph.
1651
    typedef DGR Digraph;
1652
    /// The type of the arc filter map.
1653
    typedef AF ArcFilterMap;
1654

	
1655
    typedef typename Parent::Arc Arc;
1656

	
1657
  protected:
1658
    ConstMap<typename DGR::Node, Const<bool, true> > const_true_map;
1659

	
1660
    FilterArcs() : const_true_map() {}
1661

	
1662
  public:
1663

	
1664
    /// \brief Constructor
1665
    ///
1666
    /// Creates a subdigraph for the given digraph with the given arc
1667
    /// filter map.
1668
    FilterArcs(DGR& digraph, ArcFilterMap& arc_filter)
1669
      : Parent(), const_true_map() {
1670
      Parent::initialize(digraph, const_true_map, arc_filter);
1671
    }
1672

	
1673
    /// \brief Sets the status of the given arc
1674
    ///
1675
    /// This function sets the status of the given arc.
1676
    /// It is done by simply setting the assigned value of \c a
1677
    /// to \c v in the arc filter map.
1678
    void status(const Arc& a, bool v) const { Parent::status(a, v); }
1679

	
1680
    /// \brief Returns the status of the given arc
1681
    ///
1682
    /// This function returns the status of the given arc.
1683
    /// It is \c true if the given arc is enabled (i.e. not hidden).
1684
    bool status(const Arc& a) const { return Parent::status(a); }
1685

	
1686
    /// \brief Disables the given arc
1687
    ///
1688
    /// This function disables the given arc in the subdigraph,
1689
    /// so the iteration jumps over it.
1690
    /// It is the same as \ref status() "status(a, false)".
1691
    void disable(const Arc& a) const { Parent::status(a, false); }
1692

	
1693
    /// \brief Enables the given arc
1694
    ///
1695
    /// This function enables the given arc in the subdigraph.
1696
    /// It is the same as \ref status() "status(a, true)".
1697
    void enable(const Arc& a) const { Parent::status(a, true); }
1698

	
1699
  };
1700

	
1701
  /// \brief Returns a read-only FilterArcs adaptor
1702
  ///
1703
  /// This function just returns a read-only \ref FilterArcs adaptor.
1704
  /// \ingroup graph_adaptors
1705
  /// \relates FilterArcs
1706
  template<typename DGR, typename AF>
1707
  FilterArcs<const DGR, AF>
1708
  filterArcs(const DGR& digraph, AF& arc_filter) {
1709
    return FilterArcs<const DGR, AF>(digraph, arc_filter);
1710
  }
1711

	
1712
  template<typename DGR, typename AF>
1713
  FilterArcs<const DGR, const AF>
1714
  filterArcs(const DGR& digraph, const AF& arc_filter) {
1715
    return FilterArcs<const DGR, const AF>(digraph, arc_filter);
1716
  }
1717

	
1718
  /// \ingroup graph_adaptors
1719
  ///
1720
  /// \brief Adaptor class for hiding edges in a graph.
1721
  ///
1722
  /// FilterEdges adaptor can be used for hiding edges in a graph.
1723
  /// A \c bool edge map must be specified, which defines the filter for
1724
  /// the edges. Only the edges with \c true filter value are shown in the
1725
  /// subgraph. This adaptor conforms to the \ref concepts::Graph
1726
  /// "Graph" concept.
1727
  ///
1728
  /// The adapted graph can also be modified through this adaptor
1729
  /// by adding or removing nodes or edges, unless the \c GR template
1730
  /// parameter is set to be \c const.
1731
  ///
1732
  /// \tparam GR The type of the adapted graph.
1733
  /// It must conform to the \ref concepts::Graph "Graph" concept.
1734
  /// It can also be specified to be \c const.
1735
  /// \tparam EF The type of the edge filter map.
1736
  /// It must be a \c bool (or convertible) edge map of the
1737
  /// adapted graph. The default type is
1738
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
1739
  ///
1740
  /// \note The \c Node, \c Edge and \c Arc types of this adaptor and the
1741
  /// adapted graph are convertible to each other.
1742
#ifdef DOXYGEN
1743
  template<typename GR,
1744
           typename EF>
1745
  class FilterEdges {
1746
#else
1747
  template<typename GR,
1748
           typename EF = typename GR::template EdgeMap<bool> >
1749
  class FilterEdges :
1750
    public GraphAdaptorExtender<
1751
      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true> >, 
1752
                   EF, false> > {
1753
#endif
1754
    typedef GraphAdaptorExtender<
1755
      SubGraphBase<GR, ConstMap<typename GR::Node, Const<bool, true > >, 
1756
                   EF, false> > Parent;
1757

	
1758
  public:
1759

	
1760
    /// The type of the adapted graph.
1761
    typedef GR Graph;
1762
    /// The type of the edge filter map.
1763
    typedef EF EdgeFilterMap;
1764

	
1765
    typedef typename Parent::Edge Edge;
1766

	
1767
  protected:
1768
    ConstMap<typename GR::Node, Const<bool, true> > const_true_map;
1769

	
1770
    FilterEdges() : const_true_map(true) {
1771
      Parent::setNodeFilterMap(const_true_map);
1772
    }
1773

	
1774
  public:
1775

	
1776
    /// \brief Constructor
1777
    ///
1778
    /// Creates a subgraph for the given graph with the given edge
1779
    /// filter map.
1780
    FilterEdges(GR& graph, EF& edge_filter) 
1781
      : Parent(), const_true_map() {
1782
      Parent::initialize(graph, const_true_map, edge_filter);
1783
    }
1784

	
1785
    /// \brief Sets the status of the given edge
1786
    ///
1787
    /// This function sets the status of the given edge.
1788
    /// It is done by simply setting the assigned value of \c e
1789
    /// to \c v in the edge filter map.
1790
    void status(const Edge& e, bool v) const { Parent::status(e, v); }
1791

	
1792
    /// \brief Returns the status of the given edge
1793
    ///
1794
    /// This function returns the status of the given edge.
1795
    /// It is \c true if the given edge is enabled (i.e. not hidden).
1796
    bool status(const Edge& e) const { return Parent::status(e); }
1797

	
1798
    /// \brief Disables the given edge
1799
    ///
1800
    /// This function disables the given edge in the subgraph,
1801
    /// so the iteration jumps over it.
1802
    /// It is the same as \ref status() "status(e, false)".
1803
    void disable(const Edge& e) const { Parent::status(e, false); }
1804

	
1805
    /// \brief Enables the given edge
1806
    ///
1807
    /// This function enables the given edge in the subgraph.
1808
    /// It is the same as \ref status() "status(e, true)".
1809
    void enable(const Edge& e) const { Parent::status(e, true); }
1810

	
1811
  };
1812

	
1813
  /// \brief Returns a read-only FilterEdges adaptor
1814
  ///
1815
  /// This function just returns a read-only \ref FilterEdges adaptor.
1816
  /// \ingroup graph_adaptors
1817
  /// \relates FilterEdges
1818
  template<typename GR, typename EF>
1819
  FilterEdges<const GR, EF>
1820
  filterEdges(const GR& graph, EF& edge_filter) {
1821
    return FilterEdges<const GR, EF>(graph, edge_filter);
1822
  }
1823

	
1824
  template<typename GR, typename EF>
1825
  FilterEdges<const GR, const EF>
1826
  filterEdges(const GR& graph, const EF& edge_filter) {
1827
    return FilterEdges<const GR, const EF>(graph, edge_filter);
1828
  }
1829

	
1830

	
1831
  template <typename DGR>
1832
  class UndirectorBase {
1833
  public:
1834
    typedef DGR Digraph;
1835
    typedef UndirectorBase Adaptor;
1836

	
1837
    typedef True UndirectedTag;
1838

	
1839
    typedef typename Digraph::Arc Edge;
1840
    typedef typename Digraph::Node Node;
1841

	
1842
    class Arc {
1843
      friend class UndirectorBase;
1844
    protected:
1845
      Edge _edge;
1846
      bool _forward;
1847

	
1848
      Arc(const Edge& edge, bool forward) 
1849
        : _edge(edge), _forward(forward) {}
1850

	
1851
    public:
1852
      Arc() {}
1853

	
1854
      Arc(Invalid) : _edge(INVALID), _forward(true) {}
1855

	
1856
      operator const Edge&() const { return _edge; }
1857

	
1858
      bool operator==(const Arc &other) const {
1859
        return _forward == other._forward && _edge == other._edge;
1860
      }
1861
      bool operator!=(const Arc &other) const {
1862
        return _forward != other._forward || _edge != other._edge;
1863
      }
1864
      bool operator<(const Arc &other) const {
1865
        return _forward < other._forward ||
1866
          (_forward == other._forward && _edge < other._edge);
1867
      }
1868
    };
1869

	
1870
    void first(Node& n) const {
1871
      _digraph->first(n);
1872
    }
1873

	
1874
    void next(Node& n) const {
1875
      _digraph->next(n);
1876
    }
1877

	
1878
    void first(Arc& a) const {
1879
      _digraph->first(a._edge);
1880
      a._forward = true;
1881
    }
1882

	
1883
    void next(Arc& a) const {
1884
      if (a._forward) {
1885
        a._forward = false;
1886
      } else {
1887
        _digraph->next(a._edge);
1888
        a._forward = true;
1889
      }
1890
    }
1891

	
1892
    void first(Edge& e) const {
1893
      _digraph->first(e);
1894
    }
1895

	
1896
    void next(Edge& e) const {
1897
      _digraph->next(e);
1898
    }
1899

	
1900
    void firstOut(Arc& a, const Node& n) const {
1901
      _digraph->firstIn(a._edge, n);
1902
      if (a._edge != INVALID ) {
1903
        a._forward = false;
1904
      } else {
1905
        _digraph->firstOut(a._edge, n);
1906
        a._forward = true;
1907
      }
1908
    }
1909
    void nextOut(Arc &a) const {
1910
      if (!a._forward) {
1911
        Node n = _digraph->target(a._edge);
1912
        _digraph->nextIn(a._edge);
1913
        if (a._edge == INVALID) {
1914
          _digraph->firstOut(a._edge, n);
1915
          a._forward = true;
1916
        }
1917
      }
1918
      else {
1919
        _digraph->nextOut(a._edge);
1920
      }
1921
    }
1922

	
1923
    void firstIn(Arc &a, const Node &n) const {
1924
      _digraph->firstOut(a._edge, n);
1925
      if (a._edge != INVALID ) {
1926
        a._forward = false;
1927
      } else {
1928
        _digraph->firstIn(a._edge, n);
1929
        a._forward = true;
1930
      }
1931
    }
1932
    void nextIn(Arc &a) const {
1933
      if (!a._forward) {
1934
        Node n = _digraph->source(a._edge);
1935
        _digraph->nextOut(a._edge);
1936
        if (a._edge == INVALID ) {
1937
          _digraph->firstIn(a._edge, n);
1938
          a._forward = true;
1939
        }
1940
      }
1941
      else {
1942
        _digraph->nextIn(a._edge);
1943
      }
1944
    }
1945

	
1946
    void firstInc(Edge &e, bool &d, const Node &n) const {
1947
      d = true;
1948
      _digraph->firstOut(e, n);
1949
      if (e != INVALID) return;
1950
      d = false;
1951
      _digraph->firstIn(e, n);
1952
    }
1953

	
1954
    void nextInc(Edge &e, bool &d) const {
1955
      if (d) {
1956
        Node s = _digraph->source(e);
1957
        _digraph->nextOut(e);
1958
        if (e != INVALID) return;
1959
        d = false;
1960
        _digraph->firstIn(e, s);
1961
      } else {
1962
        _digraph->nextIn(e);
1963
      }
1964
    }
1965

	
1966
    Node u(const Edge& e) const {
1967
      return _digraph->source(e);
1968
    }
1969

	
1970
    Node v(const Edge& e) const {
1971
      return _digraph->target(e);
1972
    }
1973

	
1974
    Node source(const Arc &a) const {
1975
      return a._forward ? _digraph->source(a._edge) : _digraph->target(a._edge);
1976
    }
1977

	
1978
    Node target(const Arc &a) const {
1979
      return a._forward ? _digraph->target(a._edge) : _digraph->source(a._edge);
1980
    }
1981

	
1982
    static Arc direct(const Edge &e, bool d) {
1983
      return Arc(e, d);
1984
    }
1985

	
1986
    static bool direction(const Arc &a) { return a._forward; }
1987

	
1988
    Node nodeFromId(int ix) const { return _digraph->nodeFromId(ix); }
1989
    Arc arcFromId(int ix) const {
1990
      return direct(_digraph->arcFromId(ix >> 1), bool(ix & 1));
1991
    }
1992
    Edge edgeFromId(int ix) const { return _digraph->arcFromId(ix); }
1993

	
1994
    int id(const Node &n) const { return _digraph->id(n); }
1995
    int id(const Arc &a) const {
1996
      return  (_digraph->id(a) << 1) | (a._forward ? 1 : 0);
1997
    }
1998
    int id(const Edge &e) const { return _digraph->id(e); }
1999

	
2000
    int maxNodeId() const { return _digraph->maxNodeId(); }
2001
    int maxArcId() const { return (_digraph->maxArcId() << 1) | 1; }
2002
    int maxEdgeId() const { return _digraph->maxArcId(); }
2003

	
2004
    Node addNode() { return _digraph->addNode(); }
2005
    Edge addEdge(const Node& u, const Node& v) {
2006
      return _digraph->addArc(u, v);
2007
    }
2008

	
2009
    void erase(const Node& i) { _digraph->erase(i); }
2010
    void erase(const Edge& i) { _digraph->erase(i); }
2011

	
2012
    void clear() { _digraph->clear(); }
2013

	
2014
    typedef NodeNumTagIndicator<Digraph> NodeNumTag;
2015
    int nodeNum() const { return _digraph->nodeNum(); }
2016

	
2017
    typedef ArcNumTagIndicator<Digraph> ArcNumTag;
2018
    int arcNum() const { return 2 * _digraph->arcNum(); }
2019

	
2020
    typedef ArcNumTag EdgeNumTag;
2021
    int edgeNum() const { return _digraph->arcNum(); }
2022

	
2023
    typedef FindArcTagIndicator<Digraph> FindArcTag;
2024
    Arc findArc(Node s, Node t, Arc p = INVALID) const {
2025
      if (p == INVALID) {
2026
        Edge arc = _digraph->findArc(s, t);
2027
        if (arc != INVALID) return direct(arc, true);
2028
        arc = _digraph->findArc(t, s);
2029
        if (arc != INVALID) return direct(arc, false);
2030
      } else if (direction(p)) {
2031
        Edge arc = _digraph->findArc(s, t, p);
2032
        if (arc != INVALID) return direct(arc, true);
2033
        arc = _digraph->findArc(t, s);
2034
        if (arc != INVALID) return direct(arc, false);
2035
      } else {
2036
        Edge arc = _digraph->findArc(t, s, p);
2037
        if (arc != INVALID) return direct(arc, false);
2038
      }
2039
      return INVALID;
2040
    }
2041

	
2042
    typedef FindArcTag FindEdgeTag;
2043
    Edge findEdge(Node s, Node t, Edge p = INVALID) const {
2044
      if (s != t) {
2045
        if (p == INVALID) {
2046
          Edge arc = _digraph->findArc(s, t);
2047
          if (arc != INVALID) return arc;
2048
          arc = _digraph->findArc(t, s);
2049
          if (arc != INVALID) return arc;
2050
        } else if (_digraph->source(p) == s) {
2051
          Edge arc = _digraph->findArc(s, t, p);
2052
          if (arc != INVALID) return arc;
2053
          arc = _digraph->findArc(t, s);
2054
          if (arc != INVALID) return arc;
2055
        } else {
2056
          Edge arc = _digraph->findArc(t, s, p);
2057
          if (arc != INVALID) return arc;
2058
        }
2059
      } else {
2060
        return _digraph->findArc(s, t, p);
2061
      }
2062
      return INVALID;
2063
    }
2064

	
2065
  private:
2066

	
2067
    template <typename V>
2068
    class ArcMapBase {
2069
    private:
2070

	
2071
      typedef typename DGR::template ArcMap<V> MapImpl;
2072

	
2073
    public:
2074

	
2075
      typedef typename MapTraits<MapImpl>::ReferenceMapTag ReferenceMapTag;
2076

	
2077
      typedef V Value;
2078
      typedef Arc Key;
2079
      typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReturnValue;
2080
      typedef typename MapTraits<MapImpl>::ReturnValue ReturnValue;
2081
      typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReference;
2082
      typedef typename MapTraits<MapImpl>::ReturnValue Reference;
2083

	
2084
      ArcMapBase(const UndirectorBase<DGR>& adaptor) :
2085
        _forward(*adaptor._digraph), _backward(*adaptor._digraph) {}
2086

	
2087
      ArcMapBase(const UndirectorBase<DGR>& adaptor, const V& value)
2088
        : _forward(*adaptor._digraph, value), 
2089
          _backward(*adaptor._digraph, value) {}
2090

	
2091
      void set(const Arc& a, const V& value) {
2092
        if (direction(a)) {
2093
          _forward.set(a, value);
2094
        } else {
2095
          _backward.set(a, value);
2096
        }
2097
      }
2098

	
2099
      ConstReturnValue operator[](const Arc& a) const {
2100
        if (direction(a)) {
2101
          return _forward[a];
2102
        } else {
2103
          return _backward[a];
2104
        }
2105
      }
2106

	
2107
      ReturnValue operator[](const Arc& a) {
2108
        if (direction(a)) {
2109
          return _forward[a];
2110
        } else {
2111
          return _backward[a];
2112
        }
2113
      }
2114

	
2115
    protected:
2116

	
2117
      MapImpl _forward, _backward;
2118

	
2119
    };
2120

	
2121
  public:
2122

	
2123
    template <typename V>
2124
    class NodeMap : public DGR::template NodeMap<V> {
2125
      typedef typename DGR::template NodeMap<V> Parent;
2126

	
2127
    public:
2128
      typedef V Value;
2129

	
2130
      explicit NodeMap(const UndirectorBase<DGR>& adaptor)
2131
        : Parent(*adaptor._digraph) {}
2132

	
2133
      NodeMap(const UndirectorBase<DGR>& adaptor, const V& value)
2134
        : Parent(*adaptor._digraph, value) { }
2135

	
2136
    private:
2137
      NodeMap& operator=(const NodeMap& cmap) {
2138
        return operator=<NodeMap>(cmap);
2139
      }
2140

	
2141
      template <typename CMap>
2142
      NodeMap& operator=(const CMap& cmap) {
2143
        Parent::operator=(cmap);
2144
        return *this;
2145
      }
2146

	
2147
    };
2148

	
2149
    template <typename V>
2150
    class ArcMap
2151
      : public SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> > {
2152
      typedef SubMapExtender<UndirectorBase<DGR>, ArcMapBase<V> > Parent;
2153

	
2154
    public:
2155
      typedef V Value;
2156

	
2157
      explicit ArcMap(const UndirectorBase<DGR>& adaptor)
2158
        : Parent(adaptor) {}
2159

	
2160
      ArcMap(const UndirectorBase<DGR>& adaptor, const V& value)
2161
        : Parent(adaptor, value) {}
2162

	
2163
    private:
2164
      ArcMap& operator=(const ArcMap& cmap) {
2165
        return operator=<ArcMap>(cmap);
2166
      }
2167

	
2168
      template <typename CMap>
2169
      ArcMap& operator=(const CMap& cmap) {
2170
        Parent::operator=(cmap);
2171
        return *this;
2172
      }
2173
    };
2174

	
2175
    template <typename V>
2176
    class EdgeMap : public Digraph::template ArcMap<V> {
2177
      typedef typename Digraph::template ArcMap<V> Parent;
2178

	
2179
    public:
2180
      typedef V Value;
2181

	
2182
      explicit EdgeMap(const UndirectorBase<DGR>& adaptor)
2183
        : Parent(*adaptor._digraph) {}
2184

	
2185
      EdgeMap(const UndirectorBase<DGR>& adaptor, const V& value)
2186
        : Parent(*adaptor._digraph, value) {}
2187

	
2188
    private:
2189
      EdgeMap& operator=(const EdgeMap& cmap) {
2190
        return operator=<EdgeMap>(cmap);
2191
      }
2192

	
2193
      template <typename CMap>
2194
      EdgeMap& operator=(const CMap& cmap) {
2195
        Parent::operator=(cmap);
2196
        return *this;
2197
      }
2198

	
2199
    };
2200

	
2201
    typedef typename ItemSetTraits<DGR, Node>::ItemNotifier NodeNotifier;
2202
    NodeNotifier& notifier(Node) const { return _digraph->notifier(Node()); }
2203

	
2204
    typedef typename ItemSetTraits<DGR, Edge>::ItemNotifier EdgeNotifier;
2205
    EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); }
2206
    
2207
    typedef EdgeNotifier ArcNotifier;
2208
    ArcNotifier& notifier(Arc) const { return _digraph->notifier(Edge()); }
2209

	
2210
  protected:
2211

	
2212
    UndirectorBase() : _digraph(0) {}
2213

	
2214
    DGR* _digraph;
2215

	
2216
    void initialize(DGR& digraph) {
2217
      _digraph = &digraph;
2218
    }
2219

	
2220
  };
2221

	
2222
  /// \ingroup graph_adaptors
2223
  ///
2224
  /// \brief Adaptor class for viewing a digraph as an undirected graph.
2225
  ///
2226
  /// Undirector adaptor can be used for viewing a digraph as an undirected
2227
  /// graph. All arcs of the underlying digraph are showed in the
2228
  /// adaptor as an edge (and also as a pair of arcs, of course).
2229
  /// This adaptor conforms to the \ref concepts::Graph "Graph" concept.
2230
  ///
2231
  /// The adapted digraph can also be modified through this adaptor
2232
  /// by adding or removing nodes or edges, unless the \c GR template
2233
  /// parameter is set to be \c const.
2234
  ///
2235
  /// \tparam DGR The type of the adapted digraph.
2236
  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
2237
  /// It can also be specified to be \c const.
2238
  ///
2239
  /// \note The \c Node type of this adaptor and the adapted digraph are
2240
  /// convertible to each other, moreover the \c Edge type of the adaptor
2241
  /// and the \c Arc type of the adapted digraph are also convertible to
2242
  /// each other.
2243
  /// (Thus the \c Arc type of the adaptor is convertible to the \c Arc type
2244
  /// of the adapted digraph.)
2245
  template<typename DGR>
2246
#ifdef DOXYGEN
2247
  class Undirector {
2248
#else
2249
  class Undirector :
2250
    public GraphAdaptorExtender<UndirectorBase<DGR> > {
2251
#endif
2252
    typedef GraphAdaptorExtender<UndirectorBase<DGR> > Parent;
2253
  public:
2254
    /// The type of the adapted digraph.
2255
    typedef DGR Digraph;
2256
  protected:
2257
    Undirector() { }
2258
  public:
2259

	
2260
    /// \brief Constructor
2261
    ///
2262
    /// Creates an undirected graph from the given digraph.
2263
    Undirector(DGR& digraph) {
2264
      initialize(digraph);
2265
    }
2266

	
2267
    /// \brief Arc map combined from two original arc maps
2268
    ///
2269
    /// This map adaptor class adapts two arc maps of the underlying
2270
    /// digraph to get an arc map of the undirected graph.
2271
    /// Its value type is inherited from the first arc map type (\c FW).
2272
    /// \tparam FW The type of the "foward" arc map.
2273
    /// \tparam BK The type of the "backward" arc map.
2274
    template <typename FW, typename BK>
2275
    class CombinedArcMap {
2276
    public:
2277

	
2278
      /// The key type of the map
2279
      typedef typename Parent::Arc Key;
2280
      /// The value type of the map
2281
      typedef typename FW::Value Value;
2282

	
2283
      typedef typename MapTraits<FW>::ReferenceMapTag ReferenceMapTag;
2284

	
2285
      typedef typename MapTraits<FW>::ReturnValue ReturnValue;
2286
      typedef typename MapTraits<FW>::ConstReturnValue ConstReturnValue;
2287
      typedef typename MapTraits<FW>::ReturnValue Reference;
2288
      typedef typename MapTraits<FW>::ConstReturnValue ConstReference;
2289

	
2290
      /// Constructor
2291
      CombinedArcMap(FW& forward, BK& backward)
2292
        : _forward(&forward), _backward(&backward) {}
2293

	
2294
      /// Sets the value associated with the given key.
2295
      void set(const Key& e, const Value& a) {
2296
        if (Parent::direction(e)) {
2297
          _forward->set(e, a);
2298
        } else {
2299
          _backward->set(e, a);
2300
        }
2301
      }
2302

	
2303
      /// Returns the value associated with the given key.
2304
      ConstReturnValue operator[](const Key& e) const {
2305
        if (Parent::direction(e)) {
2306
          return (*_forward)[e];
2307
        } else {
2308
          return (*_backward)[e];
2309
        }
2310
      }
2311

	
2312
      /// Returns a reference to the value associated with the given key.
2313
      ReturnValue operator[](const Key& e) {
2314
        if (Parent::direction(e)) {
2315
          return (*_forward)[e];
2316
        } else {
2317
          return (*_backward)[e];
2318
        }
2319
      }
2320

	
2321
    protected:
2322

	
2323
      FW* _forward;
2324
      BK* _backward;
2325

	
2326
    };
2327

	
2328
    /// \brief Returns a combined arc map
2329
    ///
2330
    /// This function just returns a combined arc map.
2331
    template <typename FW, typename BK>
2332
    static CombinedArcMap<FW, BK>
2333
    combinedArcMap(FW& forward, BK& backward) {
2334
      return CombinedArcMap<FW, BK>(forward, backward);
2335
    }
2336

	
2337
    template <typename FW, typename BK>
2338
    static CombinedArcMap<const FW, BK>
2339
    combinedArcMap(const FW& forward, BK& backward) {
2340
      return CombinedArcMap<const FW, BK>(forward, backward);
2341
    }
2342

	
2343
    template <typename FW, typename BK>
2344
    static CombinedArcMap<FW, const BK>
2345
    combinedArcMap(FW& forward, const BK& backward) {
2346
      return CombinedArcMap<FW, const BK>(forward, backward);
2347
    }
2348

	
2349
    template <typename FW, typename BK>
2350
    static CombinedArcMap<const FW, const BK>
2351
    combinedArcMap(const FW& forward, const BK& backward) {
2352
      return CombinedArcMap<const FW, const BK>(forward, backward);
2353
    }
2354

	
2355
  };
2356

	
2357
  /// \brief Returns a read-only Undirector adaptor
2358
  ///
2359
  /// This function just returns a read-only \ref Undirector adaptor.
2360
  /// \ingroup graph_adaptors
2361
  /// \relates Undirector
2362
  template<typename DGR>
2363
  Undirector<const DGR> undirector(const DGR& digraph) {
2364
    return Undirector<const DGR>(digraph);
2365
  }
2366

	
2367

	
2368
  template <typename GR, typename DM>
2369
  class OrienterBase {
2370
  public:
2371

	
2372
    typedef GR Graph;
2373
    typedef DM DirectionMap;
2374

	
2375
    typedef typename GR::Node Node;
2376
    typedef typename GR::Edge Arc;
2377

	
2378
    void reverseArc(const Arc& arc) {
2379
      _direction->set(arc, !(*_direction)[arc]);
2380
    }
2381

	
2382
    void first(Node& i) const { _graph->first(i); }
2383
    void first(Arc& i) const { _graph->first(i); }
2384
    void firstIn(Arc& i, const Node& n) const {
2385
      bool d = true;
2386
      _graph->firstInc(i, d, n);
2387
      while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
2388
    }
2389
    void firstOut(Arc& i, const Node& n ) const {
2390
      bool d = true;
2391
      _graph->firstInc(i, d, n);
2392
      while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
2393
    }
2394

	
2395
    void next(Node& i) const { _graph->next(i); }
2396
    void next(Arc& i) const { _graph->next(i); }
2397
    void nextIn(Arc& i) const {
2398
      bool d = !(*_direction)[i];
2399
      _graph->nextInc(i, d);
2400
      while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
2401
    }
2402
    void nextOut(Arc& i) const {
2403
      bool d = (*_direction)[i];
2404
      _graph->nextInc(i, d);
2405
      while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
2406
    }
2407

	
2408
    Node source(const Arc& e) const {
2409
      return (*_direction)[e] ? _graph->u(e) : _graph->v(e);
2410
    }
2411
    Node target(const Arc& e) const {
2412
      return (*_direction)[e] ? _graph->v(e) : _graph->u(e);
2413
    }
2414

	
2415
    typedef NodeNumTagIndicator<Graph> NodeNumTag;
2416
    int nodeNum() const { return _graph->nodeNum(); }
2417

	
2418
    typedef EdgeNumTagIndicator<Graph> ArcNumTag;
2419
    int arcNum() const { return _graph->edgeNum(); }
2420

	
2421
    typedef FindEdgeTagIndicator<Graph> FindArcTag;
2422
    Arc findArc(const Node& u, const Node& v,
2423
                const Arc& prev = INVALID) const {
2424
      Arc arc = _graph->findEdge(u, v, prev);
2425
      while (arc != INVALID && source(arc) != u) {
2426
        arc = _graph->findEdge(u, v, arc);
2427
      }
2428
      return arc;
2429
    }
2430

	
2431
    Node addNode() {
2432
      return Node(_graph->addNode());
2433
    }
2434

	
2435
    Arc addArc(const Node& u, const Node& v) {
2436
      Arc arc = _graph->addEdge(u, v);
2437
      _direction->set(arc, _graph->u(arc) == u);
2438
      return arc;
2439
    }
2440

	
2441
    void erase(const Node& i) { _graph->erase(i); }
2442
    void erase(const Arc& i) { _graph->erase(i); }
2443

	
2444
    void clear() { _graph->clear(); }
2445

	
2446
    int id(const Node& v) const { return _graph->id(v); }
2447
    int id(const Arc& e) const { return _graph->id(e); }
2448

	
2449
    Node nodeFromId(int idx) const { return _graph->nodeFromId(idx); }
2450
    Arc arcFromId(int idx) const { return _graph->edgeFromId(idx); }
2451

	
2452
    int maxNodeId() const { return _graph->maxNodeId(); }
2453
    int maxArcId() const { return _graph->maxEdgeId(); }
2454

	
2455
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
2456
    NodeNotifier& notifier(Node) const { return _graph->notifier(Node()); }
2457

	
2458
    typedef typename ItemSetTraits<GR, Arc>::ItemNotifier ArcNotifier;
2459
    ArcNotifier& notifier(Arc) const { return _graph->notifier(Arc()); }
2460

	
2461
    template <typename V>
2462
    class NodeMap : public GR::template NodeMap<V> {
2463
      typedef typename GR::template NodeMap<V> Parent;
2464

	
2465
    public:
2466

	
2467
      explicit NodeMap(const OrienterBase<GR, DM>& adapter)
2468
        : Parent(*adapter._graph) {}
2469

	
2470
      NodeMap(const OrienterBase<GR, DM>& adapter, const V& value)
2471
        : Parent(*adapter._graph, value) {}
2472

	
2473
    private:
2474
      NodeMap& operator=(const NodeMap& cmap) {
2475
        return operator=<NodeMap>(cmap);
2476
      }
2477

	
2478
      template <typename CMap>
2479
      NodeMap& operator=(const CMap& cmap) {
2480
        Parent::operator=(cmap);
2481
        return *this;
2482
      }
2483

	
2484
    };
2485

	
2486
    template <typename V>
2487
    class ArcMap : public GR::template EdgeMap<V> {
2488
      typedef typename Graph::template EdgeMap<V> Parent;
2489

	
2490
    public:
2491

	
2492
      explicit ArcMap(const OrienterBase<GR, DM>& adapter)
2493
        : Parent(*adapter._graph) { }
2494

	
2495
      ArcMap(const OrienterBase<GR, DM>& adapter, const V& value)
2496
        : Parent(*adapter._graph, value) { }
2497

	
2498
    private:
2499
      ArcMap& operator=(const ArcMap& cmap) {
2500
        return operator=<ArcMap>(cmap);
2501
      }
2502

	
2503
      template <typename CMap>
2504
      ArcMap& operator=(const CMap& cmap) {
2505
        Parent::operator=(cmap);
2506
        return *this;
2507
      }
2508
    };
2509

	
2510

	
2511

	
2512
  protected:
2513
    Graph* _graph;
2514
    DM* _direction;
2515

	
2516
    void initialize(GR& graph, DM& direction) {
2517
      _graph = &graph;
2518
      _direction = &direction;
2519
    }
2520

	
2521
  };
2522

	
2523
  /// \ingroup graph_adaptors
2524
  ///
2525
  /// \brief Adaptor class for orienting the edges of a graph to get a digraph
2526
  ///
2527
  /// Orienter adaptor can be used for orienting the edges of a graph to
2528
  /// get a digraph. A \c bool edge map of the underlying graph must be
2529
  /// specified, which define the direction of the arcs in the adaptor.
2530
  /// The arcs can be easily reversed by the \c reverseArc() member function
2531
  /// of the adaptor.
2532
  /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
2533
  ///
2534
  /// The adapted graph can also be modified through this adaptor
2535
  /// by adding or removing nodes or arcs, unless the \c GR template
2536
  /// parameter is set to be \c const.
2537
  ///
2538
  /// \tparam GR The type of the adapted graph.
2539
  /// It must conform to the \ref concepts::Graph "Graph" concept.
2540
  /// It can also be specified to be \c const.
2541
  /// \tparam DM The type of the direction map.
2542
  /// It must be a \c bool (or convertible) edge map of the
2543
  /// adapted graph. The default type is
2544
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<bool>".
2545
  ///
2546
  /// \note The \c Node type of this adaptor and the adapted graph are
2547
  /// convertible to each other, moreover the \c Arc type of the adaptor
2548
  /// and the \c Edge type of the adapted graph are also convertible to
2549
  /// each other.
2550
#ifdef DOXYGEN
2551
  template<typename GR,
2552
           typename DM>
2553
  class Orienter {
2554
#else
2555
  template<typename GR,
2556
           typename DM = typename GR::template EdgeMap<bool> >
2557
  class Orienter :
2558
    public DigraphAdaptorExtender<OrienterBase<GR, DM> > {
2559
#endif
2560
    typedef DigraphAdaptorExtender<OrienterBase<GR, DM> > Parent;
2561
  public:
2562

	
2563
    /// The type of the adapted graph.
2564
    typedef GR Graph;
2565
    /// The type of the direction edge map.
2566
    typedef DM DirectionMap;
2567

	
2568
    typedef typename Parent::Arc Arc;
2569

	
2570
  protected:
2571
    Orienter() { }
2572

	
2573
  public:
2574

	
2575
    /// \brief Constructor
2576
    ///
2577
    /// Constructor of the adaptor.
2578
    Orienter(GR& graph, DM& direction) {
2579
      Parent::initialize(graph, direction);
2580
    }
2581

	
2582
    /// \brief Reverses the given arc
2583
    ///
2584
    /// This function reverses the given arc.
2585
    /// It is done by simply negate the assigned value of \c a
2586
    /// in the direction map.
2587
    void reverseArc(const Arc& a) {
2588
      Parent::reverseArc(a);
2589
    }
2590
  };
2591

	
2592
  /// \brief Returns a read-only Orienter adaptor
2593
  ///
2594
  /// This function just returns a read-only \ref Orienter adaptor.
2595
  /// \ingroup graph_adaptors
2596
  /// \relates Orienter
2597
  template<typename GR, typename DM>
2598
  Orienter<const GR, DM>
2599
  orienter(const GR& graph, DM& direction) {
2600
    return Orienter<const GR, DM>(graph, direction);
2601
  }
2602

	
2603
  template<typename GR, typename DM>
2604
  Orienter<const GR, const DM>
2605
  orienter(const GR& graph, const DM& direction) {
2606
    return Orienter<const GR, const DM>(graph, direction);
2607
  }
2608

	
2609
  namespace _adaptor_bits {
2610

	
2611
    template <typename DGR, typename CM, typename FM, typename TL>
2612
    class ResForwardFilter {
2613
    public:
2614

	
2615
      typedef typename DGR::Arc Key;
2616
      typedef bool Value;
2617

	
2618
    private:
2619

	
2620
      const CM* _capacity;
2621
      const FM* _flow;
2622
      TL _tolerance;
2623

	
2624
    public:
2625

	
2626
      ResForwardFilter(const CM& capacity, const FM& flow,
2627
                       const TL& tolerance = TL())
2628
        : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
2629

	
2630
      bool operator[](const typename DGR::Arc& a) const {
2631
        return _tolerance.positive((*_capacity)[a] - (*_flow)[a]);
2632
      }
2633
    };
2634

	
2635
    template<typename DGR,typename CM, typename FM, typename TL>
2636
    class ResBackwardFilter {
2637
    public:
2638

	
2639
      typedef typename DGR::Arc Key;
2640
      typedef bool Value;
2641

	
2642
    private:
2643

	
2644
      const CM* _capacity;
2645
      const FM* _flow;
2646
      TL _tolerance;
2647

	
2648
    public:
2649

	
2650
      ResBackwardFilter(const CM& capacity, const FM& flow,
2651
                        const TL& tolerance = TL())
2652
        : _capacity(&capacity), _flow(&flow), _tolerance(tolerance) { }
2653

	
2654
      bool operator[](const typename DGR::Arc& a) const {
2655
        return _tolerance.positive((*_flow)[a]);
2656
      }
2657
    };
2658

	
2659
  }
2660

	
2661
  /// \ingroup graph_adaptors
2662
  ///
2663
  /// \brief Adaptor class for composing the residual digraph for directed
2664
  /// flow and circulation problems.
2665
  ///
2666
  /// ResidualDigraph can be used for composing the \e residual digraph
2667
  /// for directed flow and circulation problems. Let \f$ G=(V, A) \f$
2668
  /// be a directed graph and let \f$ F \f$ be a number type.
2669
  /// Let \f$ flow, cap: A\to F \f$ be functions on the arcs.
2670
  /// This adaptor implements a digraph structure with node set \f$ V \f$
2671
  /// and arc set \f$ A_{forward}\cup A_{backward} \f$,
2672
  /// where \f$ A_{forward}=\{uv : uv\in A, flow(uv)<cap(uv)\} \f$ and
2673
  /// \f$ A_{backward}=\{vu : uv\in A, flow(uv)>0\} \f$, i.e. the so
2674
  /// called residual digraph.
2675
  /// When the union \f$ A_{forward}\cup A_{backward} \f$ is taken,
2676
  /// multiplicities are counted, i.e. the adaptor has exactly
2677
  /// \f$ |A_{forward}| + |A_{backward}|\f$ arcs (it may have parallel
2678
  /// arcs).
2679
  /// This class conforms to the \ref concepts::Digraph "Digraph" concept.
2680
  ///
2681
  /// \tparam DGR The type of the adapted digraph.
2682
  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
2683
  /// It is implicitly \c const.
2684
  /// \tparam CM The type of the capacity map.
2685
  /// It must be an arc map of some numerical type, which defines
2686
  /// the capacities in the flow problem. It is implicitly \c const.
2687
  /// The default type is
2688
  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
2689
  /// \tparam FM The type of the flow map.
2690
  /// It must be an arc map of some numerical type, which defines
2691
  /// the flow values in the flow problem. The default type is \c CM.
2692
  /// \tparam TL The tolerance type for handling inexact computation.
2693
  /// The default tolerance type depends on the value type of the
2694
  /// capacity map.
2695
  ///
2696
  /// \note This adaptor is implemented using Undirector and FilterArcs
2697
  /// adaptors.
2698
  ///
2699
  /// \note The \c Node type of this adaptor and the adapted digraph are
2700
  /// convertible to each other, moreover the \c Arc type of the adaptor
2701
  /// is convertible to the \c Arc type of the adapted digraph.
2702
#ifdef DOXYGEN
2703
  template<typename DGR, typename CM, typename FM, typename TL>
2704
  class ResidualDigraph
2705
#else
2706
  template<typename DGR,
2707
           typename CM = typename DGR::template ArcMap<int>,
2708
           typename FM = CM,
2709
           typename TL = Tolerance<typename CM::Value> >
2710
  class ResidualDigraph 
2711
    : public SubDigraph<
2712
        Undirector<const DGR>,
2713
        ConstMap<typename DGR::Node, Const<bool, true> >,
2714
        typename Undirector<const DGR>::template CombinedArcMap<
2715
          _adaptor_bits::ResForwardFilter<const DGR, CM, FM, TL>,
2716
          _adaptor_bits::ResBackwardFilter<const DGR, CM, FM, TL> > >
2717
#endif
2718
  {
2719
  public:
2720

	
2721
    /// The type of the underlying digraph.
2722
    typedef DGR Digraph;
2723
    /// The type of the capacity map.
2724
    typedef CM CapacityMap;
2725
    /// The type of the flow map.
2726
    typedef FM FlowMap;
2727
    /// The tolerance type.
2728
    typedef TL Tolerance;
2729

	
2730
    typedef typename CapacityMap::Value Value;
2731
    typedef ResidualDigraph Adaptor;
2732

	
2733
  protected:
2734

	
2735
    typedef Undirector<const Digraph> Undirected;
2736

	
2737
    typedef ConstMap<typename DGR::Node, Const<bool, true> > NodeFilter;
2738

	
2739
    typedef _adaptor_bits::ResForwardFilter<const DGR, CM,
2740
                                            FM, TL> ForwardFilter;
2741

	
2742
    typedef _adaptor_bits::ResBackwardFilter<const DGR, CM,
2743
                                             FM, TL> BackwardFilter;
2744

	
2745
    typedef typename Undirected::
2746
      template CombinedArcMap<ForwardFilter, BackwardFilter> ArcFilter;
2747

	
2748
    typedef SubDigraph<Undirected, NodeFilter, ArcFilter> Parent;
2749

	
2750
    const CapacityMap* _capacity;
2751
    FlowMap* _flow;
2752

	
2753
    Undirected _graph;
2754
    NodeFilter _node_filter;
2755
    ForwardFilter _forward_filter;
2756
    BackwardFilter _backward_filter;
2757
    ArcFilter _arc_filter;
2758

	
2759
  public:
2760

	
2761
    /// \brief Constructor
2762
    ///
2763
    /// Constructor of the residual digraph adaptor. The parameters are the
2764
    /// digraph, the capacity map, the flow map, and a tolerance object.
2765
    ResidualDigraph(const DGR& digraph, const CM& capacity,
2766
                    FM& flow, const TL& tolerance = Tolerance())
2767
      : Parent(), _capacity(&capacity), _flow(&flow), 
2768
        _graph(digraph), _node_filter(),
2769
        _forward_filter(capacity, flow, tolerance),
2770
        _backward_filter(capacity, flow, tolerance),
2771
        _arc_filter(_forward_filter, _backward_filter)
2772
    {
2773
      Parent::initialize(_graph, _node_filter, _arc_filter);
2774
    }
2775

	
2776
    typedef typename Parent::Arc Arc;
2777

	
2778
    /// \brief Returns the residual capacity of the given arc.
2779
    ///
2780
    /// Returns the residual capacity of the given arc.
2781
    Value residualCapacity(const Arc& a) const {
2782
      if (Undirected::direction(a)) {
2783
        return (*_capacity)[a] - (*_flow)[a];
2784
      } else {
2785
        return (*_flow)[a];
2786
      }
2787
    }
2788

	
2789
    /// \brief Augments on the given arc in the residual digraph.
2790
    ///
2791
    /// Augments on the given arc in the residual digraph. It increases
2792
    /// or decreases the flow value on the original arc according to the
2793
    /// direction of the residual arc.
2794
    void augment(const Arc& a, const Value& v) const {
2795
      if (Undirected::direction(a)) {
2796
        _flow->set(a, (*_flow)[a] + v);
2797
      } else {
2798
        _flow->set(a, (*_flow)[a] - v);
2799
      }
2800
    }
2801

	
2802
    /// \brief Returns \c true if the given residual arc is a forward arc.
2803
    ///
2804
    /// Returns \c true if the given residual arc has the same orientation
2805
    /// as the original arc, i.e. it is a so called forward arc.
2806
    static bool forward(const Arc& a) {
2807
      return Undirected::direction(a);
2808
    }
2809

	
2810
    /// \brief Returns \c true if the given residual arc is a backward arc.
2811
    ///
2812
    /// Returns \c true if the given residual arc has the opposite orientation
2813
    /// than the original arc, i.e. it is a so called backward arc.
2814
    static bool backward(const Arc& a) {
2815
      return !Undirected::direction(a);
2816
    }
2817

	
2818
    /// \brief Returns the forward oriented residual arc.
2819
    ///
2820
    /// Returns the forward oriented residual arc related to the given
2821
    /// arc of the underlying digraph.
2822
    static Arc forward(const typename Digraph::Arc& a) {
2823
      return Undirected::direct(a, true);
2824
    }
2825

	
2826
    /// \brief Returns the backward oriented residual arc.
2827
    ///
2828
    /// Returns the backward oriented residual arc related to the given
2829
    /// arc of the underlying digraph.
2830
    static Arc backward(const typename Digraph::Arc& a) {
2831
      return Undirected::direct(a, false);
2832
    }
2833

	
2834
    /// \brief Residual capacity map.
2835
    ///
2836
    /// This map adaptor class can be used for obtaining the residual
2837
    /// capacities as an arc map of the residual digraph.
2838
    /// Its value type is inherited from the capacity map.
2839
    class ResidualCapacity {
2840
    protected:
2841
      const Adaptor* _adaptor;
2842
    public:
2843
      /// The key type of the map
2844
      typedef Arc Key;
2845
      /// The value type of the map
2846
      typedef typename CapacityMap::Value Value;
2847

	
2848
      /// Constructor
2849
      ResidualCapacity(const ResidualDigraph<DGR, CM, FM, TL>& adaptor) 
2850
        : _adaptor(&adaptor) {}
2851

	
2852
      /// Returns the value associated with the given residual arc
2853
      Value operator[](const Arc& a) const {
2854
        return _adaptor->residualCapacity(a);
2855
      }
2856

	
2857
    };
2858

	
2859
    /// \brief Returns a residual capacity map
2860
    ///
2861
    /// This function just returns a residual capacity map.
2862
    ResidualCapacity residualCapacity() const {
2863
      return ResidualCapacity(*this);
2864
    }
2865

	
2866
  };
2867

	
2868
  /// \brief Returns a (read-only) Residual adaptor
2869
  ///
2870
  /// This function just returns a (read-only) \ref ResidualDigraph adaptor.
2871
  /// \ingroup graph_adaptors
2872
  /// \relates ResidualDigraph
2873
    template<typename DGR, typename CM, typename FM>
2874
  ResidualDigraph<DGR, CM, FM>
2875
  residualDigraph(const DGR& digraph, const CM& capacity_map, FM& flow_map) {
2876
    return ResidualDigraph<DGR, CM, FM> (digraph, capacity_map, flow_map);
2877
  }
2878

	
2879

	
2880
  template <typename DGR>
2881
  class SplitNodesBase {
2882
    typedef DigraphAdaptorBase<const DGR> Parent;
2883

	
2884
  public:
2885

	
2886
    typedef DGR Digraph;
2887
    typedef SplitNodesBase Adaptor;
2888

	
2889
    typedef typename DGR::Node DigraphNode;
2890
    typedef typename DGR::Arc DigraphArc;
2891

	
2892
    class Node;
2893
    class Arc;
2894

	
2895
  private:
2896

	
2897
    template <typename T> class NodeMapBase;
2898
    template <typename T> class ArcMapBase;
2899

	
2900
  public:
2901

	
2902
    class Node : public DigraphNode {
2903
      friend class SplitNodesBase;
2904
      template <typename T> friend class NodeMapBase;
2905
    private:
2906

	
2907
      bool _in;
2908
      Node(DigraphNode node, bool in)
2909
        : DigraphNode(node), _in(in) {}
2910

	
2911
    public:
2912

	
2913
      Node() {}
2914
      Node(Invalid) : DigraphNode(INVALID), _in(true) {}
2915

	
2916
      bool operator==(const Node& node) const {
2917
        return DigraphNode::operator==(node) && _in == node._in;
2918
      }
2919

	
2920
      bool operator!=(const Node& node) const {
2921
        return !(*this == node);
2922
      }
2923

	
2924
      bool operator<(const Node& node) const {
2925
        return DigraphNode::operator<(node) ||
2926
          (DigraphNode::operator==(node) && _in < node._in);
2927
      }
2928
    };
2929

	
2930
    class Arc {
2931
      friend class SplitNodesBase;
2932
      template <typename T> friend class ArcMapBase;
2933
    private:
2934
      typedef BiVariant<DigraphArc, DigraphNode> ArcImpl;
2935

	
2936
      explicit Arc(const DigraphArc& arc) : _item(arc) {}
2937
      explicit Arc(const DigraphNode& node) : _item(node) {}
2938

	
2939
      ArcImpl _item;
2940

	
2941
    public:
2942
      Arc() {}
2943
      Arc(Invalid) : _item(DigraphArc(INVALID)) {}
2944

	
2945
      bool operator==(const Arc& arc) const {
2946
        if (_item.firstState()) {
2947
          if (arc._item.firstState()) {
2948
            return _item.first() == arc._item.first();
2949
          }
2950
        } else {
2951
          if (arc._item.secondState()) {
2952
            return _item.second() == arc._item.second();
2953
          }
2954
        }
2955
        return false;
2956
      }
2957

	
2958
      bool operator!=(const Arc& arc) const {
2959
        return !(*this == arc);
2960
      }
2961

	
2962
      bool operator<(const Arc& arc) const {
2963
        if (_item.firstState()) {
2964
          if (arc._item.firstState()) {
2965
            return _item.first() < arc._item.first();
2966
          }
2967
          return false;
2968
        } else {
2969
          if (arc._item.secondState()) {
2970
            return _item.second() < arc._item.second();
2971
          }
2972
          return true;
2973
        }
2974
      }
2975

	
2976
      operator DigraphArc() const { return _item.first(); }
2977
      operator DigraphNode() const { return _item.second(); }
2978

	
2979
    };
2980

	
2981
    void first(Node& n) const {
2982
      _digraph->first(n);
2983
      n._in = true;
2984
    }
2985

	
2986
    void next(Node& n) const {
2987
      if (n._in) {
2988
        n._in = false;
2989
      } else {
2990
        n._in = true;
2991
        _digraph->next(n);
2992
      }
2993
    }
2994

	
2995
    void first(Arc& e) const {
2996
      e._item.setSecond();
2997
      _digraph->first(e._item.second());
2998
      if (e._item.second() == INVALID) {
2999
        e._item.setFirst();
3000
        _digraph->first(e._item.first());
3001
      }
3002
    }
3003

	
3004
    void next(Arc& e) const {
3005
      if (e._item.secondState()) {
3006
        _digraph->next(e._item.second());
3007
        if (e._item.second() == INVALID) {
3008
          e._item.setFirst();
3009
          _digraph->first(e._item.first());
3010
        }
3011
      } else {
3012
        _digraph->next(e._item.first());
3013
      }
3014
    }
3015

	
3016
    void firstOut(Arc& e, const Node& n) const {
3017
      if (n._in) {
3018
        e._item.setSecond(n);
3019
      } else {
3020
        e._item.setFirst();
3021
        _digraph->firstOut(e._item.first(), n);
3022
      }
3023
    }
3024

	
3025
    void nextOut(Arc& e) const {
3026
      if (!e._item.firstState()) {
3027
        e._item.setFirst(INVALID);
3028
      } else {
3029
        _digraph->nextOut(e._item.first());
3030
      }
3031
    }
3032

	
3033
    void firstIn(Arc& e, const Node& n) const {
3034
      if (!n._in) {
3035
        e._item.setSecond(n);
3036
      } else {
3037
        e._item.setFirst();
3038
        _digraph->firstIn(e._item.first(), n);
3039
      }
3040
    }
3041

	
3042
    void nextIn(Arc& e) const {
3043
      if (!e._item.firstState()) {
3044
        e._item.setFirst(INVALID);
3045
      } else {
3046
        _digraph->nextIn(e._item.first());
3047
      }
3048
    }
3049

	
3050
    Node source(const Arc& e) const {
3051
      if (e._item.firstState()) {
3052
        return Node(_digraph->source(e._item.first()), false);
3053
      } else {
3054
        return Node(e._item.second(), true);
3055
      }
3056
    }
3057

	
3058
    Node target(const Arc& e) const {
3059
      if (e._item.firstState()) {
3060
        return Node(_digraph->target(e._item.first()), true);
3061
      } else {
3062
        return Node(e._item.second(), false);
3063
      }
3064
    }
3065

	
3066
    int id(const Node& n) const {
3067
      return (_digraph->id(n) << 1) | (n._in ? 0 : 1);
3068
    }
3069
    Node nodeFromId(int ix) const {
3070
      return Node(_digraph->nodeFromId(ix >> 1), (ix & 1) == 0);
3071
    }
3072
    int maxNodeId() const {
3073
      return 2 * _digraph->maxNodeId() + 1;
3074
    }
3075

	
3076
    int id(const Arc& e) const {
3077
      if (e._item.firstState()) {
3078
        return _digraph->id(e._item.first()) << 1;
3079
      } else {
3080
        return (_digraph->id(e._item.second()) << 1) | 1;
3081
      }
3082
    }
3083
    Arc arcFromId(int ix) const {
3084
      if ((ix & 1) == 0) {
3085
        return Arc(_digraph->arcFromId(ix >> 1));
3086
      } else {
3087
        return Arc(_digraph->nodeFromId(ix >> 1));
3088
      }
3089
    }
3090
    int maxArcId() const {
3091
      return std::max(_digraph->maxNodeId() << 1,
3092
                      (_digraph->maxArcId() << 1) | 1);
3093
    }
3094

	
3095
    static bool inNode(const Node& n) {
3096
      return n._in;
3097
    }
3098

	
3099
    static bool outNode(const Node& n) {
3100
      return !n._in;
3101
    }
3102

	
3103
    static bool origArc(const Arc& e) {
3104
      return e._item.firstState();
3105
    }
3106

	
3107
    static bool bindArc(const Arc& e) {
3108
      return e._item.secondState();
3109
    }
3110

	
3111
    static Node inNode(const DigraphNode& n) {
3112
      return Node(n, true);
3113
    }
3114

	
3115
    static Node outNode(const DigraphNode& n) {
3116
      return Node(n, false);
3117
    }
3118

	
3119
    static Arc arc(const DigraphNode& n) {
3120
      return Arc(n);
3121
    }
3122

	
3123
    static Arc arc(const DigraphArc& e) {
3124
      return Arc(e);
3125
    }
3126

	
3127
    typedef True NodeNumTag;
3128
    int nodeNum() const {
3129
      return  2 * countNodes(*_digraph);
3130
    }
3131

	
3132
    typedef True ArcNumTag;
3133
    int arcNum() const {
3134
      return countArcs(*_digraph) + countNodes(*_digraph);
3135
    }
3136

	
3137
    typedef True FindArcTag;
3138
    Arc findArc(const Node& u, const Node& v,
3139
                const Arc& prev = INVALID) const {
3140
      if (inNode(u) && outNode(v)) {
3141
        if (static_cast<const DigraphNode&>(u) ==
3142
            static_cast<const DigraphNode&>(v) && prev == INVALID) {
3143
          return Arc(u);
3144
        }
3145
      }
3146
      else if (outNode(u) && inNode(v)) {
3147
        return Arc(::lemon::findArc(*_digraph, u, v, prev));
3148
      }
3149
      return INVALID;
3150
    }
3151

	
3152
  private:
3153

	
3154
    template <typename V>
3155
    class NodeMapBase
3156
      : public MapTraits<typename Parent::template NodeMap<V> > {
3157
      typedef typename Parent::template NodeMap<V> NodeImpl;
3158
    public:
3159
      typedef Node Key;
3160
      typedef V Value;
3161
      typedef typename MapTraits<NodeImpl>::ReferenceMapTag ReferenceMapTag;
3162
      typedef typename MapTraits<NodeImpl>::ReturnValue ReturnValue;
3163
      typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReturnValue;
3164
      typedef typename MapTraits<NodeImpl>::ReturnValue Reference;
3165
      typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReference;
3166

	
3167
      NodeMapBase(const SplitNodesBase<DGR>& adaptor)
3168
        : _in_map(*adaptor._digraph), _out_map(*adaptor._digraph) {}
3169
      NodeMapBase(const SplitNodesBase<DGR>& adaptor, const V& value)
3170
        : _in_map(*adaptor._digraph, value),
3171
          _out_map(*adaptor._digraph, value) {}
3172

	
3173
      void set(const Node& key, const V& val) {
3174
        if (SplitNodesBase<DGR>::inNode(key)) { _in_map.set(key, val); }
3175
        else {_out_map.set(key, val); }
3176
      }
3177

	
3178
      ReturnValue operator[](const Node& key) {
3179
        if (SplitNodesBase<DGR>::inNode(key)) { return _in_map[key]; }
3180
        else { return _out_map[key]; }
3181
      }
3182

	
3183
      ConstReturnValue operator[](const Node& key) const {
3184
        if (Adaptor::inNode(key)) { return _in_map[key]; }
3185
        else { return _out_map[key]; }
3186
      }
3187

	
3188
    private:
3189
      NodeImpl _in_map, _out_map;
3190
    };
3191

	
3192
    template <typename V>
3193
    class ArcMapBase
3194
      : public MapTraits<typename Parent::template ArcMap<V> > {
3195
      typedef typename Parent::template ArcMap<V> ArcImpl;
3196
      typedef typename Parent::template NodeMap<V> NodeImpl;
3197
    public:
3198
      typedef Arc Key;
3199
      typedef V Value;
3200
      typedef typename MapTraits<ArcImpl>::ReferenceMapTag ReferenceMapTag;
3201
      typedef typename MapTraits<ArcImpl>::ReturnValue ReturnValue;
3202
      typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReturnValue;
3203
      typedef typename MapTraits<ArcImpl>::ReturnValue Reference;
3204
      typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReference;
3205

	
3206
      ArcMapBase(const SplitNodesBase<DGR>& adaptor)
3207
        : _arc_map(*adaptor._digraph), _node_map(*adaptor._digraph) {}
3208
      ArcMapBase(const SplitNodesBase<DGR>& adaptor, const V& value)
3209
        : _arc_map(*adaptor._digraph, value),
3210
          _node_map(*adaptor._digraph, value) {}
3211

	
3212
      void set(const Arc& key, const V& val) {
3213
        if (SplitNodesBase<DGR>::origArc(key)) {
3214
          _arc_map.set(static_cast<const DigraphArc&>(key), val);
3215
        } else {
3216
          _node_map.set(static_cast<const DigraphNode&>(key), val);
3217
        }
3218
      }
3219

	
3220
      ReturnValue operator[](const Arc& key) {
3221
        if (SplitNodesBase<DGR>::origArc(key)) {
3222
          return _arc_map[static_cast<const DigraphArc&>(key)];
3223
        } else {
3224
          return _node_map[static_cast<const DigraphNode&>(key)];
3225
        }
3226
      }
3227

	
3228
      ConstReturnValue operator[](const Arc& key) const {
3229
        if (SplitNodesBase<DGR>::origArc(key)) {
3230
          return _arc_map[static_cast<const DigraphArc&>(key)];
3231
        } else {
3232
          return _node_map[static_cast<const DigraphNode&>(key)];
3233
        }
3234
      }
3235

	
3236
    private:
3237
      ArcImpl _arc_map;
3238
      NodeImpl _node_map;
3239
    };
3240

	
3241
  public:
3242

	
3243
    template <typename V>
3244
    class NodeMap
3245
      : public SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> > {
3246
      typedef SubMapExtender<SplitNodesBase<DGR>, NodeMapBase<V> > Parent;
3247

	
3248
    public:
3249
      typedef V Value;
3250

	
3251
      NodeMap(const SplitNodesBase<DGR>& adaptor)
3252
        : Parent(adaptor) {}
3253

	
3254
      NodeMap(const SplitNodesBase<DGR>& adaptor, const V& value)
3255
        : Parent(adaptor, value) {}
3256

	
3257
    private:
3258
      NodeMap& operator=(const NodeMap& cmap) {
3259
        return operator=<NodeMap>(cmap);
3260
      }
3261

	
3262
      template <typename CMap>
3263
      NodeMap& operator=(const CMap& cmap) {
3264
        Parent::operator=(cmap);
3265
        return *this;
3266
      }
3267
    };
3268

	
3269
    template <typename V>
3270
    class ArcMap
3271
      : public SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> > {
3272
      typedef SubMapExtender<SplitNodesBase<DGR>, ArcMapBase<V> > Parent;
3273

	
3274
    public:
3275
      typedef V Value;
3276

	
3277
      ArcMap(const SplitNodesBase<DGR>& adaptor)
3278
        : Parent(adaptor) {}
3279

	
3280
      ArcMap(const SplitNodesBase<DGR>& adaptor, const V& value)
3281
        : Parent(adaptor, value) {}
3282

	
3283
    private:
3284
      ArcMap& operator=(const ArcMap& cmap) {
3285
        return operator=<ArcMap>(cmap);
3286
      }
3287

	
3288
      template <typename CMap>
3289
      ArcMap& operator=(const CMap& cmap) {
3290
        Parent::operator=(cmap);
3291
        return *this;
3292
      }
3293
    };
3294

	
3295
  protected:
3296

	
3297
    SplitNodesBase() : _digraph(0) {}
3298

	
3299
    DGR* _digraph;
3300

	
3301
    void initialize(Digraph& digraph) {
3302
      _digraph = &digraph;
3303
    }
3304

	
3305
  };
3306

	
3307
  /// \ingroup graph_adaptors
3308
  ///
3309
  /// \brief Adaptor class for splitting the nodes of a digraph.
3310
  ///
3311
  /// SplitNodes adaptor can be used for splitting each node into an
3312
  /// \e in-node and an \e out-node in a digraph. Formaly, the adaptor
3313
  /// replaces each node \f$ u \f$ in the digraph with two nodes,
3314
  /// namely node \f$ u_{in} \f$ and node \f$ u_{out} \f$.
3315
  /// If there is a \f$ (v, u) \f$ arc in the original digraph, then the
3316
  /// new target of the arc will be \f$ u_{in} \f$ and similarly the
3317
  /// source of each original \f$ (u, v) \f$ arc will be \f$ u_{out} \f$.
3318
  /// The adaptor adds an additional \e bind \e arc from \f$ u_{in} \f$
3319
  /// to \f$ u_{out} \f$ for each node \f$ u \f$ of the original digraph.
3320
  ///
3321
  /// The aim of this class is running an algorithm with respect to node
3322
  /// costs or capacities if the algorithm considers only arc costs or
3323
  /// capacities directly.
3324
  /// In this case you can use \c SplitNodes adaptor, and set the node
3325
  /// costs/capacities of the original digraph to the \e bind \e arcs
3326
  /// in the adaptor.
3327
  ///
3328
  /// \tparam DGR The type of the adapted digraph.
3329
  /// It must conform to the \ref concepts::Digraph "Digraph" concept.
3330
  /// It is implicitly \c const.
3331
  ///
3332
  /// \note The \c Node type of this adaptor is converible to the \c Node
3333
  /// type of the adapted digraph.
3334
  template <typename DGR>
3335
#ifdef DOXYGEN
3336
  class SplitNodes {
3337
#else
3338
  class SplitNodes
3339
    : public DigraphAdaptorExtender<SplitNodesBase<const DGR> > {
3340
#endif
3341
    typedef DigraphAdaptorExtender<SplitNodesBase<const DGR> > Parent;
3342

	
3343
  public:
3344
    typedef DGR Digraph;
3345

	
3346
    typedef typename DGR::Node DigraphNode;
3347
    typedef typename DGR::Arc DigraphArc;
3348

	
3349
    typedef typename Parent::Node Node;
3350
    typedef typename Parent::Arc Arc;
3351

	
3352
    /// \brief Constructor
3353
    ///
3354
    /// Constructor of the adaptor.
3355
    SplitNodes(const DGR& g) {
3356
      Parent::initialize(g);
3357
    }
3358

	
3359
    /// \brief Returns \c true if the given node is an in-node.
3360
    ///
3361
    /// Returns \c true if the given node is an in-node.
3362
    static bool inNode(const Node& n) {
3363
      return Parent::inNode(n);
3364
    }
3365

	
3366
    /// \brief Returns \c true if the given node is an out-node.
3367
    ///
3368
    /// Returns \c true if the given node is an out-node.
3369
    static bool outNode(const Node& n) {
3370
      return Parent::outNode(n);
3371
    }
3372

	
3373
    /// \brief Returns \c true if the given arc is an original arc.
3374
    ///
3375
    /// Returns \c true if the given arc is one of the arcs in the
3376
    /// original digraph.
3377
    static bool origArc(const Arc& a) {
3378
      return Parent::origArc(a);
3379
    }
3380

	
3381
    /// \brief Returns \c true if the given arc is a bind arc.
3382
    ///
3383
    /// Returns \c true if the given arc is a bind arc, i.e. it connects
3384
    /// an in-node and an out-node.
3385
    static bool bindArc(const Arc& a) {
3386
      return Parent::bindArc(a);
3387
    }
3388

	
3389
    /// \brief Returns the in-node created from the given original node.
3390
    ///
3391
    /// Returns the in-node created from the given original node.
3392
    static Node inNode(const DigraphNode& n) {
3393
      return Parent::inNode(n);
3394
    }
3395

	
3396
    /// \brief Returns the out-node created from the given original node.
3397
    ///
3398
    /// Returns the out-node created from the given original node.
3399
    static Node outNode(const DigraphNode& n) {
3400
      return Parent::outNode(n);
3401
    }
3402

	
3403
    /// \brief Returns the bind arc that corresponds to the given
3404
    /// original node.
3405
    ///
3406
    /// Returns the bind arc in the adaptor that corresponds to the given
3407
    /// original node, i.e. the arc connecting the in-node and out-node
3408
    /// of \c n.
3409
    static Arc arc(const DigraphNode& n) {
3410
      return Parent::arc(n);
3411
    }
3412

	
3413
    /// \brief Returns the arc that corresponds to the given original arc.
3414
    ///
3415
    /// Returns the arc in the adaptor that corresponds to the given
3416
    /// original arc.
3417
    static Arc arc(const DigraphArc& a) {
3418
      return Parent::arc(a);
3419
    }
3420

	
3421
    /// \brief Node map combined from two original node maps
3422
    ///
3423
    /// This map adaptor class adapts two node maps of the original digraph
3424
    /// to get a node map of the split digraph.
3425
    /// Its value type is inherited from the first node map type (\c IN).
3426
    /// \tparam IN The type of the node map for the in-nodes. 
3427
    /// \tparam OUT The type of the node map for the out-nodes.
3428
    template <typename IN, typename OUT>
3429
    class CombinedNodeMap {
3430
    public:
3431

	
3432
      /// The key type of the map
3433
      typedef Node Key;
3434
      /// The value type of the map
3435
      typedef typename IN::Value Value;
3436

	
3437
      typedef typename MapTraits<IN>::ReferenceMapTag ReferenceMapTag;
3438
      typedef typename MapTraits<IN>::ReturnValue ReturnValue;
3439
      typedef typename MapTraits<IN>::ConstReturnValue ConstReturnValue;
3440
      typedef typename MapTraits<IN>::ReturnValue Reference;
3441
      typedef typename MapTraits<IN>::ConstReturnValue ConstReference;
3442

	
3443
      /// Constructor
3444
      CombinedNodeMap(IN& in_map, OUT& out_map)
3445
        : _in_map(in_map), _out_map(out_map) {}
3446

	
3447
      /// Returns the value associated with the given key.
3448
      Value operator[](const Key& key) const {
3449
        if (SplitNodesBase<const DGR>::inNode(key)) {
3450
          return _in_map[key];
3451
        } else {
3452
          return _out_map[key];
3453
        }
3454
      }
3455

	
3456
      /// Returns a reference to the value associated with the given key.
3457
      Value& operator[](const Key& key) {
3458
        if (SplitNodesBase<const DGR>::inNode(key)) {
3459
          return _in_map[key];
3460
        } else {
3461
          return _out_map[key];
3462
        }
3463
      }
3464

	
3465
      /// Sets the value associated with the given key.
3466
      void set(const Key& key, const Value& value) {
3467
        if (SplitNodesBase<const DGR>::inNode(key)) {
3468
          _in_map.set(key, value);
3469
        } else {
3470
          _out_map.set(key, value);
3471
        }
3472
      }
3473

	
3474
    private:
3475

	
3476
      IN& _in_map;
3477
      OUT& _out_map;
3478

	
3479
    };
3480

	
3481

	
3482
    /// \brief Returns a combined node map
3483
    ///
3484
    /// This function just returns a combined node map.
3485
    template <typename IN, typename OUT>
3486
    static CombinedNodeMap<IN, OUT>
3487
    combinedNodeMap(IN& in_map, OUT& out_map) {
3488
      return CombinedNodeMap<IN, OUT>(in_map, out_map);
3489
    }
3490

	
3491
    template <typename IN, typename OUT>
3492
    static CombinedNodeMap<const IN, OUT>
3493
    combinedNodeMap(const IN& in_map, OUT& out_map) {
3494
      return CombinedNodeMap<const IN, OUT>(in_map, out_map);
3495
    }
3496

	
3497
    template <typename IN, typename OUT>
3498
    static CombinedNodeMap<IN, const OUT>
3499
    combinedNodeMap(IN& in_map, const OUT& out_map) {
3500
      return CombinedNodeMap<IN, const OUT>(in_map, out_map);
3501
    }
3502

	
3503
    template <typename IN, typename OUT>
3504
    static CombinedNodeMap<const IN, const OUT>
3505
    combinedNodeMap(const IN& in_map, const OUT& out_map) {
3506
      return CombinedNodeMap<const IN, const OUT>(in_map, out_map);
3507
    }
3508

	
3509
    /// \brief Arc map combined from an arc map and a node map of the
3510
    /// original digraph.
3511
    ///
3512
    /// This map adaptor class adapts an arc map and a node map of the
3513
    /// original digraph to get an arc map of the split digraph.
3514
    /// Its value type is inherited from the original arc map type (\c AM).
3515
    /// \tparam AM The type of the arc map.
3516
    /// \tparam NM the type of the node map.
3517
    template <typename AM, typename NM>
3518
    class CombinedArcMap {
3519
    public:
3520

	
3521
      /// The key type of the map
3522
      typedef Arc Key;
3523
      /// The value type of the map
3524
      typedef typename AM::Value Value;
3525

	
3526
      typedef typename MapTraits<AM>::ReferenceMapTag ReferenceMapTag;
3527
      typedef typename MapTraits<AM>::ReturnValue ReturnValue;
3528
      typedef typename MapTraits<AM>::ConstReturnValue ConstReturnValue;
3529
      typedef typename MapTraits<AM>::ReturnValue Reference;
3530
      typedef typename MapTraits<AM>::ConstReturnValue ConstReference;
3531

	
3532
      /// Constructor
3533
      CombinedArcMap(AM& arc_map, NM& node_map)
3534
        : _arc_map(arc_map), _node_map(node_map) {}
3535

	
3536
      /// Returns the value associated with the given key.
3537
      Value operator[](const Key& arc) const {
3538
        if (SplitNodesBase<const DGR>::origArc(arc)) {
3539
          return _arc_map[arc];
3540
        } else {
3541
          return _node_map[arc];
3542
        }
3543
      }
3544

	
3545
      /// Returns a reference to the value associated with the given key.
3546
      Value& operator[](const Key& arc) {
3547
        if (SplitNodesBase<const DGR>::origArc(arc)) {
3548
          return _arc_map[arc];
3549
        } else {
3550
          return _node_map[arc];
3551
        }
3552
      }
3553

	
3554
      /// Sets the value associated with the given key.
3555
      void set(const Arc& arc, const Value& val) {
3556
        if (SplitNodesBase<const DGR>::origArc(arc)) {
3557
          _arc_map.set(arc, val);
3558
        } else {
3559
          _node_map.set(arc, val);
3560
        }
3561
      }
3562

	
3563
    private:
3564

	
3565
      AM& _arc_map;
3566
      NM& _node_map;
3567

	
3568
    };
3569

	
3570
    /// \brief Returns a combined arc map
3571
    ///
3572
    /// This function just returns a combined arc map.
3573
    template <typename ArcMap, typename NodeMap>
3574
    static CombinedArcMap<ArcMap, NodeMap>
3575
    combinedArcMap(ArcMap& arc_map, NodeMap& node_map) {
3576
      return CombinedArcMap<ArcMap, NodeMap>(arc_map, node_map);
3577
    }
3578

	
3579
    template <typename ArcMap, typename NodeMap>
3580
    static CombinedArcMap<const ArcMap, NodeMap>
3581
    combinedArcMap(const ArcMap& arc_map, NodeMap& node_map) {
3582
      return CombinedArcMap<const ArcMap, NodeMap>(arc_map, node_map);
3583
    }
3584

	
3585
    template <typename ArcMap, typename NodeMap>
3586
    static CombinedArcMap<ArcMap, const NodeMap>
3587
    combinedArcMap(ArcMap& arc_map, const NodeMap& node_map) {
3588
      return CombinedArcMap<ArcMap, const NodeMap>(arc_map, node_map);
3589
    }
3590

	
3591
    template <typename ArcMap, typename NodeMap>
3592
    static CombinedArcMap<const ArcMap, const NodeMap>
3593
    combinedArcMap(const ArcMap& arc_map, const NodeMap& node_map) {
3594
      return CombinedArcMap<const ArcMap, const NodeMap>(arc_map, node_map);
3595
    }
3596

	
3597
  };
3598

	
3599
  /// \brief Returns a (read-only) SplitNodes adaptor
3600
  ///
3601
  /// This function just returns a (read-only) \ref SplitNodes adaptor.
3602
  /// \ingroup graph_adaptors
3603
  /// \relates SplitNodes
3604
  template<typename DGR>
3605
  SplitNodes<DGR>
3606
  splitNodes(const DGR& digraph) {
3607
    return SplitNodes<DGR>(digraph);
3608
  }
3609

	
3610
#undef LEMON_SCOPE_FIX
3611

	
3612
} //namespace lemon
3613

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

	
19
#ifndef LEMON_BITS_EDGE_SET_EXTENDER_H
20
#define LEMON_BITS_EDGE_SET_EXTENDER_H
21

	
22
#include <lemon/core.h>
23
#include <lemon/error.h>
24
#include <lemon/bits/default_map.h>
25
#include <lemon/bits/map_extender.h>
26

	
27
//\ingroup digraphbits
28
//\file
29
//\brief Extenders for the arc set types
30
namespace lemon {
31

	
32
  // \ingroup digraphbits
33
  //
34
  // \brief Extender for the ArcSets
35
  template <typename Base>
36
  class ArcSetExtender : public Base {
37
    typedef Base Parent;
38

	
39
  public:
40

	
41
    typedef ArcSetExtender Digraph;
42

	
43
    // Base extensions
44

	
45
    typedef typename Parent::Node Node;
46
    typedef typename Parent::Arc Arc;
47

	
48
    int maxId(Node) const {
49
      return Parent::maxNodeId();
50
    }
51

	
52
    int maxId(Arc) const {
53
      return Parent::maxArcId();
54
    }
55

	
56
    Node fromId(int id, Node) const {
57
      return Parent::nodeFromId(id);
58
    }
59

	
60
    Arc fromId(int id, Arc) const {
61
      return Parent::arcFromId(id);
62
    }
63

	
64
    Node oppositeNode(const Node &n, const Arc &e) const {
65
      if (n == Parent::source(e))
66
	return Parent::target(e);
67
      else if(n==Parent::target(e))
68
	return Parent::source(e);
69
      else
70
	return INVALID;
71
    }
72

	
73

	
74
    // Alteration notifier extensions
75

	
76
    // The arc observer registry.
77
    typedef AlterationNotifier<ArcSetExtender, Arc> ArcNotifier;
78

	
79
  protected:
80

	
81
    mutable ArcNotifier arc_notifier;
82

	
83
  public:
84

	
85
    using Parent::notifier;
86

	
87
    // Gives back the arc alteration notifier.
88
    ArcNotifier& notifier(Arc) const {
89
      return arc_notifier;
90
    }
91

	
92
    // Iterable extensions
93

	
94
    class NodeIt : public Node { 
95
      const Digraph* digraph;
96
    public:
97

	
98
      NodeIt() {}
99

	
100
      NodeIt(Invalid i) : Node(i) { }
101

	
102
      explicit NodeIt(const Digraph& _graph) : digraph(&_graph) {
103
	_graph.first(static_cast<Node&>(*this));
104
      }
105

	
106
      NodeIt(const Digraph& _graph, const Node& node) 
107
	: Node(node), digraph(&_graph) {}
108

	
109
      NodeIt& operator++() { 
110
	digraph->next(*this);
111
	return *this; 
112
      }
113

	
114
    };
115

	
116

	
117
    class ArcIt : public Arc { 
118
      const Digraph* digraph;
119
    public:
120

	
121
      ArcIt() { }
122

	
123
      ArcIt(Invalid i) : Arc(i) { }
124

	
125
      explicit ArcIt(const Digraph& _graph) : digraph(&_graph) {
126
	_graph.first(static_cast<Arc&>(*this));
127
      }
128

	
129
      ArcIt(const Digraph& _graph, const Arc& e) : 
130
	Arc(e), digraph(&_graph) { }
131

	
132
      ArcIt& operator++() { 
133
	digraph->next(*this);
134
	return *this; 
135
      }
136

	
137
    };
138

	
139

	
140
    class OutArcIt : public Arc { 
141
      const Digraph* digraph;
142
    public:
143

	
144
      OutArcIt() { }
145

	
146
      OutArcIt(Invalid i) : Arc(i) { }
147

	
148
      OutArcIt(const Digraph& _graph, const Node& node) 
149
	: digraph(&_graph) {
150
	_graph.firstOut(*this, node);
151
      }
152

	
153
      OutArcIt(const Digraph& _graph, const Arc& arc) 
154
	: Arc(arc), digraph(&_graph) {}
155

	
156
      OutArcIt& operator++() { 
157
	digraph->nextOut(*this);
158
	return *this; 
159
      }
160

	
161
    };
162

	
163

	
164
    class InArcIt : public Arc { 
165
      const Digraph* digraph;
166
    public:
167

	
168
      InArcIt() { }
169

	
170
      InArcIt(Invalid i) : Arc(i) { }
171

	
172
      InArcIt(const Digraph& _graph, const Node& node) 
173
	: digraph(&_graph) {
174
	_graph.firstIn(*this, node);
175
      }
176

	
177
      InArcIt(const Digraph& _graph, const Arc& arc) : 
178
	Arc(arc), digraph(&_graph) {}
179

	
180
      InArcIt& operator++() { 
181
	digraph->nextIn(*this);
182
	return *this; 
183
      }
184

	
185
    };
186

	
187
    // \brief Base node of the iterator
188
    //
189
    // Returns the base node (ie. the source in this case) of the iterator
190
    Node baseNode(const OutArcIt &e) const {
191
      return Parent::source(static_cast<const Arc&>(e));
192
    }
193
    // \brief Running node of the iterator
194
    //
195
    // Returns the running node (ie. the target in this case) of the
196
    // iterator
197
    Node runningNode(const OutArcIt &e) const {
198
      return Parent::target(static_cast<const Arc&>(e));
199
    }
200

	
201
    // \brief Base node of the iterator
202
    //
203
    // Returns the base node (ie. the target in this case) of the iterator
204
    Node baseNode(const InArcIt &e) const {
205
      return Parent::target(static_cast<const Arc&>(e));
206
    }
207
    // \brief Running node of the iterator
208
    //
209
    // Returns the running node (ie. the source in this case) of the
210
    // iterator
211
    Node runningNode(const InArcIt &e) const {
212
      return Parent::source(static_cast<const Arc&>(e));
213
    }
214

	
215
    using Parent::first;
216

	
217
    // Mappable extension
218
    
219
    template <typename _Value>
220
    class ArcMap 
221
      : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
222
      typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
223

	
224
    public:
225
      explicit ArcMap(const Digraph& _g) 
226
	: Parent(_g) {}
227
      ArcMap(const Digraph& _g, const _Value& _v) 
228
	: Parent(_g, _v) {}
229

	
230
      ArcMap& operator=(const ArcMap& cmap) {
231
	return operator=<ArcMap>(cmap);
232
      }
233

	
234
      template <typename CMap>
235
      ArcMap& operator=(const CMap& cmap) {
236
        Parent::operator=(cmap);
237
	return *this;
238
      }
239

	
240
    };
241

	
242

	
243
    // Alteration extension
244

	
245
    Arc addArc(const Node& from, const Node& to) {
246
      Arc arc = Parent::addArc(from, to);
247
      notifier(Arc()).add(arc);
248
      return arc;
249
    }
250
    
251
    void clear() {
252
      notifier(Arc()).clear();
253
      Parent::clear();
254
    }
255

	
256
    void erase(const Arc& arc) {
257
      notifier(Arc()).erase(arc);
258
      Parent::erase(arc);
259
    }
260

	
261
    ArcSetExtender() {
262
      arc_notifier.setContainer(*this);
263
    }
264

	
265
    ~ArcSetExtender() {
266
      arc_notifier.clear();
267
    }
268

	
269
  };
270

	
271

	
272
  // \ingroup digraphbits
273
  //
274
  // \brief Extender for the EdgeSets
275
  template <typename Base>
276
  class EdgeSetExtender : public Base {
277
    typedef Base Parent;
278

	
279
  public:
280

	
281
    typedef EdgeSetExtender Graph;
282

	
283
    typedef typename Parent::Node Node;
284
    typedef typename Parent::Arc Arc;
285
    typedef typename Parent::Edge Edge;
286

	
287
    int maxId(Node) const {
288
      return Parent::maxNodeId();
289
    }
290

	
291
    int maxId(Arc) const {
292
      return Parent::maxArcId();
293
    }
294

	
295
    int maxId(Edge) const {
296
      return Parent::maxEdgeId();
297
    }
298

	
299
    Node fromId(int id, Node) const {
300
      return Parent::nodeFromId(id);
301
    }
302

	
303
    Arc fromId(int id, Arc) const {
304
      return Parent::arcFromId(id);
305
    }
306

	
307
    Edge fromId(int id, Edge) const {
308
      return Parent::edgeFromId(id);
309
    }
310

	
311
    Node oppositeNode(const Node &n, const Edge &e) const {
312
      if( n == Parent::u(e))
313
	return Parent::v(e);
314
      else if( n == Parent::v(e))
315
	return Parent::u(e);
316
      else
317
	return INVALID;
318
    }
319

	
320
    Arc oppositeArc(const Arc &e) const {
321
      return Parent::direct(e, !Parent::direction(e));
322
    }
323

	
324
    using Parent::direct;
325
    Arc direct(const Edge &e, const Node &s) const {
326
      return Parent::direct(e, Parent::u(e) == s);
327
    }
328

	
329
    typedef AlterationNotifier<EdgeSetExtender, Arc> ArcNotifier;
330
    typedef AlterationNotifier<EdgeSetExtender, Edge> EdgeNotifier;
331

	
332

	
333
  protected:
334

	
335
    mutable ArcNotifier arc_notifier;
336
    mutable EdgeNotifier edge_notifier;
337

	
338
  public:
339

	
340
    using Parent::notifier;
341
    
342
    ArcNotifier& notifier(Arc) const {
343
      return arc_notifier;
344
    }
345

	
346
    EdgeNotifier& notifier(Edge) const {
347
      return edge_notifier;
348
    }
349

	
350

	
351
    class NodeIt : public Node { 
352
      const Graph* graph;
353
    public:
354

	
355
      NodeIt() {}
356

	
357
      NodeIt(Invalid i) : Node(i) { }
358

	
359
      explicit NodeIt(const Graph& _graph) : graph(&_graph) {
360
	_graph.first(static_cast<Node&>(*this));
361
      }
362

	
363
      NodeIt(const Graph& _graph, const Node& node) 
364
	: Node(node), graph(&_graph) {}
365

	
366
      NodeIt& operator++() { 
367
	graph->next(*this);
368
	return *this; 
369
      }
370

	
371
    };
372

	
373

	
374
    class ArcIt : public Arc { 
375
      const Graph* graph;
376
    public:
377

	
378
      ArcIt() { }
379

	
380
      ArcIt(Invalid i) : Arc(i) { }
381

	
382
      explicit ArcIt(const Graph& _graph) : graph(&_graph) {
383
	_graph.first(static_cast<Arc&>(*this));
384
      }
385

	
386
      ArcIt(const Graph& _graph, const Arc& e) : 
387
	Arc(e), graph(&_graph) { }
388

	
389
      ArcIt& operator++() { 
390
	graph->next(*this);
391
	return *this; 
392
      }
393

	
394
    };
395

	
396

	
397
    class OutArcIt : public Arc { 
398
      const Graph* graph;
399
    public:
400

	
401
      OutArcIt() { }
402

	
403
      OutArcIt(Invalid i) : Arc(i) { }
404

	
405
      OutArcIt(const Graph& _graph, const Node& node) 
406
	: graph(&_graph) {
407
	_graph.firstOut(*this, node);
408
      }
409

	
410
      OutArcIt(const Graph& _graph, const Arc& arc) 
411
	: Arc(arc), graph(&_graph) {}
412

	
413
      OutArcIt& operator++() { 
414
	graph->nextOut(*this);
415
	return *this; 
416
      }
417

	
418
    };
419

	
420

	
421
    class InArcIt : public Arc { 
422
      const Graph* graph;
423
    public:
424

	
425
      InArcIt() { }
426

	
427
      InArcIt(Invalid i) : Arc(i) { }
428

	
429
      InArcIt(const Graph& _graph, const Node& node) 
430
	: graph(&_graph) {
431
	_graph.firstIn(*this, node);
432
      }
433

	
434
      InArcIt(const Graph& _graph, const Arc& arc) : 
435
	Arc(arc), graph(&_graph) {}
436

	
437
      InArcIt& operator++() { 
438
	graph->nextIn(*this);
439
	return *this; 
440
      }
441

	
442
    };
443

	
444

	
445
    class EdgeIt : public Parent::Edge { 
446
      const Graph* graph;
447
    public:
448

	
449
      EdgeIt() { }
450

	
451
      EdgeIt(Invalid i) : Edge(i) { }
452

	
453
      explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
454
	_graph.first(static_cast<Edge&>(*this));
455
      }
456

	
457
      EdgeIt(const Graph& _graph, const Edge& e) : 
458
	Edge(e), graph(&_graph) { }
459

	
460
      EdgeIt& operator++() { 
461
	graph->next(*this);
462
	return *this; 
463
      }
464

	
465
    };
466

	
467
    class IncEdgeIt : public Parent::Edge {
468
      friend class EdgeSetExtender;
469
      const Graph* graph;
470
      bool direction;
471
    public:
472

	
473
      IncEdgeIt() { }
474

	
475
      IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
476

	
477
      IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
478
	_graph.firstInc(*this, direction, n);
479
      }
480

	
481
      IncEdgeIt(const Graph& _graph, const Edge &ue, const Node &n)
482
	: graph(&_graph), Edge(ue) {
483
	direction = (_graph.source(ue) == n);
484
      }
485

	
486
      IncEdgeIt& operator++() {
487
	graph->nextInc(*this, direction);
488
	return *this; 
489
      }
490
    };
491

	
492
    // \brief Base node of the iterator
493
    //
494
    // Returns the base node (ie. the source in this case) of the iterator
495
    Node baseNode(const OutArcIt &e) const {
496
      return Parent::source(static_cast<const Arc&>(e));
497
    }
498
    // \brief Running node of the iterator
499
    //
500
    // Returns the running node (ie. the target in this case) of the
501
    // iterator
502
    Node runningNode(const OutArcIt &e) const {
503
      return Parent::target(static_cast<const Arc&>(e));
504
    }
505

	
506
    // \brief Base node of the iterator
507
    //
508
    // Returns the base node (ie. the target in this case) of the iterator
509
    Node baseNode(const InArcIt &e) const {
510
      return Parent::target(static_cast<const Arc&>(e));
511
    }
512
    // \brief Running node of the iterator
513
    //
514
    // Returns the running node (ie. the source in this case) of the
515
    // iterator
516
    Node runningNode(const InArcIt &e) const {
517
      return Parent::source(static_cast<const Arc&>(e));
518
    }
519

	
520
    // Base node of the iterator
521
    //
522
    // Returns the base node of the iterator
523
    Node baseNode(const IncEdgeIt &e) const {
524
      return e.direction ? u(e) : v(e);
525
    }
526
    // Running node of the iterator
527
    //
528
    // Returns the running node of the iterator
529
    Node runningNode(const IncEdgeIt &e) const {
530
      return e.direction ? v(e) : u(e);
531
    }
532

	
533

	
534
    template <typename _Value>
535
    class ArcMap 
536
      : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
537
      typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
538

	
539
    public:
540
      ArcMap(const Graph& _g) 
541
	: Parent(_g) {}
542
      ArcMap(const Graph& _g, const _Value& _v) 
543
	: Parent(_g, _v) {}
544

	
545
      ArcMap& operator=(const ArcMap& cmap) {
546
	return operator=<ArcMap>(cmap);
547
      }
548

	
549
      template <typename CMap>
550
      ArcMap& operator=(const CMap& cmap) {
551
        Parent::operator=(cmap);
552
	return *this;
553
      }
554

	
555
    };
556

	
557

	
558
    template <typename _Value>
559
    class EdgeMap 
560
      : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
561
      typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
562

	
563
    public:
564
      EdgeMap(const Graph& _g) 
565
	: Parent(_g) {}
566

	
567
      EdgeMap(const Graph& _g, const _Value& _v) 
568
	: Parent(_g, _v) {}
569

	
570
      EdgeMap& operator=(const EdgeMap& cmap) {
571
	return operator=<EdgeMap>(cmap);
572
      }
573

	
574
      template <typename CMap>
575
      EdgeMap& operator=(const CMap& cmap) {
576
        Parent::operator=(cmap);
577
	return *this;
578
      }
579

	
580
    };
581

	
582

	
583
    // Alteration extension
584

	
585
    Edge addEdge(const Node& from, const Node& to) {
586
      Edge edge = Parent::addEdge(from, to);
587
      notifier(Edge()).add(edge);
588
      std::vector<Arc> arcs;
589
      arcs.push_back(Parent::direct(edge, true));
590
      arcs.push_back(Parent::direct(edge, false));
591
      notifier(Arc()).add(arcs);
592
      return edge;
593
    }
594
    
595
    void clear() {
596
      notifier(Arc()).clear();
597
      notifier(Edge()).clear();
598
      Parent::clear();
599
    }
600

	
601
    void erase(const Edge& edge) {
602
      std::vector<Arc> arcs;
603
      arcs.push_back(Parent::direct(edge, true));
604
      arcs.push_back(Parent::direct(edge, false));
605
      notifier(Arc()).erase(arcs);
606
      notifier(Edge()).erase(edge);
607
      Parent::erase(edge);
608
    }
609

	
610

	
611
    EdgeSetExtender() {
612
      arc_notifier.setContainer(*this);
613
      edge_notifier.setContainer(*this);
614
    }
615

	
616
    ~EdgeSetExtender() {
617
      edge_notifier.clear();
618
      arc_notifier.clear();
619
    }
620
    
621
  };
622

	
623
}
624

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

	
19
#ifndef LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
20
#define LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
21

	
22
#include <lemon/core.h>
23
#include <lemon/error.h>
24

	
25
namespace lemon {
26

	
27
  template <typename _Digraph>
28
  class DigraphAdaptorExtender : public _Digraph {
29
    typedef _Digraph Parent;
30

	
31
  public:
32

	
33
    typedef _Digraph Digraph;
34
    typedef DigraphAdaptorExtender Adaptor;
35

	
36
    // Base extensions
37

	
38
    typedef typename Parent::Node Node;
39
    typedef typename Parent::Arc Arc;
40

	
41
    int maxId(Node) const {
42
      return Parent::maxNodeId();
43
    }
44

	
45
    int maxId(Arc) const {
46
      return Parent::maxArcId();
47
    }
48

	
49
    Node fromId(int id, Node) const {
50
      return Parent::nodeFromId(id);
51
    }
52

	
53
    Arc fromId(int id, Arc) const {
54
      return Parent::arcFromId(id);
55
    }
56

	
57
    Node oppositeNode(const Node &n, const Arc &e) const {
58
      if (n == Parent::source(e))
59
        return Parent::target(e);
60
      else if(n==Parent::target(e))
61
        return Parent::source(e);
62
      else
63
        return INVALID;
64
    }
65

	
66
    class NodeIt : public Node {
67
      const Adaptor* _adaptor;
68
    public:
69

	
70
      NodeIt() {}
71

	
72
      NodeIt(Invalid i) : Node(i) { }
73

	
74
      explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
75
        _adaptor->first(static_cast<Node&>(*this));
76
      }
77

	
78
      NodeIt(const Adaptor& adaptor, const Node& node)
79
        : Node(node), _adaptor(&adaptor) {}
80

	
81
      NodeIt& operator++() {
82
        _adaptor->next(*this);
83
        return *this;
84
      }
85

	
86
    };
87

	
88

	
89
    class ArcIt : public Arc {
90
      const Adaptor* _adaptor;
91
    public:
92

	
93
      ArcIt() { }
94

	
95
      ArcIt(Invalid i) : Arc(i) { }
96

	
97
      explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
98
        _adaptor->first(static_cast<Arc&>(*this));
99
      }
100

	
101
      ArcIt(const Adaptor& adaptor, const Arc& e) :
102
        Arc(e), _adaptor(&adaptor) { }
103

	
104
      ArcIt& operator++() {
105
        _adaptor->next(*this);
106
        return *this;
107
      }
108

	
109
    };
110

	
111

	
112
    class OutArcIt : public Arc {
113
      const Adaptor* _adaptor;
114
    public:
115

	
116
      OutArcIt() { }
117

	
118
      OutArcIt(Invalid i) : Arc(i) { }
119

	
120
      OutArcIt(const Adaptor& adaptor, const Node& node)
121
        : _adaptor(&adaptor) {
122
        _adaptor->firstOut(*this, node);
123
      }
124

	
125
      OutArcIt(const Adaptor& adaptor, const Arc& arc)
126
        : Arc(arc), _adaptor(&adaptor) {}
127

	
128
      OutArcIt& operator++() {
129
        _adaptor->nextOut(*this);
130
        return *this;
131
      }
132

	
133
    };
134

	
135

	
136
    class InArcIt : public Arc {
137
      const Adaptor* _adaptor;
138
    public:
139

	
140
      InArcIt() { }
141

	
142
      InArcIt(Invalid i) : Arc(i) { }
143

	
144
      InArcIt(const Adaptor& adaptor, const Node& node)
145
        : _adaptor(&adaptor) {
146
        _adaptor->firstIn(*this, node);
147
      }
148

	
149
      InArcIt(const Adaptor& adaptor, const Arc& arc) :
150
        Arc(arc), _adaptor(&adaptor) {}
151

	
152
      InArcIt& operator++() {
153
        _adaptor->nextIn(*this);
154
        return *this;
155
      }
156

	
157
    };
158

	
159
    Node baseNode(const OutArcIt &e) const {
160
      return Parent::source(e);
161
    }
162
    Node runningNode(const OutArcIt &e) const {
163
      return Parent::target(e);
164
    }
165

	
166
    Node baseNode(const InArcIt &e) const {
167
      return Parent::target(e);
168
    }
169
    Node runningNode(const InArcIt &e) const {
170
      return Parent::source(e);
171
    }
172

	
173
  };
174

	
175
  template <typename _Graph>
176
  class GraphAdaptorExtender : public _Graph {
177
    typedef _Graph Parent;
178

	
179
  public:
180

	
181
    typedef _Graph Graph;
182
    typedef GraphAdaptorExtender Adaptor;
183

	
184
    typedef typename Parent::Node Node;
185
    typedef typename Parent::Arc Arc;
186
    typedef typename Parent::Edge Edge;
187

	
188
    // Graph extension
189

	
190
    int maxId(Node) const {
191
      return Parent::maxNodeId();
192
    }
193

	
194
    int maxId(Arc) const {
195
      return Parent::maxArcId();
196
    }
197

	
198
    int maxId(Edge) const {
199
      return Parent::maxEdgeId();
200
    }
201

	
202
    Node fromId(int id, Node) const {
203
      return Parent::nodeFromId(id);
204
    }
205

	
206
    Arc fromId(int id, Arc) const {
207
      return Parent::arcFromId(id);
208
    }
209

	
210
    Edge fromId(int id, Edge) const {
211
      return Parent::edgeFromId(id);
212
    }
213

	
214
    Node oppositeNode(const Node &n, const Edge &e) const {
215
      if( n == Parent::u(e))
216
        return Parent::v(e);
217
      else if( n == Parent::v(e))
218
        return Parent::u(e);
219
      else
220
        return INVALID;
221
    }
222

	
223
    Arc oppositeArc(const Arc &a) const {
224
      return Parent::direct(a, !Parent::direction(a));
225
    }
226

	
227
    using Parent::direct;
228
    Arc direct(const Edge &e, const Node &s) const {
229
      return Parent::direct(e, Parent::u(e) == s);
230
    }
231

	
232

	
233
    class NodeIt : public Node {
234
      const Adaptor* _adaptor;
235
    public:
236

	
237
      NodeIt() {}
238

	
239
      NodeIt(Invalid i) : Node(i) { }
240

	
241
      explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
242
        _adaptor->first(static_cast<Node&>(*this));
243
      }
244

	
245
      NodeIt(const Adaptor& adaptor, const Node& node)
246
        : Node(node), _adaptor(&adaptor) {}
247

	
248
      NodeIt& operator++() {
249
        _adaptor->next(*this);
250
        return *this;
251
      }
252

	
253
    };
254

	
255

	
256
    class ArcIt : public Arc {
257
      const Adaptor* _adaptor;
258
    public:
259

	
260
      ArcIt() { }
261

	
262
      ArcIt(Invalid i) : Arc(i) { }
263

	
264
      explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
265
        _adaptor->first(static_cast<Arc&>(*this));
266
      }
267

	
268
      ArcIt(const Adaptor& adaptor, const Arc& e) :
269
        Arc(e), _adaptor(&adaptor) { }
270

	
271
      ArcIt& operator++() {
272
        _adaptor->next(*this);
273
        return *this;
274
      }
275

	
276
    };
277

	
278

	
279
    class OutArcIt : public Arc {
280
      const Adaptor* _adaptor;
281
    public:
282

	
283
      OutArcIt() { }
284

	
285
      OutArcIt(Invalid i) : Arc(i) { }
286

	
287
      OutArcIt(const Adaptor& adaptor, const Node& node)
288
        : _adaptor(&adaptor) {
289
        _adaptor->firstOut(*this, node);
290
      }
291

	
292
      OutArcIt(const Adaptor& adaptor, const Arc& arc)
293
        : Arc(arc), _adaptor(&adaptor) {}
294

	
295
      OutArcIt& operator++() {
296
        _adaptor->nextOut(*this);
297
        return *this;
298
      }
299

	
300
    };
301

	
302

	
303
    class InArcIt : public Arc {
304
      const Adaptor* _adaptor;
305
    public:
306

	
307
      InArcIt() { }
308

	
309
      InArcIt(Invalid i) : Arc(i) { }
310

	
311
      InArcIt(const Adaptor& adaptor, const Node& node)
312
        : _adaptor(&adaptor) {
313
        _adaptor->firstIn(*this, node);
314
      }
315

	
316
      InArcIt(const Adaptor& adaptor, const Arc& arc) :
317
        Arc(arc), _adaptor(&adaptor) {}
318

	
319
      InArcIt& operator++() {
320
        _adaptor->nextIn(*this);
321
        return *this;
322
      }
323

	
324
    };
325

	
326
    class EdgeIt : public Parent::Edge {
327
      const Adaptor* _adaptor;
328
    public:
329

	
330
      EdgeIt() { }
331

	
332
      EdgeIt(Invalid i) : Edge(i) { }
333

	
334
      explicit EdgeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
335
        _adaptor->first(static_cast<Edge&>(*this));
336
      }
337

	
338
      EdgeIt(const Adaptor& adaptor, const Edge& e) :
339
        Edge(e), _adaptor(&adaptor) { }
340

	
341
      EdgeIt& operator++() {
342
        _adaptor->next(*this);
343
        return *this;
344
      }
345

	
346
    };
347

	
348
    class IncEdgeIt : public Edge {
349
      friend class GraphAdaptorExtender;
350
      const Adaptor* _adaptor;
351
      bool direction;
352
    public:
353

	
354
      IncEdgeIt() { }
355

	
356
      IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
357

	
358
      IncEdgeIt(const Adaptor& adaptor, const Node &n) : _adaptor(&adaptor) {
359
        _adaptor->firstInc(static_cast<Edge&>(*this), direction, n);
360
      }
361

	
362
      IncEdgeIt(const Adaptor& adaptor, const Edge &e, const Node &n)
363
        : _adaptor(&adaptor), Edge(e) {
364
        direction = (_adaptor->u(e) == n);
365
      }
366

	
367
      IncEdgeIt& operator++() {
368
        _adaptor->nextInc(*this, direction);
369
        return *this;
370
      }
371
    };
372

	
373
    Node baseNode(const OutArcIt &a) const {
374
      return Parent::source(a);
375
    }
376
    Node runningNode(const OutArcIt &a) const {
377
      return Parent::target(a);
378
    }
379

	
380
    Node baseNode(const InArcIt &a) const {
381
      return Parent::target(a);
382
    }
383
    Node runningNode(const InArcIt &a) const {
384
      return Parent::source(a);
385
    }
386

	
387
    Node baseNode(const IncEdgeIt &e) const {
388
      return e.direction ? Parent::u(e) : Parent::v(e);
389
    }
390
    Node runningNode(const IncEdgeIt &e) const {
391
      return e.direction ? Parent::v(e) : Parent::u(e);
392
    }
393

	
394
  };
395

	
396
}
397

	
398

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

	
19
#ifndef LEMON_BITS_SOLVER_BITS_H
20
#define LEMON_BITS_SOLVER_BITS_H
21

	
22
#include <vector>
23

	
24
namespace lemon {
25

	
26
  namespace _solver_bits {
27

	
28
    class VarIndex {
29
    private:
30
      struct ItemT {
31
        int prev, next;
32
        int index;
33
      };
34
      std::vector<ItemT> items;
35
      int first_item, last_item, first_free_item;
36

	
37
      std::vector<int> cross;
38

	
39
    public:
40

	
41
      VarIndex()
42
        : first_item(-1), last_item(-1), first_free_item(-1) {
43
      }
44

	
45
      void clear() {
46
        first_item = -1;
47
        first_free_item = -1;
48
        items.clear();
49
        cross.clear();
50
      }
51

	
52
      int addIndex(int idx) {
53
        int n;
54
        if (first_free_item == -1) {
55
          n = items.size();
56
          items.push_back(ItemT());
57
        } else {
58
          n = first_free_item;
59
          first_free_item = items[n].next;
60
          if (first_free_item != -1) {
61
            items[first_free_item].prev = -1;
62
          }
63
        }
64
        items[n].index = idx;
65
        if (static_cast<int>(cross.size()) <= idx) {
66
          cross.resize(idx + 1, -1);
67
        }
68
        cross[idx] = n;
69

	
70
        items[n].prev = last_item;
71
        items[n].next = -1;
72
        if (last_item != -1) {
73
          items[last_item].next = n;
74
        } else {
75
          first_item = n;
76
        }
77
        last_item = n;
78

	
79
        return n;
80
      }
81

	
82
      int addIndex(int idx, int n) {
83
        while (n >= static_cast<int>(items.size())) {
84
          items.push_back(ItemT());
85
          items.back().prev = -1;
86
          items.back().next = first_free_item;
87
          if (first_free_item != -1) {
88
            items[first_free_item].prev = items.size() - 1;
89
          }
90
          first_free_item = items.size() - 1;
91
        }
92
        if (items[n].next != -1) {
93
          items[items[n].next].prev = items[n].prev;
94
        }
95
        if (items[n].prev != -1) {
96
          items[items[n].prev].next = items[n].next;
97
        } else {
98
          first_free_item = items[n].next;
99
        }
100

	
101
        items[n].index = idx;
102
        if (static_cast<int>(cross.size()) <= idx) {
103
          cross.resize(idx + 1, -1);
104
        }
105
        cross[idx] = n;
106

	
107
        items[n].prev = last_item;
108
        items[n].next = -1;
109
        if (last_item != -1) {
110
          items[last_item].next = n;
111
        } else {
112
          first_item = n;
113
        }
114
        last_item = n;
115

	
116
        return n;
117
      }
118

	
119
      void eraseIndex(int idx) {
120
        int n = cross[idx];
121

	
122
        if (items[n].prev != -1) {
123
          items[items[n].prev].next = items[n].next;
124
        } else {
125
          first_item = items[n].next;
126
        }
127
        if (items[n].next != -1) {
128
          items[items[n].next].prev = items[n].prev;
129
        } else {
130
          last_item = items[n].prev;
131
        }
132

	
133
        if (first_free_item != -1) {
134
          items[first_free_item].prev = n;
135
        }
136
        items[n].next = first_free_item;
137
        items[n].prev = -1;
138
        first_free_item = n;
139

	
140
        while (!cross.empty() && cross.back() == -1) {
141
          cross.pop_back();
142
        }
143
      }
144

	
145
      int maxIndex() const {
146
        return cross.size() - 1;
147
      }
148

	
149
      void shiftIndices(int idx) {
150
        for (int i = idx + 1; i < static_cast<int>(cross.size()); ++i) {
151
          cross[i - 1] = cross[i];
152
          if (cross[i] != -1) {
153
            --items[cross[i]].index;
154
          }
155
        }
156
        cross.back() = -1;
157
        cross.pop_back();
158
        while (!cross.empty() && cross.back() == -1) {
159
          cross.pop_back();
160
        }
161
      }
162

	
163
      void relocateIndex(int idx, int jdx) {
164
        cross[idx] = cross[jdx];
165
        items[cross[jdx]].index = idx;
166
        cross[jdx] = -1;
167

	
168
        while (!cross.empty() && cross.back() == -1) {
169
          cross.pop_back();
170
        }
171
      }
172

	
173
      int operator[](int idx) const {
174
        return cross[idx];
175
      }
176

	
177
      int operator()(int fdx) const {
178
        return items[fdx].index;
179
      }
180

	
181
      void firstItem(int& fdx) const {
182
        fdx = first_item;
183
      }
184

	
185
      void nextItem(int& fdx) const {
186
        fdx = items[fdx].next;
187
      }
188

	
189
    };
190
  }
191
}
192

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

	
19
#ifndef LEMON_BITS_VARIANT_H
20
#define LEMON_BITS_VARIANT_H
21

	
22
#include <lemon/assert.h>
23

	
24
// \file
25
// \brief Variant types
26

	
27
namespace lemon {
28

	
29
  namespace _variant_bits {
30

	
31
    template <int left, int right>
32
    struct CTMax {
33
      static const int value = left < right ? right : left;
34
    };
35

	
36
  }
37

	
38

	
39
  // \brief Simple Variant type for two types
40
  //
41
  // Simple Variant type for two types. The Variant type is a type-safe
42
  // union. C++ has strong limitations for using unions, for
43
  // example you cannot store a type with non-default constructor or
44
  // destructor in a union. This class always knowns the current
45
  // state of the variant and it cares for the proper construction
46
  // and destruction.
47
  template <typename _First, typename _Second>
48
  class BiVariant {
49
  public:
50

	
51
    // \brief The \c First type.
52
    typedef _First First;
53
    // \brief The \c Second type.
54
    typedef _Second Second;
55

	
56
    // \brief Constructor
57
    //
58
    // This constructor initalizes to the default value of the \c First
59
    // type.
60
    BiVariant() {
61
      flag = true;
62
      new(reinterpret_cast<First*>(data)) First();
63
    }
64

	
65
    // \brief Constructor
66
    //
67
    // This constructor initalizes to the given value of the \c First
68
    // type.
69
    BiVariant(const First& f) {
70
      flag = true;
71
      new(reinterpret_cast<First*>(data)) First(f);
72
    }
73

	
74
    // \brief Constructor
75
    //
76
    // This constructor initalizes to the given value of the \c
77
    // Second type.
78
    BiVariant(const Second& s) {
79
      flag = false;
80
      new(reinterpret_cast<Second*>(data)) Second(s);
81
    }
82

	
83
    // \brief Copy constructor
84
    //
85
    // Copy constructor
86
    BiVariant(const BiVariant& bivariant) {
87
      flag = bivariant.flag;
88
      if (flag) {
89
        new(reinterpret_cast<First*>(data)) First(bivariant.first());
90
      } else {
91
        new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
92
      }
93
    }
94

	
95
    // \brief Destrcutor
96
    //
97
    // Destructor
98
    ~BiVariant() {
99
      destroy();
100
    }
101

	
102
    // \brief Set to the default value of the \c First type.
103
    //
104
    // This function sets the variant to the default value of the \c
105
    // First type.
106
    BiVariant& setFirst() {
107
      destroy();
108
      flag = true;
109
      new(reinterpret_cast<First*>(data)) First();
110
      return *this;
111
    }
112

	
113
    // \brief Set to the given value of the \c First type.
114
    //
115
    // This function sets the variant to the given value of the \c
116
    // First type.
117
    BiVariant& setFirst(const First& f) {
118
      destroy();
119
      flag = true;
120
      new(reinterpret_cast<First*>(data)) First(f);
121
      return *this;
122
    }
123

	
124
    // \brief Set to the default value of the \c Second type.
125
    //
126
    // This function sets the variant to the default value of the \c
127
    // Second type.
128
    BiVariant& setSecond() {
129
      destroy();
130
      flag = false;
131
      new(reinterpret_cast<Second*>(data)) Second();
132
      return *this;
133
    }
134

	
135
    // \brief Set to the given value of the \c Second type.
136
    //
137
    // This function sets the variant to the given value of the \c
138
    // Second type.
139
    BiVariant& setSecond(const Second& s) {
140
      destroy();
141
      flag = false;
142
      new(reinterpret_cast<Second*>(data)) Second(s);
143
      return *this;
144
    }
145

	
146
    // \brief Operator form of the \c setFirst()
147
    BiVariant& operator=(const First& f) {
148
      return setFirst(f);
149
    }
150

	
151
    // \brief Operator form of the \c setSecond()
152
    BiVariant& operator=(const Second& s) {
153
      return setSecond(s);
154
    }
155

	
156
    // \brief Assign operator
157
    BiVariant& operator=(const BiVariant& bivariant) {
158
      if (this == &bivariant) return *this;
159
      destroy();
160
      flag = bivariant.flag;
161
      if (flag) {
162
        new(reinterpret_cast<First*>(data)) First(bivariant.first());
163
      } else {
164
        new(reinterpret_cast<Second*>(data)) Second(bivariant.second());
165
      }
166
      return *this;
167
    }
168

	
169
    // \brief Reference to the value
170
    //
171
    // Reference to the value of the \c First type.
172
    // \pre The BiVariant should store value of \c First type.
173
    First& first() {
174
      LEMON_DEBUG(flag, "Variant wrong state");
175
      return *reinterpret_cast<First*>(data);
176
    }
177

	
178
    // \brief Const reference to the value
179
    //
180
    // Const reference to the value of the \c First type.
181
    // \pre The BiVariant should store value of \c First type.
182
    const First& first() const {
183
      LEMON_DEBUG(flag, "Variant wrong state");
184
      return *reinterpret_cast<const First*>(data);
185
    }
186

	
187
    // \brief Operator form of the \c first()
188
    operator First&() { return first(); }
189
    // \brief Operator form of the const \c first()
190
    operator const First&() const { return first(); }
191

	
192
    // \brief Reference to the value
193
    //
194
    // Reference to the value of the \c Second type.
195
    // \pre The BiVariant should store value of \c Second type.
196
    Second& second() {
197
      LEMON_DEBUG(!flag, "Variant wrong state");
198
      return *reinterpret_cast<Second*>(data);
199
    }
200

	
201
    // \brief Const reference to the value
202
    //
203
    // Const reference to the value of the \c Second type.
204
    // \pre The BiVariant should store value of \c Second type.
205
    const Second& second() const {
206
      LEMON_DEBUG(!flag, "Variant wrong state");
207
      return *reinterpret_cast<const Second*>(data);
208
    }
209

	
210
    // \brief Operator form of the \c second()
211
    operator Second&() { return second(); }
212
    // \brief Operator form of the const \c second()
213
    operator const Second&() const { return second(); }
214

	
215
    // \brief %True when the variant is in the first state
216
    //
217
    // %True when the variant stores value of the \c First type.
218
    bool firstState() const { return flag; }
219

	
220
    // \brief %True when the variant is in the second state
221
    //
222
    // %True when the variant stores value of the \c Second type.
223
    bool secondState() const { return !flag; }
224

	
225
  private:
226

	
227
    void destroy() {
228
      if (flag) {
229
        reinterpret_cast<First*>(data)->~First();
230
      } else {
231
        reinterpret_cast<Second*>(data)->~Second();
232
      }
233
    }
234

	
235
    char data[_variant_bits::CTMax<sizeof(First), sizeof(Second)>::value];
236
    bool flag;
237
  };
238

	
239
  namespace _variant_bits {
240

	
241
    template <int _idx, typename _TypeMap>
242
    struct Memory {
243

	
244
      typedef typename _TypeMap::template Map<_idx>::Type Current;
245

	
246
      static void destroy(int index, char* place) {
247
        if (index == _idx) {
248
          reinterpret_cast<Current*>(place)->~Current();
249
        } else {
250
          Memory<_idx - 1, _TypeMap>::destroy(index, place);
251
        }
252
      }
253

	
254
      static void copy(int index, char* to, const char* from) {
255
        if (index == _idx) {
256
          new (reinterpret_cast<Current*>(to))
257
            Current(reinterpret_cast<const Current*>(from));
258
        } else {
259
          Memory<_idx - 1, _TypeMap>::copy(index, to, from);
260
        }
261
      }
262

	
263
    };
264

	
265
    template <typename _TypeMap>
266
    struct Memory<-1, _TypeMap> {
267

	
268
      static void destroy(int, char*) {
269
        LEMON_DEBUG(false, "Variant wrong index.");
270
      }
271

	
272
      static void copy(int, char*, const char*) {
273
        LEMON_DEBUG(false, "Variant wrong index.");
274
      }
275
    };
276

	
277
    template <int _idx, typename _TypeMap>
278
    struct Size {
279
      static const int value =
280
      CTMax<sizeof(typename _TypeMap::template Map<_idx>::Type),
281
            Size<_idx - 1, _TypeMap>::value>::value;
282
    };
283

	
284
    template <typename _TypeMap>
285
    struct Size<0, _TypeMap> {
286
      static const int value =
287
      sizeof(typename _TypeMap::template Map<0>::Type);
288
    };
289

	
290
  }
291

	
292
  // \brief Variant type
293
  //
294
  // Simple Variant type. The Variant type is a type-safe union.
295
  // C++ has strong limitations for using unions, for example you
296
  // cannot store type with non-default constructor or destructor in
297
  // a union. This class always knowns the current state of the
298
  // variant and it cares for the proper construction and
299
  // destruction.
300
  //
301
  // \param _num The number of the types which can be stored in the
302
  // variant type.
303
  // \param _TypeMap This class describes the types of the Variant. The
304
  // _TypeMap::Map<index>::Type should be a valid type for each index
305
  // in the range {0, 1, ..., _num - 1}. The \c VariantTypeMap is helper
306
  // class to define such type mappings up to 10 types.
307
  //
308
  // And the usage of the class:
309
  //\code
310
  // typedef Variant<3, VariantTypeMap<int, std::string, double> > MyVariant;
311
  // MyVariant var;
312
  // var.set<0>(12);
313
  // std::cout << var.get<0>() << std::endl;
314
  // var.set<1>("alpha");
315
  // std::cout << var.get<1>() << std::endl;
316
  // var.set<2>(0.75);
317
  // std::cout << var.get<2>() << std::endl;
318
  //\endcode
319
  //
320
  // The result of course:
321
  //\code
322
  // 12
323
  // alpha
324
  // 0.75
325
  //\endcode
326
  template <int _num, typename _TypeMap>
327
  class Variant {
328
  public:
329

	
330
    static const int num = _num;
331

	
332
    typedef _TypeMap TypeMap;
333

	
334
    // \brief Constructor
335
    //
336
    // This constructor initalizes to the default value of the \c type
337
    // with 0 index.
338
    Variant() {
339
      flag = 0;
340
      new(reinterpret_cast<typename TypeMap::template Map<0>::Type*>(data))
341
        typename TypeMap::template Map<0>::Type();
342
    }
343

	
344

	
345
    // \brief Copy constructor
346
    //
347
    // Copy constructor
348
    Variant(const Variant& variant) {
349
      flag = variant.flag;
350
      _variant_bits::Memory<num - 1, TypeMap>::copy(flag, data, variant.data);
351
    }
352

	
353
    // \brief Assign operator
354
    //
355
    // Assign operator
356
    Variant& operator=(const Variant& variant) {
357
      if (this == &variant) return *this;
358
      _variant_bits::Memory<num - 1, TypeMap>::
359
        destroy(flag, data);
360
      flag = variant.flag;
361
      _variant_bits::Memory<num - 1, TypeMap>::
362
        copy(flag, data, variant.data);
363
      return *this;
364
    }
365

	
366
    // \brief Destrcutor
367
    //
368
    // Destructor
369
    ~Variant() {
370
      _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
371
    }
372

	
373
    // \brief Set to the default value of the type with \c _idx index.
374
    //
375
    // This function sets the variant to the default value of the
376
    // type with \c _idx index.
377
    template <int _idx>
378
    Variant& set() {
379
      _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
380
      flag = _idx;
381
      new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
382
        typename TypeMap::template Map<_idx>::Type();
383
      return *this;
384
    }
385

	
386
    // \brief Set to the given value of the type with \c _idx index.
387
    //
388
    // This function sets the variant to the given value of the type
389
    // with \c _idx index.
390
    template <int _idx>
391
    Variant& set(const typename _TypeMap::template Map<_idx>::Type& init) {
392
      _variant_bits::Memory<num - 1, TypeMap>::destroy(flag, data);
393
      flag = _idx;
394
      new(reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>(data))
395
        typename TypeMap::template Map<_idx>::Type(init);
396
      return *this;
397
    }
398

	
399
    // \brief Gets the current value of the type with \c _idx index.
400
    //
401
    // Gets the current value of the type with \c _idx index.
402
    template <int _idx>
403
    const typename TypeMap::template Map<_idx>::Type& get() const {
404
      LEMON_DEBUG(_idx == flag, "Variant wrong index");
405
      return *reinterpret_cast<const typename TypeMap::
406
        template Map<_idx>::Type*>(data);
407
    }
408

	
409
    // \brief Gets the current value of the type with \c _idx index.
410
    //
411
    // Gets the current value of the type with \c _idx index.
412
    template <int _idx>
413
    typename _TypeMap::template Map<_idx>::Type& get() {
414
      LEMON_DEBUG(_idx == flag, "Variant wrong index");
415
      return *reinterpret_cast<typename TypeMap::template Map<_idx>::Type*>
416
        (data);
417
    }
418

	
419
    // \brief Returns the current state of the variant.
420
    //
421
    // Returns the current state of the variant.
422
    int state() const {
423
      return flag;
424
    }
425

	
426
  private:
427

	
428
    char data[_variant_bits::Size<num - 1, TypeMap>::value];
429
    int flag;
430
  };
431

	
432
  namespace _variant_bits {
433

	
434
    template <int _index, typename _List>
435
    struct Get {
436
      typedef typename Get<_index - 1, typename _List::Next>::Type Type;
437
    };
438

	
439
    template <typename _List>
440
    struct Get<0, _List> {
441
      typedef typename _List::Type Type;
442
    };
443

	
444
    struct List {};
445

	
446
    template <typename _Type, typename _List>
447
    struct Insert {
448
      typedef _List Next;
449
      typedef _Type Type;
450
    };
451

	
452
    template <int _idx, typename _T0, typename _T1, typename _T2,
453
              typename _T3, typename _T4, typename _T5, typename _T6,
454
              typename _T7, typename _T8, typename _T9>
455
    struct Mapper {
456
      typedef List L10;
457
      typedef Insert<_T9, L10> L9;
458
      typedef Insert<_T8, L9> L8;
459
      typedef Insert<_T7, L8> L7;
460
      typedef Insert<_T6, L7> L6;
461
      typedef Insert<_T5, L6> L5;
462
      typedef Insert<_T4, L5> L4;
463
      typedef Insert<_T3, L4> L3;
464
      typedef Insert<_T2, L3> L2;
465
      typedef Insert<_T1, L2> L1;
466
      typedef Insert<_T0, L1> L0;
467
      typedef typename Get<_idx, L0>::Type Type;
468
    };
469

	
470
  }
471

	
472
  // \brief Helper class for Variant
473
  //
474
  // Helper class to define type mappings for Variant. This class
475
  // converts the template parameters to be mappable by integer.
476
  // \see Variant
477
  template <
478
    typename _T0,
479
    typename _T1 = void, typename _T2 = void, typename _T3 = void,
480
    typename _T4 = void, typename _T5 = void, typename _T6 = void,
481
    typename _T7 = void, typename _T8 = void, typename _T9 = void>
482
  struct VariantTypeMap {
483
    template <int _idx>
484
    struct Map {
485
      typedef typename _variant_bits::
486
      Mapper<_idx, _T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>::Type
487
      Type;
488
    };
489
  };
490

	
491
}
492

	
493

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

	
19
#ifndef LEMON_BUCKET_HEAP_H
20
#define LEMON_BUCKET_HEAP_H
21

	
22
///\ingroup auxdat
23
///\file
24
///\brief Bucket Heap implementation.
25

	
26
#include <vector>
27
#include <utility>
28
#include <functional>
29

	
30
namespace lemon {
31

	
32
  namespace _bucket_heap_bits {
33

	
34
    template <bool MIN>
35
    struct DirectionTraits {
36
      static bool less(int left, int right) {
37
        return left < right;
38
      }
39
      static void increase(int& value) {
40
        ++value;
41
      }
42
    };
43

	
44
    template <>
45
    struct DirectionTraits<false> {
46
      static bool less(int left, int right) {
47
        return left > right;
48
      }
49
      static void increase(int& value) {
50
        --value;
51
      }
52
    };
53

	
54
  }
55

	
56
  /// \ingroup auxdat
57
  ///
58
  /// \brief A Bucket Heap implementation.
59
  ///
60
  /// This class implements the \e bucket \e heap data structure. A \e heap
61
  /// is a data structure for storing items with specified values called \e
62
  /// priorities in such a way that finding the item with minimum priority is
63
  /// efficient. The bucket heap is very simple implementation, it can store
64
  /// only integer priorities and it stores for each priority in the
65
  /// \f$ [0..C) \f$ range a list of items. So it should be used only when
66
  /// the priorities are small. It is not intended to use as dijkstra heap.
67
  ///
68
  /// \param IM A read and write Item int map, used internally
69
  /// to handle the cross references.
70
  /// \param MIN If the given parameter is false then instead of the
71
  /// minimum value the maximum can be retrivied with the top() and
72
  /// prio() member functions.
73
  template <typename IM, bool MIN = true>
74
  class BucketHeap {
75

	
76
  public:
77
    /// \e
78
    typedef typename IM::Key Item;
79
    /// \e
80
    typedef int Prio;
81
    /// \e
82
    typedef std::pair<Item, Prio> Pair;
83
    /// \e
84
    typedef IM ItemIntMap;
85

	
86
  private:
87

	
88
    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
89

	
90
  public:
91

	
92
    /// \brief Type to represent the items states.
93
    ///
94
    /// Each Item element have a state associated to it. It may be "in heap",
95
    /// "pre heap" or "post heap". The latter two are indifferent from the
96
    /// heap's point of view, but may be useful to the user.
97
    ///
98
    /// The item-int map must be initialized in such way that it assigns
99
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
100
    enum State {
101
      IN_HEAP = 0,    ///< = 0.
102
      PRE_HEAP = -1,  ///< = -1.
103
      POST_HEAP = -2  ///< = -2.
104
    };
105

	
106
  public:
107
    /// \brief The constructor.
108
    ///
109
    /// The constructor.
110
    /// \param map should be given to the constructor, since it is used
111
    /// internally to handle the cross references. The value of the map
112
    /// should be PRE_HEAP (-1) for each element.
113
    explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
114

	
115
    /// The number of items stored in the heap.
116
    ///
117
    /// \brief Returns the number of items stored in the heap.
118
    int size() const { return _data.size(); }
119

	
120
    /// \brief Checks if the heap stores no items.
121
    ///
122
    /// Returns \c true if and only if the heap stores no items.
123
    bool empty() const { return _data.empty(); }
124

	
125
    /// \brief Make empty this heap.
126
    ///
127
    /// Make empty this heap. It does not change the cross reference
128
    /// map.  If you want to reuse a heap what is not surely empty you
129
    /// should first clear the heap and after that you should set the
130
    /// cross reference map for each item to \c PRE_HEAP.
131
    void clear() {
132
      _data.clear(); _first.clear(); _minimum = 0;
133
    }
134

	
135
  private:
136

	
137
    void relocate_last(int idx) {
138
      if (idx + 1 < int(_data.size())) {
139
        _data[idx] = _data.back();
140
        if (_data[idx].prev != -1) {
141
          _data[_data[idx].prev].next = idx;
142
        } else {
143
          _first[_data[idx].value] = idx;
144
        }
145
        if (_data[idx].next != -1) {
146
          _data[_data[idx].next].prev = idx;
147
        }
148
        _iim[_data[idx].item] = idx;
149
      }
150
      _data.pop_back();
151
    }
152

	
153
    void unlace(int idx) {
154
      if (_data[idx].prev != -1) {
155
        _data[_data[idx].prev].next = _data[idx].next;
156
      } else {
157
        _first[_data[idx].value] = _data[idx].next;
158
      }
159
      if (_data[idx].next != -1) {
160
        _data[_data[idx].next].prev = _data[idx].prev;
161
      }
162
    }
163

	
164
    void lace(int idx) {
165
      if (int(_first.size()) <= _data[idx].value) {
166
        _first.resize(_data[idx].value + 1, -1);
167
      }
168
      _data[idx].next = _first[_data[idx].value];
169
      if (_data[idx].next != -1) {
170
        _data[_data[idx].next].prev = idx;
171
      }
172
      _first[_data[idx].value] = idx;
173
      _data[idx].prev = -1;
174
    }
175

	
176
  public:
177
    /// \brief Insert a pair of item and priority into the heap.
178
    ///
179
    /// Adds \c p.first to the heap with priority \c p.second.
180
    /// \param p The pair to insert.
181
    void push(const Pair& p) {
182
      push(p.first, p.second);
183
    }
184

	
185
    /// \brief Insert an item into the heap with the given priority.
186
    ///
187
    /// Adds \c i to the heap with priority \c p.
188
    /// \param i The item to insert.
189
    /// \param p The priority of the item.
190
    void push(const Item &i, const Prio &p) {
191
      int idx = _data.size();
192
      _iim[i] = idx;
193
      _data.push_back(BucketItem(i, p));
194
      lace(idx);
195
      if (Direction::less(p, _minimum)) {
196
        _minimum = p;
197
      }
198
    }
199

	
200
    /// \brief Returns the item with minimum priority.
201
    ///
202
    /// This method returns the item with minimum priority.
203
    /// \pre The heap must be nonempty.
204
    Item top() const {
205
      while (_first[_minimum] == -1) {
206
        Direction::increase(_minimum);
207
      }
208
      return _data[_first[_minimum]].item;
209
    }
210

	
211
    /// \brief Returns the minimum priority.
212
    ///
213
    /// It returns the minimum priority.
214
    /// \pre The heap must be nonempty.
215
    Prio prio() const {
216
      while (_first[_minimum] == -1) {
217
        Direction::increase(_minimum);
218
      }
219
      return _minimum;
220
    }
221

	
222
    /// \brief Deletes the item with minimum priority.
223
    ///
224
    /// This method deletes the item with minimum priority from the heap.
225
    /// \pre The heap must be non-empty.
226
    void pop() {
227
      while (_first[_minimum] == -1) {
228
        Direction::increase(_minimum);
229
      }
230
      int idx = _first[_minimum];
231
      _iim[_data[idx].item] = -2;
232
      unlace(idx);
233
      relocate_last(idx);
234
    }
235

	
236
    /// \brief Deletes \c i from the heap.
237
    ///
238
    /// This method deletes item \c i from the heap, if \c i was
239
    /// already stored in the heap.
240
    /// \param i The item to erase.
241
    void erase(const Item &i) {
242
      int idx = _iim[i];
243
      _iim[_data[idx].item] = -2;
244
      unlace(idx);
245
      relocate_last(idx);
246
    }
247

	
248

	
249
    /// \brief Returns the priority of \c i.
250
    ///
251
    /// This function returns the priority of item \c i.
252
    /// \pre \c i must be in the heap.
253
    /// \param i The item.
254
    Prio operator[](const Item &i) const {
255
      int idx = _iim[i];
256
      return _data[idx].value;
257
    }
258

	
259
    /// \brief \c i gets to the heap with priority \c p independently
260
    /// if \c i was already there.
261
    ///
262
    /// This method calls \ref push(\c i, \c p) if \c i is not stored
263
    /// in the heap and sets the priority of \c i to \c p otherwise.
264
    /// \param i The item.
265
    /// \param p The priority.
266
    void set(const Item &i, const Prio &p) {
267
      int idx = _iim[i];
268
      if (idx < 0) {
269
        push(i, p);
270
      } else if (Direction::less(p, _data[idx].value)) {
271
        decrease(i, p);
272
      } else {
273
        increase(i, p);
274
      }
275
    }
276

	
277
    /// \brief Decreases the priority of \c i to \c p.
278
    ///
279
    /// This method decreases the priority of item \c i to \c p.
280
    /// \pre \c i must be stored in the heap with priority at least \c
281
    /// p relative to \c Compare.
282
    /// \param i The item.
283
    /// \param p The priority.
284
    void decrease(const Item &i, const Prio &p) {
285
      int idx = _iim[i];
286
      unlace(idx);
287
      _data[idx].value = p;
288
      if (Direction::less(p, _minimum)) {
289
        _minimum = p;
290
      }
291
      lace(idx);
292
    }
293

	
294
    /// \brief Increases the priority of \c i to \c p.
295
    ///
296
    /// This method sets the priority of item \c i to \c p.
297
    /// \pre \c i must be stored in the heap with priority at most \c
298
    /// p relative to \c Compare.
299
    /// \param i The item.
300
    /// \param p The priority.
301
    void increase(const Item &i, const Prio &p) {
302
      int idx = _iim[i];
303
      unlace(idx);
304
      _data[idx].value = p;
305
      lace(idx);
306
    }
307

	
308
    /// \brief Returns if \c item is in, has already been in, or has
309
    /// never been in the heap.
310
    ///
311
    /// This method returns PRE_HEAP if \c item has never been in the
312
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
313
    /// otherwise. In the latter case it is possible that \c item will
314
    /// get back to the heap again.
315
    /// \param i The item.
316
    State state(const Item &i) const {
317
      int idx = _iim[i];
318
      if (idx >= 0) idx = 0;
319
      return State(idx);
320
    }
321

	
322
    /// \brief Sets the state of the \c item in the heap.
323
    ///
324
    /// Sets the state of the \c item in the heap. It can be used to
325
    /// manually clear the heap when it is important to achive the
326
    /// better time complexity.
327
    /// \param i The item.
328
    /// \param st The state. It should not be \c IN_HEAP.
329
    void state(const Item& i, State st) {
330
      switch (st) {
331
      case POST_HEAP:
332
      case PRE_HEAP:
333
        if (state(i) == IN_HEAP) {
334
          erase(i);
335
        }
336
        _iim[i] = st;
337
        break;
338
      case IN_HEAP:
339
        break;
340
      }
341
    }
342

	
343
  private:
344

	
345
    struct BucketItem {
346
      BucketItem(const Item& _item, int _value)
347
        : item(_item), value(_value) {}
348

	
349
      Item item;
350
      int value;
351

	
352
      int prev, next;
353
    };
354

	
355
    ItemIntMap& _iim;
356
    std::vector<int> _first;
357
    std::vector<BucketItem> _data;
358
    mutable int _minimum;
359

	
360
  }; // class BucketHeap
361

	
362
  /// \ingroup auxdat
363
  ///
364
  /// \brief A Simplified Bucket Heap implementation.
365
  ///
366
  /// This class implements a simplified \e bucket \e heap data
367
  /// structure.  It does not provide some functionality but it faster
368
  /// and simplier data structure than the BucketHeap. The main
369
  /// difference is that the BucketHeap stores for every key a double
370
  /// linked list while this class stores just simple lists. In the
371
  /// other way it does not support erasing each elements just the
372
  /// minimal and it does not supports key increasing, decreasing.
373
  ///
374
  /// \param IM A read and write Item int map, used internally
375
  /// to handle the cross references.
376
  /// \param MIN If the given parameter is false then instead of the
377
  /// minimum value the maximum can be retrivied with the top() and
378
  /// prio() member functions.
379
  ///
380
  /// \sa BucketHeap
381
  template <typename IM, bool MIN = true >
382
  class SimpleBucketHeap {
383

	
384
  public:
385
    typedef typename IM::Key Item;
386
    typedef int Prio;
387
    typedef std::pair<Item, Prio> Pair;
388
    typedef IM ItemIntMap;
389

	
390
  private:
391

	
392
    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
393

	
394
  public:
395

	
396
    /// \brief Type to represent the items states.
397
    ///
398
    /// Each Item element have a state associated to it. It may be "in heap",
399
    /// "pre heap" or "post heap". The latter two are indifferent from the
400
    /// heap's point of view, but may be useful to the user.
401
    ///
402
    /// The item-int map must be initialized in such way that it assigns
403
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
404
    enum State {
405
      IN_HEAP = 0,    ///< = 0.
406
      PRE_HEAP = -1,  ///< = -1.
407
      POST_HEAP = -2  ///< = -2.
408
    };
409

	
410
  public:
411

	
412
    /// \brief The constructor.
413
    ///
414
    /// The constructor.
415
    /// \param map should be given to the constructor, since it is used
416
    /// internally to handle the cross references. The value of the map
417
    /// should be PRE_HEAP (-1) for each element.
418
    explicit SimpleBucketHeap(ItemIntMap &map)
419
      : _iim(map), _free(-1), _num(0), _minimum(0) {}
420

	
421
    /// \brief Returns the number of items stored in the heap.
422
    ///
423
    /// The number of items stored in the heap.
424
    int size() const { return _num; }
425

	
426
    /// \brief Checks if the heap stores no items.
427
    ///
428
    /// Returns \c true if and only if the heap stores no items.
429
    bool empty() const { return _num == 0; }
430

	
431
    /// \brief Make empty this heap.
432
    ///
433
    /// Make empty this heap. It does not change the cross reference
434
    /// map.  If you want to reuse a heap what is not surely empty you
435
    /// should first clear the heap and after that you should set the
436
    /// cross reference map for each item to \c PRE_HEAP.
437
    void clear() {
438
      _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
439
    }
440

	
441
    /// \brief Insert a pair of item and priority into the heap.
442
    ///
443
    /// Adds \c p.first to the heap with priority \c p.second.
444
    /// \param p The pair to insert.
445
    void push(const Pair& p) {
446
      push(p.first, p.second);
447
    }
448

	
449
    /// \brief Insert an item into the heap with the given priority.
450
    ///
451
    /// Adds \c i to the heap with priority \c p.
452
    /// \param i The item to insert.
453
    /// \param p The priority of the item.
454
    void push(const Item &i, const Prio &p) {
455
      int idx;
456
      if (_free == -1) {
457
        idx = _data.size();
458
        _data.push_back(BucketItem(i));
459
      } else {
460
        idx = _free;
461
        _free = _data[idx].next;
462
        _data[idx].item = i;
463
      }
464
      _iim[i] = idx;
465
      if (p >= int(_first.size())) _first.resize(p + 1, -1);
466
      _data[idx].next = _first[p];
467
      _first[p] = idx;
468
      if (Direction::less(p, _minimum)) {
469
        _minimum = p;
470
      }
471
      ++_num;
472
    }
473

	
474
    /// \brief Returns the item with minimum priority.
475
    ///
476
    /// This method returns the item with minimum priority.
477
    /// \pre The heap must be nonempty.
478
    Item top() const {
479
      while (_first[_minimum] == -1) {
480
        Direction::increase(_minimum);
481
      }
482
      return _data[_first[_minimum]].item;
483
    }
484

	
485
    /// \brief Returns the minimum priority.
486
    ///
487
    /// It returns the minimum priority.
488
    /// \pre The heap must be nonempty.
489
    Prio prio() const {
490
      while (_first[_minimum] == -1) {
491
        Direction::increase(_minimum);
492
      }
493
      return _minimum;
494
    }
495

	
496
    /// \brief Deletes the item with minimum priority.
497
    ///
498
    /// This method deletes the item with minimum priority from the heap.
499
    /// \pre The heap must be non-empty.
500
    void pop() {
501
      while (_first[_minimum] == -1) {
502
        Direction::increase(_minimum);
503
      }
504
      int idx = _first[_minimum];
505
      _iim[_data[idx].item] = -2;
506
      _first[_minimum] = _data[idx].next;
507
      _data[idx].next = _free;
508
      _free = idx;
509
      --_num;
510
    }
511

	
512
    /// \brief Returns the priority of \c i.
513
    ///
514
    /// This function returns the priority of item \c i.
515
    /// \warning This operator is not a constant time function
516
    /// because it scans the whole data structure to find the proper
517
    /// value.
518
    /// \pre \c i must be in the heap.
519
    /// \param i The item.
520
    Prio operator[](const Item &i) const {
521
      for (int k = 0; k < _first.size(); ++k) {
522
        int idx = _first[k];
523
        while (idx != -1) {
524
          if (_data[idx].item == i) {
525
            return k;
526
          }
527
          idx = _data[idx].next;
528
        }
529
      }
530
      return -1;
531
    }
532

	
533
    /// \brief Returns if \c item is in, has already been in, or has
534
    /// never been in the heap.
535
    ///
536
    /// This method returns PRE_HEAP if \c item has never been in the
537
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
538
    /// otherwise. In the latter case it is possible that \c item will
539
    /// get back to the heap again.
540
    /// \param i The item.
541
    State state(const Item &i) const {
542
      int idx = _iim[i];
543
      if (idx >= 0) idx = 0;
544
      return State(idx);
545
    }
546

	
547
  private:
548

	
549
    struct BucketItem {
550
      BucketItem(const Item& _item)
551
        : item(_item) {}
552

	
553
      Item item;
554
      int next;
555
    };
556

	
557
    ItemIntMap& _iim;
558
    std::vector<int> _first;
559
    std::vector<BucketItem> _data;
560
    int _free, _num;
561
    mutable int _minimum;
562

	
563
  }; // class SimpleBucketHeap
564

	
565
}
566

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

	
19
///\file
20
///\brief Implementation of the CBC MIP solver interface.
21

	
22
#include "cbc.h"
23

	
24
#include <coin/CoinModel.hpp>
25
#include <coin/CbcModel.hpp>
26
#include <coin/OsiSolverInterface.hpp>
27

	
28
#ifdef COIN_HAS_CLP
29
#include "coin/OsiClpSolverInterface.hpp"
30
#endif
31
#ifdef COIN_HAS_OSL
32
#include "coin/OsiOslSolverInterface.hpp"
33
#endif
34

	
35
#include "coin/CbcCutGenerator.hpp"
36
#include "coin/CbcHeuristicLocal.hpp"
37
#include "coin/CbcHeuristicGreedy.hpp"
38
#include "coin/CbcHeuristicFPump.hpp"
39
#include "coin/CbcHeuristicRINS.hpp"
40

	
41
#include "coin/CglGomory.hpp"
42
#include "coin/CglProbing.hpp"
43
#include "coin/CglKnapsackCover.hpp"
44
#include "coin/CglOddHole.hpp"
45
#include "coin/CglClique.hpp"
46
#include "coin/CglFlowCover.hpp"
47
#include "coin/CglMixedIntegerRounding.hpp"
48

	
49
#include "coin/CbcHeuristic.hpp"
50

	
51
namespace lemon {
52

	
53
  CbcMip::CbcMip() {
54
    _prob = new CoinModel();
55
    _prob->setProblemName("LEMON");
56
    _osi_solver = 0;
57
    _cbc_model = 0;
58
    messageLevel(MESSAGE_NOTHING);
59
  }
60

	
61
  CbcMip::CbcMip(const CbcMip& other) {
62
    _prob = new CoinModel(*other._prob);
63
    _prob->setProblemName("LEMON");
64
    _osi_solver = 0;
65
    _cbc_model = 0;
66
    messageLevel(MESSAGE_NOTHING);
67
  }
68

	
69
  CbcMip::~CbcMip() {
70
    delete _prob;
71
    if (_osi_solver) delete _osi_solver;
72
    if (_cbc_model) delete _cbc_model;
73
  }
74

	
75
  const char* CbcMip::_solverName() const { return "CbcMip"; }
76

	
77
  int CbcMip::_addCol() {
78
    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0, 0, false);
79
    return _prob->numberColumns() - 1;
80
  }
81

	
82
  CbcMip* CbcMip::newSolver() const {
83
    CbcMip* newlp = new CbcMip;
84
    return newlp;
85
  }
86

	
87
  CbcMip* CbcMip::cloneSolver() const {
88
    CbcMip* copylp = new CbcMip(*this);
89
    return copylp;
90
  }
91

	
92
  int CbcMip::_addRow() {
93
    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
94
    return _prob->numberRows() - 1;
95
  }
96

	
97

	
98
  void CbcMip::_eraseCol(int i) {
99
    _prob->deleteColumn(i);
100
  }
101

	
102
  void CbcMip::_eraseRow(int i) {
103
    _prob->deleteRow(i);
104
  }
105

	
106
  void CbcMip::_eraseColId(int i) {
107
    cols.eraseIndex(i);
108
  }
109

	
110
  void CbcMip::_eraseRowId(int i) {
111
    rows.eraseIndex(i);
112
  }
113

	
114
  void CbcMip::_getColName(int c, std::string& name) const {
115
    name = _prob->getColumnName(c);
116
  }
117

	
118
  void CbcMip::_setColName(int c, const std::string& name) {
119
    _prob->setColumnName(c, name.c_str());
120
  }
121

	
122
  int CbcMip::_colByName(const std::string& name) const {
123
    return _prob->column(name.c_str());
124
  }
125

	
126
  void CbcMip::_getRowName(int r, std::string& name) const {
127
    name = _prob->getRowName(r);
128
  }
129

	
130
  void CbcMip::_setRowName(int r, const std::string& name) {
131
    _prob->setRowName(r, name.c_str());
132
  }
133

	
134
  int CbcMip::_rowByName(const std::string& name) const {
135
    return _prob->row(name.c_str());
136
  }
137

	
138
  void CbcMip::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
139
    for (ExprIterator it = b; it != e; ++it) {
140
      _prob->setElement(i, it->first, it->second);
141
    }
142
  }
143

	
144
  void CbcMip::_getRowCoeffs(int ix, InsertIterator b) const {
145
    int length = _prob->numberRows();
146

	
147
    std::vector<int> indices(length);
148
    std::vector<Value> values(length);
149

	
150
    length = _prob->getRow(ix, &indices[0], &values[0]);
151

	
152
    for (int i = 0; i < length; ++i) {
153
      *b = std::make_pair(indices[i], values[i]);
154
      ++b;
155
    }
156
  }
157

	
158
  void CbcMip::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
159
    for (ExprIterator it = b; it != e; ++it) {
160
      _prob->setElement(it->first, ix, it->second);
161
    }
162
  }
163

	
164
  void CbcMip::_getColCoeffs(int ix, InsertIterator b) const {
165
    int length = _prob->numberColumns();
166

	
167
    std::vector<int> indices(length);
168
    std::vector<Value> values(length);
169

	
170
    length = _prob->getColumn(ix, &indices[0], &values[0]);
171

	
172
    for (int i = 0; i < length; ++i) {
173
      *b = std::make_pair(indices[i], values[i]);
174
      ++b;
175
    }
176
  }
177

	
178
  void CbcMip::_setCoeff(int ix, int jx, Value value) {
179
    _prob->setElement(ix, jx, value);
180
  }
181

	
182
  CbcMip::Value CbcMip::_getCoeff(int ix, int jx) const {
183
    return _prob->getElement(ix, jx);
184
  }
185

	
186

	
187
  void CbcMip::_setColLowerBound(int i, Value lo) {
188
    LEMON_ASSERT(lo != INF, "Invalid bound");
189
    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
190
  }
191

	
192
  CbcMip::Value CbcMip::_getColLowerBound(int i) const {
193
    double val = _prob->getColumnLower(i);
194
    return val == - COIN_DBL_MAX ? - INF : val;
195
  }
196

	
197
  void CbcMip::_setColUpperBound(int i, Value up) {
198
    LEMON_ASSERT(up != -INF, "Invalid bound");
199
    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
200
  }
201

	
202
  CbcMip::Value CbcMip::_getColUpperBound(int i) const {
203
    double val = _prob->getColumnUpper(i);
204
    return val == COIN_DBL_MAX ? INF : val;
205
  }
206

	
207
  void CbcMip::_setRowLowerBound(int i, Value lo) {
208
    LEMON_ASSERT(lo != INF, "Invalid bound");
209
    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
210
  }
211

	
212
  CbcMip::Value CbcMip::_getRowLowerBound(int i) const {
213
    double val = _prob->getRowLower(i);
214
    return val == - COIN_DBL_MAX ? - INF : val;
215
  }
216

	
217
  void CbcMip::_setRowUpperBound(int i, Value up) {
218
    LEMON_ASSERT(up != -INF, "Invalid bound");
219
    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
220
  }
221

	
222
  CbcMip::Value CbcMip::_getRowUpperBound(int i) const {
223
    double val = _prob->getRowUpper(i);
224
    return val == COIN_DBL_MAX ? INF : val;
225
  }
226

	
227
  void CbcMip::_setObjCoeffs(ExprIterator b, ExprIterator e) {
228
    int num = _prob->numberColumns();
229
    for (int i = 0; i < num; ++i) {
230
      _prob->setColumnObjective(i, 0.0);
231
    }
232
    for (ExprIterator it = b; it != e; ++it) {
233
      _prob->setColumnObjective(it->first, it->second);
234
    }
235
  }
236

	
237
  void CbcMip::_getObjCoeffs(InsertIterator b) const {
238
    int num = _prob->numberColumns();
239
    for (int i = 0; i < num; ++i) {
240
      Value coef = _prob->getColumnObjective(i);
241
      if (coef != 0.0) {
242
        *b = std::make_pair(i, coef);
243
        ++b;
244
      }
245
    }
246
  }
247

	
248
  void CbcMip::_setObjCoeff(int i, Value obj_coef) {
249
    _prob->setColumnObjective(i, obj_coef);
250
  }
251

	
252
  CbcMip::Value CbcMip::_getObjCoeff(int i) const {
253
    return _prob->getColumnObjective(i);
254
  }
255

	
256
  CbcMip::SolveExitStatus CbcMip::_solve() {
257

	
258
    if (_osi_solver) {
259
      delete _osi_solver;
260
    }
261
#ifdef COIN_HAS_CLP
262
    _osi_solver = new OsiClpSolverInterface();
263
#elif COIN_HAS_OSL
264
    _osi_solver = new OsiOslSolverInterface();
265
#else
266
#error Cannot instantiate Osi solver
267
#endif
268

	
269
    _osi_solver->loadFromCoinModel(*_prob);
270

	
271
    if (_cbc_model) {
272
      delete _cbc_model;
273
    }
274
    _cbc_model= new CbcModel(*_osi_solver);
275

	
276
    _osi_solver->messageHandler()->setLogLevel(_message_level);
277
    _cbc_model->setLogLevel(_message_level);
278

	
279
    _cbc_model->initialSolve();
280
    _cbc_model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
281

	
282
    if (!_cbc_model->isInitialSolveAbandoned() &&
283
        _cbc_model->isInitialSolveProvenOptimal() &&
284
        !_cbc_model->isInitialSolveProvenPrimalInfeasible() &&
285
        !_cbc_model->isInitialSolveProvenDualInfeasible()) {
286

	
287
      CglProbing generator1;
288
      generator1.setUsingObjective(true);
289
      generator1.setMaxPass(3);
290
      generator1.setMaxProbe(100);
291
      generator1.setMaxLook(50);
292
      generator1.setRowCuts(3);
293
      _cbc_model->addCutGenerator(&generator1, -1, "Probing");
294

	
295
      CglGomory generator2;
296
      generator2.setLimit(300);
297
      _cbc_model->addCutGenerator(&generator2, -1, "Gomory");
298

	
299
      CglKnapsackCover generator3;
300
      _cbc_model->addCutGenerator(&generator3, -1, "Knapsack");
301

	
302
      CglOddHole generator4;
303
      generator4.setMinimumViolation(0.005);
304
      generator4.setMinimumViolationPer(0.00002);
305
      generator4.setMaximumEntries(200);
306
      _cbc_model->addCutGenerator(&generator4, -1, "OddHole");
307

	
308
      CglClique generator5;
309
      generator5.setStarCliqueReport(false);
310
      generator5.setRowCliqueReport(false);
311
      _cbc_model->addCutGenerator(&generator5, -1, "Clique");
312

	
313
      CglMixedIntegerRounding mixedGen;
314
      _cbc_model->addCutGenerator(&mixedGen, -1, "MixedIntegerRounding");
315

	
316
      CglFlowCover flowGen;
317
      _cbc_model->addCutGenerator(&flowGen, -1, "FlowCover");
318

	
319
#ifdef COIN_HAS_CLP
320
      OsiClpSolverInterface* osiclp =
321
        dynamic_cast<OsiClpSolverInterface*>(_cbc_model->solver());
322
      if (osiclp->getNumRows() < 300 && osiclp->getNumCols() < 500) {
323
        osiclp->setupForRepeatedUse(2, 0);
324
      }
325
#endif
326

	
327
      CbcRounding heuristic1(*_cbc_model);
328
      heuristic1.setWhen(3);
329
      _cbc_model->addHeuristic(&heuristic1);
330

	
331
      CbcHeuristicLocal heuristic2(*_cbc_model);
332
      heuristic2.setWhen(3);
333
      _cbc_model->addHeuristic(&heuristic2);
334

	
335
      CbcHeuristicGreedyCover heuristic3(*_cbc_model);
336
      heuristic3.setAlgorithm(11);
337
      heuristic3.setWhen(3);
338
      _cbc_model->addHeuristic(&heuristic3);
339

	
340
      CbcHeuristicFPump heuristic4(*_cbc_model);
341
      heuristic4.setWhen(3);
342
      _cbc_model->addHeuristic(&heuristic4);
343

	
344
      CbcHeuristicRINS heuristic5(*_cbc_model);
345
      heuristic5.setWhen(3);
346
      _cbc_model->addHeuristic(&heuristic5);
347

	
348
      if (_cbc_model->getNumCols() < 500) {
349
        _cbc_model->setMaximumCutPassesAtRoot(-100);
350
      } else if (_cbc_model->getNumCols() < 5000) {
351
        _cbc_model->setMaximumCutPassesAtRoot(100);
352
      } else {
353
        _cbc_model->setMaximumCutPassesAtRoot(20);
354
      }
355

	
356
      if (_cbc_model->getNumCols() < 5000) {
357
        _cbc_model->setNumberStrong(10);
358
      }
359

	
360
      _cbc_model->solver()->setIntParam(OsiMaxNumIterationHotStart, 100);
361
      _cbc_model->branchAndBound();
362
    }
363

	
364
    if (_cbc_model->isAbandoned()) {
365
      return UNSOLVED;
366
    } else {
367
      return SOLVED;
368
    }
369
  }
370

	
371
  CbcMip::Value CbcMip::_getSol(int i) const {
372
    return _cbc_model->getColSolution()[i];
373
  }
374

	
375
  CbcMip::Value CbcMip::_getSolValue() const {
376
    return _cbc_model->getObjValue();
377
  }
378

	
379
  CbcMip::ProblemType CbcMip::_getType() const {
380
    if (_cbc_model->isProvenOptimal()) {
381
      return OPTIMAL;
382
    } else if (_cbc_model->isContinuousUnbounded()) {
383
      return UNBOUNDED;
384
    }
385
    return FEASIBLE;
386
  }
387

	
388
  void CbcMip::_setSense(Sense sense) {
389
    switch (sense) {
390
    case MIN:
391
      _prob->setOptimizationDirection(1.0);
392
      break;
393
    case MAX:
394
      _prob->setOptimizationDirection(- 1.0);
395
      break;
396
    }
397
  }
398

	
399
  CbcMip::Sense CbcMip::_getSense() const {
400
    if (_prob->optimizationDirection() > 0.0) {
401
      return MIN;
402
    } else if (_prob->optimizationDirection() < 0.0) {
403
      return MAX;
404
    } else {
405
      LEMON_ASSERT(false, "Wrong sense");
406
      return CbcMip::Sense();
407
    }
408
  }
409

	
410
  void CbcMip::_setColType(int i, CbcMip::ColTypes col_type) {
411
    switch (col_type){
412
    case INTEGER:
413
      _prob->setInteger(i);
414
      break;
415
    case REAL:
416
      _prob->setContinuous(i);
417
      break;
418
    default:;
419
      LEMON_ASSERT(false, "Wrong sense");
420
    }
421
  }
422

	
423
  CbcMip::ColTypes CbcMip::_getColType(int i) const {
424
    return _prob->getColumnIsInteger(i) ? INTEGER : REAL;
425
  }
426

	
427
  void CbcMip::_clear() {
428
    delete _prob;
429
    if (_osi_solver) {
430
      delete _osi_solver;
431
      _osi_solver = 0;
432
    }
433
    if (_cbc_model) {
434
      delete _cbc_model;
435
      _cbc_model = 0;
436
    }
437

	
438
    _prob = new CoinModel();
439
    rows.clear();
440
    cols.clear();
441
  }
442

	
443
  void CbcMip::_messageLevel(MessageLevel level) {
444
    switch (level) {
445
    case MESSAGE_NOTHING:
446
      _message_level = 0;
447
      break;
448
    case MESSAGE_ERROR:
449
      _message_level = 1;
450
      break;
451
    case MESSAGE_WARNING:
452
      _message_level = 1;
453
      break;
454
    case MESSAGE_NORMAL:
455
      _message_level = 2;
456
      break;
457
    case MESSAGE_VERBOSE:
458
      _message_level = 3;
459
      break;
460
    }
461
  }
462

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

	
19
// -*- C++ -*-
20
#ifndef LEMON_CBC_H
21
#define LEMON_CBC_H
22

	
23
///\file
24
///\brief Header of the LEMON-CBC mip solver interface.
25
///\ingroup lp_group
26

	
27
#include <lemon/lp_base.h>
28

	
29
class CoinModel;
30
class OsiSolverInterface;
31
class CbcModel;
32

	
33
namespace lemon {
34

	
35
  /// \brief Interface for the CBC MIP solver
36
  ///
37
  /// This class implements an interface for the CBC MIP solver.
38
  ///\ingroup lp_group
39
  class CbcMip : public MipSolver {
40
  protected:
41

	
42
    CoinModel *_prob;
43
    OsiSolverInterface *_osi_solver;
44
    CbcModel *_cbc_model;
45

	
46
  public:
47

	
48
    /// \e
49
    CbcMip();
50
    /// \e
51
    CbcMip(const CbcMip&);
52
    /// \e
53
    ~CbcMip();
54
    /// \e
55
    virtual CbcMip* newSolver() const;
56
    /// \e
57
    virtual CbcMip* cloneSolver() const;
58

	
59
  protected:
60

	
61
    virtual const char* _solverName() const;
62

	
63
    virtual int _addCol();
64
    virtual int _addRow();
65

	
66
    virtual void _eraseCol(int i);
67
    virtual void _eraseRow(int i);
68

	
69
    virtual void _eraseColId(int i);
70
    virtual void _eraseRowId(int i);
71

	
72
    virtual void _getColName(int col, std::string& name) const;
73
    virtual void _setColName(int col, const std::string& name);
74
    virtual int _colByName(const std::string& name) const;
75

	
76
    virtual void _getRowName(int row, std::string& name) const;
77
    virtual void _setRowName(int row, const std::string& name);
78
    virtual int _rowByName(const std::string& name) const;
79

	
80
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
81
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
82

	
83
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
84
    virtual void _getColCoeffs(int i, InsertIterator b) const;
85

	
86
    virtual void _setCoeff(int row, int col, Value value);
87
    virtual Value _getCoeff(int row, int col) const;
88

	
89
    virtual void _setColLowerBound(int i, Value value);
90
    virtual Value _getColLowerBound(int i) const;
91
    virtual void _setColUpperBound(int i, Value value);
92
    virtual Value _getColUpperBound(int i) const;
93

	
94
    virtual void _setRowLowerBound(int i, Value value);
95
    virtual Value _getRowLowerBound(int i) const;
96
    virtual void _setRowUpperBound(int i, Value value);
97
    virtual Value _getRowUpperBound(int i) const;
98

	
99
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
100
    virtual void _getObjCoeffs(InsertIterator b) const;
101

	
102
    virtual void _setObjCoeff(int i, Value obj_coef);
103
    virtual Value _getObjCoeff(int i) const;
104

	
105
    virtual void _setSense(Sense sense);
106
    virtual Sense _getSense() const;
107

	
108
    virtual ColTypes _getColType(int col) const;
109
    virtual void _setColType(int col, ColTypes col_type);
110

	
111
    virtual SolveExitStatus _solve();
112
    virtual ProblemType _getType() const;
113
    virtual Value _getSol(int i) const;
114
    virtual Value _getSolValue() const;
115

	
116
    virtual void _clear();
117

	
118
    virtual void _messageLevel(MessageLevel level);
119
    void _applyMessageLevel();
120

	
121
    int _message_level;
122

	
123
    
124

	
125
  };
126

	
127
}
128

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

	
19
#ifndef LEMON_CIRCULATION_H
20
#define LEMON_CIRCULATION_H
21

	
22
#include <lemon/tolerance.h>
23
#include <lemon/elevator.h>
24
#include <limits>
25

	
26
///\ingroup max_flow
27
///\file
28
///\brief Push-relabel algorithm for finding a feasible circulation.
29
///
30
namespace lemon {
31

	
32
  /// \brief Default traits class of Circulation class.
33
  ///
34
  /// Default traits class of Circulation class.
35
  ///
36
  /// \tparam GR Type of the digraph the algorithm runs on.
37
  /// \tparam LM The type of the lower bound map.
38
  /// \tparam UM The type of the upper bound (capacity) map.
39
  /// \tparam SM The type of the supply map.
40
  template <typename GR, typename LM,
41
            typename UM, typename SM>
42
  struct CirculationDefaultTraits {
43

	
44
    /// \brief The type of the digraph the algorithm runs on.
45
    typedef GR Digraph;
46

	
47
    /// \brief The type of the lower bound map.
48
    ///
49
    /// The type of the map that stores the lower bounds on the arcs.
50
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
51
    typedef LM LowerMap;
52

	
53
    /// \brief The type of the upper bound (capacity) map.
54
    ///
55
    /// The type of the map that stores the upper bounds (capacities)
56
    /// on the arcs.
57
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
58
    typedef UM UpperMap;
59

	
60
    /// \brief The type of supply map.
61
    ///
62
    /// The type of the map that stores the signed supply values of the 
63
    /// nodes. 
64
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
65
    typedef SM SupplyMap;
66

	
67
    /// \brief The type of the flow and supply values.
68
    typedef typename SupplyMap::Value Value;
69

	
70
    /// \brief The type of the map that stores the flow values.
71
    ///
72
    /// The type of the map that stores the flow values.
73
    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
74
    /// concept.
75
    typedef typename Digraph::template ArcMap<Value> FlowMap;
76

	
77
    /// \brief Instantiates a FlowMap.
78
    ///
79
    /// This function instantiates a \ref FlowMap.
80
    /// \param digraph The digraph for which we would like to define
81
    /// the flow map.
82
    static FlowMap* createFlowMap(const Digraph& digraph) {
83
      return new FlowMap(digraph);
84
    }
85

	
86
    /// \brief The elevator type used by the algorithm.
87
    ///
88
    /// The elevator type used by the algorithm.
89
    ///
90
    /// \sa Elevator
91
    /// \sa LinkedElevator
92
    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
93

	
94
    /// \brief Instantiates an Elevator.
95
    ///
96
    /// This function instantiates an \ref Elevator.
97
    /// \param digraph The digraph for which we would like to define
98
    /// the elevator.
99
    /// \param max_level The maximum level of the elevator.
100
    static Elevator* createElevator(const Digraph& digraph, int max_level) {
101
      return new Elevator(digraph, max_level);
102
    }
103

	
104
    /// \brief The tolerance used by the algorithm
105
    ///
106
    /// The tolerance used by the algorithm to handle inexact computation.
107
    typedef lemon::Tolerance<Value> Tolerance;
108

	
109
  };
110

	
111
  /**
112
     \brief Push-relabel algorithm for the network circulation problem.
113

	
114
     \ingroup max_flow
115
     This class implements a push-relabel algorithm for the \e network
116
     \e circulation problem.
117
     It is to find a feasible circulation when lower and upper bounds
118
     are given for the flow values on the arcs and lower bounds are
119
     given for the difference between the outgoing and incoming flow
120
     at the nodes.
121

	
122
     The exact formulation of this problem is the following.
123
     Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$
124
     \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and
125
     upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$
126
     holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
127
     denotes the signed supply values of the nodes.
128
     If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
129
     supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
130
     \f$-sup(u)\f$ demand.
131
     A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$
132
     solution of the following problem.
133

	
134
     \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
135
     \geq sup(u) \quad \forall u\in V, \f]
136
     \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
137
     
138
     The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
139
     zero or negative in order to have a feasible solution (since the sum
140
     of the expressions on the left-hand side of the inequalities is zero).
141
     It means that the total demand must be greater or equal to the total
142
     supply and all the supplies have to be carried out from the supply nodes,
143
     but there could be demands that are not satisfied.
144
     If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
145
     constraints have to be satisfied with equality, i.e. all demands
146
     have to be satisfied and all supplies have to be used.
147
     
148
     If you need the opposite inequalities in the supply/demand constraints
149
     (i.e. the total demand is less than the total supply and all the demands
150
     have to be satisfied while there could be supplies that are not used),
151
     then you could easily transform the problem to the above form by reversing
152
     the direction of the arcs and taking the negative of the supply values
153
     (e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
154

	
155
     This algorithm either calculates a feasible circulation, or provides
156
     a \ref barrier() "barrier", which prooves that a feasible soultion
157
     cannot exist.
158

	
159
     Note that this algorithm also provides a feasible solution for the
160
     \ref min_cost_flow "minimum cost flow problem".
161

	
162
     \tparam GR The type of the digraph the algorithm runs on.
163
     \tparam LM The type of the lower bound map. The default
164
     map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
165
     \tparam UM The type of the upper bound (capacity) map.
166
     The default map type is \c LM.
167
     \tparam SM The type of the supply map. The default map type is
168
     \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
169
  */
170
#ifdef DOXYGEN
171
template< typename GR,
172
          typename LM,
173
          typename UM,
174
          typename SM,
175
          typename TR >
176
#else
177
template< typename GR,
178
          typename LM = typename GR::template ArcMap<int>,
179
          typename UM = LM,
180
          typename SM = typename GR::template NodeMap<typename UM::Value>,
181
          typename TR = CirculationDefaultTraits<GR, LM, UM, SM> >
182
#endif
183
  class Circulation {
184
  public:
185

	
186
    ///The \ref CirculationDefaultTraits "traits class" of the algorithm.
187
    typedef TR Traits;
188
    ///The type of the digraph the algorithm runs on.
189
    typedef typename Traits::Digraph Digraph;
190
    ///The type of the flow and supply values.
191
    typedef typename Traits::Value Value;
192

	
193
    ///The type of the lower bound map.
194
    typedef typename Traits::LowerMap LowerMap;
195
    ///The type of the upper bound (capacity) map.
196
    typedef typename Traits::UpperMap UpperMap;
197
    ///The type of the supply map.
198
    typedef typename Traits::SupplyMap SupplyMap;
199
    ///The type of the flow map.
200
    typedef typename Traits::FlowMap FlowMap;
201

	
202
    ///The type of the elevator.
203
    typedef typename Traits::Elevator Elevator;
204
    ///The type of the tolerance.
205
    typedef typename Traits::Tolerance Tolerance;
206

	
207
  private:
208

	
209
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
210

	
211
    const Digraph &_g;
212
    int _node_num;
213

	
214
    const LowerMap *_lo;
215
    const UpperMap *_up;
216
    const SupplyMap *_supply;
217

	
218
    FlowMap *_flow;
219
    bool _local_flow;
220

	
221
    Elevator* _level;
222
    bool _local_level;
223

	
224
    typedef typename Digraph::template NodeMap<Value> ExcessMap;
225
    ExcessMap* _excess;
226

	
227
    Tolerance _tol;
228
    int _el;
229

	
230
  public:
231

	
232
    typedef Circulation Create;
233

	
234
    ///\name Named Template Parameters
235

	
236
    ///@{
237

	
238
    template <typename T>
239
    struct SetFlowMapTraits : public Traits {
240
      typedef T FlowMap;
241
      static FlowMap *createFlowMap(const Digraph&) {
242
        LEMON_ASSERT(false, "FlowMap is not initialized");
243
        return 0; // ignore warnings
244
      }
245
    };
246

	
247
    /// \brief \ref named-templ-param "Named parameter" for setting
248
    /// FlowMap type
249
    ///
250
    /// \ref named-templ-param "Named parameter" for setting FlowMap
251
    /// type.
252
    template <typename T>
253
    struct SetFlowMap
254
      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
255
                           SetFlowMapTraits<T> > {
256
      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
257
                          SetFlowMapTraits<T> > Create;
258
    };
259

	
260
    template <typename T>
261
    struct SetElevatorTraits : public Traits {
262
      typedef T Elevator;
263
      static Elevator *createElevator(const Digraph&, int) {
264
        LEMON_ASSERT(false, "Elevator is not initialized");
265
        return 0; // ignore warnings
266
      }
267
    };
268

	
269
    /// \brief \ref named-templ-param "Named parameter" for setting
270
    /// Elevator type
271
    ///
272
    /// \ref named-templ-param "Named parameter" for setting Elevator
273
    /// type. If this named parameter is used, then an external
274
    /// elevator object must be passed to the algorithm using the
275
    /// \ref elevator(Elevator&) "elevator()" function before calling
276
    /// \ref run() or \ref init().
277
    /// \sa SetStandardElevator
278
    template <typename T>
279
    struct SetElevator
280
      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
281
                           SetElevatorTraits<T> > {
282
      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
283
                          SetElevatorTraits<T> > Create;
284
    };
285

	
286
    template <typename T>
287
    struct SetStandardElevatorTraits : public Traits {
288
      typedef T Elevator;
289
      static Elevator *createElevator(const Digraph& digraph, int max_level) {
290
        return new Elevator(digraph, max_level);
291
      }
292
    };
293

	
294
    /// \brief \ref named-templ-param "Named parameter" for setting
295
    /// Elevator type with automatic allocation
296
    ///
297
    /// \ref named-templ-param "Named parameter" for setting Elevator
298
    /// type with automatic allocation.
299
    /// The Elevator should have standard constructor interface to be
300
    /// able to automatically created by the algorithm (i.e. the
301
    /// digraph and the maximum level should be passed to it).
302
    /// However an external elevator object could also be passed to the
303
    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
304
    /// before calling \ref run() or \ref init().
305
    /// \sa SetElevator
306
    template <typename T>
307
    struct SetStandardElevator
308
      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
309
                       SetStandardElevatorTraits<T> > {
310
      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
311
                      SetStandardElevatorTraits<T> > Create;
312
    };
313

	
314
    /// @}
315

	
316
  protected:
317

	
318
    Circulation() {}
319

	
320
  public:
321

	
322
    /// Constructor.
323

	
324
    /// The constructor of the class.
325
    ///
326
    /// \param graph The digraph the algorithm runs on.
327
    /// \param lower The lower bounds for the flow values on the arcs.
328
    /// \param upper The upper bounds (capacities) for the flow values 
329
    /// on the arcs.
330
    /// \param supply The signed supply values of the nodes.
331
    Circulation(const Digraph &graph, const LowerMap &lower,
332
                const UpperMap &upper, const SupplyMap &supply)
333
      : _g(graph), _lo(&lower), _up(&upper), _supply(&supply),
334
        _flow(NULL), _local_flow(false), _level(NULL), _local_level(false),
335
        _excess(NULL) {}
336

	
337
    /// Destructor.
338
    ~Circulation() {
339
      destroyStructures();
340
    }
341

	
342

	
343
  private:
344

	
345
    bool checkBoundMaps() {
346
      for (ArcIt e(_g);e!=INVALID;++e) {
347
        if (_tol.less((*_up)[e], (*_lo)[e])) return false;
348
      }
349
      return true;
350
    }
351

	
352
    void createStructures() {
353
      _node_num = _el = countNodes(_g);
354

	
355
      if (!_flow) {
356
        _flow = Traits::createFlowMap(_g);
357
        _local_flow = true;
358
      }
359
      if (!_level) {
360
        _level = Traits::createElevator(_g, _node_num);
361
        _local_level = true;
362
      }
363
      if (!_excess) {
364
        _excess = new ExcessMap(_g);
365
      }
366
    }
367

	
368
    void destroyStructures() {
369
      if (_local_flow) {
370
        delete _flow;
371
      }
372
      if (_local_level) {
373
        delete _level;
374
      }
375
      if (_excess) {
376
        delete _excess;
377
      }
378
    }
379

	
380
  public:
381

	
382
    /// Sets the lower bound map.
383

	
384
    /// Sets the lower bound map.
385
    /// \return <tt>(*this)</tt>
386
    Circulation& lowerMap(const LowerMap& map) {
387
      _lo = &map;
388
      return *this;
389
    }
390

	
391
    /// Sets the upper bound (capacity) map.
392

	
393
    /// Sets the upper bound (capacity) map.
394
    /// \return <tt>(*this)</tt>
395
    Circulation& upperMap(const UpperMap& map) {
396
      _up = &map;
397
      return *this;
398
    }
399

	
400
    /// Sets the supply map.
401

	
402
    /// Sets the supply map.
403
    /// \return <tt>(*this)</tt>
404
    Circulation& supplyMap(const SupplyMap& map) {
405
      _supply = &map;
406
      return *this;
407
    }
408

	
409
    /// \brief Sets the flow map.
410
    ///
411
    /// Sets the flow map.
412
    /// If you don't use this function before calling \ref run() or
413
    /// \ref init(), an instance will be allocated automatically.
414
    /// The destructor deallocates this automatically allocated map,
415
    /// of course.
416
    /// \return <tt>(*this)</tt>
417
    Circulation& flowMap(FlowMap& map) {
418
      if (_local_flow) {
419
        delete _flow;
420
        _local_flow = false;
421
      }
422
      _flow = &map;
423
      return *this;
424
    }
425

	
426
    /// \brief Sets the elevator used by algorithm.
427
    ///
428
    /// Sets the elevator used by algorithm.
429
    /// If you don't use this function before calling \ref run() or
430
    /// \ref init(), an instance will be allocated automatically.
431
    /// The destructor deallocates this automatically allocated elevator,
432
    /// of course.
433
    /// \return <tt>(*this)</tt>
434
    Circulation& elevator(Elevator& elevator) {
435
      if (_local_level) {
436
        delete _level;
437
        _local_level = false;
438
      }
439
      _level = &elevator;
440
      return *this;
441
    }
442

	
443
    /// \brief Returns a const reference to the elevator.
444
    ///
445
    /// Returns a const reference to the elevator.
446
    ///
447
    /// \pre Either \ref run() or \ref init() must be called before
448
    /// using this function.
449
    const Elevator& elevator() const {
450
      return *_level;
451
    }
452

	
453
    /// \brief Sets the tolerance used by algorithm.
454
    ///
455
    /// Sets the tolerance used by algorithm.
456
    Circulation& tolerance(const Tolerance& tolerance) const {
457
      _tol = tolerance;
458
      return *this;
459
    }
460

	
461
    /// \brief Returns a const reference to the tolerance.
462
    ///
463
    /// Returns a const reference to the tolerance.
464
    const Tolerance& tolerance() const {
465
      return tolerance;
466
    }
467

	
468
    /// \name Execution Control
469
    /// The simplest way to execute the algorithm is to call \ref run().\n
470
    /// If you need more control on the initial solution or the execution,
471
    /// first you have to call one of the \ref init() functions, then
472
    /// the \ref start() function.
473

	
474
    ///@{
475

	
476
    /// Initializes the internal data structures.
477

	
478
    /// Initializes the internal data structures and sets all flow values
479
    /// to the lower bound.
480
    void init()
481
    {
482
      LEMON_DEBUG(checkBoundMaps(),
483
        "Upper bounds must be greater or equal to the lower bounds");
484

	
485
      createStructures();
486

	
487
      for(NodeIt n(_g);n!=INVALID;++n) {
488
        (*_excess)[n] = (*_supply)[n];
489
      }
490

	
491
      for (ArcIt e(_g);e!=INVALID;++e) {
492
        _flow->set(e, (*_lo)[e]);
493
        (*_excess)[_g.target(e)] += (*_flow)[e];
494
        (*_excess)[_g.source(e)] -= (*_flow)[e];
495
      }
496

	
497
      // global relabeling tested, but in general case it provides
498
      // worse performance for random digraphs
499
      _level->initStart();
500
      for(NodeIt n(_g);n!=INVALID;++n)
501
        _level->initAddItem(n);
502
      _level->initFinish();
503
      for(NodeIt n(_g);n!=INVALID;++n)
504
        if(_tol.positive((*_excess)[n]))
505
          _level->activate(n);
506
    }
507

	
508
    /// Initializes the internal data structures using a greedy approach.
509

	
510
    /// Initializes the internal data structures using a greedy approach
511
    /// to construct the initial solution.
512
    void greedyInit()
513
    {
514
      LEMON_DEBUG(checkBoundMaps(),
515
        "Upper bounds must be greater or equal to the lower bounds");
516

	
517
      createStructures();
518

	
519
      for(NodeIt n(_g);n!=INVALID;++n) {
520
        (*_excess)[n] = (*_supply)[n];
521
      }
522

	
523
      for (ArcIt e(_g);e!=INVALID;++e) {
524
        if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) {
525
          _flow->set(e, (*_up)[e]);
526
          (*_excess)[_g.target(e)] += (*_up)[e];
527
          (*_excess)[_g.source(e)] -= (*_up)[e];
528
        } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) {
529
          _flow->set(e, (*_lo)[e]);
530
          (*_excess)[_g.target(e)] += (*_lo)[e];
531
          (*_excess)[_g.source(e)] -= (*_lo)[e];
532
        } else {
533
          Value fc = -(*_excess)[_g.target(e)];
534
          _flow->set(e, fc);
535
          (*_excess)[_g.target(e)] = 0;
536
          (*_excess)[_g.source(e)] -= fc;
537
        }
538
      }
539

	
540
      _level->initStart();
541
      for(NodeIt n(_g);n!=INVALID;++n)
542
        _level->initAddItem(n);
543
      _level->initFinish();
544
      for(NodeIt n(_g);n!=INVALID;++n)
545
        if(_tol.positive((*_excess)[n]))
546
          _level->activate(n);
547
    }
548

	
549
    ///Executes the algorithm
550

	
551
    ///This function executes the algorithm.
552
    ///
553
    ///\return \c true if a feasible circulation is found.
554
    ///
555
    ///\sa barrier()
556
    ///\sa barrierMap()
557
    bool start()
558
    {
559

	
560
      Node act;
561
      Node bact=INVALID;
562
      Node last_activated=INVALID;
563
      while((act=_level->highestActive())!=INVALID) {
564
        int actlevel=(*_level)[act];
565
        int mlevel=_node_num;
566
        Value exc=(*_excess)[act];
567

	
568
        for(OutArcIt e(_g,act);e!=INVALID; ++e) {
569
          Node v = _g.target(e);
570
          Value fc=(*_up)[e]-(*_flow)[e];
571
          if(!_tol.positive(fc)) continue;
572
          if((*_level)[v]<actlevel) {
573
            if(!_tol.less(fc, exc)) {
574
              _flow->set(e, (*_flow)[e] + exc);
575
              (*_excess)[v] += exc;
576
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
577
                _level->activate(v);
578
              (*_excess)[act] = 0;
579
              _level->deactivate(act);
580
              goto next_l;
581
            }
582
            else {
583
              _flow->set(e, (*_up)[e]);
584
              (*_excess)[v] += fc;
585
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
586
                _level->activate(v);
587
              exc-=fc;
588
            }
589
          }
590
          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
591
        }
592
        for(InArcIt e(_g,act);e!=INVALID; ++e) {
593
          Node v = _g.source(e);
594
          Value fc=(*_flow)[e]-(*_lo)[e];
595
          if(!_tol.positive(fc)) continue;
596
          if((*_level)[v]<actlevel) {
597
            if(!_tol.less(fc, exc)) {
598
              _flow->set(e, (*_flow)[e] - exc);
599
              (*_excess)[v] += exc;
600
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
601
                _level->activate(v);
602
              (*_excess)[act] = 0;
603
              _level->deactivate(act);
604
              goto next_l;
605
            }
606
            else {
607
              _flow->set(e, (*_lo)[e]);
608
              (*_excess)[v] += fc;
609
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
610
                _level->activate(v);
611
              exc-=fc;
612
            }
613
          }
614
          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
615
        }
616

	
617
        (*_excess)[act] = exc;
618
        if(!_tol.positive(exc)) _level->deactivate(act);
619
        else if(mlevel==_node_num) {
620
          _level->liftHighestActiveToTop();
621
          _el = _node_num;
622
          return false;
623
        }
624
        else {
625
          _level->liftHighestActive(mlevel+1);
626
          if(_level->onLevel(actlevel)==0) {
627
            _el = actlevel;
628
            return false;
629
          }
630
        }
631
      next_l:
632
        ;
633
      }
634
      return true;
635
    }
636

	
637
    /// Runs the algorithm.
638

	
639
    /// This function runs the algorithm.
640
    ///
641
    /// \return \c true if a feasible circulation is found.
642
    ///
643
    /// \note Apart from the return value, c.run() is just a shortcut of
644
    /// the following code.
645
    /// \code
646
    ///   c.greedyInit();
647
    ///   c.start();
648
    /// \endcode
649
    bool run() {
650
      greedyInit();
651
      return start();
652
    }
653

	
654
    /// @}
655

	
656
    /// \name Query Functions
657
    /// The results of the circulation algorithm can be obtained using
658
    /// these functions.\n
659
    /// Either \ref run() or \ref start() should be called before
660
    /// using them.
661

	
662
    ///@{
663

	
664
    /// \brief Returns the flow value on the given arc.
665
    ///
666
    /// Returns the flow value on the given arc.
667
    ///
668
    /// \pre Either \ref run() or \ref init() must be called before
669
    /// using this function.
670
    Value flow(const Arc& arc) const {
671
      return (*_flow)[arc];
672
    }
673

	
674
    /// \brief Returns a const reference to the flow map.
675
    ///
676
    /// Returns a const reference to the arc map storing the found flow.
677
    ///
678
    /// \pre Either \ref run() or \ref init() must be called before
679
    /// using this function.
680
    const FlowMap& flowMap() const {
681
      return *_flow;
682
    }
683

	
684
    /**
685
       \brief Returns \c true if the given node is in a barrier.
686

	
687
       Barrier is a set \e B of nodes for which
688

	
689
       \f[ \sum_{uv\in A: u\in B} upper(uv) -
690
           \sum_{uv\in A: v\in B} lower(uv) < \sum_{v\in B} sup(v) \f]
691

	
692
       holds. The existence of a set with this property prooves that a
693
       feasible circualtion cannot exist.
694

	
695
       This function returns \c true if the given node is in the found
696
       barrier. If a feasible circulation is found, the function
697
       gives back \c false for every node.
698

	
699
       \pre Either \ref run() or \ref init() must be called before
700
       using this function.
701

	
702
       \sa barrierMap()
703
       \sa checkBarrier()
704
    */
705
    bool barrier(const Node& node) const
706
    {
707
      return (*_level)[node] >= _el;
708
    }
709

	
710
    /// \brief Gives back a barrier.
711
    ///
712
    /// This function sets \c bar to the characteristic vector of the
713
    /// found barrier. \c bar should be a \ref concepts::WriteMap "writable"
714
    /// node map with \c bool (or convertible) value type.
715
    ///
716
    /// If a feasible circulation is found, the function gives back an
717
    /// empty set, so \c bar[v] will be \c false for all nodes \c v.
718
    ///
719
    /// \note This function calls \ref barrier() for each node,
720
    /// so it runs in O(n) time.
721
    ///
722
    /// \pre Either \ref run() or \ref init() must be called before
723
    /// using this function.
724
    ///
725
    /// \sa barrier()
726
    /// \sa checkBarrier()
727
    template<class BarrierMap>
728
    void barrierMap(BarrierMap &bar) const
729
    {
730
      for(NodeIt n(_g);n!=INVALID;++n)
731
        bar.set(n, (*_level)[n] >= _el);
732
    }
733

	
734
    /// @}
735

	
736
    /// \name Checker Functions
737
    /// The feasibility of the results can be checked using
738
    /// these functions.\n
739
    /// Either \ref run() or \ref start() should be called before
740
    /// using them.
741

	
742
    ///@{
743

	
744
    ///Check if the found flow is a feasible circulation
745

	
746
    ///Check if the found flow is a feasible circulation,
747
    ///
748
    bool checkFlow() const {
749
      for(ArcIt e(_g);e!=INVALID;++e)
750
        if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
751
      for(NodeIt n(_g);n!=INVALID;++n)
752
        {
753
          Value dif=-(*_supply)[n];
754
          for(InArcIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
755
          for(OutArcIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
756
          if(_tol.negative(dif)) return false;
757
        }
758
      return true;
759
    }
760

	
761
    ///Check whether or not the last execution provides a barrier
762

	
763
    ///Check whether or not the last execution provides a barrier.
764
    ///\sa barrier()
765
    ///\sa barrierMap()
766
    bool checkBarrier() const
767
    {
768
      Value delta=0;
769
      Value inf_cap = std::numeric_limits<Value>::has_infinity ?
770
        std::numeric_limits<Value>::infinity() :
771
        std::numeric_limits<Value>::max();
772
      for(NodeIt n(_g);n!=INVALID;++n)
773
        if(barrier(n))
774
          delta-=(*_supply)[n];
775
      for(ArcIt e(_g);e!=INVALID;++e)
776
        {
777
          Node s=_g.source(e);
778
          Node t=_g.target(e);
779
          if(barrier(s)&&!barrier(t)) {
780
            if (_tol.less(inf_cap - (*_up)[e], delta)) return false;
781
            delta+=(*_up)[e];
782
          }
783
          else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
784
        }
785
      return _tol.negative(delta);
786
    }
787

	
788
    /// @}
789

	
790
  };
791

	
792
}
793

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

	
19
#include <lemon/clp.h>
20
#include <coin/ClpSimplex.hpp>
21

	
22
namespace lemon {
23

	
24
  ClpLp::ClpLp() {
25
    _prob = new ClpSimplex();
26
    _init_temporals();
27
    messageLevel(MESSAGE_NOTHING);
28
  }
29

	
30
  ClpLp::ClpLp(const ClpLp& other) {
31
    _prob = new ClpSimplex(*other._prob);
32
    rows = other.rows;
33
    cols = other.cols;
34
    _init_temporals();
35
    messageLevel(MESSAGE_NOTHING);
36
  }
37

	
38
  ClpLp::~ClpLp() {
39
    delete _prob;
40
    _clear_temporals();
41
  }
42

	
43
  void ClpLp::_init_temporals() {
44
    _primal_ray = 0;
45
    _dual_ray = 0;
46
  }
47

	
48
  void ClpLp::_clear_temporals() {
49
    if (_primal_ray) {
50
      delete[] _primal_ray;
51
      _primal_ray = 0;
52
    }
53
    if (_dual_ray) {
54
      delete[] _dual_ray;
55
      _dual_ray = 0;
56
    }
57
  }
58

	
59
  ClpLp* ClpLp::newSolver() const {
60
    ClpLp* newlp = new ClpLp;
61
    return newlp;
62
  }
63

	
64
  ClpLp* ClpLp::cloneSolver() const {
65
    ClpLp* copylp = new ClpLp(*this);
66
    return copylp;
67
  }
68

	
69
  const char* ClpLp::_solverName() const { return "ClpLp"; }
70

	
71
  int ClpLp::_addCol() {
72
    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0);
73
    return _prob->numberColumns() - 1;
74
  }
75

	
76
  int ClpLp::_addRow() {
77
    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
78
    return _prob->numberRows() - 1;
79
  }
80

	
81

	
82
  void ClpLp::_eraseCol(int c) {
83
    _col_names_ref.erase(_prob->getColumnName(c));
84
    _prob->deleteColumns(1, &c);
85
  }
86

	
87
  void ClpLp::_eraseRow(int r) {
88
    _row_names_ref.erase(_prob->getRowName(r));
89
    _prob->deleteRows(1, &r);
90
  }
91

	
92
  void ClpLp::_eraseColId(int i) {
93
    cols.eraseIndex(i);
94
    cols.shiftIndices(i);
95
  }
96

	
97
  void ClpLp::_eraseRowId(int i) {
98
    rows.eraseIndex(i);
99
    rows.shiftIndices(i);
100
  }
101

	
102
  void ClpLp::_getColName(int c, std::string& name) const {
103
    name = _prob->getColumnName(c);
104
  }
105

	
106
  void ClpLp::_setColName(int c, const std::string& name) {
107
    _prob->setColumnName(c, const_cast<std::string&>(name));
108
    _col_names_ref[name] = c;
109
  }
110

	
111
  int ClpLp::_colByName(const std::string& name) const {
112
    std::map<std::string, int>::const_iterator it = _col_names_ref.find(name);
113
    return it != _col_names_ref.end() ? it->second : -1;
114
  }
115

	
116
  void ClpLp::_getRowName(int r, std::string& name) const {
117
    name = _prob->getRowName(r);
118
  }
119

	
120
  void ClpLp::_setRowName(int r, const std::string& name) {
121
    _prob->setRowName(r, const_cast<std::string&>(name));
122
    _row_names_ref[name] = r;
123
  }
124

	
125
  int ClpLp::_rowByName(const std::string& name) const {
126
    std::map<std::string, int>::const_iterator it = _row_names_ref.find(name);
127
    return it != _row_names_ref.end() ? it->second : -1;
128
  }
129

	
130

	
131
  void ClpLp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) {
132
    std::map<int, Value> coeffs;
133

	
134
    int n = _prob->clpMatrix()->getNumCols();
135

	
136
    const int* indices = _prob->clpMatrix()->getIndices();
137
    const double* elements = _prob->clpMatrix()->getElements();
138

	
139
    for (int i = 0; i < n; ++i) {
140
      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
141
      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
142

	
143
      const int* it = std::lower_bound(indices + begin, indices + end, ix);
144
      if (it != indices + end && *it == ix && elements[it - indices] != 0.0) {
145
        coeffs[i] = 0.0;
146
      }
147
    }
148

	
149
    for (ExprIterator it = b; it != e; ++it) {
150
      coeffs[it->first] = it->second;
151
    }
152

	
153
    for (std::map<int, Value>::iterator it = coeffs.begin();
154
         it != coeffs.end(); ++it) {
155
      _prob->modifyCoefficient(ix, it->first, it->second);
156
    }
157
  }
158

	
159
  void ClpLp::_getRowCoeffs(int ix, InsertIterator b) const {
160
    int n = _prob->clpMatrix()->getNumCols();
161

	
162
    const int* indices = _prob->clpMatrix()->getIndices();
163
    const double* elements = _prob->clpMatrix()->getElements();
164

	
165
    for (int i = 0; i < n; ++i) {
166
      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
167
      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
168

	
169
      const int* it = std::lower_bound(indices + begin, indices + end, ix);
170
      if (it != indices + end && *it == ix) {
171
        *b = std::make_pair(i, elements[it - indices]);
172
      }
173
    }
174
  }
175

	
176
  void ClpLp::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
177
    std::map<int, Value> coeffs;
178

	
179
    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
180
    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
181

	
182
    const int* indices = _prob->clpMatrix()->getIndices();
183
    const double* elements = _prob->clpMatrix()->getElements();
184

	
185
    for (CoinBigIndex i = begin; i != end; ++i) {
186
      if (elements[i] != 0.0) {
187
        coeffs[indices[i]] = 0.0;
188
      }
189
    }
190
    for (ExprIterator it = b; it != e; ++it) {
191
      coeffs[it->first] = it->second;
192
    }
193
    for (std::map<int, Value>::iterator it = coeffs.begin();
194
         it != coeffs.end(); ++it) {
195
      _prob->modifyCoefficient(it->first, ix, it->second);
196
    }
197
  }
198

	
199
  void ClpLp::_getColCoeffs(int ix, InsertIterator b) const {
200
    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
201
    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
202

	
203
    const int* indices = _prob->clpMatrix()->getIndices();
204
    const double* elements = _prob->clpMatrix()->getElements();
205

	
206
    for (CoinBigIndex i = begin; i != end; ++i) {
207
      *b = std::make_pair(indices[i], elements[i]);
208
      ++b;
209
    }
210
  }
211

	
212
  void ClpLp::_setCoeff(int ix, int jx, Value value) {
213
    _prob->modifyCoefficient(ix, jx, value);
214
  }
215

	
216
  ClpLp::Value ClpLp::_getCoeff(int ix, int jx) const {
217
    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
218
    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
219

	
220
    const int* indices = _prob->clpMatrix()->getIndices();
221
    const double* elements = _prob->clpMatrix()->getElements();
222

	
223
    const int* it = std::lower_bound(indices + begin, indices + end, jx);
224
    if (it != indices + end && *it == jx) {
225
      return elements[it - indices];
226
    } else {
227
      return 0.0;
228
    }
229
  }
230

	
231
  void ClpLp::_setColLowerBound(int i, Value lo) {
232
    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
233
  }
234

	
235
  ClpLp::Value ClpLp::_getColLowerBound(int i) const {
236
    double val = _prob->getColLower()[i];
237
    return val == - COIN_DBL_MAX ? - INF : val;
238
  }
239

	
240
  void ClpLp::_setColUpperBound(int i, Value up) {
241
    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
242
  }
243

	
244
  ClpLp::Value ClpLp::_getColUpperBound(int i) const {
245
    double val = _prob->getColUpper()[i];
246
    return val == COIN_DBL_MAX ? INF : val;
247
  }
248

	
249
  void ClpLp::_setRowLowerBound(int i, Value lo) {
250
    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
251
  }
252

	
253
  ClpLp::Value ClpLp::_getRowLowerBound(int i) const {
254
    double val = _prob->getRowLower()[i];
255
    return val == - COIN_DBL_MAX ? - INF : val;
256
  }
257

	
258
  void ClpLp::_setRowUpperBound(int i, Value up) {
259
    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
260
  }
261

	
262
  ClpLp::Value ClpLp::_getRowUpperBound(int i) const {
263
    double val = _prob->getRowUpper()[i];
264
    return val == COIN_DBL_MAX ? INF : val;
265
  }
266

	
267
  void ClpLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
268
    int num = _prob->clpMatrix()->getNumCols();
269
    for (int i = 0; i < num; ++i) {
270
      _prob->setObjectiveCoefficient(i, 0.0);
271
    }
272
    for (ExprIterator it = b; it != e; ++it) {
273
      _prob->setObjectiveCoefficient(it->first, it->second);
274
    }
275
  }
276

	
277
  void ClpLp::_getObjCoeffs(InsertIterator b) const {
278
    int num = _prob->clpMatrix()->getNumCols();
279
    for (int i = 0; i < num; ++i) {
280
      Value coef = _prob->getObjCoefficients()[i];
281
      if (coef != 0.0) {
282
        *b = std::make_pair(i, coef);
283
        ++b;
284
      }
285
    }
286
  }
287

	
288
  void ClpLp::_setObjCoeff(int i, Value obj_coef) {
289
    _prob->setObjectiveCoefficient(i, obj_coef);
290
  }
291

	
292
  ClpLp::Value ClpLp::_getObjCoeff(int i) const {
293
    return _prob->getObjCoefficients()[i];
294
  }
295

	
296
  ClpLp::SolveExitStatus ClpLp::_solve() {
297
    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
298
  }
299

	
300
  ClpLp::SolveExitStatus ClpLp::solvePrimal() {
301
    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
302
  }
303

	
304
  ClpLp::SolveExitStatus ClpLp::solveDual() {
305
    return _prob->dual() >= 0 ? SOLVED : UNSOLVED;
306
  }
307

	
308
  ClpLp::SolveExitStatus ClpLp::solveBarrier() {
309
    return _prob->barrier() >= 0 ? SOLVED : UNSOLVED;
310
  }
311

	
312
  ClpLp::Value ClpLp::_getPrimal(int i) const {
313
    return _prob->primalColumnSolution()[i];
314
  }
315
  ClpLp::Value ClpLp::_getPrimalValue() const {
316
    return _prob->objectiveValue();
317
  }
318

	
319
  ClpLp::Value ClpLp::_getDual(int i) const {
320
    return _prob->dualRowSolution()[i];
321
  }
322

	
323
  ClpLp::Value ClpLp::_getPrimalRay(int i) const {
324
    if (!_primal_ray) {
325
      _primal_ray = _prob->unboundedRay();
326
      LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided");
327
    }
328
    return _primal_ray[i];
329
  }
330

	
331
  ClpLp::Value ClpLp::_getDualRay(int i) const {
332
    if (!_dual_ray) {
333
      _dual_ray = _prob->infeasibilityRay();
334
      LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided");
335
    }
336
    return _dual_ray[i];
337
  }
338

	
339
  ClpLp::VarStatus ClpLp::_getColStatus(int i) const {
340
    switch (_prob->getColumnStatus(i)) {
341
    case ClpSimplex::basic:
342
      return BASIC;
343
    case ClpSimplex::isFree:
344
      return FREE;
345
    case ClpSimplex::atUpperBound:
346
      return UPPER;
347
    case ClpSimplex::atLowerBound:
348
      return LOWER;
349
    case ClpSimplex::isFixed:
350
      return FIXED;
351
    case ClpSimplex::superBasic:
352
      return FREE;
353
    default:
354
      LEMON_ASSERT(false, "Wrong column status");
355
      return VarStatus();
356
    }
357
  }
358

	
359
  ClpLp::VarStatus ClpLp::_getRowStatus(int i) const {
360
    switch (_prob->getColumnStatus(i)) {
361
    case ClpSimplex::basic:
362
      return BASIC;
363
    case ClpSimplex::isFree:
364
      return FREE;
365
    case ClpSimplex::atUpperBound:
366
      return UPPER;
367
    case ClpSimplex::atLowerBound:
368
      return LOWER;
369
    case ClpSimplex::isFixed:
370
      return FIXED;
371
    case ClpSimplex::superBasic:
372
      return FREE;
373
    default:
374
      LEMON_ASSERT(false, "Wrong row status");
375
      return VarStatus();
376
    }
377
  }
378

	
379

	
380
  ClpLp::ProblemType ClpLp::_getPrimalType() const {
381
    if (_prob->isProvenOptimal()) {
382
      return OPTIMAL;
383
    } else if (_prob->isProvenPrimalInfeasible()) {
384
      return INFEASIBLE;
385
    } else if (_prob->isProvenDualInfeasible()) {
386
      return UNBOUNDED;
387
    } else {
388
      return UNDEFINED;
389
    }
390
  }
391

	
392
  ClpLp::ProblemType ClpLp::_getDualType() const {
393
    if (_prob->isProvenOptimal()) {
394
      return OPTIMAL;
395
    } else if (_prob->isProvenDualInfeasible()) {
396
      return INFEASIBLE;
397
    } else if (_prob->isProvenPrimalInfeasible()) {
398
      return INFEASIBLE;
399
    } else {
400
      return UNDEFINED;
401
    }
402
  }
403

	
404
  void ClpLp::_setSense(ClpLp::Sense sense) {
405
    switch (sense) {
406
    case MIN:
407
      _prob->setOptimizationDirection(1);
408
      break;
409
    case MAX:
410
      _prob->setOptimizationDirection(-1);
411
      break;
412
    }
413
  }
414

	
415
  ClpLp::Sense ClpLp::_getSense() const {
416
    double dir = _prob->optimizationDirection();
417
    if (dir > 0.0) {
418
      return MIN;
419
    } else {
420
      return MAX;
421
    }
422
  }
423

	
424
  void ClpLp::_clear() {
425
    delete _prob;
426
    _prob = new ClpSimplex();
427
    rows.clear();
428
    cols.clear();
429
    _col_names_ref.clear();
430
    _clear_temporals();
431
  }
432

	
433
  void ClpLp::_messageLevel(MessageLevel level) {
434
    switch (level) {
435
    case MESSAGE_NOTHING:
436
      _prob->setLogLevel(0);
437
      break;
438
    case MESSAGE_ERROR:
439
      _prob->setLogLevel(1);
440
      break;
441
    case MESSAGE_WARNING:
442
      _prob->setLogLevel(2);
443
      break;
444
    case MESSAGE_NORMAL:
445
      _prob->setLogLevel(3);
446
      break;
447
    case MESSAGE_VERBOSE:
448
      _prob->setLogLevel(4);
449
      break;
450
    }
451
  }
452

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

	
19
#ifndef LEMON_CLP_H
20
#define LEMON_CLP_H
21

	
22
///\file
23
///\brief Header of the LEMON-CLP lp solver interface.
24

	
25
#include <vector>
26
#include <string>
27

	
28
#include <lemon/lp_base.h>
29

	
30
class ClpSimplex;
31

	
32
namespace lemon {
33

	
34
  /// \ingroup lp_group
35
  ///
36
  /// \brief Interface for the CLP solver
37
  ///
38
  /// This class implements an interface for the Clp LP solver.  The
39
  /// Clp library is an object oriented lp solver library developed at
40
  /// the IBM. The CLP is part of the COIN-OR package and it can be
41
  /// used with Common Public License.
42
  class ClpLp : public LpSolver {
43
  protected:
44

	
45
    ClpSimplex* _prob;
46

	
47
    std::map<std::string, int> _col_names_ref;
48
    std::map<std::string, int> _row_names_ref;
49

	
50
  public:
51

	
52
    /// \e
53
    ClpLp();
54
    /// \e
55
    ClpLp(const ClpLp&);
56
    /// \e
57
    ~ClpLp();
58

	
59
    /// \e
60
    virtual ClpLp* newSolver() const;
61
    /// \e
62
    virtual ClpLp* cloneSolver() const;
63

	
64
  protected:
65

	
66
    mutable double* _primal_ray;
67
    mutable double* _dual_ray;
68

	
69
    void _init_temporals();
70
    void _clear_temporals();
71

	
72
  protected:
73

	
74
    virtual const char* _solverName() const;
75

	
76
    virtual int _addCol();
77
    virtual int _addRow();
78

	
79
    virtual void _eraseCol(int i);
80
    virtual void _eraseRow(int i);
81

	
82
    virtual void _eraseColId(int i);
83
    virtual void _eraseRowId(int i);
84

	
85
    virtual void _getColName(int col, std::string& name) const;
86
    virtual void _setColName(int col, const std::string& name);
87
    virtual int _colByName(const std::string& name) const;
88

	
89
    virtual void _getRowName(int row, std::string& name) const;
90
    virtual void _setRowName(int row, const std::string& name);
91
    virtual int _rowByName(const std::string& name) const;
92

	
93
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
94
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
95

	
96
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
97
    virtual void _getColCoeffs(int i, InsertIterator b) const;
98

	
99
    virtual void _setCoeff(int row, int col, Value value);
100
    virtual Value _getCoeff(int row, int col) const;
101

	
102
    virtual void _setColLowerBound(int i, Value value);
103
    virtual Value _getColLowerBound(int i) const;
104
    virtual void _setColUpperBound(int i, Value value);
105
    virtual Value _getColUpperBound(int i) const;
106

	
107
    virtual void _setRowLowerBound(int i, Value value);
108
    virtual Value _getRowLowerBound(int i) const;
109
    virtual void _setRowUpperBound(int i, Value value);
110
    virtual Value _getRowUpperBound(int i) const;
111

	
112
    virtual void _setObjCoeffs(ExprIterator, ExprIterator);
113
    virtual void _getObjCoeffs(InsertIterator) const;
114

	
115
    virtual void _setObjCoeff(int i, Value obj_coef);
116
    virtual Value _getObjCoeff(int i) const;
117

	
118
    virtual void _setSense(Sense sense);
119
    virtual Sense _getSense() const;
120

	
121
    virtual SolveExitStatus _solve();
122

	
123
    virtual Value _getPrimal(int i) const;
124
    virtual Value _getDual(int i) const;
125

	
126
    virtual Value _getPrimalValue() const;
127

	
128
    virtual Value _getPrimalRay(int i) const;
129
    virtual Value _getDualRay(int i) const;
130

	
131
    virtual VarStatus _getColStatus(int i) const;
132
    virtual VarStatus _getRowStatus(int i) const;
133

	
134
    virtual ProblemType _getPrimalType() const;
135
    virtual ProblemType _getDualType() const;
136

	
137
    virtual void _clear();
138

	
139
    virtual void _messageLevel(MessageLevel);
140
    
141
  public:
142

	
143
    ///Solves LP with primal simplex method.
144
    SolveExitStatus solvePrimal();
145

	
146
    ///Solves LP with dual simplex method.
147
    SolveExitStatus solveDual();
148

	
149
    ///Solves LP with barrier method.
150
    SolveExitStatus solveBarrier();
151

	
152
    ///Returns the constraint identifier understood by CLP.
153
    int clpRow(Row r) const { return rows(id(r)); }
154

	
155
    ///Returns the variable identifier understood by CLP.
156
    int clpCol(Col c) const { return cols(id(c)); }
157

	
158
  };
159

	
160
} //END OF NAMESPACE LEMON
161

	
162
#endif //LEMON_CLP_H
163

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

	
19
#ifndef LEMON_CONNECTIVITY_H
20
#define LEMON_CONNECTIVITY_H
21

	
22
#include <lemon/dfs.h>
23
#include <lemon/bfs.h>
24
#include <lemon/core.h>
25
#include <lemon/maps.h>
26
#include <lemon/adaptors.h>
27

	
28
#include <lemon/concepts/digraph.h>
29
#include <lemon/concepts/graph.h>
30
#include <lemon/concept_check.h>
31

	
32
#include <stack>
33
#include <functional>
34

	
35
/// \ingroup graph_properties
36
/// \file
37
/// \brief Connectivity algorithms
38
///
39
/// Connectivity algorithms
40

	
41
namespace lemon {
42

	
43
  /// \ingroup graph_properties
44
  ///
45
  /// \brief Check whether an undirected graph is connected.
46
  ///
47
  /// This function checks whether the given undirected graph is connected,
48
  /// i.e. there is a path between any two nodes in the graph.
49
  ///
50
  /// \return \c true if the graph is connected.
51
  /// \note By definition, the empty graph is connected.
52
  ///
53
  /// \see countConnectedComponents(), connectedComponents()
54
  /// \see stronglyConnected()
55
  template <typename Graph>
56
  bool connected(const Graph& graph) {
57
    checkConcept<concepts::Graph, Graph>();
58
    typedef typename Graph::NodeIt NodeIt;
59
    if (NodeIt(graph) == INVALID) return true;
60
    Dfs<Graph> dfs(graph);
61
    dfs.run(NodeIt(graph));
62
    for (NodeIt it(graph); it != INVALID; ++it) {
63
      if (!dfs.reached(it)) {
64
        return false;
65
      }
66
    }
67
    return true;
68
  }
69

	
70
  /// \ingroup graph_properties
71
  ///
72
  /// \brief Count the number of connected components of an undirected graph
73
  ///
74
  /// This function counts the number of connected components of the given
75
  /// undirected graph.
76
  ///
77
  /// The connected components are the classes of an equivalence relation
78
  /// on the nodes of an undirected graph. Two nodes are in the same class
79
  /// if they are connected with a path.
80
  ///
81
  /// \return The number of connected components.
82
  /// \note By definition, the empty graph consists
83
  /// of zero connected components.
84
  ///
85
  /// \see connected(), connectedComponents()
86
  template <typename Graph>
87
  int countConnectedComponents(const Graph &graph) {
88
    checkConcept<concepts::Graph, Graph>();
89
    typedef typename Graph::Node Node;
90
    typedef typename Graph::Arc Arc;
91

	
92
    typedef NullMap<Node, Arc> PredMap;
93
    typedef NullMap<Node, int> DistMap;
94

	
95
    int compNum = 0;
96
    typename Bfs<Graph>::
97
      template SetPredMap<PredMap>::
98
      template SetDistMap<DistMap>::
99
      Create bfs(graph);
100

	
101
    PredMap predMap;
102
    bfs.predMap(predMap);
103

	
104
    DistMap distMap;
105
    bfs.distMap(distMap);
106

	
107
    bfs.init();
108
    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
109
      if (!bfs.reached(n)) {
110
        bfs.addSource(n);
111
        bfs.start();
112
        ++compNum;
113
      }
114
    }
115
    return compNum;
116
  }
117

	
118
  /// \ingroup graph_properties
119
  ///
120
  /// \brief Find the connected components of an undirected graph
121
  ///
122
  /// This function finds the connected components of the given undirected
123
  /// graph.
124
  ///
125
  /// The connected components are the classes of an equivalence relation
126
  /// on the nodes of an undirected graph. Two nodes are in the same class
127
  /// if they are connected with a path.
128
  ///
129
  /// \image html connected_components.png
130
  /// \image latex connected_components.eps "Connected components" width=\textwidth
131
  ///
132
  /// \param graph The undirected graph.
133
  /// \retval compMap A writable node map. The values will be set from 0 to
134
  /// the number of the connected components minus one. Each value of the map
135
  /// will be set exactly once, and the values of a certain component will be
136
  /// set continuously.
137
  /// \return The number of connected components.
138
  /// \note By definition, the empty graph consists
139
  /// of zero connected components.
140
  ///
141
  /// \see connected(), countConnectedComponents()
142
  template <class Graph, class NodeMap>
143
  int connectedComponents(const Graph &graph, NodeMap &compMap) {
144
    checkConcept<concepts::Graph, Graph>();
145
    typedef typename Graph::Node Node;
146
    typedef typename Graph::Arc Arc;
147
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
148

	
149
    typedef NullMap<Node, Arc> PredMap;
150
    typedef NullMap<Node, int> DistMap;
151

	
152
    int compNum = 0;
153
    typename Bfs<Graph>::
154
      template SetPredMap<PredMap>::
155
      template SetDistMap<DistMap>::
156
      Create bfs(graph);
157

	
158
    PredMap predMap;
159
    bfs.predMap(predMap);
160

	
161
    DistMap distMap;
162
    bfs.distMap(distMap);
163

	
164
    bfs.init();
165
    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
166
      if(!bfs.reached(n)) {
167
        bfs.addSource(n);
168
        while (!bfs.emptyQueue()) {
169
          compMap.set(bfs.nextNode(), compNum);
170
          bfs.processNextNode();
171
        }
172
        ++compNum;
173
      }
174
    }
175
    return compNum;
176
  }
177

	
178
  namespace _connectivity_bits {
179

	
180
    template <typename Digraph, typename Iterator >
181
    struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
182
    public:
183
      typedef typename Digraph::Node Node;
184
      LeaveOrderVisitor(Iterator it) : _it(it) {}
185

	
186
      void leave(const Node& node) {
187
        *(_it++) = node;
188
      }
189

	
190
    private:
191
      Iterator _it;
192
    };
193

	
194
    template <typename Digraph, typename Map>
195
    struct FillMapVisitor : public DfsVisitor<Digraph> {
196
    public:
197
      typedef typename Digraph::Node Node;
198
      typedef typename Map::Value Value;
199

	
200
      FillMapVisitor(Map& map, Value& value)
201
        : _map(map), _value(value) {}
202

	
203
      void reach(const Node& node) {
204
        _map.set(node, _value);
205
      }
206
    private:
207
      Map& _map;
208
      Value& _value;
209
    };
210

	
211
    template <typename Digraph, typename ArcMap>
212
    struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
213
    public:
214
      typedef typename Digraph::Node Node;
215
      typedef typename Digraph::Arc Arc;
216

	
217
      StronglyConnectedCutArcsVisitor(const Digraph& digraph,
218
                                      ArcMap& cutMap,
219
                                      int& cutNum)
220
        : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
221
          _compMap(digraph, -1), _num(-1) {
222
      }
223

	
224
      void start(const Node&) {
225
        ++_num;
226
      }
227

	
228
      void reach(const Node& node) {
229
        _compMap.set(node, _num);
230
      }
231

	
232
      void examine(const Arc& arc) {
233
         if (_compMap[_digraph.source(arc)] !=
234
             _compMap[_digraph.target(arc)]) {
235
           _cutMap.set(arc, true);
236
           ++_cutNum;
237
         }
238
      }
239
    private:
240
      const Digraph& _digraph;
241
      ArcMap& _cutMap;
242
      int& _cutNum;
243

	
244
      typename Digraph::template NodeMap<int> _compMap;
245
      int _num;
246
    };
247

	
248
  }
249

	
250

	
251
  /// \ingroup graph_properties
252
  ///
253
  /// \brief Check whether a directed graph is strongly connected.
254
  ///
255
  /// This function checks whether the given directed graph is strongly
256
  /// connected, i.e. any two nodes of the digraph are
257
  /// connected with directed paths in both direction.
258
  ///
259
  /// \return \c true if the digraph is strongly connected.
260
  /// \note By definition, the empty digraph is strongly connected.
261
  /// 
262
  /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
263
  /// \see connected()
264
  template <typename Digraph>
265
  bool stronglyConnected(const Digraph& digraph) {
266
    checkConcept<concepts::Digraph, Digraph>();
267

	
268
    typedef typename Digraph::Node Node;
269
    typedef typename Digraph::NodeIt NodeIt;
270

	
271
    typename Digraph::Node source = NodeIt(digraph);
272
    if (source == INVALID) return true;
273

	
274
    using namespace _connectivity_bits;
275

	
276
    typedef DfsVisitor<Digraph> Visitor;
277
    Visitor visitor;
278

	
279
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
280
    dfs.init();
281
    dfs.addSource(source);
282
    dfs.start();
283

	
284
    for (NodeIt it(digraph); it != INVALID; ++it) {
285
      if (!dfs.reached(it)) {
286
        return false;
287
      }
288
    }
289

	
290
    typedef ReverseDigraph<const Digraph> RDigraph;
291
    typedef typename RDigraph::NodeIt RNodeIt;
292
    RDigraph rdigraph(digraph);
293

	
294
    typedef DfsVisitor<RDigraph> RVisitor;
295
    RVisitor rvisitor;
296

	
297
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
298
    rdfs.init();
299
    rdfs.addSource(source);
300
    rdfs.start();
301

	
302
    for (RNodeIt it(rdigraph); it != INVALID; ++it) {
303
      if (!rdfs.reached(it)) {
304
        return false;
305
      }
306
    }
307

	
308
    return true;
309
  }
310

	
311
  /// \ingroup graph_properties
312
  ///
313
  /// \brief Count the number of strongly connected components of a 
314
  /// directed graph
315
  ///
316
  /// This function counts the number of strongly connected components of
317
  /// the given directed graph.
318
  ///
319
  /// The strongly connected components are the classes of an
320
  /// equivalence relation on the nodes of a digraph. Two nodes are in
321
  /// the same class if they are connected with directed paths in both
322
  /// direction.
323
  ///
324
  /// \return The number of strongly connected components.
325
  /// \note By definition, the empty digraph has zero
326
  /// strongly connected components.
327
  ///
328
  /// \see stronglyConnected(), stronglyConnectedComponents()
329
  template <typename Digraph>
330
  int countStronglyConnectedComponents(const Digraph& digraph) {
331
    checkConcept<concepts::Digraph, Digraph>();
332

	
333
    using namespace _connectivity_bits;
334

	
335
    typedef typename Digraph::Node Node;
336
    typedef typename Digraph::Arc Arc;
337
    typedef typename Digraph::NodeIt NodeIt;
338
    typedef typename Digraph::ArcIt ArcIt;
339

	
340
    typedef std::vector<Node> Container;
341
    typedef typename Container::iterator Iterator;
342

	
343
    Container nodes(countNodes(digraph));
344
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
345
    Visitor visitor(nodes.begin());
346

	
347
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
348
    dfs.init();
349
    for (NodeIt it(digraph); it != INVALID; ++it) {
350
      if (!dfs.reached(it)) {
351
        dfs.addSource(it);
352
        dfs.start();
353
      }
354
    }
355

	
356
    typedef typename Container::reverse_iterator RIterator;
357
    typedef ReverseDigraph<const Digraph> RDigraph;
358

	
359
    RDigraph rdigraph(digraph);
360

	
361
    typedef DfsVisitor<Digraph> RVisitor;
362
    RVisitor rvisitor;
363

	
364
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
365

	
366
    int compNum = 0;
367

	
368
    rdfs.init();
369
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
370
      if (!rdfs.reached(*it)) {
371
        rdfs.addSource(*it);
372
        rdfs.start();
373
        ++compNum;
374
      }
375
    }
376
    return compNum;
377
  }
378

	
379
  /// \ingroup graph_properties
380
  ///
381
  /// \brief Find the strongly connected components of a directed graph
382
  ///
383
  /// This function finds the strongly connected components of the given
384
  /// directed graph. In addition, the numbering of the components will
385
  /// satisfy that there is no arc going from a higher numbered component
386
  /// to a lower one (i.e. it provides a topological order of the components).
387
  ///
388
  /// The strongly connected components are the classes of an
389
  /// equivalence relation on the nodes of a digraph. Two nodes are in
390
  /// the same class if they are connected with directed paths in both
391
  /// direction.
392
  ///
393
  /// \image html strongly_connected_components.png
394
  /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
395
  ///
396
  /// \param digraph The digraph.
397
  /// \retval compMap A writable node map. The values will be set from 0 to
398
  /// the number of the strongly connected components minus one. Each value
399
  /// of the map will be set exactly once, and the values of a certain
400
  /// component will be set continuously.
401
  /// \return The number of strongly connected components.
402
  /// \note By definition, the empty digraph has zero
403
  /// strongly connected components.
404
  ///
405
  /// \see stronglyConnected(), countStronglyConnectedComponents()
406
  template <typename Digraph, typename NodeMap>
407
  int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
408
    checkConcept<concepts::Digraph, Digraph>();
409
    typedef typename Digraph::Node Node;
410
    typedef typename Digraph::NodeIt NodeIt;
411
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
412

	
413
    using namespace _connectivity_bits;
414

	
415
    typedef std::vector<Node> Container;
416
    typedef typename Container::iterator Iterator;
417

	
418
    Container nodes(countNodes(digraph));
419
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
420
    Visitor visitor(nodes.begin());
421

	
422
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
423
    dfs.init();
424
    for (NodeIt it(digraph); it != INVALID; ++it) {
425
      if (!dfs.reached(it)) {
426
        dfs.addSource(it);
427
        dfs.start();
428
      }
429
    }
430

	
431
    typedef typename Container::reverse_iterator RIterator;
432
    typedef ReverseDigraph<const Digraph> RDigraph;
433

	
434
    RDigraph rdigraph(digraph);
435

	
436
    int compNum = 0;
437

	
438
    typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
439
    RVisitor rvisitor(compMap, compNum);
440

	
441
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
442

	
443
    rdfs.init();
444
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
445
      if (!rdfs.reached(*it)) {
446
        rdfs.addSource(*it);
447
        rdfs.start();
448
        ++compNum;
449
      }
450
    }
451
    return compNum;
452
  }
453

	
454
  /// \ingroup graph_properties
455
  ///
456
  /// \brief Find the cut arcs of the strongly connected components.
457
  ///
458
  /// This function finds the cut arcs of the strongly connected components
459
  /// of the given digraph.
460
  ///
461
  /// The strongly connected components are the classes of an
462
  /// equivalence relation on the nodes of a digraph. Two nodes are in
463
  /// the same class if they are connected with directed paths in both
464
  /// direction.
465
  /// The strongly connected components are separated by the cut arcs.
466
  ///
467
  /// \param digraph The digraph.
468
  /// \retval cutMap A writable arc map. The values will be set to \c true
469
  /// for the cut arcs (exactly once for each cut arc), and will not be
470
  /// changed for other arcs.
471
  /// \return The number of cut arcs.
472
  ///
473
  /// \see stronglyConnected(), stronglyConnectedComponents()
474
  template <typename Digraph, typename ArcMap>
475
  int stronglyConnectedCutArcs(const Digraph& digraph, ArcMap& cutMap) {
476
    checkConcept<concepts::Digraph, Digraph>();
477
    typedef typename Digraph::Node Node;
478
    typedef typename Digraph::Arc Arc;
479
    typedef typename Digraph::NodeIt NodeIt;
480
    checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
481

	
482
    using namespace _connectivity_bits;
483

	
484
    typedef std::vector<Node> Container;
485
    typedef typename Container::iterator Iterator;
486

	
487
    Container nodes(countNodes(digraph));
488
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
489
    Visitor visitor(nodes.begin());
490

	
491
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
492
    dfs.init();
493
    for (NodeIt it(digraph); it != INVALID; ++it) {
494
      if (!dfs.reached(it)) {
495
        dfs.addSource(it);
496
        dfs.start();
497
      }
498
    }
499

	
500
    typedef typename Container::reverse_iterator RIterator;
501
    typedef ReverseDigraph<const Digraph> RDigraph;
502

	
503
    RDigraph rdigraph(digraph);
504

	
505
    int cutNum = 0;
506

	
507
    typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
508
    RVisitor rvisitor(rdigraph, cutMap, cutNum);
509

	
510
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
511

	
512
    rdfs.init();
513
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
514
      if (!rdfs.reached(*it)) {
515
        rdfs.addSource(*it);
516
        rdfs.start();
517
      }
518
    }
519
    return cutNum;
520
  }
521

	
522
  namespace _connectivity_bits {
523

	
524
    template <typename Digraph>
525
    class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
526
    public:
527
      typedef typename Digraph::Node Node;
528
      typedef typename Digraph::Arc Arc;
529
      typedef typename Digraph::Edge Edge;
530

	
531
      CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
532
        : _graph(graph), _compNum(compNum),
533
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
534

	
535
      void start(const Node& node) {
536
        _predMap.set(node, INVALID);
537
      }
538

	
539
      void reach(const Node& node) {
540
        _numMap.set(node, _num);
541
        _retMap.set(node, _num);
542
        ++_num;
543
      }
544

	
545
      void discover(const Arc& edge) {
546
        _predMap.set(_graph.target(edge), _graph.source(edge));
547
      }
548

	
549
      void examine(const Arc& edge) {
550
        if (_graph.source(edge) == _graph.target(edge) &&
551
            _graph.direction(edge)) {
552
          ++_compNum;
553
          return;
554
        }
555
        if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
556
          return;
557
        }
558
        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
559
          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
560
        }
561
      }
562

	
563
      void backtrack(const Arc& edge) {
564
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
565
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
566
        }
567
        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
568
          ++_compNum;
569
        }
570
      }
571

	
572
    private:
573
      const Digraph& _graph;
574
      int& _compNum;
575

	
576
      typename Digraph::template NodeMap<int> _numMap;
577
      typename Digraph::template NodeMap<int> _retMap;
578
      typename Digraph::template NodeMap<Node> _predMap;
579
      int _num;
580
    };
581

	
582
    template <typename Digraph, typename ArcMap>
583
    class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
584
    public:
585
      typedef typename Digraph::Node Node;
586
      typedef typename Digraph::Arc Arc;
587
      typedef typename Digraph::Edge Edge;
588

	
589
      BiNodeConnectedComponentsVisitor(const Digraph& graph,
590
                                       ArcMap& compMap, int &compNum)
591
        : _graph(graph), _compMap(compMap), _compNum(compNum),
592
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
593

	
594
      void start(const Node& node) {
595
        _predMap.set(node, INVALID);
596
      }
597

	
598
      void reach(const Node& node) {
599
        _numMap.set(node, _num);
600
        _retMap.set(node, _num);
601
        ++_num;
602
      }
603

	
604
      void discover(const Arc& edge) {
605
        Node target = _graph.target(edge);
606
        _predMap.set(target, edge);
607
        _edgeStack.push(edge);
608
      }
609

	
610
      void examine(const Arc& edge) {
611
        Node source = _graph.source(edge);
612
        Node target = _graph.target(edge);
613
        if (source == target && _graph.direction(edge)) {
614
          _compMap.set(edge, _compNum);
615
          ++_compNum;
616
          return;
617
        }
618
        if (_numMap[target] < _numMap[source]) {
619
          if (_predMap[source] != _graph.oppositeArc(edge)) {
620
            _edgeStack.push(edge);
621
          }
622
        }
623
        if (_predMap[source] != INVALID &&
624
            target == _graph.source(_predMap[source])) {
625
          return;
626
        }
627
        if (_retMap[source] > _numMap[target]) {
628
          _retMap.set(source, _numMap[target]);
629
        }
630
      }
631

	
632
      void backtrack(const Arc& edge) {
633
        Node source = _graph.source(edge);
634
        Node target = _graph.target(edge);
635
        if (_retMap[source] > _retMap[target]) {
636
          _retMap.set(source, _retMap[target]);
637
        }
638
        if (_numMap[source] <= _retMap[target]) {
639
          while (_edgeStack.top() != edge) {
640
            _compMap.set(_edgeStack.top(), _compNum);
641
            _edgeStack.pop();
642
          }
643
          _compMap.set(edge, _compNum);
644
          _edgeStack.pop();
645
          ++_compNum;
646
        }
647
      }
648

	
649
    private:
650
      const Digraph& _graph;
651
      ArcMap& _compMap;
652
      int& _compNum;
653

	
654
      typename Digraph::template NodeMap<int> _numMap;
655
      typename Digraph::template NodeMap<int> _retMap;
656
      typename Digraph::template NodeMap<Arc> _predMap;
657
      std::stack<Edge> _edgeStack;
658
      int _num;
659
    };
660

	
661

	
662
    template <typename Digraph, typename NodeMap>
663
    class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
664
    public:
665
      typedef typename Digraph::Node Node;
666
      typedef typename Digraph::Arc Arc;
667
      typedef typename Digraph::Edge Edge;
668

	
669
      BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
670
                                     int& cutNum)
671
        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
672
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
673

	
674
      void start(const Node& node) {
675
        _predMap.set(node, INVALID);
676
        rootCut = false;
677
      }
678

	
679
      void reach(const Node& node) {
680
        _numMap.set(node, _num);
681
        _retMap.set(node, _num);
682
        ++_num;
683
      }
684

	
685
      void discover(const Arc& edge) {
686
        _predMap.set(_graph.target(edge), _graph.source(edge));
687
      }
688

	
689
      void examine(const Arc& edge) {
690
        if (_graph.source(edge) == _graph.target(edge) &&
691
            _graph.direction(edge)) {
692
          if (!_cutMap[_graph.source(edge)]) {
693
            _cutMap.set(_graph.source(edge), true);
694
            ++_cutNum;
695
          }
696
          return;
697
        }
698
        if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
699
        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
700
          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
701
        }
702
      }
703

	
704
      void backtrack(const Arc& edge) {
705
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
706
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
707
        }
708
        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
709
          if (_predMap[_graph.source(edge)] != INVALID) {
710
            if (!_cutMap[_graph.source(edge)]) {
711
              _cutMap.set(_graph.source(edge), true);
712
              ++_cutNum;
713
            }
714
          } else if (rootCut) {
715
            if (!_cutMap[_graph.source(edge)]) {
716
              _cutMap.set(_graph.source(edge), true);
717
              ++_cutNum;
718
            }
719
          } else {
720
            rootCut = true;
721
          }
722
        }
723
      }
724

	
725
    private:
726
      const Digraph& _graph;
727
      NodeMap& _cutMap;
728
      int& _cutNum;
729

	
730
      typename Digraph::template NodeMap<int> _numMap;
731
      typename Digraph::template NodeMap<int> _retMap;
732
      typename Digraph::template NodeMap<Node> _predMap;
733
      std::stack<Edge> _edgeStack;
734
      int _num;
735
      bool rootCut;
736
    };
737

	
738
  }
739

	
740
  template <typename Graph>
741
  int countBiNodeConnectedComponents(const Graph& graph);
742

	
743
  /// \ingroup graph_properties
744
  ///
745
  /// \brief Check whether an undirected graph is bi-node-connected.
746
  ///
747
  /// This function checks whether the given undirected graph is 
748
  /// bi-node-connected, i.e. any two edges are on same circle.
749
  ///
750
  /// \return \c true if the graph bi-node-connected.
751
  /// \note By definition, the empty graph is bi-node-connected.
752
  ///
753
  /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents()
754
  template <typename Graph>
755
  bool biNodeConnected(const Graph& graph) {
756
    return countBiNodeConnectedComponents(graph) <= 1;
757
  }
758

	
759
  /// \ingroup graph_properties
760
  ///
761
  /// \brief Count the number of bi-node-connected components of an 
762
  /// undirected graph.
763
  ///
764
  /// This function counts the number of bi-node-connected components of
765
  /// the given undirected graph.
766
  ///
767
  /// The bi-node-connected components are the classes of an equivalence
768
  /// relation on the edges of a undirected graph. Two edges are in the
769
  /// same class if they are on same circle.
770
  ///
771
  /// \return The number of bi-node-connected components.
772
  ///
773
  /// \see biNodeConnected(), biNodeConnectedComponents()
774
  template <typename Graph>
775
  int countBiNodeConnectedComponents(const Graph& graph) {
776
    checkConcept<concepts::Graph, Graph>();
777
    typedef typename Graph::NodeIt NodeIt;
778

	
779
    using namespace _connectivity_bits;
780

	
781
    typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
782

	
783
    int compNum = 0;
784
    Visitor visitor(graph, compNum);
785

	
786
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
787
    dfs.init();
788

	
789
    for (NodeIt it(graph); it != INVALID; ++it) {
790
      if (!dfs.reached(it)) {
791
        dfs.addSource(it);
792
        dfs.start();
793
      }
794
    }
795
    return compNum;
796
  }
797

	
798
  /// \ingroup graph_properties
799
  ///
800
  /// \brief Find the bi-node-connected components of an undirected graph.
801
  ///
802
  /// This function finds the bi-node-connected components of the given
803
  /// undirected graph.
804
  ///
805
  /// The bi-node-connected components are the classes of an equivalence
806
  /// relation on the edges of a undirected graph. Two edges are in the
807
  /// same class if they are on same circle.
808
  ///
809
  /// \image html node_biconnected_components.png
810
  /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
811
  ///
812
  /// \param graph The undirected graph.
813
  /// \retval compMap A writable edge map. The values will be set from 0
814
  /// to the number of the bi-node-connected components minus one. Each
815
  /// value of the map will be set exactly once, and the values of a 
816
  /// certain component will be set continuously.
817
  /// \return The number of bi-node-connected components.
818
  ///
819
  /// \see biNodeConnected(), countBiNodeConnectedComponents()
820
  template <typename Graph, typename EdgeMap>
821
  int biNodeConnectedComponents(const Graph& graph,
822
                                EdgeMap& compMap) {
823
    checkConcept<concepts::Graph, Graph>();
824
    typedef typename Graph::NodeIt NodeIt;
825
    typedef typename Graph::Edge Edge;
826
    checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
827

	
828
    using namespace _connectivity_bits;
829

	
830
    typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
831

	
832
    int compNum = 0;
833
    Visitor visitor(graph, compMap, compNum);
834

	
835
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
836
    dfs.init();
837

	
838
    for (NodeIt it(graph); it != INVALID; ++it) {
839
      if (!dfs.reached(it)) {
840
        dfs.addSource(it);
841
        dfs.start();
842
      }
843
    }
844
    return compNum;
845
  }
846

	
847
  /// \ingroup graph_properties
848
  ///
849
  /// \brief Find the bi-node-connected cut nodes in an undirected graph.
850
  ///
851
  /// This function finds the bi-node-connected cut nodes in the given
852
  /// undirected graph.
853
  ///
854
  /// The bi-node-connected components are the classes of an equivalence
855
  /// relation on the edges of a undirected graph. Two edges are in the
856
  /// same class if they are on same circle.
857
  /// The bi-node-connected components are separted by the cut nodes of
858
  /// the components.
859
  ///
860
  /// \param graph The undirected graph.
861
  /// \retval cutMap A writable node map. The values will be set to 
862
  /// \c true for the nodes that separate two or more components
863
  /// (exactly once for each cut node), and will not be changed for
864
  /// other nodes.
865
  /// \return The number of the cut nodes.
866
  ///
867
  /// \see biNodeConnected(), biNodeConnectedComponents()
868
  template <typename Graph, typename NodeMap>
869
  int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
870
    checkConcept<concepts::Graph, Graph>();
871
    typedef typename Graph::Node Node;
872
    typedef typename Graph::NodeIt NodeIt;
873
    checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
874

	
875
    using namespace _connectivity_bits;
876

	
877
    typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
878

	
879
    int cutNum = 0;
880
    Visitor visitor(graph, cutMap, cutNum);
881

	
882
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
883
    dfs.init();
884

	
885
    for (NodeIt it(graph); it != INVALID; ++it) {
886
      if (!dfs.reached(it)) {
887
        dfs.addSource(it);
888
        dfs.start();
889
      }
890
    }
891
    return cutNum;
892
  }
893

	
894
  namespace _connectivity_bits {
895

	
896
    template <typename Digraph>
897
    class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
898
    public:
899
      typedef typename Digraph::Node Node;
900
      typedef typename Digraph::Arc Arc;
901
      typedef typename Digraph::Edge Edge;
902

	
903
      CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
904
        : _graph(graph), _compNum(compNum),
905
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
906

	
907
      void start(const Node& node) {
908
        _predMap.set(node, INVALID);
909
      }
910

	
911
      void reach(const Node& node) {
912
        _numMap.set(node, _num);
913
        _retMap.set(node, _num);
914
        ++_num;
915
      }
916

	
917
      void leave(const Node& node) {
918
        if (_numMap[node] <= _retMap[node]) {
919
          ++_compNum;
920
        }
921
      }
922

	
923
      void discover(const Arc& edge) {
924
        _predMap.set(_graph.target(edge), edge);
925
      }
926

	
927
      void examine(const Arc& edge) {
928
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
929
          return;
930
        }
931
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
932
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
933
        }
934
      }
935

	
936
      void backtrack(const Arc& edge) {
937
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
938
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
939
        }
940
      }
941

	
942
    private:
943
      const Digraph& _graph;
944
      int& _compNum;
945

	
946
      typename Digraph::template NodeMap<int> _numMap;
947
      typename Digraph::template NodeMap<int> _retMap;
948
      typename Digraph::template NodeMap<Arc> _predMap;
949
      int _num;
950
    };
951

	
952
    template <typename Digraph, typename NodeMap>
953
    class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
954
    public:
955
      typedef typename Digraph::Node Node;
956
      typedef typename Digraph::Arc Arc;
957
      typedef typename Digraph::Edge Edge;
958

	
959
      BiEdgeConnectedComponentsVisitor(const Digraph& graph,
960
                                       NodeMap& compMap, int &compNum)
961
        : _graph(graph), _compMap(compMap), _compNum(compNum),
962
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
963

	
964
      void start(const Node& node) {
965
        _predMap.set(node, INVALID);
966
      }
967

	
968
      void reach(const Node& node) {
969
        _numMap.set(node, _num);
970
        _retMap.set(node, _num);
971
        _nodeStack.push(node);
972
        ++_num;
973
      }
974

	
975
      void leave(const Node& node) {
976
        if (_numMap[node] <= _retMap[node]) {
977
          while (_nodeStack.top() != node) {
978
            _compMap.set(_nodeStack.top(), _compNum);
979
            _nodeStack.pop();
980
          }
981
          _compMap.set(node, _compNum);
982
          _nodeStack.pop();
983
          ++_compNum;
984
        }
985
      }
986

	
987
      void discover(const Arc& edge) {
988
        _predMap.set(_graph.target(edge), edge);
989
      }
990

	
991
      void examine(const Arc& edge) {
992
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
993
          return;
994
        }
995
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
996
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
997
        }
998
      }
999

	
1000
      void backtrack(const Arc& edge) {
1001
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1002
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1003
        }
1004
      }
1005

	
1006
    private:
1007
      const Digraph& _graph;
1008
      NodeMap& _compMap;
1009
      int& _compNum;
1010

	
1011
      typename Digraph::template NodeMap<int> _numMap;
1012
      typename Digraph::template NodeMap<int> _retMap;
1013
      typename Digraph::template NodeMap<Arc> _predMap;
1014
      std::stack<Node> _nodeStack;
1015
      int _num;
1016
    };
1017

	
1018

	
1019
    template <typename Digraph, typename ArcMap>
1020
    class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
1021
    public:
1022
      typedef typename Digraph::Node Node;
1023
      typedef typename Digraph::Arc Arc;
1024
      typedef typename Digraph::Edge Edge;
1025

	
1026
      BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
1027
                                     ArcMap& cutMap, int &cutNum)
1028
        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
1029
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
1030

	
1031
      void start(const Node& node) {
1032
        _predMap[node] = INVALID;
1033
      }
1034

	
1035
      void reach(const Node& node) {
1036
        _numMap.set(node, _num);
1037
        _retMap.set(node, _num);
1038
        ++_num;
1039
      }
1040

	
1041
      void leave(const Node& node) {
1042
        if (_numMap[node] <= _retMap[node]) {
1043
          if (_predMap[node] != INVALID) {
1044
            _cutMap.set(_predMap[node], true);
1045
            ++_cutNum;
1046
          }
1047
        }
1048
      }
1049

	
1050
      void discover(const Arc& edge) {
1051
        _predMap.set(_graph.target(edge), edge);
1052
      }
1053

	
1054
      void examine(const Arc& edge) {
1055
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
1056
          return;
1057
        }
1058
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1059
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1060
        }
1061
      }
1062

	
1063
      void backtrack(const Arc& edge) {
1064
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1065
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1066
        }
1067
      }
1068

	
1069
    private:
1070
      const Digraph& _graph;
1071
      ArcMap& _cutMap;
1072
      int& _cutNum;
1073

	
1074
      typename Digraph::template NodeMap<int> _numMap;
1075
      typename Digraph::template NodeMap<int> _retMap;
1076
      typename Digraph::template NodeMap<Arc> _predMap;
1077
      int _num;
1078
    };
1079
  }
1080

	
1081
  template <typename Graph>
1082
  int countBiEdgeConnectedComponents(const Graph& graph);
1083

	
1084
  /// \ingroup graph_properties
1085
  ///
1086
  /// \brief Check whether an undirected graph is bi-edge-connected.
1087
  ///
1088
  /// This function checks whether the given undirected graph is 
1089
  /// bi-edge-connected, i.e. any two nodes are connected with at least
1090
  /// two edge-disjoint paths.
1091
  ///
1092
  /// \return \c true if the graph is bi-edge-connected.
1093
  /// \note By definition, the empty graph is bi-edge-connected.
1094
  ///
1095
  /// \see countBiEdgeConnectedComponents(), biEdgeConnectedComponents()
1096
  template <typename Graph>
1097
  bool biEdgeConnected(const Graph& graph) {
1098
    return countBiEdgeConnectedComponents(graph) <= 1;
1099
  }
1100

	
1101
  /// \ingroup graph_properties
1102
  ///
1103
  /// \brief Count the number of bi-edge-connected components of an
1104
  /// undirected graph.
1105
  ///
1106
  /// This function counts the number of bi-edge-connected components of
1107
  /// the given undirected graph.
1108
  ///
1109
  /// The bi-edge-connected components are the classes of an equivalence
1110
  /// relation on the nodes of an undirected graph. Two nodes are in the
1111
  /// same class if they are connected with at least two edge-disjoint
1112
  /// paths.
1113
  ///
1114
  /// \return The number of bi-edge-connected components.
1115
  ///
1116
  /// \see biEdgeConnected(), biEdgeConnectedComponents()
1117
  template <typename Graph>
1118
  int countBiEdgeConnectedComponents(const Graph& graph) {
1119
    checkConcept<concepts::Graph, Graph>();
1120
    typedef typename Graph::NodeIt NodeIt;
1121

	
1122
    using namespace _connectivity_bits;
1123

	
1124
    typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
1125

	
1126
    int compNum = 0;
1127
    Visitor visitor(graph, compNum);
1128

	
1129
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1130
    dfs.init();
1131

	
1132
    for (NodeIt it(graph); it != INVALID; ++it) {
1133
      if (!dfs.reached(it)) {
1134
        dfs.addSource(it);
1135
        dfs.start();
1136
      }
1137
    }
1138
    return compNum;
1139
  }
1140

	
1141
  /// \ingroup graph_properties
1142
  ///
1143
  /// \brief Find the bi-edge-connected components of an undirected graph.
1144
  ///
1145
  /// This function finds the bi-edge-connected components of the given
1146
  /// undirected graph.
1147
  ///
1148
  /// The bi-edge-connected components are the classes of an equivalence
1149
  /// relation on the nodes of an undirected graph. Two nodes are in the
1150
  /// same class if they are connected with at least two edge-disjoint
1151
  /// paths.
1152
  ///
1153
  /// \image html edge_biconnected_components.png
1154
  /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
1155
  ///
1156
  /// \param graph The undirected graph.
1157
  /// \retval compMap A writable node map. The values will be set from 0 to
1158
  /// the number of the bi-edge-connected components minus one. Each value
1159
  /// of the map will be set exactly once, and the values of a certain
1160
  /// component will be set continuously.
1161
  /// \return The number of bi-edge-connected components.
1162
  ///
1163
  /// \see biEdgeConnected(), countBiEdgeConnectedComponents()
1164
  template <typename Graph, typename NodeMap>
1165
  int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
1166
    checkConcept<concepts::Graph, Graph>();
1167
    typedef typename Graph::NodeIt NodeIt;
1168
    typedef typename Graph::Node Node;
1169
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
1170

	
1171
    using namespace _connectivity_bits;
1172

	
1173
    typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
1174

	
1175
    int compNum = 0;
1176
    Visitor visitor(graph, compMap, compNum);
1177

	
1178
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1179
    dfs.init();
1180

	
1181
    for (NodeIt it(graph); it != INVALID; ++it) {
1182
      if (!dfs.reached(it)) {
1183
        dfs.addSource(it);
1184
        dfs.start();
1185
      }
1186
    }
1187
    return compNum;
1188
  }
1189

	
1190
  /// \ingroup graph_properties
1191
  ///
1192
  /// \brief Find the bi-edge-connected cut edges in an undirected graph.
1193
  ///
1194
  /// This function finds the bi-edge-connected cut edges in the given
1195
  /// undirected graph. 
1196
  ///
1197
  /// The bi-edge-connected components are the classes of an equivalence
1198
  /// relation on the nodes of an undirected graph. Two nodes are in the
1199
  /// same class if they are connected with at least two edge-disjoint
1200
  /// paths.
1201
  /// The bi-edge-connected components are separted by the cut edges of
1202
  /// the components.
1203
  ///
1204
  /// \param graph The undirected graph.
1205
  /// \retval cutMap A writable edge map. The values will be set to \c true
1206
  /// for the cut edges (exactly once for each cut edge), and will not be
1207
  /// changed for other edges.
1208
  /// \return The number of cut edges.
1209
  ///
1210
  /// \see biEdgeConnected(), biEdgeConnectedComponents()
1211
  template <typename Graph, typename EdgeMap>
1212
  int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
1213
    checkConcept<concepts::Graph, Graph>();
1214
    typedef typename Graph::NodeIt NodeIt;
1215
    typedef typename Graph::Edge Edge;
1216
    checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
1217

	
1218
    using namespace _connectivity_bits;
1219

	
1220
    typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
1221

	
1222
    int cutNum = 0;
1223
    Visitor visitor(graph, cutMap, cutNum);
1224

	
1225
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1226
    dfs.init();
1227

	
1228
    for (NodeIt it(graph); it != INVALID; ++it) {
1229
      if (!dfs.reached(it)) {
1230
        dfs.addSource(it);
1231
        dfs.start();
1232
      }
1233
    }
1234
    return cutNum;
1235
  }
1236

	
1237

	
1238
  namespace _connectivity_bits {
1239

	
1240
    template <typename Digraph, typename IntNodeMap>
1241
    class TopologicalSortVisitor : public DfsVisitor<Digraph> {
1242
    public:
1243
      typedef typename Digraph::Node Node;
1244
      typedef typename Digraph::Arc edge;
1245

	
1246
      TopologicalSortVisitor(IntNodeMap& order, int num)
1247
        : _order(order), _num(num) {}
1248

	
1249
      void leave(const Node& node) {
1250
        _order.set(node, --_num);
1251
      }
1252

	
1253
    private:
1254
      IntNodeMap& _order;
1255
      int _num;
1256
    };
1257

	
1258
  }
1259

	
1260
  /// \ingroup graph_properties
1261
  ///
1262
  /// \brief Check whether a digraph is DAG.
1263
  ///
1264
  /// This function checks whether the given digraph is DAG, i.e.
1265
  /// \e Directed \e Acyclic \e Graph.
1266
  /// \return \c true if there is no directed cycle in the digraph.
1267
  /// \see acyclic()
1268
  template <typename Digraph>
1269
  bool dag(const Digraph& digraph) {
1270

	
1271
    checkConcept<concepts::Digraph, Digraph>();
1272

	
1273
    typedef typename Digraph::Node Node;
1274
    typedef typename Digraph::NodeIt NodeIt;
1275
    typedef typename Digraph::Arc Arc;
1276

	
1277
    typedef typename Digraph::template NodeMap<bool> ProcessedMap;
1278

	
1279
    typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
1280
      Create dfs(digraph);
1281

	
1282
    ProcessedMap processed(digraph);
1283
    dfs.processedMap(processed);
1284

	
1285
    dfs.init();
1286
    for (NodeIt it(digraph); it != INVALID; ++it) {
1287
      if (!dfs.reached(it)) {
1288
        dfs.addSource(it);
1289
        while (!dfs.emptyQueue()) {
1290
          Arc arc = dfs.nextArc();
1291
          Node target = digraph.target(arc);
1292
          if (dfs.reached(target) && !processed[target]) {
1293
            return false;
1294
          }
1295
          dfs.processNextArc();
1296
        }
1297
      }
1298
    }
1299
    return true;
1300
  }
1301

	
1302
  /// \ingroup graph_properties
1303
  ///
1304
  /// \brief Sort the nodes of a DAG into topolgical order.
1305
  ///
1306
  /// This function sorts the nodes of the given acyclic digraph (DAG)
1307
  /// into topolgical order.
1308
  ///
1309
  /// \param digraph The digraph, which must be DAG.
1310
  /// \retval order A writable node map. The values will be set from 0 to
1311
  /// the number of the nodes in the digraph minus one. Each value of the
1312
  /// map will be set exactly once, and the values will be set descending
1313
  /// order.
1314
  ///
1315
  /// \see dag(), checkedTopologicalSort()
1316
  template <typename Digraph, typename NodeMap>
1317
  void topologicalSort(const Digraph& digraph, NodeMap& order) {
1318
    using namespace _connectivity_bits;
1319

	
1320
    checkConcept<concepts::Digraph, Digraph>();
1321
    checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
1322

	
1323
    typedef typename Digraph::Node Node;
1324
    typedef typename Digraph::NodeIt NodeIt;
1325
    typedef typename Digraph::Arc Arc;
1326

	
1327
    TopologicalSortVisitor<Digraph, NodeMap>
1328
      visitor(order, countNodes(digraph));
1329

	
1330
    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1331
      dfs(digraph, visitor);
1332

	
1333
    dfs.init();
1334
    for (NodeIt it(digraph); it != INVALID; ++it) {
1335
      if (!dfs.reached(it)) {
1336
        dfs.addSource(it);
1337
        dfs.start();
1338
      }
1339
    }
1340
  }
1341

	
1342
  /// \ingroup graph_properties
1343
  ///
1344
  /// \brief Sort the nodes of a DAG into topolgical order.
1345
  ///
1346
  /// This function sorts the nodes of the given acyclic digraph (DAG)
1347
  /// into topolgical order and also checks whether the given digraph
1348
  /// is DAG.
1349
  ///
1350
  /// \param digraph The digraph.
1351
  /// \retval order A readable and writable node map. The values will be
1352
  /// set from 0 to the number of the nodes in the digraph minus one. 
1353
  /// Each value of the map will be set exactly once, and the values will
1354
  /// be set descending order.
1355
  /// \return \c false if the digraph is not DAG.
1356
  ///
1357
  /// \see dag(), topologicalSort()
1358
  template <typename Digraph, typename NodeMap>
1359
  bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
1360
    using namespace _connectivity_bits;
1361

	
1362
    checkConcept<concepts::Digraph, Digraph>();
1363
    checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
1364
      NodeMap>();
1365

	
1366
    typedef typename Digraph::Node Node;
1367
    typedef typename Digraph::NodeIt NodeIt;
1368
    typedef typename Digraph::Arc Arc;
1369

	
1370
    for (NodeIt it(digraph); it != INVALID; ++it) {
1371
      order.set(it, -1);
1372
    }
1373

	
1374
    TopologicalSortVisitor<Digraph, NodeMap>
1375
      visitor(order, countNodes(digraph));
1376

	
1377
    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1378
      dfs(digraph, visitor);
1379

	
1380
    dfs.init();
1381
    for (NodeIt it(digraph); it != INVALID; ++it) {
1382
      if (!dfs.reached(it)) {
1383
        dfs.addSource(it);
1384
        while (!dfs.emptyQueue()) {
1385
           Arc arc = dfs.nextArc();
1386
           Node target = digraph.target(arc);
1387
           if (dfs.reached(target) && order[target] == -1) {
1388
             return false;
1389
           }
1390
           dfs.processNextArc();
1391
         }
1392
      }
1393
    }
1394
    return true;
1395
  }
1396

	
1397
  /// \ingroup graph_properties
1398
  ///
1399
  /// \brief Check whether an undirected graph is acyclic.
1400
  ///
1401
  /// This function checks whether the given undirected graph is acyclic.
1402
  /// \return \c true if there is no cycle in the graph.
1403
  /// \see dag()
1404
  template <typename Graph>
1405
  bool acyclic(const Graph& graph) {
1406
    checkConcept<concepts::Graph, Graph>();
1407
    typedef typename Graph::Node Node;
1408
    typedef typename Graph::NodeIt NodeIt;
1409
    typedef typename Graph::Arc Arc;
1410
    Dfs<Graph> dfs(graph);
1411
    dfs.init();
1412
    for (NodeIt it(graph); it != INVALID; ++it) {
1413
      if (!dfs.reached(it)) {
1414
        dfs.addSource(it);
1415
        while (!dfs.emptyQueue()) {
1416
          Arc arc = dfs.nextArc();
1417
          Node source = graph.source(arc);
1418
          Node target = graph.target(arc);
1419
          if (dfs.reached(target) &&
1420
              dfs.predArc(source) != graph.oppositeArc(arc)) {
1421
            return false;
1422
          }
1423
          dfs.processNextArc();
1424
        }
1425
      }
1426
    }
1427
    return true;
1428
  }
1429

	
1430
  /// \ingroup graph_properties
1431
  ///
1432
  /// \brief Check whether an undirected graph is tree.
1433
  ///
1434
  /// This function checks whether the given undirected graph is tree.
1435
  /// \return \c true if the graph is acyclic and connected.
1436
  /// \see acyclic(), connected()
1437
  template <typename Graph>
1438
  bool tree(const Graph& graph) {
1439
    checkConcept<concepts::Graph, Graph>();
1440
    typedef typename Graph::Node Node;
1441
    typedef typename Graph::NodeIt NodeIt;
1442
    typedef typename Graph::Arc Arc;
1443
    if (NodeIt(graph) == INVALID) return true;
1444
    Dfs<Graph> dfs(graph);
1445
    dfs.init();
1446
    dfs.addSource(NodeIt(graph));
1447
    while (!dfs.emptyQueue()) {
1448
      Arc arc = dfs.nextArc();
1449
      Node source = graph.source(arc);
1450
      Node target = graph.target(arc);
1451
      if (dfs.reached(target) &&
1452
          dfs.predArc(source) != graph.oppositeArc(arc)) {
1453
        return false;
1454
      }
1455
      dfs.processNextArc();
1456
    }
1457
    for (NodeIt it(graph); it != INVALID; ++it) {
1458
      if (!dfs.reached(it)) {
1459
        return false;
1460
      }
1461
    }
1462
    return true;
1463
  }
1464

	
1465
  namespace _connectivity_bits {
1466

	
1467
    template <typename Digraph>
1468
    class BipartiteVisitor : public BfsVisitor<Digraph> {
1469
    public:
1470
      typedef typename Digraph::Arc Arc;
1471
      typedef typename Digraph::Node Node;
1472

	
1473
      BipartiteVisitor(const Digraph& graph, bool& bipartite)
1474
        : _graph(graph), _part(graph), _bipartite(bipartite) {}
1475

	
1476
      void start(const Node& node) {
1477
        _part[node] = true;
1478
      }
1479
      void discover(const Arc& edge) {
1480
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1481
      }
1482
      void examine(const Arc& edge) {
1483
        _bipartite = _bipartite &&
1484
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
1485
      }
1486

	
1487
    private:
1488

	
1489
      const Digraph& _graph;
1490
      typename Digraph::template NodeMap<bool> _part;
1491
      bool& _bipartite;
1492
    };
1493

	
1494
    template <typename Digraph, typename PartMap>
1495
    class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
1496
    public:
1497
      typedef typename Digraph::Arc Arc;
1498
      typedef typename Digraph::Node Node;
1499

	
1500
      BipartitePartitionsVisitor(const Digraph& graph,
1501
                                 PartMap& part, bool& bipartite)
1502
        : _graph(graph), _part(part), _bipartite(bipartite) {}
1503

	
1504
      void start(const Node& node) {
1505
        _part.set(node, true);
1506
      }
1507
      void discover(const Arc& edge) {
1508
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1509
      }
1510
      void examine(const Arc& edge) {
1511
        _bipartite = _bipartite &&
1512
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
1513
      }
1514

	
1515
    private:
1516

	
1517
      const Digraph& _graph;
1518
      PartMap& _part;
1519
      bool& _bipartite;
1520
    };
1521
  }
1522

	
1523
  /// \ingroup graph_properties
1524
  ///
1525
  /// \brief Check whether an undirected graph is bipartite.
1526
  ///
1527
  /// The function checks whether the given undirected graph is bipartite.
1528
  /// \return \c true if the graph is bipartite.
1529
  ///
1530
  /// \see bipartitePartitions()
1531
  template<typename Graph>
1532
  bool bipartite(const Graph &graph){
1533
    using namespace _connectivity_bits;
1534

	
1535
    checkConcept<concepts::Graph, Graph>();
1536

	
1537
    typedef typename Graph::NodeIt NodeIt;
1538
    typedef typename Graph::ArcIt ArcIt;
1539

	
1540
    bool bipartite = true;
1541

	
1542
    BipartiteVisitor<Graph>
1543
      visitor(graph, bipartite);
1544
    BfsVisit<Graph, BipartiteVisitor<Graph> >
1545
      bfs(graph, visitor);
1546
    bfs.init();
1547
    for(NodeIt it(graph); it != INVALID; ++it) {
1548
      if(!bfs.reached(it)){
1549
        bfs.addSource(it);
1550
        while (!bfs.emptyQueue()) {
1551
          bfs.processNextNode();
1552
          if (!bipartite) return false;
1553
        }
1554
      }
1555
    }
1556
    return true;
1557
  }
1558

	
1559
  /// \ingroup graph_properties
1560
  ///
1561
  /// \brief Find the bipartite partitions of an undirected graph.
1562
  ///
1563
  /// This function checks whether the given undirected graph is bipartite
1564
  /// and gives back the bipartite partitions.
1565
  ///
1566
  /// \image html bipartite_partitions.png
1567
  /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
1568
  ///
1569
  /// \param graph The undirected graph.
1570
  /// \retval partMap A writable node map of \c bool (or convertible) value
1571
  /// type. The values will be set to \c true for one component and
1572
  /// \c false for the other one.
1573
  /// \return \c true if the graph is bipartite, \c false otherwise.
1574
  ///
1575
  /// \see bipartite()
1576
  template<typename Graph, typename NodeMap>
1577
  bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
1578
    using namespace _connectivity_bits;
1579

	
1580
    checkConcept<concepts::Graph, Graph>();
1581
    checkConcept<concepts::WriteMap<typename Graph::Node, bool>, NodeMap>();
1582

	
1583
    typedef typename Graph::Node Node;
1584
    typedef typename Graph::NodeIt NodeIt;
1585
    typedef typename Graph::ArcIt ArcIt;
1586

	
1587
    bool bipartite = true;
1588

	
1589
    BipartitePartitionsVisitor<Graph, NodeMap>
1590
      visitor(graph, partMap, bipartite);
1591
    BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
1592
      bfs(graph, visitor);
1593
    bfs.init();
1594
    for(NodeIt it(graph); it != INVALID; ++it) {
1595
      if(!bfs.reached(it)){
1596
        bfs.addSource(it);
1597
        while (!bfs.emptyQueue()) {
1598
          bfs.processNextNode();
1599
          if (!bipartite) return false;
1600
        }
1601
      }
1602
    }
1603
    return true;
1604
  }
1605

	
1606
  /// \ingroup graph_properties
1607
  ///
1608
  /// \brief Check whether the given graph contains no loop arcs/edges.
1609
  ///
1610
  /// This function returns \c true if there are no loop arcs/edges in
1611
  /// the given graph. It works for both directed and undirected graphs.
1612
  template <typename Graph>
1613
  bool loopFree(const Graph& graph) {
1614
    for (typename Graph::ArcIt it(graph); it != INVALID; ++it) {
1615
      if (graph.source(it) == graph.target(it)) return false;
1616
    }
1617
    return true;
1618
  }
1619

	
1620
  /// \ingroup graph_properties
1621
  ///
1622
  /// \brief Check whether the given graph contains no parallel arcs/edges.
1623
  ///
1624
  /// This function returns \c true if there are no parallel arcs/edges in
1625
  /// the given graph. It works for both directed and undirected graphs.
1626
  template <typename Graph>
1627
  bool parallelFree(const Graph& graph) {
1628
    typename Graph::template NodeMap<int> reached(graph, 0);
1629
    int cnt = 1;
1630
    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1631
      for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
1632
        if (reached[graph.target(a)] == cnt) return false;
1633
        reached[graph.target(a)] = cnt;
1634
      }
1635
      ++cnt;
1636
    }
1637
    return true;
1638
  }
1639

	
1640
  /// \ingroup graph_properties
1641
  ///
1642
  /// \brief Check whether the given graph is simple.
1643
  ///
1644
  /// This function returns \c true if the given graph is simple, i.e.
1645
  /// it contains no loop arcs/edges and no parallel arcs/edges.
1646
  /// The function works for both directed and undirected graphs.
1647
  /// \see loopFree(), parallelFree()
1648
  template <typename Graph>
1649
  bool simpleGraph(const Graph& graph) {
1650
    typename Graph::template NodeMap<int> reached(graph, 0);
1651
    int cnt = 1;
1652
    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1653
      reached[n] = cnt;
1654
      for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
1655
        if (reached[graph.target(a)] == cnt) return false;
1656
        reached[graph.target(a)] = cnt;
1657
      }
1658
      ++cnt;
1659
    }
1660
    return true;
1661
  }
1662

	
1663
} //namespace lemon
1664

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

	
19
#include <iostream>
20
#include <vector>
21
#include <cstring>
22

	
23
#include <lemon/cplex.h>
24

	
25
extern "C" {
26
#include <ilcplex/cplex.h>
27
}
28

	
29

	
30
///\file
31
///\brief Implementation of the LEMON-CPLEX lp solver interface.
32
namespace lemon {
33

	
34
  CplexEnv::LicenseError::LicenseError(int status) {
35
    if (!CPXgeterrorstring(0, status, _message)) {
36
      std::strcpy(_message, "Cplex unknown error");
37
    }
38
  }
39

	
40
  CplexEnv::CplexEnv() {
41
    int status;
42
    _cnt = new int;
43
    _env = CPXopenCPLEX(&status);
44
    if (_env == 0) {
45
      delete _cnt;
46
      _cnt = 0;
47
      throw LicenseError(status);
48
    }
49
  }
50

	
51
  CplexEnv::CplexEnv(const CplexEnv& other) {
52
    _env = other._env;
53
    _cnt = other._cnt;
54
    ++(*_cnt);
55
  }
56

	
57
  CplexEnv& CplexEnv::operator=(const CplexEnv& other) {
58
    _env = other._env;
59
    _cnt = other._cnt;
60
    ++(*_cnt);
61
    return *this;
62
  }
63

	
64
  CplexEnv::~CplexEnv() {
65
    --(*_cnt);
66
    if (*_cnt == 0) {
67
      delete _cnt;
68
      CPXcloseCPLEX(&_env);
69
    }
70
  }
71

	
72
  CplexBase::CplexBase() : LpBase() {
73
    int status;
74
    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
75
    messageLevel(MESSAGE_NOTHING);
76
  }
77

	
78
  CplexBase::CplexBase(const CplexEnv& env)
79
    : LpBase(), _env(env) {
80
    int status;
81
    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
82
    messageLevel(MESSAGE_NOTHING);
83
  }
84

	
85
  CplexBase::CplexBase(const CplexBase& cplex)
86
    : LpBase() {
87
    int status;
88
    _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
89
    rows = cplex.rows;
90
    cols = cplex.cols;
91
    messageLevel(MESSAGE_NOTHING);
92
  }
93

	
94
  CplexBase::~CplexBase() {
95
    CPXfreeprob(cplexEnv(),&_prob);
96
  }
97

	
98
  int CplexBase::_addCol() {
99
    int i = CPXgetnumcols(cplexEnv(), _prob);
100
    double lb = -INF, ub = INF;
101
    CPXnewcols(cplexEnv(), _prob, 1, 0, &lb, &ub, 0, 0);
102
    return i;
103
  }
104

	
105

	
106
  int CplexBase::_addRow() {
107
    int i = CPXgetnumrows(cplexEnv(), _prob);
108
    const double ub = INF;
109
    const char s = 'L';
110
    CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
111
    return i;
112
  }
113

	
114

	
115
  void CplexBase::_eraseCol(int i) {
116
    CPXdelcols(cplexEnv(), _prob, i, i);
117
  }
118

	
119
  void CplexBase::_eraseRow(int i) {
120
    CPXdelrows(cplexEnv(), _prob, i, i);
121
  }
122

	
123
  void CplexBase::_eraseColId(int i) {
124
    cols.eraseIndex(i);
125
    cols.shiftIndices(i);
126
  }
127
  void CplexBase::_eraseRowId(int i) {
128
    rows.eraseIndex(i);
129
    rows.shiftIndices(i);
130
  }
131

	
132
  void CplexBase::_getColName(int col, std::string &name) const {
133
    int size;
134
    CPXgetcolname(cplexEnv(), _prob, 0, 0, 0, &size, col, col);
135
    if (size == 0) {
136
      name.clear();
137
      return;
138
    }
139

	
140
    size *= -1;
141
    std::vector<char> buf(size);
142
    char *cname;
143
    int tmp;
144
    CPXgetcolname(cplexEnv(), _prob, &cname, &buf.front(), size,
145
                  &tmp, col, col);
146
    name = cname;
147
  }
148

	
149
  void CplexBase::_setColName(int col, const std::string &name) {
150
    char *cname;
151
    cname = const_cast<char*>(name.c_str());
152
    CPXchgcolname(cplexEnv(), _prob, 1, &col, &cname);
153
  }
154

	
155
  int CplexBase::_colByName(const std::string& name) const {
156
    int index;
157
    if (CPXgetcolindex(cplexEnv(), _prob,
158
                       const_cast<char*>(name.c_str()), &index) == 0) {
159
      return index;
160
    }
161
    return -1;
162
  }
163

	
164
  void CplexBase::_getRowName(int row, std::string &name) const {
165
    int size;
166
    CPXgetrowname(cplexEnv(), _prob, 0, 0, 0, &size, row, row);
167
    if (size == 0) {
168
      name.clear();
169
      return;
170
    }
171

	
172
    size *= -1;
173
    std::vector<char> buf(size);
174
    char *cname;
175
    int tmp;
176
    CPXgetrowname(cplexEnv(), _prob, &cname, &buf.front(), size,
177
                  &tmp, row, row);
178
    name = cname;
179
  }
180

	
181
  void CplexBase::_setRowName(int row, const std::string &name) {
182
    char *cname;
183
    cname = const_cast<char*>(name.c_str());
184
    CPXchgrowname(cplexEnv(), _prob, 1, &row, &cname);
185
  }
186

	
187
  int CplexBase::_rowByName(const std::string& name) const {
188
    int index;
189
    if (CPXgetrowindex(cplexEnv(), _prob,
190
                       const_cast<char*>(name.c_str()), &index) == 0) {
191
      return index;
192
    }
193
    return -1;
194
  }
195

	
196
  void CplexBase::_setRowCoeffs(int i, ExprIterator b,
197
                                      ExprIterator e)
198
  {
199
    std::vector<int> indices;
200
    std::vector<int> rowlist;
201
    std::vector<Value> values;
202

	
203
    for(ExprIterator it=b; it!=e; ++it) {
204
      indices.push_back(it->first);
205
      values.push_back(it->second);
206
      rowlist.push_back(i);
207
    }
208

	
209
    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
210
                   &rowlist.front(), &indices.front(), &values.front());
211
  }
212

	
213
  void CplexBase::_getRowCoeffs(int i, InsertIterator b) const {
214
    int tmp1, tmp2, tmp3, length;
215
    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
216

	
217
    length = -length;
218
    std::vector<int> indices(length);
219
    std::vector<double> values(length);
220

	
221
    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2,
222
               &indices.front(), &values.front(),
223
               length, &tmp3, i, i);
224

	
225
    for (int i = 0; i < length; ++i) {
226
      *b = std::make_pair(indices[i], values[i]);
227
      ++b;
228
    }
229
  }
230

	
231
  void CplexBase::_setColCoeffs(int i, ExprIterator b, ExprIterator e) {
232
    std::vector<int> indices;
233
    std::vector<int> collist;
234
    std::vector<Value> values;
235

	
236
    for(ExprIterator it=b; it!=e; ++it) {
237
      indices.push_back(it->first);
238
      values.push_back(it->second);
239
      collist.push_back(i);
240
    }
241

	
242
    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
243
                   &indices.front(), &collist.front(), &values.front());
244
  }
245

	
246
  void CplexBase::_getColCoeffs(int i, InsertIterator b) const {
247

	
248
    int tmp1, tmp2, tmp3, length;
249
    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
250

	
251
    length = -length;
252
    std::vector<int> indices(length);
253
    std::vector<double> values(length);
254

	
255
    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2,
256
               &indices.front(), &values.front(),
257
               length, &tmp3, i, i);
258

	
259
    for (int i = 0; i < length; ++i) {
260
      *b = std::make_pair(indices[i], values[i]);
261
      ++b;
262
    }
263

	
264
  }
265

	
266
  void CplexBase::_setCoeff(int row, int col, Value value) {
267
    CPXchgcoef(cplexEnv(), _prob, row, col, value);
268
  }
269

	
270
  CplexBase::Value CplexBase::_getCoeff(int row, int col) const {
271
    CplexBase::Value value;
272
    CPXgetcoef(cplexEnv(), _prob, row, col, &value);
273
    return value;
274
  }
275

	
276
  void CplexBase::_setColLowerBound(int i, Value value) {
277
    const char s = 'L';
278
    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
279
  }
280

	
281
  CplexBase::Value CplexBase::_getColLowerBound(int i) const {
282
    CplexBase::Value res;
283
    CPXgetlb(cplexEnv(), _prob, &res, i, i);
284
    return res <= -CPX_INFBOUND ? -INF : res;
285
  }
286

	
287
  void CplexBase::_setColUpperBound(int i, Value value)
288
  {
289
    const char s = 'U';
290
    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
291
  }
292

	
293
  CplexBase::Value CplexBase::_getColUpperBound(int i) const {
294
    CplexBase::Value res;
295
    CPXgetub(cplexEnv(), _prob, &res, i, i);
296
    return res >= CPX_INFBOUND ? INF : res;
297
  }
298

	
299
  CplexBase::Value CplexBase::_getRowLowerBound(int i) const {
300
    char s;
301
    CPXgetsense(cplexEnv(), _prob, &s, i, i);
302
    CplexBase::Value res;
303

	
304
    switch (s) {
305
    case 'G':
306
    case 'R':
307
    case 'E':
308
      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
309
      return res <= -CPX_INFBOUND ? -INF : res;
310
    default:
311
      return -INF;
312
    }
313
  }
314

	
315
  CplexBase::Value CplexBase::_getRowUpperBound(int i) const {
316
    char s;
317
    CPXgetsense(cplexEnv(), _prob, &s, i, i);
318
    CplexBase::Value res;
319

	
320
    switch (s) {
321
    case 'L':
322
    case 'E':
323
      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
324
      return res >= CPX_INFBOUND ? INF : res;
325
    case 'R':
326
      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
327
      {
328
        double rng;
329
        CPXgetrngval(cplexEnv(), _prob, &rng, i, i);
330
        res += rng;
331
      }
332
      return res >= CPX_INFBOUND ? INF : res;
333
    default:
334
      return INF;
335
    }
336
  }
337

	
338
  //This is easier to implement
339
  void CplexBase::_set_row_bounds(int i, Value lb, Value ub) {
340
    if (lb == -INF) {
341
      const char s = 'L';
342
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
343
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &ub);
344
    } else if (ub == INF) {
345
      const char s = 'G';
346
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
347
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
348
    } else if (lb == ub){
349
      const char s = 'E';
350
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
351
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
352
    } else {
353
      const char s = 'R';
354
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
355
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
356
      double len = ub - lb;
357
      CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
358
    }
359
  }
360

	
361
  void CplexBase::_setRowLowerBound(int i, Value lb)
362
  {
363
    LEMON_ASSERT(lb != INF, "Invalid bound");
364
    _set_row_bounds(i, lb, CplexBase::_getRowUpperBound(i));
365
  }
366

	
367
  void CplexBase::_setRowUpperBound(int i, Value ub)
368
  {
369

	
370
    LEMON_ASSERT(ub != -INF, "Invalid bound");
371
    _set_row_bounds(i, CplexBase::_getRowLowerBound(i), ub);
372
  }
373

	
374
  void CplexBase::_setObjCoeffs(ExprIterator b, ExprIterator e)
375
  {
376
    std::vector<int> indices;
377
    std::vector<Value> values;
378
    for(ExprIterator it=b; it!=e; ++it) {
379
      indices.push_back(it->first);
380
      values.push_back(it->second);
381
    }
382
    CPXchgobj(cplexEnv(), _prob, values.size(),
383
              &indices.front(), &values.front());
384

	
385
  }
386

	
387
  void CplexBase::_getObjCoeffs(InsertIterator b) const
388
  {
389
    int num = CPXgetnumcols(cplexEnv(), _prob);
390
    std::vector<Value> x(num);
391

	
392
    CPXgetobj(cplexEnv(), _prob, &x.front(), 0, num - 1);
393
    for (int i = 0; i < num; ++i) {
394
      if (x[i] != 0.0) {
395
        *b = std::make_pair(i, x[i]);
396
        ++b;
397
      }
398
    }
399
  }
400

	
401
  void CplexBase::_setObjCoeff(int i, Value obj_coef)
402
  {
403
    CPXchgobj(cplexEnv(), _prob, 1, &i, &obj_coef);
404
  }
405

	
406
  CplexBase::Value CplexBase::_getObjCoeff(int i) const
407
  {
408
    Value x;
409
    CPXgetobj(cplexEnv(), _prob, &x, i, i);
410
    return x;
411
  }
412

	
413
  void CplexBase::_setSense(CplexBase::Sense sense) {
414
    switch (sense) {
415
    case MIN:
416
      CPXchgobjsen(cplexEnv(), _prob, CPX_MIN);
417
      break;
418
    case MAX:
419
      CPXchgobjsen(cplexEnv(), _prob, CPX_MAX);
420
      break;
421
    }
422
  }
423

	
424
  CplexBase::Sense CplexBase::_getSense() const {
425
    switch (CPXgetobjsen(cplexEnv(), _prob)) {
426
    case CPX_MIN:
427
      return MIN;
428
    case CPX_MAX:
429
      return MAX;
430
    default:
431
      LEMON_ASSERT(false, "Invalid sense");
432
      return CplexBase::Sense();
433
    }
434
  }
435

	
436
  void CplexBase::_clear() {
437
    CPXfreeprob(cplexEnv(),&_prob);
438
    int status;
439
    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
440
    rows.clear();
441
    cols.clear();
442
  }
443

	
444
  void CplexBase::_messageLevel(MessageLevel level) {
445
    switch (level) {
446
    case MESSAGE_NOTHING:
447
      _message_enabled = false;
448
      break;
449
    case MESSAGE_ERROR:
450
    case MESSAGE_WARNING:
451
    case MESSAGE_NORMAL:
452
    case MESSAGE_VERBOSE:
453
      _message_enabled = true;
454
      break;
455
    }
456
  }
457

	
458
  void CplexBase::_applyMessageLevel() {
459
    CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND, 
460
                   _message_enabled ? CPX_ON : CPX_OFF);
461
  }
462

	
463
  // CplexLp members
464

	
465
  CplexLp::CplexLp()
466
    : LpBase(), LpSolver(), CplexBase() {}
467

	
468
  CplexLp::CplexLp(const CplexEnv& env)
469
    : LpBase(), LpSolver(), CplexBase(env) {}
470

	
471
  CplexLp::CplexLp(const CplexLp& other)
472
    : LpBase(), LpSolver(), CplexBase(other) {}
473

	
474
  CplexLp::~CplexLp() {}
475

	
476
  CplexLp* CplexLp::newSolver() const { return new CplexLp; }
477
  CplexLp* CplexLp::cloneSolver() const {return new CplexLp(*this); }
478

	
479
  const char* CplexLp::_solverName() const { return "CplexLp"; }
480

	
481
  void CplexLp::_clear_temporals() {
482
    _col_status.clear();
483
    _row_status.clear();
484
    _primal_ray.clear();
485
    _dual_ray.clear();
486
  }
487

	
488
  // The routine returns zero unless an error occurred during the
489
  // optimization. Examples of errors include exhausting available
490
  // memory (CPXERR_NO_MEMORY) or encountering invalid data in the
491
  // CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a
492
  // user-specified CPLEX limit, or proving the model infeasible or
493
  // unbounded, are not considered errors. Note that a zero return
494
  // value does not necessarily mean that a solution exists. Use query
495
  // routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain
496
  // further information about the status of the optimization.
497
  CplexLp::SolveExitStatus CplexLp::convertStatus(int status) {
498
#if CPX_VERSION >= 800
499
    if (status == 0) {
500
      switch (CPXgetstat(cplexEnv(), _prob)) {
501
      case CPX_STAT_OPTIMAL:
502
      case CPX_STAT_INFEASIBLE:
503
      case CPX_STAT_UNBOUNDED:
504
        return SOLVED;
505
      default:
506
        return UNSOLVED;
507
      }
508
    } else {
509
      return UNSOLVED;
510
    }
511
#else
512
    if (status == 0) {
513
      //We want to exclude some cases
514
      switch (CPXgetstat(cplexEnv(), _prob)) {
515
      case CPX_OBJ_LIM:
516
      case CPX_IT_LIM_FEAS:
517
      case CPX_IT_LIM_INFEAS:
518
      case CPX_TIME_LIM_FEAS:
519
      case CPX_TIME_LIM_INFEAS:
520
        return UNSOLVED;
521
      default:
522
        return SOLVED;
523
      }
524
    } else {
525
      return UNSOLVED;
526
    }
527
#endif
528
  }
529

	
530
  CplexLp::SolveExitStatus CplexLp::_solve() {
531
    _clear_temporals();
532
    _applyMessageLevel();
533
    return convertStatus(CPXlpopt(cplexEnv(), _prob));
534
  }
535

	
536
  CplexLp::SolveExitStatus CplexLp::solvePrimal() {
537
    _clear_temporals();
538
    _applyMessageLevel();
539
    return convertStatus(CPXprimopt(cplexEnv(), _prob));
540
  }
541

	
542
  CplexLp::SolveExitStatus CplexLp::solveDual() {
543
    _clear_temporals();
544
    _applyMessageLevel();
545
    return convertStatus(CPXdualopt(cplexEnv(), _prob));
546
  }
547

	
548
  CplexLp::SolveExitStatus CplexLp::solveBarrier() {
549
    _clear_temporals();
550
    _applyMessageLevel();
551
    return convertStatus(CPXbaropt(cplexEnv(), _prob));
552
  }
553

	
554
  CplexLp::Value CplexLp::_getPrimal(int i) const {
555
    Value x;
556
    CPXgetx(cplexEnv(), _prob, &x, i, i);
557
    return x;
558
  }
559

	
560
  CplexLp::Value CplexLp::_getDual(int i) const {
561
    Value y;
562
    CPXgetpi(cplexEnv(), _prob, &y, i, i);
563
    return y;
564
  }
565

	
566
  CplexLp::Value CplexLp::_getPrimalValue() const {
567
    Value objval;
568
    CPXgetobjval(cplexEnv(), _prob, &objval);
569
    return objval;
570
  }
571

	
572
  CplexLp::VarStatus CplexLp::_getColStatus(int i) const {
573
    if (_col_status.empty()) {
574
      _col_status.resize(CPXgetnumcols(cplexEnv(), _prob));
575
      CPXgetbase(cplexEnv(), _prob, &_col_status.front(), 0);
576
    }
577
    switch (_col_status[i]) {
578
    case CPX_BASIC:
579
      return BASIC;
580
    case CPX_FREE_SUPER:
581
      return FREE;
582
    case CPX_AT_LOWER:
583
      return LOWER;
584
    case CPX_AT_UPPER:
585
      return UPPER;
586
    default:
587
      LEMON_ASSERT(false, "Wrong column status");
588
      return CplexLp::VarStatus();
589
    }
590
  }
591

	
592
  CplexLp::VarStatus CplexLp::_getRowStatus(int i) const {
593
    if (_row_status.empty()) {
594
      _row_status.resize(CPXgetnumrows(cplexEnv(), _prob));
595
      CPXgetbase(cplexEnv(), _prob, 0, &_row_status.front());
596
    }
597
    switch (_row_status[i]) {
598
    case CPX_BASIC:
599
      return BASIC;
600
    case CPX_AT_LOWER:
601
      {
602
        char s;
603
        CPXgetsense(cplexEnv(), _prob, &s, i, i);
604
        return s != 'L' ? LOWER : UPPER;
605
      }
606
    case CPX_AT_UPPER:
607
      return UPPER;
608
    default:
609
      LEMON_ASSERT(false, "Wrong row status");
610
      return CplexLp::VarStatus();
611
    }
612
  }
613

	
614
  CplexLp::Value CplexLp::_getPrimalRay(int i) const {
615
    if (_primal_ray.empty()) {
616
      _primal_ray.resize(CPXgetnumcols(cplexEnv(), _prob));
617
      CPXgetray(cplexEnv(), _prob, &_primal_ray.front());
618
    }
619
    return _primal_ray[i];
620
  }
621

	
622
  CplexLp::Value CplexLp::_getDualRay(int i) const {
623
    if (_dual_ray.empty()) {
624

	
625
    }
626
    return _dual_ray[i];
627
  }
628

	
629
  // Cplex 7.0 status values
630
  // This table lists the statuses, returned by the CPXgetstat()
631
  // routine, for solutions to LP problems or mixed integer problems. If
632
  // no solution exists, the return value is zero.
633

	
634
  // For Simplex, Barrier
635
  // 1          CPX_OPTIMAL
636
  //          Optimal solution found
637
  // 2          CPX_INFEASIBLE
638
  //          Problem infeasible
639
  // 3    CPX_UNBOUNDED
640
  //          Problem unbounded
641
  // 4          CPX_OBJ_LIM
642
  //          Objective limit exceeded in Phase II
643
  // 5          CPX_IT_LIM_FEAS
644
  //          Iteration limit exceeded in Phase II
645
  // 6          CPX_IT_LIM_INFEAS
646
  //          Iteration limit exceeded in Phase I
647
  // 7          CPX_TIME_LIM_FEAS
648
  //          Time limit exceeded in Phase II
649
  // 8          CPX_TIME_LIM_INFEAS
650
  //          Time limit exceeded in Phase I
651
  // 9          CPX_NUM_BEST_FEAS
652
  //          Problem non-optimal, singularities in Phase II
653
  // 10         CPX_NUM_BEST_INFEAS
654
  //          Problem non-optimal, singularities in Phase I
655
  // 11         CPX_OPTIMAL_INFEAS
656
  //          Optimal solution found, unscaled infeasibilities
657
  // 12         CPX_ABORT_FEAS
658
  //          Aborted in Phase II
659
  // 13         CPX_ABORT_INFEAS
660
  //          Aborted in Phase I
661
  // 14          CPX_ABORT_DUAL_INFEAS
662
  //          Aborted in barrier, dual infeasible
663
  // 15          CPX_ABORT_PRIM_INFEAS
664
  //          Aborted in barrier, primal infeasible
665
  // 16          CPX_ABORT_PRIM_DUAL_INFEAS
666
  //          Aborted in barrier, primal and dual infeasible
667
  // 17          CPX_ABORT_PRIM_DUAL_FEAS
668
  //          Aborted in barrier, primal and dual feasible
669
  // 18          CPX_ABORT_CROSSOVER
670
  //          Aborted in crossover
671
  // 19          CPX_INForUNBD
672
  //          Infeasible or unbounded
673
  // 20   CPX_PIVOT
674
  //       User pivot used
675
  //
676
  // Pending return values
677
  // ??case CPX_ABORT_DUAL_INFEAS
678
  // ??case CPX_ABORT_CROSSOVER
679
  // ??case CPX_INForUNBD
680
  // ??case CPX_PIVOT
681

	
682
  //Some more interesting stuff:
683

	
684
  // CPX_PARAM_PROBMETHOD  1062  int  LPMETHOD
685
  // 0 Automatic
686
  // 1 Primal Simplex
687
  // 2 Dual Simplex
688
  // 3 Network Simplex
689
  // 4 Standard Barrier
690
  // Default: 0
691
  // Description: Method for linear optimization.
692
  // Determines which algorithm is used when CPXlpopt() (or "optimize"
693
  // in the Interactive Optimizer) is called. Currently the behavior of
694
  // the "Automatic" setting is that CPLEX simply invokes the dual
695
  // simplex method, but this capability may be expanded in the future
696
  // so that CPLEX chooses the method based on problem characteristics
697
#if CPX_VERSION < 900
698
  void statusSwitch(CPXENVptr cplexEnv(),int& stat){
699
    int lpmethod;
700
    CPXgetintparam (cplexEnv(),CPX_PARAM_PROBMETHOD,&lpmethod);
701
    if (lpmethod==2){
702
      if (stat==CPX_UNBOUNDED){
703
        stat=CPX_INFEASIBLE;
704
      }
705
      else{
706
        if (stat==CPX_INFEASIBLE)
707
          stat=CPX_UNBOUNDED;
708
      }
709
    }
710
  }
711
#else
712
  void statusSwitch(CPXENVptr,int&){}
713
#endif
714

	
715
  CplexLp::ProblemType CplexLp::_getPrimalType() const {
716
    // Unboundedness not treated well: the following is from cplex 9.0 doc
717
    // About Unboundedness
718

	
719
    // The treatment of models that are unbounded involves a few
720
    // subtleties. Specifically, a declaration of unboundedness means that
721
    // ILOG CPLEX has determined that the model has an unbounded
722
    // ray. Given any feasible solution x with objective z, a multiple of
723
    // the unbounded ray can be added to x to give a feasible solution
724
    // with objective z-1 (or z+1 for maximization models). Thus, if a
725
    // feasible solution exists, then the optimal objective is
726
    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
727
    // a feasible solution exists. Users can call the routine CPXsolninfo
728
    // to determine whether ILOG CPLEX has also concluded that the model
729
    // has a feasible solution.
730

	
731
    int stat = CPXgetstat(cplexEnv(), _prob);
732
#if CPX_VERSION >= 800
733
    switch (stat)
734
      {
735
      case CPX_STAT_OPTIMAL:
736
        return OPTIMAL;
737
      case CPX_STAT_UNBOUNDED:
738
        return UNBOUNDED;
739
      case CPX_STAT_INFEASIBLE:
740
        return INFEASIBLE;
741
      default:
742
        return UNDEFINED;
743
      }
744
#else
745
    statusSwitch(cplexEnv(),stat);
746
    //CPXgetstat(cplexEnv(), _prob);
747
    switch (stat) {
748
    case 0:
749
      return UNDEFINED; //Undefined
750
    case CPX_OPTIMAL://Optimal
751
      return OPTIMAL;
752
    case CPX_UNBOUNDED://Unbounded
753
      return INFEASIBLE;//In case of dual simplex
754
      //return UNBOUNDED;
755
    case CPX_INFEASIBLE://Infeasible
756
      //    case CPX_IT_LIM_INFEAS:
757
      //     case CPX_TIME_LIM_INFEAS:
758
      //     case CPX_NUM_BEST_INFEAS:
759
      //     case CPX_OPTIMAL_INFEAS:
760
      //     case CPX_ABORT_INFEAS:
761
      //     case CPX_ABORT_PRIM_INFEAS:
762
      //     case CPX_ABORT_PRIM_DUAL_INFEAS:
763
      return UNBOUNDED;//In case of dual simplex
764
      //return INFEASIBLE;
765
      //     case CPX_OBJ_LIM:
766
      //     case CPX_IT_LIM_FEAS:
767
      //     case CPX_TIME_LIM_FEAS:
768
      //     case CPX_NUM_BEST_FEAS:
769
      //     case CPX_ABORT_FEAS:
770
      //     case CPX_ABORT_PRIM_DUAL_FEAS:
771
      //       return FEASIBLE;
772
    default:
773
      return UNDEFINED; //Everything else comes here
774
      //FIXME error
775
    }
776
#endif
777
  }
778

	
779
  // Cplex 9.0 status values
780
  // CPX_STAT_ABORT_DUAL_OBJ_LIM
781
  // CPX_STAT_ABORT_IT_LIM
782
  // CPX_STAT_ABORT_OBJ_LIM
783
  // CPX_STAT_ABORT_PRIM_OBJ_LIM
784
  // CPX_STAT_ABORT_TIME_LIM
785
  // CPX_STAT_ABORT_USER
786
  // CPX_STAT_FEASIBLE_RELAXED
787
  // CPX_STAT_INFEASIBLE
788
  // CPX_STAT_INForUNBD
789
  // CPX_STAT_NUM_BEST
790
  // CPX_STAT_OPTIMAL
791
  // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
792
  // CPX_STAT_OPTIMAL_INFEAS
793
  // CPX_STAT_OPTIMAL_RELAXED
794
  // CPX_STAT_UNBOUNDED
795

	
796
  CplexLp::ProblemType CplexLp::_getDualType() const {
797
    int stat = CPXgetstat(cplexEnv(), _prob);
798
#if CPX_VERSION >= 800
799
    switch (stat) {
800
    case CPX_STAT_OPTIMAL:
801
      return OPTIMAL;
802
    case CPX_STAT_UNBOUNDED:
803
      return INFEASIBLE;
804
    default:
805
      return UNDEFINED;
806
    }
807
#else
808
    statusSwitch(cplexEnv(),stat);
809
    switch (stat) {
810
    case 0:
811
      return UNDEFINED; //Undefined
812
    case CPX_OPTIMAL://Optimal
813
      return OPTIMAL;
814
    case CPX_UNBOUNDED:
815
      return INFEASIBLE;
816
    default:
817
      return UNDEFINED; //Everything else comes here
818
      //FIXME error
819
    }
820
#endif
821
  }
822

	
823
  // CplexMip members
824

	
825
  CplexMip::CplexMip()
826
    : LpBase(), MipSolver(), CplexBase() {
827

	
828
#if CPX_VERSION < 800
829
    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
830
#else
831
    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
832
#endif
833
  }
834

	
835
  CplexMip::CplexMip(const CplexEnv& env)
836
    : LpBase(), MipSolver(), CplexBase(env) {
837

	
838
#if CPX_VERSION < 800
839
    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
840
#else
841
    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
842
#endif
843

	
844
  }
845

	
846
  CplexMip::CplexMip(const CplexMip& other)
847
    : LpBase(), MipSolver(), CplexBase(other) {}
848

	
849
  CplexMip::~CplexMip() {}
850

	
851
  CplexMip* CplexMip::newSolver() const { return new CplexMip; }
852
  CplexMip* CplexMip::cloneSolver() const {return new CplexMip(*this); }
853

	
854
  const char* CplexMip::_solverName() const { return "CplexMip"; }
855

	
856
  void CplexMip::_setColType(int i, CplexMip::ColTypes col_type) {
857

	
858
    // Note If a variable is to be changed to binary, a call to CPXchgbds
859
    // should also be made to change the bounds to 0 and 1.
860

	
861
    switch (col_type){
862
    case INTEGER: {
863
      const char t = 'I';
864
      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
865
    } break;
866
    case REAL: {
867
      const char t = 'C';
868
      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
869
    } break;
870
    default:
871
      break;
872
    }
873
  }
874

	
875
  CplexMip::ColTypes CplexMip::_getColType(int i) const {
876
    char t;
877
    CPXgetctype (cplexEnv(), _prob, &t, i, i);
878
    switch (t) {
879
    case 'I':
880
      return INTEGER;
881
    case 'C':
882
      return REAL;
883
    default:
884
      LEMON_ASSERT(false, "Invalid column type");
885
      return ColTypes();
886
    }
887

	
888
  }
889

	
890
  CplexMip::SolveExitStatus CplexMip::_solve() {
891
    int status;
892
    _applyMessageLevel();
893
    status = CPXmipopt (cplexEnv(), _prob);
894
    if (status==0)
895
      return SOLVED;
896
    else
897
      return UNSOLVED;
898

	
899
  }
900

	
901

	
902
  CplexMip::ProblemType CplexMip::_getType() const {
903

	
904
    int stat = CPXgetstat(cplexEnv(), _prob);
905

	
906
    //Fortunately, MIP statuses did not change for cplex 8.0
907
    switch (stat) {
908
    case CPXMIP_OPTIMAL:
909
      // Optimal integer solution has been found.
910
    case CPXMIP_OPTIMAL_TOL:
911
      // Optimal soluton with the tolerance defined by epgap or epagap has
912
      // been found.
913
      return OPTIMAL;
914
      //This also exists in later issues
915
      //    case CPXMIP_UNBOUNDED:
916
      //return UNBOUNDED;
917
      case CPXMIP_INFEASIBLE:
918
        return INFEASIBLE;
919
    default:
920
      return UNDEFINED;
921
    }
922
    //Unboundedness not treated well: the following is from cplex 9.0 doc
923
    // About Unboundedness
924

	
925
    // The treatment of models that are unbounded involves a few
926
    // subtleties. Specifically, a declaration of unboundedness means that
927
    // ILOG CPLEX has determined that the model has an unbounded
928
    // ray. Given any feasible solution x with objective z, a multiple of
929
    // the unbounded ray can be added to x to give a feasible solution
930
    // with objective z-1 (or z+1 for maximization models). Thus, if a
931
    // feasible solution exists, then the optimal objective is
932
    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
933
    // a feasible solution exists. Users can call the routine CPXsolninfo
934
    // to determine whether ILOG CPLEX has also concluded that the model
935
    // has a feasible solution.
936
  }
937

	
938
  CplexMip::Value CplexMip::_getSol(int i) const {
939
    Value x;
940
    CPXgetmipx(cplexEnv(), _prob, &x, i, i);
941
    return x;
942
  }
943

	
944
  CplexMip::Value CplexMip::_getSolValue() const {
945
    Value objval;
946
    CPXgetmipobjval(cplexEnv(), _prob, &objval);
947
    return objval;
948
  }
949

	
950
} //namespace lemon
951

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

	
19
#ifndef LEMON_CPLEX_H
20
#define LEMON_CPLEX_H
21

	
22
///\file
23
///\brief Header of the LEMON-CPLEX lp solver interface.
24

	
25
#include <lemon/lp_base.h>
26

	
27
struct cpxenv;
28
struct cpxlp;
29

	
30
namespace lemon {
31

	
32
  /// \brief Reference counted wrapper around cpxenv pointer
33
  ///
34
  /// The cplex uses environment object which is responsible for
35
  /// checking the proper license usage. This class provides a simple
36
  /// interface for share the environment object between different
37
  /// problems.
38
  class CplexEnv {
39
    friend class CplexBase;
40
  private:
41
    cpxenv* _env;
42
    mutable int* _cnt;
43

	
44
  public:
45

	
46
    /// \brief This exception is thrown when the license check is not
47
    /// sufficient
48
    class LicenseError : public Exception {
49
      friend class CplexEnv;
50
    private:
51

	
52
      LicenseError(int status);
53
      char _message[510];
54

	
55
    public:
56

	
57
      /// The short error message
58
      virtual const char* what() const throw() {
59
        return _message;
60
      }
61
    };
62

	
63
    /// Constructor
64
    CplexEnv();
65
    /// Shallow copy constructor
66
    CplexEnv(const CplexEnv&);
67
    /// Shallow assignement
68
    CplexEnv& operator=(const CplexEnv&);
69
    /// Destructor
70
    virtual ~CplexEnv();
71

	
72
  protected:
73

	
74
    cpxenv* cplexEnv() { return _env; }
75
    const cpxenv* cplexEnv() const { return _env; }
76
  };
77

	
78
  /// \brief Base interface for the CPLEX LP and MIP solver
79
  ///
80
  /// This class implements the common interface of the CPLEX LP and
81
  /// MIP solvers.
82
  /// \ingroup lp_group
83
  class CplexBase : virtual public LpBase {
84
  protected:
85

	
86
    CplexEnv _env;
87
    cpxlp* _prob;
88

	
89
    CplexBase();
90
    CplexBase(const CplexEnv&);
91
    CplexBase(const CplexBase &);
92
    virtual ~CplexBase();
93

	
94
    virtual int _addCol();
95
    virtual int _addRow();
96

	
97
    virtual void _eraseCol(int i);
98
    virtual void _eraseRow(int i);
99

	
100
    virtual void _eraseColId(int i);
101
    virtual void _eraseRowId(int i);
102

	
103
    virtual void _getColName(int col, std::string& name) const;
104
    virtual void _setColName(int col, const std::string& name);
105
    virtual int _colByName(const std::string& name) const;
106

	
107
    virtual void _getRowName(int row, std::string& name) const;
108
    virtual void _setRowName(int row, const std::string& name);
109
    virtual int _rowByName(const std::string& name) const;
110

	
111
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
112
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
113

	
114
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
115
    virtual void _getColCoeffs(int i, InsertIterator b) const;
116

	
117
    virtual void _setCoeff(int row, int col, Value value);
118
    virtual Value _getCoeff(int row, int col) const;
119

	
120
    virtual void _setColLowerBound(int i, Value value);
121
    virtual Value _getColLowerBound(int i) const;
122

	
123
    virtual void _setColUpperBound(int i, Value value);
124
    virtual Value _getColUpperBound(int i) const;
125

	
126
  private:
127
    void _set_row_bounds(int i, Value lb, Value ub);
128
  protected:
129

	
130
    virtual void _setRowLowerBound(int i, Value value);
131
    virtual Value _getRowLowerBound(int i) const;
132

	
133
    virtual void _setRowUpperBound(int i, Value value);
134
    virtual Value _getRowUpperBound(int i) const;
135

	
136
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
137
    virtual void _getObjCoeffs(InsertIterator b) const;
138

	
139
    virtual void _setObjCoeff(int i, Value obj_coef);
140
    virtual Value _getObjCoeff(int i) const;
141

	
142
    virtual void _setSense(Sense sense);
143
    virtual Sense _getSense() const;
144

	
145
    virtual void _clear();
146

	
147
    virtual void _messageLevel(MessageLevel level);
148
    void _applyMessageLevel();
149

	
150
    bool _message_enabled;
151

	
152
  public:
153

	
154
    /// Returns the used \c CplexEnv instance
155
    const CplexEnv& env() const { return _env; }
156

	
157
    /// \brief Returns the const cpxenv pointer
158
    ///
159
    /// \note The cpxenv might be destructed with the solver.
160
    const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
161

	
162
    /// \brief Returns the const cpxenv pointer
163
    ///
164
    /// \note The cpxenv might be destructed with the solver.
165
    cpxenv* cplexEnv() { return _env.cplexEnv(); }
166

	
167
    /// Returns the cplex problem object
168
    cpxlp* cplexLp() { return _prob; }
169
    /// Returns the cplex problem object
170
    const cpxlp* cplexLp() const { return _prob; }
171

	
172
  };
173

	
174
  /// \brief Interface for the CPLEX LP solver
175
  ///
176
  /// This class implements an interface for the CPLEX LP solver.
177
  ///\ingroup lp_group
178
  class CplexLp : public LpSolver, public CplexBase {
179
  public:
180
    /// \e
181
    CplexLp();
182
    /// \e
183
    CplexLp(const CplexEnv&);
184
    /// \e
185
    CplexLp(const CplexLp&);
186
    /// \e
187
    virtual ~CplexLp();
188

	
189
    /// \e
190
    virtual CplexLp* cloneSolver() const;
191
    /// \e
192
    virtual CplexLp* newSolver() const;
193

	
194
  private:
195

	
196
    // these values cannot retrieved element by element
197
    mutable std::vector<int> _col_status;
198
    mutable std::vector<int> _row_status;
199

	
200
    mutable std::vector<Value> _primal_ray;
201
    mutable std::vector<Value> _dual_ray;
202

	
203
    void _clear_temporals();
204

	
205
    SolveExitStatus convertStatus(int status);
206

	
207
  protected:
208

	
209
    virtual const char* _solverName() const;
210

	
211
    virtual SolveExitStatus _solve();
212
    virtual Value _getPrimal(int i) const;
213
    virtual Value _getDual(int i) const;
214
    virtual Value _getPrimalValue() const;
215

	
216
    virtual VarStatus _getColStatus(int i) const;
217
    virtual VarStatus _getRowStatus(int i) const;
218

	
219
    virtual Value _getPrimalRay(int i) const;
220
    virtual Value _getDualRay(int i) const;
221

	
222
    virtual ProblemType _getPrimalType() const;
223
    virtual ProblemType _getDualType() const;
224

	
225
  public:
226

	
227
    /// Solve with primal simplex method
228
    SolveExitStatus solvePrimal();
229

	
230
    /// Solve with dual simplex method
231
    SolveExitStatus solveDual();
232

	
233
    /// Solve with barrier method
234
    SolveExitStatus solveBarrier();
235

	
236
  };
237

	
238
  /// \brief Interface for the CPLEX MIP solver
239
  ///
240
  /// This class implements an interface for the CPLEX MIP solver.
241
  ///\ingroup lp_group
242
  class CplexMip : public MipSolver, public CplexBase {
243
  public:
244
    /// \e
245
    CplexMip();
246
    /// \e
247
    CplexMip(const CplexEnv&);
248
    /// \e
249
    CplexMip(const CplexMip&);
250
    /// \e
251
    virtual ~CplexMip();
252

	
253
    /// \e
254
    virtual CplexMip* cloneSolver() const;
255
    /// \e
256
    virtual CplexMip* newSolver() const;
257

	
258
  protected:
259

	
260

	
261
    virtual const char* _solverName() const;
262

	
263
    virtual ColTypes _getColType(int col) const;
264
    virtual void _setColType(int col, ColTypes col_type);
265

	
266
    virtual SolveExitStatus _solve();
267
    virtual ProblemType _getType() const;
268
    virtual Value _getSol(int i) const;
269
    virtual Value _getSolValue() const;
270

	
271
  };
272

	
273
} //END OF NAMESPACE LEMON
274

	
275
#endif //LEMON_CPLEX_H
276

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

	
19
#ifndef LEMON_DIMACS_H
20
#define LEMON_DIMACS_H
21

	
22
#include <iostream>
23
#include <string>
24
#include <vector>
25
#include <limits>
26
#include <lemon/maps.h>
27
#include <lemon/error.h>
28
/// \ingroup dimacs_group
29
/// \file
30
/// \brief DIMACS file format reader.
31

	
32
namespace lemon {
33

	
34
  /// \addtogroup dimacs_group
35
  /// @{
36

	
37
  /// DIMACS file type descriptor.
38
  struct DimacsDescriptor
39
  {
40
    ///\brief DIMACS file type enum
41
    ///
42
    ///DIMACS file type enum.
43
    enum Type {
44
      NONE,  ///< Undefined type.
45
      MIN,   ///< DIMACS file type for minimum cost flow problems.
46
      MAX,   ///< DIMACS file type for maximum flow problems.
47
      SP,    ///< DIMACS file type for shostest path problems.
48
      MAT    ///< DIMACS file type for plain graphs and matching problems.
49
    };
50
    ///The file type
51
    Type type;
52
    ///The number of nodes in the graph
53
    int nodeNum;
54
    ///The number of edges in the graph
55
    int edgeNum;
56
    int lineShift;
57
    ///Constructor. It sets the type to \c NONE.
58
    DimacsDescriptor() : type(NONE) {}
59
  };
60

	
61
  ///Discover the type of a DIMACS file
62

	
63
  ///This function starts seeking the beginning of the given file for the
64
  ///problem type and size info. 
65
  ///The found data is returned in a special struct that can be evaluated
66
  ///and passed to the appropriate reader function.
67
  DimacsDescriptor dimacsType(std::istream& is)
68
  {
69
    DimacsDescriptor r;
70
    std::string problem,str;
71
    char c;
72
    r.lineShift=0;
73
    while (is >> c)
74
      switch(c)
75
        {
76
        case 'p':
77
          if(is >> problem >> r.nodeNum >> r.edgeNum)
78
            {
79
              getline(is, str);
80
              r.lineShift++;
81
              if(problem=="min") r.type=DimacsDescriptor::MIN;
82
              else if(problem=="max") r.type=DimacsDescriptor::MAX;
83
              else if(problem=="sp") r.type=DimacsDescriptor::SP;
84
              else if(problem=="mat") r.type=DimacsDescriptor::MAT;
85
              else throw FormatError("Unknown problem type");
86
              return r;
87
            }
88
          else
89
            {
90
              throw FormatError("Missing or wrong problem type declaration.");
91
            }
92
          break;
93
        case 'c':
94
          getline(is, str);
95
          r.lineShift++;
96
          break;
97
        default:
98
          throw FormatError("Unknown DIMACS declaration.");
99
        }
100
    throw FormatError("Missing problem type declaration.");
101
  }
102

	
103

	
104
  /// \brief DIMACS minimum cost flow reader function.
105
  ///
106
  /// This function reads a minimum cost flow instance from DIMACS format,
107
  /// i.e. from a DIMACS file having a line starting with
108
  /// \code
109
  ///   p min
110
  /// \endcode
111
  /// At the beginning, \c g is cleared by \c g.clear(). The supply
112
  /// amount of the nodes are written to the \c supply node map
113
  /// (they are signed values). The lower bounds, capacities and costs
114
  /// of the arcs are written to the \c lower, \c capacity and \c cost
115
  /// arc maps.
116
  ///
117
  /// If the capacity of an arc is less than the lower bound, it will
118
  /// be set to "infinite" instead. The actual value of "infinite" is
119
  /// contolled by the \c infty parameter. If it is 0 (the default value),
120
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
121
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
122
  /// a non-zero value, that value will be used as "infinite".
123
  ///
124
  /// If the file type was previously evaluated by dimacsType(), then
125
  /// the descriptor struct should be given by the \c dest parameter.
126
  template <typename Digraph, typename LowerMap,
127
            typename CapacityMap, typename CostMap,
128
            typename SupplyMap>
129
  void readDimacsMin(std::istream& is,
130
                     Digraph &g,
131
                     LowerMap& lower,
132
                     CapacityMap& capacity,
133
                     CostMap& cost,
134
                     SupplyMap& supply,
135
                     typename CapacityMap::Value infty = 0,
136
                     DimacsDescriptor desc=DimacsDescriptor())
137
  {
138
    g.clear();
139
    std::vector<typename Digraph::Node> nodes;
140
    typename Digraph::Arc e;
141
    std::string problem, str;
142
    char c;
143
    int i, j;
144
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
145
    if(desc.type!=DimacsDescriptor::MIN)
146
      throw FormatError("Problem type mismatch");
147

	
148
    nodes.resize(desc.nodeNum + 1);
149
    for (int k = 1; k <= desc.nodeNum; ++k) {
150
      nodes[k] = g.addNode();
151
      supply.set(nodes[k], 0);
152
    }
153

	
154
    typename SupplyMap::Value sup;
155
    typename CapacityMap::Value low;
156
    typename CapacityMap::Value cap;
157
    typename CostMap::Value co;
158
    typedef typename CapacityMap::Value Capacity;
159
    if(infty==0)
160
      infty = std::numeric_limits<Capacity>::has_infinity ?
161
        std::numeric_limits<Capacity>::infinity() :
162
        std::numeric_limits<Capacity>::max();
163

	
164
    while (is >> c) {
165
      switch (c) {
166
      case 'c': // comment line
167
        getline(is, str);
168
        break;
169
      case 'n': // node definition line
170
        is >> i >> sup;
171
        getline(is, str);
172
        supply.set(nodes[i], sup);
173
        break;
174
      case 'a': // arc definition line
175
        is >> i >> j >> low >> cap >> co;
176
        getline(is, str);
177
        e = g.addArc(nodes[i], nodes[j]);
178
        lower.set(e, low);
179
        if (cap >= low)
180
          capacity.set(e, cap);
181
        else
182
          capacity.set(e, infty);
183
        cost.set(e, co);
184
        break;
185
      }
186
    }
187
  }
188

	
189
  template<typename Digraph, typename CapacityMap>
190
  void _readDimacs(std::istream& is,
191
                   Digraph &g,
192
                   CapacityMap& capacity,
193
                   typename Digraph::Node &s,
194
                   typename Digraph::Node &t,
195
                   typename CapacityMap::Value infty = 0,
196
                   DimacsDescriptor desc=DimacsDescriptor()) {
197
    g.clear();
198
    s=t=INVALID;
199
    std::vector<typename Digraph::Node> nodes;
200
    typename Digraph::Arc e;
201
    char c, d;
202
    int i, j;
203
    typename CapacityMap::Value _cap;
204
    std::string str;
205
    nodes.resize(desc.nodeNum + 1);
206
    for (int k = 1; k <= desc.nodeNum; ++k) {
207
      nodes[k] = g.addNode();
208
    }
209
    typedef typename CapacityMap::Value Capacity;
210

	
211
    if(infty==0)
212
      infty = std::numeric_limits<Capacity>::has_infinity ?
213
        std::numeric_limits<Capacity>::infinity() :
214
        std::numeric_limits<Capacity>::max();
215
 
216
    while (is >> c) {
217
      switch (c) {
218
      case 'c': // comment line
219
        getline(is, str);
220
        break;
221
      case 'n': // node definition line
222
        if (desc.type==DimacsDescriptor::SP) { // shortest path problem
223
          is >> i;
224
          getline(is, str);
225
          s = nodes[i];
226
        }
227
        if (desc.type==DimacsDescriptor::MAX) { // max flow problem
228
          is >> i >> d;
229
          getline(is, str);
230
          if (d == 's') s = nodes[i];
231
          if (d == 't') t = nodes[i];
232
        }
233
        break;
234
      case 'a': // arc definition line
235
        if (desc.type==DimacsDescriptor::SP) {
236
          is >> i >> j >> _cap;
237
          getline(is, str);
238
          e = g.addArc(nodes[i], nodes[j]);
239
          capacity.set(e, _cap);
240
        } 
241
        else if (desc.type==DimacsDescriptor::MAX) {
242
          is >> i >> j >> _cap;
243
          getline(is, str);
244
          e = g.addArc(nodes[i], nodes[j]);
245
          if (_cap >= 0)
246
            capacity.set(e, _cap);
247
          else
248
            capacity.set(e, infty);
249
        }
250
        else {
251
          is >> i >> j;
252
          getline(is, str);
253
          g.addArc(nodes[i], nodes[j]);
254
        }
255
        break;
256
      }
257
    }
258
  }
259

	
260
  /// \brief DIMACS maximum flow reader function.
261
  ///
262
  /// This function reads a maximum flow instance from DIMACS format,
263
  /// i.e. from a DIMACS file having a line starting with
264
  /// \code
265
  ///   p max
266
  /// \endcode
267
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
268
  /// capacities are written to the \c capacity arc map and \c s and
269
  /// \c t are set to the source and the target nodes.
270
  ///
271
  /// If the capacity of an arc is negative, it will
272
  /// be set to "infinite" instead. The actual value of "infinite" is
273
  /// contolled by the \c infty parameter. If it is 0 (the default value),
274
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
275
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
276
  /// a non-zero value, that value will be used as "infinite".
277
  ///
278
  /// If the file type was previously evaluated by dimacsType(), then
279
  /// the descriptor struct should be given by the \c dest parameter.
280
  template<typename Digraph, typename CapacityMap>
281
  void readDimacsMax(std::istream& is,
282
                     Digraph &g,
283
                     CapacityMap& capacity,
284
                     typename Digraph::Node &s,
285
                     typename Digraph::Node &t,
286
                     typename CapacityMap::Value infty = 0,
287
                     DimacsDescriptor desc=DimacsDescriptor()) {
288
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
289
    if(desc.type!=DimacsDescriptor::MAX)
290
      throw FormatError("Problem type mismatch");
291
    _readDimacs(is,g,capacity,s,t,infty,desc);
292
  }
293

	
294
  /// \brief DIMACS shortest path reader function.
295
  ///
296
  /// This function reads a shortest path instance from DIMACS format,
297
  /// i.e. from a DIMACS file having a line starting with
298
  /// \code
299
  ///   p sp
300
  /// \endcode
301
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
302
  /// lengths are written to the \c length arc map and \c s is set to the
303
  /// source node.
304
  ///
305
  /// If the file type was previously evaluated by dimacsType(), then
306
  /// the descriptor struct should be given by the \c dest parameter.
307
  template<typename Digraph, typename LengthMap>
308
  void readDimacsSp(std::istream& is,
309
                    Digraph &g,
310
                    LengthMap& length,
311
                    typename Digraph::Node &s,
312
                    DimacsDescriptor desc=DimacsDescriptor()) {
313
    typename Digraph::Node t;
314
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
315
    if(desc.type!=DimacsDescriptor::SP)
316
      throw FormatError("Problem type mismatch");
317
    _readDimacs(is, g, length, s, t, 0, desc);
318
  }
319

	
320
  /// \brief DIMACS capacitated digraph reader function.
321
  ///
322
  /// This function reads an arc capacitated digraph instance from
323
  /// DIMACS 'max' or 'sp' format.
324
  /// At the beginning, \c g is cleared by \c g.clear()
325
  /// and the arc capacities/lengths are written to the \c capacity
326
  /// arc map.
327
  ///
328
  /// In case of the 'max' format, if the capacity of an arc is negative,
329
  /// it will
330
  /// be set to "infinite" instead. The actual value of "infinite" is
331
  /// contolled by the \c infty parameter. If it is 0 (the default value),
332
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
333
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
334
  /// a non-zero value, that value will be used as "infinite".
335
  ///
336
  /// If the file type was previously evaluated by dimacsType(), then
337
  /// the descriptor struct should be given by the \c dest parameter.
338
  template<typename Digraph, typename CapacityMap>
339
  void readDimacsCap(std::istream& is,
340
                     Digraph &g,
341
                     CapacityMap& capacity,
342
                     typename CapacityMap::Value infty = 0,
343
                     DimacsDescriptor desc=DimacsDescriptor()) {
344
    typename Digraph::Node u,v;
345
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
346
    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
347
      throw FormatError("Problem type mismatch");
348
    _readDimacs(is, g, capacity, u, v, infty, desc);
349
  }
350

	
351
  template<typename Graph>
352
  typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
353
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
354
              dummy<0> = 0)
355
  {
356
    g.addEdge(s,t);
357
  }
358
  template<typename Graph>
359
  typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
360
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
361
              dummy<1> = 1)
362
  {
363
    g.addArc(s,t);
364
  }
365
  
366
  /// \brief DIMACS plain (di)graph reader function.
367
  ///
368
  /// This function reads a plain (di)graph without any designated nodes
369
  /// and maps (e.g. a matching instance) from DIMACS format, i.e. from 
370
  /// DIMACS files having a line starting with
371
  /// \code
372
  ///   p mat
373
  /// \endcode
374
  /// At the beginning, \c g is cleared by \c g.clear().
375
  ///
376
  /// If the file type was previously evaluated by dimacsType(), then
377
  /// the descriptor struct should be given by the \c dest parameter.
378
  template<typename Graph>
379
  void readDimacsMat(std::istream& is, Graph &g,
380
                     DimacsDescriptor desc=DimacsDescriptor())
381
  {
382
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
383
    if(desc.type!=DimacsDescriptor::MAT)
384
      throw FormatError("Problem type mismatch");
385

	
386
    g.clear();
387
    std::vector<typename Graph::Node> nodes;
388
    char c;
389
    int i, j;
390
    std::string str;
391
    nodes.resize(desc.nodeNum + 1);
392
    for (int k = 1; k <= desc.nodeNum; ++k) {
393
      nodes[k] = g.addNode();
394
    }
395
    
396
    while (is >> c) {
397
      switch (c) {
398
      case 'c': // comment line
399
        getline(is, str);
400
        break;
401
      case 'n': // node definition line
402
        break;
403
      case 'a': // arc definition line
404
        is >> i >> j;
405
        getline(is, str);
406
        _addArcEdge(g,nodes[i], nodes[j]);
407
        break;
408
      }
409
    }
410
  }
411

	
412
  /// DIMACS plain digraph writer function.
413
  ///
414
  /// This function writes a digraph without any designated nodes and
415
  /// maps into DIMACS format, i.e. into DIMACS file having a line
416
  /// starting with
417
  /// \code
418
  ///   p mat
419
  /// \endcode
420
  /// If \c comment is not empty, then it will be printed in the first line
421
  /// prefixed by 'c'.
422
  template<typename Digraph>
423
  void writeDimacsMat(std::ostream& os, const Digraph &g,
424
                      std::string comment="") {
425
    typedef typename Digraph::NodeIt NodeIt;
426
    typedef typename Digraph::ArcIt ArcIt;
427

	
428
    if(!comment.empty())
429
      os << "c " << comment << std::endl;
430
    os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
431

	
432
    typename Digraph::template NodeMap<int> nodes(g);
433
    int i = 1;
434
    for(NodeIt v(g); v != INVALID; ++v) {
435
      nodes.set(v, i);
436
      ++i;
437
    }
438
    for(ArcIt e(g); e != INVALID; ++e) {
439
      os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
440
         << std::endl;
441
    }
442
  }
443

	
444
  /// @}
445

	
446
} //namespace lemon
447

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

	
19
#ifndef LEMON_EDGE_SET_H
20
#define LEMON_EDGE_SET_H
21

	
22
#include <lemon/core.h>
23
#include <lemon/bits/edge_set_extender.h>
24

	
25
/// \ingroup graphs
26
/// \file
27
/// \brief ArcSet and EdgeSet classes.
28
///
29
/// Graphs which use another graph's node-set as own.
30
namespace lemon {
31

	
32
  template <typename GR>
33
  class ListArcSetBase {
34
  public:
35

	
36
    typedef typename GR::Node Node;
37
    typedef typename GR::NodeIt NodeIt;
38

	
39
  protected:
40

	
41
    struct NodeT {
42
      int first_out, first_in;
43
      NodeT() : first_out(-1), first_in(-1) {}
44
    };
45

	
46
    typedef typename ItemSetTraits<GR, Node>::
47
    template Map<NodeT>::Type NodesImplBase;
48

	
49
    NodesImplBase* _nodes;
50

	
51
    struct ArcT {
52
      Node source, target;
53
      int next_out, next_in;
54
      int prev_out, prev_in;
55
      ArcT() : prev_out(-1), prev_in(-1) {}
56
    };
57

	
58
    std::vector<ArcT> arcs;
59

	
60
    int first_arc;
61
    int first_free_arc;
62

	
63
    const GR* _graph;
64

	
65
    void initalize(const GR& graph, NodesImplBase& nodes) {
66
      _graph = &graph;
67
      _nodes = &nodes;
68
    }
69

	
70
  public:
71

	
72
    class Arc {
73
      friend class ListArcSetBase<GR>;
74
    protected:
75
      Arc(int _id) : id(_id) {}
76
      int id;
77
    public:
78
      Arc() {}
79
      Arc(Invalid) : id(-1) {}
80
      bool operator==(const Arc& arc) const { return id == arc.id; }
81
      bool operator!=(const Arc& arc) const { return id != arc.id; }
82
      bool operator<(const Arc& arc) const { return id < arc.id; }
83
    };
84

	
85
    ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
86

	
87
    Node addNode() {
88
      LEMON_ASSERT(false,
89
        "This graph structure does not support node insertion");
90
      return INVALID; // avoid warning
91
    }
92

	
93
    Arc addArc(const Node& u, const Node& v) {
94
      int n;
95
      if (first_free_arc == -1) {
96
        n = arcs.size();
97
        arcs.push_back(ArcT());
98
      } else {
99
        n = first_free_arc;
100
        first_free_arc = arcs[first_free_arc].next_in;
101
      }
102
      arcs[n].next_in = (*_nodes)[v].first_in;
103
      if ((*_nodes)[v].first_in != -1) {
104
        arcs[(*_nodes)[v].first_in].prev_in = n;
105
      }
106
      (*_nodes)[v].first_in = n;
107
      arcs[n].next_out = (*_nodes)[u].first_out;
108
      if ((*_nodes)[u].first_out != -1) {
109
        arcs[(*_nodes)[u].first_out].prev_out = n;
110
      }
111
      (*_nodes)[u].first_out = n;
112
      arcs[n].source = u;
113
      arcs[n].target = v;
114
      return Arc(n);
115
    }
116

	
117
    void erase(const Arc& arc) {
118
      int n = arc.id;
119
      if (arcs[n].prev_in != -1) {
120
        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
121
      } else {
122
        (*_nodes)[arcs[n].target].first_in = arcs[n].next_in;
123
      }
124
      if (arcs[n].next_in != -1) {
125
        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
126
      }
127

	
128
      if (arcs[n].prev_out != -1) {
129
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
130
      } else {
131
        (*_nodes)[arcs[n].source].first_out = arcs[n].next_out;
132
      }
133
      if (arcs[n].next_out != -1) {
134
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
135
      }
136

	
137
    }
138

	
139
    void clear() {
140
      Node node;
141
      for (first(node); node != INVALID; next(node)) {
142
        (*_nodes)[node].first_in = -1;
143
        (*_nodes)[node].first_out = -1;
144
      }
145
      arcs.clear();
146
      first_arc = -1;
147
      first_free_arc = -1;
148
    }
149

	
150
    void first(Node& node) const {
151
      _graph->first(node);
152
    }
153

	
154
    void next(Node& node) const {
155
      _graph->next(node);
156
    }
157

	
158
    void first(Arc& arc) const {
159
      Node node;
160
      first(node);
161
      while (node != INVALID && (*_nodes)[node].first_in == -1) {
162
        next(node);
163
      }
164
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
165
    }
166

	
167
    void next(Arc& arc) const {
168
      if (arcs[arc.id].next_in != -1) {
169
        arc.id = arcs[arc.id].next_in;
170
      } else {
171
        Node node = arcs[arc.id].target;
172
        next(node);
173
        while (node != INVALID && (*_nodes)[node].first_in == -1) {
174
          next(node);
175
        }
176
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
177
      }
178
    }
179

	
180
    void firstOut(Arc& arc, const Node& node) const {
181
      arc.id = (*_nodes)[node].first_out;
182
    }
183

	
184
    void nextOut(Arc& arc) const {
185
      arc.id = arcs[arc.id].next_out;
186
    }
187

	
188
    void firstIn(Arc& arc, const Node& node) const {
189
      arc.id = (*_nodes)[node].first_in;
190
    }
191

	
192
    void nextIn(Arc& arc) const {
193
      arc.id = arcs[arc.id].next_in;
194
    }
195

	
196
    int id(const Node& node) const { return _graph->id(node); }
197
    int id(const Arc& arc) const { return arc.id; }
198

	
199
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
200
    Arc arcFromId(int ix) const { return Arc(ix); }
201

	
202
    int maxNodeId() const { return _graph->maxNodeId(); };
203
    int maxArcId() const { return arcs.size() - 1; }
204

	
205
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
206
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
207

	
208
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
209

	
210
    NodeNotifier& notifier(Node) const {
211
      return _graph->notifier(Node());
212
    }
213

	
214
    template <typename V>
215
    class NodeMap : public GR::template NodeMap<V> {
216
      typedef typename GR::template NodeMap<V> Parent;
217

	
218
    public:
219

	
220
      explicit NodeMap(const ListArcSetBase<GR>& arcset)
221
        : Parent(*arcset._graph) {}
222

	
223
      NodeMap(const ListArcSetBase<GR>& arcset, const V& value)
224
        : Parent(*arcset._graph, value) {}
225

	
226
      NodeMap& operator=(const NodeMap& cmap) {
227
        return operator=<NodeMap>(cmap);
228
      }
229

	
230
      template <typename CMap>
231
      NodeMap& operator=(const CMap& cmap) {
232
        Parent::operator=(cmap);
233
        return *this;
234
      }
235
    };
236

	
237
  };
238

	
239
  /// \ingroup graphs
240
  ///
241
  /// \brief Digraph using a node set of another digraph or graph and
242
  /// an own arc set.
243
  ///
244
  /// This structure can be used to establish another directed graph
245
  /// over a node set of an existing one. This class uses the same
246
  /// Node type as the underlying graph, and each valid node of the
247
  /// original graph is valid in this arc set, therefore the node
248
  /// objects of the original graph can be used directly with this
249
  /// class. The node handling functions (id handling, observing, and
250
  /// iterators) works equivalently as in the original graph.
251
  ///
252
  /// This implementation is based on doubly-linked lists, from each
253
  /// node the outgoing and the incoming arcs make up lists, therefore
254
  /// one arc can be erased in constant time. It also makes possible,
255
  /// that node can be removed from the underlying graph, in this case
256
  /// all arcs incident to the given node is erased from the arc set.
257
  ///
258
  /// \param GR The type of the graph which shares its node set with
259
  /// this class. Its interface must conform to the
260
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
261
  /// concept.
262
  ///
263
  /// This class fully conforms to the \ref concepts::Digraph
264
  /// "Digraph" concept.
265
  template <typename GR>
266
  class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
267
    typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
268

	
269
  public:
270

	
271
    typedef typename Parent::Node Node;
272
    typedef typename Parent::Arc Arc;
273

	
274
    typedef typename Parent::NodesImplBase NodesImplBase;
275

	
276
    void eraseNode(const Node& node) {
277
      Arc arc;
278
      Parent::firstOut(arc, node);
279
      while (arc != INVALID ) {
280
        erase(arc);
281
        Parent::firstOut(arc, node);
282
      }
283

	
284
      Parent::firstIn(arc, node);
285
      while (arc != INVALID ) {
286
        erase(arc);
287
        Parent::firstIn(arc, node);
288
      }
289
    }
290

	
291
    void clearNodes() {
292
      Parent::clear();
293
    }
294

	
295
    class NodesImpl : public NodesImplBase {
296
      typedef NodesImplBase Parent;
297

	
298
    public:
299
      NodesImpl(const GR& graph, ListArcSet& arcset)
300
        : Parent(graph), _arcset(arcset) {}
301

	
302
      virtual ~NodesImpl() {}
303

	
304
    protected:
305

	
306
      virtual void erase(const Node& node) {
307
        _arcset.eraseNode(node);
308
        Parent::erase(node);
309
      }
310
      virtual void erase(const std::vector<Node>& nodes) {
311
        for (int i = 0; i < int(nodes.size()); ++i) {
312
          _arcset.eraseNode(nodes[i]);
313
        }
314
        Parent::erase(nodes);
315
      }
316
      virtual void clear() {
317
        _arcset.clearNodes();
318
        Parent::clear();
319
      }
320

	
321
    private:
322
      ListArcSet& _arcset;
323
    };
324

	
325
    NodesImpl _nodes;
326

	
327
  public:
328

	
329
    /// \brief Constructor of the ArcSet.
330
    ///
331
    /// Constructor of the ArcSet.
332
    ListArcSet(const GR& graph) : _nodes(graph, *this) {
333
      Parent::initalize(graph, _nodes);
334
    }
335

	
336
    /// \brief Add a new arc to the digraph.
337
    ///
338
    /// Add a new arc to the digraph with source node \c s
339
    /// and target node \c t.
340
    /// \return The new arc.
341
    Arc addArc(const Node& s, const Node& t) {
342
      return Parent::addArc(s, t);
343
    }
344

	
345
    /// \brief Erase an arc from the digraph.
346
    ///
347
    /// Erase an arc \c a from the digraph.
348
    void erase(const Arc& a) {
349
      return Parent::erase(a);
350
    }
351

	
352
  };
353

	
354
  template <typename GR>
355
  class ListEdgeSetBase {
356
  public:
357

	
358
    typedef typename GR::Node Node;
359
    typedef typename GR::NodeIt NodeIt;
360

	
361
  protected:
362

	
363
    struct NodeT {
364
      int first_out;
365
      NodeT() : first_out(-1) {}
366
    };
367

	
368
    typedef typename ItemSetTraits<GR, Node>::
369
    template Map<NodeT>::Type NodesImplBase;
370

	
371
    NodesImplBase* _nodes;
372

	
373
    struct ArcT {
374
      Node target;
375
      int prev_out, next_out;
376
      ArcT() : prev_out(-1), next_out(-1) {}
377
    };
378

	
379
    std::vector<ArcT> arcs;
380

	
381
    int first_arc;
382
    int first_free_arc;
383

	
384
    const GR* _graph;
385

	
386
    void initalize(const GR& graph, NodesImplBase& nodes) {
387
      _graph = &graph;
388
      _nodes = &nodes;
389
    }
390

	
391
  public:
392

	
393
    class Edge {
394
      friend class ListEdgeSetBase;
395
    protected:
396

	
397
      int id;
398
      explicit Edge(int _id) { id = _id;}
399

	
400
    public:
401
      Edge() {}
402
      Edge (Invalid) { id = -1; }
403
      bool operator==(const Edge& arc) const {return id == arc.id;}
404
      bool operator!=(const Edge& arc) const {return id != arc.id;}
405
      bool operator<(const Edge& arc) const {return id < arc.id;}
406
    };
407

	
408
    class Arc {
409
      friend class ListEdgeSetBase;
410
    protected:
411
      Arc(int _id) : id(_id) {}
412
      int id;
413
    public:
414
      operator Edge() const { return edgeFromId(id / 2); }
415

	
416
      Arc() {}
417
      Arc(Invalid) : id(-1) {}
418
      bool operator==(const Arc& arc) const { return id == arc.id; }
419
      bool operator!=(const Arc& arc) const { return id != arc.id; }
420
      bool operator<(const Arc& arc) const { return id < arc.id; }
421
    };
422

	
423
    ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
424

	
425
    Node addNode() {
426
      LEMON_ASSERT(false,
427
        "This graph structure does not support node insertion");
428
      return INVALID; // avoid warning
429
    }
430

	
431
    Edge addEdge(const Node& u, const Node& v) {
432
      int n;
433

	
434
      if (first_free_arc == -1) {
435
        n = arcs.size();
436
        arcs.push_back(ArcT());
437
        arcs.push_back(ArcT());
438
      } else {
439
        n = first_free_arc;
440
        first_free_arc = arcs[n].next_out;
441
      }
442

	
443
      arcs[n].target = u;
444
      arcs[n | 1].target = v;
445

	
446
      arcs[n].next_out = (*_nodes)[v].first_out;
447
      if ((*_nodes)[v].first_out != -1) {
448
        arcs[(*_nodes)[v].first_out].prev_out = n;
449
      }
450
      (*_nodes)[v].first_out = n;
451
      arcs[n].prev_out = -1;
452

	
453
      if ((*_nodes)[u].first_out != -1) {
454
        arcs[(*_nodes)[u].first_out].prev_out = (n | 1);
455
      }
456
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
457
      (*_nodes)[u].first_out = (n | 1);
458
      arcs[n | 1].prev_out = -1;
459

	
460
      return Edge(n / 2);
461
    }
462

	
463
    void erase(const Edge& arc) {
464
      int n = arc.id * 2;
465

	
466
      if (arcs[n].next_out != -1) {
467
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
468
      }
469

	
470
      if (arcs[n].prev_out != -1) {
471
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
472
      } else {
473
        (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
474
      }
475

	
476
      if (arcs[n | 1].next_out != -1) {
477
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
478
      }
479

	
480
      if (arcs[n | 1].prev_out != -1) {
481
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
482
      } else {
483
        (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
484
      }
485

	
486
      arcs[n].next_out = first_free_arc;
487
      first_free_arc = n;
488

	
489
    }
490

	
491
    void clear() {
492
      Node node;
493
      for (first(node); node != INVALID; next(node)) {
494
        (*_nodes)[node].first_out = -1;
495
      }
496
      arcs.clear();
497
      first_arc = -1;
498
      first_free_arc = -1;
499
    }
500

	
501
    void first(Node& node) const {
502
      _graph->first(node);
503
    }
504

	
505
    void next(Node& node) const {
506
      _graph->next(node);
507
    }
508

	
509
    void first(Arc& arc) const {
510
      Node node;
511
      first(node);
512
      while (node != INVALID && (*_nodes)[node].first_out == -1) {
513
        next(node);
514
      }
515
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
516
    }
517

	
518
    void next(Arc& arc) const {
519
      if (arcs[arc.id].next_out != -1) {
520
        arc.id = arcs[arc.id].next_out;
521
      } else {
522
        Node node = arcs[arc.id ^ 1].target;
523
        next(node);
524
        while(node != INVALID && (*_nodes)[node].first_out == -1) {
525
          next(node);
526
        }
527
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
528
      }
529
    }
530

	
531
    void first(Edge& edge) const {
532
      Node node;
533
      first(node);
534
      while (node != INVALID) {
535
        edge.id = (*_nodes)[node].first_out;
536
        while ((edge.id & 1) != 1) {
537
          edge.id = arcs[edge.id].next_out;
538
        }
539
        if (edge.id != -1) {
540
          edge.id /= 2;
541
          return;
542
        }
543
        next(node);
544
      }
545
      edge.id = -1;
546
    }
547

	
548
    void next(Edge& edge) const {
549
      Node node = arcs[edge.id * 2].target;
550
      edge.id = arcs[(edge.id * 2) | 1].next_out;
551
      while ((edge.id & 1) != 1) {
552
        edge.id = arcs[edge.id].next_out;
553
      }
554
      if (edge.id != -1) {
555
        edge.id /= 2;
556
        return;
557
      }
558
      next(node);
559
      while (node != INVALID) {
560
        edge.id = (*_nodes)[node].first_out;
561
        while ((edge.id & 1) != 1) {
562
          edge.id = arcs[edge.id].next_out;
563
        }
564
        if (edge.id != -1) {
565
          edge.id /= 2;
566
          return;
567
        }
568
        next(node);
569
      }
570
      edge.id = -1;
571
    }
572

	
573
    void firstOut(Arc& arc, const Node& node) const {
574
      arc.id = (*_nodes)[node].first_out;
575
    }
576

	
577
    void nextOut(Arc& arc) const {
578
      arc.id = arcs[arc.id].next_out;
579
    }
580

	
581
    void firstIn(Arc& arc, const Node& node) const {
582
      arc.id = (((*_nodes)[node].first_out) ^ 1);
583
      if (arc.id == -2) arc.id = -1;
584
    }
585

	
586
    void nextIn(Arc& arc) const {
587
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
588
      if (arc.id == -2) arc.id = -1;
589
    }
590

	
591
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
592
      int de = (*_nodes)[node].first_out;
593
      if (de != -1 ) {
594
        arc.id = de / 2;
595
        dir = ((de & 1) == 1);
596
      } else {
597
        arc.id = -1;
598
        dir = true;
599
      }
600
    }
601
    void nextInc(Edge &arc, bool& dir) const {
602
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
603
      if (de != -1 ) {
604
        arc.id = de / 2;
605
        dir = ((de & 1) == 1);
606
      } else {
607
        arc.id = -1;
608
        dir = true;
609
      }
610
    }
611

	
612
    static bool direction(Arc arc) {
613
      return (arc.id & 1) == 1;
614
    }
615

	
616
    static Arc direct(Edge edge, bool dir) {
617
      return Arc(edge.id * 2 + (dir ? 1 : 0));
618
    }
619

	
620
    int id(const Node& node) const { return _graph->id(node); }
621
    static int id(Arc e) { return e.id; }
622
    static int id(Edge e) { return e.id; }
623

	
624
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
625
    static Arc arcFromId(int id) { return Arc(id);}
626
    static Edge edgeFromId(int id) { return Edge(id);}
627

	
628
    int maxNodeId() const { return _graph->maxNodeId(); };
629
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
630
    int maxArcId() const { return arcs.size()-1; }
631

	
632
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
633
    Node target(Arc e) const { return arcs[e.id].target; }
634

	
635
    Node u(Edge e) const { return arcs[2 * e.id].target; }
636
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
637

	
638
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
639

	
640
    NodeNotifier& notifier(Node) const {
641
      return _graph->notifier(Node());
642
    }
643

	
644
    template <typename V>
645
    class NodeMap : public GR::template NodeMap<V> {
646
      typedef typename GR::template NodeMap<V> Parent;
647

	
648
    public:
649

	
650
      explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
651
        : Parent(*arcset._graph) {}
652

	
653
      NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
654
        : Parent(*arcset._graph, value) {}
655

	
656
      NodeMap& operator=(const NodeMap& cmap) {
657
        return operator=<NodeMap>(cmap);
658
      }
659

	
660
      template <typename CMap>
661
      NodeMap& operator=(const CMap& cmap) {
662
        Parent::operator=(cmap);
663
        return *this;
664
      }
665
    };
666

	
667
  };
668

	
669
  /// \ingroup graphs
670
  ///
671
  /// \brief Graph using a node set of another digraph or graph and an
672
  /// own edge set.
673
  ///
674
  /// This structure can be used to establish another graph over a
675
  /// node set of an existing one. This class uses the same Node type
676
  /// as the underlying graph, and each valid node of the original
677
  /// graph is valid in this arc set, therefore the node objects of
678
  /// the original graph can be used directly with this class. The
679
  /// node handling functions (id handling, observing, and iterators)
680
  /// works equivalently as in the original graph.
681
  ///
682
  /// This implementation is based on doubly-linked lists, from each
683
  /// node the incident edges make up lists, therefore one edge can be
684
  /// erased in constant time. It also makes possible, that node can
685
  /// be removed from the underlying graph, in this case all edges
686
  /// incident to the given node is erased from the arc set.
687
  ///
688
  /// \param GR The type of the graph which shares its node set
689
  /// with this class. Its interface must conform to the
690
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
691
  /// concept.
692
  ///
693
  /// This class fully conforms to the \ref concepts::Graph "Graph"
694
  /// concept.
695
  template <typename GR>
696
  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
697
    typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
698

	
699
  public:
700

	
701
    typedef typename Parent::Node Node;
702
    typedef typename Parent::Arc Arc;
703
    typedef typename Parent::Edge Edge;
704

	
705
    typedef typename Parent::NodesImplBase NodesImplBase;
706

	
707
    void eraseNode(const Node& node) {
708
      Arc arc;
709
      Parent::firstOut(arc, node);
710
      while (arc != INVALID ) {
711
        erase(arc);
712
        Parent::firstOut(arc, node);
713
      }
714

	
715
    }
716

	
717
    void clearNodes() {
718
      Parent::clear();
719
    }
720

	
721
    class NodesImpl : public NodesImplBase {
722
      typedef NodesImplBase Parent;
723

	
724
    public:
725
      NodesImpl(const GR& graph, ListEdgeSet& arcset)
726
        : Parent(graph), _arcset(arcset) {}
727

	
728
      virtual ~NodesImpl() {}
729

	
730
    protected:
731

	
732
      virtual void erase(const Node& node) {
733
        _arcset.eraseNode(node);
734
        Parent::erase(node);
735
      }
736
      virtual void erase(const std::vector<Node>& nodes) {
737
        for (int i = 0; i < int(nodes.size()); ++i) {
738
          _arcset.eraseNode(nodes[i]);
739
        }
740
        Parent::erase(nodes);
741
      }
742
      virtual void clear() {
743
        _arcset.clearNodes();
744
        Parent::clear();
745
      }
746

	
747
    private:
748
      ListEdgeSet& _arcset;
749
    };
750

	
751
    NodesImpl _nodes;
752

	
753
  public:
754

	
755
    /// \brief Constructor of the EdgeSet.
756
    ///
757
    /// Constructor of the EdgeSet.
758
    ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
759
      Parent::initalize(graph, _nodes);
760
    }
761

	
762
    /// \brief Add a new edge to the graph.
763
    ///
764
    /// Add a new edge to the graph with node \c u
765
    /// and node \c v endpoints.
766
    /// \return The new edge.
767
    Edge addEdge(const Node& u, const Node& v) {
768
      return Parent::addEdge(u, v);
769
    }
770

	
771
    /// \brief Erase an edge from the graph.
772
    ///
773
    /// Erase the edge \c e from the graph.
774
    void erase(const Edge& e) {
775
      return Parent::erase(e);
776
    }
777

	
778
  };
779

	
780
  template <typename GR>
781
  class SmartArcSetBase {
782
  public:
783

	
784
    typedef typename GR::Node Node;
785
    typedef typename GR::NodeIt NodeIt;
786

	
787
  protected:
788

	
789
    struct NodeT {
790
      int first_out, first_in;
791
      NodeT() : first_out(-1), first_in(-1) {}
792
    };
793

	
794
    typedef typename ItemSetTraits<GR, Node>::
795
    template Map<NodeT>::Type NodesImplBase;
796

	
797
    NodesImplBase* _nodes;
798

	
799
    struct ArcT {
800
      Node source, target;
801
      int next_out, next_in;
802
      ArcT() {}
803
    };
804

	
805
    std::vector<ArcT> arcs;
806

	
807
    const GR* _graph;
808

	
809
    void initalize(const GR& graph, NodesImplBase& nodes) {
810
      _graph = &graph;
811
      _nodes = &nodes;
812
    }
813

	
814
  public:
815

	
816
    class Arc {
817
      friend class SmartArcSetBase<GR>;
818
    protected:
819
      Arc(int _id) : id(_id) {}
820
      int id;
821
    public:
822
      Arc() {}
823
      Arc(Invalid) : id(-1) {}
824
      bool operator==(const Arc& arc) const { return id == arc.id; }
825
      bool operator!=(const Arc& arc) const { return id != arc.id; }
826
      bool operator<(const Arc& arc) const { return id < arc.id; }
827
    };
828

	
829
    SmartArcSetBase() {}
830

	
831
    Node addNode() {
832
      LEMON_ASSERT(false,
833
        "This graph structure does not support node insertion");
834
      return INVALID; // avoid warning
835
    }
836

	
837
    Arc addArc(const Node& u, const Node& v) {
838
      int n = arcs.size();
839
      arcs.push_back(ArcT());
840
      arcs[n].next_in = (*_nodes)[v].first_in;
841
      (*_nodes)[v].first_in = n;
842
      arcs[n].next_out = (*_nodes)[u].first_out;
843
      (*_nodes)[u].first_out = n;
844
      arcs[n].source = u;
845
      arcs[n].target = v;
846
      return Arc(n);
847
    }
848

	
849
    void clear() {
850
      Node node;
851
      for (first(node); node != INVALID; next(node)) {
852
        (*_nodes)[node].first_in = -1;
853
        (*_nodes)[node].first_out = -1;
854
      }
855
      arcs.clear();
856
    }
857

	
858
    void first(Node& node) const {
859
      _graph->first(node);
860
    }
861

	
862
    void next(Node& node) const {
863
      _graph->next(node);
864
    }
865

	
866
    void first(Arc& arc) const {
867
      arc.id = arcs.size() - 1;
868
    }
869

	
870
    void next(Arc& arc) const {
871
      --arc.id;
872
    }
873

	
874
    void firstOut(Arc& arc, const Node& node) const {
875
      arc.id = (*_nodes)[node].first_out;
876
    }
877

	
878
    void nextOut(Arc& arc) const {
879
      arc.id = arcs[arc.id].next_out;
880
    }
881

	
882
    void firstIn(Arc& arc, const Node& node) const {
883
      arc.id = (*_nodes)[node].first_in;
884
    }
885

	
886
    void nextIn(Arc& arc) const {
887
      arc.id = arcs[arc.id].next_in;
888
    }
889

	
890
    int id(const Node& node) const { return _graph->id(node); }
891
    int id(const Arc& arc) const { return arc.id; }
892

	
893
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
894
    Arc arcFromId(int ix) const { return Arc(ix); }
895

	
896
    int maxNodeId() const { return _graph->maxNodeId(); };
897
    int maxArcId() const { return arcs.size() - 1; }
898

	
899
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
900
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
901

	
902
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
903

	
904
    NodeNotifier& notifier(Node) const {
905
      return _graph->notifier(Node());
906
    }
907

	
908
    template <typename V>
909
    class NodeMap : public GR::template NodeMap<V> {
910
      typedef typename GR::template NodeMap<V> Parent;
911

	
912
    public:
913

	
914
      explicit NodeMap(const SmartArcSetBase<GR>& arcset)
915
        : Parent(*arcset._graph) { }
916

	
917
      NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
918
        : Parent(*arcset._graph, value) { }
919

	
920
      NodeMap& operator=(const NodeMap& cmap) {
921
        return operator=<NodeMap>(cmap);
922
      }
923

	
924
      template <typename CMap>
925
      NodeMap& operator=(const CMap& cmap) {
926
        Parent::operator=(cmap);
927
        return *this;
928
      }
929
    };
930

	
931
  };
932

	
933

	
934
  /// \ingroup graphs
935
  ///
936
  /// \brief Digraph using a node set of another digraph or graph and
937
  /// an own arc set.
938
  ///
939
  /// This structure can be used to establish another directed graph
940
  /// over a node set of an existing one. This class uses the same
941
  /// Node type as the underlying graph, and each valid node of the
942
  /// original graph is valid in this arc set, therefore the node
943
  /// objects of the original graph can be used directly with this
944
  /// class. The node handling functions (id handling, observing, and
945
  /// iterators) works equivalently as in the original graph.
946
  ///
947
  /// \param GR The type of the graph which shares its node set with
948
  /// this class. Its interface must conform to the
949
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
950
  /// concept.
951
  ///
952
  /// This implementation is slightly faster than the \c ListArcSet,
953
  /// because it uses continuous storage for arcs and it uses just
954
  /// single-linked lists for enumerate outgoing and incoming
955
  /// arcs. Therefore the arcs cannot be erased from the arc sets.
956
  ///
957
  /// \warning If a node is erased from the underlying graph and this
958
  /// node is the source or target of one arc in the arc set, then
959
  /// the arc set is invalidated, and it cannot be used anymore. The
960
  /// validity can be checked with the \c valid() member function.
961
  ///
962
  /// This class fully conforms to the \ref concepts::Digraph
963
  /// "Digraph" concept.
964
  template <typename GR>
965
  class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
966
    typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
967

	
968
  public:
969

	
970
    typedef typename Parent::Node Node;
971
    typedef typename Parent::Arc Arc;
972

	
973
  protected:
974

	
975
    typedef typename Parent::NodesImplBase NodesImplBase;
976

	
977
    void eraseNode(const Node& node) {
978
      if (typename Parent::InArcIt(*this, node) == INVALID &&
979
          typename Parent::OutArcIt(*this, node) == INVALID) {
980
        return;
981
      }
982
      throw typename NodesImplBase::Notifier::ImmediateDetach();
983
    }
984

	
985
    void clearNodes() {
986
      Parent::clear();
987
    }
988

	
989
    class NodesImpl : public NodesImplBase {
990
      typedef NodesImplBase Parent;
991

	
992
    public:
993
      NodesImpl(const GR& graph, SmartArcSet& arcset)
994
        : Parent(graph), _arcset(arcset) {}
995

	
996
      virtual ~NodesImpl() {}
997

	
998
      bool attached() const {
999
        return Parent::attached();
1000
      }
1001

	
1002
    protected:
1003

	
1004
      virtual void erase(const Node& node) {
1005
        try {
1006
          _arcset.eraseNode(node);
1007
          Parent::erase(node);
1008
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1009
          Parent::clear();
1010
          throw;
1011
        }
1012
      }
1013
      virtual void erase(const std::vector<Node>& nodes) {
1014
        try {
1015
          for (int i = 0; i < int(nodes.size()); ++i) {
1016
            _arcset.eraseNode(nodes[i]);
1017
          }
1018
          Parent::erase(nodes);
1019
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1020
          Parent::clear();
1021
          throw;
1022
        }
1023
      }
1024
      virtual void clear() {
1025
        _arcset.clearNodes();
1026
        Parent::clear();
1027
      }
1028

	
1029
    private:
1030
      SmartArcSet& _arcset;
1031
    };
1032

	
1033
    NodesImpl _nodes;
1034

	
1035
  public:
1036

	
1037
    /// \brief Constructor of the ArcSet.
1038
    ///
1039
    /// Constructor of the ArcSet.
1040
    SmartArcSet(const GR& graph) : _nodes(graph, *this) {
1041
      Parent::initalize(graph, _nodes);
1042
    }
1043

	
1044
    /// \brief Add a new arc to the digraph.
1045
    ///
1046
    /// Add a new arc to the digraph with source node \c s
1047
    /// and target node \c t.
1048
    /// \return The new arc.
1049
    Arc addArc(const Node& s, const Node& t) {
1050
      return Parent::addArc(s, t);
1051
    }
1052

	
1053
    /// \brief Validity check
1054
    ///
1055
    /// This functions gives back false if the ArcSet is
1056
    /// invalidated. It occurs when a node in the underlying graph is
1057
    /// erased and it is not isolated in the ArcSet.
1058
    bool valid() const {
1059
      return _nodes.attached();
1060
    }
1061

	
1062
  };
1063

	
1064

	
1065
  template <typename GR>
1066
  class SmartEdgeSetBase {
1067
  public:
1068

	
1069
    typedef typename GR::Node Node;
1070
    typedef typename GR::NodeIt NodeIt;
1071

	
1072
  protected:
1073

	
1074
    struct NodeT {
1075
      int first_out;
1076
      NodeT() : first_out(-1) {}
1077
    };
1078

	
1079
    typedef typename ItemSetTraits<GR, Node>::
1080
    template Map<NodeT>::Type NodesImplBase;
1081

	
1082
    NodesImplBase* _nodes;
1083

	
1084
    struct ArcT {
1085
      Node target;
1086
      int next_out;
1087
      ArcT() {}
1088
    };
1089

	
1090
    std::vector<ArcT> arcs;
1091

	
1092
    const GR* _graph;
1093

	
1094
    void initalize(const GR& graph, NodesImplBase& nodes) {
1095
      _graph = &graph;
1096
      _nodes = &nodes;
1097
    }
1098

	
1099
  public:
1100

	
1101
    class Edge {
1102
      friend class SmartEdgeSetBase;
1103
    protected:
1104

	
1105
      int id;
1106
      explicit Edge(int _id) { id = _id;}
1107

	
1108
    public:
1109
      Edge() {}
1110
      Edge (Invalid) { id = -1; }
1111
      bool operator==(const Edge& arc) const {return id == arc.id;}
1112
      bool operator!=(const Edge& arc) const {return id != arc.id;}
1113
      bool operator<(const Edge& arc) const {return id < arc.id;}
1114
    };
1115

	
1116
    class Arc {
1117
      friend class SmartEdgeSetBase;
1118
    protected:
1119
      Arc(int _id) : id(_id) {}
1120
      int id;
1121
    public:
1122
      operator Edge() const { return edgeFromId(id / 2); }
1123

	
1124
      Arc() {}
1125
      Arc(Invalid) : id(-1) {}
1126
      bool operator==(const Arc& arc) const { return id == arc.id; }
1127
      bool operator!=(const Arc& arc) const { return id != arc.id; }
1128
      bool operator<(const Arc& arc) const { return id < arc.id; }
1129
    };
1130

	
1131
    SmartEdgeSetBase() {}
1132

	
1133
    Node addNode() {
1134
      LEMON_ASSERT(false,
1135
        "This graph structure does not support node insertion");
1136
      return INVALID; // avoid warning
1137
    }
1138

	
1139
    Edge addEdge(const Node& u, const Node& v) {
1140
      int n = arcs.size();
1141
      arcs.push_back(ArcT());
1142
      arcs.push_back(ArcT());
1143

	
1144
      arcs[n].target = u;
1145
      arcs[n | 1].target = v;
1146

	
1147
      arcs[n].next_out = (*_nodes)[v].first_out;
1148
      (*_nodes)[v].first_out = n;
1149

	
1150
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
1151
      (*_nodes)[u].first_out = (n | 1);
1152

	
1153
      return Edge(n / 2);
1154
    }
1155

	
1156
    void clear() {
1157
      Node node;
1158
      for (first(node); node != INVALID; next(node)) {
1159
        (*_nodes)[node].first_out = -1;
1160
      }
1161
      arcs.clear();
1162
    }
1163

	
1164
    void first(Node& node) const {
1165
      _graph->first(node);
1166
    }
1167

	
1168
    void next(Node& node) const {
1169
      _graph->next(node);
1170
    }
1171

	
1172
    void first(Arc& arc) const {
1173
      arc.id = arcs.size() - 1;
1174
    }
1175

	
1176
    void next(Arc& arc) const {
1177
      --arc.id;
1178
    }
1179

	
1180
    void first(Edge& arc) const {
1181
      arc.id = arcs.size() / 2 - 1;
1182
    }
1183

	
1184
    void next(Edge& arc) const {
1185
      --arc.id;
1186
    }
1187

	
1188
    void firstOut(Arc& arc, const Node& node) const {
1189
      arc.id = (*_nodes)[node].first_out;
1190
    }
1191

	
1192
    void nextOut(Arc& arc) const {
1193
      arc.id = arcs[arc.id].next_out;
1194
    }
1195

	
1196
    void firstIn(Arc& arc, const Node& node) const {
1197
      arc.id = (((*_nodes)[node].first_out) ^ 1);
1198
      if (arc.id == -2) arc.id = -1;
1199
    }
1200

	
1201
    void nextIn(Arc& arc) const {
1202
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
1203
      if (arc.id == -2) arc.id = -1;
1204
    }
1205

	
1206
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
1207
      int de = (*_nodes)[node].first_out;
1208
      if (de != -1 ) {
1209
        arc.id = de / 2;
1210
        dir = ((de & 1) == 1);
1211
      } else {
1212
        arc.id = -1;
1213
        dir = true;
1214
      }
1215
    }
1216
    void nextInc(Edge &arc, bool& dir) const {
1217
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
1218
      if (de != -1 ) {
1219
        arc.id = de / 2;
1220
        dir = ((de & 1) == 1);
1221
      } else {
1222
        arc.id = -1;
1223
        dir = true;
1224
      }
1225
    }
1226

	
1227
    static bool direction(Arc arc) {
1228
      return (arc.id & 1) == 1;
1229
    }
1230

	
1231
    static Arc direct(Edge edge, bool dir) {
1232
      return Arc(edge.id * 2 + (dir ? 1 : 0));
1233
    }
1234

	
1235
    int id(Node node) const { return _graph->id(node); }
1236
    static int id(Arc arc) { return arc.id; }
1237
    static int id(Edge arc) { return arc.id; }
1238

	
1239
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
1240
    static Arc arcFromId(int id) { return Arc(id); }
1241
    static Edge edgeFromId(int id) { return Edge(id);}
1242

	
1243
    int maxNodeId() const { return _graph->maxNodeId(); };
1244
    int maxArcId() const { return arcs.size() - 1; }
1245
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
1246

	
1247
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
1248
    Node target(Arc e) const { return arcs[e.id].target; }
1249

	
1250
    Node u(Edge e) const { return arcs[2 * e.id].target; }
1251
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
1252

	
1253
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
1254

	
1255
    NodeNotifier& notifier(Node) const {
1256
      return _graph->notifier(Node());
1257
    }
1258

	
1259
    template <typename V>
1260
    class NodeMap : public GR::template NodeMap<V> {
1261
      typedef typename GR::template NodeMap<V> Parent;
1262

	
1263
    public:
1264

	
1265
      explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
1266
        : Parent(*arcset._graph) { }
1267

	
1268
      NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
1269
        : Parent(*arcset._graph, value) { }
1270

	
1271
      NodeMap& operator=(const NodeMap& cmap) {
1272
        return operator=<NodeMap>(cmap);
1273
      }
1274

	
1275
      template <typename CMap>
1276
      NodeMap& operator=(const CMap& cmap) {
1277
        Parent::operator=(cmap);
1278
        return *this;
1279
      }
1280
    };
1281

	
1282
  };
1283

	
1284
  /// \ingroup graphs
1285
  ///
1286
  /// \brief Graph using a node set of another digraph or graph and an
1287
  /// own edge set.
1288
  ///
1289
  /// This structure can be used to establish another graph over a
1290
  /// node set of an existing one. This class uses the same Node type
1291
  /// as the underlying graph, and each valid node of the original
1292
  /// graph is valid in this arc set, therefore the node objects of
1293
  /// the original graph can be used directly with this class. The
1294
  /// node handling functions (id handling, observing, and iterators)
1295
  /// works equivalently as in the original graph.
1296
  ///
1297
  /// \param GR The type of the graph which shares its node set
1298
  /// with this class. Its interface must conform to the
1299
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
1300
  ///  concept.
1301
  ///
1302
  /// This implementation is slightly faster than the \c ListEdgeSet,
1303
  /// because it uses continuous storage for edges and it uses just
1304
  /// single-linked lists for enumerate incident edges. Therefore the
1305
  /// edges cannot be erased from the edge sets.
1306
  ///
1307
  /// \warning If a node is erased from the underlying graph and this
1308
  /// node is incident to one edge in the edge set, then the edge set
1309
  /// is invalidated, and it cannot be used anymore. The validity can
1310
  /// be checked with the \c valid() member function.
1311
  ///
1312
  /// This class fully conforms to the \ref concepts::Graph
1313
  /// "Graph" concept.
1314
  template <typename GR>
1315
  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
1316
    typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
1317

	
1318
  public:
1319

	
1320
    typedef typename Parent::Node Node;
1321
    typedef typename Parent::Arc Arc;
1322
    typedef typename Parent::Edge Edge;
1323

	
1324
  protected:
1325

	
1326
    typedef typename Parent::NodesImplBase NodesImplBase;
1327

	
1328
    void eraseNode(const Node& node) {
1329
      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
1330
        return;
1331
      }
1332
      throw typename NodesImplBase::Notifier::ImmediateDetach();
1333
    }
1334

	
1335
    void clearNodes() {
1336
      Parent::clear();
1337
    }
1338

	
1339
    class NodesImpl : public NodesImplBase {
1340
      typedef NodesImplBase Parent;
1341

	
1342
    public:
1343
      NodesImpl(const GR& graph, SmartEdgeSet& arcset)
1344
        : Parent(graph), _arcset(arcset) {}
1345

	
1346
      virtual ~NodesImpl() {}
1347

	
1348
      bool attached() const {
1349
        return Parent::attached();
1350
      }
1351

	
1352
    protected:
1353

	
1354
      virtual void erase(const Node& node) {
1355
        try {
1356
          _arcset.eraseNode(node);
1357
          Parent::erase(node);
1358
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1359
          Parent::clear();
1360
          throw;
1361
        }
1362
      }
1363
      virtual void erase(const std::vector<Node>& nodes) {
1364
        try {
1365
          for (int i = 0; i < int(nodes.size()); ++i) {
1366
            _arcset.eraseNode(nodes[i]);
1367
          }
1368
          Parent::erase(nodes);
1369
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1370
          Parent::clear();
1371
          throw;
1372
        }
1373
      }
1374
      virtual void clear() {
1375
        _arcset.clearNodes();
1376
        Parent::clear();
1377
      }
1378

	
1379
    private:
1380
      SmartEdgeSet& _arcset;
1381
    };
1382

	
1383
    NodesImpl _nodes;
1384

	
1385
  public:
1386

	
1387
    /// \brief Constructor of the EdgeSet.
1388
    ///
1389
    /// Constructor of the EdgeSet.
1390
    SmartEdgeSet(const GR& graph) : _nodes(graph, *this) {
1391
      Parent::initalize(graph, _nodes);
1392
    }
1393

	
1394
    /// \brief Add a new edge to the graph.
1395
    ///
1396
    /// Add a new edge to the graph with node \c u
1397
    /// and node \c v endpoints.
1398
    /// \return The new edge.
1399
    Edge addEdge(const Node& u, const Node& v) {
1400
      return Parent::addEdge(u, v);
1401
    }
1402

	
1403
    /// \brief Validity check
1404
    ///
1405
    /// This functions gives back false if the EdgeSet is
1406
    /// invalidated. It occurs when a node in the underlying graph is
1407
    /// erased and it is not isolated in the EdgeSet.
1408
    bool valid() const {
1409
      return _nodes.attached();
1410
    }
1411

	
1412
  };
1413

	
1414
}
1415

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

	
19
#ifndef LEMON_ELEVATOR_H
20
#define LEMON_ELEVATOR_H
21

	
22
///\ingroup auxdat
23
///\file
24
///\brief Elevator class
25
///
26
///Elevator class implements an efficient data structure
27
///for labeling items in push-relabel type algorithms.
28
///
29

	
30
#include <lemon/core.h>
31
#include <lemon/bits/traits.h>
32

	
33
namespace lemon {
34

	
35
  ///Class for handling "labels" in push-relabel type algorithms.
36

	
37
  ///A class for handling "labels" in push-relabel type algorithms.
38
  ///
39
  ///\ingroup auxdat
40
  ///Using this class you can assign "labels" (nonnegative integer numbers)
41
  ///to the edges or nodes of a graph, manipulate and query them through
42
  ///operations typically arising in "push-relabel" type algorithms.
43
  ///
44
  ///Each item is either \em active or not, and you can also choose a
45
  ///highest level active item.
46
  ///
47
  ///\sa LinkedElevator
48
  ///
49
  ///\param GR Type of the underlying graph.
50
  ///\param Item Type of the items the data is assigned to (\c GR::Node,
51
  ///\c GR::Arc or \c GR::Edge).
52
  template<class GR, class Item>
53
  class Elevator
54
  {
55
  public:
56

	
57
    typedef Item Key;
58
    typedef int Value;
59

	
60
  private:
61

	
62
    typedef Item *Vit;
63
    typedef typename ItemSetTraits<GR,Item>::template Map<Vit>::Type VitMap;
64
    typedef typename ItemSetTraits<GR,Item>::template Map<int>::Type IntMap;
65

	
66
    const GR &_g;
67
    int _max_level;
68
    int _item_num;
69
    VitMap _where;
70
    IntMap _level;
71
    std::vector<Item> _items;
72
    std::vector<Vit> _first;
73
    std::vector<Vit> _last_active;
74

	
75
    int _highest_active;
76

	
77
    void copy(Item i, Vit p)
78
    {
79
      _where[*p=i] = p;
80
    }
81
    void copy(Vit s, Vit p)
82
    {
83
      if(s!=p)
84
        {
85
          Item i=*s;
86
          *p=i;
87
          _where[i] = p;
88
        }
89
    }
90
    void swap(Vit i, Vit j)
91
    {
92
      Item ti=*i;
93
      Vit ct = _where[ti];
94
      _where[ti] = _where[*i=*j];
95
      _where[*j] = ct;
96
      *j=ti;
97
    }
98

	
99
  public:
100

	
101
    ///Constructor with given maximum level.
102

	
103
    ///Constructor with given maximum level.
104
    ///
105
    ///\param graph The underlying graph.
106
    ///\param max_level The maximum allowed level.
107
    ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
108
    Elevator(const GR &graph,int max_level) :
109
      _g(graph),
110
      _max_level(max_level),
111
      _item_num(_max_level),
112
      _where(graph),
113
      _level(graph,0),
114
      _items(_max_level),
115
      _first(_max_level+2),
116
      _last_active(_max_level+2),
117
      _highest_active(-1) {}
118
    ///Constructor.
119

	
120
    ///Constructor.
121
    ///
122
    ///\param graph The underlying graph.
123
    ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
124
    ///where \c max_level is equal to the number of labeled items in the graph.
125
    Elevator(const GR &graph) :
126
      _g(graph),
127
      _max_level(countItems<GR, Item>(graph)),
128
      _item_num(_max_level),
129
      _where(graph),
130
      _level(graph,0),
131
      _items(_max_level),
132
      _first(_max_level+2),
133
      _last_active(_max_level+2),
134
      _highest_active(-1)
135
    {
136
    }
137

	
138
    ///Activate item \c i.
139

	
140
    ///Activate item \c i.
141
    ///\pre Item \c i shouldn't be active before.
142
    void activate(Item i)
143
    {
144
      const int l=_level[i];
145
      swap(_where[i],++_last_active[l]);
146
      if(l>_highest_active) _highest_active=l;
147
    }
148

	
149
    ///Deactivate item \c i.
150

	
151
    ///Deactivate item \c i.
152
    ///\pre Item \c i must be active before.
153
    void deactivate(Item i)
154
    {
155
      swap(_where[i],_last_active[_level[i]]--);
156
      while(_highest_active>=0 &&
157
            _last_active[_highest_active]<_first[_highest_active])
158
        _highest_active--;
159
    }
160

	
161
    ///Query whether item \c i is active
162
    bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; }
163

	
164
    ///Return the level of item \c i.
165
    int operator[](Item i) const { return _level[i]; }
166

	
167
    ///Return the number of items on level \c l.
168
    int onLevel(int l) const
169
    {
170
      return _first[l+1]-_first[l];
171
    }
172
    ///Return true if level \c l is empty.
173
    bool emptyLevel(int l) const
174
    {
175
      return _first[l+1]-_first[l]==0;
176
    }
177
    ///Return the number of items above level \c l.
178
    int aboveLevel(int l) const
179
    {
180
      return _first[_max_level+1]-_first[l+1];
181
    }
182
    ///Return the number of active items on level \c l.
183
    int activesOnLevel(int l) const
184
    {
185
      return _last_active[l]-_first[l]+1;
186
    }
187
    ///Return true if there is no active item on level \c l.
188
    bool activeFree(int l) const
189
    {
190
      return _last_active[l]<_first[l];
191
    }
192
    ///Return the maximum allowed level.
193
    int maxLevel() const
194
    {
195
      return _max_level;
196
    }
197

	
198
    ///\name Highest Active Item
199
    ///Functions for working with the highest level
200
    ///active item.
201

	
202
    ///@{
203

	
204
    ///Return a highest level active item.
205

	
206
    ///Return a highest level active item or INVALID if there is no active
207
    ///item.
208
    Item highestActive() const
209
    {
210
      return _highest_active>=0?*_last_active[_highest_active]:INVALID;
211
    }
212

	
213
    ///Return the highest active level.
214

	
215
    ///Return the level of the highest active item or -1 if there is no active
216
    ///item.
217
    int highestActiveLevel() const
218
    {
219
      return _highest_active;
220
    }
221

	
222
    ///Lift the highest active item by one.
223

	
224
    ///Lift the item returned by highestActive() by one.
225
    ///
226
    void liftHighestActive()
227
    {
228
      Item it = *_last_active[_highest_active];
229
      ++_level[it];
230
      swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
231
      --_first[++_highest_active];
232
    }
233

	
234
    ///Lift the highest active item to the given level.
235

	
236
    ///Lift the item returned by highestActive() to level \c new_level.
237
    ///
238
    ///\warning \c new_level must be strictly higher
239
    ///than the current level.
240
    ///
241
    void liftHighestActive(int new_level)
242
    {
243
      const Item li = *_last_active[_highest_active];
244

	
245
      copy(--_first[_highest_active+1],_last_active[_highest_active]--);
246
      for(int l=_highest_active+1;l<new_level;l++)
247
        {
248
          copy(--_first[l+1],_first[l]);
249
          --_last_active[l];
250
        }
251
      copy(li,_first[new_level]);
252
      _level[li] = new_level;
253
      _highest_active=new_level;
254
    }
255

	
256
    ///Lift the highest active item to the top level.
257

	
258
    ///Lift the item returned by highestActive() to the top level and
259
    ///deactivate it.
260
    void liftHighestActiveToTop()
261
    {
262
      const Item li = *_last_active[_highest_active];
263

	
264
      copy(--_first[_highest_active+1],_last_active[_highest_active]--);
265
      for(int l=_highest_active+1;l<_max_level;l++)
266
        {
267
          copy(--_first[l+1],_first[l]);
268
          --_last_active[l];
269
        }
270
      copy(li,_first[_max_level]);
271
      --_last_active[_max_level];
272
      _level[li] = _max_level;
273

	
274
      while(_highest_active>=0 &&
275
            _last_active[_highest_active]<_first[_highest_active])
276
        _highest_active--;
277
    }
278

	
279
    ///@}
280

	
281
    ///\name Active Item on Certain Level
282
    ///Functions for working with the active items.
283

	
284
    ///@{
285

	
286
    ///Return an active item on level \c l.
287

	
288
    ///Return an active item on level \c l or \ref INVALID if there is no such
289
    ///an item. (\c l must be from the range [0...\c max_level].
290
    Item activeOn(int l) const
291
    {
292
      return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
293
    }
294

	
295
    ///Lift the active item returned by \c activeOn(level) by one.
296

	
297
    ///Lift the active item returned by \ref activeOn() "activeOn(level)"
298
    ///by one.
299
    Item liftActiveOn(int level)
300
    {
301
      Item it =*_last_active[level];
302
      ++_level[it];
303
      swap(_last_active[level]--, --_first[level+1]);
304
      if (level+1>_highest_active) ++_highest_active;
305
    }
306

	
307
    ///Lift the active item returned by \c activeOn(level) to the given level.
308

	
309
    ///Lift the active item returned by \ref activeOn() "activeOn(level)"
310
    ///to the given level.
311
    void liftActiveOn(int level, int new_level)
312
    {
313
      const Item ai = *_last_active[level];
314

	
315
      copy(--_first[level+1], _last_active[level]--);
316
      for(int l=level+1;l<new_level;l++)
317
        {
318
          copy(_last_active[l],_first[l]);
319
          copy(--_first[l+1], _last_active[l]--);
320
        }
321
      copy(ai,_first[new_level]);
322
      _level[ai] = new_level;
323
      if (new_level>_highest_active) _highest_active=new_level;
324
    }
325

	
326
    ///Lift the active item returned by \c activeOn(level) to the top level.
327

	
328
    ///Lift the active item returned by \ref activeOn() "activeOn(level)"
329
    ///to the top level and deactivate it.
330
    void liftActiveToTop(int level)
331
    {
332
      const Item ai = *_last_active[level];
333

	
334
      copy(--_first[level+1],_last_active[level]--);
335
      for(int l=level+1;l<_max_level;l++)
336
        {
337
          copy(_last_active[l],_first[l]);
338
          copy(--_first[l+1], _last_active[l]--);
339
        }
340
      copy(ai,_first[_max_level]);
341
      --_last_active[_max_level];
342
      _level[ai] = _max_level;
343

	
344
      if (_highest_active==level) {
345
        while(_highest_active>=0 &&
346
              _last_active[_highest_active]<_first[_highest_active])
347
          _highest_active--;
348
      }
349
    }
350

	
351
    ///@}
352

	
353
    ///Lift an active item to a higher level.
354

	
355
    ///Lift an active item to a higher level.
356
    ///\param i The item to be lifted. It must be active.
357
    ///\param new_level The new level of \c i. It must be strictly higher
358
    ///than the current level.
359
    ///
360
    void lift(Item i, int new_level)
361
    {
362
      const int lo = _level[i];
363
      const Vit w = _where[i];
364

	
365
      copy(_last_active[lo],w);
366
      copy(--_first[lo+1],_last_active[lo]--);
367
      for(int l=lo+1;l<new_level;l++)
368
        {
369
          copy(_last_active[l],_first[l]);
370
          copy(--_first[l+1],_last_active[l]--);
371
        }
372
      copy(i,_first[new_level]);
373
      _level[i] = new_level;
374
      if(new_level>_highest_active) _highest_active=new_level;
375
    }
376

	
377
    ///Move an inactive item to the top but one level (in a dirty way).
378

	
379
    ///This function moves an inactive item from the top level to the top
380
    ///but one level (in a dirty way).
381
    ///\warning It makes the underlying datastructure corrupt, so use it
382
    ///only if you really know what it is for.
383
    ///\pre The item is on the top level.
384
    void dirtyTopButOne(Item i) {
385
      _level[i] = _max_level - 1;
386
    }
387

	
388
    ///Lift all items on and above the given level to the top level.
389

	
390
    ///This function lifts all items on and above level \c l to the top
391
    ///level and deactivates them.
392
    void liftToTop(int l)
393
    {
394
      const Vit f=_first[l];
395
      const Vit tl=_first[_max_level];
396
      for(Vit i=f;i!=tl;++i)
397
        _level[*i] = _max_level;
398
      for(int i=l;i<=_max_level;i++)
399
        {
400
          _first[i]=f;
401
          _last_active[i]=f-1;
402
        }
403
      for(_highest_active=l-1;
404
          _highest_active>=0 &&
405
            _last_active[_highest_active]<_first[_highest_active];
406
          _highest_active--) ;
407
    }
408

	
409
  private:
410
    int _init_lev;
411
    Vit _init_num;
412

	
413
  public:
414

	
415
    ///\name Initialization
416
    ///Using these functions you can initialize the levels of the items.
417
    ///\n
418
    ///The initialization must be started with calling \c initStart().
419
    ///Then the items should be listed level by level starting with the
420
    ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
421
    ///Finally \c initFinish() must be called.
422
    ///The items not listed are put on the highest level.
423
    ///@{
424

	
425
    ///Start the initialization process.
426
    void initStart()
427
    {
428
      _init_lev=0;
429
      _init_num=&_items[0];
430
      _first[0]=&_items[0];
431
      _last_active[0]=&_items[0]-1;
432
      Vit n=&_items[0];
433
      for(typename ItemSetTraits<GR,Item>::ItemIt i(_g);i!=INVALID;++i)
434
        {
435
          *n=i;
436
          _where[i] = n;
437
          _level[i] = _max_level;
438
          ++n;
439
        }
440
    }
441

	
442
    ///Add an item to the current level.
443
    void initAddItem(Item i)
444
    {
445
      swap(_where[i],_init_num);
446
      _level[i] = _init_lev;
447
      ++_init_num;
448
    }
449

	
450
    ///Start a new level.
451

	
452
    ///Start a new level.
453
    ///It shouldn't be used before the items on level 0 are listed.
454
    void initNewLevel()
455
    {
456
      _init_lev++;
457
      _first[_init_lev]=_init_num;
458
      _last_active[_init_lev]=_init_num-1;
459
    }
460

	
461
    ///Finalize the initialization process.
462
    void initFinish()
463
    {
464
      for(_init_lev++;_init_lev<=_max_level;_init_lev++)
465
        {
466
          _first[_init_lev]=_init_num;
467
          _last_active[_init_lev]=_init_num-1;
468
        }
469
      _first[_max_level+1]=&_items[0]+_item_num;
470
      _last_active[_max_level+1]=&_items[0]+_item_num-1;
471
      _highest_active = -1;
472
    }
473

	
474
    ///@}
475

	
476
  };
477

	
478
  ///Class for handling "labels" in push-relabel type algorithms.
479

	
480
  ///A class for handling "labels" in push-relabel type algorithms.
481
  ///
482
  ///\ingroup auxdat
483
  ///Using this class you can assign "labels" (nonnegative integer numbers)
484
  ///to the edges or nodes of a graph, manipulate and query them through
485
  ///operations typically arising in "push-relabel" type algorithms.
486
  ///
487
  ///Each item is either \em active or not, and you can also choose a
488
  ///highest level active item.
489
  ///
490
  ///\sa Elevator
491
  ///
492
  ///\param GR Type of the underlying graph.
493
  ///\param Item Type of the items the data is assigned to (\c GR::Node,
494
  ///\c GR::Arc or \c GR::Edge).
495
  template <class GR, class Item>
496
  class LinkedElevator {
497
  public:
498

	
499
    typedef Item Key;
500
    typedef int Value;
501

	
502
  private:
503

	
504
    typedef typename ItemSetTraits<GR,Item>::
505
    template Map<Item>::Type ItemMap;
506
    typedef typename ItemSetTraits<GR,Item>::
507
    template Map<int>::Type IntMap;
508
    typedef typename ItemSetTraits<GR,Item>::
509
    template Map<bool>::Type BoolMap;
510

	
511
    const GR &_graph;
512
    int _max_level;
513
    int _item_num;
514
    std::vector<Item> _first, _last;
515
    ItemMap _prev, _next;
516
    int _highest_active;
517
    IntMap _level;
518
    BoolMap _active;
519

	
520
  public:
521
    ///Constructor with given maximum level.
522

	
523
    ///Constructor with given maximum level.
524
    ///
525
    ///\param graph The underlying graph.
526
    ///\param max_level The maximum allowed level.
527
    ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
528
    LinkedElevator(const GR& graph, int max_level)
529
      : _graph(graph), _max_level(max_level), _item_num(_max_level),
530
        _first(_max_level + 1), _last(_max_level + 1),
531
        _prev(graph), _next(graph),
532
        _highest_active(-1), _level(graph), _active(graph) {}
533

	
534
    ///Constructor.
535

	
536
    ///Constructor.
537
    ///
538
    ///\param graph The underlying graph.
539
    ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
540
    ///where \c max_level is equal to the number of labeled items in the graph.
541
    LinkedElevator(const GR& graph)
542
      : _graph(graph), _max_level(countItems<GR, Item>(graph)),
543
        _item_num(_max_level),
544
        _first(_max_level + 1), _last(_max_level + 1),
545
        _prev(graph, INVALID), _next(graph, INVALID),
546
        _highest_active(-1), _level(graph), _active(graph) {}
547

	
548

	
549
    ///Activate item \c i.
550

	
551
    ///Activate item \c i.
552
    ///\pre Item \c i shouldn't be active before.
553
    void activate(Item i) {
554
      _active[i] = true;
555

	
556
      int level = _level[i];
557
      if (level > _highest_active) {
558
        _highest_active = level;
559
      }
560

	
561
      if (_prev[i] == INVALID || _active[_prev[i]]) return;
562
      //unlace
563
      _next[_prev[i]] = _next[i];
564
      if (_next[i] != INVALID) {
565
        _prev[_next[i]] = _prev[i];
566
      } else {
567
        _last[level] = _prev[i];
568
      }
569
      //lace
570
      _next[i] = _first[level];
571
      _prev[_first[level]] = i;
572
      _prev[i] = INVALID;
573
      _first[level] = i;
574

	
575
    }
576

	
577
    ///Deactivate item \c i.
578

	
579
    ///Deactivate item \c i.
580
    ///\pre Item \c i must be active before.
581
    void deactivate(Item i) {
582
      _active[i] = false;
583
      int level = _level[i];
584

	
585
      if (_next[i] == INVALID || !_active[_next[i]])
586
        goto find_highest_level;
587

	
588
      //unlace
589
      _prev[_next[i]] = _prev[i];
590
      if (_prev[i] != INVALID) {
591
        _next[_prev[i]] = _next[i];
592
      } else {
593
        _first[_level[i]] = _next[i];
594
      }
595
      //lace
596
      _prev[i] = _last[level];
597
      _next[_last[level]] = i;
598
      _next[i] = INVALID;
599
      _last[level] = i;
600

	
601
    find_highest_level:
602
      if (level == _highest_active) {
603
        while (_highest_active >= 0 && activeFree(_highest_active))
604
          --_highest_active;
605
      }
606
    }
607

	
608
    ///Query whether item \c i is active
609
    bool active(Item i) const { return _active[i]; }
610

	
611
    ///Return the level of item \c i.
612
    int operator[](Item i) const { return _level[i]; }
613

	
614
    ///Return the number of items on level \c l.
615
    int onLevel(int l) const {
616
      int num = 0;
617
      Item n = _first[l];
618
      while (n != INVALID) {
619
        ++num;
620
        n = _next[n];
621
      }
622
      return num;
623
    }
624

	
625
    ///Return true if the level is empty.
626
    bool emptyLevel(int l) const {
627
      return _first[l] == INVALID;
628
    }
629

	
630
    ///Return the number of items above level \c l.
631
    int aboveLevel(int l) const {
632
      int num = 0;
633
      for (int level = l + 1; level < _max_level; ++level)
634
        num += onLevel(level);
635
      return num;
636
    }
637

	
638
    ///Return the number of active items on level \c l.
639
    int activesOnLevel(int l) const {
640
      int num = 0;
641
      Item n = _first[l];
642
      while (n != INVALID && _active[n]) {
643
        ++num;
644
        n = _next[n];
645
      }
646
      return num;
647
    }
648

	
649
    ///Return true if there is no active item on level \c l.
650
    bool activeFree(int l) const {
651
      return _first[l] == INVALID || !_active[_first[l]];
652
    }
653

	
654
    ///Return the maximum allowed level.
655
    int maxLevel() const {
656
      return _max_level;
657
    }
658

	
659
    ///\name Highest Active Item
660
    ///Functions for working with the highest level
661
    ///active item.
662

	
663
    ///@{
664

	
665
    ///Return a highest level active item.
666

	
667
    ///Return a highest level active item or INVALID if there is no active
668
    ///item.
669
    Item highestActive() const {
670
      return _highest_active >= 0 ? _first[_highest_active] : INVALID;
671
    }
672

	
673
    ///Return the highest active level.
674

	
675
    ///Return the level of the highest active item or -1 if there is no active
676
    ///item.
677
    int highestActiveLevel() const {
678
      return _highest_active;
679
    }
680

	
681
    ///Lift the highest active item by one.
682

	
683
    ///Lift the item returned by highestActive() by one.
684
    ///
685
    void liftHighestActive() {
686
      Item i = _first[_highest_active];
687
      if (_next[i] != INVALID) {
688
        _prev[_next[i]] = INVALID;
689
        _first[_highest_active] = _next[i];
690
      } else {
691
        _first[_highest_active] = INVALID;
692
        _last[_highest_active] = INVALID;
693
      }
694
      _level[i] = ++_highest_active;
695
      if (_first[_highest_active] == INVALID) {
696
        _first[_highest_active] = i;
697
        _last[_highest_active] = i;
698
        _prev[i] = INVALID;
699
        _next[i] = INVALID;
700
      } else {
701
        _prev[_first[_highest_active]] = i;
702
        _next[i] = _first[_highest_active];
703
        _first[_highest_active] = i;
704
      }
705
    }
706

	
707
    ///Lift the highest active item to the given level.
708

	
709
    ///Lift the item returned by highestActive() to level \c new_level.
710
    ///
711
    ///\warning \c new_level must be strictly higher
712
    ///than the current level.
713
    ///
714
    void liftHighestActive(int new_level) {
715
      Item i = _first[_highest_active];
716
      if (_next[i] != INVALID) {
717
        _prev[_next[i]] = INVALID;
718
        _first[_highest_active] = _next[i];
719
      } else {
720
        _first[_highest_active] = INVALID;
721
        _last[_highest_active] = INVALID;
722
      }
723
      _level[i] = _highest_active = new_level;
724
      if (_first[_highest_active] == INVALID) {
725
        _first[_highest_active] = _last[_highest_active] = i;
726
        _prev[i] = INVALID;
727
        _next[i] = INVALID;
728
      } else {
729
        _prev[_first[_highest_active]] = i;
730
        _next[i] = _first[_highest_active];
731
        _first[_highest_active] = i;
732
      }
733
    }
734

	
735
    ///Lift the highest active item to the top level.
736

	
737
    ///Lift the item returned by highestActive() to the top level and
738
    ///deactivate it.
739
    void liftHighestActiveToTop() {
740
      Item i = _first[_highest_active];
741
      _level[i] = _max_level;
742
      if (_next[i] != INVALID) {
743
        _prev[_next[i]] = INVALID;
744
        _first[_highest_active] = _next[i];
745
      } else {
746
        _first[_highest_active] = INVALID;
747
        _last[_highest_active] = INVALID;
748
      }
749
      while (_highest_active >= 0 && activeFree(_highest_active))
750
        --_highest_active;
751
    }
752

	
753
    ///@}
754

	
755
    ///\name Active Item on Certain Level
756
    ///Functions for working with the active items.
757

	
758
    ///@{
759

	
760
    ///Return an active item on level \c l.
761

	
762
    ///Return an active item on level \c l or \ref INVALID if there is no such
763
    ///an item. (\c l must be from the range [0...\c max_level].
764
    Item activeOn(int l) const
765
    {
766
      return _active[_first[l]] ? _first[l] : INVALID;
767
    }
768

	
769
    ///Lift the active item returned by \c activeOn(l) by one.
770

	
771
    ///Lift the active item returned by \ref activeOn() "activeOn(l)"
772
    ///by one.
773
    Item liftActiveOn(int l)
774
    {
775
      Item i = _first[l];
776
      if (_next[i] != INVALID) {
777
        _prev[_next[i]] = INVALID;
778
        _first[l] = _next[i];
779
      } else {
780
        _first[l] = INVALID;
781
        _last[l] = INVALID;
782
      }
783
      _level[i] = ++l;
784
      if (_first[l] == INVALID) {
785
        _first[l] = _last[l] = i;
786
        _prev[i] = INVALID;
787
        _next[i] = INVALID;
788
      } else {
789
        _prev[_first[l]] = i;
790
        _next[i] = _first[l];
791
        _first[l] = i;
792
      }
793
      if (_highest_active < l) {
794
        _highest_active = l;
795
      }
796
    }
797

	
798
    ///Lift the active item returned by \c activeOn(l) to the given level.
799

	
800
    ///Lift the active item returned by \ref activeOn() "activeOn(l)"
801
    ///to the given level.
802
    void liftActiveOn(int l, int new_level)
803
    {
804
      Item i = _first[l];
805
      if (_next[i] != INVALID) {
806
        _prev[_next[i]] = INVALID;
807
        _first[l] = _next[i];
808
      } else {
809
        _first[l] = INVALID;
810
        _last[l] = INVALID;
811
      }
812
      _level[i] = l = new_level;
813
      if (_first[l] == INVALID) {
814
        _first[l] = _last[l] = i;
815
        _prev[i] = INVALID;
816
        _next[i] = INVALID;
817
      } else {
818
        _prev[_first[l]] = i;
819
        _next[i] = _first[l];
820
        _first[l] = i;
821
      }
822
      if (_highest_active < l) {
823
        _highest_active = l;
824
      }
825
    }
826

	
827
    ///Lift the active item returned by \c activeOn(l) to the top level.
828

	
829
    ///Lift the active item returned by \ref activeOn() "activeOn(l)"
830
    ///to the top level and deactivate it.
831
    void liftActiveToTop(int l)
832
    {
833
      Item i = _first[l];
834
      if (_next[i] != INVALID) {
835
        _prev[_next[i]] = INVALID;
836
        _first[l] = _next[i];
837
      } else {
838
        _first[l] = INVALID;
839
        _last[l] = INVALID;
840
      }
841
      _level[i] = _max_level;
842
      if (l == _highest_active) {
843
        while (_highest_active >= 0 && activeFree(_highest_active))
844
          --_highest_active;
845
      }
846
    }
847

	
848
    ///@}
849

	
850
    /// \brief Lift an active item to a higher level.
851
    ///
852
    /// Lift an active item to a higher level.
853
    /// \param i The item to be lifted. It must be active.
854
    /// \param new_level The new level of \c i. It must be strictly higher
855
    /// than the current level.
856
    ///
857
    void lift(Item i, int new_level) {
858
      if (_next[i] != INVALID) {
859
        _prev[_next[i]] = _prev[i];
860
      } else {
861
        _last[new_level] = _prev[i];
862
      }
863
      if (_prev[i] != INVALID) {
864
        _next[_prev[i]] = _next[i];
865
      } else {
866
        _first[new_level] = _next[i];
867
      }
868
      _level[i] = new_level;
869
      if (_first[new_level] == INVALID) {
870
        _first[new_level] = _last[new_level] = i;
871
        _prev[i] = INVALID;
872
        _next[i] = INVALID;
873
      } else {
874
        _prev[_first[new_level]] = i;
875
        _next[i] = _first[new_level];
876
        _first[new_level] = i;
877
      }
878
      if (_highest_active < new_level) {
879
        _highest_active = new_level;
880
      }
881
    }
882

	
883
    ///Move an inactive item to the top but one level (in a dirty way).
884

	
885
    ///This function moves an inactive item from the top level to the top
886
    ///but one level (in a dirty way).
887
    ///\warning It makes the underlying datastructure corrupt, so use it
888
    ///only if you really know what it is for.
889
    ///\pre The item is on the top level.
890
    void dirtyTopButOne(Item i) {
891
      _level[i] = _max_level - 1;
892
    }
893

	
894
    ///Lift all items on and above the given level to the top level.
895

	
896
    ///This function lifts all items on and above level \c l to the top
897
    ///level and deactivates them.
898
    void liftToTop(int l)  {
899
      for (int i = l + 1; _first[i] != INVALID; ++i) {
900
        Item n = _first[i];
901
        while (n != INVALID) {
902
          _level[n] = _max_level;
903
          n = _next[n];
904
        }
905
        _first[i] = INVALID;
906
        _last[i] = INVALID;
907
      }
908
      if (_highest_active > l - 1) {
909
        _highest_active = l - 1;
910
        while (_highest_active >= 0 && activeFree(_highest_active))
911
          --_highest_active;
912
      }
913
    }
914

	
915
  private:
916

	
917
    int _init_level;
918

	
919
  public:
920

	
921
    ///\name Initialization
922
    ///Using these functions you can initialize the levels of the items.
923
    ///\n
924
    ///The initialization must be started with calling \c initStart().
925
    ///Then the items should be listed level by level starting with the
926
    ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
927
    ///Finally \c initFinish() must be called.
928
    ///The items not listed are put on the highest level.
929
    ///@{
930

	
931
    ///Start the initialization process.
932
    void initStart() {
933

	
934
      for (int i = 0; i <= _max_level; ++i) {
935
        _first[i] = _last[i] = INVALID;
936
      }
937
      _init_level = 0;
938
      for(typename ItemSetTraits<GR,Item>::ItemIt i(_graph);
939
          i != INVALID; ++i) {
940
        _level[i] = _max_level;
941
        _active[i] = false;
942
      }
943
    }
944

	
945
    ///Add an item to the current level.
946
    void initAddItem(Item i) {
947
      _level[i] = _init_level;
948
      if (_last[_init_level] == INVALID) {
949
        _first[_init_level] = i;
950
        _last[_init_level] = i;
951
        _prev[i] = INVALID;
952
        _next[i] = INVALID;
953
      } else {
954
        _prev[i] = _last[_init_level];
955
        _next[i] = INVALID;
956
        _next[_last[_init_level]] = i;
957
        _last[_init_level] = i;
958
      }
959
    }
960

	
961
    ///Start a new level.
962

	
963
    ///Start a new level.
964
    ///It shouldn't be used before the items on level 0 are listed.
965
    void initNewLevel() {
966
      ++_init_level;
967
    }
968

	
969
    ///Finalize the initialization process.
970
    void initFinish() {
971
      _highest_active = -1;
972
    }
973

	
974
    ///@}
975

	
976
  };
977

	
978

	
979
} //END OF NAMESPACE LEMON
980

	
981
#endif
982

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

	
19
#ifndef LEMON_EULER_H
20
#define LEMON_EULER_H
21

	
22
#include<lemon/core.h>
23
#include<lemon/adaptors.h>
24
#include<lemon/connectivity.h>
25
#include <list>
26

	
27
/// \ingroup graph_properties
28
/// \file
29
/// \brief Euler tour iterators and a function for checking the \e Eulerian 
30
/// property.
31
///
32
///This file provides Euler tour iterators and a function to check
33
///if a (di)graph is \e Eulerian.
34

	
35
namespace lemon {
36

	
37
  ///Euler tour iterator for digraphs.
38

	
39
  /// \ingroup graph_prop
40
  ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed
41
  ///graph (if there exists) and it converts to the \c Arc type of the digraph.
42
  ///
43
  ///For example, if the given digraph has an Euler tour (i.e it has only one
44
  ///non-trivial component and the in-degree is equal to the out-degree 
45
  ///for all nodes), then the following code will put the arcs of \c g
46
  ///to the vector \c et according to an Euler tour of \c g.
47
  ///\code
48
  ///  std::vector<ListDigraph::Arc> et;
49
  ///  for(DiEulerIt<ListDigraph> e(g); e!=INVALID; ++e)
50
  ///    et.push_back(e);
51
  ///\endcode
52
  ///If \c g has no Euler tour, then the resulted walk will not be closed
53
  ///or not contain all arcs.
54
  ///\sa EulerIt
55
  template<typename GR>
56
  class DiEulerIt
57
  {
58
    typedef typename GR::Node Node;
59
    typedef typename GR::NodeIt NodeIt;
60
    typedef typename GR::Arc Arc;
61
    typedef typename GR::ArcIt ArcIt;
62
    typedef typename GR::OutArcIt OutArcIt;
63
    typedef typename GR::InArcIt InArcIt;
64

	
65
    const GR &g;
66
    typename GR::template NodeMap<OutArcIt> narc;
67
    std::list<Arc> euler;
68

	
69
  public:
70

	
71
    ///Constructor
72

	
73
    ///Constructor.
74
    ///\param gr A digraph.
75
    ///\param start The starting point of the tour. If it is not given,
76
    ///the tour will start from the first node that has an outgoing arc.
77
    DiEulerIt(const GR &gr, typename GR::Node start = INVALID)
78
      : g(gr), narc(g)
79
    {
80
      if (start==INVALID) {
81
        NodeIt n(g);
82
        while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
83
        start=n;
84
      }
85
      if (start!=INVALID) {
86
        for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
87
        while (narc[start]!=INVALID) {
88
          euler.push_back(narc[start]);
89
          Node next=g.target(narc[start]);
90
          ++narc[start];
91
          start=next;
92
        }
93
      }
94
    }
95

	
96
    ///Arc conversion
97
    operator Arc() { return euler.empty()?INVALID:euler.front(); }
98
    ///Compare with \c INVALID
99
    bool operator==(Invalid) { return euler.empty(); }
100
    ///Compare with \c INVALID
101
    bool operator!=(Invalid) { return !euler.empty(); }
102

	
103
    ///Next arc of the tour
104

	
105
    ///Next arc of the tour
106
    ///
107
    DiEulerIt &operator++() {
108
      Node s=g.target(euler.front());
109
      euler.pop_front();
110
      typename std::list<Arc>::iterator next=euler.begin();
111
      while(narc[s]!=INVALID) {
112
        euler.insert(next,narc[s]);
113
        Node n=g.target(narc[s]);
114
        ++narc[s];
115
        s=n;
116
      }
117
      return *this;
118
    }
119
    ///Postfix incrementation
120

	
121
    /// Postfix incrementation.
122
    ///
123
    ///\warning This incrementation
124
    ///returns an \c Arc, not a \ref DiEulerIt, as one may
125
    ///expect.
126
    Arc operator++(int)
127
    {
128
      Arc e=*this;
129
      ++(*this);
130
      return e;
131
    }
132
  };
133

	
134
  ///Euler tour iterator for graphs.
135

	
136
  /// \ingroup graph_properties
137
  ///This iterator provides an Euler tour (Eulerian circuit) of an
138
  ///\e undirected graph (if there exists) and it converts to the \c Arc
139
  ///and \c Edge types of the graph.
140
  ///
141
  ///For example, if the given graph has an Euler tour (i.e it has only one 
142
  ///non-trivial component and the degree of each node is even),
143
  ///the following code will print the arc IDs according to an
144
  ///Euler tour of \c g.
145
  ///\code
146
  ///  for(EulerIt<ListGraph> e(g); e!=INVALID; ++e) {
147
  ///    std::cout << g.id(Edge(e)) << std::eol;
148
  ///  }
149
  ///\endcode
150
  ///Although this iterator is for undirected graphs, it still returns 
151
  ///arcs in order to indicate the direction of the tour.
152
  ///(But arcs convert to edges, of course.)
153
  ///
154
  ///If \c g has no Euler tour, then the resulted walk will not be closed
155
  ///or not contain all edges.
156
  template<typename GR>
157
  class EulerIt
158
  {
159
    typedef typename GR::Node Node;
160
    typedef typename GR::NodeIt NodeIt;
161
    typedef typename GR::Arc Arc;
162
    typedef typename GR::Edge Edge;
163
    typedef typename GR::ArcIt ArcIt;
164
    typedef typename GR::OutArcIt OutArcIt;
165
    typedef typename GR::InArcIt InArcIt;
166

	
167
    const GR &g;
168
    typename GR::template NodeMap<OutArcIt> narc;
169
    typename GR::template EdgeMap<bool> visited;
170
    std::list<Arc> euler;
171

	
172
  public:
173

	
174
    ///Constructor
175

	
176
    ///Constructor.
177
    ///\param gr A graph.
178
    ///\param start The starting point of the tour. If it is not given,
179
    ///the tour will start from the first node that has an incident edge.
180
    EulerIt(const GR &gr, typename GR::Node start = INVALID)
181
      : g(gr), narc(g), visited(g, false)
182
    {
183
      if (start==INVALID) {
184
        NodeIt n(g);
185
        while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
186
        start=n;
187
      }
188
      if (start!=INVALID) {
189
        for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
190
        while(narc[start]!=INVALID) {
191
          euler.push_back(narc[start]);
192
          visited[narc[start]]=true;
193
          Node next=g.target(narc[start]);
194
          ++narc[start];
195
          start=next;
196
          while(narc[start]!=INVALID && visited[narc[start]]) ++narc[start];
197
        }
198
      }
199
    }
200

	
201
    ///Arc conversion
202
    operator Arc() const { return euler.empty()?INVALID:euler.front(); }
203
    ///Edge conversion
204
    operator Edge() const { return euler.empty()?INVALID:euler.front(); }
205
    ///Compare with \c INVALID
206
    bool operator==(Invalid) const { return euler.empty(); }
207
    ///Compare with \c INVALID
208
    bool operator!=(Invalid) const { return !euler.empty(); }
209

	
210
    ///Next arc of the tour
211

	
212
    ///Next arc of the tour
213
    ///
214
    EulerIt &operator++() {
215
      Node s=g.target(euler.front());
216
      euler.pop_front();
217
      typename std::list<Arc>::iterator next=euler.begin();
218
      while(narc[s]!=INVALID) {
219
        while(narc[s]!=INVALID && visited[narc[s]]) ++narc[s];
220
        if(narc[s]==INVALID) break;
221
        else {
222
          euler.insert(next,narc[s]);
223
          visited[narc[s]]=true;
224
          Node n=g.target(narc[s]);
225
          ++narc[s];
226
          s=n;
227
        }
228
      }
229
      return *this;
230
    }
231

	
232
    ///Postfix incrementation
233

	
234
    /// Postfix incrementation.
235
    ///
236
    ///\warning This incrementation returns an \c Arc (which converts to 
237
    ///an \c Edge), not an \ref EulerIt, as one may expect.
238
    Arc operator++(int)
239
    {
240
      Arc e=*this;
241
      ++(*this);
242
      return e;
243
    }
244
  };
245

	
246

	
247
  ///Check if the given graph is Eulerian
248

	
249
  /// \ingroup graph_properties
250
  ///This function checks if the given graph is Eulerian.
251
  ///It works for both directed and undirected graphs.
252
  ///
253
  ///By definition, a digraph is called \e Eulerian if
254
  ///and only if it is connected and the number of incoming and outgoing
255
  ///arcs are the same for each node.
256
  ///Similarly, an undirected graph is called \e Eulerian if
257
  ///and only if it is connected and the number of incident edges is even
258
  ///for each node.
259
  ///
260
  ///\note There are (di)graphs that are not Eulerian, but still have an
261
  /// Euler tour, since they may contain isolated nodes.
262
  ///
263
  ///\sa DiEulerIt, EulerIt
264
  template<typename GR>
265
#ifdef DOXYGEN
266
  bool
267
#else
268
  typename enable_if<UndirectedTagIndicator<GR>,bool>::type
269
  eulerian(const GR &g)
270
  {
271
    for(typename GR::NodeIt n(g);n!=INVALID;++n)
272
      if(countIncEdges(g,n)%2) return false;
273
    return connected(g);
274
  }
275
  template<class GR>
276
  typename disable_if<UndirectedTagIndicator<GR>,bool>::type
277
#endif
278
  eulerian(const GR &g)
279
  {
280
    for(typename GR::NodeIt n(g);n!=INVALID;++n)
281
      if(countInArcs(g,n)!=countOutArcs(g,n)) return false;
282
    return connected(undirector(g));
283
  }
284

	
285
}
286

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

	
19
#ifndef LEMON_FIB_HEAP_H
20
#define LEMON_FIB_HEAP_H
21

	
22
///\file
23
///\ingroup auxdat
24
///\brief Fibonacci Heap implementation.
25

	
26
#include <vector>
27
#include <functional>
28
#include <lemon/math.h>
29

	
30
namespace lemon {
31

	
32
  /// \ingroup auxdat
33
  ///
34
  ///\brief Fibonacci Heap.
35
  ///
36
  ///This class implements the \e Fibonacci \e heap data structure. A \e heap
37
  ///is a data structure for storing items with specified values called \e
38
  ///priorities in such a way that finding the item with minimum priority is
39
  ///efficient. \c CMP specifies the ordering of the priorities. In a heap
40
  ///one can change the priority of an item, add or erase an item, etc.
41
  ///
42
  ///The methods \ref increase and \ref erase are not efficient in a Fibonacci
43
  ///heap. In case of many calls to these operations, it is better to use a
44
  ///\ref BinHeap "binary heap".
45
  ///
46
  ///\param PRIO Type of the priority of the items.
47
  ///\param IM A read and writable Item int map, used internally
48
  ///to handle the cross references.
49
  ///\param CMP A class for the ordering of the priorities. The
50
  ///default is \c std::less<PRIO>.
51
  ///
52
  ///\sa BinHeap
53
  ///\sa Dijkstra
54
#ifdef DOXYGEN
55
  template <typename PRIO, typename IM, typename CMP>
56
#else
57
  template <typename PRIO, typename IM, typename CMP = std::less<PRIO> >
58
#endif
59
  class FibHeap {
60
  public:
61
    ///\e
62
    typedef IM ItemIntMap;
63
    ///\e
64
    typedef PRIO Prio;
65
    ///\e
66
    typedef typename ItemIntMap::Key Item;
67
    ///\e
68
    typedef std::pair<Item,Prio> Pair;
69
    ///\e
70
    typedef CMP Compare;
71

	
72
  private:
73
    class Store;
74

	
75
    std::vector<Store> _data;
76
    int _minimum;
77
    ItemIntMap &_iim;
78
    Compare _comp;
79
    int _num;
80

	
81
  public:
82

	
83
    /// \brief Type to represent the items states.
84
    ///
85
    /// Each Item element have a state associated to it. It may be "in heap",
86
    /// "pre heap" or "post heap". The latter two are indifferent from the
87
    /// heap's point of view, but may be useful to the user.
88
    ///
89
    /// The item-int map must be initialized in such way that it assigns
90
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
91
    enum State {
92
      IN_HEAP = 0,    ///< = 0.
93
      PRE_HEAP = -1,  ///< = -1.
94
      POST_HEAP = -2  ///< = -2.
95
    };
96

	
97
    /// \brief The constructor
98
    ///
99
    /// \c map should be given to the constructor, since it is
100
    ///   used internally to handle the cross references.
101
    explicit FibHeap(ItemIntMap &map)
102
      : _minimum(0), _iim(map), _num() {}
103

	
104
    /// \brief The constructor
105
    ///
106
    /// \c map should be given to the constructor, since it is used
107
    /// internally to handle the cross references. \c comp is an
108
    /// object for ordering of the priorities.
109
    FibHeap(ItemIntMap &map, const Compare &comp)
110
      : _minimum(0), _iim(map), _comp(comp), _num() {}
111

	
112
    /// \brief The number of items stored in the heap.
113
    ///
114
    /// Returns the number of items stored in the heap.
115
    int size() const { return _num; }
116

	
117
    /// \brief Checks if the heap stores no items.
118
    ///
119
    ///   Returns \c true if and only if the heap stores no items.
120
    bool empty() const { return _num==0; }
121

	
122
    /// \brief Make empty this heap.
123
    ///
124
    /// Make empty this heap. It does not change the cross reference
125
    /// map.  If you want to reuse a heap what is not surely empty you
126
    /// should first clear the heap and after that you should set the
127
    /// cross reference map for each item to \c PRE_HEAP.
128
    void clear() {
129
      _data.clear(); _minimum = 0; _num = 0;
130
    }
131

	
132
    /// \brief \c item gets to the heap with priority \c value independently
133
    /// if \c item was already there.
134
    ///
135
    /// This method calls \ref push(\c item, \c value) if \c item is not
136
    /// stored in the heap and it calls \ref decrease(\c item, \c value) or
137
    /// \ref increase(\c item, \c value) otherwise.
138
    void set (const Item& item, const Prio& value) {
139
      int i=_iim[item];
140
      if ( i >= 0 && _data[i].in ) {
141
        if ( _comp(value, _data[i].prio) ) decrease(item, value);
142
        if ( _comp(_data[i].prio, value) ) increase(item, value);
143
      } else push(item, value);
144
    }
145

	
146
    /// \brief Adds \c item to the heap with priority \c value.
147
    ///
148
    /// Adds \c item to the heap with priority \c value.
149
    /// \pre \c item must not be stored in the heap.
150
    void push (const Item& item, const Prio& value) {
151
      int i=_iim[item];
152
      if ( i < 0 ) {
153
        int s=_data.size();
154
        _iim.set( item, s );
155
        Store st;
156
        st.name=item;
157
        _data.push_back(st);
158
        i=s;
159
      } else {
160
        _data[i].parent=_data[i].child=-1;
161
        _data[i].degree=0;
162
        _data[i].in=true;
163
        _data[i].marked=false;
164
      }
165

	
166
      if ( _num ) {
167
        _data[_data[_minimum].right_neighbor].left_neighbor=i;
168
        _data[i].right_neighbor=_data[_minimum].right_neighbor;
169
        _data[_minimum].right_neighbor=i;
170
        _data[i].left_neighbor=_minimum;
171
        if ( _comp( value, _data[_minimum].prio) ) _minimum=i;
172
      } else {
173
        _data[i].right_neighbor=_data[i].left_neighbor=i;
174
        _minimum=i;
175
      }
176
      _data[i].prio=value;
177
      ++_num;
178
    }
179

	
180
    /// \brief Returns the item with minimum priority relative to \c Compare.
181
    ///
182
    /// This method returns the item with minimum priority relative to \c
183
    /// Compare.
184
    /// \pre The heap must be nonempty.
185
    Item top() const { return _data[_minimum].name; }
186

	
187
    /// \brief Returns the minimum priority relative to \c Compare.
188
    ///
189
    /// It returns the minimum priority relative to \c Compare.
190
    /// \pre The heap must be nonempty.
191
    const Prio& prio() const { return _data[_minimum].prio; }
192

	
193
    /// \brief Returns the priority of \c item.
194
    ///
195
    /// It returns the priority of \c item.
196
    /// \pre \c item must be in the heap.
197
    const Prio& operator[](const Item& item) const {
198
      return _data[_iim[item]].prio;
199
    }
200

	
201
    /// \brief Deletes the item with minimum priority relative to \c Compare.
202
    ///
203
    /// This method deletes the item with minimum priority relative to \c
204
    /// Compare from the heap.
205
    /// \pre The heap must be non-empty.
206
    void pop() {
207
      /*The first case is that there are only one root.*/
208
      if ( _data[_minimum].left_neighbor==_minimum ) {
209
        _data[_minimum].in=false;
210
        if ( _data[_minimum].degree!=0 ) {
211
          makeroot(_data[_minimum].child);
212
          _minimum=_data[_minimum].child;
213
          balance();
214
        }
215
      } else {
216
        int right=_data[_minimum].right_neighbor;
217
        unlace(_minimum);
218
        _data[_minimum].in=false;
219
        if ( _data[_minimum].degree > 0 ) {
220
          int left=_data[_minimum].left_neighbor;
221
          int child=_data[_minimum].child;
222
          int last_child=_data[child].left_neighbor;
223

	
224
          makeroot(child);
225

	
226
          _data[left].right_neighbor=child;
227
          _data[child].left_neighbor=left;
228
          _data[right].left_neighbor=last_child;
229
          _data[last_child].right_neighbor=right;
230
        }
231
        _minimum=right;
232
        balance();
233
      } // the case where there are more roots
234
      --_num;
235
    }
236

	
237
    /// \brief Deletes \c item from the heap.
238
    ///
239
    /// This method deletes \c item from the heap, if \c item was already
240
    /// stored in the heap. It is quite inefficient in Fibonacci heaps.
241
    void erase (const Item& item) {
242
      int i=_iim[item];
243

	
244
      if ( i >= 0 && _data[i].in ) {
245
        if ( _data[i].parent!=-1 ) {
246
          int p=_data[i].parent;
247
          cut(i,p);
248
          cascade(p);
249
        }
250
        _minimum=i;     //As if its prio would be -infinity
251
        pop();
252
      }
253
    }
254

	
255
    /// \brief Decreases the priority of \c item to \c value.
256
    ///
257
    /// This method decreases the priority of \c item to \c value.
258
    /// \pre \c item must be stored in the heap with priority at least \c
259
    ///   value relative to \c Compare.
260
    void decrease (Item item, const Prio& value) {
261
      int i=_iim[item];
262
      _data[i].prio=value;
263
      int p=_data[i].parent;
264

	
265
      if ( p!=-1 && _comp(value, _data[p].prio) ) {
266
        cut(i,p);
267
        cascade(p);
268
      }
269
      if ( _comp(value, _data[_minimum].prio) ) _minimum=i;
270
    }
271

	
272
    /// \brief Increases the priority of \c item to \c value.
273
    ///
274
    /// This method sets the priority of \c item to \c value. Though
275
    /// there is no precondition on the priority of \c item, this
276
    /// method should be used only if it is indeed necessary to increase
277
    /// (relative to \c Compare) the priority of \c item, because this
278
    /// method is inefficient.
279
    void increase (Item item, const Prio& value) {
280
      erase(item);
281
      push(item, value);
282
    }
283

	
284

	
285
    /// \brief Returns if \c item is in, has already been in, or has never
286
    /// been in the heap.
287
    ///
288
    /// This method returns PRE_HEAP if \c item has never been in the
289
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
290
    /// otherwise. In the latter case it is possible that \c item will
291
    /// get back to the heap again.
292
    State state(const Item &item) const {
293
      int i=_iim[item];
294
      if( i>=0 ) {
295
        if ( _data[i].in ) i=0;
296
        else i=-2;
297
      }
298
      return State(i);
299
    }
300

	
301
    /// \brief Sets the state of the \c item in the heap.
302
    ///
303
    /// Sets the state of the \c item in the heap. It can be used to
304
    /// manually clear the heap when it is important to achive the
305
    /// better time _complexity.
306
    /// \param i The item.
307
    /// \param st The state. It should not be \c IN_HEAP.
308
    void state(const Item& i, State st) {
309
      switch (st) {
310
      case POST_HEAP:
311
      case PRE_HEAP:
312
        if (state(i) == IN_HEAP) {
313
          erase(i);
314
        }
315
        _iim[i] = st;
316
        break;
317
      case IN_HEAP:
318
        break;
319
      }
320
    }
321

	
322
  private:
323

	
324
    void balance() {
325

	
326
      int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
327

	
328
      std::vector<int> A(maxdeg,-1);
329

	
330
      /*
331
       *Recall that now minimum does not point to the minimum prio element.
332
       *We set minimum to this during balance().
333
       */
334
      int anchor=_data[_minimum].left_neighbor;
335
      int next=_minimum;
336
      bool end=false;
337

	
338
      do {
339
        int active=next;
340
        if ( anchor==active ) end=true;
341
        int d=_data[active].degree;
342
        next=_data[active].right_neighbor;
343

	
344
        while (A[d]!=-1) {
345
          if( _comp(_data[active].prio, _data[A[d]].prio) ) {
346
            fuse(active,A[d]);
347
          } else {
348
            fuse(A[d],active);
349
            active=A[d];
350
          }
351
          A[d]=-1;
352
          ++d;
353
        }
354
        A[d]=active;
355
      } while ( !end );
356

	
357

	
358
      while ( _data[_minimum].parent >=0 )
359
        _minimum=_data[_minimum].parent;
360
      int s=_minimum;
361
      int m=_minimum;
362
      do {
363
        if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
364
        s=_data[s].right_neighbor;
365
      } while ( s != m );
366
    }
367

	
368
    void makeroot(int c) {
369
      int s=c;
370
      do {
371
        _data[s].parent=-1;
372
        s=_data[s].right_neighbor;
373
      } while ( s != c );
374
    }
375

	
376
    void cut(int a, int b) {
377
      /*
378
       *Replacing a from the children of b.
379
       */
380
      --_data[b].degree;
381

	
382
      if ( _data[b].degree !=0 ) {
383
        int child=_data[b].child;
384
        if ( child==a )
385
          _data[b].child=_data[child].right_neighbor;
386
        unlace(a);
387
      }
388

	
389

	
390
      /*Lacing a to the roots.*/
391
      int right=_data[_minimum].right_neighbor;
392
      _data[_minimum].right_neighbor=a;
393
      _data[a].left_neighbor=_minimum;
394
      _data[a].right_neighbor=right;
395
      _data[right].left_neighbor=a;
396

	
397
      _data[a].parent=-1;
398
      _data[a].marked=false;
399
    }
400

	
401
    void cascade(int a) {
402
      if ( _data[a].parent!=-1 ) {
403
        int p=_data[a].parent;
404

	
405
        if ( _data[a].marked==false ) _data[a].marked=true;
406
        else {
407
          cut(a,p);
408
          cascade(p);
409
        }
410
      }
411
    }
412

	
413
    void fuse(int a, int b) {
414
      unlace(b);
415

	
416
      /*Lacing b under a.*/
417
      _data[b].parent=a;
418

	
419
      if (_data[a].degree==0) {
420
        _data[b].left_neighbor=b;
421
        _data[b].right_neighbor=b;
422
        _data[a].child=b;
423
      } else {
424
        int child=_data[a].child;
425
        int last_child=_data[child].left_neighbor;
426
        _data[child].left_neighbor=b;
427
        _data[b].right_neighbor=child;
428
        _data[last_child].right_neighbor=b;
429
        _data[b].left_neighbor=last_child;
430
      }
431

	
432
      ++_data[a].degree;
433

	
434
      _data[b].marked=false;
435
    }
436

	
437
    /*
438
     *It is invoked only if a has siblings.
439
     */
440
    void unlace(int a) {
441
      int leftn=_data[a].left_neighbor;
442
      int rightn=_data[a].right_neighbor;
443
      _data[leftn].right_neighbor=rightn;
444
      _data[rightn].left_neighbor=leftn;
445
    }
446

	
447

	
448
    class Store {
449
      friend class FibHeap;
450

	
451
      Item name;
452
      int parent;
453
      int left_neighbor;
454
      int right_neighbor;
455
      int child;
456
      int degree;
457
      bool marked;
458
      bool in;
459
      Prio prio;
460

	
461
      Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
462
    };
463
  };
464

	
465
} //namespace lemon
466

	
467
#endif //LEMON_FIB_HEAP_H
468

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

	
19
#ifndef LEMON_FULL_GRAPH_H
20
#define LEMON_FULL_GRAPH_H
21

	
22
#include <lemon/core.h>
23
#include <lemon/bits/graph_extender.h>
24

	
25
///\ingroup graphs
26
///\file
27
///\brief FullGraph and FullDigraph classes.
28

	
29
namespace lemon {
30

	
31
  class FullDigraphBase {
32
  public:
33

	
34
    typedef FullDigraphBase Digraph;
35

	
36
    class Node;
37
    class Arc;
38

	
39
  protected:
40

	
41
    int _node_num;
42
    int _arc_num;
43

	
44
    FullDigraphBase() {}
45

	
46
    void construct(int n) { _node_num = n; _arc_num = n * n; }
47

	
48
  public:
49

	
50
    typedef True NodeNumTag;
51
    typedef True ArcNumTag;
52

	
53
    Node operator()(int ix) const { return Node(ix); }
54
    int index(const Node& node) const { return node._id; }
55

	
56
    Arc arc(const Node& s, const Node& t) const {
57
      return Arc(s._id * _node_num + t._id);
58
    }
59

	
60
    int nodeNum() const { return _node_num; }
61
    int arcNum() const { return _arc_num; }
62

	
63
    int maxNodeId() const { return _node_num - 1; }
64
    int maxArcId() const { return _arc_num - 1; }
65

	
66
    Node source(Arc arc) const { return arc._id / _node_num; }
67
    Node target(Arc arc) const { return arc._id % _node_num; }
68

	
69
    static int id(Node node) { return node._id; }
70
    static int id(Arc arc) { return arc._id; }
71

	
72
    static Node nodeFromId(int id) { return Node(id);}
73
    static Arc arcFromId(int id) { return Arc(id);}
74

	
75
    typedef True FindArcTag;
76

	
77
    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
78
      return prev == INVALID ? arc(s, t) : INVALID;
79
    }
80

	
81
    class Node {
82
      friend class FullDigraphBase;
83

	
84
    protected:
85
      int _id;
86
      Node(int id) : _id(id) {}
87
    public:
88
      Node() {}
89
      Node (Invalid) : _id(-1) {}
90
      bool operator==(const Node node) const {return _id == node._id;}
91
      bool operator!=(const Node node) const {return _id != node._id;}
92
      bool operator<(const Node node) const {return _id < node._id;}
93
    };
94

	
95
    class Arc {
96
      friend class FullDigraphBase;
97

	
98
    protected:
99
      int _id;  // _node_num * source + target;
100

	
101
      Arc(int id) : _id(id) {}
102

	
103
    public:
104
      Arc() { }
105
      Arc (Invalid) { _id = -1; }
106
      bool operator==(const Arc arc) const {return _id == arc._id;}
107
      bool operator!=(const Arc arc) const {return _id != arc._id;}
108
      bool operator<(const Arc arc) const {return _id < arc._id;}
109
    };
110

	
111
    void first(Node& node) const {
112
      node._id = _node_num - 1;
113
    }
114

	
115
    static void next(Node& node) {
116
      --node._id;
117
    }
118

	
119
    void first(Arc& arc) const {
120
      arc._id = _arc_num - 1;
121
    }
122

	
123
    static void next(Arc& arc) {
124
      --arc._id;
125
    }
126

	
127
    void firstOut(Arc& arc, const Node& node) const {
128
      arc._id = (node._id + 1) * _node_num - 1;
129
    }
130

	
131
    void nextOut(Arc& arc) const {
132
      if (arc._id % _node_num == 0) arc._id = 0;
133
      --arc._id;
134
    }
135

	
136
    void firstIn(Arc& arc, const Node& node) const {
137
      arc._id = _arc_num + node._id - _node_num;
138
    }
139

	
140
    void nextIn(Arc& arc) const {
141
      arc._id -= _node_num;
142
      if (arc._id < 0) arc._id = -1;
143
    }
144

	
145
  };
146

	
147
  typedef DigraphExtender<FullDigraphBase> ExtendedFullDigraphBase;
148

	
149
  /// \ingroup graphs
150
  ///
151
  /// \brief A full digraph class.
152
  ///
153
  /// This is a simple and fast directed full graph implementation.
154
  /// From each node go arcs to each node (including the source node),
155
  /// therefore the number of the arcs in the digraph is the square of
156
  /// the node number. This digraph type is completely static, so you
157
  /// can neither add nor delete either arcs or nodes, and it needs
158
  /// constant space in memory.
159
  ///
160
  /// This class fully conforms to the \ref concepts::Digraph
161
  /// "Digraph concept".
162
  ///
163
  /// The \c FullDigraph and \c FullGraph classes are very similar,
164
  /// but there are two differences. While this class conforms only
165
  /// to the \ref concepts::Digraph "Digraph" concept, the \c FullGraph
166
  /// class conforms to the \ref concepts::Graph "Graph" concept,
167
  /// moreover \c FullGraph does not contain a loop arc for each
168
  /// node as \c FullDigraph does.
169
  ///
170
  /// \sa FullGraph
171
  class FullDigraph : public ExtendedFullDigraphBase {
172
    typedef ExtendedFullDigraphBase Parent;
173

	
174
  public:
175

	
176
    /// \brief Constructor
177
    FullDigraph() { construct(0); }
178

	
179
    /// \brief Constructor
180
    ///
181
    /// Constructor.
182
    /// \param n The number of the nodes.
183
    FullDigraph(int n) { construct(n); }
184

	
185
    /// \brief Resizes the digraph
186
    ///
187
    /// Resizes the digraph. The function will fully destroy and
188
    /// rebuild the digraph. This cause that the maps of the digraph will
189
    /// reallocated automatically and the previous values will be lost.
190
    void resize(int n) {
191
      Parent::notifier(Arc()).clear();
192
      Parent::notifier(Node()).clear();
193
      construct(n);
194
      Parent::notifier(Node()).build();
195
      Parent::notifier(Arc()).build();
196
    }
197

	
198
    /// \brief Returns the node with the given index.
199
    ///
200
    /// Returns the node with the given index. Since it is a static
201
    /// digraph its nodes can be indexed with integers from the range
202
    /// <tt>[0..nodeNum()-1]</tt>.
203
    /// \sa index()
204
    Node operator()(int ix) const { return Parent::operator()(ix); }
205

	
206
    /// \brief Returns the index of the given node.
207
    ///
208
    /// Returns the index of the given node. Since it is a static
209
    /// digraph its nodes can be indexed with integers from the range
210
    /// <tt>[0..nodeNum()-1]</tt>.
211
    /// \sa operator()
212
    int index(const Node& node) const { return Parent::index(node); }
213

	
214
    /// \brief Returns the arc connecting the given nodes.
215
    ///
216
    /// Returns the arc connecting the given nodes.
217
    Arc arc(const Node& u, const Node& v) const {
218
      return Parent::arc(u, v);
219
    }
220

	
221
    /// \brief Number of nodes.
222
    int nodeNum() const { return Parent::nodeNum(); }
223
    /// \brief Number of arcs.
224
    int arcNum() const { return Parent::arcNum(); }
225
  };
226

	
227

	
228
  class FullGraphBase {
229
  public:
230

	
231
    typedef FullGraphBase Graph;
232

	
233
    class Node;
234
    class Arc;
235
    class Edge;
236

	
237
  protected:
238

	
239
    int _node_num;
240
    int _edge_num;
241

	
242
    FullGraphBase() {}
243

	
244
    void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; }
245

	
246
    int _uid(int e) const {
247
      int u = e / _node_num;
248
      int v = e % _node_num;
249
      return u < v ? u : _node_num - 2 - u;
250
    }
251

	
252
    int _vid(int e) const {
253
      int u = e / _node_num;
254
      int v = e % _node_num;
255
      return u < v ? v : _node_num - 1 - v;
256
    }
257

	
258
    void _uvid(int e, int& u, int& v) const {
259
      u = e / _node_num;
260
      v = e % _node_num;
261
      if  (u >= v) {
262
        u = _node_num - 2 - u;
263
        v = _node_num - 1 - v;
264
      }
265
    }
266

	
267
    void _stid(int a, int& s, int& t) const {
268
      if ((a & 1) == 1) {
269
        _uvid(a >> 1, s, t);
270
      } else {
271
        _uvid(a >> 1, t, s);
272
      }
273
    }
274

	
275
    int _eid(int u, int v) const {
276
      if (u < (_node_num - 1) / 2) {
277
        return u * _node_num + v;
278
      } else {
279
        return (_node_num - 1 - u) * _node_num - v - 1;
280
      }
281
    }
282

	
283
  public:
284

	
285
    Node operator()(int ix) const { return Node(ix); }
286
    int index(const Node& node) const { return node._id; }
287

	
288
    Edge edge(const Node& u, const Node& v) const {
289
      if (u._id < v._id) {
290
        return Edge(_eid(u._id, v._id));
291
      } else if (u._id != v._id) {
292
        return Edge(_eid(v._id, u._id));
293
      } else {
294
        return INVALID;
295
      }
296
    }
297

	
298
    Arc arc(const Node& s, const Node& t) const {
299
      if (s._id < t._id) {
300
        return Arc((_eid(s._id, t._id) << 1) | 1);
301
      } else if (s._id != t._id) {
302
        return Arc(_eid(t._id, s._id) << 1);
303
      } else {
304
        return INVALID;
305
      }
306
    }
307

	
308
    typedef True NodeNumTag;
309
    typedef True ArcNumTag;
310
    typedef True EdgeNumTag;
311

	
312
    int nodeNum() const { return _node_num; }
313
    int arcNum() const { return 2 * _edge_num; }
314
    int edgeNum() const { return _edge_num; }
315

	
316
    static int id(Node node) { return node._id; }
317
    static int id(Arc arc) { return arc._id; }
318
    static int id(Edge edge) { return edge._id; }
319

	
320
    int maxNodeId() const { return _node_num-1; }
321
    int maxArcId() const { return 2 * _edge_num-1; }
322
    int maxEdgeId() const { return _edge_num-1; }
323

	
324
    static Node nodeFromId(int id) { return Node(id);}
325
    static Arc arcFromId(int id) { return Arc(id);}
326
    static Edge edgeFromId(int id) { return Edge(id);}
327

	
328
    Node u(Edge edge) const {
329
      return Node(_uid(edge._id));
330
    }
331

	
332
    Node v(Edge edge) const {
333
      return Node(_vid(edge._id));
334
    }
335

	
336
    Node source(Arc arc) const {
337
      return Node((arc._id & 1) == 1 ?
338
                  _uid(arc._id >> 1) : _vid(arc._id >> 1));
339
    }
340

	
341
    Node target(Arc arc) const {
342
      return Node((arc._id & 1) == 1 ?
343
                  _vid(arc._id >> 1) : _uid(arc._id >> 1));
344
    }
345

	
346
    typedef True FindEdgeTag;
347
    typedef True FindArcTag;
348

	
349
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
350
      return prev != INVALID ? INVALID : edge(u, v);
351
    }
352

	
353
    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
354
      return prev != INVALID ? INVALID : arc(s, t);
355
    }
356

	
357
    class Node {
358
      friend class FullGraphBase;
359

	
360
    protected:
361
      int _id;
362
      Node(int id) : _id(id) {}
363
    public:
364
      Node() {}
365
      Node (Invalid) { _id = -1; }
366
      bool operator==(const Node node) const {return _id == node._id;}
367
      bool operator!=(const Node node) const {return _id != node._id;}
368
      bool operator<(const Node node) const {return _id < node._id;}
369
    };
370

	
371
    class Edge {
372
      friend class FullGraphBase;
373
      friend class Arc;
374

	
375
    protected:
376
      int _id;
377

	
378
      Edge(int id) : _id(id) {}
379

	
380
    public:
381
      Edge() { }
382
      Edge (Invalid) { _id = -1; }
383

	
384
      bool operator==(const Edge edge) const {return _id == edge._id;}
385
      bool operator!=(const Edge edge) const {return _id != edge._id;}
386
      bool operator<(const Edge edge) const {return _id < edge._id;}
387
    };
388

	
389
    class Arc {
390
      friend class FullGraphBase;
391

	
392
    protected:
393
      int _id;
394

	
395
      Arc(int id) : _id(id) {}
396

	
397
    public:
398
      Arc() { }
399
      Arc (Invalid) { _id = -1; }
400

	
401
      operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -1); }
402

	
403
      bool operator==(const Arc arc) const {return _id == arc._id;}
404
      bool operator!=(const Arc arc) const {return _id != arc._id;}
405
      bool operator<(const Arc arc) const {return _id < arc._id;}
406
    };
407

	
408
    static bool direction(Arc arc) {
409
      return (arc._id & 1) == 1;
410
    }
411

	
412
    static Arc direct(Edge edge, bool dir) {
413
      return Arc((edge._id << 1) | (dir ? 1 : 0));
414
    }
415

	
416
    void first(Node& node) const {
417
      node._id = _node_num - 1;
418
    }
419

	
420
    static void next(Node& node) {
421
      --node._id;
422
    }
423

	
424
    void first(Arc& arc) const {
425
      arc._id = (_edge_num << 1) - 1;
426
    }
427

	
428
    static void next(Arc& arc) {
429
      --arc._id;
430
    }
431

	
432
    void first(Edge& edge) const {
433
      edge._id = _edge_num - 1;
434
    }
435

	
436
    static void next(Edge& edge) {
437
      --edge._id;
438
    }
439

	
440
    void firstOut(Arc& arc, const Node& node) const {
441
      int s = node._id, t = _node_num - 1;
442
      if (s < t) {
443
        arc._id = (_eid(s, t) << 1) | 1;
444
      } else {
445
        --t;
446
        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
447
      }
448
    }
449

	
450
    void nextOut(Arc& arc) const {
451
      int s, t;
452
      _stid(arc._id, s, t);
453
      --t;
454
      if (s < t) {
455
        arc._id = (_eid(s, t) << 1) | 1;
456
      } else {
457
        if (s == t) --t;
458
        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
459
      }
460
    }
461

	
462
    void firstIn(Arc& arc, const Node& node) const {
463
      int s = _node_num - 1, t = node._id;
464
      if (s > t) {
465
        arc._id = (_eid(t, s) << 1);
466
      } else {
467
        --s;
468
        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
469
      }
470
    }
471

	
472
    void nextIn(Arc& arc) const {
473
      int s, t;
474
      _stid(arc._id, s, t);
475
      --s;
476
      if (s > t) {
477
        arc._id = (_eid(t, s) << 1);
478
      } else {
479
        if (s == t) --s;
480
        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
481
      }
482
    }
483

	
484
    void firstInc(Edge& edge, bool& dir, const Node& node) const {
485
      int u = node._id, v = _node_num - 1;
486
      if (u < v) {
487
        edge._id = _eid(u, v);
488
        dir = true;
489
      } else {
490
        --v;
491
        edge._id = (v != -1 ? _eid(v, u) : -1);
492
        dir = false;
493
      }
494
    }
495

	
496
    void nextInc(Edge& edge, bool& dir) const {
497
      int u, v;
498
      if (dir) {
499
        _uvid(edge._id, u, v);
500
        --v;
501
        if (u < v) {
502
          edge._id = _eid(u, v);
503
        } else {
504
          --v;
505
          edge._id = (v != -1 ? _eid(v, u) : -1);
506
          dir = false;
507
        }
508
      } else {
509
        _uvid(edge._id, v, u);
510
        --v;
511
        edge._id = (v != -1 ? _eid(v, u) : -1);
512
      }
513
    }
514

	
515
  };
516

	
517
  typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
518

	
519
  /// \ingroup graphs
520
  ///
521
  /// \brief An undirected full graph class.
522
  ///
523
  /// This is a simple and fast undirected full graph
524
  /// implementation. From each node go edge to each other node,
525
  /// therefore the number of edges in the graph is \f$n(n-1)/2\f$.
526
  /// This graph type is completely static, so you can neither
527
  /// add nor delete either edges or nodes, and it needs constant
528
  /// space in memory.
529
  ///
530
  /// This class fully conforms to the \ref concepts::Graph "Graph concept".
531
  ///
532
  /// The \c FullGraph and \c FullDigraph classes are very similar,
533
  /// but there are two differences. While the \c FullDigraph class
534
  /// conforms only to the \ref concepts::Digraph "Digraph" concept,
535
  /// this class conforms to the \ref concepts::Graph "Graph" concept,
536
  /// moreover \c FullGraph does not contain a loop arc for each
537
  /// node as \c FullDigraph does.
538
  ///
539
  /// \sa FullDigraph
540
  class FullGraph : public ExtendedFullGraphBase {
541
    typedef ExtendedFullGraphBase Parent;
542

	
543
  public:
544

	
545
    /// \brief Constructor
546
    FullGraph() { construct(0); }
547

	
548
    /// \brief Constructor
549
    ///
550
    /// Constructor.
551
    /// \param n The number of the nodes.
552
    FullGraph(int n) { construct(n); }
553

	
554
    /// \brief Resizes the graph
555
    ///
556
    /// Resizes the graph. The function will fully destroy and
557
    /// rebuild the graph. This cause that the maps of the graph will
558
    /// reallocated automatically and the previous values will be lost.
559
    void resize(int n) {
560
      Parent::notifier(Arc()).clear();
561
      Parent::notifier(Edge()).clear();
562
      Parent::notifier(Node()).clear();
563
      construct(n);
564
      Parent::notifier(Node()).build();
565
      Parent::notifier(Edge()).build();
566
      Parent::notifier(Arc()).build();
567
    }
568

	
569
    /// \brief Returns the node with the given index.
570
    ///
571
    /// Returns the node with the given index. Since it is a static
572
    /// graph its nodes can be indexed with integers from the range
573
    /// <tt>[0..nodeNum()-1]</tt>.
574
    /// \sa index()
575
    Node operator()(int ix) const { return Parent::operator()(ix); }
576

	
577
    /// \brief Returns the index of the given node.
578
    ///
579
    /// Returns the index of the given node. Since it is a static
580
    /// graph its nodes can be indexed with integers from the range
581
    /// <tt>[0..nodeNum()-1]</tt>.
582
    /// \sa operator()
583
    int index(const Node& node) const { return Parent::index(node); }
584

	
585
    /// \brief Returns the arc connecting the given nodes.
586
    ///
587
    /// Returns the arc connecting the given nodes.
588
    Arc arc(const Node& s, const Node& t) const {
589
      return Parent::arc(s, t);
590
    }
591

	
592
    /// \brief Returns the edge connects the given nodes.
593
    ///
594
    /// Returns the edge connects the given nodes.
595
    Edge edge(const Node& u, const Node& v) const {
596
      return Parent::edge(u, v);
597
    }
598

	
599
    /// \brief Number of nodes.
600
    int nodeNum() const { return Parent::nodeNum(); }
601
    /// \brief Number of arcs.
602
    int arcNum() const { return Parent::arcNum(); }
603
    /// \brief Number of edges.
604
    int edgeNum() const { return Parent::edgeNum(); }
605

	
606
  };
607

	
608

	
609
} //namespace lemon
610

	
611

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

	
19
///\file
20
///\brief Implementation of the LEMON GLPK LP and MIP solver interface.
21

	
22
#include <lemon/glpk.h>
23
#include <glpk.h>
24

	
25
#include <lemon/assert.h>
26

	
27
namespace lemon {
28

	
29
  // GlpkBase members
30

	
31
  GlpkBase::GlpkBase() : LpBase() {
32
    lp = glp_create_prob();
33
    glp_create_index(lp);
34
    messageLevel(MESSAGE_NOTHING);
35
  }
36

	
37
  GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
38
    lp = glp_create_prob();
39
    glp_copy_prob(lp, other.lp, GLP_ON);
40
    glp_create_index(lp);
41
    rows = other.rows;
42
    cols = other.cols;
43
    messageLevel(MESSAGE_NOTHING);
44
  }
45

	
46
  GlpkBase::~GlpkBase() {
47
    glp_delete_prob(lp);
48
  }
49

	
50
  int GlpkBase::_addCol() {
51
    int i = glp_add_cols(lp, 1);
52
    glp_set_col_bnds(lp, i, GLP_FR, 0.0, 0.0);
53
    return i;
54
  }
55

	
56
  int GlpkBase::_addRow() {
57
    int i = glp_add_rows(lp, 1);
58
    glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0);
59
    return i;
60
  }
61

	
62
  void GlpkBase::_eraseCol(int i) {
63
    int ca[2];
64
    ca[1] = i;
65
    glp_del_cols(lp, 1, ca);
66
  }
67

	
68
  void GlpkBase::_eraseRow(int i) {
69
    int ra[2];
70
    ra[1] = i;
71
    glp_del_rows(lp, 1, ra);
72
  }
73

	
74
  void GlpkBase::_eraseColId(int i) {
75
    cols.eraseIndex(i);
76
    cols.shiftIndices(i);
77
  }
78

	
79
  void GlpkBase::_eraseRowId(int i) {
80
    rows.eraseIndex(i);
81
    rows.shiftIndices(i);
82
  }
83

	
84
  void GlpkBase::_getColName(int c, std::string& name) const {
85
    const char *str = glp_get_col_name(lp, c);
86
    if (str) name = str;
87
    else name.clear();
88
  }
89

	
90
  void GlpkBase::_setColName(int c, const std::string & name) {
91
    glp_set_col_name(lp, c, const_cast<char*>(name.c_str()));
92

	
93
  }
94

	
95
  int GlpkBase::_colByName(const std::string& name) const {
96
    int k = glp_find_col(lp, const_cast<char*>(name.c_str()));
97
    return k > 0 ? k : -1;
98
  }
99

	
100
  void GlpkBase::_getRowName(int r, std::string& name) const {
101
    const char *str = glp_get_row_name(lp, r);
102
    if (str) name = str;
103
    else name.clear();
104
  }
105

	
106
  void GlpkBase::_setRowName(int r, const std::string & name) {
107
    glp_set_row_name(lp, r, const_cast<char*>(name.c_str()));
108

	
109
  }
110

	
111
  int GlpkBase::_rowByName(const std::string& name) const {
112
    int k = glp_find_row(lp, const_cast<char*>(name.c_str()));
113
    return k > 0 ? k : -1;
114
  }
115

	
116
  void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
117
    std::vector<int> indexes;
118
    std::vector<Value> values;
119

	
120
    indexes.push_back(0);
121
    values.push_back(0);
122

	
123
    for(ExprIterator it = b; it != e; ++it) {
124
      indexes.push_back(it->first);
125
      values.push_back(it->second);
126
    }
127

	
128
    glp_set_mat_row(lp, i, values.size() - 1,
129
                    &indexes.front(), &values.front());
130
  }
131

	
132
  void GlpkBase::_getRowCoeffs(int ix, InsertIterator b) const {
133
    int length = glp_get_mat_row(lp, ix, 0, 0);
134

	
135
    std::vector<int> indexes(length + 1);
136
    std::vector<Value> values(length + 1);
137

	
138
    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
139

	
140
    for (int i = 1; i <= length; ++i) {
141
      *b = std::make_pair(indexes[i], values[i]);
142
      ++b;
143
    }
144
  }
145

	
146
  void GlpkBase::_setColCoeffs(int ix, ExprIterator b,
147
                                     ExprIterator e) {
148

	
149
    std::vector<int> indexes;
150
    std::vector<Value> values;
151

	
152
    indexes.push_back(0);
153
    values.push_back(0);
154

	
155
    for(ExprIterator it = b; it != e; ++it) {
156
      indexes.push_back(it->first);
157
      values.push_back(it->second);
158
    }
159

	
160
    glp_set_mat_col(lp, ix, values.size() - 1,
161
                    &indexes.front(), &values.front());
162
  }
163

	
164
  void GlpkBase::_getColCoeffs(int ix, InsertIterator b) const {
165
    int length = glp_get_mat_col(lp, ix, 0, 0);
166

	
167
    std::vector<int> indexes(length + 1);
168
    std::vector<Value> values(length + 1);
169

	
170
    glp_get_mat_col(lp, ix, &indexes.front(), &values.front());
171

	
172
    for (int i = 1; i  <= length; ++i) {
173
      *b = std::make_pair(indexes[i], values[i]);
174
      ++b;
175
    }
176
  }
177

	
178
  void GlpkBase::_setCoeff(int ix, int jx, Value value) {
179

	
180
    if (glp_get_num_cols(lp) < glp_get_num_rows(lp)) {
181

	
182
      int length = glp_get_mat_row(lp, ix, 0, 0);
183

	
184
      std::vector<int> indexes(length + 2);
185
      std::vector<Value> values(length + 2);
186

	
187
      glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
188

	
189
      //The following code does not suppose that the elements of the
190
      //array indexes are sorted
191
      bool found = false;
192
      for (int i = 1; i  <= length; ++i) {
193
        if (indexes[i] == jx) {
194
          found = true;
195
          values[i] = value;
196
          break;
197
        }
198
      }
199
      if (!found) {
200
        ++length;
201
        indexes[length] = jx;
202
        values[length] = value;
203
      }
204

	
205
      glp_set_mat_row(lp, ix, length, &indexes.front(), &values.front());
206

	
207
    } else {
208

	
209
      int length = glp_get_mat_col(lp, jx, 0, 0);
210

	
211
      std::vector<int> indexes(length + 2);
212
      std::vector<Value> values(length + 2);
213

	
214
      glp_get_mat_col(lp, jx, &indexes.front(), &values.front());
215

	
216
      //The following code does not suppose that the elements of the
217
      //array indexes are sorted
218
      bool found = false;
219
      for (int i = 1; i <= length; ++i) {
220
        if (indexes[i] == ix) {
221
          found = true;
222
          values[i] = value;
223
          break;
224
        }
225
      }
226
      if (!found) {
227
        ++length;
228
        indexes[length] = ix;
229
        values[length] = value;
230
      }
231

	
232
      glp_set_mat_col(lp, jx, length, &indexes.front(), &values.front());
233
    }
234

	
235
  }
236

	
237
  GlpkBase::Value GlpkBase::_getCoeff(int ix, int jx) const {
238

	
239
    int length = glp_get_mat_row(lp, ix, 0, 0);
240

	
241
    std::vector<int> indexes(length + 1);
242
    std::vector<Value> values(length + 1);
243

	
244
    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
245

	
246
    for (int i = 1; i  <= length; ++i) {
247
      if (indexes[i] == jx) {
248
        return values[i];
249
      }
250
    }
251

	
252
    return 0;
253
  }
254

	
255
  void GlpkBase::_setColLowerBound(int i, Value lo) {
256
    LEMON_ASSERT(lo != INF, "Invalid bound");
257

	
258
    int b = glp_get_col_type(lp, i);
259
    double up = glp_get_col_ub(lp, i);
260
    if (lo == -INF) {
261
      switch (b) {
262
      case GLP_FR:
263
      case GLP_LO:
264
        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
265
        break;
266
      case GLP_UP:
267
        break;
268
      case GLP_DB:
269
      case GLP_FX:
270
        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
271
        break;
272
      default:
273
        break;
274
      }
275
    } else {
276
      switch (b) {
277
      case GLP_FR:
278
      case GLP_LO:
279
        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
280
        break;
281
      case GLP_UP:
282
      case GLP_DB:
283
      case GLP_FX:
284
        if (lo == up)
285
          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
286
        else
287
          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
288
        break;
289
      default:
290
        break;
291
      }
292
    }
293
  }
294

	
295
  GlpkBase::Value GlpkBase::_getColLowerBound(int i) const {
296
    int b = glp_get_col_type(lp, i);
297
    switch (b) {
298
    case GLP_LO:
299
    case GLP_DB:
300
    case GLP_FX:
301
      return glp_get_col_lb(lp, i);
302
    default:
303
      return -INF;
304
    }
305
  }
306

	
307
  void GlpkBase::_setColUpperBound(int i, Value up) {
308
    LEMON_ASSERT(up != -INF, "Invalid bound");
309

	
310
    int b = glp_get_col_type(lp, i);
311
    double lo = glp_get_col_lb(lp, i);
312
    if (up == INF) {
313
      switch (b) {
314
      case GLP_FR:
315
      case GLP_LO:
316
        break;
317
      case GLP_UP:
318
        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
319
        break;
320
      case GLP_DB:
321
      case GLP_FX:
322
        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
323
        break;
324
      default:
325
        break;
326
      }
327
    } else {
328
      switch (b) {
329
      case GLP_FR:
330
        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
331
        break;
332
      case GLP_UP:
333
        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
334
        break;
335
      case GLP_LO:
336
      case GLP_DB:
337
      case GLP_FX:
338
        if (lo == up)
339
          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
340
        else
341
          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
342
        break;
343
      default:
344
        break;
345
      }
346
    }
347

	
348
  }
349

	
350
  GlpkBase::Value GlpkBase::_getColUpperBound(int i) const {
351
    int b = glp_get_col_type(lp, i);
352
      switch (b) {
353
      case GLP_UP:
354
      case GLP_DB:
355
      case GLP_FX:
356
        return glp_get_col_ub(lp, i);
357
      default:
358
        return INF;
359
      }
360
  }
361

	
362
  void GlpkBase::_setRowLowerBound(int i, Value lo) {
363
    LEMON_ASSERT(lo != INF, "Invalid bound");
364

	
365
    int b = glp_get_row_type(lp, i);
366
    double up = glp_get_row_ub(lp, i);
367
    if (lo == -INF) {
368
      switch (b) {
369
      case GLP_FR:
370
      case GLP_LO:
371
        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
372
        break;
373
      case GLP_UP:
374
        break;
375
      case GLP_DB:
376
      case GLP_FX:
377
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
378
        break;
379
      default:
380
        break;
381
      }
382
    } else {
383
      switch (b) {
384
      case GLP_FR:
385
      case GLP_LO:
386
        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
387
        break;
388
      case GLP_UP:
389
      case GLP_DB:
390
      case GLP_FX:
391
        if (lo == up)
392
          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
393
        else
394
          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
395
        break;
396
      default:
397
        break;
398
      }
399
    }
400

	
401
  }
402

	
403
  GlpkBase::Value GlpkBase::_getRowLowerBound(int i) const {
404
    int b = glp_get_row_type(lp, i);
405
    switch (b) {
406
    case GLP_LO:
407
    case GLP_DB:
408
    case GLP_FX:
409
      return glp_get_row_lb(lp, i);
410
    default:
411
      return -INF;
412
    }
413
  }
414

	
415
  void GlpkBase::_setRowUpperBound(int i, Value up) {
416
    LEMON_ASSERT(up != -INF, "Invalid bound");
417

	
418
    int b = glp_get_row_type(lp, i);
419
    double lo = glp_get_row_lb(lp, i);
420
    if (up == INF) {
421
      switch (b) {
422
      case GLP_FR:
423
      case GLP_LO:
424
        break;
425
      case GLP_UP:
426
        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
427
        break;
428
      case GLP_DB:
429
      case GLP_FX:
430
        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
431
        break;
432
      default:
433
        break;
434
      }
435
    } else {
436
      switch (b) {
437
      case GLP_FR:
438
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
439
        break;
440
      case GLP_UP:
441
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
442
        break;
443
      case GLP_LO:
444
      case GLP_DB:
445
      case GLP_FX:
446
        if (lo == up)
447
          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
448
        else
449
          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
450
        break;
451
      default:
452
        break;
453
      }
454
    }
455
  }
456

	
457
  GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const {
458
    int b = glp_get_row_type(lp, i);
459
    switch (b) {
460
    case GLP_UP:
461
    case GLP_DB:
462
    case GLP_FX:
463
      return glp_get_row_ub(lp, i);
464
    default:
465
      return INF;
466
    }
467
  }
468

	
469
  void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) {
470
    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
471
      glp_set_obj_coef(lp, i, 0.0);
472
    }
473
    for (ExprIterator it = b; it != e; ++it) {
474
      glp_set_obj_coef(lp, it->first, it->second);
475
    }
476
  }
477

	
478
  void GlpkBase::_getObjCoeffs(InsertIterator b) const {
479
    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
480
      Value val = glp_get_obj_coef(lp, i);
481
      if (val != 0.0) {
482
        *b = std::make_pair(i, val);
483
        ++b;
484
      }
485
    }
486
  }
487

	
488
  void GlpkBase::_setObjCoeff(int i, Value obj_coef) {
489
    //i = 0 means the constant term (shift)
490
    glp_set_obj_coef(lp, i, obj_coef);
491
  }
492

	
493
  GlpkBase::Value GlpkBase::_getObjCoeff(int i) const {
494
    //i = 0 means the constant term (shift)
495
    return glp_get_obj_coef(lp, i);
496
  }
497

	
498
  void GlpkBase::_setSense(GlpkBase::Sense sense) {
499
    switch (sense) {
500
    case MIN:
501
      glp_set_obj_dir(lp, GLP_MIN);
502
      break;
503
    case MAX:
504
      glp_set_obj_dir(lp, GLP_MAX);
505
      break;
506
    }
507
  }
508

	
509
  GlpkBase::Sense GlpkBase::_getSense() const {
510
    switch(glp_get_obj_dir(lp)) {
511
    case GLP_MIN:
512
      return MIN;
513
    case GLP_MAX:
514
      return MAX;
515
    default:
516
      LEMON_ASSERT(false, "Wrong sense");
517
      return GlpkBase::Sense();
518
    }
519
  }
520

	
521
  void GlpkBase::_clear() {
522
    glp_erase_prob(lp);
523
    rows.clear();
524
    cols.clear();
525
  }
526

	
527
  void GlpkBase::freeEnv() {
528
    glp_free_env();
529
  }
530

	
531
  void GlpkBase::_messageLevel(MessageLevel level) {
532
    switch (level) {
533
    case MESSAGE_NOTHING:
534
      _message_level = GLP_MSG_OFF;
535
      break;
536
    case MESSAGE_ERROR:
537
      _message_level = GLP_MSG_ERR;
538
      break;
539
    case MESSAGE_WARNING:
540
      _message_level = GLP_MSG_ERR;
541
      break;
542
    case MESSAGE_NORMAL:
543
      _message_level = GLP_MSG_ON;
544
      break;
545
    case MESSAGE_VERBOSE:
546
      _message_level = GLP_MSG_ALL;
547
      break;
548
    }
549
  }
550

	
551
  GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
552

	
553
  // GlpkLp members
554

	
555
  GlpkLp::GlpkLp()
556
    : LpBase(), LpSolver(), GlpkBase() {
557
    presolver(false);
558
  }
559

	
560
  GlpkLp::GlpkLp(const GlpkLp& other)
561
    : LpBase(other), LpSolver(other), GlpkBase(other) {
562
    presolver(false);
563
  }
564

	
565
  GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
566
  GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
567

	
568
  const char* GlpkLp::_solverName() const { return "GlpkLp"; }
569

	
570
  void GlpkLp::_clear_temporals() {
571
    _primal_ray.clear();
572
    _dual_ray.clear();
573
  }
574

	
575
  GlpkLp::SolveExitStatus GlpkLp::_solve() {
576
    return solvePrimal();
577
  }
578

	
579
  GlpkLp::SolveExitStatus GlpkLp::solvePrimal() {
580
    _clear_temporals();
581

	
582
    glp_smcp smcp;
583
    glp_init_smcp(&smcp);
584

	
585
    smcp.msg_lev = _message_level;
586
    smcp.presolve = _presolve;
587

	
588
    // If the basis is not valid we get an error return value.
589
    // In this case we can try to create a new basis.
590
    switch (glp_simplex(lp, &smcp)) {
591
    case 0:
592
      break;
593
    case GLP_EBADB:
594
    case GLP_ESING:
595
    case GLP_ECOND:
596
      glp_term_out(false);
597
      glp_adv_basis(lp, 0);
598
      glp_term_out(true);
599
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
600
      break;
601
    default:
602
      return UNSOLVED;
603
    }
604

	
605
    return SOLVED;
606
  }
607

	
608
  GlpkLp::SolveExitStatus GlpkLp::solveDual() {
609
    _clear_temporals();
610

	
611
    glp_smcp smcp;
612
    glp_init_smcp(&smcp);
613

	
614
    smcp.msg_lev = _message_level;
615
    smcp.meth = GLP_DUAL;
616
    smcp.presolve = _presolve;
617

	
618
    // If the basis is not valid we get an error return value.
619
    // In this case we can try to create a new basis.
620
    switch (glp_simplex(lp, &smcp)) {
621
    case 0:
622
      break;
623
    case GLP_EBADB:
624
    case GLP_ESING:
625
    case GLP_ECOND:
626
      glp_term_out(false);
627
      glp_adv_basis(lp, 0);
628
      glp_term_out(true);
629
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
630
      break;
631
    default:
632
      return UNSOLVED;
633
    }
634
    return SOLVED;
635
  }
636

	
637
  GlpkLp::Value GlpkLp::_getPrimal(int i) const {
638
    return glp_get_col_prim(lp, i);
639
  }
640

	
641
  GlpkLp::Value GlpkLp::_getDual(int i) const {
642
    return glp_get_row_dual(lp, i);
643
  }
644

	
645
  GlpkLp::Value GlpkLp::_getPrimalValue() const {
646
    return glp_get_obj_val(lp);
647
  }
648

	
649
  GlpkLp::VarStatus GlpkLp::_getColStatus(int i) const {
650
    switch (glp_get_col_stat(lp, i)) {
651
    case GLP_BS:
652
      return BASIC;
653
    case GLP_UP:
654
      return UPPER;
655
    case GLP_LO:
656
      return LOWER;
657
    case GLP_NF:
658
      return FREE;
659
    case GLP_NS:
660
      return FIXED;
661
    default:
662
      LEMON_ASSERT(false, "Wrong column status");
663
      return GlpkLp::VarStatus();
664
    }
665
  }
666

	
667
  GlpkLp::VarStatus GlpkLp::_getRowStatus(int i) const {
668
    switch (glp_get_row_stat(lp, i)) {
669
    case GLP_BS:
670
      return BASIC;
671
    case GLP_UP:
672
      return UPPER;
673
    case GLP_LO:
674
      return LOWER;
675
    case GLP_NF:
676
      return FREE;
677
    case GLP_NS:
678
      return FIXED;
679
    default:
680
      LEMON_ASSERT(false, "Wrong row status");
681
      return GlpkLp::VarStatus();
682
    }
683
  }
684

	
685
  GlpkLp::Value GlpkLp::_getPrimalRay(int i) const {
686
    if (_primal_ray.empty()) {
687
      int row_num = glp_get_num_rows(lp);
688
      int col_num = glp_get_num_cols(lp);
689

	
690
      _primal_ray.resize(col_num + 1, 0.0);
691

	
692
      int index = glp_get_unbnd_ray(lp);
693
      if (index != 0) {
694
        // The primal ray is found in primal simplex second phase
695
        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
696
                      glp_get_col_stat(lp, index - row_num)) != GLP_BS,
697
                     "Wrong primal ray");
698

	
699
        bool negate = glp_get_obj_dir(lp) == GLP_MAX;
700

	
701
        if (index > row_num) {
702
          _primal_ray[index - row_num] = 1.0;
703
          if (glp_get_col_dual(lp, index - row_num) > 0) {
704
            negate = !negate;
705
          }
706
        } else {
707
          if (glp_get_row_dual(lp, index) > 0) {
708
            negate = !negate;
709
          }
710
        }
711

	
712
        std::vector<int> ray_indexes(row_num + 1);
713
        std::vector<Value> ray_values(row_num + 1);
714
        int ray_length = glp_eval_tab_col(lp, index, &ray_indexes.front(),
715
                                          &ray_values.front());
716

	
717
        for (int i = 1; i <= ray_length; ++i) {
718
          if (ray_indexes[i] > row_num) {
719
            _primal_ray[ray_indexes[i] - row_num] = ray_values[i];
720
          }
721
        }
722

	
723
        if (negate) {
724
          for (int i = 1; i <= col_num; ++i) {
725
            _primal_ray[i] = - _primal_ray[i];
726
          }
727
        }
728
      } else {
729
        for (int i = 1; i <= col_num; ++i) {
730
          _primal_ray[i] = glp_get_col_prim(lp, i);
731
        }
732
      }
733
    }
734
    return _primal_ray[i];
735
  }
736

	
737
  GlpkLp::Value GlpkLp::_getDualRay(int i) const {
738
    if (_dual_ray.empty()) {
739
      int row_num = glp_get_num_rows(lp);
740

	
741
      _dual_ray.resize(row_num + 1, 0.0);
742

	
743
      int index = glp_get_unbnd_ray(lp);
744
      if (index != 0) {
745
        // The dual ray is found in dual simplex second phase
746
        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
747
                      glp_get_col_stat(lp, index - row_num)) == GLP_BS,
748

	
749
                     "Wrong dual ray");
750

	
751
        int idx;
752
        bool negate = false;
753

	
754
        if (index > row_num) {
755
          idx = glp_get_col_bind(lp, index - row_num);
756
          if (glp_get_col_prim(lp, index - row_num) >
757
              glp_get_col_ub(lp, index - row_num)) {
758
            negate = true;
759
          }
760
        } else {
761
          idx = glp_get_row_bind(lp, index);
762
          if (glp_get_row_prim(lp, index) > glp_get_row_ub(lp, index)) {
763
            negate = true;
764
          }
765
        }
766

	
767
        _dual_ray[idx] = negate ?  - 1.0 : 1.0;
768

	
769
        glp_btran(lp, &_dual_ray.front());
770
      } else {
771
        double eps = 1e-7;
772
        // The dual ray is found in primal simplex first phase
773
        // We assume that the glpk minimizes the slack to get feasible solution
774
        for (int i = 1; i <= row_num; ++i) {
775
          int index = glp_get_bhead(lp, i);
776
          if (index <= row_num) {
777
            double res = glp_get_row_prim(lp, index);
778
            if (res > glp_get_row_ub(lp, index) + eps) {
779
              _dual_ray[i] = -1;
780
            } else if (res < glp_get_row_lb(lp, index) - eps) {
781
              _dual_ray[i] = 1;
782
            } else {
783
              _dual_ray[i] = 0;
784
            }
785
            _dual_ray[i] *= glp_get_rii(lp, index);
786
          } else {
787
            double res = glp_get_col_prim(lp, index - row_num);
788
            if (res > glp_get_col_ub(lp, index - row_num) + eps) {
789
              _dual_ray[i] = -1;
790
            } else if (res < glp_get_col_lb(lp, index - row_num) - eps) {
791
              _dual_ray[i] = 1;
792
            } else {
793
              _dual_ray[i] = 0;
794
            }
795
            _dual_ray[i] /= glp_get_sjj(lp, index - row_num);
796
          }
797
        }
798

	
799
        glp_btran(lp, &_dual_ray.front());
800

	
801
        for (int i = 1; i <= row_num; ++i) {
802
          _dual_ray[i] /= glp_get_rii(lp, i);
803
        }
804
      }
805
    }
806
    return _dual_ray[i];
807
  }
808

	
809
  GlpkLp::ProblemType GlpkLp::_getPrimalType() const {
810
    if (glp_get_status(lp) == GLP_OPT)
811
      return OPTIMAL;
812
    switch (glp_get_prim_stat(lp)) {
813
    case GLP_UNDEF:
814
      return UNDEFINED;
815
    case GLP_FEAS:
816
    case GLP_INFEAS:
817
      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
818
        return UNBOUNDED;
819
      } else {
820
        return UNDEFINED;
821
      }
822
    case GLP_NOFEAS:
823
      return INFEASIBLE;
824
    default:
825
      LEMON_ASSERT(false, "Wrong primal type");
826
      return  GlpkLp::ProblemType();
827
    }
828
  }
829

	
830
  GlpkLp::ProblemType GlpkLp::_getDualType() const {
831
    if (glp_get_status(lp) == GLP_OPT)
832
      return OPTIMAL;
833
    switch (glp_get_dual_stat(lp)) {
834
    case GLP_UNDEF:
835
      return UNDEFINED;
836
    case GLP_FEAS:
837
    case GLP_INFEAS:
838
      if (glp_get_prim_stat(lp) == GLP_NOFEAS) {
839
        return UNBOUNDED;
840
      } else {
841
        return UNDEFINED;
842
      }
843
    case GLP_NOFEAS:
844
      return INFEASIBLE;
845
    default:
846
      LEMON_ASSERT(false, "Wrong primal type");
847
      return  GlpkLp::ProblemType();
848
    }
849
  }
850

	
851
  void GlpkLp::presolver(bool presolve) {
852
    _presolve = presolve;
853
  }
854

	
855
  // GlpkMip members
856

	
857
  GlpkMip::GlpkMip()
858
    : LpBase(), MipSolver(), GlpkBase() {
859
  }
860

	
861
  GlpkMip::GlpkMip(const GlpkMip& other)
862
    : LpBase(), MipSolver(), GlpkBase(other) {
863
  }
864

	
865
  void GlpkMip::_setColType(int i, GlpkMip::ColTypes col_type) {
866
    switch (col_type) {
867
    case INTEGER:
868
      glp_set_col_kind(lp, i, GLP_IV);
869
      break;
870
    case REAL:
871
      glp_set_col_kind(lp, i, GLP_CV);
872
      break;
873
    }
874
  }
875

	
876
  GlpkMip::ColTypes GlpkMip::_getColType(int i) const {
877
    switch (glp_get_col_kind(lp, i)) {
878
    case GLP_IV:
879
    case GLP_BV:
880
      return INTEGER;
881
    default:
882
      return REAL;
883
    }
884

	
885
  }
886

	
887
  GlpkMip::SolveExitStatus GlpkMip::_solve() {
888
    glp_smcp smcp;
889
    glp_init_smcp(&smcp);
890

	
891
    smcp.msg_lev = _message_level;
892
    smcp.meth = GLP_DUAL;
893

	
894
    // If the basis is not valid we get an error return value.
895
    // In this case we can try to create a new basis.
896
    switch (glp_simplex(lp, &smcp)) {
897
    case 0:
898
      break;
899
    case GLP_EBADB:
900
    case GLP_ESING:
901
    case GLP_ECOND:
902
      glp_term_out(false);
903
      glp_adv_basis(lp, 0);
904
      glp_term_out(true);
905
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
906
      break;
907
    default:
908
      return UNSOLVED;
909
    }
910

	
911
    if (glp_get_status(lp) != GLP_OPT) return SOLVED;
912

	
913
    glp_iocp iocp;
914
    glp_init_iocp(&iocp);
915

	
916
    iocp.msg_lev = _message_level;
917

	
918
    if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
919
    return SOLVED;
920
  }
921

	
922

	
923
  GlpkMip::ProblemType GlpkMip::_getType() const {
924
    switch (glp_get_status(lp)) {
925
    case GLP_OPT:
926
      switch (glp_mip_status(lp)) {
927
      case GLP_UNDEF:
928
        return UNDEFINED;
929
      case GLP_NOFEAS:
930
        return INFEASIBLE;
931
      case GLP_FEAS:
932
        return FEASIBLE;
933
      case GLP_OPT:
934
        return OPTIMAL;
935
      default:
936
        LEMON_ASSERT(false, "Wrong problem type.");
937
        return GlpkMip::ProblemType();
938
      }
939
    case GLP_NOFEAS:
940
      return INFEASIBLE;
941
    case GLP_INFEAS:
942
    case GLP_FEAS:
943
      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
944
        return UNBOUNDED;
945
      } else {
946
        return UNDEFINED;
947
      }
948
    default:
949
      LEMON_ASSERT(false, "Wrong problem type.");
950
      return GlpkMip::ProblemType();
951
    }
952
  }
953

	
954
  GlpkMip::Value GlpkMip::_getSol(int i) const {
955
    return glp_mip_col_val(lp, i);
956
  }
957

	
958
  GlpkMip::Value GlpkMip::_getSolValue() const {
959
    return glp_mip_obj_val(lp);
960
  }
961

	
962
  GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; }
963
  GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); }
964

	
965
  const char* GlpkMip::_solverName() const { return "GlpkMip"; }
966

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

	
19
#ifndef LEMON_GLPK_H
20
#define LEMON_GLPK_H
21

	
22
///\file
23
///\brief Header of the LEMON-GLPK lp solver interface.
24
///\ingroup lp_group
25

	
26
#include <lemon/lp_base.h>
27

	
28
// forward declaration
29
#if !defined _GLP_PROB && !defined GLP_PROB
30
#define _GLP_PROB
31
#define GLP_PROB
32
typedef struct { double _opaque_prob; } glp_prob;
33
/* LP/MIP problem object */
34
#endif
35

	
36
namespace lemon {
37

	
38

	
39
  /// \brief Base interface for the GLPK LP and MIP solver
40
  ///
41
  /// This class implements the common interface of the GLPK LP and MIP solver.
42
  /// \ingroup lp_group
43
  class GlpkBase : virtual public LpBase {
44
  protected:
45

	
46
    typedef glp_prob LPX;
47
    glp_prob* lp;
48

	
49
    GlpkBase();
50
    GlpkBase(const GlpkBase&);
51
    virtual ~GlpkBase();
52

	
53
  protected:
54

	
55
    virtual int _addCol();
56
    virtual int _addRow();
57

	
58
    virtual void _eraseCol(int i);
59
    virtual void _eraseRow(int i);
60

	
61
    virtual void _eraseColId(int i);
62
    virtual void _eraseRowId(int i);
63

	
64
    virtual void _getColName(int col, std::string& name) const;
65
    virtual void _setColName(int col, const std::string& name);
66
    virtual int _colByName(const std::string& name) const;
67

	
68
    virtual void _getRowName(int row, std::string& name) const;
69
    virtual void _setRowName(int row, const std::string& name);
70
    virtual int _rowByName(const std::string& name) const;
71

	
72
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
73
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
74

	
75
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
76
    virtual void _getColCoeffs(int i, InsertIterator b) const;
77

	
78
    virtual void _setCoeff(int row, int col, Value value);
79
    virtual Value _getCoeff(int row, int col) const;
80

	
81
    virtual void _setColLowerBound(int i, Value value);
82
    virtual Value _getColLowerBound(int i) const;
83

	
84
    virtual void _setColUpperBound(int i, Value value);
85
    virtual Value _getColUpperBound(int i) const;
86

	
87
    virtual void _setRowLowerBound(int i, Value value);
88
    virtual Value _getRowLowerBound(int i) const;
89

	
90
    virtual void _setRowUpperBound(int i, Value value);
91
    virtual Value _getRowUpperBound(int i) const;
92

	
93
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
94
    virtual void _getObjCoeffs(InsertIterator b) const;
95

	
96
    virtual void _setObjCoeff(int i, Value obj_coef);
97
    virtual Value _getObjCoeff(int i) const;
98

	
99
    virtual void _setSense(Sense);
100
    virtual Sense _getSense() const;
101

	
102
    virtual void _clear();
103

	
104
    virtual void _messageLevel(MessageLevel level);
105

	
106
  private:
107

	
108
    static void freeEnv();
109

	
110
    struct FreeEnvHelper {
111
      ~FreeEnvHelper() {
112
        freeEnv();
113
      }
114
    };
115
    
116
    static FreeEnvHelper freeEnvHelper;
117

	
118
  protected:
119
    
120
    int _message_level;
121
    
122
  public:
123

	
124
    ///Pointer to the underlying GLPK data structure.
125
    LPX *lpx() {return lp;}
126
    ///Const pointer to the underlying GLPK data structure.
127
    const LPX *lpx() const {return lp;}
128

	
129
    ///Returns the constraint identifier understood by GLPK.
130
    int lpxRow(Row r) const { return rows(id(r)); }
131

	
132
    ///Returns the variable identifier understood by GLPK.
133
    int lpxCol(Col c) const { return cols(id(c)); }
134

	
135
  };
136

	
137
  /// \brief Interface for the GLPK LP solver
138
  ///
139
  /// This class implements an interface for the GLPK LP solver.
140
  ///\ingroup lp_group
141
  class GlpkLp : public LpSolver, public GlpkBase {
142
  public:
143

	
144
    ///\e
145
    GlpkLp();
146
    ///\e
147
    GlpkLp(const GlpkLp&);
148

	
149
    ///\e
150
    virtual GlpkLp* cloneSolver() const;
151
    ///\e
152
    virtual GlpkLp* newSolver() const;
153

	
154
  private:
155

	
156
    mutable std::vector<double> _primal_ray;
157
    mutable std::vector<double> _dual_ray;
158

	
159
    void _clear_temporals();
160

	
161
  protected:
162

	
163
    virtual const char* _solverName() const;
164

	
165
    virtual SolveExitStatus _solve();
166
    virtual Value _getPrimal(int i) const;
167
    virtual Value _getDual(int i) const;
168

	
169
    virtual Value _getPrimalValue() const;
170

	
171
    virtual VarStatus _getColStatus(int i) const;
172
    virtual VarStatus _getRowStatus(int i) const;
173

	
174
    virtual Value _getPrimalRay(int i) const;
175
    virtual Value _getDualRay(int i) const;
176

	
177
    virtual ProblemType _getPrimalType() const;
178
    virtual ProblemType _getDualType() const;
179

	
180
  public:
181

	
182
    ///Solve with primal simplex
183
    SolveExitStatus solvePrimal();
184

	
185
    ///Solve with dual simplex
186
    SolveExitStatus solveDual();
187

	
188
  private:
189

	
190
    bool _presolve;
191

	
192
  public:
193

	
194
    ///Turns on or off the presolver
195

	
196
    ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
197
    ///
198
    ///The presolver is off by default.
199
    void presolver(bool presolve);
200

	
201
  };
202

	
203
  /// \brief Interface for the GLPK MIP solver
204
  ///
205
  /// This class implements an interface for the GLPK MIP solver.
206
  ///\ingroup lp_group
207
  class GlpkMip : public MipSolver, public GlpkBase {
208
  public:
209

	
210
    ///\e
211
    GlpkMip();
212
    ///\e
213
    GlpkMip(const GlpkMip&);
214

	
215
    virtual GlpkMip* cloneSolver() const;
216
    virtual GlpkMip* newSolver() const;
217

	
218
  protected:
219

	
220
    virtual const char* _solverName() const;
221

	
222
    virtual ColTypes _getColType(int col) const;
223
    virtual void _setColType(int col, ColTypes col_type);
224

	
225
    virtual SolveExitStatus _solve();
226
    virtual ProblemType _getType() const;
227
    virtual Value _getSol(int i) const;
228
    virtual Value _getSolValue() const;
229

	
230
  };
231

	
232

	
233
} //END OF NAMESPACE LEMON
234

	
235
#endif //LEMON_GLPK_H
236

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

	
19
#ifndef LEMON_GOMORY_HU_TREE_H
20
#define LEMON_GOMORY_HU_TREE_H
21

	
22
#include <limits>
23

	
24
#include <lemon/core.h>
25
#include <lemon/preflow.h>
26
#include <lemon/concept_check.h>
27
#include <lemon/concepts/maps.h>
28

	
29
/// \ingroup min_cut
30
/// \file 
31
/// \brief Gomory-Hu cut tree in graphs.
32

	
33
namespace lemon {
34

	
35
  /// \ingroup min_cut
36
  ///
37
  /// \brief Gomory-Hu cut tree algorithm
38
  ///
39
  /// The Gomory-Hu tree is a tree on the node set of a given graph, but it
40
  /// may contain edges which are not in the original graph. It has the
41
  /// property that the minimum capacity edge of the path between two nodes 
42
  /// in this tree has the same weight as the minimum cut in the graph
43
  /// between these nodes. Moreover the components obtained by removing
44
  /// this edge from the tree determine the corresponding minimum cut.
45
  /// Therefore once this tree is computed, the minimum cut between any pair
46
  /// of nodes can easily be obtained.
47
  /// 
48
  /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
49
  /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{e})\f$ overall
50
  /// time complexity. It calculates a rooted Gomory-Hu tree.
51
  /// The structure of the tree and the edge weights can be
52
  /// obtained using \c predNode(), \c predValue() and \c rootDist().
53
  /// The functions \c minCutMap() and \c minCutValue() calculate
54
  /// the minimum cut and the minimum cut value between any two nodes
55
  /// in the graph. You can also list (iterate on) the nodes and the
56
  /// edges of the cuts using \c MinCutNodeIt and \c MinCutEdgeIt.
57
  ///
58
  /// \tparam GR The type of the undirected graph the algorithm runs on.
59
  /// \tparam CAP The type of the edge map containing the capacities.
60
  /// The default map type is \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
61
#ifdef DOXYGEN
62
  template <typename GR,
63
	    typename CAP>
64
#else
65
  template <typename GR,
66
	    typename CAP = typename GR::template EdgeMap<int> >
67
#endif
68
  class GomoryHu {
69
  public:
70

	
71
    /// The graph type of the algorithm
72
    typedef GR Graph;
73
    /// The capacity map type of the algorithm
74
    typedef CAP Capacity;
75
    /// The value type of capacities
76
    typedef typename Capacity::Value Value;
77
    
78
  private:
79

	
80
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
81

	
82
    const Graph& _graph;
83
    const Capacity& _capacity;
84

	
85
    Node _root;
86
    typename Graph::template NodeMap<Node>* _pred;
87
    typename Graph::template NodeMap<Value>* _weight;
88
    typename Graph::template NodeMap<int>* _order;
89

	
90
    void createStructures() {
91
      if (!_pred) {
92
	_pred = new typename Graph::template NodeMap<Node>(_graph);
93
      }
94
      if (!_weight) {
95
	_weight = new typename Graph::template NodeMap<Value>(_graph);
96
      }
97
      if (!_order) {
98
	_order = new typename Graph::template NodeMap<int>(_graph);
99
      }
100
    }
101

	
102
    void destroyStructures() {
103
      if (_pred) {
104
	delete _pred;
105
      }
106
      if (_weight) {
107
	delete _weight;
108
      }
109
      if (_order) {
110
	delete _order;
111
      }
112
    }
113
  
114
  public:
115

	
116
    /// \brief Constructor
117
    ///
118
    /// Constructor.
119
    /// \param graph The undirected graph the algorithm runs on.
120
    /// \param capacity The edge capacity map.
121
    GomoryHu(const Graph& graph, const Capacity& capacity) 
122
      : _graph(graph), _capacity(capacity),
123
	_pred(0), _weight(0), _order(0) 
124
    {
125
      checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
126
    }
127

	
128

	
129
    /// \brief Destructor
130
    ///
131
    /// Destructor.
132
    ~GomoryHu() {
133
      destroyStructures();
134
    }
135

	
136
  private:
137
  
138
    // Initialize the internal data structures
139
    void init() {
140
      createStructures();
141

	
142
      _root = NodeIt(_graph);
143
      for (NodeIt n(_graph); n != INVALID; ++n) {
144
        (*_pred)[n] = _root;
145
        (*_order)[n] = -1;
146
      }
147
      (*_pred)[_root] = INVALID;
148
      (*_weight)[_root] = std::numeric_limits<Value>::max(); 
149
    }
150

	
151

	
152
    // Start the algorithm
153
    void start() {
154
      Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
155

	
156
      for (NodeIt n(_graph); n != INVALID; ++n) {
157
	if (n == _root) continue;
158

	
159
	Node pn = (*_pred)[n];
160
	fa.source(n);
161
	fa.target(pn);
162

	
163
	fa.runMinCut();
164

	
165
	(*_weight)[n] = fa.flowValue();
166

	
167
	for (NodeIt nn(_graph); nn != INVALID; ++nn) {
168
	  if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
169
	    (*_pred)[nn] = n;
170
	  }
171
	}
172
	if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
173
	  (*_pred)[n] = (*_pred)[pn];
174
	  (*_pred)[pn] = n;
175
	  (*_weight)[n] = (*_weight)[pn];
176
	  (*_weight)[pn] = fa.flowValue();
177
	}
178
      }
179

	
180
      (*_order)[_root] = 0;
181
      int index = 1;
182

	
183
      for (NodeIt n(_graph); n != INVALID; ++n) {
184
	std::vector<Node> st;
185
	Node nn = n;
186
	while ((*_order)[nn] == -1) {
187
	  st.push_back(nn);
188
	  nn = (*_pred)[nn];
189
	}
190
	while (!st.empty()) {
191
	  (*_order)[st.back()] = index++;
192
	  st.pop_back();
193
	}
194
      }
195
    }
196

	
197
  public:
198

	
199
    ///\name Execution Control
200
 
201
    ///@{
202

	
203
    /// \brief Run the Gomory-Hu algorithm.
204
    ///
205
    /// This function runs the Gomory-Hu algorithm.
206
    void run() {
207
      init();
208
      start();
209
    }
210
    
211
    /// @}
212

	
213
    ///\name Query Functions
214
    ///The results of the algorithm can be obtained using these
215
    ///functions.\n
216
    ///\ref run() should be called before using them.\n
217
    ///See also \ref MinCutNodeIt and \ref MinCutEdgeIt.
218

	
219
    ///@{
220

	
221
    /// \brief Return the predecessor node in the Gomory-Hu tree.
222
    ///
223
    /// This function returns the predecessor node of the given node
224
    /// in the Gomory-Hu tree.
225
    /// If \c node is the root of the tree, then it returns \c INVALID.
226
    ///
227
    /// \pre \ref run() must be called before using this function.
228
    Node predNode(const Node& node) const {
229
      return (*_pred)[node];
230
    }
231

	
232
    /// \brief Return the weight of the predecessor edge in the
233
    /// Gomory-Hu tree.
234
    ///
235
    /// This function returns the weight of the predecessor edge of the 
236
    /// given node in the Gomory-Hu tree.
237
    /// If \c node is the root of the tree, the result is undefined.
238
    ///
239
    /// \pre \ref run() must be called before using this function.
240
    Value predValue(const Node& node) const {
241
      return (*_weight)[node];
242
    }
243

	
244
    /// \brief Return the distance from the root node in the Gomory-Hu tree.
245
    ///
246
    /// This function returns the distance of the given node from the root
247
    /// node in the Gomory-Hu tree.
248
    ///
249
    /// \pre \ref run() must be called before using this function.
250
    int rootDist(const Node& node) const {
251
      return (*_order)[node];
252
    }
253

	
254
    /// \brief Return the minimum cut value between two nodes
255
    ///
256
    /// This function returns the minimum cut value between the nodes
257
    /// \c s and \c t. 
258
    /// It finds the nearest common ancestor of the given nodes in the
259
    /// Gomory-Hu tree and calculates the minimum weight edge on the
260
    /// paths to the ancestor.
261
    ///
262
    /// \pre \ref run() must be called before using this function.
263
    Value minCutValue(const Node& s, const Node& t) const {
264
      Node sn = s, tn = t;
265
      Value value = std::numeric_limits<Value>::max();
266
      
267
      while (sn != tn) {
268
	if ((*_order)[sn] < (*_order)[tn]) {
269
	  if ((*_weight)[tn] <= value) value = (*_weight)[tn];
270
	  tn = (*_pred)[tn];
271
	} else {
272
	  if ((*_weight)[sn] <= value) value = (*_weight)[sn];
273
	  sn = (*_pred)[sn];
274
	}
275
      }
276
      return value;
277
    }
278

	
279
    /// \brief Return the minimum cut between two nodes
280
    ///
281
    /// This function returns the minimum cut between the nodes \c s and \c t
282
    /// in the \c cutMap parameter by setting the nodes in the component of
283
    /// \c s to \c true and the other nodes to \c false.
284
    ///
285
    /// For higher level interfaces see MinCutNodeIt and MinCutEdgeIt.
286
    ///
287
    /// \param s The base node.
288
    /// \param t The node you want to separate from node \c s.
289
    /// \param cutMap The cut will be returned in this map.
290
    /// It must be a \c bool (or convertible) \ref concepts::ReadWriteMap
291
    /// "ReadWriteMap" on the graph nodes.
292
    ///
293
    /// \return The value of the minimum cut between \c s and \c t.
294
    ///
295
    /// \pre \ref run() must be called before using this function.
296
    template <typename CutMap>
297
    Value minCutMap(const Node& s, ///< 
298
                    const Node& t,
299
                    ///< 
300
                    CutMap& cutMap
301
                    ///< 
302
                    ) const {
303
      Node sn = s, tn = t;
304
      bool s_root=false;
305
      Node rn = INVALID;
306
      Value value = std::numeric_limits<Value>::max();
307
      
308
      while (sn != tn) {
309
	if ((*_order)[sn] < (*_order)[tn]) {
310
	  if ((*_weight)[tn] <= value) {
311
	    rn = tn;
312
            s_root = false;
313
	    value = (*_weight)[tn];
314
	  }
315
	  tn = (*_pred)[tn];
316
	} else {
317
	  if ((*_weight)[sn] <= value) {
318
	    rn = sn;
319
            s_root = true;
320
	    value = (*_weight)[sn];
321
	  }
322
	  sn = (*_pred)[sn];
323
	}
324
      }
325

	
326
      typename Graph::template NodeMap<bool> reached(_graph, false);
327
      reached[_root] = true;
328
      cutMap.set(_root, !s_root);
329
      reached[rn] = true;
330
      cutMap.set(rn, s_root);
331

	
332
      std::vector<Node> st;
333
      for (NodeIt n(_graph); n != INVALID; ++n) {
334
	st.clear();
335
        Node nn = n;
336
	while (!reached[nn]) {
337
	  st.push_back(nn);
338
	  nn = (*_pred)[nn];
339
	}
340
	while (!st.empty()) {
341
	  cutMap.set(st.back(), cutMap[nn]);
342
	  st.pop_back();
343
	}
344
      }
345
      
346
      return value;
347
    }
348

	
349
    ///@}
350

	
351
    friend class MinCutNodeIt;
352

	
353
    /// Iterate on the nodes of a minimum cut
354
    
355
    /// This iterator class lists the nodes of a minimum cut found by
356
    /// GomoryHu. Before using it, you must allocate a GomoryHu class
357
    /// and call its \ref GomoryHu::run() "run()" method.
358
    ///
359
    /// This example counts the nodes in the minimum cut separating \c s from
360
    /// \c t.
361
    /// \code
362
    /// GomoruHu<Graph> gom(g, capacities);
363
    /// gom.run();
364
    /// int cnt=0;
365
    /// for(GomoruHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
366
    /// \endcode
367
    class MinCutNodeIt
368
    {
369
      bool _side;
370
      typename Graph::NodeIt _node_it;
371
      typename Graph::template NodeMap<bool> _cut;
372
    public:
373
      /// Constructor
374

	
375
      /// Constructor.
376
      ///
377
      MinCutNodeIt(GomoryHu const &gomory,
378
                   ///< The GomoryHu class. You must call its
379
                   ///  run() method
380
                   ///  before initializing this iterator.
381
                   const Node& s, ///< The base node.
382
                   const Node& t,
383
                   ///< The node you want to separate from node \c s.
384
                   bool side=true
385
                   ///< If it is \c true (default) then the iterator lists
386
                   ///  the nodes of the component containing \c s,
387
                   ///  otherwise it lists the other component.
388
                   /// \note As the minimum cut is not always unique,
389
                   /// \code
390
                   /// MinCutNodeIt(gomory, s, t, true);
391
                   /// \endcode
392
                   /// and
393
                   /// \code
394
                   /// MinCutNodeIt(gomory, t, s, false);
395
                   /// \endcode
396
                   /// does not necessarily give the same set of nodes.
397
                   /// However it is ensured that
398
                   /// \code
399
                   /// MinCutNodeIt(gomory, s, t, true);
400
                   /// \endcode
401
                   /// and
402
                   /// \code
403
                   /// MinCutNodeIt(gomory, s, t, false);
404
                   /// \endcode
405
                   /// together list each node exactly once.
406
                   )
407
        : _side(side), _cut(gomory._graph)
408
      {
409
        gomory.minCutMap(s,t,_cut);
410
        for(_node_it=typename Graph::NodeIt(gomory._graph);
411
            _node_it!=INVALID && _cut[_node_it]!=_side;
412
            ++_node_it) {}
413
      }
414
      /// Conversion to \c Node
415

	
416
      /// Conversion to \c Node.
417
      ///
418
      operator typename Graph::Node() const
419
      {
420
        return _node_it;
421
      }
422
      bool operator==(Invalid) { return _node_it==INVALID; }
423
      bool operator!=(Invalid) { return _node_it!=INVALID; }
424
      /// Next node
425

	
426
      /// Next node.
427
      ///
428
      MinCutNodeIt &operator++()
429
      {
430
        for(++_node_it;_node_it!=INVALID&&_cut[_node_it]!=_side;++_node_it) {}
431
        return *this;
432
      }
433
      /// Postfix incrementation
434

	
435
      /// Postfix incrementation.
436
      ///
437
      /// \warning This incrementation
438
      /// returns a \c Node, not a \c MinCutNodeIt, as one may
439
      /// expect.
440
      typename Graph::Node operator++(int)
441
      {
442
        typename Graph::Node n=*this;
443
        ++(*this);
444
        return n;
445
      }
446
    };
447
    
448
    friend class MinCutEdgeIt;
449
    
450
    /// Iterate on the edges of a minimum cut
451
    
452
    /// This iterator class lists the edges of a minimum cut found by
453
    /// GomoryHu. Before using it, you must allocate a GomoryHu class
454
    /// and call its \ref GomoryHu::run() "run()" method.
455
    ///
456
    /// This example computes the value of the minimum cut separating \c s from
457
    /// \c t.
458
    /// \code
459
    /// GomoruHu<Graph> gom(g, capacities);
460
    /// gom.run();
461
    /// int value=0;
462
    /// for(GomoruHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
463
    ///   value+=capacities[e];
464
    /// \endcode
465
    /// The result will be the same as the value returned by
466
    /// \ref GomoryHu::minCutValue() "gom.minCutValue(s,t)".
467
    class MinCutEdgeIt
468
    {
469
      bool _side;
470
      const Graph &_graph;
471
      typename Graph::NodeIt _node_it;
472
      typename Graph::OutArcIt _arc_it;
473
      typename Graph::template NodeMap<bool> _cut;
474
      void step()
475
      {
476
        ++_arc_it;
477
        while(_node_it!=INVALID && _arc_it==INVALID)
478
          {
479
            for(++_node_it;_node_it!=INVALID&&!_cut[_node_it];++_node_it) {}
480
            if(_node_it!=INVALID)
481
              _arc_it=typename Graph::OutArcIt(_graph,_node_it);
482
          }
483
      }
484
      
485
    public:
486
      /// Constructor
487

	
488
      /// Constructor.
489
      ///
490
      MinCutEdgeIt(GomoryHu const &gomory,
491
                   ///< The GomoryHu class. You must call its
492
                   ///  run() method
493
                   ///  before initializing this iterator.
494
                   const Node& s,  ///< The base node.
495
                   const Node& t,
496
                   ///< The node you want to separate from node \c s.
497
                   bool side=true
498
                   ///< If it is \c true (default) then the listed arcs
499
                   ///  will be oriented from the
500
                   ///  nodes of the component containing \c s,
501
                   ///  otherwise they will be oriented in the opposite
502
                   ///  direction.
503
                   )
504
        : _graph(gomory._graph), _cut(_graph)
505
      {
506
        gomory.minCutMap(s,t,_cut);
507
        if(!side)
508
          for(typename Graph::NodeIt n(_graph);n!=INVALID;++n)
509
            _cut[n]=!_cut[n];
510

	
511
        for(_node_it=typename Graph::NodeIt(_graph);
512
            _node_it!=INVALID && !_cut[_node_it];
513
            ++_node_it) {}
514
        _arc_it = _node_it!=INVALID ?
515
          typename Graph::OutArcIt(_graph,_node_it) : INVALID;
516
        while(_node_it!=INVALID && _arc_it == INVALID)
517
          {
518
            for(++_node_it; _node_it!=INVALID&&!_cut[_node_it]; ++_node_it) {}
519
            if(_node_it!=INVALID)
520
              _arc_it= typename Graph::OutArcIt(_graph,_node_it);
521
          }
522
        while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
523
      }
524
      /// Conversion to \c Arc
525

	
526
      /// Conversion to \c Arc.
527
      ///
528
      operator typename Graph::Arc() const
529
      {
530
        return _arc_it;
531
      }
532
      /// Conversion to \c Edge
533

	
534
      /// Conversion to \c Edge.
535
      ///
536
      operator typename Graph::Edge() const
537
      {
538
        return _arc_it;
539
      }
540
      bool operator==(Invalid) { return _node_it==INVALID; }
541
      bool operator!=(Invalid) { return _node_it!=INVALID; }
542
      /// Next edge
543

	
544
      /// Next edge.
545
      ///
546
      MinCutEdgeIt &operator++()
547
      {
548
        step();
549
        while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
550
        return *this;
551
      }
552
      /// Postfix incrementation
553
      
554
      /// Postfix incrementation.
555
      ///
556
      /// \warning This incrementation
557
      /// returns an \c Arc, not a \c MinCutEdgeIt, as one may expect.
558
      typename Graph::Arc operator++(int)
559
      {
560
        typename Graph::Arc e=*this;
561
        ++(*this);
562
        return e;
563
      }
564
    };
565

	
566
  };
567

	
568
}
569

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

	
19
#ifndef GRID_GRAPH_H
20
#define GRID_GRAPH_H
21

	
22
#include <lemon/core.h>
23
#include <lemon/bits/graph_extender.h>
24
#include <lemon/dim2.h>
25
#include <lemon/assert.h>
26

	
27
///\ingroup graphs
28
///\file
29
///\brief GridGraph class.
30

	
31
namespace lemon {
32

	
33
  class GridGraphBase {
34

	
35
  public:
36

	
37
    typedef GridGraphBase Graph;
38

	
39
    class Node;
40
    class Edge;
41
    class Arc;
42

	
43
  public:
44

	
45
    GridGraphBase() {}
46

	
47
  protected:
48

	
49
    void construct(int width, int height) {
50
       _width = width; _height = height;
51
      _node_num = width * height;
52
      _edge_num = 2 * _node_num - width - height;
53
      _edge_limit = _node_num - _width;
54
    }
55

	
56
  public:
57

	
58
    Node operator()(int i, int j) const {
59
      LEMON_DEBUG(0 <= i && i < _width &&
60
                  0 <= j  && j < _height, "Index out of range");
61
      return Node(i + j * _width);
62
    }
63

	
64
    int col(Node n) const {
65
      return n._id % _width;
66
    }
67

	
68
    int row(Node n) const {
69
      return n._id / _width;
70
    }
71

	
72
    dim2::Point<int> pos(Node n) const {
73
      return dim2::Point<int>(col(n), row(n));
74
    }
75

	
76
    int width() const {
77
      return _width;
78
    }
79

	
80
    int height() const {
81
      return _height;
82
    }
83

	
84
    typedef True NodeNumTag;
85
    typedef True EdgeNumTag;
86
    typedef True ArcNumTag;
87

	
88
    int nodeNum() const { return _node_num; }
89
    int edgeNum() const { return _edge_num; }
90
    int arcNum() const { return 2 * _edge_num; }
91

	
92
    Node u(Edge edge) const {
93
      if (edge._id < _edge_limit) {
94
        return edge._id;
95
      } else {
96
        return (edge._id - _edge_limit) % (_width - 1) +
97
          (edge._id - _edge_limit) / (_width - 1) * _width;
98
      }
99
    }
100

	
101
    Node v(Edge edge) const {
102
      if (edge._id < _edge_limit) {
103
        return edge._id + _width;
104
      } else {
105
        return (edge._id - _edge_limit) % (_width - 1) +
106
          (edge._id - _edge_limit) / (_width - 1) * _width + 1;
107
      }
108
    }
109

	
110
    Node source(Arc arc) const {
111
      return (arc._id & 1) == 1 ? u(arc) : v(arc);
112
    }
113

	
114
    Node target(Arc arc) const {
115
      return (arc._id & 1) == 1 ? v(arc) : u(arc);
116
    }
117

	
118
    static int id(Node node) { return node._id; }
119
    static int id(Edge edge) { return edge._id; }
120
    static int id(Arc arc) { return arc._id; }
121

	
122
    int maxNodeId() const { return _node_num - 1; }
123
    int maxEdgeId() const { return _edge_num - 1; }
124
    int maxArcId() const { return 2 * _edge_num - 1; }
125

	
126
    static Node nodeFromId(int id) { return Node(id);}
127
    static Edge edgeFromId(int id) { return Edge(id);}
128
    static Arc arcFromId(int id) { return Arc(id);}
129

	
130
    typedef True FindEdgeTag;
131
    typedef True FindArcTag;
132

	
133
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
134
      if (prev != INVALID) return INVALID;
135
      if (v._id > u._id) {
136
        if (v._id - u._id == _width)
137
          return Edge(u._id);
138
        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
139
          return Edge(u._id / _width * (_width - 1) +
140
                      u._id % _width + _edge_limit);
141
        }
142
      } else {
143
        if (u._id - v._id == _width)
144
          return Edge(v._id);
145
        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
146
          return Edge(v._id / _width * (_width - 1) +
147
                      v._id % _width + _edge_limit);
148
        }
149
      }
150
      return INVALID;
151
    }
152

	
153
    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
154
      if (prev != INVALID) return INVALID;
155
      if (v._id > u._id) {
156
        if (v._id - u._id == _width)
157
          return Arc((u._id << 1) | 1);
158
        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
159
          return Arc(((u._id / _width * (_width - 1) +
160
                       u._id % _width + _edge_limit) << 1) | 1);
161
        }
162
      } else {
163
        if (u._id - v._id == _width)
164
          return Arc(v._id << 1);
165
        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
166
          return Arc((v._id / _width * (_width - 1) +
167
                       v._id % _width + _edge_limit) << 1);
168
        }
169
      }
170
      return INVALID;
171
    }
172

	
173
    class Node {
174
      friend class GridGraphBase;
175

	
176
    protected:
177
      int _id;
178
      Node(int id) : _id(id) {}
179
    public:
180
      Node() {}
181
      Node (Invalid) : _id(-1) {}
182
      bool operator==(const Node node) const {return _id == node._id;}
183
      bool operator!=(const Node node) const {return _id != node._id;}
184
      bool operator<(const Node node) const {return _id < node._id;}
185
    };
186

	
187
    class Edge {
188
      friend class GridGraphBase;
189
      friend class Arc;
190

	
191
    protected:
192
      int _id;
193

	
194
      Edge(int id) : _id(id) {}
195

	
196
    public:
197
      Edge() {}
198
      Edge (Invalid) : _id(-1) {}
199
      bool operator==(const Edge edge) const {return _id == edge._id;}
200
      bool operator!=(const Edge edge) const {return _id != edge._id;}
201
      bool operator<(const Edge edge) const {return _id < edge._id;}
202
    };
203

	
204
    class Arc {
205
      friend class GridGraphBase;
206

	
207
    protected:
208
      int _id;
209

	
210
      Arc(int id) : _id(id) {}
211

	
212
    public:
213
      Arc() {}
214
      Arc (Invalid) : _id(-1) {}
215
      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
216
      bool operator==(const Arc arc) const {return _id == arc._id;}
217
      bool operator!=(const Arc arc) const {return _id != arc._id;}
218
      bool operator<(const Arc arc) const {return _id < arc._id;}
219
    };
220

	
221
    static bool direction(Arc arc) {
222
      return (arc._id & 1) == 1;
223
    }
224

	
225
    static Arc direct(Edge edge, bool dir) {
226
      return Arc((edge._id << 1) | (dir ? 1 : 0));
227
    }
228

	
229
    void first(Node& node) const {
230
      node._id = _node_num - 1;
231
    }
232

	
233
    static void next(Node& node) {
234
      --node._id;
235
    }
236

	
237
    void first(Edge& edge) const {
238
      edge._id = _edge_num - 1;
239
    }
240

	
241
    static void next(Edge& edge) {
242
      --edge._id;
243
    }
244

	
245
    void first(Arc& arc) const {
246
      arc._id = 2 * _edge_num - 1;
247
    }
248

	
249
    static void next(Arc& arc) {
250
      --arc._id;
251
    }
252

	
253
    void firstOut(Arc& arc, const Node& node) const {
254
      if (node._id % _width < _width - 1) {
255
        arc._id = (_edge_limit + node._id % _width +
256
                   (node._id / _width) * (_width - 1)) << 1 | 1;
257
        return;
258
      }
259
      if (node._id < _node_num - _width) {
260
        arc._id = node._id << 1 | 1;
261
        return;
262
      }
263
      if (node._id % _width > 0) {
264
        arc._id = (_edge_limit + node._id % _width +
265
                   (node._id / _width) * (_width - 1) - 1) << 1;
266
        return;
267
      }
268
      if (node._id >= _width) {
269
        arc._id = (node._id - _width) << 1;
270
        return;
271
      }
272
      arc._id = -1;
273
    }
274

	
275
    void nextOut(Arc& arc) const {
276
      int nid = arc._id >> 1;
277
      if ((arc._id & 1) == 1) {
278
        if (nid >= _edge_limit) {
279
          nid = (nid - _edge_limit) % (_width - 1) +
280
            (nid - _edge_limit) / (_width - 1) * _width;
281
          if (nid < _node_num - _width) {
282
            arc._id = nid << 1 | 1;
283
            return;
284
          }
285
        }
286
        if (nid % _width > 0) {
287
          arc._id = (_edge_limit + nid % _width +
288
                     (nid / _width) * (_width - 1) - 1) << 1;
289
          return;
290
        }
291
        if (nid >= _width) {
292
          arc._id = (nid - _width) << 1;
293
          return;
294
        }
295
      } else {
296
        if (nid >= _edge_limit) {
297
          nid = (nid - _edge_limit) % (_width - 1) +
298
            (nid - _edge_limit) / (_width - 1) * _width + 1;
299
          if (nid >= _width) {
300
            arc._id = (nid - _width) << 1;
301
            return;
302
          }
303
        }
304
      }
305
      arc._id = -1;
306
    }
307

	
308
    void firstIn(Arc& arc, const Node& node) const {
309
      if (node._id % _width < _width - 1) {
310
        arc._id = (_edge_limit + node._id % _width +
311
                   (node._id / _width) * (_width - 1)) << 1;
312
        return;
313
      }
314
      if (node._id < _node_num - _width) {
315
        arc._id = node._id << 1;
316
        return;
317
      }
318
      if (node._id % _width > 0) {
319
        arc._id = (_edge_limit + node._id % _width +
320
                   (node._id / _width) * (_width - 1) - 1) << 1 | 1;
321
        return;
322
      }
323
      if (node._id >= _width) {
324
        arc._id = (node._id - _width) << 1 | 1;
325
        return;
326
      }
327
      arc._id = -1;
328
    }
329

	
330
    void nextIn(Arc& arc) const {
331
      int nid = arc._id >> 1;
332
      if ((arc._id & 1) == 0) {
333
        if (nid >= _edge_limit) {
334
          nid = (nid - _edge_limit) % (_width - 1) +
335
            (nid - _edge_limit) / (_width - 1) * _width;
336
          if (nid < _node_num - _width) {
337
            arc._id = nid << 1;
338
            return;
339
          }
340
        }
341
        if (nid % _width > 0) {
342
          arc._id = (_edge_limit + nid % _width +
343
                     (nid / _width) * (_width - 1) - 1) << 1 | 1;
344
          return;
345
        }
346
        if (nid >= _width) {
347
          arc._id = (nid - _width) << 1 | 1;
348
          return;
349
        }
350
      } else {
351
        if (nid >= _edge_limit) {
352
          nid = (nid - _edge_limit) % (_width - 1) +
353
            (nid - _edge_limit) / (_width - 1) * _width + 1;
354
          if (nid >= _width) {
355
            arc._id = (nid - _width) << 1 | 1;
356
            return;
357
          }
358
        }
359
      }
360
      arc._id = -1;
361
    }
362

	
363
    void firstInc(Edge& edge, bool& dir, const Node& node) const {
364
      if (node._id % _width < _width - 1) {
365
        edge._id = _edge_limit + node._id % _width +
366
          (node._id / _width) * (_width - 1);
367
        dir = true;
368
        return;
369
      }
370
      if (node._id < _node_num - _width) {
371
        edge._id = node._id;
372
        dir = true;
373
        return;
374
      }
375
      if (node._id % _width > 0) {
376
        edge._id = _edge_limit + node._id % _width +
377
          (node._id / _width) * (_width - 1) - 1;
378
        dir = false;
379
        return;
380
      }
381
      if (node._id >= _width) {
382
        edge._id = node._id - _width;
383
        dir = false;
384
        return;
385
      }
386
      edge._id = -1;
387
      dir = true;
388
    }
389

	
390
    void nextInc(Edge& edge, bool& dir) const {
391
      int nid = edge._id;
392
      if (dir) {
393
        if (nid >= _edge_limit) {
394
          nid = (nid - _edge_limit) % (_width - 1) +
395
            (nid - _edge_limit) / (_width - 1) * _width;
396
          if (nid < _node_num - _width) {
397
            edge._id = nid;
398
            return;
399
          }
400
        }
401
        if (nid % _width > 0) {
402
          edge._id = _edge_limit + nid % _width +
403
            (nid / _width) * (_width - 1) - 1;
404
          dir = false;
405
          return;
406
        }
407
        if (nid >= _width) {
408
          edge._id = nid - _width;
409
          dir = false;
410
          return;
411
        }
412
      } else {
413
        if (nid >= _edge_limit) {
414
          nid = (nid - _edge_limit) % (_width - 1) +
415
            (nid - _edge_limit) / (_width - 1) * _width + 1;
416
          if (nid >= _width) {
417
            edge._id = nid - _width;
418
            return;
419
          }
420
        }
421
      }
422
      edge._id = -1;
423
      dir = true;
424
    }
425

	
426
    Arc right(Node n) const {
427
      if (n._id % _width < _width - 1) {
428
        return Arc(((_edge_limit + n._id % _width +
429
                    (n._id / _width) * (_width - 1)) << 1) | 1);
430
      } else {
431
        return INVALID;
432
      }
433
    }
434

	
435
    Arc left(Node n) const {
436
      if (n._id % _width > 0) {
437
        return Arc((_edge_limit + n._id % _width +
438
                     (n._id / _width) * (_width - 1) - 1) << 1);
439
      } else {
440
        return INVALID;
441
      }
442
    }
443

	
444
    Arc up(Node n) const {
445
      if (n._id < _edge_limit) {
446
        return Arc((n._id << 1) | 1);
447
      } else {
448
        return INVALID;
449
      }
450
    }
451

	
452
    Arc down(Node n) const {
453
      if (n._id >= _width) {
454
        return Arc((n._id - _width) << 1);
455
      } else {
456
        return INVALID;
457
      }
458
    }
459

	
460
  private:
461
    int _width, _height;
462
    int _node_num, _edge_num;
463
    int _edge_limit;
464
  };
465

	
466

	
467
  typedef GraphExtender<GridGraphBase> ExtendedGridGraphBase;
468

	
469
  /// \ingroup graphs
470
  ///
471
  /// \brief Grid graph class
472
  ///
473
  /// This class implements a special graph type. The nodes of the
474
  /// graph can be indexed by two integer \c (i,j) value where \c i is
475
  /// in the \c [0..width()-1] range and j is in the \c
476
  /// [0..height()-1] range.  Two nodes are connected in the graph if
477
  /// the indexes differ exactly on one position and exactly one is
478
  /// the difference. The nodes of the graph can be indexed by position
479
  /// with the \c operator()() function. The positions of the nodes can be
480
  /// get with \c pos(), \c col() and \c row() members. The outgoing
481
  /// arcs can be retrieved with the \c right(), \c up(), \c left()
482
  /// and \c down() functions, where the bottom-left corner is the
483
  /// origin.
484
  ///
485
  /// \image html grid_graph.png
486
  /// \image latex grid_graph.eps "Grid graph" width=\textwidth
487
  ///
488
  /// A short example about the basic usage:
489
  ///\code
490
  /// GridGraph graph(rows, cols);
491
  /// GridGraph::NodeMap<int> val(graph);
492
  /// for (int i = 0; i < graph.width(); ++i) {
493
  ///   for (int j = 0; j < graph.height(); ++j) {
494
  ///     val[graph(i, j)] = i + j;
495
  ///   }
496
  /// }
497
  ///\endcode
498
  ///
499
  /// This graph type fully conforms to the \ref concepts::Graph
500
  /// "Graph concept".
501
  class GridGraph : public ExtendedGridGraphBase {
502
    typedef ExtendedGridGraphBase Parent;
503

	
504
  public:
505

	
506
    /// \brief Map to get the indices of the nodes as dim2::Point<int>.
507
    ///
508
    /// Map to get the indices of the nodes as dim2::Point<int>.
509
    class IndexMap {
510
    public:
511
      /// \brief The key type of the map
512
      typedef GridGraph::Node Key;
513
      /// \brief The value type of the map
514
      typedef dim2::Point<int> Value;
515

	
516
      /// \brief Constructor
517
      ///
518
      /// Constructor
519
      IndexMap(const GridGraph& graph) : _graph(graph) {}
520

	
521
      /// \brief The subscript operator
522
      ///
523
      /// The subscript operator.
524
      Value operator[](Key key) const {
525
        return _graph.pos(key);
526
      }
527

	
528
    private:
529
      const GridGraph& _graph;
530
    };
531

	
532
    /// \brief Map to get the column of the nodes.
533
    ///
534
    /// Map to get the column of the nodes.
535
    class ColMap {
536
    public:
537
      /// \brief The key type of the map
538
      typedef GridGraph::Node Key;
539
      /// \brief The value type of the map
540
      typedef int Value;
541

	
542
      /// \brief Constructor
543
      ///
544
      /// Constructor
545
      ColMap(const GridGraph& graph) : _graph(graph) {}
546

	
547
      /// \brief The subscript operator
548
      ///
549
      /// The subscript operator.
550
      Value operator[](Key key) const {
551
        return _graph.col(key);
552
      }
553

	
554
    private:
555
      const GridGraph& _graph;
556
    };
557

	
558
    /// \brief Map to get the row of the nodes.
559
    ///
560
    /// Map to get the row of the nodes.
561
    class RowMap {
562
    public:
563
      /// \brief The key type of the map
564
      typedef GridGraph::Node Key;
565
      /// \brief The value type of the map
566
      typedef int Value;
567

	
568
      /// \brief Constructor
569
      ///
570
      /// Constructor
571
      RowMap(const GridGraph& graph) : _graph(graph) {}
572

	
573
      /// \brief The subscript operator
574
      ///
575
      /// The subscript operator.
576
      Value operator[](Key key) const {
577
        return _graph.row(key);
578
      }
579

	
580
    private:
581
      const GridGraph& _graph;
582
    };
583

	
584
    /// \brief Constructor
585
    ///
586
    /// Construct a grid graph with given size.
587
    GridGraph(int width, int height) { construct(width, height); }
588

	
589
    /// \brief Resize the graph
590
    ///
591
    /// Resize the graph. The function will fully destroy and rebuild
592
    /// the graph.  This cause that the maps of the graph will
593
    /// reallocated automatically and the previous values will be
594
    /// lost.
595
    void resize(int width, int height) {
596
      Parent::notifier(Arc()).clear();
597
      Parent::notifier(Edge()).clear();
598
      Parent::notifier(Node()).clear();
599
      construct(width, height);
600
      Parent::notifier(Node()).build();
601
      Parent::notifier(Edge()).build();
602
      Parent::notifier(Arc()).build();
603
    }
604

	
605
    /// \brief The node on the given position.
606
    ///
607
    /// Gives back the node on the given position.
608
    Node operator()(int i, int j) const {
609
      return Parent::operator()(i, j);
610
    }
611

	
612
    /// \brief Gives back the column index of the node.
613
    ///
614
    /// Gives back the column index of the node.
615
    int col(Node n) const {
616
      return Parent::col(n);
617
    }
618

	
619
    /// \brief Gives back the row index of the node.
620
    ///
621
    /// Gives back the row index of the node.
622
    int row(Node n) const {
623
      return Parent::row(n);
624
    }
625

	
626
    /// \brief Gives back the position of the node.
627
    ///
628
    /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
629
    dim2::Point<int> pos(Node n) const {
630
      return Parent::pos(n);
631
    }
632

	
633
    /// \brief Gives back the number of the columns.
634
    ///
635
    /// Gives back the number of the columns.
636
    int width() const {
637
      return Parent::width();
638
    }
639

	
640
    /// \brief Gives back the number of the rows.
641
    ///
642
    /// Gives back the number of the rows.
643
    int height() const {
644
      return Parent::height();
645
    }
646

	
647
    /// \brief Gives back the arc goes right from the node.
648
    ///
649
    /// Gives back the arc goes right from the node. If there is not
650
    /// outgoing arc then it gives back INVALID.
651
    Arc right(Node n) const {
652
      return Parent::right(n);
653
    }
654

	
655
    /// \brief Gives back the arc goes left from the node.
656
    ///
657
    /// Gives back the arc goes left from the node. If there is not
658
    /// outgoing arc then it gives back INVALID.
659
    Arc left(Node n) const {
660
      return Parent::left(n);
661
    }
662

	
663
    /// \brief Gives back the arc goes up from the node.
664
    ///
665
    /// Gives back the arc goes up from the node. If there is not
666
    /// outgoing arc then it gives back INVALID.
667
    Arc up(Node n) const {
668
      return Parent::up(n);
669
    }
670

	
671
    /// \brief Gives back the arc goes down from the node.
672
    ///
673
    /// Gives back the arc goes down from the node. If there is not
674
    /// outgoing arc then it gives back INVALID.
675
    Arc down(Node n) const {
676
      return Parent::down(n);
677
    }
678

	
679
    /// \brief Index map of the grid graph
680
    ///
681
    /// Just returns an IndexMap for the grid graph.
682
    IndexMap indexMap() const {
683
      return IndexMap(*this);
684
    }
685

	
686
    /// \brief Row map of the grid graph
687
    ///
688
    /// Just returns a RowMap for the grid graph.
689
    RowMap rowMap() const {
690
      return RowMap(*this);
691
    }
692

	
693
    /// \brief Column map of the grid graph
694
    ///
695
    /// Just returns a ColMap for the grid graph.
696
    ColMap colMap() const {
697
      return ColMap(*this);
698
    }
699

	
700
  };
701

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

	
19
#ifndef LEMON_HAO_ORLIN_H
20
#define LEMON_HAO_ORLIN_H
21

	
22
#include <vector>
23
#include <list>
24
#include <limits>
25

	
26
#include <lemon/maps.h>
27
#include <lemon/core.h>
28
#include <lemon/tolerance.h>
29

	
30
/// \file
31
/// \ingroup min_cut
32
/// \brief Implementation of the Hao-Orlin algorithm.
33
///
34
/// Implementation of the Hao-Orlin algorithm for finding a minimum cut 
35
/// in a digraph.
36

	
37
namespace lemon {
38

	
39
  /// \ingroup min_cut
40
  ///
41
  /// \brief Hao-Orlin algorithm for finding a minimum cut in a digraph.
42
  ///
43
  /// This class implements the Hao-Orlin algorithm for finding a minimum
44
  /// value cut in a directed graph \f$D=(V,A)\f$. 
45
  /// It takes a fixed node \f$ source \in V \f$ and
46
  /// consists of two phases: in the first phase it determines a
47
  /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
48
  /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal outgoing
49
  /// capacity) and in the second phase it determines a minimum cut
50
  /// with \f$ source \f$ on the sink-side (i.e. a set
51
  /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal outgoing
52
  /// capacity). Obviously, the smaller of these two cuts will be a
53
  /// minimum cut of \f$ D \f$. The algorithm is a modified
54
  /// preflow push-relabel algorithm. Our implementation calculates
55
  /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
56
  /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The
57
  /// purpose of such algorithm is e.g. testing network reliability.
58
  ///
59
  /// For an undirected graph you can run just the first phase of the
60
  /// algorithm or you can use the algorithm of Nagamochi and Ibaraki,
61
  /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$ 
62
  /// time. It is implemented in the NagamochiIbaraki algorithm class.
63
  ///
64
  /// \tparam GR The type of the digraph the algorithm runs on.
65
  /// \tparam CAP The type of the arc map containing the capacities,
66
  /// which can be any numreric type. The default map type is
67
  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
68
  /// \tparam TOL Tolerance class for handling inexact computations. The
69
  /// default tolerance type is \ref Tolerance "Tolerance<CAP::Value>".
70
#ifdef DOXYGEN
71
  template <typename GR, typename CAP, typename TOL>
72
#else
73
  template <typename GR,
74
            typename CAP = typename GR::template ArcMap<int>,
75
            typename TOL = Tolerance<typename CAP::Value> >
76
#endif
77
  class HaoOrlin {
78
  public:
79
   
80
    /// The digraph type of the algorithm
81
    typedef GR Digraph;
82
    /// The capacity map type of the algorithm
83
    typedef CAP CapacityMap;
84
    /// The tolerance type of the algorithm
85
    typedef TOL Tolerance;
86

	
87
  private:
88

	
89
    typedef typename CapacityMap::Value Value;
90

	
91
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
92

	
93
    const Digraph& _graph;
94
    const CapacityMap* _capacity;
95

	
96
    typedef typename Digraph::template ArcMap<Value> FlowMap;
97
    FlowMap* _flow;
98

	
99
    Node _source;
100

	
101
    int _node_num;
102

	
103
    // Bucketing structure
104
    std::vector<Node> _first, _last;
105
    typename Digraph::template NodeMap<Node>* _next;
106
    typename Digraph::template NodeMap<Node>* _prev;
107
    typename Digraph::template NodeMap<bool>* _active;
108
    typename Digraph::template NodeMap<int>* _bucket;
109

	
110
    std::vector<bool> _dormant;
111

	
112
    std::list<std::list<int> > _sets;
113
    std::list<int>::iterator _highest;
114

	
115
    typedef typename Digraph::template NodeMap<Value> ExcessMap;
116
    ExcessMap* _excess;
117

	
118
    typedef typename Digraph::template NodeMap<bool> SourceSetMap;
119
    SourceSetMap* _source_set;
120

	
121
    Value _min_cut;
122

	
123
    typedef typename Digraph::template NodeMap<bool> MinCutMap;
124
    MinCutMap* _min_cut_map;
125

	
126
    Tolerance _tolerance;
127

	
128
  public:
129

	
130
    /// \brief Constructor
131
    ///
132
    /// Constructor of the algorithm class.
133
    HaoOrlin(const Digraph& graph, const CapacityMap& capacity,
134
             const Tolerance& tolerance = Tolerance()) :
135
      _graph(graph), _capacity(&capacity), _flow(0), _source(),
136
      _node_num(), _first(), _last(), _next(0), _prev(0),
137
      _active(0), _bucket(0), _dormant(), _sets(), _highest(),
138
      _excess(0), _source_set(0), _min_cut(), _min_cut_map(0),
139
      _tolerance(tolerance) {}
140

	
141
    ~HaoOrlin() {
142
      if (_min_cut_map) {
143
        delete _min_cut_map;
144
      }
145
      if (_source_set) {
146
        delete _source_set;
147
      }
148
      if (_excess) {
149
        delete _excess;
150
      }
151
      if (_next) {
152
        delete _next;
153
      }
154
      if (_prev) {
155
        delete _prev;
156
      }
157
      if (_active) {
158
        delete _active;
159
      }
160
      if (_bucket) {
161
        delete _bucket;
162
      }
163
      if (_flow) {
164
        delete _flow;
165
      }
166
    }
167

	
168
  private:
169

	
170
    void activate(const Node& i) {
171
      (*_active)[i] = true;
172

	
173
      int bucket = (*_bucket)[i];
174

	
175
      if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return;
176
      //unlace
177
      (*_next)[(*_prev)[i]] = (*_next)[i];
178
      if ((*_next)[i] != INVALID) {
179
        (*_prev)[(*_next)[i]] = (*_prev)[i];
180
      } else {
181
        _last[bucket] = (*_prev)[i];
182
      }
183
      //lace
184
      (*_next)[i] = _first[bucket];
185
      (*_prev)[_first[bucket]] = i;
186
      (*_prev)[i] = INVALID;
187
      _first[bucket] = i;
188
    }
189

	
190
    void deactivate(const Node& i) {
191
      (*_active)[i] = false;
192
      int bucket = (*_bucket)[i];
193

	
194
      if ((*_next)[i] == INVALID || !(*_active)[(*_next)[i]]) return;
195

	
196
      //unlace
197
      (*_prev)[(*_next)[i]] = (*_prev)[i];
198
      if ((*_prev)[i] != INVALID) {
199
        (*_next)[(*_prev)[i]] = (*_next)[i];
200
      } else {
201
        _first[bucket] = (*_next)[i];
202
      }
203
      //lace
204
      (*_prev)[i] = _last[bucket];
205
      (*_next)[_last[bucket]] = i;
206
      (*_next)[i] = INVALID;
207
      _last[bucket] = i;
208
    }
209

	
210
    void addItem(const Node& i, int bucket) {
211
      (*_bucket)[i] = bucket;
212
      if (_last[bucket] != INVALID) {
213
        (*_prev)[i] = _last[bucket];
214
        (*_next)[_last[bucket]] = i;
215
        (*_next)[i] = INVALID;
216
        _last[bucket] = i;
217
      } else {
218
        (*_prev)[i] = INVALID;
219
        _first[bucket] = i;
220
        (*_next)[i] = INVALID;
221
        _last[bucket] = i;
222
      }
223
    }
224

	
225
    void findMinCutOut() {
226

	
227
      for (NodeIt n(_graph); n != INVALID; ++n) {
228
        (*_excess)[n] = 0;
229
        (*_source_set)[n] = false;
230
      }
231

	
232
      for (ArcIt a(_graph); a != INVALID; ++a) {
233
        (*_flow)[a] = 0;
234
      }
235

	
236
      int bucket_num = 0;
237
      std::vector<Node> queue(_node_num);
238
      int qfirst = 0, qlast = 0, qsep = 0;
239

	
240
      {
241
        typename Digraph::template NodeMap<bool> reached(_graph, false);
242

	
243
        reached[_source] = true;
244
        bool first_set = true;
245

	
246
        for (NodeIt t(_graph); t != INVALID; ++t) {
247
          if (reached[t]) continue;
248
          _sets.push_front(std::list<int>());
249

	
250
          queue[qlast++] = t;
251
          reached[t] = true;
252

	
253
          while (qfirst != qlast) {
254
            if (qsep == qfirst) {
255
              ++bucket_num;
256
              _sets.front().push_front(bucket_num);
257
              _dormant[bucket_num] = !first_set;
258
              _first[bucket_num] = _last[bucket_num] = INVALID;
259
              qsep = qlast;
260
            }
261

	
262
            Node n = queue[qfirst++];
263
            addItem(n, bucket_num);
264

	
265
            for (InArcIt a(_graph, n); a != INVALID; ++a) {
266
              Node u = _graph.source(a);
267
              if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
268
                reached[u] = true;
269
                queue[qlast++] = u;
270
              }
271
            }
272
          }
273
          first_set = false;
274
        }
275

	
276
        ++bucket_num;
277
        (*_bucket)[_source] = 0;
278
        _dormant[0] = true;
279
      }
280
      (*_source_set)[_source] = true;
281

	
282
      Node target = _last[_sets.back().back()];
283
      {
284
        for (OutArcIt a(_graph, _source); a != INVALID; ++a) {
285
          if (_tolerance.positive((*_capacity)[a])) {
286
            Node u = _graph.target(a);
287
            (*_flow)[a] = (*_capacity)[a];
288
            (*_excess)[u] += (*_capacity)[a];
289
            if (!(*_active)[u] && u != _source) {
290
              activate(u);
291
            }
292
          }
293
        }
294

	
295
        if ((*_active)[target]) {
296
          deactivate(target);
297
        }
298

	
299
        _highest = _sets.back().begin();
300
        while (_highest != _sets.back().end() &&
301
               !(*_active)[_first[*_highest]]) {
302
          ++_highest;
303
        }
304
      }
305

	
306
      while (true) {
307
        while (_highest != _sets.back().end()) {
308
          Node n = _first[*_highest];
309
          Value excess = (*_excess)[n];
310
          int next_bucket = _node_num;
311

	
312
          int under_bucket;
313
          if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
314
            under_bucket = -1;
315
          } else {
316
            under_bucket = *(++std::list<int>::iterator(_highest));
317
          }
318

	
319
          for (OutArcIt a(_graph, n); a != INVALID; ++a) {
320
            Node v = _graph.target(a);
321
            if (_dormant[(*_bucket)[v]]) continue;
322
            Value rem = (*_capacity)[a] - (*_flow)[a];
323
            if (!_tolerance.positive(rem)) continue;
324
            if ((*_bucket)[v] == under_bucket) {
325
              if (!(*_active)[v] && v != target) {
326
                activate(v);
327
              }
328
              if (!_tolerance.less(rem, excess)) {
329
                (*_flow)[a] += excess;
330
                (*_excess)[v] += excess;
331
                excess = 0;
332
                goto no_more_push;
333
              } else {
334
                excess -= rem;
335
                (*_excess)[v] += rem;
336
                (*_flow)[a] = (*_capacity)[a];
337
              }
338
            } else if (next_bucket > (*_bucket)[v]) {
339
              next_bucket = (*_bucket)[v];
340
            }
341
          }
342

	
343
          for (InArcIt a(_graph, n); a != INVALID; ++a) {
344
            Node v = _graph.source(a);
345
            if (_dormant[(*_bucket)[v]]) continue;
346
            Value rem = (*_flow)[a];
347
            if (!_tolerance.positive(rem)) continue;
348
            if ((*_bucket)[v] == under_bucket) {
349
              if (!(*_active)[v] && v != target) {
350
                activate(v);
351
              }
352
              if (!_tolerance.less(rem, excess)) {
353
                (*_flow)[a] -= excess;
354
                (*_excess)[v] += excess;
355
                excess = 0;
356
                goto no_more_push;
357
              } else {
358
                excess -= rem;
359
                (*_excess)[v] += rem;
360
                (*_flow)[a] = 0;
361
              }
362
            } else if (next_bucket > (*_bucket)[v]) {
363
              next_bucket = (*_bucket)[v];
364
            }
365
          }
366

	
367
        no_more_push:
368

	
369
          (*_excess)[n] = excess;
370

	
371
          if (excess != 0) {
372
            if ((*_next)[n] == INVALID) {
373
              typename std::list<std::list<int> >::iterator new_set =
374
                _sets.insert(--_sets.end(), std::list<int>());
375
              new_set->splice(new_set->end(), _sets.back(),
376
                              _sets.back().begin(), ++_highest);
377
              for (std::list<int>::iterator it = new_set->begin();
378
                   it != new_set->end(); ++it) {
379
                _dormant[*it] = true;
380
              }
381
              while (_highest != _sets.back().end() &&
382
                     !(*_active)[_first[*_highest]]) {
383
                ++_highest;
384
              }
385
            } else if (next_bucket == _node_num) {
386
              _first[(*_bucket)[n]] = (*_next)[n];
387
              (*_prev)[(*_next)[n]] = INVALID;
388

	
389
              std::list<std::list<int> >::iterator new_set =
390
                _sets.insert(--_sets.end(), std::list<int>());
391

	
392
              new_set->push_front(bucket_num);
393
              (*_bucket)[n] = bucket_num;
394
              _first[bucket_num] = _last[bucket_num] = n;
395
              (*_next)[n] = INVALID;
396
              (*_prev)[n] = INVALID;
397
              _dormant[bucket_num] = true;
398
              ++bucket_num;
399

	
400
              while (_highest != _sets.back().end() &&
401
                     !(*_active)[_first[*_highest]]) {
402
                ++_highest;
403
              }
404
            } else {
405
              _first[*_highest] = (*_next)[n];
406
              (*_prev)[(*_next)[n]] = INVALID;
407

	
408
              while (next_bucket != *_highest) {
409
                --_highest;
410
              }
411

	
412
              if (_highest == _sets.back().begin()) {
413
                _sets.back().push_front(bucket_num);
414
                _dormant[bucket_num] = false;
415
                _first[bucket_num] = _last[bucket_num] = INVALID;
416
                ++bucket_num;
417
              }
418
              --_highest;
419

	
420
              (*_bucket)[n] = *_highest;
421
              (*_next)[n] = _first[*_highest];
422
              if (_first[*_highest] != INVALID) {
423
                (*_prev)[_first[*_highest]] = n;
424
              } else {
425
                _last[*_highest] = n;
426
              }
427
              _first[*_highest] = n;
428
            }
429
          } else {
430

	
431
            deactivate(n);
432
            if (!(*_active)[_first[*_highest]]) {
433
              ++_highest;
434
              if (_highest != _sets.back().end() &&
435
                  !(*_active)[_first[*_highest]]) {
436
                _highest = _sets.back().end();
437
              }
438
            }
439
          }
440
        }
441

	
442
        if ((*_excess)[target] < _min_cut) {
443
          _min_cut = (*_excess)[target];
444
          for (NodeIt i(_graph); i != INVALID; ++i) {
445
            (*_min_cut_map)[i] = true;
446
          }
447
          for (std::list<int>::iterator it = _sets.back().begin();
448
               it != _sets.back().end(); ++it) {
449
            Node n = _first[*it];
450
            while (n != INVALID) {
451
              (*_min_cut_map)[n] = false;
452
              n = (*_next)[n];
453
            }
454
          }
455
        }
456

	
457
        {
458
          Node new_target;
459
          if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
460
            if ((*_next)[target] == INVALID) {
461
              _last[(*_bucket)[target]] = (*_prev)[target];
462
              new_target = (*_prev)[target];
463
            } else {
464
              (*_prev)[(*_next)[target]] = (*_prev)[target];
465
              new_target = (*_next)[target];
466
            }
467
            if ((*_prev)[target] == INVALID) {
468
              _first[(*_bucket)[target]] = (*_next)[target];
469
            } else {
470
              (*_next)[(*_prev)[target]] = (*_next)[target];
471
            }
472
          } else {
473
            _sets.back().pop_back();
474
            if (_sets.back().empty()) {
475
              _sets.pop_back();
476
              if (_sets.empty())
477
                break;
478
              for (std::list<int>::iterator it = _sets.back().begin();
479
                   it != _sets.back().end(); ++it) {
480
                _dormant[*it] = false;
481
              }
482
            }
483
            new_target = _last[_sets.back().back()];
484
          }
485

	
486
          (*_bucket)[target] = 0;
487

	
488
          (*_source_set)[target] = true;
489
          for (OutArcIt a(_graph, target); a != INVALID; ++a) {
490
            Value rem = (*_capacity)[a] - (*_flow)[a];
491
            if (!_tolerance.positive(rem)) continue;
492
            Node v = _graph.target(a);
493
            if (!(*_active)[v] && !(*_source_set)[v]) {
494
              activate(v);
495
            }
496
            (*_excess)[v] += rem;
497
            (*_flow)[a] = (*_capacity)[a];
498
          }
499

	
500
          for (InArcIt a(_graph, target); a != INVALID; ++a) {
501
            Value rem = (*_flow)[a];
502
            if (!_tolerance.positive(rem)) continue;
503
            Node v = _graph.source(a);
504
            if (!(*_active)[v] && !(*_source_set)[v]) {
505
              activate(v);
506
            }
507
            (*_excess)[v] += rem;
508
            (*_flow)[a] = 0;
509
          }
510

	
511
          target = new_target;
512
          if ((*_active)[target]) {
513
            deactivate(target);
514
          }
515

	
516
          _highest = _sets.back().begin();
517
          while (_highest != _sets.back().end() &&
518
                 !(*_active)[_first[*_highest]]) {
519
            ++_highest;
520
          }
521
        }
522
      }
523
    }
524

	
525
    void findMinCutIn() {
526

	
527
      for (NodeIt n(_graph); n != INVALID; ++n) {
528
        (*_excess)[n] = 0;
529
        (*_source_set)[n] = false;
530
      }
531

	
532
      for (ArcIt a(_graph); a != INVALID; ++a) {
533
        (*_flow)[a] = 0;
534
      }
535

	
536
      int bucket_num = 0;
537
      std::vector<Node> queue(_node_num);
538
      int qfirst = 0, qlast = 0, qsep = 0;
539

	
540
      {
541
        typename Digraph::template NodeMap<bool> reached(_graph, false);
542

	
543
        reached[_source] = true;
544

	
545
        bool first_set = true;
546

	
547
        for (NodeIt t(_graph); t != INVALID; ++t) {
548
          if (reached[t]) continue;
549
          _sets.push_front(std::list<int>());
550

	
551
          queue[qlast++] = t;
552
          reached[t] = true;
553

	
554
          while (qfirst != qlast) {
555
            if (qsep == qfirst) {
556
              ++bucket_num;
557
              _sets.front().push_front(bucket_num);
558
              _dormant[bucket_num] = !first_set;
559
              _first[bucket_num] = _last[bucket_num] = INVALID;
560
              qsep = qlast;
561
            }
562

	
563
            Node n = queue[qfirst++];
564
            addItem(n, bucket_num);
565

	
566
            for (OutArcIt a(_graph, n); a != INVALID; ++a) {
567
              Node u = _graph.target(a);
568
              if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
569
                reached[u] = true;
570
                queue[qlast++] = u;
571
              }
572
            }
573
          }
574
          first_set = false;
575
        }
576

	
577
        ++bucket_num;
578
        (*_bucket)[_source] = 0;
579
        _dormant[0] = true;
580
      }
581
      (*_source_set)[_source] = true;
582

	
583
      Node target = _last[_sets.back().back()];
584
      {
585
        for (InArcIt a(_graph, _source); a != INVALID; ++a) {
586
          if (_tolerance.positive((*_capacity)[a])) {
587
            Node u = _graph.source(a);
588
            (*_flow)[a] = (*_capacity)[a];
589
            (*_excess)[u] += (*_capacity)[a];
590
            if (!(*_active)[u] && u != _source) {
591
              activate(u);
592
            }
593
          }
594
        }
595
        if ((*_active)[target]) {
596
          deactivate(target);
597
        }
598

	
599
        _highest = _sets.back().begin();
600
        while (_highest != _sets.back().end() &&
601
               !(*_active)[_first[*_highest]]) {
602
          ++_highest;
603
        }
604
      }
605

	
606

	
607
      while (true) {
608
        while (_highest != _sets.back().end()) {
609
          Node n = _first[*_highest];
610
          Value excess = (*_excess)[n];
611
          int next_bucket = _node_num;
612

	
613
          int under_bucket;
614
          if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
615
            under_bucket = -1;
616
          } else {
617
            under_bucket = *(++std::list<int>::iterator(_highest));
618
          }
619

	
620
          for (InArcIt a(_graph, n); a != INVALID; ++a) {
621
            Node v = _graph.source(a);
622
            if (_dormant[(*_bucket)[v]]) continue;
623
            Value rem = (*_capacity)[a] - (*_flow)[a];
624
            if (!_tolerance.positive(rem)) continue;
625
            if ((*_bucket)[v] == under_bucket) {
626
              if (!(*_active)[v] && v != target) {
627
                activate(v);
628
              }
629
              if (!_tolerance.less(rem, excess)) {
630
                (*_flow)[a] += excess;
631
                (*_excess)[v] += excess;
632
                excess = 0;
633
                goto no_more_push;
634
              } else {
635
                excess -= rem;
636
                (*_excess)[v] += rem;
637
                (*_flow)[a] = (*_capacity)[a];
638
              }
639
            } else if (next_bucket > (*_bucket)[v]) {
640
              next_bucket = (*_bucket)[v];
641
            }
642
          }
643

	
644
          for (OutArcIt a(_graph, n); a != INVALID; ++a) {
645
            Node v = _graph.target(a);
646
            if (_dormant[(*_bucket)[v]]) continue;
647
            Value rem = (*_flow)[a];
648
            if (!_tolerance.positive(rem)) continue;
649
            if ((*_bucket)[v] == under_bucket) {
650
              if (!(*_active)[v] && v != target) {
651
                activate(v);
652
              }
653
              if (!_tolerance.less(rem, excess)) {
654
                (*_flow)[a] -= excess;
655
                (*_excess)[v] += excess;
656
                excess = 0;
657
                goto no_more_push;
658
              } else {
659
                excess -= rem;
660
                (*_excess)[v] += rem;
661
                (*_flow)[a] = 0;
662
              }
663
            } else if (next_bucket > (*_bucket)[v]) {
664
              next_bucket = (*_bucket)[v];
665
            }
666
          }
667

	
668
        no_more_push:
669

	
670
          (*_excess)[n] = excess;
671

	
672
          if (excess != 0) {
673
            if ((*_next)[n] == INVALID) {
674
              typename std::list<std::list<int> >::iterator new_set =
675
                _sets.insert(--_sets.end(), std::list<int>());
676
              new_set->splice(new_set->end(), _sets.back(),
677
                              _sets.back().begin(), ++_highest);
678
              for (std::list<int>::iterator it = new_set->begin();
679
                   it != new_set->end(); ++it) {
680
                _dormant[*it] = true;
681
              }
682
              while (_highest != _sets.back().end() &&
683
                     !(*_active)[_first[*_highest]]) {
684
                ++_highest;
685
              }
686
            } else if (next_bucket == _node_num) {
687
              _first[(*_bucket)[n]] = (*_next)[n];
688
              (*_prev)[(*_next)[n]] = INVALID;
689

	
690
              std::list<std::list<int> >::iterator new_set =
691
                _sets.insert(--_sets.end(), std::list<int>());
692

	
693
              new_set->push_front(bucket_num);
694
              (*_bucket)[n] = bucket_num;
695
              _first[bucket_num] = _last[bucket_num] = n;
696
              (*_next)[n] = INVALID;
697
              (*_prev)[n] = INVALID;
698
              _dormant[bucket_num] = true;
699
              ++bucket_num;
700

	
701
              while (_highest != _sets.back().end() &&
702
                     !(*_active)[_first[*_highest]]) {
703
                ++_highest;
704
              }
705
            } else {
706
              _first[*_highest] = (*_next)[n];
707
              (*_prev)[(*_next)[n]] = INVALID;
708

	
709
              while (next_bucket != *_highest) {
710
                --_highest;
711
              }
712
              if (_highest == _sets.back().begin()) {
713
                _sets.back().push_front(bucket_num);
714
                _dormant[bucket_num] = false;
715
                _first[bucket_num] = _last[bucket_num] = INVALID;
716
                ++bucket_num;
717
              }
718
              --_highest;
719

	
720
              (*_bucket)[n] = *_highest;
721
              (*_next)[n] = _first[*_highest];
722
              if (_first[*_highest] != INVALID) {
723
                (*_prev)[_first[*_highest]] = n;
724
              } else {
725
                _last[*_highest] = n;
726
              }
727
              _first[*_highest] = n;
728
            }
729
          } else {
730

	
731
            deactivate(n);
732
            if (!(*_active)[_first[*_highest]]) {
733
              ++_highest;
734
              if (_highest != _sets.back().end() &&
735
                  !(*_active)[_first[*_highest]]) {
736
                _highest = _sets.back().end();
737
              }
738
            }
739
          }
740
        }
741

	
742
        if ((*_excess)[target] < _min_cut) {
743
          _min_cut = (*_excess)[target];
744
          for (NodeIt i(_graph); i != INVALID; ++i) {
745
            (*_min_cut_map)[i] = false;
746
          }
747
          for (std::list<int>::iterator it = _sets.back().begin();
748
               it != _sets.back().end(); ++it) {
749
            Node n = _first[*it];
750
            while (n != INVALID) {
751
              (*_min_cut_map)[n] = true;
752
              n = (*_next)[n];
753
            }
754
          }
755
        }
756

	
757
        {
758
          Node new_target;
759
          if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
760
            if ((*_next)[target] == INVALID) {
761
              _last[(*_bucket)[target]] = (*_prev)[target];
762
              new_target = (*_prev)[target];
763
            } else {
764
              (*_prev)[(*_next)[target]] = (*_prev)[target];
765
              new_target = (*_next)[target];
766
            }
767
            if ((*_prev)[target] == INVALID) {
768
              _first[(*_bucket)[target]] = (*_next)[target];
769
            } else {
770
              (*_next)[(*_prev)[target]] = (*_next)[target];
771
            }
772
          } else {
773
            _sets.back().pop_back();
774
            if (_sets.back().empty()) {
775
              _sets.pop_back();
776
              if (_sets.empty())
777
                break;
778
              for (std::list<int>::iterator it = _sets.back().begin();
779
                   it != _sets.back().end(); ++it) {
780
                _dormant[*it] = false;
781
              }
782
            }
783
            new_target = _last[_sets.back().back()];
784
          }
785

	
786
          (*_bucket)[target] = 0;
787

	
788
          (*_source_set)[target] = true;
789
          for (InArcIt a(_graph, target); a != INVALID; ++a) {
790
            Value rem = (*_capacity)[a] - (*_flow)[a];
791
            if (!_tolerance.positive(rem)) continue;
792
            Node v = _graph.source(a);
793
            if (!(*_active)[v] && !(*_source_set)[v]) {
794
              activate(v);
795
            }
796
            (*_excess)[v] += rem;
797
            (*_flow)[a] = (*_capacity)[a];
798
          }
799

	
800
          for (OutArcIt a(_graph, target); a != INVALID; ++a) {
801
            Value rem = (*_flow)[a];
802
            if (!_tolerance.positive(rem)) continue;
803
            Node v = _graph.target(a);
804
            if (!(*_active)[v] && !(*_source_set)[v]) {
805
              activate(v);
806
            }
807
            (*_excess)[v] += rem;
808
            (*_flow)[a] = 0;
809
          }
810

	
811
          target = new_target;
812
          if ((*_active)[target]) {
813
            deactivate(target);
814
          }
815

	
816
          _highest = _sets.back().begin();
817
          while (_highest != _sets.back().end() &&
818
                 !(*_active)[_first[*_highest]]) {
819
            ++_highest;
820
          }
821
        }
822
      }
823
    }
824

	
825
  public:
826

	
827
    /// \name Execution Control
828
    /// The simplest way to execute the algorithm is to use
829
    /// one of the member functions called \ref run().
830
    /// \n
831
    /// If you need better control on the execution,
832
    /// you have to call one of the \ref init() functions first, then
833
    /// \ref calculateOut() and/or \ref calculateIn().
834

	
835
    /// @{
836

	
837
    /// \brief Initialize the internal data structures.
838
    ///
839
    /// This function initializes the internal data structures. It creates
840
    /// the maps and some bucket structures for the algorithm.
841
    /// The first node is used as the source node for the push-relabel
842
    /// algorithm.
843
    void init() {
844
      init(NodeIt(_graph));
845
    }
846

	
847
    /// \brief Initialize the internal data structures.
848
    ///
849
    /// This function initializes the internal data structures. It creates
850
    /// the maps and some bucket structures for the algorithm. 
851
    /// The given node is used as the source node for the push-relabel
852
    /// algorithm.
853
    void init(const Node& source) {
854
      _source = source;
855

	
856
      _node_num = countNodes(_graph);
857

	
858
      _first.resize(_node_num);
859
      _last.resize(_node_num);
860

	
861
      _dormant.resize(_node_num);
862

	
863
      if (!_flow) {
864
        _flow = new FlowMap(_graph);
865
      }
866
      if (!_next) {
867
        _next = new typename Digraph::template NodeMap<Node>(_graph);
868
      }
869
      if (!_prev) {
870
        _prev = new typename Digraph::template NodeMap<Node>(_graph);
871
      }
872
      if (!_active) {
873
        _active = new typename Digraph::template NodeMap<bool>(_graph);
874
      }
875
      if (!_bucket) {
876
        _bucket = new typename Digraph::template NodeMap<int>(_graph);
877
      }
878
      if (!_excess) {
879
        _excess = new ExcessMap(_graph);
880
      }
881
      if (!_source_set) {
882
        _source_set = new SourceSetMap(_graph);
883
      }
884
      if (!_min_cut_map) {
885
        _min_cut_map = new MinCutMap(_graph);
886
      }
887

	
888
      _min_cut = std::numeric_limits<Value>::max();
889
    }
890

	
891

	
892
    /// \brief Calculate a minimum cut with \f$ source \f$ on the
893
    /// source-side.
894
    ///
895
    /// This function calculates a minimum cut with \f$ source \f$ on the
896
    /// source-side (i.e. a set \f$ X\subsetneq V \f$ with
897
    /// \f$ source \in X \f$ and minimal outgoing capacity).
898
    ///
899
    /// \pre \ref init() must be called before using this function.
900
    void calculateOut() {
901
      findMinCutOut();
902
    }
903

	
904
    /// \brief Calculate a minimum cut with \f$ source \f$ on the
905
    /// sink-side.
906
    ///
907
    /// This function calculates a minimum cut with \f$ source \f$ on the
908
    /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with
909
    /// \f$ source \notin X \f$ and minimal outgoing capacity).
910
    ///
911
    /// \pre \ref init() must be called before using this function.
912
    void calculateIn() {
913
      findMinCutIn();
914
    }
915

	
916

	
917
    /// \brief Run the algorithm.
918
    ///
919
    /// This function runs the algorithm. It finds nodes \c source and
920
    /// \c target arbitrarily and then calls \ref init(), \ref calculateOut()
921
    /// and \ref calculateIn().
922
    void run() {
923
      init();
924
      calculateOut();
925
      calculateIn();
926
    }
927

	
928
    /// \brief Run the algorithm.
929
    ///
930
    /// This function runs the algorithm. It uses the given \c source node, 
931
    /// finds a proper \c target node and then calls the \ref init(),
932
    /// \ref calculateOut() and \ref calculateIn().
933
    void run(const Node& s) {
934
      init(s);
935
      calculateOut();
936
      calculateIn();
937
    }
938

	
939
    /// @}
940

	
941
    /// \name Query Functions
942
    /// The result of the %HaoOrlin algorithm
943
    /// can be obtained using these functions.\n
944
    /// \ref run(), \ref calculateOut() or \ref calculateIn() 
945
    /// should be called before using them.
946

	
947
    /// @{
948

	
949
    /// \brief Return the value of the minimum cut.
950
    ///
951
    /// This function returns the value of the minimum cut.
952
    ///
953
    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 
954
    /// must be called before using this function.
955
    Value minCutValue() const {
956
      return _min_cut;
957
    }
958

	
959

	
960
    /// \brief Return a minimum cut.
961
    ///
962
    /// This function sets \c cutMap to the characteristic vector of a
963
    /// minimum value cut: it will give a non-empty set \f$ X\subsetneq V \f$
964
    /// with minimal outgoing capacity (i.e. \c cutMap will be \c true exactly
965
    /// for the nodes of \f$ X \f$).
966
    ///
967
    /// \param cutMap A \ref concepts::WriteMap "writable" node map with
968
    /// \c bool (or convertible) value type.
969
    ///
970
    /// \return The value of the minimum cut.
971
    ///
972
    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 
973
    /// must be called before using this function.
974
    template <typename CutMap>
975
    Value minCutMap(CutMap& cutMap) const {
976
      for (NodeIt it(_graph); it != INVALID; ++it) {
977
        cutMap.set(it, (*_min_cut_map)[it]);
978
      }
979
      return _min_cut;
980
    }
981

	
982
    /// @}
983

	
984
  }; //class HaoOrlin
985

	
986
} //namespace lemon
987

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

	
19
#ifndef HYPERCUBE_GRAPH_H
20
#define HYPERCUBE_GRAPH_H
21

	
22
#include <vector>
23
#include <lemon/core.h>
24
#include <lemon/assert.h>
25
#include <lemon/bits/graph_extender.h>
26

	
27
///\ingroup graphs
28
///\file
29
///\brief HypercubeGraph class.
30

	
31
namespace lemon {
32

	
33
  class HypercubeGraphBase {
34

	
35
  public:
36

	
37
    typedef HypercubeGraphBase Graph;
38

	
39
    class Node;
40
    class Edge;
41
    class Arc;
42

	
43
  public:
44

	
45
    HypercubeGraphBase() {}
46

	
47
  protected:
48

	
49
    void construct(int dim) {
50
      LEMON_ASSERT(dim >= 1, "The number of dimensions must be at least 1.");
51
      _dim = dim;
52
      _node_num = 1 << dim;
53
      _edge_num = dim * (1 << (dim-1));
54
    }
55

	
56
  public:
57

	
58
    typedef True NodeNumTag;
59
    typedef True EdgeNumTag;
60
    typedef True ArcNumTag;
61

	
62
    int nodeNum() const { return _node_num; }
63
    int edgeNum() const { return _edge_num; }
64
    int arcNum() const { return 2 * _edge_num; }
65

	
66
    int maxNodeId() const { return _node_num - 1; }
67
    int maxEdgeId() const { return _edge_num - 1; }
68
    int maxArcId() const { return 2 * _edge_num - 1; }
69

	
70
    static Node nodeFromId(int id) { return Node(id); }
71
    static Edge edgeFromId(int id) { return Edge(id); }
72
    static Arc arcFromId(int id) { return Arc(id); }
73

	
74
    static int id(Node node) { return node._id; }
75
    static int id(Edge edge) { return edge._id; }
76
    static int id(Arc arc) { return arc._id; }
77

	
78
    Node u(Edge edge) const {
79
      int base = edge._id & ((1 << (_dim-1)) - 1);
80
      int k = edge._id >> (_dim-1);
81
      return ((base >> k) << (k+1)) | (base & ((1 << k) - 1));
82
    }
83

	
84
    Node v(Edge edge) const {
85
      int base = edge._id & ((1 << (_dim-1)) - 1);
86
      int k = edge._id >> (_dim-1);
87
      return ((base >> k) << (k+1)) | (base & ((1 << k) - 1)) | (1 << k);
88
    }
89

	
90
    Node source(Arc arc) const {
91
      return (arc._id & 1) == 1 ? u(arc) : v(arc);
92
    }
93

	
94
    Node target(Arc arc) const {
95
      return (arc._id & 1) == 1 ? v(arc) : u(arc);
96
    }
97

	
98
    typedef True FindEdgeTag;
99
    typedef True FindArcTag;
100

	
101
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
102
      if (prev != INVALID) return INVALID;
103
      int d = u._id ^ v._id;
104
      int k = 0;
105
      if (d == 0) return INVALID;
106
      for ( ; (d & 1) == 0; d >>= 1) ++k;
107
      if (d >> 1 != 0) return INVALID;
108
      return (k << (_dim-1)) | ((u._id >> (k+1)) << k) |
109
        (u._id & ((1 << k) - 1));
110
    }
111

	
112
    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
113
      Edge edge = findEdge(u, v, prev);
114
      if (edge == INVALID) return INVALID;
115
      int k = edge._id >> (_dim-1);
116
      return ((u._id >> k) & 1) == 1 ? edge._id << 1 : (edge._id << 1) | 1;
117
    }
118

	
119
    class Node {
120
      friend class HypercubeGraphBase;
121

	
122
    protected:
123
      int _id;
124
      Node(int id) : _id(id) {}
125
    public:
126
      Node() {}
127
      Node (Invalid) : _id(-1) {}
128
      bool operator==(const Node node) const {return _id == node._id;}
129
      bool operator!=(const Node node) const {return _id != node._id;}
130
      bool operator<(const Node node) const {return _id < node._id;}
131
    };
132

	
133
    class Edge {
134
      friend class HypercubeGraphBase;
135
      friend class Arc;
136

	
137
    protected:
138
      int _id;
139

	
140
      Edge(int id) : _id(id) {}
141

	
142
    public:
143
      Edge() {}
144
      Edge (Invalid) : _id(-1) {}
145
      bool operator==(const Edge edge) const {return _id == edge._id;}
146
      bool operator!=(const Edge edge) const {return _id != edge._id;}
147
      bool operator<(const Edge edge) const {return _id < edge._id;}
148
    };
149

	
150
    class Arc {
151
      friend class HypercubeGraphBase;
152

	
153
    protected:
154
      int _id;
155

	
156
      Arc(int id) : _id(id) {}
157

	
158
    public:
159
      Arc() {}
160
      Arc (Invalid) : _id(-1) {}
161
      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
162
      bool operator==(const Arc arc) const {return _id == arc._id;}
163
      bool operator!=(const Arc arc) const {return _id != arc._id;}
164
      bool operator<(const Arc arc) const {return _id < arc._id;}
165
    };
166

	
167
    void first(Node& node) const {
168
      node._id = _node_num - 1;
169
    }
170

	
171
    static void next(Node& node) {
172
      --node._id;
173
    }
174

	
175
    void first(Edge& edge) const {
176
      edge._id = _edge_num - 1;
177
    }
178

	
179
    static void next(Edge& edge) {
180
      --edge._id;
181
    }
182

	
183
    void first(Arc& arc) const {
184
      arc._id = 2 * _edge_num - 1;
185
    }
186

	
187
    static void next(Arc& arc) {
188
      --arc._id;
189
    }
190

	
191
    void firstInc(Edge& edge, bool& dir, const Node& node) const {
192
      edge._id = node._id >> 1;
193
      dir = (node._id & 1) == 0;
194
    }
195

	
196
    void nextInc(Edge& edge, bool& dir) const {
197
      Node n = dir ? u(edge) : v(edge);
198
      int k = (edge._id >> (_dim-1)) + 1;
199
      if (k < _dim) {
200
        edge._id = (k << (_dim-1)) |
201
          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
202
        dir = ((n._id >> k) & 1) == 0;
203
      } else {
204
        edge._id = -1;
205
        dir = true;
206
      }
207
    }
208

	
209
    void firstOut(Arc& arc, const Node& node) const {
210
      arc._id = ((node._id >> 1) << 1) | (~node._id & 1);
211
    }
212

	
213
    void nextOut(Arc& arc) const {
214
      Node n = (arc._id & 1) == 1 ? u(arc) : v(arc);
215
      int k = (arc._id >> _dim) + 1;
216
      if (k < _dim) {
217
        arc._id = (k << (_dim-1)) |
218
          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
219
        arc._id = (arc._id << 1) | (~(n._id >> k) & 1);
220
      } else {
221
        arc._id = -1;
222
      }
223
    }
224

	
225
    void firstIn(Arc& arc, const Node& node) const {
226
      arc._id = ((node._id >> 1) << 1) | (node._id & 1);
227
    }
228

	
229
    void nextIn(Arc& arc) const {
230
      Node n = (arc._id & 1) == 1 ? v(arc) : u(arc);
231
      int k = (arc._id >> _dim) + 1;
232
      if (k < _dim) {
233
        arc._id = (k << (_dim-1)) |
234
          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
235
        arc._id = (arc._id << 1) | ((n._id >> k) & 1);
236
      } else {
237
        arc._id = -1;
238
      }
239
    }
240

	
241
    static bool direction(Arc arc) {
242
      return (arc._id & 1) == 1;
243
    }
244

	
245
    static Arc direct(Edge edge, bool dir) {
246
      return Arc((edge._id << 1) | (dir ? 1 : 0));
247
    }
248

	
249
    int dimension() const {
250
      return _dim;
251
    }
252

	
253
    bool projection(Node node, int n) const {
254
      return static_cast<bool>(node._id & (1 << n));
255
    }
256

	
257
    int dimension(Edge edge) const {
258
      return edge._id >> (_dim-1);
259
    }
260

	
261
    int dimension(Arc arc) const {
262
      return arc._id >> _dim;
263
    }
264

	
265
    int index(Node node) const {
266
      return node._id;
267
    }
268

	
269
    Node operator()(int ix) const {
270
      return Node(ix);
271
    }
272

	
273
  private:
274
    int _dim;
275
    int _node_num, _edge_num;
276
  };
277

	
278

	
279
  typedef GraphExtender<HypercubeGraphBase> ExtendedHypercubeGraphBase;
280

	
281
  /// \ingroup graphs
282
  ///
283
  /// \brief Hypercube graph class
284
  ///
285
  /// This class implements a special graph type. The nodes of the graph
286
  /// are indiced with integers with at most \c dim binary digits.
287
  /// Two nodes are connected in the graph if and only if their indices
288
  /// differ only on one position in the binary form.
289
  ///
290
  /// \note The type of the indices is chosen to \c int for efficiency
291
  /// reasons. Thus the maximum dimension of this implementation is 26
292
  /// (assuming that the size of \c int is 32 bit).
293
  ///
294
  /// This graph type fully conforms to the \ref concepts::Graph
295
  /// "Graph concept".
296
  class HypercubeGraph : public ExtendedHypercubeGraphBase {
297
    typedef ExtendedHypercubeGraphBase Parent;
298

	
299
  public:
300

	
301
    /// \brief Constructs a hypercube graph with \c dim dimensions.
302
    ///
303
    /// Constructs a hypercube graph with \c dim dimensions.
304
    HypercubeGraph(int dim) { construct(dim); }
305

	
306
    /// \brief The number of dimensions.
307
    ///
308
    /// Gives back the number of dimensions.
309
    int dimension() const {
310
      return Parent::dimension();
311
    }
312

	
313
    /// \brief Returns \c true if the n'th bit of the node is one.
314
    ///
315
    /// Returns \c true if the n'th bit of the node is one.
316
    bool projection(Node node, int n) const {
317
      return Parent::projection(node, n);
318
    }
319

	
320
    /// \brief The dimension id of an edge.
321
    ///
322
    /// Gives back the dimension id of the given edge.
323
    /// It is in the [0..dim-1] range.
324
    int dimension(Edge edge) const {
325
      return Parent::dimension(edge);
326
    }
327

	
328
    /// \brief The dimension id of an arc.
329
    ///
330
    /// Gives back the dimension id of the given arc.
331
    /// It is in the [0..dim-1] range.
332
    int dimension(Arc arc) const {
333
      return Parent::dimension(arc);
334
    }
335

	
336
    /// \brief The index of a node.
337
    ///
338
    /// Gives back the index of the given node.
339
    /// The lower bits of the integer describes the node.
340
    int index(Node node) const {
341
      return Parent::index(node);
342
    }
343

	
344
    /// \brief Gives back a node by its index.
345
    ///
346
    /// Gives back a node by its index.
347
    Node operator()(int ix) const {
348
      return Parent::operator()(ix);
349
    }
350

	
351
    /// \brief Number of nodes.
352
    int nodeNum() const { return Parent::nodeNum(); }
353
    /// \brief Number of edges.
354
    int edgeNum() const { return Parent::edgeNum(); }
355
    /// \brief Number of arcs.
356
    int arcNum() const { return Parent::arcNum(); }
357

	
358
    /// \brief Linear combination map.
359
    ///
360
    /// This map makes possible to give back a linear combination
361
    /// for each node. It works like the \c std::accumulate function,
362
    /// so it accumulates the \c bf binary function with the \c fv first
363
    /// value. The map accumulates only on that positions (dimensions)
364
    /// where the index of the node is one. The values that have to be
365
    /// accumulated should be given by the \c begin and \c end iterators
366
    /// and the length of this range should be equal to the dimension
367
    /// number of the graph.
368
    ///
369
    ///\code
370
    /// const int DIM = 3;
371
    /// HypercubeGraph graph(DIM);
372
    /// dim2::Point<double> base[DIM];
373
    /// for (int k = 0; k < DIM; ++k) {
374
    ///   base[k].x = rnd();
375
    ///   base[k].y = rnd();
376
    /// }
377
    /// HypercubeGraph::HyperMap<dim2::Point<double> >
378
    ///   pos(graph, base, base + DIM, dim2::Point<double>(0.0, 0.0));
379
    ///\endcode
380
    ///
381
    /// \see HypercubeGraph
382
    template <typename T, typename BF = std::plus<T> >
383
    class HyperMap {
384
    public:
385

	
386
      /// \brief The key type of the map
387
      typedef Node Key;
388
      /// \brief The value type of the map
389
      typedef T Value;
390

	
391
      /// \brief Constructor for HyperMap.
392
      ///
393
      /// Construct a HyperMap for the given graph. The values that have
394
      /// to be accumulated should be given by the \c begin and \c end
395
      /// iterators and the length of this range should be equal to the
396
      /// dimension number of the graph.
397
      ///
398
      /// This map accumulates the \c bf binary function with the \c fv
399
      /// first value on that positions (dimensions) where the index of
400
      /// the node is one.
401
      template <typename It>
402
      HyperMap(const Graph& graph, It begin, It end,
403
               T fv = 0, const BF& bf = BF())
404
        : _graph(graph), _values(begin, end), _first_value(fv), _bin_func(bf)
405
      {
406
        LEMON_ASSERT(_values.size() == graph.dimension(),
407
                     "Wrong size of range");
408
      }
409

	
410
      /// \brief The partial accumulated value.
411
      ///
412
      /// Gives back the partial accumulated value.
413
      Value operator[](const Key& k) const {
414
        Value val = _first_value;
415
        int id = _graph.index(k);
416
        int n = 0;
417
        while (id != 0) {
418
          if (id & 1) {
419
            val = _bin_func(val, _values[n]);
420
          }
421
          id >>= 1;
422
          ++n;
423
        }
424
        return val;
425
      }
426

	
427
    private:
428
      const Graph& _graph;
429
      std::vector<T> _values;
430
      T _first_value;
431
      BF _bin_func;
432
    };
433

	
434
  };
435

	
436
}
437

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

	
19
#ifndef LEMON_LP_H
20
#define LEMON_LP_H
21

	
22
#include<lemon/config.h>
23

	
24

	
25
#ifdef LEMON_HAVE_GLPK
26
#include <lemon/glpk.h>
27
#elif LEMON_HAVE_CPLEX
28
#include <lemon/cplex.h>
29
#elif LEMON_HAVE_SOPLEX
30
#include <lemon/soplex.h>
31
#elif LEMON_HAVE_CLP
32
#include <lemon/clp.h>
33
#endif
34

	
35
///\file
36
///\brief Defines a default LP solver
37
///\ingroup lp_group
38
namespace lemon {
39

	
40
#ifdef DOXYGEN
41
  ///The default LP solver identifier
42

	
43
  ///The default LP solver identifier.
44
  ///\ingroup lp_group
45
  ///
46
  ///Currently, the possible values are \c GLPK, \c CPLEX,
47
  ///\c SOPLEX or \c CLP
48
#define LEMON_DEFAULT_LP SOLVER
49
  ///The default LP solver
50

	
51
  ///The default LP solver.
52
  ///\ingroup lp_group
53
  ///
54
  ///Currently, it is either \c GlpkLp, \c CplexLp, \c SoplexLp or \c ClpLp
55
  typedef GlpkLp Lp;
56

	
57
  ///The default MIP solver identifier
58

	
59
  ///The default MIP solver identifier.
60
  ///\ingroup lp_group
61
  ///
62
  ///Currently, the possible values are \c GLPK or \c CPLEX
63
#define LEMON_DEFAULT_MIP SOLVER
64
  ///The default MIP solver.
65

	
66
  ///The default MIP solver.
67
  ///\ingroup lp_group
68
  ///
69
  ///Currently, it is either \c GlpkMip or \c CplexMip
70
  typedef GlpkMip Mip;
71
#else
72
#ifdef LEMON_HAVE_GLPK
73
# define LEMON_DEFAULT_LP GLPK
74
  typedef GlpkLp Lp;
75
# define LEMON_DEFAULT_MIP GLPK
76
  typedef GlpkMip Mip;
77
#elif LEMON_HAVE_CPLEX
78
# define LEMON_DEFAULT_LP CPLEX
79
  typedef CplexLp Lp;
80
# define LEMON_DEFAULT_MIP CPLEX
81
  typedef CplexMip Mip;
82
#elif LEMON_HAVE_SOPLEX
83
# define DEFAULT_LP SOPLEX
84
  typedef SoplexLp Lp;
85
#elif LEMON_HAVE_CLP
86
# define DEFAULT_LP CLP
87
  typedef ClpLp Lp;  
88
#endif
89
#endif
90

	
91
} //namespace lemon
92

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

	
19
///\file
20
///\brief The implementation of the LP solver interface.
21

	
22
#include <lemon/lp_base.h>
23
namespace lemon {
24

	
25
  const LpBase::Value LpBase::INF =
26
    std::numeric_limits<LpBase::Value>::infinity();
27
  const LpBase::Value LpBase::NaN =
28
    std::numeric_limits<LpBase::Value>::quiet_NaN();
29

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

	
19
#ifndef LEMON_LP_BASE_H
20
#define LEMON_LP_BASE_H
21

	
22
#include<iostream>
23
#include<vector>
24
#include<map>
25
#include<limits>
26
#include<lemon/math.h>
27

	
28
#include<lemon/error.h>
29
#include<lemon/assert.h>
30

	
31
#include<lemon/core.h>
32
#include<lemon/bits/solver_bits.h>
33

	
34
///\file
35
///\brief The interface of the LP solver interface.
36
///\ingroup lp_group
37
namespace lemon {
38

	
39
  ///Common base class for LP and MIP solvers
40

	
41
  ///Usually this class is not used directly, please use one of the concrete
42
  ///implementations of the solver interface.
43
  ///\ingroup lp_group
44
  class LpBase {
45

	
46
  protected:
47

	
48
    _solver_bits::VarIndex rows;
49
    _solver_bits::VarIndex cols;
50

	
51
  public:
52

	
53
    ///Possible outcomes of an LP solving procedure
54
    enum SolveExitStatus {
55
      /// = 0. It means that the problem has been successfully solved: either
56
      ///an optimal solution has been found or infeasibility/unboundedness
57
      ///has been proved.
58
      SOLVED = 0,
59
      /// = 1. Any other case (including the case when some user specified
60
      ///limit has been exceeded).
61
      UNSOLVED = 1
62
    };
63

	
64
    ///Direction of the optimization
65
    enum Sense {
66
      /// Minimization
67
      MIN,
68
      /// Maximization
69
      MAX
70
    };
71

	
72
    ///Enum for \c messageLevel() parameter
73
    enum MessageLevel {
74
      /// No output (default value).
75
      MESSAGE_NOTHING,
76
      /// Error messages only.
77
      MESSAGE_ERROR,
78
      /// Warnings.
79
      MESSAGE_WARNING,
80
      /// Normal output.
81
      MESSAGE_NORMAL,
82
      /// Verbose output.
83
      MESSAGE_VERBOSE
84
    };
85
    
86

	
87
    ///The floating point type used by the solver
88
    typedef double Value;
89
    ///The infinity constant
90
    static const Value INF;
91
    ///The not a number constant
92
    static const Value NaN;
93

	
94
    friend class Col;
95
    friend class ColIt;
96
    friend class Row;
97
    friend class RowIt;
98

	
99
    ///Refer to a column of the LP.
100

	
101
    ///This type is used to refer to a column of the LP.
102
    ///
103
    ///Its value remains valid and correct even after the addition or erase of
104
    ///other columns.
105
    ///
106
    ///\note This class is similar to other Item types in LEMON, like
107
    ///Node and Arc types in digraph.
108
    class Col {
109
      friend class LpBase;
110
    protected:
111
      int _id;
112
      explicit Col(int id) : _id(id) {}
113
    public:
114
      typedef Value ExprValue;
115
      typedef True LpCol;
116
      /// Default constructor
117
      
118
      /// \warning The default constructor sets the Col to an
119
      /// undefined value.
120
      Col() {}
121
      /// Invalid constructor \& conversion.
122
      
123
      /// This constructor initializes the Col to be invalid.
124
      /// \sa Invalid for more details.      
125
      Col(const Invalid&) : _id(-1) {}
126
      /// Equality operator
127

	
128
      /// Two \ref Col "Col"s are equal if and only if they point to
129
      /// the same LP column or both are invalid.
130
      bool operator==(Col c) const  {return _id == c._id;}
131
      /// Inequality operator
132

	
133
      /// \sa operator==(Col c)
134
      ///
135
      bool operator!=(Col c) const  {return _id != c._id;}
136
      /// Artificial ordering operator.
137

	
138
      /// To allow the use of this object in std::map or similar
139
      /// associative container we require this.
140
      ///
141
      /// \note This operator only have to define some strict ordering of
142
      /// the items; this order has nothing to do with the iteration
143
      /// ordering of the items.
144
      bool operator<(Col c) const  {return _id < c._id;}
145
    };
146

	
147
    ///Iterator for iterate over the columns of an LP problem
148

	
149
    /// Its usage is quite simple, for example you can count the number
150
    /// of columns in an LP \c lp:
151
    ///\code
152
    /// int count=0;
153
    /// for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
154
    ///\endcode
155
    class ColIt : public Col {
156
      const LpBase *_solver;
157
    public:
158
      /// Default constructor
159
      
160
      /// \warning The default constructor sets the iterator
161
      /// to an undefined value.
162
      ColIt() {}
163
      /// Sets the iterator to the first Col
164
      
165
      /// Sets the iterator to the first Col.
166
      ///
167
      ColIt(const LpBase &solver) : _solver(&solver)
168
      {
169
        _solver->cols.firstItem(_id);
170
      }
171
      /// Invalid constructor \& conversion
172
      
173
      /// Initialize the iterator to be invalid.
174
      /// \sa Invalid for more details.
175
      ColIt(const Invalid&) : Col(INVALID) {}
176
      /// Next column
177
      
178
      /// Assign the iterator to the next column.
179
      ///
180
      ColIt &operator++()
181
      {
182
        _solver->cols.nextItem(_id);
183
        return *this;
184
      }
185
    };
186

	
187
    /// \brief Returns the ID of the column.
188
    static int id(const Col& col) { return col._id; }
189
    /// \brief Returns the column with the given ID.
190
    ///
191
    /// \pre The argument should be a valid column ID in the LP problem.
192
    static Col colFromId(int id) { return Col(id); }
193

	
194
    ///Refer to a row of the LP.
195

	
196
    ///This type is used to refer to a row of the LP.
197
    ///
198
    ///Its value remains valid and correct even after the addition or erase of
199
    ///other rows.
200
    ///
201
    ///\note This class is similar to other Item types in LEMON, like
202
    ///Node and Arc types in digraph.
203
    class Row {
204
      friend class LpBase;
205
    protected:
206
      int _id;
207
      explicit Row(int id) : _id(id) {}
208
    public:
209
      typedef Value ExprValue;
210
      typedef True LpRow;
211
      /// Default constructor
212
      
213
      /// \warning The default constructor sets the Row to an
214
      /// undefined value.
215
      Row() {}
216
      /// Invalid constructor \& conversion.
217
      
218
      /// This constructor initializes the Row to be invalid.
219
      /// \sa Invalid for more details.      
220
      Row(const Invalid&) : _id(-1) {}
221
      /// Equality operator
222

	
223
      /// Two \ref Row "Row"s are equal if and only if they point to
224
      /// the same LP row or both are invalid.
225
      bool operator==(Row r) const  {return _id == r._id;}
226
      /// Inequality operator
227
      
228
      /// \sa operator==(Row r)
229
      ///
230
      bool operator!=(Row r) const  {return _id != r._id;}
231
      /// Artificial ordering operator.
232

	
233
      /// To allow the use of this object in std::map or similar
234
      /// associative container we require this.
235
      ///
236
      /// \note This operator only have to define some strict ordering of
237
      /// the items; this order has nothing to do with the iteration
238
      /// ordering of the items.
239
      bool operator<(Row r) const  {return _id < r._id;}
240
    };
241

	
242
    ///Iterator for iterate over the rows of an LP problem
243

	
244
    /// Its usage is quite simple, for example you can count the number
245
    /// of rows in an LP \c lp:
246
    ///\code
247
    /// int count=0;
248
    /// for (LpBase::RowIt c(lp); c!=INVALID; ++c) ++count;
249
    ///\endcode
250
    class RowIt : public Row {
251
      const LpBase *_solver;
252
    public:
253
      /// Default constructor
254
      
255
      /// \warning The default constructor sets the iterator
256
      /// to an undefined value.
257
      RowIt() {}
258
      /// Sets the iterator to the first Row
259
      
260
      /// Sets the iterator to the first Row.
261
      ///
262
      RowIt(const LpBase &solver) : _solver(&solver)
263
      {
264
        _solver->rows.firstItem(_id);
265
      }
266
      /// Invalid constructor \& conversion
267
      
268
      /// Initialize the iterator to be invalid.
269
      /// \sa Invalid for more details.
270
      RowIt(const Invalid&) : Row(INVALID) {}
271
      /// Next row
272
      
273
      /// Assign the iterator to the next row.
274
      ///
275
      RowIt &operator++()
276
      {
277
        _solver->rows.nextItem(_id);
278
        return *this;
279
      }
280
    };
281

	
282
    /// \brief Returns the ID of the row.
283
    static int id(const Row& row) { return row._id; }
284
    /// \brief Returns the row with the given ID.
285
    ///
286
    /// \pre The argument should be a valid row ID in the LP problem.
287
    static Row rowFromId(int id) { return Row(id); }
288

	
289
  public:
290

	
291
    ///Linear expression of variables and a constant component
292

	
293
    ///This data structure stores a linear expression of the variables
294
    ///(\ref Col "Col"s) and also has a constant component.
295
    ///
296
    ///There are several ways to access and modify the contents of this
297
    ///container.
298
    ///\code
299
    ///e[v]=5;
300
    ///e[v]+=12;
301
    ///e.erase(v);
302
    ///\endcode
303
    ///or you can also iterate through its elements.
304
    ///\code
305
    ///double s=0;
306
    ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
307
    ///  s+=*i * primal(i);
308
    ///\endcode
309
    ///(This code computes the primal value of the expression).
310
    ///- Numbers (<tt>double</tt>'s)
311
    ///and variables (\ref Col "Col"s) directly convert to an
312
    ///\ref Expr and the usual linear operations are defined, so
313
    ///\code
314
    ///v+w
315
    ///2*v-3.12*(v-w/2)+2
316
    ///v*2.1+(3*v+(v*12+w+6)*3)/2
317
    ///\endcode
318
    ///are valid expressions.
319
    ///The usual assignment operations are also defined.
320
    ///\code
321
    ///e=v+w;
322
    ///e+=2*v-3.12*(v-w/2)+2;
323
    ///e*=3.4;
324
    ///e/=5;
325
    ///\endcode
326
    ///- The constant member can be set and read by dereference
327
    ///  operator (unary *)
328
    ///
329
    ///\code
330
    ///*e=12;
331
    ///double c=*e;
332
    ///\endcode
333
    ///
334
    ///\sa Constr
335
    class Expr {
336
      friend class LpBase;
337
    public:
338
      /// The key type of the expression
339
      typedef LpBase::Col Key;
340
      /// The value type of the expression
341
      typedef LpBase::Value Value;
342

	
343
    protected:
344
      Value const_comp;
345
      std::map<int, Value> comps;
346

	
347
    public:
348
      typedef True SolverExpr;
349
      /// Default constructor
350
      
351
      /// Construct an empty expression, the coefficients and
352
      /// the constant component are initialized to zero.
353
      Expr() : const_comp(0) {}
354
      /// Construct an expression from a column
355

	
356
      /// Construct an expression, which has a term with \c c variable
357
      /// and 1.0 coefficient.
358
      Expr(const Col &c) : const_comp(0) {
359
        typedef std::map<int, Value>::value_type pair_type;
360
        comps.insert(pair_type(id(c), 1));
361
      }
362
      /// Construct an expression from a constant
363

	
364
      /// Construct an expression, which's constant component is \c v.
365
      ///
366
      Expr(const Value &v) : const_comp(v) {}
367
      /// Returns the coefficient of the column
368
      Value operator[](const Col& c) const {
369
        std::map<int, Value>::const_iterator it=comps.find(id(c));
370
        if (it != comps.end()) {
371
          return it->second;
372
        } else {
373
          return 0;
374
        }
375
      }
376
      /// Returns the coefficient of the column
377
      Value& operator[](const Col& c) {
378
        return comps[id(c)];
379
      }
380
      /// Sets the coefficient of the column
381
      void set(const Col &c, const Value &v) {
382
        if (v != 0.0) {
383
          typedef std::map<int, Value>::value_type pair_type;
384
          comps.insert(pair_type(id(c), v));
385
        } else {
386
          comps.erase(id(c));
387
        }
388
      }
389
      /// Returns the constant component of the expression
390
      Value& operator*() { return const_comp; }
391
      /// Returns the constant component of the expression
392
      const Value& operator*() const { return const_comp; }
393
      /// \brief Removes the coefficients which's absolute value does
394
      /// not exceed \c epsilon. It also sets to zero the constant
395
      /// component, if it does not exceed epsilon in absolute value.
396
      void simplify(Value epsilon = 0.0) {
397
        std::map<int, Value>::iterator it=comps.begin();
398
        while (it != comps.end()) {
399
          std::map<int, Value>::iterator jt=it;
400
          ++jt;
401
          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
402
          it=jt;
403
        }
404
        if (std::fabs(const_comp) <= epsilon) const_comp = 0;
405
      }
406

	
407
      void simplify(Value epsilon = 0.0) const {
408
        const_cast<Expr*>(this)->simplify(epsilon);
409
      }
410

	
411
      ///Sets all coefficients and the constant component to 0.
412
      void clear() {
413
        comps.clear();
414
        const_comp=0;
415
      }
416

	
417
      ///Compound assignment
418
      Expr &operator+=(const Expr &e) {
419
        for (std::map<int, Value>::const_iterator it=e.comps.begin();
420
             it!=e.comps.end(); ++it)
421
          comps[it->first]+=it->second;
422
        const_comp+=e.const_comp;
423
        return *this;
424
      }
425
      ///Compound assignment
426
      Expr &operator-=(const Expr &e) {
427
        for (std::map<int, Value>::const_iterator it=e.comps.begin();
428
             it!=e.comps.end(); ++it)
429
          comps[it->first]-=it->second;
430
        const_comp-=e.const_comp;
431
        return *this;
432
      }
433
      ///Multiply with a constant
434
      Expr &operator*=(const Value &v) {
435
        for (std::map<int, Value>::iterator it=comps.begin();
436
             it!=comps.end(); ++it)
437
          it->second*=v;
438
        const_comp*=v;
439
        return *this;
440
      }
441
      ///Division with a constant
442
      Expr &operator/=(const Value &c) {
443
        for (std::map<int, Value>::iterator it=comps.begin();
444
             it!=comps.end(); ++it)
445
          it->second/=c;
446
        const_comp/=c;
447
        return *this;
448
      }
449

	
450
      ///Iterator over the expression
451
      
452
      ///The iterator iterates over the terms of the expression. 
453
      /// 
454
      ///\code
455
      ///double s=0;
456
      ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i)
457
      ///  s+= *i * primal(i);
458
      ///\endcode
459
      class CoeffIt {
460
      private:
461

	
462
        std::map<int, Value>::iterator _it, _end;
463

	
464
      public:
465

	
466
        /// Sets the iterator to the first term
467
        
468
        /// Sets the iterator to the first term of the expression.
469
        ///
470
        CoeffIt(Expr& e)
471
          : _it(e.comps.begin()), _end(e.comps.end()){}
472

	
473
        /// Convert the iterator to the column of the term
474
        operator Col() const {
475
          return colFromId(_it->first);
476
        }
477

	
478
        /// Returns the coefficient of the term
479
        Value& operator*() { return _it->second; }
480

	
481
        /// Returns the coefficient of the term
482
        const Value& operator*() const { return _it->second; }
483
        /// Next term
484
        
485
        /// Assign the iterator to the next term.
486
        ///
487
        CoeffIt& operator++() { ++_it; return *this; }
488

	
489
        /// Equality operator
490
        bool operator==(Invalid) const { return _it == _end; }
491
        /// Inequality operator
492
        bool operator!=(Invalid) const { return _it != _end; }
493
      };
494

	
495
      /// Const iterator over the expression
496
      
497
      ///The iterator iterates over the terms of the expression. 
498
      /// 
499
      ///\code
500
      ///double s=0;
501
      ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
502
      ///  s+=*i * primal(i);
503
      ///\endcode
504
      class ConstCoeffIt {
505
      private:
506

	
507
        std::map<int, Value>::const_iterator _it, _end;
508

	
509
      public:
510

	
511
        /// Sets the iterator to the first term
512
        
513
        /// Sets the iterator to the first term of the expression.
514
        ///
515
        ConstCoeffIt(const Expr& e)
516
          : _it(e.comps.begin()), _end(e.comps.end()){}
517

	
518
        /// Convert the iterator to the column of the term
519
        operator Col() const {
520
          return colFromId(_it->first);
521
        }
522

	
523
        /// Returns the coefficient of the term
524
        const Value& operator*() const { return _it->second; }
525

	
526
        /// Next term
527
        
528
        /// Assign the iterator to the next term.
529
        ///
530
        ConstCoeffIt& operator++() { ++_it; return *this; }
531

	
532
        /// Equality operator
533
        bool operator==(Invalid) const { return _it == _end; }
534
        /// Inequality operator
535
        bool operator!=(Invalid) const { return _it != _end; }
536
      };
537

	
538
    };
539

	
540
    ///Linear constraint
541

	
542
    ///This data stucture represents a linear constraint in the LP.
543
    ///Basically it is a linear expression with a lower or an upper bound
544
    ///(or both). These parts of the constraint can be obtained by the member
545
    ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
546
    ///respectively.
547
    ///There are two ways to construct a constraint.
548
    ///- You can set the linear expression and the bounds directly
549
    ///  by the functions above.
550
    ///- The operators <tt>\<=</tt>, <tt>==</tt> and  <tt>\>=</tt>
551
    ///  are defined between expressions, or even between constraints whenever
552
    ///  it makes sense. Therefore if \c e and \c f are linear expressions and
553
    ///  \c s and \c t are numbers, then the followings are valid expressions
554
    ///  and thus they can be used directly e.g. in \ref addRow() whenever
555
    ///  it makes sense.
556
    ///\code
557
    ///  e<=s
558
    ///  e<=f
559
    ///  e==f
560
    ///  s<=e<=t
561
    ///  e>=t
562
    ///\endcode
563
    ///\warning The validity of a constraint is checked only at run
564
    ///time, so e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will
565
    ///compile, but will fail an assertion.
566
    class Constr
567
    {
568
    public:
569
      typedef LpBase::Expr Expr;
570
      typedef Expr::Key Key;
571
      typedef Expr::Value Value;
572

	
573
    protected:
574
      Expr _expr;
575
      Value _lb,_ub;
576
    public:
577
      ///\e
578
      Constr() : _expr(), _lb(NaN), _ub(NaN) {}
579
      ///\e
580
      Constr(Value lb, const Expr &e, Value ub) :
581
        _expr(e), _lb(lb), _ub(ub) {}
582
      Constr(const Expr &e) :
583
        _expr(e), _lb(NaN), _ub(NaN) {}
584
      ///\e
585
      void clear()
586
      {
587
        _expr.clear();
588
        _lb=_ub=NaN;
589
      }
590

	
591
      ///Reference to the linear expression
592
      Expr &expr() { return _expr; }
593
      ///Cont reference to the linear expression
594
      const Expr &expr() const { return _expr; }
595
      ///Reference to the lower bound.
596

	
597
      ///\return
598
      ///- \ref INF "INF": the constraint is lower unbounded.
599
      ///- \ref NaN "NaN": lower bound has not been set.
600
      ///- finite number: the lower bound
601
      Value &lowerBound() { return _lb; }
602
      ///The const version of \ref lowerBound()
603
      const Value &lowerBound() const { return _lb; }
604
      ///Reference to the upper bound.
605

	
606
      ///\return
607
      ///- \ref INF "INF": the constraint is upper unbounded.
608
      ///- \ref NaN "NaN": upper bound has not been set.
609
      ///- finite number: the upper bound
610
      Value &upperBound() { return _ub; }
611
      ///The const version of \ref upperBound()
612
      const Value &upperBound() const { return _ub; }
613
      ///Is the constraint lower bounded?
614
      bool lowerBounded() const {
615
        return _lb != -INF && !isNaN(_lb);
616
      }
617
      ///Is the constraint upper bounded?
618
      bool upperBounded() const {
619
        return _ub != INF && !isNaN(_ub);
620
      }
621

	
622
    };
623

	
624
    ///Linear expression of rows
625

	
626
    ///This data structure represents a column of the matrix,
627
    ///thas is it strores a linear expression of the dual variables
628
    ///(\ref Row "Row"s).
629
    ///
630
    ///There are several ways to access and modify the contents of this
631
    ///container.
632
    ///\code
633
    ///e[v]=5;
634
    ///e[v]+=12;
635
    ///e.erase(v);
636
    ///\endcode
637
    ///or you can also iterate through its elements.
638
    ///\code
639
    ///double s=0;
640
    ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
641
    ///  s+=*i;
642
    ///\endcode
643
    ///(This code computes the sum of all coefficients).
644
    ///- Numbers (<tt>double</tt>'s)
645
    ///and variables (\ref Row "Row"s) directly convert to an
646
    ///\ref DualExpr and the usual linear operations are defined, so
647
    ///\code
648
    ///v+w
649
    ///2*v-3.12*(v-w/2)
650
    ///v*2.1+(3*v+(v*12+w)*3)/2
651
    ///\endcode
652
    ///are valid \ref DualExpr dual expressions.
653
    ///The usual assignment operations are also defined.
654
    ///\code
655
    ///e=v+w;
656
    ///e+=2*v-3.12*(v-w/2);
657
    ///e*=3.4;
658
    ///e/=5;
659
    ///\endcode
660
    ///
661
    ///\sa Expr
662
    class DualExpr {
663
      friend class LpBase;
664
    public:
665
      /// The key type of the expression
666
      typedef LpBase::Row Key;
667
      /// The value type of the expression
668
      typedef LpBase::Value Value;
669

	
670
    protected:
671
      std::map<int, Value> comps;
672

	
673
    public:
674
      typedef True SolverExpr;
675
      /// Default constructor
676
      
677
      /// Construct an empty expression, the coefficients are
678
      /// initialized to zero.
679
      DualExpr() {}
680
      /// Construct an expression from a row
681

	
682
      /// Construct an expression, which has a term with \c r dual
683
      /// variable and 1.0 coefficient.
684
      DualExpr(const Row &r) {
685
        typedef std::map<int, Value>::value_type pair_type;
686
        comps.insert(pair_type(id(r), 1));
687
      }
688
      /// Returns the coefficient of the row
689
      Value operator[](const Row& r) const {
690
        std::map<int, Value>::const_iterator it = comps.find(id(r));
691
        if (it != comps.end()) {
692
          return it->second;
693
        } else {
694
          return 0;
695
        }
696
      }
697
      /// Returns the coefficient of the row
698
      Value& operator[](const Row& r) {
699
        return comps[id(r)];
700
      }
701
      /// Sets the coefficient of the row
702
      void set(const Row &r, const Value &v) {
703
        if (v != 0.0) {
704
          typedef std::map<int, Value>::value_type pair_type;
705
          comps.insert(pair_type(id(r), v));
706
        } else {
707
          comps.erase(id(r));
708
        }
709
      }
710
      /// \brief Removes the coefficients which's absolute value does
711
      /// not exceed \c epsilon. 
712
      void simplify(Value epsilon = 0.0) {
713
        std::map<int, Value>::iterator it=comps.begin();
714
        while (it != comps.end()) {
715
          std::map<int, Value>::iterator jt=it;
716
          ++jt;
717
          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
718
          it=jt;
719
        }
720
      }
721

	
722
      void simplify(Value epsilon = 0.0) const {
723
        const_cast<DualExpr*>(this)->simplify(epsilon);
724
      }
725

	
726
      ///Sets all coefficients to 0.
727
      void clear() {
728
        comps.clear();
729
      }
730
      ///Compound assignment
731
      DualExpr &operator+=(const DualExpr &e) {
732
        for (std::map<int, Value>::const_iterator it=e.comps.begin();
733
             it!=e.comps.end(); ++it)
734
          comps[it->first]+=it->second;
735
        return *this;
736
      }
737
      ///Compound assignment
738
      DualExpr &operator-=(const DualExpr &e) {
739
        for (std::map<int, Value>::const_iterator it=e.comps.begin();
740
             it!=e.comps.end(); ++it)
741
          comps[it->first]-=it->second;
742
        return *this;
743
      }
744
      ///Multiply with a constant
745
      DualExpr &operator*=(const Value &v) {
746
        for (std::map<int, Value>::iterator it=comps.begin();
747
             it!=comps.end(); ++it)
748
          it->second*=v;
749
        return *this;
750
      }
751
      ///Division with a constant
752
      DualExpr &operator/=(const Value &v) {
753
        for (std::map<int, Value>::iterator it=comps.begin();
754
             it!=comps.end(); ++it)
755
          it->second/=v;
756
        return *this;
757
      }
758

	
759
      ///Iterator over the expression
760
      
761
      ///The iterator iterates over the terms of the expression. 
762
      /// 
763
      ///\code
764
      ///double s=0;
765
      ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i)
766
      ///  s+= *i * dual(i);
767
      ///\endcode
768
      class CoeffIt {
769
      private:
770

	
771
        std::map<int, Value>::iterator _it, _end;
772

	
773
      public:
774

	
775
        /// Sets the iterator to the first term
776
        
777
        /// Sets the iterator to the first term of the expression.
778
        ///
779
        CoeffIt(DualExpr& e)
780
          : _it(e.comps.begin()), _end(e.comps.end()){}
781

	
782
        /// Convert the iterator to the row of the term
783
        operator Row() const {
784
          return rowFromId(_it->first);
785
        }
786

	
787
        /// Returns the coefficient of the term
788
        Value& operator*() { return _it->second; }
789

	
790
        /// Returns the coefficient of the term
791
        const Value& operator*() const { return _it->second; }
792

	
793
        /// Next term
794
        
795
        /// Assign the iterator to the next term.
796
        ///
797
        CoeffIt& operator++() { ++_it; return *this; }
798

	
799
        /// Equality operator
800
        bool operator==(Invalid) const { return _it == _end; }
801
        /// Inequality operator
802
        bool operator!=(Invalid) const { return _it != _end; }
803
      };
804

	
805
      ///Iterator over the expression
806
      
807
      ///The iterator iterates over the terms of the expression. 
808
      /// 
809
      ///\code
810
      ///double s=0;
811
      ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
812
      ///  s+= *i * dual(i);
813
      ///\endcode
814
      class ConstCoeffIt {
815
      private:
816

	
817
        std::map<int, Value>::const_iterator _it, _end;
818

	
819
      public:
820

	
821
        /// Sets the iterator to the first term
822
        
823
        /// Sets the iterator to the first term of the expression.
824
        ///
825
        ConstCoeffIt(const DualExpr& e)
826
          : _it(e.comps.begin()), _end(e.comps.end()){}
827

	
828
        /// Convert the iterator to the row of the term
829
        operator Row() const {
830
          return rowFromId(_it->first);
831
        }
832

	
833
        /// Returns the coefficient of the term
834
        const Value& operator*() const { return _it->second; }
835

	
836
        /// Next term
837
        
838
        /// Assign the iterator to the next term.
839
        ///
840
        ConstCoeffIt& operator++() { ++_it; return *this; }
841

	
842
        /// Equality operator
843
        bool operator==(Invalid) const { return _it == _end; }
844
        /// Inequality operator
845
        bool operator!=(Invalid) const { return _it != _end; }
846
      };
847
    };
848

	
849

	
850
  protected:
851

	
852
    class InsertIterator {
853
    private:
854

	
855
      std::map<int, Value>& _host;
856
      const _solver_bits::VarIndex& _index;
857

	
858
    public:
859

	
860
      typedef std::output_iterator_tag iterator_category;
861
      typedef void difference_type;
862
      typedef void value_type;
863
      typedef void reference;
864
      typedef void pointer;
865

	
866
      InsertIterator(std::map<int, Value>& host,
867
                   const _solver_bits::VarIndex& index)
868
        : _host(host), _index(index) {}
869

	
870
      InsertIterator& operator=(const std::pair<int, Value>& value) {
871
        typedef std::map<int, Value>::value_type pair_type;
872
        _host.insert(pair_type(_index[value.first], value.second));
873
        return *this;
874
      }
875

	
876
      InsertIterator& operator*() { return *this; }
877
      InsertIterator& operator++() { return *this; }
878
      InsertIterator operator++(int) { return *this; }
879

	
880
    };
881

	
882
    class ExprIterator {
883
    private:
884
      std::map<int, Value>::const_iterator _host_it;
885
      const _solver_bits::VarIndex& _index;
886
    public:
887

	
888
      typedef std::bidirectional_iterator_tag iterator_category;
889
      typedef std::ptrdiff_t difference_type;
890
      typedef const std::pair<int, Value> value_type;
891
      typedef value_type reference;
892

	
893
      class pointer {
894
      public:
895
        pointer(value_type& _value) : value(_value) {}
896
        value_type* operator->() { return &value; }
897
      private:
898
        value_type value;
899
      };
900

	
901
      ExprIterator(const std::map<int, Value>::const_iterator& host_it,
902
                   const _solver_bits::VarIndex& index)
903
        : _host_it(host_it), _index(index) {}
904

	
905
      reference operator*() {
906
        return std::make_pair(_index(_host_it->first), _host_it->second);
907
      }
908

	
909
      pointer operator->() {
910
        return pointer(operator*());
911
      }
912

	
913
      ExprIterator& operator++() { ++_host_it; return *this; }
914
      ExprIterator operator++(int) {
915
        ExprIterator tmp(*this); ++_host_it; return tmp;
916
      }
917

	
918
      ExprIterator& operator--() { --_host_it; return *this; }
919
      ExprIterator operator--(int) {
920
        ExprIterator tmp(*this); --_host_it; return tmp;
921
      }
922

	
923
      bool operator==(const ExprIterator& it) const {
924
        return _host_it == it._host_it;
925
      }
926

	
927
      bool operator!=(const ExprIterator& it) const {
928
        return _host_it != it._host_it;
929
      }
930

	
931
    };
932

	
933
  protected:
934

	
935
    //Abstract virtual functions
936

	
937
    virtual int _addColId(int col) { return cols.addIndex(col); }
938
    virtual int _addRowId(int row) { return rows.addIndex(row); }
939

	
940
    virtual void _eraseColId(int col) { cols.eraseIndex(col); }
941
    virtual void _eraseRowId(int row) { rows.eraseIndex(row); }
942

	
943
    virtual int _addCol() = 0;
944
    virtual int _addRow() = 0;
945

	
946
    virtual void _eraseCol(int col) = 0;
947
    virtual void _eraseRow(int row) = 0;
948

	
949
    virtual void _getColName(int col, std::string& name) const = 0;
950
    virtual void _setColName(int col, const std::string& name) = 0;
951
    virtual int _colByName(const std::string& name) const = 0;
952

	
953
    virtual void _getRowName(int row, std::string& name) const = 0;
954
    virtual void _setRowName(int row, const std::string& name) = 0;
955
    virtual int _rowByName(const std::string& name) const = 0;
956

	
957
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
958
    virtual void _getRowCoeffs(int i, InsertIterator b) const = 0;
959

	
960
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
961
    virtual void _getColCoeffs(int i, InsertIterator b) const = 0;
962

	
963
    virtual void _setCoeff(int row, int col, Value value) = 0;
964
    virtual Value _getCoeff(int row, int col) const = 0;
965

	
966
    virtual void _setColLowerBound(int i, Value value) = 0;
967
    virtual Value _getColLowerBound(int i) const = 0;
968

	
969
    virtual void _setColUpperBound(int i, Value value) = 0;
970
    virtual Value _getColUpperBound(int i) const = 0;
971

	
972
    virtual void _setRowLowerBound(int i, Value value) = 0;
973
    virtual Value _getRowLowerBound(int i) const = 0;
974

	
975
    virtual void _setRowUpperBound(int i, Value value) = 0;
976
    virtual Value _getRowUpperBound(int i) const = 0;
977

	
978
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
979
    virtual void _getObjCoeffs(InsertIterator b) const = 0;
980

	
981
    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
982
    virtual Value _getObjCoeff(int i) const = 0;
983

	
984
    virtual void _setSense(Sense) = 0;
985
    virtual Sense _getSense() const = 0;
986

	
987
    virtual void _clear() = 0;
988

	
989
    virtual const char* _solverName() const = 0;
990

	
991
    virtual void _messageLevel(MessageLevel level) = 0;
992

	
993
    //Own protected stuff
994

	
995
    //Constant component of the objective function
996
    Value obj_const_comp;
997

	
998
    LpBase() : rows(), cols(), obj_const_comp(0) {}
999

	
1000
  public:
1001

	
1002
    /// Virtual destructor
1003
    virtual ~LpBase() {}
1004

	
1005
    ///Gives back the name of the solver.
1006
    const char* solverName() const {return _solverName();}
1007

	
1008
    ///\name Build Up and Modify the LP
1009

	
1010
    ///@{
1011

	
1012
    ///Add a new empty column (i.e a new variable) to the LP
1013
    Col addCol() { Col c; c._id = _addColId(_addCol()); return c;}
1014

	
1015
    ///\brief Adds several new columns (i.e variables) at once
1016
    ///
1017
    ///This magic function takes a container as its argument and fills
1018
    ///its elements with new columns (i.e. variables)
1019
    ///\param t can be
1020
    ///- a standard STL compatible iterable container with
1021
    ///\ref Col as its \c values_type like
1022
    ///\code
1023
    ///std::vector<LpBase::Col>
1024
    ///std::list<LpBase::Col>
1025
    ///\endcode
1026
    ///- a standard STL compatible iterable container with
1027
    ///\ref Col as its \c mapped_type like
1028
    ///\code
1029
    ///std::map<AnyType,LpBase::Col>
1030
    ///\endcode
1031
    ///- an iterable lemon \ref concepts::WriteMap "write map" like
1032
    ///\code
1033
    ///ListGraph::NodeMap<LpBase::Col>
1034
    ///ListGraph::ArcMap<LpBase::Col>
1035
    ///\endcode
1036
    ///\return The number of the created column.
1037
#ifdef DOXYGEN
1038
    template<class T>
1039
    int addColSet(T &t) { return 0;}
1040
#else
1041
    template<class T>
1042
    typename enable_if<typename T::value_type::LpCol,int>::type
1043
    addColSet(T &t,dummy<0> = 0) {
1044
      int s=0;
1045
      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
1046
      return s;
1047
    }
1048
    template<class T>
1049
    typename enable_if<typename T::value_type::second_type::LpCol,
1050
                       int>::type
1051
    addColSet(T &t,dummy<1> = 1) {
1052
      int s=0;
1053
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1054
        i->second=addCol();
1055
        s++;
1056
      }
1057
      return s;
1058
    }
1059
    template<class T>
1060
    typename enable_if<typename T::MapIt::Value::LpCol,
1061
                       int>::type
1062
    addColSet(T &t,dummy<2> = 2) {
1063
      int s=0;
1064
      for(typename T::MapIt i(t); i!=INVALID; ++i)
1065
        {
1066
          i.set(addCol());
1067
          s++;
1068
        }
1069
      return s;
1070
    }
1071
#endif
1072

	
1073
    ///Set a column (i.e a dual constraint) of the LP
1074

	
1075
    ///\param c is the column to be modified
1076
    ///\param e is a dual linear expression (see \ref DualExpr)
1077
    ///a better one.
1078
    void col(Col c, const DualExpr &e) {
1079
      e.simplify();
1080
      _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), rows),
1081
                    ExprIterator(e.comps.end(), rows));
1082
    }
1083

	
1084
    ///Get a column (i.e a dual constraint) of the LP
1085

	
1086
    ///\param c is the column to get
1087
    ///\return the dual expression associated to the column
1088
    DualExpr col(Col c) const {
1089
      DualExpr e;
1090
      _getColCoeffs(cols(id(c)), InsertIterator(e.comps, rows));
1091
      return e;
1092
    }
1093

	
1094
    ///Add a new column to the LP
1095

	
1096
    ///\param e is a dual linear expression (see \ref DualExpr)
1097
    ///\param o is the corresponding component of the objective
1098
    ///function. It is 0 by default.
1099
    ///\return The created column.
1100
    Col addCol(const DualExpr &e, Value o = 0) {
1101
      Col c=addCol();
1102
      col(c,e);
1103
      objCoeff(c,o);
1104
      return c;
1105
    }
1106

	
1107
    ///Add a new empty row (i.e a new constraint) to the LP
1108

	
1109
    ///This function adds a new empty row (i.e a new constraint) to the LP.
1110
    ///\return The created row
1111
    Row addRow() { Row r; r._id = _addRowId(_addRow()); return r;}
1112

	
1113
    ///\brief Add several new rows (i.e constraints) at once
1114
    ///
1115
    ///This magic function takes a container as its argument and fills
1116
    ///its elements with new row (i.e. variables)
1117
    ///\param t can be
1118
    ///- a standard STL compatible iterable container with
1119
    ///\ref Row as its \c values_type like
1120
    ///\code
1121
    ///std::vector<LpBase::Row>
1122
    ///std::list<LpBase::Row>
1123
    ///\endcode
1124
    ///- a standard STL compatible iterable container with
1125
    ///\ref Row as its \c mapped_type like
1126
    ///\code
1127
    ///std::map<AnyType,LpBase::Row>
1128
    ///\endcode
1129
    ///- an iterable lemon \ref concepts::WriteMap "write map" like
1130
    ///\code
1131
    ///ListGraph::NodeMap<LpBase::Row>
1132
    ///ListGraph::ArcMap<LpBase::Row>
1133
    ///\endcode
1134
    ///\return The number of rows created.
1135
#ifdef DOXYGEN
1136
    template<class T>
1137
    int addRowSet(T &t) { return 0;}
1138
#else
1139
    template<class T>
1140
    typename enable_if<typename T::value_type::LpRow,int>::type
1141
    addRowSet(T &t, dummy<0> = 0) {
1142
      int s=0;
1143
      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
1144
      return s;
1145
    }
1146
    template<class T>
1147
    typename enable_if<typename T::value_type::second_type::LpRow, int>::type
1148
    addRowSet(T &t, dummy<1> = 1) {
1149
      int s=0;
1150
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1151
        i->second=addRow();
1152
        s++;
1153
      }
1154
      return s;
1155
    }
1156
    template<class T>
1157
    typename enable_if<typename T::MapIt::Value::LpRow, int>::type
1158
    addRowSet(T &t, dummy<2> = 2) {
1159
      int s=0;
1160
      for(typename T::MapIt i(t); i!=INVALID; ++i)
1161
        {
1162
          i.set(addRow());
1163
          s++;
1164
        }
1165
      return s;
1166
    }
1167
#endif
1168

	
1169
    ///Set a row (i.e a constraint) of the LP
1170

	
1171
    ///\param r is the row to be modified
1172
    ///\param l is lower bound (-\ref INF means no bound)
1173
    ///\param e is a linear expression (see \ref Expr)
1174
    ///\param u is the upper bound (\ref INF means no bound)
1175
    void row(Row r, Value l, const Expr &e, Value u) {
1176
      e.simplify();
1177
      _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols),
1178
                    ExprIterator(e.comps.end(), cols));
1179
      _setRowLowerBound(rows(id(r)),l - *e);
1180
      _setRowUpperBound(rows(id(r)),u - *e);
1181
    }
1182

	
1183
    ///Set a row (i.e a constraint) of the LP
1184

	
1185
    ///\param r is the row to be modified
1186
    ///\param c is a linear expression (see \ref Constr)
1187
    void row(Row r, const Constr &c) {
1188
      row(r, c.lowerBounded()?c.lowerBound():-INF,
1189
          c.expr(), c.upperBounded()?c.upperBound():INF);
1190
    }
1191

	
1192

	
1193
    ///Get a row (i.e a constraint) of the LP
1194

	
1195
    ///\param r is the row to get
1196
    ///\return the expression associated to the row
1197
    Expr row(Row r) const {
1198
      Expr e;
1199
      _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols));
1200
      return e;
1201
    }
1202

	
1203
    ///Add a new row (i.e a new constraint) to the LP
1204

	
1205
    ///\param l is the lower bound (-\ref INF means no bound)
1206
    ///\param e is a linear expression (see \ref Expr)
1207
    ///\param u is the upper bound (\ref INF means no bound)
1208
    ///\return The created row.
1209
    Row addRow(Value l,const Expr &e, Value u) {
1210
      Row r=addRow();
1211
      row(r,l,e,u);
1212
      return r;
1213
    }
1214

	
1215
    ///Add a new row (i.e a new constraint) to the LP
1216

	
1217
    ///\param c is a linear expression (see \ref Constr)
1218
    ///\return The created row.
1219
    Row addRow(const Constr &c) {
1220
      Row r=addRow();
1221
      row(r,c);
1222
      return r;
1223
    }
1224
    ///Erase a column (i.e a variable) from the LP
1225

	
1226
    ///\param c is the column to be deleted
1227
    void erase(Col c) {
1228
      _eraseCol(cols(id(c)));
1229
      _eraseColId(cols(id(c)));
1230
    }
1231
    ///Erase a row (i.e a constraint) from the LP
1232

	
1233
    ///\param r is the row to be deleted
1234
    void erase(Row r) {
1235
      _eraseRow(rows(id(r)));
1236
      _eraseRowId(rows(id(r)));
1237
    }
1238

	
1239
    /// Get the name of a column
1240

	
1241
    ///\param c is the coresponding column
1242
    ///\return The name of the colunm
1243
    std::string colName(Col c) const {
1244
      std::string name;
1245
      _getColName(cols(id(c)), name);
1246
      return name;
1247
    }
1248

	
1249
    /// Set the name of a column
1250

	
1251
    ///\param c is the coresponding column
1252
    ///\param name The name to be given
1253
    void colName(Col c, const std::string& name) {
1254
      _setColName(cols(id(c)), name);
1255
    }
1256

	
1257
    /// Get the column by its name
1258

	
1259
    ///\param name The name of the column
1260
    ///\return the proper column or \c INVALID
1261
    Col colByName(const std::string& name) const {
1262
      int k = _colByName(name);
1263
      return k != -1 ? Col(cols[k]) : Col(INVALID);
1264
    }
1265

	
1266
    /// Get the name of a row
1267

	
1268
    ///\param r is the coresponding row
1269
    ///\return The name of the row
1270
    std::string rowName(Row r) const {
1271
      std::string name;
1272
      _getRowName(rows(id(r)), name);
1273
      return name;
1274
    }
1275

	
1276
    /// Set the name of a row
1277

	
1278
    ///\param r is the coresponding row
1279
    ///\param name The name to be given
1280
    void rowName(Row r, const std::string& name) {
1281
      _setRowName(rows(id(r)), name);
1282
    }
1283

	
1284
    /// Get the row by its name
1285

	
1286
    ///\param name The name of the row
1287
    ///\return the proper row or \c INVALID
1288
    Row rowByName(const std::string& name) const {
1289
      int k = _rowByName(name);
1290
      return k != -1 ? Row(rows[k]) : Row(INVALID);
1291
    }
1292

	
1293
    /// Set an element of the coefficient matrix of the LP
1294

	
1295
    ///\param r is the row of the element to be modified
1296
    ///\param c is the column of the element to be modified
1297
    ///\param val is the new value of the coefficient
1298
    void coeff(Row r, Col c, Value val) {
1299
      _setCoeff(rows(id(r)),cols(id(c)), val);
1300
    }
1301

	
1302
    /// Get an element of the coefficient matrix of the LP
1303

	
1304
    ///\param r is the row of the element
1305
    ///\param c is the column of the element
1306
    ///\return the corresponding coefficient
1307
    Value coeff(Row r, Col c) const {
1308
      return _getCoeff(rows(id(r)),cols(id(c)));
1309
    }
1310

	
1311
    /// Set the lower bound of a column (i.e a variable)
1312

	
1313
    /// The lower bound of a variable (column) has to be given by an
1314
    /// extended number of type Value, i.e. a finite number of type
1315
    /// Value or -\ref INF.
1316
    void colLowerBound(Col c, Value value) {
1317
      _setColLowerBound(cols(id(c)),value);
1318
    }
1319

	
1320
    /// Get the lower bound of a column (i.e a variable)
1321

	
1322
    /// This function returns the lower bound for column (variable) \c c
1323
    /// (this might be -\ref INF as well).
1324
    ///\return The lower bound for column \c c
1325
    Value colLowerBound(Col c) const {
1326
      return _getColLowerBound(cols(id(c)));
1327
    }
1328

	
1329
    ///\brief Set the lower bound of  several columns
1330
    ///(i.e variables) at once
1331
    ///
1332
    ///This magic function takes a container as its argument
1333
    ///and applies the function on all of its elements.
1334
    ///The lower bound of a variable (column) has to be given by an
1335
    ///extended number of type Value, i.e. a finite number of type
1336
    ///Value or -\ref INF.
1337
#ifdef DOXYGEN
1338
    template<class T>
1339
    void colLowerBound(T &t, Value value) { return 0;}
1340
#else
1341
    template<class T>
1342
    typename enable_if<typename T::value_type::LpCol,void>::type
1343
    colLowerBound(T &t, Value value,dummy<0> = 0) {
1344
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1345
        colLowerBound(*i, value);
1346
      }
1347
    }
1348
    template<class T>
1349
    typename enable_if<typename T::value_type::second_type::LpCol,
1350
                       void>::type
1351
    colLowerBound(T &t, Value value,dummy<1> = 1) {
1352
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1353
        colLowerBound(i->second, value);
1354
      }
1355
    }
1356
    template<class T>
1357
    typename enable_if<typename T::MapIt::Value::LpCol,
1358
                       void>::type
1359
    colLowerBound(T &t, Value value,dummy<2> = 2) {
1360
      for(typename T::MapIt i(t); i!=INVALID; ++i){
1361
        colLowerBound(*i, value);
1362
      }
1363
    }
1364
#endif
1365

	
1366
    /// Set the upper bound of a column (i.e a variable)
1367

	
1368
    /// The upper bound of a variable (column) has to be given by an
1369
    /// extended number of type Value, i.e. a finite number of type
1370
    /// Value or \ref INF.
1371
    void colUpperBound(Col c, Value value) {
1372
      _setColUpperBound(cols(id(c)),value);
1373
    };
1374

	
1375
    /// Get the upper bound of a column (i.e a variable)
1376

	
1377
    /// This function returns the upper bound for column (variable) \c c
1378
    /// (this might be \ref INF as well).
1379
    /// \return The upper bound for column \c c
1380
    Value colUpperBound(Col c) const {
1381
      return _getColUpperBound(cols(id(c)));
1382
    }
1383

	
1384
    ///\brief Set the upper bound of  several columns
1385
    ///(i.e variables) at once
1386
    ///
1387
    ///This magic function takes a container as its argument
1388
    ///and applies the function on all of its elements.
1389
    ///The upper bound of a variable (column) has to be given by an
1390
    ///extended number of type Value, i.e. a finite number of type
1391
    ///Value or \ref INF.
1392
#ifdef DOXYGEN
1393
    template<class T>
1394
    void colUpperBound(T &t, Value value) { return 0;}
1395
#else
1396
    template<class T1>
1397
    typename enable_if<typename T1::value_type::LpCol,void>::type
1398
    colUpperBound(T1 &t, Value value,dummy<0> = 0) {
1399
      for(typename T1::iterator i=t.begin();i!=t.end();++i) {
1400
        colUpperBound(*i, value);
1401
      }
1402
    }
1403
    template<class T1>
1404
    typename enable_if<typename T1::value_type::second_type::LpCol,
1405
                       void>::type
1406
    colUpperBound(T1 &t, Value value,dummy<1> = 1) {
1407
      for(typename T1::iterator i=t.begin();i!=t.end();++i) {
1408
        colUpperBound(i->second, value);
1409
      }
1410
    }
1411
    template<class T1>
1412
    typename enable_if<typename T1::MapIt::Value::LpCol,
1413
                       void>::type
1414
    colUpperBound(T1 &t, Value value,dummy<2> = 2) {
1415
      for(typename T1::MapIt i(t); i!=INVALID; ++i){
1416
        colUpperBound(*i, value);
1417
      }
1418
    }
1419
#endif
1420

	
1421
    /// Set the lower and the upper bounds of a column (i.e a variable)
1422

	
1423
    /// The lower and the upper bounds of
1424
    /// a variable (column) have to be given by an
1425
    /// extended number of type Value, i.e. a finite number of type
1426
    /// Value, -\ref INF or \ref INF.
1427
    void colBounds(Col c, Value lower, Value upper) {
1428
      _setColLowerBound(cols(id(c)),lower);
1429
      _setColUpperBound(cols(id(c)),upper);
1430
    }
1431

	
1432
    ///\brief Set the lower and the upper bound of several columns
1433
    ///(i.e variables) at once
1434
    ///
1435
    ///This magic function takes a container as its argument
1436
    ///and applies the function on all of its elements.
1437
    /// The lower and the upper bounds of
1438
    /// a variable (column) have to be given by an
1439
    /// extended number of type Value, i.e. a finite number of type
1440
    /// Value, -\ref INF or \ref INF.
1441
#ifdef DOXYGEN
1442
    template<class T>
1443
    void colBounds(T &t, Value lower, Value upper) { return 0;}
1444
#else
1445
    template<class T2>
1446
    typename enable_if<typename T2::value_type::LpCol,void>::type
1447
    colBounds(T2 &t, Value lower, Value upper,dummy<0> = 0) {
1448
      for(typename T2::iterator i=t.begin();i!=t.end();++i) {
1449
        colBounds(*i, lower, upper);
1450
      }
1451
    }
1452
    template<class T2>
1453
    typename enable_if<typename T2::value_type::second_type::LpCol, void>::type
1454
    colBounds(T2 &t, Value lower, Value upper,dummy<1> = 1) {
1455
      for(typename T2::iterator i=t.begin();i!=t.end();++i) {
1456
        colBounds(i->second, lower, upper);
1457
      }
1458
    }
1459
    template<class T2>
1460
    typename enable_if<typename T2::MapIt::Value::LpCol, void>::type
1461
    colBounds(T2 &t, Value lower, Value upper,dummy<2> = 2) {
1462
      for(typename T2::MapIt i(t); i!=INVALID; ++i){
1463
        colBounds(*i, lower, upper);
1464
      }
1465
    }
1466
#endif
1467

	
1468
    /// Set the lower bound of a row (i.e a constraint)
1469

	
1470
    /// The lower bound of a constraint (row) has to be given by an
1471
    /// extended number of type Value, i.e. a finite number of type
1472
    /// Value or -\ref INF.
1473
    void rowLowerBound(Row r, Value value) {
1474
      _setRowLowerBound(rows(id(r)),value);
1475
    }
1476

	
1477
    /// Get the lower bound of a row (i.e a constraint)
1478

	
1479
    /// This function returns the lower bound for row (constraint) \c c
1480
    /// (this might be -\ref INF as well).
1481
    ///\return The lower bound for row \c r
1482
    Value rowLowerBound(Row r) const {
1483
      return _getRowLowerBound(rows(id(r)));
1484
    }
1485

	
1486
    /// Set the upper bound of a row (i.e a constraint)
1487

	
1488
    /// The upper bound of a constraint (row) has to be given by an
1489
    /// extended number of type Value, i.e. a finite number of type
1490
    /// Value or -\ref INF.
1491
    void rowUpperBound(Row r, Value value) {
1492
      _setRowUpperBound(rows(id(r)),value);
1493
    }
1494

	
1495
    /// Get the upper bound of a row (i.e a constraint)
1496

	
1497
    /// This function returns the upper bound for row (constraint) \c c
1498
    /// (this might be -\ref INF as well).
1499
    ///\return The upper bound for row \c r
1500
    Value rowUpperBound(Row r) const {
1501
      return _getRowUpperBound(rows(id(r)));
1502
    }
1503

	
1504
    ///Set an element of the objective function
1505
    void objCoeff(Col c, Value v) {_setObjCoeff(cols(id(c)),v); };
1506

	
1507
    ///Get an element of the objective function
1508
    Value objCoeff(Col c) const { return _getObjCoeff(cols(id(c))); };
1509

	
1510
    ///Set the objective function
1511

	
1512
    ///\param e is a linear expression of type \ref Expr.
1513
    ///
1514
    void obj(const Expr& e) {
1515
      _setObjCoeffs(ExprIterator(e.comps.begin(), cols),
1516
                    ExprIterator(e.comps.end(), cols));
1517
      obj_const_comp = *e;
1518
    }
1519

	
1520
    ///Get the objective function
1521

	
1522
    ///\return the objective function as a linear expression of type
1523
    ///Expr.
1524
    Expr obj() const {
1525
      Expr e;
1526
      _getObjCoeffs(InsertIterator(e.comps, cols));
1527
      *e = obj_const_comp;
1528
      return e;
1529
    }
1530

	
1531

	
1532
    ///Set the direction of optimization
1533
    void sense(Sense sense) { _setSense(sense); }
1534

	
1535
    ///Query the direction of the optimization
1536
    Sense sense() const {return _getSense(); }
1537

	
1538
    ///Set the sense to maximization
1539
    void max() { _setSense(MAX); }
1540

	
1541
    ///Set the sense to maximization
1542
    void min() { _setSense(MIN); }
1543

	
1544
    ///Clears the problem
1545
    void clear() { _clear(); }
1546

	
1547
    /// Sets the message level of the solver
1548
    void messageLevel(MessageLevel level) { _messageLevel(level); }
1549

	
1550
    ///@}
1551

	
1552
  };
1553

	
1554
  /// Addition
1555

	
1556
  ///\relates LpBase::Expr
1557
  ///
1558
  inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) {
1559
    LpBase::Expr tmp(a);
1560
    tmp+=b;
1561
    return tmp;
1562
  }
1563
  ///Substraction
1564

	
1565
  ///\relates LpBase::Expr
1566
  ///
1567
  inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) {
1568
    LpBase::Expr tmp(a);
1569
    tmp-=b;
1570
    return tmp;
1571
  }
1572
  ///Multiply with constant
1573

	
1574
  ///\relates LpBase::Expr
1575
  ///
1576
  inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) {
1577
    LpBase::Expr tmp(a);
1578
    tmp*=b;
1579
    return tmp;
1580
  }
1581

	
1582
  ///Multiply with constant
1583

	
1584
  ///\relates LpBase::Expr
1585
  ///
1586
  inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) {
1587
    LpBase::Expr tmp(b);
1588
    tmp*=a;
1589
    return tmp;
1590
  }
1591
  ///Divide with constant
1592

	
1593
  ///\relates LpBase::Expr
1594
  ///
1595
  inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) {
1596
    LpBase::Expr tmp(a);
1597
    tmp/=b;
1598
    return tmp;
1599
  }
1600

	
1601
  ///Create constraint
1602

	
1603
  ///\relates LpBase::Constr
1604
  ///
1605
  inline LpBase::Constr operator<=(const LpBase::Expr &e,
1606
                                   const LpBase::Expr &f) {
1607
    return LpBase::Constr(0, f - e, LpBase::INF);
1608
  }
1609

	
1610
  ///Create constraint
1611

	
1612
  ///\relates LpBase::Constr
1613
  ///
1614
  inline LpBase::Constr operator<=(const LpBase::Value &e,
1615
                                   const LpBase::Expr &f) {
1616
    return LpBase::Constr(e, f, LpBase::NaN);
1617
  }
1618

	
1619
  ///Create constraint
1620

	
1621
  ///\relates LpBase::Constr
1622
  ///
1623
  inline LpBase::Constr operator<=(const LpBase::Expr &e,
1624
                                   const LpBase::Value &f) {
1625
    return LpBase::Constr(- LpBase::INF, e, f);
1626
  }
1627

	
1628
  ///Create constraint
1629

	
1630
  ///\relates LpBase::Constr
1631
  ///
1632
  inline LpBase::Constr operator>=(const LpBase::Expr &e,
1633
                                   const LpBase::Expr &f) {
1634
    return LpBase::Constr(0, e - f, LpBase::INF);
1635
  }
1636

	
1637

	
1638
  ///Create constraint
1639

	
1640
  ///\relates LpBase::Constr
1641
  ///
1642
  inline LpBase::Constr operator>=(const LpBase::Value &e,
1643
                                   const LpBase::Expr &f) {
1644
    return LpBase::Constr(LpBase::NaN, f, e);
1645
  }
1646

	
1647

	
1648
  ///Create constraint
1649

	
1650
  ///\relates LpBase::Constr
1651
  ///
1652
  inline LpBase::Constr operator>=(const LpBase::Expr &e,
1653
                                   const LpBase::Value &f) {
1654
    return LpBase::Constr(f, e, LpBase::INF);
1655
  }
1656

	
1657
  ///Create constraint
1658

	
1659
  ///\relates LpBase::Constr
1660
  ///
1661
  inline LpBase::Constr operator==(const LpBase::Expr &e,
1662
                                   const LpBase::Value &f) {
1663
    return LpBase::Constr(f, e, f);
1664
  }
1665

	
1666
  ///Create constraint
1667

	
1668
  ///\relates LpBase::Constr
1669
  ///
1670
  inline LpBase::Constr operator==(const LpBase::Expr &e,
1671
                                   const LpBase::Expr &f) {
1672
    return LpBase::Constr(0, f - e, 0);
1673
  }
1674

	
1675
  ///Create constraint
1676

	
1677
  ///\relates LpBase::Constr
1678
  ///
1679
  inline LpBase::Constr operator<=(const LpBase::Value &n,
1680
                                   const LpBase::Constr &c) {
1681
    LpBase::Constr tmp(c);
1682
    LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
1683
    tmp.lowerBound()=n;
1684
    return tmp;
1685
  }
1686
  ///Create constraint
1687

	
1688
  ///\relates LpBase::Constr
1689
  ///
1690
  inline LpBase::Constr operator<=(const LpBase::Constr &c,
1691
                                   const LpBase::Value &n)
1692
  {
1693
    LpBase::Constr tmp(c);
1694
    LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
1695
    tmp.upperBound()=n;
1696
    return tmp;
1697
  }
1698

	
1699
  ///Create constraint
1700

	
1701
  ///\relates LpBase::Constr
1702
  ///
1703
  inline LpBase::Constr operator>=(const LpBase::Value &n,
1704
                                   const LpBase::Constr &c) {
1705
    LpBase::Constr tmp(c);
1706
    LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
1707
    tmp.upperBound()=n;
1708
    return tmp;
1709
  }
1710
  ///Create constraint
1711

	
1712
  ///\relates LpBase::Constr
1713
  ///
1714
  inline LpBase::Constr operator>=(const LpBase::Constr &c,
1715
                                   const LpBase::Value &n)
1716
  {
1717
    LpBase::Constr tmp(c);
1718
    LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
1719
    tmp.lowerBound()=n;
1720
    return tmp;
1721
  }
1722

	
1723
  ///Addition
1724

	
1725
  ///\relates LpBase::DualExpr
1726
  ///
1727
  inline LpBase::DualExpr operator+(const LpBase::DualExpr &a,
1728
                                    const LpBase::DualExpr &b) {
1729
    LpBase::DualExpr tmp(a);
1730
    tmp+=b;
1731
    return tmp;
1732
  }
1733
  ///Substraction
1734

	
1735
  ///\relates LpBase::DualExpr
1736
  ///
1737
  inline LpBase::DualExpr operator-(const LpBase::DualExpr &a,
1738
                                    const LpBase::DualExpr &b) {
1739
    LpBase::DualExpr tmp(a);
1740
    tmp-=b;
1741
    return tmp;
1742
  }
1743
  ///Multiply with constant
1744

	
1745
  ///\relates LpBase::DualExpr
1746
  ///
1747
  inline LpBase::DualExpr operator*(const LpBase::DualExpr &a,
1748
                                    const LpBase::Value &b) {
1749
    LpBase::DualExpr tmp(a);
1750
    tmp*=b;
1751
    return tmp;
1752
  }
1753

	
1754
  ///Multiply with constant
1755

	
1756
  ///\relates LpBase::DualExpr
1757
  ///
1758
  inline LpBase::DualExpr operator*(const LpBase::Value &a,
1759
                                    const LpBase::DualExpr &b) {
1760
    LpBase::DualExpr tmp(b);
1761
    tmp*=a;
1762
    return tmp;
1763
  }
1764
  ///Divide with constant
1765

	
1766
  ///\relates LpBase::DualExpr
1767
  ///
1768
  inline LpBase::DualExpr operator/(const LpBase::DualExpr &a,
1769
                                    const LpBase::Value &b) {
1770
    LpBase::DualExpr tmp(a);
1771
    tmp/=b;
1772
    return tmp;
1773
  }
1774

	
1775
  /// \ingroup lp_group
1776
  ///
1777
  /// \brief Common base class for LP solvers
1778
  ///
1779
  /// This class is an abstract base class for LP solvers. This class
1780
  /// provides a full interface for set and modify an LP problem,
1781
  /// solve it and retrieve the solution. You can use one of the
1782
  /// descendants as a concrete implementation, or the \c Lp
1783
  /// default LP solver. However, if you would like to handle LP
1784
  /// solvers as reference or pointer in a generic way, you can use
1785
  /// this class directly.
1786
  class LpSolver : virtual public LpBase {
1787
  public:
1788

	
1789
    /// The problem types for primal and dual problems
1790
    enum ProblemType {
1791
      /// = 0. Feasible solution hasn't been found (but may exist).
1792
      UNDEFINED = 0,
1793
      /// = 1. The problem has no feasible solution.
1794
      INFEASIBLE = 1,
1795
      /// = 2. Feasible solution found.
1796
      FEASIBLE = 2,
1797
      /// = 3. Optimal solution exists and found.
1798
      OPTIMAL = 3,
1799
      /// = 4. The cost function is unbounded.
1800
      UNBOUNDED = 4
1801
    };
1802

	
1803
    ///The basis status of variables
1804
    enum VarStatus {
1805
      /// The variable is in the basis
1806
      BASIC, 
1807
      /// The variable is free, but not basic
1808
      FREE,
1809
      /// The variable has active lower bound 
1810
      LOWER,
1811
      /// The variable has active upper bound
1812
      UPPER,
1813
      /// The variable is non-basic and fixed
1814
      FIXED
1815
    };
1816

	
1817
  protected:
1818

	
1819
    virtual SolveExitStatus _solve() = 0;
1820

	
1821
    virtual Value _getPrimal(int i) const = 0;
1822
    virtual Value _getDual(int i) const = 0;
1823

	
1824
    virtual Value _getPrimalRay(int i) const = 0;
1825
    virtual Value _getDualRay(int i) const = 0;
1826

	
1827
    virtual Value _getPrimalValue() const = 0;
1828

	
1829
    virtual VarStatus _getColStatus(int i) const = 0;
1830
    virtual VarStatus _getRowStatus(int i) const = 0;
1831

	
1832
    virtual ProblemType _getPrimalType() const = 0;
1833
    virtual ProblemType _getDualType() const = 0;
1834

	
1835
  public:
1836

	
1837
    ///Allocate a new LP problem instance
1838
    virtual LpSolver* newSolver() const = 0;
1839
    ///Make a copy of the LP problem
1840
    virtual LpSolver* cloneSolver() const = 0;
1841

	
1842
    ///\name Solve the LP
1843

	
1844
    ///@{
1845

	
1846
    ///\e Solve the LP problem at hand
1847
    ///
1848
    ///\return The result of the optimization procedure. Possible
1849
    ///values and their meanings can be found in the documentation of
1850
    ///\ref SolveExitStatus.
1851
    SolveExitStatus solve() { return _solve(); }
1852

	
1853
    ///@}
1854

	
1855
    ///\name Obtain the Solution
1856

	
1857
    ///@{
1858

	
1859
    /// The type of the primal problem
1860
    ProblemType primalType() const {
1861
      return _getPrimalType();
1862
    }
1863

	
1864
    /// The type of the dual problem
1865
    ProblemType dualType() const {
1866
      return _getDualType();
1867
    }
1868

	
1869
    /// Return the primal value of the column
1870

	
1871
    /// Return the primal value of the column.
1872
    /// \pre The problem is solved.
1873
    Value primal(Col c) const { return _getPrimal(cols(id(c))); }
1874

	
1875
    /// Return the primal value of the expression
1876

	
1877
    /// Return the primal value of the expression, i.e. the dot
1878
    /// product of the primal solution and the expression.
1879
    /// \pre The problem is solved.
1880
    Value primal(const Expr& e) const {
1881
      double res = *e;
1882
      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
1883
        res += *c * primal(c);
1884
      }
1885
      return res;
1886
    }
1887
    /// Returns a component of the primal ray
1888
    
1889
    /// The primal ray is solution of the modified primal problem,
1890
    /// where we change each finite bound to 0, and we looking for a
1891
    /// negative objective value in case of minimization, and positive
1892
    /// objective value for maximization. If there is such solution,
1893
    /// that proofs the unsolvability of the dual problem, and if a
1894
    /// feasible primal solution exists, then the unboundness of
1895
    /// primal problem.
1896
    ///
1897
    /// \pre The problem is solved and the dual problem is infeasible.
1898
    /// \note Some solvers does not provide primal ray calculation
1899
    /// functions.
1900
    Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); }
1901

	
1902
    /// Return the dual value of the row
1903

	
1904
    /// Return the dual value of the row.
1905
    /// \pre The problem is solved.
1906
    Value dual(Row r) const { return _getDual(rows(id(r))); }
1907

	
1908
    /// Return the dual value of the dual expression
1909

	
1910
    /// Return the dual value of the dual expression, i.e. the dot
1911
    /// product of the dual solution and the dual expression.
1912
    /// \pre The problem is solved.
1913
    Value dual(const DualExpr& e) const {
1914
      double res = 0.0;
1915
      for (DualExpr::ConstCoeffIt r(e); r != INVALID; ++r) {
1916
        res += *r * dual(r);
1917
      }
1918
      return res;
1919
    }
1920

	
1921
    /// Returns a component of the dual ray
1922
    
1923
    /// The dual ray is solution of the modified primal problem, where
1924
    /// we change each finite bound to 0 (i.e. the objective function
1925
    /// coefficients in the primal problem), and we looking for a
1926
    /// ositive objective value. If there is such solution, that
1927
    /// proofs the unsolvability of the primal problem, and if a
1928
    /// feasible dual solution exists, then the unboundness of
1929
    /// dual problem.
1930
    ///
1931
    /// \pre The problem is solved and the primal problem is infeasible.
1932
    /// \note Some solvers does not provide dual ray calculation
1933
    /// functions.
1934
    Value dualRay(Row r) const { return _getDualRay(rows(id(r))); }
1935

	
1936
    /// Return the basis status of the column
1937

	
1938
    /// \see VarStatus
1939
    VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); }
1940

	
1941
    /// Return the basis status of the row
1942

	
1943
    /// \see VarStatus
1944
    VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); }
1945

	
1946
    ///The value of the objective function
1947

	
1948
    ///\return
1949
    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
1950
    /// of the primal problem, depending on whether we minimize or maximize.
1951
    ///- \ref NaN if no primal solution is found.
1952
    ///- The (finite) objective value if an optimal solution is found.
1953
    Value primal() const { return _getPrimalValue()+obj_const_comp;}
1954
    ///@}
1955

	
1956
  protected:
1957

	
1958
  };
1959

	
1960

	
1961
  /// \ingroup lp_group
1962
  ///
1963
  /// \brief Common base class for MIP solvers
1964
  ///
1965
  /// This class is an abstract base class for MIP solvers. This class
1966
  /// provides a full interface for set and modify an MIP problem,
1967
  /// solve it and retrieve the solution. You can use one of the
1968
  /// descendants as a concrete implementation, or the \c Lp
1969
  /// default MIP solver. However, if you would like to handle MIP
1970
  /// solvers as reference or pointer in a generic way, you can use
1971
  /// this class directly.
1972
  class MipSolver : virtual public LpBase {
1973
  public:
1974

	
1975
    /// The problem types for MIP problems
1976
    enum ProblemType {
1977
      /// = 0. Feasible solution hasn't been found (but may exist).
1978
      UNDEFINED = 0,
1979
      /// = 1. The problem has no feasible solution.
1980
      INFEASIBLE = 1,
1981
      /// = 2. Feasible solution found.
1982
      FEASIBLE = 2,
1983
      /// = 3. Optimal solution exists and found.
1984
      OPTIMAL = 3,
1985
      /// = 4. The cost function is unbounded.
1986
      ///The Mip or at least the relaxed problem is unbounded.
1987
      UNBOUNDED = 4
1988
    };
1989

	
1990
    ///Allocate a new MIP problem instance
1991
    virtual MipSolver* newSolver() const = 0;
1992
    ///Make a copy of the MIP problem
1993
    virtual MipSolver* cloneSolver() const = 0;
1994

	
1995
    ///\name Solve the MIP
1996

	
1997
    ///@{
1998

	
1999
    /// Solve the MIP problem at hand
2000
    ///
2001
    ///\return The result of the optimization procedure. Possible
2002
    ///values and their meanings can be found in the documentation of
2003
    ///\ref SolveExitStatus.
2004
    SolveExitStatus solve() { return _solve(); }
2005

	
2006
    ///@}
2007

	
2008
    ///\name Set Column Type
2009
    ///@{
2010

	
2011
    ///Possible variable (column) types (e.g. real, integer, binary etc.)
2012
    enum ColTypes {
2013
      /// = 0. Continuous variable (default).
2014
      REAL = 0,
2015
      /// = 1. Integer variable.
2016
      INTEGER = 1
2017
    };
2018

	
2019
    ///Sets the type of the given column to the given type
2020

	
2021
    ///Sets the type of the given column to the given type.
2022
    ///
2023
    void colType(Col c, ColTypes col_type) {
2024
      _setColType(cols(id(c)),col_type);
2025
    }
2026

	
2027
    ///Gives back the type of the column.
2028

	
2029
    ///Gives back the type of the column.
2030
    ///
2031
    ColTypes colType(Col c) const {
2032
      return _getColType(cols(id(c)));
2033
    }
2034
    ///@}
2035

	
2036
    ///\name Obtain the Solution
2037

	
2038
    ///@{
2039

	
2040
    /// The type of the MIP problem
2041
    ProblemType type() const {
2042
      return _getType();
2043
    }
2044

	
2045
    /// Return the value of the row in the solution
2046

	
2047
    ///  Return the value of the row in the solution.
2048
    /// \pre The problem is solved.
2049
    Value sol(Col c) const { return _getSol(cols(id(c))); }
2050

	
2051
    /// Return the value of the expression in the solution
2052

	
2053
    /// Return the value of the expression in the solution, i.e. the
2054
    /// dot product of the solution and the expression.
2055
    /// \pre The problem is solved.
2056
    Value sol(const Expr& e) const {
2057
      double res = *e;
2058
      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
2059
        res += *c * sol(c);
2060
      }
2061
      return res;
2062
    }
2063
    ///The value of the objective function
2064
    
2065
    ///\return
2066
    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
2067
    /// of the problem, depending on whether we minimize or maximize.
2068
    ///- \ref NaN if no primal solution is found.
2069
    ///- The (finite) objective value if an optimal solution is found.
2070
    Value solValue() const { return _getSolValue()+obj_const_comp;}
2071
    ///@}
2072

	
2073
  protected:
2074

	
2075
    virtual SolveExitStatus _solve() = 0;
2076
    virtual ColTypes _getColType(int col) const = 0;
2077
    virtual void _setColType(int col, ColTypes col_type) = 0;
2078
    virtual ProblemType _getType() const = 0;
2079
    virtual Value _getSol(int i) const = 0;
2080
    virtual Value _getSolValue() const = 0;
2081

	
2082
  };
2083

	
2084

	
2085

	
2086
} //namespace lemon
2087

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

	
19
#include <lemon/lp_skeleton.h>
20

	
21
///\file
22
///\brief A skeleton file to implement LP solver interfaces
23
namespace lemon {
24

	
25
  int SkeletonSolverBase::_addCol()
26
  {
27
    return ++col_num;
28
  }
29

	
30
  int SkeletonSolverBase::_addRow()
31
  {
32
    return ++row_num;
33
  }
34

	
35
  void SkeletonSolverBase::_eraseCol(int) {}
36
  void SkeletonSolverBase::_eraseRow(int) {}
37

	
38
  void SkeletonSolverBase::_getColName(int, std::string &) const {}
39
  void SkeletonSolverBase::_setColName(int, const std::string &) {}
40
  int SkeletonSolverBase::_colByName(const std::string&) const { return -1; }
41

	
42
  void SkeletonSolverBase::_getRowName(int, std::string &) const {}
43
  void SkeletonSolverBase::_setRowName(int, const std::string &) {}
44
  int SkeletonSolverBase::_rowByName(const std::string&) const { return -1; }
45

	
46
  void SkeletonSolverBase::_setRowCoeffs(int, ExprIterator, ExprIterator) {}
47
  void SkeletonSolverBase::_getRowCoeffs(int, InsertIterator) const {}
48

	
49
  void SkeletonSolverBase::_setColCoeffs(int, ExprIterator, ExprIterator) {}
50
  void SkeletonSolverBase::_getColCoeffs(int, InsertIterator) const {}
51

	
52
  void SkeletonSolverBase::_setCoeff(int, int, Value) {}
53
  SkeletonSolverBase::Value SkeletonSolverBase::_getCoeff(int, int) const
54
  { return 0; }
55

	
56
  void SkeletonSolverBase::_setColLowerBound(int, Value) {}
57
  SkeletonSolverBase::Value SkeletonSolverBase::_getColLowerBound(int) const
58
  {  return 0; }
59

	
60
  void SkeletonSolverBase::_setColUpperBound(int, Value) {}
61
  SkeletonSolverBase::Value SkeletonSolverBase::_getColUpperBound(int) const
62
  {  return 0; }
63

	
64
  void SkeletonSolverBase::_setRowLowerBound(int, Value) {}
65
  SkeletonSolverBase::Value SkeletonSolverBase::_getRowLowerBound(int) const
66
  {  return 0; }
67

	
68
  void SkeletonSolverBase::_setRowUpperBound(int, Value) {}
69
  SkeletonSolverBase::Value SkeletonSolverBase::_getRowUpperBound(int) const
70
  {  return 0; }
71

	
72
  void SkeletonSolverBase::_setObjCoeffs(ExprIterator, ExprIterator) {}
73
  void SkeletonSolverBase::_getObjCoeffs(InsertIterator) const {};
74

	
75
  void SkeletonSolverBase::_setObjCoeff(int, Value) {}
76
  SkeletonSolverBase::Value SkeletonSolverBase::_getObjCoeff(int) const
77
  {  return 0; }
78

	
79
  void SkeletonSolverBase::_setSense(Sense) {}
80
  SkeletonSolverBase::Sense SkeletonSolverBase::_getSense() const
81
  { return MIN; }
82

	
83
  void SkeletonSolverBase::_clear() {
84
    row_num = col_num = 0;
85
  }
86

	
87
  void SkeletonSolverBase::_messageLevel(MessageLevel) {}
88

	
89
  LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
90

	
91
  LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
92
  LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; }
93
  LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; }
94

	
95
  LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; }
96
  LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; }
97

	
98
  LpSkeleton::ProblemType LpSkeleton::_getPrimalType() const
99
  { return UNDEFINED; }
100

	
101
  LpSkeleton::ProblemType LpSkeleton::_getDualType() const
102
  { return UNDEFINED; }
103

	
104
  LpSkeleton::VarStatus LpSkeleton::_getColStatus(int) const
105
  { return BASIC; }
106

	
107
  LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
108
  { return BASIC; }
109

	
110
  LpSkeleton* LpSkeleton::newSolver() const
111
  { return static_cast<LpSkeleton*>(0); }
112

	
113
  LpSkeleton* LpSkeleton::cloneSolver() const
114
  { return static_cast<LpSkeleton*>(0); }
115

	
116
  const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
117

	
118
  MipSkeleton::SolveExitStatus MipSkeleton::_solve()
119
  { return SOLVED; }
120

	
121
  MipSkeleton::Value MipSkeleton::_getSol(int) const { return 0; }
122
  MipSkeleton::Value MipSkeleton::_getSolValue() const { return 0; }
123

	
124
  MipSkeleton::ProblemType MipSkeleton::_getType() const
125
  { return UNDEFINED; }
126

	
127
  MipSkeleton* MipSkeleton::newSolver() const
128
  { return static_cast<MipSkeleton*>(0); }
129

	
130
  MipSkeleton* MipSkeleton::cloneSolver() const
131
  { return static_cast<MipSkeleton*>(0); }
132

	
133
  const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
134

	
135
} //namespace lemon
136

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

	
19
#ifndef LEMON_LP_SKELETON_H
20
#define LEMON_LP_SKELETON_H
21

	
22
#include <lemon/lp_base.h>
23

	
24
///\file
25
///\brief Skeleton file to implement LP/MIP solver interfaces
26
///  
27
///The classes in this file do nothing, but they can serve as skeletons when
28
///implementing an interface to new solvers.
29
namespace lemon {
30

	
31
  ///A skeleton class to implement LP/MIP solver base interface
32
  
33
  ///This class does nothing, but it can serve as a skeleton when
34
  ///implementing an interface to new solvers.
35
  class SkeletonSolverBase : public virtual LpBase {
36
    int col_num,row_num;
37

	
38
  protected:
39

	
40
    SkeletonSolverBase()
41
      : col_num(-1), row_num(-1) {}
42

	
43
    /// \e
44
    virtual int _addCol();
45
    /// \e
46
    virtual int _addRow();
47
    /// \e
48
    virtual void _eraseCol(int i);
49
    /// \e
50
    virtual void _eraseRow(int i);
51

	
52
    /// \e
53
    virtual void _getColName(int col, std::string& name) const;
54
    /// \e
55
    virtual void _setColName(int col, const std::string& name);
56
    /// \e
57
    virtual int _colByName(const std::string& name) const;
58

	
59
    /// \e
60
    virtual void _getRowName(int row, std::string& name) const;
61
    /// \e
62
    virtual void _setRowName(int row, const std::string& name);
63
    /// \e
64
    virtual int _rowByName(const std::string& name) const;
65

	
66
    /// \e
67
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
68
    /// \e
69
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
70
    /// \e
71
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
72
    /// \e
73
    virtual void _getColCoeffs(int i, InsertIterator b) const;
74

	
75
    /// Set one element of the coefficient matrix
76
    virtual void _setCoeff(int row, int col, Value value);
77

	
78
    /// Get one element of the coefficient matrix
79
    virtual Value _getCoeff(int row, int col) const;
80

	
81
    /// The lower bound of a variable (column) have to be given by an
82
    /// extended number of type Value, i.e. a finite number of type
83
    /// Value or -\ref INF.
84
    virtual void _setColLowerBound(int i, Value value);
85
    /// \e
86

	
87
    /// The lower bound of a variable (column) is an
88
    /// extended number of type Value, i.e. a finite number of type
89
    /// Value or -\ref INF.
90
    virtual Value _getColLowerBound(int i) const;
91

	
92
    /// The upper bound of a variable (column) have to be given by an
93
    /// extended number of type Value, i.e. a finite number of type
94
    /// Value or \ref INF.
95
    virtual void _setColUpperBound(int i, Value value);
96
    /// \e
97

	
98
    /// The upper bound of a variable (column) is an
99
    /// extended number of type Value, i.e. a finite number of type
100
    /// Value or \ref INF.
101
    virtual Value _getColUpperBound(int i) const;
102

	
103
    /// The lower bound of a constraint (row) have to be given by an
104
    /// extended number of type Value, i.e. a finite number of type
105
    /// Value or -\ref INF.
106
    virtual void _setRowLowerBound(int i, Value value);
107
    /// \e
108

	
109
    /// The lower bound of a constraint (row) is an
110
    /// extended number of type Value, i.e. a finite number of type
111
    /// Value or -\ref INF.
112
    virtual Value _getRowLowerBound(int i) const;
113

	
114
    /// The upper bound of a constraint (row) have to be given by an
115
    /// extended number of type Value, i.e. a finite number of type
116
    /// Value or \ref INF.
117
    virtual void _setRowUpperBound(int i, Value value);
118
    /// \e
119

	
120
    /// The upper bound of a constraint (row) is an
121
    /// extended number of type Value, i.e. a finite number of type
122
    /// Value or \ref INF.
123
    virtual Value _getRowUpperBound(int i) const;
124

	
125
    /// \e
126
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
127
    /// \e
128
    virtual void _getObjCoeffs(InsertIterator b) const;
129

	
130
    /// \e
131
    virtual void _setObjCoeff(int i, Value obj_coef);
132
    /// \e
133
    virtual Value _getObjCoeff(int i) const;
134

	
135
    ///\e
136
    virtual void _setSense(Sense);
137
    ///\e
138
    virtual Sense _getSense() const;
139

	
140
    ///\e
141
    virtual void _clear();
142

	
143
    ///\e
144
    virtual void _messageLevel(MessageLevel);
145
  };
146

	
147
  /// \brief Skeleton class for an LP solver interface
148
  ///
149
  ///This class does nothing, but it can serve as a skeleton when
150
  ///implementing an interface to new solvers.
151

	
152
  ///\ingroup lp_group
153
  class LpSkeleton : public LpSolver, public SkeletonSolverBase {
154
  public:
155
    ///\e
156
    LpSkeleton() : LpSolver(), SkeletonSolverBase() {}
157
    ///\e
158
    virtual LpSkeleton* newSolver() const;
159
    ///\e
160
    virtual LpSkeleton* cloneSolver() const;
161
  protected:
162

	
163
    ///\e
164
    virtual SolveExitStatus _solve();
165

	
166
    ///\e
167
    virtual Value _getPrimal(int i) const;
168
    ///\e
169
    virtual Value _getDual(int i) const;
170

	
171
    ///\e
172
    virtual Value _getPrimalValue() const;
173

	
174
    ///\e
175
    virtual Value _getPrimalRay(int i) const;
176
    ///\e
177
    virtual Value _getDualRay(int i) const;
178

	
179
    ///\e
180
    virtual ProblemType _getPrimalType() const;
181
    ///\e
182
    virtual ProblemType _getDualType() const;
183

	
184
    ///\e
185
    virtual VarStatus _getColStatus(int i) const;
186
    ///\e
187
    virtual VarStatus _getRowStatus(int i) const;
188

	
189
    ///\e
190
    virtual const char* _solverName() const;
191

	
192
  };
193

	
194
  /// \brief Skeleton class for a MIP solver interface
195
  ///
196
  ///This class does nothing, but it can serve as a skeleton when
197
  ///implementing an interface to new solvers.
198
  ///\ingroup lp_group
199
  class MipSkeleton : public MipSolver, public SkeletonSolverBase {
200
  public:
201
    ///\e
202
    MipSkeleton() : MipSolver(), SkeletonSolverBase() {}
203
    ///\e
204
    virtual MipSkeleton* newSolver() const;
205
    ///\e
206
    virtual MipSkeleton* cloneSolver() const;
207

	
208
  protected:
209
    ///\e
210
    virtual SolveExitStatus _solve();
211

	
212
    ///\e
213
    virtual Value _getSol(int i) const;
214

	
215
    ///\e
216
    virtual Value _getSolValue() const;
217

	
218
    ///\e
219
    virtual ProblemType _getType() const;
220

	
221
    ///\e
222
    virtual const char* _solverName() const;
223
  };
224

	
225
} //namespace lemon
226

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

	
19
#ifndef LEMON_MAX_MATCHING_H
20
#define LEMON_MAX_MATCHING_H
21

	
22
#include <vector>
23
#include <queue>
24
#include <set>
25
#include <limits>
26

	
27
#include <lemon/core.h>
28
#include <lemon/unionfind.h>
29
#include <lemon/bin_heap.h>
30
#include <lemon/maps.h>
31

	
32
///\ingroup matching
33
///\file
34
///\brief Maximum matching algorithms in general graphs.
35

	
36
namespace lemon {
37

	
38
  /// \ingroup matching
39
  ///
40
  /// \brief Maximum cardinality matching in general graphs
41
  ///
42
  /// This class implements Edmonds' alternating forest matching algorithm
43
  /// for finding a maximum cardinality matching in a general undirected graph.
44
  /// It can be started from an arbitrary initial matching 
45
  /// (the default is the empty one).
46
  ///
47
  /// The dual solution of the problem is a map of the nodes to
48
  /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D),
49
  /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds
50
  /// decomposition of the graph. The nodes in \c EVEN/D induce a subgraph
51
  /// with factor-critical components, the nodes in \c ODD/A form the
52
  /// canonical barrier, and the nodes in \c MATCHED/C induce a graph having
53
  /// a perfect matching. The number of the factor-critical components
54
  /// minus the number of barrier nodes is a lower bound on the
55
  /// unmatched nodes, and the matching is optimal if and only if this bound is
56
  /// tight. This decomposition can be obtained using \ref status() or
57
  /// \ref statusMap() after running the algorithm.
58
  ///
59
  /// \tparam GR The undirected graph type the algorithm runs on.
60
  template <typename GR>
61
  class MaxMatching {
62
  public:
63

	
64
    /// The graph type of the algorithm
65
    typedef GR Graph;
66
    /// The type of the matching map
67
    typedef typename Graph::template NodeMap<typename Graph::Arc>
68
    MatchingMap;
69

	
70
    ///\brief Status constants for Gallai-Edmonds decomposition.
71
    ///
72
    ///These constants are used for indicating the Gallai-Edmonds 
73
    ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
74
    ///induce a subgraph with factor-critical components, the nodes with
75
    ///status \c ODD (or \c A) form the canonical barrier, and the nodes
76
    ///with status \c MATCHED (or \c C) induce a subgraph having a 
77
    ///perfect matching.
78
    enum Status {
79
      EVEN = 1,       ///< = 1. (\c D is an alias for \c EVEN.)
80
      D = 1,
81
      MATCHED = 0,    ///< = 0. (\c C is an alias for \c MATCHED.)
82
      C = 0,
83
      ODD = -1,       ///< = -1. (\c A is an alias for \c ODD.)
84
      A = -1,
85
      UNMATCHED = -2  ///< = -2.
86
    };
87

	
88
    /// The type of the status map
89
    typedef typename Graph::template NodeMap<Status> StatusMap;
90

	
91
  private:
92

	
93
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
94

	
95
    typedef UnionFindEnum<IntNodeMap> BlossomSet;
96
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
97
    typedef RangeMap<Node> NodeIntMap;
98
    typedef MatchingMap EarMap;
99
    typedef std::vector<Node> NodeQueue;
100

	
101
    const Graph& _graph;
102
    MatchingMap* _matching;
103
    StatusMap* _status;
104

	
105
    EarMap* _ear;
106

	
107
    IntNodeMap* _blossom_set_index;
108
    BlossomSet* _blossom_set;
109
    NodeIntMap* _blossom_rep;
110

	
111
    IntNodeMap* _tree_set_index;
112
    TreeSet* _tree_set;
113

	
114
    NodeQueue _node_queue;
115
    int _process, _postpone, _last;
116

	
117
    int _node_num;
118

	
119
  private:
120

	
121
    void createStructures() {
122
      _node_num = countNodes(_graph);
123
      if (!_matching) {
124
        _matching = new MatchingMap(_graph);
125
      }
126
      if (!_status) {
127
        _status = new StatusMap(_graph);
128
      }
129
      if (!_ear) {
130
        _ear = new EarMap(_graph);
131
      }
132
      if (!_blossom_set) {
133
        _blossom_set_index = new IntNodeMap(_graph);
134
        _blossom_set = new BlossomSet(*_blossom_set_index);
135
      }
136
      if (!_blossom_rep) {
137
        _blossom_rep = new NodeIntMap(_node_num);
138
      }
139
      if (!_tree_set) {
140
        _tree_set_index = new IntNodeMap(_graph);
141
        _tree_set = new TreeSet(*_tree_set_index);
142
      }
143
      _node_queue.resize(_node_num);
144
    }
145

	
146
    void destroyStructures() {
147
      if (_matching) {
148
        delete _matching;
149
      }
150
      if (_status) {
151
        delete _status;
152
      }
153
      if (_ear) {
154
        delete _ear;
155
      }
156
      if (_blossom_set) {
157
        delete _blossom_set;
158
        delete _blossom_set_index;
159
      }
160
      if (_blossom_rep) {
161
        delete _blossom_rep;
162
      }
163
      if (_tree_set) {
164
        delete _tree_set_index;
165
        delete _tree_set;
166
      }
167
    }
168

	
169
    void processDense(const Node& n) {
170
      _process = _postpone = _last = 0;
171
      _node_queue[_last++] = n;
172

	
173
      while (_process != _last) {
174
        Node u = _node_queue[_process++];
175
        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
176
          Node v = _graph.target(a);
177
          if ((*_status)[v] == MATCHED) {
178
            extendOnArc(a);
179
          } else if ((*_status)[v] == UNMATCHED) {
180
            augmentOnArc(a);
181
            return;
182
          }
183
        }
184
      }
185

	
186
      while (_postpone != _last) {
187
        Node u = _node_queue[_postpone++];
188

	
189
        for (OutArcIt a(_graph, u); a != INVALID ; ++a) {
190
          Node v = _graph.target(a);
191

	
192
          if ((*_status)[v] == EVEN) {
193
            if (_blossom_set->find(u) != _blossom_set->find(v)) {
194
              shrinkOnEdge(a);
195
            }
196
          }
197

	
198
          while (_process != _last) {
199
            Node w = _node_queue[_process++];
200
            for (OutArcIt b(_graph, w); b != INVALID; ++b) {
201
              Node x = _graph.target(b);
202
              if ((*_status)[x] == MATCHED) {
203
                extendOnArc(b);
204
              } else if ((*_status)[x] == UNMATCHED) {
205
                augmentOnArc(b);
206
                return;
207
              }
208
            }
209
          }
210
        }
211
      }
212
    }
213

	
214
    void processSparse(const Node& n) {
215
      _process = _last = 0;
216
      _node_queue[_last++] = n;
217
      while (_process != _last) {
218
        Node u = _node_queue[_process++];
219
        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
220
          Node v = _graph.target(a);
221

	
222
          if ((*_status)[v] == EVEN) {
223
            if (_blossom_set->find(u) != _blossom_set->find(v)) {
224
              shrinkOnEdge(a);
225
            }
226
          } else if ((*_status)[v] == MATCHED) {
227
            extendOnArc(a);
228
          } else if ((*_status)[v] == UNMATCHED) {
229
            augmentOnArc(a);
230
            return;
231
          }
232
        }
233
      }
234
    }
235

	
236
    void shrinkOnEdge(const Edge& e) {
237
      Node nca = INVALID;
238

	
239
      {
240
        std::set<Node> left_set, right_set;
241

	
242
        Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))];
243
        left_set.insert(left);
244

	
245
        Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))];
246
        right_set.insert(right);
247

	
248
        while (true) {
249
          if ((*_matching)[left] == INVALID) break;
250
          left = _graph.target((*_matching)[left]);
251
          left = (*_blossom_rep)[_blossom_set->
252
                                 find(_graph.target((*_ear)[left]))];
253
          if (right_set.find(left) != right_set.end()) {
254
            nca = left;
255
            break;
256
          }
257
          left_set.insert(left);
258

	
259
          if ((*_matching)[right] == INVALID) break;
260
          right = _graph.target((*_matching)[right]);
261
          right = (*_blossom_rep)[_blossom_set->
262
                                  find(_graph.target((*_ear)[right]))];
263
          if (left_set.find(right) != left_set.end()) {
264
            nca = right;
265
            break;
266
          }
267
          right_set.insert(right);
268
        }
269

	
270
        if (nca == INVALID) {
271
          if ((*_matching)[left] == INVALID) {
272
            nca = right;
273
            while (left_set.find(nca) == left_set.end()) {
274
              nca = _graph.target((*_matching)[nca]);
275
              nca =(*_blossom_rep)[_blossom_set->
276
                                   find(_graph.target((*_ear)[nca]))];
277
            }
278
          } else {
279
            nca = left;
280
            while (right_set.find(nca) == right_set.end()) {
281
              nca = _graph.target((*_matching)[nca]);
282
              nca = (*_blossom_rep)[_blossom_set->
283
                                   find(_graph.target((*_ear)[nca]))];
284
            }
285
          }
286
        }
287
      }
288

	
289
      {
290

	
291
        Node node = _graph.u(e);
292
        Arc arc = _graph.direct(e, true);
293
        Node base = (*_blossom_rep)[_blossom_set->find(node)];
294

	
295
        while (base != nca) {
296
          (*_ear)[node] = arc;
297

	
298
          Node n = node;
299
          while (n != base) {
300
            n = _graph.target((*_matching)[n]);
301
            Arc a = (*_ear)[n];
302
            n = _graph.target(a);
303
            (*_ear)[n] = _graph.oppositeArc(a);
304
          }
305
          node = _graph.target((*_matching)[base]);
306
          _tree_set->erase(base);
307
          _tree_set->erase(node);
308
          _blossom_set->insert(node, _blossom_set->find(base));
309
          (*_status)[node] = EVEN;
310
          _node_queue[_last++] = node;
311
          arc = _graph.oppositeArc((*_ear)[node]);
312
          node = _graph.target((*_ear)[node]);
313
          base = (*_blossom_rep)[_blossom_set->find(node)];
314
          _blossom_set->join(_graph.target(arc), base);
315
        }
316
      }
317

	
318
      (*_blossom_rep)[_blossom_set->find(nca)] = nca;
319

	
320
      {
321

	
322
        Node node = _graph.v(e);
323
        Arc arc = _graph.direct(e, false);
324
        Node base = (*_blossom_rep)[_blossom_set->find(node)];
325

	
326
        while (base != nca) {
327
          (*_ear)[node] = arc;
328

	
329
          Node n = node;
330
          while (n != base) {
331
            n = _graph.target((*_matching)[n]);
332
            Arc a = (*_ear)[n];
333
            n = _graph.target(a);
334
            (*_ear)[n] = _graph.oppositeArc(a);
335
          }
336
          node = _graph.target((*_matching)[base]);
337
          _tree_set->erase(base);
338
          _tree_set->erase(node);
339
          _blossom_set->insert(node, _blossom_set->find(base));
340
          (*_status)[node] = EVEN;
341
          _node_queue[_last++] = node;
342
          arc = _graph.oppositeArc((*_ear)[node]);
343
          node = _graph.target((*_ear)[node]);
344
          base = (*_blossom_rep)[_blossom_set->find(node)];
345
          _blossom_set->join(_graph.target(arc), base);
346
        }
347
      }
348

	
349
      (*_blossom_rep)[_blossom_set->find(nca)] = nca;
350
    }
351

	
352
    void extendOnArc(const Arc& a) {
353
      Node base = _graph.source(a);
354
      Node odd = _graph.target(a);
355

	
356
      (*_ear)[odd] = _graph.oppositeArc(a);
357
      Node even = _graph.target((*_matching)[odd]);
358
      (*_blossom_rep)[_blossom_set->insert(even)] = even;
359
      (*_status)[odd] = ODD;
360
      (*_status)[even] = EVEN;
361
      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]);
362
      _tree_set->insert(odd, tree);
363
      _tree_set->insert(even, tree);
364
      _node_queue[_last++] = even;
365

	
366
    }
367

	
368
    void augmentOnArc(const Arc& a) {
369
      Node even = _graph.source(a);
370
      Node odd = _graph.target(a);
371

	
372
      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]);
373

	
374
      (*_matching)[odd] = _graph.oppositeArc(a);
375
      (*_status)[odd] = MATCHED;
376

	
377
      Arc arc = (*_matching)[even];
378
      (*_matching)[even] = a;
379

	
380
      while (arc != INVALID) {
381
        odd = _graph.target(arc);
382
        arc = (*_ear)[odd];
383
        even = _graph.target(arc);
384
        (*_matching)[odd] = arc;
385
        arc = (*_matching)[even];
386
        (*_matching)[even] = _graph.oppositeArc((*_matching)[odd]);
387
      }
388

	
389
      for (typename TreeSet::ItemIt it(*_tree_set, tree);
390
           it != INVALID; ++it) {
391
        if ((*_status)[it] == ODD) {
392
          (*_status)[it] = MATCHED;
393
        } else {
394
          int blossom = _blossom_set->find(it);
395
          for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
396
               jt != INVALID; ++jt) {
397
            (*_status)[jt] = MATCHED;
398
          }
399
          _blossom_set->eraseClass(blossom);
400
        }
401
      }
402
      _tree_set->eraseClass(tree);
403

	
404
    }
405

	
406
  public:
407

	
408
    /// \brief Constructor
409
    ///
410
    /// Constructor.
411
    MaxMatching(const Graph& graph)
412
      : _graph(graph), _matching(0), _status(0), _ear(0),
413
        _blossom_set_index(0), _blossom_set(0), _blossom_rep(0),
414
        _tree_set_index(0), _tree_set(0) {}
415

	
416
    ~MaxMatching() {
417
      destroyStructures();
418
    }
419

	
420
    /// \name Execution Control
421
    /// The simplest way to execute the algorithm is to use the
422
    /// \c run() member function.\n
423
    /// If you need better control on the execution, you have to call
424
    /// one of the functions \ref init(), \ref greedyInit() or
425
    /// \ref matchingInit() first, then you can start the algorithm with
426
    /// \ref startSparse() or \ref startDense().
427

	
428
    ///@{
429

	
430
    /// \brief Set the initial matching to the empty matching.
431
    ///
432
    /// This function sets the initial matching to the empty matching.
433
    void init() {
434
      createStructures();
435
      for(NodeIt n(_graph); n != INVALID; ++n) {
436
        (*_matching)[n] = INVALID;
437
        (*_status)[n] = UNMATCHED;
438
      }
439
    }
440

	
441
    /// \brief Find an initial matching in a greedy way.
442
    ///
443
    /// This function finds an initial matching in a greedy way.
444
    void greedyInit() {
445
      createStructures();
446
      for (NodeIt n(_graph); n != INVALID; ++n) {
447
        (*_matching)[n] = INVALID;
448
        (*_status)[n] = UNMATCHED;
449
      }
450
      for (NodeIt n(_graph); n != INVALID; ++n) {
451
        if ((*_matching)[n] == INVALID) {
452
          for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
453
            Node v = _graph.target(a);
454
            if ((*_matching)[v] == INVALID && v != n) {
455
              (*_matching)[n] = a;
456
              (*_status)[n] = MATCHED;
457
              (*_matching)[v] = _graph.oppositeArc(a);
458
              (*_status)[v] = MATCHED;
459
              break;
460
            }
461
          }
462
        }
463
      }
464
    }
465

	
466

	
467
    /// \brief Initialize the matching from a map.
468
    ///
469
    /// This function initializes the matching from a \c bool valued edge
470
    /// map. This map should have the property that there are no two incident
471
    /// edges with \c true value, i.e. it really contains a matching.
472
    /// \return \c true if the map contains a matching.
473
    template <typename MatchingMap>
474
    bool matchingInit(const MatchingMap& matching) {
475
      createStructures();
476

	
477
      for (NodeIt n(_graph); n != INVALID; ++n) {
478
        (*_matching)[n] = INVALID;
479
        (*_status)[n] = UNMATCHED;
480
      }
481
      for(EdgeIt e(_graph); e!=INVALID; ++e) {
482
        if (matching[e]) {
483

	
484
          Node u = _graph.u(e);
485
          if ((*_matching)[u] != INVALID) return false;
486
          (*_matching)[u] = _graph.direct(e, true);
487
          (*_status)[u] = MATCHED;
488

	
489
          Node v = _graph.v(e);
490
          if ((*_matching)[v] != INVALID) return false;
491
          (*_matching)[v] = _graph.direct(e, false);
492
          (*_status)[v] = MATCHED;
493
        }
494
      }
495
      return true;
496
    }
497

	
498
    /// \brief Start Edmonds' algorithm
499
    ///
500
    /// This function runs the original Edmonds' algorithm.
501
    ///
502
    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
503
    /// called before using this function.
504
    void startSparse() {
505
      for(NodeIt n(_graph); n != INVALID; ++n) {
506
        if ((*_status)[n] == UNMATCHED) {
507
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
508
          _tree_set->insert(n);
509
          (*_status)[n] = EVEN;
510
          processSparse(n);
511
        }
512
      }
513
    }
514

	
515
    /// \brief Start Edmonds' algorithm with a heuristic improvement 
516
    /// for dense graphs
517
    ///
518
    /// This function runs Edmonds' algorithm with a heuristic of postponing
519
    /// shrinks, therefore resulting in a faster algorithm for dense graphs.
520
    ///
521
    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
522
    /// called before using this function.
523
    void startDense() {
524
      for(NodeIt n(_graph); n != INVALID; ++n) {
525
        if ((*_status)[n] == UNMATCHED) {
526
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
527
          _tree_set->insert(n);
528
          (*_status)[n] = EVEN;
529
          processDense(n);
530
        }
531
      }
532
    }
533

	
534

	
535
    /// \brief Run Edmonds' algorithm
536
    ///
537
    /// This function runs Edmonds' algorithm. An additional heuristic of 
538
    /// postponing shrinks is used for relatively dense graphs 
539
    /// (for which <tt>m>=2*n</tt> holds).
540
    void run() {
541
      if (countEdges(_graph) < 2 * countNodes(_graph)) {
542
        greedyInit();
543
        startSparse();
544
      } else {
545
        init();
546
        startDense();
547
      }
548
    }
549

	
550
    /// @}
551

	
552
    /// \name Primal Solution
553
    /// Functions to get the primal solution, i.e. the maximum matching.
554

	
555
    /// @{
556

	
557
    /// \brief Return the size (cardinality) of the matching.
558
    ///
559
    /// This function returns the size (cardinality) of the current matching. 
560
    /// After run() it returns the size of the maximum matching in the graph.
561
    int matchingSize() const {
562
      int size = 0;
563
      for (NodeIt n(_graph); n != INVALID; ++n) {
564
        if ((*_matching)[n] != INVALID) {
565
          ++size;
566
        }
567
      }
568
      return size / 2;
569
    }
570

	
571
    /// \brief Return \c true if the given edge is in the matching.
572
    ///
573
    /// This function returns \c true if the given edge is in the current 
574
    /// matching.
575
    bool matching(const Edge& edge) const {
576
      return edge == (*_matching)[_graph.u(edge)];
577
    }
578

	
579
    /// \brief Return the matching arc (or edge) incident to the given node.
580
    ///
581
    /// This function returns the matching arc (or edge) incident to the
582
    /// given node in the current matching or \c INVALID if the node is 
583
    /// not covered by the matching.
584
    Arc matching(const Node& n) const {
585
      return (*_matching)[n];
586
    }
587

	
588
    /// \brief Return a const reference to the matching map.
589
    ///
590
    /// This function returns a const reference to a node map that stores
591
    /// the matching arc (or edge) incident to each node.
592
    const MatchingMap& matchingMap() const {
593
      return *_matching;
594
    }
595

	
596
    /// \brief Return the mate of the given node.
597
    ///
598
    /// This function returns the mate of the given node in the current 
599
    /// matching or \c INVALID if the node is not covered by the matching.
600
    Node mate(const Node& n) const {
601
      return (*_matching)[n] != INVALID ?
602
        _graph.target((*_matching)[n]) : INVALID;
603
    }
604

	
605
    /// @}
606

	
607
    /// \name Dual Solution
608
    /// Functions to get the dual solution, i.e. the Gallai-Edmonds 
609
    /// decomposition.
610

	
611
    /// @{
612

	
613
    /// \brief Return the status of the given node in the Edmonds-Gallai
614
    /// decomposition.
615
    ///
616
    /// This function returns the \ref Status "status" of the given node
617
    /// in the Edmonds-Gallai decomposition.
618
    Status status(const Node& n) const {
619
      return (*_status)[n];
620
    }
621

	
622
    /// \brief Return a const reference to the status map, which stores
623
    /// the Edmonds-Gallai decomposition.
624
    ///
625
    /// This function returns a const reference to a node map that stores the
626
    /// \ref Status "status" of each node in the Edmonds-Gallai decomposition.
627
    const StatusMap& statusMap() const {
628
      return *_status;
629
    }
630

	
631
    /// \brief Return \c true if the given node is in the barrier.
632
    ///
633
    /// This function returns \c true if the given node is in the barrier.
634
    bool barrier(const Node& n) const {
635
      return (*_status)[n] == ODD;
636
    }
637

	
638
    /// @}
639

	
640
  };
641

	
642
  /// \ingroup matching
643
  ///
644
  /// \brief Weighted matching in general graphs
645
  ///
646
  /// This class provides an efficient implementation of Edmond's
647
  /// maximum weighted matching algorithm. The implementation is based
648
  /// on extensive use of priority queues and provides
649
  /// \f$O(nm\log n)\f$ time complexity.
650
  ///
651
  /// The maximum weighted matching problem is to find a subset of the 
652
  /// edges in an undirected graph with maximum overall weight for which 
653
  /// each node has at most one incident edge.
654
  /// It can be formulated with the following linear program.
655
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
656
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
657
      \quad \forall B\in\mathcal{O}\f] */
658
  /// \f[x_e \ge 0\quad \forall e\in E\f]
659
  /// \f[\max \sum_{e\in E}x_ew_e\f]
660
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
661
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
662
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
663
  /// subsets of the nodes.
664
  ///
665
  /// The algorithm calculates an optimal matching and a proof of the
666
  /// optimality. The solution of the dual problem can be used to check
667
  /// the result of the algorithm. The dual linear problem is the
668
  /// following.
669
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
670
      z_B \ge w_{uv} \quad \forall uv\in E\f] */
671
  /// \f[y_u \ge 0 \quad \forall u \in V\f]
672
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
673
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
674
      \frac{\vert B \vert - 1}{2}z_B\f] */
675
  ///
676
  /// The algorithm can be executed with the run() function. 
677
  /// After it the matching (the primal solution) and the dual solution
678
  /// can be obtained using the query functions and the 
679
  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, 
680
  /// which is able to iterate on the nodes of a blossom. 
681
  /// If the value type is integer, then the dual solution is multiplied
682
  /// by \ref MaxWeightedMatching::dualScale "4".
683
  ///
684
  /// \tparam GR The undirected graph type the algorithm runs on.
685
  /// \tparam WM The type edge weight map. The default type is 
686
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
687
#ifdef DOXYGEN
688
  template <typename GR, typename WM>
689
#else
690
  template <typename GR,
691
            typename WM = typename GR::template EdgeMap<int> >
692
#endif
693
  class MaxWeightedMatching {
694
  public:
695

	
696
    /// The graph type of the algorithm
697
    typedef GR Graph;
698
    /// The type of the edge weight map
699
    typedef WM WeightMap;
700
    /// The value type of the edge weights
701
    typedef typename WeightMap::Value Value;
702

	
703
    /// The type of the matching map
704
    typedef typename Graph::template NodeMap<typename Graph::Arc>
705
    MatchingMap;
706

	
707
    /// \brief Scaling factor for dual solution
708
    ///
709
    /// Scaling factor for dual solution. It is equal to 4 or 1
710
    /// according to the value type.
711
    static const int dualScale =
712
      std::numeric_limits<Value>::is_integer ? 4 : 1;
713

	
714
  private:
715

	
716
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
717

	
718
    typedef typename Graph::template NodeMap<Value> NodePotential;
719
    typedef std::vector<Node> BlossomNodeList;
720

	
721
    struct BlossomVariable {
722
      int begin, end;
723
      Value value;
724

	
725
      BlossomVariable(int _begin, int _end, Value _value)
726
        : begin(_begin), end(_end), value(_value) {}
727

	
728
    };
729

	
730
    typedef std::vector<BlossomVariable> BlossomPotential;
731

	
732
    const Graph& _graph;
733
    const WeightMap& _weight;
734

	
735
    MatchingMap* _matching;
736

	
737
    NodePotential* _node_potential;
738

	
739
    BlossomPotential _blossom_potential;
740
    BlossomNodeList _blossom_node_list;
741

	
742
    int _node_num;
743
    int _blossom_num;
744

	
745
    typedef RangeMap<int> IntIntMap;
746

	
747
    enum Status {
748
      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
749
    };
750

	
751
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
752
    struct BlossomData {
753
      int tree;
754
      Status status;
755
      Arc pred, next;
756
      Value pot, offset;
757
      Node base;
758
    };
759

	
760
    IntNodeMap *_blossom_index;
761
    BlossomSet *_blossom_set;
762
    RangeMap<BlossomData>* _blossom_data;
763

	
764
    IntNodeMap *_node_index;
765
    IntArcMap *_node_heap_index;
766

	
767
    struct NodeData {
768

	
769
      NodeData(IntArcMap& node_heap_index)
770
        : heap(node_heap_index) {}
771

	
772
      int blossom;
773
      Value pot;
774
      BinHeap<Value, IntArcMap> heap;
775
      std::map<int, Arc> heap_index;
776

	
777
      int tree;
778
    };
779

	
780
    RangeMap<NodeData>* _node_data;
781

	
782
    typedef ExtendFindEnum<IntIntMap> TreeSet;
783

	
784
    IntIntMap *_tree_set_index;
785
    TreeSet *_tree_set;
786

	
787
    IntNodeMap *_delta1_index;
788
    BinHeap<Value, IntNodeMap> *_delta1;
789

	
790
    IntIntMap *_delta2_index;
791
    BinHeap<Value, IntIntMap> *_delta2;
792

	
793
    IntEdgeMap *_delta3_index;
794
    BinHeap<Value, IntEdgeMap> *_delta3;
795

	
796
    IntIntMap *_delta4_index;
797
    BinHeap<Value, IntIntMap> *_delta4;
798

	
799
    Value _delta_sum;
800

	
801
    void createStructures() {
802
      _node_num = countNodes(_graph);
803
      _blossom_num = _node_num * 3 / 2;
804

	
805
      if (!_matching) {
806
        _matching = new MatchingMap(_graph);
807
      }
808
      if (!_node_potential) {
809
        _node_potential = new NodePotential(_graph);
810
      }
811
      if (!_blossom_set) {
812
        _blossom_index = new IntNodeMap(_graph);
813
        _blossom_set = new BlossomSet(*_blossom_index);
814
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
815
      }
816

	
817
      if (!_node_index) {
818
        _node_index = new IntNodeMap(_graph);
819
        _node_heap_index = new IntArcMap(_graph);
820
        _node_data = new RangeMap<NodeData>(_node_num,
821
                                              NodeData(*_node_heap_index));
822
      }
823

	
824
      if (!_tree_set) {
825
        _tree_set_index = new IntIntMap(_blossom_num);
826
        _tree_set = new TreeSet(*_tree_set_index);
827
      }
828
      if (!_delta1) {
829
        _delta1_index = new IntNodeMap(_graph);
830
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
831
      }
832
      if (!_delta2) {
833
        _delta2_index = new IntIntMap(_blossom_num);
834
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
835
      }
836
      if (!_delta3) {
837
        _delta3_index = new IntEdgeMap(_graph);
838
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
839
      }
840
      if (!_delta4) {
841
        _delta4_index = new IntIntMap(_blossom_num);
842
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
843
      }
844
    }
845

	
846
    void destroyStructures() {
847
      _node_num = countNodes(_graph);
848
      _blossom_num = _node_num * 3 / 2;
849

	
850
      if (_matching) {
851
        delete _matching;
852
      }
853
      if (_node_potential) {
854
        delete _node_potential;
855
      }
856
      if (_blossom_set) {
857
        delete _blossom_index;
858
        delete _blossom_set;
859
        delete _blossom_data;
860
      }
861

	
862
      if (_node_index) {
863
        delete _node_index;
864
        delete _node_heap_index;
865
        delete _node_data;
866
      }
867

	
868
      if (_tree_set) {
869
        delete _tree_set_index;
870
        delete _tree_set;
871
      }
872
      if (_delta1) {
873
        delete _delta1_index;
874
        delete _delta1;
875
      }
876
      if (_delta2) {
877
        delete _delta2_index;
878
        delete _delta2;
879
      }
880
      if (_delta3) {
881
        delete _delta3_index;
882
        delete _delta3;
883
      }
884
      if (_delta4) {
885
        delete _delta4_index;
886
        delete _delta4;
887
      }
888
    }
889

	
890
    void matchedToEven(int blossom, int tree) {
891
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
892
        _delta2->erase(blossom);
893
      }
894

	
895
      if (!_blossom_set->trivial(blossom)) {
896
        (*_blossom_data)[blossom].pot -=
897
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
898
      }
899

	
900
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
901
           n != INVALID; ++n) {
902

	
903
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
904
        int ni = (*_node_index)[n];
905

	
906
        (*_node_data)[ni].heap.clear();
907
        (*_node_data)[ni].heap_index.clear();
908

	
909
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
910

	
911
        _delta1->push(n, (*_node_data)[ni].pot);
912

	
913
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
914
          Node v = _graph.source(e);
915
          int vb = _blossom_set->find(v);
916
          int vi = (*_node_index)[v];
917

	
918
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
919
            dualScale * _weight[e];
920

	
921
          if ((*_blossom_data)[vb].status == EVEN) {
922
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
923
              _delta3->push(e, rw / 2);
924
            }
925
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
926
            if (_delta3->state(e) != _delta3->IN_HEAP) {
927
              _delta3->push(e, rw);
928
            }
929
          } else {
930
            typename std::map<int, Arc>::iterator it =
931
              (*_node_data)[vi].heap_index.find(tree);
932

	
933
            if (it != (*_node_data)[vi].heap_index.end()) {
934
              if ((*_node_data)[vi].heap[it->second] > rw) {
935
                (*_node_data)[vi].heap.replace(it->second, e);
936
                (*_node_data)[vi].heap.decrease(e, rw);
937
                it->second = e;
938
              }
939
            } else {
940
              (*_node_data)[vi].heap.push(e, rw);
941
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
942
            }
943

	
944
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
945
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
946

	
947
              if ((*_blossom_data)[vb].status == MATCHED) {
948
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
949
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
950
                               (*_blossom_data)[vb].offset);
951
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
952
                           (*_blossom_data)[vb].offset){
953
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
954
                                   (*_blossom_data)[vb].offset);
955
                }
956
              }
957
            }
958
          }
959
        }
960
      }
961
      (*_blossom_data)[blossom].offset = 0;
962
    }
963

	
964
    void matchedToOdd(int blossom) {
965
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
966
        _delta2->erase(blossom);
967
      }
968
      (*_blossom_data)[blossom].offset += _delta_sum;
969
      if (!_blossom_set->trivial(blossom)) {
970
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
971
                     (*_blossom_data)[blossom].offset);
972
      }
973
    }
974

	
975
    void evenToMatched(int blossom, int tree) {
976
      if (!_blossom_set->trivial(blossom)) {
977
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
978
      }
979

	
980
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
981
           n != INVALID; ++n) {
982
        int ni = (*_node_index)[n];
983
        (*_node_data)[ni].pot -= _delta_sum;
984

	
985
        _delta1->erase(n);
986

	
987
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
988
          Node v = _graph.source(e);
989
          int vb = _blossom_set->find(v);
990
          int vi = (*_node_index)[v];
991

	
992
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
993
            dualScale * _weight[e];
994

	
995
          if (vb == blossom) {
996
            if (_delta3->state(e) == _delta3->IN_HEAP) {
997
              _delta3->erase(e);
998
            }
999
          } else if ((*_blossom_data)[vb].status == EVEN) {
1000

	
1001
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1002
              _delta3->erase(e);
1003
            }
1004

	
1005
            int vt = _tree_set->find(vb);
1006

	
1007
            if (vt != tree) {
1008

	
1009
              Arc r = _graph.oppositeArc(e);
1010

	
1011
              typename std::map<int, Arc>::iterator it =
1012
                (*_node_data)[ni].heap_index.find(vt);
1013

	
1014
              if (it != (*_node_data)[ni].heap_index.end()) {
1015
                if ((*_node_data)[ni].heap[it->second] > rw) {
1016
                  (*_node_data)[ni].heap.replace(it->second, r);
1017
                  (*_node_data)[ni].heap.decrease(r, rw);
1018
                  it->second = r;
1019
                }
1020
              } else {
1021
                (*_node_data)[ni].heap.push(r, rw);
1022
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1023
              }
1024

	
1025
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1026
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1027

	
1028
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1029
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1030
                               (*_blossom_data)[blossom].offset);
1031
                } else if ((*_delta2)[blossom] >
1032
                           _blossom_set->classPrio(blossom) -
1033
                           (*_blossom_data)[blossom].offset){
1034
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1035
                                   (*_blossom_data)[blossom].offset);
1036
                }
1037
              }
1038
            }
1039

	
1040
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1041
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1042
              _delta3->erase(e);
1043
            }
1044
          } else {
1045

	
1046
            typename std::map<int, Arc>::iterator it =
1047
              (*_node_data)[vi].heap_index.find(tree);
1048

	
1049
            if (it != (*_node_data)[vi].heap_index.end()) {
1050
              (*_node_data)[vi].heap.erase(it->second);
1051
              (*_node_data)[vi].heap_index.erase(it);
1052
              if ((*_node_data)[vi].heap.empty()) {
1053
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
1054
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
1055
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
1056
              }
1057

	
1058
              if ((*_blossom_data)[vb].status == MATCHED) {
1059
                if (_blossom_set->classPrio(vb) ==
1060
                    std::numeric_limits<Value>::max()) {
1061
                  _delta2->erase(vb);
1062
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
1063
                           (*_blossom_data)[vb].offset) {
1064
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
1065
                                   (*_blossom_data)[vb].offset);
1066
                }
1067
              }
1068
            }
1069
          }
1070
        }
1071
      }
1072
    }
1073

	
1074
    void oddToMatched(int blossom) {
1075
      (*_blossom_data)[blossom].offset -= _delta_sum;
1076

	
1077
      if (_blossom_set->classPrio(blossom) !=
1078
          std::numeric_limits<Value>::max()) {
1079
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1080
                       (*_blossom_data)[blossom].offset);
1081
      }
1082

	
1083
      if (!_blossom_set->trivial(blossom)) {
1084
        _delta4->erase(blossom);
1085
      }
1086
    }
1087

	
1088
    void oddToEven(int blossom, int tree) {
1089
      if (!_blossom_set->trivial(blossom)) {
1090
        _delta4->erase(blossom);
1091
        (*_blossom_data)[blossom].pot -=
1092
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
1093
      }
1094

	
1095
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1096
           n != INVALID; ++n) {
1097
        int ni = (*_node_index)[n];
1098

	
1099
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1100

	
1101
        (*_node_data)[ni].heap.clear();
1102
        (*_node_data)[ni].heap_index.clear();
1103
        (*_node_data)[ni].pot +=
1104
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
1105

	
1106
        _delta1->push(n, (*_node_data)[ni].pot);
1107

	
1108
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1109
          Node v = _graph.source(e);
1110
          int vb = _blossom_set->find(v);
1111
          int vi = (*_node_index)[v];
1112

	
1113
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1114
            dualScale * _weight[e];
1115

	
1116
          if ((*_blossom_data)[vb].status == EVEN) {
1117
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
1118
              _delta3->push(e, rw / 2);
1119
            }
1120
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1121
            if (_delta3->state(e) != _delta3->IN_HEAP) {
1122
              _delta3->push(e, rw);
1123
            }
1124
          } else {
1125

	
1126
            typename std::map<int, Arc>::iterator it =
1127
              (*_node_data)[vi].heap_index.find(tree);
1128

	
1129
            if (it != (*_node_data)[vi].heap_index.end()) {
1130
              if ((*_node_data)[vi].heap[it->second] > rw) {
1131
                (*_node_data)[vi].heap.replace(it->second, e);
1132
                (*_node_data)[vi].heap.decrease(e, rw);
1133
                it->second = e;
1134
              }
1135
            } else {
1136
              (*_node_data)[vi].heap.push(e, rw);
1137
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
1138
            }
1139

	
1140
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
1141
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
1142

	
1143
              if ((*_blossom_data)[vb].status == MATCHED) {
1144
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
1145
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
1146
                               (*_blossom_data)[vb].offset);
1147
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
1148
                           (*_blossom_data)[vb].offset) {
1149
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
1150
                                   (*_blossom_data)[vb].offset);
1151
                }
1152
              }
1153
            }
1154
          }
1155
        }
1156
      }
1157
      (*_blossom_data)[blossom].offset = 0;
1158
    }
1159

	
1160

	
1161
    void matchedToUnmatched(int blossom) {
1162
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
1163
        _delta2->erase(blossom);
1164
      }
1165

	
1166
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1167
           n != INVALID; ++n) {
1168
        int ni = (*_node_index)[n];
1169

	
1170
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1171

	
1172
        (*_node_data)[ni].heap.clear();
1173
        (*_node_data)[ni].heap_index.clear();
1174

	
1175
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1176
          Node v = _graph.target(e);
1177
          int vb = _blossom_set->find(v);
1178
          int vi = (*_node_index)[v];
1179

	
1180
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1181
            dualScale * _weight[e];
1182

	
1183
          if ((*_blossom_data)[vb].status == EVEN) {
1184
            if (_delta3->state(e) != _delta3->IN_HEAP) {
1185
              _delta3->push(e, rw);
1186
            }
1187
          }
1188
        }
1189
      }
1190
    }
1191

	
1192
    void unmatchedToMatched(int blossom) {
1193
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1194
           n != INVALID; ++n) {
1195
        int ni = (*_node_index)[n];
1196

	
1197
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1198
          Node v = _graph.source(e);
1199
          int vb = _blossom_set->find(v);
1200
          int vi = (*_node_index)[v];
1201

	
1202
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1203
            dualScale * _weight[e];
1204

	
1205
          if (vb == blossom) {
1206
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1207
              _delta3->erase(e);
1208
            }
1209
          } else if ((*_blossom_data)[vb].status == EVEN) {
1210

	
1211
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1212
              _delta3->erase(e);
1213
            }
1214

	
1215
            int vt = _tree_set->find(vb);
1216

	
1217
            Arc r = _graph.oppositeArc(e);
1218

	
1219
            typename std::map<int, Arc>::iterator it =
1220
              (*_node_data)[ni].heap_index.find(vt);
1221

	
1222
            if (it != (*_node_data)[ni].heap_index.end()) {
1223
              if ((*_node_data)[ni].heap[it->second] > rw) {
1224
                (*_node_data)[ni].heap.replace(it->second, r);
1225
                (*_node_data)[ni].heap.decrease(r, rw);
1226
                it->second = r;
1227
              }
1228
            } else {
1229
              (*_node_data)[ni].heap.push(r, rw);
1230
              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1231
            }
1232

	
1233
            if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1234
              _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1235

	
1236
              if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1237
                _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1238
                             (*_blossom_data)[blossom].offset);
1239
              } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
1240
                         (*_blossom_data)[blossom].offset){
1241
                _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1242
                                 (*_blossom_data)[blossom].offset);
1243
              }
1244
            }
1245

	
1246
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1247
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1248
              _delta3->erase(e);
1249
            }
1250
          }
1251
        }
1252
      }
1253
    }
1254

	
1255
    void alternatePath(int even, int tree) {
1256
      int odd;
1257

	
1258
      evenToMatched(even, tree);
1259
      (*_blossom_data)[even].status = MATCHED;
1260

	
1261
      while ((*_blossom_data)[even].pred != INVALID) {
1262
        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
1263
        (*_blossom_data)[odd].status = MATCHED;
1264
        oddToMatched(odd);
1265
        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
1266

	
1267
        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
1268
        (*_blossom_data)[even].status = MATCHED;
1269
        evenToMatched(even, tree);
1270
        (*_blossom_data)[even].next =
1271
          _graph.oppositeArc((*_blossom_data)[odd].pred);
1272
      }
1273

	
1274
    }
1275

	
1276
    void destroyTree(int tree) {
1277
      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
1278
        if ((*_blossom_data)[b].status == EVEN) {
1279
          (*_blossom_data)[b].status = MATCHED;
1280
          evenToMatched(b, tree);
1281
        } else if ((*_blossom_data)[b].status == ODD) {
1282
          (*_blossom_data)[b].status = MATCHED;
1283
          oddToMatched(b);
1284
        }
1285
      }
1286
      _tree_set->eraseClass(tree);
1287
    }
1288

	
1289

	
1290
    void unmatchNode(const Node& node) {
1291
      int blossom = _blossom_set->find(node);
1292
      int tree = _tree_set->find(blossom);
1293

	
1294
      alternatePath(blossom, tree);
1295
      destroyTree(tree);
1296

	
1297
      (*_blossom_data)[blossom].status = UNMATCHED;
1298
      (*_blossom_data)[blossom].base = node;
1299
      matchedToUnmatched(blossom);
1300
    }
1301

	
1302

	
1303
    void augmentOnEdge(const Edge& edge) {
1304

	
1305
      int left = _blossom_set->find(_graph.u(edge));
1306
      int right = _blossom_set->find(_graph.v(edge));
1307

	
1308
      if ((*_blossom_data)[left].status == EVEN) {
1309
        int left_tree = _tree_set->find(left);
1310
        alternatePath(left, left_tree);
1311
        destroyTree(left_tree);
1312
      } else {
1313
        (*_blossom_data)[left].status = MATCHED;
1314
        unmatchedToMatched(left);
1315
      }
1316

	
1317
      if ((*_blossom_data)[right].status == EVEN) {
1318
        int right_tree = _tree_set->find(right);
1319
        alternatePath(right, right_tree);
1320
        destroyTree(right_tree);
1321
      } else {
1322
        (*_blossom_data)[right].status = MATCHED;
1323
        unmatchedToMatched(right);
1324
      }
1325

	
1326
      (*_blossom_data)[left].next = _graph.direct(edge, true);
1327
      (*_blossom_data)[right].next = _graph.direct(edge, false);
1328
    }
1329

	
1330
    void extendOnArc(const Arc& arc) {
1331
      int base = _blossom_set->find(_graph.target(arc));
1332
      int tree = _tree_set->find(base);
1333

	
1334
      int odd = _blossom_set->find(_graph.source(arc));
1335
      _tree_set->insert(odd, tree);
1336
      (*_blossom_data)[odd].status = ODD;
1337
      matchedToOdd(odd);
1338
      (*_blossom_data)[odd].pred = arc;
1339

	
1340
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
1341
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
1342
      _tree_set->insert(even, tree);
1343
      (*_blossom_data)[even].status = EVEN;
1344
      matchedToEven(even, tree);
1345
    }
1346

	
1347
    void shrinkOnEdge(const Edge& edge, int tree) {
1348
      int nca = -1;
1349
      std::vector<int> left_path, right_path;
1350

	
1351
      {
1352
        std::set<int> left_set, right_set;
1353
        int left = _blossom_set->find(_graph.u(edge));
1354
        left_path.push_back(left);
1355
        left_set.insert(left);
1356

	
1357
        int right = _blossom_set->find(_graph.v(edge));
1358
        right_path.push_back(right);
1359
        right_set.insert(right);
1360

	
1361
        while (true) {
1362

	
1363
          if ((*_blossom_data)[left].pred == INVALID) break;
1364

	
1365
          left =
1366
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
1367
          left_path.push_back(left);
1368
          left =
1369
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
1370
          left_path.push_back(left);
1371

	
1372
          left_set.insert(left);
1373

	
1374
          if (right_set.find(left) != right_set.end()) {
1375
            nca = left;
1376
            break;
1377
          }
1378

	
1379
          if ((*_blossom_data)[right].pred == INVALID) break;
1380

	
1381
          right =
1382
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
1383
          right_path.push_back(right);
1384
          right =
1385
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
1386
          right_path.push_back(right);
1387

	
1388
          right_set.insert(right);
1389

	
1390
          if (left_set.find(right) != left_set.end()) {
1391
            nca = right;
1392
            break;
1393
          }
1394

	
1395
        }
1396

	
1397
        if (nca == -1) {
1398
          if ((*_blossom_data)[left].pred == INVALID) {
1399
            nca = right;
1400
            while (left_set.find(nca) == left_set.end()) {
1401
              nca =
1402
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1403
              right_path.push_back(nca);
1404
              nca =
1405
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1406
              right_path.push_back(nca);
1407
            }
1408
          } else {
1409
            nca = left;
1410
            while (right_set.find(nca) == right_set.end()) {
1411
              nca =
1412
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1413
              left_path.push_back(nca);
1414
              nca =
1415
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1416
              left_path.push_back(nca);
1417
            }
1418
          }
1419
        }
1420
      }
1421

	
1422
      std::vector<int> subblossoms;
1423
      Arc prev;
1424

	
1425
      prev = _graph.direct(edge, true);
1426
      for (int i = 0; left_path[i] != nca; i += 2) {
1427
        subblossoms.push_back(left_path[i]);
1428
        (*_blossom_data)[left_path[i]].next = prev;
1429
        _tree_set->erase(left_path[i]);
1430

	
1431
        subblossoms.push_back(left_path[i + 1]);
1432
        (*_blossom_data)[left_path[i + 1]].status = EVEN;
1433
        oddToEven(left_path[i + 1], tree);
1434
        _tree_set->erase(left_path[i + 1]);
1435
        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
1436
      }
1437

	
1438
      int k = 0;
1439
      while (right_path[k] != nca) ++k;
1440

	
1441
      subblossoms.push_back(nca);
1442
      (*_blossom_data)[nca].next = prev;
1443

	
1444
      for (int i = k - 2; i >= 0; i -= 2) {
1445
        subblossoms.push_back(right_path[i + 1]);
1446
        (*_blossom_data)[right_path[i + 1]].status = EVEN;
1447
        oddToEven(right_path[i + 1], tree);
1448
        _tree_set->erase(right_path[i + 1]);
1449

	
1450
        (*_blossom_data)[right_path[i + 1]].next =
1451
          (*_blossom_data)[right_path[i + 1]].pred;
1452

	
1453
        subblossoms.push_back(right_path[i]);
1454
        _tree_set->erase(right_path[i]);
1455
      }
1456

	
1457
      int surface =
1458
        _blossom_set->join(subblossoms.begin(), subblossoms.end());
1459

	
1460
      for (int i = 0; i < int(subblossoms.size()); ++i) {
1461
        if (!_blossom_set->trivial(subblossoms[i])) {
1462
          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
1463
        }
1464
        (*_blossom_data)[subblossoms[i]].status = MATCHED;
1465
      }
1466

	
1467
      (*_blossom_data)[surface].pot = -2 * _delta_sum;
1468
      (*_blossom_data)[surface].offset = 0;
1469
      (*_blossom_data)[surface].status = EVEN;
1470
      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
1471
      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
1472

	
1473
      _tree_set->insert(surface, tree);
1474
      _tree_set->erase(nca);
1475
    }
1476

	
1477
    void splitBlossom(int blossom) {
1478
      Arc next = (*_blossom_data)[blossom].next;
1479
      Arc pred = (*_blossom_data)[blossom].pred;
1480

	
1481
      int tree = _tree_set->find(blossom);
1482

	
1483
      (*_blossom_data)[blossom].status = MATCHED;
1484
      oddToMatched(blossom);
1485
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
1486
        _delta2->erase(blossom);
1487
      }
1488

	
1489
      std::vector<int> subblossoms;
1490
      _blossom_set->split(blossom, std::back_inserter(subblossoms));
1491

	
1492
      Value offset = (*_blossom_data)[blossom].offset;
1493
      int b = _blossom_set->find(_graph.source(pred));
1494
      int d = _blossom_set->find(_graph.source(next));
1495

	
1496
      int ib = -1, id = -1;
1497
      for (int i = 0; i < int(subblossoms.size()); ++i) {
1498
        if (subblossoms[i] == b) ib = i;
1499
        if (subblossoms[i] == d) id = i;
1500

	
1501
        (*_blossom_data)[subblossoms[i]].offset = offset;
1502
        if (!_blossom_set->trivial(subblossoms[i])) {
1503
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
1504
        }
1505
        if (_blossom_set->classPrio(subblossoms[i]) !=
1506
            std::numeric_limits<Value>::max()) {
1507
          _delta2->push(subblossoms[i],
1508
                        _blossom_set->classPrio(subblossoms[i]) -
1509
                        (*_blossom_data)[subblossoms[i]].offset);
1510
        }
1511
      }
1512

	
1513
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
1514
        for (int i = (id + 1) % subblossoms.size();
1515
             i != ib; i = (i + 2) % subblossoms.size()) {
1516
          int sb = subblossoms[i];
1517
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1518
          (*_blossom_data)[sb].next =
1519
            _graph.oppositeArc((*_blossom_data)[tb].next);
1520
        }
1521

	
1522
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
1523
          int sb = subblossoms[i];
1524
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1525
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1526

	
1527
          (*_blossom_data)[sb].status = ODD;
1528
          matchedToOdd(sb);
1529
          _tree_set->insert(sb, tree);
1530
          (*_blossom_data)[sb].pred = pred;
1531
          (*_blossom_data)[sb].next =
1532
                           _graph.oppositeArc((*_blossom_data)[tb].next);
1533

	
1534
          pred = (*_blossom_data)[ub].next;
1535

	
1536
          (*_blossom_data)[tb].status = EVEN;
1537
          matchedToEven(tb, tree);
1538
          _tree_set->insert(tb, tree);
1539
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
1540
        }
1541

	
1542
        (*_blossom_data)[subblossoms[id]].status = ODD;
1543
        matchedToOdd(subblossoms[id]);
1544
        _tree_set->insert(subblossoms[id], tree);
1545
        (*_blossom_data)[subblossoms[id]].next = next;
1546
        (*_blossom_data)[subblossoms[id]].pred = pred;
1547

	
1548
      } else {
1549

	
1550
        for (int i = (ib + 1) % subblossoms.size();
1551
             i != id; i = (i + 2) % subblossoms.size()) {
1552
          int sb = subblossoms[i];
1553
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1554
          (*_blossom_data)[sb].next =
1555
            _graph.oppositeArc((*_blossom_data)[tb].next);
1556
        }
1557

	
1558
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
1559
          int sb = subblossoms[i];
1560
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1561
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1562

	
1563
          (*_blossom_data)[sb].status = ODD;
1564
          matchedToOdd(sb);
1565
          _tree_set->insert(sb, tree);
1566
          (*_blossom_data)[sb].next = next;
1567
          (*_blossom_data)[sb].pred =
1568
            _graph.oppositeArc((*_blossom_data)[tb].next);
1569

	
1570
          (*_blossom_data)[tb].status = EVEN;
1571
          matchedToEven(tb, tree);
1572
          _tree_set->insert(tb, tree);
1573
          (*_blossom_data)[tb].pred =
1574
            (*_blossom_data)[tb].next =
1575
            _graph.oppositeArc((*_blossom_data)[ub].next);
1576
          next = (*_blossom_data)[ub].next;
1577
        }
1578

	
1579
        (*_blossom_data)[subblossoms[ib]].status = ODD;
1580
        matchedToOdd(subblossoms[ib]);
1581
        _tree_set->insert(subblossoms[ib], tree);
1582
        (*_blossom_data)[subblossoms[ib]].next = next;
1583
        (*_blossom_data)[subblossoms[ib]].pred = pred;
1584
      }
1585
      _tree_set->erase(blossom);
1586
    }
1587

	
1588
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
1589
      if (_blossom_set->trivial(blossom)) {
1590
        int bi = (*_node_index)[base];
1591
        Value pot = (*_node_data)[bi].pot;
1592

	
1593
        (*_matching)[base] = matching;
1594
        _blossom_node_list.push_back(base);
1595
        (*_node_potential)[base] = pot;
1596
      } else {
1597

	
1598
        Value pot = (*_blossom_data)[blossom].pot;
1599
        int bn = _blossom_node_list.size();
1600

	
1601
        std::vector<int> subblossoms;
1602
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
1603
        int b = _blossom_set->find(base);
1604
        int ib = -1;
1605
        for (int i = 0; i < int(subblossoms.size()); ++i) {
1606
          if (subblossoms[i] == b) { ib = i; break; }
1607
        }
1608

	
1609
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
1610
          int sb = subblossoms[(ib + i) % subblossoms.size()];
1611
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
1612

	
1613
          Arc m = (*_blossom_data)[tb].next;
1614
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
1615
          extractBlossom(tb, _graph.source(m), m);
1616
        }
1617
        extractBlossom(subblossoms[ib], base, matching);
1618

	
1619
        int en = _blossom_node_list.size();
1620

	
1621
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
1622
      }
1623
    }
1624

	
1625
    void extractMatching() {
1626
      std::vector<int> blossoms;
1627
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
1628
        blossoms.push_back(c);
1629
      }
1630

	
1631
      for (int i = 0; i < int(blossoms.size()); ++i) {
1632
        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
1633

	
1634
          Value offset = (*_blossom_data)[blossoms[i]].offset;
1635
          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
1636
          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
1637
               n != INVALID; ++n) {
1638
            (*_node_data)[(*_node_index)[n]].pot -= offset;
1639
          }
1640

	
1641
          Arc matching = (*_blossom_data)[blossoms[i]].next;
1642
          Node base = _graph.source(matching);
1643
          extractBlossom(blossoms[i], base, matching);
1644
        } else {
1645
          Node base = (*_blossom_data)[blossoms[i]].base;
1646
          extractBlossom(blossoms[i], base, INVALID);
1647
        }
1648
      }
1649
    }
1650

	
1651
  public:
1652

	
1653
    /// \brief Constructor
1654
    ///
1655
    /// Constructor.
1656
    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
1657
      : _graph(graph), _weight(weight), _matching(0),
1658
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
1659
        _node_num(0), _blossom_num(0),
1660

	
1661
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
1662
        _node_index(0), _node_heap_index(0), _node_data(0),
1663
        _tree_set_index(0), _tree_set(0),
1664

	
1665
        _delta1_index(0), _delta1(0),
1666
        _delta2_index(0), _delta2(0),
1667
        _delta3_index(0), _delta3(0),
1668
        _delta4_index(0), _delta4(0),
1669

	
1670
        _delta_sum() {}
1671

	
1672
    ~MaxWeightedMatching() {
1673
      destroyStructures();
1674
    }
1675

	
1676
    /// \name Execution Control
1677
    /// The simplest way to execute the algorithm is to use the
1678
    /// \ref run() member function.
1679

	
1680
    ///@{
1681

	
1682
    /// \brief Initialize the algorithm
1683
    ///
1684
    /// This function initializes the algorithm.
1685
    void init() {
1686
      createStructures();
1687

	
1688
      for (ArcIt e(_graph); e != INVALID; ++e) {
1689
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
1690
      }
1691
      for (NodeIt n(_graph); n != INVALID; ++n) {
1692
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1693
      }
1694
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1695
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1696
      }
1697
      for (int i = 0; i < _blossom_num; ++i) {
1698
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
1699
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
1700
      }
1701

	
1702
      int index = 0;
1703
      for (NodeIt n(_graph); n != INVALID; ++n) {
1704
        Value max = 0;
1705
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1706
          if (_graph.target(e) == n) continue;
1707
          if ((dualScale * _weight[e]) / 2 > max) {
1708
            max = (dualScale * _weight[e]) / 2;
1709
          }
1710
        }
1711
        (*_node_index)[n] = index;
1712
        (*_node_data)[index].pot = max;
1713
        _delta1->push(n, max);
1714
        int blossom =
1715
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
1716

	
1717
        _tree_set->insert(blossom);
1718

	
1719
        (*_blossom_data)[blossom].status = EVEN;
1720
        (*_blossom_data)[blossom].pred = INVALID;
1721
        (*_blossom_data)[blossom].next = INVALID;
1722
        (*_blossom_data)[blossom].pot = 0;
1723
        (*_blossom_data)[blossom].offset = 0;
1724
        ++index;
1725
      }
1726
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1727
        int si = (*_node_index)[_graph.u(e)];
1728
        int ti = (*_node_index)[_graph.v(e)];
1729
        if (_graph.u(e) != _graph.v(e)) {
1730
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
1731
                            dualScale * _weight[e]) / 2);
1732
        }
1733
      }
1734
    }
1735

	
1736
    /// \brief Start the algorithm
1737
    ///
1738
    /// This function starts the algorithm.
1739
    ///
1740
    /// \pre \ref init() must be called before using this function.
1741
    void start() {
1742
      enum OpType {
1743
        D1, D2, D3, D4
1744
      };
1745

	
1746
      int unmatched = _node_num;
1747
      while (unmatched > 0) {
1748
        Value d1 = !_delta1->empty() ?
1749
          _delta1->prio() : std::numeric_limits<Value>::max();
1750

	
1751
        Value d2 = !_delta2->empty() ?
1752
          _delta2->prio() : std::numeric_limits<Value>::max();
1753

	
1754
        Value d3 = !_delta3->empty() ?
1755
          _delta3->prio() : std::numeric_limits<Value>::max();
1756

	
1757
        Value d4 = !_delta4->empty() ?
1758
          _delta4->prio() : std::numeric_limits<Value>::max();
1759

	
1760
        _delta_sum = d1; OpType ot = D1;
1761
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1762
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
1763
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
1764

	
1765

	
1766
        switch (ot) {
1767
        case D1:
1768
          {
1769
            Node n = _delta1->top();
1770
            unmatchNode(n);
1771
            --unmatched;
1772
          }
1773
          break;
1774
        case D2:
1775
          {
1776
            int blossom = _delta2->top();
1777
            Node n = _blossom_set->classTop(blossom);
1778
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
1779
            extendOnArc(e);
1780
          }
1781
          break;
1782
        case D3:
1783
          {
1784
            Edge e = _delta3->top();
1785

	
1786
            int left_blossom = _blossom_set->find(_graph.u(e));
1787
            int right_blossom = _blossom_set->find(_graph.v(e));
1788

	
1789
            if (left_blossom == right_blossom) {
1790
              _delta3->pop();
1791
            } else {
1792
              int left_tree;
1793
              if ((*_blossom_data)[left_blossom].status == EVEN) {
1794
                left_tree = _tree_set->find(left_blossom);
1795
              } else {
1796
                left_tree = -1;
1797
                ++unmatched;
1798
              }
1799
              int right_tree;
1800
              if ((*_blossom_data)[right_blossom].status == EVEN) {
1801
                right_tree = _tree_set->find(right_blossom);
1802
              } else {
1803
                right_tree = -1;
1804
                ++unmatched;
1805
              }
1806

	
1807
              if (left_tree == right_tree) {
1808
                shrinkOnEdge(e, left_tree);
1809
              } else {
1810
                augmentOnEdge(e);
1811
                unmatched -= 2;
1812
              }
1813
            }
1814
          } break;
1815
        case D4:
1816
          splitBlossom(_delta4->top());
1817
          break;
1818
        }
1819
      }
1820
      extractMatching();
1821
    }
1822

	
1823
    /// \brief Run the algorithm.
1824
    ///
1825
    /// This method runs the \c %MaxWeightedMatching algorithm.
1826
    ///
1827
    /// \note mwm.run() is just a shortcut of the following code.
1828
    /// \code
1829
    ///   mwm.init();
1830
    ///   mwm.start();
1831
    /// \endcode
1832
    void run() {
1833
      init();
1834
      start();
1835
    }
1836

	
1837
    /// @}
1838

	
1839
    /// \name Primal Solution
1840
    /// Functions to get the primal solution, i.e. the maximum weighted 
1841
    /// matching.\n
1842
    /// Either \ref run() or \ref start() function should be called before
1843
    /// using them.
1844

	
1845
    /// @{
1846

	
1847
    /// \brief Return the weight of the matching.
1848
    ///
1849
    /// This function returns the weight of the found matching.
1850
    ///
1851
    /// \pre Either run() or start() must be called before using this function.
1852
    Value matchingWeight() const {
1853
      Value sum = 0;
1854
      for (NodeIt n(_graph); n != INVALID; ++n) {
1855
        if ((*_matching)[n] != INVALID) {
1856
          sum += _weight[(*_matching)[n]];
1857
        }
1858
      }
1859
      return sum /= 2;
1860
    }
1861

	
1862
    /// \brief Return the size (cardinality) of the matching.
1863
    ///
1864
    /// This function returns the size (cardinality) of the found matching.
1865
    ///
1866
    /// \pre Either run() or start() must be called before using this function.
1867
    int matchingSize() const {
1868
      int num = 0;
1869
      for (NodeIt n(_graph); n != INVALID; ++n) {
1870
        if ((*_matching)[n] != INVALID) {
1871
          ++num;
1872
        }
1873
      }
1874
      return num /= 2;
1875
    }
1876

	
1877
    /// \brief Return \c true if the given edge is in the matching.
1878
    ///
1879
    /// This function returns \c true if the given edge is in the found 
1880
    /// matching.
1881
    ///
1882
    /// \pre Either run() or start() must be called before using this function.
1883
    bool matching(const Edge& edge) const {
1884
      return edge == (*_matching)[_graph.u(edge)];
1885
    }
1886

	
1887
    /// \brief Return the matching arc (or edge) incident to the given node.
1888
    ///
1889
    /// This function returns the matching arc (or edge) incident to the
1890
    /// given node in the found matching or \c INVALID if the node is 
1891
    /// not covered by the matching.
1892
    ///
1893
    /// \pre Either run() or start() must be called before using this function.
1894
    Arc matching(const Node& node) const {
1895
      return (*_matching)[node];
1896
    }
1897

	
1898
    /// \brief Return a const reference to the matching map.
1899
    ///
1900
    /// This function returns a const reference to a node map that stores
1901
    /// the matching arc (or edge) incident to each node.
1902
    const MatchingMap& matchingMap() const {
1903
      return *_matching;
1904
    }
1905

	
1906
    /// \brief Return the mate of the given node.
1907
    ///
1908
    /// This function returns the mate of the given node in the found 
1909
    /// matching or \c INVALID if the node is not covered by the matching.
1910
    ///
1911
    /// \pre Either run() or start() must be called before using this function.
1912
    Node mate(const Node& node) const {
1913
      return (*_matching)[node] != INVALID ?
1914
        _graph.target((*_matching)[node]) : INVALID;
1915
    }
1916

	
1917
    /// @}
1918

	
1919
    /// \name Dual Solution
1920
    /// Functions to get the dual solution.\n
1921
    /// Either \ref run() or \ref start() function should be called before
1922
    /// using them.
1923

	
1924
    /// @{
1925

	
1926
    /// \brief Return the value of the dual solution.
1927
    ///
1928
    /// This function returns the value of the dual solution. 
1929
    /// It should be equal to the primal value scaled by \ref dualScale 
1930
    /// "dual scale".
1931
    ///
1932
    /// \pre Either run() or start() must be called before using this function.
1933
    Value dualValue() const {
1934
      Value sum = 0;
1935
      for (NodeIt n(_graph); n != INVALID; ++n) {
1936
        sum += nodeValue(n);
1937
      }
1938
      for (int i = 0; i < blossomNum(); ++i) {
1939
        sum += blossomValue(i) * (blossomSize(i) / 2);
1940
      }
1941
      return sum;
1942
    }
1943

	
1944
    /// \brief Return the dual value (potential) of the given node.
1945
    ///
1946
    /// This function returns the dual value (potential) of the given node.
1947
    ///
1948
    /// \pre Either run() or start() must be called before using this function.
1949
    Value nodeValue(const Node& n) const {
1950
      return (*_node_potential)[n];
1951
    }
1952

	
1953
    /// \brief Return the number of the blossoms in the basis.
1954
    ///
1955
    /// This function returns the number of the blossoms in the basis.
1956
    ///
1957
    /// \pre Either run() or start() must be called before using this function.
1958
    /// \see BlossomIt
1959
    int blossomNum() const {
1960
      return _blossom_potential.size();
1961
    }
1962

	
1963
    /// \brief Return the number of the nodes in the given blossom.
1964
    ///
1965
    /// This function returns the number of the nodes in the given blossom.
1966
    ///
1967
    /// \pre Either run() or start() must be called before using this function.
1968
    /// \see BlossomIt
1969
    int blossomSize(int k) const {
1970
      return _blossom_potential[k].end - _blossom_potential[k].begin;
1971
    }
1972

	
1973
    /// \brief Return the dual value (ptential) of the given blossom.
1974
    ///
1975
    /// This function returns the dual value (ptential) of the given blossom.
1976
    ///
1977
    /// \pre Either run() or start() must be called before using this function.
1978
    Value blossomValue(int k) const {
1979
      return _blossom_potential[k].value;
1980
    }
1981

	
1982
    /// \brief Iterator for obtaining the nodes of a blossom.
1983
    ///
1984
    /// This class provides an iterator for obtaining the nodes of the 
1985
    /// given blossom. It lists a subset of the nodes.
1986
    /// Before using this iterator, you must allocate a 
1987
    /// MaxWeightedMatching class and execute it.
1988
    class BlossomIt {
1989
    public:
1990

	
1991
      /// \brief Constructor.
1992
      ///
1993
      /// Constructor to get the nodes of the given variable.
1994
      ///
1995
      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 
1996
      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 
1997
      /// called before initializing this iterator.
1998
      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
1999
        : _algorithm(&algorithm)
2000
      {
2001
        _index = _algorithm->_blossom_potential[variable].begin;
2002
        _last = _algorithm->_blossom_potential[variable].end;
2003
      }
2004

	
2005
      /// \brief Conversion to \c Node.
2006
      ///
2007
      /// Conversion to \c Node.
2008
      operator Node() const {
2009
        return _algorithm->_blossom_node_list[_index];
2010
      }
2011

	
2012
      /// \brief Increment operator.
2013
      ///
2014
      /// Increment operator.
2015
      BlossomIt& operator++() {
2016
        ++_index;
2017
        return *this;
2018
      }
2019

	
2020
      /// \brief Validity checking
2021
      ///
2022
      /// Checks whether the iterator is invalid.
2023
      bool operator==(Invalid) const { return _index == _last; }
2024

	
2025
      /// \brief Validity checking
2026
      ///
2027
      /// Checks whether the iterator is valid.
2028
      bool operator!=(Invalid) const { return _index != _last; }
2029

	
2030
    private:
2031
      const MaxWeightedMatching* _algorithm;
2032
      int _last;
2033
      int _index;
2034
    };
2035

	
2036
    /// @}
2037

	
2038
  };
2039

	
2040
  /// \ingroup matching
2041
  ///
2042
  /// \brief Weighted perfect matching in general graphs
2043
  ///
2044
  /// This class provides an efficient implementation of Edmond's
2045
  /// maximum weighted perfect matching algorithm. The implementation
2046
  /// is based on extensive use of priority queues and provides
2047
  /// \f$O(nm\log n)\f$ time complexity.
2048
  ///
2049
  /// The maximum weighted perfect matching problem is to find a subset of 
2050
  /// the edges in an undirected graph with maximum overall weight for which 
2051
  /// each node has exactly one incident edge.
2052
  /// It can be formulated with the following linear program.
2053
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
2054
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
2055
      \quad \forall B\in\mathcal{O}\f] */
2056
  /// \f[x_e \ge 0\quad \forall e\in E\f]
2057
  /// \f[\max \sum_{e\in E}x_ew_e\f]
2058
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
2059
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
2060
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
2061
  /// subsets of the nodes.
2062
  ///
2063
  /// The algorithm calculates an optimal matching and a proof of the
2064
  /// optimality. The solution of the dual problem can be used to check
2065
  /// the result of the algorithm. The dual linear problem is the
2066
  /// following.
2067
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
2068
      w_{uv} \quad \forall uv\in E\f] */
2069
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
2070
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
2071
      \frac{\vert B \vert - 1}{2}z_B\f] */
2072
  ///
2073
  /// The algorithm can be executed with the run() function. 
2074
  /// After it the matching (the primal solution) and the dual solution
2075
  /// can be obtained using the query functions and the 
2076
  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
2077
  /// which is able to iterate on the nodes of a blossom. 
2078
  /// If the value type is integer, then the dual solution is multiplied
2079
  /// by \ref MaxWeightedMatching::dualScale "4".
2080
  ///
2081
  /// \tparam GR The undirected graph type the algorithm runs on.
2082
  /// \tparam WM The type edge weight map. The default type is 
2083
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
2084
#ifdef DOXYGEN
2085
  template <typename GR, typename WM>
2086
#else
2087
  template <typename GR,
2088
            typename WM = typename GR::template EdgeMap<int> >
2089
#endif
2090
  class MaxWeightedPerfectMatching {
2091
  public:
2092

	
2093
    /// The graph type of the algorithm
2094
    typedef GR Graph;
2095
    /// The type of the edge weight map
2096
    typedef WM WeightMap;
2097
    /// The value type of the edge weights
2098
    typedef typename WeightMap::Value Value;
2099

	
2100
    /// \brief Scaling factor for dual solution
2101
    ///
2102
    /// Scaling factor for dual solution, it is equal to 4 or 1
2103
    /// according to the value type.
2104
    static const int dualScale =
2105
      std::numeric_limits<Value>::is_integer ? 4 : 1;
2106

	
2107
    /// The type of the matching map
2108
    typedef typename Graph::template NodeMap<typename Graph::Arc>
2109
    MatchingMap;
2110

	
2111
  private:
2112

	
2113
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2114

	
2115
    typedef typename Graph::template NodeMap<Value> NodePotential;
2116
    typedef std::vector<Node> BlossomNodeList;
2117

	
2118
    struct BlossomVariable {
2119
      int begin, end;
2120
      Value value;
2121

	
2122
      BlossomVariable(int _begin, int _end, Value _value)
2123
        : begin(_begin), end(_end), value(_value) {}
2124

	
2125
    };
2126

	
2127
    typedef std::vector<BlossomVariable> BlossomPotential;
2128

	
2129
    const Graph& _graph;
2130
    const WeightMap& _weight;
2131

	
2132
    MatchingMap* _matching;
2133

	
2134
    NodePotential* _node_potential;
2135

	
2136
    BlossomPotential _blossom_potential;
2137
    BlossomNodeList _blossom_node_list;
2138

	
2139
    int _node_num;
2140
    int _blossom_num;
2141

	
2142
    typedef RangeMap<int> IntIntMap;
2143

	
2144
    enum Status {
2145
      EVEN = -1, MATCHED = 0, ODD = 1
2146
    };
2147

	
2148
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
2149
    struct BlossomData {
2150
      int tree;
2151
      Status status;
2152
      Arc pred, next;
2153
      Value pot, offset;
2154
    };
2155

	
2156
    IntNodeMap *_blossom_index;
2157
    BlossomSet *_blossom_set;
2158
    RangeMap<BlossomData>* _blossom_data;
2159

	
2160
    IntNodeMap *_node_index;
2161
    IntArcMap *_node_heap_index;
2162

	
2163
    struct NodeData {
2164

	
2165
      NodeData(IntArcMap& node_heap_index)
2166
        : heap(node_heap_index) {}
2167

	
2168
      int blossom;
2169
      Value pot;
2170
      BinHeap<Value, IntArcMap> heap;
2171
      std::map<int, Arc> heap_index;
2172

	
2173
      int tree;
2174
    };
2175

	
2176
    RangeMap<NodeData>* _node_data;
2177

	
2178
    typedef ExtendFindEnum<IntIntMap> TreeSet;
2179

	
2180
    IntIntMap *_tree_set_index;
2181
    TreeSet *_tree_set;
2182

	
2183
    IntIntMap *_delta2_index;
2184
    BinHeap<Value, IntIntMap> *_delta2;
2185

	
2186
    IntEdgeMap *_delta3_index;
2187
    BinHeap<Value, IntEdgeMap> *_delta3;
2188

	
2189
    IntIntMap *_delta4_index;
2190
    BinHeap<Value, IntIntMap> *_delta4;
2191

	
2192
    Value _delta_sum;
2193

	
2194
    void createStructures() {
2195
      _node_num = countNodes(_graph);
2196
      _blossom_num = _node_num * 3 / 2;
2197

	
2198
      if (!_matching) {
2199
        _matching = new MatchingMap(_graph);
2200
      }
2201
      if (!_node_potential) {
2202
        _node_potential = new NodePotential(_graph);
2203
      }
2204
      if (!_blossom_set) {
2205
        _blossom_index = new IntNodeMap(_graph);
2206
        _blossom_set = new BlossomSet(*_blossom_index);
2207
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
2208
      }
2209

	
2210
      if (!_node_index) {
2211
        _node_index = new IntNodeMap(_graph);
2212
        _node_heap_index = new IntArcMap(_graph);
2213
        _node_data = new RangeMap<NodeData>(_node_num,
2214
                                            NodeData(*_node_heap_index));
2215
      }
2216

	
2217
      if (!_tree_set) {
2218
        _tree_set_index = new IntIntMap(_blossom_num);
2219
        _tree_set = new TreeSet(*_tree_set_index);
2220
      }
2221
      if (!_delta2) {
2222
        _delta2_index = new IntIntMap(_blossom_num);
2223
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
2224
      }
2225
      if (!_delta3) {
2226
        _delta3_index = new IntEdgeMap(_graph);
2227
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
2228
      }
2229
      if (!_delta4) {
2230
        _delta4_index = new IntIntMap(_blossom_num);
2231
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
2232
      }
2233
    }
2234

	
2235
    void destroyStructures() {
2236
      _node_num = countNodes(_graph);
2237
      _blossom_num = _node_num * 3 / 2;
2238

	
2239
      if (_matching) {
2240
        delete _matching;
2241
      }
2242
      if (_node_potential) {
2243
        delete _node_potential;
2244
      }
2245
      if (_blossom_set) {
2246
        delete _blossom_index;
2247
        delete _blossom_set;
2248
        delete _blossom_data;
2249
      }
2250

	
2251
      if (_node_index) {
2252
        delete _node_index;
2253
        delete _node_heap_index;
2254
        delete _node_data;
2255
      }
2256

	
2257
      if (_tree_set) {
2258
        delete _tree_set_index;
2259
        delete _tree_set;
2260
      }
2261
      if (_delta2) {
2262
        delete _delta2_index;
2263
        delete _delta2;
2264
      }
2265
      if (_delta3) {
2266
        delete _delta3_index;
2267
        delete _delta3;
2268
      }
2269
      if (_delta4) {
2270
        delete _delta4_index;
2271
        delete _delta4;
2272
      }
2273
    }
2274

	
2275
    void matchedToEven(int blossom, int tree) {
2276
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2277
        _delta2->erase(blossom);
2278
      }
2279

	
2280
      if (!_blossom_set->trivial(blossom)) {
2281
        (*_blossom_data)[blossom].pot -=
2282
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
2283
      }
2284

	
2285
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2286
           n != INVALID; ++n) {
2287

	
2288
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
2289
        int ni = (*_node_index)[n];
2290

	
2291
        (*_node_data)[ni].heap.clear();
2292
        (*_node_data)[ni].heap_index.clear();
2293

	
2294
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
2295

	
2296
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2297
          Node v = _graph.source(e);
2298
          int vb = _blossom_set->find(v);
2299
          int vi = (*_node_index)[v];
2300

	
2301
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2302
            dualScale * _weight[e];
2303

	
2304
          if ((*_blossom_data)[vb].status == EVEN) {
2305
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
2306
              _delta3->push(e, rw / 2);
2307
            }
2308
          } else {
2309
            typename std::map<int, Arc>::iterator it =
2310
              (*_node_data)[vi].heap_index.find(tree);
2311

	
2312
            if (it != (*_node_data)[vi].heap_index.end()) {
2313
              if ((*_node_data)[vi].heap[it->second] > rw) {
2314
                (*_node_data)[vi].heap.replace(it->second, e);
2315
                (*_node_data)[vi].heap.decrease(e, rw);
2316
                it->second = e;
2317
              }
2318
            } else {
2319
              (*_node_data)[vi].heap.push(e, rw);
2320
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
2321
            }
2322

	
2323
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
2324
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
2325

	
2326
              if ((*_blossom_data)[vb].status == MATCHED) {
2327
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
2328
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
2329
                               (*_blossom_data)[vb].offset);
2330
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
2331
                           (*_blossom_data)[vb].offset){
2332
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
2333
                                   (*_blossom_data)[vb].offset);
2334
                }
2335
              }
2336
            }
2337
          }
2338
        }
2339
      }
2340
      (*_blossom_data)[blossom].offset = 0;
2341
    }
2342

	
2343
    void matchedToOdd(int blossom) {
2344
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2345
        _delta2->erase(blossom);
2346
      }
2347
      (*_blossom_data)[blossom].offset += _delta_sum;
2348
      if (!_blossom_set->trivial(blossom)) {
2349
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
2350
                     (*_blossom_data)[blossom].offset);
2351
      }
2352
    }
2353

	
2354
    void evenToMatched(int blossom, int tree) {
2355
      if (!_blossom_set->trivial(blossom)) {
2356
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
2357
      }
2358

	
2359
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2360
           n != INVALID; ++n) {
2361
        int ni = (*_node_index)[n];
2362
        (*_node_data)[ni].pot -= _delta_sum;
2363

	
2364
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2365
          Node v = _graph.source(e);
2366
          int vb = _blossom_set->find(v);
2367
          int vi = (*_node_index)[v];
2368

	
2369
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2370
            dualScale * _weight[e];
2371

	
2372
          if (vb == blossom) {
2373
            if (_delta3->state(e) == _delta3->IN_HEAP) {
2374
              _delta3->erase(e);
2375
            }
2376
          } else if ((*_blossom_data)[vb].status == EVEN) {
2377

	
2378
            if (_delta3->state(e) == _delta3->IN_HEAP) {
2379
              _delta3->erase(e);
2380
            }
2381

	
2382
            int vt = _tree_set->find(vb);
2383

	
2384
            if (vt != tree) {
2385

	
2386
              Arc r = _graph.oppositeArc(e);
2387

	
2388
              typename std::map<int, Arc>::iterator it =
2389
                (*_node_data)[ni].heap_index.find(vt);
2390

	
2391
              if (it != (*_node_data)[ni].heap_index.end()) {
2392
                if ((*_node_data)[ni].heap[it->second] > rw) {
2393
                  (*_node_data)[ni].heap.replace(it->second, r);
2394
                  (*_node_data)[ni].heap.decrease(r, rw);
2395
                  it->second = r;
2396
                }
2397
              } else {
2398
                (*_node_data)[ni].heap.push(r, rw);
2399
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
2400
              }
2401

	
2402
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
2403
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
2404

	
2405
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
2406
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
2407
                               (*_blossom_data)[blossom].offset);
2408
                } else if ((*_delta2)[blossom] >
2409
                           _blossom_set->classPrio(blossom) -
2410
                           (*_blossom_data)[blossom].offset){
2411
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
2412
                                   (*_blossom_data)[blossom].offset);
2413
                }
2414
              }
2415
            }
2416
          } else {
2417

	
2418
            typename std::map<int, Arc>::iterator it =
2419
              (*_node_data)[vi].heap_index.find(tree);
2420

	
2421
            if (it != (*_node_data)[vi].heap_index.end()) {
2422
              (*_node_data)[vi].heap.erase(it->second);
2423
              (*_node_data)[vi].heap_index.erase(it);
2424
              if ((*_node_data)[vi].heap.empty()) {
2425
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
2426
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
2427
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
2428
              }
2429

	
2430
              if ((*_blossom_data)[vb].status == MATCHED) {
2431
                if (_blossom_set->classPrio(vb) ==
2432
                    std::numeric_limits<Value>::max()) {
2433
                  _delta2->erase(vb);
2434
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
2435
                           (*_blossom_data)[vb].offset) {
2436
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
2437
                                   (*_blossom_data)[vb].offset);
2438
                }
2439
              }
2440
            }
2441
          }
2442
        }
2443
      }
2444
    }
2445

	
2446
    void oddToMatched(int blossom) {
2447
      (*_blossom_data)[blossom].offset -= _delta_sum;
2448

	
2449
      if (_blossom_set->classPrio(blossom) !=
2450
          std::numeric_limits<Value>::max()) {
2451
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
2452
                       (*_blossom_data)[blossom].offset);
2453
      }
2454

	
2455
      if (!_blossom_set->trivial(blossom)) {
2456
        _delta4->erase(blossom);
2457
      }
2458
    }
2459

	
2460
    void oddToEven(int blossom, int tree) {
2461
      if (!_blossom_set->trivial(blossom)) {
2462
        _delta4->erase(blossom);
2463
        (*_blossom_data)[blossom].pot -=
2464
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
2465
      }
2466

	
2467
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2468
           n != INVALID; ++n) {
2469
        int ni = (*_node_index)[n];
2470

	
2471
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
2472

	
2473
        (*_node_data)[ni].heap.clear();
2474
        (*_node_data)[ni].heap_index.clear();
2475
        (*_node_data)[ni].pot +=
2476
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
2477

	
2478
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2479
          Node v = _graph.source(e);
2480
          int vb = _blossom_set->find(v);
2481
          int vi = (*_node_index)[v];
2482

	
2483
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2484
            dualScale * _weight[e];
2485

	
2486
          if ((*_blossom_data)[vb].status == EVEN) {
2487
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
2488
              _delta3->push(e, rw / 2);
2489
            }
2490
          } else {
2491

	
2492
            typename std::map<int, Arc>::iterator it =
2493
              (*_node_data)[vi].heap_index.find(tree);
2494

	
2495
            if (it != (*_node_data)[vi].heap_index.end()) {
2496
              if ((*_node_data)[vi].heap[it->second] > rw) {
2497
                (*_node_data)[vi].heap.replace(it->second, e);
2498
                (*_node_data)[vi].heap.decrease(e, rw);
2499
                it->second = e;
2500
              }
2501
            } else {
2502
              (*_node_data)[vi].heap.push(e, rw);
2503
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
2504
            }
2505

	
2506
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
2507
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
2508

	
2509
              if ((*_blossom_data)[vb].status == MATCHED) {
2510
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
2511
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
2512
                               (*_blossom_data)[vb].offset);
2513
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
2514
                           (*_blossom_data)[vb].offset) {
2515
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
2516
                                   (*_blossom_data)[vb].offset);
2517
                }
2518
              }
2519
            }
2520
          }
2521
        }
2522
      }
2523
      (*_blossom_data)[blossom].offset = 0;
2524
    }
2525

	
2526
    void alternatePath(int even, int tree) {
2527
      int odd;
2528

	
2529
      evenToMatched(even, tree);
2530
      (*_blossom_data)[even].status = MATCHED;
2531

	
2532
      while ((*_blossom_data)[even].pred != INVALID) {
2533
        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
2534
        (*_blossom_data)[odd].status = MATCHED;
2535
        oddToMatched(odd);
2536
        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
2537

	
2538
        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
2539
        (*_blossom_data)[even].status = MATCHED;
2540
        evenToMatched(even, tree);
2541
        (*_blossom_data)[even].next =
2542
          _graph.oppositeArc((*_blossom_data)[odd].pred);
2543
      }
2544

	
2545
    }
2546

	
2547
    void destroyTree(int tree) {
2548
      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
2549
        if ((*_blossom_data)[b].status == EVEN) {
2550
          (*_blossom_data)[b].status = MATCHED;
2551
          evenToMatched(b, tree);
2552
        } else if ((*_blossom_data)[b].status == ODD) {
2553
          (*_blossom_data)[b].status = MATCHED;
2554
          oddToMatched(b);
2555
        }
2556
      }
2557
      _tree_set->eraseClass(tree);
2558
    }
2559

	
2560
    void augmentOnEdge(const Edge& edge) {
2561

	
2562
      int left = _blossom_set->find(_graph.u(edge));
2563
      int right = _blossom_set->find(_graph.v(edge));
2564

	
2565
      int left_tree = _tree_set->find(left);
2566
      alternatePath(left, left_tree);
2567
      destroyTree(left_tree);
2568

	
2569
      int right_tree = _tree_set->find(right);
2570
      alternatePath(right, right_tree);
2571
      destroyTree(right_tree);
2572

	
2573
      (*_blossom_data)[left].next = _graph.direct(edge, true);
2574
      (*_blossom_data)[right].next = _graph.direct(edge, false);
2575
    }
2576

	
2577
    void extendOnArc(const Arc& arc) {
2578
      int base = _blossom_set->find(_graph.target(arc));
2579
      int tree = _tree_set->find(base);
2580

	
2581
      int odd = _blossom_set->find(_graph.source(arc));
2582
      _tree_set->insert(odd, tree);
2583
      (*_blossom_data)[odd].status = ODD;
2584
      matchedToOdd(odd);
2585
      (*_blossom_data)[odd].pred = arc;
2586

	
2587
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
2588
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
2589
      _tree_set->insert(even, tree);
2590
      (*_blossom_data)[even].status = EVEN;
2591
      matchedToEven(even, tree);
2592
    }
2593

	
2594
    void shrinkOnEdge(const Edge& edge, int tree) {
2595
      int nca = -1;
2596
      std::vector<int> left_path, right_path;
2597

	
2598
      {
2599
        std::set<int> left_set, right_set;
2600
        int left = _blossom_set->find(_graph.u(edge));
2601
        left_path.push_back(left);
2602
        left_set.insert(left);
2603

	
2604
        int right = _blossom_set->find(_graph.v(edge));
2605
        right_path.push_back(right);
2606
        right_set.insert(right);
2607

	
2608
        while (true) {
2609

	
2610
          if ((*_blossom_data)[left].pred == INVALID) break;
2611

	
2612
          left =
2613
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
2614
          left_path.push_back(left);
2615
          left =
2616
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
2617
          left_path.push_back(left);
2618

	
2619
          left_set.insert(left);
2620

	
2621
          if (right_set.find(left) != right_set.end()) {
2622
            nca = left;
2623
            break;
2624
          }
2625

	
2626
          if ((*_blossom_data)[right].pred == INVALID) break;
2627

	
2628
          right =
2629
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
2630
          right_path.push_back(right);
2631
          right =
2632
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
2633
          right_path.push_back(right);
2634

	
2635
          right_set.insert(right);
2636

	
2637
          if (left_set.find(right) != left_set.end()) {
2638
            nca = right;
2639
            break;
2640
          }
2641

	
2642
        }
2643

	
2644
        if (nca == -1) {
2645
          if ((*_blossom_data)[left].pred == INVALID) {
2646
            nca = right;
2647
            while (left_set.find(nca) == left_set.end()) {
2648
              nca =
2649
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2650
              right_path.push_back(nca);
2651
              nca =
2652
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2653
              right_path.push_back(nca);
2654
            }
2655
          } else {
2656
            nca = left;
2657
            while (right_set.find(nca) == right_set.end()) {
2658
              nca =
2659
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2660
              left_path.push_back(nca);
2661
              nca =
2662
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2663
              left_path.push_back(nca);
2664
            }
2665
          }
2666
        }
2667
      }
2668

	
2669
      std::vector<int> subblossoms;
2670
      Arc prev;
2671

	
2672
      prev = _graph.direct(edge, true);
2673
      for (int i = 0; left_path[i] != nca; i += 2) {
2674
        subblossoms.push_back(left_path[i]);
2675
        (*_blossom_data)[left_path[i]].next = prev;
2676
        _tree_set->erase(left_path[i]);
2677

	
2678
        subblossoms.push_back(left_path[i + 1]);
2679
        (*_blossom_data)[left_path[i + 1]].status = EVEN;
2680
        oddToEven(left_path[i + 1], tree);
2681
        _tree_set->erase(left_path[i + 1]);
2682
        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
2683
      }
2684

	
2685
      int k = 0;
2686
      while (right_path[k] != nca) ++k;
2687

	
2688
      subblossoms.push_back(nca);
2689
      (*_blossom_data)[nca].next = prev;
2690

	
2691
      for (int i = k - 2; i >= 0; i -= 2) {
2692
        subblossoms.push_back(right_path[i + 1]);
2693
        (*_blossom_data)[right_path[i + 1]].status = EVEN;
2694
        oddToEven(right_path[i + 1], tree);
2695
        _tree_set->erase(right_path[i + 1]);
2696

	
2697
        (*_blossom_data)[right_path[i + 1]].next =
2698
          (*_blossom_data)[right_path[i + 1]].pred;
2699

	
2700
        subblossoms.push_back(right_path[i]);
2701
        _tree_set->erase(right_path[i]);
2702
      }
2703

	
2704
      int surface =
2705
        _blossom_set->join(subblossoms.begin(), subblossoms.end());
2706

	
2707
      for (int i = 0; i < int(subblossoms.size()); ++i) {
2708
        if (!_blossom_set->trivial(subblossoms[i])) {
2709
          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
2710
        }
2711
        (*_blossom_data)[subblossoms[i]].status = MATCHED;
2712
      }
2713

	
2714
      (*_blossom_data)[surface].pot = -2 * _delta_sum;
2715
      (*_blossom_data)[surface].offset = 0;
2716
      (*_blossom_data)[surface].status = EVEN;
2717
      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
2718
      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
2719

	
2720
      _tree_set->insert(surface, tree);
2721
      _tree_set->erase(nca);
2722
    }
2723

	
2724
    void splitBlossom(int blossom) {
2725
      Arc next = (*_blossom_data)[blossom].next;
2726
      Arc pred = (*_blossom_data)[blossom].pred;
2727

	
2728
      int tree = _tree_set->find(blossom);
2729

	
2730
      (*_blossom_data)[blossom].status = MATCHED;
2731
      oddToMatched(blossom);
2732
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2733
        _delta2->erase(blossom);
2734
      }
2735

	
2736
      std::vector<int> subblossoms;
2737
      _blossom_set->split(blossom, std::back_inserter(subblossoms));
2738

	
2739
      Value offset = (*_blossom_data)[blossom].offset;
2740
      int b = _blossom_set->find(_graph.source(pred));
2741
      int d = _blossom_set->find(_graph.source(next));
2742

	
2743
      int ib = -1, id = -1;
2744
      for (int i = 0; i < int(subblossoms.size()); ++i) {
2745
        if (subblossoms[i] == b) ib = i;
2746
        if (subblossoms[i] == d) id = i;
2747

	
2748
        (*_blossom_data)[subblossoms[i]].offset = offset;
2749
        if (!_blossom_set->trivial(subblossoms[i])) {
2750
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
2751
        }
2752
        if (_blossom_set->classPrio(subblossoms[i]) !=
2753
            std::numeric_limits<Value>::max()) {
2754
          _delta2->push(subblossoms[i],
2755
                        _blossom_set->classPrio(subblossoms[i]) -
2756
                        (*_blossom_data)[subblossoms[i]].offset);
2757
        }
2758
      }
2759

	
2760
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
2761
        for (int i = (id + 1) % subblossoms.size();
2762
             i != ib; i = (i + 2) % subblossoms.size()) {
2763
          int sb = subblossoms[i];
2764
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2765
          (*_blossom_data)[sb].next =
2766
            _graph.oppositeArc((*_blossom_data)[tb].next);
2767
        }
2768

	
2769
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
2770
          int sb = subblossoms[i];
2771
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2772
          int ub = subblossoms[(i + 2) % subblossoms.size()];
2773

	
2774
          (*_blossom_data)[sb].status = ODD;
2775
          matchedToOdd(sb);
2776
          _tree_set->insert(sb, tree);
2777
          (*_blossom_data)[sb].pred = pred;
2778
          (*_blossom_data)[sb].next =
2779
                           _graph.oppositeArc((*_blossom_data)[tb].next);
2780

	
2781
          pred = (*_blossom_data)[ub].next;
2782

	
2783
          (*_blossom_data)[tb].status = EVEN;
2784
          matchedToEven(tb, tree);
2785
          _tree_set->insert(tb, tree);
2786
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
2787
        }
2788

	
2789
        (*_blossom_data)[subblossoms[id]].status = ODD;
2790
        matchedToOdd(subblossoms[id]);
2791
        _tree_set->insert(subblossoms[id], tree);
2792
        (*_blossom_data)[subblossoms[id]].next = next;
2793
        (*_blossom_data)[subblossoms[id]].pred = pred;
2794

	
2795
      } else {
2796

	
2797
        for (int i = (ib + 1) % subblossoms.size();
2798
             i != id; i = (i + 2) % subblossoms.size()) {
2799
          int sb = subblossoms[i];
2800
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2801
          (*_blossom_data)[sb].next =
2802
            _graph.oppositeArc((*_blossom_data)[tb].next);
2803
        }
2804

	
2805
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
2806
          int sb = subblossoms[i];
2807
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2808
          int ub = subblossoms[(i + 2) % subblossoms.size()];
2809

	
2810
          (*_blossom_data)[sb].status = ODD;
2811
          matchedToOdd(sb);
2812
          _tree_set->insert(sb, tree);
2813
          (*_blossom_data)[sb].next = next;
2814
          (*_blossom_data)[sb].pred =
2815
            _graph.oppositeArc((*_blossom_data)[tb].next);
2816

	
2817
          (*_blossom_data)[tb].status = EVEN;
2818
          matchedToEven(tb, tree);
2819
          _tree_set->insert(tb, tree);
2820
          (*_blossom_data)[tb].pred =
2821
            (*_blossom_data)[tb].next =
2822
            _graph.oppositeArc((*_blossom_data)[ub].next);
2823
          next = (*_blossom_data)[ub].next;
2824
        }
2825

	
2826
        (*_blossom_data)[subblossoms[ib]].status = ODD;
2827
        matchedToOdd(subblossoms[ib]);
2828
        _tree_set->insert(subblossoms[ib], tree);
2829
        (*_blossom_data)[subblossoms[ib]].next = next;
2830
        (*_blossom_data)[subblossoms[ib]].pred = pred;
2831
      }
2832
      _tree_set->erase(blossom);
2833
    }
2834

	
2835
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
2836
      if (_blossom_set->trivial(blossom)) {
2837
        int bi = (*_node_index)[base];
2838
        Value pot = (*_node_data)[bi].pot;
2839

	
2840
        (*_matching)[base] = matching;
2841
        _blossom_node_list.push_back(base);
2842
        (*_node_potential)[base] = pot;
2843
      } else {
2844

	
2845
        Value pot = (*_blossom_data)[blossom].pot;
2846
        int bn = _blossom_node_list.size();
2847

	
2848
        std::vector<int> subblossoms;
2849
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
2850
        int b = _blossom_set->find(base);
2851
        int ib = -1;
2852
        for (int i = 0; i < int(subblossoms.size()); ++i) {
2853
          if (subblossoms[i] == b) { ib = i; break; }
2854
        }
2855

	
2856
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
2857
          int sb = subblossoms[(ib + i) % subblossoms.size()];
2858
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
2859

	
2860
          Arc m = (*_blossom_data)[tb].next;
2861
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
2862
          extractBlossom(tb, _graph.source(m), m);
2863
        }
2864
        extractBlossom(subblossoms[ib], base, matching);
2865

	
2866
        int en = _blossom_node_list.size();
2867

	
2868
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
2869
      }
2870
    }
2871

	
2872
    void extractMatching() {
2873
      std::vector<int> blossoms;
2874
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
2875
        blossoms.push_back(c);
2876
      }
2877

	
2878
      for (int i = 0; i < int(blossoms.size()); ++i) {
2879

	
2880
        Value offset = (*_blossom_data)[blossoms[i]].offset;
2881
        (*_blossom_data)[blossoms[i]].pot += 2 * offset;
2882
        for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
2883
             n != INVALID; ++n) {
2884
          (*_node_data)[(*_node_index)[n]].pot -= offset;
2885
        }
2886

	
2887
        Arc matching = (*_blossom_data)[blossoms[i]].next;
2888
        Node base = _graph.source(matching);
2889
        extractBlossom(blossoms[i], base, matching);
2890
      }
2891
    }
2892

	
2893
  public:
2894

	
2895
    /// \brief Constructor
2896
    ///
2897
    /// Constructor.
2898
    MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
2899
      : _graph(graph), _weight(weight), _matching(0),
2900
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
2901
        _node_num(0), _blossom_num(0),
2902

	
2903
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
2904
        _node_index(0), _node_heap_index(0), _node_data(0),
2905
        _tree_set_index(0), _tree_set(0),
2906

	
2907
        _delta2_index(0), _delta2(0),
2908
        _delta3_index(0), _delta3(0),
2909
        _delta4_index(0), _delta4(0),
2910

	
2911
        _delta_sum() {}
2912

	
2913
    ~MaxWeightedPerfectMatching() {
2914
      destroyStructures();
2915
    }
2916

	
2917
    /// \name Execution Control
2918
    /// The simplest way to execute the algorithm is to use the
2919
    /// \ref run() member function.
2920

	
2921
    ///@{
2922

	
2923
    /// \brief Initialize the algorithm
2924
    ///
2925
    /// This function initializes the algorithm.
2926
    void init() {
2927
      createStructures();
2928

	
2929
      for (ArcIt e(_graph); e != INVALID; ++e) {
2930
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
2931
      }
2932
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2933
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
2934
      }
2935
      for (int i = 0; i < _blossom_num; ++i) {
2936
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
2937
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
2938
      }
2939

	
2940
      int index = 0;
2941
      for (NodeIt n(_graph); n != INVALID; ++n) {
2942
        Value max = - std::numeric_limits<Value>::max();
2943
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2944
          if (_graph.target(e) == n) continue;
2945
          if ((dualScale * _weight[e]) / 2 > max) {
2946
            max = (dualScale * _weight[e]) / 2;
2947
          }
2948
        }
2949
        (*_node_index)[n] = index;
2950
        (*_node_data)[index].pot = max;
2951
        int blossom =
2952
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
2953

	
2954
        _tree_set->insert(blossom);
2955

	
2956
        (*_blossom_data)[blossom].status = EVEN;
2957
        (*_blossom_data)[blossom].pred = INVALID;
2958
        (*_blossom_data)[blossom].next = INVALID;
2959
        (*_blossom_data)[blossom].pot = 0;
2960
        (*_blossom_data)[blossom].offset = 0;
2961
        ++index;
2962
      }
2963
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2964
        int si = (*_node_index)[_graph.u(e)];
2965
        int ti = (*_node_index)[_graph.v(e)];
2966
        if (_graph.u(e) != _graph.v(e)) {
2967
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
2968
                            dualScale * _weight[e]) / 2);
2969
        }
2970
      }
2971
    }
2972

	
2973
    /// \brief Start the algorithm
2974
    ///
2975
    /// This function starts the algorithm.
2976
    ///
2977
    /// \pre \ref init() must be called before using this function.
2978
    bool start() {
2979
      enum OpType {
2980
        D2, D3, D4
2981
      };
2982

	
2983
      int unmatched = _node_num;
2984
      while (unmatched > 0) {
2985
        Value d2 = !_delta2->empty() ?
2986
          _delta2->prio() : std::numeric_limits<Value>::max();
2987

	
2988
        Value d3 = !_delta3->empty() ?
2989
          _delta3->prio() : std::numeric_limits<Value>::max();
2990

	
2991
        Value d4 = !_delta4->empty() ?
2992
          _delta4->prio() : std::numeric_limits<Value>::max();
2993

	
2994
        _delta_sum = d2; OpType ot = D2;
2995
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
2996
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
2997

	
2998
        if (_delta_sum == std::numeric_limits<Value>::max()) {
2999
          return false;
3000
        }
3001

	
3002
        switch (ot) {
3003
        case D2:
3004
          {
3005
            int blossom = _delta2->top();
3006
            Node n = _blossom_set->classTop(blossom);
3007
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
3008
            extendOnArc(e);
3009
          }
3010
          break;
3011
        case D3:
3012
          {
3013
            Edge e = _delta3->top();
3014

	
3015
            int left_blossom = _blossom_set->find(_graph.u(e));
3016
            int right_blossom = _blossom_set->find(_graph.v(e));
3017

	
3018
            if (left_blossom == right_blossom) {
3019
              _delta3->pop();
3020
            } else {
3021
              int left_tree = _tree_set->find(left_blossom);
3022
              int right_tree = _tree_set->find(right_blossom);
3023

	
3024
              if (left_tree == right_tree) {
3025
                shrinkOnEdge(e, left_tree);
3026
              } else {
3027
                augmentOnEdge(e);
3028
                unmatched -= 2;
3029
              }
3030
            }
3031
          } break;
3032
        case D4:
3033
          splitBlossom(_delta4->top());
3034
          break;
3035
        }
3036
      }
3037
      extractMatching();
3038
      return true;
3039
    }
3040

	
3041
    /// \brief Run the algorithm.
3042
    ///
3043
    /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
3044
    ///
3045
    /// \note mwpm.run() is just a shortcut of the following code.
3046
    /// \code
3047
    ///   mwpm.init();
3048
    ///   mwpm.start();
3049
    /// \endcode
3050
    bool run() {
3051
      init();
3052
      return start();
3053
    }
3054

	
3055
    /// @}
3056

	
3057
    /// \name Primal Solution
3058
    /// Functions to get the primal solution, i.e. the maximum weighted 
3059
    /// perfect matching.\n
3060
    /// Either \ref run() or \ref start() function should be called before
3061
    /// using them.
3062

	
3063
    /// @{
3064

	
3065
    /// \brief Return the weight of the matching.
3066
    ///
3067
    /// This function returns the weight of the found matching.
3068
    ///
3069
    /// \pre Either run() or start() must be called before using this function.
3070
    Value matchingWeight() const {
3071
      Value sum = 0;
3072
      for (NodeIt n(_graph); n != INVALID; ++n) {
3073
        if ((*_matching)[n] != INVALID) {
3074
          sum += _weight[(*_matching)[n]];
3075
        }
3076
      }
3077
      return sum /= 2;
3078
    }
3079

	
3080
    /// \brief Return \c true if the given edge is in the matching.
3081
    ///
3082
    /// This function returns \c true if the given edge is in the found 
3083
    /// matching.
3084
    ///
3085
    /// \pre Either run() or start() must be called before using this function.
3086
    bool matching(const Edge& edge) const {
3087
      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
3088
    }
3089

	
3090
    /// \brief Return the matching arc (or edge) incident to the given node.
3091
    ///
3092
    /// This function returns the matching arc (or edge) incident to the
3093
    /// given node in the found matching or \c INVALID if the node is 
3094
    /// not covered by the matching.
3095
    ///
3096
    /// \pre Either run() or start() must be called before using this function.
3097
    Arc matching(const Node& node) const {
3098
      return (*_matching)[node];
3099
    }
3100

	
3101
    /// \brief Return a const reference to the matching map.
3102
    ///
3103
    /// This function returns a const reference to a node map that stores
3104
    /// the matching arc (or edge) incident to each node.
3105
    const MatchingMap& matchingMap() const {
3106
      return *_matching;
3107
    }
3108

	
3109
    /// \brief Return the mate of the given node.
3110
    ///
3111
    /// This function returns the mate of the given node in the found 
3112
    /// matching or \c INVALID if the node is not covered by the matching.
3113
    ///
3114
    /// \pre Either run() or start() must be called before using this function.
3115
    Node mate(const Node& node) const {
3116
      return _graph.target((*_matching)[node]);
3117
    }
3118

	
3119
    /// @}
3120

	
3121
    /// \name Dual Solution
3122
    /// Functions to get the dual solution.\n
3123
    /// Either \ref run() or \ref start() function should be called before
3124
    /// using them.
3125

	
3126
    /// @{
3127

	
3128
    /// \brief Return the value of the dual solution.
3129
    ///
3130
    /// This function returns the value of the dual solution. 
3131
    /// It should be equal to the primal value scaled by \ref dualScale 
3132
    /// "dual scale".
3133
    ///
3134
    /// \pre Either run() or start() must be called before using this function.
3135
    Value dualValue() const {
3136
      Value sum = 0;
3137
      for (NodeIt n(_graph); n != INVALID; ++n) {
3138
        sum += nodeValue(n);
3139
      }
3140
      for (int i = 0; i < blossomNum(); ++i) {
3141
        sum += blossomValue(i) * (blossomSize(i) / 2);
3142
      }
3143
      return sum;
3144
    }
3145

	
3146
    /// \brief Return the dual value (potential) of the given node.
3147
    ///
3148
    /// This function returns the dual value (potential) of the given node.
3149
    ///
3150
    /// \pre Either run() or start() must be called before using this function.
3151
    Value nodeValue(const Node& n) const {
3152
      return (*_node_potential)[n];
3153
    }
3154

	
3155
    /// \brief Return the number of the blossoms in the basis.
3156
    ///
3157
    /// This function returns the number of the blossoms in the basis.
3158
    ///
3159
    /// \pre Either run() or start() must be called before using this function.
3160
    /// \see BlossomIt
3161
    int blossomNum() const {
3162
      return _blossom_potential.size();
3163
    }
3164

	
3165
    /// \brief Return the number of the nodes in the given blossom.
3166
    ///
3167
    /// This function returns the number of the nodes in the given blossom.
3168
    ///
3169
    /// \pre Either run() or start() must be called before using this function.
3170
    /// \see BlossomIt
3171
    int blossomSize(int k) const {
3172
      return _blossom_potential[k].end - _blossom_potential[k].begin;
3173
    }
3174

	
3175
    /// \brief Return the dual value (ptential) of the given blossom.
3176
    ///
3177
    /// This function returns the dual value (ptential) of the given blossom.
3178
    ///
3179
    /// \pre Either run() or start() must be called before using this function.
3180
    Value blossomValue(int k) const {
3181
      return _blossom_potential[k].value;
3182
    }
3183

	
3184
    /// \brief Iterator for obtaining the nodes of a blossom.
3185
    ///
3186
    /// This class provides an iterator for obtaining the nodes of the 
3187
    /// given blossom. It lists a subset of the nodes.
3188
    /// Before using this iterator, you must allocate a 
3189
    /// MaxWeightedPerfectMatching class and execute it.
3190
    class BlossomIt {
3191
    public:
3192

	
3193
      /// \brief Constructor.
3194
      ///
3195
      /// Constructor to get the nodes of the given variable.
3196
      ///
3197
      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 
3198
      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 
3199
      /// must be called before initializing this iterator.
3200
      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
3201
        : _algorithm(&algorithm)
3202
      {
3203
        _index = _algorithm->_blossom_potential[variable].begin;
3204
        _last = _algorithm->_blossom_potential[variable].end;
3205
      }
3206

	
3207
      /// \brief Conversion to \c Node.
3208
      ///
3209
      /// Conversion to \c Node.
3210
      operator Node() const {
3211
        return _algorithm->_blossom_node_list[_index];
3212
      }
3213

	
3214
      /// \brief Increment operator.
3215
      ///
3216
      /// Increment operator.
3217
      BlossomIt& operator++() {
3218
        ++_index;
3219
        return *this;
3220
      }
3221

	
3222
      /// \brief Validity checking
3223
      ///
3224
      /// This function checks whether the iterator is invalid.
3225
      bool operator==(Invalid) const { return _index == _last; }
3226

	
3227
      /// \brief Validity checking
3228
      ///
3229
      /// This function checks whether the iterator is valid.
3230
      bool operator!=(Invalid) const { return _index != _last; }
3231

	
3232
    private:
3233
      const MaxWeightedPerfectMatching* _algorithm;
3234
      int _last;
3235
      int _index;
3236
    };
3237

	
3238
    /// @}
3239

	
3240
  };
3241

	
3242
} //END OF NAMESPACE LEMON
3243

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

	
19
#ifndef LEMON_MIN_COST_ARBORESCENCE_H
20
#define LEMON_MIN_COST_ARBORESCENCE_H
21

	
22
///\ingroup spantree
23
///\file
24
///\brief Minimum Cost Arborescence algorithm.
25

	
26
#include <vector>
27

	
28
#include <lemon/list_graph.h>
29
#include <lemon/bin_heap.h>
30
#include <lemon/assert.h>
31

	
32
namespace lemon {
33

	
34

	
35
  /// \brief Default traits class for MinCostArborescence class.
36
  ///
37
  /// Default traits class for MinCostArborescence class.
38
  /// \param GR Digraph type.
39
  /// \param CM Type of the cost map.
40
  template <class GR, class CM>
41
  struct MinCostArborescenceDefaultTraits{
42

	
43
    /// \brief The digraph type the algorithm runs on.
44
    typedef GR Digraph;
45

	
46
    /// \brief The type of the map that stores the arc costs.
47
    ///
48
    /// The type of the map that stores the arc costs.
49
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
50
    typedef CM CostMap;
51

	
52
    /// \brief The value type of the costs.
53
    ///
54
    /// The value type of the costs.
55
    typedef typename CostMap::Value Value;
56

	
57
    /// \brief The type of the map that stores which arcs are in the
58
    /// arborescence.
59
    ///
60
    /// The type of the map that stores which arcs are in the
61
    /// arborescence.  It must conform to the \ref concepts::WriteMap
62
    /// "WriteMap" concept, and its value type must be \c bool
63
    /// (or convertible). Initially it will be set to \c false on each
64
    /// arc, then it will be set on each arborescence arc once.
65
    typedef typename Digraph::template ArcMap<bool> ArborescenceMap;
66

	
67
    /// \brief Instantiates a \c ArborescenceMap.
68
    ///
69
    /// This function instantiates a \c ArborescenceMap.
70
    /// \param digraph The digraph to which we would like to calculate
71
    /// the \c ArborescenceMap.
72
    static ArborescenceMap *createArborescenceMap(const Digraph &digraph){
73
      return new ArborescenceMap(digraph);
74
    }
75

	
76
    /// \brief The type of the \c PredMap
77
    ///
78
    /// The type of the \c PredMap. It must confrom to the
79
    /// \ref concepts::WriteMap "WriteMap" concept, and its value type
80
    /// must be the \c Arc type of the digraph.
81
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
82

	
83
    /// \brief Instantiates a \c PredMap.
84
    ///
85
    /// This function instantiates a \c PredMap.
86
    /// \param digraph The digraph to which we would like to define the
87
    /// \c PredMap.
88
    static PredMap *createPredMap(const Digraph &digraph){
89
      return new PredMap(digraph);
90
    }
91

	
92
  };
93

	
94
  /// \ingroup spantree
95
  ///
96
  /// \brief Minimum Cost Arborescence algorithm class.
97
  ///
98
  /// This class provides an efficient implementation of the
99
  /// Minimum Cost Arborescence algorithm. The arborescence is a tree
100
  /// which is directed from a given source node of the digraph. One or
101
  /// more sources should be given to the algorithm and it will calculate
102
  /// the minimum cost subgraph that is the union of arborescences with the
103
  /// given sources and spans all the nodes which are reachable from the
104
  /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+e).
105
  ///
106
  /// The algorithm also provides an optimal dual solution, therefore
107
  /// the optimality of the solution can be checked.
108
  ///
109
  /// \param GR The digraph type the algorithm runs on.
110
  /// \param CM A read-only arc map storing the costs of the
111
  /// arcs. It is read once for each arc, so the map may involve in
112
  /// relatively time consuming process to compute the arc costs if
113
  /// it is necessary. The default map type is \ref
114
  /// concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
115
  /// \param TR Traits class to set various data types used
116
  /// by the algorithm. The default traits class is
117
  /// \ref MinCostArborescenceDefaultTraits
118
  /// "MinCostArborescenceDefaultTraits<GR, CM>".
119
#ifndef DOXYGEN
120
  template <typename GR,
121
            typename CM = typename GR::template ArcMap<int>,
122
            typename TR =
123
              MinCostArborescenceDefaultTraits<GR, CM> >
124
#else
125
  template <typename GR, typename CM, typedef TR>
126
#endif
127
  class MinCostArborescence {
128
  public:
129

	
130
    /// \brief The \ref MinCostArborescenceDefaultTraits "traits class" 
131
    /// of the algorithm. 
132
    typedef TR Traits;
133
    /// The type of the underlying digraph.
134
    typedef typename Traits::Digraph Digraph;
135
    /// The type of the map that stores the arc costs.
136
    typedef typename Traits::CostMap CostMap;
137
    ///The type of the costs of the arcs.
138
    typedef typename Traits::Value Value;
139
    ///The type of the predecessor map.
140
    typedef typename Traits::PredMap PredMap;
141
    ///The type of the map that stores which arcs are in the arborescence.
142
    typedef typename Traits::ArborescenceMap ArborescenceMap;
143

	
144
    typedef MinCostArborescence Create;
145

	
146
  private:
147

	
148
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
149

	
150
    struct CostArc {
151

	
152
      Arc arc;
153
      Value value;
154

	
155
      CostArc() {}
156
      CostArc(Arc _arc, Value _value) : arc(_arc), value(_value) {}
157

	
158
    };
159

	
160
    const Digraph *_digraph;
161
    const CostMap *_cost;
162

	
163
    PredMap *_pred;
164
    bool local_pred;
165

	
166
    ArborescenceMap *_arborescence;
167
    bool local_arborescence;
168

	
169
    typedef typename Digraph::template ArcMap<int> ArcOrder;
170
    ArcOrder *_arc_order;
171

	
172
    typedef typename Digraph::template NodeMap<int> NodeOrder;
173
    NodeOrder *_node_order;
174

	
175
    typedef typename Digraph::template NodeMap<CostArc> CostArcMap;
176
    CostArcMap *_cost_arcs;
177

	
178
    struct StackLevel {
179

	
180
      std::vector<CostArc> arcs;
181
      int node_level;
182

	
183
    };
184

	
185
    std::vector<StackLevel> level_stack;
186
    std::vector<Node> queue;
187

	
188
    typedef std::vector<typename Digraph::Node> DualNodeList;
189

	
190
    DualNodeList _dual_node_list;
191

	
192
    struct DualVariable {
193
      int begin, end;
194
      Value value;
195

	
196
      DualVariable(int _begin, int _end, Value _value)
197
        : begin(_begin), end(_end), value(_value) {}
198

	
199
    };
200

	
201
    typedef std::vector<DualVariable> DualVariables;
202

	
203
    DualVariables _dual_variables;
204

	
205
    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
206

	
207
    HeapCrossRef *_heap_cross_ref;
208

	
209
    typedef BinHeap<int, HeapCrossRef> Heap;
210

	
211
    Heap *_heap;
212

	
213
  protected:
214

	
215
    MinCostArborescence() {}
216

	
217
  private:
218

	
219
    void createStructures() {
220
      if (!_pred) {
221
        local_pred = true;
222
        _pred = Traits::createPredMap(*_digraph);
223
      }
224
      if (!_arborescence) {
225
        local_arborescence = true;
226
        _arborescence = Traits::createArborescenceMap(*_digraph);
227
      }
228
      if (!_arc_order) {
229
        _arc_order = new ArcOrder(*_digraph);
230
      }
231
      if (!_node_order) {
232
        _node_order = new NodeOrder(*_digraph);
233
      }
234
      if (!_cost_arcs) {
235
        _cost_arcs = new CostArcMap(*_digraph);
236
      }
237
      if (!_heap_cross_ref) {
238
        _heap_cross_ref = new HeapCrossRef(*_digraph, -1);
239
      }
240
      if (!_heap) {
241
        _heap = new Heap(*_heap_cross_ref);
242
      }
243
    }
244

	
245
    void destroyStructures() {
246
      if (local_arborescence) {
247
        delete _arborescence;
248
      }
249
      if (local_pred) {
250
        delete _pred;
251
      }
252
      if (_arc_order) {
253
        delete _arc_order;
254
      }
255
      if (_node_order) {
256
        delete _node_order;
257
      }
258
      if (_cost_arcs) {
259
        delete _cost_arcs;
260
      }
261
      if (_heap) {
262
        delete _heap;
263
      }
264
      if (_heap_cross_ref) {
265
        delete _heap_cross_ref;
266
      }
267
    }
268

	
269
    Arc prepare(Node node) {
270
      std::vector<Node> nodes;
271
      (*_node_order)[node] = _dual_node_list.size();
272
      StackLevel level;
273
      level.node_level = _dual_node_list.size();
274
      _dual_node_list.push_back(node);
275
      for (InArcIt it(*_digraph, node); it != INVALID; ++it) {
276
        Arc arc = it;
277
        Node source = _digraph->source(arc);
278
        Value value = (*_cost)[it];
279
        if (source == node || (*_node_order)[source] == -3) continue;
280
        if ((*_cost_arcs)[source].arc == INVALID) {
281
          (*_cost_arcs)[source].arc = arc;
282
          (*_cost_arcs)[source].value = value;
283
          nodes.push_back(source);
284
        } else {
285
          if ((*_cost_arcs)[source].value > value) {
286
            (*_cost_arcs)[source].arc = arc;
287
            (*_cost_arcs)[source].value = value;
288
          }
289
        }
290
      }
291
      CostArc minimum = (*_cost_arcs)[nodes[0]];
292
      for (int i = 1; i < int(nodes.size()); ++i) {
293
        if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
294
          minimum = (*_cost_arcs)[nodes[i]];
295
        }
296
      }
297
      (*_arc_order)[minimum.arc] = _dual_variables.size();
298
      DualVariable var(_dual_node_list.size() - 1,
299
                       _dual_node_list.size(), minimum.value);
300
      _dual_variables.push_back(var);
301
      for (int i = 0; i < int(nodes.size()); ++i) {
302
        (*_cost_arcs)[nodes[i]].value -= minimum.value;
303
        level.arcs.push_back((*_cost_arcs)[nodes[i]]);
304
        (*_cost_arcs)[nodes[i]].arc = INVALID;
305
      }
306
      level_stack.push_back(level);
307
      return minimum.arc;
308
    }
309

	
310
    Arc contract(Node node) {
311
      int node_bottom = bottom(node);
312
      std::vector<Node> nodes;
313
      while (!level_stack.empty() &&
314
             level_stack.back().node_level >= node_bottom) {
315
        for (int i = 0; i < int(level_stack.back().arcs.size()); ++i) {
316
          Arc arc = level_stack.back().arcs[i].arc;
317
          Node source = _digraph->source(arc);
318
          Value value = level_stack.back().arcs[i].value;
319
          if ((*_node_order)[source] >= node_bottom) continue;
320
          if ((*_cost_arcs)[source].arc == INVALID) {
321
            (*_cost_arcs)[source].arc = arc;
322
            (*_cost_arcs)[source].value = value;
323
            nodes.push_back(source);
324
          } else {
325
            if ((*_cost_arcs)[source].value > value) {
326
              (*_cost_arcs)[source].arc = arc;
327
              (*_cost_arcs)[source].value = value;
328
            }
329
          }
330
        }
331
        level_stack.pop_back();
332
      }
333
      CostArc minimum = (*_cost_arcs)[nodes[0]];
334
      for (int i = 1; i < int(nodes.size()); ++i) {
335
        if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
336
          minimum = (*_cost_arcs)[nodes[i]];
337
        }
338
      }
339
      (*_arc_order)[minimum.arc] = _dual_variables.size();
340
      DualVariable var(node_bottom, _dual_node_list.size(), minimum.value);
341
      _dual_variables.push_back(var);
342
      StackLevel level;
343
      level.node_level = node_bottom;
344
      for (int i = 0; i < int(nodes.size()); ++i) {
345
        (*_cost_arcs)[nodes[i]].value -= minimum.value;
346
        level.arcs.push_back((*_cost_arcs)[nodes[i]]);
347
        (*_cost_arcs)[nodes[i]].arc = INVALID;
348
      }
349
      level_stack.push_back(level);
350
      return minimum.arc;
351
    }
352

	
353
    int bottom(Node node) {
354
      int k = level_stack.size() - 1;
355
      while (level_stack[k].node_level > (*_node_order)[node]) {
356
        --k;
357
      }
358
      return level_stack[k].node_level;
359
    }
360

	
361
    void finalize(Arc arc) {
362
      Node node = _digraph->target(arc);
363
      _heap->push(node, (*_arc_order)[arc]);
364
      _pred->set(node, arc);
365
      while (!_heap->empty()) {
366
        Node source = _heap->top();
367
        _heap->pop();
368
        (*_node_order)[source] = -1;
369
        for (OutArcIt it(*_digraph, source); it != INVALID; ++it) {
370
          if ((*_arc_order)[it] < 0) continue;
371
          Node target = _digraph->target(it);
372
          switch(_heap->state(target)) {
373
          case Heap::PRE_HEAP:
374
            _heap->push(target, (*_arc_order)[it]);
375
            _pred->set(target, it);
376
            break;
377
          case Heap::IN_HEAP:
378
            if ((*_arc_order)[it] < (*_heap)[target]) {
379
              _heap->decrease(target, (*_arc_order)[it]);
380
              _pred->set(target, it);
381
            }
382
            break;
383
          case Heap::POST_HEAP:
384
            break;
385
          }
386
        }
387
        _arborescence->set((*_pred)[source], true);
388
      }
389
    }
390

	
391

	
392
  public:
393

	
394
    /// \name Named Template Parameters
395

	
396
    /// @{
397

	
398
    template <class T>
399
    struct SetArborescenceMapTraits : public Traits {
400
      typedef T ArborescenceMap;
401
      static ArborescenceMap *createArborescenceMap(const Digraph &)
402
      {
403
        LEMON_ASSERT(false, "ArborescenceMap is not initialized");
404
        return 0; // ignore warnings
405
      }
406
    };
407

	
408
    /// \brief \ref named-templ-param "Named parameter" for
409
    /// setting \c ArborescenceMap type
410
    ///
411
    /// \ref named-templ-param "Named parameter" for setting
412
    /// \c ArborescenceMap type.
413
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept,
414
    /// and its value type must be \c bool (or convertible).
415
    /// Initially it will be set to \c false on each arc,
416
    /// then it will be set on each arborescence arc once.
417
    template <class T>
418
    struct SetArborescenceMap
419
      : public MinCostArborescence<Digraph, CostMap,
420
                                   SetArborescenceMapTraits<T> > {
421
    };
422

	
423
    template <class T>
424
    struct SetPredMapTraits : public Traits {
425
      typedef T PredMap;
426
      static PredMap *createPredMap(const Digraph &)
427
      {
428
        LEMON_ASSERT(false, "PredMap is not initialized");
429
        return 0; // ignore warnings
430
      }
431
    };
432

	
433
    /// \brief \ref named-templ-param "Named parameter" for
434
    /// setting \c PredMap type
435
    ///
436
    /// \ref named-templ-param "Named parameter" for setting
437
    /// \c PredMap type.
438
    /// It must meet the \ref concepts::WriteMap "WriteMap" concept, 
439
    /// and its value type must be the \c Arc type of the digraph.
440
    template <class T>
441
    struct SetPredMap
442
      : public MinCostArborescence<Digraph, CostMap, SetPredMapTraits<T> > {
443
    };
444

	
445
    /// @}
446

	
447
    /// \brief Constructor.
448
    ///
449
    /// \param digraph The digraph the algorithm will run on.
450
    /// \param cost The cost map used by the algorithm.
451
    MinCostArborescence(const Digraph& digraph, const CostMap& cost)
452
      : _digraph(&digraph), _cost(&cost), _pred(0), local_pred(false),
453
        _arborescence(0), local_arborescence(false),
454
        _arc_order(0), _node_order(0), _cost_arcs(0),
455
        _heap_cross_ref(0), _heap(0) {}
456

	
457
    /// \brief Destructor.
458
    ~MinCostArborescence() {
459
      destroyStructures();
460
    }
461

	
462
    /// \brief Sets the arborescence map.
463
    ///
464
    /// Sets the arborescence map.
465
    /// \return <tt>(*this)</tt>
466
    MinCostArborescence& arborescenceMap(ArborescenceMap& m) {
467
      if (local_arborescence) {
468
        delete _arborescence;
469
      }
470
      local_arborescence = false;
471
      _arborescence = &m;
472
      return *this;
473
    }
474

	
475
    /// \brief Sets the predecessor map.
476
    ///
477
    /// Sets the predecessor map.
478
    /// \return <tt>(*this)</tt>
479
    MinCostArborescence& predMap(PredMap& m) {
480
      if (local_pred) {
481
        delete _pred;
482
      }
483
      local_pred = false;
484
      _pred = &m;
485
      return *this;
486
    }
487

	
488
    /// \name Execution Control
489
    /// The simplest way to execute the algorithm is to use
490
    /// one of the member functions called \c run(...). \n
491
    /// If you need more control on the execution,
492
    /// first you must call \ref init(), then you can add several
493
    /// source nodes with \ref addSource().
494
    /// Finally \ref start() will perform the arborescence
495
    /// computation.
496

	
497
    ///@{
498

	
499
    /// \brief Initializes the internal data structures.
500
    ///
501
    /// Initializes the internal data structures.
502
    ///
503
    void init() {
504
      createStructures();
505
      _heap->clear();
506
      for (NodeIt it(*_digraph); it != INVALID; ++it) {
507
        (*_cost_arcs)[it].arc = INVALID;
508
        (*_node_order)[it] = -3;
509
        (*_heap_cross_ref)[it] = Heap::PRE_HEAP;
510
        _pred->set(it, INVALID);
511
      }
512
      for (ArcIt it(*_digraph); it != INVALID; ++it) {
513
        _arborescence->set(it, false);
514
        (*_arc_order)[it] = -1;
515
      }
516
      _dual_node_list.clear();
517
      _dual_variables.clear();
518
    }
519

	
520
    /// \brief Adds a new source node.
521
    ///
522
    /// Adds a new source node to the algorithm.
523
    void addSource(Node source) {
524
      std::vector<Node> nodes;
525
      nodes.push_back(source);
526
      while (!nodes.empty()) {
527
        Node node = nodes.back();
528
        nodes.pop_back();
529
        for (OutArcIt it(*_digraph, node); it != INVALID; ++it) {
530
          Node target = _digraph->target(it);
531
          if ((*_node_order)[target] == -3) {
532
            (*_node_order)[target] = -2;
533
            nodes.push_back(target);
534
            queue.push_back(target);
535
          }
536
        }
537
      }
538
      (*_node_order)[source] = -1;
539
    }
540

	
541
    /// \brief Processes the next node in the priority queue.
542
    ///
543
    /// Processes the next node in the priority queue.
544
    ///
545
    /// \return The processed node.
546
    ///
547
    /// \warning The queue must not be empty.
548
    Node processNextNode() {
549
      Node node = queue.back();
550
      queue.pop_back();
551
      if ((*_node_order)[node] == -2) {
552
        Arc arc = prepare(node);
553
        Node source = _digraph->source(arc);
554
        while ((*_node_order)[source] != -1) {
555
          if ((*_node_order)[source] >= 0) {
556
            arc = contract(source);
557
          } else {
558
            arc = prepare(source);
559
          }
560
          source = _digraph->source(arc);
561
        }
562
        finalize(arc);
563
        level_stack.clear();
564
      }
565
      return node;
566
    }
567

	
568
    /// \brief Returns the number of the nodes to be processed.
569
    ///
570
    /// Returns the number of the nodes to be processed in the priority
571
    /// queue.
572
    int queueSize() const {
573
      return queue.size();
574
    }
575

	
576
    /// \brief Returns \c false if there are nodes to be processed.
577
    ///
578
    /// Returns \c false if there are nodes to be processed.
579
    bool emptyQueue() const {
580
      return queue.empty();
581
    }
582

	
583
    /// \brief Executes the algorithm.
584
    ///
585
    /// Executes the algorithm.
586
    ///
587
    /// \pre init() must be called and at least one node should be added
588
    /// with addSource() before using this function.
589
    ///
590
    ///\note mca.start() is just a shortcut of the following code.
591
    ///\code
592
    ///while (!mca.emptyQueue()) {
593
    ///  mca.processNextNode();
594
    ///}
595
    ///\endcode
596
    void start() {
597
      while (!emptyQueue()) {
598
        processNextNode();
599
      }
600
    }
601

	
602
    /// \brief Runs %MinCostArborescence algorithm from node \c s.
603
    ///
604
    /// This method runs the %MinCostArborescence algorithm from
605
    /// a root node \c s.
606
    ///
607
    /// \note mca.run(s) is just a shortcut of the following code.
608
    /// \code
609
    /// mca.init();
610
    /// mca.addSource(s);
611
    /// mca.start();
612
    /// \endcode
613
    void run(Node s) {
614
      init();
615
      addSource(s);
616
      start();
617
    }
618

	
619
    ///@}
620

	
621
    /// \name Query Functions
622
    /// The result of the %MinCostArborescence algorithm can be obtained
623
    /// using these functions.\n
624
    /// Either run() or start() must be called before using them.
625

	
626
    /// @{
627

	
628
    /// \brief Returns the cost of the arborescence.
629
    ///
630
    /// Returns the cost of the arborescence.
631
    Value arborescenceCost() const {
632
      Value sum = 0;
633
      for (ArcIt it(*_digraph); it != INVALID; ++it) {
634
        if (arborescence(it)) {
635
          sum += (*_cost)[it];
636
        }
637
      }
638
      return sum;
639
    }
640

	
641
    /// \brief Returns \c true if the arc is in the arborescence.
642
    ///
643
    /// Returns \c true if the given arc is in the arborescence.
644
    /// \param arc An arc of the digraph.
645
    /// \pre \ref run() must be called before using this function.
646
    bool arborescence(Arc arc) const {
647
      return (*_pred)[_digraph->target(arc)] == arc;
648
    }
649

	
650
    /// \brief Returns a const reference to the arborescence map.
651
    ///
652
    /// Returns a const reference to the arborescence map.
653
    /// \pre \ref run() must be called before using this function.
654
    const ArborescenceMap& arborescenceMap() const {
655
      return *_arborescence;
656
    }
657

	
658
    /// \brief Returns the predecessor arc of the given node.
659
    ///
660
    /// Returns the predecessor arc of the given node.
661
    /// \pre \ref run() must be called before using this function.
662
    Arc pred(Node node) const {
663
      return (*_pred)[node];
664
    }
665

	
666
    /// \brief Returns a const reference to the pred map.
667
    ///
668
    /// Returns a const reference to the pred map.
669
    /// \pre \ref run() must be called before using this function.
670
    const PredMap& predMap() const {
671
      return *_pred;
672
    }
673

	
674
    /// \brief Indicates that a node is reachable from the sources.
675
    ///
676
    /// Indicates that a node is reachable from the sources.
677
    bool reached(Node node) const {
678
      return (*_node_order)[node] != -3;
679
    }
680

	
681
    /// \brief Indicates that a node is processed.
682
    ///
683
    /// Indicates that a node is processed. The arborescence path exists
684
    /// from the source to the given node.
685
    bool processed(Node node) const {
686
      return (*_node_order)[node] == -1;
687
    }
688

	
689
    /// \brief Returns the number of the dual variables in basis.
690
    ///
691
    /// Returns the number of the dual variables in basis.
692
    int dualNum() const {
693
      return _dual_variables.size();
694
    }
695

	
696
    /// \brief Returns the value of the dual solution.
697
    ///
698
    /// Returns the value of the dual solution. It should be
699
    /// equal to the arborescence value.
700
    Value dualValue() const {
701
      Value sum = 0;
702
      for (int i = 0; i < int(_dual_variables.size()); ++i) {
703
        sum += _dual_variables[i].value;
704
      }
705
      return sum;
706
    }
707

	
708
    /// \brief Returns the number of the nodes in the dual variable.
709
    ///
710
    /// Returns the number of the nodes in the dual variable.
711
    int dualSize(int k) const {
712
      return _dual_variables[k].end - _dual_variables[k].begin;
713
    }
714

	
715
    /// \brief Returns the value of the dual variable.
716
    ///
717
    /// Returns the the value of the dual variable.
718
    Value dualValue(int k) const {
719
      return _dual_variables[k].value;
720
    }
721

	
722
    /// \brief LEMON iterator for getting a dual variable.
723
    ///
724
    /// This class provides a common style LEMON iterator for getting a
725
    /// dual variable of \ref MinCostArborescence algorithm.
726
    /// It iterates over a subset of the nodes.
727
    class DualIt {
728
    public:
729

	
730
      /// \brief Constructor.
731
      ///
732
      /// Constructor for getting the nodeset of the dual variable
733
      /// of \ref MinCostArborescence algorithm.
734
      DualIt(const MinCostArborescence& algorithm, int variable)
735
        : _algorithm(&algorithm)
736
      {
737
        _index = _algorithm->_dual_variables[variable].begin;
738
        _last = _algorithm->_dual_variables[variable].end;
739
      }
740

	
741
      /// \brief Conversion to \c Node.
742
      ///
743
      /// Conversion to \c Node.
744
      operator Node() const {
745
        return _algorithm->_dual_node_list[_index];
746
      }
747

	
748
      /// \brief Increment operator.
749
      ///
750
      /// Increment operator.
751
      DualIt& operator++() {
752
        ++_index;
753
        return *this;
754
      }
755

	
756
      /// \brief Validity checking
757
      ///
758
      /// Checks whether the iterator is invalid.
759
      bool operator==(Invalid) const {
760
        return _index == _last;
761
      }
762

	
763
      /// \brief Validity checking
764
      ///
765
      /// Checks whether the iterator is valid.
766
      bool operator!=(Invalid) const {
767
        return _index != _last;
768
      }
769

	
770
    private:
771
      const MinCostArborescence* _algorithm;
772
      int _index, _last;
773
    };
774

	
775
    /// @}
776

	
777
  };
778

	
779
  /// \ingroup spantree
780
  ///
781
  /// \brief Function type interface for MinCostArborescence algorithm.
782
  ///
783
  /// Function type interface for MinCostArborescence algorithm.
784
  /// \param digraph The digraph the algorithm runs on.
785
  /// \param cost An arc map storing the costs.
786
  /// \param source The source node of the arborescence.
787
  /// \retval arborescence An arc map with \c bool (or convertible) value
788
  /// type that stores the arborescence.
789
  /// \return The total cost of the arborescence.
790
  ///
791
  /// \sa MinCostArborescence
792
  template <typename Digraph, typename CostMap, typename ArborescenceMap>
793
  typename CostMap::Value minCostArborescence(const Digraph& digraph,
794
                                              const CostMap& cost,
795
                                              typename Digraph::Node source,
796
                                              ArborescenceMap& arborescence) {
797
    typename MinCostArborescence<Digraph, CostMap>
798
      ::template SetArborescenceMap<ArborescenceMap>
799
      ::Create mca(digraph, cost);
800
    mca.arborescenceMap(arborescence);
801
    mca.run(source);
802
    return mca.arborescenceCost();
803
  }
804

	
805
}
806

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

	
19
#ifndef LEMON_NAUTY_READER_H
20
#define LEMON_NAUTY_READER_H
21

	
22
#include <vector>
23
#include <iostream>
24
#include <string>
25

	
26
/// \ingroup nauty_group
27
/// \file
28
/// \brief Nauty file reader.
29

	
30
namespace lemon {
31

	
32
  /// \ingroup nauty_group
33
  ///
34
  /// \brief Nauty file reader
35
  ///
36
  /// The \e geng program is in the \e gtools suite of the nauty
37
  /// package. This tool can generate all non-isomorphic undirected
38
  /// graphs of several classes with given node number (e.g.
39
  /// general, connected, biconnected, triangle-free, 4-cycle-free,
40
  /// bipartite and graphs with given edge number and degree
41
  /// constraints). This function reads a \e nauty \e graph6 \e format
42
  /// line from the given stream and builds it in the given graph.
43
  ///
44
  /// The site of nauty package: http://cs.anu.edu.au/~bdm/nauty/
45
  ///
46
  /// For example, the number of all non-isomorphic planar graphs
47
  /// can be computed with the following code.
48
  ///\code
49
  /// int num = 0;
50
  /// SmartGraph graph;
51
  /// while (readNautyGraph(graph, std::cin)) {
52
  ///   PlanarityChecking<SmartGraph> pc(graph);
53
  ///   if (pc.run()) ++num;
54
  /// }
55
  /// std::cout << "Number of planar graphs: " << num << std::endl;
56
  ///\endcode
57
  ///
58
  /// The nauty files are quite huge, therefore instead of the direct
59
  /// file generation pipelining is recommended. For example,
60
  ///\code
61
  /// ./geng -c 10 | ./num_of_planar_graphs
62
  ///\endcode
63
  template <typename Graph>
64
  std::istream& readNautyGraph(Graph& graph, std::istream& is = std::cin) {
65
    graph.clear();
66

	
67
    std::string line;
68
    if (getline(is, line)) {
69
      int index = 0;
70

	
71
      int n;
72

	
73
      if (line[index] == '>') {
74
        index += 10;
75
      }
76

	
77
      char c = line[index++]; c -= 63;
78
      if (c != 63) {
79
        n = int(c);
80
      } else {
81
        c = line[index++]; c -= 63;
82
        n = (int(c) << 12);
83
        c = line[index++]; c -= 63;
84
        n |= (int(c) << 6);
85
        c = line[index++]; c -= 63;
86
        n |= int(c);
87
      }
88

	
89
      std::vector<typename Graph::Node> nodes;
90
      for (int i = 0; i < n; ++i) {
91
        nodes.push_back(graph.addNode());
92
      }
93

	
94
      int bit = -1;
95
      for (int j = 0; j < n; ++j) {
96
        for (int i = 0; i < j; ++i) {
97
          if (bit == -1) {
98
            c = line[index++]; c -= 63;
99
            bit = 5;
100
          }
101
          bool b = (c & (1 << (bit--))) != 0;
102

	
103
          if (b) {
104
            graph.addEdge(nodes[i], nodes[j]);
105
          }
106
        }
107
      }
108
    }
109
    return is;
110
  }
111
}
112

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

	
19
#ifndef LEMON_NETWORK_SIMPLEX_H
20
#define LEMON_NETWORK_SIMPLEX_H
21

	
22
/// \ingroup min_cost_flow_algs
23
///
24
/// \file
25
/// \brief Network Simplex algorithm for finding a minimum cost flow.
26

	
27
#include <vector>
28
#include <limits>
29
#include <algorithm>
30

	
31
#include <lemon/core.h>
32
#include <lemon/math.h>
33

	
34
namespace lemon {
35

	
36
  /// \addtogroup min_cost_flow_algs
37
  /// @{
38

	
39
  /// \brief Implementation of the primal Network Simplex algorithm
40
  /// for finding a \ref min_cost_flow "minimum cost flow".
41
  ///
42
  /// \ref NetworkSimplex implements the primal Network Simplex algorithm
43
  /// for finding a \ref min_cost_flow "minimum cost flow".
44
  /// This algorithm is a specialized version of the linear programming
45
  /// simplex method directly for the minimum cost flow problem.
46
  /// It is one of the most efficient solution methods.
47
  ///
48
  /// In general this class is the fastest implementation available
49
  /// in LEMON for the minimum cost flow problem.
50
  /// Moreover it supports both directions of the supply/demand inequality
51
  /// constraints. For more information see \ref SupplyType.
52
  ///
53
  /// Most of the parameters of the problem (except for the digraph)
54
  /// can be given using separate functions, and the algorithm can be
55
  /// executed using the \ref run() function. If some parameters are not
56
  /// specified, then default values will be used.
57
  ///
58
  /// \tparam GR The digraph type the algorithm runs on.
59
  /// \tparam V The value type used for flow amounts, capacity bounds
60
  /// and supply values in the algorithm. By default it is \c int.
61
  /// \tparam C The value type used for costs and potentials in the
62
  /// algorithm. By default it is the same as \c V.
63
  ///
64
  /// \warning Both value types must be signed and all input data must
65
  /// be integer.
66
  ///
67
  /// \note %NetworkSimplex provides five different pivot rule
68
  /// implementations, from which the most efficient one is used
69
  /// by default. For more information see \ref PivotRule.
70
  template <typename GR, typename V = int, typename C = V>
71
  class NetworkSimplex
72
  {
73
  public:
74

	
75
    /// The type of the flow amounts, capacity bounds and supply values
76
    typedef V Value;
77
    /// The type of the arc costs
78
    typedef C Cost;
79

	
80
  public:
81

	
82
    /// \brief Problem type constants for the \c run() function.
83
    ///
84
    /// Enum type containing the problem type constants that can be
85
    /// returned by the \ref run() function of the algorithm.
86
    enum ProblemType {
87
      /// The problem has no feasible solution (flow).
88
      INFEASIBLE,
89
      /// The problem has optimal solution (i.e. it is feasible and
90
      /// bounded), and the algorithm has found optimal flow and node
91
      /// potentials (primal and dual solutions).
92
      OPTIMAL,
93
      /// The objective function of the problem is unbounded, i.e.
94
      /// there is a directed cycle having negative total cost and
95
      /// infinite upper bound.
96
      UNBOUNDED
97
    };
98
    
99
    /// \brief Constants for selecting the type of the supply constraints.
100
    ///
101
    /// Enum type containing constants for selecting the supply type,
102
    /// i.e. the direction of the inequalities in the supply/demand
103
    /// constraints of the \ref min_cost_flow "minimum cost flow problem".
104
    ///
105
    /// The default supply type is \c GEQ, the \c LEQ type can be
106
    /// selected using \ref supplyType().
107
    /// The equality form is a special case of both supply types.
108
    enum SupplyType {
109
      /// This option means that there are <em>"greater or equal"</em>
110
      /// supply/demand constraints in the definition of the problem.
111
      GEQ,
112
      /// This option means that there are <em>"less or equal"</em>
113
      /// supply/demand constraints in the definition of the problem.
114
      LEQ
115
    };
116
    
117
    /// \brief Constants for selecting the pivot rule.
118
    ///
119
    /// Enum type containing constants for selecting the pivot rule for
120
    /// the \ref run() function.
121
    ///
122
    /// \ref NetworkSimplex provides five different pivot rule
123
    /// implementations that significantly affect the running time
124
    /// of the algorithm.
125
    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
126
    /// proved to be the most efficient and the most robust on various
127
    /// test inputs according to our benchmark tests.
128
    /// However another pivot rule can be selected using the \ref run()
129
    /// function with the proper parameter.
130
    enum PivotRule {
131

	
132
      /// The First Eligible pivot rule.
133
      /// The next eligible arc is selected in a wraparound fashion
134
      /// in every iteration.
135
      FIRST_ELIGIBLE,
136

	
137
      /// The Best Eligible pivot rule.
138
      /// The best eligible arc is selected in every iteration.
139
      BEST_ELIGIBLE,
140

	
141
      /// The Block Search pivot rule.
142
      /// A specified number of arcs are examined in every iteration
143
      /// in a wraparound fashion and the best eligible arc is selected
144
      /// from this block.
145
      BLOCK_SEARCH,
146

	
147
      /// The Candidate List pivot rule.
148
      /// In a major iteration a candidate list is built from eligible arcs
149
      /// in a wraparound fashion and in the following minor iterations
150
      /// the best eligible arc is selected from this list.
151
      CANDIDATE_LIST,
152

	
153
      /// The Altering Candidate List pivot rule.
154
      /// It is a modified version of the Candidate List method.
155
      /// It keeps only the several best eligible arcs from the former
156
      /// candidate list and extends this list in every iteration.
157
      ALTERING_LIST
158
    };
159
    
160
  private:
161

	
162
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
163

	
164
    typedef std::vector<Arc> ArcVector;
165
    typedef std::vector<Node> NodeVector;
166
    typedef std::vector<int> IntVector;
167
    typedef std::vector<bool> BoolVector;
168
    typedef std::vector<Value> ValueVector;
169
    typedef std::vector<Cost> CostVector;
170

	
171
    // State constants for arcs
172
    enum ArcStateEnum {
173
      STATE_UPPER = -1,
174
      STATE_TREE  =  0,
175
      STATE_LOWER =  1
176
    };
177

	
178
  private:
179

	
180
    // Data related to the underlying digraph
181
    const GR &_graph;
182
    int _node_num;
183
    int _arc_num;
184
    int _all_arc_num;
185
    int _search_arc_num;
186

	
187
    // Parameters of the problem
188
    bool _have_lower;
189
    SupplyType _stype;
190
    Value _sum_supply;
191

	
192
    // Data structures for storing the digraph
193
    IntNodeMap _node_id;
194
    IntArcMap _arc_id;
195
    IntVector _source;
196
    IntVector _target;
197

	
198
    // Node and arc data
199
    ValueVector _lower;
200
    ValueVector _upper;
201
    ValueVector _cap;
202
    CostVector _cost;
203
    ValueVector _supply;
204
    ValueVector _flow;
205
    CostVector _pi;
206

	
207
    // Data for storing the spanning tree structure
208
    IntVector _parent;
209
    IntVector _pred;
210
    IntVector _thread;
211
    IntVector _rev_thread;
212
    IntVector _succ_num;
213
    IntVector _last_succ;
214
    IntVector _dirty_revs;
215
    BoolVector _forward;
216
    IntVector _state;
217
    int _root;
218

	
219
    // Temporary data used in the current pivot iteration
220
    int in_arc, join, u_in, v_in, u_out, v_out;
221
    int first, second, right, last;
222
    int stem, par_stem, new_stem;
223
    Value delta;
224

	
225
  public:
226
  
227
    /// \brief Constant for infinite upper bounds (capacities).
228
    ///
229
    /// Constant for infinite upper bounds (capacities).
230
    /// It is \c std::numeric_limits<Value>::infinity() if available,
231
    /// \c std::numeric_limits<Value>::max() otherwise.
232
    const Value INF;
233

	
234
  private:
235

	
236
    // Implementation of the First Eligible pivot rule
237
    class FirstEligiblePivotRule
238
    {
239
    private:
240

	
241
      // References to the NetworkSimplex class
242
      const IntVector  &_source;
243
      const IntVector  &_target;
244
      const CostVector &_cost;
245
      const IntVector  &_state;
246
      const CostVector &_pi;
247
      int &_in_arc;
248
      int _search_arc_num;
249

	
250
      // Pivot rule data
251
      int _next_arc;
252

	
253
    public:
254

	
255
      // Constructor
256
      FirstEligiblePivotRule(NetworkSimplex &ns) :
257
        _source(ns._source), _target(ns._target),
258
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
259
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
260
        _next_arc(0)
261
      {}
262

	
263
      // Find next entering arc
264
      bool findEnteringArc() {
265
        Cost c;
266
        for (int e = _next_arc; e < _search_arc_num; ++e) {
267
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
268
          if (c < 0) {
269
            _in_arc = e;
270
            _next_arc = e + 1;
271
            return true;
272
          }
273
        }
274
        for (int e = 0; e < _next_arc; ++e) {
275
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
276
          if (c < 0) {
277
            _in_arc = e;
278
            _next_arc = e + 1;
279
            return true;
280
          }
281
        }
282
        return false;
283
      }
284

	
285
    }; //class FirstEligiblePivotRule
286

	
287

	
288
    // Implementation of the Best Eligible pivot rule
289
    class BestEligiblePivotRule
290
    {
291
    private:
292

	
293
      // References to the NetworkSimplex class
294
      const IntVector  &_source;
295
      const IntVector  &_target;
296
      const CostVector &_cost;
297
      const IntVector  &_state;
298
      const CostVector &_pi;
299
      int &_in_arc;
300
      int _search_arc_num;
301

	
302
    public:
303

	
304
      // Constructor
305
      BestEligiblePivotRule(NetworkSimplex &ns) :
306
        _source(ns._source), _target(ns._target),
307
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
308
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num)
309
      {}
310

	
311
      // Find next entering arc
312
      bool findEnteringArc() {
313
        Cost c, min = 0;
314
        for (int e = 0; e < _search_arc_num; ++e) {
315
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
316
          if (c < min) {
317
            min = c;
318
            _in_arc = e;
319
          }
320
        }
321
        return min < 0;
322
      }
323

	
324
    }; //class BestEligiblePivotRule
325

	
326

	
327
    // Implementation of the Block Search pivot rule
328
    class BlockSearchPivotRule
329
    {
330
    private:
331

	
332
      // References to the NetworkSimplex class
333
      const IntVector  &_source;
334
      const IntVector  &_target;
335
      const CostVector &_cost;
336
      const IntVector  &_state;
337
      const CostVector &_pi;
338
      int &_in_arc;
339
      int _search_arc_num;
340

	
341
      // Pivot rule data
342
      int _block_size;
343
      int _next_arc;
344

	
345
    public:
346

	
347
      // Constructor
348
      BlockSearchPivotRule(NetworkSimplex &ns) :
349
        _source(ns._source), _target(ns._target),
350
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
351
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
352
        _next_arc(0)
353
      {
354
        // The main parameters of the pivot rule
355
        const double BLOCK_SIZE_FACTOR = 0.5;
356
        const int MIN_BLOCK_SIZE = 10;
357

	
358
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
359
                                    std::sqrt(double(_search_arc_num))),
360
                                MIN_BLOCK_SIZE );
361
      }
362

	
363
      // Find next entering arc
364
      bool findEnteringArc() {
365
        Cost c, min = 0;
366
        int cnt = _block_size;
367
        int e, min_arc = _next_arc;
368
        for (e = _next_arc; e < _search_arc_num; ++e) {
369
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
370
          if (c < min) {
371
            min = c;
372
            min_arc = e;
373
          }
374
          if (--cnt == 0) {
375
            if (min < 0) break;
376
            cnt = _block_size;
377
          }
378
        }
379
        if (min == 0 || cnt > 0) {
380
          for (e = 0; e < _next_arc; ++e) {
381
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
382
            if (c < min) {
383
              min = c;
384
              min_arc = e;
385
            }
386
            if (--cnt == 0) {
387
              if (min < 0) break;
388
              cnt = _block_size;
389
            }
390
          }
391
        }
392
        if (min >= 0) return false;
393
        _in_arc = min_arc;
394
        _next_arc = e;
395
        return true;
396
      }
397

	
398
    }; //class BlockSearchPivotRule
399

	
400

	
401
    // Implementation of the Candidate List pivot rule
402
    class CandidateListPivotRule
403
    {
404
    private:
405

	
406
      // References to the NetworkSimplex class
407
      const IntVector  &_source;
408
      const IntVector  &_target;
409
      const CostVector &_cost;
410
      const IntVector  &_state;
411
      const CostVector &_pi;
412
      int &_in_arc;
413
      int _search_arc_num;
414

	
415
      // Pivot rule data
416
      IntVector _candidates;
417
      int _list_length, _minor_limit;
418
      int _curr_length, _minor_count;
419
      int _next_arc;
420

	
421
    public:
422

	
423
      /// Constructor
424
      CandidateListPivotRule(NetworkSimplex &ns) :
425
        _source(ns._source), _target(ns._target),
426
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
427
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
428
        _next_arc(0)
429
      {
430
        // The main parameters of the pivot rule
431
        const double LIST_LENGTH_FACTOR = 1.0;
432
        const int MIN_LIST_LENGTH = 10;
433
        const double MINOR_LIMIT_FACTOR = 0.1;
434
        const int MIN_MINOR_LIMIT = 3;
435

	
436
        _list_length = std::max( int(LIST_LENGTH_FACTOR *
437
                                     std::sqrt(double(_search_arc_num))),
438
                                 MIN_LIST_LENGTH );
439
        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
440
                                 MIN_MINOR_LIMIT );
441
        _curr_length = _minor_count = 0;
442
        _candidates.resize(_list_length);
443
      }
444

	
445
      /// Find next entering arc
446
      bool findEnteringArc() {
447
        Cost min, c;
448
        int e, min_arc = _next_arc;
449
        if (_curr_length > 0 && _minor_count < _minor_limit) {
450
          // Minor iteration: select the best eligible arc from the
451
          // current candidate list
452
          ++_minor_count;
453
          min = 0;
454
          for (int i = 0; i < _curr_length; ++i) {
455
            e = _candidates[i];
456
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
457
            if (c < min) {
458
              min = c;
459
              min_arc = e;
460
            }
461
            if (c >= 0) {
462
              _candidates[i--] = _candidates[--_curr_length];
463
            }
464
          }
465
          if (min < 0) {
466
            _in_arc = min_arc;
467
            return true;
468
          }
469
        }
470

	
471
        // Major iteration: build a new candidate list
472
        min = 0;
473
        _curr_length = 0;
474
        for (e = _next_arc; e < _search_arc_num; ++e) {
475
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
476
          if (c < 0) {
477
            _candidates[_curr_length++] = e;
478
            if (c < min) {
479
              min = c;
480
              min_arc = e;
481
            }
482
            if (_curr_length == _list_length) break;
483
          }
484
        }
485
        if (_curr_length < _list_length) {
486
          for (e = 0; e < _next_arc; ++e) {
487
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
488
            if (c < 0) {
489
              _candidates[_curr_length++] = e;
490
              if (c < min) {
491
                min = c;
492
                min_arc = e;
493
              }
494
              if (_curr_length == _list_length) break;
495
            }
496
          }
497
        }
498
        if (_curr_length == 0) return false;
499
        _minor_count = 1;
500
        _in_arc = min_arc;
501
        _next_arc = e;
502
        return true;
503
      }
504

	
505
    }; //class CandidateListPivotRule
506

	
507

	
508
    // Implementation of the Altering Candidate List pivot rule
509
    class AlteringListPivotRule
510
    {
511
    private:
512

	
513
      // References to the NetworkSimplex class
514
      const IntVector  &_source;
515
      const IntVector  &_target;
516
      const CostVector &_cost;
517
      const IntVector  &_state;
518
      const CostVector &_pi;
519
      int &_in_arc;
520
      int _search_arc_num;
521

	
522
      // Pivot rule data
523
      int _block_size, _head_length, _curr_length;
524
      int _next_arc;
525
      IntVector _candidates;
526
      CostVector _cand_cost;
527

	
528
      // Functor class to compare arcs during sort of the candidate list
529
      class SortFunc
530
      {
531
      private:
532
        const CostVector &_map;
533
      public:
534
        SortFunc(const CostVector &map) : _map(map) {}
535
        bool operator()(int left, int right) {
536
          return _map[left] > _map[right];
537
        }
538
      };
539

	
540
      SortFunc _sort_func;
541

	
542
    public:
543

	
544
      // Constructor
545
      AlteringListPivotRule(NetworkSimplex &ns) :
546
        _source(ns._source), _target(ns._target),
547
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
548
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
549
        _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
550
      {
551
        // The main parameters of the pivot rule
552
        const double BLOCK_SIZE_FACTOR = 1.5;
553
        const int MIN_BLOCK_SIZE = 10;
554
        const double HEAD_LENGTH_FACTOR = 0.1;
555
        const int MIN_HEAD_LENGTH = 3;
556

	
557
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
558
                                    std::sqrt(double(_search_arc_num))),
559
                                MIN_BLOCK_SIZE );
560
        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
561
                                 MIN_HEAD_LENGTH );
562
        _candidates.resize(_head_length + _block_size);
563
        _curr_length = 0;
564
      }
565

	
566
      // Find next entering arc
567
      bool findEnteringArc() {
568
        // Check the current candidate list
569
        int e;
570
        for (int i = 0; i < _curr_length; ++i) {
571
          e = _candidates[i];
572
          _cand_cost[e] = _state[e] *
573
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
574
          if (_cand_cost[e] >= 0) {
575
            _candidates[i--] = _candidates[--_curr_length];
576
          }
577
        }
578

	
579
        // Extend the list
580
        int cnt = _block_size;
581
        int last_arc = 0;
582
        int limit = _head_length;
583

	
584
        for (int e = _next_arc; e < _search_arc_num; ++e) {
585
          _cand_cost[e] = _state[e] *
586
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
587
          if (_cand_cost[e] < 0) {
588
            _candidates[_curr_length++] = e;
589
            last_arc = e;
590
          }
591
          if (--cnt == 0) {
592
            if (_curr_length > limit) break;
593
            limit = 0;
594
            cnt = _block_size;
595
          }
596
        }
597
        if (_curr_length <= limit) {
598
          for (int e = 0; e < _next_arc; ++e) {
599
            _cand_cost[e] = _state[e] *
600
              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
601
            if (_cand_cost[e] < 0) {
602
              _candidates[_curr_length++] = e;
603
              last_arc = e;
604
            }
605
            if (--cnt == 0) {
606
              if (_curr_length > limit) break;
607
              limit = 0;
608
              cnt = _block_size;
609
            }
610
          }
611
        }
612
        if (_curr_length == 0) return false;
613
        _next_arc = last_arc + 1;
614

	
615
        // Make heap of the candidate list (approximating a partial sort)
616
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
617
                   _sort_func );
618

	
619
        // Pop the first element of the heap
620
        _in_arc = _candidates[0];
621
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
622
                  _sort_func );
623
        _curr_length = std::min(_head_length, _curr_length - 1);
624
        return true;
625
      }
626

	
627
    }; //class AlteringListPivotRule
628

	
629
  public:
630

	
631
    /// \brief Constructor.
632
    ///
633
    /// The constructor of the class.
634
    ///
635
    /// \param graph The digraph the algorithm runs on.
636
    NetworkSimplex(const GR& graph) :
637
      _graph(graph), _node_id(graph), _arc_id(graph),
638
      INF(std::numeric_limits<Value>::has_infinity ?
639
          std::numeric_limits<Value>::infinity() :
640
          std::numeric_limits<Value>::max())
641
    {
642
      // Check the value types
643
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
644
        "The flow type of NetworkSimplex must be signed");
645
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
646
        "The cost type of NetworkSimplex must be signed");
647
        
648
      // Resize vectors
649
      _node_num = countNodes(_graph);
650
      _arc_num = countArcs(_graph);
651
      int all_node_num = _node_num + 1;
652
      int max_arc_num = _arc_num + 2 * _node_num;
653

	
654
      _source.resize(max_arc_num);
655
      _target.resize(max_arc_num);
656

	
657
      _lower.resize(_arc_num);
658
      _upper.resize(_arc_num);
659
      _cap.resize(max_arc_num);
660
      _cost.resize(max_arc_num);
661
      _supply.resize(all_node_num);
662
      _flow.resize(max_arc_num);
663
      _pi.resize(all_node_num);
664

	
665
      _parent.resize(all_node_num);
666
      _pred.resize(all_node_num);
667
      _forward.resize(all_node_num);
668
      _thread.resize(all_node_num);
669
      _rev_thread.resize(all_node_num);
670
      _succ_num.resize(all_node_num);
671
      _last_succ.resize(all_node_num);
672
      _state.resize(max_arc_num);
673

	
674
      // Copy the graph (store the arcs in a mixed order)
675
      int i = 0;
676
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
677
        _node_id[n] = i;
678
      }
679
      int k = std::max(int(std::sqrt(double(_arc_num))), 10);
680
      i = 0;
681
      for (ArcIt a(_graph); a != INVALID; ++a) {
682
        _arc_id[a] = i;
683
        _source[i] = _node_id[_graph.source(a)];
684
        _target[i] = _node_id[_graph.target(a)];
685
        if ((i += k) >= _arc_num) i = (i % k) + 1;
686
      }
687
      
688
      // Initialize maps
689
      for (int i = 0; i != _node_num; ++i) {
690
        _supply[i] = 0;
691
      }
692
      for (int i = 0; i != _arc_num; ++i) {
693
        _lower[i] = 0;
694
        _upper[i] = INF;
695
        _cost[i] = 1;
696
      }
697
      _have_lower = false;
698
      _stype = GEQ;
699
    }
700

	
701
    /// \name Parameters
702
    /// The parameters of the algorithm can be specified using these
703
    /// functions.
704

	
705
    /// @{
706

	
707
    /// \brief Set the lower bounds on the arcs.
708
    ///
709
    /// This function sets the lower bounds on the arcs.
710
    /// If it is not used before calling \ref run(), the lower bounds
711
    /// will be set to zero on all arcs.
712
    ///
713
    /// \param map An arc map storing the lower bounds.
714
    /// Its \c Value type must be convertible to the \c Value type
715
    /// of the algorithm.
716
    ///
717
    /// \return <tt>(*this)</tt>
718
    template <typename LowerMap>
719
    NetworkSimplex& lowerMap(const LowerMap& map) {
720
      _have_lower = true;
721
      for (ArcIt a(_graph); a != INVALID; ++a) {
722
        _lower[_arc_id[a]] = map[a];
723
      }
724
      return *this;
725
    }
726

	
727
    /// \brief Set the upper bounds (capacities) on the arcs.
728
    ///
729
    /// This function sets the upper bounds (capacities) on the arcs.
730
    /// If it is not used before calling \ref run(), the upper bounds
731
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
732
    /// unbounded from above on each arc).
733
    ///
734
    /// \param map An arc map storing the upper bounds.
735
    /// Its \c Value type must be convertible to the \c Value type
736
    /// of the algorithm.
737
    ///
738
    /// \return <tt>(*this)</tt>
739
    template<typename UpperMap>
740
    NetworkSimplex& upperMap(const UpperMap& map) {
741
      for (ArcIt a(_graph); a != INVALID; ++a) {
742
        _upper[_arc_id[a]] = map[a];
743
      }
744
      return *this;
745
    }
746

	
747
    /// \brief Set the costs of the arcs.
748
    ///
749
    /// This function sets the costs of the arcs.
750
    /// If it is not used before calling \ref run(), the costs
751
    /// will be set to \c 1 on all arcs.
752
    ///
753
    /// \param map An arc map storing the costs.
754
    /// Its \c Value type must be convertible to the \c Cost type
755
    /// of the algorithm.
756
    ///
757
    /// \return <tt>(*this)</tt>
758
    template<typename CostMap>
759
    NetworkSimplex& costMap(const CostMap& map) {
760
      for (ArcIt a(_graph); a != INVALID; ++a) {
761
        _cost[_arc_id[a]] = map[a];
762
      }
763
      return *this;
764
    }
765

	
766
    /// \brief Set the supply values of the nodes.
767
    ///
768
    /// This function sets the supply values of the nodes.
769
    /// If neither this function nor \ref stSupply() is used before
770
    /// calling \ref run(), the supply of each node will be set to zero.
771
    /// (It makes sense only if non-zero lower bounds are given.)
772
    ///
773
    /// \param map A node map storing the supply values.
774
    /// Its \c Value type must be convertible to the \c Value type
775
    /// of the algorithm.
776
    ///
777
    /// \return <tt>(*this)</tt>
778
    template<typename SupplyMap>
779
    NetworkSimplex& supplyMap(const SupplyMap& map) {
780
      for (NodeIt n(_graph); n != INVALID; ++n) {
781
        _supply[_node_id[n]] = map[n];
782
      }
783
      return *this;
784
    }
785

	
786
    /// \brief Set single source and target nodes and a supply value.
787
    ///
788
    /// This function sets a single source node and a single target node
789
    /// and the required flow value.
790
    /// If neither this function nor \ref supplyMap() is used before
791
    /// calling \ref run(), the supply of each node will be set to zero.
792
    /// (It makes sense only if non-zero lower bounds are given.)
793
    ///
794
    /// Using this function has the same effect as using \ref supplyMap()
795
    /// with such a map in which \c k is assigned to \c s, \c -k is
796
    /// assigned to \c t and all other nodes have zero supply value.
797
    ///
798
    /// \param s The source node.
799
    /// \param t The target node.
800
    /// \param k The required amount of flow from node \c s to node \c t
801
    /// (i.e. the supply of \c s and the demand of \c t).
802
    ///
803
    /// \return <tt>(*this)</tt>
804
    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
805
      for (int i = 0; i != _node_num; ++i) {
806
        _supply[i] = 0;
807
      }
808
      _supply[_node_id[s]] =  k;
809
      _supply[_node_id[t]] = -k;
810
      return *this;
811
    }
812
    
813
    /// \brief Set the type of the supply constraints.
814
    ///
815
    /// This function sets the type of the supply/demand constraints.
816
    /// If it is not used before calling \ref run(), the \ref GEQ supply
817
    /// type will be used.
818
    ///
819
    /// For more information see \ref SupplyType.
820
    ///
821
    /// \return <tt>(*this)</tt>
822
    NetworkSimplex& supplyType(SupplyType supply_type) {
823
      _stype = supply_type;
824
      return *this;
825
    }
826

	
827
    /// @}
828

	
829
    /// \name Execution Control
830
    /// The algorithm can be executed using \ref run().
831

	
832
    /// @{
833

	
834
    /// \brief Run the algorithm.
835
    ///
836
    /// This function runs the algorithm.
837
    /// The paramters can be specified using functions \ref lowerMap(),
838
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 
839
    /// \ref supplyType().
840
    /// For example,
841
    /// \code
842
    ///   NetworkSimplex<ListDigraph> ns(graph);
843
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
844
    ///     .supplyMap(sup).run();
845
    /// \endcode
846
    ///
847
    /// This function can be called more than once. All the parameters
848
    /// that have been given are kept for the next call, unless
849
    /// \ref reset() is called, thus only the modified parameters
850
    /// have to be set again. See \ref reset() for examples.
851
    /// However the underlying digraph must not be modified after this
852
    /// class have been constructed, since it copies and extends the graph.
853
    ///
854
    /// \param pivot_rule The pivot rule that will be used during the
855
    /// algorithm. For more information see \ref PivotRule.
856
    ///
857
    /// \return \c INFEASIBLE if no feasible flow exists,
858
    /// \n \c OPTIMAL if the problem has optimal solution
859
    /// (i.e. it is feasible and bounded), and the algorithm has found
860
    /// optimal flow and node potentials (primal and dual solutions),
861
    /// \n \c UNBOUNDED if the objective function of the problem is
862
    /// unbounded, i.e. there is a directed cycle having negative total
863
    /// cost and infinite upper bound.
864
    ///
865
    /// \see ProblemType, PivotRule
866
    ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
867
      if (!init()) return INFEASIBLE;
868
      return start(pivot_rule);
869
    }
870

	
871
    /// \brief Reset all the parameters that have been given before.
872
    ///
873
    /// This function resets all the paramaters that have been given
874
    /// before using functions \ref lowerMap(), \ref upperMap(),
875
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
876
    ///
877
    /// It is useful for multiple run() calls. If this function is not
878
    /// used, all the parameters given before are kept for the next
879
    /// \ref run() call.
880
    /// However the underlying digraph must not be modified after this
881
    /// class have been constructed, since it copies and extends the graph.
882
    ///
883
    /// For example,
884
    /// \code
885
    ///   NetworkSimplex<ListDigraph> ns(graph);
886
    ///
887
    ///   // First run
888
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
889
    ///     .supplyMap(sup).run();
890
    ///
891
    ///   // Run again with modified cost map (reset() is not called,
892
    ///   // so only the cost map have to be set again)
893
    ///   cost[e] += 100;
894
    ///   ns.costMap(cost).run();
895
    ///
896
    ///   // Run again from scratch using reset()
897
    ///   // (the lower bounds will be set to zero on all arcs)
898
    ///   ns.reset();
899
    ///   ns.upperMap(capacity).costMap(cost)
900
    ///     .supplyMap(sup).run();
901
    /// \endcode
902
    ///
903
    /// \return <tt>(*this)</tt>
904
    NetworkSimplex& reset() {
905
      for (int i = 0; i != _node_num; ++i) {
906
        _supply[i] = 0;
907
      }
908
      for (int i = 0; i != _arc_num; ++i) {
909
        _lower[i] = 0;
910
        _upper[i] = INF;
911
        _cost[i] = 1;
912
      }
913
      _have_lower = false;
914
      _stype = GEQ;
915
      return *this;
916
    }
917

	
918
    /// @}
919

	
920
    /// \name Query Functions
921
    /// The results of the algorithm can be obtained using these
922
    /// functions.\n
923
    /// The \ref run() function must be called before using them.
924

	
925
    /// @{
926

	
927
    /// \brief Return the total cost of the found flow.
928
    ///
929
    /// This function returns the total cost of the found flow.
930
    /// Its complexity is O(e).
931
    ///
932
    /// \note The return type of the function can be specified as a
933
    /// template parameter. For example,
934
    /// \code
935
    ///   ns.totalCost<double>();
936
    /// \endcode
937
    /// It is useful if the total cost cannot be stored in the \c Cost
938
    /// type of the algorithm, which is the default return type of the
939
    /// function.
940
    ///
941
    /// \pre \ref run() must be called before using this function.
942
    template <typename Number>
943
    Number totalCost() const {
944
      Number c = 0;
945
      for (ArcIt a(_graph); a != INVALID; ++a) {
946
        int i = _arc_id[a];
947
        c += Number(_flow[i]) * Number(_cost[i]);
948
      }
949
      return c;
950
    }
951

	
952
#ifndef DOXYGEN
953
    Cost totalCost() const {
954
      return totalCost<Cost>();
955
    }
956
#endif
957

	
958
    /// \brief Return the flow on the given arc.
959
    ///
960
    /// This function returns the flow on the given arc.
961
    ///
962
    /// \pre \ref run() must be called before using this function.
963
    Value flow(const Arc& a) const {
964
      return _flow[_arc_id[a]];
965
    }
966

	
967
    /// \brief Return the flow map (the primal solution).
968
    ///
969
    /// This function copies the flow value on each arc into the given
970
    /// map. The \c Value type of the algorithm must be convertible to
971
    /// the \c Value type of the map.
972
    ///
973
    /// \pre \ref run() must be called before using this function.
974
    template <typename FlowMap>
975
    void flowMap(FlowMap &map) const {
976
      for (ArcIt a(_graph); a != INVALID; ++a) {
977
        map.set(a, _flow[_arc_id[a]]);
978
      }
979
    }
980

	
981
    /// \brief Return the potential (dual value) of the given node.
982
    ///
983
    /// This function returns the potential (dual value) of the
984
    /// given node.
985
    ///
986
    /// \pre \ref run() must be called before using this function.
987
    Cost potential(const Node& n) const {
988
      return _pi[_node_id[n]];
989
    }
990

	
991
    /// \brief Return the potential map (the dual solution).
992
    ///
993
    /// This function copies the potential (dual value) of each node
994
    /// into the given map.
995
    /// The \c Cost type of the algorithm must be convertible to the
996
    /// \c Value type of the map.
997
    ///
998
    /// \pre \ref run() must be called before using this function.
999
    template <typename PotentialMap>
1000
    void potentialMap(PotentialMap &map) const {
1001
      for (NodeIt n(_graph); n != INVALID; ++n) {
1002
        map.set(n, _pi[_node_id[n]]);
1003
      }
1004
    }
1005

	
1006
    /// @}
1007

	
1008
  private:
1009

	
1010
    // Initialize internal data structures
1011
    bool init() {
1012
      if (_node_num == 0) return false;
1013

	
1014
      // Check the sum of supply values
1015
      _sum_supply = 0;
1016
      for (int i = 0; i != _node_num; ++i) {
1017
        _sum_supply += _supply[i];
1018
      }
1019
      if ( !((_stype == GEQ && _sum_supply <= 0) ||
1020
             (_stype == LEQ && _sum_supply >= 0)) ) return false;
1021

	
1022
      // Remove non-zero lower bounds
1023
      if (_have_lower) {
1024
        for (int i = 0; i != _arc_num; ++i) {
1025
          Value c = _lower[i];
1026
          if (c >= 0) {
1027
            _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
1028
          } else {
1029
            _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
1030
          }
1031
          _supply[_source[i]] -= c;
1032
          _supply[_target[i]] += c;
1033
        }
1034
      } else {
1035
        for (int i = 0; i != _arc_num; ++i) {
1036
          _cap[i] = _upper[i];
1037
        }
1038
      }
1039

	
1040
      // Initialize artifical cost
1041
      Cost ART_COST;
1042
      if (std::numeric_limits<Cost>::is_exact) {
1043
        ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
1044
      } else {
1045
        ART_COST = std::numeric_limits<Cost>::min();
1046
        for (int i = 0; i != _arc_num; ++i) {
1047
          if (_cost[i] > ART_COST) ART_COST = _cost[i];
1048
        }
1049
        ART_COST = (ART_COST + 1) * _node_num;
1050
      }
1051

	
1052
      // Initialize arc maps
1053
      for (int i = 0; i != _arc_num; ++i) {
1054
        _flow[i] = 0;
1055
        _state[i] = STATE_LOWER;
1056
      }
1057
      
1058
      // Set data for the artificial root node
1059
      _root = _node_num;
1060
      _parent[_root] = -1;
1061
      _pred[_root] = -1;
1062
      _thread[_root] = 0;
1063
      _rev_thread[0] = _root;
1064
      _succ_num[_root] = _node_num + 1;
1065
      _last_succ[_root] = _root - 1;
1066
      _supply[_root] = -_sum_supply;
1067
      _pi[_root] = 0;
1068

	
1069
      // Add artificial arcs and initialize the spanning tree data structure
1070
      if (_sum_supply == 0) {
1071
        // EQ supply constraints
1072
        _search_arc_num = _arc_num;
1073
        _all_arc_num = _arc_num + _node_num;
1074
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1075
          _parent[u] = _root;
1076
          _pred[u] = e;
1077
          _thread[u] = u + 1;
1078
          _rev_thread[u + 1] = u;
1079
          _succ_num[u] = 1;
1080
          _last_succ[u] = u;
1081
          _cap[e] = INF;
1082
          _state[e] = STATE_TREE;
1083
          if (_supply[u] >= 0) {
1084
            _forward[u] = true;
1085
            _pi[u] = 0;
1086
            _source[e] = u;
1087
            _target[e] = _root;
1088
            _flow[e] = _supply[u];
1089
            _cost[e] = 0;
1090
          } else {
1091
            _forward[u] = false;
1092
            _pi[u] = ART_COST;
1093
            _source[e] = _root;
1094
            _target[e] = u;
1095
            _flow[e] = -_supply[u];
1096
            _cost[e] = ART_COST;
1097
          }
1098
        }
1099
      }
1100
      else if (_sum_supply > 0) {
1101
        // LEQ supply constraints
1102
        _search_arc_num = _arc_num + _node_num;
1103
        int f = _arc_num + _node_num;
1104
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1105
          _parent[u] = _root;
1106
          _thread[u] = u + 1;
1107
          _rev_thread[u + 1] = u;
1108
          _succ_num[u] = 1;
1109
          _last_succ[u] = u;
1110
          if (_supply[u] >= 0) {
1111
            _forward[u] = true;
1112
            _pi[u] = 0;
1113
            _pred[u] = e;
1114
            _source[e] = u;
1115
            _target[e] = _root;
1116
            _cap[e] = INF;
1117
            _flow[e] = _supply[u];
1118
            _cost[e] = 0;
1119
            _state[e] = STATE_TREE;
1120
          } else {
1121
            _forward[u] = false;
1122
            _pi[u] = ART_COST;
1123
            _pred[u] = f;
1124
            _source[f] = _root;
1125
            _target[f] = u;
1126
            _cap[f] = INF;
1127
            _flow[f] = -_supply[u];
1128
            _cost[f] = ART_COST;
1129
            _state[f] = STATE_TREE;
1130
            _source[e] = u;
1131
            _target[e] = _root;
1132
            _cap[e] = INF;
1133
            _flow[e] = 0;
1134
            _cost[e] = 0;
1135
            _state[e] = STATE_LOWER;
1136
            ++f;
1137
          }
1138
        }
1139
        _all_arc_num = f;
1140
      }
1141
      else {
1142
        // GEQ supply constraints
1143
        _search_arc_num = _arc_num + _node_num;
1144
        int f = _arc_num + _node_num;
1145
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1146
          _parent[u] = _root;
1147
          _thread[u] = u + 1;
1148
          _rev_thread[u + 1] = u;
1149
          _succ_num[u] = 1;
1150
          _last_succ[u] = u;
1151
          if (_supply[u] <= 0) {
1152
            _forward[u] = false;
1153
            _pi[u] = 0;
1154
            _pred[u] = e;
1155
            _source[e] = _root;
1156
            _target[e] = u;
1157
            _cap[e] = INF;
1158
            _flow[e] = -_supply[u];
1159
            _cost[e] = 0;
1160
            _state[e] = STATE_TREE;
1161
          } else {
1162
            _forward[u] = true;
1163
            _pi[u] = -ART_COST;
1164
            _pred[u] = f;
1165
            _source[f] = u;
1166
            _target[f] = _root;
1167
            _cap[f] = INF;
1168
            _flow[f] = _supply[u];
1169
            _state[f] = STATE_TREE;
1170
            _cost[f] = ART_COST;
1171
            _source[e] = _root;
1172
            _target[e] = u;
1173
            _cap[e] = INF;
1174
            _flow[e] = 0;
1175
            _cost[e] = 0;
1176
            _state[e] = STATE_LOWER;
1177
            ++f;
1178
          }
1179
        }
1180
        _all_arc_num = f;
1181
      }
1182

	
1183
      return true;
1184
    }
1185

	
1186
    // Find the join node
1187
    void findJoinNode() {
1188
      int u = _source[in_arc];
1189
      int v = _target[in_arc];
1190
      while (u != v) {
1191
        if (_succ_num[u] < _succ_num[v]) {
1192
          u = _parent[u];
1193
        } else {
1194
          v = _parent[v];
1195
        }
1196
      }
1197
      join = u;
1198
    }
1199

	
1200
    // Find the leaving arc of the cycle and returns true if the
1201
    // leaving arc is not the same as the entering arc
1202
    bool findLeavingArc() {
1203
      // Initialize first and second nodes according to the direction
1204
      // of the cycle
1205
      if (_state[in_arc] == STATE_LOWER) {
1206
        first  = _source[in_arc];
1207
        second = _target[in_arc];
1208
      } else {
1209
        first  = _target[in_arc];
1210
        second = _source[in_arc];
1211
      }
1212
      delta = _cap[in_arc];
1213
      int result = 0;
1214
      Value d;
1215
      int e;
1216

	
1217
      // Search the cycle along the path form the first node to the root
1218
      for (int u = first; u != join; u = _parent[u]) {
1219
        e = _pred[u];
1220
        d = _forward[u] ?
1221
          _flow[e] : (_cap[e] == INF ? INF : _cap[e] - _flow[e]);
1222
        if (d < delta) {
1223
          delta = d;
1224
          u_out = u;
1225
          result = 1;
1226
        }
1227
      }
1228
      // Search the cycle along the path form the second node to the root
1229
      for (int u = second; u != join; u = _parent[u]) {
1230
        e = _pred[u];
1231
        d = _forward[u] ? 
1232
          (_cap[e] == INF ? INF : _cap[e] - _flow[e]) : _flow[e];
1233
        if (d <= delta) {
1234
          delta = d;
1235
          u_out = u;
1236
          result = 2;
1237
        }
1238
      }
1239

	
1240
      if (result == 1) {
1241
        u_in = first;
1242
        v_in = second;
1243
      } else {
1244
        u_in = second;
1245
        v_in = first;
1246
      }
1247
      return result != 0;
1248
    }
1249

	
1250
    // Change _flow and _state vectors
1251
    void changeFlow(bool change) {
1252
      // Augment along the cycle
1253
      if (delta > 0) {
1254
        Value val = _state[in_arc] * delta;
1255
        _flow[in_arc] += val;
1256
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
1257
          _flow[_pred[u]] += _forward[u] ? -val : val;
1258
        }
1259
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
1260
          _flow[_pred[u]] += _forward[u] ? val : -val;
1261
        }
1262
      }
1263
      // Update the state of the entering and leaving arcs
1264
      if (change) {
1265
        _state[in_arc] = STATE_TREE;
1266
        _state[_pred[u_out]] =
1267
          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
1268
      } else {
1269
        _state[in_arc] = -_state[in_arc];
1270
      }
1271
    }
1272

	
1273
    // Update the tree structure
1274
    void updateTreeStructure() {
1275
      int u, w;
1276
      int old_rev_thread = _rev_thread[u_out];
1277
      int old_succ_num = _succ_num[u_out];
1278
      int old_last_succ = _last_succ[u_out];
1279
      v_out = _parent[u_out];
1280

	
1281
      u = _last_succ[u_in];  // the last successor of u_in
1282
      right = _thread[u];    // the node after it
1283

	
1284
      // Handle the case when old_rev_thread equals to v_in
1285
      // (it also means that join and v_out coincide)
1286
      if (old_rev_thread == v_in) {
1287
        last = _thread[_last_succ[u_out]];
1288
      } else {
1289
        last = _thread[v_in];
1290
      }
1291

	
1292
      // Update _thread and _parent along the stem nodes (i.e. the nodes
1293
      // between u_in and u_out, whose parent have to be changed)
1294
      _thread[v_in] = stem = u_in;
1295
      _dirty_revs.clear();
1296
      _dirty_revs.push_back(v_in);
1297
      par_stem = v_in;
1298
      while (stem != u_out) {
1299
        // Insert the next stem node into the thread list
1300
        new_stem = _parent[stem];
1301
        _thread[u] = new_stem;
1302
        _dirty_revs.push_back(u);
1303

	
1304
        // Remove the subtree of stem from the thread list
1305
        w = _rev_thread[stem];
1306
        _thread[w] = right;
1307
        _rev_thread[right] = w;
1308

	
1309
        // Change the parent node and shift stem nodes
1310
        _parent[stem] = par_stem;
1311
        par_stem = stem;
1312
        stem = new_stem;
1313

	
1314
        // Update u and right
1315
        u = _last_succ[stem] == _last_succ[par_stem] ?
1316
          _rev_thread[par_stem] : _last_succ[stem];
1317
        right = _thread[u];
1318
      }
1319
      _parent[u_out] = par_stem;
1320
      _thread[u] = last;
1321
      _rev_thread[last] = u;
1322
      _last_succ[u_out] = u;
1323

	
1324
      // Remove the subtree of u_out from the thread list except for
1325
      // the case when old_rev_thread equals to v_in
1326
      // (it also means that join and v_out coincide)
1327
      if (old_rev_thread != v_in) {
1328
        _thread[old_rev_thread] = right;
1329
        _rev_thread[right] = old_rev_thread;
1330
      }
1331

	
1332
      // Update _rev_thread using the new _thread values
1333
      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
1334
        u = _dirty_revs[i];
1335
        _rev_thread[_thread[u]] = u;
1336
      }
1337

	
1338
      // Update _pred, _forward, _last_succ and _succ_num for the
1339
      // stem nodes from u_out to u_in
1340
      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
1341
      u = u_out;
1342
      while (u != u_in) {
1343
        w = _parent[u];
1344
        _pred[u] = _pred[w];
1345
        _forward[u] = !_forward[w];
1346
        tmp_sc += _succ_num[u] - _succ_num[w];
1347
        _succ_num[u] = tmp_sc;
1348
        _last_succ[w] = tmp_ls;
1349
        u = w;
1350
      }
1351
      _pred[u_in] = in_arc;
1352
      _forward[u_in] = (u_in == _source[in_arc]);
1353
      _succ_num[u_in] = old_succ_num;
1354

	
1355
      // Set limits for updating _last_succ form v_in and v_out
1356
      // towards the root
1357
      int up_limit_in = -1;
1358
      int up_limit_out = -1;
1359
      if (_last_succ[join] == v_in) {
1360
        up_limit_out = join;
1361
      } else {
1362
        up_limit_in = join;
1363
      }
1364

	
1365
      // Update _last_succ from v_in towards the root
1366
      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
1367
           u = _parent[u]) {
1368
        _last_succ[u] = _last_succ[u_out];
1369
      }
1370
      // Update _last_succ from v_out towards the root
1371
      if (join != old_rev_thread && v_in != old_rev_thread) {
1372
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1373
             u = _parent[u]) {
1374
          _last_succ[u] = old_rev_thread;
1375
        }
1376
      } else {
1377
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1378
             u = _parent[u]) {
1379
          _last_succ[u] = _last_succ[u_out];
1380
        }
1381
      }
1382

	
1383
      // Update _succ_num from v_in to join
1384
      for (u = v_in; u != join; u = _parent[u]) {
1385
        _succ_num[u] += old_succ_num;
1386
      }
1387
      // Update _succ_num from v_out to join
1388
      for (u = v_out; u != join; u = _parent[u]) {
1389
        _succ_num[u] -= old_succ_num;
1390
      }
1391
    }
1392

	
1393
    // Update potentials
1394
    void updatePotential() {
1395
      Cost sigma = _forward[u_in] ?
1396
        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
1397
        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
1398
      // Update potentials in the subtree, which has been moved
1399
      int end = _thread[_last_succ[u_in]];
1400
      for (int u = u_in; u != end; u = _thread[u]) {
1401
        _pi[u] += sigma;
1402
      }
1403
    }
1404

	
1405
    // Execute the algorithm
1406
    ProblemType start(PivotRule pivot_rule) {
1407
      // Select the pivot rule implementation
1408
      switch (pivot_rule) {
1409
        case FIRST_ELIGIBLE:
1410
          return start<FirstEligiblePivotRule>();
1411
        case BEST_ELIGIBLE:
1412
          return start<BestEligiblePivotRule>();
1413
        case BLOCK_SEARCH:
1414
          return start<BlockSearchPivotRule>();
1415
        case CANDIDATE_LIST:
1416
          return start<CandidateListPivotRule>();
1417
        case ALTERING_LIST:
1418
          return start<AlteringListPivotRule>();
1419
      }
1420
      return INFEASIBLE; // avoid warning
1421
    }
1422

	
1423
    template <typename PivotRuleImpl>
1424
    ProblemType start() {
1425
      PivotRuleImpl pivot(*this);
1426

	
1427
      // Execute the Network Simplex algorithm
1428
      while (pivot.findEnteringArc()) {
1429
        findJoinNode();
1430
        bool change = findLeavingArc();
1431
        if (delta >= INF) return UNBOUNDED;
1432
        changeFlow(change);
1433
        if (change) {
1434
          updateTreeStructure();
1435
          updatePotential();
1436
        }
1437
      }
1438
      
1439
      // Check feasibility
1440
      for (int e = _search_arc_num; e != _all_arc_num; ++e) {
1441
        if (_flow[e] != 0) return INFEASIBLE;
1442
      }
1443

	
1444
      // Transform the solution and the supply map to the original form
1445
      if (_have_lower) {
1446
        for (int i = 0; i != _arc_num; ++i) {
1447
          Value c = _lower[i];
1448
          if (c != 0) {
1449
            _flow[i] += c;
1450
            _supply[_source[i]] += c;
1451
            _supply[_target[i]] -= c;
1452
          }
1453
        }
1454
      }
1455
      
1456
      // Shift potentials to meet the requirements of the GEQ/LEQ type
1457
      // optimality conditions
1458
      if (_sum_supply == 0) {
1459
        if (_stype == GEQ) {
1460
          Cost max_pot = std::numeric_limits<Cost>::min();
1461
          for (int i = 0; i != _node_num; ++i) {
1462
            if (_pi[i] > max_pot) max_pot = _pi[i];
1463
          }
1464
          if (max_pot > 0) {
1465
            for (int i = 0; i != _node_num; ++i)
1466
              _pi[i] -= max_pot;
1467
          }
1468
        } else {
1469
          Cost min_pot = std::numeric_limits<Cost>::max();
1470
          for (int i = 0; i != _node_num; ++i) {
1471
            if (_pi[i] < min_pot) min_pot = _pi[i];
1472
          }
1473
          if (min_pot < 0) {
1474
            for (int i = 0; i != _node_num; ++i)
1475
              _pi[i] -= min_pot;
1476
          }
1477
        }
1478
      }
1479

	
1480
      return OPTIMAL;
1481
    }
1482

	
1483
  }; //class NetworkSimplex
1484

	
1485
  ///@}
1486

	
1487
} //namespace lemon
1488

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

	
19
#ifndef LEMON_PREFLOW_H
20
#define LEMON_PREFLOW_H
21

	
22
#include <lemon/tolerance.h>
23
#include <lemon/elevator.h>
24

	
25
/// \file
26
/// \ingroup max_flow
27
/// \brief Implementation of the preflow algorithm.
28

	
29
namespace lemon {
30

	
31
  /// \brief Default traits class of Preflow class.
32
  ///
33
  /// Default traits class of Preflow class.
34
  /// \tparam GR Digraph type.
35
  /// \tparam CAP Capacity map type.
36
  template <typename GR, typename CAP>
37
  struct PreflowDefaultTraits {
38

	
39
    /// \brief The type of the digraph the algorithm runs on.
40
    typedef GR Digraph;
41

	
42
    /// \brief The type of the map that stores the arc capacities.
43
    ///
44
    /// The type of the map that stores the arc capacities.
45
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
46
    typedef CAP CapacityMap;
47

	
48
    /// \brief The type of the flow values.
49
    typedef typename CapacityMap::Value Value;
50

	
51
    /// \brief The type of the map that stores the flow values.
52
    ///
53
    /// The type of the map that stores the flow values.
54
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
55
    typedef typename Digraph::template ArcMap<Value> FlowMap;
56

	
57
    /// \brief Instantiates a FlowMap.
58
    ///
59
    /// This function instantiates a \ref FlowMap.
60
    /// \param digraph The digraph for which we would like to define
61
    /// the flow map.
62
    static FlowMap* createFlowMap(const Digraph& digraph) {
63
      return new FlowMap(digraph);
64
    }
65

	
66
    /// \brief The elevator type used by Preflow algorithm.
67
    ///
68
    /// The elevator type used by Preflow algorithm.
69
    ///
70
    /// \sa Elevator
71
    /// \sa LinkedElevator
72
    typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
73

	
74
    /// \brief Instantiates an Elevator.
75
    ///
76
    /// This function instantiates an \ref Elevator.
77
    /// \param digraph The digraph for which we would like to define
78
    /// the elevator.
79
    /// \param max_level The maximum level of the elevator.
80
    static Elevator* createElevator(const Digraph& digraph, int max_level) {
81
      return new Elevator(digraph, max_level);
82
    }
83

	
84
    /// \brief The tolerance used by the algorithm
85
    ///
86
    /// The tolerance used by the algorithm to handle inexact computation.
87
    typedef lemon::Tolerance<Value> Tolerance;
88

	
89
  };
90

	
91

	
92
  /// \ingroup max_flow
93
  ///
94
  /// \brief %Preflow algorithm class.
95
  ///
96
  /// This class provides an implementation of Goldberg-Tarjan's \e preflow
97
  /// \e push-relabel algorithm producing a \ref max_flow
98
  /// "flow of maximum value" in a digraph.
99
  /// The preflow algorithms are the fastest known maximum
100
  /// flow algorithms. The current implementation use a mixture of the
101
  /// \e "highest label" and the \e "bound decrease" heuristics.
102
  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
103
  ///
104
  /// The algorithm consists of two phases. After the first phase
105
  /// the maximum flow value and the minimum cut is obtained. The
106
  /// second phase constructs a feasible maximum flow on each arc.
107
  ///
108
  /// \tparam GR The type of the digraph the algorithm runs on.
109
  /// \tparam CAP The type of the capacity map. The default map
110
  /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
111
#ifdef DOXYGEN
112
  template <typename GR, typename CAP, typename TR>
113
#else
114
  template <typename GR,
115
            typename CAP = typename GR::template ArcMap<int>,
116
            typename TR = PreflowDefaultTraits<GR, CAP> >
117
#endif
118
  class Preflow {
119
  public:
120

	
121
    ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
122
    typedef TR Traits;
123
    ///The type of the digraph the algorithm runs on.
124
    typedef typename Traits::Digraph Digraph;
125
    ///The type of the capacity map.
126
    typedef typename Traits::CapacityMap CapacityMap;
127
    ///The type of the flow values.
128
    typedef typename Traits::Value Value;
129

	
130
    ///The type of the flow map.
131
    typedef typename Traits::FlowMap FlowMap;
132
    ///The type of the elevator.
133
    typedef typename Traits::Elevator Elevator;
134
    ///The type of the tolerance.
135
    typedef typename Traits::Tolerance Tolerance;
136

	
137
  private:
138

	
139
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
140

	
141
    const Digraph& _graph;
142
    const CapacityMap* _capacity;
143

	
144
    int _node_num;
145

	
146
    Node _source, _target;
147

	
148
    FlowMap* _flow;
149
    bool _local_flow;
150

	
151
    Elevator* _level;
152
    bool _local_level;
153

	
154
    typedef typename Digraph::template NodeMap<Value> ExcessMap;
155
    ExcessMap* _excess;
156

	
157
    Tolerance _tolerance;
158

	
159
    bool _phase;
160

	
161

	
162
    void createStructures() {
163
      _node_num = countNodes(_graph);
164

	
165
      if (!_flow) {
166
        _flow = Traits::createFlowMap(_graph);
167
        _local_flow = true;
168
      }
169
      if (!_level) {
170
        _level = Traits::createElevator(_graph, _node_num);
171
        _local_level = true;
172
      }
173
      if (!_excess) {
174
        _excess = new ExcessMap(_graph);
175
      }
176
    }
177

	
178
    void destroyStructures() {
179
      if (_local_flow) {
180
        delete _flow;
181
      }
182
      if (_local_level) {
183
        delete _level;
184
      }
185
      if (_excess) {
186
        delete _excess;
187
      }
188
    }
189

	
190
  public:
191

	
192
    typedef Preflow Create;
193

	
194
    ///\name Named Template Parameters
195

	
196
    ///@{
197

	
198
    template <typename T>
199
    struct SetFlowMapTraits : public Traits {
200
      typedef T FlowMap;
201
      static FlowMap *createFlowMap(const Digraph&) {
202
        LEMON_ASSERT(false, "FlowMap is not initialized");
203
        return 0; // ignore warnings
204
      }
205
    };
206

	
207
    /// \brief \ref named-templ-param "Named parameter" for setting
208
    /// FlowMap type
209
    ///
210
    /// \ref named-templ-param "Named parameter" for setting FlowMap
211
    /// type.
212
    template <typename T>
213
    struct SetFlowMap
214
      : public Preflow<Digraph, CapacityMap, SetFlowMapTraits<T> > {
215
      typedef Preflow<Digraph, CapacityMap,
216
                      SetFlowMapTraits<T> > Create;
217
    };
218

	
219
    template <typename T>
220
    struct SetElevatorTraits : public Traits {
221
      typedef T Elevator;
222
      static Elevator *createElevator(const Digraph&, int) {
223
        LEMON_ASSERT(false, "Elevator is not initialized");
224
        return 0; // ignore warnings
225
      }
226
    };
227

	
228
    /// \brief \ref named-templ-param "Named parameter" for setting
229
    /// Elevator type
230
    ///
231
    /// \ref named-templ-param "Named parameter" for setting Elevator
232
    /// type. If this named parameter is used, then an external
233
    /// elevator object must be passed to the algorithm using the
234
    /// \ref elevator(Elevator&) "elevator()" function before calling
235
    /// \ref run() or \ref init().
236
    /// \sa SetStandardElevator
237
    template <typename T>
238
    struct SetElevator
239
      : public Preflow<Digraph, CapacityMap, SetElevatorTraits<T> > {
240
      typedef Preflow<Digraph, CapacityMap,
241
                      SetElevatorTraits<T> > Create;
242
    };
243

	
244
    template <typename T>
245
    struct SetStandardElevatorTraits : public Traits {
246
      typedef T Elevator;
247
      static Elevator *createElevator(const Digraph& digraph, int max_level) {
248
        return new Elevator(digraph, max_level);
249
      }
250
    };
251

	
252
    /// \brief \ref named-templ-param "Named parameter" for setting
253
    /// Elevator type with automatic allocation
254
    ///
255
    /// \ref named-templ-param "Named parameter" for setting Elevator
256
    /// type with automatic allocation.
257
    /// The Elevator should have standard constructor interface to be
258
    /// able to automatically created by the algorithm (i.e. the
259
    /// digraph and the maximum level should be passed to it).
260
    /// However an external elevator object could also be passed to the
261
    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
262
    /// before calling \ref run() or \ref init().
263
    /// \sa SetElevator
264
    template <typename T>
265
    struct SetStandardElevator
266
      : public Preflow<Digraph, CapacityMap,
267
                       SetStandardElevatorTraits<T> > {
268
      typedef Preflow<Digraph, CapacityMap,
269
                      SetStandardElevatorTraits<T> > Create;
270
    };
271

	
272
    /// @}
273

	
274
  protected:
275

	
276
    Preflow() {}
277

	
278
  public:
279

	
280

	
281
    /// \brief The constructor of the class.
282
    ///
283
    /// The constructor of the class.
284
    /// \param digraph The digraph the algorithm runs on.
285
    /// \param capacity The capacity of the arcs.
286
    /// \param source The source node.
287
    /// \param target The target node.
288
    Preflow(const Digraph& digraph, const CapacityMap& capacity,
289
            Node source, Node target)
290
      : _graph(digraph), _capacity(&capacity),
291
        _node_num(0), _source(source), _target(target),
292
        _flow(0), _local_flow(false),
293
        _level(0), _local_level(false),
294
        _excess(0), _tolerance(), _phase() {}
295

	
296
    /// \brief Destructor.
297
    ///
298
    /// Destructor.
299
    ~Preflow() {
300
      destroyStructures();
301
    }
302

	
303
    /// \brief Sets the capacity map.
304
    ///
305
    /// Sets the capacity map.
306
    /// \return <tt>(*this)</tt>
307
    Preflow& capacityMap(const CapacityMap& map) {
308
      _capacity = &map;
309
      return *this;
310
    }
311

	
312
    /// \brief Sets the flow map.
313
    ///
314
    /// Sets the flow map.
315
    /// If you don't use this function before calling \ref run() or
316
    /// \ref init(), an instance will be allocated automatically.
317
    /// The destructor deallocates this automatically allocated map,
318
    /// of course.
319
    /// \return <tt>(*this)</tt>
320
    Preflow& flowMap(FlowMap& map) {
321
      if (_local_flow) {
322
        delete _flow;
323
        _local_flow = false;
324
      }
325
      _flow = &map;
326
      return *this;
327
    }
328

	
329
    /// \brief Sets the source node.
330
    ///
331
    /// Sets the source node.
332
    /// \return <tt>(*this)</tt>
333
    Preflow& source(const Node& node) {
334
      _source = node;
335
      return *this;
336
    }
337

	
338
    /// \brief Sets the target node.
339
    ///
340
    /// Sets the target node.
341
    /// \return <tt>(*this)</tt>
342
    Preflow& target(const Node& node) {
343
      _target = node;
344
      return *this;
345
    }
346

	
347
    /// \brief Sets the elevator used by algorithm.
348
    ///
349
    /// Sets the elevator used by algorithm.
350
    /// If you don't use this function before calling \ref run() or
351
    /// \ref init(), an instance will be allocated automatically.
352
    /// The destructor deallocates this automatically allocated elevator,
353
    /// of course.
354
    /// \return <tt>(*this)</tt>
355
    Preflow& elevator(Elevator& elevator) {
356
      if (_local_level) {
357
        delete _level;
358
        _local_level = false;
359
      }
360
      _level = &elevator;
361
      return *this;
362
    }
363

	
364
    /// \brief Returns a const reference to the elevator.
365
    ///
366
    /// Returns a const reference to the elevator.
367
    ///
368
    /// \pre Either \ref run() or \ref init() must be called before
369
    /// using this function.
370
    const Elevator& elevator() const {
371
      return *_level;
372
    }
373

	
374
    /// \brief Sets the tolerance used by algorithm.
375
    ///
376
    /// Sets the tolerance used by algorithm.
377
    Preflow& tolerance(const Tolerance& tolerance) const {
378
      _tolerance = tolerance;
379
      return *this;
380
    }
381

	
382
    /// \brief Returns a const reference to the tolerance.
383
    ///
384
    /// Returns a const reference to the tolerance.
385
    const Tolerance& tolerance() const {
386
      return tolerance;
387
    }
388

	
389
    /// \name Execution Control
390
    /// The simplest way to execute the preflow algorithm is to use
391
    /// \ref run() or \ref runMinCut().\n
392
    /// If you need more control on the initial solution or the execution,
393
    /// first you have to call one of the \ref init() functions, then
394
    /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
395

	
396
    ///@{
397

	
398
    /// \brief Initializes the internal data structures.
399
    ///
400
    /// Initializes the internal data structures and sets the initial
401
    /// flow to zero on each arc.
402
    void init() {
403
      createStructures();
404

	
405
      _phase = true;
406
      for (NodeIt n(_graph); n != INVALID; ++n) {
407
        (*_excess)[n] = 0;
408
      }
409

	
410
      for (ArcIt e(_graph); e != INVALID; ++e) {
411
        _flow->set(e, 0);
412
      }
413

	
414
      typename Digraph::template NodeMap<bool> reached(_graph, false);
415

	
416
      _level->initStart();
417
      _level->initAddItem(_target);
418

	
419
      std::vector<Node> queue;
420
      reached[_source] = true;
421

	
422
      queue.push_back(_target);
423
      reached[_target] = true;
424
      while (!queue.empty()) {
425
        _level->initNewLevel();
426
        std::vector<Node> nqueue;
427
        for (int i = 0; i < int(queue.size()); ++i) {
428
          Node n = queue[i];
429
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
430
            Node u = _graph.source(e);
431
            if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
432
              reached[u] = true;
433
              _level->initAddItem(u);
434
              nqueue.push_back(u);
435
            }
436
          }
437
        }
438
        queue.swap(nqueue);
439
      }
440
      _level->initFinish();
441

	
442
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
443
        if (_tolerance.positive((*_capacity)[e])) {
444
          Node u = _graph.target(e);
445
          if ((*_level)[u] == _level->maxLevel()) continue;
446
          _flow->set(e, (*_capacity)[e]);
447
          (*_excess)[u] += (*_capacity)[e];
448
          if (u != _target && !_level->active(u)) {
449
            _level->activate(u);
450
          }
451
        }
452
      }
453
    }
454

	
455
    /// \brief Initializes the internal data structures using the
456
    /// given flow map.
457
    ///
458
    /// Initializes the internal data structures and sets the initial
459
    /// flow to the given \c flowMap. The \c flowMap should contain a
460
    /// flow or at least a preflow, i.e. at each node excluding the
461
    /// source node the incoming flow should greater or equal to the
462
    /// outgoing flow.
463
    /// \return \c false if the given \c flowMap is not a preflow.
464
    template <typename FlowMap>
465
    bool init(const FlowMap& flowMap) {
466
      createStructures();
467

	
468
      for (ArcIt e(_graph); e != INVALID; ++e) {
469
        _flow->set(e, flowMap[e]);
470
      }
471

	
472
      for (NodeIt n(_graph); n != INVALID; ++n) {
473
        Value excess = 0;
474
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
475
          excess += (*_flow)[e];
476
        }
477
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
478
          excess -= (*_flow)[e];
479
        }
480
        if (excess < 0 && n != _source) return false;
481
        (*_excess)[n] = excess;
482
      }
483

	
484
      typename Digraph::template NodeMap<bool> reached(_graph, false);
485

	
486
      _level->initStart();
487
      _level->initAddItem(_target);
488

	
489
      std::vector<Node> queue;
490
      reached[_source] = true;
491

	
492
      queue.push_back(_target);
493
      reached[_target] = true;
494
      while (!queue.empty()) {
495
        _level->initNewLevel();
496
        std::vector<Node> nqueue;
497
        for (int i = 0; i < int(queue.size()); ++i) {
498
          Node n = queue[i];
499
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
500
            Node u = _graph.source(e);
501
            if (!reached[u] &&
502
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
503
              reached[u] = true;
504
              _level->initAddItem(u);
505
              nqueue.push_back(u);
506
            }
507
          }
508
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
509
            Node v = _graph.target(e);
510
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
511
              reached[v] = true;
512
              _level->initAddItem(v);
513
              nqueue.push_back(v);
514
            }
515
          }
516
        }
517
        queue.swap(nqueue);
518
      }
519
      _level->initFinish();
520

	
521
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
522
        Value rem = (*_capacity)[e] - (*_flow)[e];
523
        if (_tolerance.positive(rem)) {
524
          Node u = _graph.target(e);
525
          if ((*_level)[u] == _level->maxLevel()) continue;
526
          _flow->set(e, (*_capacity)[e]);
527
          (*_excess)[u] += rem;
528
          if (u != _target && !_level->active(u)) {
529
            _level->activate(u);
530
          }
531
        }
532
      }
533
      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
534
        Value rem = (*_flow)[e];
535
        if (_tolerance.positive(rem)) {
536
          Node v = _graph.source(e);
537
          if ((*_level)[v] == _level->maxLevel()) continue;
538
          _flow->set(e, 0);
539
          (*_excess)[v] += rem;
540
          if (v != _target && !_level->active(v)) {
541
            _level->activate(v);
542
          }
543
        }
544
      }
545
      return true;
546
    }
547

	
548
    /// \brief Starts the first phase of the preflow algorithm.
549
    ///
550
    /// The preflow algorithm consists of two phases, this method runs
551
    /// the first phase. After the first phase the maximum flow value
552
    /// and a minimum value cut can already be computed, although a
553
    /// maximum flow is not yet obtained. So after calling this method
554
    /// \ref flowValue() returns the value of a maximum flow and \ref
555
    /// minCut() returns a minimum cut.
556
    /// \pre One of the \ref init() functions must be called before
557
    /// using this function.
558
    void startFirstPhase() {
559
      _phase = true;
560

	
561
      Node n = _level->highestActive();
562
      int level = _level->highestActiveLevel();
563
      while (n != INVALID) {
564
        int num = _node_num;
565

	
566
        while (num > 0 && n != INVALID) {
567
          Value excess = (*_excess)[n];
568
          int new_level = _level->maxLevel();
569

	
570
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
571
            Value rem = (*_capacity)[e] - (*_flow)[e];
572
            if (!_tolerance.positive(rem)) continue;
573
            Node v = _graph.target(e);
574
            if ((*_level)[v] < level) {
575
              if (!_level->active(v) && v != _target) {
576
                _level->activate(v);
577
              }
578
              if (!_tolerance.less(rem, excess)) {
579
                _flow->set(e, (*_flow)[e] + excess);
580
                (*_excess)[v] += excess;
581
                excess = 0;
582
                goto no_more_push_1;
583
              } else {
584
                excess -= rem;
585
                (*_excess)[v] += rem;
586
                _flow->set(e, (*_capacity)[e]);
587
              }
588
            } else if (new_level > (*_level)[v]) {
589
              new_level = (*_level)[v];
590
            }
591
          }
592

	
593
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
594
            Value rem = (*_flow)[e];
595
            if (!_tolerance.positive(rem)) continue;
596
            Node v = _graph.source(e);
597
            if ((*_level)[v] < level) {
598
              if (!_level->active(v) && v != _target) {
599
                _level->activate(v);
600
              }
601
              if (!_tolerance.less(rem, excess)) {
602
                _flow->set(e, (*_flow)[e] - excess);
603
                (*_excess)[v] += excess;
604
                excess = 0;
605
                goto no_more_push_1;
606
              } else {
607
                excess -= rem;
608
                (*_excess)[v] += rem;
609
                _flow->set(e, 0);
610
              }
611
            } else if (new_level > (*_level)[v]) {
612
              new_level = (*_level)[v];
613
            }
614
          }
615

	
616
        no_more_push_1:
617

	
618
          (*_excess)[n] = excess;
619

	
620
          if (excess != 0) {
621
            if (new_level + 1 < _level->maxLevel()) {
622
              _level->liftHighestActive(new_level + 1);
623
            } else {
624
              _level->liftHighestActiveToTop();
625
            }
626
            if (_level->emptyLevel(level)) {
627
              _level->liftToTop(level);
628
            }
629
          } else {
630
            _level->deactivate(n);
631
          }
632

	
633
          n = _level->highestActive();
634
          level = _level->highestActiveLevel();
635
          --num;
636
        }
637

	
638
        num = _node_num * 20;
639
        while (num > 0 && n != INVALID) {
640
          Value excess = (*_excess)[n];
641
          int new_level = _level->maxLevel();
642

	
643
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
644
            Value rem = (*_capacity)[e] - (*_flow)[e];
645
            if (!_tolerance.positive(rem)) continue;
646
            Node v = _graph.target(e);
647
            if ((*_level)[v] < level) {
648
              if (!_level->active(v) && v != _target) {
649
                _level->activate(v);
650
              }
651
              if (!_tolerance.less(rem, excess)) {
652
                _flow->set(e, (*_flow)[e] + excess);
653
                (*_excess)[v] += excess;
654
                excess = 0;
655
                goto no_more_push_2;
656
              } else {
657
                excess -= rem;
658
                (*_excess)[v] += rem;
659
                _flow->set(e, (*_capacity)[e]);
660
              }
661
            } else if (new_level > (*_level)[v]) {
662
              new_level = (*_level)[v];
663
            }
664
          }
665

	
666
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
667
            Value rem = (*_flow)[e];
668
            if (!_tolerance.positive(rem)) continue;
669
            Node v = _graph.source(e);
670
            if ((*_level)[v] < level) {
671
              if (!_level->active(v) && v != _target) {
672
                _level->activate(v);
673
              }
674
              if (!_tolerance.less(rem, excess)) {
675
                _flow->set(e, (*_flow)[e] - excess);
676
                (*_excess)[v] += excess;
677
                excess = 0;
678
                goto no_more_push_2;
679
              } else {
680
                excess -= rem;
681
                (*_excess)[v] += rem;
682
                _flow->set(e, 0);
683
              }
684
            } else if (new_level > (*_level)[v]) {
685
              new_level = (*_level)[v];
686
            }
687
          }
688

	
689
        no_more_push_2:
690

	
691
          (*_excess)[n] = excess;
692

	
693
          if (excess != 0) {
694
            if (new_level + 1 < _level->maxLevel()) {
695
              _level->liftActiveOn(level, new_level + 1);
696
            } else {
697
              _level->liftActiveToTop(level);
698
            }
699
            if (_level->emptyLevel(level)) {
700
              _level->liftToTop(level);
701
            }
702
          } else {
703
            _level->deactivate(n);
704
          }
705

	
706
          while (level >= 0 && _level->activeFree(level)) {
707
            --level;
708
          }
709
          if (level == -1) {
710
            n = _level->highestActive();
711
            level = _level->highestActiveLevel();
712
          } else {
713
            n = _level->activeOn(level);
714
          }
715
          --num;
716
        }
717
      }
718
    }
719

	
720
    /// \brief Starts the second phase of the preflow algorithm.
721
    ///
722
    /// The preflow algorithm consists of two phases, this method runs
723
    /// the second phase. After calling one of the \ref init() functions
724
    /// and \ref startFirstPhase() and then \ref startSecondPhase(),
725
    /// \ref flowMap() returns a maximum flow, \ref flowValue() returns the
726
    /// value of a maximum flow, \ref minCut() returns a minimum cut
727
    /// \pre One of the \ref init() functions and \ref startFirstPhase()
728
    /// must be called before using this function.
729
    void startSecondPhase() {
730
      _phase = false;
731

	
732
      typename Digraph::template NodeMap<bool> reached(_graph);
733
      for (NodeIt n(_graph); n != INVALID; ++n) {
734
        reached[n] = (*_level)[n] < _level->maxLevel();
735
      }
736

	
737
      _level->initStart();
738
      _level->initAddItem(_source);
739

	
740
      std::vector<Node> queue;
741
      queue.push_back(_source);
742
      reached[_source] = true;
743

	
744
      while (!queue.empty()) {
745
        _level->initNewLevel();
746
        std::vector<Node> nqueue;
747
        for (int i = 0; i < int(queue.size()); ++i) {
748
          Node n = queue[i];
749
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
750
            Node v = _graph.target(e);
751
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
752
              reached[v] = true;
753
              _level->initAddItem(v);
754
              nqueue.push_back(v);
755
            }
756
          }
757
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
758
            Node u = _graph.source(e);
759
            if (!reached[u] &&
760
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
761
              reached[u] = true;
762
              _level->initAddItem(u);
763
              nqueue.push_back(u);
764
            }
765
          }
766
        }
767
        queue.swap(nqueue);
768
      }
769
      _level->initFinish();
770

	
771
      for (NodeIt n(_graph); n != INVALID; ++n) {
772
        if (!reached[n]) {
773
          _level->dirtyTopButOne(n);
774
        } else if ((*_excess)[n] > 0 && _target != n) {
775
          _level->activate(n);
776
        }
777
      }
778

	
779
      Node n;
780
      while ((n = _level->highestActive()) != INVALID) {
781
        Value excess = (*_excess)[n];
782
        int level = _level->highestActiveLevel();
783
        int new_level = _level->maxLevel();
784

	
785
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
786
          Value rem = (*_capacity)[e] - (*_flow)[e];
787
          if (!_tolerance.positive(rem)) continue;
788
          Node v = _graph.target(e);
789
          if ((*_level)[v] < level) {
790
            if (!_level->active(v) && v != _source) {
791
              _level->activate(v);
792
            }
793
            if (!_tolerance.less(rem, excess)) {
794
              _flow->set(e, (*_flow)[e] + excess);
795
              (*_excess)[v] += excess;
796
              excess = 0;
797
              goto no_more_push;
798
            } else {
799
              excess -= rem;
800
              (*_excess)[v] += rem;
801
              _flow->set(e, (*_capacity)[e]);
802
            }
803
          } else if (new_level > (*_level)[v]) {
804
            new_level = (*_level)[v];
805
          }
806
        }
807

	
808
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
809
          Value rem = (*_flow)[e];
810
          if (!_tolerance.positive(rem)) continue;
811
          Node v = _graph.source(e);
812
          if ((*_level)[v] < level) {
813
            if (!_level->active(v) && v != _source) {
814
              _level->activate(v);
815
            }
816
            if (!_tolerance.less(rem, excess)) {
817
              _flow->set(e, (*_flow)[e] - excess);
818
              (*_excess)[v] += excess;
819
              excess = 0;
820
              goto no_more_push;
821
            } else {
822
              excess -= rem;
823
              (*_excess)[v] += rem;
824
              _flow->set(e, 0);
825
            }
826
          } else if (new_level > (*_level)[v]) {
827
            new_level = (*_level)[v];
828
          }
829
        }
830

	
831
      no_more_push:
832

	
833
        (*_excess)[n] = excess;
834

	
835
        if (excess != 0) {
836
          if (new_level + 1 < _level->maxLevel()) {
837
            _level->liftHighestActive(new_level + 1);
838
          } else {
839
            // Calculation error
840
            _level->liftHighestActiveToTop();
841
          }
842
          if (_level->emptyLevel(level)) {
843
            // Calculation error
844
            _level->liftToTop(level);
845
          }
846
        } else {
847
          _level->deactivate(n);
848
        }
849

	
850
      }
851
    }
852

	
853
    /// \brief Runs the preflow algorithm.
854
    ///
855
    /// Runs the preflow algorithm.
856
    /// \note pf.run() is just a shortcut of the following code.
857
    /// \code
858
    ///   pf.init();
859
    ///   pf.startFirstPhase();
860
    ///   pf.startSecondPhase();
861
    /// \endcode
862
    void run() {
863
      init();
864
      startFirstPhase();
865
      startSecondPhase();
866
    }
867

	
868
    /// \brief Runs the preflow algorithm to compute the minimum cut.
869
    ///
870
    /// Runs the preflow algorithm to compute the minimum cut.
871
    /// \note pf.runMinCut() is just a shortcut of the following code.
872
    /// \code
873
    ///   pf.init();
874
    ///   pf.startFirstPhase();
875
    /// \endcode
876
    void runMinCut() {
877
      init();
878
      startFirstPhase();
879
    }
880

	
881
    /// @}
882

	
883
    /// \name Query Functions
884
    /// The results of the preflow algorithm can be obtained using these
885
    /// functions.\n
886
    /// Either one of the \ref run() "run*()" functions or one of the
887
    /// \ref startFirstPhase() "start*()" functions should be called
888
    /// before using them.
889

	
890
    ///@{
891

	
892
    /// \brief Returns the value of the maximum flow.
893
    ///
894
    /// Returns the value of the maximum flow by returning the excess
895
    /// of the target node. This value equals to the value of
896
    /// the maximum flow already after the first phase of the algorithm.
897
    ///
898
    /// \pre Either \ref run() or \ref init() must be called before
899
    /// using this function.
900
    Value flowValue() const {
901
      return (*_excess)[_target];
902
    }
903

	
904
    /// \brief Returns the flow value on the given arc.
905
    ///
906
    /// Returns the flow value on the given arc. This method can
907
    /// be called after the second phase of the algorithm.
908
    ///
909
    /// \pre Either \ref run() or \ref init() must be called before
910
    /// using this function.
911
    Value flow(const Arc& arc) const {
912
      return (*_flow)[arc];
913
    }
914

	
915
    /// \brief Returns a const reference to the flow map.
916
    ///
917
    /// Returns a const reference to the arc map storing the found flow.
918
    /// This method can be called after the second phase of the algorithm.
919
    ///
920
    /// \pre Either \ref run() or \ref init() must be called before
921
    /// using this function.
922
    const FlowMap& flowMap() const {
923
      return *_flow;
924
    }
925

	
926
    /// \brief Returns \c true when the node is on the source side of the
927
    /// minimum cut.
928
    ///
929
    /// Returns true when the node is on the source side of the found
930
    /// minimum cut. This method can be called both after running \ref
931
    /// startFirstPhase() and \ref startSecondPhase().
932
    ///
933
    /// \pre Either \ref run() or \ref init() must be called before
934
    /// using this function.
935
    bool minCut(const Node& node) const {
936
      return ((*_level)[node] == _level->maxLevel()) == _phase;
937
    }
938

	
939
    /// \brief Gives back a minimum value cut.
940
    ///
941
    /// Sets \c cutMap to the characteristic vector of a minimum value
942
    /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
943
    /// node map with \c bool (or convertible) value type.
944
    ///
945
    /// This method can be called both after running \ref startFirstPhase()
946
    /// and \ref startSecondPhase(). The result after the second phase
947
    /// could be slightly different if inexact computation is used.
948
    ///
949
    /// \note This function calls \ref minCut() for each node, so it runs in
950
    /// O(n) time.
951
    ///
952
    /// \pre Either \ref run() or \ref init() must be called before
953
    /// using this function.
954
    template <typename CutMap>
955
    void minCutMap(CutMap& cutMap) const {
956
      for (NodeIt n(_graph); n != INVALID; ++n) {
957
        cutMap.set(n, minCut(n));
958
      }
959
    }
960

	
961
    /// @}
962
  };
963
}
964

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

	
19
#ifndef LEMON_RADIX_HEAP_H
20
#define LEMON_RADIX_HEAP_H
21

	
22
///\ingroup auxdat
23
///\file
24
///\brief Radix Heap implementation.
25

	
26
#include <vector>
27
#include <lemon/error.h>
28

	
29
namespace lemon {
30

	
31

	
32
  /// \ingroup auxdata
33
  ///
34
  /// \brief A Radix Heap implementation.
35
  ///
36
  /// This class implements the \e radix \e heap data structure. A \e heap
37
  /// is a data structure for storing items with specified values called \e
38
  /// priorities in such a way that finding the item with minimum priority is
39
  /// efficient. This heap type can store only items with \e int priority.
40
  /// In a heap one can change the priority of an item, add or erase an
41
  /// item, but the priority cannot be decreased under the last removed
42
  /// item's priority.
43
  ///
44
  /// \param IM A read and writable Item int map, used internally
45
  /// to handle the cross references.
46
  ///
47
  /// \see BinHeap
48
  /// \see Dijkstra
49
  template <typename IM>
50
  class RadixHeap {
51

	
52
  public:
53
    typedef typename IM::Key Item;
54
    typedef int Prio;
55
    typedef IM ItemIntMap;
56

	
57
    /// \brief Exception thrown by RadixHeap.
58
    ///
59
    /// This Exception is thrown when a smaller priority
60
    /// is inserted into the \e RadixHeap then the last time erased.
61
    /// \see RadixHeap
62

	
63
    class UnderFlowPriorityError : public Exception {
64
    public:
65
      virtual const char* what() const throw() {
66
        return "lemon::RadixHeap::UnderFlowPriorityError";
67
      }
68
    };
69

	
70
    /// \brief Type to represent the items states.
71
    ///
72
    /// Each Item element have a state associated to it. It may be "in heap",
73
    /// "pre heap" or "post heap". The latter two are indifferent from the
74
    /// heap's point of view, but may be useful to the user.
75
    ///
76
    /// The ItemIntMap \e should be initialized in such way that it maps
77
    /// PRE_HEAP (-1) to any element to be put in the heap...
78
    enum State {
79
      IN_HEAP = 0,
80
      PRE_HEAP = -1,
81
      POST_HEAP = -2
82
    };
83

	
84
  private:
85

	
86
    struct RadixItem {
87
      int prev, next, box;
88
      Item item;
89
      int prio;
90
      RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
91
    };
92

	
93
    struct RadixBox {
94
      int first;
95
      int min, size;
96
      RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
97
    };
98

	
99
    std::vector<RadixItem> data;
100
    std::vector<RadixBox> boxes;
101

	
102
    ItemIntMap &_iim;
103

	
104

	
105
  public:
106
    /// \brief The constructor.
107
    ///
108
    /// The constructor.
109
    ///
110
    /// \param map It should be given to the constructor, since it is used
111
    /// internally to handle the cross references. The value of the map
112
    /// should be PRE_HEAP (-1) for each element.
113
    ///
114
    /// \param minimal The initial minimal value of the heap.
115
    /// \param capacity It determines the initial capacity of the heap.
116
    RadixHeap(ItemIntMap &map, int minimal = 0, int capacity = 0)
117
      : _iim(map) {
118
      boxes.push_back(RadixBox(minimal, 1));
119
      boxes.push_back(RadixBox(minimal + 1, 1));
120
      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
121
        extend();
122
      }
123
    }
124

	
125
    /// The number of items stored in the heap.
126
    ///
127
    /// \brief Returns the number of items stored in the heap.
128
    int size() const { return data.size(); }
129
    /// \brief Checks if the heap stores no items.
130
    ///
131
    /// Returns \c true if and only if the heap stores no items.
132
    bool empty() const { return data.empty(); }
133

	
134
    /// \brief Make empty this heap.
135
    ///
136
    /// Make empty this heap. It does not change the cross reference
137
    /// map.  If you want to reuse a heap what is not surely empty you
138
    /// should first clear the heap and after that you should set the
139
    /// cross reference map for each item to \c PRE_HEAP.
140
    void clear(int minimal = 0, int capacity = 0) {
141
      data.clear(); boxes.clear();
142
      boxes.push_back(RadixBox(minimal, 1));
143
      boxes.push_back(RadixBox(minimal + 1, 1));
144
      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
145
        extend();
146
      }
147
    }
148

	
149
  private:
150

	
151
    bool upper(int box, Prio pr) {
152
      return pr < boxes[box].min;
153
    }
154

	
155
    bool lower(int box, Prio pr) {
156
      return pr >= boxes[box].min + boxes[box].size;
157
    }
158

	
159
    /// \brief Remove item from the box list.
160
    void remove(int index) {
161
      if (data[index].prev >= 0) {
162
        data[data[index].prev].next = data[index].next;
163
      } else {
164
        boxes[data[index].box].first = data[index].next;
165
      }
166
      if (data[index].next >= 0) {
167
        data[data[index].next].prev = data[index].prev;
168
      }
169
    }
170

	
171
    /// \brief Insert item into the box list.
172
    void insert(int box, int index) {
173
      if (boxes[box].first == -1) {
174
        boxes[box].first = index;
175
        data[index].next = data[index].prev = -1;
176
      } else {
177
        data[index].next = boxes[box].first;
178
        data[boxes[box].first].prev = index;
179
        data[index].prev = -1;
180
        boxes[box].first = index;
181
      }
182
      data[index].box = box;
183
    }
184

	
185
    /// \brief Add a new box to the box list.
186
    void extend() {
187
      int min = boxes.back().min + boxes.back().size;
188
      int bs = 2 * boxes.back().size;
189
      boxes.push_back(RadixBox(min, bs));
190
    }
191

	
192
    /// \brief Move an item up into the proper box.
193
    void bubble_up(int index) {
194
      if (!lower(data[index].box, data[index].prio)) return;
195
      remove(index);
196
      int box = findUp(data[index].box, data[index].prio);
197
      insert(box, index);
198
    }
199

	
200
    /// \brief Find up the proper box for the item with the given prio.
201
    int findUp(int start, int pr) {
202
      while (lower(start, pr)) {
203
        if (++start == int(boxes.size())) {
204
          extend();
205
        }
206
      }
207
      return start;
208
    }
209

	
210
    /// \brief Move an item down into the proper box.
211
    void bubble_down(int index) {
212
      if (!upper(data[index].box, data[index].prio)) return;
213
      remove(index);
214
      int box = findDown(data[index].box, data[index].prio);
215
      insert(box, index);
216
    }
217

	
218
    /// \brief Find up the proper box for the item with the given prio.
219
    int findDown(int start, int pr) {
220
      while (upper(start, pr)) {
221
        if (--start < 0) throw UnderFlowPriorityError();
222
      }
223
      return start;
224
    }
225

	
226
    /// \brief Find the first not empty box.
227
    int findFirst() {
228
      int first = 0;
229
      while (boxes[first].first == -1) ++first;
230
      return first;
231
    }
232

	
233
    /// \brief Gives back the minimal prio of the box.
234
    int minValue(int box) {
235
      int min = data[boxes[box].first].prio;
236
      for (int k = boxes[box].first; k != -1; k = data[k].next) {
237
        if (data[k].prio < min) min = data[k].prio;
238
      }
239
      return min;
240
    }
241

	
242
    /// \brief Rearrange the items of the heap and makes the
243
    /// first box not empty.
244
    void moveDown() {
245
      int box = findFirst();
246
      if (box == 0) return;
247
      int min = minValue(box);
248
      for (int i = 0; i <= box; ++i) {
249
        boxes[i].min = min;
250
        min += boxes[i].size;
251
      }
252
      int curr = boxes[box].first, next;
253
      while (curr != -1) {
254
        next = data[curr].next;
255
        bubble_down(curr);
256
        curr = next;
257
      }
258
    }
259

	
260
    void relocate_last(int index) {
261
      if (index != int(data.size()) - 1) {
262
        data[index] = data.back();
263
        if (data[index].prev != -1) {
264
          data[data[index].prev].next = index;
265
        } else {
266
          boxes[data[index].box].first = index;
267
        }
268
        if (data[index].next != -1) {
269
          data[data[index].next].prev = index;
270
        }
271
        _iim[data[index].item] = index;
272
      }
273
      data.pop_back();
274
    }
275

	
276
  public:
277

	
278
    /// \brief Insert an item into the heap with the given priority.
279
    ///
280
    /// Adds \c i to the heap with priority \c p.
281
    /// \param i The item to insert.
282
    /// \param p The priority of the item.
283
    void push(const Item &i, const Prio &p) {
284
      int n = data.size();
285
      _iim.set(i, n);
286
      data.push_back(RadixItem(i, p));
287
      while (lower(boxes.size() - 1, p)) {
288
        extend();
289
      }
290
      int box = findDown(boxes.size() - 1, p);
291
      insert(box, n);
292
    }
293

	
294
    /// \brief Returns the item with minimum priority.
295
    ///
296
    /// This method returns the item with minimum priority.
297
    /// \pre The heap must be nonempty.
298
    Item top() const {
299
      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
300
      return data[boxes[0].first].item;
301
    }
302

	
303
    /// \brief Returns the minimum priority.
304
    ///
305
    /// It returns the minimum priority.
306
    /// \pre The heap must be nonempty.
307
    Prio prio() const {
308
      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
309
      return data[boxes[0].first].prio;
310
     }
311

	
312
    /// \brief Deletes the item with minimum priority.
313
    ///
314
    /// This method deletes the item with minimum priority.
315
    /// \pre The heap must be non-empty.
316
    void pop() {
317
      moveDown();
318
      int index = boxes[0].first;
319
      _iim[data[index].item] = POST_HEAP;
320
      remove(index);
321
      relocate_last(index);
322
    }
323

	
324
    /// \brief Deletes \c i from the heap.
325
    ///
326
    /// This method deletes item \c i from the heap, if \c i was
327
    /// already stored in the heap.
328
    /// \param i The item to erase.
329
    void erase(const Item &i) {
330
      int index = _iim[i];
331
      _iim[i] = POST_HEAP;
332
      remove(index);
333
      relocate_last(index);
334
   }
335

	
336
    /// \brief Returns the priority of \c i.
337
    ///
338
    /// This function returns the priority of item \c i.
339
    /// \pre \c i must be in the heap.
340
    /// \param i The item.
341
    Prio operator[](const Item &i) const {
342
      int idx = _iim[i];
343
      return data[idx].prio;
344
    }
345

	
346
    /// \brief \c i gets to the heap with priority \c p independently
347
    /// if \c i was already there.
348
    ///
349
    /// This method calls \ref push(\c i, \c p) if \c i is not stored
350
    /// in the heap and sets the priority of \c i to \c p otherwise.
351
    /// It may throw an \e UnderFlowPriorityException.
352
    /// \param i The item.
353
    /// \param p The priority.
354
    void set(const Item &i, const Prio &p) {
355
      int idx = _iim[i];
356
      if( idx < 0 ) {
357
        push(i, p);
358
      }
359
      else if( p >= data[idx].prio ) {
360
        data[idx].prio = p;
361
        bubble_up(idx);
362
      } else {
363
        data[idx].prio = p;
364
        bubble_down(idx);
365
      }
366
    }
367

	
368

	
369
    /// \brief Decreases the priority of \c i to \c p.
370
    ///
371
    /// This method decreases the priority of item \c i to \c p.
372
    /// \pre \c i must be stored in the heap with priority at least \c p, and
373
    /// \c should be greater or equal to the last removed item's priority.
374
    /// \param i The item.
375
    /// \param p The priority.
376
    void decrease(const Item &i, const Prio &p) {
377
      int idx = _iim[i];
378
      data[idx].prio = p;
379
      bubble_down(idx);
380
    }
381

	
382
    /// \brief Increases the priority of \c i to \c p.
383
    ///
384
    /// This method sets the priority of item \c i to \c p.
385
    /// \pre \c i must be stored in the heap with priority at most \c p
386
    /// \param i The item.
387
    /// \param p The priority.
388
    void increase(const Item &i, const Prio &p) {
389
      int idx = _iim[i];
390
      data[idx].prio = p;
391
      bubble_up(idx);
392
    }
393

	
394
    /// \brief Returns if \c item is in, has already been in, or has
395
    /// never been in the heap.
396
    ///
397
    /// This method returns PRE_HEAP if \c item has never been in the
398
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
399
    /// otherwise. In the latter case it is possible that \c item will
400
    /// get back to the heap again.
401
    /// \param i The item.
402
    State state(const Item &i) const {
403
      int s = _iim[i];
404
      if( s >= 0 ) s = 0;
405
      return State(s);
406
    }
407

	
408
    /// \brief Sets the state of the \c item in the heap.
409
    ///
410
    /// Sets the state of the \c item in the heap. It can be used to
411
    /// manually clear the heap when it is important to achive the
412
    /// better time complexity.
413
    /// \param i The item.
414
    /// \param st The state. It should not be \c IN_HEAP.
415
    void state(const Item& i, State st) {
416
      switch (st) {
417
      case POST_HEAP:
418
      case PRE_HEAP:
419
        if (state(i) == IN_HEAP) {
420
          erase(i);
421
        }
422
        _iim[i] = st;
423
        break;
424
      case IN_HEAP:
425
        break;
426
      }
427
    }
428

	
429
  }; // class RadixHeap
430

	
431
} // namespace lemon
432

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

	
19
#ifndef RADIX_SORT_H
20
#define RADIX_SORT_H
21

	
22
/// \ingroup auxalg
23
/// \file
24
/// \brief Radix sort
25
///
26
/// Linear time sorting algorithms
27

	
28
#include <vector>
29
#include <limits>
30
#include <iterator>
31
#include <algorithm>
32

	
33
namespace lemon {
34

	
35
  namespace _radix_sort_bits {
36

	
37
    template <typename Value>
38
    struct Identity {
39
      const Value& operator()(const Value& val) {
40
        return val;
41
      }
42
    };
43

	
44

	
45
    template <typename Value, typename Iterator, typename Functor>
46
    Iterator radixSortPartition(Iterator first, Iterator last,
47
                                Functor functor, Value mask) {
48
      while (first != last && !(functor(*first) & mask)) {
49
        ++first;
50
      }
51
      if (first == last) {
52
        return first;
53
      }
54
      --last;
55
      while (first != last && (functor(*last) & mask)) {
56
        --last;
57
      }
58
      if (first == last) {
59
        return first;
60
      }
61
      std::iter_swap(first, last);
62
      ++first;
63
      if (!(first < last)) {
64
        return first;
65
      }
66
      while (true) {
67
        while (!(functor(*first) & mask)) {
68
          ++first;
69
        }
70
        --last;
71
        while (functor(*last) & mask) {
72
          --last;
73
        }
74
        if (!(first < last)) {
75
          return first;
76
        }
77
        std::iter_swap(first, last);
78
        ++first;
79
      }
80
    }
81

	
82
    template <typename Iterator, typename Functor>
83
    Iterator radixSortSignPartition(Iterator first, Iterator last,
84
                                    Functor functor) {
85
      while (first != last && functor(*first) < 0) {
86
        ++first;
87
      }
88
      if (first == last) {
89
        return first;
90
      }
91
      --last;
92
      while (first != last && functor(*last) >= 0) {
93
        --last;
94
      }
95
      if (first == last) {
96
        return first;
97
      }
98
      std::iter_swap(first, last);
99
      ++first;
100
      if (!(first < last)) {
101
        return first;
102
      }
103
      while (true) {
104
        while (functor(*first) < 0) {
105
          ++first;
106
        }
107
        --last;
108
        while (functor(*last) >= 0) {
109
          --last;
110
        }
111
        if (!(first < last)) {
112
          return first;
113
        }
114
        std::iter_swap(first, last);
115
        ++first;
116
      }
117
    }
118

	
119
    template <typename Value, typename Iterator, typename Functor>
120
    void radixIntroSort(Iterator first, Iterator last,
121
                        Functor functor, Value mask) {
122
      while (mask != 0 && last - first > 1) {
123
        Iterator cut = radixSortPartition(first, last, functor, mask);
124
        mask >>= 1;
125
        radixIntroSort(first, cut, functor, mask);
126
        first = cut;
127
      }
128
    }
129

	
130
    template <typename Value, typename Iterator, typename Functor>
131
    void radixSignedSort(Iterator first, Iterator last, Functor functor) {
132

	
133
      Iterator cut = radixSortSignPartition(first, last, functor);
134

	
135
      Value mask;
136
      int max_digit;
137
      Iterator it;
138

	
139
      mask = ~0; max_digit = 0;
140
      for (it = first; it != cut; ++it) {
141
        while ((mask & functor(*it)) != mask) {
142
          ++max_digit;
143
          mask <<= 1;
144
        }
145
      }
146
      radixIntroSort(first, cut, functor, 1 << max_digit);
147

	
148
      mask = 0; max_digit = 0;
149
      for (it = cut; it != last; ++it) {
150
        while ((mask | functor(*it)) != mask) {
151
          ++max_digit;
152
          mask <<= 1; mask |= 1;
153
        }
154
      }
155
      radixIntroSort(cut, last, functor, 1 << max_digit);
156
    }
157

	
158
    template <typename Value, typename Iterator, typename Functor>
159
    void radixUnsignedSort(Iterator first, Iterator last, Functor functor) {
160

	
161
      Value mask = 0;
162
      int max_digit = 0;
163

	
164
      Iterator it;
165
      for (it = first; it != last; ++it) {
166
        while ((mask | functor(*it)) != mask) {
167
          ++max_digit;
168
          mask <<= 1; mask |= 1;
169
        }
170
      }
171
      radixIntroSort(first, last, functor, 1 << max_digit);
172
    }
173

	
174

	
175
    template <typename Value,
176
              bool sign = std::numeric_limits<Value>::is_signed >
177
    struct RadixSortSelector {
178
      template <typename Iterator, typename Functor>
179
      static void sort(Iterator first, Iterator last, Functor functor) {
180
        radixSignedSort<Value>(first, last, functor);
181
      }
182
    };
183

	
184
    template <typename Value>
185
    struct RadixSortSelector<Value, false> {
186
      template <typename Iterator, typename Functor>
187
      static void sort(Iterator first, Iterator last, Functor functor) {
188
        radixUnsignedSort<Value>(first, last, functor);
189
      }
190
    };
191

	
192
  }
193

	
194
  /// \ingroup auxalg
195
  ///
196
  /// \brief Sorts the STL compatible range into ascending order.
197
  ///
198
  /// The \c radixSort sorts an STL compatible range into ascending
199
  /// order.  The radix sort algorithm can sort items which are mapped
200
  /// to integers with an adaptable unary function \c functor and the
201
  /// order will be ascending according to these mapped values.
202
  ///
203
  /// It is also possible to use a normal function instead
204
  /// of the functor object. If the functor is not given it will use
205
  /// the identity function instead.
206
  ///
207
  /// This is a special quick sort algorithm where the pivot
208
  /// values to split the items are choosen to be 2<sup>k</sup>
209
  /// for each \c k.
210
  /// Therefore, the time complexity of the algorithm is O(log(c)*n) and
211
  /// it uses O(log(c)) additional space, where \c c is the maximal value
212
  /// and \c n is the number of the items in the container.
213
  ///
214
  /// \param first The begin of the given range.
215
  /// \param last The end of the given range.
216
  /// \param functor An adaptible unary function or a normal function
217
  /// which maps the items to any integer type which can be either
218
  /// signed or unsigned.
219
  ///
220
  /// \sa stableRadixSort()
221
  template <typename Iterator, typename Functor>
222
  void radixSort(Iterator first, Iterator last, Functor functor) {
223
    using namespace _radix_sort_bits;
224
    typedef typename Functor::result_type Value;
225
    RadixSortSelector<Value>::sort(first, last, functor);
226
  }
227

	
228
  template <typename Iterator, typename Value, typename Key>
229
  void radixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
230
    using namespace _radix_sort_bits;
231
    RadixSortSelector<Value>::sort(first, last, functor);
232
  }
233

	
234
  template <typename Iterator, typename Value, typename Key>
235
  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
236
    using namespace _radix_sort_bits;
237
    RadixSortSelector<Value>::sort(first, last, functor);
238
  }
239

	
240
  template <typename Iterator, typename Value, typename Key>
241
  void radixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
242
    using namespace _radix_sort_bits;
243
    RadixSortSelector<Value>::sort(first, last, functor);
244
  }
245

	
246
  template <typename Iterator, typename Value, typename Key>
247
  void radixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
248
    using namespace _radix_sort_bits;
249
    RadixSortSelector<Value>::sort(first, last, functor);
250
  }
251

	
252
  template <typename Iterator>
253
  void radixSort(Iterator first, Iterator last) {
254
    using namespace _radix_sort_bits;
255
    typedef typename std::iterator_traits<Iterator>::value_type Value;
256
    RadixSortSelector<Value>::sort(first, last, Identity<Value>());
257
  }
258

	
259
  namespace _radix_sort_bits {
260

	
261
    template <typename Value>
262
    unsigned char valueByte(Value value, int byte) {
263
      return value >> (std::numeric_limits<unsigned char>::digits * byte);
264
    }
265

	
266
    template <typename Functor, typename Key>
267
    void stableRadixIntroSort(Key *first, Key *last, Key *target,
268
                              int byte, Functor functor) {
269
      const int size =
270
        unsigned(std::numeric_limits<unsigned char>::max()) + 1;
271
      std::vector<int> counter(size);
272
      for (int i = 0; i < size; ++i) {
273
        counter[i] = 0;
274
      }
275
      Key *it = first;
276
      while (first != last) {
277
        ++counter[valueByte(functor(*first), byte)];
278
        ++first;
279
      }
280
      int prev, num = 0;
281
      for (int i = 0; i < size; ++i) {
282
        prev = num;
283
        num += counter[i];
284
        counter[i] = prev;
285
      }
286
      while (it != last) {
287
        target[counter[valueByte(functor(*it), byte)]++] = *it;
288
        ++it;
289
      }
290
    }
291

	
292
    template <typename Functor, typename Key>
293
    void signedStableRadixIntroSort(Key *first, Key *last, Key *target,
294
                                    int byte, Functor functor) {
295
      const int size =
296
        unsigned(std::numeric_limits<unsigned char>::max()) + 1;
297
      std::vector<int> counter(size);
298
      for (int i = 0; i < size; ++i) {
299
        counter[i] = 0;
300
      }
301
      Key *it = first;
302
      while (first != last) {
303
        counter[valueByte(functor(*first), byte)]++;
304
        ++first;
305
      }
306
      int prev, num = 0;
307
      for (int i = size / 2; i < size; ++i) {
308
        prev = num;
309
        num += counter[i];
310
        counter[i] = prev;
311
      }
312
      for (int i = 0; i < size / 2; ++i) {
313
        prev = num;
314
        num += counter[i];
315
        counter[i] = prev;
316
      }
317
      while (it != last) {
318
        target[counter[valueByte(functor(*it), byte)]++] = *it;
319
        ++it;
320
      }
321
    }
322

	
323

	
324
    template <typename Value, typename Iterator, typename Functor>
325
    void stableRadixSignedSort(Iterator first, Iterator last, Functor functor) {
326
      if (first == last) return;
327
      typedef typename std::iterator_traits<Iterator>::value_type Key;
328
      typedef std::allocator<Key> Allocator;
329
      Allocator allocator;
330

	
331
      int length = std::distance(first, last);
332
      Key* buffer = allocator.allocate(2 * length);
333
      try {
334
        bool dir = true;
335
        std::copy(first, last, buffer);
336
        for (int i = 0; i < int(sizeof(Value)) - 1; ++i) {
337
          if (dir) {
338
            stableRadixIntroSort(buffer, buffer + length, buffer + length,
339
                                 i, functor);
340
          } else {
341
            stableRadixIntroSort(buffer + length, buffer + 2 * length, buffer,
342
                                 i, functor);
343
          }
344
          dir = !dir;
345
        }
346
        if (dir) {
347
          signedStableRadixIntroSort(buffer, buffer + length, buffer + length,
348
                                     sizeof(Value) - 1, functor);
349
          std::copy(buffer + length, buffer + 2 * length, first);
350
        }        else {
351
          signedStableRadixIntroSort(buffer + length, buffer + 2 * length,
352
                                     buffer, sizeof(Value) - 1, functor);
353
          std::copy(buffer, buffer + length, first);
354
        }
355
      } catch (...) {
356
        allocator.deallocate(buffer, 2 * length);
357
        throw;
358
      }
359
      allocator.deallocate(buffer, 2 * length);
360
    }
361

	
362
    template <typename Value, typename Iterator, typename Functor>
363
    void stableRadixUnsignedSort(Iterator first, Iterator last,
364
                                 Functor functor) {
365
      if (first == last) return;
366
      typedef typename std::iterator_traits<Iterator>::value_type Key;
367
      typedef std::allocator<Key> Allocator;
368
      Allocator allocator;
369

	
370
      int length = std::distance(first, last);
371
      Key *buffer = allocator.allocate(2 * length);
372
      try {
373
        bool dir = true;
374
        std::copy(first, last, buffer);
375
        for (int i = 0; i < int(sizeof(Value)); ++i) {
376
          if (dir) {
377
            stableRadixIntroSort(buffer, buffer + length,
378
                                 buffer + length, i, functor);
379
          } else {
380
            stableRadixIntroSort(buffer + length, buffer + 2 * length,
381
                                 buffer, i, functor);
382
          }
383
          dir = !dir;
384
        }
385
        if (dir) {
386
          std::copy(buffer, buffer + length, first);
387
        }        else {
388
          std::copy(buffer + length, buffer + 2 * length, first);
389
        }
390
      } catch (...) {
391
        allocator.deallocate(buffer, 2 * length);
392
        throw;
393
      }
394
      allocator.deallocate(buffer, 2 * length);
395
    }
396

	
397

	
398

	
399
    template <typename Value,
400
              bool sign = std::numeric_limits<Value>::is_signed >
401
    struct StableRadixSortSelector {
402
      template <typename Iterator, typename Functor>
403
      static void sort(Iterator first, Iterator last, Functor functor) {
404
        stableRadixSignedSort<Value>(first, last, functor);
405
      }
406
    };
407

	
408
    template <typename Value>
409
    struct StableRadixSortSelector<Value, false> {
410
      template <typename Iterator, typename Functor>
411
      static void sort(Iterator first, Iterator last, Functor functor) {
412
        stableRadixUnsignedSort<Value>(first, last, functor);
413
      }
414
    };
415

	
416
  }
417

	
418
  /// \ingroup auxalg
419
  ///
420
  /// \brief Sorts the STL compatible range into ascending order in a stable
421
  /// way.
422
  ///
423
  /// This function sorts an STL compatible range into ascending
424
  /// order according to an integer mapping in the same as radixSort() does.
425
  ///
426
  /// This sorting algorithm is stable, i.e. the order of two equal
427
  /// elements remains the same after the sorting.
428
  ///
429
  /// This sort algorithm  use a radix forward sort on the
430
  /// bytes of the integer number. The algorithm sorts the items
431
  /// byte-by-byte. First, it counts how many times a byte value occurs
432
  /// in the container, then it copies the corresponding items to
433
  /// another container in asceding order in O(n) time.
434
  ///
435
  /// The time complexity of the algorithm is O(log(c)*n) and
436
  /// it uses O(n) additional space, where \c c is the
437
  /// maximal value and \c n is the number of the items in the
438
  /// container.
439
  ///
440

	
441
  /// \param first The begin of the given range.
442
  /// \param last The end of the given range.
443
  /// \param functor An adaptible unary function or a normal function
444
  /// which maps the items to any integer type which can be either
445
  /// signed or unsigned.
446
  /// \sa radixSort()
447
  template <typename Iterator, typename Functor>
448
  void stableRadixSort(Iterator first, Iterator last, Functor functor) {
449
    using namespace _radix_sort_bits;
450
    typedef typename Functor::result_type Value;
451
    StableRadixSortSelector<Value>::sort(first, last, functor);
452
  }
453

	
454
  template <typename Iterator, typename Value, typename Key>
455
  void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key)) {
456
    using namespace _radix_sort_bits;
457
    StableRadixSortSelector<Value>::sort(first, last, functor);
458
  }
459

	
460
  template <typename Iterator, typename Value, typename Key>
461
  void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key)) {
462
    using namespace _radix_sort_bits;
463
    StableRadixSortSelector<Value>::sort(first, last, functor);
464
  }
465

	
466
  template <typename Iterator, typename Value, typename Key>
467
  void stableRadixSort(Iterator first, Iterator last, Value (*functor)(Key&)) {
468
    using namespace _radix_sort_bits;
469
    StableRadixSortSelector<Value>::sort(first, last, functor);
470
  }
471

	
472
  template <typename Iterator, typename Value, typename Key>
473
  void stableRadixSort(Iterator first, Iterator last, Value& (*functor)(Key&)) {
474
    using namespace _radix_sort_bits;
475
    StableRadixSortSelector<Value>::sort(first, last, functor);
476
  }
477

	
478
  template <typename Iterator>
479
  void stableRadixSort(Iterator first, Iterator last) {
480
    using namespace _radix_sort_bits;
481
    typedef typename std::iterator_traits<Iterator>::value_type Value;
482
    StableRadixSortSelector<Value>::sort(first, last, Identity<Value>());
483
  }
484

	
485
}
486

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

	
19
#include <iostream>
20
#include <lemon/soplex.h>
21

	
22
#include <soplex.h>
23
#include <spxout.h>
24

	
25

	
26
///\file
27
///\brief Implementation of the LEMON-SOPLEX lp solver interface.
28
namespace lemon {
29

	
30
  SoplexLp::SoplexLp() {
31
    soplex = new soplex::SoPlex;
32
    messageLevel(MESSAGE_NOTHING);
33
  }
34

	
35
  SoplexLp::~SoplexLp() {
36
    delete soplex;
37
  }
38

	
39
  SoplexLp::SoplexLp(const SoplexLp& lp) {
40
    rows = lp.rows;
41
    cols = lp.cols;
42

	
43
    soplex = new soplex::SoPlex;
44
    (*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex);
45

	
46
    _col_names = lp._col_names;
47
    _col_names_ref = lp._col_names_ref;
48

	
49
    _row_names = lp._row_names;
50
    _row_names_ref = lp._row_names_ref;
51

	
52
    messageLevel(MESSAGE_NOTHING);
53
  }
54

	
55
  void SoplexLp::_clear_temporals() {
56
    _primal_values.clear();
57
    _dual_values.clear();
58
  }
59

	
60
  SoplexLp* SoplexLp::newSolver() const {
61
    SoplexLp* newlp = new SoplexLp();
62
    return newlp;
63
  }
64

	
65
  SoplexLp* SoplexLp::cloneSolver() const {
66
    SoplexLp* newlp = new SoplexLp(*this);
67
    return newlp;
68
  }
69

	
70
  const char* SoplexLp::_solverName() const { return "SoplexLp"; }
71

	
72
  int SoplexLp::_addCol() {
73
    soplex::LPCol c;
74
    c.setLower(-soplex::infinity);
75
    c.setUpper(soplex::infinity);
76
    soplex->addCol(c);
77

	
78
    _col_names.push_back(std::string());
79

	
80
    return soplex->nCols() - 1;
81
  }
82

	
83
  int SoplexLp::_addRow() {
84
    soplex::LPRow r;
85
    r.setLhs(-soplex::infinity);
86
    r.setRhs(soplex::infinity);
87
    soplex->addRow(r);
88

	
89
    _row_names.push_back(std::string());
90

	
91
    return soplex->nRows() - 1;
92
  }
93

	
94

	
95
  void SoplexLp::_eraseCol(int i) {
96
    soplex->removeCol(i);
97
    _col_names_ref.erase(_col_names[i]);
98
    _col_names[i] = _col_names.back();
99
    _col_names_ref[_col_names.back()] = i;
100
    _col_names.pop_back();
101
  }
102

	
103
  void SoplexLp::_eraseRow(int i) {
104
    soplex->removeRow(i);
105
    _row_names_ref.erase(_row_names[i]);
106
    _row_names[i] = _row_names.back();
107
    _row_names_ref[_row_names.back()] = i;
108
    _row_names.pop_back();
109
  }
110

	
111
  void SoplexLp::_eraseColId(int i) {
112
    cols.eraseIndex(i);
113
    cols.relocateIndex(i, cols.maxIndex());
114
  }
115
  void SoplexLp::_eraseRowId(int i) {
116
    rows.eraseIndex(i);
117
    rows.relocateIndex(i, rows.maxIndex());
118
  }
119

	
120
  void SoplexLp::_getColName(int c, std::string &name) const {
121
    name = _col_names[c];
122
  }
123

	
124
  void SoplexLp::_setColName(int c, const std::string &name) {
125
    _col_names_ref.erase(_col_names[c]);
126
    _col_names[c] = name;
127
    if (!name.empty()) {
128
      _col_names_ref.insert(std::make_pair(name, c));
129
    }
130
  }
131

	
132
  int SoplexLp::_colByName(const std::string& name) const {
133
    std::map<std::string, int>::const_iterator it =
134
      _col_names_ref.find(name);
135
    if (it != _col_names_ref.end()) {
136
      return it->second;
137
    } else {
138
      return -1;
139
    }
140
  }
141

	
142
  void SoplexLp::_getRowName(int r, std::string &name) const {
143
    name = _row_names[r];
144
  }
145

	
146
  void SoplexLp::_setRowName(int r, const std::string &name) {
147
    _row_names_ref.erase(_row_names[r]);
148
    _row_names[r] = name;
149
    if (!name.empty()) {
150
      _row_names_ref.insert(std::make_pair(name, r));
151
    }
152
  }
153

	
154
  int SoplexLp::_rowByName(const std::string& name) const {
155
    std::map<std::string, int>::const_iterator it =
156
      _row_names_ref.find(name);
157
    if (it != _row_names_ref.end()) {
158
      return it->second;
159
    } else {
160
      return -1;
161
    }
162
  }
163

	
164

	
165
  void SoplexLp::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
166
    for (int j = 0; j < soplex->nCols(); ++j) {
167
      soplex->changeElement(i, j, 0.0);
168
    }
169
    for(ExprIterator it = b; it != e; ++it) {
170
      soplex->changeElement(i, it->first, it->second);
171
    }
172
  }
173

	
174
  void SoplexLp::_getRowCoeffs(int i, InsertIterator b) const {
175
    const soplex::SVector& vec = soplex->rowVector(i);
176
    for (int k = 0; k < vec.size(); ++k) {
177
      *b = std::make_pair(vec.index(k), vec.value(k));
178
      ++b;
179
    }
180
  }
181

	
182
  void SoplexLp::_setColCoeffs(int j, ExprIterator b, ExprIterator e) {
183
    for (int i = 0; i < soplex->nRows(); ++i) {
184
      soplex->changeElement(i, j, 0.0);
185
    }
186
    for(ExprIterator it = b; it != e; ++it) {
187
      soplex->changeElement(it->first, j, it->second);
188
    }
189
  }
190

	
191
  void SoplexLp::_getColCoeffs(int i, InsertIterator b) const {
192
    const soplex::SVector& vec = soplex->colVector(i);
193
    for (int k = 0; k < vec.size(); ++k) {
194
      *b = std::make_pair(vec.index(k), vec.value(k));
195
      ++b;
196
    }
197
  }
198

	
199
  void SoplexLp::_setCoeff(int i, int j, Value value) {
200
    soplex->changeElement(i, j, value);
201
  }
202

	
203
  SoplexLp::Value SoplexLp::_getCoeff(int i, int j) const {
204
    return soplex->rowVector(i)[j];
205
  }
206

	
207
  void SoplexLp::_setColLowerBound(int i, Value value) {
208
    LEMON_ASSERT(value != INF, "Invalid bound");
209
    soplex->changeLower(i, value != -INF ? value : -soplex::infinity);
210
  }
211

	
212
  SoplexLp::Value SoplexLp::_getColLowerBound(int i) const {
213
    double value = soplex->lower(i);
214
    return value != -soplex::infinity ? value : -INF;
215
  }
216

	
217
  void SoplexLp::_setColUpperBound(int i, Value value) {
218
    LEMON_ASSERT(value != -INF, "Invalid bound");
219
    soplex->changeUpper(i, value != INF ? value : soplex::infinity);
220
  }
221

	
222
  SoplexLp::Value SoplexLp::_getColUpperBound(int i) const {
223
    double value = soplex->upper(i);
224
    return value != soplex::infinity ? value : INF;
225
  }
226

	
227
  void SoplexLp::_setRowLowerBound(int i, Value lb) {
228
    LEMON_ASSERT(lb != INF, "Invalid bound");
229
    soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, soplex->rhs(i));
230
  }
231

	
232
  SoplexLp::Value SoplexLp::_getRowLowerBound(int i) const {
233
    double res = soplex->lhs(i);
234
    return res == -soplex::infinity ? -INF : res;
235
  }
236

	
237
  void SoplexLp::_setRowUpperBound(int i, Value ub) {
238
    LEMON_ASSERT(ub != -INF, "Invalid bound");
239
    soplex->changeRange(i, soplex->lhs(i), ub != INF ? ub : soplex::infinity);
240
  }
241

	
242
  SoplexLp::Value SoplexLp::_getRowUpperBound(int i) const {
243
    double res = soplex->rhs(i);
244
    return res == soplex::infinity ? INF : res;
245
  }
246

	
247
  void SoplexLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
248
    for (int j = 0; j < soplex->nCols(); ++j) {
249
      soplex->changeObj(j, 0.0);
250
    }
251
    for (ExprIterator it = b; it != e; ++it) {
252
      soplex->changeObj(it->first, it->second);
253
    }
254
  }
255

	
256
  void SoplexLp::_getObjCoeffs(InsertIterator b) const {
257
    for (int j = 0; j < soplex->nCols(); ++j) {
258
      Value coef = soplex->obj(j);
259
      if (coef != 0.0) {
260
        *b = std::make_pair(j, coef);
261
        ++b;
262
      }
263
    }
264
  }
265

	
266
  void SoplexLp::_setObjCoeff(int i, Value obj_coef) {
267
    soplex->changeObj(i, obj_coef);
268
  }
269

	
270
  SoplexLp::Value SoplexLp::_getObjCoeff(int i) const {
271
    return soplex->obj(i);
272
  }
273

	
274
  SoplexLp::SolveExitStatus SoplexLp::_solve() {
275

	
276
    _clear_temporals();
277
    
278
    _applyMessageLevel();
279

	
280
    soplex::SPxSolver::Status status = soplex->solve();
281

	
282
    switch (status) {
283
    case soplex::SPxSolver::OPTIMAL:
284
    case soplex::SPxSolver::INFEASIBLE:
285
    case soplex::SPxSolver::UNBOUNDED:
286
      return SOLVED;
287
    default:
288
      return UNSOLVED;
289
    }
290
  }
291

	
292
  SoplexLp::Value SoplexLp::_getPrimal(int i) const {
293
    if (_primal_values.empty()) {
294
      _primal_values.resize(soplex->nCols());
295
      soplex::Vector pv(_primal_values.size(), &_primal_values.front());
296
      soplex->getPrimal(pv);
297
    }
298
    return _primal_values[i];
299
  }
300

	
301
  SoplexLp::Value SoplexLp::_getDual(int i) const {
302
    if (_dual_values.empty()) {
303
      _dual_values.resize(soplex->nRows());
304
      soplex::Vector dv(_dual_values.size(), &_dual_values.front());
305
      soplex->getDual(dv);
306
    }
307
    return _dual_values[i];
308
  }
309

	
310
  SoplexLp::Value SoplexLp::_getPrimalValue() const {
311
    return soplex->objValue();
312
  }
313

	
314
  SoplexLp::VarStatus SoplexLp::_getColStatus(int i) const {
315
    switch (soplex->getBasisColStatus(i)) {
316
    case soplex::SPxSolver::BASIC:
317
      return BASIC;
318
    case soplex::SPxSolver::ON_UPPER:
319
      return UPPER;
320
    case soplex::SPxSolver::ON_LOWER:
321
      return LOWER;
322
    case soplex::SPxSolver::FIXED:
323
      return FIXED;
324
    case soplex::SPxSolver::ZERO:
325
      return FREE;
326
    default:
327
      LEMON_ASSERT(false, "Wrong column status");
328
      return VarStatus();
329
    }
330
  }
331

	
332
  SoplexLp::VarStatus SoplexLp::_getRowStatus(int i) const {
333
    switch (soplex->getBasisRowStatus(i)) {
334
    case soplex::SPxSolver::BASIC:
335
      return BASIC;
336
    case soplex::SPxSolver::ON_UPPER:
337
      return UPPER;
338
    case soplex::SPxSolver::ON_LOWER:
339
      return LOWER;
340
    case soplex::SPxSolver::FIXED:
341
      return FIXED;
342
    case soplex::SPxSolver::ZERO:
343
      return FREE;
344
    default:
345
      LEMON_ASSERT(false, "Wrong row status");
346
      return VarStatus();
347
    }
348
  }
349

	
350
  SoplexLp::Value SoplexLp::_getPrimalRay(int i) const {
351
    if (_primal_ray.empty()) {
352
      _primal_ray.resize(soplex->nCols());
353
      soplex::Vector pv(_primal_ray.size(), &_primal_ray.front());
354
      soplex->getDualfarkas(pv);
355
    }
356
    return _primal_ray[i];
357
  }
358

	
359
  SoplexLp::Value SoplexLp::_getDualRay(int i) const {
360
    if (_dual_ray.empty()) {
361
      _dual_ray.resize(soplex->nRows());
362
      soplex::Vector dv(_dual_ray.size(), &_dual_ray.front());
363
      soplex->getDualfarkas(dv);
364
    }
365
    return _dual_ray[i];
366
  }
367

	
368
  SoplexLp::ProblemType SoplexLp::_getPrimalType() const {
369
    switch (soplex->status()) {
370
    case soplex::SPxSolver::OPTIMAL:
371
      return OPTIMAL;
372
    case soplex::SPxSolver::UNBOUNDED:
373
      return UNBOUNDED;
374
    case soplex::SPxSolver::INFEASIBLE:
375
      return INFEASIBLE;
376
    default:
377
      return UNDEFINED;
378
    }
379
  }
380

	
381
  SoplexLp::ProblemType SoplexLp::_getDualType() const {
382
    switch (soplex->status()) {
383
    case soplex::SPxSolver::OPTIMAL:
384
      return OPTIMAL;
385
    case soplex::SPxSolver::UNBOUNDED:
386
      return UNBOUNDED;
387
    case soplex::SPxSolver::INFEASIBLE:
388
      return INFEASIBLE;
389
    default:
390
      return UNDEFINED;
391
    }
392
  }
393

	
394
  void SoplexLp::_setSense(Sense sense) {
395
    switch (sense) {
396
    case MIN:
397
      soplex->changeSense(soplex::SPxSolver::MINIMIZE);
398
      break;
399
    case MAX:
400
      soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
401
    }
402
  }
403

	
404
  SoplexLp::Sense SoplexLp::_getSense() const {
405
    switch (soplex->spxSense()) {
406
    case soplex::SPxSolver::MAXIMIZE:
407
      return MAX;
408
    case soplex::SPxSolver::MINIMIZE:
409
      return MIN;
410
    default:
411
      LEMON_ASSERT(false, "Wrong sense.");
412
      return SoplexLp::Sense();
413
    }
414
  }
415

	
416
  void SoplexLp::_clear() {
417
    soplex->clear();
418
    _col_names.clear();
419
    _col_names_ref.clear();
420
    _row_names.clear();
421
    _row_names_ref.clear();
422
    cols.clear();
423
    rows.clear();
424
    _clear_temporals();
425
  }
426

	
427
  void SoplexLp::_messageLevel(MessageLevel level) {
428
    switch (level) {
429
    case MESSAGE_NOTHING:
430
      _message_level = -1;
431
      break;
432
    case MESSAGE_ERROR:
433
      _message_level = soplex::SPxOut::ERROR;
434
      break;
435
    case MESSAGE_WARNING:
436
      _message_level = soplex::SPxOut::WARNING;
437
      break;
438
    case MESSAGE_NORMAL:
439
      _message_level = soplex::SPxOut::INFO2;
440
      break;
441
    case MESSAGE_VERBOSE:
442
      _message_level = soplex::SPxOut::DEBUG;
443
      break;
444
    }
445
  }
446

	
447
  void SoplexLp::_applyMessageLevel() {
448
    soplex::Param::setVerbose(_message_level);
449
  }
450

	
451
} //namespace lemon
452

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

	
19
#ifndef LEMON_SOPLEX_H
20
#define LEMON_SOPLEX_H
21

	
22
///\file
23
///\brief Header of the LEMON-SOPLEX lp solver interface.
24

	
25
#include <vector>
26
#include <string>
27

	
28
#include <lemon/lp_base.h>
29

	
30
// Forward declaration
31
namespace soplex {
32
  class SoPlex;
33
}
34

	
35
namespace lemon {
36

	
37
  /// \ingroup lp_group
38
  ///
39
  /// \brief Interface for the SOPLEX solver
40
  ///
41
  /// This class implements an interface for the SoPlex LP solver.
42
  /// The SoPlex library is an object oriented lp solver library
43
  /// developed at the Konrad-Zuse-Zentrum f�r Informationstechnik
44
  /// Berlin (ZIB). You can find detailed information about it at the
45
  /// <tt>http://soplex.zib.de</tt> address.
46
  class SoplexLp : public LpSolver {
47
  private:
48

	
49
    soplex::SoPlex* soplex;
50

	
51
    std::vector<std::string> _col_names;
52
    std::map<std::string, int> _col_names_ref;
53

	
54
    std::vector<std::string> _row_names;
55
    std::map<std::string, int> _row_names_ref;
56

	
57
  private:
58

	
59
    // these values cannot be retrieved element by element
60
    mutable std::vector<Value> _primal_values;
61
    mutable std::vector<Value> _dual_values;
62

	
63
    mutable std::vector<Value> _primal_ray;
64
    mutable std::vector<Value> _dual_ray;
65

	
66
    void _clear_temporals();
67

	
68
  public:
69

	
70
    /// \e
71
    SoplexLp();
72
    /// \e
73
    SoplexLp(const SoplexLp&);
74
    /// \e
75
    ~SoplexLp();
76
    /// \e
77
    virtual SoplexLp* newSolver() const;
78
    /// \e
79
    virtual SoplexLp* cloneSolver() const;
80

	
81
  protected:
82

	
83
    virtual const char* _solverName() const;
84

	
85
    virtual int _addCol();
86
    virtual int _addRow();
87

	
88
    virtual void _eraseCol(int i);
89
    virtual void _eraseRow(int i);
90

	
91
    virtual void _eraseColId(int i);
92
    virtual void _eraseRowId(int i);
93

	
94
    virtual void _getColName(int col, std::string& name) const;
95
    virtual void _setColName(int col, const std::string& name);
96
    virtual int _colByName(const std::string& name) const;
97

	
98
    virtual void _getRowName(int row, std::string& name) const;
99
    virtual void _setRowName(int row, const std::string& name);
100
    virtual int _rowByName(const std::string& name) const;
101

	
102
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
103
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
104

	
105
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
106
    virtual void _getColCoeffs(int i, InsertIterator b) const;
107

	
108
    virtual void _setCoeff(int row, int col, Value value);
109
    virtual Value _getCoeff(int row, int col) const;
110

	
111
    virtual void _setColLowerBound(int i, Value value);
112
    virtual Value _getColLowerBound(int i) const;
113
    virtual void _setColUpperBound(int i, Value value);
114
    virtual Value _getColUpperBound(int i) const;
115

	
116
    virtual void _setRowLowerBound(int i, Value value);
117
    virtual Value _getRowLowerBound(int i) const;
118
    virtual void _setRowUpperBound(int i, Value value);
119
    virtual Value _getRowUpperBound(int i) const;
120

	
121
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
122
    virtual void _getObjCoeffs(InsertIterator b) const;
123

	
124
    virtual void _setObjCoeff(int i, Value obj_coef);
125
    virtual Value _getObjCoeff(int i) const;
126

	
127
    virtual void _setSense(Sense sense);
128
    virtual Sense _getSense() const;
129

	
130
    virtual SolveExitStatus _solve();
131
    virtual Value _getPrimal(int i) const;
132
    virtual Value _getDual(int i) const;
133

	
134
    virtual Value _getPrimalValue() const;
135

	
136
    virtual Value _getPrimalRay(int i) const;
137
    virtual Value _getDualRay(int i) const;
138

	
139
    virtual VarStatus _getColStatus(int i) const;
140
    virtual VarStatus _getRowStatus(int i) const;
141

	
142
    virtual ProblemType _getPrimalType() const;
143
    virtual ProblemType _getDualType() const;
144

	
145
    virtual void _clear();
146

	
147
    void _messageLevel(MessageLevel m);
148
    void _applyMessageLevel();
149

	
150
    int _message_level;
151

	
152
  };
153

	
154
} //END OF NAMESPACE LEMON
155

	
156
#endif //LEMON_SOPLEX_H
157

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

	
19
#ifndef LEMON_SUURBALLE_H
20
#define LEMON_SUURBALLE_H
21

	
22
///\ingroup shortest_path
23
///\file
24
///\brief An algorithm for finding arc-disjoint paths between two
25
/// nodes having minimum total length.
26

	
27
#include <vector>
28
#include <limits>
29
#include <lemon/bin_heap.h>
30
#include <lemon/path.h>
31
#include <lemon/list_graph.h>
32
#include <lemon/maps.h>
33

	
34
namespace lemon {
35

	
36
  /// \addtogroup shortest_path
37
  /// @{
38

	
39
  /// \brief Algorithm for finding arc-disjoint paths between two nodes
40
  /// having minimum total length.
41
  ///
42
  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
43
  /// finding arc-disjoint paths having minimum total length (cost)
44
  /// from a given source node to a given target node in a digraph.
45
  ///
46
  /// Note that this problem is a special case of the \ref min_cost_flow
47
  /// "minimum cost flow problem". This implementation is actually an
48
  /// efficient specialized version of the \ref CapacityScaling
49
  /// "Successive Shortest Path" algorithm directly for this problem.
50
  /// Therefore this class provides query functions for flow values and
51
  /// node potentials (the dual solution) just like the minimum cost flow
52
  /// algorithms.
53
  ///
54
  /// \tparam GR The digraph type the algorithm runs on.
55
  /// \tparam LEN The type of the length map.
56
  /// The default value is <tt>GR::ArcMap<int></tt>.
57
  ///
58
  /// \warning Length values should be \e non-negative \e integers.
59
  ///
60
  /// \note For finding node-disjoint paths this algorithm can be used
61
  /// along with the \ref SplitNodes adaptor.
62
#ifdef DOXYGEN
63
  template <typename GR, typename LEN>
64
#else
65
  template < typename GR,
66
             typename LEN = typename GR::template ArcMap<int> >
67
#endif
68
  class Suurballe
69
  {
70
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
71

	
72
    typedef ConstMap<Arc, int> ConstArcMap;
73
    typedef typename GR::template NodeMap<Arc> PredMap;
74

	
75
  public:
76

	
77
    /// The type of the digraph the algorithm runs on.
78
    typedef GR Digraph;
79
    /// The type of the length map.
80
    typedef LEN LengthMap;
81
    /// The type of the lengths.
82
    typedef typename LengthMap::Value Length;
83
#ifdef DOXYGEN
84
    /// The type of the flow map.
85
    typedef GR::ArcMap<int> FlowMap;
86
    /// The type of the potential map.
87
    typedef GR::NodeMap<Length> PotentialMap;
88
#else
89
    /// The type of the flow map.
90
    typedef typename Digraph::template ArcMap<int> FlowMap;
91
    /// The type of the potential map.
92
    typedef typename Digraph::template NodeMap<Length> PotentialMap;
93
#endif
94

	
95
    /// The type of the path structures.
96
    typedef SimplePath<GR> Path;
97

	
98
  private:
99

	
100
    // ResidualDijkstra is a special implementation of the
101
    // Dijkstra algorithm for finding shortest paths in the
102
    // residual network with respect to the reduced arc lengths
103
    // and modifying the node potentials according to the
104
    // distance of the nodes.
105
    class ResidualDijkstra
106
    {
107
      typedef typename Digraph::template NodeMap<int> HeapCrossRef;
108
      typedef BinHeap<Length, HeapCrossRef> Heap;
109

	
110
    private:
111

	
112
      // The digraph the algorithm runs on
113
      const Digraph &_graph;
114

	
115
      // The main maps
116
      const FlowMap &_flow;
117
      const LengthMap &_length;
118
      PotentialMap &_potential;
119

	
120
      // The distance map
121
      PotentialMap _dist;
122
      // The pred arc map
123
      PredMap &_pred;
124
      // The processed (i.e. permanently labeled) nodes
125
      std::vector<Node> _proc_nodes;
126

	
127
      Node _s;
128
      Node _t;
129

	
130
    public:
131

	
132
      /// Constructor.
133
      ResidualDijkstra( const Digraph &graph,
134
                        const FlowMap &flow,
135
                        const LengthMap &length,
136
                        PotentialMap &potential,
137
                        PredMap &pred,
138
                        Node s, Node t ) :
139
        _graph(graph), _flow(flow), _length(length), _potential(potential),
140
        _dist(graph), _pred(pred), _s(s), _t(t) {}
141

	
142
      /// \brief Run the algorithm. It returns \c true if a path is found
143
      /// from the source node to the target node.
144
      bool run() {
145
        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
146
        Heap heap(heap_cross_ref);
147
        heap.push(_s, 0);
148
        _pred[_s] = INVALID;
149
        _proc_nodes.clear();
150

	
151
        // Process nodes
152
        while (!heap.empty() && heap.top() != _t) {
153
          Node u = heap.top(), v;
154
          Length d = heap.prio() + _potential[u], nd;
155
          _dist[u] = heap.prio();
156
          heap.pop();
157
          _proc_nodes.push_back(u);
158

	
159
          // Traverse outgoing arcs
160
          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
161
            if (_flow[e] == 0) {
162
              v = _graph.target(e);
163
              switch(heap.state(v)) {
164
              case Heap::PRE_HEAP:
165
                heap.push(v, d + _length[e] - _potential[v]);
166
                _pred[v] = e;
167
                break;
168
              case Heap::IN_HEAP:
169
                nd = d + _length[e] - _potential[v];
170
                if (nd < heap[v]) {
171
                  heap.decrease(v, nd);
172
                  _pred[v] = e;
173
                }
174
                break;
175
              case Heap::POST_HEAP:
176
                break;
177
              }
178
            }
179
          }
180

	
181
          // Traverse incoming arcs
182
          for (InArcIt e(_graph, u); e != INVALID; ++e) {
183
            if (_flow[e] == 1) {
184
              v = _graph.source(e);
185
              switch(heap.state(v)) {
186
              case Heap::PRE_HEAP:
187
                heap.push(v, d - _length[e] - _potential[v]);
188
                _pred[v] = e;
189
                break;
190
              case Heap::IN_HEAP:
191
                nd = d - _length[e] - _potential[v];
192
                if (nd < heap[v]) {
193
                  heap.decrease(v, nd);
194
                  _pred[v] = e;
195
                }
196
                break;
197
              case Heap::POST_HEAP:
198
                break;
199
              }
200
            }
201
          }
202
        }
203
        if (heap.empty()) return false;
204

	
205
        // Update potentials of processed nodes
206
        Length t_dist = heap.prio();
207
        for (int i = 0; i < int(_proc_nodes.size()); ++i)
208
          _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
209
        return true;
210
      }
211

	
212
    }; //class ResidualDijkstra
213

	
214
  private:
215

	
216
    // The digraph the algorithm runs on
217
    const Digraph &_graph;
218
    // The length map
219
    const LengthMap &_length;
220

	
221
    // Arc map of the current flow
222
    FlowMap *_flow;
223
    bool _local_flow;
224
    // Node map of the current potentials
225
    PotentialMap *_potential;
226
    bool _local_potential;
227

	
228
    // The source node
229
    Node _source;
230
    // The target node
231
    Node _target;
232

	
233
    // Container to store the found paths
234
    std::vector< SimplePath<Digraph> > paths;
235
    int _path_num;
236

	
237
    // The pred arc map
238
    PredMap _pred;
239
    // Implementation of the Dijkstra algorithm for finding augmenting
240
    // shortest paths in the residual network
241
    ResidualDijkstra *_dijkstra;
242

	
243
  public:
244

	
245
    /// \brief Constructor.
246
    ///
247
    /// Constructor.
248
    ///
249
    /// \param graph The digraph the algorithm runs on.
250
    /// \param length The length (cost) values of the arcs.
251
    Suurballe( const Digraph &graph,
252
               const LengthMap &length ) :
253
      _graph(graph), _length(length), _flow(0), _local_flow(false),
254
      _potential(0), _local_potential(false), _pred(graph)
255
    {
256
      LEMON_ASSERT(std::numeric_limits<Length>::is_integer,
257
        "The length type of Suurballe must be integer");
258
    }
259

	
260
    /// Destructor.
261
    ~Suurballe() {
262
      if (_local_flow) delete _flow;
263
      if (_local_potential) delete _potential;
264
      delete _dijkstra;
265
    }
266

	
267
    /// \brief Set the flow map.
268
    ///
269
    /// This function sets the flow map.
270
    /// If it is not used before calling \ref run() or \ref init(),
271
    /// an instance will be allocated automatically. The destructor
272
    /// deallocates this automatically allocated map, of course.
273
    ///
274
    /// The found flow contains only 0 and 1 values, since it is the
275
    /// union of the found arc-disjoint paths.
276
    ///
277
    /// \return <tt>(*this)</tt>
278
    Suurballe& flowMap(FlowMap &map) {
279
      if (_local_flow) {
280
        delete _flow;
281
        _local_flow = false;
282
      }
283
      _flow = &map;
284
      return *this;
285
    }
286

	
287
    /// \brief Set the potential map.
288
    ///
289
    /// This function sets the potential map.
290
    /// If it is not used before calling \ref run() or \ref init(),
291
    /// an instance will be allocated automatically. The destructor
292
    /// deallocates this automatically allocated map, of course.
293
    ///
294
    /// The node potentials provide the dual solution of the underlying
295
    /// \ref min_cost_flow "minimum cost flow problem".
296
    ///
297
    /// \return <tt>(*this)</tt>
298
    Suurballe& potentialMap(PotentialMap &map) {
299
      if (_local_potential) {
300
        delete _potential;
301
        _local_potential = false;
302
      }
303
      _potential = &map;
304
      return *this;
305
    }
306

	
307
    /// \name Execution Control
308
    /// The simplest way to execute the algorithm is to call the run()
309
    /// function.
310
    /// \n
311
    /// If you only need the flow that is the union of the found
312
    /// arc-disjoint paths, you may call init() and findFlow().
313

	
314
    /// @{
315

	
316
    /// \brief Run the algorithm.
317
    ///
318
    /// This function runs the algorithm.
319
    ///
320
    /// \param s The source node.
321
    /// \param t The target node.
322
    /// \param k The number of paths to be found.
323
    ///
324
    /// \return \c k if there are at least \c k arc-disjoint paths from
325
    /// \c s to \c t in the digraph. Otherwise it returns the number of
326
    /// arc-disjoint paths found.
327
    ///
328
    /// \note Apart from the return value, <tt>s.run(s, t, k)</tt> is
329
    /// just a shortcut of the following code.
330
    /// \code
331
    ///   s.init(s);
332
    ///   s.findFlow(t, k);
333
    ///   s.findPaths();
334
    /// \endcode
335
    int run(const Node& s, const Node& t, int k = 2) {
336
      init(s);
337
      findFlow(t, k);
338
      findPaths();
339
      return _path_num;
340
    }
341

	
342
    /// \brief Initialize the algorithm.
343
    ///
344
    /// This function initializes the algorithm.
345
    ///
346
    /// \param s The source node.
347
    void init(const Node& s) {
348
      _source = s;
349

	
350
      // Initialize maps
351
      if (!_flow) {
352
        _flow = new FlowMap(_graph);
353
        _local_flow = true;
354
      }
355
      if (!_potential) {
356
        _potential = new PotentialMap(_graph);
357
        _local_potential = true;
358
      }
359
      for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
360
      for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
361
    }
362

	
363
    /// \brief Execute the algorithm to find an optimal flow.
364
    ///
365
    /// This function executes the successive shortest path algorithm to
366
    /// find a minimum cost flow, which is the union of \c k (or less)
367
    /// arc-disjoint paths.
368
    ///
369
    /// \param t The target node.
370
    /// \param k The number of paths to be found.
371
    ///
372
    /// \return \c k if there are at least \c k arc-disjoint paths from
373
    /// the source node to the given node \c t in the digraph.
374
    /// Otherwise it returns the number of arc-disjoint paths found.
375
    ///
376
    /// \pre \ref init() must be called before using this function.
377
    int findFlow(const Node& t, int k = 2) {
378
      _target = t;
379
      _dijkstra =
380
        new ResidualDijkstra( _graph, *_flow, _length, *_potential, _pred,
381
                              _source, _target );
382

	
383
      // Find shortest paths
384
      _path_num = 0;
385
      while (_path_num < k) {
386
        // Run Dijkstra
387
        if (!_dijkstra->run()) break;
388
        ++_path_num;
389

	
390
        // Set the flow along the found shortest path
391
        Node u = _target;
392
        Arc e;
393
        while ((e = _pred[u]) != INVALID) {
394
          if (u == _graph.target(e)) {
395
            (*_flow)[e] = 1;
396
            u = _graph.source(e);
397
          } else {
398
            (*_flow)[e] = 0;
399
            u = _graph.target(e);
400
          }
401
        }
402
      }
403
      return _path_num;
404
    }
405

	
406
    /// \brief Compute the paths from the flow.
407
    ///
408
    /// This function computes the paths from the found minimum cost flow,
409
    /// which is the union of some arc-disjoint paths.
410
    ///
411
    /// \pre \ref init() and \ref findFlow() must be called before using
412
    /// this function.
413
    void findPaths() {
414
      FlowMap res_flow(_graph);
415
      for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
416

	
417
      paths.clear();
418
      paths.resize(_path_num);
419
      for (int i = 0; i < _path_num; ++i) {
420
        Node n = _source;
421
        while (n != _target) {
422
          OutArcIt e(_graph, n);
423
          for ( ; res_flow[e] == 0; ++e) ;
424
          n = _graph.target(e);
425
          paths[i].addBack(e);
426
          res_flow[e] = 0;
427
        }
428
      }
429
    }
430

	
431
    /// @}
432

	
433
    /// \name Query Functions
434
    /// The results of the algorithm can be obtained using these
435
    /// functions.
436
    /// \n The algorithm should be executed before using them.
437

	
438
    /// @{
439

	
440
    /// \brief Return the total length of the found paths.
441
    ///
442
    /// This function returns the total length of the found paths, i.e.
443
    /// the total cost of the found flow.
444
    /// The complexity of the function is O(e).
445
    ///
446
    /// \pre \ref run() or \ref findFlow() must be called before using
447
    /// this function.
448
    Length totalLength() const {
449
      Length c = 0;
450
      for (ArcIt e(_graph); e != INVALID; ++e)
451
        c += (*_flow)[e] * _length[e];
452
      return c;
453
    }
454

	
455
    /// \brief Return the flow value on the given arc.
456
    ///
457
    /// This function returns the flow value on the given arc.
458
    /// It is \c 1 if the arc is involved in one of the found arc-disjoint
459
    /// paths, otherwise it is \c 0.
460
    ///
461
    /// \pre \ref run() or \ref findFlow() must be called before using
462
    /// this function.
463
    int flow(const Arc& arc) const {
464
      return (*_flow)[arc];
465
    }
466

	
467
    /// \brief Return a const reference to an arc map storing the
468
    /// found flow.
469
    ///
470
    /// This function returns a const reference to an arc map storing
471
    /// the flow that is the union of the found arc-disjoint paths.
472
    ///
473
    /// \pre \ref run() or \ref findFlow() must be called before using
474
    /// this function.
475
    const FlowMap& flowMap() const {
476
      return *_flow;
477
    }
478

	
479
    /// \brief Return the potential of the given node.
480
    ///
481
    /// This function returns the potential of the given node.
482
    /// The node potentials provide the dual solution of the
483
    /// underlying \ref min_cost_flow "minimum cost flow problem".
484
    ///
485
    /// \pre \ref run() or \ref findFlow() must be called before using
486
    /// this function.
487
    Length potential(const Node& node) const {
488
      return (*_potential)[node];
489
    }
490

	
491
    /// \brief Return a const reference to a node map storing the
492
    /// found potentials (the dual solution).
493
    ///
494
    /// This function returns a const reference to a node map storing
495
    /// the found potentials that provide the dual solution of the
496
    /// underlying \ref min_cost_flow "minimum cost flow problem".
497
    ///
498
    /// \pre \ref run() or \ref findFlow() must be called before using
499
    /// this function.
500
    const PotentialMap& potentialMap() const {
501
      return *_potential;
502
    }
503

	
504
    /// \brief Return the number of the found paths.
505
    ///
506
    /// This function returns the number of the found paths.
507
    ///
508
    /// \pre \ref run() or \ref findFlow() must be called before using
509
    /// this function.
510
    int pathNum() const {
511
      return _path_num;
512
    }
513

	
514
    /// \brief Return a const reference to the specified path.
515
    ///
516
    /// This function returns a const reference to the specified path.
517
    ///
518
    /// \param i The function returns the <tt>i</tt>-th path.
519
    /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
520
    ///
521
    /// \pre \ref run() or \ref findPaths() must be called before using
522
    /// this function.
523
    Path path(int i) const {
524
      return paths[i];
525
    }
526

	
527
    /// @}
528

	
529
  }; //class Suurballe
530

	
531
  ///@}
532

	
533
} //namespace lemon
534

	
535
#endif //LEMON_SUURBALLE_H
Ignore white space 6 line context
1
AC_DEFUN([LX_CHECK_COIN],
2
[
3
  AC_ARG_WITH([coin],
4
AS_HELP_STRING([--with-coin@<:@=PREFIX@:>@], [search for CLP under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
5
AS_HELP_STRING([--without-coin], [disable checking for CLP]),
6
              [], [with_coin=yes])
7

	
8
  AC_ARG_WITH([coin-includedir],
9
AS_HELP_STRING([--with-coin-includedir=DIR], [search for CLP headers in DIR]),
10
              [], [with_coin_includedir=no])
11

	
12
  AC_ARG_WITH([coin-libdir],
13
AS_HELP_STRING([--with-coin-libdir=DIR], [search for CLP libraries in DIR]),
14
              [], [with_coin_libdir=no])
15

	
16
  lx_clp_found=no
17
  if test x"$with_coin" != x"no"; then
18
    AC_MSG_CHECKING([for CLP])
19

	
20
    if test x"$with_coin_includedir" != x"no"; then
21
      CLP_CXXFLAGS="-I$with_coin_includedir"
22
    elif test x"$with_coin" != x"yes"; then
23
      CLP_CXXFLAGS="-I$with_coin/include"
24
    fi
25

	
26
    if test x"$with_coin_libdir" != x"no"; then
27
      CLP_LDFLAGS="-L$with_coin_libdir"
28
    elif test x"$with_coin" != x"yes"; then
29
      CLP_LDFLAGS="-L$with_coin/lib"
30
    fi
31
    CLP_LIBS="-lClp -lCoinUtils -lm"
32

	
33
    lx_save_cxxflags="$CXXFLAGS"
34
    lx_save_ldflags="$LDFLAGS"
35
    lx_save_libs="$LIBS"
36
    CXXFLAGS="$CLP_CXXFLAGS"
37
    LDFLAGS="$CLP_LDFLAGS"
38
    LIBS="$CLP_LIBS"
39

	
40
    lx_clp_test_prog='
41
      #include <coin/ClpModel.hpp>
42

	
43
      int main(int argc, char** argv)
44
      {
45
        ClpModel clp;
46
        return 0;
47
      }'
48

	
49
    AC_LANG_PUSH(C++)
50
    AC_LINK_IFELSE([$lx_clp_test_prog], [lx_clp_found=yes], [lx_clp_found=no])
51
    AC_LANG_POP(C++)
52

	
53
    CXXFLAGS="$lx_save_cxxflags"
54
    LDFLAGS="$lx_save_ldflags"
55
    LIBS="$lx_save_libs"
56

	
57
    if test x"$lx_clp_found" = x"yes"; then
58
      AC_DEFINE([LEMON_HAVE_CLP], [1], [Define to 1 if you have CLP.])
59
      lx_lp_found=yes
60
      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
61
      AC_MSG_RESULT([yes])
62
    else
63
      CLP_CXXFLAGS=""
64
      CLP_LDFLAGS=""
65
      CLP_LIBS=""
66
      AC_MSG_RESULT([no])
67
    fi
68
  fi
69
  CLP_LIBS="$CLP_LDFLAGS $CLP_LIBS"
70
  AC_SUBST(CLP_CXXFLAGS)
71
  AC_SUBST(CLP_LIBS)
72
  AM_CONDITIONAL([HAVE_CLP], [test x"$lx_clp_found" = x"yes"])
73

	
74

	
75
  lx_cbc_found=no
76
  if test x"$lx_clp_found" = x"yes"; then
77
    if test x"$with_coin" != x"no"; then
78
      AC_MSG_CHECKING([for CBC])
79

	
80
      if test x"$with_coin_includedir" != x"no"; then
81
        CBC_CXXFLAGS="-I$with_coin_includedir"
82
      elif test x"$with_coin" != x"yes"; then
83
        CBC_CXXFLAGS="-I$with_coin/include"
84
      fi
85

	
86
      if test x"$with_coin_libdir" != x"no"; then
87
        CBC_LDFLAGS="-L$with_coin_libdir"
88
      elif test x"$with_coin" != x"yes"; then
89
        CBC_LDFLAGS="-L$with_coin/lib"
90
      fi
91
      CBC_LIBS="-lOsi -lCbc -lOsiCbc -lCbcSolver -lClp -lOsiClp -lCoinUtils -lVol -lOsiVol -lCgl -lm -llapack -lblas"
92

	
93
      lx_save_cxxflags="$CXXFLAGS"
94
      lx_save_ldflags="$LDFLAGS"
95
      lx_save_libs="$LIBS"
96
      CXXFLAGS="$CBC_CXXFLAGS"
97
      LDFLAGS="$CBC_LDFLAGS"
98
      LIBS="$CBC_LIBS"
99

	
100
      lx_cbc_test_prog='
101
        #include <coin/CbcModel.hpp>
102

	
103
        int main(int argc, char** argv)
104
        {
105
          CbcModel cbc;
106
          return 0;
107
        }'
108

	
109
      AC_LANG_PUSH(C++)
110
      AC_LINK_IFELSE([$lx_cbc_test_prog], [lx_cbc_found=yes], [lx_cbc_found=no])
111
      AC_LANG_POP(C++)
112

	
113
      CXXFLAGS="$lx_save_cxxflags"
114
      LDFLAGS="$lx_save_ldflags"
115
      LIBS="$lx_save_libs"
116

	
117
      if test x"$lx_cbc_found" = x"yes"; then
118
        AC_DEFINE([LEMON_HAVE_CBC], [1], [Define to 1 if you have CBC.])
119
        lx_lp_found=yes
120
        AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
121
        lx_mip_found=yes
122
        AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
123
        AC_MSG_RESULT([yes])
124
      else
125
        CBC_CXXFLAGS=""
126
        CBC_LDFLAGS=""
127
        CBC_LIBS=""
128
        AC_MSG_RESULT([no])
129
      fi
130
    fi
131
  fi
132
  CBC_LIBS="$CBC_LDFLAGS $CBC_LIBS"
133
  AC_SUBST(CBC_CXXFLAGS)
134
  AC_SUBST(CBC_LIBS)
135
  AM_CONDITIONAL([HAVE_CBC], [test x"$lx_cbc_found" = x"yes"])
136
])
Ignore white space 6 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2009
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#include <iostream>
20
#include <limits>
21

	
22
#include <lemon/list_graph.h>
23
#include <lemon/grid_graph.h>
24
#include <lemon/bfs.h>
25
#include <lemon/path.h>
26

	
27
#include <lemon/concepts/digraph.h>
28
#include <lemon/concepts/graph.h>
29
#include <lemon/concepts/graph_components.h>
30
#include <lemon/concepts/maps.h>
31
#include <lemon/concept_check.h>
32

	
33
#include <lemon/adaptors.h>
34

	
35
#include "test/test_tools.h"
36
#include "test/graph_test.h"
37

	
38
using namespace lemon;
39

	
40
void checkReverseDigraph() {
41
  // Check concepts
42
  checkConcept<concepts::Digraph, ReverseDigraph<concepts::Digraph> >();
43
  checkConcept<concepts::Digraph, ReverseDigraph<ListDigraph> >();
44
  checkConcept<concepts::AlterableDigraphComponent<>,
45
               ReverseDigraph<ListDigraph> >();
46
  checkConcept<concepts::ExtendableDigraphComponent<>,
47
               ReverseDigraph<ListDigraph> >();
48
  checkConcept<concepts::ErasableDigraphComponent<>,
49
               ReverseDigraph<ListDigraph> >();
50
  checkConcept<concepts::ClearableDigraphComponent<>,
51
               ReverseDigraph<ListDigraph> >();
52

	
53
  // Create a digraph and an adaptor
54
  typedef ListDigraph Digraph;
55
  typedef ReverseDigraph<Digraph> Adaptor;
56

	
57
  Digraph digraph;
58
  Adaptor adaptor(digraph);
59

	
60
  // Add nodes and arcs to the original digraph
61
  Digraph::Node n1 = digraph.addNode();
62
  Digraph::Node n2 = digraph.addNode();
63
  Digraph::Node n3 = digraph.addNode();
64

	
65
  Digraph::Arc a1 = digraph.addArc(n1, n2);
66
  Digraph::Arc a2 = digraph.addArc(n1, n3);
67
  Digraph::Arc a3 = digraph.addArc(n2, n3);
68

	
69
  // Check the adaptor
70
  checkGraphNodeList(adaptor, 3);
71
  checkGraphArcList(adaptor, 3);
72
  checkGraphConArcList(adaptor, 3);
73

	
74
  checkGraphOutArcList(adaptor, n1, 0);
75
  checkGraphOutArcList(adaptor, n2, 1);
76
  checkGraphOutArcList(adaptor, n3, 2);
77

	
78
  checkGraphInArcList(adaptor, n1, 2);
79
  checkGraphInArcList(adaptor, n2, 1);
80
  checkGraphInArcList(adaptor, n3, 0);
81

	
82
  checkNodeIds(adaptor);
83
  checkArcIds(adaptor);
84

	
85
  checkGraphNodeMap(adaptor);
86
  checkGraphArcMap(adaptor);
87

	
88
  // Check the orientation of the arcs
89
  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
90
    check(adaptor.source(a) == digraph.target(a), "Wrong reverse");
91
    check(adaptor.target(a) == digraph.source(a), "Wrong reverse");
92
  }
93

	
94
  // Add and erase nodes and arcs in the digraph through the adaptor
95
  Adaptor::Node n4 = adaptor.addNode();
96

	
97
  Adaptor::Arc a4 = adaptor.addArc(n4, n3);
98
  Adaptor::Arc a5 = adaptor.addArc(n2, n4);
99
  Adaptor::Arc a6 = adaptor.addArc(n2, n4);
100
  Adaptor::Arc a7 = adaptor.addArc(n1, n4);
101
  Adaptor::Arc a8 = adaptor.addArc(n1, n2);
102

	
103
  adaptor.erase(a1);
104
  adaptor.erase(n3);
105

	
106
  // Check the adaptor
107
  checkGraphNodeList(adaptor, 3);
108
  checkGraphArcList(adaptor, 4);
109
  checkGraphConArcList(adaptor, 4);
110

	
111
  checkGraphOutArcList(adaptor, n1, 2);
112
  checkGraphOutArcList(adaptor, n2, 2);
113
  checkGraphOutArcList(adaptor, n4, 0);
114

	
115
  checkGraphInArcList(adaptor, n1, 0);
116
  checkGraphInArcList(adaptor, n2, 1);
117
  checkGraphInArcList(adaptor, n4, 3);
118

	
119
  checkNodeIds(adaptor);
120
  checkArcIds(adaptor);
121

	
122
  checkGraphNodeMap(adaptor);
123
  checkGraphArcMap(adaptor);
124

	
125
  // Check the digraph
126
  checkGraphNodeList(digraph, 3);
127
  checkGraphArcList(digraph, 4);
128
  checkGraphConArcList(digraph, 4);
129

	
130
  checkGraphOutArcList(digraph, n1, 0);
131
  checkGraphOutArcList(digraph, n2, 1);
132
  checkGraphOutArcList(digraph, n4, 3);
133

	
134
  checkGraphInArcList(digraph, n1, 2);
135
  checkGraphInArcList(digraph, n2, 2);
136
  checkGraphInArcList(digraph, n4, 0);
137

	
138
  checkNodeIds(digraph);
139
  checkArcIds(digraph);
140

	
141
  checkGraphNodeMap(digraph);
142
  checkGraphArcMap(digraph);
143

	
144
  // Check the conversion of nodes and arcs
145
  Digraph::Node nd = n4;
146
  nd = n4;
147
  Adaptor::Node na = n1;
148
  na = n2;
149
  Digraph::Arc ad = a4;
150
  ad = a5;
151
  Adaptor::Arc aa = a1;
152
  aa = a2;
153
}
154

	
155
void checkSubDigraph() {
156
  // Check concepts
157
  checkConcept<concepts::Digraph, SubDigraph<concepts::Digraph> >();
158
  checkConcept<concepts::Digraph, SubDigraph<ListDigraph> >();
159
  checkConcept<concepts::AlterableDigraphComponent<>,
160
               SubDigraph<ListDigraph> >();
161
  checkConcept<concepts::ExtendableDigraphComponent<>,
162
               SubDigraph<ListDigraph> >();
163
  checkConcept<concepts::ErasableDigraphComponent<>,
164
               SubDigraph<ListDigraph> >();
165
  checkConcept<concepts::ClearableDigraphComponent<>,
166
               SubDigraph<ListDigraph> >();
167

	
168
  // Create a digraph and an adaptor
169
  typedef ListDigraph Digraph;
170
  typedef Digraph::NodeMap<bool> NodeFilter;
171
  typedef Digraph::ArcMap<bool> ArcFilter;
172
  typedef SubDigraph<Digraph, NodeFilter, ArcFilter> Adaptor;
173

	
174
  Digraph digraph;
175
  NodeFilter node_filter(digraph);
176
  ArcFilter arc_filter(digraph);
177
  Adaptor adaptor(digraph, node_filter, arc_filter);
178

	
179
  // Add nodes and arcs to the original digraph and the adaptor
180
  Digraph::Node n1 = digraph.addNode();
181
  Digraph::Node n2 = digraph.addNode();
182
  Adaptor::Node n3 = adaptor.addNode();
183

	
184
  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
185

	
186
  Digraph::Arc a1 = digraph.addArc(n1, n2);
187
  Digraph::Arc a2 = digraph.addArc(n1, n3);
188
  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
189

	
190
  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
191

	
192
  checkGraphNodeList(adaptor, 3);
193
  checkGraphArcList(adaptor, 3);
194
  checkGraphConArcList(adaptor, 3);
195

	
196
  checkGraphOutArcList(adaptor, n1, 2);
197
  checkGraphOutArcList(adaptor, n2, 1);
198
  checkGraphOutArcList(adaptor, n3, 0);
199

	
200
  checkGraphInArcList(adaptor, n1, 0);
201
  checkGraphInArcList(adaptor, n2, 1);
202
  checkGraphInArcList(adaptor, n3, 2);
203

	
204
  checkNodeIds(adaptor);
205
  checkArcIds(adaptor);
206

	
207
  checkGraphNodeMap(adaptor);
208
  checkGraphArcMap(adaptor);
209

	
210
  // Hide an arc
211
  adaptor.status(a2, false);
212
  adaptor.disable(a3);
213
  if (!adaptor.status(a3)) adaptor.enable(a3);
214

	
215
  checkGraphNodeList(adaptor, 3);
216
  checkGraphArcList(adaptor, 2);
217
  checkGraphConArcList(adaptor, 2);
218

	
219
  checkGraphOutArcList(adaptor, n1, 1);
220
  checkGraphOutArcList(adaptor, n2, 1);
221
  checkGraphOutArcList(adaptor, n3, 0);
222

	
223
  checkGraphInArcList(adaptor, n1, 0);
224
  checkGraphInArcList(adaptor, n2, 1);
225
  checkGraphInArcList(adaptor, n3, 1);
226

	
227
  checkNodeIds(adaptor);
228
  checkArcIds(adaptor);
229

	
230
  checkGraphNodeMap(adaptor);
231
  checkGraphArcMap(adaptor);
232

	
233
  // Hide a node
234
  adaptor.status(n1, false);
235
  adaptor.disable(n3);
236
  if (!adaptor.status(n3)) adaptor.enable(n3);
237

	
238
  checkGraphNodeList(adaptor, 2);
239
  checkGraphArcList(adaptor, 1);
240
  checkGraphConArcList(adaptor, 1);
241

	
242
  checkGraphOutArcList(adaptor, n2, 1);
243
  checkGraphOutArcList(adaptor, n3, 0);
244

	
245
  checkGraphInArcList(adaptor, n2, 0);
246
  checkGraphInArcList(adaptor, n3, 1);
247

	
248
  checkNodeIds(adaptor);
249
  checkArcIds(adaptor);
250

	
251
  checkGraphNodeMap(adaptor);
252
  checkGraphArcMap(adaptor);
253

	
254
  // Hide all nodes and arcs
255
  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
256
  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
257

	
258
  checkGraphNodeList(adaptor, 0);
259
  checkGraphArcList(adaptor, 0);
260
  checkGraphConArcList(adaptor, 0);
261

	
262
  checkNodeIds(adaptor);
263
  checkArcIds(adaptor);
264

	
265
  checkGraphNodeMap(adaptor);
266
  checkGraphArcMap(adaptor);
267

	
268
  // Check the conversion of nodes and arcs
269
  Digraph::Node nd = n3;
270
  nd = n3;
271
  Adaptor::Node na = n1;
272
  na = n2;
273
  Digraph::Arc ad = a3;
274
  ad = a3;
275
  Adaptor::Arc aa = a1;
276
  aa = a2;
277
}
278

	
279
void checkFilterNodes1() {
280
  // Check concepts
281
  checkConcept<concepts::Digraph, FilterNodes<concepts::Digraph> >();
282
  checkConcept<concepts::Digraph, FilterNodes<ListDigraph> >();
283
  checkConcept<concepts::AlterableDigraphComponent<>,
284
               FilterNodes<ListDigraph> >();
285
  checkConcept<concepts::ExtendableDigraphComponent<>,
286
               FilterNodes<ListDigraph> >();
287
  checkConcept<concepts::ErasableDigraphComponent<>,
288
               FilterNodes<ListDigraph> >();
289
  checkConcept<concepts::ClearableDigraphComponent<>,
290
               FilterNodes<ListDigraph> >();
291

	
292
  // Create a digraph and an adaptor
293
  typedef ListDigraph Digraph;
294
  typedef Digraph::NodeMap<bool> NodeFilter;
295
  typedef FilterNodes<Digraph, NodeFilter> Adaptor;
296

	
297
  Digraph digraph;
298
  NodeFilter node_filter(digraph);
299
  Adaptor adaptor(digraph, node_filter);
300

	
301
  // Add nodes and arcs to the original digraph and the adaptor
302
  Digraph::Node n1 = digraph.addNode();
303
  Digraph::Node n2 = digraph.addNode();
304
  Adaptor::Node n3 = adaptor.addNode();
305

	
306
  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
307

	
308
  Digraph::Arc a1 = digraph.addArc(n1, n2);
309
  Digraph::Arc a2 = digraph.addArc(n1, n3);
310
  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
311

	
312
  checkGraphNodeList(adaptor, 3);
313
  checkGraphArcList(adaptor, 3);
314
  checkGraphConArcList(adaptor, 3);
315

	
316
  checkGraphOutArcList(adaptor, n1, 2);
317
  checkGraphOutArcList(adaptor, n2, 1);
318
  checkGraphOutArcList(adaptor, n3, 0);
319

	
320
  checkGraphInArcList(adaptor, n1, 0);
321
  checkGraphInArcList(adaptor, n2, 1);
322
  checkGraphInArcList(adaptor, n3, 2);
323

	
324
  checkNodeIds(adaptor);
325
  checkArcIds(adaptor);
326

	
327
  checkGraphNodeMap(adaptor);
328
  checkGraphArcMap(adaptor);
329

	
330
  // Hide a node
331
  adaptor.status(n1, false);
332
  adaptor.disable(n3);
333
  if (!adaptor.status(n3)) adaptor.enable(n3);
334

	
335
  checkGraphNodeList(adaptor, 2);
336
  checkGraphArcList(adaptor, 1);
337
  checkGraphConArcList(adaptor, 1);
338

	
339
  checkGraphOutArcList(adaptor, n2, 1);
340
  checkGraphOutArcList(adaptor, n3, 0);
341

	
342
  checkGraphInArcList(adaptor, n2, 0);
343
  checkGraphInArcList(adaptor, n3, 1);
344

	
345
  checkNodeIds(adaptor);
346
  checkArcIds(adaptor);
347

	
348
  checkGraphNodeMap(adaptor);
349
  checkGraphArcMap(adaptor);
350

	
351
  // Hide all nodes
352
  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
353

	
354
  checkGraphNodeList(adaptor, 0);
355
  checkGraphArcList(adaptor, 0);
356
  checkGraphConArcList(adaptor, 0);
357

	
358
  checkNodeIds(adaptor);
359
  checkArcIds(adaptor);
360

	
361
  checkGraphNodeMap(adaptor);
362
  checkGraphArcMap(adaptor);
363

	
364
  // Check the conversion of nodes and arcs
365
  Digraph::Node nd = n3;
366
  nd = n3;
367
  Adaptor::Node na = n1;
368
  na = n2;
369
  Digraph::Arc ad = a3;
370
  ad = a3;
371
  Adaptor::Arc aa = a1;
372
  aa = a2;
373
}
374

	
375
void checkFilterArcs() {
376
  // Check concepts
377
  checkConcept<concepts::Digraph, FilterArcs<concepts::Digraph> >();
378
  checkConcept<concepts::Digraph, FilterArcs<ListDigraph> >();
379
  checkConcept<concepts::AlterableDigraphComponent<>,
380
               FilterArcs<ListDigraph> >();
381
  checkConcept<concepts::ExtendableDigraphComponent<>,
382
               FilterArcs<ListDigraph> >();
383
  checkConcept<concepts::ErasableDigraphComponent<>,
384
               FilterArcs<ListDigraph> >();
385
  checkConcept<concepts::ClearableDigraphComponent<>,
386
               FilterArcs<ListDigraph> >();
387

	
388
  // Create a digraph and an adaptor
389
  typedef ListDigraph Digraph;
390
  typedef Digraph::ArcMap<bool> ArcFilter;
391
  typedef FilterArcs<Digraph, ArcFilter> Adaptor;
392

	
393
  Digraph digraph;
394
  ArcFilter arc_filter(digraph);
395
  Adaptor adaptor(digraph, arc_filter);
396

	
397
  // Add nodes and arcs to the original digraph and the adaptor
398
  Digraph::Node n1 = digraph.addNode();
399
  Digraph::Node n2 = digraph.addNode();
400
  Adaptor::Node n3 = adaptor.addNode();
401

	
402
  Digraph::Arc a1 = digraph.addArc(n1, n2);
403
  Digraph::Arc a2 = digraph.addArc(n1, n3);
404
  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
405

	
406
  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
407

	
408
  checkGraphNodeList(adaptor, 3);
409
  checkGraphArcList(adaptor, 3);
410
  checkGraphConArcList(adaptor, 3);
411

	
412
  checkGraphOutArcList(adaptor, n1, 2);
413
  checkGraphOutArcList(adaptor, n2, 1);
414
  checkGraphOutArcList(adaptor, n3, 0);
415

	
416
  checkGraphInArcList(adaptor, n1, 0);
417
  checkGraphInArcList(adaptor, n2, 1);
418
  checkGraphInArcList(adaptor, n3, 2);
419

	
420
  checkNodeIds(adaptor);
421
  checkArcIds(adaptor);
422

	
423
  checkGraphNodeMap(adaptor);
424
  checkGraphArcMap(adaptor);
425

	
426
  // Hide an arc
427
  adaptor.status(a2, false);
428
  adaptor.disable(a3);
429
  if (!adaptor.status(a3)) adaptor.enable(a3);
430

	
431
  checkGraphNodeList(adaptor, 3);
432
  checkGraphArcList(adaptor, 2);
433
  checkGraphConArcList(adaptor, 2);
434

	
435
  checkGraphOutArcList(adaptor, n1, 1);
436
  checkGraphOutArcList(adaptor, n2, 1);
437
  checkGraphOutArcList(adaptor, n3, 0);
438

	
439
  checkGraphInArcList(adaptor, n1, 0);
440
  checkGraphInArcList(adaptor, n2, 1);
441
  checkGraphInArcList(adaptor, n3, 1);
442

	
443
  checkNodeIds(adaptor);
444
  checkArcIds(adaptor);
445

	
446
  checkGraphNodeMap(adaptor);
447
  checkGraphArcMap(adaptor);
448

	
449
  // Hide all arcs
450
  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
451

	
452
  checkGraphNodeList(adaptor, 3);
453
  checkGraphArcList(adaptor, 0);
454
  checkGraphConArcList(adaptor, 0);
455

	
456
  checkNodeIds(adaptor);
457
  checkArcIds(adaptor);
458

	
459
  checkGraphNodeMap(adaptor);
460
  checkGraphArcMap(adaptor);
461

	
462
  // Check the conversion of nodes and arcs
463
  Digraph::Node nd = n3;
464
  nd = n3;
465
  Adaptor::Node na = n1;
466
  na = n2;
467
  Digraph::Arc ad = a3;
468
  ad = a3;
469
  Adaptor::Arc aa = a1;
470
  aa = a2;
471
}
472

	
473
void checkUndirector() {
474
  // Check concepts
475
  checkConcept<concepts::Graph, Undirector<concepts::Digraph> >();
476
  checkConcept<concepts::Graph, Undirector<ListDigraph> >();
477
  checkConcept<concepts::AlterableGraphComponent<>,
478
               Undirector<ListDigraph> >();
479
  checkConcept<concepts::ExtendableGraphComponent<>,
480
               Undirector<ListDigraph> >();
481
  checkConcept<concepts::ErasableGraphComponent<>,
482
               Undirector<ListDigraph> >();
483
  checkConcept<concepts::ClearableGraphComponent<>,
484
               Undirector<ListDigraph> >();
485

	
486

	
487
  // Create a digraph and an adaptor
488
  typedef ListDigraph Digraph;
489
  typedef Undirector<Digraph> Adaptor;
490

	
491
  Digraph digraph;
492
  Adaptor adaptor(digraph);
493

	
494
  // Add nodes and arcs/edges to the original digraph and the adaptor
495
  Digraph::Node n1 = digraph.addNode();
496
  Digraph::Node n2 = digraph.addNode();
497
  Adaptor::Node n3 = adaptor.addNode();
498

	
499
  Digraph::Arc a1 = digraph.addArc(n1, n2);
500
  Digraph::Arc a2 = digraph.addArc(n1, n3);
501
  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
502

	
503
  // Check the original digraph
504
  checkGraphNodeList(digraph, 3);
505
  checkGraphArcList(digraph, 3);
506
  checkGraphConArcList(digraph, 3);
507

	
508
  checkGraphOutArcList(digraph, n1, 2);
509
  checkGraphOutArcList(digraph, n2, 1);
510
  checkGraphOutArcList(digraph, n3, 0);
511

	
512
  checkGraphInArcList(digraph, n1, 0);
513
  checkGraphInArcList(digraph, n2, 1);
514
  checkGraphInArcList(digraph, n3, 2);
515

	
516
  checkNodeIds(digraph);
517
  checkArcIds(digraph);
518

	
519
  checkGraphNodeMap(digraph);
520
  checkGraphArcMap(digraph);
521

	
522
  // Check the adaptor
523
  checkGraphNodeList(adaptor, 3);
524
  checkGraphArcList(adaptor, 6);
525
  checkGraphEdgeList(adaptor, 3);
526
  checkGraphConArcList(adaptor, 6);
527
  checkGraphConEdgeList(adaptor, 3);
528

	
529
  checkGraphIncEdgeArcLists(adaptor, n1, 2);
530
  checkGraphIncEdgeArcLists(adaptor, n2, 2);
531
  checkGraphIncEdgeArcLists(adaptor, n3, 2);
532

	
533
  checkNodeIds(adaptor);
534
  checkArcIds(adaptor);
535
  checkEdgeIds(adaptor);
536

	
537
  checkGraphNodeMap(adaptor);
538
  checkGraphArcMap(adaptor);
539
  checkGraphEdgeMap(adaptor);
540

	
541
  // Check the edges of the adaptor
542
  for (Adaptor::EdgeIt e(adaptor); e != INVALID; ++e) {
543
    check(adaptor.u(e) == digraph.source(e), "Wrong undir");
544
    check(adaptor.v(e) == digraph.target(e), "Wrong undir");
545
  }
546

	
547
  // Check CombinedArcMap
548
  typedef Adaptor::CombinedArcMap
549
    <Digraph::ArcMap<int>, Digraph::ArcMap<int> > IntCombinedMap;
550
  typedef Adaptor::CombinedArcMap
551
    <Digraph::ArcMap<bool>, Digraph::ArcMap<bool> > BoolCombinedMap;
552
  checkConcept<concepts::ReferenceMap<Adaptor::Arc, int, int&, const int&>,
553
    IntCombinedMap>();
554
  checkConcept<concepts::ReferenceMap<Adaptor::Arc, bool, bool&, const bool&>,
555
    BoolCombinedMap>();
556

	
557
  Digraph::ArcMap<int> fw_map(digraph), bk_map(digraph);
558
  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
559
    fw_map[a] = digraph.id(a);
560
    bk_map[a] = -digraph.id(a);
561
  }
562

	
563
  Adaptor::CombinedArcMap<Digraph::ArcMap<int>, Digraph::ArcMap<int> >
564
    comb_map(fw_map, bk_map);
565
  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
566
    if (adaptor.source(a) == digraph.source(a)) {
567
      check(comb_map[a] == fw_map[a], "Wrong combined map");
568
    } else {
569
      check(comb_map[a] == bk_map[a], "Wrong combined map");
570
    }
571
  }
572

	
573
  // Check the conversion of nodes and arcs/edges
574
  Digraph::Node nd = n3;
575
  nd = n3;
576
  Adaptor::Node na = n1;
577
  na = n2;
578
  Digraph::Arc ad = e3;
579
  ad = e3;
580
  Adaptor::Edge ea = a1;
581
  ea = a2;
582
}
583

	
584
void checkResidualDigraph() {
585
  // Check concepts
586
  checkConcept<concepts::Digraph, ResidualDigraph<concepts::Digraph> >();
587
  checkConcept<concepts::Digraph, ResidualDigraph<ListDigraph> >();
588

	
589
  // Create a digraph and an adaptor
590
  typedef ListDigraph Digraph;
591
  typedef Digraph::ArcMap<int> IntArcMap;
592
  typedef ResidualDigraph<Digraph, IntArcMap> Adaptor;
593

	
594
  Digraph digraph;
595
  IntArcMap capacity(digraph), flow(digraph);
596
  Adaptor adaptor(digraph, capacity, flow);
597

	
598
  Digraph::Node n1 = digraph.addNode();
599
  Digraph::Node n2 = digraph.addNode();
600
  Digraph::Node n3 = digraph.addNode();
601
  Digraph::Node n4 = digraph.addNode();
602

	
603
  Digraph::Arc a1 = digraph.addArc(n1, n2);
604
  Digraph::Arc a2 = digraph.addArc(n1, n3);
605
  Digraph::Arc a3 = digraph.addArc(n1, n4);
606
  Digraph::Arc a4 = digraph.addArc(n2, n3);
607
  Digraph::Arc a5 = digraph.addArc(n2, n4);
608
  Digraph::Arc a6 = digraph.addArc(n3, n4);
609

	
610
  capacity[a1] = 8;
611
  capacity[a2] = 6;
612
  capacity[a3] = 4;
613
  capacity[a4] = 4;
614
  capacity[a5] = 6;
615
  capacity[a6] = 10;
616

	
617
  // Check the adaptor with various flow values
618
  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
619
    flow[a] = 0;
620
  }
621

	
622
  checkGraphNodeList(adaptor, 4);
623
  checkGraphArcList(adaptor, 6);
624
  checkGraphConArcList(adaptor, 6);
625

	
626
  checkGraphOutArcList(adaptor, n1, 3);
627
  checkGraphOutArcList(adaptor, n2, 2);
628
  checkGraphOutArcList(adaptor, n3, 1);
629
  checkGraphOutArcList(adaptor, n4, 0);
630

	
631
  checkGraphInArcList(adaptor, n1, 0);
632
  checkGraphInArcList(adaptor, n2, 1);
633
  checkGraphInArcList(adaptor, n3, 2);
634
  checkGraphInArcList(adaptor, n4, 3);
635

	
636
  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
637
    flow[a] = capacity[a] / 2;
638
  }
639

	
640
  checkGraphNodeList(adaptor, 4);
641
  checkGraphArcList(adaptor, 12);
642
  checkGraphConArcList(adaptor, 12);
643

	
644
  checkGraphOutArcList(adaptor, n1, 3);
645
  checkGraphOutArcList(adaptor, n2, 3);
646
  checkGraphOutArcList(adaptor, n3, 3);
647
  checkGraphOutArcList(adaptor, n4, 3);
648

	
649
  checkGraphInArcList(adaptor, n1, 3);
650
  checkGraphInArcList(adaptor, n2, 3);
651
  checkGraphInArcList(adaptor, n3, 3);
652
  checkGraphInArcList(adaptor, n4, 3);
653

	
654
  checkNodeIds(adaptor);
655
  checkArcIds(adaptor);
656

	
657
  checkGraphNodeMap(adaptor);
658
  checkGraphArcMap(adaptor);
659

	
660
  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
661
    flow[a] = capacity[a];
662
  }
663

	
664
  checkGraphNodeList(adaptor, 4);
665
  checkGraphArcList(adaptor, 6);
666
  checkGraphConArcList(adaptor, 6);
667

	
668
  checkGraphOutArcList(adaptor, n1, 0);
669
  checkGraphOutArcList(adaptor, n2, 1);
670
  checkGraphOutArcList(adaptor, n3, 2);
671
  checkGraphOutArcList(adaptor, n4, 3);
672

	
673
  checkGraphInArcList(adaptor, n1, 3);
674
  checkGraphInArcList(adaptor, n2, 2);
675
  checkGraphInArcList(adaptor, n3, 1);
676
  checkGraphInArcList(adaptor, n4, 0);
677

	
678
  // Saturate all backward arcs
679
  // (set the flow to zero on all forward arcs)
680
  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
681
    if (adaptor.backward(a))
682
      adaptor.augment(a, adaptor.residualCapacity(a));
683
  }
684

	
685
  checkGraphNodeList(adaptor, 4);
686
  checkGraphArcList(adaptor, 6);
687
  checkGraphConArcList(adaptor, 6);
688

	
689
  checkGraphOutArcList(adaptor, n1, 3);
690
  checkGraphOutArcList(adaptor, n2, 2);
691
  checkGraphOutArcList(adaptor, n3, 1);
692
  checkGraphOutArcList(adaptor, n4, 0);
693

	
694
  checkGraphInArcList(adaptor, n1, 0);
695
  checkGraphInArcList(adaptor, n2, 1);
696
  checkGraphInArcList(adaptor, n3, 2);
697
  checkGraphInArcList(adaptor, n4, 3);
698

	
699
  // Find maximum flow by augmenting along shortest paths
700
  int flow_value = 0;
701
  Adaptor::ResidualCapacity res_cap(adaptor);
702
  while (true) {
703

	
704
    Bfs<Adaptor> bfs(adaptor);
705
    bfs.run(n1, n4);
706

	
707
    if (!bfs.reached(n4)) break;
708

	
709
    Path<Adaptor> p = bfs.path(n4);
710

	
711
    int min = std::numeric_limits<int>::max();
712
    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
713
      if (res_cap[a] < min) min = res_cap[a];
714
    }
715

	
716
    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
717
      adaptor.augment(a, min);
718
    }
719
    flow_value += min;
720
  }
721

	
722
  check(flow_value == 18, "Wrong flow with res graph adaptor");
723

	
724
  // Check forward() and backward()
725
  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
726
    check(adaptor.forward(a) != adaptor.backward(a),
727
          "Wrong forward() or backward()");
728
    check((adaptor.forward(a) && adaptor.forward(Digraph::Arc(a)) == a) ||
729
          (adaptor.backward(a) && adaptor.backward(Digraph::Arc(a)) == a),
730
          "Wrong forward() or backward()");
731
  }
732

	
733
  // Check the conversion of nodes and arcs
734
  Digraph::Node nd = Adaptor::NodeIt(adaptor);
735
  nd = ++Adaptor::NodeIt(adaptor);
736
  Adaptor::Node na = n1;
737
  na = n2;
738
  Digraph::Arc ad = Adaptor::ArcIt(adaptor);
739
  ad = ++Adaptor::ArcIt(adaptor);
740
}
741

	
742
void checkSplitNodes() {
743
  // Check concepts
744
  checkConcept<concepts::Digraph, SplitNodes<concepts::Digraph> >();
745
  checkConcept<concepts::Digraph, SplitNodes<ListDigraph> >();
746

	
747
  // Create a digraph and an adaptor
748
  typedef ListDigraph Digraph;
749
  typedef SplitNodes<Digraph> Adaptor;
750

	
751
  Digraph digraph;
752
  Adaptor adaptor(digraph);
753

	
754
  Digraph::Node n1 = digraph.addNode();
755
  Digraph::Node n2 = digraph.addNode();
756
  Digraph::Node n3 = digraph.addNode();
757

	
758
  Digraph::Arc a1 = digraph.addArc(n1, n2);
759
  Digraph::Arc a2 = digraph.addArc(n1, n3);
760
  Digraph::Arc a3 = digraph.addArc(n2, n3);
761

	
762
  checkGraphNodeList(adaptor, 6);
763
  checkGraphArcList(adaptor, 6);
764
  checkGraphConArcList(adaptor, 6);
765

	
766
  checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
767
  checkGraphOutArcList(adaptor, adaptor.outNode(n1), 2);
768
  checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
769
  checkGraphOutArcList(adaptor, adaptor.outNode(n2), 1);
770
  checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
771
  checkGraphOutArcList(adaptor, adaptor.outNode(n3), 0);
772

	
773
  checkGraphInArcList(adaptor, adaptor.inNode(n1), 0);
774
  checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
775
  checkGraphInArcList(adaptor, adaptor.inNode(n2), 1);
776
  checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
777
  checkGraphInArcList(adaptor, adaptor.inNode(n3), 2);
778
  checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
779

	
780
  checkNodeIds(adaptor);
781
  checkArcIds(adaptor);
782

	
783
  checkGraphNodeMap(adaptor);
784
  checkGraphArcMap(adaptor);
785

	
786
  // Check split
787
  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
788
    if (adaptor.origArc(a)) {
789
      Digraph::Arc oa = a;
790
      check(adaptor.source(a) == adaptor.outNode(digraph.source(oa)),
791
            "Wrong split");
792
      check(adaptor.target(a) == adaptor.inNode(digraph.target(oa)),
793
            "Wrong split");
794
    } else {
795
      Digraph::Node on = a;
796
      check(adaptor.source(a) == adaptor.inNode(on), "Wrong split");
797
      check(adaptor.target(a) == adaptor.outNode(on), "Wrong split");
798
    }
799
  }
800

	
801
  // Check combined node map
802
  typedef Adaptor::CombinedNodeMap
803
    <Digraph::NodeMap<int>, Digraph::NodeMap<int> > IntCombinedNodeMap;
804
  typedef Adaptor::CombinedNodeMap
805
    <Digraph::NodeMap<bool>, Digraph::NodeMap<bool> > BoolCombinedNodeMap;
806
  checkConcept<concepts::ReferenceMap<Adaptor::Node, int, int&, const int&>,
807
    IntCombinedNodeMap>();
808
//checkConcept<concepts::ReferenceMap<Adaptor::Node, bool, bool&, const bool&>,
809
//  BoolCombinedNodeMap>();
810
  checkConcept<concepts::ReadWriteMap<Adaptor::Node, bool>,
811
    BoolCombinedNodeMap>();
812

	
813
  Digraph::NodeMap<int> in_map(digraph), out_map(digraph);
814
  for (Digraph::NodeIt n(digraph); n != INVALID; ++n) {
815
    in_map[n] = digraph.id(n);
816
    out_map[n] = -digraph.id(n);
817
  }
818

	
819
  Adaptor::CombinedNodeMap<Digraph::NodeMap<int>, Digraph::NodeMap<int> >
820
    node_map(in_map, out_map);
821
  for (Adaptor::NodeIt n(adaptor); n != INVALID; ++n) {
822
    if (adaptor.inNode(n)) {
823
      check(node_map[n] == in_map[n], "Wrong combined node map");
824
    } else {
825
      check(node_map[n] == out_map[n], "Wrong combined node map");
826
    }
827
  }
828

	
829
  // Check combined arc map
830
  typedef Adaptor::CombinedArcMap
831
    <Digraph::ArcMap<int>, Digraph::NodeMap<int> > IntCombinedArcMap;
832
  typedef Adaptor::CombinedArcMap
833
    <Digraph::ArcMap<bool>, Digraph::NodeMap<bool> > BoolCombinedArcMap;
834
  checkConcept<concepts::ReferenceMap<Adaptor::Arc, int, int&, const int&>,
835
    IntCombinedArcMap>();
836
//checkConcept<concepts::ReferenceMap<Adaptor::Arc, bool, bool&, const bool&>,
837
//  BoolCombinedArcMap>();
838
  checkConcept<concepts::ReadWriteMap<Adaptor::Arc, bool>,
839
    BoolCombinedArcMap>();
840

	
841
  Digraph::ArcMap<int> a_map(digraph);
842
  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
843
    a_map[a] = digraph.id(a);
844
  }
845

	
846
  Adaptor::CombinedArcMap<Digraph::ArcMap<int>, Digraph::NodeMap<int> >
847
    arc_map(a_map, out_map);
848
  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
849
    check(arc_map[adaptor.arc(a)] == a_map[a],  "Wrong combined arc map");
850
  }
851
  for (Digraph::NodeIt n(digraph); n != INVALID; ++n) {
852
    check(arc_map[adaptor.arc(n)] == out_map[n],  "Wrong combined arc map");
853
  }
854

	
855
  // Check the conversion of nodes
856
  Digraph::Node nd = adaptor.inNode(n1);
857
  check (nd == n1, "Wrong node conversion");
858
  nd = adaptor.outNode(n2);
859
  check (nd == n2, "Wrong node conversion");
860
}
861

	
862
void checkSubGraph() {
863
  // Check concepts
864
  checkConcept<concepts::Graph, SubGraph<concepts::Graph> >();
865
  checkConcept<concepts::Graph, SubGraph<ListGraph> >();
866
  checkConcept<concepts::AlterableGraphComponent<>,
867
               SubGraph<ListGraph> >();
868
  checkConcept<concepts::ExtendableGraphComponent<>,
869
               SubGraph<ListGraph> >();
870
  checkConcept<concepts::ErasableGraphComponent<>,
871
               SubGraph<ListGraph> >();
872
  checkConcept<concepts::ClearableGraphComponent<>,
873
               SubGraph<ListGraph> >();
874

	
875
  // Create a graph and an adaptor
876
  typedef ListGraph Graph;
877
  typedef Graph::NodeMap<bool> NodeFilter;
878
  typedef Graph::EdgeMap<bool> EdgeFilter;
879
  typedef SubGraph<Graph, NodeFilter, EdgeFilter> Adaptor;
880

	
881
  Graph graph;
882
  NodeFilter node_filter(graph);
883
  EdgeFilter edge_filter(graph);
884
  Adaptor adaptor(graph, node_filter, edge_filter);
885

	
886
  // Add nodes and edges to the original graph and the adaptor
887
  Graph::Node n1 = graph.addNode();
888
  Graph::Node n2 = graph.addNode();
889
  Adaptor::Node n3 = adaptor.addNode();
890
  Adaptor::Node n4 = adaptor.addNode();
891

	
892
  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
893

	
894
  Graph::Edge e1 = graph.addEdge(n1, n2);
895
  Graph::Edge e2 = graph.addEdge(n1, n3);
896
  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
897
  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
898

	
899
  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
900

	
901
  checkGraphNodeList(adaptor, 4);
902
  checkGraphArcList(adaptor, 8);
903
  checkGraphEdgeList(adaptor, 4);
904
  checkGraphConArcList(adaptor, 8);
905
  checkGraphConEdgeList(adaptor, 4);
906

	
907
  checkGraphIncEdgeArcLists(adaptor, n1, 2);
908
  checkGraphIncEdgeArcLists(adaptor, n2, 2);
909
  checkGraphIncEdgeArcLists(adaptor, n3, 3);
910
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
911

	
912
  checkNodeIds(adaptor);
913
  checkArcIds(adaptor);
914
  checkEdgeIds(adaptor);
915

	
916
  checkGraphNodeMap(adaptor);
917
  checkGraphArcMap(adaptor);
918
  checkGraphEdgeMap(adaptor);
919

	
920
  // Hide an edge
921
  adaptor.status(e2, false);
922
  adaptor.disable(e3);
923
  if (!adaptor.status(e3)) adaptor.enable(e3);
924

	
925
  checkGraphNodeList(adaptor, 4);
926
  checkGraphArcList(adaptor, 6);
927
  checkGraphEdgeList(adaptor, 3);
928
  checkGraphConArcList(adaptor, 6);
929
  checkGraphConEdgeList(adaptor, 3);
930

	
931
  checkGraphIncEdgeArcLists(adaptor, n1, 1);
932
  checkGraphIncEdgeArcLists(adaptor, n2, 2);
933
  checkGraphIncEdgeArcLists(adaptor, n3, 2);
934
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
935

	
936
  checkNodeIds(adaptor);
937
  checkArcIds(adaptor);
938
  checkEdgeIds(adaptor);
939

	
940
  checkGraphNodeMap(adaptor);
941
  checkGraphArcMap(adaptor);
942
  checkGraphEdgeMap(adaptor);
943

	
944
  // Hide a node
945
  adaptor.status(n1, false);
946
  adaptor.disable(n3);
947
  if (!adaptor.status(n3)) adaptor.enable(n3);
948

	
949
  checkGraphNodeList(adaptor, 3);
950
  checkGraphArcList(adaptor, 4);
951
  checkGraphEdgeList(adaptor, 2);
952
  checkGraphConArcList(adaptor, 4);
953
  checkGraphConEdgeList(adaptor, 2);
954

	
955
  checkGraphIncEdgeArcLists(adaptor, n2, 1);
956
  checkGraphIncEdgeArcLists(adaptor, n3, 2);
957
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
958

	
959
  checkNodeIds(adaptor);
960
  checkArcIds(adaptor);
961
  checkEdgeIds(adaptor);
962

	
963
  checkGraphNodeMap(adaptor);
964
  checkGraphArcMap(adaptor);
965
  checkGraphEdgeMap(adaptor);
966

	
967
  // Hide all nodes and edges
968
  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
969
  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
970

	
971
  checkGraphNodeList(adaptor, 0);
972
  checkGraphArcList(adaptor, 0);
973
  checkGraphEdgeList(adaptor, 0);
974
  checkGraphConArcList(adaptor, 0);
975
  checkGraphConEdgeList(adaptor, 0);
976

	
977
  checkNodeIds(adaptor);
978
  checkArcIds(adaptor);
979
  checkEdgeIds(adaptor);
980

	
981
  checkGraphNodeMap(adaptor);
982
  checkGraphArcMap(adaptor);
983
  checkGraphEdgeMap(adaptor);
984

	
985
  // Check the conversion of nodes and edges
986
  Graph::Node ng = n3;
987
  ng = n4;
988
  Adaptor::Node na = n1;
989
  na = n2;
990
  Graph::Edge eg = e3;
991
  eg = e4;
992
  Adaptor::Edge ea = e1;
993
  ea = e2;
994
}
995

	
996
void checkFilterNodes2() {
997
  // Check concepts
998
  checkConcept<concepts::Graph, FilterNodes<concepts::Graph> >();
999
  checkConcept<concepts::Graph, FilterNodes<ListGraph> >();
1000
  checkConcept<concepts::AlterableGraphComponent<>,
1001
               FilterNodes<ListGraph> >();
1002
  checkConcept<concepts::ExtendableGraphComponent<>,
1003
               FilterNodes<ListGraph> >();
1004
  checkConcept<concepts::ErasableGraphComponent<>,
1005
               FilterNodes<ListGraph> >();
1006
  checkConcept<concepts::ClearableGraphComponent<>,
1007
               FilterNodes<ListGraph> >();
1008

	
1009
  // Create a graph and an adaptor
1010
  typedef ListGraph Graph;
1011
  typedef Graph::NodeMap<bool> NodeFilter;
1012
  typedef FilterNodes<Graph, NodeFilter> Adaptor;
1013

	
1014
  // Add nodes and edges to the original graph and the adaptor
1015
  Graph graph;
1016
  NodeFilter node_filter(graph);
1017
  Adaptor adaptor(graph, node_filter);
1018

	
1019
  Graph::Node n1 = graph.addNode();
1020
  Graph::Node n2 = graph.addNode();
1021
  Adaptor::Node n3 = adaptor.addNode();
1022
  Adaptor::Node n4 = adaptor.addNode();
1023

	
1024
  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
1025

	
1026
  Graph::Edge e1 = graph.addEdge(n1, n2);
1027
  Graph::Edge e2 = graph.addEdge(n1, n3);
1028
  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
1029
  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
1030

	
1031
  checkGraphNodeList(adaptor, 4);
1032
  checkGraphArcList(adaptor, 8);
1033
  checkGraphEdgeList(adaptor, 4);
1034
  checkGraphConArcList(adaptor, 8);
1035
  checkGraphConEdgeList(adaptor, 4);
1036

	
1037
  checkGraphIncEdgeArcLists(adaptor, n1, 2);
1038
  checkGraphIncEdgeArcLists(adaptor, n2, 2);
1039
  checkGraphIncEdgeArcLists(adaptor, n3, 3);
1040
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
1041

	
1042
  checkNodeIds(adaptor);
1043
  checkArcIds(adaptor);
1044
  checkEdgeIds(adaptor);
1045

	
1046
  checkGraphNodeMap(adaptor);
1047
  checkGraphArcMap(adaptor);
1048
  checkGraphEdgeMap(adaptor);
1049

	
1050
  // Hide a node
1051
  adaptor.status(n1, false);
1052
  adaptor.disable(n3);
1053
  if (!adaptor.status(n3)) adaptor.enable(n3);
1054

	
1055
  checkGraphNodeList(adaptor, 3);
1056
  checkGraphArcList(adaptor, 4);
1057
  checkGraphEdgeList(adaptor, 2);
1058
  checkGraphConArcList(adaptor, 4);
1059
  checkGraphConEdgeList(adaptor, 2);
1060

	
1061
  checkGraphIncEdgeArcLists(adaptor, n2, 1);
1062
  checkGraphIncEdgeArcLists(adaptor, n3, 2);
1063
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
1064

	
1065
  checkNodeIds(adaptor);
1066
  checkArcIds(adaptor);
1067
  checkEdgeIds(adaptor);
1068

	
1069
  checkGraphNodeMap(adaptor);
1070
  checkGraphArcMap(adaptor);
1071
  checkGraphEdgeMap(adaptor);
1072

	
1073
  // Hide all nodes
1074
  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
1075

	
1076
  checkGraphNodeList(adaptor, 0);
1077
  checkGraphArcList(adaptor, 0);
1078
  checkGraphEdgeList(adaptor, 0);
1079
  checkGraphConArcList(adaptor, 0);
1080
  checkGraphConEdgeList(adaptor, 0);
1081

	
1082
  checkNodeIds(adaptor);
1083
  checkArcIds(adaptor);
1084
  checkEdgeIds(adaptor);
1085

	
1086
  checkGraphNodeMap(adaptor);
1087
  checkGraphArcMap(adaptor);
1088
  checkGraphEdgeMap(adaptor);
1089

	
1090
  // Check the conversion of nodes and edges
1091
  Graph::Node ng = n3;
1092
  ng = n4;
1093
  Adaptor::Node na = n1;
1094
  na = n2;
1095
  Graph::Edge eg = e3;
1096
  eg = e4;
1097
  Adaptor::Edge ea = e1;
1098
  ea = e2;
1099
}
1100

	
1101
void checkFilterEdges() {
1102
  // Check concepts
1103
  checkConcept<concepts::Graph, FilterEdges<concepts::Graph> >();
1104
  checkConcept<concepts::Graph, FilterEdges<ListGraph> >();
1105
  checkConcept<concepts::AlterableGraphComponent<>,
1106
               FilterEdges<ListGraph> >();
1107
  checkConcept<concepts::ExtendableGraphComponent<>,
1108
               FilterEdges<ListGraph> >();
1109
  checkConcept<concepts::ErasableGraphComponent<>,
1110
               FilterEdges<ListGraph> >();
1111
  checkConcept<concepts::ClearableGraphComponent<>,
1112
               FilterEdges<ListGraph> >();
1113

	
1114
  // Create a graph and an adaptor
1115
  typedef ListGraph Graph;
1116
  typedef Graph::EdgeMap<bool> EdgeFilter;
1117
  typedef FilterEdges<Graph, EdgeFilter> Adaptor;
1118

	
1119
  Graph graph;
1120
  EdgeFilter edge_filter(graph);
1121
  Adaptor adaptor(graph, edge_filter);
1122

	
1123
  // Add nodes and edges to the original graph and the adaptor
1124
  Graph::Node n1 = graph.addNode();
1125
  Graph::Node n2 = graph.addNode();
1126
  Adaptor::Node n3 = adaptor.addNode();
1127
  Adaptor::Node n4 = adaptor.addNode();
1128

	
1129
  Graph::Edge e1 = graph.addEdge(n1, n2);
1130
  Graph::Edge e2 = graph.addEdge(n1, n3);
1131
  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
1132
  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
1133

	
1134
  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
1135

	
1136
  checkGraphNodeList(adaptor, 4);
1137
  checkGraphArcList(adaptor, 8);
1138
  checkGraphEdgeList(adaptor, 4);
1139
  checkGraphConArcList(adaptor, 8);
1140
  checkGraphConEdgeList(adaptor, 4);
1141

	
1142
  checkGraphIncEdgeArcLists(adaptor, n1, 2);
1143
  checkGraphIncEdgeArcLists(adaptor, n2, 2);
1144
  checkGraphIncEdgeArcLists(adaptor, n3, 3);
1145
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
1146

	
1147
  checkNodeIds(adaptor);
1148
  checkArcIds(adaptor);
1149
  checkEdgeIds(adaptor);
1150

	
1151
  checkGraphNodeMap(adaptor);
1152
  checkGraphArcMap(adaptor);
1153
  checkGraphEdgeMap(adaptor);
1154

	
1155
  // Hide an edge
1156
  adaptor.status(e2, false);
1157
  adaptor.disable(e3);
1158
  if (!adaptor.status(e3)) adaptor.enable(e3);
1159

	
1160
  checkGraphNodeList(adaptor, 4);
1161
  checkGraphArcList(adaptor, 6);
1162
  checkGraphEdgeList(adaptor, 3);
1163
  checkGraphConArcList(adaptor, 6);
1164
  checkGraphConEdgeList(adaptor, 3);
1165

	
1166
  checkGraphIncEdgeArcLists(adaptor, n1, 1);
1167
  checkGraphIncEdgeArcLists(adaptor, n2, 2);
1168
  checkGraphIncEdgeArcLists(adaptor, n3, 2);
1169
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
1170

	
1171
  checkNodeIds(adaptor);
1172
  checkArcIds(adaptor);
1173
  checkEdgeIds(adaptor);
1174

	
1175
  checkGraphNodeMap(adaptor);
1176
  checkGraphArcMap(adaptor);
1177
  checkGraphEdgeMap(adaptor);
1178

	
1179
  // Hide all edges
1180
  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
1181

	
1182
  checkGraphNodeList(adaptor, 4);
1183
  checkGraphArcList(adaptor, 0);
1184
  checkGraphEdgeList(adaptor, 0);
1185
  checkGraphConArcList(adaptor, 0);
1186
  checkGraphConEdgeList(adaptor, 0);
1187

	
1188
  checkNodeIds(adaptor);
1189
  checkArcIds(adaptor);
1190
  checkEdgeIds(adaptor);
1191

	
1192
  checkGraphNodeMap(adaptor);
1193
  checkGraphArcMap(adaptor);
1194
  checkGraphEdgeMap(adaptor);
1195

	
1196
  // Check the conversion of nodes and edges
1197
  Graph::Node ng = n3;
1198
  ng = n4;
1199
  Adaptor::Node na = n1;
1200
  na = n2;
1201
  Graph::Edge eg = e3;
1202
  eg = e4;
1203
  Adaptor::Edge ea = e1;
1204
  ea = e2;
1205
}
1206

	
1207
void checkOrienter() {
1208
  // Check concepts
1209
  checkConcept<concepts::Digraph, Orienter<concepts::Graph> >();
1210
  checkConcept<concepts::Digraph, Orienter<ListGraph> >();
1211
  checkConcept<concepts::AlterableDigraphComponent<>,
1212
               Orienter<ListGraph> >();
1213
  checkConcept<concepts::ExtendableDigraphComponent<>,
1214
               Orienter<ListGraph> >();
1215
  checkConcept<concepts::ErasableDigraphComponent<>,
1216
               Orienter<ListGraph> >();
1217
  checkConcept<concepts::ClearableDigraphComponent<>,
1218
               Orienter<ListGraph> >();
1219

	
1220
  // Create a graph and an adaptor
1221
  typedef ListGraph Graph;
1222
  typedef ListGraph::EdgeMap<bool> DirMap;
1223
  typedef Orienter<Graph> Adaptor;
1224

	
1225
  Graph graph;
1226
  DirMap dir(graph);
1227
  Adaptor adaptor(graph, dir);
1228

	
1229
  // Add nodes and edges to the original graph and the adaptor
1230
  Graph::Node n1 = graph.addNode();
1231
  Graph::Node n2 = graph.addNode();
1232
  Adaptor::Node n3 = adaptor.addNode();
1233

	
1234
  Graph::Edge e1 = graph.addEdge(n1, n2);
1235
  Graph::Edge e2 = graph.addEdge(n1, n3);
1236
  Adaptor::Arc e3 = adaptor.addArc(n2, n3);
1237

	
1238
  dir[e1] = dir[e2] = dir[e3] = true;
1239

	
1240
  // Check the original graph
1241
  checkGraphNodeList(graph, 3);
1242
  checkGraphArcList(graph, 6);
1243
  checkGraphConArcList(graph, 6);
1244
  checkGraphEdgeList(graph, 3);
1245
  checkGraphConEdgeList(graph, 3);
1246

	
1247
  checkGraphIncEdgeArcLists(graph, n1, 2);
1248
  checkGraphIncEdgeArcLists(graph, n2, 2);
1249
  checkGraphIncEdgeArcLists(graph, n3, 2);
1250

	
1251
  checkNodeIds(graph);
1252
  checkArcIds(graph);
1253
  checkEdgeIds(graph);
1254

	
1255
  checkGraphNodeMap(graph);
1256
  checkGraphArcMap(graph);
1257
  checkGraphEdgeMap(graph);
1258

	
1259
  // Check the adaptor
1260
  checkGraphNodeList(adaptor, 3);
1261
  checkGraphArcList(adaptor, 3);
1262
  checkGraphConArcList(adaptor, 3);
1263

	
1264
  checkGraphOutArcList(adaptor, n1, 2);
1265
  checkGraphOutArcList(adaptor, n2, 1);
1266
  checkGraphOutArcList(adaptor, n3, 0);
1267

	
1268
  checkGraphInArcList(adaptor, n1, 0);
1269
  checkGraphInArcList(adaptor, n2, 1);
1270
  checkGraphInArcList(adaptor, n3, 2);
1271

	
1272
  checkNodeIds(adaptor);
1273
  checkArcIds(adaptor);
1274

	
1275
  checkGraphNodeMap(adaptor);
1276
  checkGraphArcMap(adaptor);
1277

	
1278
  // Check direction changing
1279
  {
1280
    dir[e1] = true;
1281
    Adaptor::Node u = adaptor.source(e1);
1282
    Adaptor::Node v = adaptor.target(e1);
1283

	
1284
    dir[e1] = false;
1285
    check (u == adaptor.target(e1), "Wrong dir");
1286
    check (v == adaptor.source(e1), "Wrong dir");
1287

	
1288
    check ((u == n1 && v == n2) || (u == n2 && v == n1), "Wrong dir");
1289
    dir[e1] = n1 == u;
1290
  }
1291

	
1292
  {
1293
    dir[e2] = true;
1294
    Adaptor::Node u = adaptor.source(e2);
1295
    Adaptor::Node v = adaptor.target(e2);
1296

	
1297
    dir[e2] = false;
1298
    check (u == adaptor.target(e2), "Wrong dir");
1299
    check (v == adaptor.source(e2), "Wrong dir");
1300

	
1301
    check ((u == n1 && v == n3) || (u == n3 && v == n1), "Wrong dir");
1302
    dir[e2] = n3 == u;
1303
  }
1304

	
1305
  {
1306
    dir[e3] = true;
1307
    Adaptor::Node u = adaptor.source(e3);
1308
    Adaptor::Node v = adaptor.target(e3);
1309

	
1310
    dir[e3] = false;
1311
    check (u == adaptor.target(e3), "Wrong dir");
1312
    check (v == adaptor.source(e3), "Wrong dir");
1313

	
1314
    check ((u == n2 && v == n3) || (u == n3 && v == n2), "Wrong dir");
1315
    dir[e3] = n2 == u;
1316
  }
1317

	
1318
  // Check the adaptor again
1319
  checkGraphNodeList(adaptor, 3);
1320
  checkGraphArcList(adaptor, 3);
1321
  checkGraphConArcList(adaptor, 3);
1322

	
1323
  checkGraphOutArcList(adaptor, n1, 1);
1324
  checkGraphOutArcList(adaptor, n2, 1);
1325
  checkGraphOutArcList(adaptor, n3, 1);
1326

	
1327
  checkGraphInArcList(adaptor, n1, 1);
1328
  checkGraphInArcList(adaptor, n2, 1);
1329
  checkGraphInArcList(adaptor, n3, 1);
1330

	
1331
  checkNodeIds(adaptor);
1332
  checkArcIds(adaptor);
1333

	
1334
  checkGraphNodeMap(adaptor);
1335
  checkGraphArcMap(adaptor);
1336

	
1337
  // Check reverseArc()
1338
  adaptor.reverseArc(e2);
1339
  adaptor.reverseArc(e3);
1340
  adaptor.reverseArc(e2);
1341

	
1342
  checkGraphNodeList(adaptor, 3);
1343
  checkGraphArcList(adaptor, 3);
1344
  checkGraphConArcList(adaptor, 3);
1345

	
1346
  checkGraphOutArcList(adaptor, n1, 1);
1347
  checkGraphOutArcList(adaptor, n2, 0);
1348
  checkGraphOutArcList(adaptor, n3, 2);
1349

	
1350
  checkGraphInArcList(adaptor, n1, 1);
1351
  checkGraphInArcList(adaptor, n2, 2);
1352
  checkGraphInArcList(adaptor, n3, 0);
1353

	
1354
  // Check the conversion of nodes and arcs/edges
1355
  Graph::Node ng = n3;
1356
  ng = n3;
1357
  Adaptor::Node na = n1;
1358
  na = n2;
1359
  Graph::Edge eg = e3;
1360
  eg = e3;
1361
  Adaptor::Arc aa = e1;
1362
  aa = e2;
1363
}
1364

	
1365
void checkCombiningAdaptors() {
1366
  // Create a grid graph
1367
  GridGraph graph(2,2);
1368
  GridGraph::Node n1 = graph(0,0);
1369
  GridGraph::Node n2 = graph(0,1);
1370
  GridGraph::Node n3 = graph(1,0);
1371
  GridGraph::Node n4 = graph(1,1);
1372

	
1373
  GridGraph::EdgeMap<bool> dir_map(graph);
1374
  dir_map[graph.right(n1)] = graph.u(graph.right(n1)) == n1;
1375
  dir_map[graph.up(n1)] = graph.u(graph.up(n1)) != n1;
1376
  dir_map[graph.left(n4)] = graph.u(graph.left(n4)) != n4;
1377
  dir_map[graph.down(n4)] = graph.u(graph.down(n4)) != n4;
1378

	
1379
  // Apply several adaptors on the grid graph
1380
  typedef SplitNodes< ReverseDigraph< const Orienter<
1381
            const GridGraph, GridGraph::EdgeMap<bool> > > >
1382
    RevSplitGridGraph;
1383
  typedef ReverseDigraph<const RevSplitGridGraph> SplitGridGraph;
1384
  typedef Undirector<const SplitGridGraph> USplitGridGraph;
1385
  typedef Undirector<const USplitGridGraph> UUSplitGridGraph;
1386
  checkConcept<concepts::Digraph, RevSplitGridGraph>();
1387
  checkConcept<concepts::Digraph, SplitGridGraph>();
1388
  checkConcept<concepts::Graph, USplitGridGraph>();
1389
  checkConcept<concepts::Graph, UUSplitGridGraph>();
1390

	
1391
  RevSplitGridGraph rev_adaptor =
1392
    splitNodes(reverseDigraph(orienter(graph, dir_map)));
1393
  SplitGridGraph adaptor = reverseDigraph(rev_adaptor);
1394
  USplitGridGraph uadaptor = undirector(adaptor);
1395
  UUSplitGridGraph uuadaptor = undirector(uadaptor);
1396

	
1397
  // Check adaptor
1398
  checkGraphNodeList(adaptor, 8);
1399
  checkGraphArcList(adaptor, 8);
1400
  checkGraphConArcList(adaptor, 8);
1401

	
1402
  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n1), 1);
1403
  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n1), 1);
1404
  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n2), 2);
1405
  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n2), 1);
1406
  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n3), 1);
1407
  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n3), 1);
1408
  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n4), 0);
1409
  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n4), 1);
1410

	
1411
  checkGraphInArcList(adaptor, rev_adaptor.inNode(n1), 1);
1412
  checkGraphInArcList(adaptor, rev_adaptor.outNode(n1), 1);
1413
  checkGraphInArcList(adaptor, rev_adaptor.inNode(n2), 1);
1414
  checkGraphInArcList(adaptor, rev_adaptor.outNode(n2), 0);
1415
  checkGraphInArcList(adaptor, rev_adaptor.inNode(n3), 1);
1416
  checkGraphInArcList(adaptor, rev_adaptor.outNode(n3), 1);
1417
  checkGraphInArcList(adaptor, rev_adaptor.inNode(n4), 1);
1418
  checkGraphInArcList(adaptor, rev_adaptor.outNode(n4), 2);
1419

	
1420
  checkNodeIds(adaptor);
1421
  checkArcIds(adaptor);
1422

	
1423
  checkGraphNodeMap(adaptor);
1424
  checkGraphArcMap(adaptor);
1425

	
1426
  // Check uadaptor
1427
  checkGraphNodeList(uadaptor, 8);
1428
  checkGraphEdgeList(uadaptor, 8);
1429
  checkGraphArcList(uadaptor, 16);
1430
  checkGraphConEdgeList(uadaptor, 8);
1431
  checkGraphConArcList(uadaptor, 16);
1432

	
1433
  checkNodeIds(uadaptor);
1434
  checkEdgeIds(uadaptor);
1435
  checkArcIds(uadaptor);
1436

	
1437
  checkGraphNodeMap(uadaptor);
1438
  checkGraphEdgeMap(uadaptor);
1439
  checkGraphArcMap(uadaptor);
1440

	
1441
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n1), 2);
1442
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n1), 2);
1443
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n2), 3);
1444
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n2), 1);
1445
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n3), 2);
1446
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n3), 2);
1447
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n4), 1);
1448
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n4), 3);
1449

	
1450
  // Check uuadaptor
1451
  checkGraphNodeList(uuadaptor, 8);
1452
  checkGraphEdgeList(uuadaptor, 16);
1453
  checkGraphArcList(uuadaptor, 32);
1454
  checkGraphConEdgeList(uuadaptor, 16);
1455
  checkGraphConArcList(uuadaptor, 32);
1456

	
1457
  checkNodeIds(uuadaptor);
1458
  checkEdgeIds(uuadaptor);
1459
  checkArcIds(uuadaptor);
1460

	
1461
  checkGraphNodeMap(uuadaptor);
1462
  checkGraphEdgeMap(uuadaptor);
1463
  checkGraphArcMap(uuadaptor);
1464
}
1465

	
1466
int main(int, const char **) {
1467
  // Check the digraph adaptors (using ListDigraph)
1468
  checkReverseDigraph();
1469
  checkSubDigraph();
1470
  checkFilterNodes1();
1471
  checkFilterArcs();
1472
  checkUndirector();
1473
  checkResidualDigraph();
1474
  checkSplitNodes();
1475

	
1476
  // Check the graph adaptors (using ListGraph)
1477
  checkSubGraph();
1478
  checkFilterNodes2();
1479
  checkFilterEdges();
1480
  checkOrienter();
1481

	
1482
  // Combine adaptors (using GridGraph)
1483
  checkCombiningAdaptors();
1484

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

	
19
#include <iostream>
20

	
21
#include "test_tools.h"
22
#include <lemon/list_graph.h>
23
#include <lemon/circulation.h>
24
#include <lemon/lgf_reader.h>
25
#include <lemon/concepts/digraph.h>
26
#include <lemon/concepts/maps.h>
27

	
28
using namespace lemon;
29

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

	
52
void checkCirculationCompile()
53
{
54
  typedef int VType;
55
  typedef concepts::Digraph Digraph;
56

	
57
  typedef Digraph::Node Node;
58
  typedef Digraph::Arc Arc;
59
  typedef concepts::ReadMap<Arc,VType> CapMap;
60
  typedef concepts::ReadMap<Node,VType> SupplyMap;
61
  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
62
  typedef concepts::WriteMap<Node,bool> BarrierMap;
63

	
64
  typedef Elevator<Digraph, Digraph::Node> Elev;
65
  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
66

	
67
  Digraph g;
68
  Node n;
69
  Arc a;
70
  CapMap lcap, ucap;
71
  SupplyMap supply;
72
  FlowMap flow;
73
  BarrierMap bar;
74
  VType v;
75
  bool b;
76

	
77
  typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
78
            ::SetFlowMap<FlowMap>
79
            ::SetElevator<Elev>
80
            ::SetStandardElevator<LinkedElev>
81
            ::Create CirculationType;
82
  CirculationType circ_test(g, lcap, ucap, supply);
83
  const CirculationType& const_circ_test = circ_test;
84
   
85
  circ_test
86
    .lowerMap(lcap)
87
    .upperMap(ucap)
88
    .supplyMap(supply)
89
    .flowMap(flow);
90

	
91
  circ_test.init();
92
  circ_test.greedyInit();
93
  circ_test.start();
94
  circ_test.run();
95

	
96
  v = const_circ_test.flow(a);
97
  const FlowMap& fm = const_circ_test.flowMap();
98
  b = const_circ_test.barrier(n);
99
  const_circ_test.barrierMap(bar);
100
  
101
  ignore_unused_variable_warning(fm);
102
}
103

	
104
template <class G, class LM, class UM, class DM>
105
void checkCirculation(const G& g, const LM& lm, const UM& um,
106
                      const DM& dm, bool find)
107
{
108
  Circulation<G, LM, UM, DM> circ(g, lm, um, dm);
109
  bool ret = circ.run();
110
  if (find) {
111
    check(ret, "A feasible solution should have been found.");
112
    check(circ.checkFlow(), "The found flow is corrupt.");
113
    check(!circ.checkBarrier(), "A barrier should not have been found.");
114
  } else {
115
    check(!ret, "A feasible solution should not have been found.");
116
    check(circ.checkBarrier(), "The found barrier is corrupt.");
117
  }
118
}
119

	
120
int main (int, char*[])
121
{
122
  typedef ListDigraph Digraph;
123
  DIGRAPH_TYPEDEFS(Digraph);
124

	
125
  Digraph g;
126
  IntArcMap lo(g), up(g);
127
  IntNodeMap delta(g, 0);
128
  Node s, t;
129

	
130
  std::istringstream input(test_lgf);
131
  DigraphReader<Digraph>(g,input).
132
    arcMap("lcap", lo).
133
    arcMap("ucap", up).
134
    node("source",s).
135
    node("sink",t).
136
    run();
137

	
138
  delta[s] = 7; delta[t] = -7;
139
  checkCirculation(g, lo, up, delta, true);
140

	
141
  delta[s] = 13; delta[t] = -13;
142
  checkCirculation(g, lo, up, delta, true);
143

	
144
  delta[s] = 6; delta[t] = -6;
145
  checkCirculation(g, lo, up, delta, false);
146

	
147
  delta[s] = 14; delta[t] = -14;
148
  checkCirculation(g, lo, up, delta, false);
149

	
150
  delta[s] = 7; delta[t] = -13;
151
  checkCirculation(g, lo, up, delta, true);
152

	
153
  delta[s] = 5; delta[t] = -15;
154
  checkCirculation(g, lo, up, delta, true);
155

	
156
  delta[s] = 10; delta[t] = -11;
157
  checkCirculation(g, lo, up, delta, true);
158

	
159
  delta[s] = 11; delta[t] = -10;
160
  checkCirculation(g, lo, up, delta, false);
161

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

	
19
#include <lemon/connectivity.h>
20
#include <lemon/list_graph.h>
21
#include <lemon/adaptors.h>
22

	
23
#include "test_tools.h"
24

	
25
using namespace lemon;
26

	
27

	
28
int main()
29
{
30
  typedef ListDigraph Digraph;
31
  typedef Undirector<Digraph> Graph;
32
  
33
  {
34
    Digraph d;
35
    Digraph::NodeMap<int> order(d);
36
    Graph g(d);
37
    
38
    check(stronglyConnected(d), "The empty digraph is strongly connected");
39
    check(countStronglyConnectedComponents(d) == 0,
40
          "The empty digraph has 0 strongly connected component");
41
    check(connected(g), "The empty graph is connected");
42
    check(countConnectedComponents(g) == 0,
43
          "The empty graph has 0 connected component");
44

	
45
    check(biNodeConnected(g), "The empty graph is bi-node-connected");
46
    check(countBiNodeConnectedComponents(g) == 0,
47
          "The empty graph has 0 bi-node-connected component");
48
    check(biEdgeConnected(g), "The empty graph is bi-edge-connected");
49
    check(countBiEdgeConnectedComponents(g) == 0,
50
          "The empty graph has 0 bi-edge-connected component");
51
          
52
    check(dag(d), "The empty digraph is DAG.");
53
    check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
54
    check(loopFree(d), "The empty digraph is loop-free.");
55
    check(parallelFree(d), "The empty digraph is parallel-free.");
56
    check(simpleGraph(d), "The empty digraph is simple.");
57

	
58
    check(acyclic(g), "The empty graph is acyclic.");
59
    check(tree(g), "The empty graph is tree.");
60
    check(bipartite(g), "The empty graph is bipartite.");
61
    check(loopFree(g), "The empty graph is loop-free.");
62
    check(parallelFree(g), "The empty graph is parallel-free.");
63
    check(simpleGraph(g), "The empty graph is simple.");
64
  }
65

	
66
  {
67
    Digraph d;
68
    Digraph::NodeMap<int> order(d);
69
    Graph g(d);
70
    Digraph::Node n = d.addNode();
71

	
72
    check(stronglyConnected(d), "This digraph is strongly connected");
73
    check(countStronglyConnectedComponents(d) == 1,
74
          "This digraph has 1 strongly connected component");
75
    check(connected(g), "This graph is connected");
76
    check(countConnectedComponents(g) == 1,
77
          "This graph has 1 connected component");
78

	
79
    check(biNodeConnected(g), "This graph is bi-node-connected");
80
    check(countBiNodeConnectedComponents(g) == 0,
81
          "This graph has 0 bi-node-connected component");
82
    check(biEdgeConnected(g), "This graph is bi-edge-connected");
83
    check(countBiEdgeConnectedComponents(g) == 1,
84
          "This graph has 1 bi-edge-connected component");
85
          
86
    check(dag(d), "This digraph is DAG.");
87
    check(checkedTopologicalSort(d, order), "This digraph is DAG.");
88
    check(loopFree(d), "This digraph is loop-free.");
89
    check(parallelFree(d), "This digraph is parallel-free.");
90
    check(simpleGraph(d), "This digraph is simple.");
91

	
92
    check(acyclic(g), "This graph is acyclic.");
93
    check(tree(g), "This graph is tree.");
94
    check(bipartite(g), "This graph is bipartite.");
95
    check(loopFree(g), "This graph is loop-free.");
96
    check(parallelFree(g), "This graph is parallel-free.");
97
    check(simpleGraph(g), "This graph is simple.");
98
  }
99

	
100
  {
101
    Digraph d;
102
    Digraph::NodeMap<int> order(d);
103
    Graph g(d);
104
    
105
    Digraph::Node n1 = d.addNode();
106
    Digraph::Node n2 = d.addNode();
107
    Digraph::Node n3 = d.addNode();
108
    Digraph::Node n4 = d.addNode();
109
    Digraph::Node n5 = d.addNode();
110
    Digraph::Node n6 = d.addNode();
111
    
112
    d.addArc(n1, n3);
113
    d.addArc(n3, n2);
114
    d.addArc(n2, n1);
115
    d.addArc(n4, n2);
116
    d.addArc(n4, n3);
117
    d.addArc(n5, n6);
118
    d.addArc(n6, n5);
119

	
120
    check(!stronglyConnected(d), "This digraph is not strongly connected");
121
    check(countStronglyConnectedComponents(d) == 3,
122
          "This digraph has 3 strongly connected components");
123
    check(!connected(g), "This graph is not connected");
124
    check(countConnectedComponents(g) == 2,
125
          "This graph has 2 connected components");
126

	
127
    check(!dag(d), "This digraph is not DAG.");
128
    check(!checkedTopologicalSort(d, order), "This digraph is not DAG.");
129
    check(loopFree(d), "This digraph is loop-free.");
130
    check(parallelFree(d), "This digraph is parallel-free.");
131
    check(simpleGraph(d), "This digraph is simple.");
132

	
133
    check(!acyclic(g), "This graph is not acyclic.");
134
    check(!tree(g), "This graph is not tree.");
135
    check(!bipartite(g), "This graph is not bipartite.");
136
    check(loopFree(g), "This graph is loop-free.");
137
    check(!parallelFree(g), "This graph is not parallel-free.");
138
    check(!simpleGraph(g), "This graph is not simple.");
139
    
140
    d.addArc(n3, n3);
141
    
142
    check(!loopFree(d), "This digraph is not loop-free.");
143
    check(!loopFree(g), "This graph is not loop-free.");
144
    check(!simpleGraph(d), "This digraph is not simple.");
145
    
146
    d.addArc(n3, n2);
147
    
148
    check(!parallelFree(d), "This digraph is not parallel-free.");
149
  }
150
  
151
  {
152
    Digraph d;
153
    Digraph::ArcMap<bool> cutarcs(d, false);
154
    Graph g(d);
155
    
156
    Digraph::Node n1 = d.addNode();
157
    Digraph::Node n2 = d.addNode();
158
    Digraph::Node n3 = d.addNode();
159
    Digraph::Node n4 = d.addNode();
160
    Digraph::Node n5 = d.addNode();
161
    Digraph::Node n6 = d.addNode();
162
    Digraph::Node n7 = d.addNode();
163
    Digraph::Node n8 = d.addNode();
164

	
165
    d.addArc(n1, n2);
166
    d.addArc(n5, n1);
167
    d.addArc(n2, n8);
168
    d.addArc(n8, n5);
169
    d.addArc(n6, n4);
170
    d.addArc(n4, n6);
171
    d.addArc(n2, n5);
172
    d.addArc(n1, n8);
173
    d.addArc(n6, n7);
174
    d.addArc(n7, n6);
175
   
176
    check(!stronglyConnected(d), "This digraph is not strongly connected");
177
    check(countStronglyConnectedComponents(d) == 3,
178
          "This digraph has 3 strongly connected components");
179
    Digraph::NodeMap<int> scomp1(d);
180
    check(stronglyConnectedComponents(d, scomp1) == 3,
181
          "This digraph has 3 strongly connected components");
182
    check(scomp1[n1] != scomp1[n3] && scomp1[n1] != scomp1[n4] &&
183
          scomp1[n3] != scomp1[n4], "Wrong stronglyConnectedComponents()");
184
    check(scomp1[n1] == scomp1[n2] && scomp1[n1] == scomp1[n5] &&
185
          scomp1[n1] == scomp1[n8], "Wrong stronglyConnectedComponents()");
186
    check(scomp1[n4] == scomp1[n6] && scomp1[n4] == scomp1[n7],
187
          "Wrong stronglyConnectedComponents()");
188
    Digraph::ArcMap<bool> scut1(d, false);
189
    check(stronglyConnectedCutArcs(d, scut1) == 0,
190
          "This digraph has 0 strongly connected cut arc.");
191
    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
192
      check(!scut1[a], "Wrong stronglyConnectedCutArcs()");
193
    }
194

	
195
    check(!connected(g), "This graph is not connected");
196
    check(countConnectedComponents(g) == 3,
197
          "This graph has 3 connected components");
198
    Graph::NodeMap<int> comp(g);
199
    check(connectedComponents(g, comp) == 3,
200
          "This graph has 3 connected components");
201
    check(comp[n1] != comp[n3] && comp[n1] != comp[n4] &&
202
          comp[n3] != comp[n4], "Wrong connectedComponents()");
203
    check(comp[n1] == comp[n2] && comp[n1] == comp[n5] &&
204
          comp[n1] == comp[n8], "Wrong connectedComponents()");
205
    check(comp[n4] == comp[n6] && comp[n4] == comp[n7],
206
          "Wrong connectedComponents()");
207

	
208
    cutarcs[d.addArc(n3, n1)] = true;
209
    cutarcs[d.addArc(n3, n5)] = true;
210
    cutarcs[d.addArc(n3, n8)] = true;
211
    cutarcs[d.addArc(n8, n6)] = true;
212
    cutarcs[d.addArc(n8, n7)] = true;
213

	
214
    check(!stronglyConnected(d), "This digraph is not strongly connected");
215
    check(countStronglyConnectedComponents(d) == 3,
216
          "This digraph has 3 strongly connected components");
217
    Digraph::NodeMap<int> scomp2(d);
218
    check(stronglyConnectedComponents(d, scomp2) == 3,
219
          "This digraph has 3 strongly connected components");
220
    check(scomp2[n3] == 0, "Wrong stronglyConnectedComponents()");
221
    check(scomp2[n1] == 1 && scomp2[n2] == 1 && scomp2[n5] == 1 &&
222
          scomp2[n8] == 1, "Wrong stronglyConnectedComponents()");
223
    check(scomp2[n4] == 2 && scomp2[n6] == 2 && scomp2[n7] == 2,
224
          "Wrong stronglyConnectedComponents()");
225
    Digraph::ArcMap<bool> scut2(d, false);
226
    check(stronglyConnectedCutArcs(d, scut2) == 5,
227
          "This digraph has 5 strongly connected cut arcs.");
228
    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
229
      check(scut2[a] == cutarcs[a], "Wrong stronglyConnectedCutArcs()");
230
    }
231
  }
232

	
233
  {
234
    // DAG example for topological sort from the book New Algorithms
235
    // (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein)
236
    Digraph d;
237
    Digraph::NodeMap<int> order(d);
238
    
239
    Digraph::Node belt = d.addNode();
240
    Digraph::Node trousers = d.addNode();
241
    Digraph::Node necktie = d.addNode();
242
    Digraph::Node coat = d.addNode();
243
    Digraph::Node socks = d.addNode();
244
    Digraph::Node shirt = d.addNode();
245
    Digraph::Node shoe = d.addNode();
246
    Digraph::Node watch = d.addNode();
247
    Digraph::Node pants = d.addNode();
248

	
249
    d.addArc(socks, shoe);
250
    d.addArc(pants, shoe);
251
    d.addArc(pants, trousers);
252
    d.addArc(trousers, shoe);
253
    d.addArc(trousers, belt);
254
    d.addArc(belt, coat);
255
    d.addArc(shirt, belt);
256
    d.addArc(shirt, necktie);
257
    d.addArc(necktie, coat);
258
    
259
    check(dag(d), "This digraph is DAG.");
260
    topologicalSort(d, order);
261
    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
262
      check(order[d.source(a)] < order[d.target(a)],
263
            "Wrong topologicalSort()");
264
    }
265
  }
266

	
267
  {
268
    ListGraph g;
269
    ListGraph::NodeMap<bool> map(g);
270
    
271
    ListGraph::Node n1 = g.addNode();
272
    ListGraph::Node n2 = g.addNode();
273
    ListGraph::Node n3 = g.addNode();
274
    ListGraph::Node n4 = g.addNode();
275
    ListGraph::Node n5 = g.addNode();
276
    ListGraph::Node n6 = g.addNode();
277
    ListGraph::Node n7 = g.addNode();
278

	
279
    g.addEdge(n1, n3);
280
    g.addEdge(n1, n4);
281
    g.addEdge(n2, n5);
282
    g.addEdge(n3, n6);
283
    g.addEdge(n4, n6);
284
    g.addEdge(n4, n7);
285
    g.addEdge(n5, n7);
286
   
287
    check(bipartite(g), "This graph is bipartite");
288
    check(bipartitePartitions(g, map), "This graph is bipartite");
289
    
290
    check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
291
          "Wrong bipartitePartitions()");
292
    check(map[n3] == map[n4] && map[n3] == map[n5],
293
          "Wrong bipartitePartitions()");
294
  }
295

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

	
19
#include <iostream>
20
#include <vector>
21

	
22
#include <lemon/concepts/digraph.h>
23
#include <lemon/concepts/graph.h>
24
#include <lemon/concept_check.h>
25

	
26
#include <lemon/list_graph.h>
27

	
28
#include <lemon/edge_set.h>
29

	
30
#include "graph_test.h"
31
#include "test_tools.h"
32

	
33
using namespace lemon;
34

	
35
void checkSmartArcSet() {
36
  checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
37

	
38
  typedef ListDigraph Digraph;
39
  typedef SmartArcSet<Digraph> ArcSet;
40

	
41
  Digraph digraph;
42
  Digraph::Node
43
    n1 = digraph.addNode(),
44
    n2 = digraph.addNode();
45

	
46
  Digraph::Arc ga1 = digraph.addArc(n1, n2);
47

	
48
  ArcSet arc_set(digraph);
49

	
50
  Digraph::Arc ga2 = digraph.addArc(n2, n1);
51

	
52
  checkGraphNodeList(arc_set, 2);
53
  checkGraphArcList(arc_set, 0);
54

	
55
  Digraph::Node
56
    n3 = digraph.addNode();
57
  checkGraphNodeList(arc_set, 3);
58
  checkGraphArcList(arc_set, 0);
59

	
60
  ArcSet::Arc a1 = arc_set.addArc(n1, n2);
61
  check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
62
  checkGraphNodeList(arc_set, 3);
63
  checkGraphArcList(arc_set, 1);
64

	
65
  checkGraphOutArcList(arc_set, n1, 1);
66
  checkGraphOutArcList(arc_set, n2, 0);
67
  checkGraphOutArcList(arc_set, n3, 0);
68

	
69
  checkGraphInArcList(arc_set, n1, 0);
70
  checkGraphInArcList(arc_set, n2, 1);
71
  checkGraphInArcList(arc_set, n3, 0);
72

	
73
  checkGraphConArcList(arc_set, 1);
74

	
75
  ArcSet::Arc a2 = arc_set.addArc(n2, n1),
76
    a3 = arc_set.addArc(n2, n3),
77
    a4 = arc_set.addArc(n2, n3);
78
  checkGraphNodeList(arc_set, 3);
79
  checkGraphArcList(arc_set, 4);
80

	
81
  checkGraphOutArcList(arc_set, n1, 1);
82
  checkGraphOutArcList(arc_set, n2, 3);
83
  checkGraphOutArcList(arc_set, n3, 0);
84

	
85
  checkGraphInArcList(arc_set, n1, 1);
86
  checkGraphInArcList(arc_set, n2, 1);
87
  checkGraphInArcList(arc_set, n3, 2);
88

	
89
  checkGraphConArcList(arc_set, 4);
90

	
91
  checkNodeIds(arc_set);
92
  checkArcIds(arc_set);
93
  checkGraphNodeMap(arc_set);
94
  checkGraphArcMap(arc_set);
95

	
96
  check(arc_set.valid(), "Wrong validity");
97
  digraph.erase(n1);
98
  check(!arc_set.valid(), "Wrong validity");
99
}
100

	
101
void checkListArcSet() {
102
  checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
103

	
104
  typedef ListDigraph Digraph;
105
  typedef ListArcSet<Digraph> ArcSet;
106

	
107
  Digraph digraph;
108
  Digraph::Node
109
    n1 = digraph.addNode(),
110
    n2 = digraph.addNode();
111

	
112
  Digraph::Arc ga1 = digraph.addArc(n1, n2);
113

	
114
  ArcSet arc_set(digraph);
115

	
116
  Digraph::Arc ga2 = digraph.addArc(n2, n1);
117

	
118
  checkGraphNodeList(arc_set, 2);
119
  checkGraphArcList(arc_set, 0);
120

	
121
  Digraph::Node
122
    n3 = digraph.addNode();
123
  checkGraphNodeList(arc_set, 3);
124
  checkGraphArcList(arc_set, 0);
125

	
126
  ArcSet::Arc a1 = arc_set.addArc(n1, n2);
127
  check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
128
  checkGraphNodeList(arc_set, 3);
129
  checkGraphArcList(arc_set, 1);
130

	
131
  checkGraphOutArcList(arc_set, n1, 1);
132
  checkGraphOutArcList(arc_set, n2, 0);
133
  checkGraphOutArcList(arc_set, n3, 0);
134

	
135
  checkGraphInArcList(arc_set, n1, 0);
136
  checkGraphInArcList(arc_set, n2, 1);
137
  checkGraphInArcList(arc_set, n3, 0);
138

	
139
  checkGraphConArcList(arc_set, 1);
140

	
141
  ArcSet::Arc a2 = arc_set.addArc(n2, n1),
142
    a3 = arc_set.addArc(n2, n3),
143
    a4 = arc_set.addArc(n2, n3);
144
  checkGraphNodeList(arc_set, 3);
145
  checkGraphArcList(arc_set, 4);
146

	
147
  checkGraphOutArcList(arc_set, n1, 1);
148
  checkGraphOutArcList(arc_set, n2, 3);
149
  checkGraphOutArcList(arc_set, n3, 0);
150

	
151
  checkGraphInArcList(arc_set, n1, 1);
152
  checkGraphInArcList(arc_set, n2, 1);
153
  checkGraphInArcList(arc_set, n3, 2);
154

	
155
  checkGraphConArcList(arc_set, 4);
156

	
157
  checkNodeIds(arc_set);
158
  checkArcIds(arc_set);
159
  checkGraphNodeMap(arc_set);
160
  checkGraphArcMap(arc_set);
161

	
162
  digraph.erase(n1);
163

	
164
  checkGraphNodeList(arc_set, 2);
165
  checkGraphArcList(arc_set, 2);
166

	
167
  checkGraphOutArcList(arc_set, n2, 2);
168
  checkGraphOutArcList(arc_set, n3, 0);
169

	
170
  checkGraphInArcList(arc_set, n2, 0);
171
  checkGraphInArcList(arc_set, n3, 2);
172

	
173
  checkNodeIds(arc_set);
174
  checkArcIds(arc_set);
175
  checkGraphNodeMap(arc_set);
176
  checkGraphArcMap(arc_set);
177

	
178
  checkGraphConArcList(arc_set, 2);
179
}
180

	
181
void checkSmartEdgeSet() {
182
  checkConcept<concepts::Digraph, SmartEdgeSet<ListDigraph> >();
183

	
184
  typedef ListDigraph Digraph;
185
  typedef SmartEdgeSet<Digraph> EdgeSet;
186

	
187
  Digraph digraph;
188
  Digraph::Node
189
    n1 = digraph.addNode(),
190
    n2 = digraph.addNode();
191

	
192
  Digraph::Arc ga1 = digraph.addArc(n1, n2);
193

	
194
  EdgeSet edge_set(digraph);
195

	
196
  Digraph::Arc ga2 = digraph.addArc(n2, n1);
197

	
198
  checkGraphNodeList(edge_set, 2);
199
  checkGraphArcList(edge_set, 0);
200
  checkGraphEdgeList(edge_set, 0);
201

	
202
  Digraph::Node
203
    n3 = digraph.addNode();
204
  checkGraphNodeList(edge_set, 3);
205
  checkGraphArcList(edge_set, 0);
206
  checkGraphEdgeList(edge_set, 0);
207

	
208
  EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
209
  check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
210
        (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
211
  checkGraphNodeList(edge_set, 3);
212
  checkGraphArcList(edge_set, 2);
213
  checkGraphEdgeList(edge_set, 1);
214

	
215
  checkGraphOutArcList(edge_set, n1, 1);
216
  checkGraphOutArcList(edge_set, n2, 1);
217
  checkGraphOutArcList(edge_set, n3, 0);
218

	
219
  checkGraphInArcList(edge_set, n1, 1);
220
  checkGraphInArcList(edge_set, n2, 1);
221
  checkGraphInArcList(edge_set, n3, 0);
222

	
223
  checkGraphIncEdgeList(edge_set, n1, 1);
224
  checkGraphIncEdgeList(edge_set, n2, 1);
225
  checkGraphIncEdgeList(edge_set, n3, 0);
226

	
227
  checkGraphConEdgeList(edge_set, 1);
228
  checkGraphConArcList(edge_set, 2);
229

	
230
  EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
231
    e3 = edge_set.addEdge(n2, n3),
232
    e4 = edge_set.addEdge(n2, n3);
233
  checkGraphNodeList(edge_set, 3);
234
  checkGraphEdgeList(edge_set, 4);
235

	
236
  checkGraphOutArcList(edge_set, n1, 2);
237
  checkGraphOutArcList(edge_set, n2, 4);
238
  checkGraphOutArcList(edge_set, n3, 2);
239

	
240
  checkGraphInArcList(edge_set, n1, 2);
241
  checkGraphInArcList(edge_set, n2, 4);
242
  checkGraphInArcList(edge_set, n3, 2);
243

	
244
  checkGraphIncEdgeList(edge_set, n1, 2);
245
  checkGraphIncEdgeList(edge_set, n2, 4);
246
  checkGraphIncEdgeList(edge_set, n3, 2);
247

	
248
  checkGraphConEdgeList(edge_set, 4);
249
  checkGraphConArcList(edge_set, 8);
250

	
251
  checkArcDirections(edge_set);
252

	
253
  checkNodeIds(edge_set);
254
  checkArcIds(edge_set);
255
  checkEdgeIds(edge_set);
256
  checkGraphNodeMap(edge_set);
257
  checkGraphArcMap(edge_set);
258
  checkGraphEdgeMap(edge_set);
259

	
260
  check(edge_set.valid(), "Wrong validity");
261
  digraph.erase(n1);
262
  check(!edge_set.valid(), "Wrong validity");
263
}
264

	
265
void checkListEdgeSet() {
266
  checkConcept<concepts::Digraph, ListEdgeSet<ListDigraph> >();
267

	
268
  typedef ListDigraph Digraph;
269
  typedef ListEdgeSet<Digraph> EdgeSet;
270

	
271
  Digraph digraph;
272
  Digraph::Node
273
    n1 = digraph.addNode(),
274
    n2 = digraph.addNode();
275

	
276
  Digraph::Arc ga1 = digraph.addArc(n1, n2);
277

	
278
  EdgeSet edge_set(digraph);
279

	
280
  Digraph::Arc ga2 = digraph.addArc(n2, n1);
281

	
282
  checkGraphNodeList(edge_set, 2);
283
  checkGraphArcList(edge_set, 0);
284
  checkGraphEdgeList(edge_set, 0);
285

	
286
  Digraph::Node
287
    n3 = digraph.addNode();
288
  checkGraphNodeList(edge_set, 3);
289
  checkGraphArcList(edge_set, 0);
290
  checkGraphEdgeList(edge_set, 0);
291

	
292
  EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
293
  check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
294
        (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
295
  checkGraphNodeList(edge_set, 3);
296
  checkGraphArcList(edge_set, 2);
297
  checkGraphEdgeList(edge_set, 1);
298

	
299
  checkGraphOutArcList(edge_set, n1, 1);
300
  checkGraphOutArcList(edge_set, n2, 1);
301
  checkGraphOutArcList(edge_set, n3, 0);
302

	
303
  checkGraphInArcList(edge_set, n1, 1);
304
  checkGraphInArcList(edge_set, n2, 1);
305
  checkGraphInArcList(edge_set, n3, 0);
306

	
307
  checkGraphIncEdgeList(edge_set, n1, 1);
308
  checkGraphIncEdgeList(edge_set, n2, 1);
309
  checkGraphIncEdgeList(edge_set, n3, 0);
310

	
311
  checkGraphConEdgeList(edge_set, 1);
312
  checkGraphConArcList(edge_set, 2);
313

	
314
  EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
315
    e3 = edge_set.addEdge(n2, n3),
316
    e4 = edge_set.addEdge(n2, n3);
317
  checkGraphNodeList(edge_set, 3);
318
  checkGraphEdgeList(edge_set, 4);
319

	
320
  checkGraphOutArcList(edge_set, n1, 2);
321
  checkGraphOutArcList(edge_set, n2, 4);
322
  checkGraphOutArcList(edge_set, n3, 2);
323

	
324
  checkGraphInArcList(edge_set, n1, 2);
325
  checkGraphInArcList(edge_set, n2, 4);
326
  checkGraphInArcList(edge_set, n3, 2);
327

	
328
  checkGraphIncEdgeList(edge_set, n1, 2);
329
  checkGraphIncEdgeList(edge_set, n2, 4);
330
  checkGraphIncEdgeList(edge_set, n3, 2);
331

	
332
  checkGraphConEdgeList(edge_set, 4);
333
  checkGraphConArcList(edge_set, 8);
334

	
335
  checkArcDirections(edge_set);
336

	
337
  checkNodeIds(edge_set);
338
  checkArcIds(edge_set);
339
  checkEdgeIds(edge_set);
340
  checkGraphNodeMap(edge_set);
341
  checkGraphArcMap(edge_set);
342
  checkGraphEdgeMap(edge_set);
343

	
344
  digraph.erase(n1);
345

	
346
  checkGraphNodeList(edge_set, 2);
347
  checkGraphArcList(edge_set, 4);
348
  checkGraphEdgeList(edge_set, 2);
349

	
350
  checkGraphOutArcList(edge_set, n2, 2);
351
  checkGraphOutArcList(edge_set, n3, 2);
352

	
353
  checkGraphInArcList(edge_set, n2, 2);
354
  checkGraphInArcList(edge_set, n3, 2);
355

	
356
  checkGraphIncEdgeList(edge_set, n2, 2);
357
  checkGraphIncEdgeList(edge_set, n3, 2);
358

	
359
  checkNodeIds(edge_set);
360
  checkArcIds(edge_set);
361
  checkEdgeIds(edge_set);
362
  checkGraphNodeMap(edge_set);
363
  checkGraphArcMap(edge_set);
364
  checkGraphEdgeMap(edge_set);
365

	
366
  checkGraphConEdgeList(edge_set, 2);
367
  checkGraphConArcList(edge_set, 4);
368

	
369
}
370

	
371

	
372
int main() {
373

	
374
  checkSmartArcSet();
375
  checkListArcSet();
376
  checkSmartEdgeSet();
377
  checkListEdgeSet();
378

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

	
19
#include <lemon/euler.h>
20
#include <lemon/list_graph.h>
21
#include <lemon/adaptors.h>
22
#include "test_tools.h"
23

	
24
using namespace lemon;
25

	
26
template <typename Digraph>
27
void checkDiEulerIt(const Digraph& g,
28
                    const typename Digraph::Node& start = INVALID)
29
{
30
  typename Digraph::template ArcMap<int> visitationNumber(g, 0);
31

	
32
  DiEulerIt<Digraph> e(g, start);
33
  if (e == INVALID) return;
34
  typename Digraph::Node firstNode = g.source(e);
35
  typename Digraph::Node lastNode = g.target(e);
36
  if (start != INVALID) {
37
    check(firstNode == start, "checkDiEulerIt: Wrong first node");
38
  }
39

	
40
  for (; e != INVALID; ++e) {
41
    if (e != INVALID) lastNode = g.target(e);
42
    ++visitationNumber[e];
43
  }
44

	
45
  check(firstNode == lastNode,
46
      "checkDiEulerIt: First and last nodes are not the same");
47

	
48
  for (typename Digraph::ArcIt a(g); a != INVALID; ++a)
49
  {
50
    check(visitationNumber[a] == 1,
51
        "checkDiEulerIt: Not visited or multiple times visited arc found");
52
  }
53
}
54

	
55
template <typename Graph>
56
void checkEulerIt(const Graph& g,
57
                  const typename Graph::Node& start = INVALID)
58
{
59
  typename Graph::template EdgeMap<int> visitationNumber(g, 0);
60

	
61
  EulerIt<Graph> e(g, start);
62
  if (e == INVALID) return;
63
  typename Graph::Node firstNode = g.source(typename Graph::Arc(e));
64
  typename Graph::Node lastNode = g.target(typename Graph::Arc(e));
65
  if (start != INVALID) {
66
    check(firstNode == start, "checkEulerIt: Wrong first node");
67
  }
68

	
69
  for (; e != INVALID; ++e) {
70
    if (e != INVALID) lastNode = g.target(typename Graph::Arc(e));
71
    ++visitationNumber[e];
72
  }
73

	
74
  check(firstNode == lastNode,
75
      "checkEulerIt: First and last nodes are not the same");
76

	
77
  for (typename Graph::EdgeIt e(g); e != INVALID; ++e)
78
  {
79
    check(visitationNumber[e] == 1,
80
        "checkEulerIt: Not visited or multiple times visited edge found");
81
  }
82
}
83

	
84
int main()
85
{
86
  typedef ListDigraph Digraph;
87
  typedef Undirector<Digraph> Graph;
88
  
89
  {
90
    Digraph d;
91
    Graph g(d);
92
    
93
    checkDiEulerIt(d);
94
    checkDiEulerIt(g);
95
    checkEulerIt(g);
96

	
97
    check(eulerian(d), "This graph is Eulerian");
98
    check(eulerian(g), "This graph is Eulerian");
99
  }
100
  {
101
    Digraph d;
102
    Graph g(d);
103
    Digraph::Node n = d.addNode();
104

	
105
    checkDiEulerIt(d);
106
    checkDiEulerIt(g);
107
    checkEulerIt(g);
108

	
109
    check(eulerian(d), "This graph is Eulerian");
110
    check(eulerian(g), "This graph is Eulerian");
111
  }
112
  {
113
    Digraph d;
114
    Graph g(d);
115
    Digraph::Node n = d.addNode();
116
    d.addArc(n, n);
117

	
118
    checkDiEulerIt(d);
119
    checkDiEulerIt(g);
120
    checkEulerIt(g);
121

	
122
    check(eulerian(d), "This graph is Eulerian");
123
    check(eulerian(g), "This graph is Eulerian");
124
  }
125
  {
126
    Digraph d;
127
    Graph g(d);
128
    Digraph::Node n1 = d.addNode();
129
    Digraph::Node n2 = d.addNode();
130
    Digraph::Node n3 = d.addNode();
131
    
132
    d.addArc(n1, n2);
133
    d.addArc(n2, n1);
134
    d.addArc(n2, n3);
135
    d.addArc(n3, n2);
136

	
137
    checkDiEulerIt(d);
138
    checkDiEulerIt(d, n2);
139
    checkDiEulerIt(g);
140
    checkDiEulerIt(g, n2);
141
    checkEulerIt(g);
142
    checkEulerIt(g, n2);
143

	
144
    check(eulerian(d), "This graph is Eulerian");
145
    check(eulerian(g), "This graph is Eulerian");
146
  }
147
  {
148
    Digraph d;
149
    Graph g(d);
150
    Digraph::Node n1 = d.addNode();
151
    Digraph::Node n2 = d.addNode();
152
    Digraph::Node n3 = d.addNode();
153
    Digraph::Node n4 = d.addNode();
154
    Digraph::Node n5 = d.addNode();
155
    Digraph::Node n6 = d.addNode();
156
    
157
    d.addArc(n1, n2);
158
    d.addArc(n2, n4);
159
    d.addArc(n1, n3);
160
    d.addArc(n3, n4);
161
    d.addArc(n4, n1);
162
    d.addArc(n3, n5);
163
    d.addArc(n5, n2);
164
    d.addArc(n4, n6);
165
    d.addArc(n2, n6);
166
    d.addArc(n6, n1);
167
    d.addArc(n6, n3);
168

	
169
    checkDiEulerIt(d);
170
    checkDiEulerIt(d, n1);
171
    checkDiEulerIt(d, n5);
172

	
173
    checkDiEulerIt(g);
174
    checkDiEulerIt(g, n1);
175
    checkDiEulerIt(g, n5);
176
    checkEulerIt(g);
177
    checkEulerIt(g, n1);
178
    checkEulerIt(g, n5);
179

	
180
    check(eulerian(d), "This graph is Eulerian");
181
    check(eulerian(g), "This graph is Eulerian");
182
  }
183
  {
184
    Digraph d;
185
    Graph g(d);
186
    Digraph::Node n0 = d.addNode();
187
    Digraph::Node n1 = d.addNode();
188
    Digraph::Node n2 = d.addNode();
189
    Digraph::Node n3 = d.addNode();
190
    Digraph::Node n4 = d.addNode();
191
    Digraph::Node n5 = d.addNode();
192
    
193
    d.addArc(n1, n2);
194
    d.addArc(n2, n3);
195
    d.addArc(n3, n1);
196

	
197
    checkDiEulerIt(d);
198
    checkDiEulerIt(d, n2);
199

	
200
    checkDiEulerIt(g);
201
    checkDiEulerIt(g, n2);
202
    checkEulerIt(g);
203
    checkEulerIt(g, n2);
204

	
205
    check(!eulerian(d), "This graph is not Eulerian");
206
    check(!eulerian(g), "This graph is not Eulerian");
207
  }
208
  {
209
    Digraph d;
210
    Graph g(d);
211
    Digraph::Node n1 = d.addNode();
212
    Digraph::Node n2 = d.addNode();
213
    Digraph::Node n3 = d.addNode();
214
    
215
    d.addArc(n1, n2);
216
    d.addArc(n2, n3);
217

	
218
    check(!eulerian(d), "This graph is not Eulerian");
219
    check(!eulerian(g), "This graph is not Eulerian");
220
  }
221

	
222
  return 0;
223
}
Ignore white space 6 line context
1
#include <iostream>
2

	
3
#include "test_tools.h"
4
#include <lemon/smart_graph.h>
5
#include <lemon/concepts/graph.h>
6
#include <lemon/concepts/maps.h>
7
#include <lemon/lgf_reader.h>
8
#include <lemon/gomory_hu.h>
9
#include <cstdlib>
10

	
11
using namespace std;
12
using namespace lemon;
13

	
14
typedef SmartGraph Graph;
15

	
16
char test_lgf[] =
17
  "@nodes\n"
18
  "label\n"
19
  "0\n"
20
  "1\n"
21
  "2\n"
22
  "3\n"
23
  "4\n"
24
  "@arcs\n"
25
  "     label capacity\n"
26
  "0 1  0     1\n"
27
  "1 2  1     1\n"
28
  "2 3  2     1\n"
29
  "0 3  4     5\n"
30
  "0 3  5     10\n"
31
  "0 3  6     7\n"
32
  "4 2  7     1\n"
33
  "@attributes\n"
34
  "source 0\n"
35
  "target 3\n";
36
  
37
void checkGomoryHuCompile()
38
{
39
  typedef int Value;
40
  typedef concepts::Graph Graph;
41

	
42
  typedef Graph::Node Node;
43
  typedef Graph::Edge Edge;
44
  typedef concepts::ReadMap<Edge, Value> CapMap;
45
  typedef concepts::ReadWriteMap<Node, bool> CutMap;
46

	
47
  Graph g;
48
  Node n;
49
  CapMap cap;
50
  CutMap cut;
51
  Value v;
52
  int d;
53

	
54
  GomoryHu<Graph, CapMap> gh_test(g, cap);
55
  const GomoryHu<Graph, CapMap>&
56
    const_gh_test = gh_test;
57

	
58
  gh_test.run();
59

	
60
  n = const_gh_test.predNode(n);
61
  v = const_gh_test.predValue(n);
62
  d = const_gh_test.rootDist(n);
63
  v = const_gh_test.minCutValue(n, n);
64
  v = const_gh_test.minCutMap(n, n, cut);
65
}
66

	
67
GRAPH_TYPEDEFS(Graph);
68
typedef Graph::EdgeMap<int> IntEdgeMap;
69
typedef Graph::NodeMap<bool> BoolNodeMap;
70

	
71
int cutValue(const Graph& graph, const BoolNodeMap& cut,
72
	     const IntEdgeMap& capacity) {
73

	
74
  int sum = 0;
75
  for (EdgeIt e(graph); e != INVALID; ++e) {
76
    Node s = graph.u(e);
77
    Node t = graph.v(e);
78

	
79
    if (cut[s] != cut[t]) {
80
      sum += capacity[e];
81
    }
82
  }
83
  return sum;
84
}
85

	
86

	
87
int main() {
88
  Graph graph;
89
  IntEdgeMap capacity(graph);
90

	
91
  std::istringstream input(test_lgf);
92
  GraphReader<Graph>(graph, input).
93
    edgeMap("capacity", capacity).run();
94

	
95
  GomoryHu<Graph> ght(graph, capacity);
96
  ght.run();
97

	
98
  for (NodeIt u(graph); u != INVALID; ++u) {
99
    for (NodeIt v(graph); v != u; ++v) {
100
      Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
101
      pf.runMinCut();
102
      BoolNodeMap cm(graph);
103
      ght.minCutMap(u, v, cm);
104
      check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
105
      check(cm[u] != cm[v], "Wrong cut 2");
106
      check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 3");
107

	
108
      int sum=0;
109
      for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
110
        sum+=capacity[a]; 
111
      check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
112

	
113
      sum=0;
114
      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n)
115
        sum++;
116
      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n)
117
        sum++;
118
      check(sum == countNodes(graph), "Problem with MinCutNodeIt");
119
    }
120
  }
121
  
122
  return 0;
123
}
Ignore white space 6 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2009
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#include <sstream>
20

	
21
#include <lemon/smart_graph.h>
22
#include <lemon/adaptors.h>
23
#include <lemon/concepts/digraph.h>
24
#include <lemon/concepts/maps.h>
25
#include <lemon/lgf_reader.h>
26
#include <lemon/hao_orlin.h>
27

	
28
#include "test_tools.h"
29

	
30
using namespace lemon;
31
using namespace std;
32

	
33
const std::string lgf =
34
  "@nodes\n"
35
  "label\n"
36
  "0\n"
37
  "1\n"
38
  "2\n"
39
  "3\n"
40
  "4\n"
41
  "5\n"
42
  "@edges\n"
43
  "     cap1 cap2 cap3\n"
44
  "0 1  1    1    1   \n"
45
  "0 2  2    2    4   \n"
46
  "1 2  4    4    4   \n"
47
  "3 4  1    1    1   \n"
48
  "3 5  2    2    4   \n"
49
  "4 5  4    4    4   \n"
50
  "5 4  4    4    4   \n"
51
  "2 3  1    6    6   \n"
52
  "4 0  1    6    6   \n";
53

	
54
void checkHaoOrlinCompile()
55
{
56
  typedef int Value;
57
  typedef concepts::Digraph Digraph;
58

	
59
  typedef Digraph::Node Node;
60
  typedef Digraph::Arc Arc;
61
  typedef concepts::ReadMap<Arc, Value> CapMap;
62
  typedef concepts::WriteMap<Node, bool> CutMap;
63

	
64
  Digraph g;
65
  Node n;
66
  CapMap cap;
67
  CutMap cut;
68
  Value v;
69

	
70
  HaoOrlin<Digraph, CapMap> ho_test(g, cap);
71
  const HaoOrlin<Digraph, CapMap>&
72
    const_ho_test = ho_test;
73

	
74
  ho_test.init();
75
  ho_test.init(n);
76
  ho_test.calculateOut();
77
  ho_test.calculateIn();
78
  ho_test.run();
79
  ho_test.run(n);
80

	
81
  v = const_ho_test.minCutValue();
82
  v = const_ho_test.minCutMap(cut);
83
}
84

	
85
template <typename Graph, typename CapMap, typename CutMap>
86
typename CapMap::Value 
87
  cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
88
{
89
  typename CapMap::Value sum = 0;
90
  for (typename Graph::ArcIt a(graph); a != INVALID; ++a) {
91
    if (cut[graph.source(a)] && !cut[graph.target(a)])
92
      sum += cap[a];
93
  }
94
  return sum;
95
}
96

	
97
int main() {
98
  SmartDigraph graph;
99
  SmartDigraph::ArcMap<int> cap1(graph), cap2(graph), cap3(graph);
100
  SmartDigraph::NodeMap<bool> cut(graph);
101

	
102
  istringstream input(lgf);
103
  digraphReader(graph, input)
104
    .arcMap("cap1", cap1)
105
    .arcMap("cap2", cap2)
106
    .arcMap("cap3", cap3)
107
    .run();
108

	
109
  {
110
    HaoOrlin<SmartDigraph> ho(graph, cap1);
111
    ho.run();
112
    ho.minCutMap(cut);
113
    
114
    check(ho.minCutValue() == 1, "Wrong cut value");
115
    check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
116
  }
117
  {
118
    HaoOrlin<SmartDigraph> ho(graph, cap2);
119
    ho.run();
120
    ho.minCutMap(cut);
121

	
122
    check(ho.minCutValue() == 1, "Wrong cut value");
123
    check(ho.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
124
  }
125
  {
126
    HaoOrlin<SmartDigraph> ho(graph, cap3);
127
    ho.run();
128
    ho.minCutMap(cut);
129
    
130
    check(ho.minCutValue() == 1, "Wrong cut value");
131
    check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
132
  }
133
  
134
  typedef Undirector<SmartDigraph> UGraph;
135
  UGraph ugraph(graph);
136
  
137
  {
138
    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
139
    ho.run();
140
    ho.minCutMap(cut);
141
    
142
    check(ho.minCutValue() == 2, "Wrong cut value");
143
    check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
144
  }
145
  {
146
    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap2);
147
    ho.run();
148
    ho.minCutMap(cut);
149
    
150
    check(ho.minCutValue() == 5, "Wrong cut value");
151
    check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
152
  }
153
  {
154
    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap3);
155
    ho.run();
156
    ho.minCutMap(cut);
157
    
158
    check(ho.minCutValue() == 5, "Wrong cut value");
159
    check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
160
  }
161

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

	
19
#include <sstream>
20
#include <lemon/lp_skeleton.h>
21
#include "test_tools.h"
22
#include <lemon/tolerance.h>
23

	
24
#include <lemon/config.h>
25

	
26
#ifdef LEMON_HAVE_GLPK
27
#include <lemon/glpk.h>
28
#endif
29

	
30
#ifdef LEMON_HAVE_CPLEX
31
#include <lemon/cplex.h>
32
#endif
33

	
34
#ifdef LEMON_HAVE_SOPLEX
35
#include <lemon/soplex.h>
36
#endif
37

	
38
#ifdef LEMON_HAVE_CLP
39
#include <lemon/clp.h>
40
#endif
41

	
42
using namespace lemon;
43

	
44
void lpTest(LpSolver& lp)
45
{
46

	
47
  typedef LpSolver LP;
48

	
49
  std::vector<LP::Col> x(10);
50
  //  for(int i=0;i<10;i++) x.push_back(lp.addCol());
51
  lp.addColSet(x);
52
  lp.colLowerBound(x,1);
53
  lp.colUpperBound(x,1);
54
  lp.colBounds(x,1,2);
55

	
56
  std::vector<LP::Col> y(10);
57
  lp.addColSet(y);
58

	
59
  lp.colLowerBound(y,1);
60
  lp.colUpperBound(y,1);
61
  lp.colBounds(y,1,2);
62

	
63
  std::map<int,LP::Col> z;
64

	
65
  z.insert(std::make_pair(12,INVALID));
66
  z.insert(std::make_pair(2,INVALID));
67
  z.insert(std::make_pair(7,INVALID));
68
  z.insert(std::make_pair(5,INVALID));
69

	
70
  lp.addColSet(z);
71

	
72
  lp.colLowerBound(z,1);
73
  lp.colUpperBound(z,1);
74
  lp.colBounds(z,1,2);
75

	
76
  {
77
    LP::Expr e,f,g;
78
    LP::Col p1,p2,p3,p4,p5;
79
    LP::Constr c;
80

	
81
    p1=lp.addCol();
82
    p2=lp.addCol();
83
    p3=lp.addCol();
84
    p4=lp.addCol();
85
    p5=lp.addCol();
86

	
87
    e[p1]=2;
88
    *e=12;
89
    e[p1]+=2;
90
    *e+=12;
91
    e[p1]-=2;
92
    *e-=12;
93

	
94
    e=2;
95
    e=2.2;
96
    e=p1;
97
    e=f;
98

	
99
    e+=2;
100
    e+=2.2;
101
    e+=p1;
102
    e+=f;
103

	
104
    e-=2;
105
    e-=2.2;
106
    e-=p1;
107
    e-=f;
108

	
109
    e*=2;
110
    e*=2.2;
111
    e/=2;
112
    e/=2.2;
113

	
114
    e=((p1+p2)+(p1-p2)+(p1+12)+(12+p1)+(p1-12)+(12-p1)+
115
       (f+12)+(12+f)+(p1+f)+(f+p1)+(f+g)+
116
       (f-12)+(12-f)+(p1-f)+(f-p1)+(f-g)+
117
       2.2*f+f*2.2+f/2.2+
118
       2*f+f*2+f/2+
119
       2.2*p1+p1*2.2+p1/2.2+
120
       2*p1+p1*2+p1/2
121
       );
122

	
123

	
124
    c = (e  <= f  );
125
    c = (e  <= 2.2);
126
    c = (e  <= 2  );
127
    c = (e  <= p1 );
128
    c = (2.2<= f  );
129
    c = (2  <= f  );
130
    c = (p1 <= f  );
131
    c = (p1 <= p2 );
132
    c = (p1 <= 2.2);
133
    c = (p1 <= 2  );
134
    c = (2.2<= p2 );
135
    c = (2  <= p2 );
136

	
137
    c = (e  >= f  );
138
    c = (e  >= 2.2);
139
    c = (e  >= 2  );
140
    c = (e  >= p1 );
141
    c = (2.2>= f  );
142
    c = (2  >= f  );
143
    c = (p1 >= f  );
144
    c = (p1 >= p2 );
145
    c = (p1 >= 2.2);
146
    c = (p1 >= 2  );
147
    c = (2.2>= p2 );
148
    c = (2  >= p2 );
149

	
150
    c = (e  == f  );
151
    c = (e  == 2.2);
152
    c = (e  == 2  );
153
    c = (e  == p1 );
154
    c = (2.2== f  );
155
    c = (2  == f  );
156
    c = (p1 == f  );
157
    //c = (p1 == p2 );
158
    c = (p1 == 2.2);
159
    c = (p1 == 2  );
160
    c = (2.2== p2 );
161
    c = (2  == p2 );
162

	
163
    c = ((2 <= e) <= 3);
164
    c = ((2 <= p1) <= 3);
165

	
166
    c = ((2 >= e) >= 3);
167
    c = ((2 >= p1) >= 3);
168

	
169
    e[x[3]]=2;
170
    e[x[3]]=4;
171
    e[x[3]]=1;
172
    *e=12;
173

	
174
    lp.addRow(-LP::INF,e,23);
175
    lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
176
    lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
177

	
178
    lp.addRow(x[1]+x[3]<=x[5]-3);
179
    lp.addRow((-7<=x[1]+x[3]-12)<=3);
180
    lp.addRow(x[1]<=x[5]);
181

	
182
    std::ostringstream buf;
183

	
184

	
185
    e=((p1+p2)+(p1-0.99*p2));
186
    //e.prettyPrint(std::cout);
187
    //(e<=2).prettyPrint(std::cout);
188
    double tolerance=0.001;
189
    e.simplify(tolerance);
190
    buf << "Coeff. of p2 should be 0.01";
191
    check(e[p2]>0, buf.str());
192

	
193
    tolerance=0.02;
194
    e.simplify(tolerance);
195
    buf << "Coeff. of p2 should be 0";
196
    check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
197

	
198
    //Test for clone/new
199
    LP* lpnew = lp.newSolver();
200
    LP* lpclone = lp.cloneSolver();
201
    delete lpnew;
202
    delete lpclone;
203

	
204
  }
205

	
206
  {
207
    LP::DualExpr e,f,g;
208
    LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID,
209
      p4 = INVALID, p5 = INVALID;
210

	
211
    e[p1]=2;
212
    e[p1]+=2;
213
    e[p1]-=2;
214

	
215
    e=p1;
216
    e=f;
217

	
218
    e+=p1;
219
    e+=f;
220

	
221
    e-=p1;
222
    e-=f;
223

	
224
    e*=2;
225
    e*=2.2;
226
    e/=2;
227
    e/=2.2;
228

	
229
    e=((p1+p2)+(p1-p2)+
230
       (p1+f)+(f+p1)+(f+g)+
231
       (p1-f)+(f-p1)+(f-g)+
232
       2.2*f+f*2.2+f/2.2+
233
       2*f+f*2+f/2+
234
       2.2*p1+p1*2.2+p1/2.2+
235
       2*p1+p1*2+p1/2
236
       );
237
  }
238

	
239
}
240

	
241
void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat,
242
                   double exp_opt) {
243
  using std::string;
244
  lp.solve();
245

	
246
  std::ostringstream buf;
247
  buf << "PrimalType should be: " << int(stat) << int(lp.primalType());
248

	
249
  check(lp.primalType()==stat, buf.str());
250

	
251
  if (stat ==  LpSolver::OPTIMAL) {
252
    std::ostringstream sbuf;
253
    sbuf << "Wrong optimal value (" << lp.primal() <<") with "
254
         << lp.solverName() <<"\n     the right optimum is " << exp_opt;
255
    check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
256
  }
257
}
258

	
259
void aTest(LpSolver & lp)
260
{
261
  typedef LpSolver LP;
262

	
263
 //The following example is very simple
264

	
265
  typedef LpSolver::Row Row;
266
  typedef LpSolver::Col Col;
267

	
268

	
269
  Col x1 = lp.addCol();
270
  Col x2 = lp.addCol();
271

	
272

	
273
  //Constraints
274
  Row upright=lp.addRow(x1+2*x2 <=1);
275
  lp.addRow(x1+x2 >=-1);
276
  lp.addRow(x1-x2 <=1);
277
  lp.addRow(x1-x2 >=-1);
278
  //Nonnegativity of the variables
279
  lp.colLowerBound(x1, 0);
280
  lp.colLowerBound(x2, 0);
281
  //Objective function
282
  lp.obj(x1+x2);
283

	
284
  lp.sense(lp.MAX);
285

	
286
  //Testing the problem retrieving routines
287
  check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
288
  check(lp.sense() == lp.MAX,"This is a maximization!");
289
  check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
290
  check(lp.colLowerBound(x1)==0,
291
        "The lower bound for variable x1 should be 0.");
292
  check(lp.colUpperBound(x1)==LpSolver::INF,
293
        "The upper bound for variable x1 should be infty.");
294
  check(lp.rowLowerBound(upright) == -LpSolver::INF,
295
        "The lower bound for the first row should be -infty.");
296
  check(lp.rowUpperBound(upright)==1,
297
        "The upper bound for the first row should be 1.");
298
  LpSolver::Expr e = lp.row(upright);
299
  check(e[x1] == 1, "The first coefficient should 1.");
300
  check(e[x2] == 2, "The second coefficient should 1.");
301

	
302
  lp.row(upright, x1+x2 <=1);
303
  e = lp.row(upright);
304
  check(e[x1] == 1, "The first coefficient should 1.");
305
  check(e[x2] == 1, "The second coefficient should 1.");
306

	
307
  LpSolver::DualExpr de = lp.col(x1);
308
  check(  de[upright] == 1, "The first coefficient should 1.");
309

	
310
  LpSolver* clp = lp.cloneSolver();
311

	
312
  //Testing the problem retrieving routines
313
  check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
314
  check(clp->sense() == clp->MAX,"This is a maximization!");
315
  check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
316
  //  std::cout<<lp.colLowerBound(x1)<<std::endl;
317
  check(clp->colLowerBound(x1)==0,
318
        "The lower bound for variable x1 should be 0.");
319
  check(clp->colUpperBound(x1)==LpSolver::INF,
320
        "The upper bound for variable x1 should be infty.");
321

	
322
  check(lp.rowLowerBound(upright)==-LpSolver::INF,
323
        "The lower bound for the first row should be -infty.");
324
  check(lp.rowUpperBound(upright)==1,
325
        "The upper bound for the first row should be 1.");
326
  e = clp->row(upright);
327
  check(e[x1] == 1, "The first coefficient should 1.");
328
  check(e[x2] == 1, "The second coefficient should 1.");
329

	
330
  de = clp->col(x1);
331
  check(de[upright] == 1, "The first coefficient should 1.");
332

	
333
  delete clp;
334

	
335
  //Maximization of x1+x2
336
  //over the triangle with vertices (0,0) (0,1) (1,0)
337
  double expected_opt=1;
338
  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
339

	
340
  //Minimization
341
  lp.sense(lp.MIN);
342
  expected_opt=0;
343
  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
344

	
345
  //Vertex (-1,0) instead of (0,0)
346
  lp.colLowerBound(x1, -LpSolver::INF);
347
  expected_opt=-1;
348
  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
349

	
350
  //Erase one constraint and return to maximization
351
  lp.erase(upright);
352
  lp.sense(lp.MAX);
353
  expected_opt=LpSolver::INF;
354
  solveAndCheck(lp, LpSolver::UNBOUNDED, expected_opt);
355

	
356
  //Infeasibilty
357
  lp.addRow(x1+x2 <=-2);
358
  solveAndCheck(lp, LpSolver::INFEASIBLE, expected_opt);
359

	
360
}
361

	
362
template<class LP>
363
void cloneTest()
364
{
365
  //Test for clone/new
366

	
367
  LP* lp = new LP();
368
  LP* lpnew = lp->newSolver();
369
  LP* lpclone = lp->cloneSolver();
370
  delete lp;
371
  delete lpnew;
372
  delete lpclone;
373
}
374

	
375
int main()
376
{
377
  LpSkeleton lp_skel;
378
  lpTest(lp_skel);
379

	
380
#ifdef LEMON_HAVE_GLPK
381
  {
382
    GlpkLp lp_glpk1,lp_glpk2;
383
    lpTest(lp_glpk1);
384
    aTest(lp_glpk2);
385
    cloneTest<GlpkLp>();
386
  }
387
#endif
388

	
389
#ifdef LEMON_HAVE_CPLEX
390
  try {
391
    CplexLp lp_cplex1,lp_cplex2;
392
    lpTest(lp_cplex1);
393
    aTest(lp_cplex2);
394
    cloneTest<CplexLp>();
395
  } catch (CplexEnv::LicenseError& error) {
396
    check(false, error.what());
397
  }
398
#endif
399

	
400
#ifdef LEMON_HAVE_SOPLEX
401
  {
402
    SoplexLp lp_soplex1,lp_soplex2;
403
    lpTest(lp_soplex1);
404
    aTest(lp_soplex2);
405
    cloneTest<SoplexLp>();
406
  }
407
#endif
408

	
409
#ifdef LEMON_HAVE_CLP
410
  {
411
    ClpLp lp_clp1,lp_clp2;
412
    lpTest(lp_clp1);
413
    aTest(lp_clp2);
414
    cloneTest<ClpLp>();
415
  }
416
#endif
417

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

	
19
#include <iostream>
20
#include <sstream>
21
#include <vector>
22
#include <queue>
23
#include <cstdlib>
24

	
25
#include <lemon/matching.h>
26
#include <lemon/smart_graph.h>
27
#include <lemon/concepts/graph.h>
28
#include <lemon/concepts/maps.h>
29
#include <lemon/lgf_reader.h>
30
#include <lemon/math.h>
31

	
32
#include "test_tools.h"
33

	
34
using namespace std;
35
using namespace lemon;
36

	
37
GRAPH_TYPEDEFS(SmartGraph);
38

	
39

	
40
const int lgfn = 3;
41
const std::string lgf[lgfn] = {
42
  "@nodes\n"
43
  "label\n"
44
  "0\n"
45
  "1\n"
46
  "2\n"
47
  "3\n"
48
  "4\n"
49
  "5\n"
50
  "6\n"
51
  "7\n"
52
  "@edges\n"
53
  "     label  weight\n"
54
  "7 4  0      984\n"
55
  "0 7  1      73\n"
56
  "7 1  2      204\n"
57
  "2 3  3      583\n"
58
  "2 7  4      565\n"
59
  "2 1  5      582\n"
60
  "0 4  6      551\n"
61
  "2 5  7      385\n"
62
  "1 5  8      561\n"
63
  "5 3  9      484\n"
64
  "7 5  10     904\n"
65
  "3 6  11     47\n"
66
  "7 6  12     888\n"
67
  "3 0  13     747\n"
68
  "6 1  14     310\n",
69

	
70
  "@nodes\n"
71
  "label\n"
72
  "0\n"
73
  "1\n"
74
  "2\n"
75
  "3\n"
76
  "4\n"
77
  "5\n"
78
  "6\n"
79
  "7\n"
80
  "@edges\n"
81
  "     label  weight\n"
82
  "2 5  0      710\n"
83
  "0 5  1      241\n"
84
  "2 4  2      856\n"
85
  "2 6  3      762\n"
86
  "4 1  4      747\n"
87
  "6 1  5      962\n"
88
  "4 7  6      723\n"
89
  "1 7  7      661\n"
90
  "2 3  8      376\n"
91
  "1 0  9      416\n"
92
  "6 7  10     391\n",
93

	
94
  "@nodes\n"
95
  "label\n"
96
  "0\n"
97
  "1\n"
98
  "2\n"
99
  "3\n"
100
  "4\n"
101
  "5\n"
102
  "6\n"
103
  "7\n"
104
  "@edges\n"
105
  "     label  weight\n"
106
  "6 2  0      553\n"
107
  "0 7  1      653\n"
108
  "6 3  2      22\n"
109
  "4 7  3      846\n"
110
  "7 2  4      981\n"
111
  "7 6  5      250\n"
112
  "5 2  6      539\n",
113
};
114

	
115
void checkMaxMatchingCompile()
116
{
117
  typedef concepts::Graph Graph;
118
  typedef Graph::Node Node;
119
  typedef Graph::Edge Edge;
120
  typedef Graph::EdgeMap<bool> MatMap;
121

	
122
  Graph g;
123
  Node n;
124
  Edge e;
125
  MatMap mat(g);
126

	
127
  MaxMatching<Graph> mat_test(g);
128
  const MaxMatching<Graph>&
129
    const_mat_test = mat_test;
130

	
131
  mat_test.init();
132
  mat_test.greedyInit();
133
  mat_test.matchingInit(mat);
134
  mat_test.startSparse();
135
  mat_test.startDense();
136
  mat_test.run();
137
  
138
  const_mat_test.matchingSize();
139
  const_mat_test.matching(e);
140
  const_mat_test.matching(n);
141
  const MaxMatching<Graph>::MatchingMap& mmap =
142
    const_mat_test.matchingMap();
143
  e = mmap[n];
144
  const_mat_test.mate(n);
145

	
146
  MaxMatching<Graph>::Status stat = 
147
    const_mat_test.status(n);
148
  const MaxMatching<Graph>::StatusMap& smap =
149
    const_mat_test.statusMap();
150
  stat = smap[n];
151
  const_mat_test.barrier(n);
152
}
153

	
154
void checkMaxWeightedMatchingCompile()
155
{
156
  typedef concepts::Graph Graph;
157
  typedef Graph::Node Node;
158
  typedef Graph::Edge Edge;
159
  typedef Graph::EdgeMap<int> WeightMap;
160

	
161
  Graph g;
162
  Node n;
163
  Edge e;
164
  WeightMap w(g);
165

	
166
  MaxWeightedMatching<Graph> mat_test(g, w);
167
  const MaxWeightedMatching<Graph>&
168
    const_mat_test = mat_test;
169

	
170
  mat_test.init();
171
  mat_test.start();
172
  mat_test.run();
173
  
174
  const_mat_test.matchingWeight();
175
  const_mat_test.matchingSize();
176
  const_mat_test.matching(e);
177
  const_mat_test.matching(n);
178
  const MaxWeightedMatching<Graph>::MatchingMap& mmap =
179
    const_mat_test.matchingMap();
180
  e = mmap[n];
181
  const_mat_test.mate(n);
182
  
183
  int k = 0;
184
  const_mat_test.dualValue();
185
  const_mat_test.nodeValue(n);
186
  const_mat_test.blossomNum();
187
  const_mat_test.blossomSize(k);
188
  const_mat_test.blossomValue(k);
189
}
190

	
191
void checkMaxWeightedPerfectMatchingCompile()
192
{
193
  typedef concepts::Graph Graph;
194
  typedef Graph::Node Node;
195
  typedef Graph::Edge Edge;
196
  typedef Graph::EdgeMap<int> WeightMap;
197

	
198
  Graph g;
199
  Node n;
200
  Edge e;
201
  WeightMap w(g);
202

	
203
  MaxWeightedPerfectMatching<Graph> mat_test(g, w);
204
  const MaxWeightedPerfectMatching<Graph>&
205
    const_mat_test = mat_test;
206

	
207
  mat_test.init();
208
  mat_test.start();
209
  mat_test.run();
210
  
211
  const_mat_test.matchingWeight();
212
  const_mat_test.matching(e);
213
  const_mat_test.matching(n);
214
  const MaxWeightedPerfectMatching<Graph>::MatchingMap& mmap =
215
    const_mat_test.matchingMap();
216
  e = mmap[n];
217
  const_mat_test.mate(n);
218
  
219
  int k = 0;
220
  const_mat_test.dualValue();
221
  const_mat_test.nodeValue(n);
222
  const_mat_test.blossomNum();
223
  const_mat_test.blossomSize(k);
224
  const_mat_test.blossomValue(k);
225
}
226

	
227
void checkMatching(const SmartGraph& graph,
228
                   const MaxMatching<SmartGraph>& mm) {
229
  int num = 0;
230

	
231
  IntNodeMap comp_index(graph);
232
  UnionFind<IntNodeMap> comp(comp_index);
233

	
234
  int barrier_num = 0;
235

	
236
  for (NodeIt n(graph); n != INVALID; ++n) {
237
    check(mm.status(n) == MaxMatching<SmartGraph>::EVEN ||
238
          mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
239
    if (mm.status(n) == MaxMatching<SmartGraph>::ODD) {
240
      ++barrier_num;
241
    } else {
242
      comp.insert(n);
243
    }
244
  }
245

	
246
  for (EdgeIt e(graph); e != INVALID; ++e) {
247
    if (mm.matching(e)) {
248
      check(e == mm.matching(graph.u(e)), "Wrong matching");
249
      check(e == mm.matching(graph.v(e)), "Wrong matching");
250
      ++num;
251
    }
252
    check(mm.status(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
253
          mm.status(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
254
          "Wrong Gallai-Edmonds decomposition");
255

	
256
    check(mm.status(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
257
          mm.status(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
258
          "Wrong Gallai-Edmonds decomposition");
259

	
260
    if (mm.status(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
261
        mm.status(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
262
      comp.join(graph.u(e), graph.v(e));
263
    }
264
  }
265

	
266
  std::set<int> comp_root;
267
  int odd_comp_num = 0;
268
  for (NodeIt n(graph); n != INVALID; ++n) {
269
    if (mm.status(n) != MaxMatching<SmartGraph>::ODD) {
270
      int root = comp.find(n);
271
      if (comp_root.find(root) == comp_root.end()) {
272
        comp_root.insert(root);
273
        if (comp.size(n) % 2 == 1) {
274
          ++odd_comp_num;
275
        }
276
      }
277
    }
278
  }
279

	
280
  check(mm.matchingSize() == num, "Wrong matching");
281
  check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
282
         "Wrong matching");
283
  return;
284
}
285

	
286
void checkWeightedMatching(const SmartGraph& graph,
287
                   const SmartGraph::EdgeMap<int>& weight,
288
                   const MaxWeightedMatching<SmartGraph>& mwm) {
289
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
290
    if (graph.u(e) == graph.v(e)) continue;
291
    int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
292

	
293
    for (int i = 0; i < mwm.blossomNum(); ++i) {
294
      bool s = false, t = false;
295
      for (MaxWeightedMatching<SmartGraph>::BlossomIt n(mwm, i);
296
           n != INVALID; ++n) {
297
        if (graph.u(e) == n) s = true;
298
        if (graph.v(e) == n) t = true;
299
      }
300
      if (s == true && t == true) {
301
        rw += mwm.blossomValue(i);
302
      }
303
    }
304
    rw -= weight[e] * mwm.dualScale;
305

	
306
    check(rw >= 0, "Negative reduced weight");
307
    check(rw == 0 || !mwm.matching(e),
308
          "Non-zero reduced weight on matching edge");
309
  }
310

	
311
  int pv = 0;
312
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
313
    if (mwm.matching(n) != INVALID) {
314
      check(mwm.nodeValue(n) >= 0, "Invalid node value");
315
      pv += weight[mwm.matching(n)];
316
      SmartGraph::Node o = graph.target(mwm.matching(n));
317
      check(mwm.mate(n) == o, "Invalid matching");
318
      check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)),
319
            "Invalid matching");
320
    } else {
321
      check(mwm.mate(n) == INVALID, "Invalid matching");
322
      check(mwm.nodeValue(n) == 0, "Invalid matching");
323
    }
324
  }
325

	
326
  int dv = 0;
327
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
328
    dv += mwm.nodeValue(n);
329
  }
330

	
331
  for (int i = 0; i < mwm.blossomNum(); ++i) {
332
    check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
333
    check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
334
    dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
335
  }
336

	
337
  check(pv * mwm.dualScale == dv * 2, "Wrong duality");
338

	
339
  return;
340
}
341

	
342
void checkWeightedPerfectMatching(const SmartGraph& graph,
343
                          const SmartGraph::EdgeMap<int>& weight,
344
                          const MaxWeightedPerfectMatching<SmartGraph>& mwpm) {
345
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
346
    if (graph.u(e) == graph.v(e)) continue;
347
    int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e));
348

	
349
    for (int i = 0; i < mwpm.blossomNum(); ++i) {
350
      bool s = false, t = false;
351
      for (MaxWeightedPerfectMatching<SmartGraph>::BlossomIt n(mwpm, i);
352
           n != INVALID; ++n) {
353
        if (graph.u(e) == n) s = true;
354
        if (graph.v(e) == n) t = true;
355
      }
356
      if (s == true && t == true) {
357
        rw += mwpm.blossomValue(i);
358
      }
359
    }
360
    rw -= weight[e] * mwpm.dualScale;
361

	
362
    check(rw >= 0, "Negative reduced weight");
363
    check(rw == 0 || !mwpm.matching(e),
364
          "Non-zero reduced weight on matching edge");
365
  }
366

	
367
  int pv = 0;
368
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
369
    check(mwpm.matching(n) != INVALID, "Non perfect");
370
    pv += weight[mwpm.matching(n)];
371
    SmartGraph::Node o = graph.target(mwpm.matching(n));
372
    check(mwpm.mate(n) == o, "Invalid matching");
373
    check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)),
374
          "Invalid matching");
375
  }
376

	
377
  int dv = 0;
378
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
379
    dv += mwpm.nodeValue(n);
380
  }
381

	
382
  for (int i = 0; i < mwpm.blossomNum(); ++i) {
383
    check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
384
    check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
385
    dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
386
  }
387

	
388
  check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
389

	
390
  return;
391
}
392

	
393

	
394
int main() {
395

	
396
  for (int i = 0; i < lgfn; ++i) {
397
    SmartGraph graph;
398
    SmartGraph::EdgeMap<int> weight(graph);
399

	
400
    istringstream lgfs(lgf[i]);
401
    graphReader(graph, lgfs).
402
      edgeMap("weight", weight).run();
403

	
404
    MaxMatching<SmartGraph> mm(graph);
405
    mm.run();
406
    checkMatching(graph, mm);
407

	
408
    MaxWeightedMatching<SmartGraph> mwm(graph, weight);
409
    mwm.run();
410
    checkWeightedMatching(graph, weight, mwm);
411

	
412
    MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
413
    bool perfect = mwpm.run();
414

	
415
    check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
416
          "Perfect matching found");
417

	
418
    if (perfect) {
419
      checkWeightedPerfectMatching(graph, weight, mwpm);
420
    }
421
  }
422

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

	
19
#include <iostream>
20
#include <set>
21
#include <vector>
22
#include <iterator>
23

	
24
#include <lemon/smart_graph.h>
25
#include <lemon/min_cost_arborescence.h>
26
#include <lemon/lgf_reader.h>
27
#include <lemon/concepts/digraph.h>
28

	
29
#include "test_tools.h"
30

	
31
using namespace lemon;
32
using namespace std;
33

	
34
const char test_lgf[] =
35
  "@nodes\n"
36
  "label\n"
37
  "0\n"
38
  "1\n"
39
  "2\n"
40
  "3\n"
41
  "4\n"
42
  "5\n"
43
  "6\n"
44
  "7\n"
45
  "8\n"
46
  "9\n"
47
  "@arcs\n"
48
  "     label  cost\n"
49
  "1 8  0      107\n"
50
  "0 3  1      70\n"
51
  "2 1  2      46\n"
52
  "4 1  3      28\n"
53
  "4 4  4      91\n"
54
  "3 9  5      76\n"
55
  "9 8  6      61\n"
56
  "8 1  7      39\n"
57
  "9 8  8      74\n"
58
  "8 0  9      39\n"
59
  "4 3  10     45\n"
60
  "2 2  11     34\n"
61
  "0 1  12     100\n"
62
  "6 3  13     95\n"
63
  "4 1  14     22\n"
64
  "1 1  15     31\n"
65
  "7 2  16     51\n"
66
  "2 6  17     29\n"
67
  "8 3  18     115\n"
68
  "6 9  19     32\n"
69
  "1 1  20     60\n"
70
  "0 3  21     40\n"
71
  "@attributes\n"
72
  "source 0\n";
73

	
74

	
75
void checkMinCostArborescenceCompile()
76
{
77
  typedef double VType;
78
  typedef concepts::Digraph Digraph;
79
  typedef concepts::ReadMap<Digraph::Arc, VType> CostMap;
80
  typedef Digraph::Node Node;
81
  typedef Digraph::Arc Arc;
82
  typedef concepts::WriteMap<Digraph::Arc, bool> ArbMap;
83
  typedef concepts::ReadWriteMap<Digraph::Node, Digraph::Arc> PredMap;
84

	
85
  typedef MinCostArborescence<Digraph, CostMap>::
86
            SetArborescenceMap<ArbMap>::
87
            SetPredMap<PredMap>::Create MinCostArbType;
88

	
89
  Digraph g;
90
  Node s, n;
91
  Arc e;
92
  VType c;
93
  bool b;
94
  int i;
95
  CostMap cost;
96
  ArbMap arb;
97
  PredMap pred;
98

	
99
  MinCostArbType mcarb_test(g, cost);
100
  const MinCostArbType& const_mcarb_test = mcarb_test;
101

	
102
  mcarb_test
103
    .arborescenceMap(arb)
104
    .predMap(pred)
105
    .run(s);
106

	
107
  mcarb_test.init();
108
  mcarb_test.addSource(s);
109
  mcarb_test.start();
110
  n = mcarb_test.processNextNode();
111
  b = const_mcarb_test.emptyQueue();
112
  i = const_mcarb_test.queueSize();
113
  
114
  c = const_mcarb_test.arborescenceCost();
115
  b = const_mcarb_test.arborescence(e);
116
  e = const_mcarb_test.pred(n);
117
  const MinCostArbType::ArborescenceMap &am =
118
    const_mcarb_test.arborescenceMap();
119
  const MinCostArbType::PredMap &pm =
120
    const_mcarb_test.predMap();
121
  b = const_mcarb_test.reached(n);
122
  b = const_mcarb_test.processed(n);
123
  
124
  i = const_mcarb_test.dualNum();
125
  c = const_mcarb_test.dualValue();
126
  i = const_mcarb_test.dualSize(i);
127
  c = const_mcarb_test.dualValue(i);
128
  
129
  ignore_unused_variable_warning(am);
130
  ignore_unused_variable_warning(pm);
131
}
132

	
133
int main() {
134
  typedef SmartDigraph Digraph;
135
  DIGRAPH_TYPEDEFS(Digraph);
136

	
137
  typedef Digraph::ArcMap<double> CostMap;
138

	
139
  Digraph digraph;
140
  CostMap cost(digraph);
141
  Node source;
142

	
143
  std::istringstream is(test_lgf);
144
  digraphReader(digraph, is).
145
    arcMap("cost", cost).
146
    node("source", source).run();
147

	
148
  MinCostArborescence<Digraph, CostMap> mca(digraph, cost);
149
  mca.run(source);
150

	
151
  vector<pair<double, set<Node> > > dualSolution(mca.dualNum());
152

	
153
  for (int i = 0; i < mca.dualNum(); ++i) {
154
    dualSolution[i].first = mca.dualValue(i);
155
    for (MinCostArborescence<Digraph, CostMap>::DualIt it(mca, i);
156
         it != INVALID; ++it) {
157
      dualSolution[i].second.insert(it);
158
    }
159
  }
160

	
161
  for (ArcIt it(digraph); it != INVALID; ++it) {
162
    if (mca.reached(digraph.source(it))) {
163
      double sum = 0.0;
164
      for (int i = 0; i < int(dualSolution.size()); ++i) {
165
        if (dualSolution[i].second.find(digraph.target(it))
166
            != dualSolution[i].second.end() &&
167
            dualSolution[i].second.find(digraph.source(it))
168
            == dualSolution[i].second.end()) {
169
          sum += dualSolution[i].first;
170
        }
171
      }
172
      if (mca.arborescence(it)) {
173
        check(sum == cost[it], "Invalid dual solution");
174
      }
175
      check(sum <= cost[it], "Invalid dual solution");
176
    }
177
  }
178

	
179

	
180
  check(mca.dualValue() == mca.arborescenceCost(), "Invalid dual solution");
181

	
182
  check(mca.reached(source), "Invalid arborescence");
183
  for (ArcIt a(digraph); a != INVALID; ++a) {
184
    check(!mca.reached(digraph.source(a)) ||
185
          mca.reached(digraph.target(a)), "Invalid arborescence");
186
  }
187

	
188
  for (NodeIt n(digraph); n != INVALID; ++n) {
189
    if (!mca.reached(n)) continue;
190
    int cnt = 0;
191
    for (InArcIt a(digraph, n); a != INVALID; ++a) {
192
      if (mca.arborescence(a)) {
193
        check(mca.pred(n) == a, "Invalid arborescence");
194
        ++cnt;
195
      }
196
    }
197
    check((n == source ? cnt == 0 : cnt == 1), "Invalid arborescence");
198
  }
199

	
200
  Digraph::ArcMap<bool> arborescence(digraph);
201
  check(mca.arborescenceCost() ==
202
        minCostArborescence(digraph, cost, source, arborescence),
203
        "Wrong result of the function interface");
204

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

	
19
#include <iostream>
20
#include <fstream>
21
#include <limits>
22

	
23
#include <lemon/list_graph.h>
24
#include <lemon/lgf_reader.h>
25

	
26
#include <lemon/network_simplex.h>
27

	
28
#include <lemon/concepts/digraph.h>
29
#include <lemon/concept_check.h>
30

	
31
#include "test_tools.h"
32

	
33
using namespace lemon;
34

	
35
char test_lgf[] =
36
  "@nodes\n"
37
  "label  sup1 sup2 sup3 sup4 sup5 sup6\n"
38
  "    1    20   27    0   30   20   30\n"
39
  "    2    -4    0    0    0   -8   -3\n"
40
  "    3     0    0    0    0    0    0\n"
41
  "    4     0    0    0    0    0    0\n"
42
  "    5     9    0    0    0    6   11\n"
43
  "    6    -6    0    0    0   -5   -6\n"
44
  "    7     0    0    0    0    0    0\n"
45
  "    8     0    0    0    0    0    3\n"
46
  "    9     3    0    0    0    0    0\n"
47
  "   10    -2    0    0    0   -7   -2\n"
48
  "   11     0    0    0    0  -10    0\n"
49
  "   12   -20  -27    0  -30  -30  -20\n"
50
  "\n"                
51
  "@arcs\n"
52
  "       cost  cap low1 low2 low3\n"
53
  " 1  2    70   11    0    8    8\n"
54
  " 1  3   150    3    0    1    0\n"
55
  " 1  4    80   15    0    2    2\n"
56
  " 2  8    80   12    0    0    0\n"
57
  " 3  5   140    5    0    3    1\n"
58
  " 4  6    60   10    0    1    0\n"
59
  " 4  7    80    2    0    0    0\n"
60
  " 4  8   110    3    0    0    0\n"
61
  " 5  7    60   14    0    0    0\n"
62
  " 5 11   120   12    0    0    0\n"
63
  " 6  3     0    3    0    0    0\n"
64
  " 6  9   140    4    0    0    0\n"
65
  " 6 10    90    8    0    0    0\n"
66
  " 7  1    30    5    0    0   -5\n"
67
  " 8 12    60   16    0    4    3\n"
68
  " 9 12    50    6    0    0    0\n"
69
  "10 12    70   13    0    5    2\n"
70
  "10  2   100    7    0    0    0\n"
71
  "10  7    60   10    0    0   -3\n"
72
  "11 10    20   14    0    6  -20\n"
73
  "12 11    30   10    0    0  -10\n"
74
  "\n"
75
  "@attributes\n"
76
  "source 1\n"
77
  "target 12\n";
78

	
79

	
80
enum SupplyType {
81
  EQ,
82
  GEQ,
83
  LEQ
84
};
85

	
86
// Check the interface of an MCF algorithm
87
template <typename GR, typename Value, typename Cost>
88
class McfClassConcept
89
{
90
public:
91

	
92
  template <typename MCF>
93
  struct Constraints {
94
    void constraints() {
95
      checkConcept<concepts::Digraph, GR>();
96
      
97
      const Constraints& me = *this;
98

	
99
      MCF mcf(me.g);
100
      const MCF& const_mcf = mcf;
101

	
102
      b = mcf.reset()
103
             .lowerMap(me.lower)
104
             .upperMap(me.upper)
105
             .costMap(me.cost)
106
             .supplyMap(me.sup)
107
             .stSupply(me.n, me.n, me.k)
108
             .run();
109

	
110
      c = const_mcf.totalCost();
111
      x = const_mcf.template totalCost<double>();
112
      v = const_mcf.flow(me.a);
113
      c = const_mcf.potential(me.n);
114
      const_mcf.flowMap(fm);
115
      const_mcf.potentialMap(pm);
116
    }
117

	
118
    typedef typename GR::Node Node;
119
    typedef typename GR::Arc Arc;
120
    typedef concepts::ReadMap<Node, Value> NM;
121
    typedef concepts::ReadMap<Arc, Value> VAM;
122
    typedef concepts::ReadMap<Arc, Cost> CAM;
123
    typedef concepts::WriteMap<Arc, Value> FlowMap;
124
    typedef concepts::WriteMap<Node, Cost> PotMap;
125
  
126
    GR g;
127
    VAM lower;
128
    VAM upper;
129
    CAM cost;
130
    NM sup;
131
    Node n;
132
    Arc a;
133
    Value k;
134

	
135
    FlowMap fm;
136
    PotMap pm;
137
    bool b;
138
    double x;
139
    typename MCF::Value v;
140
    typename MCF::Cost c;
141
  };
142

	
143
};
144

	
145

	
146
// Check the feasibility of the given flow (primal soluiton)
147
template < typename GR, typename LM, typename UM,
148
           typename SM, typename FM >
149
bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
150
                const SM& supply, const FM& flow,
151
                SupplyType type = EQ )
152
{
153
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
154

	
155
  for (ArcIt e(gr); e != INVALID; ++e) {
156
    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
157
  }
158

	
159
  for (NodeIt n(gr); n != INVALID; ++n) {
160
    typename SM::Value sum = 0;
161
    for (OutArcIt e(gr, n); e != INVALID; ++e)
162
      sum += flow[e];
163
    for (InArcIt e(gr, n); e != INVALID; ++e)
164
      sum -= flow[e];
165
    bool b = (type ==  EQ && sum == supply[n]) ||
166
             (type == GEQ && sum >= supply[n]) ||
167
             (type == LEQ && sum <= supply[n]);
168
    if (!b) return false;
169
  }
170

	
171
  return true;
172
}
173

	
174
// Check the feasibility of the given potentials (dual soluiton)
175
// using the "Complementary Slackness" optimality condition
176
template < typename GR, typename LM, typename UM,
177
           typename CM, typename SM, typename FM, typename PM >
178
bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
179
                     const CM& cost, const SM& supply, const FM& flow, 
180
                     const PM& pi, SupplyType type )
181
{
182
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
183

	
184
  bool opt = true;
185
  for (ArcIt e(gr); opt && e != INVALID; ++e) {
186
    typename CM::Value red_cost =
187
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
188
    opt = red_cost == 0 ||
189
          (red_cost > 0 && flow[e] == lower[e]) ||
190
          (red_cost < 0 && flow[e] == upper[e]);
191
  }
192
  
193
  for (NodeIt n(gr); opt && n != INVALID; ++n) {
194
    typename SM::Value sum = 0;
195
    for (OutArcIt e(gr, n); e != INVALID; ++e)
196
      sum += flow[e];
197
    for (InArcIt e(gr, n); e != INVALID; ++e)
198
      sum -= flow[e];
199
    if (type != LEQ) {
200
      opt = (pi[n] <= 0) && (sum == supply[n] || pi[n] == 0);
201
    } else {
202
      opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0);
203
    }
204
  }
205
  
206
  return opt;
207
}
208

	
209
// Check whether the dual cost is equal to the primal cost
210
template < typename GR, typename LM, typename UM,
211
           typename CM, typename SM, typename PM >
212
bool checkDualCost( const GR& gr, const LM& lower, const UM& upper,
213
                    const CM& cost, const SM& supply, const PM& pi,
214
                    typename CM::Value total )
215
{
216
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
217

	
218
  typename CM::Value dual_cost = 0;
219
  SM red_supply(gr);
220
  for (NodeIt n(gr); n != INVALID; ++n) {
221
    red_supply[n] = supply[n];
222
  }
223
  for (ArcIt a(gr); a != INVALID; ++a) {
224
    if (lower[a] != 0) {
225
      dual_cost += lower[a] * cost[a];
226
      red_supply[gr.source(a)] -= lower[a];
227
      red_supply[gr.target(a)] += lower[a];
228
    }
229
  }
230
  
231
  for (NodeIt n(gr); n != INVALID; ++n) {
232
    dual_cost -= red_supply[n] * pi[n];
233
  }
234
  for (ArcIt a(gr); a != INVALID; ++a) {
235
    typename CM::Value red_cost =
236
      cost[a] + pi[gr.source(a)] - pi[gr.target(a)];
237
    dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
238
  }
239
  
240
  return dual_cost == total;
241
}
242

	
243
// Run a minimum cost flow algorithm and check the results
244
template < typename MCF, typename GR,
245
           typename LM, typename UM,
246
           typename CM, typename SM,
247
           typename PT >
248
void checkMcf( const MCF& mcf, PT mcf_result,
249
               const GR& gr, const LM& lower, const UM& upper,
250
               const CM& cost, const SM& supply,
251
               PT result, bool optimal, typename CM::Value total,
252
               const std::string &test_id = "",
253
               SupplyType type = EQ )
254
{
255
  check(mcf_result == result, "Wrong result " + test_id);
256
  if (optimal) {
257
    typename GR::template ArcMap<typename SM::Value> flow(gr);
258
    typename GR::template NodeMap<typename CM::Value> pi(gr);
259
    mcf.flowMap(flow);
260
    mcf.potentialMap(pi);
261
    check(checkFlow(gr, lower, upper, supply, flow, type),
262
          "The flow is not feasible " + test_id);
263
    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
264
    check(checkPotential(gr, lower, upper, cost, supply, flow, pi, type),
265
          "Wrong potentials " + test_id);
266
    check(checkDualCost(gr, lower, upper, cost, supply, pi, total),
267
          "Wrong dual cost " + test_id);
268
  }
269
}
270

	
271
int main()
272
{
273
  // Check the interfaces
274
  {
275
    typedef concepts::Digraph GR;
276
    checkConcept< McfClassConcept<GR, int, int>,
277
                  NetworkSimplex<GR> >();
278
    checkConcept< McfClassConcept<GR, double, double>,
279
                  NetworkSimplex<GR, double> >();
280
    checkConcept< McfClassConcept<GR, int, double>,
281
                  NetworkSimplex<GR, int, double> >();
282
  }
283

	
284
  // Run various MCF tests
285
  typedef ListDigraph Digraph;
286
  DIGRAPH_TYPEDEFS(ListDigraph);
287

	
288
  // Read the test digraph
289
  Digraph gr;
290
  Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
291
  Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
292
  ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
293
  Node v, w;
294

	
295
  std::istringstream input(test_lgf);
296
  DigraphReader<Digraph>(gr, input)
297
    .arcMap("cost", c)
298
    .arcMap("cap", u)
299
    .arcMap("low1", l1)
300
    .arcMap("low2", l2)
301
    .arcMap("low3", l3)
302
    .nodeMap("sup1", s1)
303
    .nodeMap("sup2", s2)
304
    .nodeMap("sup3", s3)
305
    .nodeMap("sup4", s4)
306
    .nodeMap("sup5", s5)
307
    .nodeMap("sup6", s6)
308
    .node("source", v)
309
    .node("target", w)
310
    .run();
311
  
312
  // Build test digraphs with negative costs
313
  Digraph neg_gr;
314
  Node n1 = neg_gr.addNode();
315
  Node n2 = neg_gr.addNode();
316
  Node n3 = neg_gr.addNode();
317
  Node n4 = neg_gr.addNode();
318
  Node n5 = neg_gr.addNode();
319
  Node n6 = neg_gr.addNode();
320
  Node n7 = neg_gr.addNode();
321
  
322
  Arc a1 = neg_gr.addArc(n1, n2);
323
  Arc a2 = neg_gr.addArc(n1, n3);
324
  Arc a3 = neg_gr.addArc(n2, n4);
325
  Arc a4 = neg_gr.addArc(n3, n4);
326
  Arc a5 = neg_gr.addArc(n3, n2);
327
  Arc a6 = neg_gr.addArc(n5, n3);
328
  Arc a7 = neg_gr.addArc(n5, n6);
329
  Arc a8 = neg_gr.addArc(n6, n7);
330
  Arc a9 = neg_gr.addArc(n7, n5);
331
  
332
  Digraph::ArcMap<int> neg_c(neg_gr), neg_l1(neg_gr, 0), neg_l2(neg_gr, 0);
333
  ConstMap<Arc, int> neg_u1(std::numeric_limits<int>::max()), neg_u2(5000);
334
  Digraph::NodeMap<int> neg_s(neg_gr, 0);
335
  
336
  neg_l2[a7] =  1000;
337
  neg_l2[a8] = -1000;
338
  
339
  neg_s[n1] =  100;
340
  neg_s[n4] = -100;
341
  
342
  neg_c[a1] =  100;
343
  neg_c[a2] =   30;
344
  neg_c[a3] =   20;
345
  neg_c[a4] =   80;
346
  neg_c[a5] =   50;
347
  neg_c[a6] =   10;
348
  neg_c[a7] =   80;
349
  neg_c[a8] =   30;
350
  neg_c[a9] = -120;
351

	
352
  Digraph negs_gr;
353
  Digraph::NodeMap<int> negs_s(negs_gr);
354
  Digraph::ArcMap<int> negs_c(negs_gr);
355
  ConstMap<Arc, int> negs_l(0), negs_u(1000);
356
  n1 = negs_gr.addNode();
357
  n2 = negs_gr.addNode();
358
  negs_s[n1] = 100;
359
  negs_s[n2] = -300;
360
  negs_c[negs_gr.addArc(n1, n2)] = -1;
361

	
362

	
363
  // A. Test NetworkSimplex with the default pivot rule
364
  {
365
    NetworkSimplex<Digraph> mcf(gr);
366

	
367
    // Check the equality form
368
    mcf.upperMap(u).costMap(c);
369
    checkMcf(mcf, mcf.supplyMap(s1).run(),
370
             gr, l1, u, c, s1, mcf.OPTIMAL, true,   5240, "#A1");
371
    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
372
             gr, l1, u, c, s2, mcf.OPTIMAL, true,   7620, "#A2");
373
    mcf.lowerMap(l2);
374
    checkMcf(mcf, mcf.supplyMap(s1).run(),
375
             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#A3");
376
    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
377
             gr, l2, u, c, s2, mcf.OPTIMAL, true,   8010, "#A4");
378
    mcf.reset();
379
    checkMcf(mcf, mcf.supplyMap(s1).run(),
380
             gr, l1, cu, cc, s1, mcf.OPTIMAL, true,   74, "#A5");
381
    checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
382
             gr, l2, cu, cc, s2, mcf.OPTIMAL, true,   94, "#A6");
383
    mcf.reset();
384
    checkMcf(mcf, mcf.run(),
385
             gr, l1, cu, cc, s3, mcf.OPTIMAL, true,    0, "#A7");
386
    checkMcf(mcf, mcf.lowerMap(l2).upperMap(u).run(),
387
             gr, l2, u, cc, s3, mcf.INFEASIBLE, false, 0, "#A8");
388
    mcf.reset().lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
389
    checkMcf(mcf, mcf.run(),
390
             gr, l3, u, c, s4, mcf.OPTIMAL, true,   6360, "#A9");
391

	
392
    // Check the GEQ form
393
    mcf.reset().upperMap(u).costMap(c).supplyMap(s5);
394
    checkMcf(mcf, mcf.run(),
395
             gr, l1, u, c, s5, mcf.OPTIMAL, true,   3530, "#A10", GEQ);
396
    mcf.supplyType(mcf.GEQ);
397
    checkMcf(mcf, mcf.lowerMap(l2).run(),
398
             gr, l2, u, c, s5, mcf.OPTIMAL, true,   4540, "#A11", GEQ);
399
    mcf.supplyMap(s6);
400
    checkMcf(mcf, mcf.run(),
401
             gr, l2, u, c, s6, mcf.INFEASIBLE, false,  0, "#A12", GEQ);
402

	
403
    // Check the LEQ form
404
    mcf.reset().supplyType(mcf.LEQ);
405
    mcf.upperMap(u).costMap(c).supplyMap(s6);
406
    checkMcf(mcf, mcf.run(),
407
             gr, l1, u, c, s6, mcf.OPTIMAL, true,   5080, "#A13", LEQ);
408
    checkMcf(mcf, mcf.lowerMap(l2).run(),
409
             gr, l2, u, c, s6, mcf.OPTIMAL, true,   5930, "#A14", LEQ);
410
    mcf.supplyMap(s5);
411
    checkMcf(mcf, mcf.run(),
412
             gr, l2, u, c, s5, mcf.INFEASIBLE, false,  0, "#A15", LEQ);
413

	
414
    // Check negative costs
415
    NetworkSimplex<Digraph> neg_mcf(neg_gr);
416
    neg_mcf.lowerMap(neg_l1).costMap(neg_c).supplyMap(neg_s);
417
    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u1,
418
      neg_c, neg_s, neg_mcf.UNBOUNDED, false,    0, "#A16");
419
    neg_mcf.upperMap(neg_u2);
420
    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l1, neg_u2,
421
      neg_c, neg_s, neg_mcf.OPTIMAL, true,  -40000, "#A17");
422
    neg_mcf.reset().lowerMap(neg_l2).costMap(neg_c).supplyMap(neg_s);
423
    checkMcf(neg_mcf, neg_mcf.run(), neg_gr, neg_l2, neg_u1,
424
      neg_c, neg_s, neg_mcf.UNBOUNDED, false,    0, "#A18");
425
      
426
    NetworkSimplex<Digraph> negs_mcf(negs_gr);
427
    negs_mcf.costMap(negs_c).supplyMap(negs_s);
428
    checkMcf(negs_mcf, negs_mcf.run(), negs_gr, negs_l, negs_u,
429
      negs_c, negs_s, negs_mcf.OPTIMAL, true, -300, "#A19", GEQ);
430
  }
431

	
432
  // B. Test NetworkSimplex with each pivot rule
433
  {
434
    NetworkSimplex<Digraph> mcf(gr);
435
    mcf.supplyMap(s1).costMap(c).upperMap(u).lowerMap(l2);
436

	
437
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::FIRST_ELIGIBLE),
438
             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B1");
439
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BEST_ELIGIBLE),
440
             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B2");
441
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BLOCK_SEARCH),
442
             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B3");
443
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::CANDIDATE_LIST),
444
             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B4");
445
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::ALTERING_LIST),
446
             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#B5");
447
  }
448

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

	
19
#include "test_tools.h"
20

	
21
#include <lemon/config.h>
22

	
23
#ifdef LEMON_HAVE_CPLEX
24
#include <lemon/cplex.h>
25
#endif
26

	
27
#ifdef LEMON_HAVE_GLPK
28
#include <lemon/glpk.h>
29
#endif
30

	
31
#ifdef LEMON_HAVE_CBC
32
#include <lemon/cbc.h>
33
#endif
34

	
35

	
36
using namespace lemon;
37

	
38
void solveAndCheck(MipSolver& mip, MipSolver::ProblemType stat,
39
                   double exp_opt) {
40
  using std::string;
41

	
42
  mip.solve();
43
  //int decimal,sign;
44
  std::ostringstream buf;
45
  buf << "Type should be: " << int(stat)<<" and it is "<<int(mip.type());
46

	
47

	
48
  //  itoa(stat,buf1, 10);
49
  check(mip.type()==stat, buf.str());
50

	
51
  if (stat ==  MipSolver::OPTIMAL) {
52
    std::ostringstream sbuf;
53
    buf << "Wrong optimal value: the right optimum is " << exp_opt;
54
    check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
55
    //+ecvt(exp_opt,2)
56
  }
57
}
58

	
59
void aTest(MipSolver& mip)
60
{
61
  //The following example is very simple
62

	
63

	
64
  typedef MipSolver::Row Row;
65
  typedef MipSolver::Col Col;
66

	
67

	
68
  Col x1 = mip.addCol();
69
  Col x2 = mip.addCol();
70

	
71

	
72
  //Objective function
73
  mip.obj(x1);
74

	
75
  mip.max();
76

	
77
  //Unconstrained optimization
78
  mip.solve();
79
  //Check it out!
80

	
81
  //Constraints
82
  mip.addRow(2 * x1 + x2 <= 2);
83
  Row y2 = mip.addRow(x1 - 2 * x2 <= 0);
84

	
85
  //Nonnegativity of the variable x1
86
  mip.colLowerBound(x1, 0);
87

	
88

	
89
  //Maximization of x1
90
  //over the triangle with vertices (0,0),(4/5,2/5),(0,2)
91
  double expected_opt=4.0/5.0;
92
  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
93

	
94

	
95
  //Restrict x2 to integer
96
  mip.colType(x2,MipSolver::INTEGER);
97
  expected_opt=1.0/2.0;
98
  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
99

	
100

	
101
  //Restrict both to integer
102
  mip.colType(x1,MipSolver::INTEGER);
103
  expected_opt=0;
104
  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
105

	
106
  //Erase a variable
107
  mip.erase(x2);
108
  mip.rowUpperBound(y2, 8);
109
  expected_opt=1;
110
  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
111

	
112
}
113

	
114

	
115
template<class MIP>
116
void cloneTest()
117
{
118

	
119
  MIP* mip = new MIP();
120
  MIP* mipnew = mip->newSolver();
121
  MIP* mipclone = mip->cloneSolver();
122
  delete mip;
123
  delete mipnew;
124
  delete mipclone;
125
}
126

	
127
int main()
128
{
129

	
130
#ifdef LEMON_HAVE_GLPK
131
  {
132
    GlpkMip mip1;
133
    aTest(mip1);
134
    cloneTest<GlpkMip>();
135
  }
136
#endif
137

	
138
#ifdef LEMON_HAVE_CPLEX
139
  try {
140
    CplexMip mip2;
141
    aTest(mip2);
142
    cloneTest<CplexMip>();
143
  } catch (CplexEnv::LicenseError& error) {
144
    check(false, error.what());
145
  }
146
#endif
147

	
148
#ifdef LEMON_HAVE_CBC
149
  {
150
    CbcMip mip1;
151
    aTest(mip1);
152
    cloneTest<CbcMip>();
153
  }
154
#endif
155

	
156
  return 0;
157

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

	
19
#include <iostream>
20

	
21
#include "test_tools.h"
22
#include <lemon/smart_graph.h>
23
#include <lemon/preflow.h>
24
#include <lemon/concepts/digraph.h>
25
#include <lemon/concepts/maps.h>
26
#include <lemon/lgf_reader.h>
27
#include <lemon/elevator.h>
28

	
29
using namespace lemon;
30

	
31
char test_lgf[] =
32
  "@nodes\n"
33
  "label\n"
34
  "0\n"
35
  "1\n"
36
  "2\n"
37
  "3\n"
38
  "4\n"
39
  "5\n"
40
  "6\n"
41
  "7\n"
42
  "8\n"
43
  "9\n"
44
  "@arcs\n"
45
  "    label capacity\n"
46
  "0 1 0     20\n"
47
  "0 2 1     0\n"
48
  "1 1 2     3\n"
49
  "1 2 3     8\n"
50
  "1 3 4     8\n"
51
  "2 5 5     5\n"
52
  "3 2 6     5\n"
53
  "3 5 7     5\n"
54
  "3 6 8     5\n"
55
  "4 3 9     3\n"
56
  "5 7 10    3\n"
57
  "5 6 11    10\n"
58
  "5 8 12    10\n"
59
  "6 8 13    8\n"
60
  "8 9 14    20\n"
61
  "8 1 15    5\n"
62
  "9 5 16    5\n"
63
  "@attributes\n"
64
  "source 1\n"
65
  "target 8\n";
66

	
67
void checkPreflowCompile()
68
{
69
  typedef int VType;
70
  typedef concepts::Digraph Digraph;
71

	
72
  typedef Digraph::Node Node;
73
  typedef Digraph::Arc Arc;
74
  typedef concepts::ReadMap<Arc,VType> CapMap;
75
  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
76
  typedef concepts::WriteMap<Node,bool> CutMap;
77

	
78
  typedef Elevator<Digraph, Digraph::Node> Elev;
79
  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
80

	
81
  Digraph g;
82
  Node n;
83
  Arc e;
84
  CapMap cap;
85
  FlowMap flow;
86
  CutMap cut;
87
  VType v;
88
  bool b;
89

	
90
  typedef Preflow<Digraph, CapMap>
91
            ::SetFlowMap<FlowMap>
92
            ::SetElevator<Elev>
93
            ::SetStandardElevator<LinkedElev>
94
            ::Create PreflowType;
95
  PreflowType preflow_test(g, cap, n, n);
96
  const PreflowType& const_preflow_test = preflow_test;
97

	
98
  preflow_test
99
    .capacityMap(cap)
100
    .flowMap(flow)
101
    .source(n)
102
    .target(n);
103

	
104
  preflow_test.init();
105
  preflow_test.init(cap);
106
  preflow_test.startFirstPhase();
107
  preflow_test.startSecondPhase();
108
  preflow_test.run();
109
  preflow_test.runMinCut();
110

	
111
  v = const_preflow_test.flowValue();
112
  v = const_preflow_test.flow(e);
113
  const FlowMap& fm = const_preflow_test.flowMap();
114
  b = const_preflow_test.minCut(n);
115
  const_preflow_test.minCutMap(cut);
116
  
117
  ignore_unused_variable_warning(fm);
118
}
119

	
120
int cutValue (const SmartDigraph& g,
121
              const SmartDigraph::NodeMap<bool>& cut,
122
              const SmartDigraph::ArcMap<int>& cap) {
123

	
124
  int c=0;
125
  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
126
    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
127
  }
128
  return c;
129
}
130

	
131
bool checkFlow(const SmartDigraph& g,
132
               const SmartDigraph::ArcMap<int>& flow,
133
               const SmartDigraph::ArcMap<int>& cap,
134
               SmartDigraph::Node s, SmartDigraph::Node t) {
135

	
136
  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
137
    if (flow[e] < 0 || flow[e] > cap[e]) return false;
138
  }
139

	
140
  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
141
    if (n == s || n == t) continue;
142
    int sum = 0;
143
    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
144
      sum += flow[e];
145
    }
146
    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
147
      sum -= flow[e];
148
    }
149
    if (sum != 0) return false;
150
  }
151
  return true;
152
}
153

	
154
int main() {
155

	
156
  typedef SmartDigraph Digraph;
157

	
158
  typedef Digraph::Node Node;
159
  typedef Digraph::NodeIt NodeIt;
160
  typedef Digraph::ArcIt ArcIt;
161
  typedef Digraph::ArcMap<int> CapMap;
162
  typedef Digraph::ArcMap<int> FlowMap;
163
  typedef Digraph::NodeMap<bool> CutMap;
164

	
165
  typedef Preflow<Digraph, CapMap> PType;
166

	
167
  Digraph g;
168
  Node s, t;
169
  CapMap cap(g);
170
  std::istringstream input(test_lgf);
171
  DigraphReader<Digraph>(g,input).
172
    arcMap("capacity", cap).
173
    node("source",s).
174
    node("target",t).
175
    run();
176

	
177
  PType preflow_test(g, cap, s, t);
178
  preflow_test.run();
179

	
180
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
181
        "The flow is not feasible.");
182

	
183
  CutMap min_cut(g);
184
  preflow_test.minCutMap(min_cut);
185
  int min_cut_value=cutValue(g,min_cut,cap);
186

	
187
  check(preflow_test.flowValue() == min_cut_value,
188
        "The max flow value is not equal to the three min cut values.");
189

	
190
  FlowMap flow(g);
191
  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
192

	
193
  int flow_value=preflow_test.flowValue();
194

	
195
  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
196
  preflow_test.init(flow);
197
  preflow_test.startFirstPhase();
198

	
199
  CutMap min_cut1(g);
200
  preflow_test.minCutMap(min_cut1);
201
  min_cut_value=cutValue(g,min_cut1,cap);
202

	
203
  check(preflow_test.flowValue() == min_cut_value &&
204
        min_cut_value == 2*flow_value,
205
        "The max flow value or the min cut value is wrong.");
206

	
207
  preflow_test.startSecondPhase();
208

	
209
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
210
        "The flow is not feasible.");
211

	
212
  CutMap min_cut2(g);
213
  preflow_test.minCutMap(min_cut2);
214
  min_cut_value=cutValue(g,min_cut2,cap);
215

	
216
  check(preflow_test.flowValue() == min_cut_value &&
217
        min_cut_value == 2*flow_value,
218
        "The max flow value or the three min cut values were not doubled");
219

	
220

	
221
  preflow_test.flowMap(flow);
222

	
223
  NodeIt tmp1(g,s);
224
  ++tmp1;
225
  if ( tmp1 != INVALID ) s=tmp1;
226

	
227
  NodeIt tmp2(g,t);
228
  ++tmp2;
229
  if ( tmp2 != INVALID ) t=tmp2;
230

	
231
  preflow_test.source(s);
232
  preflow_test.target(t);
233

	
234
  preflow_test.run();
235

	
236
  CutMap min_cut3(g);
237
  preflow_test.minCutMap(min_cut3);
238
  min_cut_value=cutValue(g,min_cut3,cap);
239

	
240

	
241
  check(preflow_test.flowValue() == min_cut_value,
242
        "The max flow value or the three min cut values are incorrect.");
243

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

	
19
#include <lemon/time_measure.h>
20
#include <lemon/smart_graph.h>
21
#include <lemon/maps.h>
22
#include <lemon/radix_sort.h>
23
#include <lemon/math.h>
24

	
25
#include "test_tools.h"
26

	
27
#include <vector>
28
#include <algorithm>
29

	
30
using namespace lemon;
31

	
32
static const int n = 10000;
33

	
34
struct Negate {
35
  typedef int argument_type;
36
  typedef int result_type;
37
  int operator()(int a) { return - a; }
38
};
39

	
40
int negate(int a) { return - a; }
41

	
42

	
43
void generateIntSequence(int n, std::vector<int>& data) {
44
  int prime = 9973;
45
  int root = 136, value = 1;
46
  for (int i = 0; i < n; ++i) {
47
    data.push_back(value - prime / 2);
48
    value = (value * root) % prime;
49
  }
50
}
51

	
52
void generateCharSequence(int n, std::vector<unsigned char>& data) {
53
  int prime = 251;
54
  int root = 3, value = root;
55
  for (int i = 0; i < n; ++i) {
56
    data.push_back(static_cast<unsigned char>(value));
57
    value = (value * root) % prime;
58
  }
59
}
60

	
61
void checkRadixSort() {
62
  {
63
    std::vector<int> data1;
64
    generateIntSequence(n, data1);
65

	
66
    std::vector<int> data2(data1);
67
    std::sort(data1.begin(), data1.end());
68

	
69
    radixSort(data2.begin(), data2.end());
70
    for (int i = 0; i < n; ++i) {
71
      check(data1[i] == data2[i], "Test failed");
72
    }
73

	
74
    radixSort(data2.begin(), data2.end(), Negate());
75
    for (int i = 0; i < n; ++i) {
76
      check(data1[i] == data2[n - 1 - i], "Test failed");
77
    }
78

	
79
    radixSort(data2.begin(), data2.end(), negate);
80
    for (int i = 0; i < n; ++i) {
81
      check(data1[i] == data2[n - 1 - i], "Test failed");
82
    }
83

	
84
  }
85

	
86
  {
87
    std::vector<unsigned char> data1(n);
88
    generateCharSequence(n, data1);
89

	
90
    std::vector<unsigned char> data2(data1);
91
    std::sort(data1.begin(), data1.end());
92

	
93
    radixSort(data2.begin(), data2.end());
94
    for (int i = 0; i < n; ++i) {
95
      check(data1[i] == data2[i], "Test failed");
96
    }
97

	
98
  }
99
}
100

	
101

	
102
void checkStableRadixSort() {
103
  {
104
    std::vector<int> data1;
105
    generateIntSequence(n, data1);
106

	
107
    std::vector<int> data2(data1);
108
    std::sort(data1.begin(), data1.end());
109

	
110
    stableRadixSort(data2.begin(), data2.end());
111
    for (int i = 0; i < n; ++i) {
112
      check(data1[i] == data2[i], "Test failed");
113
    }
114

	
115
    stableRadixSort(data2.begin(), data2.end(), Negate());
116
    for (int i = 0; i < n; ++i) {
117
      check(data1[i] == data2[n - 1 - i], "Test failed");
118
    }
119

	
120
    stableRadixSort(data2.begin(), data2.end(), negate);
121
    for (int i = 0; i < n; ++i) {
122
      check(data1[i] == data2[n - 1 - i], "Test failed");
123
    }
124
  }
125

	
126
  {
127
    std::vector<unsigned char> data1(n);
128
    generateCharSequence(n, data1);
129

	
130
    std::vector<unsigned char> data2(data1);
131
    std::sort(data1.begin(), data1.end());
132

	
133
    radixSort(data2.begin(), data2.end());
134
    for (int i = 0; i < n; ++i) {
135
      check(data1[i] == data2[i], "Test failed");
136
    }
137

	
138
  }
139
}
140

	
141
int main() {
142

	
143
  checkRadixSort();
144
  checkStableRadixSort();
145

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

	
19
#include <iostream>
20

	
21
#include <lemon/list_graph.h>
22
#include <lemon/lgf_reader.h>
23
#include <lemon/path.h>
24
#include <lemon/suurballe.h>
25
#include <lemon/concepts/digraph.h>
26

	
27
#include "test_tools.h"
28

	
29
using namespace lemon;
30

	
31
char test_lgf[] =
32
  "@nodes\n"
33
  "label\n"
34
  "1\n"
35
  "2\n"
36
  "3\n"
37
  "4\n"
38
  "5\n"
39
  "6\n"
40
  "7\n"
41
  "8\n"
42
  "9\n"
43
  "10\n"
44
  "11\n"
45
  "12\n"
46
  "@arcs\n"
47
  "      length\n"
48
  " 1  2  70\n"
49
  " 1  3 150\n"
50
  " 1  4  80\n"
51
  " 2  8  80\n"
52
  " 3  5 140\n"
53
  " 4  6  60\n"
54
  " 4  7  80\n"
55
  " 4  8 110\n"
56
  " 5  7  60\n"
57
  " 5 11 120\n"
58
  " 6  3   0\n"
59
  " 6  9 140\n"
60
  " 6 10  90\n"
61
  " 7  1  30\n"
62
  " 8 12  60\n"
63
  " 9 12  50\n"
64
  "10 12  70\n"
65
  "10  2 100\n"
66
  "10  7  60\n"
67
  "11 10  20\n"
68
  "12 11  30\n"
69
  "@attributes\n"
70
  "source  1\n"
71
  "target 12\n"
72
  "@end\n";
73

	
74
// Check the interface of Suurballe
75
void checkSuurballeCompile()
76
{
77
  typedef int VType;
78
  typedef concepts::Digraph Digraph;
79

	
80
  typedef Digraph::Node Node;
81
  typedef Digraph::Arc Arc;
82
  typedef concepts::ReadMap<Arc, VType> LengthMap;
83
  
84
  typedef Suurballe<Digraph, LengthMap> SuurballeType;
85

	
86
  Digraph g;
87
  Node n;
88
  Arc e;
89
  LengthMap len;
90
  SuurballeType::FlowMap flow(g);
91
  SuurballeType::PotentialMap pi(g);
92

	
93
  SuurballeType suurb_test(g, len);
94
  const SuurballeType& const_suurb_test = suurb_test;
95

	
96
  suurb_test
97
    .flowMap(flow)
98
    .potentialMap(pi);
99

	
100
  int k;
101
  k = suurb_test.run(n, n);
102
  k = suurb_test.run(n, n, k);
103
  suurb_test.init(n);
104
  k = suurb_test.findFlow(n);
105
  k = suurb_test.findFlow(n, k);
106
  suurb_test.findPaths();
107
  
108
  int f;
109
  VType c;
110
  c = const_suurb_test.totalLength();
111
  f = const_suurb_test.flow(e);
112
  const SuurballeType::FlowMap& fm =
113
    const_suurb_test.flowMap();
114
  c = const_suurb_test.potential(n);
115
  const SuurballeType::PotentialMap& pm =
116
    const_suurb_test.potentialMap();
117
  k = const_suurb_test.pathNum();
118
  Path<Digraph> p = const_suurb_test.path(k);
119
  
120
  ignore_unused_variable_warning(fm);
121
  ignore_unused_variable_warning(pm);
122
}
123

	
124
// Check the feasibility of the flow
125
template <typename Digraph, typename FlowMap>
126
bool checkFlow( const Digraph& gr, const FlowMap& flow,
127
                typename Digraph::Node s, typename Digraph::Node t,
128
                int value )
129
{
130
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
131
  for (ArcIt e(gr); e != INVALID; ++e)
132
    if (!(flow[e] == 0 || flow[e] == 1)) return false;
133

	
134
  for (NodeIt n(gr); n != INVALID; ++n) {
135
    int sum = 0;
136
    for (OutArcIt e(gr, n); e != INVALID; ++e)
137
      sum += flow[e];
138
    for (InArcIt e(gr, n); e != INVALID; ++e)
139
      sum -= flow[e];
140
    if (n == s && sum != value) return false;
141
    if (n == t && sum != -value) return false;
142
    if (n != s && n != t && sum != 0) return false;
143
  }
144

	
145
  return true;
146
}
147

	
148
// Check the optimalitiy of the flow
149
template < typename Digraph, typename CostMap,
150
           typename FlowMap, typename PotentialMap >
151
bool checkOptimality( const Digraph& gr, const CostMap& cost,
152
                      const FlowMap& flow, const PotentialMap& pi )
153
{
154
  // Check the "Complementary Slackness" optimality condition
155
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
156
  bool opt = true;
157
  for (ArcIt e(gr); e != INVALID; ++e) {
158
    typename CostMap::Value red_cost =
159
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
160
    opt = (flow[e] == 0 && red_cost >= 0) ||
161
          (flow[e] == 1 && red_cost <= 0);
162
    if (!opt) break;
163
  }
164
  return opt;
165
}
166

	
167
// Check a path
168
template <typename Digraph, typename Path>
169
bool checkPath( const Digraph& gr, const Path& path,
170
                typename Digraph::Node s, typename Digraph::Node t)
171
{
172
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
173
  Node n = s;
174
  for (int i = 0; i < path.length(); ++i) {
175
    if (gr.source(path.nth(i)) != n) return false;
176
    n = gr.target(path.nth(i));
177
  }
178
  return n == t;
179
}
180

	
181

	
182
int main()
183
{
184
  DIGRAPH_TYPEDEFS(ListDigraph);
185

	
186
  // Read the test digraph
187
  ListDigraph digraph;
188
  ListDigraph::ArcMap<int> length(digraph);
189
  Node s, t;
190

	
191
  std::istringstream input(test_lgf);
192
  DigraphReader<ListDigraph>(digraph, input).
193
    arcMap("length", length).
194
    node("source", s).
195
    node("target", t).
196
    run();
197

	
198
  // Find 2 paths
199
  {
200
    Suurballe<ListDigraph> suurballe(digraph, length);
201
    check(suurballe.run(s, t) == 2, "Wrong number of paths");
202
    check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
203
          "The flow is not feasible");
204
    check(suurballe.totalLength() == 510, "The flow is not optimal");
205
    check(checkOptimality(digraph, length, suurballe.flowMap(),
206
                          suurballe.potentialMap()),
207
          "Wrong potentials");
208
    for (int i = 0; i < suurballe.pathNum(); ++i)
209
      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
210
  }
211

	
212
  // Find 3 paths
213
  {
214
    Suurballe<ListDigraph> suurballe(digraph, length);
215
    check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
216
    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
217
          "The flow is not feasible");
218
    check(suurballe.totalLength() == 1040, "The flow is not optimal");
219
    check(checkOptimality(digraph, length, suurballe.flowMap(),
220
                          suurballe.potentialMap()),
221
          "Wrong potentials");
222
    for (int i = 0; i < suurballe.pathNum(); ++i)
223
      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
224
  }
225

	
226
  // Find 5 paths (only 3 can be found)
227
  {
228
    Suurballe<ListDigraph> suurballe(digraph, length);
229
    check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
230
    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
231
          "The flow is not feasible");
232
    check(suurballe.totalLength() == 1040, "The flow is not optimal");
233
    check(checkOptimality(digraph, length, suurballe.flowMap(),
234
                          suurballe.potentialMap()),
235
          "Wrong potentials");
236
    for (int i = 0; i < suurballe.pathNum(); ++i)
237
      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
238
  }
239

	
240
  return 0;
241
}
Ignore white space 6 line context
1
INCLUDE_DIRECTORIES(
2
  ${PROJECT_SOURCE_DIR}
3
  ${PROJECT_BINARY_DIR}
4
)
5

	
6
LINK_DIRECTORIES(
7
  ${PROJECT_BINARY_DIR}/lemon
8
)
9

	
10
ADD_EXECUTABLE(lgf-gen lgf-gen.cc)
11
TARGET_LINK_LIBRARIES(lgf-gen lemon)
12

	
13
ADD_EXECUTABLE(dimacs-to-lgf dimacs-to-lgf.cc)
14
TARGET_LINK_LIBRARIES(dimacs-to-lgf lemon)
15

	
16
ADD_EXECUTABLE(dimacs-solver dimacs-solver.cc)
17
TARGET_LINK_LIBRARIES(dimacs-solver lemon)
18

	
19
INSTALL(
20
  TARGETS lgf-gen dimacs-to-lgf dimacs-solver
21
  RUNTIME DESTINATION bin
22
  COMPONENT bin
23
)
24

	
25
IF(NOT WIN32)
26
  INSTALL(
27
    PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/lemon-0.x-to-1.x.sh
28
    DESTINATION bin
29
    COMPONENT bin
30
  )
31
ENDIF()
Ignore white space 6 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2009
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
///\ingroup tools
20
///\file
21
///\brief DIMACS problem solver.
22
///
23
/// This program solves various problems given in DIMACS format.
24
///
25
/// See
26
/// \code
27
///   dimacs-solver --help
28
/// \endcode
29
/// for more info on usage.
30

	
31
#include <iostream>
32
#include <fstream>
33
#include <cstring>
34

	
35
#include <lemon/smart_graph.h>
36
#include <lemon/dimacs.h>
37
#include <lemon/lgf_writer.h>
38
#include <lemon/time_measure.h>
39

	
40
#include <lemon/arg_parser.h>
41
#include <lemon/error.h>
42

	
43
#include <lemon/dijkstra.h>
44
#include <lemon/preflow.h>
45
#include <lemon/matching.h>
46
#include <lemon/network_simplex.h>
47

	
48
using namespace lemon;
49
typedef SmartDigraph Digraph;
50
DIGRAPH_TYPEDEFS(Digraph);
51
typedef SmartGraph Graph;
52

	
53
template<class Value>
54
void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
55
              DimacsDescriptor &desc)
56
{
57
  bool report = !ap.given("q");
58
  Digraph g;
59
  Node s;
60
  Digraph::ArcMap<Value> len(g);
61
  Timer t;
62
  t.restart();
63
  readDimacsSp(is, g, len, s, desc);
64
  if(report) std::cerr << "Read the file: " << t << '\n';
65
  t.restart();
66
  Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
67
  if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
68
  t.restart();
69
  dij.run(s);
70
  if(report) std::cerr << "Run Dijkstra: " << t << '\n';
71
}
72

	
73
template<class Value>
74
void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
75
               Value infty, DimacsDescriptor &desc)
76
{
77
  bool report = !ap.given("q");
78
  Digraph g;
79
  Node s,t;
80
  Digraph::ArcMap<Value> cap(g);
81
  Timer ti;
82
  ti.restart();
83
  readDimacsMax(is, g, cap, s, t, infty, desc);
84
  if(report) std::cerr << "Read the file: " << ti << '\n';
85
  ti.restart();
86
  Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
87
  if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
88
  ti.restart();
89
  pre.run();
90
  if(report) std::cerr << "Run Preflow: " << ti << '\n';
91
  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';  
92
}
93

	
94
template<class Value>
95
void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
96
               Value infty, DimacsDescriptor &desc)
97
{
98
  bool report = !ap.given("q");
99
  Digraph g;
100
  Digraph::ArcMap<Value> lower(g), cap(g), cost(g);
101
  Digraph::NodeMap<Value> sup(g);
102
  Timer ti;
103

	
104
  ti.restart();
105
  readDimacsMin(is, g, lower, cap, cost, sup, infty, desc);
106
  ti.stop();
107
  Value sum_sup = 0;
108
  for (Digraph::NodeIt n(g); n != INVALID; ++n) {
109
    sum_sup += sup[n];
110
  }
111
  if (report) {
112
    std::cerr << "Sum of supply values: " << sum_sup << "\n";
113
    if (sum_sup <= 0)
114
      std::cerr << "GEQ supply contraints are used for NetworkSimplex\n\n";
115
    else
116
      std::cerr << "LEQ supply contraints are used for NetworkSimplex\n\n";
117
  }
118
  if (report) std::cerr << "Read the file: " << ti << '\n';
119

	
120
  ti.restart();
121
  NetworkSimplex<Digraph, Value> ns(g);
122
  ns.lowerMap(lower).upperMap(cap).costMap(cost).supplyMap(sup);
123
  if (sum_sup > 0) ns.supplyType(ns.LEQ);
124
  if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n';
125
  ti.restart();
126
  bool res = ns.run();
127
  if (report) {
128
    std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
129
    std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n';
130
    if (res) std::cerr << "Min flow cost: " << ns.totalCost() << '\n';
131
  }
132
}
133

	
134
void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
135
              DimacsDescriptor &desc)
136
{
137
  bool report = !ap.given("q");
138
  Graph g;
139
  Timer ti;
140
  ti.restart();
141
  readDimacsMat(is, g, desc);
142
  if(report) std::cerr << "Read the file: " << ti << '\n';
143
  ti.restart();
144
  MaxMatching<Graph> mat(g);
145
  if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
146
  ti.restart();
147
  mat.run();
148
  if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
149
  if(report) std::cerr << "\nCardinality of max matching: "
150
                       << mat.matchingSize() << '\n';  
151
}
152

	
153

	
154
template<class Value>
155
void solve(ArgParser &ap, std::istream &is, std::ostream &os,
156
           DimacsDescriptor &desc)
157
{
158
  std::stringstream iss(static_cast<std::string>(ap["infcap"]));
159
  Value infty;
160
  iss >> infty;
161
  if(iss.fail())
162
    {
163
      std::cerr << "Cannot interpret '"
164
                << static_cast<std::string>(ap["infcap"]) << "' as infinite"
165
                << std::endl;
166
      exit(1);
167
    }
168
  
169
  switch(desc.type)
170
    {
171
    case DimacsDescriptor::MIN:
172
      solve_min<Value>(ap,is,os,infty,desc);
173
      break;
174
    case DimacsDescriptor::MAX:
175
      solve_max<Value>(ap,is,os,infty,desc);
176
      break;
177
    case DimacsDescriptor::SP:
178
      solve_sp<Value>(ap,is,os,desc);
179
      break;
180
    case DimacsDescriptor::MAT:
181
      solve_mat(ap,is,os,desc);
182
      break;
183
    default:
184
      break;
185
    }
186
}
187

	
188
int main(int argc, const char *argv[]) {
189
  typedef SmartDigraph Digraph;
190

	
191
  typedef Digraph::Arc Arc;
192

	
193
  std::string inputName;
194
  std::string outputName;
195

	
196
  ArgParser ap(argc, argv);
197
  ap.other("[INFILE [OUTFILE]]",
198
           "If either the INFILE or OUTFILE file is missing the standard\n"
199
           "     input/output will be used instead.")
200
    .boolOption("q", "Do not print any report")
201
    .boolOption("int","Use 'int' for capacities, costs etc. (default)")
202
    .optionGroup("datatype","int")
203
#ifdef LEMON_HAVE_LONG_LONG
204
    .boolOption("long","Use 'long long' for capacities, costs etc.")
205
    .optionGroup("datatype","long")
206
#endif
207
    .boolOption("double","Use 'double' for capacities, costs etc.")
208
    .optionGroup("datatype","double")
209
    .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
210
    .optionGroup("datatype","ldouble")
211
    .onlyOneGroup("datatype")
212
    .stringOption("infcap","Value used for 'very high' capacities","0")
213
    .run();
214

	
215
  std::ifstream input;
216
  std::ofstream output;
217

	
218
  switch(ap.files().size())
219
    {
220
    case 2:
221
      output.open(ap.files()[1].c_str());
222
      if (!output) {
223
        throw IoError("Cannot open the file for writing", ap.files()[1]);
224
      }
225
    case 1:
226
      input.open(ap.files()[0].c_str());
227
      if (!input) {
228
        throw IoError("File cannot be found", ap.files()[0]);
229
      }
230
    case 0:
231
      break;
232
    default:
233
      std::cerr << ap.commandName() << ": too many arguments\n";
234
      return 1;
235
    }
236
  std::istream& is = (ap.files().size()<1 ? std::cin : input);
237
  std::ostream& os = (ap.files().size()<2 ? std::cout : output);
238

	
239
  DimacsDescriptor desc = dimacsType(is);
240
  
241
  if(!ap.given("q"))
242
    {
243
      std::cout << "Problem type: ";
244
      switch(desc.type)
245
        {
246
        case DimacsDescriptor::MIN:
247
          std::cout << "min";
248
          break;
249
        case DimacsDescriptor::MAX:
250
          std::cout << "max";
251
          break;
252
        case DimacsDescriptor::SP:
253
          std::cout << "sp";
254
        case DimacsDescriptor::MAT:
255
          std::cout << "mat";
256
          break;
257
        default:
258
          exit(1);
259
          break;
260
        }
261
      std::cout << "\nNum of nodes: " << desc.nodeNum;
262
      std::cout << "\nNum of arcs:  " << desc.edgeNum;
263
      std::cout << "\n\n";
264
    }
265
    
266
  if(ap.given("double"))
267
    solve<double>(ap,is,os,desc);
268
  else if(ap.given("ldouble"))
269
    solve<long double>(ap,is,os,desc);
270
#ifdef LEMON_HAVE_LONG_LONG
271
  else if(ap.given("long"))
272
    solve<long long>(ap,is,os,desc);
273
#endif
274
  else solve<int>(ap,is,os,desc);
275

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

	
19
///\ingroup tools
20
///\file
21
///\brief DIMACS to LGF converter.
22
///
23
/// This program converts various DIMACS formats to the LEMON Digraph Format
24
/// (LGF).
25
///
26
/// See
27
/// \code
28
///   dimacs-to-lgf --help
29
/// \endcode
30
/// for more info on the usage.
31

	
32
#include <iostream>
33
#include <fstream>
34
#include <cstring>
35

	
36
#include <lemon/smart_graph.h>
37
#include <lemon/dimacs.h>
38
#include <lemon/lgf_writer.h>
39

	
40
#include <lemon/arg_parser.h>
41
#include <lemon/error.h>
42

	
43
using namespace std;
44
using namespace lemon;
45

	
46

	
47
int main(int argc, const char *argv[]) {
48
  typedef SmartDigraph Digraph;
49

	
50
  typedef Digraph::Arc Arc;
51
  typedef Digraph::Node Node;
52
  typedef Digraph::ArcIt ArcIt;
53
  typedef Digraph::NodeIt NodeIt;
54
  typedef Digraph::ArcMap<double> DoubleArcMap;
55
  typedef Digraph::NodeMap<double> DoubleNodeMap;
56

	
57
  std::string inputName;
58
  std::string outputName;
59

	
60
  ArgParser ap(argc, argv);
61
  ap.other("[INFILE [OUTFILE]]",
62
           "If either the INFILE or OUTFILE file is missing the standard\n"
63
           "     input/output will be used instead.")
64
    .run();
65

	
66
  ifstream input;
67
  ofstream output;
68

	
69
  switch(ap.files().size())
70
    {
71
    case 2:
72
      output.open(ap.files()[1].c_str());
73
      if (!output) {
74
        throw IoError("Cannot open the file for writing", ap.files()[1]);
75
      }
76
    case 1:
77
      input.open(ap.files()[0].c_str());
78
      if (!input) {
79
        throw IoError("File cannot be found", ap.files()[0]);
80
      }
81
    case 0:
82
      break;
83
    default:
84
      cerr << ap.commandName() << ": too many arguments\n";
85
      return 1;
86
  }
87
  istream& is = (ap.files().size()<1 ? cin : input);
88
  ostream& os = (ap.files().size()<2 ? cout : output);
89

	
90
  DimacsDescriptor desc = dimacsType(is);
91
  switch(desc.type)
92
    {
93
    case DimacsDescriptor::MIN:
94
      {
95
        Digraph digraph;
96
        DoubleArcMap lower(digraph), capacity(digraph), cost(digraph);
97
        DoubleNodeMap supply(digraph);
98
        readDimacsMin(is, digraph, lower, capacity, cost, supply, 0, desc);
99
        DigraphWriter<Digraph>(digraph, os).
100
          nodeMap("supply", supply).
101
          arcMap("lower", lower).
102
          arcMap("capacity", capacity).
103
          arcMap("cost", cost).
104
          attribute("problem","min").
105
          run();
106
      }
107
      break;
108
    case DimacsDescriptor::MAX:
109
      {
110
        Digraph digraph;
111
        Node s, t;
112
        DoubleArcMap capacity(digraph);
113
        readDimacsMax(is, digraph, capacity, s, t, 0, desc);
114
        DigraphWriter<Digraph>(digraph, os).
115
          arcMap("capacity", capacity).
116
          node("source", s).
117
          node("target", t).
118
          attribute("problem","max").
119
          run();
120
      }
121
      break;
122
    case DimacsDescriptor::SP:
123
      {
124
        Digraph digraph;
125
        Node s;
126
        DoubleArcMap capacity(digraph);
127
        readDimacsSp(is, digraph, capacity, s, desc);
128
        DigraphWriter<Digraph>(digraph, os).
129
          arcMap("capacity", capacity).
130
          node("source", s).
131
          attribute("problem","sp").
132
          run();
133
      }
134
      break;
135
    case DimacsDescriptor::MAT:
136
      {
137
        Digraph digraph;
138
        readDimacsMat(is, digraph,desc);
139
        DigraphWriter<Digraph>(digraph, os).
140
          attribute("problem","mat").
141
          run();
142
      }
143
      break;
144
    default:
145
      break;
146
    }
147
  return 0;
148
}
Ignore white space 6 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2009
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
/// \ingroup tools
20
/// \file
21
/// \brief Special plane graph generator.
22
///
23
/// Graph generator application for various types of plane graphs.
24
///
25
/// See
26
/// \code
27
///   lgf-gen --help
28
/// \endcode
29
/// for more information on the usage.
30

	
31
#include <algorithm>
32
#include <set>
33
#include <ctime>
34
#include <lemon/list_graph.h>
35
#include <lemon/random.h>
36
#include <lemon/dim2.h>
37
#include <lemon/bfs.h>
38
#include <lemon/counter.h>
39
#include <lemon/suurballe.h>
40
#include <lemon/graph_to_eps.h>
41
#include <lemon/lgf_writer.h>
42
#include <lemon/arg_parser.h>
43
#include <lemon/euler.h>
44
#include <lemon/math.h>
45
#include <lemon/kruskal.h>
46
#include <lemon/time_measure.h>
47

	
48
using namespace lemon;
49

	
50
typedef dim2::Point<double> Point;
51

	
52
GRAPH_TYPEDEFS(ListGraph);
53

	
54
bool progress=true;
55

	
56
int N;
57
// int girth;
58

	
59
ListGraph g;
60

	
61
std::vector<Node> nodes;
62
ListGraph::NodeMap<Point> coords(g);
63

	
64

	
65
double totalLen(){
66
  double tlen=0;
67
  for(EdgeIt e(g);e!=INVALID;++e)
68
    tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
69
  return tlen;
70
}
71

	
72
int tsp_impr_num=0;
73

	
74
const double EPSILON=1e-8;
75
bool tsp_improve(Node u, Node v)
76
{
77
  double luv=std::sqrt((coords[v]-coords[u]).normSquare());
78
  Node u2=u;
79
  Node v2=v;
80
  do {
81
    Node n;
82
    for(IncEdgeIt e(g,v2);(n=g.runningNode(e))==u2;++e) { }
83
    u2=v2;
84
    v2=n;
85
    if(luv+std::sqrt((coords[v2]-coords[u2]).normSquare())-EPSILON>
86
       std::sqrt((coords[u]-coords[u2]).normSquare())+
87
       std::sqrt((coords[v]-coords[v2]).normSquare()))
88
      {
89
         g.erase(findEdge(g,u,v));
90
         g.erase(findEdge(g,u2,v2));
91
        g.addEdge(u2,u);
92
        g.addEdge(v,v2);
93
        tsp_impr_num++;
94
        return true;
95
      }
96
  } while(v2!=u);
97
  return false;
98
}
99

	
100
bool tsp_improve(Node u)
101
{
102
  for(IncEdgeIt e(g,u);e!=INVALID;++e)
103
    if(tsp_improve(u,g.runningNode(e))) return true;
104
  return false;
105
}
106

	
107
void tsp_improve()
108
{
109
  bool b;
110
  do {
111
    b=false;
112
    for(NodeIt n(g);n!=INVALID;++n)
113
      if(tsp_improve(n)) b=true;
114
  } while(b);
115
}
116

	
117
void tsp()
118
{
119
  for(int i=0;i<N;i++) g.addEdge(nodes[i],nodes[(i+1)%N]);
120
  tsp_improve();
121
}
122

	
123
class Line
124
{
125
public:
126
  Point a;
127
  Point b;
128
  Line(Point _a,Point _b) :a(_a),b(_b) {}
129
  Line(Node _a,Node _b) : a(coords[_a]),b(coords[_b]) {}
130
  Line(const Arc &e) : a(coords[g.source(e)]),b(coords[g.target(e)]) {}
131
  Line(const Edge &e) : a(coords[g.u(e)]),b(coords[g.v(e)]) {}
132
};
133

	
134
inline std::ostream& operator<<(std::ostream &os, const Line &l)
135
{
136
  os << l.a << "->" << l.b;
137
  return os;
138
}
139

	
140
bool cross(Line a, Line b)
141
{
142
  Point ao=rot90(a.b-a.a);
143
  Point bo=rot90(b.b-b.a);
144
  return (ao*(b.a-a.a))*(ao*(b.b-a.a))<0 &&
145
    (bo*(a.a-b.a))*(bo*(a.b-b.a))<0;
146
}
147

	
148
struct Parc
149
{
150
  Node a;
151
  Node b;
152
  double len;
153
};
154

	
155
bool pedgeLess(Parc a,Parc b)
156
{
157
  return a.len<b.len;
158
}
159

	
160
std::vector<Edge> arcs;
161

	
162
namespace _delaunay_bits {
163

	
164
  struct Part {
165
    int prev, curr, next;
166

	
167
    Part(int p, int c, int n) : prev(p), curr(c), next(n) {}
168
  };
169

	
170
  inline std::ostream& operator<<(std::ostream& os, const Part& part) {
171
    os << '(' << part.prev << ',' << part.curr << ',' << part.next << ')';
172
    return os;
173
  }
174

	
175
  inline double circle_point(const Point& p, const Point& q, const Point& r) {
176
    double a = p.x * (q.y - r.y) + q.x * (r.y - p.y) + r.x * (p.y - q.y);
177
    if (a == 0) return std::numeric_limits<double>::quiet_NaN();
178

	
179
    double d = (p.x * p.x + p.y * p.y) * (q.y - r.y) +
180
      (q.x * q.x + q.y * q.y) * (r.y - p.y) +
181
      (r.x * r.x + r.y * r.y) * (p.y - q.y);
182

	
183
    double e = (p.x * p.x + p.y * p.y) * (q.x - r.x) +
184
      (q.x * q.x + q.y * q.y) * (r.x - p.x) +
185
      (r.x * r.x + r.y * r.y) * (p.x - q.x);
186

	
187
    double f = (p.x * p.x + p.y * p.y) * (q.x * r.y - r.x * q.y) +
188
      (q.x * q.x + q.y * q.y) * (r.x * p.y - p.x * r.y) +
189
      (r.x * r.x + r.y * r.y) * (p.x * q.y - q.x * p.y);
190

	
191
    return d / (2 * a) + std::sqrt((d * d + e * e) / (4 * a * a) + f / a);
192
  }
193

	
194
  inline bool circle_form(const Point& p, const Point& q, const Point& r) {
195
    return rot90(q - p) * (r - q) < 0.0;
196
  }
197

	
198
  inline double intersection(const Point& p, const Point& q, double sx) {
199
    const double epsilon = 1e-8;
200

	
201
    if (p.x == q.x) return (p.y + q.y) / 2.0;
202

	
203
    if (sx < p.x + epsilon) return p.y;
204
    if (sx < q.x + epsilon) return q.y;
205

	
206
    double a = q.x - p.x;
207
    double b = (q.x - sx) * p.y - (p.x - sx) * q.y;
208
    double d = (q.x - sx) * (p.x - sx) * (p - q).normSquare();
209
    return (b - std::sqrt(d)) / a;
210
  }
211

	
212
  struct YLess {
213

	
214

	
215
    YLess(const std::vector<Point>& points, double& sweep)
216
      : _points(points), _sweep(sweep) {}
217

	
218
    bool operator()(const Part& l, const Part& r) const {
219
      const double epsilon = 1e-8;
220

	
221
      //      std::cerr << l << " vs " << r << std::endl;
222
      double lbx = l.prev != -1 ?
223
        intersection(_points[l.prev], _points[l.curr], _sweep) :
224
        - std::numeric_limits<double>::infinity();
225
      double rbx = r.prev != -1 ?
226
        intersection(_points[r.prev], _points[r.curr], _sweep) :
227
        - std::numeric_limits<double>::infinity();
228
      double lex = l.next != -1 ?
229
        intersection(_points[l.curr], _points[l.next], _sweep) :
230
        std::numeric_limits<double>::infinity();
231
      double rex = r.next != -1 ?
232
        intersection(_points[r.curr], _points[r.next], _sweep) :
233
        std::numeric_limits<double>::infinity();
234

	
235
      if (lbx > lex) std::swap(lbx, lex);
236
      if (rbx > rex) std::swap(rbx, rex);
237

	
238
      if (lex < epsilon + rex && lbx + epsilon < rex) return true;
239
      if (rex < epsilon + lex && rbx + epsilon < lex) return false;
240
      return lex < rex;
241
    }
242

	
243
    const std::vector<Point>& _points;
244
    double& _sweep;
245
  };
246

	
247
  struct BeachIt;
248

	
249
  typedef std::multimap<double, BeachIt> SpikeHeap;
250

	
251
  typedef std::multimap<Part, SpikeHeap::iterator, YLess> Beach;
252

	
253
  struct BeachIt {
254
    Beach::iterator it;
255

	
256
    BeachIt(Beach::iterator iter) : it(iter) {}
257
  };
258

	
259
}
260

	
261
inline void delaunay() {
262
  Counter cnt("Number of arcs added: ");
263

	
264
  using namespace _delaunay_bits;
265

	
266
  typedef _delaunay_bits::Part Part;
267
  typedef std::vector<std::pair<double, int> > SiteHeap;
268

	
269

	
270
  std::vector<Point> points;
271
  std::vector<Node> nodes;
272

	
273
  for (NodeIt it(g); it != INVALID; ++it) {
274
    nodes.push_back(it);
275
    points.push_back(coords[it]);
276
  }
277

	
278
  SiteHeap siteheap(points.size());
279

	
280
  double sweep;
281

	
282

	
283
  for (int i = 0; i < int(siteheap.size()); ++i) {
284
    siteheap[i] = std::make_pair(points[i].x, i);
285
  }
286

	
287
  std::sort(siteheap.begin(), siteheap.end());
288
  sweep = siteheap.front().first;
289

	
290
  YLess yless(points, sweep);
291
  Beach beach(yless);
292

	
293
  SpikeHeap spikeheap;
294

	
295
  std::set<std::pair<int, int> > arcs;
296

	
297
  int siteindex = 0;
298
  {
299
    SiteHeap front;
300

	
301
    while (siteindex < int(siteheap.size()) &&
302
           siteheap[0].first == siteheap[siteindex].first) {
303
      front.push_back(std::make_pair(points[siteheap[siteindex].second].y,
304
                                     siteheap[siteindex].second));
305
      ++siteindex;
306
    }
307

	
308
    std::sort(front.begin(), front.end());
309

	
310
    for (int i = 0; i < int(front.size()); ++i) {
311
      int prev = (i == 0 ? -1 : front[i - 1].second);
312
      int curr = front[i].second;
313
      int next = (i + 1 == int(front.size()) ? -1 : front[i + 1].second);
314

	
315
      beach.insert(std::make_pair(Part(prev, curr, next),
316
                                  spikeheap.end()));
317
    }
318
  }
319

	
320
  while (siteindex < int(points.size()) || !spikeheap.empty()) {
321

	
322
    SpikeHeap::iterator spit = spikeheap.begin();
323

	
324
    if (siteindex < int(points.size()) &&
325
        (spit == spikeheap.end() || siteheap[siteindex].first < spit->first)) {
326
      int site = siteheap[siteindex].second;
327
      sweep = siteheap[siteindex].first;
328

	
329
      Beach::iterator bit = beach.upper_bound(Part(site, site, site));
330

	
331
      if (bit->second != spikeheap.end()) {
332
        spikeheap.erase(bit->second);
333
      }
334

	
335
      int prev = bit->first.prev;
336
      int curr = bit->first.curr;
337
      int next = bit->first.next;
338

	
339
      beach.erase(bit);
340

	
341
      SpikeHeap::iterator pit = spikeheap.end();
342
      if (prev != -1 &&
343
          circle_form(points[prev], points[curr], points[site])) {
344
        double x = circle_point(points[prev], points[curr], points[site]);
345
        pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
346
        pit->second.it =
347
          beach.insert(std::make_pair(Part(prev, curr, site), pit));
348
      } else {
349
        beach.insert(std::make_pair(Part(prev, curr, site), pit));
350
      }
351

	
352
      beach.insert(std::make_pair(Part(curr, site, curr), spikeheap.end()));
353

	
354
      SpikeHeap::iterator nit = spikeheap.end();
355
      if (next != -1 &&
356
          circle_form(points[site], points[curr],points[next])) {
357
        double x = circle_point(points[site], points[curr], points[next]);
358
        nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
359
        nit->second.it =
360
          beach.insert(std::make_pair(Part(site, curr, next), nit));
361
      } else {
362
        beach.insert(std::make_pair(Part(site, curr, next), nit));
363
      }
364

	
365
      ++siteindex;
366
    } else {
367
      sweep = spit->first;
368

	
369
      Beach::iterator bit = spit->second.it;
370

	
371
      int prev = bit->first.prev;
372
      int curr = bit->first.curr;
373
      int next = bit->first.next;
374

	
375
      {
376
        std::pair<int, int> arc;
377

	
378
        arc = prev < curr ?
379
          std::make_pair(prev, curr) : std::make_pair(curr, prev);
380

	
381
        if (arcs.find(arc) == arcs.end()) {
382
          arcs.insert(arc);
383
          g.addEdge(nodes[prev], nodes[curr]);
384
          ++cnt;
385
        }
386

	
387
        arc = curr < next ?
388
          std::make_pair(curr, next) : std::make_pair(next, curr);
389

	
390
        if (arcs.find(arc) == arcs.end()) {
391
          arcs.insert(arc);
392
          g.addEdge(nodes[curr], nodes[next]);
393
          ++cnt;
394
        }
395
      }
396

	
397
      Beach::iterator pbit = bit; --pbit;
398
      int ppv = pbit->first.prev;
399
      Beach::iterator nbit = bit; ++nbit;
400
      int nnt = nbit->first.next;
401

	
402
      if (bit->second != spikeheap.end()) spikeheap.erase(bit->second);
403
      if (pbit->second != spikeheap.end()) spikeheap.erase(pbit->second);
404
      if (nbit->second != spikeheap.end()) spikeheap.erase(nbit->second);
405

	
406
      beach.erase(nbit);
407
      beach.erase(bit);
408
      beach.erase(pbit);
409

	
410
      SpikeHeap::iterator pit = spikeheap.end();
411
      if (ppv != -1 && ppv != next &&
412
          circle_form(points[ppv], points[prev], points[next])) {
413
        double x = circle_point(points[ppv], points[prev], points[next]);
414
        if (x < sweep) x = sweep;
415
        pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
416
        pit->second.it =
417
          beach.insert(std::make_pair(Part(ppv, prev, next), pit));
418
      } else {
419
        beach.insert(std::make_pair(Part(ppv, prev, next), pit));
420
      }
421

	
422
      SpikeHeap::iterator nit = spikeheap.end();
423
      if (nnt != -1 && prev != nnt &&
424
          circle_form(points[prev], points[next], points[nnt])) {
425
        double x = circle_point(points[prev], points[next], points[nnt]);
426
        if (x < sweep) x = sweep;
427
        nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
428
        nit->second.it =
429
          beach.insert(std::make_pair(Part(prev, next, nnt), nit));
430
      } else {
431
        beach.insert(std::make_pair(Part(prev, next, nnt), nit));
432
      }
433

	
434
    }
435
  }
436

	
437
  for (Beach::iterator it = beach.begin(); it != beach.end(); ++it) {
438
    int curr = it->first.curr;
439
    int next = it->first.next;
440

	
441
    if (next == -1) continue;
442

	
443
    std::pair<int, int> arc;
444

	
445
    arc = curr < next ?
446
      std::make_pair(curr, next) : std::make_pair(next, curr);
447

	
448
    if (arcs.find(arc) == arcs.end()) {
449
      arcs.insert(arc);
450
      g.addEdge(nodes[curr], nodes[next]);
451
      ++cnt;
452
    }
453
  }
454
}
455

	
456
void sparse(int d)
457
{
458
  Counter cnt("Number of arcs removed: ");
459
  Bfs<ListGraph> bfs(g);
460
  for(std::vector<Edge>::reverse_iterator ei=arcs.rbegin();
461
      ei!=arcs.rend();++ei)
462
    {
463
      Node a=g.u(*ei);
464
      Node b=g.v(*ei);
465
      g.erase(*ei);
466
      bfs.run(a,b);
467
      if(bfs.predArc(b)==INVALID || bfs.dist(b)>d)
468
        g.addEdge(a,b);
469
      else cnt++;
470
    }
471
}
472

	
473
void sparse2(int d)
474
{
475
  Counter cnt("Number of arcs removed: ");
476
  for(std::vector<Edge>::reverse_iterator ei=arcs.rbegin();
477
      ei!=arcs.rend();++ei)
478
    {
479
      Node a=g.u(*ei);
480
      Node b=g.v(*ei);
481
      g.erase(*ei);
482
      ConstMap<Arc,int> cegy(1);
483
      Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
484
      int k=sur.run(a,b,2);
485
      if(k<2 || sur.totalLength()>d)
486
        g.addEdge(a,b);
487
      else cnt++;
488
//       else std::cout << "Remove arc " << g.id(a) << "-" << g.id(b) << '\n';
489
    }
490
}
491

	
492
void sparseTriangle(int d)
493
{
494
  Counter cnt("Number of arcs added: ");
495
  std::vector<Parc> pedges;
496
  for(NodeIt n(g);n!=INVALID;++n)
497
    for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
498
      {
499
        Parc p;
500
        p.a=n;
501
        p.b=m;
502
        p.len=(coords[m]-coords[n]).normSquare();
503
        pedges.push_back(p);
504
      }
505
  std::sort(pedges.begin(),pedges.end(),pedgeLess);
506
  for(std::vector<Parc>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
507
    {
508
      Line li(pi->a,pi->b);
509
      EdgeIt e(g);
510
      for(;e!=INVALID && !cross(e,li);++e) ;
511
      Edge ne;
512
      if(e==INVALID) {
513
        ConstMap<Arc,int> cegy(1);
514
        Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
515
        int k=sur.run(pi->a,pi->b,2);
516
        if(k<2 || sur.totalLength()>d)
517
          {
518
            ne=g.addEdge(pi->a,pi->b);
519
            arcs.push_back(ne);
520
            cnt++;
521
          }
522
      }
523
    }
524
}
525

	
526
template <typename Graph, typename CoordMap>
527
class LengthSquareMap {
528
public:
529
  typedef typename Graph::Edge Key;
530
  typedef typename CoordMap::Value::Value Value;
531

	
532
  LengthSquareMap(const Graph& graph, const CoordMap& coords)
533
    : _graph(graph), _coords(coords) {}
534

	
535
  Value operator[](const Key& key) const {
536
    return (_coords[_graph.v(key)] -
537
            _coords[_graph.u(key)]).normSquare();
538
  }
539

	
540
private:
541

	
542
  const Graph& _graph;
543
  const CoordMap& _coords;
544
};
545

	
546
void minTree() {
547
  std::vector<Parc> pedges;
548
  Timer T;
549
  std::cout << T.realTime() << "s: Creating delaunay triangulation...\n";
550
  delaunay();
551
  std::cout << T.realTime() << "s: Calculating spanning tree...\n";
552
  LengthSquareMap<ListGraph, ListGraph::NodeMap<Point> > ls(g, coords);
553
  ListGraph::EdgeMap<bool> tree(g);
554
  kruskal(g, ls, tree);
555
  std::cout << T.realTime() << "s: Removing non tree arcs...\n";
556
  std::vector<Edge> remove;
557
  for (EdgeIt e(g); e != INVALID; ++e) {
558
    if (!tree[e]) remove.push_back(e);
559
  }
560
  for(int i = 0; i < int(remove.size()); ++i) {
561
    g.erase(remove[i]);
562
  }
563
  std::cout << T.realTime() << "s: Done\n";
564
}
565

	
566
void tsp2()
567
{
568
  std::cout << "Find a tree..." << std::endl;
569

	
570
  minTree();
571

	
572
  std::cout << "Total arc length (tree) : " << totalLen() << std::endl;
573

	
574
  std::cout << "Make it Euler..." << std::endl;
575

	
576
  {
577
    std::vector<Node> leafs;
578
    for(NodeIt n(g);n!=INVALID;++n)
579
      if(countIncEdges(g,n)%2==1) leafs.push_back(n);
580

	
581
//    for(unsigned int i=0;i<leafs.size();i+=2)
582
//       g.addArc(leafs[i],leafs[i+1]);
583

	
584
    std::vector<Parc> pedges;
585
    for(unsigned int i=0;i<leafs.size()-1;i++)
586
      for(unsigned int j=i+1;j<leafs.size();j++)
587
        {
588
          Node n=leafs[i];
589
          Node m=leafs[j];
590
          Parc p;
591
          p.a=n;
592
          p.b=m;
593
          p.len=(coords[m]-coords[n]).normSquare();
594
          pedges.push_back(p);
595
        }
596
    std::sort(pedges.begin(),pedges.end(),pedgeLess);
597
    for(unsigned int i=0;i<pedges.size();i++)
598
      if(countIncEdges(g,pedges[i].a)%2 &&
599
         countIncEdges(g,pedges[i].b)%2)
600
        g.addEdge(pedges[i].a,pedges[i].b);
601
  }
602

	
603
  for(NodeIt n(g);n!=INVALID;++n)
604
    if(countIncEdges(g,n)%2 || countIncEdges(g,n)==0 )
605
      std::cout << "GEBASZ!!!" << std::endl;
606

	
607
  for(EdgeIt e(g);e!=INVALID;++e)
608
    if(g.u(e)==g.v(e))
609
      std::cout << "LOOP GEBASZ!!!" << std::endl;
610

	
611
  std::cout << "Number of arcs : " << countEdges(g) << std::endl;
612

	
613
  std::cout << "Total arc length (euler) : " << totalLen() << std::endl;
614

	
615
  ListGraph::EdgeMap<Arc> enext(g);
616
  {
617
    EulerIt<ListGraph> e(g);
618
    Arc eo=e;
619
    Arc ef=e;
620
//     std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl;
621
    for(++e;e!=INVALID;++e)
622
      {
623
//         std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl;
624
        enext[eo]=e;
625
        eo=e;
626
      }
627
    enext[eo]=ef;
628
  }
629

	
630
  std::cout << "Creating a tour from that..." << std::endl;
631

	
632
  int nnum = countNodes(g);
633
  int ednum = countEdges(g);
634

	
635
  for(Arc p=enext[EdgeIt(g)];ednum>nnum;p=enext[p])
636
    {
637
//       std::cout << "Checking arc " << g.id(p) << std::endl;
638
      Arc e=enext[p];
639
      Arc f=enext[e];
640
      Node n2=g.source(f);
641
      Node n1=g.oppositeNode(n2,e);
642
      Node n3=g.oppositeNode(n2,f);
643
      if(countIncEdges(g,n2)>2)
644
        {
645
//           std::cout << "Remove an Arc" << std::endl;
646
          Arc ff=enext[f];
647
          g.erase(e);
648
          g.erase(f);
649
          if(n1!=n3)
650
            {
651
              Arc ne=g.direct(g.addEdge(n1,n3),n1);
652
              enext[p]=ne;
653
              enext[ne]=ff;
654
              ednum--;
655
            }
656
          else {
657
            enext[p]=ff;
658
            ednum-=2;
659
          }
660
        }
661
    }
662

	
663
  std::cout << "Total arc length (tour) : " << totalLen() << std::endl;
664

	
665
  std::cout << "2-opt the tour..." << std::endl;
666

	
667
  tsp_improve();
668

	
669
  std::cout << "Total arc length (2-opt tour) : " << totalLen() << std::endl;
670
}
671

	
672

	
673
int main(int argc,const char **argv)
674
{
675
  ArgParser ap(argc,argv);
676

	
677
//   bool eps;
678
  bool disc_d, square_d, gauss_d;
679
//   bool tsp_a,two_a,tree_a;
680
  int num_of_cities=1;
681
  double area=1;
682
  N=100;
683
//   girth=10;
684
  std::string ndist("disc");
685
  ap.refOption("n", "Number of nodes (default is 100)", N)
686
    .intOption("g", "Girth parameter (default is 10)", 10)
687
    .refOption("cities", "Number of cities (default is 1)", num_of_cities)
688
    .refOption("area", "Full relative area of the cities (default is 1)", area)
689
    .refOption("disc", "Nodes are evenly distributed on a unit disc (default)",
690
               disc_d)
691
    .optionGroup("dist", "disc")
692
    .refOption("square", "Nodes are evenly distributed on a unit square",
693
               square_d)
694
    .optionGroup("dist", "square")
695
    .refOption("gauss", "Nodes are located according to a two-dim Gauss "
696
               "distribution", gauss_d)
697
    .optionGroup("dist", "gauss")
698
    .onlyOneGroup("dist")
699
    .boolOption("eps", "Also generate .eps output (<prefix>.eps)")
700
    .boolOption("nonodes", "Draw only the edges in the generated .eps output")
701
    .boolOption("dir", "Directed graph is generated (each edge is replaced by "
702
                "two directed arcs)")
703
    .boolOption("2con", "Create a two connected planar graph")
704
    .optionGroup("alg","2con")
705
    .boolOption("tree", "Create a min. cost spanning tree")
706
    .optionGroup("alg","tree")
707
    .boolOption("tsp", "Create a TSP tour")
708
    .optionGroup("alg","tsp")
709
    .boolOption("tsp2", "Create a TSP tour (tree based)")
710
    .optionGroup("alg","tsp2")
711
    .boolOption("dela", "Delaunay triangulation graph")
712
    .optionGroup("alg","dela")
713
    .onlyOneGroup("alg")
714
    .boolOption("rand", "Use time seed for random number generator")
715
    .optionGroup("rand", "rand")
716
    .intOption("seed", "Random seed", -1)
717
    .optionGroup("rand", "seed")
718
    .onlyOneGroup("rand")
719
    .other("[prefix]","Prefix of the output files. Default is 'lgf-gen-out'")
720
    .run();
721

	
722
  if (ap["rand"]) {
723
    int seed = int(time(0));
724
    std::cout << "Random number seed: " << seed << std::endl;
725
    rnd = Random(seed);
726
  }
727
  if (ap.given("seed")) {
728
    int seed = ap["seed"];
729
    std::cout << "Random number seed: " << seed << std::endl;
730
    rnd = Random(seed);
731
  }
732

	
733
  std::string prefix;
734
  switch(ap.files().size())
735
    {
736
    case 0:
737
      prefix="lgf-gen-out";
738
      break;
739
    case 1:
740
      prefix=ap.files()[0];
741
      break;
742
    default:
743
      std::cerr << "\nAt most one prefix can be given\n\n";
744
      exit(1);
745
    }
746

	
747
  double sum_sizes=0;
748
  std::vector<double> sizes;
749
  std::vector<double> cum_sizes;
750
  for(int s=0;s<num_of_cities;s++)
751
    {
752
      //         sum_sizes+=rnd.exponential();
753
      double d=rnd();
754
      sum_sizes+=d;
755
      sizes.push_back(d);
756
      cum_sizes.push_back(sum_sizes);
757
    }
758
  int i=0;
759
  for(int s=0;s<num_of_cities;s++)
760
    {
761
      Point center=(num_of_cities==1?Point(0,0):rnd.disc());
762
      if(gauss_d)
763
        for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
764
          Node n=g.addNode();
765
          nodes.push_back(n);
766
          coords[n]=center+rnd.gauss2()*area*
767
            std::sqrt(sizes[s]/sum_sizes);
768
        }
769
      else if(square_d)
770
        for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
771
          Node n=g.addNode();
772
          nodes.push_back(n);
773
          coords[n]=center+Point(rnd()*2-1,rnd()*2-1)*area*
774
            std::sqrt(sizes[s]/sum_sizes);
775
        }
776
      else if(disc_d || true)
777
        for(;i<N*(cum_sizes[s]/sum_sizes);i++) {
778
          Node n=g.addNode();
779
          nodes.push_back(n);
780
          coords[n]=center+rnd.disc()*area*
781
            std::sqrt(sizes[s]/sum_sizes);
782
        }
783
    }
784

	
785
//   for (ListGraph::NodeIt n(g); n != INVALID; ++n) {
786
//     std::cerr << coords[n] << std::endl;
787
//   }
788

	
789
  if(ap["tsp"]) {
790
    tsp();
791
    std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
792
  }
793
  if(ap["tsp2"]) {
794
    tsp2();
795
    std::cout << "#2-opt improvements: " << tsp_impr_num << std::endl;
796
  }
797
  else if(ap["2con"]) {
798
    std::cout << "Make triangles\n";
799
    //   triangle();
800
    sparseTriangle(ap["g"]);
801
    std::cout << "Make it sparser\n";
802
    sparse2(ap["g"]);
803
  }
804
  else if(ap["tree"]) {
805
    minTree();
806
  }
807
  else if(ap["dela"]) {
808
    delaunay();
809
  }
810

	
811

	
812
  std::cout << "Number of nodes    : " << countNodes(g) << std::endl;
813
  std::cout << "Number of arcs    : " << countEdges(g) << std::endl;
814
  double tlen=0;
815
  for(EdgeIt e(g);e!=INVALID;++e)
816
    tlen+=std::sqrt((coords[g.v(e)]-coords[g.u(e)]).normSquare());
817
  std::cout << "Total arc length  : " << tlen << std::endl;
818

	
819
  if(ap["eps"])
820
    graphToEps(g,prefix+".eps").scaleToA4().
821
      scale(600).nodeScale(.005).arcWidthScale(.001).preScale(false).
822
      coords(coords).hideNodes(ap.given("nonodes")).run();
823

	
824
  if(ap["dir"])
825
    DigraphWriter<ListGraph>(g,prefix+".lgf").
826
      nodeMap("coordinates_x",scaleMap(xMap(coords),600)).
827
      nodeMap("coordinates_y",scaleMap(yMap(coords),600)).
828
      run();
829
  else GraphWriter<ListGraph>(g,prefix+".lgf").
830
         nodeMap("coordinates_x",scaleMap(xMap(coords),600)).
831
         nodeMap("coordinates_y",scaleMap(yMap(coords),600)).
832
         run();
833
}
834

	
Ignore white space 6 line context
1 1
syntax: glob
2 2
*.obj
3 3
*.orig
4 4
*.rej
5 5
*~
6 6
*.o
7 7
*.log
8 8
*.lo
9 9
*.tar.*
10 10
*.bak
11 11
Makefile.in
12 12
aclocal.m4
13 13
config.h.in
14 14
configure
15 15
Makefile
16 16
config.h
17 17
config.log
18 18
config.status
19 19
libtool
20 20
stamp-h1
21 21
lemon/lemon.pc
22 22
lemon/libemon.la
23 23
lemon/stamp-h2
24 24
doc/Doxyfile
25
cmake/cmake.version
25
cmake/version.cmake
26 26
.dirstamp
27 27
.libs/*
28 28
.deps/*
29 29
demo/*.eps
30
m4/libtool.m4
31
m4/ltoptions.m4
32
m4/ltsugar.m4
33
m4/ltversion.m4
34
m4/lt~obsolete.m4
30 35

	
31 36
syntax: regexp
32 37
(.*/)?\#[^/]*\#$
33 38
(.*/)?\.\#[^/]*$
34 39
^doc/html/.*
35 40
^doc/.*\.tag
36 41
^autom4te.cache/.*
37 42
^build-aux/.*
38
^objs.*/.*
43
^.*objs.*/.*
39 44
^test/[a-z_]*$
45
^tools/[a-z-_]*$
40 46
^demo/.*_demo$
41
^build/.*
47
^.*build.*/.*
42 48
^doc/gen-images/.*
43 49
CMakeFiles
44 50
DartTestfile.txt
45 51
cmake_install.cmake
46 52
CMakeCache.txt
Ignore white space 6 line context
1 1
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
2 2

	
3
IF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
4
  INCLUDE(${CMAKE_SOURCE_DIR}/cmake/version.cmake)
5
ELSE(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
6
  SET(PROJECT_NAME "LEMON")
7
  SET(PROJECT_VERSION "hg-tip" CACHE STRING "LEMON version string.")
8
ENDIF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
9

	
3
SET(PROJECT_NAME "LEMON")
10 4
PROJECT(${PROJECT_NAME})
11 5

	
12
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
6
IF(EXISTS ${PROJECT_SOURCE_DIR}/cmake/version.cmake)
7
  INCLUDE(${PROJECT_SOURCE_DIR}/cmake/version.cmake)
8
ELSEIF(DEFINED ENV{LEMON_VERSION})
9
  SET(LEMON_VERSION $ENV{LEMON_VERSION} CACHE STRING "LEMON version string.")
10
ELSE()
11
  EXECUTE_PROCESS(
12
    COMMAND hg id -i
13
    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
14
    OUTPUT_VARIABLE HG_REVISION
15
    ERROR_QUIET
16
    OUTPUT_STRIP_TRAILING_WHITESPACE
17
  )
18
  IF(HG_REVISION STREQUAL "")
19
    SET(HG_REVISION "hg-tip")
20
  ENDIF()
21
  SET(LEMON_VERSION ${HG_REVISION} CACHE STRING "LEMON version string.")
22
ENDIF()
13 23

	
14
INCLUDE(FindDoxygen)
15
INCLUDE(FindGhostscript)
24
SET(PROJECT_VERSION ${LEMON_VERSION})
16 25

	
17
ADD_DEFINITIONS(-DHAVE_CONFIG_H)
26
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
27

	
28
FIND_PACKAGE(Doxygen)
29
FIND_PACKAGE(Ghostscript)
30
FIND_PACKAGE(GLPK 4.33)
31
FIND_PACKAGE(CPLEX)
32
FIND_PACKAGE(COIN)
18 33

	
19 34
INCLUDE(CheckTypeSize)
20
CHECK_TYPE_SIZE("long long" LEMON_LONG_LONG)
35
CHECK_TYPE_SIZE("long long" LONG_LONG)
36
SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
21 37

	
22 38
ENABLE_TESTING()
23 39

	
24 40
ADD_SUBDIRECTORY(lemon)
25
ADD_SUBDIRECTORY(demo)
26
ADD_SUBDIRECTORY(doc)
27
ADD_SUBDIRECTORY(test)
41
IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
42
  ADD_SUBDIRECTORY(demo)
43
  ADD_SUBDIRECTORY(tools)
44
  ADD_SUBDIRECTORY(doc)
45
  ADD_SUBDIRECTORY(test)
46
ENDIF()
28 47

	
29
IF(WIN32)
48
CONFIGURE_FILE(
49
  ${PROJECT_SOURCE_DIR}/cmake/LEMONConfig.cmake.in
50
  ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
51
  @ONLY
52
)
53
IF(UNIX)
54
  INSTALL(
55
    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
56
    DESTINATION share/lemon/cmake
57
  )
58
ELSEIF(WIN32)
59
  INSTALL(
60
    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
61
    DESTINATION cmake
62
  )
63
ENDIF()
64

	
65
IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR} AND WIN32)
30 66
  SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
31 67
  SET(CPACK_PACKAGE_VENDOR "EGRES")
32 68
  SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
33
    "LEMON - Library of Efficient Models and Optimization in Networks")
34
  SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
69
    "LEMON - Library for Efficient Modeling and Optimization in Networks")
70
  SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
35 71

	
36 72
  SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
37 73

	
38 74
  SET(CPACK_PACKAGE_INSTALL_DIRECTORY
39 75
    "${PROJECT_NAME} ${PROJECT_VERSION}")
40 76
  SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
41 77
    "${PROJECT_NAME} ${PROJECT_VERSION}")
42 78

	
43
  SET(CPACK_COMPONENTS_ALL headers library html_documentation)
79
  SET(CPACK_COMPONENTS_ALL headers library html_documentation bin)
44 80

	
45 81
  SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
46 82
  SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
83
  SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities")
47 84
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
48 85

	
49 86
  SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
50 87
    "C++ header files")
51 88
  SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
52 89
    "DLL and import library")
90
  SET(CPACK_COMPONENT_BIN_DESCRIPTION
91
    "Command line utilities")
53 92
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
54 93
    "Doxygen generated documentation")
55 94

	
56 95
  SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
57 96

	
58 97
  SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
59 98
  SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
60 99
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
61 100

	
62 101
  SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
63 102
    "Components needed to develop software using LEMON")
64 103
  SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
65 104
    "Documentation of LEMON")
66 105

	
67 106
  SET(CPACK_ALL_INSTALL_TYPES Full Developer)
68 107

	
69 108
  SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
70 109
  SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
71 110
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
72 111

	
73 112
  SET(CPACK_GENERATOR "NSIS")
74
  SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/lemon.ico")
75
  SET(CPACK_NSIS_MUI_UNIICON "${CMAKE_SOURCE_DIR}/cmake/nsis/uninstall.ico")
76
  #SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
113
  SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis/lemon.ico")
114
  SET(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/cmake/nsis/uninstall.ico")
115
  #SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
77 116
  SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
78 117
  SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
79 118
  SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
80 119
  SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lemon.cs.elte.hu")
81 120
  SET(CPACK_NSIS_CONTACT "lemon-user@lemon.cs.elte.hu")
82 121
  SET(CPACK_NSIS_CREATE_ICONS_EXTRA "
83 122
    CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\share\\\\doc\\\\index.html\\\"
84 123
    ")
85 124
  SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
86 125
    !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
87 126
    Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Documentation.lnk\\\"
88 127
    ")
89 128

	
90 129
  INCLUDE(CPack)
91
ENDIF(WIN32)
130
ENDIF()
Ignore white space 6 line context
1 1
Installation Instructions
2 2
=========================
3 3

	
4 4
Since you are reading this I assume you already obtained one of the release
5 5
tarballs and successfully extracted it. The latest version of LEMON is
6 6
available at our web page (http://lemon.cs.elte.hu/).
7 7

	
8 8
LEMON provides two different build environments, one is based on "autotool",
9 9
while the other is based on "cmake". This file contains instructions only for
10 10
the former one, which is the recommended build environment on Linux, Mac OSX
11 11
and other unices or if you use Cygwin on Windows. For cmake installation
12 12
instructions visit http://lemon.cs.elte.hu.
13 13

	
14 14
In order to install LEMON from the extracted source tarball you have to
15 15
issue the following commands:
16 16

	
17 17
   1. `cd lemon-x.y.z'
18 18

	
19 19
      This command changes to the directory which was created when you
20 20
      extracted the sources. The x.y.z part is a version number.
21 21

	
22 22
   2. `./configure'
23 23

	
24 24
      This command runs the configure shell script, which does some checks and
25 25
      creates the makefiles.
26 26

	
27 27
   3. `make'
28 28

	
29 29
      This command compiles the non-template part of LEMON into libemon.a
30
      file. It also compiles the programs in the tools and demo subdirectories
31
      when enabled.
30
      file. It also compiles the programs in the tools subdirectory by
31
      default.
32 32

	
33 33
   4. `make check'
34 34

	
35 35
      This step is optional, but recommended. It runs the test programs that
36 36
      we developed for LEMON to check whether the library works properly on
37 37
      your platform.
38 38

	
39 39
   5. `make install'
40 40

	
41 41
      This command installs LEMON under /usr/local (you will need root
42 42
      privileges to be able to do that). If you want to install it to some
43 43
      other location, then pass the --prefix=DIRECTORY flag to configure in
44 44
      step 2. For example: `./configure --prefix=/home/username/lemon'.
45 45

	
46 46
   6. `make install-html'
47 47

	
48 48
      This command installs the documentation under share/doc/lemon/docs. The
49 49
      generated documentation is included in the tarball. If you want to
50 50
      generate it yourself, then run `make html'. Note that for this you need
51 51
      to have the following programs installed: Doxygen, Graphviz, Ghostscript,
52 52
      Latex.
53 53

	
54 54

	
55 55
Configure Options and Variables
56 56
===============================
57 57

	
58 58
In step 2 you can customize the actions of configure by setting variables
59 59
and passing options to it. This can be done like this:
60 60
`./configure [OPTION]... [VARIABLE=VALUE]...'
61 61

	
62 62
Below you will find some useful variables and options (see `./configure --help'
63 63
for more):
64 64

	
65 65
CXX='comp'
66 66

	
67 67
  Change the C++ compiler to 'comp'.
68 68

	
69 69
CXXFLAGS='flags'
70 70

	
71 71
  Pass the 'flags' to the compiler. For example CXXFLAGS='-O3 -march=pentium-m'
72 72
  turns on generation of aggressively optimized Pentium-M specific code.
73 73

	
74 74
--prefix=PREFIX
75 75

	
76 76
  Set the installation prefix to PREFIX. By default it is /usr/local.
77 77

	
78
--enable-demo
79

	
80
   Build the examples in the demo subdirectory.
81

	
82
--disable-demo
83

	
84
   Do not build the examples in the demo subdirectory (default).
85

	
86 78
--enable-tools
87 79

	
88 80
   Build the programs in the tools subdirectory (default).
89 81

	
90 82
--disable-tools
91 83

	
92 84
   Do not build the programs in the tools subdirectory.
93 85

	
94 86
--with-glpk[=PREFIX]
95 87

	
96 88
   Enable GLPK support (default). You should specify the prefix too if
97 89
   you installed GLPK to some non-standard location (e.g. your home
98 90
   directory). If it is not found, GLPK support will be disabled.
99 91

	
100 92
--with-glpk-includedir=DIR
101 93

	
102 94
   The directory where the GLPK header files are located. This is only
103 95
   useful when the GLPK headers and libraries are not under the same
104 96
   prefix (which is unlikely).
105 97

	
106 98
--with-glpk-libdir=DIR
107 99

	
108 100
   The directory where the GLPK libraries are located. This is only
109 101
   useful when the GLPK headers and libraries are not under the same
110 102
   prefix (which is unlikely).
111 103

	
112 104
--without-glpk
113 105

	
114 106
   Disable GLPK support.
115 107

	
116 108
--with-cplex[=PREFIX]
117 109

	
118 110
   Enable CPLEX support (default). You should specify the prefix too
119 111
   if you installed CPLEX to some non-standard location
120 112
   (e.g. /opt/ilog/cplex75). If it is not found, CPLEX support will be
121 113
   disabled.
122 114

	
123 115
--with-cplex-includedir=DIR
124 116

	
125 117
   The directory where the CPLEX header files are located. This is
126 118
   only useful when the CPLEX headers and libraries are not under the
127 119
   same prefix (e.g.  /usr/local/cplex/cplex75/include).
128 120

	
129 121
--with-cplex-libdir=DIR
130 122

	
131 123
   The directory where the CPLEX libraries are located. This is only
132 124
   useful when the CPLEX headers and libraries are not under the same
133 125
   prefix (e.g.
134 126
   /usr/local/cplex/cplex75/lib/i86_linux2_glibc2.2_gcc3.0/static_pic_mt).
135 127

	
136 128
--without-cplex
137 129

	
138 130
   Disable CPLEX support.
139 131

	
140 132
--with-soplex[=PREFIX]
141 133

	
142 134
   Enable SoPlex support (default). You should specify the prefix too if
143 135
   you installed SoPlex to some non-standard location (e.g. your home
144 136
   directory). If it is not found, SoPlex support will be disabled.
145 137

	
146 138
--with-soplex-includedir=DIR
147 139

	
148 140
   The directory where the SoPlex header files are located. This is only
149 141
   useful when the SoPlex headers and libraries are not under the same
150 142
   prefix (which is unlikely).
151 143

	
152 144
--with-soplex-libdir=DIR
153 145

	
154 146
   The directory where the SoPlex libraries are located. This is only
155 147
   useful when the SoPlex headers and libraries are not under the same
156 148
   prefix (which is unlikely).
157 149

	
158 150
--without-soplex
159 151

	
160 152
   Disable SoPlex support.
153

	
154
--with-coin[=PREFIX]
155

	
156
   Enable support for COIN-OR solvers (CLP and CBC). You should
157
   specify the prefix too. (by default, COIN-OR tools install
158
   themselves to the source code directory). This command enables the
159
   solvers that are actually found.
160

	
161
--with-coin-includedir=DIR
162

	
163
   The directory where the COIN-OR header files are located. This is
164
   only useful when the COIN-OR headers and libraries are not under
165
   the same prefix (which is unlikely).
166

	
167
--with-coin-libdir=DIR
168

	
169
   The directory where the COIN-OR libraries are located. This is only
170
   useful when the COIN-OR headers and libraries are not under the
171
   same prefix (which is unlikely).
172

	
173
--without-coin
174

	
175
   Disable COIN-OR support.
Ignore white space 6 line context
1 1
LEMON code without an explicit copyright notice is covered by the following
2 2
copyright/license.
3 3

	
4
Copyright (C) 2003-2008 Egervary Jeno Kombinatorikus Optimalizalasi
4
Copyright (C) 2003-2009 Egervary Jeno Kombinatorikus Optimalizalasi
5 5
Kutatocsoport (Egervary Combinatorial Optimization Research Group,
6 6
EGRES).
7 7

	
8 8
===========================================================================
9 9
Boost Software License, Version 1.0
10 10
===========================================================================
11 11

	
12 12
Permission is hereby granted, free of charge, to any person or organization
13 13
obtaining a copy of the software and accompanying documentation covered by
14 14
this license (the "Software") to use, reproduce, display, distribute,
15 15
execute, and transmit the Software, and to prepare derivative works of the
16 16
Software, and to permit third-parties to whom the Software is furnished to
17 17
do so, all subject to the following:
18 18

	
19 19
The copyright notices in the Software and this entire statement, including
20 20
the above license grant, this restriction and the following disclaimer,
21 21
must be included in all copies of the Software, in whole or in part, and
22 22
all derivative works of the Software, unless such copies or derivative
23 23
works are solely in the form of machine-executable object code generated by
24 24
a source language processor.
25 25

	
26 26
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 27
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 28
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29 29
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30 30
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31 31
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32 32
DEALINGS IN THE SOFTWARE.
Ignore white space 6 line context
1 1
ACLOCAL_AMFLAGS = -I m4
2 2

	
3
AM_CXXFLAGS = $(WARNINGCXXFLAGS)
4

	
3 5
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
4 6
LDADD = $(top_builddir)/lemon/libemon.la
5 7

	
6 8
EXTRA_DIST = \
7 9
	AUTHORS \
8 10
	LICENSE \
9 11
	m4/lx_check_cplex.m4 \
10 12
	m4/lx_check_glpk.m4 \
11 13
	m4/lx_check_soplex.m4 \
14
	m4/lx_check_coin.m4 \
12 15
	CMakeLists.txt \
13 16
	cmake/FindGhostscript.cmake \
17
	cmake/FindCPLEX.cmake \
18
	cmake/FindGLPK.cmake \
19
	cmake/FindCOIN.cmake \
14 20
	cmake/version.cmake.in \
15 21
	cmake/version.cmake \
16 22
	cmake/nsis/lemon.ico \
17 23
	cmake/nsis/uninstall.ico
18 24

	
19 25
pkgconfigdir = $(libdir)/pkgconfig
20 26
lemondir = $(pkgincludedir)
21 27
bitsdir = $(lemondir)/bits
22 28
conceptdir = $(lemondir)/concepts
23 29
pkgconfig_DATA =
24 30
lib_LTLIBRARIES =
25 31
lemon_HEADERS =
26 32
bits_HEADERS =
27 33
concept_HEADERS =
28 34
noinst_HEADERS =
29 35
noinst_PROGRAMS =
30 36
bin_PROGRAMS =
31 37
check_PROGRAMS =
32 38
dist_bin_SCRIPTS =
33 39
TESTS =
34 40
XFAIL_TESTS =
35 41

	
36 42
include lemon/Makefile.am
37 43
include test/Makefile.am
38 44
include doc/Makefile.am
39
include demo/Makefile.am
40 45
include tools/Makefile.am
41 46

	
47
DIST_SUBDIRS = demo
48

	
49
demo:
50
	$(MAKE) $(AM_MAKEFLAGS) -C demo
51

	
42 52
MRPROPERFILES = \
43 53
	aclocal.m4 \
44 54
	config.h.in \
45 55
	config.h.in~ \
46 56
	configure \
47 57
	Makefile.in \
48 58
	build-aux/config.guess \
49 59
	build-aux/config.sub \
50 60
	build-aux/depcomp \
51 61
	build-aux/install-sh \
52 62
	build-aux/ltmain.sh \
53 63
	build-aux/missing \
54 64
	doc/doxygen.log
55 65

	
56 66
mrproper:
57 67
	$(MAKE) $(AM_MAKEFLAGS) maintainer-clean
58 68
	-rm -f $(MRPROPERFILES)
59 69

	
60 70
dist-bz2: dist
61 71
	zcat $(PACKAGE)-$(VERSION).tar.gz | \
62 72
	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
63 73

	
64 74
distcheck-bz2: distcheck
65 75
	zcat $(PACKAGE)-$(VERSION).tar.gz | \
66 76
	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
67 77

	
68
.PHONY: mrproper dist-bz2 distcheck-bz2
78
.PHONY: demo mrproper dist-bz2 distcheck-bz2
Ignore white space 6 line context
1
2009-05-13 Version 1.1 released
2

	
3
        This is the second stable release of the 1.x series. It
4
        features a better coverage of the tools available in the 0.x
5
        series, a thoroughly reworked LP/MIP interface plus various
6
        improvements in the existing tools.
7

	
8
        * Much improved M$ Windows support
9
          * Various improvements in the CMAKE build system
10
          * Compilation warnings are fixed/suppressed
11
        * Support IBM xlC compiler
12
        * New algorithms
13
          * Connectivity related algorithms (#61)
14
          * Euler walks (#65)
15
          * Preflow push-relabel max. flow algorithm (#176)
16
          * Circulation algorithm (push-relabel based) (#175)
17
          * Suurballe algorithm (#47)
18
          * Gomory-Hu algorithm (#66)
19
          * Hao-Orlin algorithm (#58)
20
          * Edmond's maximum cardinality and weighted matching algorithms
21
            in general graphs (#48,#265)
22
          * Minimum cost arborescence/branching (#60)
23
          * Network Simplex min. cost flow algorithm (#234)
24
        * New data structures
25
          * Full graph structure (#57)
26
          * Grid graph structure (#57)
27
          * Hypercube graph structure (#57)
28
          * Graph adaptors (#67)
29
          * ArcSet and EdgeSet classes (#67)
30
          * Elevator class (#174)
31
        * Other new tools
32
          * LP/MIP interface (#44)
33
            * Support for GLPK, CPLEX, Soplex, COIN-OR CLP and CBC
34
          * Reader for the Nauty file format (#55)
35
          * DIMACS readers (#167)
36
          * Radix sort algorithms (#72)
37
          * RangeIdMap and CrossRefMap (#160)
38
        * New command line tools
39
          * DIMACS to LGF converter (#182)
40
          * lgf-gen - a graph generator (#45)
41
          * DIMACS solver utility (#226)
42
        * Other code improvements
43
          * Lognormal distribution added to Random (#102)
44
          * Better (i.e. O(1) time) item counting in SmartGraph (#3)
45
          * The standard maps of graphs are guaranteed to be
46
            reference maps (#190)
47
        * Miscellaneous
48
          * Various doc improvements
49
          * Improved 0.x -> 1.x converter script
50

	
51
        * Several bugfixes (compared to release 1.0):
52
          #170: Bugfix SmartDigraph::split()
53
          #171: Bugfix in SmartGraph::restoreSnapshot()
54
          #172: Extended test cases for graphs and digraphs
55
          #173: Bugfix in Random
56
                * operator()s always return a double now
57
                * the faulty real<Num>(Num) and real<Num>(Num,Num)
58
                  have been removed
59
          #187: Remove DijkstraWidestPathOperationTraits
60
          #61:  Bugfix in DfsVisit
61
          #193: Bugfix in GraphReader::skipSection()
62
          #195: Bugfix in ConEdgeIt()
63
          #197: Bugfix in heap unionfind
64
                * This bug affects Edmond's general matching algorithms
65
          #207: Fix 'make install' without 'make html' using CMAKE
66
          #208: Suppress or fix VS2008 compilation warnings
67
          ----: Update the LEMON icon
68
          ----: Enable the component-based installer
69
                (in installers made by CPACK)
70
          ----: Set the proper version for CMAKE in the tarballs
71
                (made by autotools)
72
          ----: Minor clarification in the LICENSE file
73
          ----: Add missing unistd.h include to time_measure.h
74
          #204: Compilation bug fixed in graph_to_eps.h with VS2005
75
          #214,#215: windows.h should never be included by lemon headers
76
          #230: Build systems check the availability of 'long long' type
77
          #229: Default implementation of Tolerance<> is used for integer types
78
          #211,#212: Various fixes for compiling on AIX
79
          ----: Improvements in CMAKE config
80
                - docs is installed in share/doc/
81
                - detects newer versions of Ghostscript
82
          #239: Fix missing 'inline' specifier in time_measure.h
83
          #274,#280: Install lemon/config.h
84
          #275: Prefix macro names with LEMON_ in lemon/config.h
85
          ----: Small script for making the release tarballs added
86
          ----: Minor improvement in unify-sources.sh (a76f55d7d397)
87

	
1 88
2009-03-27 LEMON joins to the COIN-OR initiative
2 89

	
3 90
        COIN-OR (Computational Infrastructure for Operations Research,
4 91
        http://www.coin-or.org) project is an initiative to spur the
5 92
        development of open-source software for the operations research
6 93
        community.
7 94

	
8 95
2008-10-13 Version 1.0 released
9 96

	
10 97
	This is the first stable release of LEMON. Compared to the 0.x
11 98
	release series, it features a considerably smaller but more
12 99
	matured set of tools. The API has also completely revised and
13 100
	changed in several places.
14 101

	
15 102
	* The major name changes compared to the 0.x series (see the
16 103
          Migration Guide in the doc for more details)
17 104
          * Graph -> Digraph, UGraph -> Graph
18 105
          * Edge -> Arc, UEdge -> Edge
19 106
	  * source(UEdge)/target(UEdge) -> u(Edge)/v(Edge)
20 107
	* Other improvements
21 108
	  * Better documentation
22 109
	  * Reviewed and cleaned up codebase
23 110
	  * CMake based build system (along with the autotools based one)
24 111
	* Contents of the library (ported from 0.x)
25 112
	  * Algorithms
26 113
       	    * breadth-first search (bfs.h)
27 114
       	    * depth-first search (dfs.h)
28 115
       	    * Dijkstra's algorithm (dijkstra.h)
29 116
       	    * Kruskal's algorithm (kruskal.h)
30 117
    	  * Data structures
31 118
       	    * graph data structures (list_graph.h, smart_graph.h)
32 119
       	    * path data structures (path.h)
33 120
       	    * binary heap data structure (bin_heap.h)
34 121
       	    * union-find data structures (unionfind.h)
35 122
       	    * miscellaneous property maps (maps.h)
36 123
       	    * two dimensional vector and bounding box (dim2.h)
37 124
          * Concepts
38 125
       	    * graph structure concepts (concepts/digraph.h, concepts/graph.h,
39 126
              concepts/graph_components.h)
40 127
       	    * concepts for other structures (concepts/heap.h, concepts/maps.h,
41 128
	      concepts/path.h)
42 129
    	  * Tools
43 130
       	    * Mersenne twister random number generator (random.h)
44 131
       	    * tools for measuring cpu and wall clock time (time_measure.h)
45 132
       	    * tools for counting steps and events (counter.h)
46 133
       	    * tool for parsing command line arguments (arg_parser.h)
47 134
       	    * tool for visualizing graphs (graph_to_eps.h)
48 135
       	    * tools for reading and writing data in LEMON Graph Format
49 136
              (lgf_reader.h, lgf_writer.h)
50 137
            * tools to handle the anomalies of calculations with
51 138
	      floating point numbers (tolerance.h)
52 139
            * tools to manage RGB colors (color.h)
53 140
    	  * Infrastructure
54 141
       	    * extended assertion handling (assert.h)
55 142
       	    * exception classes and error handling (error.h)
56 143
      	    * concept checking (concept_check.h)
57 144
       	    * commonly used mathematical constants (math.h)
Ignore white space 6 line context
1
==================================================================
2
LEMON - a Library of Efficient Models and Optimization in Networks
3
==================================================================
1
=====================================================================
2
LEMON - a Library for Efficient Modeling and Optimization in Networks
3
=====================================================================
4 4

	
5 5
LEMON is an open source library written in C++. It provides
6 6
easy-to-use implementations of common data structures and algorithms
7 7
in the area of optimization and helps implementing new ones. The main
8 8
focus is on graphs and graph algorithms, thus it is especially
9 9
suitable for solving design and optimization problems of
10 10
telecommunication networks. To achieve wide usability its data
11 11
structures and algorithms provide generic interfaces.
12 12

	
13 13
Contents
14 14
========
15 15

	
16 16
LICENSE
17 17

	
18 18
   Copying, distribution and modification conditions and terms.
19 19

	
20 20
INSTALL
21 21

	
22 22
   General building and installation instructions.
23 23

	
24 24
lemon/
25 25

	
26 26
   Source code of LEMON library.
27 27

	
28 28
doc/
29 29

	
30 30
   Documentation of LEMON. The starting page is doc/html/index.html.
31 31

	
32 32
demo/
33 33

	
34 34
   Some example programs to make you easier to get familiar with LEMON.
35 35

	
36 36
test/
37 37

	
38 38
   Programs to check the integrity and correctness of LEMON.
39 39

	
40 40
tools/
41 41

	
42 42
   Various utilities related to LEMON.
Ignore white space 6 line context
1
SET(PROJECT_NAME "@PACKAGE_NAME@")
2
SET(PROJECT_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
1
SET(LEMON_VERSION "@PACKAGE_VERSION@" CACHE STRING "LEMON version string.")
Ignore white space 6 line context
1 1
dnl Process this file with autoconf to produce a configure script.
2 2

	
3 3
dnl Version information.
4 4
m4_define([lemon_version_number],
5
	[m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
5
          [m4_normalize(esyscmd([echo ${LEMON_VERSION}]))])
6 6
dnl m4_define([lemon_version_number], [])
7 7
m4_define([lemon_hg_path], [m4_normalize(esyscmd([./scripts/chg-len.py]))])
8
m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i]))])
8
m4_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i 2> /dev/null]))])
9 9
m4_define([lemon_version], [ifelse(lemon_version_number(),
10
			   [],
11
			   [lemon_hg_path().lemon_hg_revision()],
12
			   [lemon_version_number()])])
10
                           [],
11
                           [ifelse(lemon_hg_revision(),
12
                           [],
13
                           [hg-tip],
14
                           [lemon_hg_path().lemon_hg_revision()])],
15
                           [lemon_version_number()])])
13 16

	
14 17
AC_PREREQ([2.59])
15 18
AC_INIT([LEMON], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
16 19
AC_CONFIG_AUX_DIR([build-aux])
17 20
AC_CONFIG_MACRO_DIR([m4])
18 21
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects nostdinc])
19 22
AC_CONFIG_SRCDIR([lemon/list_graph.h])
20 23
AC_CONFIG_HEADERS([config.h lemon/config.h])
21 24

	
22
lx_cmdline_cxxflags_set=${CXXFLAGS+set}
25
AC_DEFINE([LEMON_VERSION], [lemon_version()], [The version string])
23 26

	
24 27
dnl Do compilation tests using the C++ compiler.
25 28
AC_LANG([C++])
26 29

	
27 30
dnl Check the existence of long long type.
28 31
AC_CHECK_TYPE(long long, [long_long_found=yes], [long_long_found=no])
29 32
if test x"$long_long_found" = x"yes"; then
30 33
  AC_DEFINE([LEMON_HAVE_LONG_LONG], [1], [Define to 1 if you have long long.])
31 34
fi
32 35

	
33 36
dnl Checks for programs.
34 37
AC_PROG_CXX
35 38
AC_PROG_CXXCPP
36 39
AC_PROG_INSTALL
37 40
AC_DISABLE_SHARED
38 41
AC_PROG_LIBTOOL
39 42

	
40 43
AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
41 44
AC_CHECK_PROG([gs_found],[gs],[yes],[no])
42 45

	
43 46
dnl Detect Intel compiler.
44 47
AC_MSG_CHECKING([whether we are using the Intel C++ compiler])
45 48
AC_COMPILE_IFELSE([#ifndef __INTEL_COMPILER
46 49
choke me
47 50
#endif], [ICC=[yes]], [ICC=[no]])
48 51
if test x"$ICC" = x"yes"; then
49 52
  AC_MSG_RESULT([yes])
50 53
else
51 54
  AC_MSG_RESULT([no])
52 55
fi
53 56

	
54 57
dnl Set custom compiler flags when using g++.
55
if test x"$lx_cmdline_cxxflags_set" != x"set" -a "$GXX" = yes -a "$ICC" = no; then
56
  CXXFLAGS="$CXXFLAGS -Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
58
if test "$GXX" = yes -a "$ICC" = no; then
59
  WARNINGCXXFLAGS="-Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
57 60
fi
61
AC_SUBST([WARNINGCXXFLAGS])
58 62

	
59 63
dnl Checks for libraries.
60
#LX_CHECK_GLPK
61
#LX_CHECK_CPLEX
62
#LX_CHECK_SOPLEX
64
LX_CHECK_GLPK
65
LX_CHECK_CPLEX
66
LX_CHECK_SOPLEX
67
LX_CHECK_COIN
63 68

	
64
dnl Disable/enable building the demo programs.
65
AC_ARG_ENABLE([demo],
66
AS_HELP_STRING([--enable-demo], [build the demo programs])
67
AS_HELP_STRING([--disable-demo], [do not build the demo programs @<:@default@:>@]),
68
              [], [enable_demo=no])
69
AC_MSG_CHECKING([whether to build the demo programs])
70
if test x"$enable_demo" != x"no"; then
71
  AC_MSG_RESULT([yes])
72
else
73
  AC_MSG_RESULT([no])
74
fi
75
AM_CONDITIONAL([WANT_DEMO], [test x"$enable_demo" != x"no"])
69
AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"])
70
AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"])
76 71

	
77 72
dnl Disable/enable building the binary tools.
78 73
AC_ARG_ENABLE([tools],
79 74
AS_HELP_STRING([--enable-tools], [build additional tools @<:@default@:>@])
80 75
AS_HELP_STRING([--disable-tools], [do not build additional tools]),
81 76
              [], [enable_tools=yes])
82 77
AC_MSG_CHECKING([whether to build the additional tools])
83 78
if test x"$enable_tools" != x"no"; then
84 79
  AC_MSG_RESULT([yes])
85 80
else
86 81
  AC_MSG_RESULT([no])
87 82
fi
88 83
AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
89 84

	
90 85
dnl Checks for header files.
91 86
AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
92 87

	
93 88
dnl Checks for typedefs, structures, and compiler characteristics.
94 89
AC_C_CONST
95 90
AC_C_INLINE
96 91
AC_TYPE_SIZE_T
97 92
AC_HEADER_TIME
98 93
AC_STRUCT_TM
99 94

	
100 95
dnl Checks for library functions.
101 96
AC_HEADER_STDC
102 97
AC_CHECK_FUNCS(gettimeofday times ctime_r)
103 98

	
104 99
dnl Add dependencies on files generated by configure.
105 100
AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
106 101
  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
107 102

	
108 103
AC_CONFIG_FILES([
109 104
Makefile
105
demo/Makefile
110 106
cmake/version.cmake
111 107
doc/Doxyfile
112 108
lemon/lemon.pc
113 109
])
114 110

	
115 111
AC_OUTPUT
116 112

	
117 113
echo
118 114
echo '****************************** SUMMARY ******************************'
119 115
echo
120 116
echo Package version............... : $PACKAGE-$VERSION
121 117
echo
122 118
echo C++ compiler.................. : $CXX
123
echo C++ compiles flags............ : $CXXFLAGS
119
echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS
124 120
echo
125 121
echo Compiler supports long long... : $long_long_found
126 122
echo
127
#echo GLPK support.................. : $lx_glpk_found
128
#echo CPLEX support................. : $lx_cplex_found
129
#echo SOPLEX support................ : $lx_soplex_found
130
#echo
131
echo Build demo programs........... : $enable_demo
123
echo GLPK support.................. : $lx_glpk_found
124
echo CPLEX support................. : $lx_cplex_found
125
echo SOPLEX support................ : $lx_soplex_found
126
echo CLP support................... : $lx_clp_found
127
echo CBC support................... : $lx_cbc_found
128
echo
132 129
echo Build additional tools........ : $enable_tools
133 130
echo
134 131
echo The packace will be installed in
135 132
echo -n '  '
136 133
echo $prefix.
137 134
echo
138 135
echo '*********************************************************************'
139 136

	
140 137
echo
141 138
echo Configure complete, now type \'make\' and then \'make install\'.
142 139
echo
Ignore white space 6 line context
1 1
INCLUDE_DIRECTORIES(
2
  ${CMAKE_SOURCE_DIR}
2
  ${PROJECT_SOURCE_DIR}
3 3
  ${PROJECT_BINARY_DIR}
4 4
)
5 5

	
6
LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
6
LINK_DIRECTORIES(
7
  ${PROJECT_BINARY_DIR}/lemon
8
)
7 9

	
8 10
SET(DEMOS
9 11
  arg_parser_demo
10 12
  graph_to_eps_demo
11
  lgf_demo)
13
  lgf_demo
14
)
12 15

	
13 16
FOREACH(DEMO_NAME ${DEMOS})
14 17
  ADD_EXECUTABLE(${DEMO_NAME} ${DEMO_NAME}.cc)
15 18
  TARGET_LINK_LIBRARIES(${DEMO_NAME} lemon)
16
ENDFOREACH(DEMO_NAME)
19
ENDFOREACH()
Ignore white space 6 line context
1
EXTRA_DIST += \
2
	demo/CMakeLists.txt \
3
	demo/digraph.lgf
1
AM_CXXFLAGS = $(WARNINGCXXFLAGS)
4 2

	
5
if WANT_DEMO
3
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
4
LDADD = $(top_builddir)/lemon/libemon.la
6 5

	
7
noinst_PROGRAMS += \
8
	demo/arg_parser_demo \
9
	demo/graph_to_eps_demo \
10
	demo/lgf_demo
6
EXTRA_DIST = \
7
	CMakeLists.txt \
8
	digraph.lgf
11 9

	
12
endif WANT_DEMO
10
noinst_PROGRAMS = \
11
	arg_parser_demo \
12
	graph_to_eps_demo \
13
	lgf_demo
13 14

	
14
demo_arg_parser_demo_SOURCES = demo/arg_parser_demo.cc
15
demo_graph_to_eps_demo_SOURCES = demo/graph_to_eps_demo.cc
16
demo_lgf_demo_SOURCES = demo/lgf_demo.cc
15
arg_parser_demo_SOURCES = arg_parser_demo.cc
16
graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc
17
lgf_demo_SOURCES = lgf_demo.cc
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
///\ingroup demos
20 20
///\file
21 21
///\brief Argument parser demo
22 22
///
23 23
/// This example shows how the argument parser can be used.
24 24
///
25 25
/// \include arg_parser_demo.cc
26 26

	
27 27
#include <lemon/arg_parser.h>
28 28

	
29 29
using namespace lemon;
30 30
int main(int argc, char **argv)
31 31
{
32 32
  // Initialize the argument parser
33 33
  ArgParser ap(argc, argv);
34 34
  int i;
35 35
  std::string s;
36 36
  double d = 1.0;
37 37
  bool b, nh;
38 38
  bool g1, g2, g3;
39 39

	
40 40
  // Add a mandatory integer option with storage reference
41 41
  ap.refOption("n", "An integer input.", i, true);
42 42
  // Add a double option with storage reference (the default value is 1.0)
43 43
  ap.refOption("val", "A double input.", d);
44 44
  // Add a double option without storage reference (the default value is 3.14)
45 45
  ap.doubleOption("val2", "A double input.", 3.14);
46 46
  // Set synonym for -val option
47 47
  ap.synonym("vals", "val");
48 48
  // Add a string option
49 49
  ap.refOption("name", "A string input.", s);
50 50
  // Add bool options
51 51
  ap.refOption("f", "A switch.", b)
52 52
    .refOption("nohelp", "", nh)
53 53
    .refOption("gra", "Choice A", g1)
54 54
    .refOption("grb", "Choice B", g2)
55 55
    .refOption("grc", "Choice C", g3);
56 56
  // Bundle -gr* options into a group
57 57
  ap.optionGroup("gr", "gra")
58 58
    .optionGroup("gr", "grb")
59 59
    .optionGroup("gr", "grc");
60 60
  // Set the group mandatory
61 61
  ap.mandatoryGroup("gr");
62 62
  // Set the options of the group exclusive (only one option can be given)
63 63
  ap.onlyOneGroup("gr");
64 64
  // Add non-parsed arguments (e.g. input files)
65 65
  ap.other("infile", "The input file.")
66 66
    .other("...");
67 67

	
68 68
  // Perform the parsing process
69 69
  // (in case of any error it terminates the program)
70 70
  ap.parse();
71 71

	
72 72
  // Check each option if it has been given and print its value
73 73
  std::cout << "Parameters of '" << ap.commandName() << "':\n";
74 74

	
75 75
  std::cout << "  Value of -n: " << i << std::endl;
76 76
  if(ap.given("val")) std::cout << "  Value of -val: " << d << std::endl;
77 77
  if(ap.given("val2")) {
78 78
    d = ap["val2"];
79 79
    std::cout << "  Value of -val2: " << d << std::endl;
80 80
  }
81 81
  if(ap.given("name")) std::cout << "  Value of -name: " << s << std::endl;
82 82
  if(ap.given("f")) std::cout << "  -f is given\n";
83 83
  if(ap.given("nohelp")) std::cout << "  Value of -nohelp: " << nh << std::endl;
84 84
  if(ap.given("gra")) std::cout << "  -gra is given\n";
85 85
  if(ap.given("grb")) std::cout << "  -grb is given\n";
86 86
  if(ap.given("grc")) std::cout << "  -grc is given\n";
87 87

	
88 88
  switch(ap.files().size()) {
89 89
  case 0:
90 90
    std::cout << "  No file argument was given.\n";
91 91
    break;
92 92
  case 1:
93 93
    std::cout << "  1 file argument was given. It is:\n";
94 94
    break;
95 95
  default:
96 96
    std::cout << "  "
97 97
              << ap.files().size() << " file arguments were given. They are:\n";
98 98
  }
99 99
  for(unsigned int i=0;i<ap.files().size();++i)
100 100
    std::cout << "    '" << ap.files()[i] << "'\n";
101 101

	
102 102
  return 0;
103 103
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
/// \ingroup demos
20 20
/// \file
21 21
/// \brief Demo of the graph drawing function \ref graphToEps()
22 22
///
23 23
/// This demo program shows examples how to use the function \ref
24 24
/// graphToEps(). It takes no input but simply creates seven
25 25
/// <tt>.eps</tt> files demonstrating the capability of \ref
26 26
/// graphToEps(), and showing how to draw directed graphs,
27 27
/// how to handle parallel egdes, how to change the properties (like
28 28
/// color, shape, size, title etc.) of nodes and arcs individually
29 29
/// using appropriate graph maps.
30 30
///
31 31
/// \include graph_to_eps_demo.cc
32 32

	
33 33
#include<lemon/list_graph.h>
34 34
#include<lemon/graph_to_eps.h>
35 35
#include<lemon/math.h>
36 36

	
37 37
using namespace std;
38 38
using namespace lemon;
39 39

	
40 40
int main()
41 41
{
42 42
  Palette palette;
43 43
  Palette paletteW(true);
44 44

	
45 45
  // Create a small digraph
46 46
  ListDigraph g;
47 47
  typedef ListDigraph::Node Node;
48 48
  typedef ListDigraph::NodeIt NodeIt;
49 49
  typedef ListDigraph::Arc Arc;
50 50
  typedef dim2::Point<int> Point;
51 51

	
52 52
  Node n1=g.addNode();
53 53
  Node n2=g.addNode();
54 54
  Node n3=g.addNode();
55 55
  Node n4=g.addNode();
56 56
  Node n5=g.addNode();
57 57

	
58 58
  ListDigraph::NodeMap<Point> coords(g);
59 59
  ListDigraph::NodeMap<double> sizes(g);
60 60
  ListDigraph::NodeMap<int> colors(g);
61 61
  ListDigraph::NodeMap<int> shapes(g);
62 62
  ListDigraph::ArcMap<int> acolors(g);
63 63
  ListDigraph::ArcMap<int> widths(g);
64 64

	
65 65
  coords[n1]=Point(50,50);  sizes[n1]=1; colors[n1]=1; shapes[n1]=0;
66 66
  coords[n2]=Point(50,70);  sizes[n2]=2; colors[n2]=2; shapes[n2]=2;
67 67
  coords[n3]=Point(70,70);  sizes[n3]=1; colors[n3]=3; shapes[n3]=0;
68 68
  coords[n4]=Point(70,50);  sizes[n4]=2; colors[n4]=4; shapes[n4]=1;
69 69
  coords[n5]=Point(85,60);  sizes[n5]=3; colors[n5]=5; shapes[n5]=2;
70 70

	
71 71
  Arc a;
72 72

	
73 73
  a=g.addArc(n1,n2); acolors[a]=0; widths[a]=1;
74 74
  a=g.addArc(n2,n3); acolors[a]=0; widths[a]=1;
75 75
  a=g.addArc(n3,n5); acolors[a]=0; widths[a]=3;
76 76
  a=g.addArc(n5,n4); acolors[a]=0; widths[a]=1;
77 77
  a=g.addArc(n4,n1); acolors[a]=0; widths[a]=1;
78 78
  a=g.addArc(n2,n4); acolors[a]=1; widths[a]=2;
79 79
  a=g.addArc(n3,n4); acolors[a]=2; widths[a]=1;
80 80

	
81 81
  IdMap<ListDigraph,Node> id(g);
82 82

	
83 83
  // Create .eps files showing the digraph with different options
84 84
  cout << "Create 'graph_to_eps_demo_out_1_pure.eps'" << endl;
85 85
  graphToEps(g,"graph_to_eps_demo_out_1_pure.eps").
86 86
    coords(coords).
87 87
    title("Sample .eps figure").
88
    copyright("(C) 2003-2008 LEMON Project").
88
    copyright("(C) 2003-2009 LEMON Project").
89 89
    run();
90 90

	
91 91
  cout << "Create 'graph_to_eps_demo_out_2.eps'" << endl;
92 92
  graphToEps(g,"graph_to_eps_demo_out_2.eps").
93 93
    coords(coords).
94 94
    title("Sample .eps figure").
95
    copyright("(C) 2003-2008 LEMON Project").
95
    copyright("(C) 2003-2009 LEMON Project").
96 96
    absoluteNodeSizes().absoluteArcWidths().
97 97
    nodeScale(2).nodeSizes(sizes).
98 98
    nodeShapes(shapes).
99 99
    nodeColors(composeMap(palette,colors)).
100 100
    arcColors(composeMap(palette,acolors)).
101 101
    arcWidthScale(.4).arcWidths(widths).
102 102
    nodeTexts(id).nodeTextSize(3).
103 103
    run();
104 104

	
105 105
  cout << "Create 'graph_to_eps_demo_out_3_arr.eps'" << endl;
106 106
  graphToEps(g,"graph_to_eps_demo_out_3_arr.eps").
107 107
    title("Sample .eps figure (with arrowheads)").
108
    copyright("(C) 2003-2008 LEMON Project").
108
    copyright("(C) 2003-2009 LEMON Project").
109 109
    absoluteNodeSizes().absoluteArcWidths().
110 110
    nodeColors(composeMap(palette,colors)).
111 111
    coords(coords).
112 112
    nodeScale(2).nodeSizes(sizes).
113 113
    nodeShapes(shapes).
114 114
    arcColors(composeMap(palette,acolors)).
115 115
    arcWidthScale(.4).arcWidths(widths).
116 116
    nodeTexts(id).nodeTextSize(3).
117 117
    drawArrows().arrowWidth(2).arrowLength(2).
118 118
    run();
119 119

	
120 120
  // Add more arcs to the digraph
121 121
  a=g.addArc(n1,n4); acolors[a]=2; widths[a]=1;
122 122
  a=g.addArc(n4,n1); acolors[a]=1; widths[a]=2;
123 123

	
124 124
  a=g.addArc(n1,n2); acolors[a]=1; widths[a]=1;
125 125
  a=g.addArc(n1,n2); acolors[a]=2; widths[a]=1;
126 126
  a=g.addArc(n1,n2); acolors[a]=3; widths[a]=1;
127 127
  a=g.addArc(n1,n2); acolors[a]=4; widths[a]=1;
128 128
  a=g.addArc(n1,n2); acolors[a]=5; widths[a]=1;
129 129
  a=g.addArc(n1,n2); acolors[a]=6; widths[a]=1;
130 130
  a=g.addArc(n1,n2); acolors[a]=7; widths[a]=1;
131 131

	
132 132
  cout << "Create 'graph_to_eps_demo_out_4_par.eps'" << endl;
133 133
  graphToEps(g,"graph_to_eps_demo_out_4_par.eps").
134 134
    title("Sample .eps figure (parallel arcs)").
135
    copyright("(C) 2003-2008 LEMON Project").
135
    copyright("(C) 2003-2009 LEMON Project").
136 136
    absoluteNodeSizes().absoluteArcWidths().
137 137
    nodeShapes(shapes).
138 138
    coords(coords).
139 139
    nodeScale(2).nodeSizes(sizes).
140 140
    nodeColors(composeMap(palette,colors)).
141 141
    arcColors(composeMap(palette,acolors)).
142 142
    arcWidthScale(.4).arcWidths(widths).
143 143
    nodeTexts(id).nodeTextSize(3).
144 144
    enableParallel().parArcDist(1.5).
145 145
    run();
146 146

	
147 147
  cout << "Create 'graph_to_eps_demo_out_5_par_arr.eps'" << endl;
148 148
  graphToEps(g,"graph_to_eps_demo_out_5_par_arr.eps").
149 149
    title("Sample .eps figure (parallel arcs and arrowheads)").
150
    copyright("(C) 2003-2008 LEMON Project").
150
    copyright("(C) 2003-2009 LEMON Project").
151 151
    absoluteNodeSizes().absoluteArcWidths().
152 152
    nodeScale(2).nodeSizes(sizes).
153 153
    coords(coords).
154 154
    nodeShapes(shapes).
155 155
    nodeColors(composeMap(palette,colors)).
156 156
    arcColors(composeMap(palette,acolors)).
157 157
    arcWidthScale(.3).arcWidths(widths).
158 158
    nodeTexts(id).nodeTextSize(3).
159 159
    enableParallel().parArcDist(1).
160 160
    drawArrows().arrowWidth(1).arrowLength(1).
161 161
    run();
162 162

	
163 163
  cout << "Create 'graph_to_eps_demo_out_6_par_arr_a4.eps'" << endl;
164 164
  graphToEps(g,"graph_to_eps_demo_out_6_par_arr_a4.eps").
165 165
    title("Sample .eps figure (fits to A4)").
166
    copyright("(C) 2003-2008 LEMON Project").
166
    copyright("(C) 2003-2009 LEMON Project").
167 167
    scaleToA4().
168 168
    absoluteNodeSizes().absoluteArcWidths().
169 169
    nodeScale(2).nodeSizes(sizes).
170 170
    coords(coords).
171 171
    nodeShapes(shapes).
172 172
    nodeColors(composeMap(palette,colors)).
173 173
    arcColors(composeMap(palette,acolors)).
174 174
    arcWidthScale(.3).arcWidths(widths).
175 175
    nodeTexts(id).nodeTextSize(3).
176 176
    enableParallel().parArcDist(1).
177 177
    drawArrows().arrowWidth(1).arrowLength(1).
178 178
    run();
179 179

	
180 180
  // Create an .eps file showing the colors of a default Palette
181 181
  ListDigraph h;
182 182
  ListDigraph::NodeMap<int> hcolors(h);
183 183
  ListDigraph::NodeMap<Point> hcoords(h);
184 184

	
185
  int cols=int(sqrt(double(palette.size())));
185
  int cols=int(std::sqrt(double(palette.size())));
186 186
  for(int i=0;i<int(paletteW.size());i++) {
187 187
    Node n=h.addNode();
188 188
    hcoords[n]=Point(1+i%cols,1+i/cols);
189 189
    hcolors[n]=i;
190 190
  }
191 191

	
192 192
  cout << "Create 'graph_to_eps_demo_out_7_colors.eps'" << endl;
193 193
  graphToEps(h,"graph_to_eps_demo_out_7_colors.eps").
194 194
    scale(60).
195 195
    title("Sample .eps figure (Palette demo)").
196
    copyright("(C) 2003-2008 LEMON Project").
196
    copyright("(C) 2003-2009 LEMON Project").
197 197
    coords(hcoords).
198 198
    absoluteNodeSizes().absoluteArcWidths().
199 199
    nodeScale(.45).
200 200
    distantColorNodeTexts().
201 201
    nodeTexts(hcolors).nodeTextSize(.6).
202 202
    nodeColors(composeMap(paletteW,hcolors)).
203 203
    run();
204 204

	
205 205
  return 0;
206 206
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
///\ingroup demos
20 20
///\file
21 21
///\brief Demonstrating graph input and output
22 22
///
23 23
/// This program gives an example of how to read and write a digraph
24 24
/// and additional maps from/to a stream or a file using the
25 25
/// \ref lgf-format "LGF" format.
26 26
///
27 27
/// The \c "digraph.lgf" file:
28 28
/// \include digraph.lgf
29 29
///
30 30
/// And the program which reads it and prints the digraph to the
31 31
/// standard output:
32 32
/// \include lgf_demo.cc
33 33

	
34 34
#include <iostream>
35 35
#include <lemon/smart_graph.h>
36 36
#include <lemon/lgf_reader.h>
37 37
#include <lemon/lgf_writer.h>
38 38

	
39 39
using namespace lemon;
40 40

	
41 41
int main() {
42 42
  SmartDigraph g;
43 43
  SmartDigraph::ArcMap<int> cap(g);
44 44
  SmartDigraph::Node s, t;
45 45

	
46 46
  try {
47 47
    digraphReader(g, "digraph.lgf"). // read the directed graph into g
48 48
      arcMap("capacity", cap).       // read the 'capacity' arc map into cap
49 49
      node("source", s).             // read 'source' node to s
50 50
      node("target", t).             // read 'target' node to t
51 51
      run();
52 52
  } catch (Exception& error) { // check if there was any error
53 53
    std::cerr << "Error: " << error.what() << std::endl;
54 54
    return -1;
55 55
  }
56 56

	
57 57
  std::cout << "A digraph is read from 'digraph.lgf'." << std::endl;
58 58
  std::cout << "Number of nodes: " << countNodes(g) << std::endl;
59 59
  std::cout << "Number of arcs: " << countArcs(g) << std::endl;
60 60

	
61 61
  std::cout << "We can write it to the standard output:" << std::endl;
62 62

	
63 63
  digraphWriter(g).                // write g to the standard output
64 64
    arcMap("capacity", cap).       // write cap into 'capacity'
65 65
    node("source", s).             // write s to 'source'
66 66
    node("target", t).             // write t to 'target'
67 67
    run();
68 68

	
69 69
  return 0;
70 70
}
Ignore white space 6 line context
1 1
SET(PACKAGE_NAME ${PROJECT_NAME})
2 2
SET(PACKAGE_VERSION ${PROJECT_VERSION})
3
SET(abs_top_srcdir ${CMAKE_SOURCE_DIR})
4
SET(abs_top_builddir ${CMAKE_BINARY_DIR})
3
SET(abs_top_srcdir ${PROJECT_SOURCE_DIR})
4
SET(abs_top_builddir ${PROJECT_BINARY_DIR})
5 5

	
6 6
CONFIGURE_FILE(
7
  ${CMAKE_SOURCE_DIR}/doc/Doxyfile.in
8
  ${CMAKE_BINARY_DIR}/doc/Doxyfile
9
  @ONLY)
7
  ${PROJECT_SOURCE_DIR}/doc/Doxyfile.in
8
  ${PROJECT_BINARY_DIR}/doc/Doxyfile
9
  @ONLY
10
)
10 11

	
11 12
IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
12 13
  FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
14
  SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha)
15
  ADD_CUSTOM_TARGET(html
16
    COMMAND ${CMAKE_COMMAND} -E remove_directory gen-images
17
    COMMAND ${CMAKE_COMMAND} -E make_directory gen-images
18
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps
19
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps
20
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
21
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
22
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
23
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
24
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
25
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
26
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
27
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
28
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
29
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
30
    COMMAND ${CMAKE_COMMAND} -E remove_directory html
31
    COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
32
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
33
  )
34

	
35
  SET_TARGET_PROPERTIES(html PROPERTIES PROJECT_LABEL BUILD_DOC)
36

	
13 37
  IF(UNIX)
14
    ADD_CUSTOM_TARGET(html
15
      COMMAND rm -rf gen-images
16
      COMMAND mkdir gen-images
17
      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
18
      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
19
      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
20
      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
21
      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
22
      COMMAND rm -rf html
23
      COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
24
      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
38
    INSTALL(
39
      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
40
      DESTINATION share/doc/lemon/html
41
      COMPONENT html_documentation
42
    )
25 43
  ELSEIF(WIN32)
26
    ADD_CUSTOM_TARGET(html
27
      COMMAND if exist gen-images rmdir /s /q gen-images
28
      COMMAND mkdir gen-images
29
      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
30
      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
31
      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
32
      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
33
      COMMAND ${GHOSTSCRIPT_EXECUTABLE} -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
34
      COMMAND if exist html rmdir /s /q html
35
      COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
36
      WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
37
  ENDIF(UNIX)
38
  INSTALL(
39
    DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
40
    DESTINATION share/doc
41
    COMPONENT html_documentation)
42
ENDIF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
44
    INSTALL(
45
      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
46
      DESTINATION doc
47
      COMPONENT html_documentation
48
    )
49
  ENDIF()
50

	
51
ENDIF()
Ignore white space 6 line context
1 1
# Doxyfile 1.5.7.1
2 2

	
3 3
#---------------------------------------------------------------------------
4 4
# Project related configuration options
5 5
#---------------------------------------------------------------------------
6 6
DOXYFILE_ENCODING      = UTF-8
7 7
PROJECT_NAME           = @PACKAGE_NAME@
8 8
PROJECT_NUMBER         = @PACKAGE_VERSION@
9 9
OUTPUT_DIRECTORY       = 
10 10
CREATE_SUBDIRS         = NO
11 11
OUTPUT_LANGUAGE        = English
12 12
BRIEF_MEMBER_DESC      = YES
13 13
REPEAT_BRIEF           = NO
14 14
ABBREVIATE_BRIEF       = 
15 15
ALWAYS_DETAILED_SEC    = NO
16 16
INLINE_INHERITED_MEMB  = NO
17 17
FULL_PATH_NAMES        = YES
18 18
STRIP_FROM_PATH        = "@abs_top_srcdir@"
19 19
STRIP_FROM_INC_PATH    = "@abs_top_srcdir@"
20 20
SHORT_NAMES            = YES
21 21
JAVADOC_AUTOBRIEF      = NO
22 22
QT_AUTOBRIEF           = NO
23 23
MULTILINE_CPP_IS_BRIEF = NO
24 24
DETAILS_AT_TOP         = YES
25 25
INHERIT_DOCS           = NO
26 26
SEPARATE_MEMBER_PAGES  = NO
27 27
TAB_SIZE               = 8
28 28
ALIASES                = 
29 29
OPTIMIZE_OUTPUT_FOR_C  = NO
30 30
OPTIMIZE_OUTPUT_JAVA   = NO
31 31
OPTIMIZE_FOR_FORTRAN   = NO
32 32
OPTIMIZE_OUTPUT_VHDL   = NO
33 33
BUILTIN_STL_SUPPORT    = YES
34 34
CPP_CLI_SUPPORT        = NO
35 35
SIP_SUPPORT            = NO
36 36
IDL_PROPERTY_SUPPORT   = YES
37 37
DISTRIBUTE_GROUP_DOC   = NO
38 38
SUBGROUPING            = YES
39 39
TYPEDEF_HIDES_STRUCT   = NO
40 40
SYMBOL_CACHE_SIZE      = 0
41 41
#---------------------------------------------------------------------------
42 42
# Build related configuration options
43 43
#---------------------------------------------------------------------------
44 44
EXTRACT_ALL            = NO
45 45
EXTRACT_PRIVATE        = YES
46 46
EXTRACT_STATIC         = YES
47 47
EXTRACT_LOCAL_CLASSES  = NO
48 48
EXTRACT_LOCAL_METHODS  = NO
49 49
EXTRACT_ANON_NSPACES   = NO
50 50
HIDE_UNDOC_MEMBERS     = YES
51 51
HIDE_UNDOC_CLASSES     = YES
52 52
HIDE_FRIEND_COMPOUNDS  = NO
53 53
HIDE_IN_BODY_DOCS      = NO
54 54
INTERNAL_DOCS          = NO
55 55
CASE_SENSE_NAMES       = YES
56 56
HIDE_SCOPE_NAMES       = YES
57 57
SHOW_INCLUDE_FILES     = YES
58 58
INLINE_INFO            = YES
59 59
SORT_MEMBER_DOCS       = NO
60 60
SORT_BRIEF_DOCS        = NO
61 61
SORT_GROUP_NAMES       = NO
62 62
SORT_BY_SCOPE_NAME     = NO
63 63
GENERATE_TODOLIST      = YES
64 64
GENERATE_TESTLIST      = YES
65 65
GENERATE_BUGLIST       = YES
66 66
GENERATE_DEPRECATEDLIST= YES
67 67
ENABLED_SECTIONS       = 
68 68
MAX_INITIALIZER_LINES  = 5
69
SHOW_USED_FILES        = YES
69
SHOW_USED_FILES        = NO
70 70
SHOW_DIRECTORIES       = YES
71 71
SHOW_FILES             = YES
72 72
SHOW_NAMESPACES        = YES
73 73
FILE_VERSION_FILTER    = 
74 74
LAYOUT_FILE            = DoxygenLayout.xml
75 75
#---------------------------------------------------------------------------
76 76
# configuration options related to warning and progress messages
77 77
#---------------------------------------------------------------------------
78 78
QUIET                  = NO
79 79
WARNINGS               = YES
80 80
WARN_IF_UNDOCUMENTED   = YES
81 81
WARN_IF_DOC_ERROR      = YES
82 82
WARN_NO_PARAMDOC       = NO
83 83
WARN_FORMAT            = "$file:$line: $text"
84 84
WARN_LOGFILE           = doxygen.log
85 85
#---------------------------------------------------------------------------
86 86
# configuration options related to the input files
87 87
#---------------------------------------------------------------------------
88 88
INPUT                  = "@abs_top_srcdir@/doc" \
89 89
                         "@abs_top_srcdir@/lemon" \
90 90
                         "@abs_top_srcdir@/lemon/bits" \
91 91
                         "@abs_top_srcdir@/lemon/concepts" \
92 92
                         "@abs_top_srcdir@/demo" \
93 93
                         "@abs_top_srcdir@/tools" \
94 94
                         "@abs_top_srcdir@/test/test_tools.h"
95 95
INPUT_ENCODING         = UTF-8
96 96
FILE_PATTERNS          = *.h \
97 97
                         *.cc \
98 98
                         *.dox
99 99
RECURSIVE              = NO
100 100
EXCLUDE                = 
101 101
EXCLUDE_SYMLINKS       = NO
102 102
EXCLUDE_PATTERNS       = 
103 103
EXCLUDE_SYMBOLS        = 
104 104
EXAMPLE_PATH           = "@abs_top_srcdir@/demo" \
105 105
                         "@abs_top_srcdir@/LICENSE" \
106 106
                         "@abs_top_srcdir@/doc"
107 107
EXAMPLE_PATTERNS       = 
108 108
EXAMPLE_RECURSIVE      = NO
109 109
IMAGE_PATH             = "@abs_top_srcdir@/doc/images" \
110 110
                         "@abs_top_builddir@/doc/gen-images"
111 111
INPUT_FILTER           = 
112 112
FILTER_PATTERNS        = 
113 113
FILTER_SOURCE_FILES    = NO
114 114
#---------------------------------------------------------------------------
115 115
# configuration options related to source browsing
116 116
#---------------------------------------------------------------------------
117 117
SOURCE_BROWSER         = NO
118 118
INLINE_SOURCES         = NO
119 119
STRIP_CODE_COMMENTS    = YES
120 120
REFERENCED_BY_RELATION = NO
121 121
REFERENCES_RELATION    = NO
122 122
REFERENCES_LINK_SOURCE = YES
123 123
USE_HTAGS              = NO
124 124
VERBATIM_HEADERS       = NO
125 125
#---------------------------------------------------------------------------
126 126
# configuration options related to the alphabetical class index
127 127
#---------------------------------------------------------------------------
128 128
ALPHABETICAL_INDEX     = YES
129 129
COLS_IN_ALPHA_INDEX    = 2
130 130
IGNORE_PREFIX          = 
131 131
#---------------------------------------------------------------------------
132 132
# configuration options related to the HTML output
133 133
#---------------------------------------------------------------------------
134 134
GENERATE_HTML          = YES
135 135
HTML_OUTPUT            = html
136 136
HTML_FILE_EXTENSION    = .html
137 137
HTML_HEADER            = 
138 138
HTML_FOOTER            = 
139 139
HTML_STYLESHEET        = 
140 140
HTML_ALIGN_MEMBERS     = YES
141 141
HTML_DYNAMIC_SECTIONS  = NO
142 142
GENERATE_DOCSET        = NO
143 143
DOCSET_FEEDNAME        = "Doxygen generated docs"
144 144
DOCSET_BUNDLE_ID       = org.doxygen.Project
145 145
GENERATE_HTMLHELP      = NO
146 146
CHM_FILE               = 
147 147
HHC_LOCATION           = 
148 148
GENERATE_CHI           = NO
149 149
CHM_INDEX_ENCODING     = 
150 150
BINARY_TOC             = NO
151 151
TOC_EXPAND             = NO
152 152
GENERATE_QHP           = NO
153 153
QCH_FILE               = 
154 154
QHP_NAMESPACE          = org.doxygen.Project
155 155
QHP_VIRTUAL_FOLDER     = doc
156 156
QHG_LOCATION           = 
157 157
DISABLE_INDEX          = NO
158 158
ENUM_VALUES_PER_LINE   = 4
159 159
GENERATE_TREEVIEW      = NO
160 160
TREEVIEW_WIDTH         = 250
161 161
FORMULA_FONTSIZE       = 10
162 162
#---------------------------------------------------------------------------
163 163
# configuration options related to the LaTeX output
164 164
#---------------------------------------------------------------------------
165 165
GENERATE_LATEX         = NO
166 166
LATEX_OUTPUT           = latex
167 167
LATEX_CMD_NAME         = latex
168 168
MAKEINDEX_CMD_NAME     = makeindex
169 169
COMPACT_LATEX          = YES
170 170
PAPER_TYPE             = a4wide
171 171
EXTRA_PACKAGES         = amsmath \
172 172
                         amssymb
173 173
LATEX_HEADER           = 
174 174
PDF_HYPERLINKS         = YES
175 175
USE_PDFLATEX           = YES
176 176
LATEX_BATCHMODE        = NO
177 177
LATEX_HIDE_INDICES     = NO
178 178
#---------------------------------------------------------------------------
179 179
# configuration options related to the RTF output
180 180
#---------------------------------------------------------------------------
181 181
GENERATE_RTF           = NO
182 182
RTF_OUTPUT             = rtf
183 183
COMPACT_RTF            = NO
184 184
RTF_HYPERLINKS         = NO
185 185
RTF_STYLESHEET_FILE    = 
186 186
RTF_EXTENSIONS_FILE    = 
187 187
#---------------------------------------------------------------------------
188 188
# configuration options related to the man page output
189 189
#---------------------------------------------------------------------------
190 190
GENERATE_MAN           = NO
191 191
MAN_OUTPUT             = man
192 192
MAN_EXTENSION          = .3
193 193
MAN_LINKS              = NO
194 194
#---------------------------------------------------------------------------
195 195
# configuration options related to the XML output
196 196
#---------------------------------------------------------------------------
197 197
GENERATE_XML           = NO
198 198
XML_OUTPUT             = xml
199 199
XML_SCHEMA             = 
200 200
XML_DTD                = 
201 201
XML_PROGRAMLISTING     = YES
202 202
#---------------------------------------------------------------------------
203 203
# configuration options for the AutoGen Definitions output
204 204
#---------------------------------------------------------------------------
205 205
GENERATE_AUTOGEN_DEF   = NO
206 206
#---------------------------------------------------------------------------
207 207
# configuration options related to the Perl module output
208 208
#---------------------------------------------------------------------------
209 209
GENERATE_PERLMOD       = NO
210 210
PERLMOD_LATEX          = NO
211 211
PERLMOD_PRETTY         = YES
212 212
PERLMOD_MAKEVAR_PREFIX = 
213 213
#---------------------------------------------------------------------------
214 214
# Configuration options related to the preprocessor   
215 215
#---------------------------------------------------------------------------
216 216
ENABLE_PREPROCESSING   = YES
217 217
MACRO_EXPANSION        = NO
218 218
EXPAND_ONLY_PREDEF     = NO
219 219
SEARCH_INCLUDES        = YES
220 220
INCLUDE_PATH           = 
221 221
INCLUDE_FILE_PATTERNS  = 
222 222
PREDEFINED             = DOXYGEN
223 223
EXPAND_AS_DEFINED      = 
224 224
SKIP_FUNCTION_MACROS   = YES
225 225
#---------------------------------------------------------------------------
226 226
# Configuration::additions related to external references   
227 227
#---------------------------------------------------------------------------
228 228
TAGFILES               = "@abs_top_srcdir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/  "
229 229
GENERATE_TAGFILE       = html/lemon.tag
230 230
ALLEXTERNALS           = NO
231 231
EXTERNAL_GROUPS        = NO
232 232
PERL_PATH              = /usr/bin/perl
233 233
#---------------------------------------------------------------------------
234 234
# Configuration options related to the dot tool   
235 235
#---------------------------------------------------------------------------
236 236
CLASS_DIAGRAMS         = YES
237 237
MSCGEN_PATH            = 
238 238
HIDE_UNDOC_RELATIONS   = YES
239 239
HAVE_DOT               = YES
240 240
DOT_FONTNAME           = FreeSans
241 241
DOT_FONTSIZE           = 10
242 242
DOT_FONTPATH           = 
243 243
CLASS_GRAPH            = YES
244 244
COLLABORATION_GRAPH    = NO
245 245
GROUP_GRAPHS           = NO
246 246
UML_LOOK               = NO
247 247
TEMPLATE_RELATIONS     = NO
248 248
INCLUDE_GRAPH          = NO
249 249
INCLUDED_BY_GRAPH      = NO
250 250
CALL_GRAPH             = NO
251 251
CALLER_GRAPH           = NO
252 252
GRAPHICAL_HIERARCHY    = NO
253 253
DIRECTORY_GRAPH        = NO
254 254
DOT_IMAGE_FORMAT       = png
255 255
DOT_PATH               = 
256 256
DOTFILE_DIRS           = 
257 257
DOT_GRAPH_MAX_NODES    = 50
258 258
MAX_DOT_GRAPH_DEPTH    = 0
259 259
DOT_TRANSPARENT        = NO
260 260
DOT_MULTI_TARGETS      = NO
261 261
GENERATE_LEGEND        = YES
262 262
DOT_CLEANUP            = YES
263 263
#---------------------------------------------------------------------------
264 264
# Configuration::additions related to the search engine   
265 265
#---------------------------------------------------------------------------
266 266
SEARCHENGINE           = NO
Ignore white space 6 line context
1 1
EXTRA_DIST += \
2 2
	doc/Doxyfile.in \
3 3
	doc/DoxygenLayout.xml \
4 4
	doc/coding_style.dox \
5 5
	doc/dirs.dox \
6 6
	doc/groups.dox \
7 7
	doc/lgf.dox \
8 8
	doc/license.dox \
9 9
	doc/mainpage.dox \
10 10
	doc/migration.dox \
11
	doc/min_cost_flow.dox \
11 12
	doc/named-param.dox \
12 13
	doc/namespaces.dox \
13 14
	doc/html \
14 15
	doc/CMakeLists.txt
15 16

	
16 17
DOC_EPS_IMAGES18 = \
18
	grid_graph.eps \
17 19
	nodeshape_0.eps \
18 20
	nodeshape_1.eps \
19 21
	nodeshape_2.eps \
20 22
	nodeshape_3.eps \
21 23
	nodeshape_4.eps
22 24

	
25
DOC_EPS_IMAGES27 = \
26
	bipartite_matching.eps \
27
	bipartite_partitions.eps \
28
	connected_components.eps \
29
	edge_biconnected_components.eps \
30
	node_biconnected_components.eps \
31
	strongly_connected_components.eps
32

	
23 33
DOC_EPS_IMAGES = \
24
	$(DOC_EPS_IMAGES18)
34
	$(DOC_EPS_IMAGES18) \
35
	$(DOC_EPS_IMAGES27)
25 36

	
26 37
DOC_PNG_IMAGES = \
27 38
	$(DOC_EPS_IMAGES:%.eps=doc/gen-images/%.png)
28 39

	
29 40
EXTRA_DIST += $(DOC_EPS_IMAGES:%=doc/images/%)
30 41

	
31 42
doc/html:
32 43
	$(MAKE) $(AM_MAKEFLAGS) html
33 44

	
34 45
GS_COMMAND=gs -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4
35 46

	
36 47
$(DOC_EPS_IMAGES18:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
37 48
	-mkdir doc/gen-images
38 49
	if test ${gs_found} = yes; then \
39 50
	  $(GS_COMMAND) -sDEVICE=pngalpha -r18 -sOutputFile=$@ $<; \
40 51
	else \
41 52
	  echo; \
42 53
	  echo "Ghostscript not found."; \
43 54
	  echo; \
44 55
	  exit 1; \
45 56
	fi
46 57

	
58
$(DOC_EPS_IMAGES27:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
59
	-mkdir doc/gen-images
60
	if test ${gs_found} = yes; then \
61
	  $(GS_COMMAND) -sDEVICE=pngalpha -r27 -sOutputFile=$@ $<; \
62
	else \
63
	  echo; \
64
	  echo "Ghostscript not found."; \
65
	  echo; \
66
	  exit 1; \
67
	fi
68

	
47 69
html-local: $(DOC_PNG_IMAGES)
48 70
	if test ${doxygen_found} = yes; then \
49 71
	  cd doc; \
50 72
	  doxygen Doxyfile; \
51 73
	  cd ..; \
52 74
	else \
53 75
	  echo; \
54 76
	  echo "Doxygen not found."; \
55 77
	  echo; \
56 78
	  exit 1; \
57 79
	fi
58 80

	
59 81
clean-local:
60 82
	-rm -rf doc/html
61 83
	-rm -f doc/doxygen.log
62 84
	-rm -f $(DOC_PNG_IMAGES)
63 85
	-rm -rf doc/gen-images
64 86

	
65 87
update-external-tags:
66 88
	wget -O doc/libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag && \
67 89
	mv doc/libstdc++.tag.tmp doc/libstdc++.tag || \
68 90
	rm doc/libstdc++.tag.tmp
69 91

	
70 92
install-html-local: doc/html
71 93
	@$(NORMAL_INSTALL)
72
	$(mkinstalldirs) $(DESTDIR)$(htmldir)/docs
94
	$(mkinstalldirs) $(DESTDIR)$(htmldir)/html
73 95
	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
74 96
	  f="`echo $$p | sed -e 's|^.*/||'`"; \
75
	  echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/docs/$$f"; \
76
	  $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/docs/$$f; \
97
	  echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \
98
	  $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \
77 99
	done
78 100

	
79 101
uninstall-local:
80 102
	@$(NORMAL_UNINSTALL)
81 103
	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
82 104
	  f="`echo $$p | sed -e 's|^.*/||'`"; \
83
	  echo " rm -f $(DESTDIR)$(htmldir)/docs/$$f"; \
84
	  rm -f $(DESTDIR)$(htmldir)/docs/$$f; \
105
	  echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \
106
	  rm -f $(DESTDIR)$(htmldir)/html/$$f; \
85 107
	done
86 108

	
87 109
.PHONY: update-external-tags
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
/*!
20 20

	
21 21
\page coding_style LEMON Coding Style
22 22

	
23 23
\section naming_conv Naming Conventions
24 24

	
25 25
In order to make development easier we have made some conventions
26 26
according to coding style. These include names of types, classes,
27 27
functions, variables, constants and exceptions. If these conventions
28 28
are met in one's code then it is easier to read and maintain
29 29
it. Please comply with these conventions if you want to contribute
30 30
developing LEMON library.
31 31

	
32 32
\note When the coding style requires the capitalization of an abbreviation,
33 33
only the first letter should be upper case.
34 34

	
35 35
\code
36 36
XmlReader
37 37
\endcode
38 38

	
39 39

	
40 40
\warning In some cases we diverge from these rules.
41 41
This is primary done because STL uses different naming convention and
42 42
in certain cases
43 43
it is beneficial to provide STL compatible interface.
44 44

	
45 45
\subsection cs-files File Names
46 46

	
47 47
The header file names should look like the following.
48 48

	
49 49
\code
50 50
header_file.h
51 51
\endcode
52 52

	
53 53
Note that all standard LEMON headers are located in the \c lemon subdirectory,
54 54
so you should include them from C++ source like this:
55 55

	
56 56
\code
57 57
#include <lemon/header_file.h>
58 58
\endcode
59 59

	
60 60
The source code files use the same style and they have '.cc' extension.
61 61

	
62 62
\code
63 63
source_code.cc
64 64
\endcode
65 65

	
66 66
\subsection cs-class Classes and other types
67 67

	
68 68
The name of a class or any type should look like the following.
69 69

	
70 70
\code
71 71
AllWordsCapitalizedWithoutUnderscores
72 72
\endcode
73 73

	
74 74
\subsection cs-func Methods and other functions
75 75

	
76 76
The name of a function should look like the following.
77 77

	
78 78
\code
79 79
firstWordLowerCaseRestCapitalizedWithoutUnderscores
80 80
\endcode
81 81

	
82 82
\subsection cs-funcs Constants, Macros
83 83

	
84 84
The names of constants and macros should look like the following.
85 85

	
86 86
\code
87 87
ALL_UPPER_CASE_WITH_UNDERSCORES
88 88
\endcode
89 89

	
90 90
\subsection cs-loc-var Class and instance member variables, auto variables
91 91

	
92 92
The names of class and instance member variables and auto variables
93 93
(=variables used locally in methods) should look like the following.
94 94

	
95 95
\code
96 96
all_lower_case_with_underscores
97 97
\endcode
98 98

	
99 99
\subsection pri-loc-var Private member variables
100 100

	
101 101
Private member variables should start with underscore
102 102

	
103 103
\code
104 104
_start_with_underscores
105 105
\endcode
106 106

	
107 107
\subsection cs-excep Exceptions
108 108

	
109 109
When writing exceptions please comply the following naming conventions.
110 110

	
111 111
\code
112 112
ClassNameEndsWithException
113 113
\endcode
114 114

	
115 115
or
116 116

	
117 117
\code
118 118
ClassNameEndsWithError
119 119
\endcode
120 120

	
121 121
\section header-template Template Header File
122 122

	
123 123
Each LEMON header file should look like this:
124 124

	
125 125
\include template.h
126 126

	
127 127
*/
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
/**
20 20
\dir demo
21 21
\brief A collection of demo applications.
22 22

	
23 23
This directory contains several simple demo applications, mainly
24 24
for educational purposes.
25 25
*/
26 26

	
27 27
/**
28 28
\dir doc
29 29
\brief Auxiliary (and the whole generated) documentation.
30 30

	
31 31
This directory contains some auxiliary pages and the whole generated
32 32
documentation.
33 33
*/
34 34

	
35 35
/**
36 36
\dir test
37 37
\brief Test programs.
38 38

	
39 39
This directory contains several test programs that check the consistency
40 40
of the code.
41 41
*/
42 42

	
43 43
/**
44 44
\dir tools
45 45
\brief Some useful executables.
46 46

	
47 47
This directory contains the sources of some useful complete executables.
48 48
*/
49 49

	
50 50
/**
51 51
\dir lemon
52 52
\brief Base include directory of LEMON.
53 53

	
54 54
This is the base directory of LEMON includes, so each include file must be
55 55
prefixed with this, e.g.
56 56
\code
57 57
#include<lemon/list_graph.h>
58 58
#include<lemon/dijkstra.h>
59 59
\endcode
60 60
*/
61 61

	
62 62
/**
63 63
\dir concepts
64 64
\brief Concept descriptors and checking classes.
65 65

	
66 66
This directory contains the concept descriptors and concept checking tools.
67 67
For more information see the \ref concept "Concepts" module.
68 68
*/
69 69

	
70 70
/**
71 71
\dir bits
72 72
\brief Auxiliary tools for implementation.
73 73

	
74
This directory contains some auxiliary classes for implementing graphs, 
74
This directory contains some auxiliary classes for implementing graphs,
75 75
maps and some other classes.
76 76
As a user you typically don't have to deal with these files.
77 77
*/
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
namespace lemon {
20

	
19 21
/**
20 22
@defgroup datas Data Structures
21
This group describes the several data structures implemented in LEMON.
23
This group contains the several data structures implemented in LEMON.
22 24
*/
23 25

	
24 26
/**
25 27
@defgroup graphs Graph Structures
26 28
@ingroup datas
27 29
\brief Graph structures implemented in LEMON.
28 30

	
29 31
The implementation of combinatorial algorithms heavily relies on
30 32
efficient graph implementations. LEMON offers data structures which are
31 33
planned to be easily used in an experimental phase of implementation studies,
32 34
and thereafter the program code can be made efficient by small modifications.
33 35

	
34 36
The most efficient implementation of diverse applications require the
35 37
usage of different physical graph implementations. These differences
36 38
appear in the size of graph we require to handle, memory or time usage
37 39
limitations or in the set of operations through which the graph can be
38 40
accessed.  LEMON provides several physical graph structures to meet
39 41
the diverging requirements of the possible users.  In order to save on
40 42
running time or on memory usage, some structures may fail to provide
41 43
some graph features like arc/edge or node deletion.
42 44

	
43 45
Alteration of standard containers need a very limited number of
44 46
operations, these together satisfy the everyday requirements.
45 47
In the case of graph structures, different operations are needed which do
46 48
not alter the physical graph, but gives another view. If some nodes or
47 49
arcs have to be hidden or the reverse oriented graph have to be used, then
48 50
this is the case. It also may happen that in a flow implementation
49 51
the residual graph can be accessed by another algorithm, or a node-set
50 52
is to be shrunk for another algorithm.
51 53
LEMON also provides a variety of graphs for these requirements called
52 54
\ref graph_adaptors "graph adaptors". Adaptors cannot be used alone but only
53 55
in conjunction with other graph representations.
54 56

	
55 57
You are free to use the graph structure that fit your requirements
56 58
the best, most graph algorithms and auxiliary data structures can be used
57 59
with any graph structure.
58 60

	
59 61
<b>See also:</b> \ref graph_concepts "Graph Structure Concepts".
60 62
*/
61 63

	
62 64
/**
63
@defgroup semi_adaptors Semi-Adaptor Classes for Graphs
65
@defgroup graph_adaptors Adaptor Classes for Graphs
64 66
@ingroup graphs
65
\brief Graph types between real graphs and graph adaptors.
67
\brief Adaptor classes for digraphs and graphs
66 68

	
67
This group describes some graph types between real graphs and graph adaptors.
68
These classes wrap graphs to give new functionality as the adaptors do it.
69
On the other hand they are not light-weight structures as the adaptors.
69
This group contains several useful adaptor classes for digraphs and graphs.
70

	
71
The main parts of LEMON are the different graph structures, generic
72
graph algorithms, graph concepts, which couple them, and graph
73
adaptors. While the previous notions are more or less clear, the
74
latter one needs further explanation. Graph adaptors are graph classes
75
which serve for considering graph structures in different ways.
76

	
77
A short example makes this much clearer.  Suppose that we have an
78
instance \c g of a directed graph type, say ListDigraph and an algorithm
79
\code
80
template <typename Digraph>
81
int algorithm(const Digraph&);
82
\endcode
83
is needed to run on the reverse oriented graph.  It may be expensive
84
(in time or in memory usage) to copy \c g with the reversed
85
arcs.  In this case, an adaptor class is used, which (according
86
to LEMON \ref concepts::Digraph "digraph concepts") works as a digraph.
87
The adaptor uses the original digraph structure and digraph operations when
88
methods of the reversed oriented graph are called.  This means that the adaptor
89
have minor memory usage, and do not perform sophisticated algorithmic
90
actions.  The purpose of it is to give a tool for the cases when a
91
graph have to be used in a specific alteration.  If this alteration is
92
obtained by a usual construction like filtering the node or the arc set or
93
considering a new orientation, then an adaptor is worthwhile to use.
94
To come back to the reverse oriented graph, in this situation
95
\code
96
template<typename Digraph> class ReverseDigraph;
97
\endcode
98
template class can be used. The code looks as follows
99
\code
100
ListDigraph g;
101
ReverseDigraph<ListDigraph> rg(g);
102
int result = algorithm(rg);
103
\endcode
104
During running the algorithm, the original digraph \c g is untouched.
105
This techniques give rise to an elegant code, and based on stable
106
graph adaptors, complex algorithms can be implemented easily.
107

	
108
In flow, circulation and matching problems, the residual
109
graph is of particular importance. Combining an adaptor implementing
110
this with shortest path algorithms or minimum mean cycle algorithms,
111
a range of weighted and cardinality optimization algorithms can be
112
obtained. For other examples, the interested user is referred to the
113
detailed documentation of particular adaptors.
114

	
115
The behavior of graph adaptors can be very different. Some of them keep
116
capabilities of the original graph while in other cases this would be
117
meaningless. This means that the concepts that they meet depend
118
on the graph adaptor, and the wrapped graph.
119
For example, if an arc of a reversed digraph is deleted, this is carried
120
out by deleting the corresponding arc of the original digraph, thus the
121
adaptor modifies the original digraph.
122
However in case of a residual digraph, this operation has no sense.
123

	
124
Let us stand one more example here to simplify your work.
125
ReverseDigraph has constructor
126
\code
127
ReverseDigraph(Digraph& digraph);
128
\endcode
129
This means that in a situation, when a <tt>const %ListDigraph&</tt>
130
reference to a graph is given, then it have to be instantiated with
131
<tt>Digraph=const %ListDigraph</tt>.
132
\code
133
int algorithm1(const ListDigraph& g) {
134
  ReverseDigraph<const ListDigraph> rg(g);
135
  return algorithm2(rg);
136
}
137
\endcode
70 138
*/
71 139

	
72 140
/**
73 141
@defgroup maps Maps
74 142
@ingroup datas
75 143
\brief Map structures implemented in LEMON.
76 144

	
77
This group describes the map structures implemented in LEMON.
145
This group contains the map structures implemented in LEMON.
78 146

	
79 147
LEMON provides several special purpose maps and map adaptors that e.g. combine
80 148
new maps from existing ones.
81 149

	
82 150
<b>See also:</b> \ref map_concepts "Map Concepts".
83 151
*/
84 152

	
85 153
/**
86 154
@defgroup graph_maps Graph Maps
87 155
@ingroup maps
88 156
\brief Special graph-related maps.
89 157

	
90
This group describes maps that are specifically designed to assign
91
values to the nodes and arcs of graphs.
158
This group contains maps that are specifically designed to assign
159
values to the nodes and arcs/edges of graphs.
160

	
161
If you are looking for the standard graph maps (\c NodeMap, \c ArcMap,
162
\c EdgeMap), see the \ref graph_concepts "Graph Structure Concepts".
92 163
*/
93 164

	
94 165
/**
95 166
\defgroup map_adaptors Map Adaptors
96 167
\ingroup maps
97 168
\brief Tools to create new maps from existing ones
98 169

	
99
This group describes map adaptors that are used to create "implicit"
170
This group contains map adaptors that are used to create "implicit"
100 171
maps from other maps.
101 172

	
102
Most of them are \ref lemon::concepts::ReadMap "read-only maps".
173
Most of them are \ref concepts::ReadMap "read-only maps".
103 174
They can make arithmetic and logical operations between one or two maps
104 175
(negation, shifting, addition, multiplication, logical 'and', 'or',
105 176
'not' etc.) or e.g. convert a map to another one of different Value type.
106 177

	
107 178
The typical usage of this classes is passing implicit maps to
108 179
algorithms.  If a function type algorithm is called then the function
109 180
type map adaptors can be used comfortable. For example let's see the
110 181
usage of map adaptors with the \c graphToEps() function.
111 182
\code
112 183
  Color nodeColor(int deg) {
113 184
    if (deg >= 2) {
114 185
      return Color(0.5, 0.0, 0.5);
115 186
    } else if (deg == 1) {
116 187
      return Color(1.0, 0.5, 1.0);
117 188
    } else {
118 189
      return Color(0.0, 0.0, 0.0);
119 190
    }
120 191
  }
121 192

	
122 193
  Digraph::NodeMap<int> degree_map(graph);
123 194

	
124 195
  graphToEps(graph, "graph.eps")
125 196
    .coords(coords).scaleToA4().undirected()
126 197
    .nodeColors(composeMap(functorToMap(nodeColor), degree_map))
127 198
    .run();
128 199
\endcode
129 200
The \c functorToMap() function makes an \c int to \c Color map from the
130 201
\c nodeColor() function. The \c composeMap() compose the \c degree_map
131 202
and the previously created map. The composed map is a proper function to
132 203
get the color of each node.
133 204

	
134 205
The usage with class type algorithms is little bit harder. In this
135 206
case the function type map adaptors can not be used, because the
136 207
function map adaptors give back temporary objects.
137 208
\code
138 209
  Digraph graph;
139 210

	
140 211
  typedef Digraph::ArcMap<double> DoubleArcMap;
141 212
  DoubleArcMap length(graph);
142 213
  DoubleArcMap speed(graph);
143 214

	
144 215
  typedef DivMap<DoubleArcMap, DoubleArcMap> TimeMap;
145 216
  TimeMap time(length, speed);
146 217

	
147 218
  Dijkstra<Digraph, TimeMap> dijkstra(graph, time);
148 219
  dijkstra.run(source, target);
149 220
\endcode
150 221
We have a length map and a maximum speed map on the arcs of a digraph.
151 222
The minimum time to pass the arc can be calculated as the division of
152 223
the two maps which can be done implicitly with the \c DivMap template
153 224
class. We use the implicit minimum time map as the length map of the
154 225
\c Dijkstra algorithm.
155 226
*/
156 227

	
157 228
/**
158 229
@defgroup matrices Matrices
159 230
@ingroup datas
160 231
\brief Two dimensional data storages implemented in LEMON.
161 232

	
162
This group describes two dimensional data storages implemented in LEMON.
233
This group contains two dimensional data storages implemented in LEMON.
163 234
*/
164 235

	
165 236
/**
166 237
@defgroup paths Path Structures
167 238
@ingroup datas
168 239
\brief %Path structures implemented in LEMON.
169 240

	
170
This group describes the path structures implemented in LEMON.
241
This group contains the path structures implemented in LEMON.
171 242

	
172 243
LEMON provides flexible data structures to work with paths.
173 244
All of them have similar interfaces and they can be copied easily with
174 245
assignment operators and copy constructors. This makes it easy and
175 246
efficient to have e.g. the Dijkstra algorithm to store its result in
176 247
any kind of path structure.
177 248

	
178 249
\sa lemon::concepts::Path
179 250
*/
180 251

	
181 252
/**
182 253
@defgroup auxdat Auxiliary Data Structures
183 254
@ingroup datas
184 255
\brief Auxiliary data structures implemented in LEMON.
185 256

	
186
This group describes some data structures implemented in LEMON in
257
This group contains some data structures implemented in LEMON in
187 258
order to make it easier to implement combinatorial algorithms.
188 259
*/
189 260

	
190 261
/**
191 262
@defgroup algs Algorithms
192
\brief This group describes the several algorithms
263
\brief This group contains the several algorithms
193 264
implemented in LEMON.
194 265

	
195
This group describes the several algorithms
266
This group contains the several algorithms
196 267
implemented in LEMON.
197 268
*/
198 269

	
199 270
/**
200 271
@defgroup search Graph Search
201 272
@ingroup algs
202 273
\brief Common graph search algorithms.
203 274

	
204
This group describes the common graph search algorithms like
205
Breadth-First Search (BFS) and Depth-First Search (DFS).
275
This group contains the common graph search algorithms, namely
276
\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
206 277
*/
207 278

	
208 279
/**
209 280
@defgroup shortest_path Shortest Path Algorithms
210 281
@ingroup algs
211 282
\brief Algorithms for finding shortest paths.
212 283

	
213
This group describes the algorithms for finding shortest paths in graphs.
284
This group contains the algorithms for finding shortest paths in digraphs.
285

	
286
 - \ref Dijkstra algorithm for finding shortest paths from a source node
287
   when all arc lengths are non-negative.
288
 - \ref BellmanFord "Bellman-Ford" algorithm for finding shortest paths
289
   from a source node when arc lenghts can be either positive or negative,
290
   but the digraph should not contain directed cycles with negative total
291
   length.
292
 - \ref FloydWarshall "Floyd-Warshall" and \ref Johnson "Johnson" algorithms
293
   for solving the \e all-pairs \e shortest \e paths \e problem when arc
294
   lenghts can be either positive or negative, but the digraph should
295
   not contain directed cycles with negative total length.
296
 - \ref Suurballe A successive shortest path algorithm for finding
297
   arc-disjoint paths between two nodes having minimum total length.
214 298
*/
215 299

	
216 300
/**
217 301
@defgroup max_flow Maximum Flow Algorithms
218 302
@ingroup algs
219 303
\brief Algorithms for finding maximum flows.
220 304

	
221
This group describes the algorithms for finding maximum flows and
305
This group contains the algorithms for finding maximum flows and
222 306
feasible circulations.
223 307

	
224
The maximum flow problem is to find a flow between a single source and
225
a single target that is maximum. Formally, there is a \f$G=(V,A)\f$
226
directed graph, an \f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity
227
function and given \f$s, t \in V\f$ source and target node. The
228
maximum flow is the \f$f_a\f$ solution of the next optimization problem:
308
The \e maximum \e flow \e problem is to find a flow of maximum value between
309
a single source and a single target. Formally, there is a \f$G=(V,A)\f$
310
digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and
311
\f$s, t \in V\f$ source and target nodes.
312
A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the
313
following optimization problem.
229 314

	
230
\f[ 0 \le f_a \le c_a \f]
231
\f[ \sum_{v\in\delta^{-}(u)}f_{vu}=\sum_{v\in\delta^{+}(u)}f_{uv}
232
\qquad \forall u \in V \setminus \{s,t\}\f]
233
\f[ \max \sum_{v\in\delta^{+}(s)}f_{uv} - \sum_{v\in\delta^{-}(s)}f_{vu}\f]
315
\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
316
\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
317
    \quad \forall u\in V\setminus\{s,t\} \f]
318
\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
234 319

	
235 320
LEMON contains several algorithms for solving maximum flow problems:
236
- \ref lemon::EdmondsKarp "Edmonds-Karp"
237
- \ref lemon::Preflow "Goldberg's Preflow algorithm"
238
- \ref lemon::DinitzSleatorTarjan "Dinitz's blocking flow algorithm with dynamic trees"
239
- \ref lemon::GoldbergTarjan "Preflow algorithm with dynamic trees"
321
- \ref EdmondsKarp Edmonds-Karp algorithm.
322
- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm.
323
- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees.
324
- \ref GoldbergTarjan Preflow push-relabel algorithm with dynamic trees.
240 325

	
241
In most cases the \ref lemon::Preflow "Preflow" algorithm provides the
242
fastest method to compute the maximum flow. All impelementations
243
provides functions to query the minimum cut, which is the dual linear
244
programming problem of the maximum flow.
326
In most cases the \ref Preflow "Preflow" algorithm provides the
327
fastest method for computing a maximum flow. All implementations
328
also provide functions to query the minimum cut, which is the dual
329
problem of maximum flow.
330

	
331
\ref Circulation is a preflow push-relabel algorithm implemented directly 
332
for finding feasible circulations, which is a somewhat different problem,
333
but it is strongly related to maximum flow.
334
For more information, see \ref Circulation.
245 335
*/
246 336

	
247 337
/**
248
@defgroup min_cost_flow Minimum Cost Flow Algorithms
338
@defgroup min_cost_flow_algs Minimum Cost Flow Algorithms
249 339
@ingroup algs
250 340

	
251 341
\brief Algorithms for finding minimum cost flows and circulations.
252 342

	
253
This group describes the algorithms for finding minimum cost flows and
254
circulations.
343
This group contains the algorithms for finding minimum cost flows and
344
circulations. For more information about this problem and its dual
345
solution see \ref min_cost_flow "Minimum Cost Flow Problem".
346

	
347
LEMON contains several algorithms for this problem.
348
 - \ref NetworkSimplex Primal Network Simplex algorithm with various
349
   pivot strategies.
350
 - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
351
   cost scaling.
352
 - \ref CapacityScaling Successive Shortest %Path algorithm with optional
353
   capacity scaling.
354
 - \ref CancelAndTighten The Cancel and Tighten algorithm.
355
 - \ref CycleCanceling Cycle-Canceling algorithms.
356

	
357
In general NetworkSimplex is the most efficient implementation,
358
but in special cases other algorithms could be faster.
359
For example, if the total supply and/or capacities are rather small,
360
CapacityScaling is usually the fastest algorithm (without effective scaling).
255 361
*/
256 362

	
257 363
/**
258 364
@defgroup min_cut Minimum Cut Algorithms
259 365
@ingroup algs
260 366

	
261 367
\brief Algorithms for finding minimum cut in graphs.
262 368

	
263
This group describes the algorithms for finding minimum cut in graphs.
369
This group contains the algorithms for finding minimum cut in graphs.
264 370

	
265
The minimum cut problem is to find a non-empty and non-complete
266
\f$X\f$ subset of the vertices with minimum overall capacity on
267
outgoing arcs. Formally, there is \f$G=(V,A)\f$ directed graph, an
268
\f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
371
The \e minimum \e cut \e problem is to find a non-empty and non-complete
372
\f$X\f$ subset of the nodes with minimum overall capacity on
373
outgoing arcs. Formally, there is a \f$G=(V,A)\f$ digraph, a
374
\f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
269 375
cut is the \f$X\f$ solution of the next optimization problem:
270 376

	
271 377
\f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
272
\sum_{uv\in A, u\in X, v\not\in X}c_{uv}\f]
378
    \sum_{uv\in A, u\in X, v\not\in X}cap(uv) \f]
273 379

	
274 380
LEMON contains several algorithms related to minimum cut problems:
275 381

	
276
- \ref lemon::HaoOrlin "Hao-Orlin algorithm" to calculate minimum cut
277
  in directed graphs
278
- \ref lemon::NagamochiIbaraki "Nagamochi-Ibaraki algorithm" to
279
  calculate minimum cut in undirected graphs
280
- \ref lemon::GomoryHuTree "Gomory-Hu tree computation" to calculate all
281
  pairs minimum cut in undirected graphs
382
- \ref HaoOrlin "Hao-Orlin algorithm" for calculating minimum cut
383
  in directed graphs.
384
- \ref NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
385
  calculating minimum cut in undirected graphs.
386
- \ref GomoryHu "Gomory-Hu tree computation" for calculating
387
  all-pairs minimum cut in undirected graphs.
282 388

	
283 389
If you want to find minimum cut just between two distinict nodes,
284
please see the \ref max_flow "Maximum Flow page".
390
see the \ref max_flow "maximum flow problem".
285 391
*/
286 392

	
287 393
/**
288
@defgroup graph_prop Connectivity and Other Graph Properties
394
@defgroup graph_properties Connectivity and Other Graph Properties
289 395
@ingroup algs
290 396
\brief Algorithms for discovering the graph properties
291 397

	
292
This group describes the algorithms for discovering the graph properties
398
This group contains the algorithms for discovering the graph properties
293 399
like connectivity, bipartiteness, euler property, simplicity etc.
294 400

	
295 401
\image html edge_biconnected_components.png
296 402
\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
297 403
*/
298 404

	
299 405
/**
300 406
@defgroup planar Planarity Embedding and Drawing
301 407
@ingroup algs
302 408
\brief Algorithms for planarity checking, embedding and drawing
303 409

	
304
This group describes the algorithms for planarity checking,
410
This group contains the algorithms for planarity checking,
305 411
embedding and drawing.
306 412

	
307 413
\image html planar.png
308 414
\image latex planar.eps "Plane graph" width=\textwidth
309 415
*/
310 416

	
311 417
/**
312 418
@defgroup matching Matching Algorithms
313 419
@ingroup algs
314 420
\brief Algorithms for finding matchings in graphs and bipartite graphs.
315 421

	
316
This group contains algorithm objects and functions to calculate
422
This group contains the algorithms for calculating
317 423
matchings in graphs and bipartite graphs. The general matching problem is
318
finding a subset of the arcs which does not shares common endpoints.
424
finding a subset of the edges for which each node has at most one incident
425
edge.
319 426

	
320 427
There are several different algorithms for calculate matchings in
321 428
graphs.  The matching problems in bipartite graphs are generally
322 429
easier than in general graphs. The goal of the matching optimization
323
can be the finding maximum cardinality, maximum weight or minimum cost
430
can be finding maximum cardinality, maximum weight or minimum cost
324 431
matching. The search can be constrained to find perfect or
325 432
maximum cardinality matching.
326 433

	
327
LEMON contains the next algorithms:
328
- \ref lemon::MaxBipartiteMatching "MaxBipartiteMatching" Hopcroft-Karp
329
  augmenting path algorithm for calculate maximum cardinality matching in
330
  bipartite graphs
331
- \ref lemon::PrBipartiteMatching "PrBipartiteMatching" Push-Relabel
332
  algorithm for calculate maximum cardinality matching in bipartite graphs
333
- \ref lemon::MaxWeightedBipartiteMatching "MaxWeightedBipartiteMatching"
334
  Successive shortest path algorithm for calculate maximum weighted matching
335
  and maximum weighted bipartite matching in bipartite graph
336
- \ref lemon::MinCostMaxBipartiteMatching "MinCostMaxBipartiteMatching"
337
  Successive shortest path algorithm for calculate minimum cost maximum
338
  matching in bipartite graph
339
- \ref lemon::MaxMatching "MaxMatching" Edmond's blossom shrinking algorithm
340
  for calculate maximum cardinality matching in general graph
341
- \ref lemon::MaxWeightedMatching "MaxWeightedMatching" Edmond's blossom
342
  shrinking algorithm for calculate maximum weighted matching in general
343
  graph
344
- \ref lemon::MaxWeightedPerfectMatching "MaxWeightedPerfectMatching"
345
  Edmond's blossom shrinking algorithm for calculate maximum weighted
346
  perfect matching in general graph
434
The matching algorithms implemented in LEMON:
435
- \ref MaxBipartiteMatching Hopcroft-Karp augmenting path algorithm
436
  for calculating maximum cardinality matching in bipartite graphs.
437
- \ref PrBipartiteMatching Push-relabel algorithm
438
  for calculating maximum cardinality matching in bipartite graphs.
439
- \ref MaxWeightedBipartiteMatching
440
  Successive shortest path algorithm for calculating maximum weighted
441
  matching and maximum weighted bipartite matching in bipartite graphs.
442
- \ref MinCostMaxBipartiteMatching
443
  Successive shortest path algorithm for calculating minimum cost maximum
444
  matching in bipartite graphs.
445
- \ref MaxMatching Edmond's blossom shrinking algorithm for calculating
446
  maximum cardinality matching in general graphs.
447
- \ref MaxWeightedMatching Edmond's blossom shrinking algorithm for calculating
448
  maximum weighted matching in general graphs.
449
- \ref MaxWeightedPerfectMatching
450
  Edmond's blossom shrinking algorithm for calculating maximum weighted
451
  perfect matching in general graphs.
347 452

	
348 453
\image html bipartite_matching.png
349 454
\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
350 455
*/
351 456

	
352 457
/**
353 458
@defgroup spantree Minimum Spanning Tree Algorithms
354 459
@ingroup algs
355
\brief Algorithms for finding a minimum cost spanning tree in a graph.
460
\brief Algorithms for finding minimum cost spanning trees and arborescences.
356 461

	
357
This group describes the algorithms for finding a minimum cost spanning
358
tree in a graph
462
This group contains the algorithms for finding minimum cost spanning
463
trees and arborescences.
359 464
*/
360 465

	
361 466
/**
362 467
@defgroup auxalg Auxiliary Algorithms
363 468
@ingroup algs
364 469
\brief Auxiliary algorithms implemented in LEMON.
365 470

	
366
This group describes some algorithms implemented in LEMON
471
This group contains some algorithms implemented in LEMON
367 472
in order to make it easier to implement complex algorithms.
368 473
*/
369 474

	
370 475
/**
371 476
@defgroup approx Approximation Algorithms
372 477
@ingroup algs
373 478
\brief Approximation algorithms.
374 479

	
375
This group describes the approximation and heuristic algorithms
480
This group contains the approximation and heuristic algorithms
376 481
implemented in LEMON.
377 482
*/
378 483

	
379 484
/**
380 485
@defgroup gen_opt_group General Optimization Tools
381
\brief This group describes some general optimization frameworks
486
\brief This group contains some general optimization frameworks
382 487
implemented in LEMON.
383 488

	
384
This group describes some general optimization frameworks
489
This group contains some general optimization frameworks
385 490
implemented in LEMON.
386 491
*/
387 492

	
388 493
/**
389 494
@defgroup lp_group Lp and Mip Solvers
390 495
@ingroup gen_opt_group
391 496
\brief Lp and Mip solver interfaces for LEMON.
392 497

	
393
This group describes Lp and Mip solver interfaces for LEMON. The
498
This group contains Lp and Mip solver interfaces for LEMON. The
394 499
various LP solvers could be used in the same manner with this
395 500
interface.
396 501
*/
397 502

	
398 503
/**
399 504
@defgroup lp_utils Tools for Lp and Mip Solvers
400 505
@ingroup lp_group
401 506
\brief Helper tools to the Lp and Mip solvers.
402 507

	
403 508
This group adds some helper tools to general optimization framework
404 509
implemented in LEMON.
405 510
*/
406 511

	
407 512
/**
408 513
@defgroup metah Metaheuristics
409 514
@ingroup gen_opt_group
410 515
\brief Metaheuristics for LEMON library.
411 516

	
412
This group describes some metaheuristic optimization tools.
517
This group contains some metaheuristic optimization tools.
413 518
*/
414 519

	
415 520
/**
416 521
@defgroup utils Tools and Utilities
417 522
\brief Tools and utilities for programming in LEMON
418 523

	
419 524
Tools and utilities for programming in LEMON.
420 525
*/
421 526

	
422 527
/**
423 528
@defgroup gutils Basic Graph Utilities
424 529
@ingroup utils
425 530
\brief Simple basic graph utilities.
426 531

	
427
This group describes some simple basic graph utilities.
532
This group contains some simple basic graph utilities.
428 533
*/
429 534

	
430 535
/**
431 536
@defgroup misc Miscellaneous Tools
432 537
@ingroup utils
433 538
\brief Tools for development, debugging and testing.
434 539

	
435
This group describes several useful tools for development,
540
This group contains several useful tools for development,
436 541
debugging and testing.
437 542
*/
438 543

	
439 544
/**
440 545
@defgroup timecount Time Measuring and Counting
441 546
@ingroup misc
442 547
\brief Simple tools for measuring the performance of algorithms.
443 548

	
444
This group describes simple tools for measuring the performance
549
This group contains simple tools for measuring the performance
445 550
of algorithms.
446 551
*/
447 552

	
448 553
/**
449 554
@defgroup exceptions Exceptions
450 555
@ingroup utils
451 556
\brief Exceptions defined in LEMON.
452 557

	
453
This group describes the exceptions defined in LEMON.
558
This group contains the exceptions defined in LEMON.
454 559
*/
455 560

	
456 561
/**
457 562
@defgroup io_group Input-Output
458 563
\brief Graph Input-Output methods
459 564

	
460
This group describes the tools for importing and exporting graphs
565
This group contains the tools for importing and exporting graphs
461 566
and graph related data. Now it supports the \ref lgf-format
462 567
"LEMON Graph Format", the \c DIMACS format and the encapsulated
463 568
postscript (EPS) format.
464 569
*/
465 570

	
466 571
/**
467
@defgroup lemon_io LEMON Input-Output
572
@defgroup lemon_io LEMON Graph Format
468 573
@ingroup io_group
469 574
\brief Reading and writing LEMON Graph Format.
470 575

	
471
This group describes methods for reading and writing
576
This group contains methods for reading and writing
472 577
\ref lgf-format "LEMON Graph Format".
473 578
*/
474 579

	
475 580
/**
476 581
@defgroup eps_io Postscript Exporting
477 582
@ingroup io_group
478 583
\brief General \c EPS drawer and graph exporter
479 584

	
480
This group describes general \c EPS drawing methods and special
585
This group contains general \c EPS drawing methods and special
481 586
graph exporting tools.
482 587
*/
483 588

	
484 589
/**
590
@defgroup dimacs_group DIMACS format
591
@ingroup io_group
592
\brief Read and write files in DIMACS format
593

	
594
Tools to read a digraph from or write it to a file in DIMACS format data.
595
*/
596

	
597
/**
598
@defgroup nauty_group NAUTY Format
599
@ingroup io_group
600
\brief Read \e Nauty format
601

	
602
Tool to read graphs from \e Nauty format data.
603
*/
604

	
605
/**
485 606
@defgroup concept Concepts
486 607
\brief Skeleton classes and concept checking classes
487 608

	
488
This group describes the data/algorithm skeletons and concept checking
609
This group contains the data/algorithm skeletons and concept checking
489 610
classes implemented in LEMON.
490 611

	
491 612
The purpose of the classes in this group is fourfold.
492 613

	
493 614
- These classes contain the documentations of the %concepts. In order
494 615
  to avoid document multiplications, an implementation of a concept
495 616
  simply refers to the corresponding concept class.
496 617

	
497 618
- These classes declare every functions, <tt>typedef</tt>s etc. an
498 619
  implementation of the %concepts should provide, however completely
499 620
  without implementations and real data structures behind the
500 621
  interface. On the other hand they should provide nothing else. All
501 622
  the algorithms working on a data structure meeting a certain concept
502 623
  should compile with these classes. (Though it will not run properly,
503 624
  of course.) In this way it is easily to check if an algorithm
504 625
  doesn't use any extra feature of a certain implementation.
505 626

	
506 627
- The concept descriptor classes also provide a <em>checker class</em>
507 628
  that makes it possible to check whether a certain implementation of a
508 629
  concept indeed provides all the required features.
509 630

	
510 631
- Finally, They can serve as a skeleton of a new implementation of a concept.
511 632
*/
512 633

	
513 634
/**
514 635
@defgroup graph_concepts Graph Structure Concepts
515 636
@ingroup concept
516 637
\brief Skeleton and concept checking classes for graph structures
517 638

	
518
This group describes the skeletons and concept checking classes of LEMON's
639
This group contains the skeletons and concept checking classes of LEMON's
519 640
graph structures and helper classes used to implement these.
520 641
*/
521 642

	
522 643
/**
523 644
@defgroup map_concepts Map Concepts
524 645
@ingroup concept
525 646
\brief Skeleton and concept checking classes for maps
526 647

	
527
This group describes the skeletons and concept checking classes of maps.
648
This group contains the skeletons and concept checking classes of maps.
528 649
*/
529 650

	
530 651
/**
531 652
\anchor demoprograms
532 653

	
533
@defgroup demos Demo programs
654
@defgroup demos Demo Programs
534 655

	
535 656
Some demo programs are listed here. Their full source codes can be found in
536 657
the \c demo subdirectory of the source tree.
537 658

	
538
It order to compile them, use <tt>--enable-demo</tt> configure option when
539
build the library.
659
In order to compile them, use the <tt>make demo</tt> or the
660
<tt>make check</tt> commands.
540 661
*/
541 662

	
542 663
/**
543
@defgroup tools Standalone utility applications
664
@defgroup tools Standalone Utility Applications
544 665

	
545 666
Some utility applications are listed here.
546 667

	
547 668
The standard compilation procedure (<tt>./configure;make</tt>) will compile
548 669
them, as well.
549 670
*/
550 671

	
672
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
namespace lemon {
20 20
/*!
21 21

	
22 22

	
23 23

	
24 24
\page lgf-format LEMON Graph Format (LGF)
25 25

	
26 26
The \e LGF is a <em>column oriented</em>
27 27
file format for storing graphs and associated data like
28 28
node and edge maps.
29 29

	
30 30
Each line with \c '#' first non-whitespace
31 31
character is considered as a comment line.
32 32

	
33 33
Otherwise the file consists of sections starting with
34 34
a header line. The header lines starts with an \c '@' character followed by the
35 35
type of section. The standard section types are \c \@nodes, \c
36 36
\@arcs and \c \@edges
37 37
and \@attributes. Each header line may also have an optional
38 38
\e name, which can be use to distinguish the sections of the same
39 39
type.
40 40

	
41 41
The standard sections are column oriented, each line consists of
42 42
<em>token</em>s separated by whitespaces. A token can be \e plain or
43 43
\e quoted. A plain token is just a sequence of non-whitespace characters,
44 44
while a quoted token is a
45 45
character sequence surrounded by double quotes, and it can also
46 46
contain whitespaces and escape sequences.
47 47

	
48 48
The \c \@nodes section describes a set of nodes and associated
49 49
maps. The first is a header line, its columns are the names of the
50 50
maps appearing in the following lines.
51 51
One of the maps must be called \c
52 52
"label", which plays special role in the file.
53 53
The following
54 54
non-empty lines until the next section describes nodes of the
55 55
graph. Each line contains the values of the node maps
56 56
associated to the current node.
57 57

	
58 58
\code
59 59
 @nodes
60 60
 label  coordinates  size    title
61 61
 1      (10,20)      10      "First node"
62 62
 2      (80,80)      8       "Second node"
63 63
 3      (40,10)      10      "Third node"
64 64
\endcode
65 65

	
66 66
The \c \@arcs section is very similar to the \c \@nodes section,
67 67
it again starts with a header line describing the names of the maps,
68 68
but the \c "label" map is not obligatory here. The following lines
69 69
describe the arcs. The first two tokens of each line are
70 70
the source and the target node of the arc, respectively, then come the map
71 71
values. The source and target tokens must be node labels.
72 72

	
73 73
\code
74 74
 @arcs
75 75
         capacity
76 76
 1   2   16
77 77
 1   3   12
78 78
 2   3   18
79 79
\endcode
80 80

	
81 81
The \c \@edges is just a synonym of \c \@arcs. The \@arcs section can
82 82
also store the edge set of an undirected graph. In such case there is
83 83
a conventional method for store arc maps in the file, if two columns
84 84
has the same caption with \c '+' and \c '-' prefix, then these columns
85 85
can be regarded as the values of an arc map.
86 86

	
87 87
The \c \@attributes section contains key-value pairs, each line
88 88
consists of two tokens, an attribute name, and then an attribute
89 89
value. The value of the attribute could be also a label value of a
90 90
node or an edge, or even an edge label prefixed with \c '+' or \c '-',
91 91
which regards to the forward or backward directed arc of the
92 92
corresponding edge.
93 93

	
94 94
\code
95 95
 @attributes
96 96
 source 1
97 97
 target 3
98 98
 caption "LEMON test digraph"
99 99
\endcode
100 100

	
101 101
The \e LGF can contain extra sections, but there is no restriction on
102 102
the format of such sections.
103 103

	
104 104
*/
105 105
}
106 106

	
107 107
//  LocalWords:  whitespace whitespaces
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
/**
20 20

	
21 21
\page license License Terms
22 22

	
23 23
\verbinclude LICENSE
24 24

	
25 25
*/
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
/**
20 20
\mainpage LEMON Documentation
21 21

	
22 22
\section intro Introduction
23 23

	
24 24
\subsection whatis What is LEMON
25 25

	
26
LEMON stands for
27
<b>L</b>ibrary of <b>E</b>fficient <b>M</b>odels
26
LEMON stands for <b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
28 27
and <b>O</b>ptimization in <b>N</b>etworks.
29 28
It is a C++ template
30 29
library aimed at combinatorial optimization tasks which
31 30
often involve in working
32 31
with graphs.
33 32

	
34 33
<b>
35 34
LEMON is an <a class="el" href="http://opensource.org/">open&nbsp;source</a>
36 35
project.
37 36
You are free to use it in your commercial or
38 37
non-commercial applications under very permissive
39 38
\ref license "license terms".
40 39
</b>
41 40

	
42 41
\subsection howtoread How to read the documentation
43 42

	
44
If you want to get a quick start and see the most important features then
45
take a look at our \ref quicktour
46
"Quick Tour to LEMON" which will guide you along.
43
If you would like to get to know the library, see
44
<a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
47 45

	
48
If you already feel like using our library, see the page that tells you
49
\ref getstart "How to start using LEMON".
50

	
51
If you
52
want to see how LEMON works, see
53
some \ref demoprograms "demo programs".
54

	
55
If you know what you are looking for then try to find it under the
56
<a class="el" href="modules.html">Modules</a>
57
section.
46
If you know what you are looking for, then try to find it under the
47
<a class="el" href="modules.html">Modules</a> section.
58 48

	
59 49
If you are a user of the old (0.x) series of LEMON, please check out the
60 50
\ref migration "Migration Guide" for the backward incompatibilities.
61 51
*/
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
namespace lemon {
20 20
/*!
21 21

	
22 22
\page migration Migration from the 0.x Series
23 23

	
24 24
This guide gives an in depth description on what has changed compared
25 25
to the 0.x release series.
26 26

	
27 27
Many of these changes adjusted automatically by the
28
<tt>script/lemon-0.x-to-1.x.sh</tt> tool. Those requiring manual
28
<tt>lemon-0.x-to-1.x.sh</tt> tool. Those requiring manual
29 29
update are typeset <b>boldface</b>.
30 30

	
31 31
\section migration-graph Graph Related Name Changes
32 32

	
33 33
- \ref concepts::Digraph "Directed graphs" are called \c Digraph and
34 34
  they have <tt>Arc</tt>s (instead of <tt>Edge</tt>s), while
35 35
  \ref concepts::Graph "undirected graphs" are called \c Graph
36 36
  (instead of \c UGraph) and they have <tt>Edge</tt>s (instead of
37 37
  <tt>UEdge</tt>s). These changes reflected thoroughly everywhere in
38 38
  the library. Namely,
39 39
  - \c Graph -> \c Digraph
40 40
    - \c %ListGraph -> \c ListDigraph, \c %SmartGraph -> \c SmartDigraph etc.
41 41
  - \c UGraph -> \c Graph
42 42
    - \c ListUGraph -> \c ListGraph, \c SmartUGraph -> \c SmartGraph etc.
43 43
  - \c Edge -> \c Arc, \c UEdge -> \c Edge
44 44
  - \c EdgeMap -> \c ArcMap, \c UEdgeMap -> \c EdgeMap
45 45
  - \c EdgeIt -> \c ArcIt, \c UEdgeIt -> \c EdgeIt
46 46
  - Class names and function names containing the words \c graph,
47 47
    \c ugraph, \e edge or \e arc should also be updated.
48 48
- <b>The two endpoints of an (\e undirected) \c Edge can be obtained by the
49 49
  <tt>u()</tt> and <tt>v()</tt> member function of the graph
50 50
  (instead of <tt>source()</tt> and <tt>target()</tt>). This change
51 51
  must be done by hand.</b>
52 52
  \n Of course, you can still use <tt>source()</tt> and <tt>target()</tt>
53 53
  for <tt>Arc</tt>s (directed edges).
54 54

	
55 55
\warning
56
<b>The <tt>script/lemon-0.x-to-1.x.sh</tt> tool replaces all instances of
57
the words \c graph, \c digraph, \c edge and \c arc, so it replaces them
58
in strings, comments etc. as well as in all identifiers.</b>
56
<b>The <tt>lemon-0.x-to-1.x.sh</tt> script replaces the words \c graph,
57
\c ugraph, \c edge and \c uedge in your own identifiers and in
58
strings, comments etc. as well as in all LEMON specific identifiers.
59
So use the script carefully and make a backup copy of your source files
60
before applying the script to them.</b>
59 61

	
60 62
\section migration-lgf LGF tools
61 63
 - The \ref lgf-format "LGF file format" has changed,
62 64
   <tt>\@nodeset</tt> has changed to <tt>\@nodes</tt>,
63 65
   <tt>\@edgeset</tt> and <tt>\@uedgeset</tt> to <tt>\@arcs</tt> or
64 66
   <tt>\@edges</tt>, which become completely equivalents. The
65 67
   <tt>\@nodes</tt>, <tt>\@edges</tt> and <tt>\@uedges</tt> sections are
66 68
   removed from the format, the content of them should be
67 69
   the part of <tt>\@attributes</tt> section. The data fields in
68 70
   the sections must follow a strict format, they must be either character
69 71
   sequences without whitespaces or quoted strings.
70 72
 - The <tt>LemonReader</tt> and <tt>LemonWriter</tt> core interfaces
71 73
   are no longer available.
72 74
 - The implementation of the general section readers and writers has changed
73 75
   they are simple functors now. Beside the old
74 76
   stream based section handling, currently line oriented section
75 77
   reading and writing are also supported. In the
76 78
   section readers the lines must be counted manually. The sections
77 79
   should be read and written with the SectionWriter and SectionReader
78 80
   classes.
79 81
 - Instead of the item readers and writers, item converters should be
80 82
   used. The converters are functors, which map the type to
81 83
   std::string or std::string to the type. The converters for standard
82 84
   containers hasn't yet been implemented in the new LEMON. The converters
83 85
   can return strings in any format, because if it is necessary, the LGF
84 86
   writer and reader will quote and unquote the given value.
85 87
 - The DigraphReader and DigraphWriter can used similarly to the
86 88
   0.x series, however the <tt>read</tt> or <tt>write</tt> prefix of
87 89
   the member functions are removed.
88 90
 - The new LEMON supports the function like interface, the \c
89 91
   digraphReader and \c digraphWriter functions are more convenient than
90 92
   using the classes directly.
91 93

	
92 94
\section migration-search BFS, DFS and Dijkstra
93 95
- <b>Using the function interface of BFS, DFS and %Dijkstra both source and
94 96
  target nodes can be given as parameters of the <tt>run()</tt> function
95 97
  (instead of \c bfs(), \c dfs() or \c dijkstra() itself).</b>
96 98
- \ref named-templ-param "Named class template parameters" of \c Bfs,
97 99
  \c Dfs, \c Dijkstra, \c BfsVisit, \c DfsVisit are renamed to start
98 100
  with "Set" instead of "Def". Namely,
99 101
  - \c DefPredMap -> \c SetPredMap
100 102
  - \c DefDistMap -> \c SetDistMap
101 103
  - \c DefReachedMap -> \c SetReachedMap
102 104
  - \c DefProcessedMap -> \c SetProcessedMap
103 105
  - \c DefHeap -> \c SetHeap
104 106
  - \c DefStandardHeap -> \c SetStandardHeap
105 107
  - \c DefOperationTraits -> \c SetOperationTraits
106 108
  - \c DefProcessedMapToBeDefaultMap -> \c SetStandardProcessedMap
107 109

	
108 110
\section migration-error Exceptions and Debug tools
109 111

	
110 112
<b>The class hierarchy of exceptions has largely been simplified. Now,
111 113
only the i/o related tools may throw exceptions. All other exceptions
112 114
have been replaced with either the \c LEMON_ASSERT or the \c LEMON_DEBUG
113 115
macros.</b>
114 116

	
115 117
<b>On the other hand, the parameter order of constructors of the
116 118
exceptions has been changed. See \ref IoError and \ref FormatError for
117 119
more details.</b>
118 120

	
119 121
\section migration-other Others
120 122
- <b>The contents of <tt>graph_utils.h</tt> are moved to <tt>core.h</tt>
121 123
  and <tt>maps.h</tt>. <tt>core.h</tt> is included by all graph types,
122 124
  therefore it usually do not have to be included directly.</b>
123 125
- <b><tt>path_utils.h</tt> is merged to \c path.h.</b>
124 126
- <b>The semantic of the assignment operations and copy constructors of maps
125 127
  are still under discussion. So, you must copy them by hand (i.e. copy
126 128
  each entry one-by-one)</b>
127 129
- <b>The parameters of the graph copying tools (i.e. \c GraphCopy,
128 130
  \c DigraphCopy) have to be given in the from-to order.</b>
129 131
- \c copyDigraph() and \c copyGraph() are renamed to \c digraphCopy()
130 132
  and \c graphCopy(), respectively.
131 133
- <b>The interface of \ref DynArcLookUp has changed. It is now the same as
132 134
  of \ref ArcLookUp and \ref AllArcLookUp</b>
133 135
- Some map types should also been renamed. Namely,
134 136
  - \c IntegerMap -> \c RangeMap
135 137
  - \c StdMap -> \c SparseMap
136 138
  - \c FunctorMap -> \c FunctorToMap
137 139
  - \c MapFunctor -> \c MapToFunctor
138 140
  - \c ForkWriteMap -> \c ForkMap
139 141
  - \c StoreBoolMap -> \c LoggerBoolMap
140 142
- \c dim2::BoundingBox -> \c dim2::Box
141 143

	
142 144
*/
143 145
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
/*!
20 20

	
21 21
\page named-param Named Parameters
22 22

	
23 23
\section named-func-param Named Function Parameters
24 24

	
25 25
Several modern languages provide a convenient way to refer the
26 26
function parameters by name also when you call the function. It is
27 27
especially comfortable in case of a function having tons of parameters
28 28
with natural default values. Sadly, C++ lack this amenity.
29 29

	
30 30
However, with a crafty trick and with some little
31 31
inconvenience, it is possible to emulate is.
32 32
The example below shows how to do it.
33 33

	
34 34
\code
35 35
class namedFn
36 36
{
37 37
  int _id;
38 38
  double _val;
39 39
  int _dim;
40 40

	
41 41
  public:
42 42
  namedFn() : _id(0), _val(1), _dim(2) {}
43 43
  namedFn& id(int p)     { _id  = p ; return *this; }
44 44
  namedFn& val(double p) { _val = p ; return *this; }
45 45
  namedFn& dim(int p)    { _dim = p ; return *this; }
46 46

	
47 47
  run() {
48 48
    std::cout << "Here comes the function itself\n" <<
49 49
              << "With parameters "
50 50
              << _id << ", " << _val << ", " << _dim << std::endl;
51 51
  }
52 52
};
53 53
\endcode
54 54

	
55 55
Then you can use it like this.
56 56

	
57 57
\code
58 58
namedFn().id(3).val(2).run();
59 59
\endcode
60 60

	
61 61
The trick is obvious, each "named parameter" changes one component of
62 62
the underlying class, then gives back a reference to it. Finally,
63 63
<tt>run()</tt> executes the algorithm itself.
64 64

	
65 65
\note Although it is a class, namedFn is used pretty much like as it were
66 66
a function. That it why we called it namedFn instead of \c NamedFn.
67 67

	
68 68
\note In fact, the final <tt>.run()</tt> could be made unnecessary,
69 69
because the algorithm could also be implemented in the destructor of
70 70
\c namedFn instead. This however would make it impossible to implement
71 71
functions with return values, and would also cause serious problems when
72 72
implementing \ref named-templ-func-param "named template parameters".
73 73
<b>Therefore, by convention, <tt>.run()</tt> must be used
74 74
explicitly to execute a function having named parameters
75 75
everywhere in LEMON.</b>
76 76

	
77 77
\section named-templ-func-param Named Function Template Parameters
78 78

	
79 79
A named parameter can also be a template function. The usage is
80 80
exactly the same, but the implementation behind is a kind of black
81 81
magic and they are the dirtiest part of the LEMON code.
82 82

	
83 83
You will probably never need to know how it works, but if you really
84 84
committed, have a look at \ref lemon/graph_to_eps.h for an example.
85 85

	
86 86
\section traits-classes Traits Classes
87 87

	
88 88
A similar game can also be played when defining classes. In this case
89 89
the type of the class attributes can be changed. Initially we have to
90 90
define a special class called <em>Traits Class</em> defining the
91 91
default type of the attributes. Then the types of these attributes can
92 92
be changed in the same way as described in the next section.
93 93

	
94 94
See \ref lemon::DijkstraDefaultTraits for an
95 95
example how a traits class implementation looks like.
96 96

	
97 97
\section named-templ-param Named Class Template Parameters
98 98

	
99 99
If we would like to change the type of an attribute in a class that
100 100
was instantiated by using a traits class as a template parameter, and
101 101
the class contains named parameters, we do not have to instantiate again
102 102
the class with new traits class, but instead adaptor classes can
103 103
be used as shown in the following example.
104 104

	
105 105
\code
106 106
Dijkstra<>::SetPredMap<NullMap<Node,Arc> >::Create
107 107
\endcode
108 108

	
109 109
It can also be used in conjunction with other named template
110 110
parameters in arbitrary order.
111 111

	
112 112
\code
113 113
Dijkstra<>::SetDistMap<MyMap>::SetPredMap<NullMap<Node,Arc> >::Create
114 114
\endcode
115 115

	
116 116
The result will be an instantiated Dijkstra class, in which the
117 117
DistMap and the PredMap is modified.
118 118

	
119 119
*/
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
/// The namespace of LEMON
20 20

	
21 21
/// The namespace of LEMON
22 22
///
23 23
namespace lemon {
24 24

	
25 25
  /// The namespace of LEMON concepts and concept checking classes
26 26

	
27 27
  /// The namespace of LEMON concepts and concept checking classes
28 28
  ///
29 29
  namespace concepts {}
30 30
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_TEMPLATE_H
20 20
#define LEMON_TEMPLATE_H
21 21

	
22 22
#endif // LEMON_TEMPLATE_H
Ignore white space 6 line context
1 1
INCLUDE_DIRECTORIES(
2
  ${CMAKE_SOURCE_DIR}
2
  ${PROJECT_SOURCE_DIR}
3 3
  ${PROJECT_BINARY_DIR}
4 4
)
5 5

	
6 6
CONFIGURE_FILE(
7 7
  ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
8 8
  ${CMAKE_CURRENT_BINARY_DIR}/config.h
9 9
)
10 10

	
11
ADD_LIBRARY(lemon
11
SET(LEMON_SOURCES
12 12
  arg_parser.cc
13 13
  base.cc
14 14
  color.cc
15
  lp_base.cc
16
  lp_skeleton.cc
15 17
  random.cc
16 18
  bits/windows.cc
17 19
)
18 20

	
21
IF(LEMON_HAVE_GLPK)
22
  SET(LEMON_SOURCES ${LEMON_SOURCES} glpk.cc)
23
  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIRS})
24
  IF(WIN32)
25
    INSTALL(FILES ${GLPK_BIN_DIR}/glpk.dll DESTINATION bin)
26
    INSTALL(FILES ${GLPK_BIN_DIR}/libltdl3.dll DESTINATION bin)
27
    INSTALL(FILES ${GLPK_BIN_DIR}/zlib1.dll DESTINATION bin)
28
  ENDIF()
29
ENDIF()
30

	
31
IF(LEMON_HAVE_CPLEX)
32
  SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc)
33
  INCLUDE_DIRECTORIES(${CPLEX_INCLUDE_DIRS})
34
ENDIF()
35

	
36
IF(LEMON_HAVE_CLP)
37
  SET(LEMON_SOURCES ${LEMON_SOURCES} clp.cc)
38
  INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
39
ENDIF()
40

	
41
IF(LEMON_HAVE_CBC)
42
  SET(LEMON_SOURCES ${LEMON_SOURCES} cbc.cc)
43
  INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
44
ENDIF()
45

	
46
ADD_LIBRARY(lemon ${LEMON_SOURCES})
47
IF(UNIX)
48
  SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon)
49
ENDIF()
50

	
19 51
INSTALL(
20 52
  TARGETS lemon
21 53
  ARCHIVE DESTINATION lib
22
  COMPONENT library)
54
  COMPONENT library
55
)
23 56

	
24 57
INSTALL(
25 58
  DIRECTORY . bits concepts
26 59
  DESTINATION include/lemon
27 60
  COMPONENT headers
28
  FILES_MATCHING PATTERN "*.h")
61
  FILES_MATCHING PATTERN "*.h"
62
)
29 63

	
30 64
INSTALL(
31 65
  FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h
32 66
  DESTINATION include/lemon
33
  COMPONENT headers)
67
  COMPONENT headers
68
)
Ignore white space 6 line context
1 1
EXTRA_DIST += \
2 2
	lemon/lemon.pc.in \
3
	lemon/CMakeLists.txt
3
	lemon/CMakeLists.txt \
4
	lemon/config.h.cmake
4 5

	
5 6
pkgconfig_DATA += lemon/lemon.pc
6 7

	
7 8
lib_LTLIBRARIES += lemon/libemon.la
8 9

	
9 10
lemon_libemon_la_SOURCES = \
10
        lemon/arg_parser.cc \
11
        lemon/base.cc \
12
        lemon/color.cc \
13
        lemon/random.cc \
11
	lemon/arg_parser.cc \
12
	lemon/base.cc \
13
	lemon/color.cc \
14
	lemon/lp_base.cc \
15
	lemon/lp_skeleton.cc \
16
	lemon/random.cc \
14 17
	lemon/bits/windows.cc
15 18

	
16
#lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS)
17
#lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
19
nodist_lemon_HEADERS = lemon/config.h	
18 20

	
19
nodist_lemon_HEADERS = lemon/config.h
21
lemon_libemon_la_CXXFLAGS = \
22
	$(AM_CXXFLAGS) \
23
	$(GLPK_CFLAGS) \
24
	$(CPLEX_CFLAGS) \
25
	$(SOPLEX_CXXFLAGS) \
26
	$(CLP_CXXFLAGS) \
27
	$(CBC_CXXFLAGS)
28

	
29
lemon_libemon_la_LDFLAGS = \
30
	$(GLPK_LIBS) \
31
	$(CPLEX_LIBS) \
32
	$(SOPLEX_LIBS) \
33
	$(CLP_LIBS) \
34
	$(CBC_LIBS)
35

	
36
if HAVE_GLPK
37
lemon_libemon_la_SOURCES += lemon/glpk.cc
38
endif
39

	
40
if HAVE_CPLEX
41
lemon_libemon_la_SOURCES += lemon/cplex.cc
42
endif
43

	
44
if HAVE_SOPLEX
45
lemon_libemon_la_SOURCES += lemon/soplex.cc
46
endif
47

	
48
if HAVE_CLP
49
lemon_libemon_la_SOURCES += lemon/clp.cc
50
endif
51

	
52
if HAVE_CBC
53
lemon_libemon_la_SOURCES += lemon/cbc.cc
54
endif
20 55

	
21 56
lemon_HEADERS += \
22
        lemon/arg_parser.h \
57
	lemon/adaptors.h \
58
	lemon/arg_parser.h \
23 59
	lemon/assert.h \
24
        lemon/bfs.h \
25
        lemon/bin_heap.h \
26
        lemon/color.h \
60
	lemon/bfs.h \
61
	lemon/bin_heap.h \
62
	lemon/bucket_heap.h \
63
	lemon/cbc.h \
64
	lemon/circulation.h \
65
	lemon/clp.h \
66
	lemon/color.h \
27 67
	lemon/concept_check.h \
28
        lemon/counter.h \
68
	lemon/connectivity.h \
69
	lemon/counter.h \
29 70
	lemon/core.h \
30
        lemon/dfs.h \
31
        lemon/dijkstra.h \
32
        lemon/dim2.h \
71
	lemon/cplex.h \
72
	lemon/dfs.h \
73
	lemon/dijkstra.h \
74
	lemon/dim2.h \
75
	lemon/dimacs.h \
76
	lemon/edge_set.h \
77
	lemon/elevator.h \
33 78
	lemon/error.h \
34
        lemon/graph_to_eps.h \
79
	lemon/euler.h \
80
	lemon/fib_heap.h \
81
	lemon/full_graph.h \
82
	lemon/glpk.h \
83
	lemon/gomory_hu.h \
84
	lemon/graph_to_eps.h \
85
	lemon/grid_graph.h \
86
	lemon/hypercube_graph.h \
35 87
	lemon/kruskal.h \
88
	lemon/hao_orlin.h \
36 89
	lemon/lgf_reader.h \
37 90
	lemon/lgf_writer.h \
38 91
	lemon/list_graph.h \
92
	lemon/lp.h \
93
	lemon/lp_base.h \
94
	lemon/lp_skeleton.h \
95
	lemon/list_graph.h \
39 96
	lemon/maps.h \
97
	lemon/matching.h \
40 98
	lemon/math.h \
99
	lemon/min_cost_arborescence.h \
100
	lemon/nauty_reader.h \
101
	lemon/network_simplex.h \
41 102
	lemon/path.h \
42
        lemon/random.h \
103
	lemon/preflow.h \
104
	lemon/radix_heap.h \
105
	lemon/radix_sort.h \
106
	lemon/random.h \
43 107
	lemon/smart_graph.h \
44
        lemon/time_measure.h \
45
        lemon/tolerance.h \
108
	lemon/soplex.h \
109
	lemon/suurballe.h \
110
	lemon/time_measure.h \
111
	lemon/tolerance.h \
46 112
	lemon/unionfind.h \
47 113
	lemon/bits/windows.h
48 114

	
49 115
bits_HEADERS += \
50 116
	lemon/bits/alteration_notifier.h \
51 117
	lemon/bits/array_map.h \
52
	lemon/bits/base_extender.h \
53
        lemon/bits/bezier.h \
118
	lemon/bits/bezier.h \
54 119
	lemon/bits/default_map.h \
55
        lemon/bits/enable_if.h \
120
	lemon/bits/edge_set_extender.h \
121
	lemon/bits/enable_if.h \
122
	lemon/bits/graph_adaptor_extender.h \
56 123
	lemon/bits/graph_extender.h \
57 124
	lemon/bits/map_extender.h \
58 125
	lemon/bits/path_dump.h \
126
	lemon/bits/solver_bits.h \
59 127
	lemon/bits/traits.h \
128
	lemon/bits/variant.h \
60 129
	lemon/bits/vector_map.h
61 130

	
62 131
concept_HEADERS += \
63 132
	lemon/concepts/digraph.h \
64 133
	lemon/concepts/graph.h \
65 134
	lemon/concepts/graph_components.h \
66 135
	lemon/concepts/heap.h \
67 136
	lemon/concepts/maps.h \
68 137
	lemon/concepts/path.h
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/arg_parser.h>
20 20

	
21 21
namespace lemon {
22 22

	
23 23
  void ArgParser::_showHelp(void *p)
24 24
  {
25 25
    (static_cast<ArgParser*>(p))->showHelp();
26 26
    exit(1);
27 27
  }
28 28

	
29 29
  ArgParser::ArgParser(int argc, const char * const *argv)
30 30
    :_argc(argc), _argv(argv), _command_name(argv[0]) {
31 31
    funcOption("-help","Print a short help message",_showHelp,this);
32 32
    synonym("help","-help");
33 33
    synonym("h","-help");
34 34
  }
35 35

	
36 36
  ArgParser::~ArgParser()
37 37
  {
38 38
    for(Opts::iterator i=_opts.begin();i!=_opts.end();++i)
39 39
      if(i->second.self_delete)
40 40
        switch(i->second.type) {
41 41
        case BOOL:
42 42
          delete i->second.bool_p;
43 43
          break;
44 44
        case STRING:
45 45
          delete i->second.string_p;
46 46
          break;
47 47
        case DOUBLE:
48 48
          delete i->second.double_p;
49 49
          break;
50 50
        case INTEGER:
51 51
          delete i->second.int_p;
52 52
          break;
53 53
        case UNKNOWN:
54 54
          break;
55 55
        case FUNC:
56 56
          break;
57 57
        }
58 58
  }
59 59

	
60 60

	
61 61
  ArgParser &ArgParser::intOption(const std::string &name,
62 62
                               const std::string &help,
63 63
                               int value, bool obl)
64 64
  {
65 65
    ParData p;
66 66
    p.int_p=new int(value);
67 67
    p.self_delete=true;
68 68
    p.help=help;
69 69
    p.type=INTEGER;
70 70
    p.mandatory=obl;
71 71
    _opts[name]=p;
72 72
    return *this;
73 73
  }
74 74

	
75 75
  ArgParser &ArgParser::doubleOption(const std::string &name,
76 76
                               const std::string &help,
77 77
                               double value, bool obl)
78 78
  {
79 79
    ParData p;
80 80
    p.double_p=new double(value);
81 81
    p.self_delete=true;
82 82
    p.help=help;
83 83
    p.type=DOUBLE;
84 84
    p.mandatory=obl;
85 85
    _opts[name]=p;
86 86
    return *this;
87 87
  }
88 88

	
89 89
  ArgParser &ArgParser::boolOption(const std::string &name,
90 90
                               const std::string &help,
91 91
                               bool value, bool obl)
92 92
  {
93 93
    ParData p;
94 94
    p.bool_p=new bool(value);
95 95
    p.self_delete=true;
96 96
    p.help=help;
97 97
    p.type=BOOL;
98 98
    p.mandatory=obl;
99 99
    _opts[name]=p;
100 100
    return *this;
101 101
  }
102 102

	
103 103
  ArgParser &ArgParser::stringOption(const std::string &name,
104 104
                               const std::string &help,
105 105
                               std::string value, bool obl)
106 106
  {
107 107
    ParData p;
108 108
    p.string_p=new std::string(value);
109 109
    p.self_delete=true;
110 110
    p.help=help;
111 111
    p.type=STRING;
112 112
    p.mandatory=obl;
113 113
    _opts[name]=p;
114 114
    return *this;
115 115
  }
116 116

	
117 117
  ArgParser &ArgParser::refOption(const std::string &name,
118 118
                               const std::string &help,
119 119
                               int &ref, bool obl)
120 120
  {
121 121
    ParData p;
122 122
    p.int_p=&ref;
123 123
    p.self_delete=false;
124 124
    p.help=help;
125 125
    p.type=INTEGER;
126 126
    p.mandatory=obl;
127 127
    _opts[name]=p;
128 128
    return *this;
129 129
  }
130 130

	
131 131
  ArgParser &ArgParser::refOption(const std::string &name,
132 132
                                  const std::string &help,
133 133
                                  double &ref, bool obl)
134 134
  {
135 135
    ParData p;
136 136
    p.double_p=&ref;
137 137
    p.self_delete=false;
138 138
    p.help=help;
139 139
    p.type=DOUBLE;
140 140
    p.mandatory=obl;
141 141
    _opts[name]=p;
142 142
    return *this;
143 143
  }
144 144

	
145 145
  ArgParser &ArgParser::refOption(const std::string &name,
146 146
                                  const std::string &help,
147 147
                                  bool &ref, bool obl)
148 148
  {
149 149
    ParData p;
150 150
    p.bool_p=&ref;
151 151
    p.self_delete=false;
152 152
    p.help=help;
153 153
    p.type=BOOL;
154 154
    p.mandatory=obl;
155 155
    _opts[name]=p;
156 156

	
157 157
    ref = false;
158 158

	
159 159
    return *this;
160 160
  }
161 161

	
162 162
  ArgParser &ArgParser::refOption(const std::string &name,
163 163
                               const std::string &help,
164 164
                               std::string &ref, bool obl)
165 165
  {
166 166
    ParData p;
167 167
    p.string_p=&ref;
168 168
    p.self_delete=false;
169 169
    p.help=help;
170 170
    p.type=STRING;
171 171
    p.mandatory=obl;
172 172
    _opts[name]=p;
173 173
    return *this;
174 174
  }
175 175

	
176 176
  ArgParser &ArgParser::funcOption(const std::string &name,
177 177
                               const std::string &help,
178 178
                               void (*func)(void *),void *data)
179 179
  {
180 180
    ParData p;
181 181
    p.func_p.p=func;
182 182
    p.func_p.data=data;
183 183
    p.self_delete=false;
184 184
    p.help=help;
185 185
    p.type=FUNC;
186 186
    p.mandatory=false;
187 187
    _opts[name]=p;
188 188
    return *this;
189 189
  }
190 190

	
191 191
  ArgParser &ArgParser::optionGroup(const std::string &group,
192 192
                                    const std::string &opt)
193 193
  {
194 194
    Opts::iterator i = _opts.find(opt);
195 195
    LEMON_ASSERT(i!=_opts.end(), "Unknown option: '"+opt+"'");
196 196
    LEMON_ASSERT(!(i->second.ingroup),
197 197
                 "Option already in option group: '"+opt+"'");
198 198
    GroupData &g=_groups[group];
199 199
    g.opts.push_back(opt);
200 200
    i->second.ingroup=true;
201 201
    return *this;
202 202
  }
203 203

	
204 204
  ArgParser &ArgParser::onlyOneGroup(const std::string &group)
205 205
  {
206 206
    GroupData &g=_groups[group];
207 207
    g.only_one=true;
208 208
    return *this;
209 209
  }
210 210

	
211 211
  ArgParser &ArgParser::synonym(const std::string &syn,
212 212
                                const std::string &opt)
213 213
  {
214 214
    Opts::iterator o = _opts.find(opt);
215 215
    Opts::iterator s = _opts.find(syn);
216 216
    LEMON_ASSERT(o!=_opts.end(), "Unknown option: '"+opt+"'");
217 217
    LEMON_ASSERT(s==_opts.end(), "Option already used: '"+syn+"'");
218 218
    ParData p;
219 219
    p.help=opt;
220 220
    p.mandatory=false;
221 221
    p.syn=true;
222 222
    _opts[syn]=p;
223 223
    o->second.has_syn=true;
224 224
    return *this;
225 225
  }
226 226

	
227 227
  ArgParser &ArgParser::mandatoryGroup(const std::string &group)
228 228
  {
229 229
    GroupData &g=_groups[group];
230 230
    g.mandatory=true;
231 231
    return *this;
232 232
  }
233 233

	
234 234
  ArgParser &ArgParser::other(const std::string &name,
235 235
                              const std::string &help)
236 236
  {
237 237
    _others_help.push_back(OtherArg(name,help));
238 238
    return *this;
239 239
  }
240 240

	
241 241
  void ArgParser::show(std::ostream &os,Opts::const_iterator i) const
242 242
  {
243 243
    os << "-" << i->first;
244 244
    if(i->second.has_syn)
245 245
      for(Opts::const_iterator j=_opts.begin();j!=_opts.end();++j)
246 246
        if(j->second.syn&&j->second.help==i->first)
247 247
          os << "|-" << j->first;
248 248
    switch(i->second.type) {
249 249
    case STRING:
250 250
      os << " str";
251 251
      break;
252 252
    case INTEGER:
253 253
      os << " int";
254 254
      break;
255 255
    case DOUBLE:
256 256
      os << " num";
257 257
      break;
258 258
    default:
259 259
      break;
260 260
    }
261 261
  }
262 262

	
263 263
  void ArgParser::show(std::ostream &os,Groups::const_iterator i) const
264 264
  {
265 265
    GroupData::Opts::const_iterator o=i->second.opts.begin();
266 266
    while(o!=i->second.opts.end()) {
267 267
      show(os,_opts.find(*o));
268 268
      ++o;
269 269
      if(o!=i->second.opts.end()) os<<'|';
270 270
    }
271 271
  }
272 272

	
273 273
  void ArgParser::showHelp(Opts::const_iterator i) const
274 274
  {
275 275
    if(i->second.help.size()==0||i->second.syn) return;
276 276
    std::cerr << "  ";
277 277
    show(std::cerr,i);
278 278
    std::cerr << std::endl;
279 279
    std::cerr << "     " << i->second.help << std::endl;
280 280
  }
281 281
  void ArgParser::showHelp(std::vector<ArgParser::OtherArg>::const_iterator i)
282 282
    const
283 283
  {
284 284
    if(i->help.size()==0) return;
285 285
    std::cerr << "  " << i->name << std::endl
286 286
              << "     " << i->help << std::endl;
287 287
  }
288 288

	
289 289
  void ArgParser::shortHelp() const
290 290
  {
291 291
    const unsigned int LINE_LEN=77;
292 292
    const std::string indent("    ");
293 293
    std::cerr << "Usage:\n  " << _command_name;
294 294
    int pos=_command_name.size()+2;
295 295
    for(Groups::const_iterator g=_groups.begin();g!=_groups.end();++g) {
296 296
      std::ostringstream cstr;
297 297
      cstr << ' ';
298 298
      if(!g->second.mandatory) cstr << '[';
299 299
      show(cstr,g);
300 300
      if(!g->second.mandatory) cstr << ']';
301 301
      if(pos+cstr.str().size()>LINE_LEN) {
302 302
        std::cerr << std::endl << indent;
303 303
        pos=indent.size();
304 304
      }
305 305
      std::cerr << cstr.str();
306 306
      pos+=cstr.str().size();
307 307
    }
308 308
    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i)
309 309
      if(!i->second.ingroup&&!i->second.syn) {
310 310
        std::ostringstream cstr;
311 311
        cstr << ' ';
312 312
        if(!i->second.mandatory) cstr << '[';
313 313
        show(cstr,i);
314 314
        if(!i->second.mandatory) cstr << ']';
315 315
        if(pos+cstr.str().size()>LINE_LEN) {
316 316
          std::cerr << std::endl << indent;
317 317
          pos=indent.size();
318 318
        }
319 319
        std::cerr << cstr.str();
320 320
        pos+=cstr.str().size();
321 321
      }
322 322
    for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
323 323
        i!=_others_help.end();++i)
324 324
      {
325 325
        std::ostringstream cstr;
326 326
        cstr << ' ' << i->name;
327 327

	
328 328
        if(pos+cstr.str().size()>LINE_LEN) {
329 329
          std::cerr << std::endl << indent;
330 330
          pos=indent.size();
331 331
        }
332 332
        std::cerr << cstr.str();
333 333
        pos+=cstr.str().size();
334 334
      }
335 335
    std::cerr << std::endl;
336 336
  }
337 337

	
338 338
  void ArgParser::showHelp() const
339 339
  {
340 340
    shortHelp();
341 341
    std::cerr << "Where:\n";
342 342
    for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
343 343
        i!=_others_help.end();++i) showHelp(i);
344 344
    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
345 345
    exit(1);
346 346
  }
347 347

	
348 348

	
349 349
  void ArgParser::unknownOpt(std::string arg) const
350 350
  {
351 351
    std::cerr << "\nUnknown option: " << arg << "\n";
352 352
    std::cerr << "\nType '" << _command_name <<
353 353
      " --help' to obtain a short summary on the usage.\n\n";
354 354
    exit(1);
355 355
  }
356 356

	
357 357
  void ArgParser::requiresValue(std::string arg, OptType t) const
358 358
  {
359 359
    std::cerr << "Argument '" << arg << "' requires a";
360 360
    switch(t) {
361 361
    case STRING:
362 362
      std::cerr << " string";
363 363
      break;
364 364
    case INTEGER:
365 365
      std::cerr << "n integer";
366 366
      break;
367 367
    case DOUBLE:
368 368
      std::cerr << " floating point";
369 369
      break;
370 370
    default:
371 371
      break;
372 372
    }
373 373
    std::cerr << " value\n\n";
374 374
    showHelp();
375 375
  }
376 376

	
377 377

	
378 378
  void ArgParser::checkMandatories() const
379 379
  {
380 380
    bool ok=true;
381 381
    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i)
382 382
      if(i->second.mandatory&&!i->second.set)
383 383
        {
384 384
          if(ok)
385 385
            std::cerr << _command_name
386 386
                      << ": The following mandatory arguments are missing.\n";
387 387
          ok=false;
388 388
          showHelp(i);
389 389
        }
390 390
    for(Groups::const_iterator i=_groups.begin();i!=_groups.end();++i)
391 391
      if(i->second.mandatory||i->second.only_one)
392 392
        {
393 393
          int set=0;
394 394
          for(GroupData::Opts::const_iterator o=i->second.opts.begin();
395 395
              o!=i->second.opts.end();++o)
396 396
            if(_opts.find(*o)->second.set) ++set;
397 397
          if(i->second.mandatory&&!set) {
398 398
            std::cerr << _command_name <<
399 399
              ": At least one of the following arguments is mandatory.\n";
400 400
            ok=false;
401 401
            for(GroupData::Opts::const_iterator o=i->second.opts.begin();
402 402
                o!=i->second.opts.end();++o)
403 403
              showHelp(_opts.find(*o));
404 404
          }
405 405
          if(i->second.only_one&&set>1) {
406 406
            std::cerr << _command_name <<
407 407
              ": At most one of the following arguments can be given.\n";
408 408
            ok=false;
409 409
            for(GroupData::Opts::const_iterator o=i->second.opts.begin();
410 410
                o!=i->second.opts.end();++o)
411 411
              showHelp(_opts.find(*o));
412 412
          }
413 413
        }
414 414
    if(!ok) {
415 415
      std::cerr << "\nType '" << _command_name <<
416 416
        " --help' to obtain a short summary on the usage.\n\n";
417 417
      exit(1);
418 418
    }
419 419
  }
420 420

	
421 421
  ArgParser &ArgParser::parse()
422 422
  {
423 423
    for(int ar=1; ar<_argc; ++ar) {
424 424
      std::string arg(_argv[ar]);
425 425
      if (arg[0] != '-' || arg.size() == 1) {
426 426
        _file_args.push_back(arg);
427 427
      }
428 428
      else {
429 429
        Opts::iterator i = _opts.find(arg.substr(1));
430 430
        if(i==_opts.end()) unknownOpt(arg);
431 431
        else {
432 432
          if(i->second.syn) i=_opts.find(i->second.help);
433 433
          ParData &p(i->second);
434 434
          if (p.type==BOOL) *p.bool_p=true;
435 435
          else if (p.type==FUNC) p.func_p.p(p.func_p.data);
436 436
          else if(++ar==_argc) requiresValue(arg, p.type);
437 437
          else {
438 438
            std::string val(_argv[ar]);
439 439
            std::istringstream vals(val);
440 440
            switch(p.type) {
441 441
            case STRING:
442 442
              *p.string_p=val;
443 443
              break;
444 444
            case INTEGER:
445 445
              vals >> *p.int_p;
446 446
              break;
447 447
            case DOUBLE:
448 448
              vals >> *p.double_p;
449 449
              break;
450 450
            default:
451 451
              break;
452 452
            }
453 453
            if(p.type!=STRING&&(!vals||!vals.eof()))
454 454
              requiresValue(arg, p.type);
455 455
          }
456 456
          p.set = true;
457 457
        }
458 458
      }
459 459
    }
460 460
    checkMandatories();
461 461

	
462 462
    return *this;
463 463
  }
464 464

	
465 465
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_ARG_PARSER_H
20 20
#define LEMON_ARG_PARSER_H
21 21

	
22 22
#include <vector>
23 23
#include <map>
24 24
#include <list>
25 25
#include <string>
26 26
#include <iostream>
27 27
#include <sstream>
28 28
#include <algorithm>
29 29
#include <lemon/assert.h>
30 30

	
31 31
///\ingroup misc
32 32
///\file
33 33
///\brief A tool to parse command line arguments.
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  ///Command line arguments parser
38 38

	
39 39
  ///\ingroup misc
40 40
  ///Command line arguments parser.
41 41
  ///
42 42
  ///For a complete example see the \ref arg_parser_demo.cc demo file.
43 43
  class ArgParser {
44 44

	
45 45
    static void _showHelp(void *p);
46 46
  protected:
47 47

	
48 48
    int _argc;
49 49
    const char * const *_argv;
50 50

	
51 51
    enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
52 52

	
53 53
    class ParData {
54 54
    public:
55 55
      union {
56 56
        bool *bool_p;
57 57
        int *int_p;
58 58
        double *double_p;
59 59
        std::string *string_p;
60 60
        struct {
61 61
          void (*p)(void *);
62 62
          void *data;
63 63
        } func_p;
64 64

	
65 65
      };
66 66
      std::string help;
67 67
      bool mandatory;
68 68
      OptType type;
69 69
      bool set;
70 70
      bool ingroup;
71 71
      bool has_syn;
72 72
      bool syn;
73 73
      bool self_delete;
74 74
      ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
75 75
                  has_syn(false), syn(false), self_delete(false) {}
76 76
    };
77 77

	
78 78
    typedef std::map<std::string,ParData> Opts;
79 79
    Opts _opts;
80 80

	
81 81
    class GroupData
82 82
    {
83 83
    public:
84 84
      typedef std::list<std::string> Opts;
85 85
      Opts opts;
86 86
      bool only_one;
87 87
      bool mandatory;
88 88
      GroupData() :only_one(false), mandatory(false) {}
89 89
    };
90 90

	
91 91
    typedef std::map<std::string,GroupData> Groups;
92 92
    Groups _groups;
93 93

	
94 94
    struct OtherArg
95 95
    {
96 96
      std::string name;
97 97
      std::string help;
98 98
      OtherArg(std::string n, std::string h) :name(n), help(h) {}
99 99

	
100 100
    };
101 101

	
102 102
    std::vector<OtherArg> _others_help;
103 103
    std::vector<std::string> _file_args;
104 104
    std::string _command_name;
105 105

	
106 106

	
107 107
  private:
108 108
    //Bind a function to an option.
109 109

	
110 110
    //\param name The name of the option. The leading '-' must be omitted.
111 111
    //\param help A help string.
112 112
    //\retval func The function to be called when the option is given. It
113 113
    //  must be of type "void f(void *)"
114 114
    //\param data Data to be passed to \c func
115 115
    ArgParser &funcOption(const std::string &name,
116 116
                    const std::string &help,
117 117
                    void (*func)(void *),void *data);
118 118

	
119 119
  public:
120 120

	
121 121
    ///Constructor
122 122
    ArgParser(int argc, const char * const *argv);
123 123

	
124 124
    ~ArgParser();
125 125

	
126 126
    ///\name Options
127 127
    ///
128 128

	
129 129
    ///@{
130 130

	
131 131
    ///Add a new integer type option
132 132

	
133 133
    ///Add a new integer type option.
134 134
    ///\param name The name of the option. The leading '-' must be omitted.
135 135
    ///\param help A help string.
136 136
    ///\param value A default value for the option.
137 137
    ///\param obl Indicate if the option is mandatory.
138 138
    ArgParser &intOption(const std::string &name,
139 139
                    const std::string &help,
140 140
                    int value=0, bool obl=false);
141 141

	
142 142
    ///Add a new floating point type option
143 143

	
144 144
    ///Add a new floating point type option.
145 145
    ///\param name The name of the option. The leading '-' must be omitted.
146 146
    ///\param help A help string.
147 147
    ///\param value A default value for the option.
148 148
    ///\param obl Indicate if the option is mandatory.
149 149
    ArgParser &doubleOption(const std::string &name,
150 150
                      const std::string &help,
151 151
                      double value=0, bool obl=false);
152 152

	
153 153
    ///Add a new bool type option
154 154

	
155 155
    ///Add a new bool type option.
156 156
    ///\param name The name of the option. The leading '-' must be omitted.
157 157
    ///\param help A help string.
158 158
    ///\param value A default value for the option.
159 159
    ///\param obl Indicate if the option is mandatory.
160 160
    ///\note A mandatory bool obtion is of very little use.
161 161
    ArgParser &boolOption(const std::string &name,
162 162
                      const std::string &help,
163 163
                      bool value=false, bool obl=false);
164 164

	
165 165
    ///Add a new string type option
166 166

	
167 167
    ///Add a new string type option.
168 168
    ///\param name The name of the option. The leading '-' must be omitted.
169 169
    ///\param help A help string.
170 170
    ///\param value A default value for the option.
171 171
    ///\param obl Indicate if the option is mandatory.
172 172
    ArgParser &stringOption(const std::string &name,
173 173
                      const std::string &help,
174 174
                      std::string value="", bool obl=false);
175 175

	
176 176
    ///Give help string for non-parsed arguments.
177 177

	
178 178
    ///With this function you can give help string for non-parsed arguments.
179 179
    ///The parameter \c name will be printed in the short usage line, while
180 180
    ///\c help gives a more detailed description.
181 181
    ArgParser &other(const std::string &name,
182 182
                     const std::string &help="");
183 183

	
184 184
    ///@}
185 185

	
186 186
    ///\name Options with External Storage
187 187
    ///Using this functions, the value of the option will be directly written
188 188
    ///into a variable once the option appears in the command line.
189 189

	
190 190
    ///@{
191 191

	
192 192
    ///Add a new integer type option with a storage reference
193 193

	
194 194
    ///Add a new integer type option with a storage reference.
195 195
    ///\param name The name of the option. The leading '-' must be omitted.
196 196
    ///\param help A help string.
197 197
    ///\param obl Indicate if the option is mandatory.
198 198
    ///\retval ref The value of the argument will be written to this variable.
199 199
    ArgParser &refOption(const std::string &name,
200 200
                    const std::string &help,
201 201
                    int &ref, bool obl=false);
202 202

	
203 203
    ///Add a new floating type option with a storage reference
204 204

	
205 205
    ///Add a new floating type option with a storage reference.
206 206
    ///\param name The name of the option. The leading '-' must be omitted.
207 207
    ///\param help A help string.
208 208
    ///\param obl Indicate if the option is mandatory.
209 209
    ///\retval ref The value of the argument will be written to this variable.
210 210
    ArgParser &refOption(const std::string &name,
211 211
                      const std::string &help,
212 212
                      double &ref, bool obl=false);
213 213

	
214 214
    ///Add a new bool type option with a storage reference
215 215

	
216 216
    ///Add a new bool type option with a storage reference.
217 217
    ///\param name The name of the option. The leading '-' must be omitted.
218 218
    ///\param help A help string.
219 219
    ///\param obl Indicate if the option is mandatory.
220 220
    ///\retval ref The value of the argument will be written to this variable.
221 221
    ///\note A mandatory bool obtion is of very little use.
222 222
    ArgParser &refOption(const std::string &name,
223 223
                      const std::string &help,
224 224
                      bool &ref, bool obl=false);
225 225

	
226 226
    ///Add a new string type option with a storage reference
227 227

	
228 228
    ///Add a new string type option with a storage reference.
229 229
    ///\param name The name of the option. The leading '-' must be omitted.
230 230
    ///\param help A help string.
231 231
    ///\param obl Indicate if the option is mandatory.
232 232
    ///\retval ref The value of the argument will be written to this variable.
233 233
    ArgParser &refOption(const std::string &name,
234 234
                      const std::string &help,
235 235
                      std::string &ref, bool obl=false);
236 236

	
237 237
    ///@}
238 238

	
239 239
    ///\name Option Groups and Synonyms
240 240
    ///
241 241

	
242 242
    ///@{
243 243

	
244 244
    ///Bundle some options into a group
245 245

	
246 246
    /// You can group some option by calling this function repeatedly for each
247 247
    /// option to be grouped with the same groupname.
248 248
    ///\param group The group name.
249 249
    ///\param opt The option name.
250 250
    ArgParser &optionGroup(const std::string &group,
251 251
                           const std::string &opt);
252 252

	
253 253
    ///Make the members of a group exclusive
254 254

	
255 255
    ///If you call this function for a group, than at most one of them can be
256 256
    ///given at the same time.
257 257
    ArgParser &onlyOneGroup(const std::string &group);
258 258

	
259 259
    ///Make a group mandatory
260 260

	
261 261
    ///Using this function, at least one of the members of \c group
262 262
    ///must be given.
263 263
    ArgParser &mandatoryGroup(const std::string &group);
264 264

	
265 265
    ///Create synonym to an option
266 266

	
267 267
    ///With this function you can create a synonym \c syn of the
268 268
    ///option \c opt.
269 269
    ArgParser &synonym(const std::string &syn,
270 270
                           const std::string &opt);
271 271

	
272 272
    ///@}
273 273

	
274 274
  private:
275 275
    void show(std::ostream &os,Opts::const_iterator i) const;
276 276
    void show(std::ostream &os,Groups::const_iterator i) const;
277 277
    void showHelp(Opts::const_iterator i) const;
278 278
    void showHelp(std::vector<OtherArg>::const_iterator i) const;
279 279

	
280 280
    void unknownOpt(std::string arg) const;
281 281

	
282 282
    void requiresValue(std::string arg, OptType t) const;
283 283
    void checkMandatories() const;
284 284

	
285 285
    void shortHelp() const;
286 286
    void showHelp() const;
287 287
  public:
288 288

	
289 289
    ///Start the parsing process
290 290
    ArgParser &parse();
291 291

	
292 292
    /// Synonym for parse()
293 293
    ArgParser &run()
294 294
    {
295 295
      return parse();
296 296
    }
297 297

	
298 298
    ///Give back the command name (the 0th argument)
299 299
    const std::string &commandName() const { return _command_name; }
300 300

	
301 301
    ///Check if an opion has been given to the command.
302 302
    bool given(std::string op) const
303 303
    {
304 304
      Opts::const_iterator i = _opts.find(op);
305 305
      return i!=_opts.end()?i->second.set:false;
306 306
    }
307 307

	
308 308

	
309 309
    ///Magic type for operator[]
310 310

	
311 311
    ///This is the type of the return value of ArgParser::operator[]().
312 312
    ///It automatically converts to \c int, \c double, \c bool or
313 313
    ///\c std::string if the type of the option matches, which is checked
314 314
    ///with an \ref LEMON_ASSERT "assertion" (i.e. it performs runtime
315 315
    ///type checking).
316 316
    class RefType
317 317
    {
318 318
      const ArgParser &_parser;
319 319
      std::string _name;
320 320
    public:
321 321
      ///\e
322 322
      RefType(const ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
323 323
      ///\e
324 324
      operator bool()
325 325
      {
326 326
        Opts::const_iterator i = _parser._opts.find(_name);
327 327
        LEMON_ASSERT(i!=_parser._opts.end(),
328 328
                     std::string()+"Unkown option: '"+_name+"'");
329 329
        LEMON_ASSERT(i->second.type==ArgParser::BOOL,
330 330
                     std::string()+"'"+_name+"' is a bool option");
331 331
        return *(i->second.bool_p);
332 332
      }
333 333
      ///\e
334 334
      operator std::string()
335 335
      {
336 336
        Opts::const_iterator i = _parser._opts.find(_name);
337 337
        LEMON_ASSERT(i!=_parser._opts.end(),
338 338
                     std::string()+"Unkown option: '"+_name+"'");
339 339
        LEMON_ASSERT(i->second.type==ArgParser::STRING,
340 340
                     std::string()+"'"+_name+"' is a string option");
341 341
        return *(i->second.string_p);
342 342
      }
343 343
      ///\e
344 344
      operator double()
345 345
      {
346 346
        Opts::const_iterator i = _parser._opts.find(_name);
347 347
        LEMON_ASSERT(i!=_parser._opts.end(),
348 348
                     std::string()+"Unkown option: '"+_name+"'");
349 349
        LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
350 350
                     i->second.type==ArgParser::INTEGER,
351 351
                     std::string()+"'"+_name+"' is a floating point option");
352 352
        return i->second.type==ArgParser::DOUBLE ?
353 353
          *(i->second.double_p) : *(i->second.int_p);
354 354
      }
355 355
      ///\e
356 356
      operator int()
357 357
      {
358 358
        Opts::const_iterator i = _parser._opts.find(_name);
359 359
        LEMON_ASSERT(i!=_parser._opts.end(),
360 360
                     std::string()+"Unkown option: '"+_name+"'");
361 361
        LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
362 362
                     std::string()+"'"+_name+"' is an integer option");
363 363
        return *(i->second.int_p);
364 364
      }
365 365

	
366 366
    };
367 367

	
368 368
    ///Give back the value of an option
369 369

	
370 370
    ///Give back the value of an option.
371 371
    ///\sa RefType
372 372
    RefType operator[](const std::string &n) const
373 373
    {
374 374
      return RefType(*this, n);
375 375
    }
376 376

	
377 377
    ///Give back the non-option type arguments.
378 378

	
379 379
    ///Give back a reference to a vector consisting of the program arguments
380 380
    ///not starting with a '-' character.
381 381
    const std::vector<std::string> &files() const { return _file_args; }
382 382

	
383 383
  };
384 384
}
385 385

	
386 386
#endif // LEMON_ARG_PARSER_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_ASSERT_H
20 20
#define LEMON_ASSERT_H
21 21

	
22 22
/// \ingroup exceptions
23 23
/// \file
24 24
/// \brief Extended assertion handling
25 25

	
26 26
#include <lemon/error.h>
27 27

	
28 28
namespace lemon {
29 29

	
30 30
  inline void assert_fail_abort(const char *file, int line,
31 31
                                const char *function, const char* message,
32 32
                                const char *assertion)
33 33
  {
34 34
    std::cerr << file << ":" << line << ": ";
35 35
    if (function)
36 36
      std::cerr << function << ": ";
37 37
    std::cerr << message;
38 38
    if (assertion)
39 39
      std::cerr << " (assertion '" << assertion << "' failed)";
40 40
    std::cerr << std::endl;
41 41
    std::abort();
42 42
  }
43 43

	
44 44
  namespace _assert_bits {
45 45

	
46 46

	
47 47
    inline const char* cstringify(const std::string& str) {
48 48
      return str.c_str();
49 49
    }
50 50

	
51 51
    inline const char* cstringify(const char* str) {
52 52
      return str;
53 53
    }
54 54
  }
55 55
}
56 56

	
57 57
#endif // LEMON_ASSERT_H
58 58

	
59 59
#undef LEMON_ASSERT
60 60
#undef LEMON_DEBUG
61 61

	
62 62
#if (defined(LEMON_ASSERT_ABORT) ? 1 : 0) +               \
63 63
  (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) > 1
64 64
#error "LEMON assertion system is not set properly"
65 65
#endif
66 66

	
67 67
#if ((defined(LEMON_ASSERT_ABORT) ? 1 : 0) +            \
68 68
     (defined(LEMON_ASSERT_CUSTOM) ? 1 : 0) == 1 ||     \
69 69
     defined(LEMON_ENABLE_ASSERTS)) &&                  \
70 70
  (defined(LEMON_DISABLE_ASSERTS) ||                    \
71 71
   defined(NDEBUG))
72 72
#error "LEMON assertion system is not set properly"
73 73
#endif
74 74

	
75 75

	
76 76
#if defined LEMON_ASSERT_ABORT
77 77
#  undef LEMON_ASSERT_HANDLER
78 78
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
79 79
#elif defined LEMON_ASSERT_CUSTOM
80 80
#  undef LEMON_ASSERT_HANDLER
81 81
#  ifndef LEMON_CUSTOM_ASSERT_HANDLER
82 82
#    error "LEMON_CUSTOM_ASSERT_HANDLER is not set"
83 83
#  endif
84 84
#  define LEMON_ASSERT_HANDLER LEMON_CUSTOM_ASSERT_HANDLER
85 85
#elif defined LEMON_DISABLE_ASSERTS
86 86
#  undef LEMON_ASSERT_HANDLER
87 87
#elif defined NDEBUG
88 88
#  undef LEMON_ASSERT_HANDLER
89 89
#else
90 90
#  define LEMON_ASSERT_HANDLER ::lemon::assert_fail_abort
91 91
#endif
92 92

	
93 93
#ifndef LEMON_FUNCTION_NAME
94 94
#  if defined __GNUC__
95 95
#    define LEMON_FUNCTION_NAME (__PRETTY_FUNCTION__)
96 96
#  elif defined _MSC_VER
97 97
#    define LEMON_FUNCTION_NAME (__FUNCSIG__)
98 98
#  elif __STDC_VERSION__ >= 199901L
99 99
#    define LEMON_FUNCTION_NAME (__func__)
100 100
#  else
101 101
#    define LEMON_FUNCTION_NAME ("<unknown>")
102 102
#  endif
103 103
#endif
104 104

	
105 105
#ifdef DOXYGEN
106 106

	
107 107
/// \ingroup exceptions
108 108
///
109 109
/// \brief Macro for assertion with customizable message
110 110
///
111 111
/// Macro for assertion with customizable message.
112 112
/// \param exp An expression that must be convertible to \c bool.  If it is \c
113 113
/// false, then an assertion is raised. The concrete behaviour depends on the
114 114
/// settings of the assertion system.
115 115
/// \param msg A <tt>const char*</tt> parameter, which can be used to provide
116 116
/// information about the circumstances of the failed assertion.
117 117
///
118 118
/// The assertions are enabled in the default behaviour.
119 119
/// You can disable them with the following code:
120 120
/// \code
121 121
/// #define LEMON_DISABLE_ASSERTS
122 122
/// \endcode
123 123
/// or with compilation parameters:
124 124
/// \code
125 125
/// g++ -DLEMON_DISABLE_ASSERTS
126 126
/// make CXXFLAGS='-DLEMON_DISABLE_ASSERTS'
127 127
/// \endcode
128 128
/// The checking is also disabled when the standard macro \c NDEBUG is defined.
129 129
///
130 130
/// As a default behaviour the failed assertion prints a short log message to
131 131
/// the standard error and aborts the execution.
132 132
///
133 133
/// However, the following modes can be used in the assertion system:
134 134
/// - \c LEMON_ASSERT_ABORT The failed assertion prints a short log message to
135 135
///   the standard error and aborts the program. It is the default behaviour.
136 136
/// - \c LEMON_ASSERT_CUSTOM The user can define own assertion handler
137 137
///   function.
138 138
///   \code
139 139
///     void custom_assert_handler(const char* file, int line,
140 140
///                                const char* function, const char* message,
141 141
///                                const char* assertion);
142 142
///   \endcode
143 143
///   The name of the function should be defined as the \c
144 144
///   LEMON_CUSTOM_ASSERT_HANDLER macro name.
145 145
///   \code
146 146
///     #define LEMON_CUSTOM_ASSERT_HANDLER custom_assert_handler
147 147
///   \endcode
148 148
///   Whenever an assertion is occured, the custom assertion
149 149
///   handler is called with appropiate parameters.
150 150
///
151 151
/// The assertion mode can also be changed within one compilation unit.
152 152
/// If the macros are redefined with other settings and the
153 153
/// \ref lemon/assert.h "assert.h" file is reincluded, then the
154 154
/// behaviour is changed appropiately to the new settings.
155 155
#  define LEMON_ASSERT(exp, msg)                                        \
156 156
  (static_cast<void> (!!(exp) ? 0 : (                                   \
157 157
    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
158 158
                         LEMON_FUNCTION_NAME,                           \
159 159
                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
160 160

	
161 161
/// \ingroup exceptions
162 162
///
163 163
/// \brief Macro for internal assertions
164 164
///
165 165
/// Macro for internal assertions, it is used in the library to check
166 166
/// the consistency of results of algorithms, several pre- and
167 167
/// postconditions and invariants. The checking is disabled by
168 168
/// default, but it can be turned on with the macro \c
169 169
/// LEMON_ENABLE_DEBUG.
170 170
/// \code
171 171
/// #define LEMON_ENABLE_DEBUG
172 172
/// \endcode
173 173
/// or with compilation parameters:
174 174
/// \code
175 175
/// g++ -DLEMON_ENABLE_DEBUG
176 176
/// make CXXFLAGS='-DLEMON_ENABLE_DEBUG'
177 177
/// \endcode
178 178
///
179 179
/// This macro works like the \c LEMON_ASSERT macro, therefore the
180 180
/// current behaviour depends on the settings of \c LEMON_ASSERT
181 181
/// macro.
182 182
///
183 183
/// \see LEMON_ASSERT
184 184
#  define LEMON_DEBUG(exp, msg)                                         \
185 185
  (static_cast<void> (!!(exp) ? 0 : (                                   \
186 186
    LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                            \
187 187
                         LEMON_FUNCTION_NAME,                           \
188 188
                         ::lemon::_assert_bits::cstringify(msg), #exp), 0)))
189 189

	
190 190
#else
191 191

	
192 192
#  ifndef LEMON_ASSERT_HANDLER
193 193
#    define LEMON_ASSERT(exp, msg)  (static_cast<void>(0))
194 194
#    define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
195 195
#  else
196 196
#    define LEMON_ASSERT(exp, msg)                                      \
197 197
       (static_cast<void> (!!(exp) ? 0 : (                              \
198 198
        LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                        \
199 199
                             LEMON_FUNCTION_NAME,                       \
200 200
                             ::lemon::_assert_bits::cstringify(msg),    \
201 201
                             #exp), 0)))
202 202
#    if LEMON_ENABLE_DEBUG
203 203
#      define LEMON_DEBUG(exp, msg)                                     \
204 204
         (static_cast<void> (!!(exp) ? 0 : (                            \
205 205
           LEMON_ASSERT_HANDLER(__FILE__, __LINE__,                     \
206 206
                                LEMON_FUNCTION_NAME,                    \
207 207
                                ::lemon::_assert_bits::cstringify(msg), \
208 208
                                #exp), 0)))
209 209
#    else
210 210
#      define LEMON_DEBUG(exp, msg) (static_cast<void>(0))
211 211
#    endif
212 212
#  endif
213 213

	
214 214
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
///\file
20 20
///\brief Some basic non-inline functions and static global data.
21 21

	
22 22
#include<lemon/tolerance.h>
23 23
#include<lemon/core.h>
24 24
namespace lemon {
25 25

	
26
  float Tolerance<float>::def_epsilon = 1e-4;
26
  float Tolerance<float>::def_epsilon = static_cast<float>(1e-4);
27 27
  double Tolerance<double>::def_epsilon = 1e-10;
28 28
  long double Tolerance<long double>::def_epsilon = 1e-14;
29 29

	
30 30
#ifndef LEMON_ONLY_TEMPLATES
31 31
  const Invalid INVALID = Invalid();
32 32
#endif
33 33

	
34 34
} //namespace lemon
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_BFS_H
20 20
#define LEMON_BFS_H
21 21

	
22 22
///\ingroup search
23 23
///\file
24 24
///\brief BFS algorithm.
25 25

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

	
33 33
namespace lemon {
34 34

	
35 35
  ///Default traits class of Bfs class.
36 36

	
37 37
  ///Default traits class of Bfs class.
38 38
  ///\tparam GR Digraph type.
39 39
  template<class GR>
40 40
  struct BfsDefaultTraits
41 41
  {
42 42
    ///The type of the digraph the algorithm runs on.
43 43
    typedef GR Digraph;
44 44

	
45 45
    ///\brief The type of the map that stores the predecessor
46 46
    ///arcs of the shortest paths.
47 47
    ///
48 48
    ///The type of the map that stores the predecessor
49 49
    ///arcs of the shortest paths.
50 50
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
51 51
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
52
    ///Instantiates a PredMap.
52
    ///Instantiates a \c PredMap.
53 53

	
54
    ///This function instantiates a PredMap.
54
    ///This function instantiates a \ref PredMap.
55 55
    ///\param g is the digraph, to which we would like to define the
56
    ///PredMap.
56
    ///\ref PredMap.
57 57
    static PredMap *createPredMap(const Digraph &g)
58 58
    {
59 59
      return new PredMap(g);
60 60
    }
61 61

	
62 62
    ///The type of the map that indicates which nodes are processed.
63 63

	
64 64
    ///The type of the map that indicates which nodes are processed.
65 65
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
66 66
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
67
    ///Instantiates a ProcessedMap.
67
    ///Instantiates a \c ProcessedMap.
68 68

	
69
    ///This function instantiates a ProcessedMap.
69
    ///This function instantiates a \ref ProcessedMap.
70 70
    ///\param g is the digraph, to which
71
    ///we would like to define the ProcessedMap
71
    ///we would like to define the \ref ProcessedMap
72 72
#ifdef DOXYGEN
73 73
    static ProcessedMap *createProcessedMap(const Digraph &g)
74 74
#else
75 75
    static ProcessedMap *createProcessedMap(const Digraph &)
76 76
#endif
77 77
    {
78 78
      return new ProcessedMap();
79 79
    }
80 80

	
81 81
    ///The type of the map that indicates which nodes are reached.
82 82

	
83 83
    ///The type of the map that indicates which nodes are reached.
84 84
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
85 85
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
86
    ///Instantiates a ReachedMap.
86
    ///Instantiates a \c ReachedMap.
87 87

	
88
    ///This function instantiates a ReachedMap.
88
    ///This function instantiates a \ref ReachedMap.
89 89
    ///\param g is the digraph, to which
90
    ///we would like to define the ReachedMap.
90
    ///we would like to define the \ref ReachedMap.
91 91
    static ReachedMap *createReachedMap(const Digraph &g)
92 92
    {
93 93
      return new ReachedMap(g);
94 94
    }
95 95

	
96 96
    ///The type of the map that stores the distances of the nodes.
97 97

	
98 98
    ///The type of the map that stores the distances of the nodes.
99 99
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
100 100
    typedef typename Digraph::template NodeMap<int> DistMap;
101
    ///Instantiates a DistMap.
101
    ///Instantiates a \c DistMap.
102 102

	
103
    ///This function instantiates a DistMap.
103
    ///This function instantiates a \ref DistMap.
104 104
    ///\param g is the digraph, to which we would like to define the
105
    ///DistMap.
105
    ///\ref DistMap.
106 106
    static DistMap *createDistMap(const Digraph &g)
107 107
    {
108 108
      return new DistMap(g);
109 109
    }
110 110
  };
111 111

	
112 112
  ///%BFS algorithm class.
113 113

	
114 114
  ///\ingroup search
115 115
  ///This class provides an efficient implementation of the %BFS algorithm.
116 116
  ///
117 117
  ///There is also a \ref bfs() "function-type interface" for the BFS
118 118
  ///algorithm, which is convenient in the simplier cases and it can be
119 119
  ///used easier.
120 120
  ///
121 121
  ///\tparam GR The type of the digraph the algorithm runs on.
122
  ///The default value is \ref ListDigraph. The value of GR is not used
123
  ///directly by \ref Bfs, it is only passed to \ref BfsDefaultTraits.
124
  ///\tparam TR Traits class to set various data types used by the algorithm.
125
  ///The default traits class is
126
  ///\ref BfsDefaultTraits "BfsDefaultTraits<GR>".
127
  ///See \ref BfsDefaultTraits for the documentation of
128
  ///a Bfs traits class.
122
  ///The default type is \ref ListDigraph.
129 123
#ifdef DOXYGEN
130 124
  template <typename GR,
131 125
            typename TR>
132 126
#else
133 127
  template <typename GR=ListDigraph,
134 128
            typename TR=BfsDefaultTraits<GR> >
135 129
#endif
136 130
  class Bfs {
137 131
  public:
138 132

	
139 133
    ///The type of the digraph the algorithm runs on.
140 134
    typedef typename TR::Digraph Digraph;
141 135

	
142 136
    ///\brief The type of the map that stores the predecessor arcs of the
143 137
    ///shortest paths.
144 138
    typedef typename TR::PredMap PredMap;
145 139
    ///The type of the map that stores the distances of the nodes.
146 140
    typedef typename TR::DistMap DistMap;
147 141
    ///The type of the map that indicates which nodes are reached.
148 142
    typedef typename TR::ReachedMap ReachedMap;
149 143
    ///The type of the map that indicates which nodes are processed.
150 144
    typedef typename TR::ProcessedMap ProcessedMap;
151 145
    ///The type of the paths.
152 146
    typedef PredMapPath<Digraph, PredMap> Path;
153 147

	
154
    ///The traits class.
148
    ///The \ref BfsDefaultTraits "traits class" of the algorithm.
155 149
    typedef TR Traits;
156 150

	
157 151
  private:
158 152

	
159 153
    typedef typename Digraph::Node Node;
160 154
    typedef typename Digraph::NodeIt NodeIt;
161 155
    typedef typename Digraph::Arc Arc;
162 156
    typedef typename Digraph::OutArcIt OutArcIt;
163 157

	
164 158
    //Pointer to the underlying digraph.
165 159
    const Digraph *G;
166 160
    //Pointer to the map of predecessor arcs.
167 161
    PredMap *_pred;
168 162
    //Indicates if _pred is locally allocated (true) or not.
169 163
    bool local_pred;
170 164
    //Pointer to the map of distances.
171 165
    DistMap *_dist;
172 166
    //Indicates if _dist is locally allocated (true) or not.
173 167
    bool local_dist;
174 168
    //Pointer to the map of reached status of the nodes.
175 169
    ReachedMap *_reached;
176 170
    //Indicates if _reached is locally allocated (true) or not.
177 171
    bool local_reached;
178 172
    //Pointer to the map of processed status of the nodes.
179 173
    ProcessedMap *_processed;
180 174
    //Indicates if _processed is locally allocated (true) or not.
181 175
    bool local_processed;
182 176

	
183 177
    std::vector<typename Digraph::Node> _queue;
184 178
    int _queue_head,_queue_tail,_queue_next_dist;
185 179
    int _curr_dist;
186 180

	
187 181
    //Creates the maps if necessary.
188 182
    void create_maps()
189 183
    {
190 184
      if(!_pred) {
191 185
        local_pred = true;
192 186
        _pred = Traits::createPredMap(*G);
193 187
      }
194 188
      if(!_dist) {
195 189
        local_dist = true;
196 190
        _dist = Traits::createDistMap(*G);
197 191
      }
198 192
      if(!_reached) {
199 193
        local_reached = true;
200 194
        _reached = Traits::createReachedMap(*G);
201 195
      }
202 196
      if(!_processed) {
203 197
        local_processed = true;
204 198
        _processed = Traits::createProcessedMap(*G);
205 199
      }
206 200
    }
207 201

	
208 202
  protected:
209 203

	
210 204
    Bfs() {}
211 205

	
212 206
  public:
213 207

	
214 208
    typedef Bfs Create;
215 209

	
216
    ///\name Named template parameters
210
    ///\name Named Template Parameters
217 211

	
218 212
    ///@{
219 213

	
220 214
    template <class T>
221 215
    struct SetPredMapTraits : public Traits {
222 216
      typedef T PredMap;
223 217
      static PredMap *createPredMap(const Digraph &)
224 218
      {
225 219
        LEMON_ASSERT(false, "PredMap is not initialized");
226 220
        return 0; // ignore warnings
227 221
      }
228 222
    };
229 223
    ///\brief \ref named-templ-param "Named parameter" for setting
230
    ///PredMap type.
224
    ///\c PredMap type.
231 225
    ///
232 226
    ///\ref named-templ-param "Named parameter" for setting
233
    ///PredMap type.
227
    ///\c PredMap type.
228
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
234 229
    template <class T>
235 230
    struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
236 231
      typedef Bfs< Digraph, SetPredMapTraits<T> > Create;
237 232
    };
238 233

	
239 234
    template <class T>
240 235
    struct SetDistMapTraits : public Traits {
241 236
      typedef T DistMap;
242 237
      static DistMap *createDistMap(const Digraph &)
243 238
      {
244 239
        LEMON_ASSERT(false, "DistMap is not initialized");
245 240
        return 0; // ignore warnings
246 241
      }
247 242
    };
248 243
    ///\brief \ref named-templ-param "Named parameter" for setting
249
    ///DistMap type.
244
    ///\c DistMap type.
250 245
    ///
251 246
    ///\ref named-templ-param "Named parameter" for setting
252
    ///DistMap type.
247
    ///\c DistMap type.
248
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
253 249
    template <class T>
254 250
    struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
255 251
      typedef Bfs< Digraph, SetDistMapTraits<T> > Create;
256 252
    };
257 253

	
258 254
    template <class T>
259 255
    struct SetReachedMapTraits : public Traits {
260 256
      typedef T ReachedMap;
261 257
      static ReachedMap *createReachedMap(const Digraph &)
262 258
      {
263 259
        LEMON_ASSERT(false, "ReachedMap is not initialized");
264 260
        return 0; // ignore warnings
265 261
      }
266 262
    };
267 263
    ///\brief \ref named-templ-param "Named parameter" for setting
268
    ///ReachedMap type.
264
    ///\c ReachedMap type.
269 265
    ///
270 266
    ///\ref named-templ-param "Named parameter" for setting
271
    ///ReachedMap type.
267
    ///\c ReachedMap type.
268
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
272 269
    template <class T>
273 270
    struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
274 271
      typedef Bfs< Digraph, SetReachedMapTraits<T> > Create;
275 272
    };
276 273

	
277 274
    template <class T>
278 275
    struct SetProcessedMapTraits : public Traits {
279 276
      typedef T ProcessedMap;
280 277
      static ProcessedMap *createProcessedMap(const Digraph &)
281 278
      {
282 279
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
283 280
        return 0; // ignore warnings
284 281
      }
285 282
    };
286 283
    ///\brief \ref named-templ-param "Named parameter" for setting
287
    ///ProcessedMap type.
284
    ///\c ProcessedMap type.
288 285
    ///
289 286
    ///\ref named-templ-param "Named parameter" for setting
290
    ///ProcessedMap type.
287
    ///\c ProcessedMap type.
288
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
291 289
    template <class T>
292 290
    struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
293 291
      typedef Bfs< Digraph, SetProcessedMapTraits<T> > Create;
294 292
    };
295 293

	
296 294
    struct SetStandardProcessedMapTraits : public Traits {
297 295
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
298 296
      static ProcessedMap *createProcessedMap(const Digraph &g)
299 297
      {
300 298
        return new ProcessedMap(g);
301 299
        return 0; // ignore warnings
302 300
      }
303 301
    };
304 302
    ///\brief \ref named-templ-param "Named parameter" for setting
305
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
303
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
306 304
    ///
307 305
    ///\ref named-templ-param "Named parameter" for setting
308
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
306
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
309 307
    ///If you don't set it explicitly, it will be automatically allocated.
310 308
    struct SetStandardProcessedMap :
311 309
      public Bfs< Digraph, SetStandardProcessedMapTraits > {
312 310
      typedef Bfs< Digraph, SetStandardProcessedMapTraits > Create;
313 311
    };
314 312

	
315 313
    ///@}
316 314

	
317 315
  public:
318 316

	
319 317
    ///Constructor.
320 318

	
321 319
    ///Constructor.
322 320
    ///\param g The digraph the algorithm runs on.
323 321
    Bfs(const Digraph &g) :
324 322
      G(&g),
325 323
      _pred(NULL), local_pred(false),
326 324
      _dist(NULL), local_dist(false),
327 325
      _reached(NULL), local_reached(false),
328 326
      _processed(NULL), local_processed(false)
329 327
    { }
330 328

	
331 329
    ///Destructor.
332 330
    ~Bfs()
333 331
    {
334 332
      if(local_pred) delete _pred;
335 333
      if(local_dist) delete _dist;
336 334
      if(local_reached) delete _reached;
337 335
      if(local_processed) delete _processed;
338 336
    }
339 337

	
340 338
    ///Sets the map that stores the predecessor arcs.
341 339

	
342 340
    ///Sets the map that stores the predecessor arcs.
343
    ///If you don't use this function before calling \ref run(),
344
    ///it will allocate one. The destructor deallocates this
345
    ///automatically allocated map, of course.
341
    ///If you don't use this function before calling \ref run(Node) "run()"
342
    ///or \ref init(), an instance will be allocated automatically.
343
    ///The destructor deallocates this automatically allocated map,
344
    ///of course.
346 345
    ///\return <tt> (*this) </tt>
347 346
    Bfs &predMap(PredMap &m)
348 347
    {
349 348
      if(local_pred) {
350 349
        delete _pred;
351 350
        local_pred=false;
352 351
      }
353 352
      _pred = &m;
354 353
      return *this;
355 354
    }
356 355

	
357 356
    ///Sets the map that indicates which nodes are reached.
358 357

	
359 358
    ///Sets the map that indicates which nodes are reached.
360
    ///If you don't use this function before calling \ref run(),
361
    ///it will allocate one. The destructor deallocates this
362
    ///automatically allocated map, of course.
359
    ///If you don't use this function before calling \ref run(Node) "run()"
360
    ///or \ref init(), an instance will be allocated automatically.
361
    ///The destructor deallocates this automatically allocated map,
362
    ///of course.
363 363
    ///\return <tt> (*this) </tt>
364 364
    Bfs &reachedMap(ReachedMap &m)
365 365
    {
366 366
      if(local_reached) {
367 367
        delete _reached;
368 368
        local_reached=false;
369 369
      }
370 370
      _reached = &m;
371 371
      return *this;
372 372
    }
373 373

	
374 374
    ///Sets the map that indicates which nodes are processed.
375 375

	
376 376
    ///Sets the map that indicates which nodes are processed.
377
    ///If you don't use this function before calling \ref run(),
378
    ///it will allocate one. The destructor deallocates this
379
    ///automatically allocated map, of course.
377
    ///If you don't use this function before calling \ref run(Node) "run()"
378
    ///or \ref init(), an instance will be allocated automatically.
379
    ///The destructor deallocates this automatically allocated map,
380
    ///of course.
380 381
    ///\return <tt> (*this) </tt>
381 382
    Bfs &processedMap(ProcessedMap &m)
382 383
    {
383 384
      if(local_processed) {
384 385
        delete _processed;
385 386
        local_processed=false;
386 387
      }
387 388
      _processed = &m;
388 389
      return *this;
389 390
    }
390 391

	
391 392
    ///Sets the map that stores the distances of the nodes.
392 393

	
393 394
    ///Sets the map that stores the distances of the nodes calculated by
394 395
    ///the algorithm.
395
    ///If you don't use this function before calling \ref run(),
396
    ///it will allocate one. The destructor deallocates this
397
    ///automatically allocated map, of course.
396
    ///If you don't use this function before calling \ref run(Node) "run()"
397
    ///or \ref init(), an instance will be allocated automatically.
398
    ///The destructor deallocates this automatically allocated map,
399
    ///of course.
398 400
    ///\return <tt> (*this) </tt>
399 401
    Bfs &distMap(DistMap &m)
400 402
    {
401 403
      if(local_dist) {
402 404
        delete _dist;
403 405
        local_dist=false;
404 406
      }
405 407
      _dist = &m;
406 408
      return *this;
407 409
    }
408 410

	
409 411
  public:
410 412

	
411
    ///\name Execution control
412
    ///The simplest way to execute the algorithm is to use
413
    ///one of the member functions called \ref lemon::Bfs::run() "run()".
414
    ///\n
415
    ///If you need more control on the execution, first you must call
416
    ///\ref lemon::Bfs::init() "init()", then you can add several source
417
    ///nodes with \ref lemon::Bfs::addSource() "addSource()".
418
    ///Finally \ref lemon::Bfs::start() "start()" will perform the
419
    ///actual path computation.
413
    ///\name Execution Control
414
    ///The simplest way to execute the BFS algorithm is to use one of the
415
    ///member functions called \ref run(Node) "run()".\n
416
    ///If you need more control on the execution, first you have to call
417
    ///\ref init(), then you can add several source nodes with
418
    ///\ref addSource(). Finally the actual path computation can be
419
    ///performed with one of the \ref start() functions.
420 420

	
421 421
    ///@{
422 422

	
423
    ///\brief Initializes the internal data structures.
424
    ///
423 425
    ///Initializes the internal data structures.
424

	
425
    ///Initializes the internal data structures.
426
    ///
427 426
    void init()
428 427
    {
429 428
      create_maps();
430 429
      _queue.resize(countNodes(*G));
431 430
      _queue_head=_queue_tail=0;
432 431
      _curr_dist=1;
433 432
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
434 433
        _pred->set(u,INVALID);
435 434
        _reached->set(u,false);
436 435
        _processed->set(u,false);
437 436
      }
438 437
    }
439 438

	
440 439
    ///Adds a new source node.
441 440

	
442 441
    ///Adds a new source node to the set of nodes to be processed.
443 442
    ///
444 443
    void addSource(Node s)
445 444
    {
446 445
      if(!(*_reached)[s])
447 446
        {
448 447
          _reached->set(s,true);
449 448
          _pred->set(s,INVALID);
450 449
          _dist->set(s,0);
451 450
          _queue[_queue_head++]=s;
452 451
          _queue_next_dist=_queue_head;
453 452
        }
454 453
    }
455 454

	
456 455
    ///Processes the next node.
457 456

	
458 457
    ///Processes the next node.
459 458
    ///
460 459
    ///\return The processed node.
461 460
    ///
462 461
    ///\pre The queue must not be empty.
463 462
    Node processNextNode()
464 463
    {
465 464
      if(_queue_tail==_queue_next_dist) {
466 465
        _curr_dist++;
467 466
        _queue_next_dist=_queue_head;
468 467
      }
469 468
      Node n=_queue[_queue_tail++];
470 469
      _processed->set(n,true);
471 470
      Node m;
472 471
      for(OutArcIt e(*G,n);e!=INVALID;++e)
473 472
        if(!(*_reached)[m=G->target(e)]) {
474 473
          _queue[_queue_head++]=m;
475 474
          _reached->set(m,true);
476 475
          _pred->set(m,e);
477 476
          _dist->set(m,_curr_dist);
478 477
        }
479 478
      return n;
480 479
    }
481 480

	
482 481
    ///Processes the next node.
483 482

	
484 483
    ///Processes the next node and checks if the given target node
485 484
    ///is reached. If the target node is reachable from the processed
486 485
    ///node, then the \c reach parameter will be set to \c true.
487 486
    ///
488 487
    ///\param target The target node.
489 488
    ///\retval reach Indicates if the target node is reached.
490 489
    ///It should be initially \c false.
491 490
    ///
492 491
    ///\return The processed node.
493 492
    ///
494 493
    ///\pre The queue must not be empty.
495 494
    Node processNextNode(Node target, bool& reach)
496 495
    {
497 496
      if(_queue_tail==_queue_next_dist) {
498 497
        _curr_dist++;
499 498
        _queue_next_dist=_queue_head;
500 499
      }
501 500
      Node n=_queue[_queue_tail++];
502 501
      _processed->set(n,true);
503 502
      Node m;
504 503
      for(OutArcIt e(*G,n);e!=INVALID;++e)
505 504
        if(!(*_reached)[m=G->target(e)]) {
506 505
          _queue[_queue_head++]=m;
507 506
          _reached->set(m,true);
508 507
          _pred->set(m,e);
509 508
          _dist->set(m,_curr_dist);
510 509
          reach = reach || (target == m);
511 510
        }
512 511
      return n;
513 512
    }
514 513

	
515 514
    ///Processes the next node.
516 515

	
517 516
    ///Processes the next node and checks if at least one of reached
518 517
    ///nodes has \c true value in the \c nm node map. If one node
519 518
    ///with \c true value is reachable from the processed node, then the
520 519
    ///\c rnode parameter will be set to the first of such nodes.
521 520
    ///
522 521
    ///\param nm A \c bool (or convertible) node map that indicates the
523 522
    ///possible targets.
524 523
    ///\retval rnode The reached target node.
525 524
    ///It should be initially \c INVALID.
526 525
    ///
527 526
    ///\return The processed node.
528 527
    ///
529 528
    ///\pre The queue must not be empty.
530 529
    template<class NM>
531 530
    Node processNextNode(const NM& nm, Node& rnode)
532 531
    {
533 532
      if(_queue_tail==_queue_next_dist) {
534 533
        _curr_dist++;
535 534
        _queue_next_dist=_queue_head;
536 535
      }
537 536
      Node n=_queue[_queue_tail++];
538 537
      _processed->set(n,true);
539 538
      Node m;
540 539
      for(OutArcIt e(*G,n);e!=INVALID;++e)
541 540
        if(!(*_reached)[m=G->target(e)]) {
542 541
          _queue[_queue_head++]=m;
543 542
          _reached->set(m,true);
544 543
          _pred->set(m,e);
545 544
          _dist->set(m,_curr_dist);
546 545
          if (nm[m] && rnode == INVALID) rnode = m;
547 546
        }
548 547
      return n;
549 548
    }
550 549

	
551 550
    ///The next node to be processed.
552 551

	
553 552
    ///Returns the next node to be processed or \c INVALID if the queue
554 553
    ///is empty.
555 554
    Node nextNode() const
556 555
    {
557 556
      return _queue_tail<_queue_head?_queue[_queue_tail]:INVALID;
558 557
    }
559 558

	
560
    ///\brief Returns \c false if there are nodes
561
    ///to be processed.
562
    ///
563
    ///Returns \c false if there are nodes
564
    ///to be processed in the queue.
559
    ///Returns \c false if there are nodes to be processed.
560

	
561
    ///Returns \c false if there are nodes to be processed
562
    ///in the queue.
565 563
    bool emptyQueue() const { return _queue_tail==_queue_head; }
566 564

	
567 565
    ///Returns the number of the nodes to be processed.
568 566

	
569
    ///Returns the number of the nodes to be processed in the queue.
567
    ///Returns the number of the nodes to be processed
568
    ///in the queue.
570 569
    int queueSize() const { return _queue_head-_queue_tail; }
571 570

	
572 571
    ///Executes the algorithm.
573 572

	
574 573
    ///Executes the algorithm.
575 574
    ///
576 575
    ///This method runs the %BFS algorithm from the root node(s)
577 576
    ///in order to compute the shortest path to each node.
578 577
    ///
579 578
    ///The algorithm computes
580 579
    ///- the shortest path tree (forest),
581 580
    ///- the distance of each node from the root(s).
582 581
    ///
583 582
    ///\pre init() must be called and at least one root node should be
584 583
    ///added with addSource() before using this function.
585 584
    ///
586 585
    ///\note <tt>b.start()</tt> is just a shortcut of the following code.
587 586
    ///\code
588 587
    ///  while ( !b.emptyQueue() ) {
589 588
    ///    b.processNextNode();
590 589
    ///  }
591 590
    ///\endcode
592 591
    void start()
593 592
    {
594 593
      while ( !emptyQueue() ) processNextNode();
595 594
    }
596 595

	
597 596
    ///Executes the algorithm until the given target node is reached.
598 597

	
599 598
    ///Executes the algorithm until the given target node is reached.
600 599
    ///
601 600
    ///This method runs the %BFS algorithm from the root node(s)
602 601
    ///in order to compute the shortest path to \c t.
603 602
    ///
604 603
    ///The algorithm computes
605 604
    ///- the shortest path to \c t,
606 605
    ///- the distance of \c t from the root(s).
607 606
    ///
608 607
    ///\pre init() must be called and at least one root node should be
609 608
    ///added with addSource() before using this function.
610 609
    ///
611 610
    ///\note <tt>b.start(t)</tt> is just a shortcut of the following code.
612 611
    ///\code
613 612
    ///  bool reach = false;
614 613
    ///  while ( !b.emptyQueue() && !reach ) {
615 614
    ///    b.processNextNode(t, reach);
616 615
    ///  }
617 616
    ///\endcode
618 617
    void start(Node t)
619 618
    {
620 619
      bool reach = false;
621 620
      while ( !emptyQueue() && !reach ) processNextNode(t, reach);
622 621
    }
623 622

	
624 623
    ///Executes the algorithm until a condition is met.
625 624

	
626 625
    ///Executes the algorithm until a condition is met.
627 626
    ///
628 627
    ///This method runs the %BFS algorithm from the root node(s) in
629 628
    ///order to compute the shortest path to a node \c v with
630 629
    /// <tt>nm[v]</tt> true, if such a node can be found.
631 630
    ///
632 631
    ///\param nm A \c bool (or convertible) node map. The algorithm
633 632
    ///will stop when it reaches a node \c v with <tt>nm[v]</tt> true.
634 633
    ///
635 634
    ///\return The reached node \c v with <tt>nm[v]</tt> true or
636 635
    ///\c INVALID if no such node was found.
637 636
    ///
638 637
    ///\pre init() must be called and at least one root node should be
639 638
    ///added with addSource() before using this function.
640 639
    ///
641 640
    ///\note <tt>b.start(nm)</tt> is just a shortcut of the following code.
642 641
    ///\code
643 642
    ///  Node rnode = INVALID;
644 643
    ///  while ( !b.emptyQueue() && rnode == INVALID ) {
645 644
    ///    b.processNextNode(nm, rnode);
646 645
    ///  }
647 646
    ///  return rnode;
648 647
    ///\endcode
649 648
    template<class NodeBoolMap>
650 649
    Node start(const NodeBoolMap &nm)
651 650
    {
652 651
      Node rnode = INVALID;
653 652
      while ( !emptyQueue() && rnode == INVALID ) {
654 653
        processNextNode(nm, rnode);
655 654
      }
656 655
      return rnode;
657 656
    }
658 657

	
659 658
    ///Runs the algorithm from the given source node.
660 659

	
661 660
    ///This method runs the %BFS algorithm from node \c s
662 661
    ///in order to compute the shortest path to each node.
663 662
    ///
664 663
    ///The algorithm computes
665 664
    ///- the shortest path tree,
666 665
    ///- the distance of each node from the root.
667 666
    ///
668 667
    ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
669 668
    ///\code
670 669
    ///  b.init();
671 670
    ///  b.addSource(s);
672 671
    ///  b.start();
673 672
    ///\endcode
674 673
    void run(Node s) {
675 674
      init();
676 675
      addSource(s);
677 676
      start();
678 677
    }
679 678

	
680 679
    ///Finds the shortest path between \c s and \c t.
681 680

	
682 681
    ///This method runs the %BFS algorithm from node \c s
683 682
    ///in order to compute the shortest path to node \c t
684 683
    ///(it stops searching when \c t is processed).
685 684
    ///
686 685
    ///\return \c true if \c t is reachable form \c s.
687 686
    ///
688 687
    ///\note Apart from the return value, <tt>b.run(s,t)</tt> is just a
689 688
    ///shortcut of the following code.
690 689
    ///\code
691 690
    ///  b.init();
692 691
    ///  b.addSource(s);
693 692
    ///  b.start(t);
694 693
    ///\endcode
695 694
    bool run(Node s,Node t) {
696 695
      init();
697 696
      addSource(s);
698 697
      start(t);
699 698
      return reached(t);
700 699
    }
701 700

	
702 701
    ///Runs the algorithm to visit all nodes in the digraph.
703 702

	
704 703
    ///This method runs the %BFS algorithm in order to
705 704
    ///compute the shortest path to each node.
706 705
    ///
707 706
    ///The algorithm computes
708 707
    ///- the shortest path tree (forest),
709 708
    ///- the distance of each node from the root(s).
710 709
    ///
711 710
    ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
712 711
    ///\code
713 712
    ///  b.init();
714 713
    ///  for (NodeIt n(gr); n != INVALID; ++n) {
715 714
    ///    if (!b.reached(n)) {
716 715
    ///      b.addSource(n);
717 716
    ///      b.start();
718 717
    ///    }
719 718
    ///  }
720 719
    ///\endcode
721 720
    void run() {
722 721
      init();
723 722
      for (NodeIt n(*G); n != INVALID; ++n) {
724 723
        if (!reached(n)) {
725 724
          addSource(n);
726 725
          start();
727 726
        }
728 727
      }
729 728
    }
730 729

	
731 730
    ///@}
732 731

	
733 732
    ///\name Query Functions
734
    ///The result of the %BFS algorithm can be obtained using these
733
    ///The results of the BFS algorithm can be obtained using these
735 734
    ///functions.\n
736
    ///Either \ref lemon::Bfs::run() "run()" or \ref lemon::Bfs::start()
737
    ///"start()" must be called before using them.
735
    ///Either \ref run(Node) "run()" or \ref start() should be called
736
    ///before using them.
738 737

	
739 738
    ///@{
740 739

	
741 740
    ///The shortest path to a node.
742 741

	
743 742
    ///Returns the shortest path to a node.
744 743
    ///
745
    ///\warning \c t should be reachable from the root(s).
744
    ///\warning \c t should be reached from the root(s).
746 745
    ///
747
    ///\pre Either \ref run() or \ref start() must be called before
748
    ///using this function.
746
    ///\pre Either \ref run(Node) "run()" or \ref init()
747
    ///must be called before using this function.
749 748
    Path path(Node t) const { return Path(*G, *_pred, t); }
750 749

	
751 750
    ///The distance of a node from the root(s).
752 751

	
753 752
    ///Returns the distance of a node from the root(s).
754 753
    ///
755
    ///\warning If node \c v is not reachable from the root(s), then
754
    ///\warning If node \c v is not reached from the root(s), then
756 755
    ///the return value of this function is undefined.
757 756
    ///
758
    ///\pre Either \ref run() or \ref start() must be called before
759
    ///using this function.
757
    ///\pre Either \ref run(Node) "run()" or \ref init()
758
    ///must be called before using this function.
760 759
    int dist(Node v) const { return (*_dist)[v]; }
761 760

	
762 761
    ///Returns the 'previous arc' of the shortest path tree for a node.
763 762

	
764 763
    ///This function returns the 'previous arc' of the shortest path
765 764
    ///tree for the node \c v, i.e. it returns the last arc of a
766
    ///shortest path from the root(s) to \c v. It is \c INVALID if \c v
767
    ///is not reachable from the root(s) or if \c v is a root.
765
    ///shortest path from a root to \c v. It is \c INVALID if \c v
766
    ///is not reached from the root(s) or if \c v is a root.
768 767
    ///
769 768
    ///The shortest path tree used here is equal to the shortest path
770 769
    ///tree used in \ref predNode().
771 770
    ///
772
    ///\pre Either \ref run() or \ref start() must be called before
773
    ///using this function.
771
    ///\pre Either \ref run(Node) "run()" or \ref init()
772
    ///must be called before using this function.
774 773
    Arc predArc(Node v) const { return (*_pred)[v];}
775 774

	
776 775
    ///Returns the 'previous node' of the shortest path tree for a node.
777 776

	
778 777
    ///This function returns the 'previous node' of the shortest path
779 778
    ///tree for the node \c v, i.e. it returns the last but one node
780
    ///from a shortest path from the root(s) to \c v. It is \c INVALID
781
    ///if \c v is not reachable from the root(s) or if \c v is a root.
779
    ///from a shortest path from a root to \c v. It is \c INVALID
780
    ///if \c v is not reached from the root(s) or if \c v is a root.
782 781
    ///
783 782
    ///The shortest path tree used here is equal to the shortest path
784 783
    ///tree used in \ref predArc().
785 784
    ///
786
    ///\pre Either \ref run() or \ref start() must be called before
787
    ///using this function.
785
    ///\pre Either \ref run(Node) "run()" or \ref init()
786
    ///must be called before using this function.
788 787
    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
789 788
                                  G->source((*_pred)[v]); }
790 789

	
791 790
    ///\brief Returns a const reference to the node map that stores the
792 791
    /// distances of the nodes.
793 792
    ///
794 793
    ///Returns a const reference to the node map that stores the distances
795 794
    ///of the nodes calculated by the algorithm.
796 795
    ///
797
    ///\pre Either \ref run() or \ref init()
796
    ///\pre Either \ref run(Node) "run()" or \ref init()
798 797
    ///must be called before using this function.
799 798
    const DistMap &distMap() const { return *_dist;}
800 799

	
801 800
    ///\brief Returns a const reference to the node map that stores the
802 801
    ///predecessor arcs.
803 802
    ///
804 803
    ///Returns a const reference to the node map that stores the predecessor
805 804
    ///arcs, which form the shortest path tree.
806 805
    ///
807
    ///\pre Either \ref run() or \ref init()
806
    ///\pre Either \ref run(Node) "run()" or \ref init()
808 807
    ///must be called before using this function.
809 808
    const PredMap &predMap() const { return *_pred;}
810 809

	
811
    ///Checks if a node is reachable from the root(s).
810
    ///Checks if a node is reached from the root(s).
812 811

	
813
    ///Returns \c true if \c v is reachable from the root(s).
814
    ///\pre Either \ref run() or \ref start()
812
    ///Returns \c true if \c v is reached from the root(s).
813
    ///
814
    ///\pre Either \ref run(Node) "run()" or \ref init()
815 815
    ///must be called before using this function.
816 816
    bool reached(Node v) const { return (*_reached)[v]; }
817 817

	
818 818
    ///@}
819 819
  };
820 820

	
821 821
  ///Default traits class of bfs() function.
822 822

	
823 823
  ///Default traits class of bfs() function.
824 824
  ///\tparam GR Digraph type.
825 825
  template<class GR>
826 826
  struct BfsWizardDefaultTraits
827 827
  {
828 828
    ///The type of the digraph the algorithm runs on.
829 829
    typedef GR Digraph;
830 830

	
831 831
    ///\brief The type of the map that stores the predecessor
832 832
    ///arcs of the shortest paths.
833 833
    ///
834 834
    ///The type of the map that stores the predecessor
835 835
    ///arcs of the shortest paths.
836 836
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
837 837
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
838 838
    ///Instantiates a PredMap.
839 839

	
840 840
    ///This function instantiates a PredMap.
841 841
    ///\param g is the digraph, to which we would like to define the
842 842
    ///PredMap.
843 843
    static PredMap *createPredMap(const Digraph &g)
844 844
    {
845 845
      return new PredMap(g);
846 846
    }
847 847

	
848 848
    ///The type of the map that indicates which nodes are processed.
849 849

	
850 850
    ///The type of the map that indicates which nodes are processed.
851 851
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
852 852
    ///By default it is a NullMap.
853 853
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
854 854
    ///Instantiates a ProcessedMap.
855 855

	
856 856
    ///This function instantiates a ProcessedMap.
857 857
    ///\param g is the digraph, to which
858 858
    ///we would like to define the ProcessedMap.
859 859
#ifdef DOXYGEN
860 860
    static ProcessedMap *createProcessedMap(const Digraph &g)
861 861
#else
862 862
    static ProcessedMap *createProcessedMap(const Digraph &)
863 863
#endif
864 864
    {
865 865
      return new ProcessedMap();
866 866
    }
867 867

	
868 868
    ///The type of the map that indicates which nodes are reached.
869 869

	
870 870
    ///The type of the map that indicates which nodes are reached.
871 871
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
872 872
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
873 873
    ///Instantiates a ReachedMap.
874 874

	
875 875
    ///This function instantiates a ReachedMap.
876 876
    ///\param g is the digraph, to which
877 877
    ///we would like to define the ReachedMap.
878 878
    static ReachedMap *createReachedMap(const Digraph &g)
879 879
    {
880 880
      return new ReachedMap(g);
881 881
    }
882 882

	
883 883
    ///The type of the map that stores the distances of the nodes.
884 884

	
885 885
    ///The type of the map that stores the distances of the nodes.
886 886
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
887 887
    typedef typename Digraph::template NodeMap<int> DistMap;
888 888
    ///Instantiates a DistMap.
889 889

	
890 890
    ///This function instantiates a DistMap.
891 891
    ///\param g is the digraph, to which we would like to define
892 892
    ///the DistMap
893 893
    static DistMap *createDistMap(const Digraph &g)
894 894
    {
895 895
      return new DistMap(g);
896 896
    }
897 897

	
898 898
    ///The type of the shortest paths.
899 899

	
900 900
    ///The type of the shortest paths.
901 901
    ///It must meet the \ref concepts::Path "Path" concept.
902 902
    typedef lemon::Path<Digraph> Path;
903 903
  };
904 904

	
905 905
  /// Default traits class used by BfsWizard
906 906

	
907 907
  /// To make it easier to use Bfs algorithm
908 908
  /// we have created a wizard class.
909 909
  /// This \ref BfsWizard class needs default traits,
910 910
  /// as well as the \ref Bfs class.
911 911
  /// The \ref BfsWizardBase is a class to be the default traits of the
912 912
  /// \ref BfsWizard class.
913 913
  template<class GR>
914 914
  class BfsWizardBase : public BfsWizardDefaultTraits<GR>
915 915
  {
916 916

	
917 917
    typedef BfsWizardDefaultTraits<GR> Base;
918 918
  protected:
919 919
    //The type of the nodes in the digraph.
920 920
    typedef typename Base::Digraph::Node Node;
921 921

	
922 922
    //Pointer to the digraph the algorithm runs on.
923 923
    void *_g;
924 924
    //Pointer to the map of reached nodes.
925 925
    void *_reached;
926 926
    //Pointer to the map of processed nodes.
927 927
    void *_processed;
928 928
    //Pointer to the map of predecessors arcs.
929 929
    void *_pred;
930 930
    //Pointer to the map of distances.
931 931
    void *_dist;
932 932
    //Pointer to the shortest path to the target node.
933 933
    void *_path;
934 934
    //Pointer to the distance of the target node.
935 935
    int *_di;
936 936

	
937 937
    public:
938 938
    /// Constructor.
939 939

	
940 940
    /// This constructor does not require parameters, therefore it initiates
941 941
    /// all of the attributes to \c 0.
942 942
    BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
943 943
                      _dist(0), _path(0), _di(0) {}
944 944

	
945 945
    /// Constructor.
946 946

	
947 947
    /// This constructor requires one parameter,
948 948
    /// others are initiated to \c 0.
949 949
    /// \param g The digraph the algorithm runs on.
950 950
    BfsWizardBase(const GR &g) :
951 951
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
952 952
      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
953 953

	
954 954
  };
955 955

	
956 956
  /// Auxiliary class for the function-type interface of BFS algorithm.
957 957

	
958 958
  /// This auxiliary class is created to implement the
959 959
  /// \ref bfs() "function-type interface" of \ref Bfs algorithm.
960
  /// It does not have own \ref run() method, it uses the functions
961
  /// and features of the plain \ref Bfs.
960
  /// It does not have own \ref run(Node) "run()" method, it uses the
961
  /// functions and features of the plain \ref Bfs.
962 962
  ///
963 963
  /// This class should only be used through the \ref bfs() function,
964 964
  /// which makes it easier to use the algorithm.
965 965
  template<class TR>
966 966
  class BfsWizard : public TR
967 967
  {
968 968
    typedef TR Base;
969 969

	
970 970
    ///The type of the digraph the algorithm runs on.
971 971
    typedef typename TR::Digraph Digraph;
972 972

	
973 973
    typedef typename Digraph::Node Node;
974 974
    typedef typename Digraph::NodeIt NodeIt;
975 975
    typedef typename Digraph::Arc Arc;
976 976
    typedef typename Digraph::OutArcIt OutArcIt;
977 977

	
978 978
    ///\brief The type of the map that stores the predecessor
979 979
    ///arcs of the shortest paths.
980 980
    typedef typename TR::PredMap PredMap;
981 981
    ///\brief The type of the map that stores the distances of the nodes.
982 982
    typedef typename TR::DistMap DistMap;
983 983
    ///\brief The type of the map that indicates which nodes are reached.
984 984
    typedef typename TR::ReachedMap ReachedMap;
985 985
    ///\brief The type of the map that indicates which nodes are processed.
986 986
    typedef typename TR::ProcessedMap ProcessedMap;
987 987
    ///The type of the shortest paths
988 988
    typedef typename TR::Path Path;
989 989

	
990 990
  public:
991 991

	
992 992
    /// Constructor.
993 993
    BfsWizard() : TR() {}
994 994

	
995 995
    /// Constructor that requires parameters.
996 996

	
997 997
    /// Constructor that requires parameters.
998 998
    /// These parameters will be the default values for the traits class.
999 999
    /// \param g The digraph the algorithm runs on.
1000 1000
    BfsWizard(const Digraph &g) :
1001 1001
      TR(g) {}
1002 1002

	
1003 1003
    ///Copy constructor
1004 1004
    BfsWizard(const TR &b) : TR(b) {}
1005 1005

	
1006 1006
    ~BfsWizard() {}
1007 1007

	
1008 1008
    ///Runs BFS algorithm from the given source node.
1009 1009

	
1010 1010
    ///This method runs BFS algorithm from node \c s
1011 1011
    ///in order to compute the shortest path to each node.
1012 1012
    void run(Node s)
1013 1013
    {
1014 1014
      Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
1015 1015
      if (Base::_pred)
1016 1016
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1017 1017
      if (Base::_dist)
1018 1018
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1019 1019
      if (Base::_reached)
1020 1020
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
1021 1021
      if (Base::_processed)
1022 1022
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1023 1023
      if (s!=INVALID)
1024 1024
        alg.run(s);
1025 1025
      else
1026 1026
        alg.run();
1027 1027
    }
1028 1028

	
1029 1029
    ///Finds the shortest path between \c s and \c t.
1030 1030

	
1031 1031
    ///This method runs BFS algorithm from node \c s
1032 1032
    ///in order to compute the shortest path to node \c t
1033 1033
    ///(it stops searching when \c t is processed).
1034 1034
    ///
1035 1035
    ///\return \c true if \c t is reachable form \c s.
1036 1036
    bool run(Node s, Node t)
1037 1037
    {
1038 1038
      Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
1039 1039
      if (Base::_pred)
1040 1040
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1041 1041
      if (Base::_dist)
1042 1042
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1043 1043
      if (Base::_reached)
1044 1044
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
1045 1045
      if (Base::_processed)
1046 1046
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1047 1047
      alg.run(s,t);
1048 1048
      if (Base::_path)
1049 1049
        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
1050 1050
      if (Base::_di)
1051 1051
        *Base::_di = alg.dist(t);
1052 1052
      return alg.reached(t);
1053 1053
    }
1054 1054

	
1055 1055
    ///Runs BFS algorithm to visit all nodes in the digraph.
1056 1056

	
1057 1057
    ///This method runs BFS algorithm in order to compute
1058 1058
    ///the shortest path to each node.
1059 1059
    void run()
1060 1060
    {
1061 1061
      run(INVALID);
1062 1062
    }
1063 1063

	
1064 1064
    template<class T>
1065 1065
    struct SetPredMapBase : public Base {
1066 1066
      typedef T PredMap;
1067 1067
      static PredMap *createPredMap(const Digraph &) { return 0; };
1068 1068
      SetPredMapBase(const TR &b) : TR(b) {}
1069 1069
    };
1070 1070
    ///\brief \ref named-func-param "Named parameter"
1071 1071
    ///for setting PredMap object.
1072 1072
    ///
1073 1073
    ///\ref named-func-param "Named parameter"
1074 1074
    ///for setting PredMap object.
1075 1075
    template<class T>
1076 1076
    BfsWizard<SetPredMapBase<T> > predMap(const T &t)
1077 1077
    {
1078 1078
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1079 1079
      return BfsWizard<SetPredMapBase<T> >(*this);
1080 1080
    }
1081 1081

	
1082 1082
    template<class T>
1083 1083
    struct SetReachedMapBase : public Base {
1084 1084
      typedef T ReachedMap;
1085 1085
      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
1086 1086
      SetReachedMapBase(const TR &b) : TR(b) {}
1087 1087
    };
1088 1088
    ///\brief \ref named-func-param "Named parameter"
1089 1089
    ///for setting ReachedMap object.
1090 1090
    ///
1091 1091
    /// \ref named-func-param "Named parameter"
1092 1092
    ///for setting ReachedMap object.
1093 1093
    template<class T>
1094 1094
    BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
1095 1095
    {
1096 1096
      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
1097 1097
      return BfsWizard<SetReachedMapBase<T> >(*this);
1098 1098
    }
1099 1099

	
1100 1100
    template<class T>
1101 1101
    struct SetDistMapBase : public Base {
1102 1102
      typedef T DistMap;
1103 1103
      static DistMap *createDistMap(const Digraph &) { return 0; };
1104 1104
      SetDistMapBase(const TR &b) : TR(b) {}
1105 1105
    };
1106 1106
    ///\brief \ref named-func-param "Named parameter"
1107 1107
    ///for setting DistMap object.
1108 1108
    ///
1109 1109
    /// \ref named-func-param "Named parameter"
1110 1110
    ///for setting DistMap object.
1111 1111
    template<class T>
1112 1112
    BfsWizard<SetDistMapBase<T> > distMap(const T &t)
1113 1113
    {
1114 1114
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1115 1115
      return BfsWizard<SetDistMapBase<T> >(*this);
1116 1116
    }
1117 1117

	
1118 1118
    template<class T>
1119 1119
    struct SetProcessedMapBase : public Base {
1120 1120
      typedef T ProcessedMap;
1121 1121
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1122 1122
      SetProcessedMapBase(const TR &b) : TR(b) {}
1123 1123
    };
1124 1124
    ///\brief \ref named-func-param "Named parameter"
1125 1125
    ///for setting ProcessedMap object.
1126 1126
    ///
1127 1127
    /// \ref named-func-param "Named parameter"
1128 1128
    ///for setting ProcessedMap object.
1129 1129
    template<class T>
1130 1130
    BfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
1131 1131
    {
1132 1132
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1133 1133
      return BfsWizard<SetProcessedMapBase<T> >(*this);
1134 1134
    }
1135 1135

	
1136 1136
    template<class T>
1137 1137
    struct SetPathBase : public Base {
1138 1138
      typedef T Path;
1139 1139
      SetPathBase(const TR &b) : TR(b) {}
1140 1140
    };
1141 1141
    ///\brief \ref named-func-param "Named parameter"
1142 1142
    ///for getting the shortest path to the target node.
1143 1143
    ///
1144 1144
    ///\ref named-func-param "Named parameter"
1145 1145
    ///for getting the shortest path to the target node.
1146 1146
    template<class T>
1147 1147
    BfsWizard<SetPathBase<T> > path(const T &t)
1148 1148
    {
1149 1149
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1150 1150
      return BfsWizard<SetPathBase<T> >(*this);
1151 1151
    }
1152 1152

	
1153 1153
    ///\brief \ref named-func-param "Named parameter"
1154 1154
    ///for getting the distance of the target node.
1155 1155
    ///
1156 1156
    ///\ref named-func-param "Named parameter"
1157 1157
    ///for getting the distance of the target node.
1158 1158
    BfsWizard dist(const int &d)
1159 1159
    {
1160 1160
      Base::_di=const_cast<int*>(&d);
1161 1161
      return *this;
1162 1162
    }
1163 1163

	
1164 1164
  };
1165 1165

	
1166 1166
  ///Function-type interface for BFS algorithm.
1167 1167

	
1168 1168
  /// \ingroup search
1169 1169
  ///Function-type interface for BFS algorithm.
1170 1170
  ///
1171 1171
  ///This function also has several \ref named-func-param "named parameters",
1172 1172
  ///they are declared as the members of class \ref BfsWizard.
1173 1173
  ///The following examples show how to use these parameters.
1174 1174
  ///\code
1175 1175
  ///  // Compute shortest path from node s to each node
1176 1176
  ///  bfs(g).predMap(preds).distMap(dists).run(s);
1177 1177
  ///
1178 1178
  ///  // Compute shortest path from s to t
1179 1179
  ///  bool reached = bfs(g).path(p).dist(d).run(s,t);
1180 1180
  ///\endcode
1181
  ///\warning Don't forget to put the \ref BfsWizard::run() "run()"
1181
  ///\warning Don't forget to put the \ref BfsWizard::run(Node) "run()"
1182 1182
  ///to the end of the parameter list.
1183 1183
  ///\sa BfsWizard
1184 1184
  ///\sa Bfs
1185 1185
  template<class GR>
1186 1186
  BfsWizard<BfsWizardBase<GR> >
1187 1187
  bfs(const GR &digraph)
1188 1188
  {
1189 1189
    return BfsWizard<BfsWizardBase<GR> >(digraph);
1190 1190
  }
1191 1191

	
1192 1192
#ifdef DOXYGEN
1193 1193
  /// \brief Visitor class for BFS.
1194 1194
  ///
1195 1195
  /// This class defines the interface of the BfsVisit events, and
1196 1196
  /// it could be the base of a real visitor class.
1197
  template <typename _Digraph>
1197
  template <typename GR>
1198 1198
  struct BfsVisitor {
1199
    typedef _Digraph Digraph;
1199
    typedef GR Digraph;
1200 1200
    typedef typename Digraph::Arc Arc;
1201 1201
    typedef typename Digraph::Node Node;
1202 1202
    /// \brief Called for the source node(s) of the BFS.
1203 1203
    ///
1204 1204
    /// This function is called for the source node(s) of the BFS.
1205 1205
    void start(const Node& node) {}
1206 1206
    /// \brief Called when a node is reached first time.
1207 1207
    ///
1208 1208
    /// This function is called when a node is reached first time.
1209 1209
    void reach(const Node& node) {}
1210 1210
    /// \brief Called when a node is processed.
1211 1211
    ///
1212 1212
    /// This function is called when a node is processed.
1213 1213
    void process(const Node& node) {}
1214 1214
    /// \brief Called when an arc reaches a new node.
1215 1215
    ///
1216 1216
    /// This function is called when the BFS finds an arc whose target node
1217 1217
    /// is not reached yet.
1218 1218
    void discover(const Arc& arc) {}
1219 1219
    /// \brief Called when an arc is examined but its target node is
1220 1220
    /// already discovered.
1221 1221
    ///
1222 1222
    /// This function is called when an arc is examined but its target node is
1223 1223
    /// already discovered.
1224 1224
    void examine(const Arc& arc) {}
1225 1225
  };
1226 1226
#else
1227
  template <typename _Digraph>
1227
  template <typename GR>
1228 1228
  struct BfsVisitor {
1229
    typedef _Digraph Digraph;
1229
    typedef GR Digraph;
1230 1230
    typedef typename Digraph::Arc Arc;
1231 1231
    typedef typename Digraph::Node Node;
1232 1232
    void start(const Node&) {}
1233 1233
    void reach(const Node&) {}
1234 1234
    void process(const Node&) {}
1235 1235
    void discover(const Arc&) {}
1236 1236
    void examine(const Arc&) {}
1237 1237

	
1238 1238
    template <typename _Visitor>
1239 1239
    struct Constraints {
1240 1240
      void constraints() {
1241 1241
        Arc arc;
1242 1242
        Node node;
1243 1243
        visitor.start(node);
1244 1244
        visitor.reach(node);
1245 1245
        visitor.process(node);
1246 1246
        visitor.discover(arc);
1247 1247
        visitor.examine(arc);
1248 1248
      }
1249 1249
      _Visitor& visitor;
1250 1250
    };
1251 1251
  };
1252 1252
#endif
1253 1253

	
1254 1254
  /// \brief Default traits class of BfsVisit class.
1255 1255
  ///
1256 1256
  /// Default traits class of BfsVisit class.
1257
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1258
  template<class _Digraph>
1257
  /// \tparam GR The type of the digraph the algorithm runs on.
1258
  template<class GR>
1259 1259
  struct BfsVisitDefaultTraits {
1260 1260

	
1261 1261
    /// \brief The type of the digraph the algorithm runs on.
1262
    typedef _Digraph Digraph;
1262
    typedef GR Digraph;
1263 1263

	
1264 1264
    /// \brief The type of the map that indicates which nodes are reached.
1265 1265
    ///
1266 1266
    /// The type of the map that indicates which nodes are reached.
1267 1267
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1268 1268
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
1269 1269

	
1270 1270
    /// \brief Instantiates a ReachedMap.
1271 1271
    ///
1272 1272
    /// This function instantiates a ReachedMap.
1273 1273
    /// \param digraph is the digraph, to which
1274 1274
    /// we would like to define the ReachedMap.
1275 1275
    static ReachedMap *createReachedMap(const Digraph &digraph) {
1276 1276
      return new ReachedMap(digraph);
1277 1277
    }
1278 1278

	
1279 1279
  };
1280 1280

	
1281 1281
  /// \ingroup search
1282 1282
  ///
1283
  /// \brief %BFS algorithm class with visitor interface.
1283
  /// \brief BFS algorithm class with visitor interface.
1284 1284
  ///
1285
  /// This class provides an efficient implementation of the %BFS algorithm
1285
  /// This class provides an efficient implementation of the BFS algorithm
1286 1286
  /// with visitor interface.
1287 1287
  ///
1288
  /// The %BfsVisit class provides an alternative interface to the Bfs
1288
  /// The BfsVisit class provides an alternative interface to the Bfs
1289 1289
  /// class. It works with callback mechanism, the BfsVisit object calls
1290 1290
  /// the member functions of the \c Visitor class on every BFS event.
1291 1291
  ///
1292 1292
  /// This interface of the BFS algorithm should be used in special cases
1293 1293
  /// when extra actions have to be performed in connection with certain
1294 1294
  /// events of the BFS algorithm. Otherwise consider to use Bfs or bfs()
1295 1295
  /// instead.
1296 1296
  ///
1297
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1298
  /// The default value is
1299
  /// \ref ListDigraph. The value of _Digraph is not used directly by
1300
  /// \ref BfsVisit, it is only passed to \ref BfsVisitDefaultTraits.
1301
  /// \tparam _Visitor The Visitor type that is used by the algorithm.
1302
  /// \ref BfsVisitor "BfsVisitor<_Digraph>" is an empty visitor, which
1297
  /// \tparam GR The type of the digraph the algorithm runs on.
1298
  /// The default type is \ref ListDigraph.
1299
  /// The value of GR is not used directly by \ref BfsVisit,
1300
  /// it is only passed to \ref BfsVisitDefaultTraits.
1301
  /// \tparam VS The Visitor type that is used by the algorithm.
1302
  /// \ref BfsVisitor "BfsVisitor<GR>" is an empty visitor, which
1303 1303
  /// does not observe the BFS events. If you want to observe the BFS
1304 1304
  /// events, you should implement your own visitor class.
1305
  /// \tparam _Traits Traits class to set various data types used by the
1305
  /// \tparam TR Traits class to set various data types used by the
1306 1306
  /// algorithm. The default traits class is
1307
  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<_Digraph>".
1307
  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<GR>".
1308 1308
  /// See \ref BfsVisitDefaultTraits for the documentation of
1309 1309
  /// a BFS visit traits class.
1310 1310
#ifdef DOXYGEN
1311
  template <typename _Digraph, typename _Visitor, typename _Traits>
1311
  template <typename GR, typename VS, typename TR>
1312 1312
#else
1313
  template <typename _Digraph = ListDigraph,
1314
            typename _Visitor = BfsVisitor<_Digraph>,
1315
            typename _Traits = BfsVisitDefaultTraits<_Digraph> >
1313
  template <typename GR = ListDigraph,
1314
            typename VS = BfsVisitor<GR>,
1315
            typename TR = BfsVisitDefaultTraits<GR> >
1316 1316
#endif
1317 1317
  class BfsVisit {
1318 1318
  public:
1319 1319

	
1320 1320
    ///The traits class.
1321
    typedef _Traits Traits;
1321
    typedef TR Traits;
1322 1322

	
1323 1323
    ///The type of the digraph the algorithm runs on.
1324 1324
    typedef typename Traits::Digraph Digraph;
1325 1325

	
1326 1326
    ///The visitor type used by the algorithm.
1327
    typedef _Visitor Visitor;
1327
    typedef VS Visitor;
1328 1328

	
1329 1329
    ///The type of the map that indicates which nodes are reached.
1330 1330
    typedef typename Traits::ReachedMap ReachedMap;
1331 1331

	
1332 1332
  private:
1333 1333

	
1334 1334
    typedef typename Digraph::Node Node;
1335 1335
    typedef typename Digraph::NodeIt NodeIt;
1336 1336
    typedef typename Digraph::Arc Arc;
1337 1337
    typedef typename Digraph::OutArcIt OutArcIt;
1338 1338

	
1339 1339
    //Pointer to the underlying digraph.
1340 1340
    const Digraph *_digraph;
1341 1341
    //Pointer to the visitor object.
1342 1342
    Visitor *_visitor;
1343 1343
    //Pointer to the map of reached status of the nodes.
1344 1344
    ReachedMap *_reached;
1345 1345
    //Indicates if _reached is locally allocated (true) or not.
1346 1346
    bool local_reached;
1347 1347

	
1348 1348
    std::vector<typename Digraph::Node> _list;
1349 1349
    int _list_front, _list_back;
1350 1350

	
1351 1351
    //Creates the maps if necessary.
1352 1352
    void create_maps() {
1353 1353
      if(!_reached) {
1354 1354
        local_reached = true;
1355 1355
        _reached = Traits::createReachedMap(*_digraph);
1356 1356
      }
1357 1357
    }
1358 1358

	
1359 1359
  protected:
1360 1360

	
1361 1361
    BfsVisit() {}
1362 1362

	
1363 1363
  public:
1364 1364

	
1365 1365
    typedef BfsVisit Create;
1366 1366

	
1367
    /// \name Named template parameters
1367
    /// \name Named Template Parameters
1368 1368

	
1369 1369
    ///@{
1370 1370
    template <class T>
1371 1371
    struct SetReachedMapTraits : public Traits {
1372 1372
      typedef T ReachedMap;
1373 1373
      static ReachedMap *createReachedMap(const Digraph &digraph) {
1374 1374
        LEMON_ASSERT(false, "ReachedMap is not initialized");
1375 1375
        return 0; // ignore warnings
1376 1376
      }
1377 1377
    };
1378 1378
    /// \brief \ref named-templ-param "Named parameter" for setting
1379 1379
    /// ReachedMap type.
1380 1380
    ///
1381 1381
    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
1382 1382
    template <class T>
1383 1383
    struct SetReachedMap : public BfsVisit< Digraph, Visitor,
1384 1384
                                            SetReachedMapTraits<T> > {
1385 1385
      typedef BfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
1386 1386
    };
1387 1387
    ///@}
1388 1388

	
1389 1389
  public:
1390 1390

	
1391 1391
    /// \brief Constructor.
1392 1392
    ///
1393 1393
    /// Constructor.
1394 1394
    ///
1395 1395
    /// \param digraph The digraph the algorithm runs on.
1396 1396
    /// \param visitor The visitor object of the algorithm.
1397 1397
    BfsVisit(const Digraph& digraph, Visitor& visitor)
1398 1398
      : _digraph(&digraph), _visitor(&visitor),
1399 1399
        _reached(0), local_reached(false) {}
1400 1400

	
1401 1401
    /// \brief Destructor.
1402 1402
    ~BfsVisit() {
1403 1403
      if(local_reached) delete _reached;
1404 1404
    }
1405 1405

	
1406 1406
    /// \brief Sets the map that indicates which nodes are reached.
1407 1407
    ///
1408 1408
    /// Sets the map that indicates which nodes are reached.
1409
    /// If you don't use this function before calling \ref run(),
1410
    /// it will allocate one. The destructor deallocates this
1411
    /// automatically allocated map, of course.
1409
    /// If you don't use this function before calling \ref run(Node) "run()"
1410
    /// or \ref init(), an instance will be allocated automatically.
1411
    /// The destructor deallocates this automatically allocated map,
1412
    /// of course.
1412 1413
    /// \return <tt> (*this) </tt>
1413 1414
    BfsVisit &reachedMap(ReachedMap &m) {
1414 1415
      if(local_reached) {
1415 1416
        delete _reached;
1416 1417
        local_reached = false;
1417 1418
      }
1418 1419
      _reached = &m;
1419 1420
      return *this;
1420 1421
    }
1421 1422

	
1422 1423
  public:
1423 1424

	
1424
    /// \name Execution control
1425
    /// The simplest way to execute the algorithm is to use
1426
    /// one of the member functions called \ref lemon::BfsVisit::run()
1427
    /// "run()".
1428
    /// \n
1429
    /// If you need more control on the execution, first you must call
1430
    /// \ref lemon::BfsVisit::init() "init()", then you can add several
1431
    /// source nodes with \ref lemon::BfsVisit::addSource() "addSource()".
1432
    /// Finally \ref lemon::BfsVisit::start() "start()" will perform the
1433
    /// actual path computation.
1425
    /// \name Execution Control
1426
    /// The simplest way to execute the BFS algorithm is to use one of the
1427
    /// member functions called \ref run(Node) "run()".\n
1428
    /// If you need more control on the execution, first you have to call
1429
    /// \ref init(), then you can add several source nodes with
1430
    /// \ref addSource(). Finally the actual path computation can be
1431
    /// performed with one of the \ref start() functions.
1434 1432

	
1435 1433
    /// @{
1436 1434

	
1437 1435
    /// \brief Initializes the internal data structures.
1438 1436
    ///
1439 1437
    /// Initializes the internal data structures.
1440 1438
    void init() {
1441 1439
      create_maps();
1442 1440
      _list.resize(countNodes(*_digraph));
1443 1441
      _list_front = _list_back = -1;
1444 1442
      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
1445 1443
        _reached->set(u, false);
1446 1444
      }
1447 1445
    }
1448 1446

	
1449 1447
    /// \brief Adds a new source node.
1450 1448
    ///
1451 1449
    /// Adds a new source node to the set of nodes to be processed.
1452 1450
    void addSource(Node s) {
1453 1451
      if(!(*_reached)[s]) {
1454 1452
          _reached->set(s,true);
1455 1453
          _visitor->start(s);
1456 1454
          _visitor->reach(s);
1457 1455
          _list[++_list_back] = s;
1458 1456
        }
1459 1457
    }
1460 1458

	
1461 1459
    /// \brief Processes the next node.
1462 1460
    ///
1463 1461
    /// Processes the next node.
1464 1462
    ///
1465 1463
    /// \return The processed node.
1466 1464
    ///
1467 1465
    /// \pre The queue must not be empty.
1468 1466
    Node processNextNode() {
1469 1467
      Node n = _list[++_list_front];
1470 1468
      _visitor->process(n);
1471 1469
      Arc e;
1472 1470
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1473 1471
        Node m = _digraph->target(e);
1474 1472
        if (!(*_reached)[m]) {
1475 1473
          _visitor->discover(e);
1476 1474
          _visitor->reach(m);
1477 1475
          _reached->set(m, true);
1478 1476
          _list[++_list_back] = m;
1479 1477
        } else {
1480 1478
          _visitor->examine(e);
1481 1479
        }
1482 1480
      }
1483 1481
      return n;
1484 1482
    }
1485 1483

	
1486 1484
    /// \brief Processes the next node.
1487 1485
    ///
1488 1486
    /// Processes the next node and checks if the given target node
1489 1487
    /// is reached. If the target node is reachable from the processed
1490 1488
    /// node, then the \c reach parameter will be set to \c true.
1491 1489
    ///
1492 1490
    /// \param target The target node.
1493 1491
    /// \retval reach Indicates if the target node is reached.
1494 1492
    /// It should be initially \c false.
1495 1493
    ///
1496 1494
    /// \return The processed node.
1497 1495
    ///
1498 1496
    /// \pre The queue must not be empty.
1499 1497
    Node processNextNode(Node target, bool& reach) {
1500 1498
      Node n = _list[++_list_front];
1501 1499
      _visitor->process(n);
1502 1500
      Arc e;
1503 1501
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1504 1502
        Node m = _digraph->target(e);
1505 1503
        if (!(*_reached)[m]) {
1506 1504
          _visitor->discover(e);
1507 1505
          _visitor->reach(m);
1508 1506
          _reached->set(m, true);
1509 1507
          _list[++_list_back] = m;
1510 1508
          reach = reach || (target == m);
1511 1509
        } else {
1512 1510
          _visitor->examine(e);
1513 1511
        }
1514 1512
      }
1515 1513
      return n;
1516 1514
    }
1517 1515

	
1518 1516
    /// \brief Processes the next node.
1519 1517
    ///
1520 1518
    /// Processes the next node and checks if at least one of reached
1521 1519
    /// nodes has \c true value in the \c nm node map. If one node
1522 1520
    /// with \c true value is reachable from the processed node, then the
1523 1521
    /// \c rnode parameter will be set to the first of such nodes.
1524 1522
    ///
1525 1523
    /// \param nm A \c bool (or convertible) node map that indicates the
1526 1524
    /// possible targets.
1527 1525
    /// \retval rnode The reached target node.
1528 1526
    /// It should be initially \c INVALID.
1529 1527
    ///
1530 1528
    /// \return The processed node.
1531 1529
    ///
1532 1530
    /// \pre The queue must not be empty.
1533 1531
    template <typename NM>
1534 1532
    Node processNextNode(const NM& nm, Node& rnode) {
1535 1533
      Node n = _list[++_list_front];
1536 1534
      _visitor->process(n);
1537 1535
      Arc e;
1538 1536
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1539 1537
        Node m = _digraph->target(e);
1540 1538
        if (!(*_reached)[m]) {
1541 1539
          _visitor->discover(e);
1542 1540
          _visitor->reach(m);
1543 1541
          _reached->set(m, true);
1544 1542
          _list[++_list_back] = m;
1545 1543
          if (nm[m] && rnode == INVALID) rnode = m;
1546 1544
        } else {
1547 1545
          _visitor->examine(e);
1548 1546
        }
1549 1547
      }
1550 1548
      return n;
1551 1549
    }
1552 1550

	
1553 1551
    /// \brief The next node to be processed.
1554 1552
    ///
1555 1553
    /// Returns the next node to be processed or \c INVALID if the queue
1556 1554
    /// is empty.
1557 1555
    Node nextNode() const {
1558 1556
      return _list_front != _list_back ? _list[_list_front + 1] : INVALID;
1559 1557
    }
1560 1558

	
1561 1559
    /// \brief Returns \c false if there are nodes
1562 1560
    /// to be processed.
1563 1561
    ///
1564 1562
    /// Returns \c false if there are nodes
1565 1563
    /// to be processed in the queue.
1566 1564
    bool emptyQueue() const { return _list_front == _list_back; }
1567 1565

	
1568 1566
    /// \brief Returns the number of the nodes to be processed.
1569 1567
    ///
1570 1568
    /// Returns the number of the nodes to be processed in the queue.
1571 1569
    int queueSize() const { return _list_back - _list_front; }
1572 1570

	
1573 1571
    /// \brief Executes the algorithm.
1574 1572
    ///
1575 1573
    /// Executes the algorithm.
1576 1574
    ///
1577 1575
    /// This method runs the %BFS algorithm from the root node(s)
1578 1576
    /// in order to compute the shortest path to each node.
1579 1577
    ///
1580 1578
    /// The algorithm computes
1581 1579
    /// - the shortest path tree (forest),
1582 1580
    /// - the distance of each node from the root(s).
1583 1581
    ///
1584 1582
    /// \pre init() must be called and at least one root node should be added
1585 1583
    /// with addSource() before using this function.
1586 1584
    ///
1587 1585
    /// \note <tt>b.start()</tt> is just a shortcut of the following code.
1588 1586
    /// \code
1589 1587
    ///   while ( !b.emptyQueue() ) {
1590 1588
    ///     b.processNextNode();
1591 1589
    ///   }
1592 1590
    /// \endcode
1593 1591
    void start() {
1594 1592
      while ( !emptyQueue() ) processNextNode();
1595 1593
    }
1596 1594

	
1597 1595
    /// \brief Executes the algorithm until the given target node is reached.
1598 1596
    ///
1599 1597
    /// Executes the algorithm until the given target node is reached.
1600 1598
    ///
1601 1599
    /// This method runs the %BFS algorithm from the root node(s)
1602 1600
    /// in order to compute the shortest path to \c t.
1603 1601
    ///
1604 1602
    /// The algorithm computes
1605 1603
    /// - the shortest path to \c t,
1606 1604
    /// - the distance of \c t from the root(s).
1607 1605
    ///
1608 1606
    /// \pre init() must be called and at least one root node should be
1609 1607
    /// added with addSource() before using this function.
1610 1608
    ///
1611 1609
    /// \note <tt>b.start(t)</tt> is just a shortcut of the following code.
1612 1610
    /// \code
1613 1611
    ///   bool reach = false;
1614 1612
    ///   while ( !b.emptyQueue() && !reach ) {
1615 1613
    ///     b.processNextNode(t, reach);
1616 1614
    ///   }
1617 1615
    /// \endcode
1618 1616
    void start(Node t) {
1619 1617
      bool reach = false;
1620 1618
      while ( !emptyQueue() && !reach ) processNextNode(t, reach);
1621 1619
    }
1622 1620

	
1623 1621
    /// \brief Executes the algorithm until a condition is met.
1624 1622
    ///
1625 1623
    /// Executes the algorithm until a condition is met.
1626 1624
    ///
1627 1625
    /// This method runs the %BFS algorithm from the root node(s) in
1628 1626
    /// order to compute the shortest path to a node \c v with
1629 1627
    /// <tt>nm[v]</tt> true, if such a node can be found.
1630 1628
    ///
1631 1629
    /// \param nm must be a bool (or convertible) node map. The
1632 1630
    /// algorithm will stop when it reaches a node \c v with
1633 1631
    /// <tt>nm[v]</tt> true.
1634 1632
    ///
1635 1633
    /// \return The reached node \c v with <tt>nm[v]</tt> true or
1636 1634
    /// \c INVALID if no such node was found.
1637 1635
    ///
1638 1636
    /// \pre init() must be called and at least one root node should be
1639 1637
    /// added with addSource() before using this function.
1640 1638
    ///
1641 1639
    /// \note <tt>b.start(nm)</tt> is just a shortcut of the following code.
1642 1640
    /// \code
1643 1641
    ///   Node rnode = INVALID;
1644 1642
    ///   while ( !b.emptyQueue() && rnode == INVALID ) {
1645 1643
    ///     b.processNextNode(nm, rnode);
1646 1644
    ///   }
1647 1645
    ///   return rnode;
1648 1646
    /// \endcode
1649 1647
    template <typename NM>
1650 1648
    Node start(const NM &nm) {
1651 1649
      Node rnode = INVALID;
1652 1650
      while ( !emptyQueue() && rnode == INVALID ) {
1653 1651
        processNextNode(nm, rnode);
1654 1652
      }
1655 1653
      return rnode;
1656 1654
    }
1657 1655

	
1658 1656
    /// \brief Runs the algorithm from the given source node.
1659 1657
    ///
1660 1658
    /// This method runs the %BFS algorithm from node \c s
1661 1659
    /// in order to compute the shortest path to each node.
1662 1660
    ///
1663 1661
    /// The algorithm computes
1664 1662
    /// - the shortest path tree,
1665 1663
    /// - the distance of each node from the root.
1666 1664
    ///
1667 1665
    /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
1668 1666
    ///\code
1669 1667
    ///   b.init();
1670 1668
    ///   b.addSource(s);
1671 1669
    ///   b.start();
1672 1670
    ///\endcode
1673 1671
    void run(Node s) {
1674 1672
      init();
1675 1673
      addSource(s);
1676 1674
      start();
1677 1675
    }
1678 1676

	
1679 1677
    /// \brief Finds the shortest path between \c s and \c t.
1680 1678
    ///
1681 1679
    /// This method runs the %BFS algorithm from node \c s
1682 1680
    /// in order to compute the shortest path to node \c t
1683 1681
    /// (it stops searching when \c t is processed).
1684 1682
    ///
1685 1683
    /// \return \c true if \c t is reachable form \c s.
1686 1684
    ///
1687 1685
    /// \note Apart from the return value, <tt>b.run(s,t)</tt> is just a
1688 1686
    /// shortcut of the following code.
1689 1687
    ///\code
1690 1688
    ///   b.init();
1691 1689
    ///   b.addSource(s);
1692 1690
    ///   b.start(t);
1693 1691
    ///\endcode
1694 1692
    bool run(Node s,Node t) {
1695 1693
      init();
1696 1694
      addSource(s);
1697 1695
      start(t);
1698 1696
      return reached(t);
1699 1697
    }
1700 1698

	
1701 1699
    /// \brief Runs the algorithm to visit all nodes in the digraph.
1702 1700
    ///
1703 1701
    /// This method runs the %BFS algorithm in order to
1704 1702
    /// compute the shortest path to each node.
1705 1703
    ///
1706 1704
    /// The algorithm computes
1707 1705
    /// - the shortest path tree (forest),
1708 1706
    /// - the distance of each node from the root(s).
1709 1707
    ///
1710 1708
    /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
1711 1709
    ///\code
1712 1710
    ///  b.init();
1713 1711
    ///  for (NodeIt n(gr); n != INVALID; ++n) {
1714 1712
    ///    if (!b.reached(n)) {
1715 1713
    ///      b.addSource(n);
1716 1714
    ///      b.start();
1717 1715
    ///    }
1718 1716
    ///  }
1719 1717
    ///\endcode
1720 1718
    void run() {
1721 1719
      init();
1722 1720
      for (NodeIt it(*_digraph); it != INVALID; ++it) {
1723 1721
        if (!reached(it)) {
1724 1722
          addSource(it);
1725 1723
          start();
1726 1724
        }
1727 1725
      }
1728 1726
    }
1729 1727

	
1730 1728
    ///@}
1731 1729

	
1732 1730
    /// \name Query Functions
1733
    /// The result of the %BFS algorithm can be obtained using these
1731
    /// The results of the BFS algorithm can be obtained using these
1734 1732
    /// functions.\n
1735
    /// Either \ref lemon::BfsVisit::run() "run()" or
1736
    /// \ref lemon::BfsVisit::start() "start()" must be called before
1737
    /// using them.
1733
    /// Either \ref run(Node) "run()" or \ref start() should be called
1734
    /// before using them.
1735

	
1738 1736
    ///@{
1739 1737

	
1740
    /// \brief Checks if a node is reachable from the root(s).
1738
    /// \brief Checks if a node is reached from the root(s).
1741 1739
    ///
1742
    /// Returns \c true if \c v is reachable from the root(s).
1743
    /// \pre Either \ref run() or \ref start()
1740
    /// Returns \c true if \c v is reached from the root(s).
1741
    ///
1742
    /// \pre Either \ref run(Node) "run()" or \ref init()
1744 1743
    /// must be called before using this function.
1745
    bool reached(Node v) { return (*_reached)[v]; }
1744
    bool reached(Node v) const { return (*_reached)[v]; }
1746 1745

	
1747 1746
    ///@}
1748 1747

	
1749 1748
  };
1750 1749

	
1751 1750
} //END OF NAMESPACE LEMON
1752 1751

	
1753 1752
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_BIN_HEAP_H
20 20
#define LEMON_BIN_HEAP_H
21 21

	
22 22
///\ingroup auxdat
23 23
///\file
24 24
///\brief Binary Heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <utility>
28 28
#include <functional>
29 29

	
30 30
namespace lemon {
31 31

	
32 32
  ///\ingroup auxdat
33 33
  ///
34 34
  ///\brief A Binary Heap implementation.
35 35
  ///
36
  ///This class implements the \e binary \e heap data structure. A \e heap
37
  ///is a data structure for storing items with specified values called \e
38
  ///priorities in such a way that finding the item with minimum priority is
39
  ///efficient. \c Compare specifies the ordering of the priorities. In a heap
40
  ///one can change the priority of an item, add or erase an item, etc.
36
  ///This class implements the \e binary \e heap data structure.
41 37
  ///
42
  ///\tparam _Prio Type of the priority of the items.
43
  ///\tparam _ItemIntMap A read and writable Item int map, used internally
38
  ///A \e heap is a data structure for storing items with specified values
39
  ///called \e priorities in such a way that finding the item with minimum
40
  ///priority is efficient. \c CMP specifies the ordering of the priorities.
41
  ///In a heap one can change the priority of an item, add or erase an
42
  ///item, etc.
43
  ///
44
  ///\tparam PR Type of the priority of the items.
45
  ///\tparam IM A read and writable item map with int values, used internally
44 46
  ///to handle the cross references.
45
  ///\tparam _Compare A class for the ordering of the priorities. The
46
  ///default is \c std::less<_Prio>.
47
  ///\tparam CMP A functor class for the ordering of the priorities.
48
  ///The default is \c std::less<PR>.
47 49
  ///
48 50
  ///\sa FibHeap
49 51
  ///\sa Dijkstra
50
  template <typename _Prio, typename _ItemIntMap,
51
            typename _Compare = std::less<_Prio> >
52
  template <typename PR, typename IM, typename CMP = std::less<PR> >
52 53
  class BinHeap {
53 54

	
54 55
  public:
55 56
    ///\e
56
    typedef _ItemIntMap ItemIntMap;
57
    typedef IM ItemIntMap;
57 58
    ///\e
58
    typedef _Prio Prio;
59
    typedef PR Prio;
59 60
    ///\e
60 61
    typedef typename ItemIntMap::Key Item;
61 62
    ///\e
62 63
    typedef std::pair<Item,Prio> Pair;
63 64
    ///\e
64
    typedef _Compare Compare;
65
    typedef CMP Compare;
65 66

	
66 67
    /// \brief Type to represent the items states.
67 68
    ///
68 69
    /// Each Item element have a state associated to it. It may be "in heap",
69 70
    /// "pre heap" or "post heap". The latter two are indifferent from the
70 71
    /// heap's point of view, but may be useful to the user.
71 72
    ///
72
    /// The ItemIntMap \e should be initialized in such way that it maps
73
    /// PRE_HEAP (-1) to any element to be put in the heap...
73
    /// The item-int map must be initialized in such way that it assigns
74
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
74 75
    enum State {
75
      IN_HEAP = 0,
76
      PRE_HEAP = -1,
77
      POST_HEAP = -2
76
      IN_HEAP = 0,    ///< = 0.
77
      PRE_HEAP = -1,  ///< = -1.
78
      POST_HEAP = -2  ///< = -2.
78 79
    };
79 80

	
80 81
  private:
81
    std::vector<Pair> data;
82
    Compare comp;
83
    ItemIntMap &iim;
82
    std::vector<Pair> _data;
83
    Compare _comp;
84
    ItemIntMap &_iim;
84 85

	
85 86
  public:
86 87
    /// \brief The constructor.
87 88
    ///
88 89
    /// The constructor.
89
    /// \param _iim should be given to the constructor, since it is used
90
    /// \param map should be given to the constructor, since it is used
90 91
    /// internally to handle the cross references. The value of the map
91
    /// should be PRE_HEAP (-1) for each element.
92
    explicit BinHeap(ItemIntMap &_iim) : iim(_iim) {}
92
    /// must be \c PRE_HEAP (<tt>-1</tt>) for every item.
93
    explicit BinHeap(ItemIntMap &map) : _iim(map) {}
93 94

	
94 95
    /// \brief The constructor.
95 96
    ///
96 97
    /// The constructor.
97
    /// \param _iim should be given to the constructor, since it is used
98
    /// \param map should be given to the constructor, since it is used
98 99
    /// internally to handle the cross references. The value of the map
99 100
    /// should be PRE_HEAP (-1) for each element.
100 101
    ///
101
    /// \param _comp The comparator function object.
102
    BinHeap(ItemIntMap &_iim, const Compare &_comp)
103
      : iim(_iim), comp(_comp) {}
102
    /// \param comp The comparator function object.
103
    BinHeap(ItemIntMap &map, const Compare &comp)
104
      : _iim(map), _comp(comp) {}
104 105

	
105 106

	
106 107
    /// The number of items stored in the heap.
107 108
    ///
108 109
    /// \brief Returns the number of items stored in the heap.
109
    int size() const { return data.size(); }
110
    int size() const { return _data.size(); }
110 111

	
111 112
    /// \brief Checks if the heap stores no items.
112 113
    ///
113 114
    /// Returns \c true if and only if the heap stores no items.
114
    bool empty() const { return data.empty(); }
115
    bool empty() const { return _data.empty(); }
115 116

	
116 117
    /// \brief Make empty this heap.
117 118
    ///
118 119
    /// Make empty this heap. It does not change the cross reference map.
119 120
    /// If you want to reuse what is not surely empty you should first clear
120 121
    /// the heap and after that you should set the cross reference map for
121 122
    /// each item to \c PRE_HEAP.
122 123
    void clear() {
123
      data.clear();
124
      _data.clear();
124 125
    }
125 126

	
126 127
  private:
127 128
    static int parent(int i) { return (i-1)/2; }
128 129

	
129 130
    static int second_child(int i) { return 2*i+2; }
130 131
    bool less(const Pair &p1, const Pair &p2) const {
131
      return comp(p1.second, p2.second);
132
      return _comp(p1.second, p2.second);
132 133
    }
133 134

	
134 135
    int bubble_up(int hole, Pair p) {
135 136
      int par = parent(hole);
136
      while( hole>0 && less(p,data[par]) ) {
137
        move(data[par],hole);
137
      while( hole>0 && less(p,_data[par]) ) {
138
        move(_data[par],hole);
138 139
        hole = par;
139 140
        par = parent(hole);
140 141
      }
141 142
      move(p, hole);
142 143
      return hole;
143 144
    }
144 145

	
145 146
    int bubble_down(int hole, Pair p, int length) {
146 147
      int child = second_child(hole);
147 148
      while(child < length) {
148
        if( less(data[child-1], data[child]) ) {
149
        if( less(_data[child-1], _data[child]) ) {
149 150
          --child;
150 151
        }
151
        if( !less(data[child], p) )
152
        if( !less(_data[child], p) )
152 153
          goto ok;
153
        move(data[child], hole);
154
        move(_data[child], hole);
154 155
        hole = child;
155 156
        child = second_child(hole);
156 157
      }
157 158
      child--;
158
      if( child<length && less(data[child], p) ) {
159
        move(data[child], hole);
159
      if( child<length && less(_data[child], p) ) {
160
        move(_data[child], hole);
160 161
        hole=child;
161 162
      }
162 163
    ok:
163 164
      move(p, hole);
164 165
      return hole;
165 166
    }
166 167

	
167 168
    void move(const Pair &p, int i) {
168
      data[i] = p;
169
      iim.set(p.first, i);
169
      _data[i] = p;
170
      _iim.set(p.first, i);
170 171
    }
171 172

	
172 173
  public:
173 174
    /// \brief Insert a pair of item and priority into the heap.
174 175
    ///
175 176
    /// Adds \c p.first to the heap with priority \c p.second.
176 177
    /// \param p The pair to insert.
177 178
    void push(const Pair &p) {
178
      int n = data.size();
179
      data.resize(n+1);
179
      int n = _data.size();
180
      _data.resize(n+1);
180 181
      bubble_up(n, p);
181 182
    }
182 183

	
183 184
    /// \brief Insert an item into the heap with the given heap.
184 185
    ///
185 186
    /// Adds \c i to the heap with priority \c p.
186 187
    /// \param i The item to insert.
187 188
    /// \param p The priority of the item.
188 189
    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
189 190

	
190 191
    /// \brief Returns the item with minimum priority relative to \c Compare.
191 192
    ///
192 193
    /// This method returns the item with minimum priority relative to \c
193 194
    /// Compare.
194 195
    /// \pre The heap must be nonempty.
195 196
    Item top() const {
196
      return data[0].first;
197
      return _data[0].first;
197 198
    }
198 199

	
199 200
    /// \brief Returns the minimum priority relative to \c Compare.
200 201
    ///
201 202
    /// It returns the minimum priority relative to \c Compare.
202 203
    /// \pre The heap must be nonempty.
203 204
    Prio prio() const {
204
      return data[0].second;
205
      return _data[0].second;
205 206
    }
206 207

	
207 208
    /// \brief Deletes the item with minimum priority relative to \c Compare.
208 209
    ///
209 210
    /// This method deletes the item with minimum priority relative to \c
210 211
    /// Compare from the heap.
211 212
    /// \pre The heap must be non-empty.
212 213
    void pop() {
213
      int n = data.size()-1;
214
      iim.set(data[0].first, POST_HEAP);
214
      int n = _data.size()-1;
215
      _iim.set(_data[0].first, POST_HEAP);
215 216
      if (n > 0) {
216
        bubble_down(0, data[n], n);
217
        bubble_down(0, _data[n], n);
217 218
      }
218
      data.pop_back();
219
      _data.pop_back();
219 220
    }
220 221

	
221 222
    /// \brief Deletes \c i from the heap.
222 223
    ///
223 224
    /// This method deletes item \c i from the heap.
224 225
    /// \param i The item to erase.
225 226
    /// \pre The item should be in the heap.
226 227
    void erase(const Item &i) {
227
      int h = iim[i];
228
      int n = data.size()-1;
229
      iim.set(data[h].first, POST_HEAP);
228
      int h = _iim[i];
229
      int n = _data.size()-1;
230
      _iim.set(_data[h].first, POST_HEAP);
230 231
      if( h < n ) {
231
        if ( bubble_up(h, data[n]) == h) {
232
          bubble_down(h, data[n], n);
232
        if ( bubble_up(h, _data[n]) == h) {
233
          bubble_down(h, _data[n], n);
233 234
        }
234 235
      }
235
      data.pop_back();
236
      _data.pop_back();
236 237
    }
237 238

	
238 239

	
239 240
    /// \brief Returns the priority of \c i.
240 241
    ///
241 242
    /// This function returns the priority of item \c i.
243
    /// \param i The item.
242 244
    /// \pre \c i must be in the heap.
243
    /// \param i The item.
244 245
    Prio operator[](const Item &i) const {
245
      int idx = iim[i];
246
      return data[idx].second;
246
      int idx = _iim[i];
247
      return _data[idx].second;
247 248
    }
248 249

	
249 250
    /// \brief \c i gets to the heap with priority \c p independently
250 251
    /// if \c i was already there.
251 252
    ///
252 253
    /// This method calls \ref push(\c i, \c p) if \c i is not stored
253 254
    /// in the heap and sets the priority of \c i to \c p otherwise.
254 255
    /// \param i The item.
255 256
    /// \param p The priority.
256 257
    void set(const Item &i, const Prio &p) {
257
      int idx = iim[i];
258
      int idx = _iim[i];
258 259
      if( idx < 0 ) {
259 260
        push(i,p);
260 261
      }
261
      else if( comp(p, data[idx].second) ) {
262
      else if( _comp(p, _data[idx].second) ) {
262 263
        bubble_up(idx, Pair(i,p));
263 264
      }
264 265
      else {
265
        bubble_down(idx, Pair(i,p), data.size());
266
        bubble_down(idx, Pair(i,p), _data.size());
266 267
      }
267 268
    }
268 269

	
269 270
    /// \brief Decreases the priority of \c i to \c p.
270 271
    ///
271 272
    /// This method decreases the priority of item \c i to \c p.
273
    /// \param i The item.
274
    /// \param p The priority.
272 275
    /// \pre \c i must be stored in the heap with priority at least \c
273 276
    /// p relative to \c Compare.
274
    /// \param i The item.
275
    /// \param p The priority.
276 277
    void decrease(const Item &i, const Prio &p) {
277
      int idx = iim[i];
278
      int idx = _iim[i];
278 279
      bubble_up(idx, Pair(i,p));
279 280
    }
280 281

	
281 282
    /// \brief Increases the priority of \c i to \c p.
282 283
    ///
283 284
    /// This method sets the priority of item \c i to \c p.
285
    /// \param i The item.
286
    /// \param p The priority.
284 287
    /// \pre \c i must be stored in the heap with priority at most \c
285 288
    /// p relative to \c Compare.
286
    /// \param i The item.
287
    /// \param p The priority.
288 289
    void increase(const Item &i, const Prio &p) {
289
      int idx = iim[i];
290
      bubble_down(idx, Pair(i,p), data.size());
290
      int idx = _iim[i];
291
      bubble_down(idx, Pair(i,p), _data.size());
291 292
    }
292 293

	
293 294
    /// \brief Returns if \c item is in, has already been in, or has
294 295
    /// never been in the heap.
295 296
    ///
296 297
    /// This method returns PRE_HEAP if \c item has never been in the
297 298
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
298 299
    /// otherwise. In the latter case it is possible that \c item will
299 300
    /// get back to the heap again.
300 301
    /// \param i The item.
301 302
    State state(const Item &i) const {
302
      int s = iim[i];
303
      int s = _iim[i];
303 304
      if( s>=0 )
304 305
        s=0;
305 306
      return State(s);
306 307
    }
307 308

	
308 309
    /// \brief Sets the state of the \c item in the heap.
309 310
    ///
310 311
    /// Sets the state of the \c item in the heap. It can be used to
311 312
    /// manually clear the heap when it is important to achive the
312 313
    /// better time complexity.
313 314
    /// \param i The item.
314 315
    /// \param st The state. It should not be \c IN_HEAP.
315 316
    void state(const Item& i, State st) {
316 317
      switch (st) {
317 318
      case POST_HEAP:
318 319
      case PRE_HEAP:
319 320
        if (state(i) == IN_HEAP) {
320 321
          erase(i);
321 322
        }
322
        iim[i] = st;
323
        _iim[i] = st;
323 324
        break;
324 325
      case IN_HEAP:
325 326
        break;
326 327
      }
327 328
    }
328 329

	
329 330
    /// \brief Replaces an item in the heap.
330 331
    ///
331 332
    /// The \c i item is replaced with \c j item. The \c i item should
332 333
    /// be in the heap, while the \c j should be out of the heap. The
333 334
    /// \c i item will out of the heap and \c j will be in the heap
334 335
    /// with the same prioriority as prevoiusly the \c i item.
335 336
    void replace(const Item& i, const Item& j) {
336
      int idx = iim[i];
337
      iim.set(i, iim[j]);
338
      iim.set(j, idx);
339
      data[idx].first = j;
337
      int idx = _iim[i];
338
      _iim.set(i, _iim[j]);
339
      _iim.set(j, idx);
340
      _data[idx].first = j;
340 341
    }
341 342

	
342 343
  }; // class BinHeap
343 344

	
344 345
} // namespace lemon
345 346

	
346 347
#endif // LEMON_BIN_HEAP_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_BITS_ALTERATION_NOTIFIER_H
20 20
#define LEMON_BITS_ALTERATION_NOTIFIER_H
21 21

	
22 22
#include <vector>
23 23
#include <list>
24 24

	
25 25
#include <lemon/core.h>
26 26

	
27 27
//\ingroup graphbits
28 28
//\file
29 29
//\brief Observer notifier for graph alteration observers.
30 30

	
31 31
namespace lemon {
32 32

	
33 33
  // \ingroup graphbits
34 34
  //
35 35
  // \brief Notifier class to notify observes about alterations in
36 36
  // a container.
37 37
  //
38
  // The simple graph's can be refered as two containers, one node container
39
  // and one edge container. But they are not standard containers they
40
  // does not store values directly they are just key continars for more
41
  // value containers which are the node and edge maps.
38
  // The simple graphs can be refered as two containers: a node container
39
  // and an edge container. But they do not store values directly, they
40
  // are just key continars for more value containers, which are the
41
  // node and edge maps.
42 42
  //
43
  // The graph's node and edge sets can be changed as we add or erase
43
  // The node and edge sets of the graphs can be changed as we add or erase
44 44
  // nodes and edges in the graph. LEMON would like to handle easily
45 45
  // that the node and edge maps should contain values for all nodes or
46 46
  // edges. If we want to check on every indicing if the map contains
47 47
  // the current indicing key that cause a drawback in the performance
48
  // in the library. We use another solution we notify all maps about
48
  // in the library. We use another solution: we notify all maps about
49 49
  // an alteration in the graph, which cause only drawback on the
50 50
  // alteration of the graph.
51 51
  //
52
  // This class provides an interface to the container. The \e first() and \e
53
  // next() member functions make possible to iterate on the keys of the
54
  // container. The \e id() function returns an integer id for each key.
55
  // The \e maxId() function gives back an upper bound of the ids.
52
  // This class provides an interface to a node or edge container.
53
  // The first() and next() member functions make possible
54
  // to iterate on the keys of the container.
55
  // The id() function returns an integer id for each key.
56
  // The maxId() function gives back an upper bound of the ids.
56 57
  //
57 58
  // For the proper functonality of this class, we should notify it
58
  // about each alteration in the container. The alterations have four type
59
  // as \e add(), \e erase(), \e build() and \e clear(). The \e add() and
60
  // \e erase() signals that only one or few items added or erased to or
61
  // from the graph. If all items are erased from the graph or from an empty
62
  // graph a new graph is builded then it can be signaled with the
59
  // about each alteration in the container. The alterations have four type:
60
  // add(), erase(), build() and clear(). The add() and
61
  // erase() signal that only one or few items added or erased to or
62
  // from the graph. If all items are erased from the graph or if a new graph
63
  // is built from an empty graph, then it can be signaled with the
63 64
  // clear() and build() members. Important rule that if we erase items
64
  // from graph we should first signal the alteration and after that erase
65
  // from graphs we should first signal the alteration and after that erase
65 66
  // them from the container, on the other way on item addition we should
66 67
  // first extend the container and just after that signal the alteration.
67 68
  //
68 69
  // The alteration can be observed with a class inherited from the
69
  // \e ObserverBase nested class. The signals can be handled with
70
  // ObserverBase nested class. The signals can be handled with
70 71
  // overriding the virtual functions defined in the base class.  The
71 72
  // observer base can be attached to the notifier with the
72
  // \e attach() member and can be detached with detach() function. The
73
  // attach() member and can be detached with detach() function. The
73 74
  // alteration handlers should not call any function which signals
74 75
  // an other alteration in the same notifier and should not
75 76
  // detach any observer from the notifier.
76 77
  //
77
  // Alteration observers try to be exception safe. If an \e add() or
78
  // a \e clear() function throws an exception then the remaining
78
  // Alteration observers try to be exception safe. If an add() or
79
  // a clear() function throws an exception then the remaining
79 80
  // observeres will not be notified and the fulfilled additions will
80
  // be rolled back by calling the \e erase() or \e clear()
81
  // functions. Thence the \e erase() and \e clear() should not throw
82
  // exception. Actullay, it can be throw only \ref ImmediateDetach
83
  // exception which detach the observer from the notifier.
81
  // be rolled back by calling the erase() or clear() functions.
82
  // Hence erase() and clear() should not throw exception.
83
  // Actullay, they can throw only \ref ImmediateDetach exception,
84
  // which detach the observer from the notifier.
84 85
  //
85
  // There are some place when the alteration observing is not completly
86
  // There are some cases, when the alteration observing is not completly
86 87
  // reliable. If we want to carry out the node degree in the graph
87
  // as in the \ref InDegMap and we use the reverseEdge that cause
88
  // as in the \ref InDegMap and we use the reverseArc(), then it cause
88 89
  // unreliable functionality. Because the alteration observing signals
89
  // only erasing and adding but not the reversing it will stores bad
90
  // degrees. The sub graph adaptors cannot signal the alterations because
91
  // just a setting in the filter map can modify the graph and this cannot
92
  // be watched in any way.
90
  // only erasing and adding but not the reversing, it will stores bad
91
  // degrees. Apart form that the subgraph adaptors cannot even signal
92
  // the alterations because just a setting in the filter map can modify
93
  // the graph and this cannot be watched in any way.
93 94
  //
94 95
  // \param _Container The container which is observed.
95 96
  // \param _Item The item type which is obserbved.
96 97

	
97 98
  template <typename _Container, typename _Item>
98 99
  class AlterationNotifier {
99 100
  public:
100 101

	
101 102
    typedef True Notifier;
102 103

	
103 104
    typedef _Container Container;
104 105
    typedef _Item Item;
105 106

	
106
    // \brief Exception which can be called from \e clear() and
107
    // \e erase().
107
    // \brief Exception which can be called from clear() and
108
    // erase().
108 109
    //
109
    // From the \e clear() and \e erase() function only this
110
    // From the clear() and erase() function only this
110 111
    // exception is allowed to throw. The exception immediatly
111 112
    // detaches the current observer from the notifier. Because the
112
    // \e clear() and \e erase() should not throw other exceptions
113
    // clear() and erase() should not throw other exceptions
113 114
    // it can be used to invalidate the observer.
114 115
    struct ImmediateDetach {};
115 116

	
116 117
    // \brief ObserverBase is the base class for the observers.
117 118
    //
118 119
    // ObserverBase is the abstract base class for the observers.
119 120
    // It will be notified about an item was inserted into or
120 121
    // erased from the graph.
121 122
    //
122 123
    // The observer interface contains some pure virtual functions
123 124
    // to override. The add() and erase() functions are
124
    // to notify the oberver when one item is added or
125
    // erased.
125
    // to notify the oberver when one item is added or erased.
126 126
    //
127 127
    // The build() and clear() members are to notify the observer
128 128
    // about the container is built from an empty container or
129 129
    // is cleared to an empty container.
130 130
    class ObserverBase {
131 131
    protected:
132 132
      typedef AlterationNotifier Notifier;
133 133

	
134 134
      friend class AlterationNotifier;
135 135

	
136 136
      // \brief Default constructor.
137 137
      //
138 138
      // Default constructor for ObserverBase.
139 139
      ObserverBase() : _notifier(0) {}
140 140

	
141 141
      // \brief Constructor which attach the observer into notifier.
142 142
      //
143 143
      // Constructor which attach the observer into notifier.
144 144
      ObserverBase(AlterationNotifier& nf) {
145 145
        attach(nf);
146 146
      }
147 147

	
148 148
      // \brief Constructor which attach the obserever to the same notifier.
149 149
      //
150 150
      // Constructor which attach the obserever to the same notifier as
151 151
      // the other observer is attached to.
152 152
      ObserverBase(const ObserverBase& copy) {
153 153
        if (copy.attached()) {
154 154
          attach(*copy.notifier());
155 155
        }
156 156
      }
157 157

	
158 158
      // \brief Destructor
159 159
      virtual ~ObserverBase() {
160 160
        if (attached()) {
161 161
          detach();
162 162
        }
163 163
      }
164 164

	
165 165
      // \brief Attaches the observer into an AlterationNotifier.
166 166
      //
167 167
      // This member attaches the observer into an AlterationNotifier.
168 168
      void attach(AlterationNotifier& nf) {
169 169
        nf.attach(*this);
170 170
      }
171 171

	
172 172
      // \brief Detaches the observer into an AlterationNotifier.
173 173
      //
174 174
      // This member detaches the observer from an AlterationNotifier.
175 175
      void detach() {
176 176
        _notifier->detach(*this);
177 177
      }
178 178

	
179 179
      // \brief Gives back a pointer to the notifier which the map
180 180
      // attached into.
181 181
      //
182 182
      // This function gives back a pointer to the notifier which the map
183 183
      // attached into.
184 184
      Notifier* notifier() const { return const_cast<Notifier*>(_notifier); }
185 185

	
186 186
      // Gives back true when the observer is attached into a notifier.
187 187
      bool attached() const { return _notifier != 0; }
188 188

	
189 189
    private:
190 190

	
191 191
      ObserverBase& operator=(const ObserverBase& copy);
192 192

	
193 193
    protected:
194 194

	
195 195
      Notifier* _notifier;
196 196
      typename std::list<ObserverBase*>::iterator _index;
197 197

	
198 198
      // \brief The member function to notificate the observer about an
199 199
      // item is added to the container.
200 200
      //
201 201
      // The add() member function notificates the observer about an item
202 202
      // is added to the container. It have to be overrided in the
203 203
      // subclasses.
204 204
      virtual void add(const Item&) = 0;
205 205

	
206 206
      // \brief The member function to notificate the observer about
207 207
      // more item is added to the container.
208 208
      //
209 209
      // The add() member function notificates the observer about more item
210 210
      // is added to the container. It have to be overrided in the
211 211
      // subclasses.
212 212
      virtual void add(const std::vector<Item>& items) = 0;
213 213

	
214 214
      // \brief The member function to notificate the observer about an
215 215
      // item is erased from the container.
216 216
      //
217 217
      // The erase() member function notificates the observer about an
218 218
      // item is erased from the container. It have to be overrided in
219 219
      // the subclasses.
220 220
      virtual void erase(const Item&) = 0;
221 221

	
222 222
      // \brief The member function to notificate the observer about
223 223
      // more item is erased from the container.
224 224
      //
225 225
      // The erase() member function notificates the observer about more item
226 226
      // is erased from the container. It have to be overrided in the
227 227
      // subclasses.
228 228
      virtual void erase(const std::vector<Item>& items) = 0;
229 229

	
230 230
      // \brief The member function to notificate the observer about the
231 231
      // container is built.
232 232
      //
233 233
      // The build() member function notificates the observer about the
234 234
      // container is built from an empty container. It have to be
235 235
      // overrided in the subclasses.
236 236
      virtual void build() = 0;
237 237

	
238 238
      // \brief The member function to notificate the observer about all
239 239
      // items are erased from the container.
240 240
      //
241 241
      // The clear() member function notificates the observer about all
242 242
      // items are erased from the container. It have to be overrided in
243 243
      // the subclasses.
244 244
      virtual void clear() = 0;
245 245

	
246 246
    };
247 247

	
248 248
  protected:
249 249

	
250 250
    const Container* container;
251 251

	
252 252
    typedef std::list<ObserverBase*> Observers;
253 253
    Observers _observers;
254 254

	
255 255

	
256 256
  public:
257 257

	
258 258
    // \brief Default constructor.
259 259
    //
260 260
    // The default constructor of the AlterationNotifier.
261 261
    // It creates an empty notifier.
262 262
    AlterationNotifier()
263 263
      : container(0) {}
264 264

	
265 265
    // \brief Constructor.
266 266
    //
267 267
    // Constructor with the observed container parameter.
268 268
    AlterationNotifier(const Container& _container)
269 269
      : container(&_container) {}
270 270

	
271 271
    // \brief Copy Constructor of the AlterationNotifier.
272 272
    //
273 273
    // Copy constructor of the AlterationNotifier.
274 274
    // It creates only an empty notifier because the copiable
275 275
    // notifier's observers have to be registered still into that notifier.
276 276
    AlterationNotifier(const AlterationNotifier& _notifier)
277 277
      : container(_notifier.container) {}
278 278

	
279 279
    // \brief Destructor.
280 280
    //
281 281
    // Destructor of the AlterationNotifier.
282 282
    ~AlterationNotifier() {
283 283
      typename Observers::iterator it;
284 284
      for (it = _observers.begin(); it != _observers.end(); ++it) {
285 285
        (*it)->_notifier = 0;
286 286
      }
287 287
    }
288 288

	
289 289
    // \brief Sets the container.
290 290
    //
291 291
    // Sets the container.
292 292
    void setContainer(const Container& _container) {
293 293
      container = &_container;
294 294
    }
295 295

	
296 296
  protected:
297 297

	
298 298
    AlterationNotifier& operator=(const AlterationNotifier&);
299 299

	
300 300
  public:
301 301

	
302 302
    // \brief First item in the container.
303 303
    //
304 304
    // Returns the first item in the container. It is
305 305
    // for start the iteration on the container.
306 306
    void first(Item& item) const {
307 307
      container->first(item);
308 308
    }
309 309

	
310 310
    // \brief Next item in the container.
311 311
    //
312 312
    // Returns the next item in the container. It is
313 313
    // for iterate on the container.
314 314
    void next(Item& item) const {
315 315
      container->next(item);
316 316
    }
317 317

	
318 318
    // \brief Returns the id of the item.
319 319
    //
320 320
    // Returns the id of the item provided by the container.
321 321
    int id(const Item& item) const {
322 322
      return container->id(item);
323 323
    }
324 324

	
325 325
    // \brief Returns the maximum id of the container.
326 326
    //
327 327
    // Returns the maximum id of the container.
328 328
    int maxId() const {
329 329
      return container->maxId(Item());
330 330
    }
331 331

	
332 332
  protected:
333 333

	
334 334
    void attach(ObserverBase& observer) {
335 335
      observer._index = _observers.insert(_observers.begin(), &observer);
336 336
      observer._notifier = this;
337 337
    }
338 338

	
339 339
    void detach(ObserverBase& observer) {
340 340
      _observers.erase(observer._index);
341 341
      observer._index = _observers.end();
342 342
      observer._notifier = 0;
343 343
    }
344 344

	
345 345
  public:
346 346

	
347 347
    // \brief Notifies all the registed observers about an item added to
348 348
    // the container.
349 349
    //
350 350
    // It notifies all the registed observers about an item added to
351 351
    // the container.
352 352
    void add(const Item& item) {
353 353
      typename Observers::reverse_iterator it;
354 354
      try {
355 355
        for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
356 356
          (*it)->add(item);
357 357
        }
358 358
      } catch (...) {
359 359
        typename Observers::iterator jt;
360 360
        for (jt = it.base(); jt != _observers.end(); ++jt) {
361 361
          (*jt)->erase(item);
362 362
        }
363 363
        throw;
364 364
      }
365 365
    }
366 366

	
367 367
    // \brief Notifies all the registed observers about more item added to
368 368
    // the container.
369 369
    //
370 370
    // It notifies all the registed observers about more item added to
371 371
    // the container.
372 372
    void add(const std::vector<Item>& items) {
373 373
      typename Observers::reverse_iterator it;
374 374
      try {
375 375
        for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
376 376
          (*it)->add(items);
377 377
        }
378 378
      } catch (...) {
379 379
        typename Observers::iterator jt;
380 380
        for (jt = it.base(); jt != _observers.end(); ++jt) {
381 381
          (*jt)->erase(items);
382 382
        }
383 383
        throw;
384 384
      }
385 385
    }
386 386

	
387 387
    // \brief Notifies all the registed observers about an item erased from
388 388
    // the container.
389 389
    //
390 390
    // It notifies all the registed observers about an item erased from
391 391
    // the container.
392 392
    void erase(const Item& item) throw() {
393 393
      typename Observers::iterator it = _observers.begin();
394 394
      while (it != _observers.end()) {
395 395
        try {
396 396
          (*it)->erase(item);
397 397
          ++it;
398 398
        } catch (const ImmediateDetach&) {
399 399
          (*it)->_index = _observers.end();
400 400
          (*it)->_notifier = 0;
401 401
          it = _observers.erase(it);
402 402
        }
403 403
      }
404 404
    }
405 405

	
406 406
    // \brief Notifies all the registed observers about more item erased
407 407
    // from the container.
408 408
    //
409 409
    // It notifies all the registed observers about more item erased from
410 410
    // the container.
411 411
    void erase(const std::vector<Item>& items) {
412 412
      typename Observers::iterator it = _observers.begin();
413 413
      while (it != _observers.end()) {
414 414
        try {
415 415
          (*it)->erase(items);
416 416
          ++it;
417 417
        } catch (const ImmediateDetach&) {
418 418
          (*it)->_index = _observers.end();
419 419
          (*it)->_notifier = 0;
420 420
          it = _observers.erase(it);
421 421
        }
422 422
      }
423 423
    }
424 424

	
425 425
    // \brief Notifies all the registed observers about the container is
426 426
    // built.
427 427
    //
428 428
    // Notifies all the registed observers about the container is built
429 429
    // from an empty container.
430 430
    void build() {
431 431
      typename Observers::reverse_iterator it;
432 432
      try {
433 433
        for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
434 434
          (*it)->build();
435 435
        }
436 436
      } catch (...) {
437 437
        typename Observers::iterator jt;
438 438
        for (jt = it.base(); jt != _observers.end(); ++jt) {
439 439
          (*jt)->clear();
440 440
        }
441 441
        throw;
442 442
      }
443 443
    }
444 444

	
445 445
    // \brief Notifies all the registed observers about all items are
446 446
    // erased.
447 447
    //
448 448
    // Notifies all the registed observers about all items are erased
449 449
    // from the container.
450 450
    void clear() {
451 451
      typename Observers::iterator it = _observers.begin();
452 452
      while (it != _observers.end()) {
453 453
        try {
454 454
          (*it)->clear();
455 455
          ++it;
456 456
        } catch (const ImmediateDetach&) {
457 457
          (*it)->_index = _observers.end();
458 458
          (*it)->_notifier = 0;
459 459
          it = _observers.erase(it);
460 460
        }
461 461
      }
462 462
    }
463 463
  };
464 464

	
465 465
}
466 466

	
467 467
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_BITS_ARRAY_MAP_H
20 20
#define LEMON_BITS_ARRAY_MAP_H
21 21

	
22 22
#include <memory>
23 23

	
24 24
#include <lemon/bits/traits.h>
25 25
#include <lemon/bits/alteration_notifier.h>
26 26
#include <lemon/concept_check.h>
27 27
#include <lemon/concepts/maps.h>
28 28

	
29 29
// \ingroup graphbits
30 30
// \file
31 31
// \brief Graph map based on the array storage.
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  // \ingroup graphbits
36 36
  //
37 37
  // \brief Graph map based on the array storage.
38 38
  //
39
  // The ArrayMap template class is graph map structure what
40
  // automatically updates the map when a key is added to or erased from
41
  // the map. This map uses the allocators to implement
42
  // the container functionality.
39
  // The ArrayMap template class is graph map structure that automatically
40
  // updates the map when a key is added to or erased from the graph.
41
  // This map uses the allocators to implement the container functionality.
43 42
  //
44
  // The template parameters are the Graph the current Item type and
43
  // The template parameters are the Graph, the current Item type and
45 44
  // the Value type of the map.
46 45
  template <typename _Graph, typename _Item, typename _Value>
47 46
  class ArrayMap
48 47
    : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
49 48
  public:
50
    // The graph type of the maps.
51
    typedef _Graph Graph;
52
    // The item type of the map.
49
    // The graph type.
50
    typedef _Graph GraphType;
51
    // The item type.
53 52
    typedef _Item Item;
54 53
    // The reference map tag.
55 54
    typedef True ReferenceMapTag;
56 55

	
57
    // The key type of the maps.
56
    // The key type of the map.
58 57
    typedef _Item Key;
59 58
    // The value type of the map.
60 59
    typedef _Value Value;
61 60

	
62 61
    // The const reference type of the map.
63 62
    typedef const _Value& ConstReference;
64 63
    // The reference type of the map.
65 64
    typedef _Value& Reference;
66 65

	
66
    // The map type.
67
    typedef ArrayMap Map;
68

	
67 69
    // The notifier type.
68 70
    typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
69 71

	
72
  private:
73
  
70 74
    // The MapBase of the Map which imlements the core regisitry function.
71 75
    typedef typename Notifier::ObserverBase Parent;
72 76

	
73
  private:
74 77
    typedef std::allocator<Value> Allocator;
75 78

	
76 79
  public:
77 80

	
78 81
    // \brief Graph initialized map constructor.
79 82
    //
80 83
    // Graph initialized map constructor.
81
    explicit ArrayMap(const Graph& graph) {
84
    explicit ArrayMap(const GraphType& graph) {
82 85
      Parent::attach(graph.notifier(Item()));
83 86
      allocate_memory();
84 87
      Notifier* nf = Parent::notifier();
85 88
      Item it;
86 89
      for (nf->first(it); it != INVALID; nf->next(it)) {
87 90
        int id = nf->id(it);;
88 91
        allocator.construct(&(values[id]), Value());
89 92
      }
90 93
    }
91 94

	
92 95
    // \brief Constructor to use default value to initialize the map.
93 96
    //
94 97
    // It constructs a map and initialize all of the the map.
95
    ArrayMap(const Graph& graph, const Value& value) {
98
    ArrayMap(const GraphType& graph, const Value& value) {
96 99
      Parent::attach(graph.notifier(Item()));
97 100
      allocate_memory();
98 101
      Notifier* nf = Parent::notifier();
99 102
      Item it;
100 103
      for (nf->first(it); it != INVALID; nf->next(it)) {
101 104
        int id = nf->id(it);;
102 105
        allocator.construct(&(values[id]), value);
103 106
      }
104 107
    }
105 108

	
106 109
  private:
107 110
    // \brief Constructor to copy a map of the same map type.
108 111
    //
109 112
    // Constructor to copy a map of the same map type.
110 113
    ArrayMap(const ArrayMap& copy) : Parent() {
111 114
      if (copy.attached()) {
112 115
        attach(*copy.notifier());
113 116
      }
114 117
      capacity = copy.capacity;
115 118
      if (capacity == 0) return;
116 119
      values = allocator.allocate(capacity);
117 120
      Notifier* nf = Parent::notifier();
118 121
      Item it;
119 122
      for (nf->first(it); it != INVALID; nf->next(it)) {
120 123
        int id = nf->id(it);;
121 124
        allocator.construct(&(values[id]), copy.values[id]);
122 125
      }
123 126
    }
124 127

	
125 128
    // \brief Assign operator.
126 129
    //
127 130
    // This operator assigns for each item in the map the
128 131
    // value mapped to the same item in the copied map.
129 132
    // The parameter map should be indiced with the same
130 133
    // itemset because this assign operator does not change
131 134
    // the container of the map.
132 135
    ArrayMap& operator=(const ArrayMap& cmap) {
133 136
      return operator=<ArrayMap>(cmap);
134 137
    }
135 138

	
136 139

	
137 140
    // \brief Template assign operator.
138 141
    //
139
    // The given parameter should be conform to the ReadMap
142
    // The given parameter should conform to the ReadMap
140 143
    // concecpt and could be indiced by the current item set of
141 144
    // the NodeMap. In this case the value for each item
142 145
    // is assigned by the value of the given ReadMap.
143 146
    template <typename CMap>
144 147
    ArrayMap& operator=(const CMap& cmap) {
145 148
      checkConcept<concepts::ReadMap<Key, _Value>, CMap>();
146 149
      const typename Parent::Notifier* nf = Parent::notifier();
147 150
      Item it;
148 151
      for (nf->first(it); it != INVALID; nf->next(it)) {
149 152
        set(it, cmap[it]);
150 153
      }
151 154
      return *this;
152 155
    }
153 156

	
154 157
  public:
155 158
    // \brief The destructor of the map.
156 159
    //
157 160
    // The destructor of the map.
158 161
    virtual ~ArrayMap() {
159 162
      if (attached()) {
160 163
        clear();
161 164
        detach();
162 165
      }
163 166
    }
164 167

	
165 168
  protected:
166 169

	
167 170
    using Parent::attach;
168 171
    using Parent::detach;
169 172
    using Parent::attached;
170 173

	
171 174
  public:
172 175

	
173 176
    // \brief The subscript operator.
174 177
    //
175 178
    // The subscript operator. The map can be subscripted by the
176 179
    // actual keys of the graph.
177 180
    Value& operator[](const Key& key) {
178 181
      int id = Parent::notifier()->id(key);
179 182
      return values[id];
180 183
    }
181 184

	
182 185
    // \brief The const subscript operator.
183 186
    //
184 187
    // The const subscript operator. The map can be subscripted by the
185 188
    // actual keys of the graph.
186 189
    const Value& operator[](const Key& key) const {
187 190
      int id = Parent::notifier()->id(key);
188 191
      return values[id];
189 192
    }
190 193

	
191 194
    // \brief Setter function of the map.
192 195
    //
193 196
    // Setter function of the map. Equivalent with map[key] = val.
194 197
    // This is a compatibility feature with the not dereferable maps.
195 198
    void set(const Key& key, const Value& val) {
196 199
      (*this)[key] = val;
197 200
    }
198 201

	
199 202
  protected:
200 203

	
201 204
    // \brief Adds a new key to the map.
202 205
    //
203
    // It adds a new key to the map. It called by the observer notifier
206
    // It adds a new key to the map. It is called by the observer notifier
204 207
    // and it overrides the add() member function of the observer base.
205 208
    virtual void add(const Key& key) {
206 209
      Notifier* nf = Parent::notifier();
207 210
      int id = nf->id(key);
208 211
      if (id >= capacity) {
209 212
        int new_capacity = (capacity == 0 ? 1 : capacity);
210 213
        while (new_capacity <= id) {
211 214
          new_capacity <<= 1;
212 215
        }
213 216
        Value* new_values = allocator.allocate(new_capacity);
214 217
        Item it;
215 218
        for (nf->first(it); it != INVALID; nf->next(it)) {
216 219
          int jd = nf->id(it);;
217 220
          if (id != jd) {
218 221
            allocator.construct(&(new_values[jd]), values[jd]);
219 222
            allocator.destroy(&(values[jd]));
220 223
          }
221 224
        }
222 225
        if (capacity != 0) allocator.deallocate(values, capacity);
223 226
        values = new_values;
224 227
        capacity = new_capacity;
225 228
      }
226 229
      allocator.construct(&(values[id]), Value());
227 230
    }
228 231

	
229 232
    // \brief Adds more new keys to the map.
230 233
    //
231
    // It adds more new keys to the map. It called by the observer notifier
234
    // It adds more new keys to the map. It is called by the observer notifier
232 235
    // and it overrides the add() member function of the observer base.
233 236
    virtual void add(const std::vector<Key>& keys) {
234 237
      Notifier* nf = Parent::notifier();
235 238
      int max_id = -1;
236 239
      for (int i = 0; i < int(keys.size()); ++i) {
237 240
        int id = nf->id(keys[i]);
238 241
        if (id > max_id) {
239 242
          max_id = id;
240 243
        }
241 244
      }
242 245
      if (max_id >= capacity) {
243 246
        int new_capacity = (capacity == 0 ? 1 : capacity);
244 247
        while (new_capacity <= max_id) {
245 248
          new_capacity <<= 1;
246 249
        }
247 250
        Value* new_values = allocator.allocate(new_capacity);
248 251
        Item it;
249 252
        for (nf->first(it); it != INVALID; nf->next(it)) {
250 253
          int id = nf->id(it);
251 254
          bool found = false;
252 255
          for (int i = 0; i < int(keys.size()); ++i) {
253 256
            int jd = nf->id(keys[i]);
254 257
            if (id == jd) {
255 258
              found = true;
256 259
              break;
257 260
            }
258 261
          }
259 262
          if (found) continue;
260 263
          allocator.construct(&(new_values[id]), values[id]);
261 264
          allocator.destroy(&(values[id]));
262 265
        }
263 266
        if (capacity != 0) allocator.deallocate(values, capacity);
264 267
        values = new_values;
265 268
        capacity = new_capacity;
266 269
      }
267 270
      for (int i = 0; i < int(keys.size()); ++i) {
268 271
        int id = nf->id(keys[i]);
269 272
        allocator.construct(&(values[id]), Value());
270 273
      }
271 274
    }
272 275

	
273 276
    // \brief Erase a key from the map.
274 277
    //
275
    // Erase a key from the map. It called by the observer notifier
278
    // Erase a key from the map. It is called by the observer notifier
276 279
    // and it overrides the erase() member function of the observer base.
277 280
    virtual void erase(const Key& key) {
278 281
      int id = Parent::notifier()->id(key);
279 282
      allocator.destroy(&(values[id]));
280 283
    }
281 284

	
282 285
    // \brief Erase more keys from the map.
283 286
    //
284
    // Erase more keys from the map. It called by the observer notifier
287
    // Erase more keys from the map. It is called by the observer notifier
285 288
    // and it overrides the erase() member function of the observer base.
286 289
    virtual void erase(const std::vector<Key>& keys) {
287 290
      for (int i = 0; i < int(keys.size()); ++i) {
288 291
        int id = Parent::notifier()->id(keys[i]);
289 292
        allocator.destroy(&(values[id]));
290 293
      }
291 294
    }
292 295

	
293
    // \brief Buildes the map.
296
    // \brief Builds the map.
294 297
    //
295
    // It buildes the map. It called by the observer notifier
298
    // It builds the map. It is called by the observer notifier
296 299
    // and it overrides the build() member function of the observer base.
297 300
    virtual void build() {
298 301
      Notifier* nf = Parent::notifier();
299 302
      allocate_memory();
300 303
      Item it;
301 304
      for (nf->first(it); it != INVALID; nf->next(it)) {
302 305
        int id = nf->id(it);;
303 306
        allocator.construct(&(values[id]), Value());
304 307
      }
305 308
    }
306 309

	
307 310
    // \brief Clear the map.
308 311
    //
309
    // It erase all items from the map. It called by the observer notifier
312
    // It erase all items from the map. It is called by the observer notifier
310 313
    // and it overrides the clear() member function of the observer base.
311 314
    virtual void clear() {
312 315
      Notifier* nf = Parent::notifier();
313 316
      if (capacity != 0) {
314 317
        Item it;
315 318
        for (nf->first(it); it != INVALID; nf->next(it)) {
316 319
          int id = nf->id(it);
317 320
          allocator.destroy(&(values[id]));
318 321
        }
319 322
        allocator.deallocate(values, capacity);
320 323
        capacity = 0;
321 324
      }
322 325
    }
323 326

	
324 327
  private:
325 328

	
326 329
    void allocate_memory() {
327 330
      int max_id = Parent::notifier()->maxId();
328 331
      if (max_id == -1) {
329 332
        capacity = 0;
330 333
        values = 0;
331 334
        return;
332 335
      }
333 336
      capacity = 1;
334 337
      while (capacity <= max_id) {
335 338
        capacity <<= 1;
336 339
      }
337 340
      values = allocator.allocate(capacity);
338 341
    }
339 342

	
340 343
    int capacity;
341 344
    Value* values;
342 345
    Allocator allocator;
343 346

	
344 347
  };
345 348

	
346 349
}
347 350

	
348 351
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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 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
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_BITS_DEFAULT_MAP_H
20 20
#define LEMON_BITS_DEFAULT_MAP_H
21 21

	
22 22
#include <lemon/config.h>
23 23
#include <lemon/bits/array_map.h>
24 24
#include <lemon/bits/vector_map.h>
25 25
//#include <lemon/bits/debug_map.h>
26 26

	
27 27
//\ingroup graphbits
28 28
//\file
29 29
//\brief Graph maps that construct and destruct their elements dynamically.
30 30

	
31 31
namespace lemon {
32 32

	
33 33

	
34 34
  //#ifndef LEMON_USE_DEBUG_MAP
35 35

	
36 36
  template <typename _Graph, typename _Item, typename _Value>
37 37
  struct DefaultMapSelector {
38 38
    typedef ArrayMap<_Graph, _Item, _Value> Map;
39 39
  };
40 40

	
41 41
  // bool
42 42
  template <typename _Graph, typename _Item>
43 43
  struct DefaultMapSelector<_Graph, _Item, bool> {
44 44
    typedef VectorMap<_Graph, _Item, bool> Map;
45 45
  };
46 46

	
47 47
  // char
48 48
  template <typename _Graph, typename _Item>
49 49
  struct DefaultMapSelector<_Graph, _Item, char> {
50 50
    typedef VectorMap<_Graph, _Item, char> Map;
51 51
  };
52 52

	
53 53
  template <typename _Graph, typename _Item>
54 54
  struct DefaultMapSelector<_Graph, _Item, signed char> {
55 55
    typedef VectorMap<_Graph, _Item, signed char> Map;
56 56
  };
57 57

	
58 58
  template <typename _Graph, typename _Item>
59 59
  struct DefaultMapSelector<_Graph, _Item, unsigned char> {
60 60
    typedef VectorMap<_Graph, _Item, unsigned char> Map;
61 61
  };
62 62

	
63 63

	
64 64
  // int
65 65
  template <typename _Graph, typename _Item>
66 66
  struct DefaultMapSelector<_Graph, _Item, signed int> {
67 67
    typedef VectorMap<_Graph, _Item, signed int> Map;
68 68
  };
69 69

	
70 70
  template <typename _Graph, typename _Item>
71 71
  struct DefaultMapSelector<_Graph, _Item, unsigned int> {
72 72
    typedef VectorMap<_Graph, _Item, unsigned int> Map;
73 73
  };
74 74

	
75 75

	
76 76
  // short
77 77
  template <typename _Graph, typename _Item>
78 78
  struct DefaultMapSelector<_Graph, _Item, signed short> {
79 79
    typedef VectorMap<_Graph, _Item, signed short> Map;
80 80
  };
81 81

	
82 82
  template <typename _Graph, typename _Item>
83 83
  struct DefaultMapSelector<_Graph, _Item, unsigned short> {
84 84
    typedef VectorMap<_Graph, _Item, unsigned short> Map;
85 85
  };
86 86

	
87 87

	
88 88
  // long
89 89
  template <typename _Graph, typename _Item>
90 90
  struct DefaultMapSelector<_Graph, _Item, signed long> {
91 91
    typedef VectorMap<_Graph, _Item, signed long> Map;
92 92
  };
93 93

	
94 94
  template <typename _Graph, typename _Item>
95 95
  struct DefaultMapSelector<_Graph, _Item, unsigned long> {
96 96
    typedef VectorMap<_Graph, _Item, unsigned long> Map;
97 97
  };
98 98

	
99 99

	
100 100
#if defined LEMON_HAVE_LONG_LONG
101 101

	
102 102
  // long long
103 103
  template <typename _Graph, typename _Item>
104 104
  struct DefaultMapSelector<_Graph, _Item, signed long long> {
105 105
    typedef VectorMap<_Graph, _Item, signed long long> Map;
106 106
  };
107 107

	
108 108
  template <typename _Graph, typename _Item>
109 109
  struct DefaultMapSelector<_Graph, _Item, unsigned long long> {
110 110
    typedef VectorMap<_Graph, _Item, unsigned long long> Map;
111 111
  };
112 112

	
113 113
#endif
114 114

	
115 115

	
116 116
  // float
117 117
  template <typename _Graph, typename _Item>
118 118
  struct DefaultMapSelector<_Graph, _Item, float> {
119 119
    typedef VectorMap<_Graph, _Item, float> Map;
120 120
  };
121 121

	
122 122

	
123 123
  // double
124 124
  template <typename _Graph, typename _Item>
125 125
  struct DefaultMapSelector<_Graph, _Item, double> {
126 126
    typedef VectorMap<_Graph, _Item,  double> Map;
127 127
  };
128 128

	
129 129

	
130 130
  // long double
131 131
  template <typename _Graph, typename _Item>
132 132
  struct DefaultMapSelector<_Graph, _Item, long double> {
133 133
    typedef VectorMap<_Graph, _Item, long double> Map;
134 134
  };
135 135

	
136 136

	
137 137
  // pointer
138 138
  template <typename _Graph, typename _Item, typename _Ptr>
139 139
  struct DefaultMapSelector<_Graph, _Item, _Ptr*> {
140 140
    typedef VectorMap<_Graph, _Item, _Ptr*> Map;
141 141
  };
142 142

	
143 143
// #else
144 144

	
145 145
//   template <typename _Graph, typename _Item, typename _Value>
146 146
//   struct DefaultMapSelector {
147 147
//     typedef DebugMap<_Graph, _Item, _Value> Map;
148 148
//   };
149 149

	
150 150
// #endif
151 151

	
152 152
  // DefaultMap class
153 153
  template <typename _Graph, typename _Item, typename _Value>
154 154
  class DefaultMap
155 155
    : public DefaultMapSelector<_Graph, _Item, _Value>::Map {
156
    typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
157

	
156 158
  public:
157
    typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
158 159
    typedef DefaultMap<_Graph, _Item, _Value> Map;
159

	
160
    typedef typename Parent::Graph Graph;
160
    
161
    typedef typename Parent::GraphType GraphType;
161 162
    typedef typename Parent::Value Value;
162 163

	
163
    explicit DefaultMap(const Graph& graph) : Parent(graph) {}
164
    DefaultMap(const Graph& graph, const Value& value)
164
    explicit DefaultMap(const GraphType& graph) : Parent(graph) {}
165
    DefaultMap(const GraphType& graph, const Value& value)
165 166
      : Parent(graph, value) {}
166 167

	
167 168
    DefaultMap& operator=(const DefaultMap& cmap) {
168 169
      return operator=<DefaultMap>(cmap);
169 170
    }
170 171

	
171 172
    template <typename CMap>
172 173
    DefaultMap& operator=(const CMap& cmap) {
173 174
      Parent::operator=(cmap);
174 175
      return *this;
175 176
    }
176 177

	
177 178
  };
178 179

	
179 180
}
180 181

	
181 182
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
// This file contains a modified version of the enable_if library from BOOST.
20 20
// See the appropriate copyright notice below.
21 21

	
22 22
// Boost enable_if library
23 23

	
24 24
// Copyright 2003 (c) The Trustees of Indiana University.
25 25

	
26 26
// Use, modification, and distribution is subject to the Boost Software
27 27
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
28 28
// http://www.boost.org/LICENSE_1_0.txt)
29 29

	
30 30
//    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
31 31
//             Jeremiah Willcock (jewillco at osl.iu.edu)
32 32
//             Andrew Lumsdaine (lums at osl.iu.edu)
33 33

	
34 34

	
35 35
#ifndef LEMON_BITS_ENABLE_IF_H
36 36
#define LEMON_BITS_ENABLE_IF_H
37 37

	
38 38
//\file
39 39
//\brief Miscellaneous basic utilities
40 40

	
41 41
namespace lemon
42 42
{
43 43

	
44 44
  // Basic type for defining "tags". A "YES" condition for \c enable_if.
45 45

	
46 46
  // Basic type for defining "tags". A "YES" condition for \c enable_if.
47 47
  //
48 48
  //\sa False
49 49
  struct True {
50 50
    //\e
51 51
    static const bool value = true;
52 52
  };
53 53

	
54 54
  // Basic type for defining "tags". A "NO" condition for \c enable_if.
55 55

	
56 56
  // Basic type for defining "tags". A "NO" condition for \c enable_if.
57 57
  //
58 58
  //\sa True
59 59
  struct False {
60 60
    //\e
61 61
    static const bool value = false;
62 62
  };
63 63

	
64 64

	
65 65

	
66 66
  template <typename T>
67 67
  struct Wrap {
68 68
    const T &value;
69 69
    Wrap(const T &t) : value(t) {}
70 70
  };
71 71

	
72 72
  /**************** dummy class to avoid ambiguity ****************/
73 73

	
74 74
  template<int T> struct dummy { dummy(int) {} };
75 75

	
76 76
  /**************** enable_if from BOOST ****************/
77 77

	
78 78
  template <typename Type, typename T = void>
79 79
  struct exists {
80 80
    typedef T type;
81 81
  };
82 82

	
83 83

	
84 84
  template <bool B, class T = void>
85 85
  struct enable_if_c {
86 86
    typedef T type;
87 87
  };
88 88

	
89 89
  template <class T>
90 90
  struct enable_if_c<false, T> {};
91 91

	
92 92
  template <class Cond, class T = void>
93 93
  struct enable_if : public enable_if_c<Cond::value, T> {};
94 94

	
95 95
  template <bool B, class T>
96 96
  struct lazy_enable_if_c {
97 97
    typedef typename T::type type;
98 98
  };
99 99

	
100 100
  template <class T>
101 101
  struct lazy_enable_if_c<false, T> {};
102 102

	
103 103
  template <class Cond, class T>
104 104
  struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
105 105

	
106 106

	
107 107
  template <bool B, class T = void>
108 108
  struct disable_if_c {
109 109
    typedef T type;
110 110
  };
111 111

	
112 112
  template <class T>
113 113
  struct disable_if_c<true, T> {};
114 114

	
115 115
  template <class Cond, class T = void>
116 116
  struct disable_if : public disable_if_c<Cond::value, T> {};
117 117

	
118 118
  template <bool B, class T>
119 119
  struct lazy_disable_if_c {
120 120
    typedef typename T::type type;
121 121
  };
122 122

	
123 123
  template <class T>
124 124
  struct lazy_disable_if_c<true, T> {};
125 125

	
126 126
  template <class Cond, class T>
127 127
  struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
128 128

	
129 129
} // namespace lemon
130 130

	
131 131
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_BITS_GRAPH_EXTENDER_H
20 20
#define LEMON_BITS_GRAPH_EXTENDER_H
21 21

	
22 22
#include <lemon/core.h>
23 23

	
24 24
#include <lemon/bits/map_extender.h>
25 25
#include <lemon/bits/default_map.h>
26 26

	
27 27
#include <lemon/concept_check.h>
28 28
#include <lemon/concepts/maps.h>
29 29

	
30 30
//\ingroup graphbits
31 31
//\file
32
//\brief Extenders for the digraph types
32
//\brief Extenders for the graph types
33 33
namespace lemon {
34 34

	
35 35
  // \ingroup graphbits
36 36
  //
37
  // \brief Extender for the Digraphs
37
  // \brief Extender for the digraph implementations
38 38
  template <typename Base>
39 39
  class DigraphExtender : public Base {
40
    typedef Base Parent;
41

	
40 42
  public:
41 43

	
42
    typedef Base Parent;
43 44
    typedef DigraphExtender Digraph;
44 45

	
45 46
    // Base extensions
46 47

	
47 48
    typedef typename Parent::Node Node;
48 49
    typedef typename Parent::Arc Arc;
49 50

	
50 51
    int maxId(Node) const {
51 52
      return Parent::maxNodeId();
52 53
    }
53 54

	
54 55
    int maxId(Arc) const {
55 56
      return Parent::maxArcId();
56 57
    }
57 58

	
58 59
    Node fromId(int id, Node) const {
59 60
      return Parent::nodeFromId(id);
60 61
    }
61 62

	
62 63
    Arc fromId(int id, Arc) const {
63 64
      return Parent::arcFromId(id);
64 65
    }
65 66

	
66 67
    Node oppositeNode(const Node &node, const Arc &arc) const {
67 68
      if (node == Parent::source(arc))
68 69
        return Parent::target(arc);
69 70
      else if(node == Parent::target(arc))
70 71
        return Parent::source(arc);
71 72
      else
72 73
        return INVALID;
73 74
    }
74 75

	
75 76
    // Alterable extension
76 77

	
77 78
    typedef AlterationNotifier<DigraphExtender, Node> NodeNotifier;
78 79
    typedef AlterationNotifier<DigraphExtender, Arc> ArcNotifier;
79 80

	
80 81

	
81 82
  protected:
82 83

	
83 84
    mutable NodeNotifier node_notifier;
84 85
    mutable ArcNotifier arc_notifier;
85 86

	
86 87
  public:
87 88

	
88 89
    NodeNotifier& notifier(Node) const {
89 90
      return node_notifier;
90 91
    }
91 92

	
92 93
    ArcNotifier& notifier(Arc) const {
93 94
      return arc_notifier;
94 95
    }
95 96

	
96 97
    class NodeIt : public Node {
97 98
      const Digraph* _digraph;
98 99
    public:
99 100

	
100 101
      NodeIt() {}
101 102

	
102 103
      NodeIt(Invalid i) : Node(i) { }
103 104

	
104 105
      explicit NodeIt(const Digraph& digraph) : _digraph(&digraph) {
105 106
        _digraph->first(static_cast<Node&>(*this));
106 107
      }
107 108

	
108 109
      NodeIt(const Digraph& digraph, const Node& node)
109 110
        : Node(node), _digraph(&digraph) {}
110 111

	
111 112
      NodeIt& operator++() {
112 113
        _digraph->next(*this);
113 114
        return *this;
114 115
      }
115 116

	
116 117
    };
117 118

	
118 119

	
119 120
    class ArcIt : public Arc {
120 121
      const Digraph* _digraph;
121 122
    public:
122 123

	
123 124
      ArcIt() { }
124 125

	
125 126
      ArcIt(Invalid i) : Arc(i) { }
126 127

	
127 128
      explicit ArcIt(const Digraph& digraph) : _digraph(&digraph) {
128 129
        _digraph->first(static_cast<Arc&>(*this));
129 130
      }
130 131

	
131 132
      ArcIt(const Digraph& digraph, const Arc& arc) :
132 133
        Arc(arc), _digraph(&digraph) { }
133 134

	
134 135
      ArcIt& operator++() {
135 136
        _digraph->next(*this);
136 137
        return *this;
137 138
      }
138 139

	
139 140
    };
140 141

	
141 142

	
142 143
    class OutArcIt : public Arc {
143 144
      const Digraph* _digraph;
144 145
    public:
145 146

	
146 147
      OutArcIt() { }
147 148

	
148 149
      OutArcIt(Invalid i) : Arc(i) { }
149 150

	
150 151
      OutArcIt(const Digraph& digraph, const Node& node)
151 152
        : _digraph(&digraph) {
152 153
        _digraph->firstOut(*this, node);
153 154
      }
154 155

	
155 156
      OutArcIt(const Digraph& digraph, const Arc& arc)
156 157
        : Arc(arc), _digraph(&digraph) {}
157 158

	
158 159
      OutArcIt& operator++() {
159 160
        _digraph->nextOut(*this);
160 161
        return *this;
161 162
      }
162 163

	
163 164
    };
164 165

	
165 166

	
166 167
    class InArcIt : public Arc {
167 168
      const Digraph* _digraph;
168 169
    public:
169 170

	
170 171
      InArcIt() { }
171 172

	
172 173
      InArcIt(Invalid i) : Arc(i) { }
173 174

	
174 175
      InArcIt(const Digraph& digraph, const Node& node)
175 176
        : _digraph(&digraph) {
176 177
        _digraph->firstIn(*this, node);
177 178
      }
178 179

	
179 180
      InArcIt(const Digraph& digraph, const Arc& arc) :
180 181
        Arc(arc), _digraph(&digraph) {}
181 182

	
182 183
      InArcIt& operator++() {
183 184
        _digraph->nextIn(*this);
184 185
        return *this;
185 186
      }
186 187

	
187 188
    };
188 189

	
189 190
    // \brief Base node of the iterator
190 191
    //
191 192
    // Returns the base node (i.e. the source in this case) of the iterator
192 193
    Node baseNode(const OutArcIt &arc) const {
193 194
      return Parent::source(arc);
194 195
    }
195 196
    // \brief Running node of the iterator
196 197
    //
197 198
    // Returns the running node (i.e. the target in this case) of the
198 199
    // iterator
199 200
    Node runningNode(const OutArcIt &arc) const {
200 201
      return Parent::target(arc);
201 202
    }
202 203

	
203 204
    // \brief Base node of the iterator
204 205
    //
205 206
    // Returns the base node (i.e. the target in this case) of the iterator
206 207
    Node baseNode(const InArcIt &arc) const {
207 208
      return Parent::target(arc);
208 209
    }
209 210
    // \brief Running node of the iterator
210 211
    //
211 212
    // Returns the running node (i.e. the source in this case) of the
212 213
    // iterator
213 214
    Node runningNode(const InArcIt &arc) const {
214 215
      return Parent::source(arc);
215 216
    }
216 217

	
217 218

	
218 219
    template <typename _Value>
219 220
    class NodeMap
220 221
      : public MapExtender<DefaultMap<Digraph, Node, _Value> > {
221
    public:
222
      typedef DigraphExtender Digraph;
223 222
      typedef MapExtender<DefaultMap<Digraph, Node, _Value> > Parent;
224 223

	
224
    public:
225 225
      explicit NodeMap(const Digraph& digraph)
226 226
        : Parent(digraph) {}
227 227
      NodeMap(const Digraph& digraph, const _Value& value)
228 228
        : Parent(digraph, value) {}
229 229

	
230 230
    private:
231 231
      NodeMap& operator=(const NodeMap& cmap) {
232 232
        return operator=<NodeMap>(cmap);
233 233
      }
234 234

	
235 235
      template <typename CMap>
236 236
      NodeMap& operator=(const CMap& cmap) {
237 237
        Parent::operator=(cmap);
238 238
        return *this;
239 239
      }
240 240

	
241 241
    };
242 242

	
243 243
    template <typename _Value>
244 244
    class ArcMap
245 245
      : public MapExtender<DefaultMap<Digraph, Arc, _Value> > {
246
    public:
247
      typedef DigraphExtender Digraph;
248 246
      typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
249 247

	
248
    public:
250 249
      explicit ArcMap(const Digraph& digraph)
251 250
        : Parent(digraph) {}
252 251
      ArcMap(const Digraph& digraph, const _Value& value)
253 252
        : Parent(digraph, value) {}
254 253

	
255 254
    private:
256 255
      ArcMap& operator=(const ArcMap& cmap) {
257 256
        return operator=<ArcMap>(cmap);
258 257
      }
259 258

	
260 259
      template <typename CMap>
261 260
      ArcMap& operator=(const CMap& cmap) {
262 261
        Parent::operator=(cmap);
263 262
        return *this;
264 263
      }
265 264
    };
266 265

	
267 266

	
268 267
    Node addNode() {
269 268
      Node node = Parent::addNode();
270 269
      notifier(Node()).add(node);
271 270
      return node;
272 271
    }
273 272

	
274 273
    Arc addArc(const Node& from, const Node& to) {
275 274
      Arc arc = Parent::addArc(from, to);
276 275
      notifier(Arc()).add(arc);
277 276
      return arc;
278 277
    }
279 278

	
280 279
    void clear() {
281 280
      notifier(Arc()).clear();
282 281
      notifier(Node()).clear();
283 282
      Parent::clear();
284 283
    }
285 284

	
286 285
    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
287 286
    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
288 287
      Parent::build(digraph, nodeRef, arcRef);
289 288
      notifier(Node()).build();
290 289
      notifier(Arc()).build();
291 290
    }
292 291

	
293 292
    void erase(const Node& node) {
294 293
      Arc arc;
295 294
      Parent::firstOut(arc, node);
296 295
      while (arc != INVALID ) {
297 296
        erase(arc);
298 297
        Parent::firstOut(arc, node);
299 298
      }
300 299

	
301 300
      Parent::firstIn(arc, node);
302 301
      while (arc != INVALID ) {
303 302
        erase(arc);
304 303
        Parent::firstIn(arc, node);
305 304
      }
306 305

	
307 306
      notifier(Node()).erase(node);
308 307
      Parent::erase(node);
309 308
    }
310 309

	
311 310
    void erase(const Arc& arc) {
312 311
      notifier(Arc()).erase(arc);
313 312
      Parent::erase(arc);
314 313
    }
315 314

	
316 315
    DigraphExtender() {
317 316
      node_notifier.setContainer(*this);
318 317
      arc_notifier.setContainer(*this);
319 318
    }
320 319

	
321 320

	
322 321
    ~DigraphExtender() {
323 322
      arc_notifier.clear();
324 323
      node_notifier.clear();
325 324
    }
326 325
  };
327 326

	
328 327
  // \ingroup _graphbits
329 328
  //
330 329
  // \brief Extender for the Graphs
331 330
  template <typename Base>
332 331
  class GraphExtender : public Base {
332
    typedef Base Parent;
333

	
333 334
  public:
334 335

	
335
    typedef Base Parent;
336 336
    typedef GraphExtender Graph;
337 337

	
338 338
    typedef True UndirectedTag;
339 339

	
340 340
    typedef typename Parent::Node Node;
341 341
    typedef typename Parent::Arc Arc;
342 342
    typedef typename Parent::Edge Edge;
343 343

	
344 344
    // Graph extension
345 345

	
346 346
    int maxId(Node) const {
347 347
      return Parent::maxNodeId();
348 348
    }
349 349

	
350 350
    int maxId(Arc) const {
351 351
      return Parent::maxArcId();
352 352
    }
353 353

	
354 354
    int maxId(Edge) const {
355 355
      return Parent::maxEdgeId();
356 356
    }
357 357

	
358 358
    Node fromId(int id, Node) const {
359 359
      return Parent::nodeFromId(id);
360 360
    }
361 361

	
362 362
    Arc fromId(int id, Arc) const {
363 363
      return Parent::arcFromId(id);
364 364
    }
365 365

	
366 366
    Edge fromId(int id, Edge) const {
367 367
      return Parent::edgeFromId(id);
368 368
    }
369 369

	
370 370
    Node oppositeNode(const Node &n, const Edge &e) const {
371 371
      if( n == Parent::u(e))
372 372
        return Parent::v(e);
373 373
      else if( n == Parent::v(e))
374 374
        return Parent::u(e);
375 375
      else
376 376
        return INVALID;
377 377
    }
378 378

	
379 379
    Arc oppositeArc(const Arc &arc) const {
380 380
      return Parent::direct(arc, !Parent::direction(arc));
381 381
    }
382 382

	
383 383
    using Parent::direct;
384 384
    Arc direct(const Edge &edge, const Node &node) const {
385 385
      return Parent::direct(edge, Parent::u(edge) == node);
386 386
    }
387 387

	
388 388
    // Alterable extension
389 389

	
390 390
    typedef AlterationNotifier<GraphExtender, Node> NodeNotifier;
391 391
    typedef AlterationNotifier<GraphExtender, Arc> ArcNotifier;
392 392
    typedef AlterationNotifier<GraphExtender, Edge> EdgeNotifier;
393 393

	
394 394

	
395 395
  protected:
396 396

	
397 397
    mutable NodeNotifier node_notifier;
398 398
    mutable ArcNotifier arc_notifier;
399 399
    mutable EdgeNotifier edge_notifier;
400 400

	
401 401
  public:
402 402

	
403 403
    NodeNotifier& notifier(Node) const {
404 404
      return node_notifier;
405 405
    }
406 406

	
407 407
    ArcNotifier& notifier(Arc) const {
408 408
      return arc_notifier;
409 409
    }
410 410

	
411 411
    EdgeNotifier& notifier(Edge) const {
412 412
      return edge_notifier;
413 413
    }
414 414

	
415 415

	
416 416

	
417 417
    class NodeIt : public Node {
418 418
      const Graph* _graph;
419 419
    public:
420 420

	
421 421
      NodeIt() {}
422 422

	
423 423
      NodeIt(Invalid i) : Node(i) { }
424 424

	
425 425
      explicit NodeIt(const Graph& graph) : _graph(&graph) {
426 426
        _graph->first(static_cast<Node&>(*this));
427 427
      }
428 428

	
429 429
      NodeIt(const Graph& graph, const Node& node)
430 430
        : Node(node), _graph(&graph) {}
431 431

	
432 432
      NodeIt& operator++() {
433 433
        _graph->next(*this);
434 434
        return *this;
435 435
      }
436 436

	
437 437
    };
438 438

	
439 439

	
440 440
    class ArcIt : public Arc {
441 441
      const Graph* _graph;
442 442
    public:
443 443

	
444 444
      ArcIt() { }
445 445

	
446 446
      ArcIt(Invalid i) : Arc(i) { }
447 447

	
448 448
      explicit ArcIt(const Graph& graph) : _graph(&graph) {
449 449
        _graph->first(static_cast<Arc&>(*this));
450 450
      }
451 451

	
452 452
      ArcIt(const Graph& graph, const Arc& arc) :
453 453
        Arc(arc), _graph(&graph) { }
454 454

	
455 455
      ArcIt& operator++() {
456 456
        _graph->next(*this);
457 457
        return *this;
458 458
      }
459 459

	
460 460
    };
461 461

	
462 462

	
463 463
    class OutArcIt : public Arc {
464 464
      const Graph* _graph;
465 465
    public:
466 466

	
467 467
      OutArcIt() { }
468 468

	
469 469
      OutArcIt(Invalid i) : Arc(i) { }
470 470

	
471 471
      OutArcIt(const Graph& graph, const Node& node)
472 472
        : _graph(&graph) {
473 473
        _graph->firstOut(*this, node);
474 474
      }
475 475

	
476 476
      OutArcIt(const Graph& graph, const Arc& arc)
477 477
        : Arc(arc), _graph(&graph) {}
478 478

	
479 479
      OutArcIt& operator++() {
480 480
        _graph->nextOut(*this);
481 481
        return *this;
482 482
      }
483 483

	
484 484
    };
485 485

	
486 486

	
487 487
    class InArcIt : public Arc {
488 488
      const Graph* _graph;
489 489
    public:
490 490

	
491 491
      InArcIt() { }
492 492

	
493 493
      InArcIt(Invalid i) : Arc(i) { }
494 494

	
495 495
      InArcIt(const Graph& graph, const Node& node)
496 496
        : _graph(&graph) {
497 497
        _graph->firstIn(*this, node);
498 498
      }
499 499

	
500 500
      InArcIt(const Graph& graph, const Arc& arc) :
501 501
        Arc(arc), _graph(&graph) {}
502 502

	
503 503
      InArcIt& operator++() {
504 504
        _graph->nextIn(*this);
505 505
        return *this;
506 506
      }
507 507

	
508 508
    };
509 509

	
510 510

	
511 511
    class EdgeIt : public Parent::Edge {
512 512
      const Graph* _graph;
513 513
    public:
514 514

	
515 515
      EdgeIt() { }
516 516

	
517 517
      EdgeIt(Invalid i) : Edge(i) { }
518 518

	
519 519
      explicit EdgeIt(const Graph& graph) : _graph(&graph) {
520 520
        _graph->first(static_cast<Edge&>(*this));
521 521
      }
522 522

	
523 523
      EdgeIt(const Graph& graph, const Edge& edge) :
524 524
        Edge(edge), _graph(&graph) { }
525 525

	
526 526
      EdgeIt& operator++() {
527 527
        _graph->next(*this);
528 528
        return *this;
529 529
      }
530 530

	
531 531
    };
532 532

	
533 533
    class IncEdgeIt : public Parent::Edge {
534 534
      friend class GraphExtender;
535 535
      const Graph* _graph;
536 536
      bool _direction;
537 537
    public:
538 538

	
539 539
      IncEdgeIt() { }
540 540

	
541 541
      IncEdgeIt(Invalid i) : Edge(i), _direction(false) { }
542 542

	
543 543
      IncEdgeIt(const Graph& graph, const Node &node) : _graph(&graph) {
544 544
        _graph->firstInc(*this, _direction, node);
545 545
      }
546 546

	
547 547
      IncEdgeIt(const Graph& graph, const Edge &edge, const Node &node)
548 548
        : _graph(&graph), Edge(edge) {
549 549
        _direction = (_graph->source(edge) == node);
550 550
      }
551 551

	
552 552
      IncEdgeIt& operator++() {
553 553
        _graph->nextInc(*this, _direction);
554 554
        return *this;
555 555
      }
556 556
    };
557 557

	
558 558
    // \brief Base node of the iterator
559 559
    //
560 560
    // Returns the base node (ie. the source in this case) of the iterator
561 561
    Node baseNode(const OutArcIt &arc) const {
562 562
      return Parent::source(static_cast<const Arc&>(arc));
563 563
    }
564 564
    // \brief Running node of the iterator
565 565
    //
566 566
    // Returns the running node (ie. the target in this case) of the
567 567
    // iterator
568 568
    Node runningNode(const OutArcIt &arc) const {
569 569
      return Parent::target(static_cast<const Arc&>(arc));
570 570
    }
571 571

	
572 572
    // \brief Base node of the iterator
573 573
    //
574 574
    // Returns the base node (ie. the target in this case) of the iterator
575 575
    Node baseNode(const InArcIt &arc) const {
576 576
      return Parent::target(static_cast<const Arc&>(arc));
577 577
    }
578 578
    // \brief Running node of the iterator
579 579
    //
580 580
    // Returns the running node (ie. the source in this case) of the
581 581
    // iterator
582 582
    Node runningNode(const InArcIt &arc) const {
583 583
      return Parent::source(static_cast<const Arc&>(arc));
584 584
    }
585 585

	
586 586
    // Base node of the iterator
587 587
    //
588 588
    // Returns the base node of the iterator
589 589
    Node baseNode(const IncEdgeIt &edge) const {
590 590
      return edge._direction ? u(edge) : v(edge);
591 591
    }
592 592
    // Running node of the iterator
593 593
    //
594 594
    // Returns the running node of the iterator
595 595
    Node runningNode(const IncEdgeIt &edge) const {
596 596
      return edge._direction ? v(edge) : u(edge);
597 597
    }
598 598

	
599 599
    // Mappable extension
600 600

	
601 601
    template <typename _Value>
602 602
    class NodeMap
603 603
      : public MapExtender<DefaultMap<Graph, Node, _Value> > {
604
    public:
605
      typedef GraphExtender Graph;
606 604
      typedef MapExtender<DefaultMap<Graph, Node, _Value> > Parent;
607 605

	
606
    public:
608 607
      NodeMap(const Graph& graph)
609 608
        : Parent(graph) {}
610 609
      NodeMap(const Graph& graph, const _Value& value)
611 610
        : Parent(graph, value) {}
612 611

	
613 612
    private:
614 613
      NodeMap& operator=(const NodeMap& cmap) {
615 614
        return operator=<NodeMap>(cmap);
616 615
      }
617 616

	
618 617
      template <typename CMap>
619 618
      NodeMap& operator=(const CMap& cmap) {
620 619
        Parent::operator=(cmap);
621 620
        return *this;
622 621
      }
623 622

	
624 623
    };
625 624

	
626 625
    template <typename _Value>
627 626
    class ArcMap
628 627
      : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
629
    public:
630
      typedef GraphExtender Graph;
631 628
      typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
632 629

	
630
    public:
633 631
      ArcMap(const Graph& graph)
634 632
        : Parent(graph) {}
635 633
      ArcMap(const Graph& graph, const _Value& value)
636 634
        : Parent(graph, value) {}
637 635

	
638 636
    private:
639 637
      ArcMap& operator=(const ArcMap& cmap) {
640 638
        return operator=<ArcMap>(cmap);
641 639
      }
642 640

	
643 641
      template <typename CMap>
644 642
      ArcMap& operator=(const CMap& cmap) {
645 643
        Parent::operator=(cmap);
646 644
        return *this;
647 645
      }
648 646
    };
649 647

	
650 648

	
651 649
    template <typename _Value>
652 650
    class EdgeMap
653 651
      : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
654
    public:
655
      typedef GraphExtender Graph;
656 652
      typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
657 653

	
654
    public:
658 655
      EdgeMap(const Graph& graph)
659 656
        : Parent(graph) {}
660 657

	
661 658
      EdgeMap(const Graph& graph, const _Value& value)
662 659
        : Parent(graph, value) {}
663 660

	
664 661
    private:
665 662
      EdgeMap& operator=(const EdgeMap& cmap) {
666 663
        return operator=<EdgeMap>(cmap);
667 664
      }
668 665

	
669 666
      template <typename CMap>
670 667
      EdgeMap& operator=(const CMap& cmap) {
671 668
        Parent::operator=(cmap);
672 669
        return *this;
673 670
      }
674 671

	
675 672
    };
676 673

	
677 674
    // Alteration extension
678 675

	
679 676
    Node addNode() {
680 677
      Node node = Parent::addNode();
681 678
      notifier(Node()).add(node);
682 679
      return node;
683 680
    }
684 681

	
685 682
    Edge addEdge(const Node& from, const Node& to) {
686 683
      Edge edge = Parent::addEdge(from, to);
687 684
      notifier(Edge()).add(edge);
688 685
      std::vector<Arc> ev;
689 686
      ev.push_back(Parent::direct(edge, true));
690 687
      ev.push_back(Parent::direct(edge, false));
691 688
      notifier(Arc()).add(ev);
692 689
      return edge;
693 690
    }
694 691

	
695 692
    void clear() {
696 693
      notifier(Arc()).clear();
697 694
      notifier(Edge()).clear();
698 695
      notifier(Node()).clear();
699 696
      Parent::clear();
700 697
    }
701 698

	
702 699
    template <typename Graph, typename NodeRefMap, typename EdgeRefMap>
703 700
    void build(const Graph& graph, NodeRefMap& nodeRef,
704 701
               EdgeRefMap& edgeRef) {
705 702
      Parent::build(graph, nodeRef, edgeRef);
706 703
      notifier(Node()).build();
707 704
      notifier(Edge()).build();
708 705
      notifier(Arc()).build();
709 706
    }
710 707

	
711 708
    void erase(const Node& node) {
712 709
      Arc arc;
713 710
      Parent::firstOut(arc, node);
714 711
      while (arc != INVALID ) {
715 712
        erase(arc);
716 713
        Parent::firstOut(arc, node);
717 714
      }
718 715

	
719 716
      Parent::firstIn(arc, node);
720 717
      while (arc != INVALID ) {
721 718
        erase(arc);
722 719
        Parent::firstIn(arc, node);
723 720
      }
724 721

	
725 722
      notifier(Node()).erase(node);
726 723
      Parent::erase(node);
727 724
    }
728 725

	
729 726
    void erase(const Edge& edge) {
730 727
      std::vector<Arc> av;
731 728
      av.push_back(Parent::direct(edge, true));
732 729
      av.push_back(Parent::direct(edge, false));
733 730
      notifier(Arc()).erase(av);
734 731
      notifier(Edge()).erase(edge);
735 732
      Parent::erase(edge);
736 733
    }
737 734

	
738 735
    GraphExtender() {
739 736
      node_notifier.setContainer(*this);
740 737
      arc_notifier.setContainer(*this);
741 738
      edge_notifier.setContainer(*this);
742 739
    }
743 740

	
744 741
    ~GraphExtender() {
745 742
      edge_notifier.clear();
746 743
      arc_notifier.clear();
747 744
      node_notifier.clear();
748 745
    }
749 746

	
750 747
  };
751 748

	
752 749
}
753 750

	
754 751
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_BITS_MAP_EXTENDER_H
20 20
#define LEMON_BITS_MAP_EXTENDER_H
21 21

	
22 22
#include <iterator>
23 23

	
24 24
#include <lemon/bits/traits.h>
25 25

	
26 26
#include <lemon/concept_check.h>
27 27
#include <lemon/concepts/maps.h>
28 28

	
29 29
//\file
30 30
//\brief Extenders for iterable maps.
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  // \ingroup graphbits
35 35
  //
36 36
  // \brief Extender for maps
37 37
  template <typename _Map>
38 38
  class MapExtender : public _Map {
39
    typedef _Map Parent;
40
    typedef typename Parent::GraphType GraphType;
41

	
39 42
  public:
40 43

	
41
    typedef _Map Parent;
42 44
    typedef MapExtender Map;
43

	
44

	
45
    typedef typename Parent::Graph Graph;
46 45
    typedef typename Parent::Key Item;
47 46

	
48 47
    typedef typename Parent::Key Key;
49 48
    typedef typename Parent::Value Value;
49
    typedef typename Parent::Reference Reference;
50
    typedef typename Parent::ConstReference ConstReference;
51

	
52
    typedef typename Parent::ReferenceMapTag ReferenceMapTag;
50 53

	
51 54
    class MapIt;
52 55
    class ConstMapIt;
53 56

	
54 57
    friend class MapIt;
55 58
    friend class ConstMapIt;
56 59

	
57 60
  public:
58 61

	
59
    MapExtender(const Graph& graph)
62
    MapExtender(const GraphType& graph)
60 63
      : Parent(graph) {}
61 64

	
62
    MapExtender(const Graph& graph, const Value& value)
65
    MapExtender(const GraphType& graph, const Value& value)
63 66
      : Parent(graph, value) {}
64 67

	
65 68
  private:
66 69
    MapExtender& operator=(const MapExtender& cmap) {
67 70
      return operator=<MapExtender>(cmap);
68 71
    }
69 72

	
70 73
    template <typename CMap>
71 74
    MapExtender& operator=(const CMap& cmap) {
72 75
      Parent::operator=(cmap);
73 76
      return *this;
74 77
    }
75 78

	
76 79
  public:
77 80
    class MapIt : public Item {
81
      typedef Item Parent;
82

	
78 83
    public:
79 84

	
80
      typedef Item Parent;
81 85
      typedef typename Map::Value Value;
82 86

	
83 87
      MapIt() : map(NULL) {}
84 88

	
85 89
      MapIt(Invalid i) : Parent(i), map(NULL) {}
86 90

	
87 91
      explicit MapIt(Map& _map) : map(&_map) {
88 92
        map->notifier()->first(*this);
89 93
      }
90 94

	
91 95
      MapIt(const Map& _map, const Item& item)
92 96
        : Parent(item), map(&_map) {}
93 97

	
94 98
      MapIt& operator++() {
95 99
        map->notifier()->next(*this);
96 100
        return *this;
97 101
      }
98 102

	
99 103
      typename MapTraits<Map>::ConstReturnValue operator*() const {
100 104
        return (*map)[*this];
101 105
      }
102 106

	
103 107
      typename MapTraits<Map>::ReturnValue operator*() {
104 108
        return (*map)[*this];
105 109
      }
106 110

	
107 111
      void set(const Value& value) {
108 112
        map->set(*this, value);
109 113
      }
110 114

	
111 115
    protected:
112 116
      Map* map;
113 117

	
114 118
    };
115 119

	
116 120
    class ConstMapIt : public Item {
121
      typedef Item Parent;
122

	
117 123
    public:
118 124

	
119
      typedef Item Parent;
120

	
121 125
      typedef typename Map::Value Value;
122 126

	
123 127
      ConstMapIt() : map(NULL) {}
124 128

	
125 129
      ConstMapIt(Invalid i) : Parent(i), map(NULL) {}
126 130

	
127 131
      explicit ConstMapIt(Map& _map) : map(&_map) {
128 132
        map->notifier()->first(*this);
129 133
      }
130 134

	
131 135
      ConstMapIt(const Map& _map, const Item& item)
132 136
        : Parent(item), map(_map) {}
133 137

	
134 138
      ConstMapIt& operator++() {
135 139
        map->notifier()->next(*this);
136 140
        return *this;
137 141
      }
138 142

	
139 143
      typename MapTraits<Map>::ConstReturnValue operator*() const {
140 144
        return map[*this];
141 145
      }
142 146

	
143 147
    protected:
144 148
      const Map* map;
145 149
    };
146 150

	
147 151
    class ItemIt : public Item {
148
    public:
149

	
150 152
      typedef Item Parent;
151 153

	
154
    public:
152 155
      ItemIt() : map(NULL) {}
153 156

	
157

	
154 158
      ItemIt(Invalid i) : Parent(i), map(NULL) {}
155 159

	
156 160
      explicit ItemIt(Map& _map) : map(&_map) {
157 161
        map->notifier()->first(*this);
158 162
      }
159 163

	
160 164
      ItemIt(const Map& _map, const Item& item)
161 165
        : Parent(item), map(&_map) {}
162 166

	
163 167
      ItemIt& operator++() {
164 168
        map->notifier()->next(*this);
165 169
        return *this;
166 170
      }
167 171

	
168 172
    protected:
169 173
      const Map* map;
170 174

	
171 175
    };
172 176
  };
173 177

	
174 178
  // \ingroup graphbits
175 179
  //
176 180
  // \brief Extender for maps which use a subset of the items.
177 181
  template <typename _Graph, typename _Map>
178 182
  class SubMapExtender : public _Map {
183
    typedef _Map Parent;
184
    typedef _Graph GraphType;
185

	
179 186
  public:
180 187

	
181
    typedef _Map Parent;
182 188
    typedef SubMapExtender Map;
183

	
184
    typedef _Graph Graph;
185

	
186 189
    typedef typename Parent::Key Item;
187 190

	
188 191
    typedef typename Parent::Key Key;
189 192
    typedef typename Parent::Value Value;
193
    typedef typename Parent::Reference Reference;
194
    typedef typename Parent::ConstReference ConstReference;
195

	
196
    typedef typename Parent::ReferenceMapTag ReferenceMapTag;
190 197

	
191 198
    class MapIt;
192 199
    class ConstMapIt;
193 200

	
194 201
    friend class MapIt;
195 202
    friend class ConstMapIt;
196 203

	
197 204
  public:
198 205

	
199
    SubMapExtender(const Graph& _graph)
206
    SubMapExtender(const GraphType& _graph)
200 207
      : Parent(_graph), graph(_graph) {}
201 208

	
202
    SubMapExtender(const Graph& _graph, const Value& _value)
209
    SubMapExtender(const GraphType& _graph, const Value& _value)
203 210
      : Parent(_graph, _value), graph(_graph) {}
204 211

	
205 212
  private:
206 213
    SubMapExtender& operator=(const SubMapExtender& cmap) {
207 214
      return operator=<MapExtender>(cmap);
208 215
    }
209 216

	
210 217
    template <typename CMap>
211 218
    SubMapExtender& operator=(const CMap& cmap) {
212 219
      checkConcept<concepts::ReadMap<Key, Value>, CMap>();
213 220
      Item it;
214 221
      for (graph.first(it); it != INVALID; graph.next(it)) {
215 222
        Parent::set(it, cmap[it]);
216 223
      }
217 224
      return *this;
218 225
    }
219 226

	
220 227
  public:
221 228
    class MapIt : public Item {
229
      typedef Item Parent;
230

	
222 231
    public:
223

	
224
      typedef Item Parent;
225 232
      typedef typename Map::Value Value;
226 233

	
227 234
      MapIt() : map(NULL) {}
228 235

	
229 236
      MapIt(Invalid i) : Parent(i), map(NULL) { }
230 237

	
231 238
      explicit MapIt(Map& _map) : map(&_map) {
232 239
        map->graph.first(*this);
233 240
      }
234 241

	
235 242
      MapIt(const Map& _map, const Item& item)
236 243
        : Parent(item), map(&_map) {}
237 244

	
238 245
      MapIt& operator++() {
239 246
        map->graph.next(*this);
240 247
        return *this;
241 248
      }
242 249

	
243 250
      typename MapTraits<Map>::ConstReturnValue operator*() const {
244 251
        return (*map)[*this];
245 252
      }
246 253

	
247 254
      typename MapTraits<Map>::ReturnValue operator*() {
248 255
        return (*map)[*this];
249 256
      }
250 257

	
251 258
      void set(const Value& value) {
252 259
        map->set(*this, value);
253 260
      }
254 261

	
255 262
    protected:
256 263
      Map* map;
257 264

	
258 265
    };
259 266

	
260 267
    class ConstMapIt : public Item {
268
      typedef Item Parent;
269

	
261 270
    public:
262 271

	
263
      typedef Item Parent;
264

	
265 272
      typedef typename Map::Value Value;
266 273

	
267 274
      ConstMapIt() : map(NULL) {}
268 275

	
269 276
      ConstMapIt(Invalid i) : Parent(i), map(NULL) { }
270 277

	
271 278
      explicit ConstMapIt(Map& _map) : map(&_map) {
272 279
        map->graph.first(*this);
273 280
      }
274 281

	
275 282
      ConstMapIt(const Map& _map, const Item& item)
276 283
        : Parent(item), map(&_map) {}
277 284

	
278 285
      ConstMapIt& operator++() {
279 286
        map->graph.next(*this);
280 287
        return *this;
281 288
      }
282 289

	
283 290
      typename MapTraits<Map>::ConstReturnValue operator*() const {
284 291
        return (*map)[*this];
285 292
      }
286 293

	
287 294
    protected:
288 295
      const Map* map;
289 296
    };
290 297

	
291 298
    class ItemIt : public Item {
292
    public:
293

	
294 299
      typedef Item Parent;
295 300

	
301
    public:
296 302
      ItemIt() : map(NULL) {}
297 303

	
304

	
298 305
      ItemIt(Invalid i) : Parent(i), map(NULL) { }
299 306

	
300 307
      explicit ItemIt(Map& _map) : map(&_map) {
301 308
        map->graph.first(*this);
302 309
      }
303 310

	
304 311
      ItemIt(const Map& _map, const Item& item)
305 312
        : Parent(item), map(&_map) {}
306 313

	
307 314
      ItemIt& operator++() {
308 315
        map->graph.next(*this);
309 316
        return *this;
310 317
      }
311 318

	
312 319
    protected:
313 320
      const Map* map;
314 321

	
315 322
    };
316 323

	
317 324
  private:
318 325

	
319
    const Graph& graph;
326
    const GraphType& graph;
320 327

	
321 328
  };
322 329

	
323 330
}
324 331

	
325 332
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
#ifndef LEMON_BITS_PRED_MAP_PATH_H
20
#define LEMON_BITS_PRED_MAP_PATH_H
19
#ifndef LEMON_BITS_PATH_DUMP_H
20
#define LEMON_BITS_PATH_DUMP_H
21

	
22
#include <lemon/core.h>
23
#include <lemon/concept_check.h>
21 24

	
22 25
namespace lemon {
23 26

	
24 27
  template <typename _Digraph, typename _PredMap>
25 28
  class PredMapPath {
26 29
  public:
27 30
    typedef True RevPathTag;
28 31

	
29 32
    typedef _Digraph Digraph;
30 33
    typedef typename Digraph::Arc Arc;
31 34
    typedef _PredMap PredMap;
32 35

	
33 36
    PredMapPath(const Digraph& _digraph, const PredMap& _predMap,
34 37
                typename Digraph::Node _target)
35 38
      : digraph(_digraph), predMap(_predMap), target(_target) {}
36 39

	
37 40
    int length() const {
38 41
      int len = 0;
39 42
      typename Digraph::Node node = target;
40 43
      typename Digraph::Arc arc;
41 44
      while ((arc = predMap[node]) != INVALID) {
42 45
        node = digraph.source(arc);
43 46
        ++len;
44 47
      }
45 48
      return len;
46 49
    }
47 50

	
48 51
    bool empty() const {
49 52
      return predMap[target] != INVALID;
50 53
    }
51 54

	
52 55
    class RevArcIt {
53 56
    public:
54 57
      RevArcIt() {}
55 58
      RevArcIt(Invalid) : path(0), current(INVALID) {}
56 59
      RevArcIt(const PredMapPath& _path)
57 60
        : path(&_path), current(_path.target) {
58 61
        if (path->predMap[current] == INVALID) current = INVALID;
59 62
      }
60 63

	
61 64
      operator const typename Digraph::Arc() const {
62 65
        return path->predMap[current];
63 66
      }
64 67

	
65 68
      RevArcIt& operator++() {
66 69
        current = path->digraph.source(path->predMap[current]);
67 70
        if (path->predMap[current] == INVALID) current = INVALID;
68 71
        return *this;
69 72
      }
70 73

	
71 74
      bool operator==(const RevArcIt& e) const {
72 75
        return current == e.current;
73 76
      }
74 77

	
75 78
      bool operator!=(const RevArcIt& e) const {
76 79
        return current != e.current;
77 80
      }
78 81

	
79 82
      bool operator<(const RevArcIt& e) const {
80 83
        return current < e.current;
81 84
      }
82 85

	
83 86
    private:
84 87
      const PredMapPath* path;
85 88
      typename Digraph::Node current;
86 89
    };
87 90

	
88 91
  private:
89 92
    const Digraph& digraph;
90 93
    const PredMap& predMap;
91 94
    typename Digraph::Node target;
92 95
  };
93 96

	
94 97

	
95 98
  template <typename _Digraph, typename _PredMatrixMap>
96 99
  class PredMatrixMapPath {
97 100
  public:
98 101
    typedef True RevPathTag;
99 102

	
100 103
    typedef _Digraph Digraph;
101 104
    typedef typename Digraph::Arc Arc;
102 105
    typedef _PredMatrixMap PredMatrixMap;
103 106

	
104 107
    PredMatrixMapPath(const Digraph& _digraph,
105 108
                      const PredMatrixMap& _predMatrixMap,
106 109
                      typename Digraph::Node _source,
107 110
                      typename Digraph::Node _target)
108 111
      : digraph(_digraph), predMatrixMap(_predMatrixMap),
109 112
        source(_source), target(_target) {}
110 113

	
111 114
    int length() const {
112 115
      int len = 0;
113 116
      typename Digraph::Node node = target;
114 117
      typename Digraph::Arc arc;
115 118
      while ((arc = predMatrixMap(source, node)) != INVALID) {
116 119
        node = digraph.source(arc);
117 120
        ++len;
118 121
      }
119 122
      return len;
120 123
    }
121 124

	
122 125
    bool empty() const {
123 126
      return source != target;
124 127
    }
125 128

	
126 129
    class RevArcIt {
127 130
    public:
128 131
      RevArcIt() {}
129 132
      RevArcIt(Invalid) : path(0), current(INVALID) {}
130 133
      RevArcIt(const PredMatrixMapPath& _path)
131 134
        : path(&_path), current(_path.target) {
132 135
        if (path->predMatrixMap(path->source, current) == INVALID)
133 136
          current = INVALID;
134 137
      }
135 138

	
136 139
      operator const typename Digraph::Arc() const {
137 140
        return path->predMatrixMap(path->source, current);
138 141
      }
139 142

	
140 143
      RevArcIt& operator++() {
141 144
        current =
142 145
          path->digraph.source(path->predMatrixMap(path->source, current));
143 146
        if (path->predMatrixMap(path->source, current) == INVALID)
144 147
          current = INVALID;
145 148
        return *this;
146 149
      }
147 150

	
148 151
      bool operator==(const RevArcIt& e) const {
149 152
        return current == e.current;
150 153
      }
151 154

	
152 155
      bool operator!=(const RevArcIt& e) const {
153 156
        return current != e.current;
154 157
      }
155 158

	
156 159
      bool operator<(const RevArcIt& e) const {
157 160
        return current < e.current;
158 161
      }
159 162

	
160 163
    private:
161 164
      const PredMatrixMapPath* path;
162 165
      typename Digraph::Node current;
163 166
    };
164 167

	
165 168
  private:
166 169
    const Digraph& digraph;
167 170
    const PredMatrixMap& predMatrixMap;
168 171
    typename Digraph::Node source;
169 172
    typename Digraph::Node target;
170 173
  };
171 174

	
172 175
}
173 176

	
174 177
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_BITS_TRAITS_H
20 20
#define LEMON_BITS_TRAITS_H
21 21

	
22 22
//\file
23 23
//\brief Traits for graphs and maps
24 24
//
25 25

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

	
28 28
namespace lemon {
29 29

	
30 30
  struct InvalidType {};
31 31

	
32
  template <typename _Graph, typename _Item>
32
  template <typename GR, typename _Item>
33 33
  class ItemSetTraits {};
34 34

	
35 35

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

	
48
  template <typename _Graph>
49
  class ItemSetTraits<_Graph, typename _Graph::Node> {
48
  template <typename GR>
49
  class ItemSetTraits<GR, typename GR::Node> {
50 50
  public:
51 51

	
52
    typedef _Graph Graph;
52
    typedef GR Graph;
53
    typedef GR Digraph;
53 54

	
54
    typedef typename Graph::Node Item;
55
    typedef typename Graph::NodeIt ItemIt;
55
    typedef typename GR::Node Item;
56
    typedef typename GR::NodeIt ItemIt;
56 57

	
57
    typedef typename NodeNotifierIndicator<Graph>::Type ItemNotifier;
58
    typedef typename NodeNotifierIndicator<GR>::Type ItemNotifier;
58 59

	
59
    template <typename _Value>
60
    class Map : public Graph::template NodeMap<_Value> {
60
    template <typename V>
61
    class Map : public GR::template NodeMap<V> {
62
      typedef typename GR::template NodeMap<V> Parent;
63

	
61 64
    public:
62
      typedef typename Graph::template NodeMap<_Value> Parent;
63
      typedef typename Graph::template NodeMap<_Value> Type;
65
      typedef typename GR::template NodeMap<V> Type;
64 66
      typedef typename Parent::Value Value;
65 67

	
66
      Map(const Graph& _digraph) : Parent(_digraph) {}
67
      Map(const Graph& _digraph, const Value& _value)
68
      Map(const GR& _digraph) : Parent(_digraph) {}
69
      Map(const GR& _digraph, const Value& _value)
68 70
        : Parent(_digraph, _value) {}
69 71

	
70 72
     };
71 73

	
72 74
  };
73 75

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

	
86
  template <typename _Graph>
87
  class ItemSetTraits<_Graph, typename _Graph::Arc> {
88
  template <typename GR>
89
  class ItemSetTraits<GR, typename GR::Arc> {
88 90
  public:
89 91

	
90
    typedef _Graph Graph;
92
    typedef GR Graph;
93
    typedef GR Digraph;
91 94

	
92
    typedef typename Graph::Arc Item;
93
    typedef typename Graph::ArcIt ItemIt;
95
    typedef typename GR::Arc Item;
96
    typedef typename GR::ArcIt ItemIt;
94 97

	
95
    typedef typename ArcNotifierIndicator<Graph>::Type ItemNotifier;
98
    typedef typename ArcNotifierIndicator<GR>::Type ItemNotifier;
96 99

	
97
    template <typename _Value>
98
    class Map : public Graph::template ArcMap<_Value> {
100
    template <typename V>
101
    class Map : public GR::template ArcMap<V> {
102
      typedef typename GR::template ArcMap<V> Parent;
103

	
99 104
    public:
100
      typedef typename Graph::template ArcMap<_Value> Parent;
101
      typedef typename Graph::template ArcMap<_Value> Type;
105
      typedef typename GR::template ArcMap<V> Type;
102 106
      typedef typename Parent::Value Value;
103 107

	
104
      Map(const Graph& _digraph) : Parent(_digraph) {}
105
      Map(const Graph& _digraph, const Value& _value)
108
      Map(const GR& _digraph) : Parent(_digraph) {}
109
      Map(const GR& _digraph, const Value& _value)
106 110
        : Parent(_digraph, _value) {}
107 111
    };
108 112

	
109 113
  };
110 114

	
111
  template <typename Graph, typename Enable = void>
115
  template <typename GR, typename Enable = void>
112 116
  struct EdgeNotifierIndicator {
113 117
    typedef InvalidType Type;
114 118
  };
115
  template <typename Graph>
119
  template <typename GR>
116 120
  struct EdgeNotifierIndicator<
117
    Graph,
118
    typename enable_if<typename Graph::EdgeNotifier::Notifier, void>::type
121
    GR,
122
    typename enable_if<typename GR::EdgeNotifier::Notifier, void>::type
119 123
  > {
120
    typedef typename Graph::EdgeNotifier Type;
124
    typedef typename GR::EdgeNotifier Type;
121 125
  };
122 126

	
123
  template <typename _Graph>
124
  class ItemSetTraits<_Graph, typename _Graph::Edge> {
127
  template <typename GR>
128
  class ItemSetTraits<GR, typename GR::Edge> {
125 129
  public:
126 130

	
127
    typedef _Graph Graph;
131
    typedef GR Graph;
132
    typedef GR Digraph;
128 133

	
129
    typedef typename Graph::Edge Item;
130
    typedef typename Graph::EdgeIt ItemIt;
134
    typedef typename GR::Edge Item;
135
    typedef typename GR::EdgeIt ItemIt;
131 136

	
132
    typedef typename EdgeNotifierIndicator<Graph>::Type ItemNotifier;
137
    typedef typename EdgeNotifierIndicator<GR>::Type ItemNotifier;
133 138

	
134
    template <typename _Value>
135
    class Map : public Graph::template EdgeMap<_Value> {
139
    template <typename V>
140
    class Map : public GR::template EdgeMap<V> {
141
      typedef typename GR::template EdgeMap<V> Parent;
142

	
136 143
    public:
137
      typedef typename Graph::template EdgeMap<_Value> Parent;
138
      typedef typename Graph::template EdgeMap<_Value> Type;
144
      typedef typename GR::template EdgeMap<V> Type;
139 145
      typedef typename Parent::Value Value;
140 146

	
141
      Map(const Graph& _digraph) : Parent(_digraph) {}
142
      Map(const Graph& _digraph, const Value& _value)
147
      Map(const GR& _digraph) : Parent(_digraph) {}
148
      Map(const GR& _digraph, const Value& _value)
143 149
        : Parent(_digraph, _value) {}
144 150
    };
145 151

	
146 152
  };
147 153

	
148 154
  template <typename Map, typename Enable = void>
149 155
  struct MapTraits {
150 156
    typedef False ReferenceMapTag;
151 157

	
152 158
    typedef typename Map::Key Key;
153 159
    typedef typename Map::Value Value;
154 160

	
155 161
    typedef Value ConstReturnValue;
156 162
    typedef Value ReturnValue;
157 163
  };
158 164

	
159 165
  template <typename Map>
160 166
  struct MapTraits<
161 167
    Map, typename enable_if<typename Map::ReferenceMapTag, void>::type >
162 168
  {
163 169
    typedef True ReferenceMapTag;
164 170

	
165 171
    typedef typename Map::Key Key;
166 172
    typedef typename Map::Value Value;
167 173

	
168 174
    typedef typename Map::ConstReference ConstReturnValue;
169 175
    typedef typename Map::Reference ReturnValue;
170 176

	
171 177
    typedef typename Map::ConstReference ConstReference;
172 178
    typedef typename Map::Reference Reference;
173 179
 };
174 180

	
175 181
  template <typename MatrixMap, typename Enable = void>
176 182
  struct MatrixMapTraits {
177 183
    typedef False ReferenceMapTag;
178 184

	
179 185
    typedef typename MatrixMap::FirstKey FirstKey;
180 186
    typedef typename MatrixMap::SecondKey SecondKey;
181 187
    typedef typename MatrixMap::Value Value;
182 188

	
183 189
    typedef Value ConstReturnValue;
184 190
    typedef Value ReturnValue;
185 191
  };
186 192

	
187 193
  template <typename MatrixMap>
188 194
  struct MatrixMapTraits<
189 195
    MatrixMap, typename enable_if<typename MatrixMap::ReferenceMapTag,
190 196
                                  void>::type >
191 197
  {
192 198
    typedef True ReferenceMapTag;
193 199

	
194 200
    typedef typename MatrixMap::FirstKey FirstKey;
195 201
    typedef typename MatrixMap::SecondKey SecondKey;
196 202
    typedef typename MatrixMap::Value Value;
197 203

	
198 204
    typedef typename MatrixMap::ConstReference ConstReturnValue;
199 205
    typedef typename MatrixMap::Reference ReturnValue;
200 206

	
201 207
    typedef typename MatrixMap::ConstReference ConstReference;
202 208
    typedef typename MatrixMap::Reference Reference;
203 209
 };
204 210

	
205 211
  // Indicators for the tags
206 212

	
207
  template <typename Graph, typename Enable = void>
213
  template <typename GR, typename Enable = void>
208 214
  struct NodeNumTagIndicator {
209 215
    static const bool value = false;
210 216
  };
211 217

	
212
  template <typename Graph>
218
  template <typename GR>
213 219
  struct NodeNumTagIndicator<
214
    Graph,
215
    typename enable_if<typename Graph::NodeNumTag, void>::type
220
    GR,
221
    typename enable_if<typename GR::NodeNumTag, void>::type
216 222
  > {
217 223
    static const bool value = true;
218 224
  };
219 225

	
220
  template <typename Graph, typename Enable = void>
226
  template <typename GR, typename Enable = void>
227
  struct ArcNumTagIndicator {
228
    static const bool value = false;
229
  };
230

	
231
  template <typename GR>
232
  struct ArcNumTagIndicator<
233
    GR,
234
    typename enable_if<typename GR::ArcNumTag, void>::type
235
  > {
236
    static const bool value = true;
237
  };
238

	
239
  template <typename GR, typename Enable = void>
221 240
  struct EdgeNumTagIndicator {
222 241
    static const bool value = false;
223 242
  };
224 243

	
225
  template <typename Graph>
244
  template <typename GR>
226 245
  struct EdgeNumTagIndicator<
227
    Graph,
228
    typename enable_if<typename Graph::EdgeNumTag, void>::type
246
    GR,
247
    typename enable_if<typename GR::EdgeNumTag, void>::type
229 248
  > {
230 249
    static const bool value = true;
231 250
  };
232 251

	
233
  template <typename Graph, typename Enable = void>
252
  template <typename GR, typename Enable = void>
253
  struct FindArcTagIndicator {
254
    static const bool value = false;
255
  };
256

	
257
  template <typename GR>
258
  struct FindArcTagIndicator<
259
    GR,
260
    typename enable_if<typename GR::FindArcTag, void>::type
261
  > {
262
    static const bool value = true;
263
  };
264

	
265
  template <typename GR, typename Enable = void>
234 266
  struct FindEdgeTagIndicator {
235 267
    static const bool value = false;
236 268
  };
237 269

	
238
  template <typename Graph>
270
  template <typename GR>
239 271
  struct FindEdgeTagIndicator<
240
    Graph,
241
    typename enable_if<typename Graph::FindEdgeTag, void>::type
272
    GR,
273
    typename enable_if<typename GR::FindEdgeTag, void>::type
242 274
  > {
243 275
    static const bool value = true;
244 276
  };
245 277

	
246
  template <typename Graph, typename Enable = void>
278
  template <typename GR, typename Enable = void>
247 279
  struct UndirectedTagIndicator {
248 280
    static const bool value = false;
249 281
  };
250 282

	
251
  template <typename Graph>
283
  template <typename GR>
252 284
  struct UndirectedTagIndicator<
253
    Graph,
254
    typename enable_if<typename Graph::UndirectedTag, void>::type
285
    GR,
286
    typename enable_if<typename GR::UndirectedTag, void>::type
255 287
  > {
256 288
    static const bool value = true;
257 289
  };
258 290

	
259
  template <typename Graph, typename Enable = void>
291
  template <typename GR, typename Enable = void>
260 292
  struct BuildTagIndicator {
261 293
    static const bool value = false;
262 294
  };
263 295

	
264
  template <typename Graph>
296
  template <typename GR>
265 297
  struct BuildTagIndicator<
266
    Graph,
267
    typename enable_if<typename Graph::BuildTag, void>::type
298
    GR,
299
    typename enable_if<typename GR::BuildTag, void>::type
268 300
  > {
269 301
    static const bool value = true;
270 302
  };
271 303

	
272 304
}
273 305

	
274 306
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_BITS_VECTOR_MAP_H
20 20
#define LEMON_BITS_VECTOR_MAP_H
21 21

	
22 22
#include <vector>
23 23
#include <algorithm>
24 24

	
25 25
#include <lemon/core.h>
26 26
#include <lemon/bits/alteration_notifier.h>
27 27

	
28 28
#include <lemon/concept_check.h>
29 29
#include <lemon/concepts/maps.h>
30 30

	
31 31
//\ingroup graphbits
32 32
//
33 33
//\file
34 34
//\brief Vector based graph maps.
35 35
namespace lemon {
36 36

	
37 37
  // \ingroup graphbits
38 38
  //
39 39
  // \brief Graph map based on the std::vector storage.
40 40
  //
41
  // The VectorMap template class is graph map structure what
42
  // automatically updates the map when a key is added to or erased from
43
  // the map. This map type uses the std::vector to store the values.
41
  // The VectorMap template class is graph map structure that automatically
42
  // updates the map when a key is added to or erased from the graph.
43
  // This map type uses std::vector to store the values.
44 44
  //
45 45
  // \tparam _Graph The graph this map is attached to.
46 46
  // \tparam _Item The item type of the graph items.
47 47
  // \tparam _Value The value type of the map.
48 48
  template <typename _Graph, typename _Item, typename _Value>
49 49
  class VectorMap
50 50
    : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
51 51
  private:
52 52

	
53 53
    // The container type of the map.
54 54
    typedef std::vector<_Value> Container;
55 55

	
56 56
  public:
57 57

	
58 58
    // The graph type of the map.
59
    typedef _Graph Graph;
59
    typedef _Graph GraphType;
60 60
    // The item type of the map.
61 61
    typedef _Item Item;
62 62
    // The reference map tag.
63 63
    typedef True ReferenceMapTag;
64 64

	
65 65
    // The key type of the map.
66 66
    typedef _Item Key;
67 67
    // The value type of the map.
68 68
    typedef _Value Value;
69 69

	
70 70
    // The notifier type.
71 71
    typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
72 72

	
73 73
    // The map type.
74 74
    typedef VectorMap Map;
75
    // The base class of the map.
76
    typedef typename Notifier::ObserverBase Parent;
77 75

	
78 76
    // The reference type of the map;
79 77
    typedef typename Container::reference Reference;
80 78
    // The const reference type of the map;
81 79
    typedef typename Container::const_reference ConstReference;
82 80

	
81
  private:
82

	
83
    // The base class of the map.
84
    typedef typename Notifier::ObserverBase Parent;
85

	
86
  public:
83 87

	
84 88
    // \brief Constructor to attach the new map into the notifier.
85 89
    //
86 90
    // It constructs a map and attachs it into the notifier.
87 91
    // It adds all the items of the graph to the map.
88
    VectorMap(const Graph& graph) {
92
    VectorMap(const GraphType& graph) {
89 93
      Parent::attach(graph.notifier(Item()));
90 94
      container.resize(Parent::notifier()->maxId() + 1);
91 95
    }
92 96

	
93 97
    // \brief Constructor uses given value to initialize the map.
94 98
    //
95 99
    // It constructs a map uses a given value to initialize the map.
96 100
    // It adds all the items of the graph to the map.
97
    VectorMap(const Graph& graph, const Value& value) {
101
    VectorMap(const GraphType& graph, const Value& value) {
98 102
      Parent::attach(graph.notifier(Item()));
99 103
      container.resize(Parent::notifier()->maxId() + 1, value);
100 104
    }
101 105

	
102 106
  private:
103 107
    // \brief Copy constructor
104 108
    //
105 109
    // Copy constructor.
106 110
    VectorMap(const VectorMap& _copy) : Parent() {
107 111
      if (_copy.attached()) {
108 112
        Parent::attach(*_copy.notifier());
109 113
        container = _copy.container;
110 114
      }
111 115
    }
112 116

	
113 117
    // \brief Assign operator.
114 118
    //
115 119
    // This operator assigns for each item in the map the
116 120
    // value mapped to the same item in the copied map.
117 121
    // The parameter map should be indiced with the same
118 122
    // itemset because this assign operator does not change
119 123
    // the container of the map.
120 124
    VectorMap& operator=(const VectorMap& cmap) {
121 125
      return operator=<VectorMap>(cmap);
122 126
    }
123 127

	
124 128

	
125 129
    // \brief Template assign operator.
126 130
    //
127
    // The given parameter should be conform to the ReadMap
131
    // The given parameter should conform to the ReadMap
128 132
    // concecpt and could be indiced by the current item set of
129 133
    // the NodeMap. In this case the value for each item
130 134
    // is assigned by the value of the given ReadMap.
131 135
    template <typename CMap>
132 136
    VectorMap& operator=(const CMap& cmap) {
133 137
      checkConcept<concepts::ReadMap<Key, _Value>, CMap>();
134 138
      const typename Parent::Notifier* nf = Parent::notifier();
135 139
      Item it;
136 140
      for (nf->first(it); it != INVALID; nf->next(it)) {
137 141
        set(it, cmap[it]);
138 142
      }
139 143
      return *this;
140 144
    }
141 145

	
142 146
  public:
143 147

	
144 148
    // \brief The subcript operator.
145 149
    //
146 150
    // The subscript operator. The map can be subscripted by the
147 151
    // actual items of the graph.
148 152
    Reference operator[](const Key& key) {
149 153
      return container[Parent::notifier()->id(key)];
150 154
    }
151 155

	
152 156
    // \brief The const subcript operator.
153 157
    //
154 158
    // The const subscript operator. The map can be subscripted by the
155 159
    // actual items of the graph.
156 160
    ConstReference operator[](const Key& key) const {
157 161
      return container[Parent::notifier()->id(key)];
158 162
    }
159 163

	
160 164

	
161 165
    // \brief The setter function of the map.
162 166
    //
163 167
    // It the same as operator[](key) = value expression.
164 168
    void set(const Key& key, const Value& value) {
165 169
      (*this)[key] = value;
166 170
    }
167 171

	
168 172
  protected:
169 173

	
170 174
    // \brief Adds a new key to the map.
171 175
    //
172
    // It adds a new key to the map. It called by the observer notifier
176
    // It adds a new key to the map. It is called by the observer notifier
173 177
    // and it overrides the add() member function of the observer base.
174 178
    virtual void add(const Key& key) {
175 179
      int id = Parent::notifier()->id(key);
176 180
      if (id >= int(container.size())) {
177 181
        container.resize(id + 1);
178 182
      }
179 183
    }
180 184

	
181 185
    // \brief Adds more new keys to the map.
182 186
    //
183
    // It adds more new keys to the map. It called by the observer notifier
187
    // It adds more new keys to the map. It is called by the observer notifier
184 188
    // and it overrides the add() member function of the observer base.
185 189
    virtual void add(const std::vector<Key>& keys) {
186 190
      int max = container.size() - 1;
187 191
      for (int i = 0; i < int(keys.size()); ++i) {
188 192
        int id = Parent::notifier()->id(keys[i]);
189 193
        if (id >= max) {
190 194
          max = id;
191 195
        }
192 196
      }
193 197
      container.resize(max + 1);
194 198
    }
195 199

	
196 200
    // \brief Erase a key from the map.
197 201
    //
198
    // Erase a key from the map. It called by the observer notifier
202
    // Erase a key from the map. It is called by the observer notifier
199 203
    // and it overrides the erase() member function of the observer base.
200 204
    virtual void erase(const Key& key) {
201 205
      container[Parent::notifier()->id(key)] = Value();
202 206
    }
203 207

	
204 208
    // \brief Erase more keys from the map.
205 209
    //
206
    // Erase more keys from the map. It called by the observer notifier
210
    // It erases more keys from the map. It is called by the observer notifier
207 211
    // and it overrides the erase() member function of the observer base.
208 212
    virtual void erase(const std::vector<Key>& keys) {
209 213
      for (int i = 0; i < int(keys.size()); ++i) {
210 214
        container[Parent::notifier()->id(keys[i])] = Value();
211 215
      }
212 216
    }
213 217

	
214
    // \brief Buildes the map.
218
    // \brief Build the map.
215 219
    //
216
    // It buildes the map. It called by the observer notifier
220
    // It builds the map. It is called by the observer notifier
217 221
    // and it overrides the build() member function of the observer base.
218 222
    virtual void build() {
219 223
      int size = Parent::notifier()->maxId() + 1;
220 224
      container.reserve(size);
221 225
      container.resize(size);
222 226
    }
223 227

	
224 228
    // \brief Clear the map.
225 229
    //
226
    // It erase all items from the map. It called by the observer notifier
230
    // It erases all items from the map. It is called by the observer notifier
227 231
    // and it overrides the clear() member function of the observer base.
228 232
    virtual void clear() {
229 233
      container.clear();
230 234
    }
231 235

	
232 236
  private:
233 237

	
234 238
    Container container;
235 239

	
236 240
  };
237 241

	
238 242
}
239 243

	
240 244
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
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
#ifndef LEMON_WINDOWS_H
20
#define LEMON_WINDOWS_H
19
#ifndef LEMON_BITS_WINDOWS_H
20
#define LEMON_BITS_WINDOWS_H
21 21

	
22 22
#include <string>
23 23

	
24 24
namespace lemon {
25 25
  namespace bits {
26 26
    void getWinProcTimes(double &rtime,
27 27
                         double &utime, double &stime,
28 28
                         double &cutime, double &cstime);
29 29
    std::string getWinFormattedDate();
30 30
    int getWinRndSeed();
31 31
  }
32 32
}
33 33

	
34 34
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
///\file
20 20
///\brief Color constants
21 21

	
22 22
#include<lemon/color.h>
23 23

	
24 24
namespace lemon {
25 25

	
26 26
  const Color WHITE(1,1,1);
27 27

	
28 28
  const Color BLACK(0,0,0);
29 29
  const Color RED(1,0,0);
30 30
  const Color GREEN(0,1,0);
31 31
  const Color BLUE(0,0,1);
32 32
  const Color YELLOW(1,1,0);
33 33
  const Color MAGENTA(1,0,1);
34 34
  const Color CYAN(0,1,1);
35 35

	
36 36
  const Color GREY(0,0,0);
37 37
  const Color DARK_RED(.5,0,0);
38 38
  const Color DARK_GREEN(0,.5,0);
39 39
  const Color DARK_BLUE(0,0,.5);
40 40
  const Color DARK_YELLOW(.5,.5,0);
41 41
  const Color DARK_MAGENTA(.5,0,.5);
42 42
  const Color DARK_CYAN(0,.5,.5);
43 43

	
44 44
} //namespace lemon
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_COLOR_H
20 20
#define LEMON_COLOR_H
21 21

	
22 22
#include<vector>
23 23
#include<lemon/math.h>
24 24
#include<lemon/maps.h>
25 25

	
26 26

	
27 27
///\ingroup misc
28 28
///\file
29 29
///\brief Tools to manage RGB colors.
30 30

	
31 31
namespace lemon {
32 32

	
33 33

	
34 34
  /// \addtogroup misc
35 35
  /// @{
36 36

	
37 37
  ///Data structure representing RGB colors.
38 38

	
39 39
  ///Data structure representing RGB colors.
40 40
  class Color
41 41
  {
42 42
    double _r,_g,_b;
43 43
  public:
44 44
    ///Default constructor
45 45
    Color() {}
46 46
    ///Constructor
47 47
    Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
48 48
    ///Set the red component
49 49
    double & red() {return _r;}
50 50
    ///Return the red component
51 51
    const double & red() const {return _r;}
52 52
    ///Set the green component
53 53
    double & green() {return _g;}
54 54
    ///Return the green component
55 55
    const double & green() const {return _g;}
56 56
    ///Set the blue component
57 57
    double & blue() {return _b;}
58 58
    ///Return the blue component
59 59
    const double & blue() const {return _b;}
60 60
    ///Set the color components
61 61
    void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
62 62
  };
63 63

	
64 64
  /// White color constant
65 65
  extern const Color WHITE;
66 66
  /// Black color constant
67 67
  extern const Color BLACK;
68 68
  /// Red color constant
69 69
  extern const Color RED;
70 70
  /// Green color constant
71 71
  extern const Color GREEN;
72 72
  /// Blue color constant
73 73
  extern const Color BLUE;
74 74
  /// Yellow color constant
75 75
  extern const Color YELLOW;
76 76
  /// Magenta color constant
77 77
  extern const Color MAGENTA;
78 78
  /// Cyan color constant
79 79
  extern const Color CYAN;
80 80
  /// Grey color constant
81 81
  extern const Color GREY;
82 82
  /// Dark red color constant
83 83
  extern const Color DARK_RED;
84 84
  /// Dark green color constant
85 85
  extern const Color DARK_GREEN;
86 86
  /// Drak blue color constant
87 87
  extern const Color DARK_BLUE;
88 88
  /// Dark yellow color constant
89 89
  extern const Color DARK_YELLOW;
90 90
  /// Dark magenta color constant
91 91
  extern const Color DARK_MAGENTA;
92 92
  /// Dark cyan color constant
93 93
  extern const Color DARK_CYAN;
94 94

	
95 95
  ///Map <tt>int</tt>s to different <tt>Color</tt>s
96 96

	
97 97
  ///This map assigns one of the predefined \ref Color "Color"s to
98 98
  ///each <tt>int</tt>. It is possible to change the colors as well as
99 99
  ///their number. The integer range is cyclically mapped to the
100 100
  ///provided set of colors.
101 101
  ///
102 102
  ///This is a true \ref concepts::ReferenceMap "reference map", so
103 103
  ///you can also change the actual colors.
104 104

	
105 105
  class Palette : public MapBase<int,Color>
106 106
  {
107 107
    std::vector<Color> colors;
108 108
  public:
109 109
    ///Constructor
110 110

	
111 111
    ///Constructor.
112 112
    ///\param have_white Indicates whether white is among the
113 113
    ///provided initial colors (\c true) or not (\c false). If it is true,
114 114
    ///white will be assigned to \c 0.
115 115
    ///\param num The number of the allocated colors. If it is \c -1,
116 116
    ///the default color configuration is set up (26 color plus optionaly the
117 117
    ///white).  If \c num is less then 26/27 then the default color
118 118
    ///list is cut. Otherwise the color list is filled repeatedly with
119 119
    ///the default color list.  (The colors can be changed later on.)
120 120
    Palette(bool have_white=false,int num=-1)
121 121
    {
122 122
      if (num==0) return;
123 123
      do {
124 124
        if(have_white) colors.push_back(Color(1,1,1));
125 125

	
126 126
        colors.push_back(Color(0,0,0));
127 127
        colors.push_back(Color(1,0,0));
128 128
        colors.push_back(Color(0,1,0));
129 129
        colors.push_back(Color(0,0,1));
130 130
        colors.push_back(Color(1,1,0));
131 131
        colors.push_back(Color(1,0,1));
132 132
        colors.push_back(Color(0,1,1));
133 133

	
134 134
        colors.push_back(Color(.5,0,0));
135 135
        colors.push_back(Color(0,.5,0));
136 136
        colors.push_back(Color(0,0,.5));
137 137
        colors.push_back(Color(.5,.5,0));
138 138
        colors.push_back(Color(.5,0,.5));
139 139
        colors.push_back(Color(0,.5,.5));
140 140

	
141 141
        colors.push_back(Color(.5,.5,.5));
142 142
        colors.push_back(Color(1,.5,.5));
143 143
        colors.push_back(Color(.5,1,.5));
144 144
        colors.push_back(Color(.5,.5,1));
145 145
        colors.push_back(Color(1,1,.5));
146 146
        colors.push_back(Color(1,.5,1));
147 147
        colors.push_back(Color(.5,1,1));
148 148

	
149 149
        colors.push_back(Color(1,.5,0));
150 150
        colors.push_back(Color(.5,1,0));
151 151
        colors.push_back(Color(1,0,.5));
152 152
        colors.push_back(Color(0,1,.5));
153 153
        colors.push_back(Color(0,.5,1));
154 154
        colors.push_back(Color(.5,0,1));
155 155
      } while(int(colors.size())<num);
156 156
      if(num>=0) colors.resize(num);
157 157
    }
158 158
    ///\e
159 159
    Color &operator[](int i)
160 160
    {
161 161
      return colors[i%colors.size()];
162 162
    }
163 163
    ///\e
164 164
    const Color &operator[](int i) const
165 165
    {
166 166
      return colors[i%colors.size()];
167 167
    }
168 168
    ///\e
169 169
    void set(int i,const Color &c)
170 170
    {
171 171
      colors[i%colors.size()]=c;
172 172
    }
173 173
    ///Adds a new color to the end of the color list.
174 174
    void add(const Color &c)
175 175
    {
176 176
      colors.push_back(c);
177 177
    }
178 178

	
179 179
    ///Sets the number of the existing colors.
180 180
    void resize(int s) { colors.resize(s);}
181 181
    ///Returns the number of the existing colors.
182 182
    int size() const { return int(colors.size());}
183 183
  };
184 184

	
185 185
  ///Returns a visibly distinct \ref Color
186 186

	
187 187
  ///Returns a \ref Color which is as different from the given parameter
188 188
  ///as it is possible.
189 189
  inline Color distantColor(const Color &c)
190 190
  {
191 191
    return Color(c.red()<.5?1:0,c.green()<.5?1:0,c.blue()<.5?1:0);
192 192
  }
193 193
  ///Returns black for light colors and white for the dark ones.
194 194

	
195 195
  ///Returns black for light colors and white for the dark ones.
196 196
  inline Color distantBW(const Color &c){
197 197
    return (.2125*c.red()+.7154*c.green()+.0721*c.blue())<.5 ? WHITE : BLACK;
198 198
  }
199 199

	
200 200
  /// @}
201 201

	
202 202
} //END OF NAMESPACE LEMON
203 203

	
204 204
#endif // LEMON_COLOR_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
// The contents of this file was inspired by the concept checking
20 20
// utility of the BOOST library (http://www.boost.org).
21 21

	
22 22
///\file
23 23
///\brief Basic utilities for concept checking.
24 24
///
25 25

	
26 26
#ifndef LEMON_CONCEPT_CHECK_H
27 27
#define LEMON_CONCEPT_CHECK_H
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  /*
32 32
    "inline" is used for ignore_unused_variable_warning()
33 33
    and function_requires() to make sure there is no
34 34
    overtarget with g++.
35 35
  */
36 36

	
37 37
  template <class T> inline void ignore_unused_variable_warning(const T&) { }
38 38

	
39 39
  ///\e
40 40
  template <class Concept>
41 41
  inline void function_requires()
42 42
  {
43 43
#if !defined(NDEBUG)
44 44
    void (Concept::*x)() = & Concept::constraints;
45 45
    ignore_unused_variable_warning(x);
46 46
#endif
47 47
  }
48 48

	
49 49
  ///\e
50 50
  template <typename Concept, typename Type>
51 51
  inline void checkConcept() {
52 52
#if !defined(NDEBUG)
53 53
    typedef typename Concept::template Constraints<Type> ConceptCheck;
54 54
    void (ConceptCheck::*x)() = & ConceptCheck::constraints;
55 55
    ignore_unused_variable_warning(x);
56 56
#endif
57 57
  }
58 58

	
59 59
} // namespace lemon
60 60

	
61 61
#endif // LEMON_CONCEPT_CHECK_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
#ifndef LEMON_CONCEPT_DIGRAPH_H
20
#define LEMON_CONCEPT_DIGRAPH_H
19
#ifndef LEMON_CONCEPTS_DIGRAPH_H
20
#define LEMON_CONCEPTS_DIGRAPH_H
21 21

	
22 22
///\ingroup graph_concepts
23 23
///\file
24 24
///\brief The concept of directed graphs.
25 25

	
26 26
#include <lemon/core.h>
27 27
#include <lemon/concepts/maps.h>
28 28
#include <lemon/concept_check.h>
29 29
#include <lemon/concepts/graph_components.h>
30 30

	
31 31
namespace lemon {
32 32
  namespace concepts {
33 33

	
34 34
    /// \ingroup graph_concepts
35 35
    ///
36 36
    /// \brief Class describing the concept of directed graphs.
37 37
    ///
38 38
    /// This class describes the \ref concept "concept" of the
39 39
    /// immutable directed digraphs.
40 40
    ///
41 41
    /// Note that actual digraph implementation like @ref ListDigraph or
42 42
    /// @ref SmartDigraph may have several additional functionality.
43 43
    ///
44 44
    /// \sa concept
45 45
    class Digraph {
46 46
    private:
47 47
      ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
48 48

	
49 49
      ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
50 50
      ///
51 51
      Digraph(const Digraph &) {};
52 52
      ///\brief Assignment of \ref Digraph "Digraph"s to another ones are
53 53
      ///\e not allowed. Use DigraphCopy() instead.
54 54

	
55 55
      ///Assignment of \ref Digraph "Digraph"s to another ones are
56 56
      ///\e not allowed.  Use DigraphCopy() instead.
57 57

	
58 58
      void operator=(const Digraph &) {}
59 59
    public:
60 60
      ///\e
61 61

	
62 62
      /// Defalult constructor.
63 63

	
64 64
      /// Defalult constructor.
65 65
      ///
66 66
      Digraph() { }
67 67
      /// Class for identifying a node of the digraph
68 68

	
69 69
      /// This class identifies a node of the digraph. It also serves
70 70
      /// as a base class of the node iterators,
71 71
      /// thus they will convert to this type.
72 72
      class Node {
73 73
      public:
74 74
        /// Default constructor
75 75

	
76 76
        /// @warning The default constructor sets the iterator
77 77
        /// to an undefined value.
78 78
        Node() { }
79 79
        /// Copy constructor.
80 80

	
81 81
        /// Copy constructor.
82 82
        ///
83 83
        Node(const Node&) { }
84 84

	
85 85
        /// Invalid constructor \& conversion.
86 86

	
87 87
        /// This constructor initializes the iterator to be invalid.
88 88
        /// \sa Invalid for more details.
89 89
        Node(Invalid) { }
90 90
        /// Equality operator
91 91

	
92 92
        /// Two iterators are equal if and only if they point to the
93 93
        /// same object or both are invalid.
94 94
        bool operator==(Node) const { return true; }
95 95

	
96 96
        /// Inequality operator
97 97

	
98 98
        /// \sa operator==(Node n)
99 99
        ///
100 100
        bool operator!=(Node) const { return true; }
101 101

	
102 102
        /// Artificial ordering operator.
103 103

	
104 104
        /// To allow the use of digraph descriptors as key type in std::map or
105 105
        /// similar associative container we require this.
106 106
        ///
107 107
        /// \note This operator only have to define some strict ordering of
108 108
        /// the items; this order has nothing to do with the iteration
109 109
        /// ordering of the items.
110 110
        bool operator<(Node) const { return false; }
111 111

	
112 112
      };
113 113

	
114 114
      /// This iterator goes through each node.
115 115

	
116 116
      /// This iterator goes through each node.
117 117
      /// Its usage is quite simple, for example you can count the number
118 118
      /// of nodes in digraph \c g of type \c Digraph like this:
119 119
      ///\code
120 120
      /// int count=0;
121 121
      /// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count;
122 122
      ///\endcode
123 123
      class NodeIt : public Node {
124 124
      public:
125 125
        /// Default constructor
126 126

	
127 127
        /// @warning The default constructor sets the iterator
128 128
        /// to an undefined value.
129 129
        NodeIt() { }
130 130
        /// Copy constructor.
131 131

	
132 132
        /// Copy constructor.
133 133
        ///
134 134
        NodeIt(const NodeIt& n) : Node(n) { }
135 135
        /// Invalid constructor \& conversion.
136 136

	
137 137
        /// Initialize the iterator to be invalid.
138 138
        /// \sa Invalid for more details.
139 139
        NodeIt(Invalid) { }
140 140
        /// Sets the iterator to the first node.
141 141

	
142 142
        /// Sets the iterator to the first node of \c g.
143 143
        ///
144 144
        NodeIt(const Digraph&) { }
145 145
        /// Node -> NodeIt conversion.
146 146

	
147 147
        /// Sets the iterator to the node of \c the digraph pointed by
148 148
        /// the trivial iterator.
149 149
        /// This feature necessitates that each time we
150 150
        /// iterate the arc-set, the iteration order is the same.
151 151
        NodeIt(const Digraph&, const Node&) { }
152 152
        /// Next node.
153 153

	
154 154
        /// Assign the iterator to the next node.
155 155
        ///
156 156
        NodeIt& operator++() { return *this; }
157 157
      };
158 158

	
159 159

	
160 160
      /// Class for identifying an arc of the digraph
161 161

	
162 162
      /// This class identifies an arc of the digraph. It also serves
163 163
      /// as a base class of the arc iterators,
164 164
      /// thus they will convert to this type.
165 165
      class Arc {
166 166
      public:
167 167
        /// Default constructor
168 168

	
169 169
        /// @warning The default constructor sets the iterator
170 170
        /// to an undefined value.
171 171
        Arc() { }
172 172
        /// Copy constructor.
173 173

	
174 174
        /// Copy constructor.
175 175
        ///
176 176
        Arc(const Arc&) { }
177 177
        /// Initialize the iterator to be invalid.
178 178

	
179 179
        /// Initialize the iterator to be invalid.
180 180
        ///
181 181
        Arc(Invalid) { }
182 182
        /// Equality operator
183 183

	
184 184
        /// Two iterators are equal if and only if they point to the
185 185
        /// same object or both are invalid.
186 186
        bool operator==(Arc) const { return true; }
187 187
        /// Inequality operator
188 188

	
189 189
        /// \sa operator==(Arc n)
190 190
        ///
191 191
        bool operator!=(Arc) const { return true; }
192 192

	
193 193
        /// Artificial ordering operator.
194 194

	
195 195
        /// To allow the use of digraph descriptors as key type in std::map or
196 196
        /// similar associative container we require this.
197 197
        ///
198 198
        /// \note This operator only have to define some strict ordering of
199 199
        /// the items; this order has nothing to do with the iteration
200 200
        /// ordering of the items.
201 201
        bool operator<(Arc) const { return false; }
202 202
      };
203 203

	
204 204
      /// This iterator goes trough the outgoing arcs of a node.
205 205

	
206 206
      /// This iterator goes trough the \e outgoing arcs of a certain node
207 207
      /// of a digraph.
208 208
      /// Its usage is quite simple, for example you can count the number
209 209
      /// of outgoing arcs of a node \c n
210 210
      /// in digraph \c g of type \c Digraph as follows.
211 211
      ///\code
212 212
      /// int count=0;
213 213
      /// for (Digraph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
214 214
      ///\endcode
215 215

	
216 216
      class OutArcIt : public Arc {
217 217
      public:
218 218
        /// Default constructor
219 219

	
220 220
        /// @warning The default constructor sets the iterator
221 221
        /// to an undefined value.
222 222
        OutArcIt() { }
223 223
        /// Copy constructor.
224 224

	
225 225
        /// Copy constructor.
226 226
        ///
227 227
        OutArcIt(const OutArcIt& e) : Arc(e) { }
228 228
        /// Initialize the iterator to be invalid.
229 229

	
230 230
        /// Initialize the iterator to be invalid.
231 231
        ///
232 232
        OutArcIt(Invalid) { }
233 233
        /// This constructor sets the iterator to the first outgoing arc.
234 234

	
235 235
        /// This constructor sets the iterator to the first outgoing arc of
236 236
        /// the node.
237 237
        OutArcIt(const Digraph&, const Node&) { }
238 238
        /// Arc -> OutArcIt conversion
239 239

	
240 240
        /// Sets the iterator to the value of the trivial iterator.
241 241
        /// This feature necessitates that each time we
242 242
        /// iterate the arc-set, the iteration order is the same.
243 243
        OutArcIt(const Digraph&, const Arc&) { }
244 244
        ///Next outgoing arc
245 245

	
246 246
        /// Assign the iterator to the next
247 247
        /// outgoing arc of the corresponding node.
248 248
        OutArcIt& operator++() { return *this; }
249 249
      };
250 250

	
251 251
      /// This iterator goes trough the incoming arcs of a node.
252 252

	
253 253
      /// This iterator goes trough the \e incoming arcs of a certain node
254 254
      /// of a digraph.
255 255
      /// Its usage is quite simple, for example you can count the number
256 256
      /// of outgoing arcs of a node \c n
257 257
      /// in digraph \c g of type \c Digraph as follows.
258 258
      ///\code
259 259
      /// int count=0;
260 260
      /// for(Digraph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
261 261
      ///\endcode
262 262

	
263 263
      class InArcIt : public Arc {
264 264
      public:
265 265
        /// Default constructor
266 266

	
267 267
        /// @warning The default constructor sets the iterator
268 268
        /// to an undefined value.
269 269
        InArcIt() { }
270 270
        /// Copy constructor.
271 271

	
272 272
        /// Copy constructor.
273 273
        ///
274 274
        InArcIt(const InArcIt& e) : Arc(e) { }
275 275
        /// Initialize the iterator to be invalid.
276 276

	
277 277
        /// Initialize the iterator to be invalid.
278 278
        ///
279 279
        InArcIt(Invalid) { }
280 280
        /// This constructor sets the iterator to first incoming arc.
281 281

	
282 282
        /// This constructor set the iterator to the first incoming arc of
283 283
        /// the node.
284 284
        InArcIt(const Digraph&, const Node&) { }
285 285
        /// Arc -> InArcIt conversion
286 286

	
287 287
        /// Sets the iterator to the value of the trivial iterator \c e.
288 288
        /// This feature necessitates that each time we
289 289
        /// iterate the arc-set, the iteration order is the same.
290 290
        InArcIt(const Digraph&, const Arc&) { }
291 291
        /// Next incoming arc
292 292

	
293 293
        /// Assign the iterator to the next inarc of the corresponding node.
294 294
        ///
295 295
        InArcIt& operator++() { return *this; }
296 296
      };
297 297
      /// This iterator goes through each arc.
298 298

	
299 299
      /// This iterator goes through each arc of a digraph.
300 300
      /// Its usage is quite simple, for example you can count the number
301 301
      /// of arcs in a digraph \c g of type \c Digraph as follows:
302 302
      ///\code
303 303
      /// int count=0;
304 304
      /// for(Digraph::ArcIt e(g); e!=INVALID; ++e) ++count;
305 305
      ///\endcode
306 306
      class ArcIt : public Arc {
307 307
      public:
308 308
        /// Default constructor
309 309

	
310 310
        /// @warning The default constructor sets the iterator
311 311
        /// to an undefined value.
312 312
        ArcIt() { }
313 313
        /// Copy constructor.
314 314

	
315 315
        /// Copy constructor.
316 316
        ///
317 317
        ArcIt(const ArcIt& e) : Arc(e) { }
318 318
        /// Initialize the iterator to be invalid.
319 319

	
320 320
        /// Initialize the iterator to be invalid.
321 321
        ///
322 322
        ArcIt(Invalid) { }
323 323
        /// This constructor sets the iterator to the first arc.
324 324

	
325 325
        /// This constructor sets the iterator to the first arc of \c g.
326 326
        ///@param g the digraph
327 327
        ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
328 328
        /// Arc -> ArcIt conversion
329 329

	
330 330
        /// Sets the iterator to the value of the trivial iterator \c e.
331 331
        /// This feature necessitates that each time we
332 332
        /// iterate the arc-set, the iteration order is the same.
333 333
        ArcIt(const Digraph&, const Arc&) { }
334 334
        ///Next arc
335 335

	
336 336
        /// Assign the iterator to the next arc.
337 337
        ArcIt& operator++() { return *this; }
338 338
      };
339 339
      ///Gives back the target node of an arc.
340 340

	
341 341
      ///Gives back the target node of an arc.
342 342
      ///
343 343
      Node target(Arc) const { return INVALID; }
344 344
      ///Gives back the source node of an arc.
345 345

	
346 346
      ///Gives back the source node of an arc.
347 347
      ///
348 348
      Node source(Arc) const { return INVALID; }
349 349

	
350 350
      /// \brief Returns the ID of the node.
351 351
      int id(Node) const { return -1; }
352 352

	
353 353
      /// \brief Returns the ID of the arc.
354 354
      int id(Arc) const { return -1; }
355 355

	
356 356
      /// \brief Returns the node with the given ID.
357 357
      ///
358 358
      /// \pre The argument should be a valid node ID in the graph.
359 359
      Node nodeFromId(int) const { return INVALID; }
360 360

	
361 361
      /// \brief Returns the arc with the given ID.
362 362
      ///
363 363
      /// \pre The argument should be a valid arc ID in the graph.
364 364
      Arc arcFromId(int) const { return INVALID; }
365 365

	
366 366
      /// \brief Returns an upper bound on the node IDs.
367 367
      int maxNodeId() const { return -1; }
368 368

	
369 369
      /// \brief Returns an upper bound on the arc IDs.
370 370
      int maxArcId() const { return -1; }
371 371

	
372 372
      void first(Node&) const {}
373 373
      void next(Node&) const {}
374 374

	
375 375
      void first(Arc&) const {}
376 376
      void next(Arc&) const {}
377 377

	
378 378

	
379 379
      void firstIn(Arc&, const Node&) const {}
380 380
      void nextIn(Arc&) const {}
381 381

	
382 382
      void firstOut(Arc&, const Node&) const {}
383 383
      void nextOut(Arc&) const {}
384 384

	
385 385
      // The second parameter is dummy.
386 386
      Node fromId(int, Node) const { return INVALID; }
387 387
      // The second parameter is dummy.
388 388
      Arc fromId(int, Arc) const { return INVALID; }
389 389

	
390 390
      // Dummy parameter.
391 391
      int maxId(Node) const { return -1; }
392 392
      // Dummy parameter.
393 393
      int maxId(Arc) const { return -1; }
394 394

	
395 395
      /// \brief The base node of the iterator.
396 396
      ///
397 397
      /// Gives back the base node of the iterator.
398 398
      /// It is always the target of the pointed arc.
399 399
      Node baseNode(const InArcIt&) const { return INVALID; }
400 400

	
401 401
      /// \brief The running node of the iterator.
402 402
      ///
403 403
      /// Gives back the running node of the iterator.
404 404
      /// It is always the source of the pointed arc.
405 405
      Node runningNode(const InArcIt&) const { return INVALID; }
406 406

	
407 407
      /// \brief The base node of the iterator.
408 408
      ///
409 409
      /// Gives back the base node of the iterator.
410 410
      /// It is always the source of the pointed arc.
411 411
      Node baseNode(const OutArcIt&) const { return INVALID; }
412 412

	
413 413
      /// \brief The running node of the iterator.
414 414
      ///
415 415
      /// Gives back the running node of the iterator.
416 416
      /// It is always the target of the pointed arc.
417 417
      Node runningNode(const OutArcIt&) const { return INVALID; }
418 418

	
419 419
      /// \brief The opposite node on the given arc.
420 420
      ///
421 421
      /// Gives back the opposite node on the given arc.
422 422
      Node oppositeNode(const Node&, const Arc&) const { return INVALID; }
423 423

	
424
      /// \brief Read write map of the nodes to type \c T.
424
      /// \brief Reference map of the nodes to type \c T.
425 425
      ///
426
      /// ReadWrite map of the nodes to type \c T.
427
      /// \sa Reference
426
      /// Reference map of the nodes to type \c T.
428 427
      template<class T>
429
      class NodeMap : public ReadWriteMap< Node, T > {
428
      class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
430 429
      public:
431 430

	
432 431
        ///\e
433 432
        NodeMap(const Digraph&) { }
434 433
        ///\e
435 434
        NodeMap(const Digraph&, T) { }
436 435

	
437 436
      private:
438 437
        ///Copy constructor
439
        NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
438
        NodeMap(const NodeMap& nm) : 
439
          ReferenceMap<Node, T, T&, const T&>(nm) { }
440 440
        ///Assignment operator
441 441
        template <typename CMap>
442 442
        NodeMap& operator=(const CMap&) {
443 443
          checkConcept<ReadMap<Node, T>, CMap>();
444 444
          return *this;
445 445
        }
446 446
      };
447 447

	
448
      /// \brief Read write map of the arcs to type \c T.
448
      /// \brief Reference map of the arcs to type \c T.
449 449
      ///
450 450
      /// Reference map of the arcs to type \c T.
451
      /// \sa Reference
452 451
      template<class T>
453
      class ArcMap : public ReadWriteMap<Arc,T> {
452
      class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
454 453
      public:
455 454

	
456 455
        ///\e
457 456
        ArcMap(const Digraph&) { }
458 457
        ///\e
459 458
        ArcMap(const Digraph&, T) { }
460 459
      private:
461 460
        ///Copy constructor
462
        ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { }
461
        ArcMap(const ArcMap& em) :
462
          ReferenceMap<Arc, T, T&, const T&>(em) { }
463 463
        ///Assignment operator
464 464
        template <typename CMap>
465 465
        ArcMap& operator=(const CMap&) {
466 466
          checkConcept<ReadMap<Arc, T>, CMap>();
467 467
          return *this;
468 468
        }
469 469
      };
470 470

	
471 471
      template <typename _Digraph>
472 472
      struct Constraints {
473 473
        void constraints() {
474
          checkConcept<BaseDigraphComponent, _Digraph>();
474 475
          checkConcept<IterableDigraphComponent<>, _Digraph>();
475 476
          checkConcept<IDableDigraphComponent<>, _Digraph>();
476 477
          checkConcept<MappableDigraphComponent<>, _Digraph>();
477 478
        }
478 479
      };
479 480

	
480 481
    };
481 482

	
482 483
  } //namespace concepts
483 484
} //namespace lemon
484 485

	
485 486

	
486 487

	
487
#endif // LEMON_CONCEPT_DIGRAPH_H
488
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
///\ingroup graph_concepts
20 20
///\file
21 21
///\brief The concept of Undirected Graphs.
22 22

	
23
#ifndef LEMON_CONCEPT_GRAPH_H
24
#define LEMON_CONCEPT_GRAPH_H
23
#ifndef LEMON_CONCEPTS_GRAPH_H
24
#define LEMON_CONCEPTS_GRAPH_H
25 25

	
26 26
#include <lemon/concepts/graph_components.h>
27
#include <lemon/concepts/graph.h>
28 27
#include <lemon/core.h>
29 28

	
30 29
namespace lemon {
31 30
  namespace concepts {
32 31

	
33 32
    /// \ingroup graph_concepts
34 33
    ///
35 34
    /// \brief Class describing the concept of Undirected Graphs.
36 35
    ///
37 36
    /// This class describes the common interface of all Undirected
38 37
    /// Graphs.
39 38
    ///
40 39
    /// As all concept describing classes it provides only interface
41 40
    /// without any sensible implementation. So any algorithm for
42 41
    /// undirected graph should compile with this class, but it will not
43 42
    /// run properly, of course.
44 43
    ///
45 44
    /// The LEMON undirected graphs also fulfill the concept of
46 45
    /// directed graphs (\ref lemon::concepts::Digraph "Digraph
47 46
    /// Concept"). Each edges can be seen as two opposite
48 47
    /// directed arc and consequently the undirected graph can be
49 48
    /// seen as the direceted graph of these directed arcs. The
50 49
    /// Graph has the Edge inner class for the edges and
51 50
    /// the Arc type for the directed arcs. The Arc type is
52 51
    /// convertible to Edge or inherited from it so from a directed
53 52
    /// arc we can get the represented edge.
54 53
    ///
55 54
    /// In the sense of the LEMON each edge has a default
56 55
    /// direction (it should be in every computer implementation,
57 56
    /// because the order of edge's nodes defines an
58 57
    /// orientation). With the default orientation we can define that
59 58
    /// the directed arc is forward or backward directed. With the \c
60 59
    /// direction() and \c direct() function we can get the direction
61 60
    /// of the directed arc and we can direct an edge.
62 61
    ///
63 62
    /// The EdgeIt is an iterator for the edges. We can use
64 63
    /// the EdgeMap to map values for the edges. The InArcIt and
65 64
    /// OutArcIt iterates on the same edges but with opposite
66 65
    /// direction. The IncEdgeIt iterates also on the same edges
67 66
    /// as the OutArcIt and InArcIt but it is not convertible to Arc just
68 67
    /// to Edge.
69 68
    class Graph {
70 69
    public:
71 70
      /// \brief The undirected graph should be tagged by the
72 71
      /// UndirectedTag.
73 72
      ///
74 73
      /// The undirected graph should be tagged by the UndirectedTag. This
75 74
      /// tag helps the enable_if technics to make compile time
76 75
      /// specializations for undirected graphs.
77 76
      typedef True UndirectedTag;
78 77

	
79 78
      /// \brief The base type of node iterators,
80 79
      /// or in other words, the trivial node iterator.
81 80
      ///
82 81
      /// This is the base type of each node iterator,
83 82
      /// thus each kind of node iterator converts to this.
84 83
      /// More precisely each kind of node iterator should be inherited
85 84
      /// from the trivial node iterator.
86 85
      class Node {
87 86
      public:
88 87
        /// Default constructor
89 88

	
90 89
        /// @warning The default constructor sets the iterator
91 90
        /// to an undefined value.
92 91
        Node() { }
93 92
        /// Copy constructor.
94 93

	
95 94
        /// Copy constructor.
96 95
        ///
97 96
        Node(const Node&) { }
98 97

	
99 98
        /// Invalid constructor \& conversion.
100 99

	
101 100
        /// This constructor initializes the iterator to be invalid.
102 101
        /// \sa Invalid for more details.
103 102
        Node(Invalid) { }
104 103
        /// Equality operator
105 104

	
106 105
        /// Two iterators are equal if and only if they point to the
107 106
        /// same object or both are invalid.
108 107
        bool operator==(Node) const { return true; }
109 108

	
110 109
        /// Inequality operator
111 110

	
112 111
        /// \sa operator==(Node n)
113 112
        ///
114 113
        bool operator!=(Node) const { return true; }
115 114

	
116 115
        /// Artificial ordering operator.
117 116

	
118 117
        /// To allow the use of graph descriptors as key type in std::map or
119 118
        /// similar associative container we require this.
120 119
        ///
121 120
        /// \note This operator only have to define some strict ordering of
122 121
        /// the items; this order has nothing to do with the iteration
123 122
        /// ordering of the items.
124 123
        bool operator<(Node) const { return false; }
125 124

	
126 125
      };
127 126

	
128 127
      /// This iterator goes through each node.
129 128

	
130 129
      /// This iterator goes through each node.
131 130
      /// Its usage is quite simple, for example you can count the number
132 131
      /// of nodes in graph \c g of type \c Graph like this:
133 132
      ///\code
134 133
      /// int count=0;
135 134
      /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
136 135
      ///\endcode
137 136
      class NodeIt : public Node {
138 137
      public:
139 138
        /// Default constructor
140 139

	
141 140
        /// @warning The default constructor sets the iterator
142 141
        /// to an undefined value.
143 142
        NodeIt() { }
144 143
        /// Copy constructor.
145 144

	
146 145
        /// Copy constructor.
147 146
        ///
148 147
        NodeIt(const NodeIt& n) : Node(n) { }
149 148
        /// Invalid constructor \& conversion.
150 149

	
151 150
        /// Initialize the iterator to be invalid.
152 151
        /// \sa Invalid for more details.
153 152
        NodeIt(Invalid) { }
154 153
        /// Sets the iterator to the first node.
155 154

	
156 155
        /// Sets the iterator to the first node of \c g.
157 156
        ///
158 157
        NodeIt(const Graph&) { }
159 158
        /// Node -> NodeIt conversion.
160 159

	
161 160
        /// Sets the iterator to the node of \c the graph pointed by
162 161
        /// the trivial iterator.
163 162
        /// This feature necessitates that each time we
164 163
        /// iterate the arc-set, the iteration order is the same.
165 164
        NodeIt(const Graph&, const Node&) { }
166 165
        /// Next node.
167 166

	
168 167
        /// Assign the iterator to the next node.
169 168
        ///
170 169
        NodeIt& operator++() { return *this; }
171 170
      };
172 171

	
173 172

	
174 173
      /// The base type of the edge iterators.
175 174

	
176 175
      /// The base type of the edge iterators.
177 176
      ///
178 177
      class Edge {
179 178
      public:
180 179
        /// Default constructor
181 180

	
182 181
        /// @warning The default constructor sets the iterator
183 182
        /// to an undefined value.
184 183
        Edge() { }
185 184
        /// Copy constructor.
186 185

	
187 186
        /// Copy constructor.
188 187
        ///
189 188
        Edge(const Edge&) { }
190 189
        /// Initialize the iterator to be invalid.
191 190

	
192 191
        /// Initialize the iterator to be invalid.
193 192
        ///
194 193
        Edge(Invalid) { }
195 194
        /// Equality operator
196 195

	
197 196
        /// Two iterators are equal if and only if they point to the
198 197
        /// same object or both are invalid.
199 198
        bool operator==(Edge) const { return true; }
200 199
        /// Inequality operator
201 200

	
202 201
        /// \sa operator==(Edge n)
203 202
        ///
204 203
        bool operator!=(Edge) const { return true; }
205 204

	
206 205
        /// Artificial ordering operator.
207 206

	
208 207
        /// To allow the use of graph descriptors as key type in std::map or
209 208
        /// similar associative container we require this.
210 209
        ///
211 210
        /// \note This operator only have to define some strict ordering of
212 211
        /// the items; this order has nothing to do with the iteration
213 212
        /// ordering of the items.
214 213
        bool operator<(Edge) const { return false; }
215 214
      };
216 215

	
217 216
      /// This iterator goes through each edge.
218 217

	
219 218
      /// This iterator goes through each edge of a graph.
220 219
      /// Its usage is quite simple, for example you can count the number
221 220
      /// of edges in a graph \c g of type \c Graph as follows:
222 221
      ///\code
223 222
      /// int count=0;
224 223
      /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
225 224
      ///\endcode
226 225
      class EdgeIt : public Edge {
227 226
      public:
228 227
        /// Default constructor
229 228

	
230 229
        /// @warning The default constructor sets the iterator
231 230
        /// to an undefined value.
232 231
        EdgeIt() { }
233 232
        /// Copy constructor.
234 233

	
235 234
        /// Copy constructor.
236 235
        ///
237 236
        EdgeIt(const EdgeIt& e) : Edge(e) { }
238 237
        /// Initialize the iterator to be invalid.
239 238

	
240 239
        /// Initialize the iterator to be invalid.
241 240
        ///
242 241
        EdgeIt(Invalid) { }
243 242
        /// This constructor sets the iterator to the first edge.
244 243

	
245 244
        /// This constructor sets the iterator to the first edge.
246 245
        EdgeIt(const Graph&) { }
247 246
        /// Edge -> EdgeIt conversion
248 247

	
249 248
        /// Sets the iterator to the value of the trivial iterator.
250 249
        /// This feature necessitates that each time we
251 250
        /// iterate the edge-set, the iteration order is the
252 251
        /// same.
253 252
        EdgeIt(const Graph&, const Edge&) { }
254 253
        /// Next edge
255 254

	
256 255
        /// Assign the iterator to the next edge.
257 256
        EdgeIt& operator++() { return *this; }
258 257
      };
259 258

	
260 259
      /// \brief This iterator goes trough the incident undirected
261 260
      /// arcs of a node.
262 261
      ///
263 262
      /// This iterator goes trough the incident edges
264 263
      /// of a certain node of a graph. You should assume that the
265 264
      /// loop arcs will be iterated twice.
266 265
      ///
267 266
      /// Its usage is quite simple, for example you can compute the
268 267
      /// degree (i.e. count the number of incident arcs of a node \c n
269 268
      /// in graph \c g of type \c Graph as follows.
270 269
      ///
271 270
      ///\code
272 271
      /// int count=0;
273 272
      /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
274 273
      ///\endcode
275 274
      class IncEdgeIt : public Edge {
276 275
      public:
277 276
        /// Default constructor
278 277

	
279 278
        /// @warning The default constructor sets the iterator
280 279
        /// to an undefined value.
281 280
        IncEdgeIt() { }
282 281
        /// Copy constructor.
283 282

	
284 283
        /// Copy constructor.
285 284
        ///
286 285
        IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
287 286
        /// Initialize the iterator to be invalid.
288 287

	
289 288
        /// Initialize the iterator to be invalid.
290 289
        ///
291 290
        IncEdgeIt(Invalid) { }
292 291
        /// This constructor sets the iterator to first incident arc.
293 292

	
294 293
        /// This constructor set the iterator to the first incident arc of
295 294
        /// the node.
296 295
        IncEdgeIt(const Graph&, const Node&) { }
297 296
        /// Edge -> IncEdgeIt conversion
298 297

	
299 298
        /// Sets the iterator to the value of the trivial iterator \c e.
300 299
        /// This feature necessitates that each time we
301 300
        /// iterate the arc-set, the iteration order is the same.
302 301
        IncEdgeIt(const Graph&, const Edge&) { }
303 302
        /// Next incident arc
304 303

	
305 304
        /// Assign the iterator to the next incident arc
306 305
        /// of the corresponding node.
307 306
        IncEdgeIt& operator++() { return *this; }
308 307
      };
309 308

	
310 309
      /// The directed arc type.
311 310

	
312 311
      /// The directed arc type. It can be converted to the
313 312
      /// edge or it should be inherited from the undirected
314
      /// arc.
315
      class Arc : public Edge {
313
      /// edge.
314
      class Arc {
316 315
      public:
317 316
        /// Default constructor
318 317

	
319 318
        /// @warning The default constructor sets the iterator
320 319
        /// to an undefined value.
321 320
        Arc() { }
322 321
        /// Copy constructor.
323 322

	
324 323
        /// Copy constructor.
325 324
        ///
326
        Arc(const Arc& e) : Edge(e) { }
325
        Arc(const Arc&) { }
327 326
        /// Initialize the iterator to be invalid.
328 327

	
329 328
        /// Initialize the iterator to be invalid.
330 329
        ///
331 330
        Arc(Invalid) { }
332 331
        /// Equality operator
333 332

	
334 333
        /// Two iterators are equal if and only if they point to the
335 334
        /// same object or both are invalid.
336 335
        bool operator==(Arc) const { return true; }
337 336
        /// Inequality operator
338 337

	
339 338
        /// \sa operator==(Arc n)
340 339
        ///
341 340
        bool operator!=(Arc) const { return true; }
342 341

	
343 342
        /// Artificial ordering operator.
344 343

	
345 344
        /// To allow the use of graph descriptors as key type in std::map or
346 345
        /// similar associative container we require this.
347 346
        ///
348 347
        /// \note This operator only have to define some strict ordering of
349 348
        /// the items; this order has nothing to do with the iteration
350 349
        /// ordering of the items.
351 350
        bool operator<(Arc) const { return false; }
352 351

	
352
        /// Converison to Edge
353
        operator Edge() const { return Edge(); }
353 354
      };
354 355
      /// This iterator goes through each directed arc.
355 356

	
356 357
      /// This iterator goes through each arc of a graph.
357 358
      /// Its usage is quite simple, for example you can count the number
358 359
      /// of arcs in a graph \c g of type \c Graph as follows:
359 360
      ///\code
360 361
      /// int count=0;
361 362
      /// for(Graph::ArcIt e(g); e!=INVALID; ++e) ++count;
362 363
      ///\endcode
363 364
      class ArcIt : public Arc {
364 365
      public:
365 366
        /// Default constructor
366 367

	
367 368
        /// @warning The default constructor sets the iterator
368 369
        /// to an undefined value.
369 370
        ArcIt() { }
370 371
        /// Copy constructor.
371 372

	
372 373
        /// Copy constructor.
373 374
        ///
374 375
        ArcIt(const ArcIt& e) : Arc(e) { }
375 376
        /// Initialize the iterator to be invalid.
376 377

	
377 378
        /// Initialize the iterator to be invalid.
378 379
        ///
379 380
        ArcIt(Invalid) { }
380 381
        /// This constructor sets the iterator to the first arc.
381 382

	
382 383
        /// This constructor sets the iterator to the first arc of \c g.
383 384
        ///@param g the graph
384 385
        ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
385 386
        /// Arc -> ArcIt conversion
386 387

	
387 388
        /// Sets the iterator to the value of the trivial iterator \c e.
388 389
        /// This feature necessitates that each time we
389 390
        /// iterate the arc-set, the iteration order is the same.
390 391
        ArcIt(const Graph&, const Arc&) { }
391 392
        ///Next arc
392 393

	
393 394
        /// Assign the iterator to the next arc.
394 395
        ArcIt& operator++() { return *this; }
395 396
      };
396 397

	
397 398
      /// This iterator goes trough the outgoing directed arcs of a node.
398 399

	
399 400
      /// This iterator goes trough the \e outgoing arcs of a certain node
400 401
      /// of a graph.
401 402
      /// Its usage is quite simple, for example you can count the number
402 403
      /// of outgoing arcs of a node \c n
403 404
      /// in graph \c g of type \c Graph as follows.
404 405
      ///\code
405 406
      /// int count=0;
406 407
      /// for (Graph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
407 408
      ///\endcode
408 409

	
409 410
      class OutArcIt : public Arc {
410 411
      public:
411 412
        /// Default constructor
412 413

	
413 414
        /// @warning The default constructor sets the iterator
414 415
        /// to an undefined value.
415 416
        OutArcIt() { }
416 417
        /// Copy constructor.
417 418

	
418 419
        /// Copy constructor.
419 420
        ///
420 421
        OutArcIt(const OutArcIt& e) : Arc(e) { }
421 422
        /// Initialize the iterator to be invalid.
422 423

	
423 424
        /// Initialize the iterator to be invalid.
424 425
        ///
425 426
        OutArcIt(Invalid) { }
426 427
        /// This constructor sets the iterator to the first outgoing arc.
427 428

	
428 429
        /// This constructor sets the iterator to the first outgoing arc of
429 430
        /// the node.
430 431
        ///@param n the node
431 432
        ///@param g the graph
432 433
        OutArcIt(const Graph& n, const Node& g) {
433 434
          ignore_unused_variable_warning(n);
434 435
          ignore_unused_variable_warning(g);
435 436
        }
436 437
        /// Arc -> OutArcIt conversion
437 438

	
438 439
        /// Sets the iterator to the value of the trivial iterator.
439 440
        /// This feature necessitates that each time we
440 441
        /// iterate the arc-set, the iteration order is the same.
441 442
        OutArcIt(const Graph&, const Arc&) { }
442 443
        ///Next outgoing arc
443 444

	
444 445
        /// Assign the iterator to the next
445 446
        /// outgoing arc of the corresponding node.
446 447
        OutArcIt& operator++() { return *this; }
447 448
      };
448 449

	
449 450
      /// This iterator goes trough the incoming directed arcs of a node.
450 451

	
451 452
      /// This iterator goes trough the \e incoming arcs of a certain node
452 453
      /// of a graph.
453 454
      /// Its usage is quite simple, for example you can count the number
454 455
      /// of outgoing arcs of a node \c n
455 456
      /// in graph \c g of type \c Graph as follows.
456 457
      ///\code
457 458
      /// int count=0;
458 459
      /// for(Graph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
459 460
      ///\endcode
460 461

	
461 462
      class InArcIt : public Arc {
462 463
      public:
463 464
        /// Default constructor
464 465

	
465 466
        /// @warning The default constructor sets the iterator
466 467
        /// to an undefined value.
467 468
        InArcIt() { }
468 469
        /// Copy constructor.
469 470

	
470 471
        /// Copy constructor.
471 472
        ///
472 473
        InArcIt(const InArcIt& e) : Arc(e) { }
473 474
        /// Initialize the iterator to be invalid.
474 475

	
475 476
        /// Initialize the iterator to be invalid.
476 477
        ///
477 478
        InArcIt(Invalid) { }
478 479
        /// This constructor sets the iterator to first incoming arc.
479 480

	
480 481
        /// This constructor set the iterator to the first incoming arc of
481 482
        /// the node.
482 483
        ///@param n the node
483 484
        ///@param g the graph
484 485
        InArcIt(const Graph& g, const Node& n) {
485 486
          ignore_unused_variable_warning(n);
486 487
          ignore_unused_variable_warning(g);
487 488
        }
488 489
        /// Arc -> InArcIt conversion
489 490

	
490 491
        /// Sets the iterator to the value of the trivial iterator \c e.
491 492
        /// This feature necessitates that each time we
492 493
        /// iterate the arc-set, the iteration order is the same.
493 494
        InArcIt(const Graph&, const Arc&) { }
494 495
        /// Next incoming arc
495 496

	
496 497
        /// Assign the iterator to the next inarc of the corresponding node.
497 498
        ///
498 499
        InArcIt& operator++() { return *this; }
499 500
      };
500 501

	
501
      /// \brief Read write map of the nodes to type \c T.
502
      /// \brief Reference map of the nodes to type \c T.
502 503
      ///
503
      /// ReadWrite map of the nodes to type \c T.
504
      /// \sa Reference
504
      /// Reference map of the nodes to type \c T.
505 505
      template<class T>
506
      class NodeMap : public ReadWriteMap< Node, T >
506
      class NodeMap : public ReferenceMap<Node, T, T&, const T&>
507 507
      {
508 508
      public:
509 509

	
510 510
        ///\e
511 511
        NodeMap(const Graph&) { }
512 512
        ///\e
513 513
        NodeMap(const Graph&, T) { }
514 514

	
515 515
      private:
516 516
        ///Copy constructor
517
        NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
517
        NodeMap(const NodeMap& nm) :
518
          ReferenceMap<Node, T, T&, const T&>(nm) { }
518 519
        ///Assignment operator
519 520
        template <typename CMap>
520 521
        NodeMap& operator=(const CMap&) {
521 522
          checkConcept<ReadMap<Node, T>, CMap>();
522 523
          return *this;
523 524
        }
524 525
      };
525 526

	
526
      /// \brief Read write map of the directed arcs to type \c T.
527
      /// \brief Reference map of the arcs to type \c T.
527 528
      ///
528
      /// Reference map of the directed arcs to type \c T.
529
      /// \sa Reference
529
      /// Reference map of the arcs to type \c T.
530 530
      template<class T>
531
      class ArcMap : public ReadWriteMap<Arc,T>
531
      class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
532 532
      {
533 533
      public:
534 534

	
535 535
        ///\e
536 536
        ArcMap(const Graph&) { }
537 537
        ///\e
538 538
        ArcMap(const Graph&, T) { }
539 539
      private:
540 540
        ///Copy constructor
541
        ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { }
541
        ArcMap(const ArcMap& em) :
542
          ReferenceMap<Arc, T, T&, const T&>(em) { }
542 543
        ///Assignment operator
543 544
        template <typename CMap>
544 545
        ArcMap& operator=(const CMap&) {
545 546
          checkConcept<ReadMap<Arc, T>, CMap>();
546 547
          return *this;
547 548
        }
548 549
      };
549 550

	
550
      /// Read write map of the edges to type \c T.
551
      /// Reference map of the edges to type \c T.
551 552

	
552
      /// Reference map of the arcs to type \c T.
553
      /// \sa Reference
553
      /// Reference map of the edges to type \c T.
554 554
      template<class T>
555
      class EdgeMap : public ReadWriteMap<Edge,T>
555
      class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
556 556
      {
557 557
      public:
558 558

	
559 559
        ///\e
560 560
        EdgeMap(const Graph&) { }
561 561
        ///\e
562 562
        EdgeMap(const Graph&, T) { }
563 563
      private:
564 564
        ///Copy constructor
565
        EdgeMap(const EdgeMap& em) : ReadWriteMap<Edge,T>(em) {}
565
        EdgeMap(const EdgeMap& em) :
566
          ReferenceMap<Edge, T, T&, const T&>(em) {}
566 567
        ///Assignment operator
567 568
        template <typename CMap>
568 569
        EdgeMap& operator=(const CMap&) {
569 570
          checkConcept<ReadMap<Edge, T>, CMap>();
570 571
          return *this;
571 572
        }
572 573
      };
573 574

	
574 575
      /// \brief Direct the given edge.
575 576
      ///
576 577
      /// Direct the given edge. The returned arc source
577 578
      /// will be the given node.
578 579
      Arc direct(const Edge&, const Node&) const {
579 580
        return INVALID;
580 581
      }
581 582

	
582 583
      /// \brief Direct the given edge.
583 584
      ///
584 585
      /// Direct the given edge. The returned arc
585 586
      /// represents the given edge and the direction comes
586 587
      /// from the bool parameter. The source of the edge and
587 588
      /// the directed arc is the same when the given bool is true.
588 589
      Arc direct(const Edge&, bool) const {
589 590
        return INVALID;
590 591
      }
591 592

	
592 593
      /// \brief Returns true if the arc has default orientation.
593 594
      ///
594 595
      /// Returns whether the given directed arc is same orientation as
595 596
      /// the corresponding edge's default orientation.
596 597
      bool direction(Arc) const { return true; }
597 598

	
598 599
      /// \brief Returns the opposite directed arc.
599 600
      ///
600 601
      /// Returns the opposite directed arc.
601 602
      Arc oppositeArc(Arc) const { return INVALID; }
602 603

	
603 604
      /// \brief Opposite node on an arc
604 605
      ///
605
      /// \return the opposite of the given Node on the given Edge
606
      /// \return The opposite of the given node on the given edge.
606 607
      Node oppositeNode(Node, Edge) const { return INVALID; }
607 608

	
608 609
      /// \brief First node of the edge.
609 610
      ///
610
      /// \return the first node of the given Edge.
611
      /// \return The first node of the given edge.
611 612
      ///
612 613
      /// Naturally edges don't have direction and thus
613
      /// don't have source and target node. But we use these two methods
614
      /// to query the two nodes of the arc. The direction of the arc
615
      /// which arises this way is called the inherent direction of the
614
      /// don't have source and target node. However we use \c u() and \c v()
615
      /// methods to query the two nodes of the arc. The direction of the
616
      /// arc which arises this way is called the inherent direction of the
616 617
      /// edge, and is used to define the "default" direction
617 618
      /// of the directed versions of the arcs.
618
      /// \sa direction
619
      /// \sa v()
620
      /// \sa direction()
619 621
      Node u(Edge) const { return INVALID; }
620 622

	
621 623
      /// \brief Second node of the edge.
624
      ///
625
      /// \return The second node of the given edge.
626
      ///
627
      /// Naturally edges don't have direction and thus
628
      /// don't have source and target node. However we use \c u() and \c v()
629
      /// methods to query the two nodes of the arc. The direction of the
630
      /// arc which arises this way is called the inherent direction of the
631
      /// edge, and is used to define the "default" direction
632
      /// of the directed versions of the arcs.
633
      /// \sa u()
634
      /// \sa direction()
622 635
      Node v(Edge) const { return INVALID; }
623 636

	
624 637
      /// \brief Source node of the directed arc.
625 638
      Node source(Arc) const { return INVALID; }
626 639

	
627 640
      /// \brief Target node of the directed arc.
628 641
      Node target(Arc) const { return INVALID; }
629 642

	
630 643
      /// \brief Returns the id of the node.
631 644
      int id(Node) const { return -1; }
632 645

	
633 646
      /// \brief Returns the id of the edge.
634 647
      int id(Edge) const { return -1; }
635 648

	
636 649
      /// \brief Returns the id of the arc.
637 650
      int id(Arc) const { return -1; }
638 651

	
639 652
      /// \brief Returns the node with the given id.
640 653
      ///
641 654
      /// \pre The argument should be a valid node id in the graph.
642 655
      Node nodeFromId(int) const { return INVALID; }
643 656

	
644 657
      /// \brief Returns the edge with the given id.
645 658
      ///
646 659
      /// \pre The argument should be a valid edge id in the graph.
647 660
      Edge edgeFromId(int) const { return INVALID; }
648 661

	
649 662
      /// \brief Returns the arc with the given id.
650 663
      ///
651 664
      /// \pre The argument should be a valid arc id in the graph.
652 665
      Arc arcFromId(int) const { return INVALID; }
653 666

	
654 667
      /// \brief Returns an upper bound on the node IDs.
655 668
      int maxNodeId() const { return -1; }
656 669

	
657 670
      /// \brief Returns an upper bound on the edge IDs.
658 671
      int maxEdgeId() const { return -1; }
659 672

	
660 673
      /// \brief Returns an upper bound on the arc IDs.
661 674
      int maxArcId() const { return -1; }
662 675

	
663 676
      void first(Node&) const {}
664 677
      void next(Node&) const {}
665 678

	
666 679
      void first(Edge&) const {}
667 680
      void next(Edge&) const {}
668 681

	
669 682
      void first(Arc&) const {}
670 683
      void next(Arc&) const {}
671 684

	
672 685
      void firstOut(Arc&, Node) const {}
673 686
      void nextOut(Arc&) const {}
674 687

	
675 688
      void firstIn(Arc&, Node) const {}
676 689
      void nextIn(Arc&) const {}
677 690

	
678 691
      void firstInc(Edge &, bool &, const Node &) const {}
679 692
      void nextInc(Edge &, bool &) const {}
680 693

	
681 694
      // The second parameter is dummy.
682 695
      Node fromId(int, Node) const { return INVALID; }
683 696
      // The second parameter is dummy.
684 697
      Edge fromId(int, Edge) const { return INVALID; }
685 698
      // The second parameter is dummy.
686 699
      Arc fromId(int, Arc) const { return INVALID; }
687 700

	
688 701
      // Dummy parameter.
689 702
      int maxId(Node) const { return -1; }
690 703
      // Dummy parameter.
691 704
      int maxId(Edge) const { return -1; }
692 705
      // Dummy parameter.
693 706
      int maxId(Arc) const { return -1; }
694 707

	
695 708
      /// \brief Base node of the iterator
696 709
      ///
697 710
      /// Returns the base node (the source in this case) of the iterator
698 711
      Node baseNode(OutArcIt e) const {
699 712
        return source(e);
700 713
      }
701 714
      /// \brief Running node of the iterator
702 715
      ///
703 716
      /// Returns the running node (the target in this case) of the
704 717
      /// iterator
705 718
      Node runningNode(OutArcIt e) const {
706 719
        return target(e);
707 720
      }
708 721

	
709 722
      /// \brief Base node of the iterator
710 723
      ///
711 724
      /// Returns the base node (the target in this case) of the iterator
712 725
      Node baseNode(InArcIt e) const {
713 726
        return target(e);
714 727
      }
715 728
      /// \brief Running node of the iterator
716 729
      ///
717 730
      /// Returns the running node (the source in this case) of the
718 731
      /// iterator
719 732
      Node runningNode(InArcIt e) const {
720 733
        return source(e);
721 734
      }
722 735

	
723 736
      /// \brief Base node of the iterator
724 737
      ///
725 738
      /// Returns the base node of the iterator
726 739
      Node baseNode(IncEdgeIt) const {
727 740
        return INVALID;
728 741
      }
729 742

	
730 743
      /// \brief Running node of the iterator
731 744
      ///
732 745
      /// Returns the running node of the iterator
733 746
      Node runningNode(IncEdgeIt) const {
734 747
        return INVALID;
735 748
      }
736 749

	
737 750
      template <typename _Graph>
738 751
      struct Constraints {
739 752
        void constraints() {
753
          checkConcept<BaseGraphComponent, _Graph>();
740 754
          checkConcept<IterableGraphComponent<>, _Graph>();
741 755
          checkConcept<IDableGraphComponent<>, _Graph>();
742 756
          checkConcept<MappableGraphComponent<>, _Graph>();
743 757
        }
744 758
      };
745 759

	
746 760
    };
747 761

	
748 762
  }
749 763

	
750 764
}
751 765

	
752 766
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
///\ingroup graph_concepts
20 20
///\file
21 21
///\brief The concept of graph components.
22 22

	
23

	
24
#ifndef LEMON_CONCEPT_GRAPH_COMPONENTS_H
25
#define LEMON_CONCEPT_GRAPH_COMPONENTS_H
23
#ifndef LEMON_CONCEPTS_GRAPH_COMPONENTS_H
24
#define LEMON_CONCEPTS_GRAPH_COMPONENTS_H
26 25

	
27 26
#include <lemon/core.h>
28 27
#include <lemon/concepts/maps.h>
29 28

	
30 29
#include <lemon/bits/alteration_notifier.h>
31 30

	
32 31
namespace lemon {
33 32
  namespace concepts {
34 33

	
35
    /// \brief Skeleton class for graph Node and Arc types
34
    /// \brief Concept class for \c Node, \c Arc and \c Edge types.
36 35
    ///
37
    /// This class describes the interface of Node and Arc (and Edge
38
    /// in undirected graphs) subtypes of graph types.
36
    /// This class describes the concept of \c Node, \c Arc and \c Edge
37
    /// subtypes of digraph and graph types.
39 38
    ///
40 39
    /// \note This class is a template class so that we can use it to
41
    /// create graph skeleton classes. The reason for this is than Node
42
    /// and Arc types should \em not derive from the same base class.
43
    /// For Node you should instantiate it with character 'n' and for Arc
44
    /// with 'a'.
45

	
40
    /// create graph skeleton classes. The reason for this is that \c Node
41
    /// and \c Arc (or \c Edge) types should \e not derive from the same 
42
    /// base class. For \c Node you should instantiate it with character
43
    /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'.
46 44
#ifndef DOXYGEN
47
    template <char _selector = '0'>
45
    template <char sel = '0'>
48 46
#endif
49 47
    class GraphItem {
50 48
    public:
51 49
      /// \brief Default constructor.
52 50
      ///
51
      /// Default constructor.
53 52
      /// \warning The default constructor is not required to set
54 53
      /// the item to some well-defined value. So you should consider it
55 54
      /// as uninitialized.
56 55
      GraphItem() {}
56

	
57 57
      /// \brief Copy constructor.
58 58
      ///
59 59
      /// Copy constructor.
60
      GraphItem(const GraphItem &) {}
61

	
62
      /// \brief Constructor for conversion from \c INVALID.
60 63
      ///
61
      GraphItem(const GraphItem &) {}
62
      /// \brief Invalid constructor \& conversion.
63
      ///
64
      /// This constructor initializes the item to be invalid.
64
      /// Constructor for conversion from \c INVALID.
65
      /// It initializes the item to be invalid.
65 66
      /// \sa Invalid for more details.
66 67
      GraphItem(Invalid) {}
67
      /// \brief Assign operator for nodes.
68

	
69
      /// \brief Assignment operator.
68 70
      ///
69
      /// The nodes are assignable.
71
      /// Assignment operator for the item.
72
      GraphItem& operator=(const GraphItem&) { return *this; }
73

	
74
      /// \brief Assignment operator for INVALID.
70 75
      ///
71
      GraphItem& operator=(GraphItem const&) { return *this; }
76
      /// This operator makes the item invalid.
77
      GraphItem& operator=(Invalid) { return *this; }
78

	
72 79
      /// \brief Equality operator.
73 80
      ///
74
      /// Two iterators are equal if and only if they represents the
75
      /// same node in the graph or both are invalid.
76
      bool operator==(GraphItem) const { return false; }
81
      /// Equality operator.
82
      bool operator==(const GraphItem&) const { return false; }
83

	
77 84
      /// \brief Inequality operator.
78 85
      ///
79
      /// \sa operator==(const Node& n)
86
      /// Inequality operator.
87
      bool operator!=(const GraphItem&) const { return false; }
88

	
89
      /// \brief Ordering operator.
80 90
      ///
81
      bool operator!=(GraphItem) const { return false; }
82

	
83
      /// \brief Artificial ordering operator.
84
      ///
85
      /// To allow the use of graph descriptors as key type in std::map or
86
      /// similar associative container we require this.
91
      /// This operator defines an ordering of the items.
92
      /// It makes possible to use graph item types as key types in 
93
      /// associative containers (e.g. \c std::map).
87 94
      ///
88 95
      /// \note This operator only have to define some strict ordering of
89 96
      /// the items; this order has nothing to do with the iteration
90 97
      /// ordering of the items.
91
      bool operator<(GraphItem) const { return false; }
98
      bool operator<(const GraphItem&) const { return false; }
92 99

	
93 100
      template<typename _GraphItem>
94 101
      struct Constraints {
95 102
        void constraints() {
96 103
          _GraphItem i1;
104
          i1=INVALID;
97 105
          _GraphItem i2 = i1;
98 106
          _GraphItem i3 = INVALID;
99 107

	
100 108
          i1 = i2 = i3;
101 109

	
102 110
          bool b;
103
          //          b = (ia == ib) && (ia != ib) && (ia < ib);
104 111
          b = (ia == ib) && (ia != ib);
105 112
          b = (ia == INVALID) && (ib != INVALID);
106 113
          b = (ia < ib);
107 114
        }
108 115

	
109 116
        const _GraphItem &ia;
110 117
        const _GraphItem &ib;
111 118
      };
112 119
    };
113 120

	
114
    /// \brief An empty base directed graph class.
121
    /// \brief Base skeleton class for directed graphs.
115 122
    ///
116
    /// This class provides the minimal set of features needed for a
117
    /// directed graph structure. All digraph concepts have to be
118
    /// conform to this base directed graph. It just provides types
119
    /// for nodes and arcs and functions to get the source and the
120
    /// target of the arcs.
123
    /// This class describes the base interface of directed graph types.
124
    /// All digraph %concepts have to conform to this class.
125
    /// It just provides types for nodes and arcs and functions 
126
    /// to get the source and the target nodes of arcs.
121 127
    class BaseDigraphComponent {
122 128
    public:
123 129

	
124 130
      typedef BaseDigraphComponent Digraph;
125 131

	
126 132
      /// \brief Node class of the digraph.
127 133
      ///
128
      /// This class represents the Nodes of the digraph.
129
      ///
134
      /// This class represents the nodes of the digraph.
130 135
      typedef GraphItem<'n'> Node;
131 136

	
132 137
      /// \brief Arc class of the digraph.
133 138
      ///
134
      /// This class represents the Arcs of the digraph.
139
      /// This class represents the arcs of the digraph.
140
      typedef GraphItem<'a'> Arc;
141

	
142
      /// \brief Return the source node of an arc.
135 143
      ///
136
      typedef GraphItem<'e'> Arc;
144
      /// This function returns the source node of an arc.
145
      Node source(const Arc&) const { return INVALID; }
137 146

	
138
      /// \brief Gives back the target node of an arc.
147
      /// \brief Return the target node of an arc.
139 148
      ///
140
      /// Gives back the target node of an arc.
149
      /// This function returns the target node of an arc.
150
      Node target(const Arc&) const { return INVALID; }
151

	
152
      /// \brief Return the opposite node on the given arc.
141 153
      ///
142
      Node target(const Arc&) const { return INVALID;}
143

	
144
      /// \brief Gives back the source node of an arc.
145
      ///
146
      /// Gives back the source node of an arc.
147
      ///
148
      Node source(const Arc&) const { return INVALID;}
149

	
150
      /// \brief Gives back the opposite node on the given arc.
151
      ///
152
      /// Gives back the opposite node on the given arc.
154
      /// This function returns the opposite node on the given arc.
153 155
      Node oppositeNode(const Node&, const Arc&) const {
154 156
        return INVALID;
155 157
      }
156 158

	
157 159
      template <typename _Digraph>
158 160
      struct Constraints {
159 161
        typedef typename _Digraph::Node Node;
160 162
        typedef typename _Digraph::Arc Arc;
161 163

	
162 164
        void constraints() {
163 165
          checkConcept<GraphItem<'n'>, Node>();
164 166
          checkConcept<GraphItem<'a'>, Arc>();
165 167
          {
166 168
            Node n;
167 169
            Arc e(INVALID);
168 170
            n = digraph.source(e);
169 171
            n = digraph.target(e);
170 172
            n = digraph.oppositeNode(n, e);
171 173
          }
172 174
        }
173 175

	
174 176
        const _Digraph& digraph;
175 177
      };
176 178
    };
177 179

	
178
    /// \brief An empty base undirected graph class.
180
    /// \brief Base skeleton class for undirected graphs.
179 181
    ///
180
    /// This class provides the minimal set of features needed for an
181
    /// undirected graph structure. All undirected graph concepts have
182
    /// to be conform to this base graph. It just provides types for
183
    /// nodes, arcs and edges and functions to get the
184
    /// source and the target of the arcs and edges,
185
    /// conversion from arcs to edges and function to get
186
    /// both direction of the edges.
182
    /// This class describes the base interface of undirected graph types.
183
    /// All graph %concepts have to conform to this class.
184
    /// It extends the interface of \ref BaseDigraphComponent with an
185
    /// \c Edge type and functions to get the end nodes of edges,
186
    /// to convert from arcs to edges and to get both direction of edges.
187 187
    class BaseGraphComponent : public BaseDigraphComponent {
188 188
    public:
189

	
190
      typedef BaseGraphComponent Graph;
191

	
189 192
      typedef BaseDigraphComponent::Node Node;
190 193
      typedef BaseDigraphComponent::Arc Arc;
191
      /// \brief Undirected arc class of the graph.
194

	
195
      /// \brief Undirected edge class of the graph.
192 196
      ///
193
      /// This class represents the edges of the graph.
194
      /// The undirected graphs can be used as a directed graph which
195
      /// for each arc contains the opposite arc too so the graph is
196
      /// bidirected. The edge represents two opposite
197
      /// directed arcs.
198
      class Edge : public GraphItem<'u'> {
197
      /// This class represents the undirected edges of the graph.
198
      /// Undirected graphs can be used as directed graphs, each edge is
199
      /// represented by two opposite directed arcs.
200
      class Edge : public GraphItem<'e'> {
201
        typedef GraphItem<'e'> Parent;
202

	
199 203
      public:
200
        typedef GraphItem<'u'> Parent;
201 204
        /// \brief Default constructor.
202 205
        ///
206
        /// Default constructor.
203 207
        /// \warning The default constructor is not required to set
204 208
        /// the item to some well-defined value. So you should consider it
205 209
        /// as uninitialized.
206 210
        Edge() {}
211

	
207 212
        /// \brief Copy constructor.
208 213
        ///
209 214
        /// Copy constructor.
215
        Edge(const Edge &) : Parent() {}
216

	
217
        /// \brief Constructor for conversion from \c INVALID.
210 218
        ///
211
        Edge(const Edge &) : Parent() {}
212
        /// \brief Invalid constructor \& conversion.
213
        ///
214
        /// This constructor initializes the item to be invalid.
219
        /// Constructor for conversion from \c INVALID.
220
        /// It initializes the item to be invalid.
215 221
        /// \sa Invalid for more details.
216 222
        Edge(Invalid) {}
217
        /// \brief Converter from arc to edge.
223

	
224
        /// \brief Constructor for conversion from an arc.
218 225
        ///
226
        /// Constructor for conversion from an arc.
219 227
        /// Besides the core graph item functionality each arc should
220 228
        /// be convertible to the represented edge.
221 229
        Edge(const Arc&) {}
222
        /// \brief Assign arc to edge.
223
        ///
224
        /// Besides the core graph item functionality each arc should
225
        /// be convertible to the represented edge.
226
        Edge& operator=(const Arc&) { return *this; }
227
      };
230
     };
228 231

	
229
      /// \brief Returns the direction of the arc.
232
      /// \brief Return one end node of an edge.
233
      ///
234
      /// This function returns one end node of an edge.
235
      Node u(const Edge&) const { return INVALID; }
236

	
237
      /// \brief Return the other end node of an edge.
238
      ///
239
      /// This function returns the other end node of an edge.
240
      Node v(const Edge&) const { return INVALID; }
241

	
242
      /// \brief Return a directed arc related to an edge.
243
      ///
244
      /// This function returns a directed arc from its direction and the
245
      /// represented edge.
246
      Arc direct(const Edge&, bool) const { return INVALID; }
247

	
248
      /// \brief Return a directed arc related to an edge.
249
      ///
250
      /// This function returns a directed arc from its source node and the
251
      /// represented edge.
252
      Arc direct(const Edge&, const Node&) const { return INVALID; }
253

	
254
      /// \brief Return the direction of the arc.
230 255
      ///
231 256
      /// Returns the direction of the arc. Each arc represents an
232 257
      /// edge with a direction. It gives back the
233 258
      /// direction.
234 259
      bool direction(const Arc&) const { return true; }
235 260

	
236
      /// \brief Returns the directed arc.
261
      /// \brief Return the opposite arc.
237 262
      ///
238
      /// Returns the directed arc from its direction and the
239
      /// represented edge.
240
      Arc direct(const Edge&, bool) const { return INVALID;}
241

	
242
      /// \brief Returns the directed arc.
243
      ///
244
      /// Returns the directed arc from its source and the
245
      /// represented edge.
246
      Arc direct(const Edge&, const Node&) const { return INVALID;}
247

	
248
      /// \brief Returns the opposite arc.
249
      ///
250
      /// Returns the opposite arc. It is the arc representing the
251
      /// same edge and has opposite direction.
252
      Arc oppositeArc(const Arc&) const { return INVALID;}
253

	
254
      /// \brief Gives back one ending of an edge.
255
      ///
256
      /// Gives back one ending of an edge.
257
      Node u(const Edge&) const { return INVALID;}
258

	
259
      /// \brief Gives back the other ending of an edge.
260
      ///
261
      /// Gives back the other ending of an edge.
262
      Node v(const Edge&) const { return INVALID;}
263
      /// This function returns the opposite arc, i.e. the arc representing
264
      /// the same edge and has opposite direction.
265
      Arc oppositeArc(const Arc&) const { return INVALID; }
263 266

	
264 267
      template <typename _Graph>
265 268
      struct Constraints {
266 269
        typedef typename _Graph::Node Node;
267 270
        typedef typename _Graph::Arc Arc;
268 271
        typedef typename _Graph::Edge Edge;
269 272

	
270 273
        void constraints() {
271 274
          checkConcept<BaseDigraphComponent, _Graph>();
272
          checkConcept<GraphItem<'u'>, Edge>();
275
          checkConcept<GraphItem<'e'>, Edge>();
273 276
          {
274 277
            Node n;
275 278
            Edge ue(INVALID);
276 279
            Arc e;
277 280
            n = graph.u(ue);
278 281
            n = graph.v(ue);
279 282
            e = graph.direct(ue, true);
283
            e = graph.direct(ue, false);
280 284
            e = graph.direct(ue, n);
281 285
            e = graph.oppositeArc(e);
282 286
            ue = e;
283 287
            bool d = graph.direction(e);
284 288
            ignore_unused_variable_warning(d);
285 289
          }
286 290
        }
287 291

	
288 292
        const _Graph& graph;
289 293
      };
290 294

	
291 295
    };
292 296

	
293
    /// \brief An empty idable base digraph class.
297
    /// \brief Skeleton class for \e idable directed graphs.
294 298
    ///
295
    /// This class provides beside the core digraph features
296
    /// core id functions for the digraph structure.
297
    /// The most of the base digraphs should be conform to this concept.
298
    /// The id's are unique and immutable.
299
    template <typename _Base = BaseDigraphComponent>
300
    class IDableDigraphComponent : public _Base {
299
    /// This class describes the interface of \e idable directed graphs.
300
    /// It extends \ref BaseDigraphComponent with the core ID functions.
301
    /// The ids of the items must be unique and immutable.
302
    /// This concept is part of the Digraph concept.
303
    template <typename BAS = BaseDigraphComponent>
304
    class IDableDigraphComponent : public BAS {
301 305
    public:
302 306

	
303
      typedef _Base Base;
307
      typedef BAS Base;
304 308
      typedef typename Base::Node Node;
305 309
      typedef typename Base::Arc Arc;
306 310

	
307
      /// \brief Gives back an unique integer id for the Node.
311
      /// \brief Return a unique integer id for the given node.
308 312
      ///
309
      /// Gives back an unique integer id for the Node.
313
      /// This function returns a unique integer id for the given node.
314
      int id(const Node&) const { return -1; }
315

	
316
      /// \brief Return the node by its unique id.
310 317
      ///
311
      int id(const Node&) const { return -1;}
318
      /// This function returns the node by its unique id.
319
      /// If the digraph does not contain a node with the given id,
320
      /// then the result of the function is undefined.
321
      Node nodeFromId(int) const { return INVALID; }
312 322

	
313
      /// \brief Gives back the node by the unique id.
323
      /// \brief Return a unique integer id for the given arc.
314 324
      ///
315
      /// Gives back the node by the unique id.
316
      /// If the digraph does not contain node with the given id
317
      /// then the result of the function is undetermined.
318
      Node nodeFromId(int) const { return INVALID;}
325
      /// This function returns a unique integer id for the given arc.
326
      int id(const Arc&) const { return -1; }
319 327

	
320
      /// \brief Gives back an unique integer id for the Arc.
328
      /// \brief Return the arc by its unique id.
321 329
      ///
322
      /// Gives back an unique integer id for the Arc.
330
      /// This function returns the arc by its unique id.
331
      /// If the digraph does not contain an arc with the given id,
332
      /// then the result of the function is undefined.
333
      Arc arcFromId(int) const { return INVALID; }
334

	
335
      /// \brief Return an integer greater or equal to the maximum
336
      /// node id.
323 337
      ///
324
      int id(const Arc&) const { return -1;}
338
      /// This function returns an integer greater or equal to the
339
      /// maximum node id.
340
      int maxNodeId() const { return -1; }
325 341

	
326
      /// \brief Gives back the arc by the unique id.
342
      /// \brief Return an integer greater or equal to the maximum
343
      /// arc id.
327 344
      ///
328
      /// Gives back the arc by the unique id.
329
      /// If the digraph does not contain arc with the given id
330
      /// then the result of the function is undetermined.
331
      Arc arcFromId(int) const { return INVALID;}
332

	
333
      /// \brief Gives back an integer greater or equal to the maximum
334
      /// Node id.
335
      ///
336
      /// Gives back an integer greater or equal to the maximum Node
337
      /// id.
338
      int maxNodeId() const { return -1;}
339

	
340
      /// \brief Gives back an integer greater or equal to the maximum
341
      /// Arc id.
342
      ///
343
      /// Gives back an integer greater or equal to the maximum Arc
344
      /// id.
345
      int maxArcId() const { return -1;}
345
      /// This function returns an integer greater or equal to the
346
      /// maximum arc id.
347
      int maxArcId() const { return -1; }
346 348

	
347 349
      template <typename _Digraph>
348 350
      struct Constraints {
349 351

	
350 352
        void constraints() {
351 353
          checkConcept<Base, _Digraph >();
352 354
          typename _Digraph::Node node;
355
          node=INVALID;
353 356
          int nid = digraph.id(node);
354 357
          nid = digraph.id(node);
355 358
          node = digraph.nodeFromId(nid);
356 359
          typename _Digraph::Arc arc;
360
          arc=INVALID;
357 361
          int eid = digraph.id(arc);
358 362
          eid = digraph.id(arc);
359 363
          arc = digraph.arcFromId(eid);
360 364

	
361 365
          nid = digraph.maxNodeId();
362 366
          ignore_unused_variable_warning(nid);
363 367
          eid = digraph.maxArcId();
364 368
          ignore_unused_variable_warning(eid);
365 369
        }
366 370

	
367 371
        const _Digraph& digraph;
368 372
      };
369 373
    };
370 374

	
371
    /// \brief An empty idable base undirected graph class.
375
    /// \brief Skeleton class for \e idable undirected graphs.
372 376
    ///
373
    /// This class provides beside the core undirected graph features
374
    /// core id functions for the undirected graph structure.  The
375
    /// most of the base undirected graphs should be conform to this
376
    /// concept.  The id's are unique and immutable.
377
    template <typename _Base = BaseGraphComponent>
378
    class IDableGraphComponent : public IDableDigraphComponent<_Base> {
377
    /// This class describes the interface of \e idable undirected
378
    /// graphs. It extends \ref IDableDigraphComponent with the core ID
379
    /// functions of undirected graphs.
380
    /// The ids of the items must be unique and immutable.
381
    /// This concept is part of the Graph concept.
382
    template <typename BAS = BaseGraphComponent>
383
    class IDableGraphComponent : public IDableDigraphComponent<BAS> {
379 384
    public:
380 385

	
381
      typedef _Base Base;
386
      typedef BAS Base;
382 387
      typedef typename Base::Edge Edge;
383 388

	
384
      using IDableDigraphComponent<_Base>::id;
389
      using IDableDigraphComponent<Base>::id;
385 390

	
386
      /// \brief Gives back an unique integer id for the Edge.
391
      /// \brief Return a unique integer id for the given edge.
387 392
      ///
388
      /// Gives back an unique integer id for the Edge.
393
      /// This function returns a unique integer id for the given edge.
394
      int id(const Edge&) const { return -1; }
395

	
396
      /// \brief Return the edge by its unique id.
389 397
      ///
390
      int id(const Edge&) const { return -1;}
398
      /// This function returns the edge by its unique id.
399
      /// If the graph does not contain an edge with the given id,
400
      /// then the result of the function is undefined.
401
      Edge edgeFromId(int) const { return INVALID; }
391 402

	
392
      /// \brief Gives back the edge by the unique id.
403
      /// \brief Return an integer greater or equal to the maximum
404
      /// edge id.
393 405
      ///
394
      /// Gives back the edge by the unique id.  If the
395
      /// graph does not contain arc with the given id then the
396
      /// result of the function is undetermined.
397
      Edge edgeFromId(int) const { return INVALID;}
398

	
399
      /// \brief Gives back an integer greater or equal to the maximum
400
      /// Edge id.
401
      ///
402
      /// Gives back an integer greater or equal to the maximum Edge
403
      /// id.
404
      int maxEdgeId() const { return -1;}
406
      /// This function returns an integer greater or equal to the
407
      /// maximum edge id.
408
      int maxEdgeId() const { return -1; }
405 409

	
406 410
      template <typename _Graph>
407 411
      struct Constraints {
408 412

	
409 413
        void constraints() {
410
          checkConcept<Base, _Graph >();
411 414
          checkConcept<IDableDigraphComponent<Base>, _Graph >();
412 415
          typename _Graph::Edge edge;
413 416
          int ueid = graph.id(edge);
414 417
          ueid = graph.id(edge);
415 418
          edge = graph.edgeFromId(ueid);
416 419
          ueid = graph.maxEdgeId();
417 420
          ignore_unused_variable_warning(ueid);
418 421
        }
419 422

	
420 423
        const _Graph& graph;
421 424
      };
422 425
    };
423 426

	
424
    /// \brief Skeleton class for graph NodeIt and ArcIt
427
    /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
425 428
    ///
426
    /// Skeleton class for graph NodeIt and ArcIt.
427
    ///
428
    template <typename _Graph, typename _Item>
429
    class GraphItemIt : public _Item {
429
    /// This class describes the concept of \c NodeIt, \c ArcIt and 
430
    /// \c EdgeIt subtypes of digraph and graph types.
431
    template <typename GR, typename Item>
432
    class GraphItemIt : public Item {
430 433
    public:
431 434
      /// \brief Default constructor.
432 435
      ///
433
      /// @warning The default constructor sets the iterator
434
      /// to an undefined value.
436
      /// Default constructor.
437
      /// \warning The default constructor is not required to set
438
      /// the iterator to some well-defined value. So you should consider it
439
      /// as uninitialized.
435 440
      GraphItemIt() {}
441

	
436 442
      /// \brief Copy constructor.
437 443
      ///
438 444
      /// Copy constructor.
445
      GraphItemIt(const GraphItemIt& it) : Item(it) {}
446

	
447
      /// \brief Constructor that sets the iterator to the first item.
439 448
      ///
440
      GraphItemIt(const GraphItemIt& ) {}
441
      /// \brief Sets the iterator to the first item.
449
      /// Constructor that sets the iterator to the first item.
450
      explicit GraphItemIt(const GR&) {}
451

	
452
      /// \brief Constructor for conversion from \c INVALID.
442 453
      ///
443
      /// Sets the iterator to the first item of \c the graph.
444
      ///
445
      explicit GraphItemIt(const _Graph&) {}
446
      /// \brief Invalid constructor \& conversion.
447
      ///
448
      /// This constructor initializes the item to be invalid.
454
      /// Constructor for conversion from \c INVALID.
455
      /// It initializes the iterator to be invalid.
449 456
      /// \sa Invalid for more details.
450 457
      GraphItemIt(Invalid) {}
451
      /// \brief Assign operator for items.
458

	
459
      /// \brief Assignment operator.
452 460
      ///
453
      /// The items are assignable.
461
      /// Assignment operator for the iterator.
462
      GraphItemIt& operator=(const GraphItemIt&) { return *this; }
463

	
464
      /// \brief Increment the iterator.
454 465
      ///
455
      GraphItemIt& operator=(const GraphItemIt&) { return *this; }
456
      /// \brief Next item.
457
      ///
458
      /// Assign the iterator to the next item.
459
      ///
466
      /// This operator increments the iterator, i.e. assigns it to the
467
      /// next item.
460 468
      GraphItemIt& operator++() { return *this; }
469
 
461 470
      /// \brief Equality operator
462 471
      ///
472
      /// Equality operator.
463 473
      /// Two iterators are equal if and only if they point to the
464 474
      /// same object or both are invalid.
465 475
      bool operator==(const GraphItemIt&) const { return true;}
476

	
466 477
      /// \brief Inequality operator
467 478
      ///
468
      /// \sa operator==(Node n)
469
      ///
479
      /// Inequality operator.
480
      /// Two iterators are equal if and only if they point to the
481
      /// same object or both are invalid.
470 482
      bool operator!=(const GraphItemIt&) const { return true;}
471 483

	
472 484
      template<typename _GraphItemIt>
473 485
      struct Constraints {
474 486
        void constraints() {
487
          checkConcept<GraphItem<>, _GraphItemIt>();
475 488
          _GraphItemIt it1(g);
476 489
          _GraphItemIt it2;
490
          _GraphItemIt it3 = it1;
491
          _GraphItemIt it4 = INVALID;
477 492

	
478 493
          it2 = ++it1;
479 494
          ++it2 = it1;
480 495
          ++(++it1);
481 496

	
482
          _Item bi = it1;
497
          Item bi = it1;
483 498
          bi = it2;
484 499
        }
485
        _Graph& g;
500
        const GR& g;
486 501
      };
487 502
    };
488 503

	
489
    /// \brief Skeleton class for graph InArcIt and OutArcIt
504
    /// \brief Concept class for \c InArcIt, \c OutArcIt and 
505
    /// \c IncEdgeIt types.
490 506
    ///
491
    /// \note Because InArcIt and OutArcIt may not inherit from the same
492
    /// base class, the _selector is a additional template parameter. For
493
    /// InArcIt you should instantiate it with character 'i' and for
494
    /// OutArcIt with 'o'.
495
    template <typename _Graph,
496
              typename _Item = typename _Graph::Arc,
497
              typename _Base = typename _Graph::Node,
498
              char _selector = '0'>
499
    class GraphIncIt : public _Item {
507
    /// This class describes the concept of \c InArcIt, \c OutArcIt 
508
    /// and \c IncEdgeIt subtypes of digraph and graph types.
509
    ///
510
    /// \note Since these iterator classes do not inherit from the same
511
    /// base class, there is an additional template parameter (selector)
512
    /// \c sel. For \c InArcIt you should instantiate it with character 
513
    /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'.
514
    template <typename GR,
515
              typename Item = typename GR::Arc,
516
              typename Base = typename GR::Node,
517
              char sel = '0'>
518
    class GraphIncIt : public Item {
500 519
    public:
501 520
      /// \brief Default constructor.
502 521
      ///
503
      /// @warning The default constructor sets the iterator
504
      /// to an undefined value.
522
      /// Default constructor.
523
      /// \warning The default constructor is not required to set
524
      /// the iterator to some well-defined value. So you should consider it
525
      /// as uninitialized.
505 526
      GraphIncIt() {}
527

	
506 528
      /// \brief Copy constructor.
507 529
      ///
508 530
      /// Copy constructor.
531
      GraphIncIt(const GraphIncIt& it) : Item(it) {}
532

	
533
      /// \brief Constructor that sets the iterator to the first 
534
      /// incoming or outgoing arc.
509 535
      ///
510
      GraphIncIt(GraphIncIt const& gi) : _Item(gi) {}
511
      /// \brief Sets the iterator to the first arc incoming into or outgoing
512
      /// from the node.
536
      /// Constructor that sets the iterator to the first arc 
537
      /// incoming to or outgoing from the given node.
538
      explicit GraphIncIt(const GR&, const Base&) {}
539

	
540
      /// \brief Constructor for conversion from \c INVALID.
513 541
      ///
514
      /// Sets the iterator to the first arc incoming into or outgoing
515
      /// from the node.
516
      ///
517
      explicit GraphIncIt(const _Graph&, const _Base&) {}
518
      /// \brief Invalid constructor \& conversion.
519
      ///
520
      /// This constructor initializes the item to be invalid.
542
      /// Constructor for conversion from \c INVALID.
543
      /// It initializes the iterator to be invalid.
521 544
      /// \sa Invalid for more details.
522 545
      GraphIncIt(Invalid) {}
523
      /// \brief Assign operator for iterators.
546

	
547
      /// \brief Assignment operator.
524 548
      ///
525
      /// The iterators are assignable.
549
      /// Assignment operator for the iterator.
550
      GraphIncIt& operator=(const GraphIncIt&) { return *this; }
551

	
552
      /// \brief Increment the iterator.
526 553
      ///
527
      GraphIncIt& operator=(GraphIncIt const&) { return *this; }
528
      /// \brief Next item.
529
      ///
530
      /// Assign the iterator to the next item.
531
      ///
554
      /// This operator increments the iterator, i.e. assigns it to the
555
      /// next arc incoming to or outgoing from the given node.
532 556
      GraphIncIt& operator++() { return *this; }
533 557

	
534 558
      /// \brief Equality operator
535 559
      ///
560
      /// Equality operator.
536 561
      /// Two iterators are equal if and only if they point to the
537 562
      /// same object or both are invalid.
538 563
      bool operator==(const GraphIncIt&) const { return true;}
539 564

	
540 565
      /// \brief Inequality operator
541 566
      ///
542
      /// \sa operator==(Node n)
543
      ///
567
      /// Inequality operator.
568
      /// Two iterators are equal if and only if they point to the
569
      /// same object or both are invalid.
544 570
      bool operator!=(const GraphIncIt&) const { return true;}
545 571

	
546 572
      template <typename _GraphIncIt>
547 573
      struct Constraints {
548 574
        void constraints() {
549
          checkConcept<GraphItem<_selector>, _GraphIncIt>();
575
          checkConcept<GraphItem<sel>, _GraphIncIt>();
550 576
          _GraphIncIt it1(graph, node);
551 577
          _GraphIncIt it2;
578
          _GraphIncIt it3 = it1;
579
          _GraphIncIt it4 = INVALID;
552 580

	
553 581
          it2 = ++it1;
554 582
          ++it2 = it1;
555 583
          ++(++it1);
556
          _Item e = it1;
584
          Item e = it1;
557 585
          e = it2;
558

	
559 586
        }
560

	
561
        _Item arc;
562
        _Base node;
563
        _Graph graph;
564
        _GraphIncIt it;
587
        const Base& node;
588
        const GR& graph;
565 589
      };
566 590
    };
567 591

	
568

	
569
    /// \brief An empty iterable digraph class.
592
    /// \brief Skeleton class for iterable directed graphs.
570 593
    ///
571
    /// This class provides beside the core digraph features
572
    /// iterator based iterable interface for the digraph structure.
594
    /// This class describes the interface of iterable directed
595
    /// graphs. It extends \ref BaseDigraphComponent with the core
596
    /// iterable interface.
573 597
    /// This concept is part of the Digraph concept.
574
    template <typename _Base = BaseDigraphComponent>
575
    class IterableDigraphComponent : public _Base {
598
    template <typename BAS = BaseDigraphComponent>
599
    class IterableDigraphComponent : public BAS {
576 600

	
577 601
    public:
578 602

	
579
      typedef _Base Base;
603
      typedef BAS Base;
580 604
      typedef typename Base::Node Node;
581 605
      typedef typename Base::Arc Arc;
582 606

	
583 607
      typedef IterableDigraphComponent Digraph;
584 608

	
585
      /// \name Base iteration
609
      /// \name Base Iteration
586 610
      ///
587
      /// This interface provides functions for iteration on digraph items
611
      /// This interface provides functions for iteration on digraph items.
588 612
      ///
589 613
      /// @{
590 614

	
591
      /// \brief Gives back the first node in the iterating order.
615
      /// \brief Return the first node.
592 616
      ///
593
      /// Gives back the first node in the iterating order.
594
      ///
617
      /// This function gives back the first node in the iteration order.
595 618
      void first(Node&) const {}
596 619

	
597
      /// \brief Gives back the next node in the iterating order.
620
      /// \brief Return the next node.
598 621
      ///
599
      /// Gives back the next node in the iterating order.
600
      ///
622
      /// This function gives back the next node in the iteration order.
601 623
      void next(Node&) const {}
602 624

	
603
      /// \brief Gives back the first arc in the iterating order.
625
      /// \brief Return the first arc.
604 626
      ///
605
      /// Gives back the first arc in the iterating order.
606
      ///
627
      /// This function gives back the first arc in the iteration order.
607 628
      void first(Arc&) const {}
608 629

	
609
      /// \brief Gives back the next arc in the iterating order.
630
      /// \brief Return the next arc.
610 631
      ///
611
      /// Gives back the next arc in the iterating order.
612
      ///
632
      /// This function gives back the next arc in the iteration order.
613 633
      void next(Arc&) const {}
614 634

	
615

	
616
      /// \brief Gives back the first of the arcs point to the given
617
      /// node.
635
      /// \brief Return the first arc incomming to the given node.
618 636
      ///
619
      /// Gives back the first of the arcs point to the given node.
620
      ///
637
      /// This function gives back the first arc incomming to the
638
      /// given node.
621 639
      void firstIn(Arc&, const Node&) const {}
622 640

	
623
      /// \brief Gives back the next of the arcs points to the given
624
      /// node.
641
      /// \brief Return the next arc incomming to the given node.
625 642
      ///
626
      /// Gives back the next of the arcs points to the given node.
627
      ///
643
      /// This function gives back the next arc incomming to the
644
      /// given node.
628 645
      void nextIn(Arc&) const {}
629 646

	
630
      /// \brief Gives back the first of the arcs start from the
647
      /// \brief Return the first arc outgoing form the given node.
648
      ///
649
      /// This function gives back the first arc outgoing form the
631 650
      /// given node.
632
      ///
633
      /// Gives back the first of the arcs start from the given node.
634
      ///
635 651
      void firstOut(Arc&, const Node&) const {}
636 652

	
637
      /// \brief Gives back the next of the arcs start from the given
638
      /// node.
653
      /// \brief Return the next arc outgoing form the given node.
639 654
      ///
640
      /// Gives back the next of the arcs start from the given node.
641
      ///
655
      /// This function gives back the next arc outgoing form the
656
      /// given node.
642 657
      void nextOut(Arc&) const {}
643 658

	
644 659
      /// @}
645 660

	
646
      /// \name Class based iteration
661
      /// \name Class Based Iteration
647 662
      ///
648
      /// This interface provides functions for iteration on digraph items
663
      /// This interface provides iterator classes for digraph items.
649 664
      ///
650 665
      /// @{
651 666

	
652 667
      /// \brief This iterator goes through each node.
653 668
      ///
654 669
      /// This iterator goes through each node.
655 670
      ///
656 671
      typedef GraphItemIt<Digraph, Node> NodeIt;
657 672

	
658
      /// \brief This iterator goes through each node.
673
      /// \brief This iterator goes through each arc.
659 674
      ///
660
      /// This iterator goes through each node.
675
      /// This iterator goes through each arc.
661 676
      ///
662 677
      typedef GraphItemIt<Digraph, Arc> ArcIt;
663 678

	
664 679
      /// \brief This iterator goes trough the incoming arcs of a node.
665 680
      ///
666
      /// This iterator goes trough the \e inccoming arcs of a certain node
681
      /// This iterator goes trough the \e incoming arcs of a certain node
667 682
      /// of a digraph.
668 683
      typedef GraphIncIt<Digraph, Arc, Node, 'i'> InArcIt;
669 684

	
670 685
      /// \brief This iterator goes trough the outgoing arcs of a node.
671 686
      ///
672 687
      /// This iterator goes trough the \e outgoing arcs of a certain node
673 688
      /// of a digraph.
674 689
      typedef GraphIncIt<Digraph, Arc, Node, 'o'> OutArcIt;
675 690

	
676 691
      /// \brief The base node of the iterator.
677 692
      ///
678
      /// Gives back the base node of the iterator.
679
      /// It is always the target of the pointed arc.
693
      /// This function gives back the base node of the iterator.
694
      /// It is always the target node of the pointed arc.
680 695
      Node baseNode(const InArcIt&) const { return INVALID; }
681 696

	
682 697
      /// \brief The running node of the iterator.
683 698
      ///
684
      /// Gives back the running node of the iterator.
685
      /// It is always the source of the pointed arc.
699
      /// This function gives back the running node of the iterator.
700
      /// It is always the source node of the pointed arc.
686 701
      Node runningNode(const InArcIt&) const { return INVALID; }
687 702

	
688 703
      /// \brief The base node of the iterator.
689 704
      ///
690
      /// Gives back the base node of the iterator.
691
      /// It is always the source of the pointed arc.
705
      /// This function gives back the base node of the iterator.
706
      /// It is always the source node of the pointed arc.
692 707
      Node baseNode(const OutArcIt&) const { return INVALID; }
693 708

	
694 709
      /// \brief The running node of the iterator.
695 710
      ///
696
      /// Gives back the running node of the iterator.
697
      /// It is always the target of the pointed arc.
711
      /// This function gives back the running node of the iterator.
712
      /// It is always the target node of the pointed arc.
698 713
      Node runningNode(const OutArcIt&) const { return INVALID; }
699 714

	
700 715
      /// @}
701 716

	
702 717
      template <typename _Digraph>
703 718
      struct Constraints {
704 719
        void constraints() {
705 720
          checkConcept<Base, _Digraph>();
706 721

	
707 722
          {
708 723
            typename _Digraph::Node node(INVALID);
709 724
            typename _Digraph::Arc arc(INVALID);
710 725
            {
711 726
              digraph.first(node);
712 727
              digraph.next(node);
713 728
            }
714 729
            {
715 730
              digraph.first(arc);
716 731
              digraph.next(arc);
717 732
            }
718 733
            {
719 734
              digraph.firstIn(arc, node);
720 735
              digraph.nextIn(arc);
721 736
            }
722 737
            {
723 738
              digraph.firstOut(arc, node);
724 739
              digraph.nextOut(arc);
725 740
            }
726 741
          }
727 742

	
728 743
          {
729 744
            checkConcept<GraphItemIt<_Digraph, typename _Digraph::Arc>,
730 745
              typename _Digraph::ArcIt >();
731 746
            checkConcept<GraphItemIt<_Digraph, typename _Digraph::Node>,
732 747
              typename _Digraph::NodeIt >();
733 748
            checkConcept<GraphIncIt<_Digraph, typename _Digraph::Arc,
734 749
              typename _Digraph::Node, 'i'>, typename _Digraph::InArcIt>();
735 750
            checkConcept<GraphIncIt<_Digraph, typename _Digraph::Arc,
736 751
              typename _Digraph::Node, 'o'>, typename _Digraph::OutArcIt>();
737 752

	
738 753
            typename _Digraph::Node n;
739
            typename _Digraph::InArcIt ieit(INVALID);
740
            typename _Digraph::OutArcIt oeit(INVALID);
741
            n = digraph.baseNode(ieit);
742
            n = digraph.runningNode(ieit);
743
            n = digraph.baseNode(oeit);
744
            n = digraph.runningNode(oeit);
754
            const typename _Digraph::InArcIt iait(INVALID);
755
            const typename _Digraph::OutArcIt oait(INVALID);
756
            n = digraph.baseNode(iait);
757
            n = digraph.runningNode(iait);
758
            n = digraph.baseNode(oait);
759
            n = digraph.runningNode(oait);
745 760
            ignore_unused_variable_warning(n);
746 761
          }
747 762
        }
748 763

	
749 764
        const _Digraph& digraph;
750

	
751 765
      };
752 766
    };
753 767

	
754
    /// \brief An empty iterable undirected graph class.
768
    /// \brief Skeleton class for iterable undirected graphs.
755 769
    ///
756
    /// This class provides beside the core graph features iterator
757
    /// based iterable interface for the undirected graph structure.
770
    /// This class describes the interface of iterable undirected
771
    /// graphs. It extends \ref IterableDigraphComponent with the core
772
    /// iterable interface of undirected graphs.
758 773
    /// This concept is part of the Graph concept.
759
    template <typename _Base = BaseGraphComponent>
760
    class IterableGraphComponent : public IterableDigraphComponent<_Base> {
774
    template <typename BAS = BaseGraphComponent>
775
    class IterableGraphComponent : public IterableDigraphComponent<BAS> {
761 776
    public:
762 777

	
763
      typedef _Base Base;
778
      typedef BAS Base;
764 779
      typedef typename Base::Node Node;
765 780
      typedef typename Base::Arc Arc;
766 781
      typedef typename Base::Edge Edge;
767 782

	
768 783

	
769 784
      typedef IterableGraphComponent Graph;
770 785

	
771
      /// \name Base iteration
786
      /// \name Base Iteration
772 787
      ///
773
      /// This interface provides functions for iteration on graph items
788
      /// This interface provides functions for iteration on edges.
789
      ///
774 790
      /// @{
775 791

	
776
      using IterableDigraphComponent<_Base>::first;
777
      using IterableDigraphComponent<_Base>::next;
792
      using IterableDigraphComponent<Base>::first;
793
      using IterableDigraphComponent<Base>::next;
778 794

	
779
      /// \brief Gives back the first edge in the iterating
780
      /// order.
795
      /// \brief Return the first edge.
781 796
      ///
782
      /// Gives back the first edge in the iterating order.
783
      ///
797
      /// This function gives back the first edge in the iteration order.
784 798
      void first(Edge&) const {}
785 799

	
786
      /// \brief Gives back the next edge in the iterating
787
      /// order.
800
      /// \brief Return the next edge.
788 801
      ///
789
      /// Gives back the next edge in the iterating order.
790
      ///
802
      /// This function gives back the next edge in the iteration order.
791 803
      void next(Edge&) const {}
792 804

	
793

	
794
      /// \brief Gives back the first of the edges from the
805
      /// \brief Return the first edge incident to the given node.
806
      ///
807
      /// This function gives back the first edge incident to the given 
808
      /// node. The bool parameter gives back the direction for which the
809
      /// source node of the directed arc representing the edge is the 
795 810
      /// given node.
796
      ///
797
      /// Gives back the first of the edges from the given
798
      /// node. The bool parameter gives back that direction which
799
      /// gives a good direction of the edge so the source of the
800
      /// directed arc is the given node.
801 811
      void firstInc(Edge&, bool&, const Node&) const {}
802 812

	
803 813
      /// \brief Gives back the next of the edges from the
804 814
      /// given node.
805 815
      ///
806
      /// Gives back the next of the edges from the given
807
      /// node. The bool parameter should be used as the \c firstInc()
808
      /// use it.
816
      /// This function gives back the next edge incident to the given 
817
      /// node. The bool parameter should be used as \c firstInc() use it.
809 818
      void nextInc(Edge&, bool&) const {}
810 819

	
811
      using IterableDigraphComponent<_Base>::baseNode;
812
      using IterableDigraphComponent<_Base>::runningNode;
820
      using IterableDigraphComponent<Base>::baseNode;
821
      using IterableDigraphComponent<Base>::runningNode;
813 822

	
814 823
      /// @}
815 824

	
816
      /// \name Class based iteration
825
      /// \name Class Based Iteration
817 826
      ///
818
      /// This interface provides functions for iteration on graph items
827
      /// This interface provides iterator classes for edges.
819 828
      ///
820 829
      /// @{
821 830

	
822
      /// \brief This iterator goes through each node.
831
      /// \brief This iterator goes through each edge.
823 832
      ///
824
      /// This iterator goes through each node.
833
      /// This iterator goes through each edge.
825 834
      typedef GraphItemIt<Graph, Edge> EdgeIt;
826
      /// \brief This iterator goes trough the incident arcs of a
835

	
836
      /// \brief This iterator goes trough the incident edges of a
827 837
      /// node.
828 838
      ///
829
      /// This iterator goes trough the incident arcs of a certain
839
      /// This iterator goes trough the incident edges of a certain
830 840
      /// node of a graph.
831
      typedef GraphIncIt<Graph, Edge, Node, 'u'> IncEdgeIt;
841
      typedef GraphIncIt<Graph, Edge, Node, 'e'> IncEdgeIt;
842

	
832 843
      /// \brief The base node of the iterator.
833 844
      ///
834
      /// Gives back the base node of the iterator.
845
      /// This function gives back the base node of the iterator.
835 846
      Node baseNode(const IncEdgeIt&) const { return INVALID; }
836 847

	
837 848
      /// \brief The running node of the iterator.
838 849
      ///
839
      /// Gives back the running node of the iterator.
850
      /// This function gives back the running node of the iterator.
840 851
      Node runningNode(const IncEdgeIt&) const { return INVALID; }
841 852

	
842 853
      /// @}
843 854

	
844 855
      template <typename _Graph>
845 856
      struct Constraints {
846 857
        void constraints() {
847 858
          checkConcept<IterableDigraphComponent<Base>, _Graph>();
848 859

	
849 860
          {
850 861
            typename _Graph::Node node(INVALID);
851 862
            typename _Graph::Edge edge(INVALID);
852 863
            bool dir;
853 864
            {
854 865
              graph.first(edge);
855 866
              graph.next(edge);
856 867
            }
857 868
            {
858 869
              graph.firstInc(edge, dir, node);
859 870
              graph.nextInc(edge, dir);
860 871
            }
861 872

	
862 873
          }
863 874

	
864 875
          {
865 876
            checkConcept<GraphItemIt<_Graph, typename _Graph::Edge>,
866 877
              typename _Graph::EdgeIt >();
867 878
            checkConcept<GraphIncIt<_Graph, typename _Graph::Edge,
868
              typename _Graph::Node, 'u'>, typename _Graph::IncEdgeIt>();
879
              typename _Graph::Node, 'e'>, typename _Graph::IncEdgeIt>();
869 880

	
870 881
            typename _Graph::Node n;
871
            typename _Graph::IncEdgeIt ueit(INVALID);
872
            n = graph.baseNode(ueit);
873
            n = graph.runningNode(ueit);
882
            const typename _Graph::IncEdgeIt ieit(INVALID);
883
            n = graph.baseNode(ieit);
884
            n = graph.runningNode(ieit);
874 885
          }
875 886
        }
876 887

	
877 888
        const _Graph& graph;
878

	
879 889
      };
880 890
    };
881 891

	
882
    /// \brief An empty alteration notifier digraph class.
892
    /// \brief Skeleton class for alterable directed graphs.
883 893
    ///
884
    /// This class provides beside the core digraph features alteration
885
    /// notifier interface for the digraph structure.  This implements
894
    /// This class describes the interface of alterable directed
895
    /// graphs. It extends \ref BaseDigraphComponent with the alteration
896
    /// notifier interface. It implements
886 897
    /// an observer-notifier pattern for each digraph item. More
887 898
    /// obsevers can be registered into the notifier and whenever an
888
    /// alteration occured in the digraph all the observers will
899
    /// alteration occured in the digraph all the observers will be
889 900
    /// notified about it.
890
    template <typename _Base = BaseDigraphComponent>
891
    class AlterableDigraphComponent : public _Base {
901
    template <typename BAS = BaseDigraphComponent>
902
    class AlterableDigraphComponent : public BAS {
892 903
    public:
893 904

	
894
      typedef _Base Base;
905
      typedef BAS Base;
895 906
      typedef typename Base::Node Node;
896 907
      typedef typename Base::Arc Arc;
897 908

	
898 909

	
899
      /// The node observer registry.
910
      /// Node alteration notifier class.
900 911
      typedef AlterationNotifier<AlterableDigraphComponent, Node>
901 912
      NodeNotifier;
902
      /// The arc observer registry.
913
      /// Arc alteration notifier class.
903 914
      typedef AlterationNotifier<AlterableDigraphComponent, Arc>
904 915
      ArcNotifier;
905 916

	
906
      /// \brief Gives back the node alteration notifier.
917
      /// \brief Return the node alteration notifier.
907 918
      ///
908
      /// Gives back the node alteration notifier.
919
      /// This function gives back the node alteration notifier.
909 920
      NodeNotifier& notifier(Node) const {
910
        return NodeNotifier();
921
         return NodeNotifier();
911 922
      }
912 923

	
913
      /// \brief Gives back the arc alteration notifier.
924
      /// \brief Return the arc alteration notifier.
914 925
      ///
915
      /// Gives back the arc alteration notifier.
926
      /// This function gives back the arc alteration notifier.
916 927
      ArcNotifier& notifier(Arc) const {
917 928
        return ArcNotifier();
918 929
      }
919 930

	
920 931
      template <typename _Digraph>
921 932
      struct Constraints {
922 933
        void constraints() {
923 934
          checkConcept<Base, _Digraph>();
924 935
          typename _Digraph::NodeNotifier& nn
925 936
            = digraph.notifier(typename _Digraph::Node());
926 937

	
927 938
          typename _Digraph::ArcNotifier& en
928 939
            = digraph.notifier(typename _Digraph::Arc());
929 940

	
930 941
          ignore_unused_variable_warning(nn);
931 942
          ignore_unused_variable_warning(en);
932 943
        }
933 944

	
934 945
        const _Digraph& digraph;
935

	
936 946
      };
937

	
938 947
    };
939 948

	
940
    /// \brief An empty alteration notifier undirected graph class.
949
    /// \brief Skeleton class for alterable undirected graphs.
941 950
    ///
942
    /// This class provides beside the core graph features alteration
943
    /// notifier interface for the graph structure.  This implements
944
    /// an observer-notifier pattern for each graph item. More
951
    /// This class describes the interface of alterable undirected
952
    /// graphs. It extends \ref AlterableDigraphComponent with the alteration
953
    /// notifier interface of undirected graphs. It implements
954
    /// an observer-notifier pattern for the edges. More
945 955
    /// obsevers can be registered into the notifier and whenever an
946
    /// alteration occured in the graph all the observers will
956
    /// alteration occured in the graph all the observers will be
947 957
    /// notified about it.
948
    template <typename _Base = BaseGraphComponent>
949
    class AlterableGraphComponent : public AlterableDigraphComponent<_Base> {
958
    template <typename BAS = BaseGraphComponent>
959
    class AlterableGraphComponent : public AlterableDigraphComponent<BAS> {
950 960
    public:
951 961

	
952
      typedef _Base Base;
962
      typedef BAS Base;
953 963
      typedef typename Base::Edge Edge;
954 964

	
955 965

	
956
      /// The arc observer registry.
966
      /// Edge alteration notifier class.
957 967
      typedef AlterationNotifier<AlterableGraphComponent, Edge>
958 968
      EdgeNotifier;
959 969

	
960
      /// \brief Gives back the arc alteration notifier.
970
      /// \brief Return the edge alteration notifier.
961 971
      ///
962
      /// Gives back the arc alteration notifier.
972
      /// This function gives back the edge alteration notifier.
963 973
      EdgeNotifier& notifier(Edge) const {
964 974
        return EdgeNotifier();
965 975
      }
966 976

	
967 977
      template <typename _Graph>
968 978
      struct Constraints {
969 979
        void constraints() {
970
          checkConcept<AlterableGraphComponent<Base>, _Graph>();
980
          checkConcept<AlterableDigraphComponent<Base>, _Graph>();
971 981
          typename _Graph::EdgeNotifier& uen
972 982
            = graph.notifier(typename _Graph::Edge());
973 983
          ignore_unused_variable_warning(uen);
974 984
        }
975 985

	
976 986
        const _Graph& graph;
977

	
978 987
      };
979

	
980 988
    };
981 989

	
982
    /// \brief Class describing the concept of graph maps
990
    /// \brief Concept class for standard graph maps.
983 991
    ///
984
    /// This class describes the common interface of the graph maps
985
    /// (NodeMap, ArcMap), that is maps that can be used to
986
    /// associate data to graph descriptors (nodes or arcs).
987
    template <typename _Graph, typename _Item, typename _Value>
988
    class GraphMap : public ReadWriteMap<_Item, _Value> {
992
    /// This class describes the concept of standard graph maps, i.e.
993
    /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and 
994
    /// graph types, which can be used for associating data to graph items.
995
    /// The standard graph maps must conform to the ReferenceMap concept.
996
    template <typename GR, typename K, typename V>
997
    class GraphMap : public ReferenceMap<K, V, V&, const V&> {
998
      typedef ReferenceMap<K, V, V&, const V&> Parent;
999

	
989 1000
    public:
990 1001

	
991
      typedef ReadWriteMap<_Item, _Value> Parent;
1002
      /// The key type of the map.
1003
      typedef K Key;
1004
      /// The value type of the map.
1005
      typedef V Value;
1006
      /// The reference type of the map.
1007
      typedef Value& Reference;
1008
      /// The const reference type of the map.
1009
      typedef const Value& ConstReference;
992 1010

	
993
      /// The graph type of the map.
994
      typedef _Graph Graph;
995
      /// The key type of the map.
996
      typedef _Item Key;
997
      /// The value type of the map.
998
      typedef _Value Value;
1011
      // The reference map tag.
1012
      typedef True ReferenceMapTag;
999 1013

	
1000 1014
      /// \brief Construct a new map.
1001 1015
      ///
1002 1016
      /// Construct a new map for the graph.
1003
      explicit GraphMap(const Graph&) {}
1017
      explicit GraphMap(const GR&) {}
1004 1018
      /// \brief Construct a new map with default value.
1005 1019
      ///
1006
      /// Construct a new map for the graph and initalise the values.
1007
      GraphMap(const Graph&, const Value&) {}
1020
      /// Construct a new map for the graph and initalize the values.
1021
      GraphMap(const GR&, const Value&) {}
1008 1022

	
1009 1023
    private:
1010 1024
      /// \brief Copy constructor.
1011 1025
      ///
1012 1026
      /// Copy Constructor.
1013 1027
      GraphMap(const GraphMap&) : Parent() {}
1014 1028

	
1015
      /// \brief Assign operator.
1029
      /// \brief Assignment operator.
1016 1030
      ///
1017
      /// Assign operator. It does not mofify the underlying graph,
1031
      /// Assignment operator. It does not mofify the underlying graph,
1018 1032
      /// it just iterates on the current item set and set the  map
1019 1033
      /// with the value returned by the assigned map.
1020 1034
      template <typename CMap>
1021 1035
      GraphMap& operator=(const CMap&) {
1022 1036
        checkConcept<ReadMap<Key, Value>, CMap>();
1023 1037
        return *this;
1024 1038
      }
1025 1039

	
1026 1040
    public:
1027 1041
      template<typename _Map>
1028 1042
      struct Constraints {
1029 1043
        void constraints() {
1030
          checkConcept<ReadWriteMap<Key, Value>, _Map >();
1031
          // Construction with a graph parameter
1032
          _Map a(g);
1033
          // Constructor with a graph and a default value parameter
1034
          _Map a2(g,t);
1035
          // Copy constructor.
1036
          // _Map b(c);
1044
          checkConcept
1045
            <ReferenceMap<Key, Value, Value&, const Value&>, _Map>();
1046
          _Map m1(g);
1047
          _Map m2(g,t);
1048
          
1049
          // Copy constructor
1050
          // _Map m3(m);
1037 1051

	
1052
          // Assignment operator
1038 1053
          // ReadMap<Key, Value> cmap;
1039
          // b = cmap;
1054
          // m3 = cmap;
1040 1055

	
1041
          ignore_unused_variable_warning(a);
1042
          ignore_unused_variable_warning(a2);
1043
          // ignore_unused_variable_warning(b);
1056
          ignore_unused_variable_warning(m1);
1057
          ignore_unused_variable_warning(m2);
1058
          // ignore_unused_variable_warning(m3);
1044 1059
        }
1045 1060

	
1046
        const _Map &c;
1047
        const Graph &g;
1061
        const _Map &m;
1062
        const GR &g;
1048 1063
        const typename GraphMap::Value &t;
1049 1064
      };
1050 1065

	
1051 1066
    };
1052 1067

	
1053
    /// \brief An empty mappable digraph class.
1068
    /// \brief Skeleton class for mappable directed graphs.
1054 1069
    ///
1055
    /// This class provides beside the core digraph features
1056
    /// map interface for the digraph structure.
1070
    /// This class describes the interface of mappable directed graphs.
1071
    /// It extends \ref BaseDigraphComponent with the standard digraph 
1072
    /// map classes, namely \c NodeMap and \c ArcMap.
1057 1073
    /// This concept is part of the Digraph concept.
1058
    template <typename _Base = BaseDigraphComponent>
1059
    class MappableDigraphComponent : public _Base  {
1074
    template <typename BAS = BaseDigraphComponent>
1075
    class MappableDigraphComponent : public BAS  {
1060 1076
    public:
1061 1077

	
1062
      typedef _Base Base;
1078
      typedef BAS Base;
1063 1079
      typedef typename Base::Node Node;
1064 1080
      typedef typename Base::Arc Arc;
1065 1081

	
1066 1082
      typedef MappableDigraphComponent Digraph;
1067 1083

	
1068
      /// \brief ReadWrite map of the nodes.
1084
      /// \brief Standard graph map for the nodes.
1069 1085
      ///
1070
      /// ReadWrite map of the nodes.
1071
      ///
1072
      template <typename _Value>
1073
      class NodeMap : public GraphMap<Digraph, Node, _Value> {
1086
      /// Standard graph map for the nodes.
1087
      /// It conforms to the ReferenceMap concept.
1088
      template <typename V>
1089
      class NodeMap : public GraphMap<MappableDigraphComponent, Node, V> {
1090
        typedef GraphMap<MappableDigraphComponent, Node, V> Parent;
1091

	
1074 1092
      public:
1075
        typedef GraphMap<MappableDigraphComponent, Node, _Value> Parent;
1076

	
1077 1093
        /// \brief Construct a new map.
1078 1094
        ///
1079 1095
        /// Construct a new map for the digraph.
1080 1096
        explicit NodeMap(const MappableDigraphComponent& digraph)
1081 1097
          : Parent(digraph) {}
1082 1098

	
1083 1099
        /// \brief Construct a new map with default value.
1084 1100
        ///
1085
        /// Construct a new map for the digraph and initalise the values.
1086
        NodeMap(const MappableDigraphComponent& digraph, const _Value& value)
1101
        /// Construct a new map for the digraph and initalize the values.
1102
        NodeMap(const MappableDigraphComponent& digraph, const V& value)
1087 1103
          : Parent(digraph, value) {}
1088 1104

	
1089 1105
      private:
1090 1106
        /// \brief Copy constructor.
1091 1107
        ///
1092 1108
        /// Copy Constructor.
1093 1109
        NodeMap(const NodeMap& nm) : Parent(nm) {}
1094 1110

	
1095
        /// \brief Assign operator.
1111
        /// \brief Assignment operator.
1096 1112
        ///
1097
        /// Assign operator.
1113
        /// Assignment operator.
1098 1114
        template <typename CMap>
1099 1115
        NodeMap& operator=(const CMap&) {
1100
          checkConcept<ReadMap<Node, _Value>, CMap>();
1116
          checkConcept<ReadMap<Node, V>, CMap>();
1101 1117
          return *this;
1102 1118
        }
1103 1119

	
1104 1120
      };
1105 1121

	
1106
      /// \brief ReadWrite map of the arcs.
1122
      /// \brief Standard graph map for the arcs.
1107 1123
      ///
1108
      /// ReadWrite map of the arcs.
1109
      ///
1110
      template <typename _Value>
1111
      class ArcMap : public GraphMap<Digraph, Arc, _Value> {
1124
      /// Standard graph map for the arcs.
1125
      /// It conforms to the ReferenceMap concept.
1126
      template <typename V>
1127
      class ArcMap : public GraphMap<MappableDigraphComponent, Arc, V> {
1128
        typedef GraphMap<MappableDigraphComponent, Arc, V> Parent;
1129

	
1112 1130
      public:
1113
        typedef GraphMap<MappableDigraphComponent, Arc, _Value> Parent;
1114

	
1115 1131
        /// \brief Construct a new map.
1116 1132
        ///
1117 1133
        /// Construct a new map for the digraph.
1118 1134
        explicit ArcMap(const MappableDigraphComponent& digraph)
1119 1135
          : Parent(digraph) {}
1120 1136

	
1121 1137
        /// \brief Construct a new map with default value.
1122 1138
        ///
1123
        /// Construct a new map for the digraph and initalise the values.
1124
        ArcMap(const MappableDigraphComponent& digraph, const _Value& value)
1139
        /// Construct a new map for the digraph and initalize the values.
1140
        ArcMap(const MappableDigraphComponent& digraph, const V& value)
1125 1141
          : Parent(digraph, value) {}
1126 1142

	
1127 1143
      private:
1128 1144
        /// \brief Copy constructor.
1129 1145
        ///
1130 1146
        /// Copy Constructor.
1131 1147
        ArcMap(const ArcMap& nm) : Parent(nm) {}
1132 1148

	
1133
        /// \brief Assign operator.
1149
        /// \brief Assignment operator.
1134 1150
        ///
1135
        /// Assign operator.
1151
        /// Assignment operator.
1136 1152
        template <typename CMap>
1137 1153
        ArcMap& operator=(const CMap&) {
1138
          checkConcept<ReadMap<Arc, _Value>, CMap>();
1154
          checkConcept<ReadMap<Arc, V>, CMap>();
1139 1155
          return *this;
1140 1156
        }
1141 1157

	
1142 1158
      };
1143 1159

	
1144 1160

	
1145 1161
      template <typename _Digraph>
1146 1162
      struct Constraints {
1147 1163

	
1148 1164
        struct Dummy {
1149 1165
          int value;
1150 1166
          Dummy() : value(0) {}
1151 1167
          Dummy(int _v) : value(_v) {}
1152 1168
        };
1153 1169

	
1154 1170
        void constraints() {
1155 1171
          checkConcept<Base, _Digraph>();
1156 1172
          { // int map test
1157 1173
            typedef typename _Digraph::template NodeMap<int> IntNodeMap;
1158 1174
            checkConcept<GraphMap<_Digraph, typename _Digraph::Node, int>,
1159 1175
              IntNodeMap >();
1160 1176
          } { // bool map test
1161 1177
            typedef typename _Digraph::template NodeMap<bool> BoolNodeMap;
1162 1178
            checkConcept<GraphMap<_Digraph, typename _Digraph::Node, bool>,
1163 1179
              BoolNodeMap >();
1164 1180
          } { // Dummy map test
1165 1181
            typedef typename _Digraph::template NodeMap<Dummy> DummyNodeMap;
1166 1182
            checkConcept<GraphMap<_Digraph, typename _Digraph::Node, Dummy>,
1167 1183
              DummyNodeMap >();
1168 1184
          }
1169 1185

	
1170 1186
          { // int map test
1171 1187
            typedef typename _Digraph::template ArcMap<int> IntArcMap;
1172 1188
            checkConcept<GraphMap<_Digraph, typename _Digraph::Arc, int>,
1173 1189
              IntArcMap >();
1174 1190
          } { // bool map test
1175 1191
            typedef typename _Digraph::template ArcMap<bool> BoolArcMap;
1176 1192
            checkConcept<GraphMap<_Digraph, typename _Digraph::Arc, bool>,
1177 1193
              BoolArcMap >();
1178 1194
          } { // Dummy map test
1179 1195
            typedef typename _Digraph::template ArcMap<Dummy> DummyArcMap;
1180 1196
            checkConcept<GraphMap<_Digraph, typename _Digraph::Arc, Dummy>,
1181 1197
              DummyArcMap >();
1182 1198
          }
1183 1199
        }
1184 1200

	
1185
        _Digraph& digraph;
1201
        const _Digraph& digraph;
1186 1202
      };
1187 1203
    };
1188 1204

	
1189
    /// \brief An empty mappable base bipartite graph class.
1205
    /// \brief Skeleton class for mappable undirected graphs.
1190 1206
    ///
1191
    /// This class provides beside the core graph features
1192
    /// map interface for the graph structure.
1207
    /// This class describes the interface of mappable undirected graphs.
1208
    /// It extends \ref MappableDigraphComponent with the standard graph 
1209
    /// map class for edges (\c EdgeMap).
1193 1210
    /// This concept is part of the Graph concept.
1194
    template <typename _Base = BaseGraphComponent>
1195
    class MappableGraphComponent : public MappableDigraphComponent<_Base>  {
1211
    template <typename BAS = BaseGraphComponent>
1212
    class MappableGraphComponent : public MappableDigraphComponent<BAS>  {
1196 1213
    public:
1197 1214

	
1198
      typedef _Base Base;
1215
      typedef BAS Base;
1199 1216
      typedef typename Base::Edge Edge;
1200 1217

	
1201 1218
      typedef MappableGraphComponent Graph;
1202 1219

	
1203
      /// \brief ReadWrite map of the edges.
1220
      /// \brief Standard graph map for the edges.
1204 1221
      ///
1205
      /// ReadWrite map of the edges.
1206
      ///
1207
      template <typename _Value>
1208
      class EdgeMap : public GraphMap<Graph, Edge, _Value> {
1222
      /// Standard graph map for the edges.
1223
      /// It conforms to the ReferenceMap concept.
1224
      template <typename V>
1225
      class EdgeMap : public GraphMap<MappableGraphComponent, Edge, V> {
1226
        typedef GraphMap<MappableGraphComponent, Edge, V> Parent;
1227

	
1209 1228
      public:
1210
        typedef GraphMap<MappableGraphComponent, Edge, _Value> Parent;
1211

	
1212 1229
        /// \brief Construct a new map.
1213 1230
        ///
1214 1231
        /// Construct a new map for the graph.
1215 1232
        explicit EdgeMap(const MappableGraphComponent& graph)
1216 1233
          : Parent(graph) {}
1217 1234

	
1218 1235
        /// \brief Construct a new map with default value.
1219 1236
        ///
1220
        /// Construct a new map for the graph and initalise the values.
1221
        EdgeMap(const MappableGraphComponent& graph, const _Value& value)
1237
        /// Construct a new map for the graph and initalize the values.
1238
        EdgeMap(const MappableGraphComponent& graph, const V& value)
1222 1239
          : Parent(graph, value) {}
1223 1240

	
1224 1241
      private:
1225 1242
        /// \brief Copy constructor.
1226 1243
        ///
1227 1244
        /// Copy Constructor.
1228 1245
        EdgeMap(const EdgeMap& nm) : Parent(nm) {}
1229 1246

	
1230
        /// \brief Assign operator.
1247
        /// \brief Assignment operator.
1231 1248
        ///
1232
        /// Assign operator.
1249
        /// Assignment operator.
1233 1250
        template <typename CMap>
1234 1251
        EdgeMap& operator=(const CMap&) {
1235
          checkConcept<ReadMap<Edge, _Value>, CMap>();
1252
          checkConcept<ReadMap<Edge, V>, CMap>();
1236 1253
          return *this;
1237 1254
        }
1238 1255

	
1239 1256
      };
1240 1257

	
1241 1258

	
1242 1259
      template <typename _Graph>
1243 1260
      struct Constraints {
1244 1261

	
1245 1262
        struct Dummy {
1246 1263
          int value;
1247 1264
          Dummy() : value(0) {}
1248 1265
          Dummy(int _v) : value(_v) {}
1249 1266
        };
1250 1267

	
1251 1268
        void constraints() {
1252
          checkConcept<MappableGraphComponent<Base>, _Graph>();
1269
          checkConcept<MappableDigraphComponent<Base>, _Graph>();
1253 1270

	
1254 1271
          { // int map test
1255 1272
            typedef typename _Graph::template EdgeMap<int> IntEdgeMap;
1256 1273
            checkConcept<GraphMap<_Graph, typename _Graph::Edge, int>,
1257 1274
              IntEdgeMap >();
1258 1275
          } { // bool map test
1259 1276
            typedef typename _Graph::template EdgeMap<bool> BoolEdgeMap;
1260 1277
            checkConcept<GraphMap<_Graph, typename _Graph::Edge, bool>,
1261 1278
              BoolEdgeMap >();
1262 1279
          } { // Dummy map test
1263 1280
            typedef typename _Graph::template EdgeMap<Dummy> DummyEdgeMap;
1264 1281
            checkConcept<GraphMap<_Graph, typename _Graph::Edge, Dummy>,
1265 1282
              DummyEdgeMap >();
1266 1283
          }
1267 1284
        }
1268 1285

	
1269
        _Graph& graph;
1286
        const _Graph& graph;
1270 1287
      };
1271 1288
    };
1272 1289

	
1273
    /// \brief An empty extendable digraph class.
1290
    /// \brief Skeleton class for extendable directed graphs.
1274 1291
    ///
1275
    /// This class provides beside the core digraph features digraph
1276
    /// extendable interface for the digraph structure.  The main
1277
    /// difference between the base and this interface is that the
1278
    /// digraph alterations should handled already on this level.
1279
    template <typename _Base = BaseDigraphComponent>
1280
    class ExtendableDigraphComponent : public _Base {
1292
    /// This class describes the interface of extendable directed graphs.
1293
    /// It extends \ref BaseDigraphComponent with functions for adding 
1294
    /// nodes and arcs to the digraph.
1295
    /// This concept requires \ref AlterableDigraphComponent.
1296
    template <typename BAS = BaseDigraphComponent>
1297
    class ExtendableDigraphComponent : public BAS {
1281 1298
    public:
1282
      typedef _Base Base;
1299
      typedef BAS Base;
1283 1300

	
1284
      typedef typename _Base::Node Node;
1285
      typedef typename _Base::Arc Arc;
1301
      typedef typename Base::Node Node;
1302
      typedef typename Base::Arc Arc;
1286 1303

	
1287
      /// \brief Adds a new node to the digraph.
1304
      /// \brief Add a new node to the digraph.
1288 1305
      ///
1289
      /// Adds a new node to the digraph.
1290
      ///
1306
      /// This function adds a new node to the digraph.
1291 1307
      Node addNode() {
1292 1308
        return INVALID;
1293 1309
      }
1294 1310

	
1295
      /// \brief Adds a new arc connects the given two nodes.
1311
      /// \brief Add a new arc connecting the given two nodes.
1296 1312
      ///
1297
      /// Adds a new arc connects the the given two nodes.
1313
      /// This function adds a new arc connecting the given two nodes
1314
      /// of the digraph.
1298 1315
      Arc addArc(const Node&, const Node&) {
1299 1316
        return INVALID;
1300 1317
      }
1301 1318

	
1302 1319
      template <typename _Digraph>
1303 1320
      struct Constraints {
1304 1321
        void constraints() {
1305 1322
          checkConcept<Base, _Digraph>();
1306 1323
          typename _Digraph::Node node_a, node_b;
1307 1324
          node_a = digraph.addNode();
1308 1325
          node_b = digraph.addNode();
1309 1326
          typename _Digraph::Arc arc;
1310 1327
          arc = digraph.addArc(node_a, node_b);
1311 1328
        }
1312 1329

	
1313 1330
        _Digraph& digraph;
1314 1331
      };
1315 1332
    };
1316 1333

	
1317
    /// \brief An empty extendable base undirected graph class.
1334
    /// \brief Skeleton class for extendable undirected graphs.
1318 1335
    ///
1319
    /// This class provides beside the core undirected graph features
1320
    /// core undircted graph extend interface for the graph structure.
1321
    /// The main difference between the base and this interface is
1322
    /// that the graph alterations should handled already on this
1323
    /// level.
1324
    template <typename _Base = BaseGraphComponent>
1325
    class ExtendableGraphComponent : public _Base {
1336
    /// This class describes the interface of extendable undirected graphs.
1337
    /// It extends \ref BaseGraphComponent with functions for adding 
1338
    /// nodes and edges to the graph.
1339
    /// This concept requires \ref AlterableGraphComponent.
1340
    template <typename BAS = BaseGraphComponent>
1341
    class ExtendableGraphComponent : public BAS {
1326 1342
    public:
1327 1343

	
1328
      typedef _Base Base;
1329
      typedef typename _Base::Node Node;
1330
      typedef typename _Base::Edge Edge;
1344
      typedef BAS Base;
1345
      typedef typename Base::Node Node;
1346
      typedef typename Base::Edge Edge;
1331 1347

	
1332
      /// \brief Adds a new node to the graph.
1348
      /// \brief Add a new node to the digraph.
1333 1349
      ///
1334
      /// Adds a new node to the graph.
1335
      ///
1350
      /// This function adds a new node to the digraph.
1336 1351
      Node addNode() {
1337 1352
        return INVALID;
1338 1353
      }
1339 1354

	
1340
      /// \brief Adds a new arc connects the given two nodes.
1355
      /// \brief Add a new edge connecting the given two nodes.
1341 1356
      ///
1342
      /// Adds a new arc connects the the given two nodes.
1343
      Edge addArc(const Node&, const Node&) {
1357
      /// This function adds a new edge connecting the given two nodes
1358
      /// of the graph.
1359
      Edge addEdge(const Node&, const Node&) {
1344 1360
        return INVALID;
1345 1361
      }
1346 1362

	
1347 1363
      template <typename _Graph>
1348 1364
      struct Constraints {
1349 1365
        void constraints() {
1350 1366
          checkConcept<Base, _Graph>();
1351 1367
          typename _Graph::Node node_a, node_b;
1352 1368
          node_a = graph.addNode();
1353 1369
          node_b = graph.addNode();
1354 1370
          typename _Graph::Edge edge;
1355 1371
          edge = graph.addEdge(node_a, node_b);
1356 1372
        }
1357 1373

	
1358 1374
        _Graph& graph;
1359 1375
      };
1360 1376
    };
1361 1377

	
1362
    /// \brief An empty erasable digraph class.
1378
    /// \brief Skeleton class for erasable directed graphs.
1363 1379
    ///
1364
    /// This class provides beside the core digraph features core erase
1365
    /// functions for the digraph structure. The main difference between
1366
    /// the base and this interface is that the digraph alterations
1367
    /// should handled already on this level.
1368
    template <typename _Base = BaseDigraphComponent>
1369
    class ErasableDigraphComponent : public _Base {
1380
    /// This class describes the interface of erasable directed graphs.
1381
    /// It extends \ref BaseDigraphComponent with functions for removing 
1382
    /// nodes and arcs from the digraph.
1383
    /// This concept requires \ref AlterableDigraphComponent.
1384
    template <typename BAS = BaseDigraphComponent>
1385
    class ErasableDigraphComponent : public BAS {
1370 1386
    public:
1371 1387

	
1372
      typedef _Base Base;
1388
      typedef BAS Base;
1373 1389
      typedef typename Base::Node Node;
1374 1390
      typedef typename Base::Arc Arc;
1375 1391

	
1376 1392
      /// \brief Erase a node from the digraph.
1377 1393
      ///
1378
      /// Erase a node from the digraph. This function should
1379
      /// erase all arcs connecting to the node.
1394
      /// This function erases the given node from the digraph and all arcs 
1395
      /// connected to the node.
1380 1396
      void erase(const Node&) {}
1381 1397

	
1382 1398
      /// \brief Erase an arc from the digraph.
1383 1399
      ///
1384
      /// Erase an arc from the digraph.
1385
      ///
1400
      /// This function erases the given arc from the digraph.
1386 1401
      void erase(const Arc&) {}
1387 1402

	
1388 1403
      template <typename _Digraph>
1389 1404
      struct Constraints {
1390 1405
        void constraints() {
1391 1406
          checkConcept<Base, _Digraph>();
1392
          typename _Digraph::Node node;
1407
          const typename _Digraph::Node node(INVALID);
1393 1408
          digraph.erase(node);
1394
          typename _Digraph::Arc arc;
1409
          const typename _Digraph::Arc arc(INVALID);
1395 1410
          digraph.erase(arc);
1396 1411
        }
1397 1412

	
1398 1413
        _Digraph& digraph;
1399 1414
      };
1400 1415
    };
1401 1416

	
1402
    /// \brief An empty erasable base undirected graph class.
1417
    /// \brief Skeleton class for erasable undirected graphs.
1403 1418
    ///
1404
    /// This class provides beside the core undirected graph features
1405
    /// core erase functions for the undirceted graph structure. The
1406
    /// main difference between the base and this interface is that
1407
    /// the graph alterations should handled already on this level.
1408
    template <typename _Base = BaseGraphComponent>
1409
    class ErasableGraphComponent : public _Base {
1419
    /// This class describes the interface of erasable undirected graphs.
1420
    /// It extends \ref BaseGraphComponent with functions for removing 
1421
    /// nodes and edges from the graph.
1422
    /// This concept requires \ref AlterableGraphComponent.
1423
    template <typename BAS = BaseGraphComponent>
1424
    class ErasableGraphComponent : public BAS {
1410 1425
    public:
1411 1426

	
1412
      typedef _Base Base;
1427
      typedef BAS Base;
1413 1428
      typedef typename Base::Node Node;
1414 1429
      typedef typename Base::Edge Edge;
1415 1430

	
1416 1431
      /// \brief Erase a node from the graph.
1417 1432
      ///
1418
      /// Erase a node from the graph. This function should erase
1419
      /// arcs connecting to the node.
1433
      /// This function erases the given node from the graph and all edges
1434
      /// connected to the node.
1420 1435
      void erase(const Node&) {}
1421 1436

	
1422
      /// \brief Erase an arc from the graph.
1437
      /// \brief Erase an edge from the digraph.
1423 1438
      ///
1424
      /// Erase an arc from the graph.
1425
      ///
1439
      /// This function erases the given edge from the digraph.
1426 1440
      void erase(const Edge&) {}
1427 1441

	
1428 1442
      template <typename _Graph>
1429 1443
      struct Constraints {
1430 1444
        void constraints() {
1431 1445
          checkConcept<Base, _Graph>();
1432
          typename _Graph::Node node;
1446
          const typename _Graph::Node node(INVALID);
1433 1447
          graph.erase(node);
1434
          typename _Graph::Edge edge;
1448
          const typename _Graph::Edge edge(INVALID);
1435 1449
          graph.erase(edge);
1436 1450
        }
1437 1451

	
1438 1452
        _Graph& graph;
1439 1453
      };
1440 1454
    };
1441 1455

	
1442
    /// \brief An empty clearable base digraph class.
1456
    /// \brief Skeleton class for clearable directed graphs.
1443 1457
    ///
1444
    /// This class provides beside the core digraph features core clear
1445
    /// functions for the digraph structure. The main difference between
1446
    /// the base and this interface is that the digraph alterations
1447
    /// should handled already on this level.
1448
    template <typename _Base = BaseDigraphComponent>
1449
    class ClearableDigraphComponent : public _Base {
1458
    /// This class describes the interface of clearable directed graphs.
1459
    /// It extends \ref BaseDigraphComponent with a function for clearing
1460
    /// the digraph.
1461
    /// This concept requires \ref AlterableDigraphComponent.
1462
    template <typename BAS = BaseDigraphComponent>
1463
    class ClearableDigraphComponent : public BAS {
1450 1464
    public:
1451 1465

	
1452
      typedef _Base Base;
1466
      typedef BAS Base;
1453 1467

	
1454 1468
      /// \brief Erase all nodes and arcs from the digraph.
1455 1469
      ///
1456
      /// Erase all nodes and arcs from the digraph.
1457
      ///
1470
      /// This function erases all nodes and arcs from the digraph.
1458 1471
      void clear() {}
1459 1472

	
1460 1473
      template <typename _Digraph>
1461 1474
      struct Constraints {
1462 1475
        void constraints() {
1463 1476
          checkConcept<Base, _Digraph>();
1464 1477
          digraph.clear();
1465 1478
        }
1466 1479

	
1467
        _Digraph digraph;
1480
        _Digraph& digraph;
1468 1481
      };
1469 1482
    };
1470 1483

	
1471
    /// \brief An empty clearable base undirected graph class.
1484
    /// \brief Skeleton class for clearable undirected graphs.
1472 1485
    ///
1473
    /// This class provides beside the core undirected graph features
1474
    /// core clear functions for the undirected graph structure. The
1475
    /// main difference between the base and this interface is that
1476
    /// the graph alterations should handled already on this level.
1477
    template <typename _Base = BaseGraphComponent>
1478
    class ClearableGraphComponent : public ClearableDigraphComponent<_Base> {
1486
    /// This class describes the interface of clearable undirected graphs.
1487
    /// It extends \ref BaseGraphComponent with a function for clearing
1488
    /// the graph.
1489
    /// This concept requires \ref AlterableGraphComponent.
1490
    template <typename BAS = BaseGraphComponent>
1491
    class ClearableGraphComponent : public ClearableDigraphComponent<BAS> {
1479 1492
    public:
1480 1493

	
1481
      typedef _Base Base;
1494
      typedef BAS Base;
1495

	
1496
      /// \brief Erase all nodes and edges from the graph.
1497
      ///
1498
      /// This function erases all nodes and edges from the graph.
1499
      void clear() {}
1482 1500

	
1483 1501
      template <typename _Graph>
1484 1502
      struct Constraints {
1485 1503
        void constraints() {
1486
          checkConcept<ClearableGraphComponent<Base>, _Graph>();
1504
          checkConcept<Base, _Graph>();
1505
          graph.clear();
1487 1506
        }
1488 1507

	
1489
        _Graph graph;
1508
        _Graph& graph;
1490 1509
      };
1491 1510
    };
1492 1511

	
1493 1512
  }
1494 1513

	
1495 1514
}
1496 1515

	
1497 1516
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
///\ingroup concept
20 20
///\file
21 21
///\brief The concept of heaps.
22 22

	
23
#ifndef LEMON_CONCEPT_HEAP_H
24
#define LEMON_CONCEPT_HEAP_H
23
#ifndef LEMON_CONCEPTS_HEAP_H
24
#define LEMON_CONCEPTS_HEAP_H
25 25

	
26 26
#include <lemon/core.h>
27
#include <lemon/concept_check.h>
27 28

	
28 29
namespace lemon {
29 30

	
30 31
  namespace concepts {
31 32

	
32 33
    /// \addtogroup concept
33 34
    /// @{
34 35

	
35 36
    /// \brief The heap concept.
36 37
    ///
37
    /// Concept class describing the main interface of heaps.
38
    template <typename Priority, typename ItemIntMap>
38
    /// Concept class describing the main interface of heaps. A \e heap
39
    /// is a data structure for storing items with specified values called
40
    /// \e priorities in such a way that finding the item with minimum
41
    /// priority is efficient. In a heap one can change the priority of an
42
    /// item, add or erase an item, etc.
43
    ///
44
    /// \tparam PR Type of the priority of the items.
45
    /// \tparam IM A read and writable item map with int values, used
46
    /// internally to handle the cross references.
47
    /// \tparam Comp A functor class for the ordering of the priorities.
48
    /// The default is \c std::less<PR>.
49
#ifdef DOXYGEN
50
    template <typename PR, typename IM, typename Comp = std::less<PR> >
51
#else
52
    template <typename PR, typename IM>
53
#endif
39 54
    class Heap {
40 55
    public:
41 56

	
57
      /// Type of the item-int map.
58
      typedef IM ItemIntMap;
59
      /// Type of the priorities.
60
      typedef PR Prio;
42 61
      /// Type of the items stored in the heap.
43 62
      typedef typename ItemIntMap::Key Item;
44 63

	
45
      /// Type of the priorities.
46
      typedef Priority Prio;
47

	
48 64
      /// \brief Type to represent the states of the items.
49 65
      ///
50 66
      /// Each item has a state associated to it. It can be "in heap",
51 67
      /// "pre heap" or "post heap". The later two are indifferent
52 68
      /// from the point of view of the heap, but may be useful for
53 69
      /// the user.
54 70
      ///
55
      /// The \c ItemIntMap must be initialized in such a way, that it
56
      /// assigns \c PRE_HEAP (<tt>-1</tt>) to every item.
71
      /// The item-int map must be initialized in such way that it assigns
72
      /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
57 73
      enum State {
58
        IN_HEAP = 0,
59
        PRE_HEAP = -1,
60
        POST_HEAP = -2
74
        IN_HEAP = 0,    ///< = 0. The "in heap" state constant.
75
        PRE_HEAP = -1,  ///< = -1. The "pre heap" state constant.
76
        POST_HEAP = -2  ///< = -2. The "post heap" state constant.
61 77
      };
62 78

	
63 79
      /// \brief The constructor.
64 80
      ///
65 81
      /// The constructor.
66 82
      /// \param map A map that assigns \c int values to keys of type
67 83
      /// \c Item. It is used internally by the heap implementations to
68 84
      /// handle the cross references. The assigned value must be
69 85
      /// \c PRE_HEAP (<tt>-1</tt>) for every item.
70 86
      explicit Heap(ItemIntMap &map) {}
71 87

	
72 88
      /// \brief The number of items stored in the heap.
73 89
      ///
74 90
      /// Returns the number of items stored in the heap.
75 91
      int size() const { return 0; }
76 92

	
77 93
      /// \brief Checks if the heap is empty.
78 94
      ///
79 95
      /// Returns \c true if the heap is empty.
80 96
      bool empty() const { return false; }
81 97

	
82 98
      /// \brief Makes the heap empty.
83 99
      ///
84 100
      /// Makes the heap empty.
85 101
      void clear();
86 102

	
87 103
      /// \brief Inserts an item into the heap with the given priority.
88 104
      ///
89 105
      /// Inserts the given item into the heap with the given priority.
90 106
      /// \param i The item to insert.
91 107
      /// \param p The priority of the item.
92 108
      void push(const Item &i, const Prio &p) {}
93 109

	
94 110
      /// \brief Returns the item having minimum priority.
95 111
      ///
96 112
      /// Returns the item having minimum priority.
97 113
      /// \pre The heap must be non-empty.
98 114
      Item top() const {}
99 115

	
100 116
      /// \brief The minimum priority.
101 117
      ///
102 118
      /// Returns the minimum priority.
103 119
      /// \pre The heap must be non-empty.
104 120
      Prio prio() const {}
105 121

	
106 122
      /// \brief Removes the item having minimum priority.
107 123
      ///
108 124
      /// Removes the item having minimum priority.
109 125
      /// \pre The heap must be non-empty.
110 126
      void pop() {}
111 127

	
112 128
      /// \brief Removes an item from the heap.
113 129
      ///
114 130
      /// Removes the given item from the heap if it is already stored.
115 131
      /// \param i The item to delete.
116 132
      void erase(const Item &i) {}
117 133

	
118 134
      /// \brief The priority of an item.
119 135
      ///
120 136
      /// Returns the priority of the given item.
137
      /// \param i The item.
121 138
      /// \pre \c i must be in the heap.
122
      /// \param i The item.
123 139
      Prio operator[](const Item &i) const {}
124 140

	
125 141
      /// \brief Sets the priority of an item or inserts it, if it is
126 142
      /// not stored in the heap.
127 143
      ///
128 144
      /// This method sets the priority of the given item if it is
129 145
      /// already stored in the heap.
130 146
      /// Otherwise it inserts the given item with the given priority.
131 147
      ///
132 148
      /// \param i The item.
133 149
      /// \param p The priority.
134 150
      void set(const Item &i, const Prio &p) {}
135 151

	
136 152
      /// \brief Decreases the priority of an item to the given value.
137 153
      ///
138 154
      /// Decreases the priority of an item to the given value.
139
      /// \pre \c i must be stored in the heap with priority at least \c p.
140 155
      /// \param i The item.
141 156
      /// \param p The priority.
157
      /// \pre \c i must be stored in the heap with priority at least \c p.
142 158
      void decrease(const Item &i, const Prio &p) {}
143 159

	
144 160
      /// \brief Increases the priority of an item to the given value.
145 161
      ///
146 162
      /// Increases the priority of an item to the given value.
147
      /// \pre \c i must be stored in the heap with priority at most \c p.
148 163
      /// \param i The item.
149 164
      /// \param p The priority.
165
      /// \pre \c i must be stored in the heap with priority at most \c p.
150 166
      void increase(const Item &i, const Prio &p) {}
151 167

	
152 168
      /// \brief Returns if an item is in, has already been in, or has
153 169
      /// never been in the heap.
154 170
      ///
155 171
      /// This method returns \c PRE_HEAP if the given item has never
156 172
      /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
157 173
      /// and \c POST_HEAP otherwise.
158 174
      /// In the latter case it is possible that the item will get back
159 175
      /// to the heap again.
160 176
      /// \param i The item.
161 177
      State state(const Item &i) const {}
162 178

	
163 179
      /// \brief Sets the state of an item in the heap.
164 180
      ///
165 181
      /// Sets the state of the given item in the heap. It can be used
166 182
      /// to manually clear the heap when it is important to achive the
167 183
      /// better time complexity.
168 184
      /// \param i The item.
169 185
      /// \param st The state. It should not be \c IN_HEAP.
170 186
      void state(const Item& i, State st) {}
171 187

	
172 188

	
173 189
      template <typename _Heap>
174 190
      struct Constraints {
175 191
      public:
176 192
        void constraints() {
177 193
          typedef typename _Heap::Item OwnItem;
178 194
          typedef typename _Heap::Prio OwnPrio;
179 195
          typedef typename _Heap::State OwnState;
180 196

	
181 197
          Item item;
182 198
          Prio prio;
183 199
          item=Item();
184 200
          prio=Prio();
185 201
          ignore_unused_variable_warning(item);
186 202
          ignore_unused_variable_warning(prio);
187 203

	
188 204
          OwnItem own_item;
189 205
          OwnPrio own_prio;
190 206
          OwnState own_state;
191 207
          own_item=Item();
192 208
          own_prio=Prio();
193 209
          ignore_unused_variable_warning(own_item);
194 210
          ignore_unused_variable_warning(own_prio);
195 211
          ignore_unused_variable_warning(own_state);
196 212

	
197 213
          _Heap heap1(map);
198 214
          _Heap heap2 = heap1;
199 215
          ignore_unused_variable_warning(heap1);
200 216
          ignore_unused_variable_warning(heap2);
201 217

	
202 218
          int s = heap.size();
203 219
          ignore_unused_variable_warning(s);
204 220
          bool e = heap.empty();
205 221
          ignore_unused_variable_warning(e);
206 222

	
207 223
          prio = heap.prio();
208 224
          item = heap.top();
209 225
          prio = heap[item];
210 226
          own_prio = heap.prio();
211 227
          own_item = heap.top();
212 228
          own_prio = heap[own_item];
213 229

	
214 230
          heap.push(item, prio);
215 231
          heap.push(own_item, own_prio);
216 232
          heap.pop();
217 233

	
218 234
          heap.set(item, prio);
219 235
          heap.decrease(item, prio);
220 236
          heap.increase(item, prio);
221 237
          heap.set(own_item, own_prio);
222 238
          heap.decrease(own_item, own_prio);
223 239
          heap.increase(own_item, own_prio);
224 240

	
225 241
          heap.erase(item);
226 242
          heap.erase(own_item);
227 243
          heap.clear();
228 244

	
229 245
          own_state = heap.state(own_item);
230 246
          heap.state(own_item, own_state);
231 247

	
232 248
          own_state = _Heap::PRE_HEAP;
233 249
          own_state = _Heap::IN_HEAP;
234 250
          own_state = _Heap::POST_HEAP;
235 251
        }
236 252

	
237 253
        _Heap& heap;
238 254
        ItemIntMap& map;
239 255
      };
240 256
    };
241 257

	
242 258
    /// @}
243 259
  } // namespace lemon
244 260
}
245
#endif // LEMON_CONCEPT_PATH_H
261
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
#ifndef LEMON_CONCEPT_MAPS_H
20
#define LEMON_CONCEPT_MAPS_H
19
#ifndef LEMON_CONCEPTS_MAPS_H
20
#define LEMON_CONCEPTS_MAPS_H
21 21

	
22 22
#include <lemon/core.h>
23 23
#include <lemon/concept_check.h>
24 24

	
25 25
///\ingroup map_concepts
26 26
///\file
27 27
///\brief The concept of maps.
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  namespace concepts {
32 32

	
33 33
    /// \addtogroup map_concepts
34 34
    /// @{
35 35

	
36 36
    /// Readable map concept
37 37

	
38 38
    /// Readable map concept.
39 39
    ///
40 40
    template<typename K, typename T>
41 41
    class ReadMap
42 42
    {
43 43
    public:
44 44
      /// The key type of the map.
45 45
      typedef K Key;
46 46
      /// \brief The value type of the map.
47 47
      /// (The type of objects associated with the keys).
48 48
      typedef T Value;
49 49

	
50 50
      /// Returns the value associated with the given key.
51 51
      Value operator[](const Key &) const {
52 52
        return *static_cast<Value *>(0);
53 53
      }
54 54

	
55 55
      template<typename _ReadMap>
56 56
      struct Constraints {
57 57
        void constraints() {
58 58
          Value val = m[key];
59 59
          val = m[key];
60 60
          typename _ReadMap::Value own_val = m[own_key];
61 61
          own_val = m[own_key];
62 62

	
63 63
          ignore_unused_variable_warning(key);
64 64
          ignore_unused_variable_warning(val);
65 65
          ignore_unused_variable_warning(own_key);
66 66
          ignore_unused_variable_warning(own_val);
67 67
        }
68 68
        const Key& key;
69 69
        const typename _ReadMap::Key& own_key;
70 70
        const _ReadMap& m;
71 71
      };
72 72

	
73 73
    };
74 74

	
75 75

	
76 76
    /// Writable map concept
77 77

	
78 78
    /// Writable map concept.
79 79
    ///
80 80
    template<typename K, typename T>
81 81
    class WriteMap
82 82
    {
83 83
    public:
84 84
      /// The key type of the map.
85 85
      typedef K Key;
86 86
      /// \brief The value type of the map.
87 87
      /// (The type of objects associated with the keys).
88 88
      typedef T Value;
89 89

	
90 90
      /// Sets the value associated with the given key.
91 91
      void set(const Key &, const Value &) {}
92 92

	
93 93
      /// Default constructor.
94 94
      WriteMap() {}
95 95

	
96 96
      template <typename _WriteMap>
97 97
      struct Constraints {
98 98
        void constraints() {
99 99
          m.set(key, val);
100 100
          m.set(own_key, own_val);
101 101

	
102 102
          ignore_unused_variable_warning(key);
103 103
          ignore_unused_variable_warning(val);
104 104
          ignore_unused_variable_warning(own_key);
105 105
          ignore_unused_variable_warning(own_val);
106 106
        }
107 107
        const Key& key;
108 108
        const Value& val;
109 109
        const typename _WriteMap::Key& own_key;
110 110
        const typename _WriteMap::Value& own_val;
111 111
        _WriteMap& m;
112 112
      };
113 113
    };
114 114

	
115 115
    /// Read/writable map concept
116 116

	
117 117
    /// Read/writable map concept.
118 118
    ///
119 119
    template<typename K, typename T>
120 120
    class ReadWriteMap : public ReadMap<K,T>,
121 121
                         public WriteMap<K,T>
122 122
    {
123 123
    public:
124 124
      /// The key type of the map.
125 125
      typedef K Key;
126 126
      /// \brief The value type of the map.
127 127
      /// (The type of objects associated with the keys).
128 128
      typedef T Value;
129 129

	
130 130
      /// Returns the value associated with the given key.
131 131
      Value operator[](const Key &) const {
132 132
        return *static_cast<Value *>(0);
133 133
      }
134 134

	
135 135
      /// Sets the value associated with the given key.
136 136
      void set(const Key &, const Value &) {}
137 137

	
138 138
      template<typename _ReadWriteMap>
139 139
      struct Constraints {
140 140
        void constraints() {
141 141
          checkConcept<ReadMap<K, T>, _ReadWriteMap >();
142 142
          checkConcept<WriteMap<K, T>, _ReadWriteMap >();
143 143
        }
144 144
      };
145 145
    };
146 146

	
147 147

	
148 148
    /// Dereferable map concept
149 149

	
150 150
    /// Dereferable map concept.
151 151
    ///
152 152
    template<typename K, typename T, typename R, typename CR>
153 153
    class ReferenceMap : public ReadWriteMap<K,T>
154 154
    {
155 155
    public:
156 156
      /// Tag for reference maps.
157 157
      typedef True ReferenceMapTag;
158 158
      /// The key type of the map.
159 159
      typedef K Key;
160 160
      /// \brief The value type of the map.
161 161
      /// (The type of objects associated with the keys).
162 162
      typedef T Value;
163 163
      /// The reference type of the map.
164 164
      typedef R Reference;
165 165
      /// The const reference type of the map.
166 166
      typedef CR ConstReference;
167 167

	
168 168
    public:
169 169

	
170 170
      /// Returns a reference to the value associated with the given key.
171 171
      Reference operator[](const Key &) {
172 172
        return *static_cast<Value *>(0);
173 173
      }
174 174

	
175 175
      /// Returns a const reference to the value associated with the given key.
176 176
      ConstReference operator[](const Key &) const {
177 177
        return *static_cast<Value *>(0);
178 178
      }
179 179

	
180 180
      /// Sets the value associated with the given key.
181 181
      void set(const Key &k,const Value &t) { operator[](k)=t; }
182 182

	
183 183
      template<typename _ReferenceMap>
184 184
      struct Constraints {
185
        void constraints() {
185
        typename enable_if<typename _ReferenceMap::ReferenceMapTag, void>::type
186
        constraints() {
186 187
          checkConcept<ReadWriteMap<K, T>, _ReferenceMap >();
187 188
          ref = m[key];
188 189
          m[key] = val;
189 190
          m[key] = ref;
190 191
          m[key] = cref;
191 192
          own_ref = m[own_key];
192 193
          m[own_key] = own_val;
193 194
          m[own_key] = own_ref;
194 195
          m[own_key] = own_cref;
195 196
          m[key] = m[own_key];
196 197
          m[own_key] = m[key];
197 198
        }
198 199
        const Key& key;
199 200
        Value& val;
200 201
        Reference ref;
201 202
        ConstReference cref;
202 203
        const typename _ReferenceMap::Key& own_key;
203 204
        typename _ReferenceMap::Value& own_val;
204 205
        typename _ReferenceMap::Reference own_ref;
205 206
        typename _ReferenceMap::ConstReference own_cref;
206 207
        _ReferenceMap& m;
207 208
      };
208 209
    };
209 210

	
210 211
    // @}
211 212

	
212 213
  } //namespace concepts
213 214

	
214 215
} //namespace lemon
215 216

	
216
#endif // LEMON_CONCEPT_MAPS_H
217
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
///\ingroup concept
20 20
///\file
21 21
///\brief Classes for representing paths in digraphs.
22 22
///
23 23

	
24
#ifndef LEMON_CONCEPT_PATH_H
25
#define LEMON_CONCEPT_PATH_H
24
#ifndef LEMON_CONCEPTS_PATH_H
25
#define LEMON_CONCEPTS_PATH_H
26 26

	
27 27
#include <lemon/core.h>
28 28
#include <lemon/concept_check.h>
29 29

	
30 30
namespace lemon {
31 31
  namespace concepts {
32 32

	
33 33
    /// \addtogroup concept
34 34
    /// @{
35 35

	
36 36
    /// \brief A skeleton structure for representing directed paths in
37 37
    /// a digraph.
38 38
    ///
39 39
    /// A skeleton structure for representing directed paths in a
40 40
    /// digraph.
41
    /// \tparam _Digraph The digraph type in which the path is.
41
    /// \tparam GR The digraph type in which the path is.
42 42
    ///
43 43
    /// In a sense, the path can be treated as a list of arcs. The
44 44
    /// lemon path type stores just this list. As a consequence it
45 45
    /// cannot enumerate the nodes in the path and the zero length
46 46
    /// paths cannot store the source.
47 47
    ///
48
    template <typename _Digraph>
48
    template <typename GR>
49 49
    class Path {
50 50
    public:
51 51

	
52 52
      /// Type of the underlying digraph.
53
      typedef _Digraph Digraph;
53
      typedef GR Digraph;
54 54
      /// Arc type of the underlying digraph.
55 55
      typedef typename Digraph::Arc Arc;
56 56

	
57 57
      class ArcIt;
58 58

	
59 59
      /// \brief Default constructor
60 60
      Path() {}
61 61

	
62 62
      /// \brief Template constructor
63 63
      template <typename CPath>
64 64
      Path(const CPath& cpath) {}
65 65

	
66 66
      /// \brief Template assigment
67 67
      template <typename CPath>
68 68
      Path& operator=(const CPath& cpath) {
69 69
        ignore_unused_variable_warning(cpath);
70 70
        return *this;
71 71
      }
72 72

	
73 73
      /// Length of the path ie. the number of arcs in the path.
74 74
      int length() const { return 0;}
75 75

	
76 76
      /// Returns whether the path is empty.
77 77
      bool empty() const { return true;}
78 78

	
79 79
      /// Resets the path to an empty path.
80 80
      void clear() {}
81 81

	
82 82
      /// \brief LEMON style iterator for path arcs
83 83
      ///
84 84
      /// This class is used to iterate on the arcs of the paths.
85 85
      class ArcIt {
86 86
      public:
87 87
        /// Default constructor
88 88
        ArcIt() {}
89 89
        /// Invalid constructor
90 90
        ArcIt(Invalid) {}
91 91
        /// Constructor for first arc
92 92
        ArcIt(const Path &) {}
93 93

	
94 94
        /// Conversion to Arc
95 95
        operator Arc() const { return INVALID; }
96 96

	
97 97
        /// Next arc
98 98
        ArcIt& operator++() {return *this;}
99 99

	
100 100
        /// Comparison operator
101 101
        bool operator==(const ArcIt&) const {return true;}
102 102
        /// Comparison operator
103 103
        bool operator!=(const ArcIt&) const {return true;}
104 104
        /// Comparison operator
105 105
        bool operator<(const ArcIt&) const {return false;}
106 106

	
107 107
      };
108 108

	
109 109
      template <typename _Path>
110 110
      struct Constraints {
111 111
        void constraints() {
112 112
          Path<Digraph> pc;
113 113
          _Path p, pp(pc);
114 114
          int l = p.length();
115 115
          int e = p.empty();
116 116
          p.clear();
117 117

	
118 118
          p = pc;
119 119

	
120 120
          typename _Path::ArcIt id, ii(INVALID), i(p);
121 121

	
122 122
          ++i;
123 123
          typename Digraph::Arc ed = i;
124 124

	
125 125
          e = (i == ii);
126 126
          e = (i != ii);
127 127
          e = (i < ii);
128 128

	
129 129
          ignore_unused_variable_warning(l);
130 130
          ignore_unused_variable_warning(pp);
131 131
          ignore_unused_variable_warning(e);
132 132
          ignore_unused_variable_warning(id);
133 133
          ignore_unused_variable_warning(ii);
134 134
          ignore_unused_variable_warning(ed);
135 135
        }
136 136
      };
137 137

	
138 138
    };
139 139

	
140 140
    namespace _path_bits {
141 141

	
142 142
      template <typename _Digraph, typename _Path, typename RevPathTag = void>
143 143
      struct PathDumperConstraints {
144 144
        void constraints() {
145 145
          int l = p.length();
146 146
          int e = p.empty();
147 147

	
148 148
          typename _Path::ArcIt id, i(p);
149 149

	
150 150
          ++i;
151 151
          typename _Digraph::Arc ed = i;
152 152

	
153 153
          e = (i == INVALID);
154 154
          e = (i != INVALID);
155 155

	
156 156
          ignore_unused_variable_warning(l);
157 157
          ignore_unused_variable_warning(e);
158 158
          ignore_unused_variable_warning(id);
159 159
          ignore_unused_variable_warning(ed);
160 160
        }
161 161
        _Path& p;
162 162
      };
163 163

	
164 164
      template <typename _Digraph, typename _Path>
165 165
      struct PathDumperConstraints<
166 166
        _Digraph, _Path,
167 167
        typename enable_if<typename _Path::RevPathTag, void>::type
168 168
      > {
169 169
        void constraints() {
170 170
          int l = p.length();
171 171
          int e = p.empty();
172 172

	
173 173
          typename _Path::RevArcIt id, i(p);
174 174

	
175 175
          ++i;
176 176
          typename _Digraph::Arc ed = i;
177 177

	
178 178
          e = (i == INVALID);
179 179
          e = (i != INVALID);
180 180

	
181 181
          ignore_unused_variable_warning(l);
182 182
          ignore_unused_variable_warning(e);
183 183
          ignore_unused_variable_warning(id);
184 184
          ignore_unused_variable_warning(ed);
185 185
        }
186 186
        _Path& p;
187 187
      };
188 188

	
189 189
    }
190 190

	
191 191

	
192 192
    /// \brief A skeleton structure for path dumpers.
193 193
    ///
194 194
    /// A skeleton structure for path dumpers. The path dumpers are
195 195
    /// the generalization of the paths. The path dumpers can
196 196
    /// enumerate the arcs of the path wheter in forward or in
197 197
    /// backward order.  In most time these classes are not used
198 198
    /// directly rather it used to assign a dumped class to a real
199 199
    /// path type.
200 200
    ///
201 201
    /// The main purpose of this concept is that the shortest path
202 202
    /// algorithms can enumerate easily the arcs in reverse order.
203 203
    /// If we would like to give back a real path from these
204 204
    /// algorithms then we should create a temporarly path object. In
205 205
    /// LEMON such algorithms gives back a path dumper what can
206 206
    /// assigned to a real path and the dumpers can be implemented as
207 207
    /// an adaptor class to the predecessor map.
208

	
209
    /// \tparam _Digraph  The digraph type in which the path is.
208
    ///
209
    /// \tparam GR The digraph type in which the path is.
210 210
    ///
211 211
    /// The paths can be constructed from any path type by a
212 212
    /// template constructor or a template assignment operator.
213
    ///
214
    template <typename _Digraph>
213
    template <typename GR>
215 214
    class PathDumper {
216 215
    public:
217 216

	
218 217
      /// Type of the underlying digraph.
219
      typedef _Digraph Digraph;
218
      typedef GR Digraph;
220 219
      /// Arc type of the underlying digraph.
221 220
      typedef typename Digraph::Arc Arc;
222 221

	
223 222
      /// Length of the path ie. the number of arcs in the path.
224 223
      int length() const { return 0;}
225 224

	
226 225
      /// Returns whether the path is empty.
227 226
      bool empty() const { return true;}
228 227

	
229 228
      /// \brief Forward or reverse dumping
230 229
      ///
231 230
      /// If the RevPathTag is defined and true then reverse dumping
232 231
      /// is provided in the path dumper. In this case instead of the
233 232
      /// ArcIt the RevArcIt iterator should be implemented in the
234 233
      /// dumper.
235 234
      typedef False RevPathTag;
236 235

	
237 236
      /// \brief LEMON style iterator for path arcs
238 237
      ///
239 238
      /// This class is used to iterate on the arcs of the paths.
240 239
      class ArcIt {
241 240
      public:
242 241
        /// Default constructor
243 242
        ArcIt() {}
244 243
        /// Invalid constructor
245 244
        ArcIt(Invalid) {}
246 245
        /// Constructor for first arc
247 246
        ArcIt(const PathDumper&) {}
248 247

	
249 248
        /// Conversion to Arc
250 249
        operator Arc() const { return INVALID; }
251 250

	
252 251
        /// Next arc
253 252
        ArcIt& operator++() {return *this;}
254 253

	
255 254
        /// Comparison operator
256 255
        bool operator==(const ArcIt&) const {return true;}
257 256
        /// Comparison operator
258 257
        bool operator!=(const ArcIt&) const {return true;}
259 258
        /// Comparison operator
260 259
        bool operator<(const ArcIt&) const {return false;}
261 260

	
262 261
      };
263 262

	
264 263
      /// \brief LEMON style iterator for path arcs
265 264
      ///
266 265
      /// This class is used to iterate on the arcs of the paths in
267 266
      /// reverse direction.
268 267
      class RevArcIt {
269 268
      public:
270 269
        /// Default constructor
271 270
        RevArcIt() {}
272 271
        /// Invalid constructor
273 272
        RevArcIt(Invalid) {}
274 273
        /// Constructor for first arc
275 274
        RevArcIt(const PathDumper &) {}
276 275

	
277 276
        /// Conversion to Arc
278 277
        operator Arc() const { return INVALID; }
279 278

	
280 279
        /// Next arc
281 280
        RevArcIt& operator++() {return *this;}
282 281

	
283 282
        /// Comparison operator
284 283
        bool operator==(const RevArcIt&) const {return true;}
285 284
        /// Comparison operator
286 285
        bool operator!=(const RevArcIt&) const {return true;}
287 286
        /// Comparison operator
288 287
        bool operator<(const RevArcIt&) const {return false;}
289 288

	
290 289
      };
291 290

	
292 291
      template <typename _Path>
293 292
      struct Constraints {
294 293
        void constraints() {
295 294
          function_requires<_path_bits::
296 295
            PathDumperConstraints<Digraph, _Path> >();
297 296
        }
298 297
      };
299 298

	
300 299
    };
301 300

	
302 301

	
303 302
    ///@}
304 303
  }
305 304

	
306 305
} // namespace lemon
307 306

	
308
#endif // LEMON_CONCEPT_PATH_H
307
#endif
Ignore white space 6 line context
1
#define LEMON_VERSION "@PROJECT_VERSION@"
1 2
#cmakedefine LEMON_HAVE_LONG_LONG 1
3
#cmakedefine LEMON_HAVE_LP 1
4
#cmakedefine LEMON_HAVE_MIP 1
5
#cmakedefine LEMON_HAVE_GLPK 1
6
#cmakedefine LEMON_HAVE_CPLEX 1
7
#cmakedefine LEMON_HAVE_CLP 1
8
#cmakedefine LEMON_HAVE_CBC 1
Ignore white space 6 line context
1
/* The version string */
2
#undef LEMON_VERSION
3

	
4
/* Define to 1 if you have long long */
5
#undef LEMON_HAVE_LONG_LONG
6

	
7
/* Define to 1 if you have any LP solver. */
8
#undef LEMON_HAVE_LP
9

	
10
/* Define to 1 if you have any MIP solver. */
11
#undef LEMON_HAVE_MIP
12

	
1 13
/* Define to 1 if you have CPLEX. */
2 14
#undef LEMON_HAVE_CPLEX
3 15

	
4 16
/* Define to 1 if you have GLPK. */
5 17
#undef LEMON_HAVE_GLPK
6 18

	
7
/* Define to 1 if you have long long */
8
#undef LEMON_HAVE_LONG_LONG
19
/* Define to 1 if you have SOPLEX */
20
#undef LEMON_HAVE_SOPLEX
21

	
22
/* Define to 1 if you have CLP */
23
#undef LEMON_HAVE_CLP
24

	
25
/* Define to 1 if you have CBC */
26
#undef LEMON_HAVE_CBC
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_CORE_H
20 20
#define LEMON_CORE_H
21 21

	
22 22
#include <vector>
23 23
#include <algorithm>
24 24

	
25 25
#include <lemon/config.h>
26 26
#include <lemon/bits/enable_if.h>
27 27
#include <lemon/bits/traits.h>
28 28
#include <lemon/assert.h>
29 29

	
30
// Disable the following warnings when compiling with MSVC:
31
// C4250: 'class1' : inherits 'class2::member' via dominance
32
// C4355: 'this' : used in base member initializer list
33
// C4503: 'function' : decorated name length exceeded, name was truncated
34
// C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
35
// C4996: 'function': was declared deprecated
36
#ifdef _MSC_VER
37
#pragma warning( disable : 4250 4355 4503 4800 4996 )
38
#endif
39

	
30 40
///\file
31 41
///\brief LEMON core utilities.
32 42
///
33 43
///This header file contains core utilities for LEMON.
34 44
///It is automatically included by all graph types, therefore it usually
35 45
///do not have to be included directly.
36 46

	
37 47
namespace lemon {
38 48

	
39 49
  /// \brief Dummy type to make it easier to create invalid iterators.
40 50
  ///
41 51
  /// Dummy type to make it easier to create invalid iterators.
42 52
  /// See \ref INVALID for the usage.
43 53
  struct Invalid {
44 54
  public:
45 55
    bool operator==(Invalid) { return true;  }
46 56
    bool operator!=(Invalid) { return false; }
47 57
    bool operator< (Invalid) { return false; }
48 58
  };
49 59

	
50 60
  /// \brief Invalid iterators.
51 61
  ///
52 62
  /// \ref Invalid is a global type that converts to each iterator
53 63
  /// in such a way that the value of the target iterator will be invalid.
54 64
#ifdef LEMON_ONLY_TEMPLATES
55 65
  const Invalid INVALID = Invalid();
56 66
#else
57 67
  extern const Invalid INVALID;
58 68
#endif
59 69

	
60 70
  /// \addtogroup gutils
61 71
  /// @{
62 72

	
63 73
  ///Create convenience typedefs for the digraph types and iterators
64 74

	
65 75
  ///This \c \#define creates convenient type definitions for the following
66 76
  ///types of \c Digraph: \c Node,  \c NodeIt, \c Arc, \c ArcIt, \c InArcIt,
67 77
  ///\c OutArcIt, \c BoolNodeMap, \c IntNodeMap, \c DoubleNodeMap,
68 78
  ///\c BoolArcMap, \c IntArcMap, \c DoubleArcMap.
69 79
  ///
70 80
  ///\note If the graph type is a dependent type, ie. the graph type depend
71 81
  ///on a template parameter, then use \c TEMPLATE_DIGRAPH_TYPEDEFS()
72 82
  ///macro.
73 83
#define DIGRAPH_TYPEDEFS(Digraph)                                       \
74 84
  typedef Digraph::Node Node;                                           \
75 85
  typedef Digraph::NodeIt NodeIt;                                       \
76 86
  typedef Digraph::Arc Arc;                                             \
77 87
  typedef Digraph::ArcIt ArcIt;                                         \
78 88
  typedef Digraph::InArcIt InArcIt;                                     \
79 89
  typedef Digraph::OutArcIt OutArcIt;                                   \
80 90
  typedef Digraph::NodeMap<bool> BoolNodeMap;                           \
81 91
  typedef Digraph::NodeMap<int> IntNodeMap;                             \
82 92
  typedef Digraph::NodeMap<double> DoubleNodeMap;                       \
83 93
  typedef Digraph::ArcMap<bool> BoolArcMap;                             \
84 94
  typedef Digraph::ArcMap<int> IntArcMap;                               \
85 95
  typedef Digraph::ArcMap<double> DoubleArcMap
86 96

	
87 97
  ///Create convenience typedefs for the digraph types and iterators
88 98

	
89 99
  ///\see DIGRAPH_TYPEDEFS
90 100
  ///
91 101
  ///\note Use this macro, if the graph type is a dependent type,
92 102
  ///ie. the graph type depend on a template parameter.
93 103
#define TEMPLATE_DIGRAPH_TYPEDEFS(Digraph)                              \
94 104
  typedef typename Digraph::Node Node;                                  \
95 105
  typedef typename Digraph::NodeIt NodeIt;                              \
96 106
  typedef typename Digraph::Arc Arc;                                    \
97 107
  typedef typename Digraph::ArcIt ArcIt;                                \
98 108
  typedef typename Digraph::InArcIt InArcIt;                            \
99 109
  typedef typename Digraph::OutArcIt OutArcIt;                          \
100 110
  typedef typename Digraph::template NodeMap<bool> BoolNodeMap;         \
101 111
  typedef typename Digraph::template NodeMap<int> IntNodeMap;           \
102 112
  typedef typename Digraph::template NodeMap<double> DoubleNodeMap;     \
103 113
  typedef typename Digraph::template ArcMap<bool> BoolArcMap;           \
104 114
  typedef typename Digraph::template ArcMap<int> IntArcMap;             \
105 115
  typedef typename Digraph::template ArcMap<double> DoubleArcMap
106 116

	
107 117
  ///Create convenience typedefs for the graph types and iterators
108 118

	
109 119
  ///This \c \#define creates the same convenient type definitions as defined
110 120
  ///by \ref DIGRAPH_TYPEDEFS(Graph) and six more, namely it creates
111 121
  ///\c Edge, \c EdgeIt, \c IncEdgeIt, \c BoolEdgeMap, \c IntEdgeMap,
112 122
  ///\c DoubleEdgeMap.
113 123
  ///
114 124
  ///\note If the graph type is a dependent type, ie. the graph type depend
115 125
  ///on a template parameter, then use \c TEMPLATE_GRAPH_TYPEDEFS()
116 126
  ///macro.
117 127
#define GRAPH_TYPEDEFS(Graph)                                           \
118 128
  DIGRAPH_TYPEDEFS(Graph);                                              \
119 129
  typedef Graph::Edge Edge;                                             \
120 130
  typedef Graph::EdgeIt EdgeIt;                                         \
121 131
  typedef Graph::IncEdgeIt IncEdgeIt;                                   \
122 132
  typedef Graph::EdgeMap<bool> BoolEdgeMap;                             \
123 133
  typedef Graph::EdgeMap<int> IntEdgeMap;                               \
124 134
  typedef Graph::EdgeMap<double> DoubleEdgeMap
125 135

	
126 136
  ///Create convenience typedefs for the graph types and iterators
127 137

	
128 138
  ///\see GRAPH_TYPEDEFS
129 139
  ///
130 140
  ///\note Use this macro, if the graph type is a dependent type,
131 141
  ///ie. the graph type depend on a template parameter.
132 142
#define TEMPLATE_GRAPH_TYPEDEFS(Graph)                                  \
133 143
  TEMPLATE_DIGRAPH_TYPEDEFS(Graph);                                     \
134 144
  typedef typename Graph::Edge Edge;                                    \
135 145
  typedef typename Graph::EdgeIt EdgeIt;                                \
136 146
  typedef typename Graph::IncEdgeIt IncEdgeIt;                          \
137 147
  typedef typename Graph::template EdgeMap<bool> BoolEdgeMap;           \
138 148
  typedef typename Graph::template EdgeMap<int> IntEdgeMap;             \
139 149
  typedef typename Graph::template EdgeMap<double> DoubleEdgeMap
140 150

	
141 151
  /// \brief Function to count the items in a graph.
142 152
  ///
143 153
  /// This function counts the items (nodes, arcs etc.) in a graph.
144 154
  /// The complexity of the function is linear because
145 155
  /// it iterates on all of the items.
146 156
  template <typename Graph, typename Item>
147 157
  inline int countItems(const Graph& g) {
148 158
    typedef typename ItemSetTraits<Graph, Item>::ItemIt ItemIt;
149 159
    int num = 0;
150 160
    for (ItemIt it(g); it != INVALID; ++it) {
151 161
      ++num;
152 162
    }
153 163
    return num;
154 164
  }
155 165

	
156 166
  // Node counting:
157 167

	
158 168
  namespace _core_bits {
159 169

	
160 170
    template <typename Graph, typename Enable = void>
161 171
    struct CountNodesSelector {
162 172
      static int count(const Graph &g) {
163 173
        return countItems<Graph, typename Graph::Node>(g);
164 174
      }
165 175
    };
166 176

	
167 177
    template <typename Graph>
168 178
    struct CountNodesSelector<
169 179
      Graph, typename
170 180
      enable_if<typename Graph::NodeNumTag, void>::type>
171 181
    {
172 182
      static int count(const Graph &g) {
173 183
        return g.nodeNum();
174 184
      }
175 185
    };
176 186
  }
177 187

	
178 188
  /// \brief Function to count the nodes in the graph.
179 189
  ///
180 190
  /// This function counts the nodes in the graph.
181 191
  /// The complexity of the function is <em>O</em>(<em>n</em>), but for some
182 192
  /// graph structures it is specialized to run in <em>O</em>(1).
183 193
  ///
184 194
  /// \note If the graph contains a \c nodeNum() member function and a
185 195
  /// \c NodeNumTag tag then this function calls directly the member
186 196
  /// function to query the cardinality of the node set.
187 197
  template <typename Graph>
188 198
  inline int countNodes(const Graph& g) {
189 199
    return _core_bits::CountNodesSelector<Graph>::count(g);
190 200
  }
191 201

	
192 202
  // Arc counting:
193 203

	
194 204
  namespace _core_bits {
195 205

	
196 206
    template <typename Graph, typename Enable = void>
197 207
    struct CountArcsSelector {
198 208
      static int count(const Graph &g) {
199 209
        return countItems<Graph, typename Graph::Arc>(g);
200 210
      }
201 211
    };
202 212

	
203 213
    template <typename Graph>
204 214
    struct CountArcsSelector<
205 215
      Graph,
206 216
      typename enable_if<typename Graph::ArcNumTag, void>::type>
207 217
    {
208 218
      static int count(const Graph &g) {
209 219
        return g.arcNum();
210 220
      }
211 221
    };
212 222
  }
213 223

	
214 224
  /// \brief Function to count the arcs in the graph.
215 225
  ///
216 226
  /// This function counts the arcs in the graph.
217 227
  /// The complexity of the function is <em>O</em>(<em>m</em>), but for some
218 228
  /// graph structures it is specialized to run in <em>O</em>(1).
219 229
  ///
220 230
  /// \note If the graph contains a \c arcNum() member function and a
221 231
  /// \c ArcNumTag tag then this function calls directly the member
222 232
  /// function to query the cardinality of the arc set.
223 233
  template <typename Graph>
224 234
  inline int countArcs(const Graph& g) {
225 235
    return _core_bits::CountArcsSelector<Graph>::count(g);
226 236
  }
227 237

	
228 238
  // Edge counting:
229 239

	
230 240
  namespace _core_bits {
231 241

	
232 242
    template <typename Graph, typename Enable = void>
233 243
    struct CountEdgesSelector {
234 244
      static int count(const Graph &g) {
235 245
        return countItems<Graph, typename Graph::Edge>(g);
236 246
      }
237 247
    };
238 248

	
239 249
    template <typename Graph>
240 250
    struct CountEdgesSelector<
241 251
      Graph,
242 252
      typename enable_if<typename Graph::EdgeNumTag, void>::type>
243 253
    {
244 254
      static int count(const Graph &g) {
245 255
        return g.edgeNum();
246 256
      }
247 257
    };
248 258
  }
249 259

	
250 260
  /// \brief Function to count the edges in the graph.
251 261
  ///
252 262
  /// This function counts the edges in the graph.
253 263
  /// The complexity of the function is <em>O</em>(<em>m</em>), but for some
254 264
  /// graph structures it is specialized to run in <em>O</em>(1).
255 265
  ///
256 266
  /// \note If the graph contains a \c edgeNum() member function and a
257 267
  /// \c EdgeNumTag tag then this function calls directly the member
258 268
  /// function to query the cardinality of the edge set.
259 269
  template <typename Graph>
260 270
  inline int countEdges(const Graph& g) {
261 271
    return _core_bits::CountEdgesSelector<Graph>::count(g);
262 272

	
263 273
  }
264 274

	
265 275

	
266 276
  template <typename Graph, typename DegIt>
267 277
  inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) {
268 278
    int num = 0;
269 279
    for (DegIt it(_g, _n); it != INVALID; ++it) {
270 280
      ++num;
271 281
    }
272 282
    return num;
273 283
  }
274 284

	
275 285
  /// \brief Function to count the number of the out-arcs from node \c n.
276 286
  ///
277 287
  /// This function counts the number of the out-arcs from node \c n
278 288
  /// in the graph \c g.
279 289
  template <typename Graph>
280 290
  inline int countOutArcs(const Graph& g,  const typename Graph::Node& n) {
281 291
    return countNodeDegree<Graph, typename Graph::OutArcIt>(g, n);
282 292
  }
283 293

	
284 294
  /// \brief Function to count the number of the in-arcs to node \c n.
285 295
  ///
286 296
  /// This function counts the number of the in-arcs to node \c n
287 297
  /// in the graph \c g.
288 298
  template <typename Graph>
289 299
  inline int countInArcs(const Graph& g,  const typename Graph::Node& n) {
290 300
    return countNodeDegree<Graph, typename Graph::InArcIt>(g, n);
291 301
  }
292 302

	
293 303
  /// \brief Function to count the number of the inc-edges to node \c n.
294 304
  ///
295 305
  /// This function counts the number of the inc-edges to node \c n
296 306
  /// in the undirected graph \c g.
297 307
  template <typename Graph>
298 308
  inline int countIncEdges(const Graph& g,  const typename Graph::Node& n) {
299 309
    return countNodeDegree<Graph, typename Graph::IncEdgeIt>(g, n);
300 310
  }
301 311

	
302 312
  namespace _core_bits {
303 313

	
304 314
    template <typename Digraph, typename Item, typename RefMap>
305 315
    class MapCopyBase {
306 316
    public:
307 317
      virtual void copy(const Digraph& from, const RefMap& refMap) = 0;
308 318

	
309 319
      virtual ~MapCopyBase() {}
310 320
    };
311 321

	
312 322
    template <typename Digraph, typename Item, typename RefMap,
313 323
              typename FromMap, typename ToMap>
314 324
    class MapCopy : public MapCopyBase<Digraph, Item, RefMap> {
315 325
    public:
316 326

	
317 327
      MapCopy(const FromMap& map, ToMap& tmap)
318 328
        : _map(map), _tmap(tmap) {}
319 329

	
320 330
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
321 331
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
322 332
        for (ItemIt it(digraph); it != INVALID; ++it) {
323 333
          _tmap.set(refMap[it], _map[it]);
324 334
        }
325 335
      }
326 336

	
327 337
    private:
328 338
      const FromMap& _map;
329 339
      ToMap& _tmap;
330 340
    };
331 341

	
332 342
    template <typename Digraph, typename Item, typename RefMap, typename It>
333 343
    class ItemCopy : public MapCopyBase<Digraph, Item, RefMap> {
334 344
    public:
335 345

	
336 346
      ItemCopy(const Item& item, It& it) : _item(item), _it(it) {}
337 347

	
338 348
      virtual void copy(const Digraph&, const RefMap& refMap) {
339 349
        _it = refMap[_item];
340 350
      }
341 351

	
342 352
    private:
343 353
      Item _item;
344 354
      It& _it;
345 355
    };
346 356

	
347 357
    template <typename Digraph, typename Item, typename RefMap, typename Ref>
348 358
    class RefCopy : public MapCopyBase<Digraph, Item, RefMap> {
349 359
    public:
350 360

	
351 361
      RefCopy(Ref& map) : _map(map) {}
352 362

	
353 363
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
354 364
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
355 365
        for (ItemIt it(digraph); it != INVALID; ++it) {
356 366
          _map.set(it, refMap[it]);
357 367
        }
358 368
      }
359 369

	
360 370
    private:
361 371
      Ref& _map;
362 372
    };
363 373

	
364 374
    template <typename Digraph, typename Item, typename RefMap,
365 375
              typename CrossRef>
366 376
    class CrossRefCopy : public MapCopyBase<Digraph, Item, RefMap> {
367 377
    public:
368 378

	
369 379
      CrossRefCopy(CrossRef& cmap) : _cmap(cmap) {}
370 380

	
371 381
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
372 382
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
373 383
        for (ItemIt it(digraph); it != INVALID; ++it) {
374 384
          _cmap.set(refMap[it], it);
375 385
        }
376 386
      }
377 387

	
378 388
    private:
379 389
      CrossRef& _cmap;
380 390
    };
381 391

	
382 392
    template <typename Digraph, typename Enable = void>
383 393
    struct DigraphCopySelector {
384 394
      template <typename From, typename NodeRefMap, typename ArcRefMap>
385 395
      static void copy(const From& from, Digraph &to,
386 396
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
387 397
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
388 398
          nodeRefMap[it] = to.addNode();
389 399
        }
390 400
        for (typename From::ArcIt it(from); it != INVALID; ++it) {
391 401
          arcRefMap[it] = to.addArc(nodeRefMap[from.source(it)],
392 402
                                    nodeRefMap[from.target(it)]);
393 403
        }
394 404
      }
395 405
    };
396 406

	
397 407
    template <typename Digraph>
398 408
    struct DigraphCopySelector<
399 409
      Digraph,
400 410
      typename enable_if<typename Digraph::BuildTag, void>::type>
401 411
    {
402 412
      template <typename From, typename NodeRefMap, typename ArcRefMap>
403 413
      static void copy(const From& from, Digraph &to,
404 414
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
405 415
        to.build(from, nodeRefMap, arcRefMap);
406 416
      }
407 417
    };
408 418

	
409 419
    template <typename Graph, typename Enable = void>
410 420
    struct GraphCopySelector {
411 421
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
412 422
      static void copy(const From& from, Graph &to,
413 423
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
414 424
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
415 425
          nodeRefMap[it] = to.addNode();
416 426
        }
417 427
        for (typename From::EdgeIt it(from); it != INVALID; ++it) {
418 428
          edgeRefMap[it] = to.addEdge(nodeRefMap[from.u(it)],
419 429
                                      nodeRefMap[from.v(it)]);
420 430
        }
421 431
      }
422 432
    };
423 433

	
424 434
    template <typename Graph>
425 435
    struct GraphCopySelector<
426 436
      Graph,
427 437
      typename enable_if<typename Graph::BuildTag, void>::type>
428 438
    {
429 439
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
430 440
      static void copy(const From& from, Graph &to,
431 441
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
432 442
        to.build(from, nodeRefMap, edgeRefMap);
433 443
      }
434 444
    };
435 445

	
436 446
  }
437 447

	
438 448
  /// \brief Class to copy a digraph.
439 449
  ///
440 450
  /// Class to copy a digraph to another digraph (duplicate a digraph). The
441 451
  /// simplest way of using it is through the \c digraphCopy() function.
442 452
  ///
443 453
  /// This class not only make a copy of a digraph, but it can create
444 454
  /// references and cross references between the nodes and arcs of
445 455
  /// the two digraphs, and it can copy maps to use with the newly created
446 456
  /// digraph.
447 457
  ///
448 458
  /// To make a copy from a digraph, first an instance of DigraphCopy
449 459
  /// should be created, then the data belongs to the digraph should
450 460
  /// assigned to copy. In the end, the \c run() member should be
451 461
  /// called.
452 462
  ///
453 463
  /// The next code copies a digraph with several data:
454 464
  ///\code
455 465
  ///  DigraphCopy<OrigGraph, NewGraph> cg(orig_graph, new_graph);
456 466
  ///  // Create references for the nodes
457 467
  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
458 468
  ///  cg.nodeRef(nr);
459 469
  ///  // Create cross references (inverse) for the arcs
460 470
  ///  NewGraph::ArcMap<OrigGraph::Arc> acr(new_graph);
461 471
  ///  cg.arcCrossRef(acr);
462 472
  ///  // Copy an arc map
463 473
  ///  OrigGraph::ArcMap<double> oamap(orig_graph);
464 474
  ///  NewGraph::ArcMap<double> namap(new_graph);
465 475
  ///  cg.arcMap(oamap, namap);
466 476
  ///  // Copy a node
467 477
  ///  OrigGraph::Node on;
468 478
  ///  NewGraph::Node nn;
469 479
  ///  cg.node(on, nn);
470 480
  ///  // Execute copying
471 481
  ///  cg.run();
472 482
  ///\endcode
473 483
  template <typename From, typename To>
474 484
  class DigraphCopy {
475 485
  private:
476 486

	
477 487
    typedef typename From::Node Node;
478 488
    typedef typename From::NodeIt NodeIt;
479 489
    typedef typename From::Arc Arc;
480 490
    typedef typename From::ArcIt ArcIt;
481 491

	
482 492
    typedef typename To::Node TNode;
483 493
    typedef typename To::Arc TArc;
484 494

	
485 495
    typedef typename From::template NodeMap<TNode> NodeRefMap;
486 496
    typedef typename From::template ArcMap<TArc> ArcRefMap;
487 497

	
488 498
  public:
489 499

	
490 500
    /// \brief Constructor of DigraphCopy.
491 501
    ///
492 502
    /// Constructor of DigraphCopy for copying the content of the
493 503
    /// \c from digraph into the \c to digraph.
494 504
    DigraphCopy(const From& from, To& to)
495 505
      : _from(from), _to(to) {}
496 506

	
497 507
    /// \brief Destructor of DigraphCopy
498 508
    ///
499 509
    /// Destructor of DigraphCopy.
500 510
    ~DigraphCopy() {
501 511
      for (int i = 0; i < int(_node_maps.size()); ++i) {
502 512
        delete _node_maps[i];
503 513
      }
504 514
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
505 515
        delete _arc_maps[i];
506 516
      }
507 517

	
508 518
    }
509 519

	
510 520
    /// \brief Copy the node references into the given map.
511 521
    ///
512 522
    /// This function copies the node references into the given map.
513 523
    /// The parameter should be a map, whose key type is the Node type of
514 524
    /// the source digraph, while the value type is the Node type of the
515 525
    /// destination digraph.
516 526
    template <typename NodeRef>
517 527
    DigraphCopy& nodeRef(NodeRef& map) {
518 528
      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
519 529
                           NodeRefMap, NodeRef>(map));
520 530
      return *this;
521 531
    }
522 532

	
523 533
    /// \brief Copy the node cross references into the given map.
524 534
    ///
525 535
    /// This function copies the node cross references (reverse references)
526 536
    /// into the given map. The parameter should be a map, whose key type
527 537
    /// is the Node type of the destination digraph, while the value type is
528 538
    /// the Node type of the source digraph.
529 539
    template <typename NodeCrossRef>
530 540
    DigraphCopy& nodeCrossRef(NodeCrossRef& map) {
531 541
      _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node,
532 542
                           NodeRefMap, NodeCrossRef>(map));
533 543
      return *this;
534 544
    }
535 545

	
536 546
    /// \brief Make a copy of the given node map.
537 547
    ///
538 548
    /// This function makes a copy of the given node map for the newly
539 549
    /// created digraph.
540 550
    /// The key type of the new map \c tmap should be the Node type of the
541 551
    /// destination digraph, and the key type of the original map \c map
542 552
    /// should be the Node type of the source digraph.
543 553
    template <typename FromMap, typename ToMap>
544 554
    DigraphCopy& nodeMap(const FromMap& map, ToMap& tmap) {
545 555
      _node_maps.push_back(new _core_bits::MapCopy<From, Node,
546 556
                           NodeRefMap, FromMap, ToMap>(map, tmap));
547 557
      return *this;
548 558
    }
549 559

	
550 560
    /// \brief Make a copy of the given node.
551 561
    ///
552 562
    /// This function makes a copy of the given node.
553 563
    DigraphCopy& node(const Node& node, TNode& tnode) {
554 564
      _node_maps.push_back(new _core_bits::ItemCopy<From, Node,
555 565
                           NodeRefMap, TNode>(node, tnode));
556 566
      return *this;
557 567
    }
558 568

	
559 569
    /// \brief Copy the arc references into the given map.
560 570
    ///
561 571
    /// This function copies the arc references into the given map.
562 572
    /// The parameter should be a map, whose key type is the Arc type of
563 573
    /// the source digraph, while the value type is the Arc type of the
564 574
    /// destination digraph.
565 575
    template <typename ArcRef>
566 576
    DigraphCopy& arcRef(ArcRef& map) {
567 577
      _arc_maps.push_back(new _core_bits::RefCopy<From, Arc,
568 578
                          ArcRefMap, ArcRef>(map));
569 579
      return *this;
570 580
    }
571 581

	
572 582
    /// \brief Copy the arc cross references into the given map.
573 583
    ///
574 584
    /// This function copies the arc cross references (reverse references)
575 585
    /// into the given map. The parameter should be a map, whose key type
576 586
    /// is the Arc type of the destination digraph, while the value type is
577 587
    /// the Arc type of the source digraph.
578 588
    template <typename ArcCrossRef>
579 589
    DigraphCopy& arcCrossRef(ArcCrossRef& map) {
580 590
      _arc_maps.push_back(new _core_bits::CrossRefCopy<From, Arc,
581 591
                          ArcRefMap, ArcCrossRef>(map));
582 592
      return *this;
583 593
    }
584 594

	
585 595
    /// \brief Make a copy of the given arc map.
586 596
    ///
587 597
    /// This function makes a copy of the given arc map for the newly
588 598
    /// created digraph.
589 599
    /// The key type of the new map \c tmap should be the Arc type of the
590 600
    /// destination digraph, and the key type of the original map \c map
591 601
    /// should be the Arc type of the source digraph.
592 602
    template <typename FromMap, typename ToMap>
593 603
    DigraphCopy& arcMap(const FromMap& map, ToMap& tmap) {
594 604
      _arc_maps.push_back(new _core_bits::MapCopy<From, Arc,
595 605
                          ArcRefMap, FromMap, ToMap>(map, tmap));
596 606
      return *this;
597 607
    }
598 608

	
599 609
    /// \brief Make a copy of the given arc.
600 610
    ///
601 611
    /// This function makes a copy of the given arc.
602 612
    DigraphCopy& arc(const Arc& arc, TArc& tarc) {
603 613
      _arc_maps.push_back(new _core_bits::ItemCopy<From, Arc,
604 614
                          ArcRefMap, TArc>(arc, tarc));
605 615
      return *this;
606 616
    }
607 617

	
608 618
    /// \brief Execute copying.
609 619
    ///
610 620
    /// This function executes the copying of the digraph along with the
611 621
    /// copying of the assigned data.
612 622
    void run() {
613 623
      NodeRefMap nodeRefMap(_from);
614 624
      ArcRefMap arcRefMap(_from);
615 625
      _core_bits::DigraphCopySelector<To>::
616 626
        copy(_from, _to, nodeRefMap, arcRefMap);
617 627
      for (int i = 0; i < int(_node_maps.size()); ++i) {
618 628
        _node_maps[i]->copy(_from, nodeRefMap);
619 629
      }
620 630
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
621 631
        _arc_maps[i]->copy(_from, arcRefMap);
622 632
      }
623 633
    }
624 634

	
625 635
  protected:
626 636

	
627 637
    const From& _from;
628 638
    To& _to;
629 639

	
630 640
    std::vector<_core_bits::MapCopyBase<From, Node, NodeRefMap>* >
631 641
      _node_maps;
632 642

	
633 643
    std::vector<_core_bits::MapCopyBase<From, Arc, ArcRefMap>* >
634 644
      _arc_maps;
635 645

	
636 646
  };
637 647

	
638 648
  /// \brief Copy a digraph to another digraph.
639 649
  ///
640 650
  /// This function copies a digraph to another digraph.
641 651
  /// The complete usage of it is detailed in the DigraphCopy class, but
642 652
  /// a short example shows a basic work:
643 653
  ///\code
644 654
  /// digraphCopy(src, trg).nodeRef(nr).arcCrossRef(acr).run();
645 655
  ///\endcode
646 656
  ///
647 657
  /// After the copy the \c nr map will contain the mapping from the
648 658
  /// nodes of the \c from digraph to the nodes of the \c to digraph and
649 659
  /// \c acr will contain the mapping from the arcs of the \c to digraph
650 660
  /// to the arcs of the \c from digraph.
651 661
  ///
652 662
  /// \see DigraphCopy
653 663
  template <typename From, typename To>
654 664
  DigraphCopy<From, To> digraphCopy(const From& from, To& to) {
655 665
    return DigraphCopy<From, To>(from, to);
656 666
  }
657 667

	
658 668
  /// \brief Class to copy a graph.
659 669
  ///
660 670
  /// Class to copy a graph to another graph (duplicate a graph). The
661 671
  /// simplest way of using it is through the \c graphCopy() function.
662 672
  ///
663 673
  /// This class not only make a copy of a graph, but it can create
664 674
  /// references and cross references between the nodes, edges and arcs of
665 675
  /// the two graphs, and it can copy maps for using with the newly created
666 676
  /// graph.
667 677
  ///
668 678
  /// To make a copy from a graph, first an instance of GraphCopy
669 679
  /// should be created, then the data belongs to the graph should
670 680
  /// assigned to copy. In the end, the \c run() member should be
671 681
  /// called.
672 682
  ///
673 683
  /// The next code copies a graph with several data:
674 684
  ///\code
675 685
  ///  GraphCopy<OrigGraph, NewGraph> cg(orig_graph, new_graph);
676 686
  ///  // Create references for the nodes
677 687
  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
678 688
  ///  cg.nodeRef(nr);
679 689
  ///  // Create cross references (inverse) for the edges
680 690
  ///  NewGraph::EdgeMap<OrigGraph::Edge> ecr(new_graph);
681 691
  ///  cg.edgeCrossRef(ecr);
682 692
  ///  // Copy an edge map
683 693
  ///  OrigGraph::EdgeMap<double> oemap(orig_graph);
684 694
  ///  NewGraph::EdgeMap<double> nemap(new_graph);
685 695
  ///  cg.edgeMap(oemap, nemap);
686 696
  ///  // Copy a node
687 697
  ///  OrigGraph::Node on;
688 698
  ///  NewGraph::Node nn;
689 699
  ///  cg.node(on, nn);
690 700
  ///  // Execute copying
691 701
  ///  cg.run();
692 702
  ///\endcode
693 703
  template <typename From, typename To>
694 704
  class GraphCopy {
695 705
  private:
696 706

	
697 707
    typedef typename From::Node Node;
698 708
    typedef typename From::NodeIt NodeIt;
699 709
    typedef typename From::Arc Arc;
700 710
    typedef typename From::ArcIt ArcIt;
701 711
    typedef typename From::Edge Edge;
702 712
    typedef typename From::EdgeIt EdgeIt;
703 713

	
704 714
    typedef typename To::Node TNode;
705 715
    typedef typename To::Arc TArc;
706 716
    typedef typename To::Edge TEdge;
707 717

	
708 718
    typedef typename From::template NodeMap<TNode> NodeRefMap;
709 719
    typedef typename From::template EdgeMap<TEdge> EdgeRefMap;
710 720

	
711 721
    struct ArcRefMap {
712 722
      ArcRefMap(const From& from, const To& to,
713 723
                const EdgeRefMap& edge_ref, const NodeRefMap& node_ref)
714 724
        : _from(from), _to(to),
715 725
          _edge_ref(edge_ref), _node_ref(node_ref) {}
716 726

	
717 727
      typedef typename From::Arc Key;
718 728
      typedef typename To::Arc Value;
719 729

	
720 730
      Value operator[](const Key& key) const {
721 731
        bool forward = _from.u(key) != _from.v(key) ?
722 732
          _node_ref[_from.source(key)] ==
723 733
          _to.source(_to.direct(_edge_ref[key], true)) :
724 734
          _from.direction(key);
725 735
        return _to.direct(_edge_ref[key], forward);
726 736
      }
727 737

	
728 738
      const From& _from;
729 739
      const To& _to;
730 740
      const EdgeRefMap& _edge_ref;
731 741
      const NodeRefMap& _node_ref;
732 742
    };
733 743

	
734 744
  public:
735 745

	
736 746
    /// \brief Constructor of GraphCopy.
737 747
    ///
738 748
    /// Constructor of GraphCopy for copying the content of the
739 749
    /// \c from graph into the \c to graph.
740 750
    GraphCopy(const From& from, To& to)
741 751
      : _from(from), _to(to) {}
742 752

	
743 753
    /// \brief Destructor of GraphCopy
744 754
    ///
745 755
    /// Destructor of GraphCopy.
746 756
    ~GraphCopy() {
747 757
      for (int i = 0; i < int(_node_maps.size()); ++i) {
748 758
        delete _node_maps[i];
749 759
      }
750 760
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
751 761
        delete _arc_maps[i];
752 762
      }
753 763
      for (int i = 0; i < int(_edge_maps.size()); ++i) {
754 764
        delete _edge_maps[i];
755 765
      }
756 766
    }
757 767

	
758 768
    /// \brief Copy the node references into the given map.
759 769
    ///
760 770
    /// This function copies the node references into the given map.
761 771
    /// The parameter should be a map, whose key type is the Node type of
762 772
    /// the source graph, while the value type is the Node type of the
763 773
    /// destination graph.
764 774
    template <typename NodeRef>
765 775
    GraphCopy& nodeRef(NodeRef& map) {
766 776
      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
767 777
                           NodeRefMap, NodeRef>(map));
768 778
      return *this;
769 779
    }
770 780

	
771 781
    /// \brief Copy the node cross references into the given map.
772 782
    ///
773 783
    /// This function copies the node cross references (reverse references)
774 784
    /// into the given map. The parameter should be a map, whose key type
775 785
    /// is the Node type of the destination graph, while the value type is
776 786
    /// the Node type of the source graph.
777 787
    template <typename NodeCrossRef>
778 788
    GraphCopy& nodeCrossRef(NodeCrossRef& map) {
779 789
      _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node,
780 790
                           NodeRefMap, NodeCrossRef>(map));
781 791
      return *this;
782 792
    }
783 793

	
784 794
    /// \brief Make a copy of the given node map.
785 795
    ///
786 796
    /// This function makes a copy of the given node map for the newly
787 797
    /// created graph.
788 798
    /// The key type of the new map \c tmap should be the Node type of the
789 799
    /// destination graph, and the key type of the original map \c map
790 800
    /// should be the Node type of the source graph.
791 801
    template <typename FromMap, typename ToMap>
792 802
    GraphCopy& nodeMap(const FromMap& map, ToMap& tmap) {
793 803
      _node_maps.push_back(new _core_bits::MapCopy<From, Node,
794 804
                           NodeRefMap, FromMap, ToMap>(map, tmap));
795 805
      return *this;
796 806
    }
797 807

	
798 808
    /// \brief Make a copy of the given node.
799 809
    ///
800 810
    /// This function makes a copy of the given node.
801 811
    GraphCopy& node(const Node& node, TNode& tnode) {
802 812
      _node_maps.push_back(new _core_bits::ItemCopy<From, Node,
803 813
                           NodeRefMap, TNode>(node, tnode));
804 814
      return *this;
805 815
    }
806 816

	
807 817
    /// \brief Copy the arc references into the given map.
808 818
    ///
809 819
    /// This function copies the arc references into the given map.
810 820
    /// The parameter should be a map, whose key type is the Arc type of
811 821
    /// the source graph, while the value type is the Arc type of the
812 822
    /// destination graph.
813 823
    template <typename ArcRef>
814 824
    GraphCopy& arcRef(ArcRef& map) {
815 825
      _arc_maps.push_back(new _core_bits::RefCopy<From, Arc,
816 826
                          ArcRefMap, ArcRef>(map));
817 827
      return *this;
818 828
    }
819 829

	
820 830
    /// \brief Copy the arc cross references into the given map.
821 831
    ///
822 832
    /// This function copies the arc cross references (reverse references)
823 833
    /// into the given map. The parameter should be a map, whose key type
824 834
    /// is the Arc type of the destination graph, while the value type is
825 835
    /// the Arc type of the source graph.
826 836
    template <typename ArcCrossRef>
827 837
    GraphCopy& arcCrossRef(ArcCrossRef& map) {
828 838
      _arc_maps.push_back(new _core_bits::CrossRefCopy<From, Arc,
829 839
                          ArcRefMap, ArcCrossRef>(map));
830 840
      return *this;
831 841
    }
832 842

	
833 843
    /// \brief Make a copy of the given arc map.
834 844
    ///
835 845
    /// This function makes a copy of the given arc map for the newly
836 846
    /// created graph.
837 847
    /// The key type of the new map \c tmap should be the Arc type of the
838 848
    /// destination graph, and the key type of the original map \c map
839 849
    /// should be the Arc type of the source graph.
840 850
    template <typename FromMap, typename ToMap>
841 851
    GraphCopy& arcMap(const FromMap& map, ToMap& tmap) {
842 852
      _arc_maps.push_back(new _core_bits::MapCopy<From, Arc,
843 853
                          ArcRefMap, FromMap, ToMap>(map, tmap));
844 854
      return *this;
845 855
    }
846 856

	
847 857
    /// \brief Make a copy of the given arc.
848 858
    ///
849 859
    /// This function makes a copy of the given arc.
850 860
    GraphCopy& arc(const Arc& arc, TArc& tarc) {
851 861
      _arc_maps.push_back(new _core_bits::ItemCopy<From, Arc,
852 862
                          ArcRefMap, TArc>(arc, tarc));
853 863
      return *this;
854 864
    }
855 865

	
856 866
    /// \brief Copy the edge references into the given map.
857 867
    ///
858 868
    /// This function copies the edge references into the given map.
859 869
    /// The parameter should be a map, whose key type is the Edge type of
860 870
    /// the source graph, while the value type is the Edge type of the
861 871
    /// destination graph.
862 872
    template <typename EdgeRef>
863 873
    GraphCopy& edgeRef(EdgeRef& map) {
864 874
      _edge_maps.push_back(new _core_bits::RefCopy<From, Edge,
865 875
                           EdgeRefMap, EdgeRef>(map));
866 876
      return *this;
867 877
    }
868 878

	
869 879
    /// \brief Copy the edge cross references into the given map.
870 880
    ///
871 881
    /// This function copies the edge cross references (reverse references)
872 882
    /// into the given map. The parameter should be a map, whose key type
873 883
    /// is the Edge type of the destination graph, while the value type is
874 884
    /// the Edge type of the source graph.
875 885
    template <typename EdgeCrossRef>
876 886
    GraphCopy& edgeCrossRef(EdgeCrossRef& map) {
877 887
      _edge_maps.push_back(new _core_bits::CrossRefCopy<From,
878 888
                           Edge, EdgeRefMap, EdgeCrossRef>(map));
879 889
      return *this;
880 890
    }
881 891

	
882 892
    /// \brief Make a copy of the given edge map.
883 893
    ///
884 894
    /// This function makes a copy of the given edge map for the newly
885 895
    /// created graph.
886 896
    /// The key type of the new map \c tmap should be the Edge type of the
887 897
    /// destination graph, and the key type of the original map \c map
888 898
    /// should be the Edge type of the source graph.
889 899
    template <typename FromMap, typename ToMap>
890 900
    GraphCopy& edgeMap(const FromMap& map, ToMap& tmap) {
891 901
      _edge_maps.push_back(new _core_bits::MapCopy<From, Edge,
892 902
                           EdgeRefMap, FromMap, ToMap>(map, tmap));
893 903
      return *this;
894 904
    }
895 905

	
896 906
    /// \brief Make a copy of the given edge.
897 907
    ///
898 908
    /// This function makes a copy of the given edge.
899 909
    GraphCopy& edge(const Edge& edge, TEdge& tedge) {
900 910
      _edge_maps.push_back(new _core_bits::ItemCopy<From, Edge,
901 911
                           EdgeRefMap, TEdge>(edge, tedge));
902 912
      return *this;
903 913
    }
904 914

	
905 915
    /// \brief Execute copying.
906 916
    ///
907 917
    /// This function executes the copying of the graph along with the
908 918
    /// copying of the assigned data.
909 919
    void run() {
910 920
      NodeRefMap nodeRefMap(_from);
911 921
      EdgeRefMap edgeRefMap(_from);
912 922
      ArcRefMap arcRefMap(_from, _to, edgeRefMap, nodeRefMap);
913 923
      _core_bits::GraphCopySelector<To>::
914 924
        copy(_from, _to, nodeRefMap, edgeRefMap);
915 925
      for (int i = 0; i < int(_node_maps.size()); ++i) {
916 926
        _node_maps[i]->copy(_from, nodeRefMap);
917 927
      }
918 928
      for (int i = 0; i < int(_edge_maps.size()); ++i) {
919 929
        _edge_maps[i]->copy(_from, edgeRefMap);
920 930
      }
921 931
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
922 932
        _arc_maps[i]->copy(_from, arcRefMap);
923 933
      }
924 934
    }
925 935

	
926 936
  private:
927 937

	
928 938
    const From& _from;
929 939
    To& _to;
930 940

	
931 941
    std::vector<_core_bits::MapCopyBase<From, Node, NodeRefMap>* >
932 942
      _node_maps;
933 943

	
934 944
    std::vector<_core_bits::MapCopyBase<From, Arc, ArcRefMap>* >
935 945
      _arc_maps;
936 946

	
937 947
    std::vector<_core_bits::MapCopyBase<From, Edge, EdgeRefMap>* >
938 948
      _edge_maps;
939 949

	
940 950
  };
941 951

	
942 952
  /// \brief Copy a graph to another graph.
943 953
  ///
944 954
  /// This function copies a graph to another graph.
945 955
  /// The complete usage of it is detailed in the GraphCopy class,
946 956
  /// but a short example shows a basic work:
947 957
  ///\code
948 958
  /// graphCopy(src, trg).nodeRef(nr).edgeCrossRef(ecr).run();
949 959
  ///\endcode
950 960
  ///
951 961
  /// After the copy the \c nr map will contain the mapping from the
952 962
  /// nodes of the \c from graph to the nodes of the \c to graph and
953 963
  /// \c ecr will contain the mapping from the edges of the \c to graph
954 964
  /// to the edges of the \c from graph.
955 965
  ///
956 966
  /// \see GraphCopy
957 967
  template <typename From, typename To>
958 968
  GraphCopy<From, To>
959 969
  graphCopy(const From& from, To& to) {
960 970
    return GraphCopy<From, To>(from, to);
961 971
  }
962 972

	
963 973
  namespace _core_bits {
964 974

	
965 975
    template <typename Graph, typename Enable = void>
966 976
    struct FindArcSelector {
967 977
      typedef typename Graph::Node Node;
968 978
      typedef typename Graph::Arc Arc;
969 979
      static Arc find(const Graph &g, Node u, Node v, Arc e) {
970 980
        if (e == INVALID) {
971 981
          g.firstOut(e, u);
972 982
        } else {
973 983
          g.nextOut(e);
974 984
        }
975 985
        while (e != INVALID && g.target(e) != v) {
976 986
          g.nextOut(e);
977 987
        }
978 988
        return e;
979 989
      }
980 990
    };
981 991

	
982 992
    template <typename Graph>
983 993
    struct FindArcSelector<
984 994
      Graph,
985 995
      typename enable_if<typename Graph::FindArcTag, void>::type>
986 996
    {
987 997
      typedef typename Graph::Node Node;
988 998
      typedef typename Graph::Arc Arc;
989 999
      static Arc find(const Graph &g, Node u, Node v, Arc prev) {
990 1000
        return g.findArc(u, v, prev);
991 1001
      }
992 1002
    };
993 1003
  }
994 1004

	
995 1005
  /// \brief Find an arc between two nodes of a digraph.
996 1006
  ///
997 1007
  /// This function finds an arc from node \c u to node \c v in the
998 1008
  /// digraph \c g.
999 1009
  ///
1000 1010
  /// If \c prev is \ref INVALID (this is the default value), then
1001 1011
  /// it finds the first arc from \c u to \c v. Otherwise it looks for
1002 1012
  /// the next arc from \c u to \c v after \c prev.
1003 1013
  /// \return The found arc or \ref INVALID if there is no such an arc.
1004 1014
  ///
1005 1015
  /// Thus you can iterate through each arc from \c u to \c v as it follows.
1006 1016
  ///\code
1007 1017
  /// for(Arc e = findArc(g,u,v); e != INVALID; e = findArc(g,u,v,e)) {
1008 1018
  ///   ...
1009 1019
  /// }
1010 1020
  ///\endcode
1011 1021
  ///
1012 1022
  /// \note \ref ConArcIt provides iterator interface for the same
1013 1023
  /// functionality.
1014 1024
  ///
1015 1025
  ///\sa ConArcIt
1016 1026
  ///\sa ArcLookUp, AllArcLookUp, DynArcLookUp
1017 1027
  template <typename Graph>
1018 1028
  inline typename Graph::Arc
1019 1029
  findArc(const Graph &g, typename Graph::Node u, typename Graph::Node v,
1020 1030
          typename Graph::Arc prev = INVALID) {
1021 1031
    return _core_bits::FindArcSelector<Graph>::find(g, u, v, prev);
1022 1032
  }
1023 1033

	
1024 1034
  /// \brief Iterator for iterating on parallel arcs connecting the same nodes.
1025 1035
  ///
1026 1036
  /// Iterator for iterating on parallel arcs connecting the same nodes. It is
1027 1037
  /// a higher level interface for the \ref findArc() function. You can
1028 1038
  /// use it the following way:
1029 1039
  ///\code
1030 1040
  /// for (ConArcIt<Graph> it(g, src, trg); it != INVALID; ++it) {
1031 1041
  ///   ...
1032 1042
  /// }
1033 1043
  ///\endcode
1034 1044
  ///
1035 1045
  ///\sa findArc()
1036 1046
  ///\sa ArcLookUp, AllArcLookUp, DynArcLookUp
1037
  template <typename _Graph>
1038
  class ConArcIt : public _Graph::Arc {
1047
  template <typename GR>
1048
  class ConArcIt : public GR::Arc {
1049
    typedef typename GR::Arc Parent;
1050

	
1039 1051
  public:
1040 1052

	
1041
    typedef _Graph Graph;
1042
    typedef typename Graph::Arc Parent;
1043

	
1044
    typedef typename Graph::Arc Arc;
1045
    typedef typename Graph::Node Node;
1053
    typedef typename GR::Arc Arc;
1054
    typedef typename GR::Node Node;
1046 1055

	
1047 1056
    /// \brief Constructor.
1048 1057
    ///
1049 1058
    /// Construct a new ConArcIt iterating on the arcs that
1050 1059
    /// connects nodes \c u and \c v.
1051
    ConArcIt(const Graph& g, Node u, Node v) : _graph(g) {
1060
    ConArcIt(const GR& g, Node u, Node v) : _graph(g) {
1052 1061
      Parent::operator=(findArc(_graph, u, v));
1053 1062
    }
1054 1063

	
1055 1064
    /// \brief Constructor.
1056 1065
    ///
1057 1066
    /// Construct a new ConArcIt that continues the iterating from arc \c a.
1058
    ConArcIt(const Graph& g, Arc a) : Parent(a), _graph(g) {}
1067
    ConArcIt(const GR& g, Arc a) : Parent(a), _graph(g) {}
1059 1068

	
1060 1069
    /// \brief Increment operator.
1061 1070
    ///
1062 1071
    /// It increments the iterator and gives back the next arc.
1063 1072
    ConArcIt& operator++() {
1064 1073
      Parent::operator=(findArc(_graph, _graph.source(*this),
1065 1074
                                _graph.target(*this), *this));
1066 1075
      return *this;
1067 1076
    }
1068 1077
  private:
1069
    const Graph& _graph;
1078
    const GR& _graph;
1070 1079
  };
1071 1080

	
1072 1081
  namespace _core_bits {
1073 1082

	
1074 1083
    template <typename Graph, typename Enable = void>
1075 1084
    struct FindEdgeSelector {
1076 1085
      typedef typename Graph::Node Node;
1077 1086
      typedef typename Graph::Edge Edge;
1078 1087
      static Edge find(const Graph &g, Node u, Node v, Edge e) {
1079 1088
        bool b;
1080 1089
        if (u != v) {
1081 1090
          if (e == INVALID) {
1082 1091
            g.firstInc(e, b, u);
1083 1092
          } else {
1084 1093
            b = g.u(e) == u;
1085 1094
            g.nextInc(e, b);
1086 1095
          }
1087 1096
          while (e != INVALID && (b ? g.v(e) : g.u(e)) != v) {
1088 1097
            g.nextInc(e, b);
1089 1098
          }
1090 1099
        } else {
1091 1100
          if (e == INVALID) {
1092 1101
            g.firstInc(e, b, u);
1093 1102
          } else {
1094 1103
            b = true;
1095 1104
            g.nextInc(e, b);
1096 1105
          }
1097 1106
          while (e != INVALID && (!b || g.v(e) != v)) {
1098 1107
            g.nextInc(e, b);
1099 1108
          }
1100 1109
        }
1101 1110
        return e;
1102 1111
      }
1103 1112
    };
1104 1113

	
1105 1114
    template <typename Graph>
1106 1115
    struct FindEdgeSelector<
1107 1116
      Graph,
1108 1117
      typename enable_if<typename Graph::FindEdgeTag, void>::type>
1109 1118
    {
1110 1119
      typedef typename Graph::Node Node;
1111 1120
      typedef typename Graph::Edge Edge;
1112 1121
      static Edge find(const Graph &g, Node u, Node v, Edge prev) {
1113 1122
        return g.findEdge(u, v, prev);
1114 1123
      }
1115 1124
    };
1116 1125
  }
1117 1126

	
1118 1127
  /// \brief Find an edge between two nodes of a graph.
1119 1128
  ///
1120 1129
  /// This function finds an edge from node \c u to node \c v in graph \c g.
1121 1130
  /// If node \c u and node \c v is equal then each loop edge
1122 1131
  /// will be enumerated once.
1123 1132
  ///
1124 1133
  /// If \c prev is \ref INVALID (this is the default value), then
1125 1134
  /// it finds the first edge from \c u to \c v. Otherwise it looks for
1126 1135
  /// the next edge from \c u to \c v after \c prev.
1127 1136
  /// \return The found edge or \ref INVALID if there is no such an edge.
1128 1137
  ///
1129 1138
  /// Thus you can iterate through each edge between \c u and \c v
1130 1139
  /// as it follows.
1131 1140
  ///\code
1132 1141
  /// for(Edge e = findEdge(g,u,v); e != INVALID; e = findEdge(g,u,v,e)) {
1133 1142
  ///   ...
1134 1143
  /// }
1135 1144
  ///\endcode
1136 1145
  ///
1137 1146
  /// \note \ref ConEdgeIt provides iterator interface for the same
1138 1147
  /// functionality.
1139 1148
  ///
1140 1149
  ///\sa ConEdgeIt
1141 1150
  template <typename Graph>
1142 1151
  inline typename Graph::Edge
1143 1152
  findEdge(const Graph &g, typename Graph::Node u, typename Graph::Node v,
1144 1153
            typename Graph::Edge p = INVALID) {
1145 1154
    return _core_bits::FindEdgeSelector<Graph>::find(g, u, v, p);
1146 1155
  }
1147 1156

	
1148 1157
  /// \brief Iterator for iterating on parallel edges connecting the same nodes.
1149 1158
  ///
1150 1159
  /// Iterator for iterating on parallel edges connecting the same nodes.
1151 1160
  /// It is a higher level interface for the findEdge() function. You can
1152 1161
  /// use it the following way:
1153 1162
  ///\code
1154 1163
  /// for (ConEdgeIt<Graph> it(g, u, v); it != INVALID; ++it) {
1155 1164
  ///   ...
1156 1165
  /// }
1157 1166
  ///\endcode
1158 1167
  ///
1159 1168
  ///\sa findEdge()
1160
  template <typename _Graph>
1161
  class ConEdgeIt : public _Graph::Edge {
1169
  template <typename GR>
1170
  class ConEdgeIt : public GR::Edge {
1171
    typedef typename GR::Edge Parent;
1172

	
1162 1173
  public:
1163 1174

	
1164
    typedef _Graph Graph;
1165
    typedef typename Graph::Edge Parent;
1166

	
1167
    typedef typename Graph::Edge Edge;
1168
    typedef typename Graph::Node Node;
1175
    typedef typename GR::Edge Edge;
1176
    typedef typename GR::Node Node;
1169 1177

	
1170 1178
    /// \brief Constructor.
1171 1179
    ///
1172 1180
    /// Construct a new ConEdgeIt iterating on the edges that
1173 1181
    /// connects nodes \c u and \c v.
1174
    ConEdgeIt(const Graph& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
1182
    ConEdgeIt(const GR& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
1175 1183
      Parent::operator=(findEdge(_graph, _u, _v));
1176 1184
    }
1177 1185

	
1178 1186
    /// \brief Constructor.
1179 1187
    ///
1180 1188
    /// Construct a new ConEdgeIt that continues iterating from edge \c e.
1181
    ConEdgeIt(const Graph& g, Edge e) : Parent(e), _graph(g) {}
1189
    ConEdgeIt(const GR& g, Edge e) : Parent(e), _graph(g) {}
1182 1190

	
1183 1191
    /// \brief Increment operator.
1184 1192
    ///
1185 1193
    /// It increments the iterator and gives back the next edge.
1186 1194
    ConEdgeIt& operator++() {
1187 1195
      Parent::operator=(findEdge(_graph, _u, _v, *this));
1188 1196
      return *this;
1189 1197
    }
1190 1198
  private:
1191
    const Graph& _graph;
1199
    const GR& _graph;
1192 1200
    Node _u, _v;
1193 1201
  };
1194 1202

	
1195 1203

	
1196 1204
  ///Dynamic arc look-up between given endpoints.
1197 1205

	
1198 1206
  ///Using this class, you can find an arc in a digraph from a given
1199 1207
  ///source to a given target in amortized time <em>O</em>(log<em>d</em>),
1200 1208
  ///where <em>d</em> is the out-degree of the source node.
1201 1209
  ///
1202 1210
  ///It is possible to find \e all parallel arcs between two nodes with
1203 1211
  ///the \c operator() member.
1204 1212
  ///
1205 1213
  ///This is a dynamic data structure. Consider to use \ref ArcLookUp or
1206 1214
  ///\ref AllArcLookUp if your digraph is not changed so frequently.
1207 1215
  ///
1208 1216
  ///This class uses a self-adjusting binary search tree, the Splay tree
1209 1217
  ///of Sleator and Tarjan to guarantee the logarithmic amortized
1210 1218
  ///time bound for arc look-ups. This class also guarantees the
1211 1219
  ///optimal time bound in a constant factor for any distribution of
1212 1220
  ///queries.
1213 1221
  ///
1214
  ///\tparam G The type of the underlying digraph.
1222
  ///\tparam GR The type of the underlying digraph.
1215 1223
  ///
1216 1224
  ///\sa ArcLookUp
1217 1225
  ///\sa AllArcLookUp
1218
  template<class G>
1226
  template <typename GR>
1219 1227
  class DynArcLookUp
1220
    : protected ItemSetTraits<G, typename G::Arc>::ItemNotifier::ObserverBase
1228
    : protected ItemSetTraits<GR, typename GR::Arc>::ItemNotifier::ObserverBase
1221 1229
  {
1222
  public:
1223
    typedef typename ItemSetTraits<G, typename G::Arc>
1230
    typedef typename ItemSetTraits<GR, typename GR::Arc>
1224 1231
    ::ItemNotifier::ObserverBase Parent;
1225 1232

	
1226
    TEMPLATE_DIGRAPH_TYPEDEFS(G);
1227
    typedef G Digraph;
1233
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
1234

	
1235
  public:
1236

	
1237
    /// The Digraph type
1238
    typedef GR Digraph;
1228 1239

	
1229 1240
  protected:
1230 1241

	
1231
    class AutoNodeMap : public ItemSetTraits<G, Node>::template Map<Arc>::Type {
1242
    class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type {
1243
      typedef typename ItemSetTraits<GR, Node>::template Map<Arc>::Type Parent;
1244

	
1232 1245
    public:
1233 1246

	
1234
      typedef typename ItemSetTraits<G, Node>::template Map<Arc>::Type Parent;
1235

	
1236
      AutoNodeMap(const G& digraph) : Parent(digraph, INVALID) {}
1247
      AutoNodeMap(const GR& digraph) : Parent(digraph, INVALID) {}
1237 1248

	
1238 1249
      virtual void add(const Node& node) {
1239 1250
        Parent::add(node);
1240 1251
        Parent::set(node, INVALID);
1241 1252
      }
1242 1253

	
1243 1254
      virtual void add(const std::vector<Node>& nodes) {
1244 1255
        Parent::add(nodes);
1245 1256
        for (int i = 0; i < int(nodes.size()); ++i) {
1246 1257
          Parent::set(nodes[i], INVALID);
1247 1258
        }
1248 1259
      }
1249 1260

	
1250 1261
      virtual void build() {
1251 1262
        Parent::build();
1252 1263
        Node it;
1253 1264
        typename Parent::Notifier* nf = Parent::notifier();
1254 1265
        for (nf->first(it); it != INVALID; nf->next(it)) {
1255 1266
          Parent::set(it, INVALID);
1256 1267
        }
1257 1268
      }
1258 1269
    };
1259 1270

	
1260
    const Digraph &_g;
1261
    AutoNodeMap _head;
1262
    typename Digraph::template ArcMap<Arc> _parent;
1263
    typename Digraph::template ArcMap<Arc> _left;
1264
    typename Digraph::template ArcMap<Arc> _right;
1265

	
1266 1271
    class ArcLess {
1267 1272
      const Digraph &g;
1268 1273
    public:
1269 1274
      ArcLess(const Digraph &_g) : g(_g) {}
1270 1275
      bool operator()(Arc a,Arc b) const
1271 1276
      {
1272 1277
        return g.target(a)<g.target(b);
1273 1278
      }
1274 1279
    };
1275 1280

	
1281
  protected: 
1282

	
1283
    const Digraph &_g;
1284
    AutoNodeMap _head;
1285
    typename Digraph::template ArcMap<Arc> _parent;
1286
    typename Digraph::template ArcMap<Arc> _left;
1287
    typename Digraph::template ArcMap<Arc> _right;
1288

	
1276 1289
  public:
1277 1290

	
1278 1291
    ///Constructor
1279 1292

	
1280 1293
    ///Constructor.
1281 1294
    ///
1282 1295
    ///It builds up the search database.
1283 1296
    DynArcLookUp(const Digraph &g)
1284 1297
      : _g(g),_head(g),_parent(g),_left(g),_right(g)
1285 1298
    {
1286 1299
      Parent::attach(_g.notifier(typename Digraph::Arc()));
1287 1300
      refresh();
1288 1301
    }
1289 1302

	
1290 1303
  protected:
1291 1304

	
1292 1305
    virtual void add(const Arc& arc) {
1293 1306
      insert(arc);
1294 1307
    }
1295 1308

	
1296 1309
    virtual void add(const std::vector<Arc>& arcs) {
1297 1310
      for (int i = 0; i < int(arcs.size()); ++i) {
1298 1311
        insert(arcs[i]);
1299 1312
      }
1300 1313
    }
1301 1314

	
1302 1315
    virtual void erase(const Arc& arc) {
1303 1316
      remove(arc);
1304 1317
    }
1305 1318

	
1306 1319
    virtual void erase(const std::vector<Arc>& arcs) {
1307 1320
      for (int i = 0; i < int(arcs.size()); ++i) {
1308 1321
        remove(arcs[i]);
1309 1322
      }
1310 1323
    }
1311 1324

	
1312 1325
    virtual void build() {
1313 1326
      refresh();
1314 1327
    }
1315 1328

	
1316 1329
    virtual void clear() {
1317 1330
      for(NodeIt n(_g);n!=INVALID;++n) {
1318
        _head.set(n, INVALID);
1331
        _head[n] = INVALID;
1319 1332
      }
1320 1333
    }
1321 1334

	
1322 1335
    void insert(Arc arc) {
1323 1336
      Node s = _g.source(arc);
1324 1337
      Node t = _g.target(arc);
1325
      _left.set(arc, INVALID);
1326
      _right.set(arc, INVALID);
1338
      _left[arc] = INVALID;
1339
      _right[arc] = INVALID;
1327 1340

	
1328 1341
      Arc e = _head[s];
1329 1342
      if (e == INVALID) {
1330
        _head.set(s, arc);
1331
        _parent.set(arc, INVALID);
1343
        _head[s] = arc;
1344
        _parent[arc] = INVALID;
1332 1345
        return;
1333 1346
      }
1334 1347
      while (true) {
1335 1348
        if (t < _g.target(e)) {
1336 1349
          if (_left[e] == INVALID) {
1337
            _left.set(e, arc);
1338
            _parent.set(arc, e);
1350
            _left[e] = arc;
1351
            _parent[arc] = e;
1339 1352
            splay(arc);
1340 1353
            return;
1341 1354
          } else {
1342 1355
            e = _left[e];
1343 1356
          }
1344 1357
        } else {
1345 1358
          if (_right[e] == INVALID) {
1346
            _right.set(e, arc);
1347
            _parent.set(arc, e);
1359
            _right[e] = arc;
1360
            _parent[arc] = e;
1348 1361
            splay(arc);
1349 1362
            return;
1350 1363
          } else {
1351 1364
            e = _right[e];
1352 1365
          }
1353 1366
        }
1354 1367
      }
1355 1368
    }
1356 1369

	
1357 1370
    void remove(Arc arc) {
1358 1371
      if (_left[arc] == INVALID) {
1359 1372
        if (_right[arc] != INVALID) {
1360
          _parent.set(_right[arc], _parent[arc]);
1373
          _parent[_right[arc]] = _parent[arc];
1361 1374
        }
1362 1375
        if (_parent[arc] != INVALID) {
1363 1376
          if (_left[_parent[arc]] == arc) {
1364
            _left.set(_parent[arc], _right[arc]);
1377
            _left[_parent[arc]] = _right[arc];
1365 1378
          } else {
1366
            _right.set(_parent[arc], _right[arc]);
1379
            _right[_parent[arc]] = _right[arc];
1367 1380
          }
1368 1381
        } else {
1369
          _head.set(_g.source(arc), _right[arc]);
1382
          _head[_g.source(arc)] = _right[arc];
1370 1383
        }
1371 1384
      } else if (_right[arc] == INVALID) {
1372
        _parent.set(_left[arc], _parent[arc]);
1385
        _parent[_left[arc]] = _parent[arc];
1373 1386
        if (_parent[arc] != INVALID) {
1374 1387
          if (_left[_parent[arc]] == arc) {
1375
            _left.set(_parent[arc], _left[arc]);
1388
            _left[_parent[arc]] = _left[arc];
1376 1389
          } else {
1377
            _right.set(_parent[arc], _left[arc]);
1390
            _right[_parent[arc]] = _left[arc];
1378 1391
          }
1379 1392
        } else {
1380
          _head.set(_g.source(arc), _left[arc]);
1393
          _head[_g.source(arc)] = _left[arc];
1381 1394
        }
1382 1395
      } else {
1383 1396
        Arc e = _left[arc];
1384 1397
        if (_right[e] != INVALID) {
1385 1398
          e = _right[e];
1386 1399
          while (_right[e] != INVALID) {
1387 1400
            e = _right[e];
1388 1401
          }
1389 1402
          Arc s = _parent[e];
1390
          _right.set(_parent[e], _left[e]);
1403
          _right[_parent[e]] = _left[e];
1391 1404
          if (_left[e] != INVALID) {
1392
            _parent.set(_left[e], _parent[e]);
1405
            _parent[_left[e]] = _parent[e];
1393 1406
          }
1394 1407

	
1395
          _left.set(e, _left[arc]);
1396
          _parent.set(_left[arc], e);
1397
          _right.set(e, _right[arc]);
1398
          _parent.set(_right[arc], e);
1408
          _left[e] = _left[arc];
1409
          _parent[_left[arc]] = e;
1410
          _right[e] = _right[arc];
1411
          _parent[_right[arc]] = e;
1399 1412

	
1400
          _parent.set(e, _parent[arc]);
1413
          _parent[e] = _parent[arc];
1401 1414
          if (_parent[arc] != INVALID) {
1402 1415
            if (_left[_parent[arc]] == arc) {
1403
              _left.set(_parent[arc], e);
1416
              _left[_parent[arc]] = e;
1404 1417
            } else {
1405
              _right.set(_parent[arc], e);
1418
              _right[_parent[arc]] = e;
1406 1419
            }
1407 1420
          }
1408 1421
          splay(s);
1409 1422
        } else {
1410
          _right.set(e, _right[arc]);
1411
          _parent.set(_right[arc], e);
1412
          _parent.set(e, _parent[arc]);
1423
          _right[e] = _right[arc];
1424
          _parent[_right[arc]] = e;
1425
          _parent[e] = _parent[arc];
1413 1426

	
1414 1427
          if (_parent[arc] != INVALID) {
1415 1428
            if (_left[_parent[arc]] == arc) {
1416
              _left.set(_parent[arc], e);
1429
              _left[_parent[arc]] = e;
1417 1430
            } else {
1418
              _right.set(_parent[arc], e);
1431
              _right[_parent[arc]] = e;
1419 1432
            }
1420 1433
          } else {
1421
            _head.set(_g.source(arc), e);
1434
            _head[_g.source(arc)] = e;
1422 1435
          }
1423 1436
        }
1424 1437
      }
1425 1438
    }
1426 1439

	
1427 1440
    Arc refreshRec(std::vector<Arc> &v,int a,int b)
1428 1441
    {
1429 1442
      int m=(a+b)/2;
1430 1443
      Arc me=v[m];
1431 1444
      if (a < m) {
1432 1445
        Arc left = refreshRec(v,a,m-1);
1433
        _left.set(me, left);
1434
        _parent.set(left, me);
1446
        _left[me] = left;
1447
        _parent[left] = me;
1435 1448
      } else {
1436
        _left.set(me, INVALID);
1449
        _left[me] = INVALID;
1437 1450
      }
1438 1451
      if (m < b) {
1439 1452
        Arc right = refreshRec(v,m+1,b);
1440
        _right.set(me, right);
1441
        _parent.set(right, me);
1453
        _right[me] = right;
1454
        _parent[right] = me;
1442 1455
      } else {
1443
        _right.set(me, INVALID);
1456
        _right[me] = INVALID;
1444 1457
      }
1445 1458
      return me;
1446 1459
    }
1447 1460

	
1448 1461
    void refresh() {
1449 1462
      for(NodeIt n(_g);n!=INVALID;++n) {
1450 1463
        std::vector<Arc> v;
1451 1464
        for(OutArcIt a(_g,n);a!=INVALID;++a) v.push_back(a);
1452 1465
        if (!v.empty()) {
1453 1466
          std::sort(v.begin(),v.end(),ArcLess(_g));
1454 1467
          Arc head = refreshRec(v,0,v.size()-1);
1455
          _head.set(n, head);
1456
          _parent.set(head, INVALID);
1468
          _head[n] = head;
1469
          _parent[head] = INVALID;
1457 1470
        }
1458
        else _head.set(n, INVALID);
1471
        else _head[n] = INVALID;
1459 1472
      }
1460 1473
    }
1461 1474

	
1462 1475
    void zig(Arc v) {
1463 1476
      Arc w = _parent[v];
1464
      _parent.set(v, _parent[w]);
1465
      _parent.set(w, v);
1466
      _left.set(w, _right[v]);
1467
      _right.set(v, w);
1477
      _parent[v] = _parent[w];
1478
      _parent[w] = v;
1479
      _left[w] = _right[v];
1480
      _right[v] = w;
1468 1481
      if (_parent[v] != INVALID) {
1469 1482
        if (_right[_parent[v]] == w) {
1470
          _right.set(_parent[v], v);
1483
          _right[_parent[v]] = v;
1471 1484
        } else {
1472
          _left.set(_parent[v], v);
1485
          _left[_parent[v]] = v;
1473 1486
        }
1474 1487
      }
1475 1488
      if (_left[w] != INVALID){
1476
        _parent.set(_left[w], w);
1489
        _parent[_left[w]] = w;
1477 1490
      }
1478 1491
    }
1479 1492

	
1480 1493
    void zag(Arc v) {
1481 1494
      Arc w = _parent[v];
1482
      _parent.set(v, _parent[w]);
1483
      _parent.set(w, v);
1484
      _right.set(w, _left[v]);
1485
      _left.set(v, w);
1495
      _parent[v] = _parent[w];
1496
      _parent[w] = v;
1497
      _right[w] = _left[v];
1498
      _left[v] = w;
1486 1499
      if (_parent[v] != INVALID){
1487 1500
        if (_left[_parent[v]] == w) {
1488
          _left.set(_parent[v], v);
1501
          _left[_parent[v]] = v;
1489 1502
        } else {
1490
          _right.set(_parent[v], v);
1503
          _right[_parent[v]] = v;
1491 1504
        }
1492 1505
      }
1493 1506
      if (_right[w] != INVALID){
1494
        _parent.set(_right[w], w);
1507
        _parent[_right[w]] = w;
1495 1508
      }
1496 1509
    }
1497 1510

	
1498 1511
    void splay(Arc v) {
1499 1512
      while (_parent[v] != INVALID) {
1500 1513
        if (v == _left[_parent[v]]) {
1501 1514
          if (_parent[_parent[v]] == INVALID) {
1502 1515
            zig(v);
1503 1516
          } else {
1504 1517
            if (_parent[v] == _left[_parent[_parent[v]]]) {
1505 1518
              zig(_parent[v]);
1506 1519
              zig(v);
1507 1520
            } else {
1508 1521
              zig(v);
1509 1522
              zag(v);
1510 1523
            }
1511 1524
          }
1512 1525
        } else {
1513 1526
          if (_parent[_parent[v]] == INVALID) {
1514 1527
            zag(v);
1515 1528
          } else {
1516 1529
            if (_parent[v] == _left[_parent[_parent[v]]]) {
1517 1530
              zag(v);
1518 1531
              zig(v);
1519 1532
            } else {
1520 1533
              zag(_parent[v]);
1521 1534
              zag(v);
1522 1535
            }
1523 1536
          }
1524 1537
        }
1525 1538
      }
1526 1539
      _head[_g.source(v)] = v;
1527 1540
    }
1528 1541

	
1529 1542

	
1530 1543
  public:
1531 1544

	
1532 1545
    ///Find an arc between two nodes.
1533 1546

	
1534 1547
    ///Find an arc between two nodes.
1535 1548
    ///\param s The source node.
1536 1549
    ///\param t The target node.
1537 1550
    ///\param p The previous arc between \c s and \c t. It it is INVALID or
1538 1551
    ///not given, the operator finds the first appropriate arc.
1539 1552
    ///\return An arc from \c s to \c t after \c p or
1540 1553
    ///\ref INVALID if there is no more.
1541 1554
    ///
1542 1555
    ///For example, you can count the number of arcs from \c u to \c v in the
1543 1556
    ///following way.
1544 1557
    ///\code
1545 1558
    ///DynArcLookUp<ListDigraph> ae(g);
1546 1559
    ///...
1547 1560
    ///int n = 0;
1548 1561
    ///for(Arc a = ae(u,v); a != INVALID; a = ae(u,v,a)) n++;
1549 1562
    ///\endcode
1550 1563
    ///
1551 1564
    ///Finding the arcs take at most <em>O</em>(log<em>d</em>)
1552 1565
    ///amortized time, specifically, the time complexity of the lookups
1553 1566
    ///is equal to the optimal search tree implementation for the
1554 1567
    ///current query distribution in a constant factor.
1555 1568
    ///
1556 1569
    ///\note This is a dynamic data structure, therefore the data
1557 1570
    ///structure is updated after each graph alteration. Thus although
1558 1571
    ///this data structure is theoretically faster than \ref ArcLookUp
1559 1572
    ///and \ref AllArcLookUp, it often provides worse performance than
1560 1573
    ///them.
1561 1574
    Arc operator()(Node s, Node t, Arc p = INVALID) const  {
1562 1575
      if (p == INVALID) {
1563 1576
        Arc a = _head[s];
1564 1577
        if (a == INVALID) return INVALID;
1565 1578
        Arc r = INVALID;
1566 1579
        while (true) {
1567 1580
          if (_g.target(a) < t) {
1568 1581
            if (_right[a] == INVALID) {
1569 1582
              const_cast<DynArcLookUp&>(*this).splay(a);
1570 1583
              return r;
1571 1584
            } else {
1572 1585
              a = _right[a];
1573 1586
            }
1574 1587
          } else {
1575 1588
            if (_g.target(a) == t) {
1576 1589
              r = a;
1577 1590
            }
1578 1591
            if (_left[a] == INVALID) {
1579 1592
              const_cast<DynArcLookUp&>(*this).splay(a);
1580 1593
              return r;
1581 1594
            } else {
1582 1595
              a = _left[a];
1583 1596
            }
1584 1597
          }
1585 1598
        }
1586 1599
      } else {
1587 1600
        Arc a = p;
1588 1601
        if (_right[a] != INVALID) {
1589 1602
          a = _right[a];
1590 1603
          while (_left[a] != INVALID) {
1591 1604
            a = _left[a];
1592 1605
          }
1593 1606
          const_cast<DynArcLookUp&>(*this).splay(a);
1594 1607
        } else {
1595 1608
          while (_parent[a] != INVALID && _right[_parent[a]] ==  a) {
1596 1609
            a = _parent[a];
1597 1610
          }
1598 1611
          if (_parent[a] == INVALID) {
1599 1612
            return INVALID;
1600 1613
          } else {
1601 1614
            a = _parent[a];
1602 1615
            const_cast<DynArcLookUp&>(*this).splay(a);
1603 1616
          }
1604 1617
        }
1605 1618
        if (_g.target(a) == t) return a;
1606 1619
        else return INVALID;
1607 1620
      }
1608 1621
    }
1609 1622

	
1610 1623
  };
1611 1624

	
1612 1625
  ///Fast arc look-up between given endpoints.
1613 1626

	
1614 1627
  ///Using this class, you can find an arc in a digraph from a given
1615 1628
  ///source to a given target in time <em>O</em>(log<em>d</em>),
1616 1629
  ///where <em>d</em> is the out-degree of the source node.
1617 1630
  ///
1618 1631
  ///It is not possible to find \e all parallel arcs between two nodes.
1619 1632
  ///Use \ref AllArcLookUp for this purpose.
1620 1633
  ///
1621 1634
  ///\warning This class is static, so you should call refresh() (or at
1622 1635
  ///least refresh(Node)) to refresh this data structure whenever the
1623 1636
  ///digraph changes. This is a time consuming (superlinearly proportional
1624 1637
  ///(<em>O</em>(<em>m</em> log<em>m</em>)) to the number of arcs).
1625 1638
  ///
1626
  ///\tparam G The type of the underlying digraph.
1639
  ///\tparam GR The type of the underlying digraph.
1627 1640
  ///
1628 1641
  ///\sa DynArcLookUp
1629 1642
  ///\sa AllArcLookUp
1630
  template<class G>
1643
  template<class GR>
1631 1644
  class ArcLookUp
1632 1645
  {
1646
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
1647

	
1633 1648
  public:
1634
    TEMPLATE_DIGRAPH_TYPEDEFS(G);
1635
    typedef G Digraph;
1649

	
1650
    /// The Digraph type
1651
    typedef GR Digraph;
1636 1652

	
1637 1653
  protected:
1638 1654
    const Digraph &_g;
1639 1655
    typename Digraph::template NodeMap<Arc> _head;
1640 1656
    typename Digraph::template ArcMap<Arc> _left;
1641 1657
    typename Digraph::template ArcMap<Arc> _right;
1642 1658

	
1643 1659
    class ArcLess {
1644 1660
      const Digraph &g;
1645 1661
    public:
1646 1662
      ArcLess(const Digraph &_g) : g(_g) {}
1647 1663
      bool operator()(Arc a,Arc b) const
1648 1664
      {
1649 1665
        return g.target(a)<g.target(b);
1650 1666
      }
1651 1667
    };
1652 1668

	
1653 1669
  public:
1654 1670

	
1655 1671
    ///Constructor
1656 1672

	
1657 1673
    ///Constructor.
1658 1674
    ///
1659 1675
    ///It builds up the search database, which remains valid until the digraph
1660 1676
    ///changes.
1661 1677
    ArcLookUp(const Digraph &g) :_g(g),_head(g),_left(g),_right(g) {refresh();}
1662 1678

	
1663 1679
  private:
1664 1680
    Arc refreshRec(std::vector<Arc> &v,int a,int b)
1665 1681
    {
1666 1682
      int m=(a+b)/2;
1667 1683
      Arc me=v[m];
1668 1684
      _left[me] = a<m?refreshRec(v,a,m-1):INVALID;
1669 1685
      _right[me] = m<b?refreshRec(v,m+1,b):INVALID;
1670 1686
      return me;
1671 1687
    }
1672 1688
  public:
1673 1689
    ///Refresh the search data structure at a node.
1674 1690

	
1675 1691
    ///Build up the search database of node \c n.
1676 1692
    ///
1677 1693
    ///It runs in time <em>O</em>(<em>d</em> log<em>d</em>), where <em>d</em>
1678 1694
    ///is the number of the outgoing arcs of \c n.
1679 1695
    void refresh(Node n)
1680 1696
    {
1681 1697
      std::vector<Arc> v;
1682 1698
      for(OutArcIt e(_g,n);e!=INVALID;++e) v.push_back(e);
1683 1699
      if(v.size()) {
1684 1700
        std::sort(v.begin(),v.end(),ArcLess(_g));
1685 1701
        _head[n]=refreshRec(v,0,v.size()-1);
1686 1702
      }
1687 1703
      else _head[n]=INVALID;
1688 1704
    }
1689 1705
    ///Refresh the full data structure.
1690 1706

	
1691 1707
    ///Build up the full search database. In fact, it simply calls
1692 1708
    ///\ref refresh(Node) "refresh(n)" for each node \c n.
1693 1709
    ///
1694 1710
    ///It runs in time <em>O</em>(<em>m</em> log<em>D</em>), where <em>m</em> is
1695 1711
    ///the number of the arcs in the digraph and <em>D</em> is the maximum
1696 1712
    ///out-degree of the digraph.
1697 1713
    void refresh()
1698 1714
    {
1699 1715
      for(NodeIt n(_g);n!=INVALID;++n) refresh(n);
1700 1716
    }
1701 1717

	
1702 1718
    ///Find an arc between two nodes.
1703 1719

	
1704 1720
    ///Find an arc between two nodes in time <em>O</em>(log<em>d</em>),
1705 1721
    ///where <em>d</em> is the number of outgoing arcs of \c s.
1706 1722
    ///\param s The source node.
1707 1723
    ///\param t The target node.
1708 1724
    ///\return An arc from \c s to \c t if there exists,
1709 1725
    ///\ref INVALID otherwise.
1710 1726
    ///
1711 1727
    ///\warning If you change the digraph, refresh() must be called before using
1712 1728
    ///this operator. If you change the outgoing arcs of
1713 1729
    ///a single node \c n, then \ref refresh(Node) "refresh(n)" is enough.
1714 1730
    Arc operator()(Node s, Node t) const
1715 1731
    {
1716 1732
      Arc e;
1717 1733
      for(e=_head[s];
1718 1734
          e!=INVALID&&_g.target(e)!=t;
1719 1735
          e = t < _g.target(e)?_left[e]:_right[e]) ;
1720 1736
      return e;
1721 1737
    }
1722 1738

	
1723 1739
  };
1724 1740

	
1725 1741
  ///Fast look-up of all arcs between given endpoints.
1726 1742

	
1727 1743
  ///This class is the same as \ref ArcLookUp, with the addition
1728 1744
  ///that it makes it possible to find all parallel arcs between given
1729 1745
  ///endpoints.
1730 1746
  ///
1731 1747
  ///\warning This class is static, so you should call refresh() (or at
1732 1748
  ///least refresh(Node)) to refresh this data structure whenever the
1733 1749
  ///digraph changes. This is a time consuming (superlinearly proportional
1734 1750
  ///(<em>O</em>(<em>m</em> log<em>m</em>)) to the number of arcs).
1735 1751
  ///
1736
  ///\tparam G The type of the underlying digraph.
1752
  ///\tparam GR The type of the underlying digraph.
1737 1753
  ///
1738 1754
  ///\sa DynArcLookUp
1739 1755
  ///\sa ArcLookUp
1740
  template<class G>
1741
  class AllArcLookUp : public ArcLookUp<G>
1756
  template<class GR>
1757
  class AllArcLookUp : public ArcLookUp<GR>
1742 1758
  {
1743
    using ArcLookUp<G>::_g;
1744
    using ArcLookUp<G>::_right;
1745
    using ArcLookUp<G>::_left;
1746
    using ArcLookUp<G>::_head;
1759
    using ArcLookUp<GR>::_g;
1760
    using ArcLookUp<GR>::_right;
1761
    using ArcLookUp<GR>::_left;
1762
    using ArcLookUp<GR>::_head;
1747 1763

	
1748
    TEMPLATE_DIGRAPH_TYPEDEFS(G);
1749
    typedef G Digraph;
1764
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
1750 1765

	
1751
    typename Digraph::template ArcMap<Arc> _next;
1766
    typename GR::template ArcMap<Arc> _next;
1752 1767

	
1753 1768
    Arc refreshNext(Arc head,Arc next=INVALID)
1754 1769
    {
1755 1770
      if(head==INVALID) return next;
1756 1771
      else {
1757 1772
        next=refreshNext(_right[head],next);
1758 1773
        _next[head]=( next!=INVALID && _g.target(next)==_g.target(head))
1759 1774
          ? next : INVALID;
1760 1775
        return refreshNext(_left[head],head);
1761 1776
      }
1762 1777
    }
1763 1778

	
1764 1779
    void refreshNext()
1765 1780
    {
1766 1781
      for(NodeIt n(_g);n!=INVALID;++n) refreshNext(_head[n]);
1767 1782
    }
1768 1783

	
1769 1784
  public:
1785

	
1786
    /// The Digraph type
1787
    typedef GR Digraph;
1788

	
1770 1789
    ///Constructor
1771 1790

	
1772 1791
    ///Constructor.
1773 1792
    ///
1774 1793
    ///It builds up the search database, which remains valid until the digraph
1775 1794
    ///changes.
1776
    AllArcLookUp(const Digraph &g) : ArcLookUp<G>(g), _next(g) {refreshNext();}
1795
    AllArcLookUp(const Digraph &g) : ArcLookUp<GR>(g), _next(g) {refreshNext();}
1777 1796

	
1778 1797
    ///Refresh the data structure at a node.
1779 1798

	
1780 1799
    ///Build up the search database of node \c n.
1781 1800
    ///
1782 1801
    ///It runs in time <em>O</em>(<em>d</em> log<em>d</em>), where <em>d</em> is
1783 1802
    ///the number of the outgoing arcs of \c n.
1784 1803
    void refresh(Node n)
1785 1804
    {
1786
      ArcLookUp<G>::refresh(n);
1805
      ArcLookUp<GR>::refresh(n);
1787 1806
      refreshNext(_head[n]);
1788 1807
    }
1789 1808

	
1790 1809
    ///Refresh the full data structure.
1791 1810

	
1792 1811
    ///Build up the full search database. In fact, it simply calls
1793 1812
    ///\ref refresh(Node) "refresh(n)" for each node \c n.
1794 1813
    ///
1795 1814
    ///It runs in time <em>O</em>(<em>m</em> log<em>D</em>), where <em>m</em> is
1796 1815
    ///the number of the arcs in the digraph and <em>D</em> is the maximum
1797 1816
    ///out-degree of the digraph.
1798 1817
    void refresh()
1799 1818
    {
1800 1819
      for(NodeIt n(_g);n!=INVALID;++n) refresh(_head[n]);
1801 1820
    }
1802 1821

	
1803 1822
    ///Find an arc between two nodes.
1804 1823

	
1805 1824
    ///Find an arc between two nodes.
1806 1825
    ///\param s The source node.
1807 1826
    ///\param t The target node.
1808 1827
    ///\param prev The previous arc between \c s and \c t. It it is INVALID or
1809 1828
    ///not given, the operator finds the first appropriate arc.
1810 1829
    ///\return An arc from \c s to \c t after \c prev or
1811 1830
    ///\ref INVALID if there is no more.
1812 1831
    ///
1813 1832
    ///For example, you can count the number of arcs from \c u to \c v in the
1814 1833
    ///following way.
1815 1834
    ///\code
1816 1835
    ///AllArcLookUp<ListDigraph> ae(g);
1817 1836
    ///...
1818 1837
    ///int n = 0;
1819 1838
    ///for(Arc a = ae(u,v); a != INVALID; a=ae(u,v,a)) n++;
1820 1839
    ///\endcode
1821 1840
    ///
1822 1841
    ///Finding the first arc take <em>O</em>(log<em>d</em>) time,
1823 1842
    ///where <em>d</em> is the number of outgoing arcs of \c s. Then the
1824 1843
    ///consecutive arcs are found in constant time.
1825 1844
    ///
1826 1845
    ///\warning If you change the digraph, refresh() must be called before using
1827 1846
    ///this operator. If you change the outgoing arcs of
1828 1847
    ///a single node \c n, then \ref refresh(Node) "refresh(n)" is enough.
1829 1848
    ///
1830 1849
#ifdef DOXYGEN
1831 1850
    Arc operator()(Node s, Node t, Arc prev=INVALID) const {}
1832 1851
#else
1833
    using ArcLookUp<G>::operator() ;
1852
    using ArcLookUp<GR>::operator() ;
1834 1853
    Arc operator()(Node s, Node t, Arc prev) const
1835 1854
    {
1836 1855
      return prev==INVALID?(*this)(s,t):_next[prev];
1837 1856
    }
1838 1857
#endif
1839 1858

	
1840 1859
  };
1841 1860

	
1842 1861
  /// @}
1843 1862

	
1844 1863
} //namespace lemon
1845 1864

	
1846 1865
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_COUNTER_H
20 20
#define LEMON_COUNTER_H
21 21

	
22 22
#include <string>
23 23
#include <iostream>
24 24

	
25 25
///\ingroup timecount
26 26
///\file
27 27
///\brief Tools for counting steps and events
28 28

	
29 29
namespace lemon
30 30
{
31 31

	
32 32
  template<class P> class _NoSubCounter;
33 33

	
34 34
  template<class P>
35 35
  class _SubCounter
36 36
  {
37 37
    P &_parent;
38 38
    std::string _title;
39 39
    std::ostream &_os;
40 40
    int count;
41 41
  public:
42 42

	
43 43
    typedef _SubCounter<_SubCounter<P> > SubCounter;
44 44
    typedef _NoSubCounter<_SubCounter<P> > NoSubCounter;
45 45

	
46 46
    _SubCounter(P &parent)
47 47
      : _parent(parent), _title(), _os(std::cerr), count(0) {}
48 48
    _SubCounter(P &parent,std::string title,std::ostream &os=std::cerr)
49 49
      : _parent(parent), _title(title), _os(os), count(0) {}
50 50
    _SubCounter(P &parent,const char *title,std::ostream &os=std::cerr)
51 51
      : _parent(parent), _title(title), _os(os), count(0) {}
52 52
    ~_SubCounter() {
53 53
      _os << _title << count <<std::endl;
54 54
      _parent+=count;
55 55
    }
56 56
    _SubCounter &operator++() { count++; return *this;}
57 57
    int operator++(int) { return count++; }
58 58
    _SubCounter &operator--() { count--; return *this;}
59 59
    int operator--(int) { return count--; }
60 60
    _SubCounter &operator+=(int c) { count+=c; return *this;}
61 61
    _SubCounter &operator-=(int c) { count-=c; return *this;}
62 62
    operator int() {return count;}
63 63
  };
64 64

	
65 65
  template<class P>
66 66
  class _NoSubCounter
67 67
  {
68 68
    P &_parent;
69 69
  public:
70 70
    typedef _NoSubCounter<_NoSubCounter<P> > SubCounter;
71 71
    typedef _NoSubCounter<_NoSubCounter<P> > NoSubCounter;
72 72

	
73 73
    _NoSubCounter(P &parent) :_parent(parent) {}
74 74
    _NoSubCounter(P &parent,std::string,std::ostream &)
75 75
      :_parent(parent) {}
76 76
    _NoSubCounter(P &parent,std::string)
77 77
      :_parent(parent) {}
78 78
    _NoSubCounter(P &parent,const char *,std::ostream &)
79 79
      :_parent(parent) {}
80 80
    _NoSubCounter(P &parent,const char *)
81 81
      :_parent(parent) {}
82 82
    ~_NoSubCounter() {}
83 83
    _NoSubCounter &operator++() { ++_parent; return *this;}
84 84
    int operator++(int) { _parent++; return 0;}
85 85
    _NoSubCounter &operator--() { --_parent; return *this;}
86 86
    int operator--(int) { _parent--; return 0;}
87 87
    _NoSubCounter &operator+=(int c) { _parent+=c; return *this;}
88 88
    _NoSubCounter &operator-=(int c) { _parent-=c; return *this;}
89 89
    operator int() {return 0;}
90 90
  };
91 91

	
92 92

	
93 93
  /// \addtogroup timecount
94 94
  /// @{
95 95

	
96 96
  /// A counter class
97 97

	
98 98
  /// This class makes it easier to count certain events (e.g. for debug
99 99
  /// reasons).
100 100
  /// You can increment or decrement the counter using \c operator++,
101 101
  /// \c operator--, \c operator+= and \c operator-=. You can also
102 102
  /// define subcounters for the different phases of the algorithm or
103 103
  /// for different types of operations.
104 104
  /// A report containing the given title and the value of the counter
105 105
  /// is automatically printed on destruction.
106 106
  ///
107 107
  /// The following example shows the usage of counters and subcounters.
108 108
  /// \code
109 109
  /// // Bubble sort
110 110
  /// std::vector<T> v;
111 111
  /// ...
112 112
  /// Counter op("Operations: ");
113 113
  /// Counter::SubCounter as(op, "Assignments: ");
114 114
  /// Counter::SubCounter co(op, "Comparisons: ");
115 115
  /// for (int i = v.size()-1; i > 0; --i) {
116 116
  ///   for (int j = 0; j < i; ++j) {
117 117
  ///     if (v[j] > v[j+1]) {
118 118
  ///       T tmp = v[j];
119 119
  ///       v[j] = v[j+1];
120 120
  ///       v[j+1] = tmp;
121 121
  ///       as += 3;          // three assignments
122 122
  ///     }
123 123
  ///     ++co;               // one comparison
124 124
  ///   }
125 125
  /// }
126 126
  /// \endcode
127 127
  ///
128 128
  /// This code prints out something like that:
129 129
  /// \code
130 130
  /// Comparisons: 45
131 131
  /// Assignments: 57
132 132
  /// Operations: 102
133 133
  /// \endcode
134 134
  ///
135 135
  /// \sa NoCounter
136 136
  class Counter
137 137
  {
138 138
    std::string _title;
139 139
    std::ostream &_os;
140 140
    int count;
141 141
  public:
142 142

	
143 143
    /// SubCounter class
144 144

	
145 145
    /// This class can be used to setup subcounters for a \ref Counter
146 146
    /// to have finer reports. A subcounter provides exactly the same
147 147
    /// operations as the main \ref Counter, but it also increments and
148 148
    /// decrements the value of its parent.
149 149
    /// Subcounters can also have subcounters.
150 150
    ///
151 151
    /// The parent counter must be given as the first parameter of the
152 152
    /// constructor. Apart from that a title and an \c ostream object
153 153
    /// can also be given just like for the main \ref Counter.
154 154
    ///
155 155
    /// A report containing the given title and the value of the
156 156
    /// subcounter is automatically printed on destruction. If you
157 157
    /// would like to turn off this report, use \ref NoSubCounter
158 158
    /// instead.
159 159
    ///
160 160
    /// \sa NoSubCounter
161 161
    typedef _SubCounter<Counter> SubCounter;
162 162

	
163 163
    /// SubCounter class without printing report on destruction
164 164

	
165 165
    /// This class can be used to setup subcounters for a \ref Counter.
166 166
    /// It is the same as \ref SubCounter but it does not print report
167 167
    /// on destruction. (It modifies the value of its parent, so 'No'
168 168
    /// only means 'do not print'.)
169 169
    ///
170 170
    /// Replacing \ref SubCounter "SubCounter"s with \ref NoSubCounter
171 171
    /// "NoSubCounter"s makes it possible to turn off reporting
172 172
    /// subcounter values without actually removing the definitions
173 173
    /// and the increment or decrement operators.
174 174
    ///
175 175
    /// \sa SubCounter
176 176
    typedef _NoSubCounter<Counter> NoSubCounter;
177 177

	
178 178
    /// Constructor.
179 179
    Counter() : _title(), _os(std::cerr), count(0) {}
180 180
    /// Constructor.
181 181
    Counter(std::string title,std::ostream &os=std::cerr)
182 182
      : _title(title), _os(os), count(0) {}
183 183
    /// Constructor.
184 184
    Counter(const char *title,std::ostream &os=std::cerr)
185 185
      : _title(title), _os(os), count(0) {}
186 186
    /// Destructor. Prints the given title and the value of the counter.
187 187
    ~Counter() {
188 188
      _os << _title << count <<std::endl;
189 189
    }
190 190
    ///\e
191 191
    Counter &operator++() { count++; return *this;}
192 192
    ///\e
193 193
    int operator++(int) { return count++;}
194 194
    ///\e
195 195
    Counter &operator--() { count--; return *this;}
196 196
    ///\e
197 197
    int operator--(int) { return count--;}
198 198
    ///\e
199 199
    Counter &operator+=(int c) { count+=c; return *this;}
200 200
    ///\e
201 201
    Counter &operator-=(int c) { count-=c; return *this;}
202 202
    /// Resets the counter to the given value.
203 203

	
204 204
    /// Resets the counter to the given value.
205 205
    /// \note This function does not reset the values of
206 206
    /// \ref SubCounter "SubCounter"s but it resets \ref NoSubCounter
207 207
    /// "NoSubCounter"s along with the main counter.
208 208
    void reset(int c=0) {count=c;}
209 209
    /// Returns the value of the counter.
210 210
    operator int() {return count;}
211 211
  };
212 212

	
213 213
  /// 'Do nothing' version of Counter.
214 214

	
215 215
  /// This class can be used in the same way as \ref Counter however it
216 216
  /// does not count at all and does not print report on destruction.
217 217
  ///
218 218
  /// Replacing a \ref Counter with a \ref NoCounter makes it possible
219 219
  /// to turn off all counting and reporting (SubCounters should also
220 220
  /// be replaced with NoSubCounters), so it does not affect the
221 221
  /// efficiency of the program at all.
222 222
  ///
223 223
  /// \sa Counter
224 224
  class NoCounter
225 225
  {
226 226
  public:
227 227
    typedef _NoSubCounter<NoCounter> SubCounter;
228 228
    typedef _NoSubCounter<NoCounter> NoSubCounter;
229 229

	
230 230
    NoCounter() {}
231 231
    NoCounter(std::string,std::ostream &) {}
232 232
    NoCounter(const char *,std::ostream &) {}
233 233
    NoCounter(std::string) {}
234 234
    NoCounter(const char *) {}
235 235
    NoCounter &operator++() { return *this; }
236 236
    int operator++(int) { return 0; }
237 237
    NoCounter &operator--() { return *this; }
238 238
    int operator--(int) { return 0; }
239 239
    NoCounter &operator+=(int) { return *this;}
240 240
    NoCounter &operator-=(int) { return *this;}
241 241
    void reset(int) {}
242 242
    void reset() {}
243 243
    operator int() {return 0;}
244 244
  };
245 245

	
246 246
  ///@}
247 247
}
248 248

	
249 249
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_DFS_H
20 20
#define LEMON_DFS_H
21 21

	
22 22
///\ingroup search
23 23
///\file
24 24
///\brief DFS algorithm.
25 25

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

	
33 33
namespace lemon {
34 34

	
35 35
  ///Default traits class of Dfs class.
36 36

	
37 37
  ///Default traits class of Dfs class.
38 38
  ///\tparam GR Digraph type.
39 39
  template<class GR>
40 40
  struct DfsDefaultTraits
41 41
  {
42 42
    ///The type of the digraph the algorithm runs on.
43 43
    typedef GR Digraph;
44 44

	
45 45
    ///\brief The type of the map that stores the predecessor
46 46
    ///arcs of the %DFS paths.
47 47
    ///
48 48
    ///The type of the map that stores the predecessor
49 49
    ///arcs of the %DFS paths.
50 50
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
51 51
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
52
    ///Instantiates a PredMap.
52
    ///Instantiates a \c PredMap.
53 53

	
54
    ///This function instantiates a PredMap.
54
    ///This function instantiates a \ref PredMap.
55 55
    ///\param g is the digraph, to which we would like to define the
56
    ///PredMap.
56
    ///\ref PredMap.
57 57
    static PredMap *createPredMap(const Digraph &g)
58 58
    {
59 59
      return new PredMap(g);
60 60
    }
61 61

	
62 62
    ///The type of the map that indicates which nodes are processed.
63 63

	
64 64
    ///The type of the map that indicates which nodes are processed.
65 65
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
66 66
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
67
    ///Instantiates a ProcessedMap.
67
    ///Instantiates a \c ProcessedMap.
68 68

	
69
    ///This function instantiates a ProcessedMap.
69
    ///This function instantiates a \ref ProcessedMap.
70 70
    ///\param g is the digraph, to which
71
    ///we would like to define the ProcessedMap
71
    ///we would like to define the \ref ProcessedMap.
72 72
#ifdef DOXYGEN
73 73
    static ProcessedMap *createProcessedMap(const Digraph &g)
74 74
#else
75 75
    static ProcessedMap *createProcessedMap(const Digraph &)
76 76
#endif
77 77
    {
78 78
      return new ProcessedMap();
79 79
    }
80 80

	
81 81
    ///The type of the map that indicates which nodes are reached.
82 82

	
83 83
    ///The type of the map that indicates which nodes are reached.
84 84
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
85 85
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
86
    ///Instantiates a ReachedMap.
86
    ///Instantiates a \c ReachedMap.
87 87

	
88
    ///This function instantiates a ReachedMap.
88
    ///This function instantiates a \ref ReachedMap.
89 89
    ///\param g is the digraph, to which
90
    ///we would like to define the ReachedMap.
90
    ///we would like to define the \ref ReachedMap.
91 91
    static ReachedMap *createReachedMap(const Digraph &g)
92 92
    {
93 93
      return new ReachedMap(g);
94 94
    }
95 95

	
96 96
    ///The type of the map that stores the distances of the nodes.
97 97

	
98 98
    ///The type of the map that stores the distances of the nodes.
99 99
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
100 100
    typedef typename Digraph::template NodeMap<int> DistMap;
101
    ///Instantiates a DistMap.
101
    ///Instantiates a \c DistMap.
102 102

	
103
    ///This function instantiates a DistMap.
103
    ///This function instantiates a \ref DistMap.
104 104
    ///\param g is the digraph, to which we would like to define the
105
    ///DistMap.
105
    ///\ref DistMap.
106 106
    static DistMap *createDistMap(const Digraph &g)
107 107
    {
108 108
      return new DistMap(g);
109 109
    }
110 110
  };
111 111

	
112 112
  ///%DFS algorithm class.
113 113

	
114 114
  ///\ingroup search
115 115
  ///This class provides an efficient implementation of the %DFS algorithm.
116 116
  ///
117 117
  ///There is also a \ref dfs() "function-type interface" for the DFS
118 118
  ///algorithm, which is convenient in the simplier cases and it can be
119 119
  ///used easier.
120 120
  ///
121 121
  ///\tparam GR The type of the digraph the algorithm runs on.
122
  ///The default value is \ref ListDigraph. The value of GR is not used
123
  ///directly by \ref Dfs, it is only passed to \ref DfsDefaultTraits.
124
  ///\tparam TR Traits class to set various data types used by the algorithm.
125
  ///The default traits class is
126
  ///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
127
  ///See \ref DfsDefaultTraits for the documentation of
128
  ///a Dfs traits class.
122
  ///The default type is \ref ListDigraph.
129 123
#ifdef DOXYGEN
130 124
  template <typename GR,
131 125
            typename TR>
132 126
#else
133 127
  template <typename GR=ListDigraph,
134 128
            typename TR=DfsDefaultTraits<GR> >
135 129
#endif
136 130
  class Dfs {
137 131
  public:
138 132

	
139 133
    ///The type of the digraph the algorithm runs on.
140 134
    typedef typename TR::Digraph Digraph;
141 135

	
142 136
    ///\brief The type of the map that stores the predecessor arcs of the
143 137
    ///DFS paths.
144 138
    typedef typename TR::PredMap PredMap;
145 139
    ///The type of the map that stores the distances of the nodes.
146 140
    typedef typename TR::DistMap DistMap;
147 141
    ///The type of the map that indicates which nodes are reached.
148 142
    typedef typename TR::ReachedMap ReachedMap;
149 143
    ///The type of the map that indicates which nodes are processed.
150 144
    typedef typename TR::ProcessedMap ProcessedMap;
151 145
    ///The type of the paths.
152 146
    typedef PredMapPath<Digraph, PredMap> Path;
153 147

	
154
    ///The traits class.
148
    ///The \ref DfsDefaultTraits "traits class" of the algorithm.
155 149
    typedef TR Traits;
156 150

	
157 151
  private:
158 152

	
159 153
    typedef typename Digraph::Node Node;
160 154
    typedef typename Digraph::NodeIt NodeIt;
161 155
    typedef typename Digraph::Arc Arc;
162 156
    typedef typename Digraph::OutArcIt OutArcIt;
163 157

	
164 158
    //Pointer to the underlying digraph.
165 159
    const Digraph *G;
166 160
    //Pointer to the map of predecessor arcs.
167 161
    PredMap *_pred;
168 162
    //Indicates if _pred is locally allocated (true) or not.
169 163
    bool local_pred;
170 164
    //Pointer to the map of distances.
171 165
    DistMap *_dist;
172 166
    //Indicates if _dist is locally allocated (true) or not.
173 167
    bool local_dist;
174 168
    //Pointer to the map of reached status of the nodes.
175 169
    ReachedMap *_reached;
176 170
    //Indicates if _reached is locally allocated (true) or not.
177 171
    bool local_reached;
178 172
    //Pointer to the map of processed status of the nodes.
179 173
    ProcessedMap *_processed;
180 174
    //Indicates if _processed is locally allocated (true) or not.
181 175
    bool local_processed;
182 176

	
183 177
    std::vector<typename Digraph::OutArcIt> _stack;
184 178
    int _stack_head;
185 179

	
186 180
    //Creates the maps if necessary.
187 181
    void create_maps()
188 182
    {
189 183
      if(!_pred) {
190 184
        local_pred = true;
191 185
        _pred = Traits::createPredMap(*G);
192 186
      }
193 187
      if(!_dist) {
194 188
        local_dist = true;
195 189
        _dist = Traits::createDistMap(*G);
196 190
      }
197 191
      if(!_reached) {
198 192
        local_reached = true;
199 193
        _reached = Traits::createReachedMap(*G);
200 194
      }
201 195
      if(!_processed) {
202 196
        local_processed = true;
203 197
        _processed = Traits::createProcessedMap(*G);
204 198
      }
205 199
    }
206 200

	
207 201
  protected:
208 202

	
209 203
    Dfs() {}
210 204

	
211 205
  public:
212 206

	
213 207
    typedef Dfs Create;
214 208

	
215
    ///\name Named template parameters
209
    ///\name Named Template Parameters
216 210

	
217 211
    ///@{
218 212

	
219 213
    template <class T>
220 214
    struct SetPredMapTraits : public Traits {
221 215
      typedef T PredMap;
222 216
      static PredMap *createPredMap(const Digraph &)
223 217
      {
224 218
        LEMON_ASSERT(false, "PredMap is not initialized");
225 219
        return 0; // ignore warnings
226 220
      }
227 221
    };
228 222
    ///\brief \ref named-templ-param "Named parameter" for setting
229
    ///PredMap type.
223
    ///\c PredMap type.
230 224
    ///
231 225
    ///\ref named-templ-param "Named parameter" for setting
232
    ///PredMap type.
226
    ///\c PredMap type.
227
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
233 228
    template <class T>
234 229
    struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
235 230
      typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
236 231
    };
237 232

	
238 233
    template <class T>
239 234
    struct SetDistMapTraits : public Traits {
240 235
      typedef T DistMap;
241 236
      static DistMap *createDistMap(const Digraph &)
242 237
      {
243 238
        LEMON_ASSERT(false, "DistMap is not initialized");
244 239
        return 0; // ignore warnings
245 240
      }
246 241
    };
247 242
    ///\brief \ref named-templ-param "Named parameter" for setting
248
    ///DistMap type.
243
    ///\c DistMap type.
249 244
    ///
250 245
    ///\ref named-templ-param "Named parameter" for setting
251
    ///DistMap type.
246
    ///\c DistMap type.
247
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
252 248
    template <class T>
253 249
    struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
254 250
      typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
255 251
    };
256 252

	
257 253
    template <class T>
258 254
    struct SetReachedMapTraits : public Traits {
259 255
      typedef T ReachedMap;
260 256
      static ReachedMap *createReachedMap(const Digraph &)
261 257
      {
262 258
        LEMON_ASSERT(false, "ReachedMap is not initialized");
263 259
        return 0; // ignore warnings
264 260
      }
265 261
    };
266 262
    ///\brief \ref named-templ-param "Named parameter" for setting
267
    ///ReachedMap type.
263
    ///\c ReachedMap type.
268 264
    ///
269 265
    ///\ref named-templ-param "Named parameter" for setting
270
    ///ReachedMap type.
266
    ///\c ReachedMap type.
267
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
271 268
    template <class T>
272 269
    struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
273 270
      typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
274 271
    };
275 272

	
276 273
    template <class T>
277 274
    struct SetProcessedMapTraits : public Traits {
278 275
      typedef T ProcessedMap;
279 276
      static ProcessedMap *createProcessedMap(const Digraph &)
280 277
      {
281 278
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
282 279
        return 0; // ignore warnings
283 280
      }
284 281
    };
285 282
    ///\brief \ref named-templ-param "Named parameter" for setting
286
    ///ProcessedMap type.
283
    ///\c ProcessedMap type.
287 284
    ///
288 285
    ///\ref named-templ-param "Named parameter" for setting
289
    ///ProcessedMap type.
286
    ///\c ProcessedMap type.
287
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
290 288
    template <class T>
291 289
    struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
292 290
      typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
293 291
    };
294 292

	
295 293
    struct SetStandardProcessedMapTraits : public Traits {
296 294
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
297 295
      static ProcessedMap *createProcessedMap(const Digraph &g)
298 296
      {
299 297
        return new ProcessedMap(g);
300 298
      }
301 299
    };
302 300
    ///\brief \ref named-templ-param "Named parameter" for setting
303
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
301
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
304 302
    ///
305 303
    ///\ref named-templ-param "Named parameter" for setting
306
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
304
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
307 305
    ///If you don't set it explicitly, it will be automatically allocated.
308 306
    struct SetStandardProcessedMap :
309 307
      public Dfs< Digraph, SetStandardProcessedMapTraits > {
310 308
      typedef Dfs< Digraph, SetStandardProcessedMapTraits > Create;
311 309
    };
312 310

	
313 311
    ///@}
314 312

	
315 313
  public:
316 314

	
317 315
    ///Constructor.
318 316

	
319 317
    ///Constructor.
320 318
    ///\param g The digraph the algorithm runs on.
321 319
    Dfs(const Digraph &g) :
322 320
      G(&g),
323 321
      _pred(NULL), local_pred(false),
324 322
      _dist(NULL), local_dist(false),
325 323
      _reached(NULL), local_reached(false),
326 324
      _processed(NULL), local_processed(false)
327 325
    { }
328 326

	
329 327
    ///Destructor.
330 328
    ~Dfs()
331 329
    {
332 330
      if(local_pred) delete _pred;
333 331
      if(local_dist) delete _dist;
334 332
      if(local_reached) delete _reached;
335 333
      if(local_processed) delete _processed;
336 334
    }
337 335

	
338 336
    ///Sets the map that stores the predecessor arcs.
339 337

	
340 338
    ///Sets the map that stores the predecessor arcs.
341
    ///If you don't use this function before calling \ref run(),
342
    ///it will allocate one. The destructor deallocates this
343
    ///automatically allocated map, of course.
339
    ///If you don't use this function before calling \ref run(Node) "run()"
340
    ///or \ref init(), an instance will be allocated automatically.
341
    ///The destructor deallocates this automatically allocated map,
342
    ///of course.
344 343
    ///\return <tt> (*this) </tt>
345 344
    Dfs &predMap(PredMap &m)
346 345
    {
347 346
      if(local_pred) {
348 347
        delete _pred;
349 348
        local_pred=false;
350 349
      }
351 350
      _pred = &m;
352 351
      return *this;
353 352
    }
354 353

	
355 354
    ///Sets the map that indicates which nodes are reached.
356 355

	
357 356
    ///Sets the map that indicates which nodes are reached.
358
    ///If you don't use this function before calling \ref run(),
359
    ///it will allocate one. The destructor deallocates this
360
    ///automatically allocated map, of course.
357
    ///If you don't use this function before calling \ref run(Node) "run()"
358
    ///or \ref init(), an instance will be allocated automatically.
359
    ///The destructor deallocates this automatically allocated map,
360
    ///of course.
361 361
    ///\return <tt> (*this) </tt>
362 362
    Dfs &reachedMap(ReachedMap &m)
363 363
    {
364 364
      if(local_reached) {
365 365
        delete _reached;
366 366
        local_reached=false;
367 367
      }
368 368
      _reached = &m;
369 369
      return *this;
370 370
    }
371 371

	
372 372
    ///Sets the map that indicates which nodes are processed.
373 373

	
374 374
    ///Sets the map that indicates which nodes are processed.
375
    ///If you don't use this function before calling \ref run(),
376
    ///it will allocate one. The destructor deallocates this
377
    ///automatically allocated map, of course.
375
    ///If you don't use this function before calling \ref run(Node) "run()"
376
    ///or \ref init(), an instance will be allocated automatically.
377
    ///The destructor deallocates this automatically allocated map,
378
    ///of course.
378 379
    ///\return <tt> (*this) </tt>
379 380
    Dfs &processedMap(ProcessedMap &m)
380 381
    {
381 382
      if(local_processed) {
382 383
        delete _processed;
383 384
        local_processed=false;
384 385
      }
385 386
      _processed = &m;
386 387
      return *this;
387 388
    }
388 389

	
389 390
    ///Sets the map that stores the distances of the nodes.
390 391

	
391 392
    ///Sets the map that stores the distances of the nodes calculated by
392 393
    ///the algorithm.
393
    ///If you don't use this function before calling \ref run(),
394
    ///it will allocate one. The destructor deallocates this
395
    ///automatically allocated map, of course.
394
    ///If you don't use this function before calling \ref run(Node) "run()"
395
    ///or \ref init(), an instance will be allocated automatically.
396
    ///The destructor deallocates this automatically allocated map,
397
    ///of course.
396 398
    ///\return <tt> (*this) </tt>
397 399
    Dfs &distMap(DistMap &m)
398 400
    {
399 401
      if(local_dist) {
400 402
        delete _dist;
401 403
        local_dist=false;
402 404
      }
403 405
      _dist = &m;
404 406
      return *this;
405 407
    }
406 408

	
407 409
  public:
408 410

	
409
    ///\name Execution control
410
    ///The simplest way to execute the algorithm is to use
411
    ///one of the member functions called \ref lemon::Dfs::run() "run()".
412
    ///\n
413
    ///If you need more control on the execution, first you must call
414
    ///\ref lemon::Dfs::init() "init()", then you can add a source node
415
    ///with \ref lemon::Dfs::addSource() "addSource()".
416
    ///Finally \ref lemon::Dfs::start() "start()" will perform the
417
    ///actual path computation.
411
    ///\name Execution Control
412
    ///The simplest way to execute the DFS algorithm is to use one of the
413
    ///member functions called \ref run(Node) "run()".\n
414
    ///If you need more control on the execution, first you have to call
415
    ///\ref init(), then you can add a source node with \ref addSource()
416
    ///and perform the actual computation with \ref start().
417
    ///This procedure can be repeated if there are nodes that have not
418
    ///been reached.
418 419

	
419 420
    ///@{
420 421

	
422
    ///\brief Initializes the internal data structures.
423
    ///
421 424
    ///Initializes the internal data structures.
422

	
423
    ///Initializes the internal data structures.
424
    ///
425 425
    void init()
426 426
    {
427 427
      create_maps();
428 428
      _stack.resize(countNodes(*G));
429 429
      _stack_head=-1;
430 430
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
431 431
        _pred->set(u,INVALID);
432 432
        _reached->set(u,false);
433 433
        _processed->set(u,false);
434 434
      }
435 435
    }
436 436

	
437 437
    ///Adds a new source node.
438 438

	
439 439
    ///Adds a new source node to the set of nodes to be processed.
440 440
    ///
441
    ///\pre The stack must be empty. (Otherwise the algorithm gives
442
    ///false results.)
443
    ///
444
    ///\warning Distances will be wrong (or at least strange) in case of
445
    ///multiple sources.
441
    ///\pre The stack must be empty. Otherwise the algorithm gives
442
    ///wrong results. (One of the outgoing arcs of all the source nodes
443
    ///except for the last one will not be visited and distances will
444
    ///also be wrong.)
446 445
    void addSource(Node s)
447 446
    {
448 447
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
449 448
      if(!(*_reached)[s])
450 449
        {
451 450
          _reached->set(s,true);
452 451
          _pred->set(s,INVALID);
453 452
          OutArcIt e(*G,s);
454 453
          if(e!=INVALID) {
455 454
            _stack[++_stack_head]=e;
456 455
            _dist->set(s,_stack_head);
457 456
          }
458 457
          else {
459 458
            _processed->set(s,true);
460 459
            _dist->set(s,0);
461 460
          }
462 461
        }
463 462
    }
464 463

	
465 464
    ///Processes the next arc.
466 465

	
467 466
    ///Processes the next arc.
468 467
    ///
469 468
    ///\return The processed arc.
470 469
    ///
471 470
    ///\pre The stack must not be empty.
472 471
    Arc processNextArc()
473 472
    {
474 473
      Node m;
475 474
      Arc e=_stack[_stack_head];
476 475
      if(!(*_reached)[m=G->target(e)]) {
477 476
        _pred->set(m,e);
478 477
        _reached->set(m,true);
479 478
        ++_stack_head;
480 479
        _stack[_stack_head] = OutArcIt(*G, m);
481 480
        _dist->set(m,_stack_head);
482 481
      }
483 482
      else {
484 483
        m=G->source(e);
485 484
        ++_stack[_stack_head];
486 485
      }
487 486
      while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
488 487
        _processed->set(m,true);
489 488
        --_stack_head;
490 489
        if(_stack_head>=0) {
491 490
          m=G->source(_stack[_stack_head]);
492 491
          ++_stack[_stack_head];
493 492
        }
494 493
      }
495 494
      return e;
496 495
    }
497 496

	
498 497
    ///Next arc to be processed.
499 498

	
500 499
    ///Next arc to be processed.
501 500
    ///
502 501
    ///\return The next arc to be processed or \c INVALID if the stack
503 502
    ///is empty.
504 503
    OutArcIt nextArc() const
505 504
    {
506 505
      return _stack_head>=0?_stack[_stack_head]:INVALID;
507 506
    }
508 507

	
509
    ///\brief Returns \c false if there are nodes
510
    ///to be processed.
511
    ///
512
    ///Returns \c false if there are nodes
513
    ///to be processed in the queue (stack).
508
    ///Returns \c false if there are nodes to be processed.
509

	
510
    ///Returns \c false if there are nodes to be processed
511
    ///in the queue (stack).
514 512
    bool emptyQueue() const { return _stack_head<0; }
515 513

	
516 514
    ///Returns the number of the nodes to be processed.
517 515

	
518
    ///Returns the number of the nodes to be processed in the queue (stack).
516
    ///Returns the number of the nodes to be processed
517
    ///in the queue (stack).
519 518
    int queueSize() const { return _stack_head+1; }
520 519

	
521 520
    ///Executes the algorithm.
522 521

	
523 522
    ///Executes the algorithm.
524 523
    ///
525 524
    ///This method runs the %DFS algorithm from the root node
526 525
    ///in order to compute the DFS path to each node.
527 526
    ///
528 527
    /// The algorithm computes
529 528
    ///- the %DFS tree,
530 529
    ///- the distance of each node from the root in the %DFS tree.
531 530
    ///
532 531
    ///\pre init() must be called and a root node should be
533 532
    ///added with addSource() before using this function.
534 533
    ///
535 534
    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
536 535
    ///\code
537 536
    ///  while ( !d.emptyQueue() ) {
538 537
    ///    d.processNextArc();
539 538
    ///  }
540 539
    ///\endcode
541 540
    void start()
542 541
    {
543 542
      while ( !emptyQueue() ) processNextArc();
544 543
    }
545 544

	
546 545
    ///Executes the algorithm until the given target node is reached.
547 546

	
548 547
    ///Executes the algorithm until the given target node is reached.
549 548
    ///
550 549
    ///This method runs the %DFS algorithm from the root node
551 550
    ///in order to compute the DFS path to \c t.
552 551
    ///
553 552
    ///The algorithm computes
554 553
    ///- the %DFS path to \c t,
555 554
    ///- the distance of \c t from the root in the %DFS tree.
556 555
    ///
557 556
    ///\pre init() must be called and a root node should be
558 557
    ///added with addSource() before using this function.
559 558
    void start(Node t)
560 559
    {
561 560
      while ( !emptyQueue() && G->target(_stack[_stack_head])!=t )
562 561
        processNextArc();
563 562
    }
564 563

	
565 564
    ///Executes the algorithm until a condition is met.
566 565

	
567 566
    ///Executes the algorithm until a condition is met.
568 567
    ///
569 568
    ///This method runs the %DFS algorithm from the root node
570 569
    ///until an arc \c a with <tt>am[a]</tt> true is found.
571 570
    ///
572 571
    ///\param am A \c bool (or convertible) arc map. The algorithm
573 572
    ///will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
574 573
    ///
575 574
    ///\return The reached arc \c a with <tt>am[a]</tt> true or
576 575
    ///\c INVALID if no such arc was found.
577 576
    ///
578 577
    ///\pre init() must be called and a root node should be
579 578
    ///added with addSource() before using this function.
580 579
    ///
581 580
    ///\warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
582 581
    ///not a node map.
583 582
    template<class ArcBoolMap>
584 583
    Arc start(const ArcBoolMap &am)
585 584
    {
586 585
      while ( !emptyQueue() && !am[_stack[_stack_head]] )
587 586
        processNextArc();
588 587
      return emptyQueue() ? INVALID : _stack[_stack_head];
589 588
    }
590 589

	
591 590
    ///Runs the algorithm from the given source node.
592 591

	
593 592
    ///This method runs the %DFS algorithm from node \c s
594 593
    ///in order to compute the DFS path to each node.
595 594
    ///
596 595
    ///The algorithm computes
597 596
    ///- the %DFS tree,
598 597
    ///- the distance of each node from the root in the %DFS tree.
599 598
    ///
600 599
    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
601 600
    ///\code
602 601
    ///  d.init();
603 602
    ///  d.addSource(s);
604 603
    ///  d.start();
605 604
    ///\endcode
606 605
    void run(Node s) {
607 606
      init();
608 607
      addSource(s);
609 608
      start();
610 609
    }
611 610

	
612 611
    ///Finds the %DFS path between \c s and \c t.
613 612

	
614 613
    ///This method runs the %DFS algorithm from node \c s
615 614
    ///in order to compute the DFS path to node \c t
616 615
    ///(it stops searching when \c t is processed)
617 616
    ///
618 617
    ///\return \c true if \c t is reachable form \c s.
619 618
    ///
620 619
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is
621 620
    ///just a shortcut of the following code.
622 621
    ///\code
623 622
    ///  d.init();
624 623
    ///  d.addSource(s);
625 624
    ///  d.start(t);
626 625
    ///\endcode
627 626
    bool run(Node s,Node t) {
628 627
      init();
629 628
      addSource(s);
630 629
      start(t);
631 630
      return reached(t);
632 631
    }
633 632

	
634 633
    ///Runs the algorithm to visit all nodes in the digraph.
635 634

	
636 635
    ///This method runs the %DFS algorithm in order to compute the
637 636
    ///%DFS path to each node.
638 637
    ///
639 638
    ///The algorithm computes
640
    ///- the %DFS tree,
641
    ///- the distance of each node from the root in the %DFS tree.
639
    ///- the %DFS tree (forest),
640
    ///- the distance of each node from the root(s) in the %DFS tree.
642 641
    ///
643 642
    ///\note <tt>d.run()</tt> is just a shortcut of the following code.
644 643
    ///\code
645 644
    ///  d.init();
646 645
    ///  for (NodeIt n(digraph); n != INVALID; ++n) {
647 646
    ///    if (!d.reached(n)) {
648 647
    ///      d.addSource(n);
649 648
    ///      d.start();
650 649
    ///    }
651 650
    ///  }
652 651
    ///\endcode
653 652
    void run() {
654 653
      init();
655 654
      for (NodeIt it(*G); it != INVALID; ++it) {
656 655
        if (!reached(it)) {
657 656
          addSource(it);
658 657
          start();
659 658
        }
660 659
      }
661 660
    }
662 661

	
663 662
    ///@}
664 663

	
665 664
    ///\name Query Functions
666
    ///The result of the %DFS algorithm can be obtained using these
665
    ///The results of the DFS algorithm can be obtained using these
667 666
    ///functions.\n
668
    ///Either \ref lemon::Dfs::run() "run()" or \ref lemon::Dfs::start()
669
    ///"start()" must be called before using them.
667
    ///Either \ref run(Node) "run()" or \ref start() should be called
668
    ///before using them.
670 669

	
671 670
    ///@{
672 671

	
673 672
    ///The DFS path to a node.
674 673

	
675 674
    ///Returns the DFS path to a node.
676 675
    ///
677
    ///\warning \c t should be reachable from the root.
676
    ///\warning \c t should be reached from the root(s).
678 677
    ///
679
    ///\pre Either \ref run() or \ref start() must be called before
680
    ///using this function.
678
    ///\pre Either \ref run(Node) "run()" or \ref init()
679
    ///must be called before using this function.
681 680
    Path path(Node t) const { return Path(*G, *_pred, t); }
682 681

	
683
    ///The distance of a node from the root.
682
    ///The distance of a node from the root(s).
684 683

	
685
    ///Returns the distance of a node from the root.
684
    ///Returns the distance of a node from the root(s).
686 685
    ///
687
    ///\warning If node \c v is not reachable from the root, then
686
    ///\warning If node \c v is not reached from the root(s), then
688 687
    ///the return value of this function is undefined.
689 688
    ///
690
    ///\pre Either \ref run() or \ref start() must be called before
691
    ///using this function.
689
    ///\pre Either \ref run(Node) "run()" or \ref init()
690
    ///must be called before using this function.
692 691
    int dist(Node v) const { return (*_dist)[v]; }
693 692

	
694 693
    ///Returns the 'previous arc' of the %DFS tree for a node.
695 694

	
696 695
    ///This function returns the 'previous arc' of the %DFS tree for the
697
    ///node \c v, i.e. it returns the last arc of a %DFS path from the
698
    ///root to \c v. It is \c INVALID
699
    ///if \c v is not reachable from the root(s) or if \c v is a root.
696
    ///node \c v, i.e. it returns the last arc of a %DFS path from a
697
    ///root to \c v. It is \c INVALID if \c v is not reached from the
698
    ///root(s) or if \c v is a root.
700 699
    ///
701 700
    ///The %DFS tree used here is equal to the %DFS tree used in
702 701
    ///\ref predNode().
703 702
    ///
704
    ///\pre Either \ref run() or \ref start() must be called before using
705
    ///this function.
703
    ///\pre Either \ref run(Node) "run()" or \ref init()
704
    ///must be called before using this function.
706 705
    Arc predArc(Node v) const { return (*_pred)[v];}
707 706

	
708 707
    ///Returns the 'previous node' of the %DFS tree.
709 708

	
710 709
    ///This function returns the 'previous node' of the %DFS
711 710
    ///tree for the node \c v, i.e. it returns the last but one node
712
    ///from a %DFS path from the root to \c v. It is \c INVALID
713
    ///if \c v is not reachable from the root(s) or if \c v is a root.
711
    ///from a %DFS path from a root to \c v. It is \c INVALID
712
    ///if \c v is not reached from the root(s) or if \c v is a root.
714 713
    ///
715 714
    ///The %DFS tree used here is equal to the %DFS tree used in
716 715
    ///\ref predArc().
717 716
    ///
718
    ///\pre Either \ref run() or \ref start() must be called before
719
    ///using this function.
717
    ///\pre Either \ref run(Node) "run()" or \ref init()
718
    ///must be called before using this function.
720 719
    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
721 720
                                  G->source((*_pred)[v]); }
722 721

	
723 722
    ///\brief Returns a const reference to the node map that stores the
724 723
    ///distances of the nodes.
725 724
    ///
726 725
    ///Returns a const reference to the node map that stores the
727 726
    ///distances of the nodes calculated by the algorithm.
728 727
    ///
729
    ///\pre Either \ref run() or \ref init()
728
    ///\pre Either \ref run(Node) "run()" or \ref init()
730 729
    ///must be called before using this function.
731 730
    const DistMap &distMap() const { return *_dist;}
732 731

	
733 732
    ///\brief Returns a const reference to the node map that stores the
734 733
    ///predecessor arcs.
735 734
    ///
736 735
    ///Returns a const reference to the node map that stores the predecessor
737 736
    ///arcs, which form the DFS tree.
738 737
    ///
739
    ///\pre Either \ref run() or \ref init()
738
    ///\pre Either \ref run(Node) "run()" or \ref init()
740 739
    ///must be called before using this function.
741 740
    const PredMap &predMap() const { return *_pred;}
742 741

	
743
    ///Checks if a node is reachable from the root(s).
742
    ///Checks if a node is reached from the root(s).
744 743

	
745
    ///Returns \c true if \c v is reachable from the root(s).
746
    ///\pre Either \ref run() or \ref start()
744
    ///Returns \c true if \c v is reached from the root(s).
745
    ///
746
    ///\pre Either \ref run(Node) "run()" or \ref init()
747 747
    ///must be called before using this function.
748 748
    bool reached(Node v) const { return (*_reached)[v]; }
749 749

	
750 750
    ///@}
751 751
  };
752 752

	
753 753
  ///Default traits class of dfs() function.
754 754

	
755 755
  ///Default traits class of dfs() function.
756 756
  ///\tparam GR Digraph type.
757 757
  template<class GR>
758 758
  struct DfsWizardDefaultTraits
759 759
  {
760 760
    ///The type of the digraph the algorithm runs on.
761 761
    typedef GR Digraph;
762 762

	
763 763
    ///\brief The type of the map that stores the predecessor
764 764
    ///arcs of the %DFS paths.
765 765
    ///
766 766
    ///The type of the map that stores the predecessor
767 767
    ///arcs of the %DFS paths.
768 768
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
769 769
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
770 770
    ///Instantiates a PredMap.
771 771

	
772 772
    ///This function instantiates a PredMap.
773 773
    ///\param g is the digraph, to which we would like to define the
774 774
    ///PredMap.
775 775
    static PredMap *createPredMap(const Digraph &g)
776 776
    {
777 777
      return new PredMap(g);
778 778
    }
779 779

	
780 780
    ///The type of the map that indicates which nodes are processed.
781 781

	
782 782
    ///The type of the map that indicates which nodes are processed.
783 783
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
784 784
    ///By default it is a NullMap.
785 785
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
786 786
    ///Instantiates a ProcessedMap.
787 787

	
788 788
    ///This function instantiates a ProcessedMap.
789 789
    ///\param g is the digraph, to which
790 790
    ///we would like to define the ProcessedMap.
791 791
#ifdef DOXYGEN
792 792
    static ProcessedMap *createProcessedMap(const Digraph &g)
793 793
#else
794 794
    static ProcessedMap *createProcessedMap(const Digraph &)
795 795
#endif
796 796
    {
797 797
      return new ProcessedMap();
798 798
    }
799 799

	
800 800
    ///The type of the map that indicates which nodes are reached.
801 801

	
802 802
    ///The type of the map that indicates which nodes are reached.
803 803
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
804 804
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
805 805
    ///Instantiates a ReachedMap.
806 806

	
807 807
    ///This function instantiates a ReachedMap.
808 808
    ///\param g is the digraph, to which
809 809
    ///we would like to define the ReachedMap.
810 810
    static ReachedMap *createReachedMap(const Digraph &g)
811 811
    {
812 812
      return new ReachedMap(g);
813 813
    }
814 814

	
815 815
    ///The type of the map that stores the distances of the nodes.
816 816

	
817 817
    ///The type of the map that stores the distances of the nodes.
818 818
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
819 819
    typedef typename Digraph::template NodeMap<int> DistMap;
820 820
    ///Instantiates a DistMap.
821 821

	
822 822
    ///This function instantiates a DistMap.
823 823
    ///\param g is the digraph, to which we would like to define
824 824
    ///the DistMap
825 825
    static DistMap *createDistMap(const Digraph &g)
826 826
    {
827 827
      return new DistMap(g);
828 828
    }
829 829

	
830 830
    ///The type of the DFS paths.
831 831

	
832 832
    ///The type of the DFS paths.
833 833
    ///It must meet the \ref concepts::Path "Path" concept.
834 834
    typedef lemon::Path<Digraph> Path;
835 835
  };
836 836

	
837 837
  /// Default traits class used by DfsWizard
838 838

	
839 839
  /// To make it easier to use Dfs algorithm
840 840
  /// we have created a wizard class.
841 841
  /// This \ref DfsWizard class needs default traits,
842 842
  /// as well as the \ref Dfs class.
843 843
  /// The \ref DfsWizardBase is a class to be the default traits of the
844 844
  /// \ref DfsWizard class.
845 845
  template<class GR>
846 846
  class DfsWizardBase : public DfsWizardDefaultTraits<GR>
847 847
  {
848 848

	
849 849
    typedef DfsWizardDefaultTraits<GR> Base;
850 850
  protected:
851 851
    //The type of the nodes in the digraph.
852 852
    typedef typename Base::Digraph::Node Node;
853 853

	
854 854
    //Pointer to the digraph the algorithm runs on.
855 855
    void *_g;
856 856
    //Pointer to the map of reached nodes.
857 857
    void *_reached;
858 858
    //Pointer to the map of processed nodes.
859 859
    void *_processed;
860 860
    //Pointer to the map of predecessors arcs.
861 861
    void *_pred;
862 862
    //Pointer to the map of distances.
863 863
    void *_dist;
864 864
    //Pointer to the DFS path to the target node.
865 865
    void *_path;
866 866
    //Pointer to the distance of the target node.
867 867
    int *_di;
868 868

	
869 869
    public:
870 870
    /// Constructor.
871 871

	
872 872
    /// This constructor does not require parameters, therefore it initiates
873 873
    /// all of the attributes to \c 0.
874 874
    DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
875 875
                      _dist(0), _path(0), _di(0) {}
876 876

	
877 877
    /// Constructor.
878 878

	
879 879
    /// This constructor requires one parameter,
880 880
    /// others are initiated to \c 0.
881 881
    /// \param g The digraph the algorithm runs on.
882 882
    DfsWizardBase(const GR &g) :
883 883
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
884 884
      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
885 885

	
886 886
  };
887 887

	
888 888
  /// Auxiliary class for the function-type interface of DFS algorithm.
889 889

	
890 890
  /// This auxiliary class is created to implement the
891 891
  /// \ref dfs() "function-type interface" of \ref Dfs algorithm.
892
  /// It does not have own \ref run() method, it uses the functions
893
  /// and features of the plain \ref Dfs.
892
  /// It does not have own \ref run(Node) "run()" method, it uses the
893
  /// functions and features of the plain \ref Dfs.
894 894
  ///
895 895
  /// This class should only be used through the \ref dfs() function,
896 896
  /// which makes it easier to use the algorithm.
897 897
  template<class TR>
898 898
  class DfsWizard : public TR
899 899
  {
900 900
    typedef TR Base;
901 901

	
902 902
    ///The type of the digraph the algorithm runs on.
903 903
    typedef typename TR::Digraph Digraph;
904 904

	
905 905
    typedef typename Digraph::Node Node;
906 906
    typedef typename Digraph::NodeIt NodeIt;
907 907
    typedef typename Digraph::Arc Arc;
908 908
    typedef typename Digraph::OutArcIt OutArcIt;
909 909

	
910 910
    ///\brief The type of the map that stores the predecessor
911 911
    ///arcs of the DFS paths.
912 912
    typedef typename TR::PredMap PredMap;
913 913
    ///\brief The type of the map that stores the distances of the nodes.
914 914
    typedef typename TR::DistMap DistMap;
915 915
    ///\brief The type of the map that indicates which nodes are reached.
916 916
    typedef typename TR::ReachedMap ReachedMap;
917 917
    ///\brief The type of the map that indicates which nodes are processed.
918 918
    typedef typename TR::ProcessedMap ProcessedMap;
919 919
    ///The type of the DFS paths
920 920
    typedef typename TR::Path Path;
921 921

	
922 922
  public:
923 923

	
924 924
    /// Constructor.
925 925
    DfsWizard() : TR() {}
926 926

	
927 927
    /// Constructor that requires parameters.
928 928

	
929 929
    /// Constructor that requires parameters.
930 930
    /// These parameters will be the default values for the traits class.
931 931
    /// \param g The digraph the algorithm runs on.
932 932
    DfsWizard(const Digraph &g) :
933 933
      TR(g) {}
934 934

	
935 935
    ///Copy constructor
936 936
    DfsWizard(const TR &b) : TR(b) {}
937 937

	
938 938
    ~DfsWizard() {}
939 939

	
940 940
    ///Runs DFS algorithm from the given source node.
941 941

	
942 942
    ///This method runs DFS algorithm from node \c s
943 943
    ///in order to compute the DFS path to each node.
944 944
    void run(Node s)
945 945
    {
946 946
      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
947 947
      if (Base::_pred)
948 948
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
949 949
      if (Base::_dist)
950 950
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
951 951
      if (Base::_reached)
952 952
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
953 953
      if (Base::_processed)
954 954
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
955 955
      if (s!=INVALID)
956 956
        alg.run(s);
957 957
      else
958 958
        alg.run();
959 959
    }
960 960

	
961 961
    ///Finds the DFS path between \c s and \c t.
962 962

	
963 963
    ///This method runs DFS algorithm from node \c s
964 964
    ///in order to compute the DFS path to node \c t
965 965
    ///(it stops searching when \c t is processed).
966 966
    ///
967 967
    ///\return \c true if \c t is reachable form \c s.
968 968
    bool run(Node s, Node t)
969 969
    {
970 970
      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
971 971
      if (Base::_pred)
972 972
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
973 973
      if (Base::_dist)
974 974
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
975 975
      if (Base::_reached)
976 976
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
977 977
      if (Base::_processed)
978 978
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
979 979
      alg.run(s,t);
980 980
      if (Base::_path)
981 981
        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
982 982
      if (Base::_di)
983 983
        *Base::_di = alg.dist(t);
984 984
      return alg.reached(t);
985 985
      }
986 986

	
987 987
    ///Runs DFS algorithm to visit all nodes in the digraph.
988 988

	
989 989
    ///This method runs DFS algorithm in order to compute
990 990
    ///the DFS path to each node.
991 991
    void run()
992 992
    {
993 993
      run(INVALID);
994 994
    }
995 995

	
996 996
    template<class T>
997 997
    struct SetPredMapBase : public Base {
998 998
      typedef T PredMap;
999 999
      static PredMap *createPredMap(const Digraph &) { return 0; };
1000 1000
      SetPredMapBase(const TR &b) : TR(b) {}
1001 1001
    };
1002 1002
    ///\brief \ref named-func-param "Named parameter"
1003 1003
    ///for setting PredMap object.
1004 1004
    ///
1005 1005
    ///\ref named-func-param "Named parameter"
1006 1006
    ///for setting PredMap object.
1007 1007
    template<class T>
1008 1008
    DfsWizard<SetPredMapBase<T> > predMap(const T &t)
1009 1009
    {
1010 1010
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1011 1011
      return DfsWizard<SetPredMapBase<T> >(*this);
1012 1012
    }
1013 1013

	
1014 1014
    template<class T>
1015 1015
    struct SetReachedMapBase : public Base {
1016 1016
      typedef T ReachedMap;
1017 1017
      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
1018 1018
      SetReachedMapBase(const TR &b) : TR(b) {}
1019 1019
    };
1020 1020
    ///\brief \ref named-func-param "Named parameter"
1021 1021
    ///for setting ReachedMap object.
1022 1022
    ///
1023 1023
    /// \ref named-func-param "Named parameter"
1024 1024
    ///for setting ReachedMap object.
1025 1025
    template<class T>
1026 1026
    DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
1027 1027
    {
1028 1028
      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
1029 1029
      return DfsWizard<SetReachedMapBase<T> >(*this);
1030 1030
    }
1031 1031

	
1032 1032
    template<class T>
1033 1033
    struct SetDistMapBase : public Base {
1034 1034
      typedef T DistMap;
1035 1035
      static DistMap *createDistMap(const Digraph &) { return 0; };
1036 1036
      SetDistMapBase(const TR &b) : TR(b) {}
1037 1037
    };
1038 1038
    ///\brief \ref named-func-param "Named parameter"
1039 1039
    ///for setting DistMap object.
1040 1040
    ///
1041 1041
    /// \ref named-func-param "Named parameter"
1042 1042
    ///for setting DistMap object.
1043 1043
    template<class T>
1044 1044
    DfsWizard<SetDistMapBase<T> > distMap(const T &t)
1045 1045
    {
1046 1046
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1047 1047
      return DfsWizard<SetDistMapBase<T> >(*this);
1048 1048
    }
1049 1049

	
1050 1050
    template<class T>
1051 1051
    struct SetProcessedMapBase : public Base {
1052 1052
      typedef T ProcessedMap;
1053 1053
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1054 1054
      SetProcessedMapBase(const TR &b) : TR(b) {}
1055 1055
    };
1056 1056
    ///\brief \ref named-func-param "Named parameter"
1057 1057
    ///for setting ProcessedMap object.
1058 1058
    ///
1059 1059
    /// \ref named-func-param "Named parameter"
1060 1060
    ///for setting ProcessedMap object.
1061 1061
    template<class T>
1062 1062
    DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
1063 1063
    {
1064 1064
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1065 1065
      return DfsWizard<SetProcessedMapBase<T> >(*this);
1066 1066
    }
1067 1067

	
1068 1068
    template<class T>
1069 1069
    struct SetPathBase : public Base {
1070 1070
      typedef T Path;
1071 1071
      SetPathBase(const TR &b) : TR(b) {}
1072 1072
    };
1073 1073
    ///\brief \ref named-func-param "Named parameter"
1074 1074
    ///for getting the DFS path to the target node.
1075 1075
    ///
1076 1076
    ///\ref named-func-param "Named parameter"
1077 1077
    ///for getting the DFS path to the target node.
1078 1078
    template<class T>
1079 1079
    DfsWizard<SetPathBase<T> > path(const T &t)
1080 1080
    {
1081 1081
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1082 1082
      return DfsWizard<SetPathBase<T> >(*this);
1083 1083
    }
1084 1084

	
1085 1085
    ///\brief \ref named-func-param "Named parameter"
1086 1086
    ///for getting the distance of the target node.
1087 1087
    ///
1088 1088
    ///\ref named-func-param "Named parameter"
1089 1089
    ///for getting the distance of the target node.
1090 1090
    DfsWizard dist(const int &d)
1091 1091
    {
1092 1092
      Base::_di=const_cast<int*>(&d);
1093 1093
      return *this;
1094 1094
    }
1095 1095

	
1096 1096
  };
1097 1097

	
1098 1098
  ///Function-type interface for DFS algorithm.
1099 1099

	
1100 1100
  ///\ingroup search
1101 1101
  ///Function-type interface for DFS algorithm.
1102 1102
  ///
1103 1103
  ///This function also has several \ref named-func-param "named parameters",
1104 1104
  ///they are declared as the members of class \ref DfsWizard.
1105 1105
  ///The following examples show how to use these parameters.
1106 1106
  ///\code
1107 1107
  ///  // Compute the DFS tree
1108 1108
  ///  dfs(g).predMap(preds).distMap(dists).run(s);
1109 1109
  ///
1110 1110
  ///  // Compute the DFS path from s to t
1111 1111
  ///  bool reached = dfs(g).path(p).dist(d).run(s,t);
1112 1112
  ///\endcode
1113

	
1114
  ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
1113
  ///\warning Don't forget to put the \ref DfsWizard::run(Node) "run()"
1115 1114
  ///to the end of the parameter list.
1116 1115
  ///\sa DfsWizard
1117 1116
  ///\sa Dfs
1118 1117
  template<class GR>
1119 1118
  DfsWizard<DfsWizardBase<GR> >
1120 1119
  dfs(const GR &digraph)
1121 1120
  {
1122 1121
    return DfsWizard<DfsWizardBase<GR> >(digraph);
1123 1122
  }
1124 1123

	
1125 1124
#ifdef DOXYGEN
1126 1125
  /// \brief Visitor class for DFS.
1127 1126
  ///
1128 1127
  /// This class defines the interface of the DfsVisit events, and
1129 1128
  /// it could be the base of a real visitor class.
1130
  template <typename _Digraph>
1129
  template <typename GR>
1131 1130
  struct DfsVisitor {
1132
    typedef _Digraph Digraph;
1131
    typedef GR Digraph;
1133 1132
    typedef typename Digraph::Arc Arc;
1134 1133
    typedef typename Digraph::Node Node;
1135 1134
    /// \brief Called for the source node of the DFS.
1136 1135
    ///
1137 1136
    /// This function is called for the source node of the DFS.
1138 1137
    void start(const Node& node) {}
1139 1138
    /// \brief Called when the source node is leaved.
1140 1139
    ///
1141 1140
    /// This function is called when the source node is leaved.
1142 1141
    void stop(const Node& node) {}
1143 1142
    /// \brief Called when a node is reached first time.
1144 1143
    ///
1145 1144
    /// This function is called when a node is reached first time.
1146 1145
    void reach(const Node& node) {}
1147 1146
    /// \brief Called when an arc reaches a new node.
1148 1147
    ///
1149 1148
    /// This function is called when the DFS finds an arc whose target node
1150 1149
    /// is not reached yet.
1151 1150
    void discover(const Arc& arc) {}
1152 1151
    /// \brief Called when an arc is examined but its target node is
1153 1152
    /// already discovered.
1154 1153
    ///
1155 1154
    /// This function is called when an arc is examined but its target node is
1156 1155
    /// already discovered.
1157 1156
    void examine(const Arc& arc) {}
1158 1157
    /// \brief Called when the DFS steps back from a node.
1159 1158
    ///
1160 1159
    /// This function is called when the DFS steps back from a node.
1161 1160
    void leave(const Node& node) {}
1162 1161
    /// \brief Called when the DFS steps back on an arc.
1163 1162
    ///
1164 1163
    /// This function is called when the DFS steps back on an arc.
1165 1164
    void backtrack(const Arc& arc) {}
1166 1165
  };
1167 1166
#else
1168
  template <typename _Digraph>
1167
  template <typename GR>
1169 1168
  struct DfsVisitor {
1170
    typedef _Digraph Digraph;
1169
    typedef GR Digraph;
1171 1170
    typedef typename Digraph::Arc Arc;
1172 1171
    typedef typename Digraph::Node Node;
1173 1172
    void start(const Node&) {}
1174 1173
    void stop(const Node&) {}
1175 1174
    void reach(const Node&) {}
1176 1175
    void discover(const Arc&) {}
1177 1176
    void examine(const Arc&) {}
1178 1177
    void leave(const Node&) {}
1179 1178
    void backtrack(const Arc&) {}
1180 1179

	
1181 1180
    template <typename _Visitor>
1182 1181
    struct Constraints {
1183 1182
      void constraints() {
1184 1183
        Arc arc;
1185 1184
        Node node;
1186 1185
        visitor.start(node);
1187 1186
        visitor.stop(arc);
1188 1187
        visitor.reach(node);
1189 1188
        visitor.discover(arc);
1190 1189
        visitor.examine(arc);
1191 1190
        visitor.leave(node);
1192 1191
        visitor.backtrack(arc);
1193 1192
      }
1194 1193
      _Visitor& visitor;
1195 1194
    };
1196 1195
  };
1197 1196
#endif
1198 1197

	
1199 1198
  /// \brief Default traits class of DfsVisit class.
1200 1199
  ///
1201 1200
  /// Default traits class of DfsVisit class.
1202 1201
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1203
  template<class _Digraph>
1202
  template<class GR>
1204 1203
  struct DfsVisitDefaultTraits {
1205 1204

	
1206 1205
    /// \brief The type of the digraph the algorithm runs on.
1207
    typedef _Digraph Digraph;
1206
    typedef GR Digraph;
1208 1207

	
1209 1208
    /// \brief The type of the map that indicates which nodes are reached.
1210 1209
    ///
1211 1210
    /// The type of the map that indicates which nodes are reached.
1212 1211
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1213 1212
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
1214 1213

	
1215 1214
    /// \brief Instantiates a ReachedMap.
1216 1215
    ///
1217 1216
    /// This function instantiates a ReachedMap.
1218 1217
    /// \param digraph is the digraph, to which
1219 1218
    /// we would like to define the ReachedMap.
1220 1219
    static ReachedMap *createReachedMap(const Digraph &digraph) {
1221 1220
      return new ReachedMap(digraph);
1222 1221
    }
1223 1222

	
1224 1223
  };
1225 1224

	
1226 1225
  /// \ingroup search
1227 1226
  ///
1228
  /// \brief %DFS algorithm class with visitor interface.
1227
  /// \brief DFS algorithm class with visitor interface.
1229 1228
  ///
1230
  /// This class provides an efficient implementation of the %DFS algorithm
1229
  /// This class provides an efficient implementation of the DFS algorithm
1231 1230
  /// with visitor interface.
1232 1231
  ///
1233
  /// The %DfsVisit class provides an alternative interface to the Dfs
1232
  /// The DfsVisit class provides an alternative interface to the Dfs
1234 1233
  /// class. It works with callback mechanism, the DfsVisit object calls
1235 1234
  /// the member functions of the \c Visitor class on every DFS event.
1236 1235
  ///
1237 1236
  /// This interface of the DFS algorithm should be used in special cases
1238 1237
  /// when extra actions have to be performed in connection with certain
1239 1238
  /// events of the DFS algorithm. Otherwise consider to use Dfs or dfs()
1240 1239
  /// instead.
1241 1240
  ///
1242
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1243
  /// The default value is
1244
  /// \ref ListDigraph. The value of _Digraph is not used directly by
1245
  /// \ref DfsVisit, it is only passed to \ref DfsVisitDefaultTraits.
1246
  /// \tparam _Visitor The Visitor type that is used by the algorithm.
1247
  /// \ref DfsVisitor "DfsVisitor<_Digraph>" is an empty visitor, which
1241
  /// \tparam GR The type of the digraph the algorithm runs on.
1242
  /// The default type is \ref ListDigraph.
1243
  /// The value of GR is not used directly by \ref DfsVisit,
1244
  /// it is only passed to \ref DfsVisitDefaultTraits.
1245
  /// \tparam VS The Visitor type that is used by the algorithm.
1246
  /// \ref DfsVisitor "DfsVisitor<GR>" is an empty visitor, which
1248 1247
  /// does not observe the DFS events. If you want to observe the DFS
1249 1248
  /// events, you should implement your own visitor class.
1250
  /// \tparam _Traits Traits class to set various data types used by the
1249
  /// \tparam TR Traits class to set various data types used by the
1251 1250
  /// algorithm. The default traits class is
1252
  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<_Digraph>".
1251
  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<GR>".
1253 1252
  /// See \ref DfsVisitDefaultTraits for the documentation of
1254 1253
  /// a DFS visit traits class.
1255 1254
#ifdef DOXYGEN
1256
  template <typename _Digraph, typename _Visitor, typename _Traits>
1255
  template <typename GR, typename VS, typename TR>
1257 1256
#else
1258
  template <typename _Digraph = ListDigraph,
1259
            typename _Visitor = DfsVisitor<_Digraph>,
1260
            typename _Traits = DfsVisitDefaultTraits<_Digraph> >
1257
  template <typename GR = ListDigraph,
1258
            typename VS = DfsVisitor<GR>,
1259
            typename TR = DfsVisitDefaultTraits<GR> >
1261 1260
#endif
1262 1261
  class DfsVisit {
1263 1262
  public:
1264 1263

	
1265 1264
    ///The traits class.
1266
    typedef _Traits Traits;
1265
    typedef TR Traits;
1267 1266

	
1268 1267
    ///The type of the digraph the algorithm runs on.
1269 1268
    typedef typename Traits::Digraph Digraph;
1270 1269

	
1271 1270
    ///The visitor type used by the algorithm.
1272
    typedef _Visitor Visitor;
1271
    typedef VS Visitor;
1273 1272

	
1274 1273
    ///The type of the map that indicates which nodes are reached.
1275 1274
    typedef typename Traits::ReachedMap ReachedMap;
1276 1275

	
1277 1276
  private:
1278 1277

	
1279 1278
    typedef typename Digraph::Node Node;
1280 1279
    typedef typename Digraph::NodeIt NodeIt;
1281 1280
    typedef typename Digraph::Arc Arc;
1282 1281
    typedef typename Digraph::OutArcIt OutArcIt;
1283 1282

	
1284 1283
    //Pointer to the underlying digraph.
1285 1284
    const Digraph *_digraph;
1286 1285
    //Pointer to the visitor object.
1287 1286
    Visitor *_visitor;
1288 1287
    //Pointer to the map of reached status of the nodes.
1289 1288
    ReachedMap *_reached;
1290 1289
    //Indicates if _reached is locally allocated (true) or not.
1291 1290
    bool local_reached;
1292 1291

	
1293 1292
    std::vector<typename Digraph::Arc> _stack;
1294 1293
    int _stack_head;
1295 1294

	
1296 1295
    //Creates the maps if necessary.
1297 1296
    void create_maps() {
1298 1297
      if(!_reached) {
1299 1298
        local_reached = true;
1300 1299
        _reached = Traits::createReachedMap(*_digraph);
1301 1300
      }
1302 1301
    }
1303 1302

	
1304 1303
  protected:
1305 1304

	
1306 1305
    DfsVisit() {}
1307 1306

	
1308 1307
  public:
1309 1308

	
1310 1309
    typedef DfsVisit Create;
1311 1310

	
1312
    /// \name Named template parameters
1311
    /// \name Named Template Parameters
1313 1312

	
1314 1313
    ///@{
1315 1314
    template <class T>
1316 1315
    struct SetReachedMapTraits : public Traits {
1317 1316
      typedef T ReachedMap;
1318 1317
      static ReachedMap *createReachedMap(const Digraph &digraph) {
1319 1318
        LEMON_ASSERT(false, "ReachedMap is not initialized");
1320 1319
        return 0; // ignore warnings
1321 1320
      }
1322 1321
    };
1323 1322
    /// \brief \ref named-templ-param "Named parameter" for setting
1324 1323
    /// ReachedMap type.
1325 1324
    ///
1326 1325
    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
1327 1326
    template <class T>
1328 1327
    struct SetReachedMap : public DfsVisit< Digraph, Visitor,
1329 1328
                                            SetReachedMapTraits<T> > {
1330 1329
      typedef DfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
1331 1330
    };
1332 1331
    ///@}
1333 1332

	
1334 1333
  public:
1335 1334

	
1336 1335
    /// \brief Constructor.
1337 1336
    ///
1338 1337
    /// Constructor.
1339 1338
    ///
1340 1339
    /// \param digraph The digraph the algorithm runs on.
1341 1340
    /// \param visitor The visitor object of the algorithm.
1342 1341
    DfsVisit(const Digraph& digraph, Visitor& visitor)
1343 1342
      : _digraph(&digraph), _visitor(&visitor),
1344 1343
        _reached(0), local_reached(false) {}
1345 1344

	
1346 1345
    /// \brief Destructor.
1347 1346
    ~DfsVisit() {
1348 1347
      if(local_reached) delete _reached;
1349 1348
    }
1350 1349

	
1351 1350
    /// \brief Sets the map that indicates which nodes are reached.
1352 1351
    ///
1353 1352
    /// Sets the map that indicates which nodes are reached.
1354
    /// If you don't use this function before calling \ref run(),
1355
    /// it will allocate one. The destructor deallocates this
1356
    /// automatically allocated map, of course.
1353
    /// If you don't use this function before calling \ref run(Node) "run()"
1354
    /// or \ref init(), an instance will be allocated automatically.
1355
    /// The destructor deallocates this automatically allocated map,
1356
    /// of course.
1357 1357
    /// \return <tt> (*this) </tt>
1358 1358
    DfsVisit &reachedMap(ReachedMap &m) {
1359 1359
      if(local_reached) {
1360 1360
        delete _reached;
1361 1361
        local_reached=false;
1362 1362
      }
1363 1363
      _reached = &m;
1364 1364
      return *this;
1365 1365
    }
1366 1366

	
1367 1367
  public:
1368 1368

	
1369
    /// \name Execution control
1370
    /// The simplest way to execute the algorithm is to use
1371
    /// one of the member functions called \ref lemon::DfsVisit::run()
1372
    /// "run()".
1373
    /// \n
1374
    /// If you need more control on the execution, first you must call
1375
    /// \ref lemon::DfsVisit::init() "init()", then you can add several
1376
    /// source nodes with \ref lemon::DfsVisit::addSource() "addSource()".
1377
    /// Finally \ref lemon::DfsVisit::start() "start()" will perform the
1378
    /// actual path computation.
1369
    /// \name Execution Control
1370
    /// The simplest way to execute the DFS algorithm is to use one of the
1371
    /// member functions called \ref run(Node) "run()".\n
1372
    /// If you need more control on the execution, first you have to call
1373
    /// \ref init(), then you can add a source node with \ref addSource()
1374
    /// and perform the actual computation with \ref start().
1375
    /// This procedure can be repeated if there are nodes that have not
1376
    /// been reached.
1379 1377

	
1380 1378
    /// @{
1381 1379

	
1382 1380
    /// \brief Initializes the internal data structures.
1383 1381
    ///
1384 1382
    /// Initializes the internal data structures.
1385 1383
    void init() {
1386 1384
      create_maps();
1387 1385
      _stack.resize(countNodes(*_digraph));
1388 1386
      _stack_head = -1;
1389 1387
      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
1390 1388
        _reached->set(u, false);
1391 1389
      }
1392 1390
    }
1393 1391

	
1394
    ///Adds a new source node.
1395

	
1396
    ///Adds a new source node to the set of nodes to be processed.
1392
    /// \brief Adds a new source node.
1397 1393
    ///
1398
    ///\pre The stack must be empty. (Otherwise the algorithm gives
1399
    ///false results.)
1394
    /// Adds a new source node to the set of nodes to be processed.
1400 1395
    ///
1401
    ///\warning Distances will be wrong (or at least strange) in case of
1402
    ///multiple sources.
1396
    /// \pre The stack must be empty. Otherwise the algorithm gives
1397
    /// wrong results. (One of the outgoing arcs of all the source nodes
1398
    /// except for the last one will not be visited and distances will
1399
    /// also be wrong.)
1403 1400
    void addSource(Node s)
1404 1401
    {
1405 1402
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
1406 1403
      if(!(*_reached)[s]) {
1407 1404
          _reached->set(s,true);
1408 1405
          _visitor->start(s);
1409 1406
          _visitor->reach(s);
1410 1407
          Arc e;
1411 1408
          _digraph->firstOut(e, s);
1412 1409
          if (e != INVALID) {
1413 1410
            _stack[++_stack_head] = e;
1414 1411
          } else {
1415 1412
            _visitor->leave(s);
1413
            _visitor->stop(s);
1416 1414
          }
1417 1415
        }
1418 1416
    }
1419 1417

	
1420 1418
    /// \brief Processes the next arc.
1421 1419
    ///
1422 1420
    /// Processes the next arc.
1423 1421
    ///
1424 1422
    /// \return The processed arc.
1425 1423
    ///
1426 1424
    /// \pre The stack must not be empty.
1427 1425
    Arc processNextArc() {
1428 1426
      Arc e = _stack[_stack_head];
1429 1427
      Node m = _digraph->target(e);
1430 1428
      if(!(*_reached)[m]) {
1431 1429
        _visitor->discover(e);
1432 1430
        _visitor->reach(m);
1433 1431
        _reached->set(m, true);
1434 1432
        _digraph->firstOut(_stack[++_stack_head], m);
1435 1433
      } else {
1436 1434
        _visitor->examine(e);
1437 1435
        m = _digraph->source(e);
1438 1436
        _digraph->nextOut(_stack[_stack_head]);
1439 1437
      }
1440 1438
      while (_stack_head>=0 && _stack[_stack_head] == INVALID) {
1441 1439
        _visitor->leave(m);
1442 1440
        --_stack_head;
1443 1441
        if (_stack_head >= 0) {
1444 1442
          _visitor->backtrack(_stack[_stack_head]);
1445 1443
          m = _digraph->source(_stack[_stack_head]);
1446 1444
          _digraph->nextOut(_stack[_stack_head]);
1447 1445
        } else {
1448 1446
          _visitor->stop(m);
1449 1447
        }
1450 1448
      }
1451 1449
      return e;
1452 1450
    }
1453 1451

	
1454 1452
    /// \brief Next arc to be processed.
1455 1453
    ///
1456 1454
    /// Next arc to be processed.
1457 1455
    ///
1458 1456
    /// \return The next arc to be processed or INVALID if the stack is
1459 1457
    /// empty.
1460 1458
    Arc nextArc() const {
1461 1459
      return _stack_head >= 0 ? _stack[_stack_head] : INVALID;
1462 1460
    }
1463 1461

	
1464 1462
    /// \brief Returns \c false if there are nodes
1465 1463
    /// to be processed.
1466 1464
    ///
1467 1465
    /// Returns \c false if there are nodes
1468 1466
    /// to be processed in the queue (stack).
1469 1467
    bool emptyQueue() const { return _stack_head < 0; }
1470 1468

	
1471 1469
    /// \brief Returns the number of the nodes to be processed.
1472 1470
    ///
1473 1471
    /// Returns the number of the nodes to be processed in the queue (stack).
1474 1472
    int queueSize() const { return _stack_head + 1; }
1475 1473

	
1476 1474
    /// \brief Executes the algorithm.
1477 1475
    ///
1478 1476
    /// Executes the algorithm.
1479 1477
    ///
1480 1478
    /// This method runs the %DFS algorithm from the root node
1481 1479
    /// in order to compute the %DFS path to each node.
1482 1480
    ///
1483 1481
    /// The algorithm computes
1484 1482
    /// - the %DFS tree,
1485 1483
    /// - the distance of each node from the root in the %DFS tree.
1486 1484
    ///
1487 1485
    /// \pre init() must be called and a root node should be
1488 1486
    /// added with addSource() before using this function.
1489 1487
    ///
1490 1488
    /// \note <tt>d.start()</tt> is just a shortcut of the following code.
1491 1489
    /// \code
1492 1490
    ///   while ( !d.emptyQueue() ) {
1493 1491
    ///     d.processNextArc();
1494 1492
    ///   }
1495 1493
    /// \endcode
1496 1494
    void start() {
1497 1495
      while ( !emptyQueue() ) processNextArc();
1498 1496
    }
1499 1497

	
1500 1498
    /// \brief Executes the algorithm until the given target node is reached.
1501 1499
    ///
1502 1500
    /// Executes the algorithm until the given target node is reached.
1503 1501
    ///
1504 1502
    /// This method runs the %DFS algorithm from the root node
1505 1503
    /// in order to compute the DFS path to \c t.
1506 1504
    ///
1507 1505
    /// The algorithm computes
1508 1506
    /// - the %DFS path to \c t,
1509 1507
    /// - the distance of \c t from the root in the %DFS tree.
1510 1508
    ///
1511 1509
    /// \pre init() must be called and a root node should be added
1512 1510
    /// with addSource() before using this function.
1513 1511
    void start(Node t) {
1514 1512
      while ( !emptyQueue() && _digraph->target(_stack[_stack_head]) != t )
1515 1513
        processNextArc();
1516 1514
    }
1517 1515

	
1518 1516
    /// \brief Executes the algorithm until a condition is met.
1519 1517
    ///
1520 1518
    /// Executes the algorithm until a condition is met.
1521 1519
    ///
1522 1520
    /// This method runs the %DFS algorithm from the root node
1523 1521
    /// until an arc \c a with <tt>am[a]</tt> true is found.
1524 1522
    ///
1525 1523
    /// \param am A \c bool (or convertible) arc map. The algorithm
1526 1524
    /// will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
1527 1525
    ///
1528 1526
    /// \return The reached arc \c a with <tt>am[a]</tt> true or
1529 1527
    /// \c INVALID if no such arc was found.
1530 1528
    ///
1531 1529
    /// \pre init() must be called and a root node should be added
1532 1530
    /// with addSource() before using this function.
1533 1531
    ///
1534 1532
    /// \warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
1535 1533
    /// not a node map.
1536 1534
    template <typename AM>
1537 1535
    Arc start(const AM &am) {
1538 1536
      while ( !emptyQueue() && !am[_stack[_stack_head]] )
1539 1537
        processNextArc();
1540 1538
      return emptyQueue() ? INVALID : _stack[_stack_head];
1541 1539
    }
1542 1540

	
1543 1541
    /// \brief Runs the algorithm from the given source node.
1544 1542
    ///
1545 1543
    /// This method runs the %DFS algorithm from node \c s.
1546 1544
    /// in order to compute the DFS path to each node.
1547 1545
    ///
1548 1546
    /// The algorithm computes
1549 1547
    /// - the %DFS tree,
1550 1548
    /// - the distance of each node from the root in the %DFS tree.
1551 1549
    ///
1552 1550
    /// \note <tt>d.run(s)</tt> is just a shortcut of the following code.
1553 1551
    ///\code
1554 1552
    ///   d.init();
1555 1553
    ///   d.addSource(s);
1556 1554
    ///   d.start();
1557 1555
    ///\endcode
1558 1556
    void run(Node s) {
1559 1557
      init();
1560 1558
      addSource(s);
1561 1559
      start();
1562 1560
    }
1563 1561

	
1564 1562
    /// \brief Finds the %DFS path between \c s and \c t.
1565 1563

	
1566 1564
    /// This method runs the %DFS algorithm from node \c s
1567 1565
    /// in order to compute the DFS path to node \c t
1568 1566
    /// (it stops searching when \c t is processed).
1569 1567
    ///
1570 1568
    /// \return \c true if \c t is reachable form \c s.
1571 1569
    ///
1572 1570
    /// \note Apart from the return value, <tt>d.run(s,t)</tt> is
1573 1571
    /// just a shortcut of the following code.
1574 1572
    ///\code
1575 1573
    ///   d.init();
1576 1574
    ///   d.addSource(s);
1577 1575
    ///   d.start(t);
1578 1576
    ///\endcode
1579 1577
    bool run(Node s,Node t) {
1580 1578
      init();
1581 1579
      addSource(s);
1582 1580
      start(t);
1583 1581
      return reached(t);
1584 1582
    }
1585 1583

	
1586 1584
    /// \brief Runs the algorithm to visit all nodes in the digraph.
1587 1585

	
1588 1586
    /// This method runs the %DFS algorithm in order to
1589 1587
    /// compute the %DFS path to each node.
1590 1588
    ///
1591 1589
    /// The algorithm computes
1592
    /// - the %DFS tree,
1593
    /// - the distance of each node from the root in the %DFS tree.
1590
    /// - the %DFS tree (forest),
1591
    /// - the distance of each node from the root(s) in the %DFS tree.
1594 1592
    ///
1595 1593
    /// \note <tt>d.run()</tt> is just a shortcut of the following code.
1596 1594
    ///\code
1597 1595
    ///   d.init();
1598 1596
    ///   for (NodeIt n(digraph); n != INVALID; ++n) {
1599 1597
    ///     if (!d.reached(n)) {
1600 1598
    ///       d.addSource(n);
1601 1599
    ///       d.start();
1602 1600
    ///     }
1603 1601
    ///   }
1604 1602
    ///\endcode
1605 1603
    void run() {
1606 1604
      init();
1607 1605
      for (NodeIt it(*_digraph); it != INVALID; ++it) {
1608 1606
        if (!reached(it)) {
1609 1607
          addSource(it);
1610 1608
          start();
1611 1609
        }
1612 1610
      }
1613 1611
    }
1614 1612

	
1615 1613
    ///@}
1616 1614

	
1617 1615
    /// \name Query Functions
1618
    /// The result of the %DFS algorithm can be obtained using these
1616
    /// The results of the DFS algorithm can be obtained using these
1619 1617
    /// functions.\n
1620
    /// Either \ref lemon::DfsVisit::run() "run()" or
1621
    /// \ref lemon::DfsVisit::start() "start()" must be called before
1622
    /// using them.
1618
    /// Either \ref run(Node) "run()" or \ref start() should be called
1619
    /// before using them.
1620

	
1623 1621
    ///@{
1624 1622

	
1625
    /// \brief Checks if a node is reachable from the root(s).
1623
    /// \brief Checks if a node is reached from the root(s).
1626 1624
    ///
1627
    /// Returns \c true if \c v is reachable from the root(s).
1628
    /// \pre Either \ref run() or \ref start()
1625
    /// Returns \c true if \c v is reached from the root(s).
1626
    ///
1627
    /// \pre Either \ref run(Node) "run()" or \ref init()
1629 1628
    /// must be called before using this function.
1630
    bool reached(Node v) { return (*_reached)[v]; }
1629
    bool reached(Node v) const { return (*_reached)[v]; }
1631 1630

	
1632 1631
    ///@}
1633 1632

	
1634 1633
  };
1635 1634

	
1636 1635
} //END OF NAMESPACE LEMON
1637 1636

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

	
19 19
#ifndef LEMON_DIJKSTRA_H
20 20
#define LEMON_DIJKSTRA_H
21 21

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

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

	
35 35
namespace lemon {
36 36

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

	
57 59
  ///Default traits class of Dijkstra class.
58 60

	
59 61
  ///Default traits class of Dijkstra class.
60 62
  ///\tparam GR The type of the digraph.
61
  ///\tparam LM The type of the length map.
62
  template<class GR, class LM>
63
  ///\tparam LEN The type of the length map.
64
  template<typename GR, typename LEN>
63 65
  struct DijkstraDefaultTraits
64 66
  {
65 67
    ///The type of the digraph the algorithm runs on.
66 68
    typedef GR Digraph;
67 69

	
68 70
    ///The type of the map that stores the arc lengths.
69 71

	
70 72
    ///The type of the map that stores the arc lengths.
71 73
    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
72
    typedef LM LengthMap;
74
    typedef LEN LengthMap;
73 75
    ///The type of the length of the arcs.
74
    typedef typename LM::Value Value;
76
    typedef typename LEN::Value Value;
75 77

	
76
    /// Operation traits for Dijkstra algorithm.
78
    /// Operation traits for %Dijkstra algorithm.
77 79

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

	
82 84
    /// The cross reference type used by the heap.
83 85

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

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

	
97
    ///The heap type used by the Dijkstra algorithm.
99
    ///The heap type used by the %Dijkstra algorithm.
98 100

	
99 101
    ///The heap type used by the Dijkstra algorithm.
100 102
    ///
101 103
    ///\sa BinHeap
102 104
    ///\sa Dijkstra
103
    typedef BinHeap<typename LM::Value, HeapCrossRef, std::less<Value> > Heap;
104
    ///Instantiates a \ref Heap.
105
    typedef BinHeap<typename LEN::Value, HeapCrossRef, std::less<Value> > Heap;
106
    ///Instantiates a \c Heap.
105 107

	
106 108
    ///This function instantiates a \ref Heap.
107 109
    static Heap *createHeap(HeapCrossRef& r)
108 110
    {
109 111
      return new Heap(r);
110 112
    }
111 113

	
112 114
    ///\brief The type of the map that stores the predecessor
113 115
    ///arcs of the shortest paths.
114 116
    ///
115 117
    ///The type of the map that stores the predecessor
116 118
    ///arcs of the shortest paths.
117 119
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
118 120
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
119
    ///Instantiates a PredMap.
121
    ///Instantiates a \c PredMap.
120 122

	
121
    ///This function instantiates a PredMap.
123
    ///This function instantiates a \ref PredMap.
122 124
    ///\param g is the digraph, to which we would like to define the
123
    ///PredMap.
125
    ///\ref PredMap.
124 126
    static PredMap *createPredMap(const Digraph &g)
125 127
    {
126 128
      return new PredMap(g);
127 129
    }
128 130

	
129 131
    ///The type of the map that indicates which nodes are processed.
130 132

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

	
137
    ///This function instantiates a ProcessedMap.
139
    ///This function instantiates a \ref ProcessedMap.
138 140
    ///\param g is the digraph, to which
139
    ///we would like to define the ProcessedMap
141
    ///we would like to define the \ref ProcessedMap.
140 142
#ifdef DOXYGEN
141 143
    static ProcessedMap *createProcessedMap(const Digraph &g)
142 144
#else
143 145
    static ProcessedMap *createProcessedMap(const Digraph &)
144 146
#endif
145 147
    {
146 148
      return new ProcessedMap();
147 149
    }
148 150

	
149 151
    ///The type of the map that stores the distances of the nodes.
150 152

	
151 153
    ///The type of the map that stores the distances of the nodes.
152 154
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
153
    typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
154
    ///Instantiates a DistMap.
155
    typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
156
    ///Instantiates a \c DistMap.
155 157

	
156
    ///This function instantiates a DistMap.
158
    ///This function instantiates a \ref DistMap.
157 159
    ///\param g is the digraph, to which we would like to define
158
    ///the DistMap
160
    ///the \ref DistMap.
159 161
    static DistMap *createDistMap(const Digraph &g)
160 162
    {
161 163
      return new DistMap(g);
162 164
    }
163 165
  };
164 166

	
165 167
  ///%Dijkstra algorithm class.
166 168

	
167 169
  /// \ingroup shortest_path
168 170
  ///This class provides an efficient implementation of the %Dijkstra algorithm.
169 171
  ///
170 172
  ///The arc lengths are passed to the algorithm using a
171 173
  ///\ref concepts::ReadMap "ReadMap",
172 174
  ///so it is easy to change it to any kind of length.
173 175
  ///The type of the length is determined by the
174 176
  ///\ref concepts::ReadMap::Value "Value" of the length map.
175 177
  ///It is also possible to change the underlying priority heap.
176 178
  ///
177 179
  ///There is also a \ref dijkstra() "function-type interface" for the
178 180
  ///%Dijkstra algorithm, which is convenient in the simplier cases and
179 181
  ///it can be used easier.
180 182
  ///
181 183
  ///\tparam GR The type of the digraph the algorithm runs on.
182
  ///The default value is \ref ListDigraph.
183
  ///The value of GR is not used directly by \ref Dijkstra, it is only
184
  ///passed to \ref DijkstraDefaultTraits.
185
  ///\tparam LM A readable arc map that determines the lengths of the
186
  ///arcs. It is read once for each arc, so the map may involve in
184
  ///The default type is \ref ListDigraph.
185
  ///\tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
186
  ///the lengths of the arcs.
187
  ///It is read once for each arc, so the map may involve in
187 188
  ///relatively time consuming process to compute the arc lengths if
188 189
  ///it is necessary. The default map type is \ref
189
  ///concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
190
  ///The value of LM is not used directly by \ref Dijkstra, it is only
191
  ///passed to \ref DijkstraDefaultTraits.
192
  ///\tparam TR Traits class to set various data types used by the algorithm.
193
  ///The default traits class is \ref DijkstraDefaultTraits
194
  ///"DijkstraDefaultTraits<GR,LM>". See \ref DijkstraDefaultTraits
195
  ///for the documentation of a Dijkstra traits class.
190
  ///concepts::Digraph::ArcMap "GR::ArcMap<int>".
196 191
#ifdef DOXYGEN
197
  template <typename GR, typename LM, typename TR>
192
  template <typename GR, typename LEN, typename TR>
198 193
#else
199 194
  template <typename GR=ListDigraph,
200
            typename LM=typename GR::template ArcMap<int>,
201
            typename TR=DijkstraDefaultTraits<GR,LM> >
195
            typename LEN=typename GR::template ArcMap<int>,
196
            typename TR=DijkstraDefaultTraits<GR,LEN> >
202 197
#endif
203 198
  class Dijkstra {
204 199
  public:
205 200

	
206 201
    ///The type of the digraph the algorithm runs on.
207 202
    typedef typename TR::Digraph Digraph;
208 203

	
209 204
    ///The type of the length of the arcs.
210 205
    typedef typename TR::LengthMap::Value Value;
211 206
    ///The type of the map that stores the arc lengths.
212 207
    typedef typename TR::LengthMap LengthMap;
213 208
    ///\brief The type of the map that stores the predecessor arcs of the
214 209
    ///shortest paths.
215 210
    typedef typename TR::PredMap PredMap;
216 211
    ///The type of the map that stores the distances of the nodes.
217 212
    typedef typename TR::DistMap DistMap;
218 213
    ///The type of the map that indicates which nodes are processed.
219 214
    typedef typename TR::ProcessedMap ProcessedMap;
220 215
    ///The type of the paths.
221 216
    typedef PredMapPath<Digraph, PredMap> Path;
222 217
    ///The cross reference type used for the current heap.
223 218
    typedef typename TR::HeapCrossRef HeapCrossRef;
224 219
    ///The heap type used by the algorithm.
225 220
    typedef typename TR::Heap Heap;
226
    ///The operation traits class.
221
    ///\brief The \ref DijkstraDefaultOperationTraits "operation traits class"
222
    ///of the algorithm.
227 223
    typedef typename TR::OperationTraits OperationTraits;
228 224

	
229
    ///The traits class.
225
    ///The \ref DijkstraDefaultTraits "traits class" of the algorithm.
230 226
    typedef TR Traits;
231 227

	
232 228
  private:
233 229

	
234 230
    typedef typename Digraph::Node Node;
235 231
    typedef typename Digraph::NodeIt NodeIt;
236 232
    typedef typename Digraph::Arc Arc;
237 233
    typedef typename Digraph::OutArcIt OutArcIt;
238 234

	
239 235
    //Pointer to the underlying digraph.
240 236
    const Digraph *G;
241 237
    //Pointer to the length map.
242
    const LengthMap *length;
238
    const LengthMap *_length;
243 239
    //Pointer to the map of predecessors arcs.
244 240
    PredMap *_pred;
245 241
    //Indicates if _pred is locally allocated (true) or not.
246 242
    bool local_pred;
247 243
    //Pointer to the map of distances.
248 244
    DistMap *_dist;
249 245
    //Indicates if _dist is locally allocated (true) or not.
250 246
    bool local_dist;
251 247
    //Pointer to the map of processed status of the nodes.
252 248
    ProcessedMap *_processed;
253 249
    //Indicates if _processed is locally allocated (true) or not.
254 250
    bool local_processed;
255 251
    //Pointer to the heap cross references.
256 252
    HeapCrossRef *_heap_cross_ref;
257 253
    //Indicates if _heap_cross_ref is locally allocated (true) or not.
258 254
    bool local_heap_cross_ref;
259 255
    //Pointer to the heap.
260 256
    Heap *_heap;
261 257
    //Indicates if _heap is locally allocated (true) or not.
262 258
    bool local_heap;
263 259

	
264 260
    //Creates the maps if necessary.
265 261
    void create_maps()
266 262
    {
267 263
      if(!_pred) {
268 264
        local_pred = true;
269 265
        _pred = Traits::createPredMap(*G);
270 266
      }
271 267
      if(!_dist) {
272 268
        local_dist = true;
273 269
        _dist = Traits::createDistMap(*G);
274 270
      }
275 271
      if(!_processed) {
276 272
        local_processed = true;
277 273
        _processed = Traits::createProcessedMap(*G);
278 274
      }
279 275
      if (!_heap_cross_ref) {
280 276
        local_heap_cross_ref = true;
281 277
        _heap_cross_ref = Traits::createHeapCrossRef(*G);
282 278
      }
283 279
      if (!_heap) {
284 280
        local_heap = true;
285 281
        _heap = Traits::createHeap(*_heap_cross_ref);
286 282
      }
287 283
    }
288 284

	
289 285
  public:
290 286

	
291 287
    typedef Dijkstra Create;
292 288

	
293
    ///\name Named template parameters
289
    ///\name Named Template Parameters
294 290

	
295 291
    ///@{
296 292

	
297 293
    template <class T>
298 294
    struct SetPredMapTraits : public Traits {
299 295
      typedef T PredMap;
300 296
      static PredMap *createPredMap(const Digraph &)
301 297
      {
302 298
        LEMON_ASSERT(false, "PredMap is not initialized");
303 299
        return 0; // ignore warnings
304 300
      }
305 301
    };
306 302
    ///\brief \ref named-templ-param "Named parameter" for setting
307
    ///PredMap type.
303
    ///\c PredMap type.
308 304
    ///
309 305
    ///\ref named-templ-param "Named parameter" for setting
310
    ///PredMap type.
306
    ///\c PredMap type.
307
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
311 308
    template <class T>
312 309
    struct SetPredMap
313 310
      : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
314 311
      typedef Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > Create;
315 312
    };
316 313

	
317 314
    template <class T>
318 315
    struct SetDistMapTraits : public Traits {
319 316
      typedef T DistMap;
320 317
      static DistMap *createDistMap(const Digraph &)
321 318
      {
322 319
        LEMON_ASSERT(false, "DistMap is not initialized");
323 320
        return 0; // ignore warnings
324 321
      }
325 322
    };
326 323
    ///\brief \ref named-templ-param "Named parameter" for setting
327
    ///DistMap type.
324
    ///\c DistMap type.
328 325
    ///
329 326
    ///\ref named-templ-param "Named parameter" for setting
330
    ///DistMap type.
327
    ///\c DistMap type.
328
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
331 329
    template <class T>
332 330
    struct SetDistMap
333 331
      : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
334 332
      typedef Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > Create;
335 333
    };
336 334

	
337 335
    template <class T>
338 336
    struct SetProcessedMapTraits : public Traits {
339 337
      typedef T ProcessedMap;
340 338
      static ProcessedMap *createProcessedMap(const Digraph &)
341 339
      {
342 340
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
343 341
        return 0; // ignore warnings
344 342
      }
345 343
    };
346 344
    ///\brief \ref named-templ-param "Named parameter" for setting
347
    ///ProcessedMap type.
345
    ///\c ProcessedMap type.
348 346
    ///
349 347
    ///\ref named-templ-param "Named parameter" for setting
350
    ///ProcessedMap type.
348
    ///\c ProcessedMap type.
349
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
351 350
    template <class T>
352 351
    struct SetProcessedMap
353 352
      : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
354 353
      typedef Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > Create;
355 354
    };
356 355

	
357 356
    struct SetStandardProcessedMapTraits : public Traits {
358 357
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
359 358
      static ProcessedMap *createProcessedMap(const Digraph &g)
360 359
      {
361 360
        return new ProcessedMap(g);
362 361
      }
363 362
    };
364 363
    ///\brief \ref named-templ-param "Named parameter" for setting
365
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
364
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
366 365
    ///
367 366
    ///\ref named-templ-param "Named parameter" for setting
368
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
367
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
369 368
    ///If you don't set it explicitly, it will be automatically allocated.
370 369
    struct SetStandardProcessedMap
371 370
      : public Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits > {
372 371
      typedef Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits >
373 372
      Create;
374 373
    };
375 374

	
376 375
    template <class H, class CR>
377 376
    struct SetHeapTraits : public Traits {
378 377
      typedef CR HeapCrossRef;
379 378
      typedef H Heap;
380 379
      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
381 380
        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
382 381
        return 0; // ignore warnings
383 382
      }
384 383
      static Heap *createHeap(HeapCrossRef &)
385 384
      {
386 385
        LEMON_ASSERT(false, "Heap is not initialized");
387 386
        return 0; // ignore warnings
388 387
      }
389 388
    };
390 389
    ///\brief \ref named-templ-param "Named parameter" for setting
391
    ///heap and cross reference type
390
    ///heap and cross reference types
392 391
    ///
393 392
    ///\ref named-templ-param "Named parameter" for setting heap and cross
394
    ///reference type.
393
    ///reference types. If this named parameter is used, then external
394
    ///heap and cross reference objects must be passed to the algorithm
395
    ///using the \ref heap() function before calling \ref run(Node) "run()"
396
    ///or \ref init().
397
    ///\sa SetStandardHeap
395 398
    template <class H, class CR = typename Digraph::template NodeMap<int> >
396 399
    struct SetHeap
397 400
      : public Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > {
398 401
      typedef Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > Create;
399 402
    };
400 403

	
401 404
    template <class H, class CR>
402 405
    struct SetStandardHeapTraits : public Traits {
403 406
      typedef CR HeapCrossRef;
404 407
      typedef H Heap;
405 408
      static HeapCrossRef *createHeapCrossRef(const Digraph &G) {
406 409
        return new HeapCrossRef(G);
407 410
      }
408 411
      static Heap *createHeap(HeapCrossRef &R)
409 412
      {
410 413
        return new Heap(R);
411 414
      }
412 415
    };
413 416
    ///\brief \ref named-templ-param "Named parameter" for setting
414
    ///heap and cross reference type with automatic allocation
417
    ///heap and cross reference types with automatic allocation
415 418
    ///
416 419
    ///\ref named-templ-param "Named parameter" for setting heap and cross
417
    ///reference type. It can allocate the heap and the cross reference
418
    ///object if the cross reference's constructor waits for the digraph as
419
    ///parameter and the heap's constructor waits for the cross reference.
420
    ///reference types with automatic allocation.
421
    ///They should have standard constructor interfaces to be able to
422
    ///automatically created by the algorithm (i.e. the digraph should be
423
    ///passed to the constructor of the cross reference and the cross
424
    ///reference should be passed to the constructor of the heap).
425
    ///However external heap and cross reference objects could also be
426
    ///passed to the algorithm using the \ref heap() function before
427
    ///calling \ref run(Node) "run()" or \ref init().
428
    ///\sa SetHeap
420 429
    template <class H, class CR = typename Digraph::template NodeMap<int> >
421 430
    struct SetStandardHeap
422 431
      : public Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> > {
423 432
      typedef Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> >
424 433
      Create;
425 434
    };
426 435

	
427 436
    template <class T>
428 437
    struct SetOperationTraitsTraits : public Traits {
429 438
      typedef T OperationTraits;
430 439
    };
431 440

	
432 441
    /// \brief \ref named-templ-param "Named parameter" for setting
433 442
    ///\c OperationTraits type
434 443
    ///
435 444
    ///\ref named-templ-param "Named parameter" for setting
436
    ///\ref OperationTraits type.
445
    ///\c OperationTraits type.
437 446
    template <class T>
438 447
    struct SetOperationTraits
439 448
      : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
440 449
      typedef Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> >
441 450
      Create;
442 451
    };
443 452

	
444 453
    ///@}
445 454

	
446 455
  protected:
447 456

	
448 457
    Dijkstra() {}
449 458

	
450 459
  public:
451 460

	
452 461
    ///Constructor.
453 462

	
454 463
    ///Constructor.
455
    ///\param _g The digraph the algorithm runs on.
456
    ///\param _length The length map used by the algorithm.
457
    Dijkstra(const Digraph& _g, const LengthMap& _length) :
458
      G(&_g), length(&_length),
464
    ///\param g The digraph the algorithm runs on.
465
    ///\param length The length map used by the algorithm.
466
    Dijkstra(const Digraph& g, const LengthMap& length) :
467
      G(&g), _length(&length),
459 468
      _pred(NULL), local_pred(false),
460 469
      _dist(NULL), local_dist(false),
461 470
      _processed(NULL), local_processed(false),
462 471
      _heap_cross_ref(NULL), local_heap_cross_ref(false),
463 472
      _heap(NULL), local_heap(false)
464 473
    { }
465 474

	
466 475
    ///Destructor.
467 476
    ~Dijkstra()
468 477
    {
469 478
      if(local_pred) delete _pred;
470 479
      if(local_dist) delete _dist;
471 480
      if(local_processed) delete _processed;
472 481
      if(local_heap_cross_ref) delete _heap_cross_ref;
473 482
      if(local_heap) delete _heap;
474 483
    }
475 484

	
476 485
    ///Sets the length map.
477 486

	
478 487
    ///Sets the length map.
479 488
    ///\return <tt> (*this) </tt>
480 489
    Dijkstra &lengthMap(const LengthMap &m)
481 490
    {
482
      length = &m;
491
      _length = &m;
483 492
      return *this;
484 493
    }
485 494

	
486 495
    ///Sets the map that stores the predecessor arcs.
487 496

	
488 497
    ///Sets the map that stores the predecessor arcs.
489
    ///If you don't use this function before calling \ref run(),
490
    ///it will allocate one. The destructor deallocates this
491
    ///automatically allocated map, of course.
498
    ///If you don't use this function before calling \ref run(Node) "run()"
499
    ///or \ref init(), an instance will be allocated automatically.
500
    ///The destructor deallocates this automatically allocated map,
501
    ///of course.
492 502
    ///\return <tt> (*this) </tt>
493 503
    Dijkstra &predMap(PredMap &m)
494 504
    {
495 505
      if(local_pred) {
496 506
        delete _pred;
497 507
        local_pred=false;
498 508
      }
499 509
      _pred = &m;
500 510
      return *this;
501 511
    }
502 512

	
503 513
    ///Sets the map that indicates which nodes are processed.
504 514

	
505 515
    ///Sets the map that indicates which nodes are processed.
506
    ///If you don't use this function before calling \ref run(),
507
    ///it will allocate one. The destructor deallocates this
508
    ///automatically allocated map, of course.
516
    ///If you don't use this function before calling \ref run(Node) "run()"
517
    ///or \ref init(), an instance will be allocated automatically.
518
    ///The destructor deallocates this automatically allocated map,
519
    ///of course.
509 520
    ///\return <tt> (*this) </tt>
510 521
    Dijkstra &processedMap(ProcessedMap &m)
511 522
    {
512 523
      if(local_processed) {
513 524
        delete _processed;
514 525
        local_processed=false;
515 526
      }
516 527
      _processed = &m;
517 528
      return *this;
518 529
    }
519 530

	
520 531
    ///Sets the map that stores the distances of the nodes.
521 532

	
522 533
    ///Sets the map that stores the distances of the nodes calculated by the
523 534
    ///algorithm.
524
    ///If you don't use this function before calling \ref run(),
525
    ///it will allocate one. The destructor deallocates this
526
    ///automatically allocated map, of course.
535
    ///If you don't use this function before calling \ref run(Node) "run()"
536
    ///or \ref init(), an instance will be allocated automatically.
537
    ///The destructor deallocates this automatically allocated map,
538
    ///of course.
527 539
    ///\return <tt> (*this) </tt>
528 540
    Dijkstra &distMap(DistMap &m)
529 541
    {
530 542
      if(local_dist) {
531 543
        delete _dist;
532 544
        local_dist=false;
533 545
      }
534 546
      _dist = &m;
535 547
      return *this;
536 548
    }
537 549

	
538 550
    ///Sets the heap and the cross reference used by algorithm.
539 551

	
540 552
    ///Sets the heap and the cross reference used by algorithm.
541
    ///If you don't use this function before calling \ref run(),
542
    ///it will allocate one. The destructor deallocates this
543
    ///automatically allocated heap and cross reference, of course.
553
    ///If you don't use this function before calling \ref run(Node) "run()"
554
    ///or \ref init(), heap and cross reference instances will be
555
    ///allocated automatically.
556
    ///The destructor deallocates these automatically allocated objects,
557
    ///of course.
544 558
    ///\return <tt> (*this) </tt>
545 559
    Dijkstra &heap(Heap& hp, HeapCrossRef &cr)
546 560
    {
547 561
      if(local_heap_cross_ref) {
548 562
        delete _heap_cross_ref;
549 563
        local_heap_cross_ref=false;
550 564
      }
551 565
      _heap_cross_ref = &cr;
552 566
      if(local_heap) {
553 567
        delete _heap;
554 568
        local_heap=false;
555 569
      }
556 570
      _heap = &hp;
557 571
      return *this;
558 572
    }
559 573

	
560 574
  private:
561 575

	
562 576
    void finalizeNodeData(Node v,Value dst)
563 577
    {
564 578
      _processed->set(v,true);
565 579
      _dist->set(v, dst);
566 580
    }
567 581

	
568 582
  public:
569 583

	
570
    ///\name Execution control
571
    ///The simplest way to execute the algorithm is to use one of the
572
    ///member functions called \ref lemon::Dijkstra::run() "run()".
573
    ///\n
574
    ///If you need more control on the execution, first you must call
575
    ///\ref lemon::Dijkstra::init() "init()", then you can add several
576
    ///source nodes with \ref lemon::Dijkstra::addSource() "addSource()".
577
    ///Finally \ref lemon::Dijkstra::start() "start()" will perform the
578
    ///actual path computation.
584
    ///\name Execution Control
585
    ///The simplest way to execute the %Dijkstra algorithm is to use
586
    ///one of the member functions called \ref run(Node) "run()".\n
587
    ///If you need more control on the execution, first you have to call
588
    ///\ref init(), then you can add several source nodes with
589
    ///\ref addSource(). Finally the actual path computation can be
590
    ///performed with one of the \ref start() functions.
579 591

	
580 592
    ///@{
581 593

	
594
    ///\brief Initializes the internal data structures.
595
    ///
582 596
    ///Initializes the internal data structures.
583

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

	
597 608
    ///Adds a new source node.
598 609

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

	
615 626
    ///Processes the next node in the priority heap
616 627

	
617 628
    ///Processes the next node in the priority heap.
618 629
    ///
619 630
    ///\return The processed node.
620 631
    ///
621 632
    ///\warning The priority heap must not be empty.
622 633
    Node processNextNode()
623 634
    {
624 635
      Node v=_heap->top();
625 636
      Value oldvalue=_heap->prio();
626 637
      _heap->pop();
627 638
      finalizeNodeData(v,oldvalue);
628 639

	
629 640
      for(OutArcIt e(*G,v); e!=INVALID; ++e) {
630 641
        Node w=G->target(e);
631 642
        switch(_heap->state(w)) {
632 643
        case Heap::PRE_HEAP:
633
          _heap->push(w,OperationTraits::plus(oldvalue, (*length)[e]));
644
          _heap->push(w,OperationTraits::plus(oldvalue, (*_length)[e]));
634 645
          _pred->set(w,e);
635 646
          break;
636 647
        case Heap::IN_HEAP:
637 648
          {
638
            Value newvalue = OperationTraits::plus(oldvalue, (*length)[e]);
649
            Value newvalue = OperationTraits::plus(oldvalue, (*_length)[e]);
639 650
            if ( OperationTraits::less(newvalue, (*_heap)[w]) ) {
640 651
              _heap->decrease(w, newvalue);
641 652
              _pred->set(w,e);
642 653
            }
643 654
          }
644 655
          break;
645 656
        case Heap::POST_HEAP:
646 657
          break;
647 658
        }
648 659
      }
649 660
      return v;
650 661
    }
651 662

	
652 663
    ///The next node to be processed.
653 664

	
654 665
    ///Returns the next node to be processed or \c INVALID if the
655 666
    ///priority heap is empty.
656 667
    Node nextNode() const
657 668
    {
658 669
      return !_heap->empty()?_heap->top():INVALID;
659 670
    }
660 671

	
661
    ///\brief Returns \c false if there are nodes
662
    ///to be processed.
663
    ///
664
    ///Returns \c false if there are nodes
665
    ///to be processed in the priority heap.
672
    ///Returns \c false if there are nodes to be processed.
673

	
674
    ///Returns \c false if there are nodes to be processed
675
    ///in the priority heap.
666 676
    bool emptyQueue() const { return _heap->empty(); }
667 677

	
668
    ///Returns the number of the nodes to be processed in the priority heap
678
    ///Returns the number of the nodes to be processed.
669 679

	
670
    ///Returns the number of the nodes to be processed in the priority heap.
671
    ///
680
    ///Returns the number of the nodes to be processed
681
    ///in the priority heap.
672 682
    int queueSize() const { return _heap->size(); }
673 683

	
674 684
    ///Executes the algorithm.
675 685

	
676 686
    ///Executes the algorithm.
677 687
    ///
678 688
    ///This method runs the %Dijkstra algorithm from the root node(s)
679 689
    ///in order to compute the shortest path to each node.
680 690
    ///
681 691
    ///The algorithm computes
682 692
    ///- the shortest path tree (forest),
683 693
    ///- the distance of each node from the root(s).
684 694
    ///
685 695
    ///\pre init() must be called and at least one root node should be
686 696
    ///added with addSource() before using this function.
687 697
    ///
688 698
    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
689 699
    ///\code
690 700
    ///  while ( !d.emptyQueue() ) {
691 701
    ///    d.processNextNode();
692 702
    ///  }
693 703
    ///\endcode
694 704
    void start()
695 705
    {
696 706
      while ( !emptyQueue() ) processNextNode();
697 707
    }
698 708

	
699 709
    ///Executes the algorithm until the given target node is processed.
700 710

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

	
721 731
    ///Executes the algorithm until a condition is met.
722 732

	
723 733
    ///Executes the algorithm until a condition is met.
724 734
    ///
725 735
    ///This method runs the %Dijkstra algorithm from the root node(s) in
726 736
    ///order to compute the shortest path to a node \c v with
727 737
    /// <tt>nm[v]</tt> true, if such a node can be found.
728 738
    ///
729 739
    ///\param nm A \c bool (or convertible) node map. The algorithm
730 740
    ///will stop when it reaches a node \c v with <tt>nm[v]</tt> true.
731 741
    ///
732 742
    ///\return The reached node \c v with <tt>nm[v]</tt> true or
733 743
    ///\c INVALID if no such node was found.
734 744
    ///
735 745
    ///\pre init() must be called and at least one root node should be
736 746
    ///added with addSource() before using this function.
737 747
    template<class NodeBoolMap>
738 748
    Node start(const NodeBoolMap &nm)
739 749
    {
740 750
      while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
741 751
      if ( _heap->empty() ) return INVALID;
742 752
      finalizeNodeData(_heap->top(),_heap->prio());
743 753
      return _heap->top();
744 754
    }
745 755

	
746 756
    ///Runs the algorithm from the given source node.
747 757

	
748 758
    ///This method runs the %Dijkstra algorithm from node \c s
749 759
    ///in order to compute the shortest path to each node.
750 760
    ///
751 761
    ///The algorithm computes
752 762
    ///- the shortest path tree,
753 763
    ///- the distance of each node from the root.
754 764
    ///
755 765
    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
756 766
    ///\code
757 767
    ///  d.init();
758 768
    ///  d.addSource(s);
759 769
    ///  d.start();
760 770
    ///\endcode
761 771
    void run(Node s) {
762 772
      init();
763 773
      addSource(s);
764 774
      start();
765 775
    }
766 776

	
767 777
    ///Finds the shortest path between \c s and \c t.
768 778

	
769 779
    ///This method runs the %Dijkstra algorithm from node \c s
770 780
    ///in order to compute the shortest path to node \c t
771 781
    ///(it stops searching when \c t is processed).
772 782
    ///
773 783
    ///\return \c true if \c t is reachable form \c s.
774 784
    ///
775 785
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is just a
776 786
    ///shortcut of the following code.
777 787
    ///\code
778 788
    ///  d.init();
779 789
    ///  d.addSource(s);
780 790
    ///  d.start(t);
781 791
    ///\endcode
782 792
    bool run(Node s,Node t) {
783 793
      init();
784 794
      addSource(s);
785 795
      start(t);
786 796
      return (*_heap_cross_ref)[t] == Heap::POST_HEAP;
787 797
    }
788 798

	
789 799
    ///@}
790 800

	
791 801
    ///\name Query Functions
792
    ///The result of the %Dijkstra algorithm can be obtained using these
802
    ///The results of the %Dijkstra algorithm can be obtained using these
793 803
    ///functions.\n
794
    ///Either \ref lemon::Dijkstra::run() "run()" or
795
    ///\ref lemon::Dijkstra::start() "start()" must be called before
796
    ///using them.
804
    ///Either \ref run(Node) "run()" or \ref start() should be called
805
    ///before using them.
797 806

	
798 807
    ///@{
799 808

	
800 809
    ///The shortest path to a node.
801 810

	
802 811
    ///Returns the shortest path to a node.
803 812
    ///
804
    ///\warning \c t should be reachable from the root(s).
813
    ///\warning \c t should be reached from the root(s).
805 814
    ///
806
    ///\pre Either \ref run() or \ref start() must be called before
807
    ///using this function.
815
    ///\pre Either \ref run(Node) "run()" or \ref init()
816
    ///must be called before using this function.
808 817
    Path path(Node t) const { return Path(*G, *_pred, t); }
809 818

	
810 819
    ///The distance of a node from the root(s).
811 820

	
812 821
    ///Returns the distance of a node from the root(s).
813 822
    ///
814
    ///\warning If node \c v is not reachable from the root(s), then
823
    ///\warning If node \c v is not reached from the root(s), then
815 824
    ///the return value of this function is undefined.
816 825
    ///
817
    ///\pre Either \ref run() or \ref start() must be called before
818
    ///using this function.
826
    ///\pre Either \ref run(Node) "run()" or \ref init()
827
    ///must be called before using this function.
819 828
    Value dist(Node v) const { return (*_dist)[v]; }
820 829

	
821 830
    ///Returns the 'previous arc' of the shortest path tree for a node.
822 831

	
823 832
    ///This function returns the 'previous arc' of the shortest path
824 833
    ///tree for the node \c v, i.e. it returns the last arc of a
825
    ///shortest path from the root(s) to \c v. It is \c INVALID if \c v
826
    ///is not reachable from the root(s) or if \c v is a root.
834
    ///shortest path from a root to \c v. It is \c INVALID if \c v
835
    ///is not reached from the root(s) or if \c v is a root.
827 836
    ///
828 837
    ///The shortest path tree used here is equal to the shortest path
829 838
    ///tree used in \ref predNode().
830 839
    ///
831
    ///\pre Either \ref run() or \ref start() must be called before
832
    ///using this function.
840
    ///\pre Either \ref run(Node) "run()" or \ref init()
841
    ///must be called before using this function.
833 842
    Arc predArc(Node v) const { return (*_pred)[v]; }
834 843

	
835 844
    ///Returns the 'previous node' of the shortest path tree for a node.
836 845

	
837 846
    ///This function returns the 'previous node' of the shortest path
838 847
    ///tree for the node \c v, i.e. it returns the last but one node
839
    ///from a shortest path from the root(s) to \c v. It is \c INVALID
840
    ///if \c v is not reachable from the root(s) or if \c v is a root.
848
    ///from a shortest path from a root to \c v. It is \c INVALID
849
    ///if \c v is not reached from the root(s) or if \c v is a root.
841 850
    ///
842 851
    ///The shortest path tree used here is equal to the shortest path
843 852
    ///tree used in \ref predArc().
844 853
    ///
845
    ///\pre Either \ref run() or \ref start() must be called before
846
    ///using this function.
854
    ///\pre Either \ref run(Node) "run()" or \ref init()
855
    ///must be called before using this function.
847 856
    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
848 857
                                  G->source((*_pred)[v]); }
849 858

	
850 859
    ///\brief Returns a const reference to the node map that stores the
851 860
    ///distances of the nodes.
852 861
    ///
853 862
    ///Returns a const reference to the node map that stores the distances
854 863
    ///of the nodes calculated by the algorithm.
855 864
    ///
856
    ///\pre Either \ref run() or \ref init()
865
    ///\pre Either \ref run(Node) "run()" or \ref init()
857 866
    ///must be called before using this function.
858 867
    const DistMap &distMap() const { return *_dist;}
859 868

	
860 869
    ///\brief Returns a const reference to the node map that stores the
861 870
    ///predecessor arcs.
862 871
    ///
863 872
    ///Returns a const reference to the node map that stores the predecessor
864 873
    ///arcs, which form the shortest path tree.
865 874
    ///
866
    ///\pre Either \ref run() or \ref init()
875
    ///\pre Either \ref run(Node) "run()" or \ref init()
867 876
    ///must be called before using this function.
868 877
    const PredMap &predMap() const { return *_pred;}
869 878

	
870
    ///Checks if a node is reachable from the root(s).
879
    ///Checks if a node is reached from the root(s).
871 880

	
872
    ///Returns \c true if \c v is reachable from the root(s).
873
    ///\pre Either \ref run() or \ref start()
881
    ///Returns \c true if \c v is reached from the root(s).
882
    ///
883
    ///\pre Either \ref run(Node) "run()" or \ref init()
874 884
    ///must be called before using this function.
875 885
    bool reached(Node v) const { return (*_heap_cross_ref)[v] !=
876 886
                                        Heap::PRE_HEAP; }
877 887

	
878 888
    ///Checks if a node is processed.
879 889

	
880 890
    ///Returns \c true if \c v is processed, i.e. the shortest
881 891
    ///path to \c v has already found.
882
    ///\pre Either \ref run() or \ref init()
892
    ///
893
    ///\pre Either \ref run(Node) "run()" or \ref init()
883 894
    ///must be called before using this function.
884 895
    bool processed(Node v) const { return (*_heap_cross_ref)[v] ==
885 896
                                          Heap::POST_HEAP; }
886 897

	
887 898
    ///The current distance of a node from the root(s).
888 899

	
889 900
    ///Returns the current distance of a node from the root(s).
890 901
    ///It may be decreased in the following processes.
891
    ///\pre Either \ref run() or \ref init()
902
    ///
903
    ///\pre Either \ref run(Node) "run()" or \ref init()
892 904
    ///must be called before using this function and
893 905
    ///node \c v must be reached but not necessarily processed.
894 906
    Value currentDist(Node v) const {
895 907
      return processed(v) ? (*_dist)[v] : (*_heap)[v];
896 908
    }
897 909

	
898 910
    ///@}
899 911
  };
900 912

	
901 913

	
902 914
  ///Default traits class of dijkstra() function.
903 915

	
904 916
  ///Default traits class of dijkstra() function.
905 917
  ///\tparam GR The type of the digraph.
906
  ///\tparam LM The type of the length map.
907
  template<class GR, class LM>
918
  ///\tparam LEN The type of the length map.
919
  template<class GR, class LEN>
908 920
  struct DijkstraWizardDefaultTraits
909 921
  {
910 922
    ///The type of the digraph the algorithm runs on.
911 923
    typedef GR Digraph;
912 924
    ///The type of the map that stores the arc lengths.
913 925

	
914 926
    ///The type of the map that stores the arc lengths.
915 927
    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
916
    typedef LM LengthMap;
928
    typedef LEN LengthMap;
917 929
    ///The type of the length of the arcs.
918
    typedef typename LM::Value Value;
930
    typedef typename LEN::Value Value;
919 931

	
920 932
    /// Operation traits for Dijkstra algorithm.
921 933

	
922 934
    /// This class defines the operations that are used in the algorithm.
923 935
    /// \see DijkstraDefaultOperationTraits
924 936
    typedef DijkstraDefaultOperationTraits<Value> OperationTraits;
925 937

	
926 938
    /// The cross reference type used by the heap.
927 939

	
928 940
    /// The cross reference type used by the heap.
929 941
    /// Usually it is \c Digraph::NodeMap<int>.
930 942
    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
931 943
    ///Instantiates a \ref HeapCrossRef.
932 944

	
933 945
    ///This function instantiates a \ref HeapCrossRef.
934 946
    /// \param g is the digraph, to which we would like to define the
935 947
    /// HeapCrossRef.
936 948
    static HeapCrossRef *createHeapCrossRef(const Digraph &g)
937 949
    {
938 950
      return new HeapCrossRef(g);
939 951
    }
940 952

	
941 953
    ///The heap type used by the Dijkstra algorithm.
942 954

	
943 955
    ///The heap type used by the Dijkstra algorithm.
944 956
    ///
945 957
    ///\sa BinHeap
946 958
    ///\sa Dijkstra
947 959
    typedef BinHeap<Value, typename Digraph::template NodeMap<int>,
948 960
                    std::less<Value> > Heap;
949 961

	
950 962
    ///Instantiates a \ref Heap.
951 963

	
952 964
    ///This function instantiates a \ref Heap.
953 965
    /// \param r is the HeapCrossRef which is used.
954 966
    static Heap *createHeap(HeapCrossRef& r)
955 967
    {
956 968
      return new Heap(r);
957 969
    }
958 970

	
959 971
    ///\brief The type of the map that stores the predecessor
960 972
    ///arcs of the shortest paths.
961 973
    ///
962 974
    ///The type of the map that stores the predecessor
963 975
    ///arcs of the shortest paths.
964 976
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
965 977
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
966 978
    ///Instantiates a PredMap.
967 979

	
968 980
    ///This function instantiates a PredMap.
969 981
    ///\param g is the digraph, to which we would like to define the
970 982
    ///PredMap.
971 983
    static PredMap *createPredMap(const Digraph &g)
972 984
    {
973 985
      return new PredMap(g);
974 986
    }
975 987

	
976 988
    ///The type of the map that indicates which nodes are processed.
977 989

	
978 990
    ///The type of the map that indicates which nodes are processed.
979 991
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
980 992
    ///By default it is a NullMap.
981 993
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
982 994
    ///Instantiates a ProcessedMap.
983 995

	
984 996
    ///This function instantiates a ProcessedMap.
985 997
    ///\param g is the digraph, to which
986 998
    ///we would like to define the ProcessedMap.
987 999
#ifdef DOXYGEN
988 1000
    static ProcessedMap *createProcessedMap(const Digraph &g)
989 1001
#else
990 1002
    static ProcessedMap *createProcessedMap(const Digraph &)
991 1003
#endif
992 1004
    {
993 1005
      return new ProcessedMap();
994 1006
    }
995 1007

	
996 1008
    ///The type of the map that stores the distances of the nodes.
997 1009

	
998 1010
    ///The type of the map that stores the distances of the nodes.
999 1011
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
1000
    typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
1012
    typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
1001 1013
    ///Instantiates a DistMap.
1002 1014

	
1003 1015
    ///This function instantiates a DistMap.
1004 1016
    ///\param g is the digraph, to which we would like to define
1005 1017
    ///the DistMap
1006 1018
    static DistMap *createDistMap(const Digraph &g)
1007 1019
    {
1008 1020
      return new DistMap(g);
1009 1021
    }
1010 1022

	
1011 1023
    ///The type of the shortest paths.
1012 1024

	
1013 1025
    ///The type of the shortest paths.
1014 1026
    ///It must meet the \ref concepts::Path "Path" concept.
1015 1027
    typedef lemon::Path<Digraph> Path;
1016 1028
  };
1017 1029

	
1018 1030
  /// Default traits class used by DijkstraWizard
1019 1031

	
1020 1032
  /// To make it easier to use Dijkstra algorithm
1021 1033
  /// we have created a wizard class.
1022 1034
  /// This \ref DijkstraWizard class needs default traits,
1023 1035
  /// as well as the \ref Dijkstra class.
1024 1036
  /// The \ref DijkstraWizardBase is a class to be the default traits of the
1025 1037
  /// \ref DijkstraWizard class.
1026
  template<class GR,class LM>
1027
  class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LM>
1038
  template<typename GR, typename LEN>
1039
  class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LEN>
1028 1040
  {
1029
    typedef DijkstraWizardDefaultTraits<GR,LM> Base;
1041
    typedef DijkstraWizardDefaultTraits<GR,LEN> Base;
1030 1042
  protected:
1031 1043
    //The type of the nodes in the digraph.
1032 1044
    typedef typename Base::Digraph::Node Node;
1033 1045

	
1034 1046
    //Pointer to the digraph the algorithm runs on.
1035 1047
    void *_g;
1036 1048
    //Pointer to the length map.
1037 1049
    void *_length;
1038 1050
    //Pointer to the map of processed nodes.
1039 1051
    void *_processed;
1040 1052
    //Pointer to the map of predecessors arcs.
1041 1053
    void *_pred;
1042 1054
    //Pointer to the map of distances.
1043 1055
    void *_dist;
1044 1056
    //Pointer to the shortest path to the target node.
1045 1057
    void *_path;
1046 1058
    //Pointer to the distance of the target node.
1047 1059
    void *_di;
1048 1060

	
1049 1061
  public:
1050 1062
    /// Constructor.
1051 1063

	
1052 1064
    /// This constructor does not require parameters, therefore it initiates
1053 1065
    /// all of the attributes to \c 0.
1054 1066
    DijkstraWizardBase() : _g(0), _length(0), _processed(0), _pred(0),
1055 1067
                           _dist(0), _path(0), _di(0) {}
1056 1068

	
1057 1069
    /// Constructor.
1058 1070

	
1059 1071
    /// This constructor requires two parameters,
1060 1072
    /// others are initiated to \c 0.
1061 1073
    /// \param g The digraph the algorithm runs on.
1062 1074
    /// \param l The length map.
1063
    DijkstraWizardBase(const GR &g,const LM &l) :
1075
    DijkstraWizardBase(const GR &g,const LEN &l) :
1064 1076
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
1065
      _length(reinterpret_cast<void*>(const_cast<LM*>(&l))),
1077
      _length(reinterpret_cast<void*>(const_cast<LEN*>(&l))),
1066 1078
      _processed(0), _pred(0), _dist(0), _path(0), _di(0) {}
1067 1079

	
1068 1080
  };
1069 1081

	
1070 1082
  /// Auxiliary class for the function-type interface of Dijkstra algorithm.
1071 1083

	
1072 1084
  /// This auxiliary class is created to implement the
1073 1085
  /// \ref dijkstra() "function-type interface" of \ref Dijkstra algorithm.
1074
  /// It does not have own \ref run() method, it uses the functions
1075
  /// and features of the plain \ref Dijkstra.
1086
  /// It does not have own \ref run(Node) "run()" method, it uses the
1087
  /// functions and features of the plain \ref Dijkstra.
1076 1088
  ///
1077 1089
  /// This class should only be used through the \ref dijkstra() function,
1078 1090
  /// which makes it easier to use the algorithm.
1079 1091
  template<class TR>
1080 1092
  class DijkstraWizard : public TR
1081 1093
  {
1082 1094
    typedef TR Base;
1083 1095

	
1084 1096
    ///The type of the digraph the algorithm runs on.
1085 1097
    typedef typename TR::Digraph Digraph;
1086 1098

	
1087 1099
    typedef typename Digraph::Node Node;
1088 1100
    typedef typename Digraph::NodeIt NodeIt;
1089 1101
    typedef typename Digraph::Arc Arc;
1090 1102
    typedef typename Digraph::OutArcIt OutArcIt;
1091 1103

	
1092 1104
    ///The type of the map that stores the arc lengths.
1093 1105
    typedef typename TR::LengthMap LengthMap;
1094 1106
    ///The type of the length of the arcs.
1095 1107
    typedef typename LengthMap::Value Value;
1096 1108
    ///\brief The type of the map that stores the predecessor
1097 1109
    ///arcs of the shortest paths.
1098 1110
    typedef typename TR::PredMap PredMap;
1099 1111
    ///The type of the map that stores the distances of the nodes.
1100 1112
    typedef typename TR::DistMap DistMap;
1101 1113
    ///The type of the map that indicates which nodes are processed.
1102 1114
    typedef typename TR::ProcessedMap ProcessedMap;
1103 1115
    ///The type of the shortest paths
1104 1116
    typedef typename TR::Path Path;
1105 1117
    ///The heap type used by the dijkstra algorithm.
1106 1118
    typedef typename TR::Heap Heap;
1107 1119

	
1108 1120
  public:
1109 1121

	
1110 1122
    /// Constructor.
1111 1123
    DijkstraWizard() : TR() {}
1112 1124

	
1113 1125
    /// Constructor that requires parameters.
1114 1126

	
1115 1127
    /// Constructor that requires parameters.
1116 1128
    /// These parameters will be the default values for the traits class.
1117 1129
    /// \param g The digraph the algorithm runs on.
1118 1130
    /// \param l The length map.
1119 1131
    DijkstraWizard(const Digraph &g, const LengthMap &l) :
1120 1132
      TR(g,l) {}
1121 1133

	
1122 1134
    ///Copy constructor
1123 1135
    DijkstraWizard(const TR &b) : TR(b) {}
1124 1136

	
1125 1137
    ~DijkstraWizard() {}
1126 1138

	
1127 1139
    ///Runs Dijkstra algorithm from the given source node.
1128 1140

	
1129 1141
    ///This method runs %Dijkstra algorithm from the given source node
1130 1142
    ///in order to compute the shortest path to each node.
1131 1143
    void run(Node s)
1132 1144
    {
1133 1145
      Dijkstra<Digraph,LengthMap,TR>
1134 1146
        dijk(*reinterpret_cast<const Digraph*>(Base::_g),
1135 1147
             *reinterpret_cast<const LengthMap*>(Base::_length));
1136 1148
      if (Base::_pred)
1137 1149
        dijk.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1138 1150
      if (Base::_dist)
1139 1151
        dijk.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1140 1152
      if (Base::_processed)
1141 1153
        dijk.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1142 1154
      dijk.run(s);
1143 1155
    }
1144 1156

	
1145 1157
    ///Finds the shortest path between \c s and \c t.
1146 1158

	
1147 1159
    ///This method runs the %Dijkstra algorithm from node \c s
1148 1160
    ///in order to compute the shortest path to node \c t
1149 1161
    ///(it stops searching when \c t is processed).
1150 1162
    ///
1151 1163
    ///\return \c true if \c t is reachable form \c s.
1152 1164
    bool run(Node s, Node t)
1153 1165
    {
1154 1166
      Dijkstra<Digraph,LengthMap,TR>
1155 1167
        dijk(*reinterpret_cast<const Digraph*>(Base::_g),
1156 1168
             *reinterpret_cast<const LengthMap*>(Base::_length));
1157 1169
      if (Base::_pred)
1158 1170
        dijk.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1159 1171
      if (Base::_dist)
1160 1172
        dijk.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1161 1173
      if (Base::_processed)
1162 1174
        dijk.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1163 1175
      dijk.run(s,t);
1164 1176
      if (Base::_path)
1165 1177
        *reinterpret_cast<Path*>(Base::_path) = dijk.path(t);
1166 1178
      if (Base::_di)
1167 1179
        *reinterpret_cast<Value*>(Base::_di) = dijk.dist(t);
1168 1180
      return dijk.reached(t);
1169 1181
    }
1170 1182

	
1171 1183
    template<class T>
1172 1184
    struct SetPredMapBase : public Base {
1173 1185
      typedef T PredMap;
1174 1186
      static PredMap *createPredMap(const Digraph &) { return 0; };
1175 1187
      SetPredMapBase(const TR &b) : TR(b) {}
1176 1188
    };
1177 1189
    ///\brief \ref named-func-param "Named parameter"
1178 1190
    ///for setting PredMap object.
1179 1191
    ///
1180 1192
    ///\ref named-func-param "Named parameter"
1181 1193
    ///for setting PredMap object.
1182 1194
    template<class T>
1183 1195
    DijkstraWizard<SetPredMapBase<T> > predMap(const T &t)
1184 1196
    {
1185 1197
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1186 1198
      return DijkstraWizard<SetPredMapBase<T> >(*this);
1187 1199
    }
1188 1200

	
1189 1201
    template<class T>
1190 1202
    struct SetDistMapBase : public Base {
1191 1203
      typedef T DistMap;
1192 1204
      static DistMap *createDistMap(const Digraph &) { return 0; };
1193 1205
      SetDistMapBase(const TR &b) : TR(b) {}
1194 1206
    };
1195 1207
    ///\brief \ref named-func-param "Named parameter"
1196 1208
    ///for setting DistMap object.
1197 1209
    ///
1198 1210
    ///\ref named-func-param "Named parameter"
1199 1211
    ///for setting DistMap object.
1200 1212
    template<class T>
1201 1213
    DijkstraWizard<SetDistMapBase<T> > distMap(const T &t)
1202 1214
    {
1203 1215
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1204 1216
      return DijkstraWizard<SetDistMapBase<T> >(*this);
1205 1217
    }
1206 1218

	
1207 1219
    template<class T>
1208 1220
    struct SetProcessedMapBase : public Base {
1209 1221
      typedef T ProcessedMap;
1210 1222
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1211 1223
      SetProcessedMapBase(const TR &b) : TR(b) {}
1212 1224
    };
1213 1225
    ///\brief \ref named-func-param "Named parameter"
1214 1226
    ///for setting ProcessedMap object.
1215 1227
    ///
1216 1228
    /// \ref named-func-param "Named parameter"
1217 1229
    ///for setting ProcessedMap object.
1218 1230
    template<class T>
1219 1231
    DijkstraWizard<SetProcessedMapBase<T> > processedMap(const T &t)
1220 1232
    {
1221 1233
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1222 1234
      return DijkstraWizard<SetProcessedMapBase<T> >(*this);
1223 1235
    }
1224 1236

	
1225 1237
    template<class T>
1226 1238
    struct SetPathBase : public Base {
1227 1239
      typedef T Path;
1228 1240
      SetPathBase(const TR &b) : TR(b) {}
1229 1241
    };
1230 1242
    ///\brief \ref named-func-param "Named parameter"
1231 1243
    ///for getting the shortest path to the target node.
1232 1244
    ///
1233 1245
    ///\ref named-func-param "Named parameter"
1234 1246
    ///for getting the shortest path to the target node.
1235 1247
    template<class T>
1236 1248
    DijkstraWizard<SetPathBase<T> > path(const T &t)
1237 1249
    {
1238 1250
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1239 1251
      return DijkstraWizard<SetPathBase<T> >(*this);
1240 1252
    }
1241 1253

	
1242 1254
    ///\brief \ref named-func-param "Named parameter"
1243 1255
    ///for getting the distance of the target node.
1244 1256
    ///
1245 1257
    ///\ref named-func-param "Named parameter"
1246 1258
    ///for getting the distance of the target node.
1247 1259
    DijkstraWizard dist(const Value &d)
1248 1260
    {
1249 1261
      Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
1250 1262
      return *this;
1251 1263
    }
1252 1264

	
1253 1265
  };
1254 1266

	
1255 1267
  ///Function-type interface for Dijkstra algorithm.
1256 1268

	
1257 1269
  /// \ingroup shortest_path
1258 1270
  ///Function-type interface for Dijkstra algorithm.
1259 1271
  ///
1260 1272
  ///This function also has several \ref named-func-param "named parameters",
1261 1273
  ///they are declared as the members of class \ref DijkstraWizard.
1262 1274
  ///The following examples show how to use these parameters.
1263 1275
  ///\code
1264 1276
  ///  // Compute shortest path from node s to each node
1265 1277
  ///  dijkstra(g,length).predMap(preds).distMap(dists).run(s);
1266 1278
  ///
1267 1279
  ///  // Compute shortest path from s to t
1268 1280
  ///  bool reached = dijkstra(g,length).path(p).dist(d).run(s,t);
1269 1281
  ///\endcode
1270
  ///\warning Don't forget to put the \ref DijkstraWizard::run() "run()"
1282
  ///\warning Don't forget to put the \ref DijkstraWizard::run(Node) "run()"
1271 1283
  ///to the end of the parameter list.
1272 1284
  ///\sa DijkstraWizard
1273 1285
  ///\sa Dijkstra
1274
  template<class GR, class LM>
1275
  DijkstraWizard<DijkstraWizardBase<GR,LM> >
1276
  dijkstra(const GR &digraph, const LM &length)
1286
  template<typename GR, typename LEN>
1287
  DijkstraWizard<DijkstraWizardBase<GR,LEN> >
1288
  dijkstra(const GR &digraph, const LEN &length)
1277 1289
  {
1278
    return DijkstraWizard<DijkstraWizardBase<GR,LM> >(digraph,length);
1290
    return DijkstraWizard<DijkstraWizardBase<GR,LEN> >(digraph,length);
1279 1291
  }
1280 1292

	
1281 1293
} //END OF NAMESPACE LEMON
1282 1294

	
1283 1295
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_DIM2_H
20 20
#define LEMON_DIM2_H
21 21

	
22 22
#include <iostream>
23 23

	
24 24
///\ingroup misc
25 25
///\file
26 26
///\brief A simple two dimensional vector and a bounding box implementation
27 27
///
28 28
/// The class \ref lemon::dim2::Point "dim2::Point" implements
29 29
/// a two dimensional vector with the usual operations.
30 30
///
31 31
/// The class \ref lemon::dim2::Box "dim2::Box" can be used to determine
32 32
/// the rectangular bounding box of a set of
33 33
/// \ref lemon::dim2::Point "dim2::Point"'s.
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  ///Tools for handling two dimensional coordinates
38 38

	
39 39
  ///This namespace is a storage of several
40 40
  ///tools for handling two dimensional coordinates
41 41
  namespace dim2 {
42 42

	
43 43
  /// \addtogroup misc
44 44
  /// @{
45 45

	
46 46
  /// Two dimensional vector (plain vector)
47 47

	
48 48
  /// A simple two dimensional vector (plain vector) implementation
49 49
  /// with the usual vector operations.
50 50
  template<typename T>
51 51
    class Point {
52 52

	
53 53
    public:
54 54

	
55 55
      typedef T Value;
56 56

	
57 57
      ///First coordinate
58 58
      T x;
59 59
      ///Second coordinate
60 60
      T y;
61 61

	
62 62
      ///Default constructor
63 63
      Point() {}
64 64

	
65 65
      ///Construct an instance from coordinates
66 66
      Point(T a, T b) : x(a), y(b) { }
67 67

	
68 68
      ///Returns the dimension of the vector (i.e. returns 2).
69 69

	
70 70
      ///The dimension of the vector.
71 71
      ///This function always returns 2.
72 72
      int size() const { return 2; }
73 73

	
74 74
      ///Subscripting operator
75 75

	
76 76
      ///\c p[0] is \c p.x and \c p[1] is \c p.y
77 77
      ///
78 78
      T& operator[](int idx) { return idx == 0 ? x : y; }
79 79

	
80 80
      ///Const subscripting operator
81 81

	
82 82
      ///\c p[0] is \c p.x and \c p[1] is \c p.y
83 83
      ///
84 84
      const T& operator[](int idx) const { return idx == 0 ? x : y; }
85 85

	
86 86
      ///Conversion constructor
87 87
      template<class TT> Point(const Point<TT> &p) : x(p.x), y(p.y) {}
88 88

	
89 89
      ///Give back the square of the norm of the vector
90 90
      T normSquare() const {
91 91
        return x*x+y*y;
92 92
      }
93 93

	
94 94
      ///Increment the left hand side by \c u
95 95
      Point<T>& operator +=(const Point<T>& u) {
96 96
        x += u.x;
97 97
        y += u.y;
98 98
        return *this;
99 99
      }
100 100

	
101 101
      ///Decrement the left hand side by \c u
102 102
      Point<T>& operator -=(const Point<T>& u) {
103 103
        x -= u.x;
104 104
        y -= u.y;
105 105
        return *this;
106 106
      }
107 107

	
108 108
      ///Multiply the left hand side with a scalar
109 109
      Point<T>& operator *=(const T &u) {
110 110
        x *= u;
111 111
        y *= u;
112 112
        return *this;
113 113
      }
114 114

	
115 115
      ///Divide the left hand side by a scalar
116 116
      Point<T>& operator /=(const T &u) {
117 117
        x /= u;
118 118
        y /= u;
119 119
        return *this;
120 120
      }
121 121

	
122 122
      ///Return the scalar product of two vectors
123 123
      T operator *(const Point<T>& u) const {
124 124
        return x*u.x+y*u.y;
125 125
      }
126 126

	
127 127
      ///Return the sum of two vectors
128 128
      Point<T> operator+(const Point<T> &u) const {
129 129
        Point<T> b=*this;
130 130
        return b+=u;
131 131
      }
132 132

	
133 133
      ///Return the negative of the vector
134 134
      Point<T> operator-() const {
135 135
        Point<T> b=*this;
136 136
        b.x=-b.x; b.y=-b.y;
137 137
        return b;
138 138
      }
139 139

	
140 140
      ///Return the difference of two vectors
141 141
      Point<T> operator-(const Point<T> &u) const {
142 142
        Point<T> b=*this;
143 143
        return b-=u;
144 144
      }
145 145

	
146 146
      ///Return a vector multiplied by a scalar
147 147
      Point<T> operator*(const T &u) const {
148 148
        Point<T> b=*this;
149 149
        return b*=u;
150 150
      }
151 151

	
152 152
      ///Return a vector divided by a scalar
153 153
      Point<T> operator/(const T &u) const {
154 154
        Point<T> b=*this;
155 155
        return b/=u;
156 156
      }
157 157

	
158 158
      ///Test equality
159 159
      bool operator==(const Point<T> &u) const {
160 160
        return (x==u.x) && (y==u.y);
161 161
      }
162 162

	
163 163
      ///Test inequality
164 164
      bool operator!=(Point u) const {
165 165
        return  (x!=u.x) || (y!=u.y);
166 166
      }
167 167

	
168 168
    };
169 169

	
170 170
  ///Return a Point
171 171

	
172 172
  ///Return a Point.
173 173
  ///\relates Point
174 174
  template <typename T>
175 175
  inline Point<T> makePoint(const T& x, const T& y) {
176 176
    return Point<T>(x, y);
177 177
  }
178 178

	
179 179
  ///Return a vector multiplied by a scalar
180 180

	
181 181
  ///Return a vector multiplied by a scalar.
182 182
  ///\relates Point
183 183
  template<typename T> Point<T> operator*(const T &u,const Point<T> &x) {
184 184
    return x*u;
185 185
  }
186 186

	
187 187
  ///Read a plain vector from a stream
188 188

	
189 189
  ///Read a plain vector from a stream.
190 190
  ///\relates Point
191 191
  ///
192 192
  template<typename T>
193 193
  inline std::istream& operator>>(std::istream &is, Point<T> &z) {
194 194
    char c;
195 195
    if (is >> c) {
196 196
      if (c != '(') is.putback(c);
197 197
    } else {
198 198
      is.clear();
199 199
    }
200 200
    if (!(is >> z.x)) return is;
201 201
    if (is >> c) {
202 202
      if (c != ',') is.putback(c);
203 203
    } else {
204 204
      is.clear();
205 205
    }
206 206
    if (!(is >> z.y)) return is;
207 207
    if (is >> c) {
208 208
      if (c != ')') is.putback(c);
209 209
    } else {
210 210
      is.clear();
211 211
    }
212 212
    return is;
213 213
  }
214 214

	
215 215
  ///Write a plain vector to a stream
216 216

	
217 217
  ///Write a plain vector to a stream.
218 218
  ///\relates Point
219 219
  ///
220 220
  template<typename T>
221 221
  inline std::ostream& operator<<(std::ostream &os, const Point<T>& z)
222 222
  {
223 223
    os << "(" << z.x << "," << z.y << ")";
224 224
    return os;
225 225
  }
226 226

	
227 227
  ///Rotate by 90 degrees
228 228

	
229 229
  ///Returns the parameter rotated by 90 degrees in positive direction.
230 230
  ///\relates Point
231 231
  ///
232 232
  template<typename T>
233 233
  inline Point<T> rot90(const Point<T> &z)
234 234
  {
235 235
    return Point<T>(-z.y,z.x);
236 236
  }
237 237

	
238 238
  ///Rotate by 180 degrees
239 239

	
240 240
  ///Returns the parameter rotated by 180 degrees.
241 241
  ///\relates Point
242 242
  ///
243 243
  template<typename T>
244 244
  inline Point<T> rot180(const Point<T> &z)
245 245
  {
246 246
    return Point<T>(-z.x,-z.y);
247 247
  }
248 248

	
249 249
  ///Rotate by 270 degrees
250 250

	
251 251
  ///Returns the parameter rotated by 90 degrees in negative direction.
252 252
  ///\relates Point
253 253
  ///
254 254
  template<typename T>
255 255
  inline Point<T> rot270(const Point<T> &z)
256 256
  {
257 257
    return Point<T>(z.y,-z.x);
258 258
  }
259 259

	
260 260

	
261 261

	
262 262
  /// Bounding box of plain vectors (points).
263 263

	
264 264
  /// A class to calculate or store the bounding box of plain vectors
265 265
  /// (\ref Point "points").
266 266
  template<typename T>
267 267
  class Box {
268 268
      Point<T> _bottom_left, _top_right;
269 269
      bool _empty;
270 270
    public:
271 271

	
272 272
      ///Default constructor: creates an empty box
273 273
      Box() { _empty = true; }
274 274

	
275 275
      ///Construct a box from one point
276 276
      Box(Point<T> a) {
277 277
        _bottom_left = _top_right = a;
278 278
        _empty = false;
279 279
      }
280 280

	
281 281
      ///Construct a box from two points
282 282

	
283 283
      ///Construct a box from two points.
284 284
      ///\param a The bottom left corner.
285 285
      ///\param b The top right corner.
286 286
      ///\warning The coordinates of the bottom left corner must be no more
287 287
      ///than those of the top right one.
288 288
      Box(Point<T> a,Point<T> b)
289 289
      {
290 290
        _bottom_left = a;
291 291
        _top_right = b;
292 292
        _empty = false;
293 293
      }
294 294

	
295 295
      ///Construct a box from four numbers
296 296

	
297 297
      ///Construct a box from four numbers.
298 298
      ///\param l The left side of the box.
299 299
      ///\param b The bottom of the box.
300 300
      ///\param r The right side of the box.
301 301
      ///\param t The top of the box.
302 302
      ///\warning The left side must be no more than the right side and
303 303
      ///bottom must be no more than the top.
304 304
      Box(T l,T b,T r,T t)
305 305
      {
306 306
        _bottom_left=Point<T>(l,b);
307 307
        _top_right=Point<T>(r,t);
308 308
        _empty = false;
309 309
      }
310 310

	
311 311
      ///Return \c true if the box is empty.
312 312

	
313 313
      ///Return \c true if the box is empty (i.e. return \c false
314 314
      ///if at least one point was added to the box or the coordinates of
315 315
      ///the box were set).
316 316
      ///
317 317
      ///The coordinates of an empty box are not defined.
318 318
      bool empty() const {
319 319
        return _empty;
320 320
      }
321 321

	
322 322
      ///Make the box empty
323 323
      void clear() {
324 324
        _empty = true;
325 325
      }
326 326

	
327 327
      ///Give back the bottom left corner of the box
328 328

	
329 329
      ///Give back the bottom left corner of the box.
330 330
      ///If the box is empty, then the return value is not defined.
331 331
      Point<T> bottomLeft() const {
332 332
        return _bottom_left;
333 333
      }
334 334

	
335 335
      ///Set the bottom left corner of the box
336 336

	
337 337
      ///Set the bottom left corner of the box.
338 338
      ///\pre The box must not be empty.
339 339
      void bottomLeft(Point<T> p) {
340 340
        _bottom_left = p;
341 341
      }
342 342

	
343 343
      ///Give back the top right corner of the box
344 344

	
345 345
      ///Give back the top right corner of the box.
346 346
      ///If the box is empty, then the return value is not defined.
347 347
      Point<T> topRight() const {
348 348
        return _top_right;
349 349
      }
350 350

	
351 351
      ///Set the top right corner of the box
352 352

	
353 353
      ///Set the top right corner of the box.
354 354
      ///\pre The box must not be empty.
355 355
      void topRight(Point<T> p) {
356 356
        _top_right = p;
357 357
      }
358 358

	
359 359
      ///Give back the bottom right corner of the box
360 360

	
361 361
      ///Give back the bottom right corner of the box.
362 362
      ///If the box is empty, then the return value is not defined.
363 363
      Point<T> bottomRight() const {
364 364
        return Point<T>(_top_right.x,_bottom_left.y);
365 365
      }
366 366

	
367 367
      ///Set the bottom right corner of the box
368 368

	
369 369
      ///Set the bottom right corner of the box.
370 370
      ///\pre The box must not be empty.
371 371
      void bottomRight(Point<T> p) {
372 372
        _top_right.x = p.x;
373 373
        _bottom_left.y = p.y;
374 374
      }
375 375

	
376 376
      ///Give back the top left corner of the box
377 377

	
378 378
      ///Give back the top left corner of the box.
379 379
      ///If the box is empty, then the return value is not defined.
380 380
      Point<T> topLeft() const {
381 381
        return Point<T>(_bottom_left.x,_top_right.y);
382 382
      }
383 383

	
384 384
      ///Set the top left corner of the box
385 385

	
386 386
      ///Set the top left corner of the box.
387 387
      ///\pre The box must not be empty.
388 388
      void topLeft(Point<T> p) {
389 389
        _top_right.y = p.y;
390 390
        _bottom_left.x = p.x;
391 391
      }
392 392

	
393 393
      ///Give back the bottom of the box
394 394

	
395 395
      ///Give back the bottom of the box.
396 396
      ///If the box is empty, then the return value is not defined.
397 397
      T bottom() const {
398 398
        return _bottom_left.y;
399 399
      }
400 400

	
401 401
      ///Set the bottom of the box
402 402

	
403 403
      ///Set the bottom of the box.
404 404
      ///\pre The box must not be empty.
405 405
      void bottom(T t) {
406 406
        _bottom_left.y = t;
407 407
      }
408 408

	
409 409
      ///Give back the top of the box
410 410

	
411 411
      ///Give back the top of the box.
412 412
      ///If the box is empty, then the return value is not defined.
413 413
      T top() const {
414 414
        return _top_right.y;
415 415
      }
416 416

	
417 417
      ///Set the top of the box
418 418

	
419 419
      ///Set the top of the box.
420 420
      ///\pre The box must not be empty.
421 421
      void top(T t) {
422 422
        _top_right.y = t;
423 423
      }
424 424

	
425 425
      ///Give back the left side of the box
426 426

	
427 427
      ///Give back the left side of the box.
428 428
      ///If the box is empty, then the return value is not defined.
429 429
      T left() const {
430 430
        return _bottom_left.x;
431 431
      }
432 432

	
433 433
      ///Set the left side of the box
434 434

	
435 435
      ///Set the left side of the box.
436 436
      ///\pre The box must not be empty.
437 437
      void left(T t) {
438 438
        _bottom_left.x = t;
439 439
      }
440 440

	
441 441
      /// Give back the right side of the box
442 442

	
443 443
      /// Give back the right side of the box.
444 444
      ///If the box is empty, then the return value is not defined.
445 445
      T right() const {
446 446
        return _top_right.x;
447 447
      }
448 448

	
449 449
      ///Set the right side of the box
450 450

	
451 451
      ///Set the right side of the box.
452 452
      ///\pre The box must not be empty.
453 453
      void right(T t) {
454 454
        _top_right.x = t;
455 455
      }
456 456

	
457 457
      ///Give back the height of the box
458 458

	
459 459
      ///Give back the height of the box.
460 460
      ///If the box is empty, then the return value is not defined.
461 461
      T height() const {
462 462
        return _top_right.y-_bottom_left.y;
463 463
      }
464 464

	
465 465
      ///Give back the width of the box
466 466

	
467 467
      ///Give back the width of the box.
468 468
      ///If the box is empty, then the return value is not defined.
469 469
      T width() const {
470 470
        return _top_right.x-_bottom_left.x;
471 471
      }
472 472

	
473 473
      ///Checks whether a point is inside the box
474 474
      bool inside(const Point<T>& u) const {
475 475
        if (_empty)
476 476
          return false;
477 477
        else {
478 478
          return ( (u.x-_bottom_left.x)*(_top_right.x-u.x) >= 0 &&
479 479
                   (u.y-_bottom_left.y)*(_top_right.y-u.y) >= 0 );
480 480
        }
481 481
      }
482 482

	
483 483
      ///Increments the box with a point
484 484

	
485 485
      ///Increments the box with a point.
486 486
      ///
487 487
      Box& add(const Point<T>& u){
488 488
        if (_empty) {
489 489
          _bottom_left = _top_right = u;
490 490
          _empty = false;
491 491
        }
492 492
        else {
493 493
          if (_bottom_left.x > u.x) _bottom_left.x = u.x;
494 494
          if (_bottom_left.y > u.y) _bottom_left.y = u.y;
495 495
          if (_top_right.x < u.x) _top_right.x = u.x;
496 496
          if (_top_right.y < u.y) _top_right.y = u.y;
497 497
        }
498 498
        return *this;
499 499
      }
500 500

	
501 501
      ///Increments the box to contain another box
502 502

	
503 503
      ///Increments the box to contain another box.
504 504
      ///
505 505
      Box& add(const Box &u){
506 506
        if ( !u.empty() ){
507 507
          add(u._bottom_left);
508 508
          add(u._top_right);
509 509
        }
510 510
        return *this;
511 511
      }
512 512

	
513 513
      ///Intersection of two boxes
514 514

	
515 515
      ///Intersection of two boxes.
516 516
      ///
517 517
      Box operator&(const Box& u) const {
518 518
        Box b;
519 519
        if (_empty || u._empty) {
520 520
          b._empty = true;
521 521
        } else {
522 522
          b._bottom_left.x = std::max(_bottom_left.x, u._bottom_left.x);
523 523
          b._bottom_left.y = std::max(_bottom_left.y, u._bottom_left.y);
524 524
          b._top_right.x = std::min(_top_right.x, u._top_right.x);
525 525
          b._top_right.y = std::min(_top_right.y, u._top_right.y);
526 526
          b._empty = b._bottom_left.x > b._top_right.x ||
527 527
                     b._bottom_left.y > b._top_right.y;
528 528
        }
529 529
        return b;
530 530
      }
531 531

	
532 532
  };//class Box
533 533

	
534 534

	
535 535
  ///Read a box from a stream
536 536

	
537 537
  ///Read a box from a stream.
538 538
  ///\relates Box
539 539
  template<typename T>
540 540
  inline std::istream& operator>>(std::istream &is, Box<T>& b) {
541 541
    char c;
542 542
    Point<T> p;
543 543
    if (is >> c) {
544 544
      if (c != '(') is.putback(c);
545 545
    } else {
546 546
      is.clear();
547 547
    }
548 548
    if (!(is >> p)) return is;
549 549
    b.bottomLeft(p);
550 550
    if (is >> c) {
551 551
      if (c != ',') is.putback(c);
552 552
    } else {
553 553
      is.clear();
554 554
    }
555 555
    if (!(is >> p)) return is;
556 556
    b.topRight(p);
557 557
    if (is >> c) {
558 558
      if (c != ')') is.putback(c);
559 559
    } else {
560 560
      is.clear();
561 561
    }
562 562
    return is;
563 563
  }
564 564

	
565 565
  ///Write a box to a stream
566 566

	
567 567
  ///Write a box to a stream.
568 568
  ///\relates Box
569 569
  template<typename T>
570 570
  inline std::ostream& operator<<(std::ostream &os, const Box<T>& b)
571 571
  {
572 572
    os << "(" << b.bottomLeft() << "," << b.topRight() << ")";
573 573
    return os;
574 574
  }
575 575

	
576 576
  ///Map of x-coordinates of a <tt>Point</tt>-map
577 577

	
578 578
  ///Map of x-coordinates of a \ref Point "Point"-map.
579 579
  ///
580 580
  template<class M>
581 581
  class XMap
582 582
  {
583 583
    M& _map;
584 584
  public:
585 585

	
586 586
    typedef typename M::Value::Value Value;
587 587
    typedef typename M::Key Key;
588 588
    ///\e
589 589
    XMap(M& map) : _map(map) {}
590 590
    Value operator[](Key k) const {return _map[k].x;}
591 591
    void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
592 592
  };
593 593

	
594 594
  ///Returns an XMap class
595 595

	
596 596
  ///This function just returns an XMap class.
597 597
  ///\relates XMap
598 598
  template<class M>
599 599
  inline XMap<M> xMap(M &m)
600 600
  {
601 601
    return XMap<M>(m);
602 602
  }
603 603

	
604 604
  template<class M>
605 605
  inline XMap<M> xMap(const M &m)
606 606
  {
607 607
    return XMap<M>(m);
608 608
  }
609 609

	
610 610
  ///Constant (read only) version of XMap
611 611

	
612 612
  ///Constant (read only) version of XMap.
613 613
  ///
614 614
  template<class M>
615 615
  class ConstXMap
616 616
  {
617 617
    const M& _map;
618 618
  public:
619 619

	
620 620
    typedef typename M::Value::Value Value;
621 621
    typedef typename M::Key Key;
622 622
    ///\e
623 623
    ConstXMap(const M &map) : _map(map) {}
624 624
    Value operator[](Key k) const {return _map[k].x;}
625 625
  };
626 626

	
627 627
  ///Returns a ConstXMap class
628 628

	
629 629
  ///This function just returns a ConstXMap class.
630 630
  ///\relates ConstXMap
631 631
  template<class M>
632 632
  inline ConstXMap<M> xMap(const M &m)
633 633
  {
634 634
    return ConstXMap<M>(m);
635 635
  }
636 636

	
637 637
  ///Map of y-coordinates of a <tt>Point</tt>-map
638 638

	
639 639
  ///Map of y-coordinates of a \ref Point "Point"-map.
640 640
  ///
641 641
  template<class M>
642 642
  class YMap
643 643
  {
644 644
    M& _map;
645 645
  public:
646 646

	
647 647
    typedef typename M::Value::Value Value;
648 648
    typedef typename M::Key Key;
649 649
    ///\e
650 650
    YMap(M& map) : _map(map) {}
651 651
    Value operator[](Key k) const {return _map[k].y;}
652 652
    void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
653 653
  };
654 654

	
655 655
  ///Returns a YMap class
656 656

	
657 657
  ///This function just returns a YMap class.
658 658
  ///\relates YMap
659 659
  template<class M>
660 660
  inline YMap<M> yMap(M &m)
661 661
  {
662 662
    return YMap<M>(m);
663 663
  }
664 664

	
665 665
  template<class M>
666 666
  inline YMap<M> yMap(const M &m)
667 667
  {
668 668
    return YMap<M>(m);
669 669
  }
670 670

	
671 671
  ///Constant (read only) version of YMap
672 672

	
673 673
  ///Constant (read only) version of YMap.
674 674
  ///
675 675
  template<class M>
676 676
  class ConstYMap
677 677
  {
678 678
    const M& _map;
679 679
  public:
680 680

	
681 681
    typedef typename M::Value::Value Value;
682 682
    typedef typename M::Key Key;
683 683
    ///\e
684 684
    ConstYMap(const M &map) : _map(map) {}
685 685
    Value operator[](Key k) const {return _map[k].y;}
686 686
  };
687 687

	
688 688
  ///Returns a ConstYMap class
689 689

	
690 690
  ///This function just returns a ConstYMap class.
691 691
  ///\relates ConstYMap
692 692
  template<class M>
693 693
  inline ConstYMap<M> yMap(const M &m)
694 694
  {
695 695
    return ConstYMap<M>(m);
696 696
  }
697 697

	
698 698

	
699 699
  ///\brief Map of the normSquare() of a <tt>Point</tt>-map
700 700
  ///
701 701
  ///Map of the \ref Point::normSquare() "normSquare()"
702 702
  ///of a \ref Point "Point"-map.
703 703
  template<class M>
704 704
  class NormSquareMap
705 705
  {
706 706
    const M& _map;
707 707
  public:
708 708

	
709 709
    typedef typename M::Value::Value Value;
710 710
    typedef typename M::Key Key;
711 711
    ///\e
712 712
    NormSquareMap(const M &map) : _map(map) {}
713 713
    Value operator[](Key k) const {return _map[k].normSquare();}
714 714
  };
715 715

	
716 716
  ///Returns a NormSquareMap class
717 717

	
718 718
  ///This function just returns a NormSquareMap class.
719 719
  ///\relates NormSquareMap
720 720
  template<class M>
721 721
  inline NormSquareMap<M> normSquareMap(const M &m)
722 722
  {
723 723
    return NormSquareMap<M>(m);
724 724
  }
725 725

	
726 726
  /// @}
727 727

	
728 728
  } //namespce dim2
729 729

	
730 730
} //namespace lemon
731 731

	
732 732
#endif //LEMON_DIM2_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_ERROR_H
20 20
#define LEMON_ERROR_H
21 21

	
22 22
/// \ingroup exceptions
23 23
/// \file
24 24
/// \brief Basic exception classes and error handling.
25 25

	
26 26
#include <exception>
27 27
#include <string>
28 28
#include <sstream>
29 29
#include <iostream>
30 30
#include <cstdlib>
31 31
#include <memory>
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  /// \addtogroup exceptions
36 36
  /// @{
37 37

	
38 38
  /// \brief Generic exception class.
39 39
  ///
40 40
  /// Base class for exceptions used in LEMON.
41 41
  ///
42 42
  class Exception : public std::exception {
43 43
  public:
44 44
    ///Constructor
45 45
    Exception() throw() {}
46 46
    ///Virtual destructor
47 47
    virtual ~Exception() throw() {}
48 48
    ///A short description of the exception
49 49
    virtual const char* what() const throw() {
50 50
      return "lemon::Exception";
51 51
    }
52 52
  };
53 53

	
54 54
  /// \brief Input-Output error
55 55
  ///
56 56
  /// This exception is thrown when a file operation cannot be
57 57
  /// succeeded.
58 58
  class IoError : public Exception {
59 59
  protected:
60 60
    std::string _message;
61 61
    std::string _file;
62 62

	
63 63
    mutable std::string _what;
64 64
  public:
65 65

	
66 66
    /// Copy constructor
67 67
    IoError(const IoError &error) throw() : Exception() {
68 68
      message(error._message);
69 69
      file(error._file);
70 70
    }
71 71

	
72 72
    /// Constructor
73 73
    explicit IoError(const char *message) throw() {
74 74
      IoError::message(message);
75 75
    }
76 76

	
77 77
    /// Constructor
78 78
    explicit IoError(const std::string &message) throw() {
79 79
      IoError::message(message);
80 80
    }
81 81

	
82 82
    /// Constructor
83 83
    explicit IoError(const char *message,
84 84
                     const std::string &file) throw() {
85 85
      IoError::message(message);
86 86
      IoError::file(file);
87 87
    }
88 88

	
89 89
    /// Constructor
90 90
    explicit IoError(const std::string &message,
91 91
                     const std::string &file) throw() {
92 92
      IoError::message(message);
93 93
      IoError::file(file);
94 94
    }
95 95

	
96 96
    /// Virtual destructor
97 97
    virtual ~IoError() throw() {}
98 98

	
99 99
    /// Set the error message
100 100
    void message(const char *message) throw() {
101 101
      try {
102 102
        _message = message;
103 103
      } catch (...) {}
104 104
    }
105 105

	
106 106
    /// Set the error message
107 107
    void message(const std::string& message) throw() {
108 108
      try {
109 109
        _message = message;
110 110
      } catch (...) {}
111 111
    }
112 112

	
113 113
    /// Set the file name
114 114
    void file(const std::string &file) throw() {
115 115
      try {
116 116
        _file = file;
117 117
      } catch (...) {}
118 118
    }
119 119

	
120 120
    /// Returns the error message
121 121
    const std::string& message() const throw() {
122 122
      return _message;
123 123
    }
124 124

	
125 125
    /// \brief Returns the filename
126 126
    ///
127 127
    /// Returns the filename or an empty string if it was not specified.
128 128
    const std::string& file() const throw() {
129 129
      return _file;
130 130
    }
131 131

	
132 132
    /// \brief Returns a short error message
133 133
    ///
134 134
    /// Returns a short error message which contains the message and the
135 135
    /// file name.
136 136
    virtual const char* what() const throw() {
137 137
      try {
138 138
        _what.clear();
139 139
        std::ostringstream oss;
140 140
        oss << "lemon:IoError" << ": ";
141 141
        oss << _message;
142 142
        if (!_file.empty()) {
143 143
          oss << " ('" << _file << "')";
144 144
        }
145 145
        _what = oss.str();
146 146
      }
147 147
      catch (...) {}
148 148
      if (!_what.empty()) return _what.c_str();
149 149
      else return "lemon:IoError";
150 150
    }
151 151

	
152 152
  };
153 153

	
154 154
  /// \brief Format error
155 155
  ///
156 156
  /// This exception is thrown when an input file has wrong
157 157
  /// format or a data representation is not legal.
158 158
  class FormatError : public Exception {
159 159
  protected:
160 160
    std::string _message;
161 161
    std::string _file;
162 162
    int _line;
163 163

	
164 164
    mutable std::string _what;
165 165
  public:
166 166

	
167 167
    /// Copy constructor
168 168
    FormatError(const FormatError &error) throw() : Exception() {
169 169
      message(error._message);
170 170
      file(error._file);
171 171
      line(error._line);
172 172
    }
173 173

	
174 174
    /// Constructor
175 175
    explicit FormatError(const char *message) throw() {
176 176
      FormatError::message(message);
177 177
      _line = 0;
178 178
    }
179 179

	
180 180
    /// Constructor
181 181
    explicit FormatError(const std::string &message) throw() {
182 182
      FormatError::message(message);
183 183
      _line = 0;
184 184
    }
185 185

	
186 186
    /// Constructor
187 187
    explicit FormatError(const char *message,
188 188
                         const std::string &file, int line = 0) throw() {
189 189
      FormatError::message(message);
190 190
      FormatError::file(file);
191 191
      FormatError::line(line);
192 192
    }
193 193

	
194 194
    /// Constructor
195 195
    explicit FormatError(const std::string &message,
196 196
                         const std::string &file, int line = 0) throw() {
197 197
      FormatError::message(message);
198 198
      FormatError::file(file);
199 199
      FormatError::line(line);
200 200
    }
201 201

	
202 202
    /// Virtual destructor
203 203
    virtual ~FormatError() throw() {}
204 204

	
205 205
    /// Set the line number
206 206
    void line(int line) throw() { _line = line; }
207 207

	
208 208
    /// Set the error message
209 209
    void message(const char *message) throw() {
210 210
      try {
211 211
        _message = message;
212 212
      } catch (...) {}
213 213
    }
214 214

	
215 215
    /// Set the error message
216 216
    void message(const std::string& message) throw() {
217 217
      try {
218 218
        _message = message;
219 219
      } catch (...) {}
220 220
    }
221 221

	
222 222
    /// Set the file name
223 223
    void file(const std::string &file) throw() {
224 224
      try {
225 225
        _file = file;
226 226
      } catch (...) {}
227 227
    }
228 228

	
229 229
    /// \brief Returns the line number
230 230
    ///
231 231
    /// Returns the line number or zero if it was not specified.
232 232
    int line() const throw() { return _line; }
233 233

	
234 234
    /// Returns the error message
235 235
    const std::string& message() const throw() {
236 236
      return _message;
237 237
    }
238 238

	
239 239
    /// \brief Returns the filename
240 240
    ///
241 241
    /// Returns the filename or an empty string if it was not specified.
242 242
    const std::string& file() const throw() {
243 243
      return _file;
244 244
    }
245 245

	
246 246
    /// \brief Returns a short error message
247 247
    ///
248 248
    /// Returns a short error message which contains the message, the
249 249
    /// file name and the line number.
250 250
    virtual const char* what() const throw() {
251 251
      try {
252 252
        _what.clear();
253 253
        std::ostringstream oss;
254 254
        oss << "lemon:FormatError" << ": ";
255 255
        oss << _message;
256 256
        if (!_file.empty() || _line != 0) {
257 257
          oss << " (";
258 258
          if (!_file.empty()) oss << "in file '" << _file << "'";
259 259
          if (!_file.empty() && _line != 0) oss << " ";
260 260
          if (_line != 0) oss << "at line " << _line;
261 261
          oss << ")";
262 262
        }
263 263
        _what = oss.str();
264 264
      }
265 265
      catch (...) {}
266 266
      if (!_what.empty()) return _what.c_str();
267 267
      else return "lemon:FormatError";
268 268
    }
269 269

	
270 270
  };
271 271

	
272 272
  /// @}
273 273

	
274 274
}
275 275

	
276 276
#endif // LEMON_ERROR_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_GRAPH_TO_EPS_H
20 20
#define LEMON_GRAPH_TO_EPS_H
21 21

	
22 22
#include<iostream>
23 23
#include<fstream>
24 24
#include<sstream>
25 25
#include<algorithm>
26 26
#include<vector>
27 27

	
28 28
#ifndef WIN32
29 29
#include<sys/time.h>
30 30
#include<ctime>
31 31
#else
32 32
#include<lemon/bits/windows.h>
33 33
#endif
34 34

	
35 35
#include<lemon/math.h>
36 36
#include<lemon/core.h>
37 37
#include<lemon/dim2.h>
38 38
#include<lemon/maps.h>
39 39
#include<lemon/color.h>
40 40
#include<lemon/bits/bezier.h>
41 41
#include<lemon/error.h>
42 42

	
43 43

	
44 44
///\ingroup eps_io
45 45
///\file
46 46
///\brief A well configurable tool for visualizing graphs
47 47

	
48 48
namespace lemon {
49 49

	
50 50
  namespace _graph_to_eps_bits {
51 51
    template<class MT>
52 52
    class _NegY {
53 53
    public:
54 54
      typedef typename MT::Key Key;
55 55
      typedef typename MT::Value Value;
56 56
      const MT &map;
57 57
      int yscale;
58 58
      _NegY(const MT &m,bool b) : map(m), yscale(1-b*2) {}
59 59
      Value operator[](Key n) { return Value(map[n].x,map[n].y*yscale);}
60 60
    };
61 61
  }
62 62

	
63 63
///Default traits class of GraphToEps
64 64

	
65 65
///Default traits class of \ref GraphToEps.
66 66
///
67
///\c G is the type of the underlying graph.
68
template<class G>
67
///\param GR is the type of the underlying graph.
68
template<class GR>
69 69
struct DefaultGraphToEpsTraits
70 70
{
71
  typedef G Graph;
71
  typedef GR Graph;
72
  typedef GR Digraph;
72 73
  typedef typename Graph::Node Node;
73 74
  typedef typename Graph::NodeIt NodeIt;
74 75
  typedef typename Graph::Arc Arc;
75 76
  typedef typename Graph::ArcIt ArcIt;
76 77
  typedef typename Graph::InArcIt InArcIt;
77 78
  typedef typename Graph::OutArcIt OutArcIt;
78 79

	
79 80

	
80 81
  const Graph &g;
81 82

	
82 83
  std::ostream& os;
83 84

	
84 85
  typedef ConstMap<typename Graph::Node,dim2::Point<double> > CoordsMapType;
85 86
  CoordsMapType _coords;
86 87
  ConstMap<typename Graph::Node,double > _nodeSizes;
87 88
  ConstMap<typename Graph::Node,int > _nodeShapes;
88 89

	
89 90
  ConstMap<typename Graph::Node,Color > _nodeColors;
90 91
  ConstMap<typename Graph::Arc,Color > _arcColors;
91 92

	
92 93
  ConstMap<typename Graph::Arc,double > _arcWidths;
93 94

	
94 95
  double _arcWidthScale;
95 96

	
96 97
  double _nodeScale;
97 98
  double _xBorder, _yBorder;
98 99
  double _scale;
99 100
  double _nodeBorderQuotient;
100 101

	
101 102
  bool _drawArrows;
102 103
  double _arrowLength, _arrowWidth;
103 104

	
104 105
  bool _showNodes, _showArcs;
105 106

	
106 107
  bool _enableParallel;
107 108
  double _parArcDist;
108 109

	
109 110
  bool _showNodeText;
110 111
  ConstMap<typename Graph::Node,bool > _nodeTexts;
111 112
  double _nodeTextSize;
112 113

	
113 114
  bool _showNodePsText;
114 115
  ConstMap<typename Graph::Node,bool > _nodePsTexts;
115 116
  char *_nodePsTextsPreamble;
116 117

	
117 118
  bool _undirected;
118 119

	
119 120
  bool _pleaseRemoveOsStream;
120 121

	
121 122
  bool _scaleToA4;
122 123

	
123 124
  std::string _title;
124 125
  std::string _copyright;
125 126

	
126 127
  enum NodeTextColorType
127 128
    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
128 129
  ConstMap<typename Graph::Node,Color > _nodeTextColors;
129 130

	
130 131
  bool _autoNodeScale;
131 132
  bool _autoArcWidthScale;
132 133

	
133 134
  bool _absoluteNodeSizes;
134 135
  bool _absoluteArcWidths;
135 136

	
136 137
  bool _negY;
137 138

	
138 139
  bool _preScale;
139 140
  ///Constructor
140 141

	
141 142
  ///Constructor
142
  ///\param _g  Reference to the graph to be printed.
143
  ///\param _os Reference to the output stream.
144
  ///\param _os Reference to the output stream.
143
  ///\param gr  Reference to the graph to be printed.
144
  ///\param ost Reference to the output stream.
145 145
  ///By default it is <tt>std::cout</tt>.
146
  ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
146
  ///\param pros If it is \c true, then the \c ostream referenced by \c os
147 147
  ///will be explicitly deallocated by the destructor.
148
  DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
149
                          bool _pros=false) :
150
    g(_g), os(_os),
148
  DefaultGraphToEpsTraits(const GR &gr, std::ostream& ost = std::cout,
149
                          bool pros = false) :
150
    g(gr), os(ost),
151 151
    _coords(dim2::Point<double>(1,1)), _nodeSizes(1), _nodeShapes(0),
152 152
    _nodeColors(WHITE), _arcColors(BLACK),
153 153
    _arcWidths(1.0), _arcWidthScale(0.003),
154 154
    _nodeScale(.01), _xBorder(10), _yBorder(10), _scale(1.0),
155 155
    _nodeBorderQuotient(.1),
156 156
    _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
157 157
    _showNodes(true), _showArcs(true),
158 158
    _enableParallel(false), _parArcDist(1),
159 159
    _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
160 160
    _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
161
    _undirected(lemon::UndirectedTagIndicator<G>::value),
162
    _pleaseRemoveOsStream(_pros), _scaleToA4(false),
161
    _undirected(lemon::UndirectedTagIndicator<GR>::value),
162
    _pleaseRemoveOsStream(pros), _scaleToA4(false),
163 163
    _nodeTextColorType(SAME_COL), _nodeTextColors(BLACK),
164 164
    _autoNodeScale(false),
165 165
    _autoArcWidthScale(false),
166 166
    _absoluteNodeSizes(false),
167 167
    _absoluteArcWidths(false),
168 168
    _negY(false),
169 169
    _preScale(true)
170 170
  {}
171 171
};
172 172

	
173 173
///Auxiliary class to implement the named parameters of \ref graphToEps()
174 174

	
175 175
///Auxiliary class to implement the named parameters of \ref graphToEps().
176 176
///
177 177
///For detailed examples see the \ref graph_to_eps_demo.cc demo file.
178 178
template<class T> class GraphToEps : public T
179 179
{
180 180
  // Can't believe it is required by the C++ standard
181 181
  using T::g;
182 182
  using T::os;
183 183

	
184 184
  using T::_coords;
185 185
  using T::_nodeSizes;
186 186
  using T::_nodeShapes;
187 187
  using T::_nodeColors;
188 188
  using T::_arcColors;
189 189
  using T::_arcWidths;
190 190

	
191 191
  using T::_arcWidthScale;
192 192
  using T::_nodeScale;
193 193
  using T::_xBorder;
194 194
  using T::_yBorder;
195 195
  using T::_scale;
196 196
  using T::_nodeBorderQuotient;
197 197

	
198 198
  using T::_drawArrows;
199 199
  using T::_arrowLength;
200 200
  using T::_arrowWidth;
201 201

	
202 202
  using T::_showNodes;
203 203
  using T::_showArcs;
204 204

	
205 205
  using T::_enableParallel;
206 206
  using T::_parArcDist;
207 207

	
208 208
  using T::_showNodeText;
209 209
  using T::_nodeTexts;
210 210
  using T::_nodeTextSize;
211 211

	
212 212
  using T::_showNodePsText;
213 213
  using T::_nodePsTexts;
214 214
  using T::_nodePsTextsPreamble;
215 215

	
216 216
  using T::_undirected;
217 217

	
218 218
  using T::_pleaseRemoveOsStream;
219 219

	
220 220
  using T::_scaleToA4;
221 221

	
222 222
  using T::_title;
223 223
  using T::_copyright;
224 224

	
225 225
  using T::NodeTextColorType;
226 226
  using T::CUST_COL;
227 227
  using T::DIST_COL;
228 228
  using T::DIST_BW;
229 229
  using T::_nodeTextColorType;
230 230
  using T::_nodeTextColors;
231 231

	
232 232
  using T::_autoNodeScale;
233 233
  using T::_autoArcWidthScale;
234 234

	
235 235
  using T::_absoluteNodeSizes;
236 236
  using T::_absoluteArcWidths;
237 237

	
238 238

	
239 239
  using T::_negY;
240 240
  using T::_preScale;
241 241

	
242 242
  // dradnats ++C eht yb deriuqer si ti eveileb t'naC
243 243

	
244 244
  typedef typename T::Graph Graph;
245
  typedef typename T::Digraph Digraph;
245 246
  typedef typename Graph::Node Node;
246 247
  typedef typename Graph::NodeIt NodeIt;
247 248
  typedef typename Graph::Arc Arc;
248 249
  typedef typename Graph::ArcIt ArcIt;
249 250
  typedef typename Graph::InArcIt InArcIt;
250 251
  typedef typename Graph::OutArcIt OutArcIt;
251 252

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

	
257 258
  bool dontPrint;
258 259

	
259 260
public:
260 261
  ///Node shapes
261 262

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

	
291 288
private:
292 289
  class arcLess {
293 290
    const Graph &g;
294 291
  public:
295 292
    arcLess(const Graph &_g) : g(_g) {}
296 293
    bool operator()(Arc a,Arc b) const
297 294
    {
298 295
      Node ai=std::min(g.source(a),g.target(a));
299 296
      Node aa=std::max(g.source(a),g.target(a));
300 297
      Node bi=std::min(g.source(b),g.target(b));
301 298
      Node ba=std::max(g.source(b),g.target(b));
302 299
      return ai<bi ||
303 300
        (ai==bi && (aa < ba ||
304 301
                    (aa==ba && ai==g.source(a) && bi==g.target(b))));
305 302
    }
306 303
  };
307 304
  bool isParallel(Arc e,Arc f) const
308 305
  {
309 306
    return (g.source(e)==g.source(f)&&
310 307
            g.target(e)==g.target(f)) ||
311 308
      (g.source(e)==g.target(f)&&
312 309
       g.target(e)==g.source(f));
313 310
  }
314 311
  template<class TT>
315 312
  static std::string psOut(const dim2::Point<TT> &p)
316 313
    {
317 314
      std::ostringstream os;
318 315
      os << p.x << ' ' << p.y;
319 316
      return os.str();
320 317
    }
321 318
  static std::string psOut(const Color &c)
322 319
    {
323 320
      std::ostringstream os;
324 321
      os << c.red() << ' ' << c.green() << ' ' << c.blue();
325 322
      return os.str();
326 323
    }
327 324

	
328 325
public:
329 326
  GraphToEps(const T &t) : T(t), dontPrint(false) {};
330 327

	
331 328
  template<class X> struct CoordsTraits : public T {
332 329
  typedef X CoordsMapType;
333 330
    const X &_coords;
334 331
    CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
335 332
  };
336 333
  ///Sets the map of the node coordinates
337 334

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

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

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

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

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

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

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

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

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

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

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

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

	
501 498
  ///Turns on/off the absolutematic node size scaling.
502 499

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

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

	
516 513
  ///Turn on/off pre-scaling
517 514

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

	
527 524
  ///Sets a global scale factor for arc widths
528 525

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

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

	
550 547
  ///Turns on/off the absolutematic arc width scaling.
551 548
  ///
552 549
  ///\sa arcWidthScale()
553 550
  ///
554 551
  GraphToEps<T> &absoluteArcWidths(bool b=true) {
555 552
    _absoluteArcWidths=b;return *this;
556 553
  }
557 554
  ///Sets a global scale factor for the whole picture
558 555
  GraphToEps<T> &scale(double d) {_scale=d;return *this;}
559 556
  ///Sets the width of the border around the picture
560 557
  GraphToEps<T> &border(double b=10) {_xBorder=_yBorder=b;return *this;}
561 558
  ///Sets the width of the border around the picture
562 559
  GraphToEps<T> &border(double x, double y) {
563 560
    _xBorder=x;_yBorder=y;return *this;
564 561
  }
565 562
  ///Sets whether to draw arrows
566 563
  GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
567 564
  ///Sets the length of the arrowheads
568 565
  GraphToEps<T> &arrowLength(double d=1.0) {_arrowLength*=d;return *this;}
569 566
  ///Sets the width of the arrowheads
570 567
  GraphToEps<T> &arrowWidth(double d=.3) {_arrowWidth*=d;return *this;}
571 568

	
572 569
  ///Scales the drawing to fit to A4 page
573 570
  GraphToEps<T> &scaleToA4() {_scaleToA4=true;return *this;}
574 571

	
575 572
  ///Enables parallel arcs
576 573
  GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
577 574

	
578 575
  ///Sets the distance between parallel arcs
579 576
  GraphToEps<T> &parArcDist(double d) {_parArcDist*=d;return *this;}
580 577

	
581 578
  ///Hides the arcs
582 579
  GraphToEps<T> &hideArcs(bool b=true) {_showArcs=!b;return *this;}
583 580
  ///Hides the nodes
584 581
  GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
585 582

	
586 583
  ///Sets the size of the node texts
587 584
  GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
588 585

	
589 586
  ///Sets the color of the node texts to be different from the node color
590 587

	
591 588
  ///Sets the color of the node texts to be as different from the node color
592 589
  ///as it is possible.
593 590
  GraphToEps<T> &distantColorNodeTexts()
594 591
  {_nodeTextColorType=DIST_COL;return *this;}
595 592
  ///Sets the color of the node texts to be black or white and always visible.
596 593

	
597 594
  ///Sets the color of the node texts to be black or white according to
598 595
  ///which is more different from the node color.
599 596
  GraphToEps<T> &distantBWNodeTexts()
600 597
  {_nodeTextColorType=DIST_BW;return *this;}
601 598

	
602 599
  ///Gives a preamble block for node Postscript block.
603 600

	
604 601
  ///Gives a preamble block for node Postscript block.
605 602
  ///
606 603
  ///\sa nodePsTexts()
607 604
  GraphToEps<T> & nodePsTextsPreamble(const char *str) {
608 605
    _nodePsTextsPreamble=str ;return *this;
609 606
  }
610 607
  ///Sets whether the graph is undirected
611 608

	
612 609
  ///Sets whether the graph is undirected.
613 610
  ///
614 611
  ///This setting is the default for undirected graphs.
615 612
  ///
616 613
  ///\sa directed()
617 614
   GraphToEps<T> &undirected(bool b=true) {_undirected=b;return *this;}
618 615

	
619 616
  ///Sets whether the graph is directed
620 617

	
621 618
  ///Sets whether the graph is directed.
622 619
  ///Use it to show the edges as a pair of directed ones.
623 620
  ///
624 621
  ///This setting is the default for digraphs.
625 622
  ///
626 623
  ///\sa undirected()
627 624
  GraphToEps<T> &directed(bool b=true) {_undirected=!b;return *this;}
628 625

	
629 626
  ///Sets the title.
630 627

	
631 628
  ///Sets the title of the generated image,
632 629
  ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
633 630
  ///the EPS file.
634 631
  GraphToEps<T> &title(const std::string &t) {_title=t;return *this;}
635 632
  ///Sets the copyright statement.
636 633

	
637 634
  ///Sets the copyright statement of the generated image,
638 635
  ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
639 636
  ///the EPS file.
640 637
  GraphToEps<T> &copyright(const std::string &t) {_copyright=t;return *this;}
641 638

	
642 639
protected:
643 640
  bool isInsideNode(dim2::Point<double> p, double r,int t)
644 641
  {
645 642
    switch(t) {
646 643
    case CIRCLE:
647 644
    case MALE:
648 645
    case FEMALE:
649 646
      return p.normSquare()<=r*r;
650 647
    case SQUARE:
651 648
      return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
652 649
    case DIAMOND:
653 650
      return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r;
654 651
    }
655 652
    return false;
656 653
  }
657 654

	
658 655
public:
659 656
  ~GraphToEps() { }
660 657

	
661 658
  ///Draws the graph.
662 659

	
663 660
  ///Like other functions using
664 661
  ///\ref named-templ-func-param "named template parameters",
665 662
  ///this function calls the algorithm itself, i.e. in this case
666 663
  ///it draws the graph.
667 664
  void run() {
668 665
    const double EPSILON=1e-9;
669 666
    if(dontPrint) return;
670 667

	
671 668
    _graph_to_eps_bits::_NegY<typename T::CoordsMapType>
672 669
      mycoords(_coords,_negY);
673 670

	
674 671
    os << "%!PS-Adobe-2.0 EPSF-2.0\n";
675 672
    if(_title.size()>0) os << "%%Title: " << _title << '\n';
676 673
     if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n';
677 674
    os << "%%Creator: LEMON, graphToEps()\n";
678 675

	
679 676
    {
680 677
      os << "%%CreationDate: ";
681 678
#ifndef WIN32
682 679
      timeval tv;
683 680
      gettimeofday(&tv, 0);
684 681

	
685 682
      char cbuf[26];
686 683
      ctime_r(&tv.tv_sec,cbuf);
687 684
      os << cbuf;
688 685
#else
689 686
      os << bits::getWinFormattedDate();
690 687
#endif
691 688
    }
692 689
    os << std::endl;
693 690

	
694 691
    if (_autoArcWidthScale) {
695 692
      double max_w=0;
696 693
      for(ArcIt e(g);e!=INVALID;++e)
697 694
        max_w=std::max(double(_arcWidths[e]),max_w);
698 695
      if(max_w>EPSILON) {
699 696
        _arcWidthScale/=max_w;
700 697
      }
701 698
    }
702 699

	
703 700
    if (_autoNodeScale) {
704 701
      double max_s=0;
705 702
      for(NodeIt n(g);n!=INVALID;++n)
706 703
        max_s=std::max(double(_nodeSizes[n]),max_s);
707 704
      if(max_s>EPSILON) {
708 705
        _nodeScale/=max_s;
709 706
      }
710 707
    }
711 708

	
712 709
    double diag_len = 1;
713 710
    if(!(_absoluteNodeSizes&&_absoluteArcWidths)) {
714 711
      dim2::Box<double> bb;
715 712
      for(NodeIt n(g);n!=INVALID;++n) bb.add(mycoords[n]);
716 713
      if (bb.empty()) {
717 714
        bb = dim2::Box<double>(dim2::Point<double>(0,0));
718 715
      }
719 716
      diag_len = std::sqrt((bb.bottomLeft()-bb.topRight()).normSquare());
720 717
      if(diag_len<EPSILON) diag_len = 1;
721 718
      if(!_absoluteNodeSizes) _nodeScale*=diag_len;
722 719
      if(!_absoluteArcWidths) _arcWidthScale*=diag_len;
723 720
    }
724 721

	
725 722
    dim2::Box<double> bb;
726 723
    for(NodeIt n(g);n!=INVALID;++n) {
727 724
      double ns=_nodeSizes[n]*_nodeScale;
728 725
      dim2::Point<double> p(ns,ns);
729 726
      switch(_nodeShapes[n]) {
730 727
      case CIRCLE:
731 728
      case SQUARE:
732 729
      case DIAMOND:
733 730
        bb.add(p+mycoords[n]);
734 731
        bb.add(-p+mycoords[n]);
735 732
        break;
736 733
      case MALE:
737 734
        bb.add(-p+mycoords[n]);
738 735
        bb.add(dim2::Point<double>(1.5*ns,1.5*std::sqrt(3.0)*ns)+mycoords[n]);
739 736
        break;
740 737
      case FEMALE:
741 738
        bb.add(p+mycoords[n]);
742 739
        bb.add(dim2::Point<double>(-ns,-3.01*ns)+mycoords[n]);
743 740
        break;
744 741
      }
745 742
    }
746 743
    if (bb.empty()) {
747 744
      bb = dim2::Box<double>(dim2::Point<double>(0,0));
748 745
    }
749 746

	
750 747
    if(_scaleToA4)
751 748
      os <<"%%BoundingBox: 0 0 596 842\n%%DocumentPaperSizes: a4\n";
752 749
    else {
753 750
      if(_preScale) {
754 751
        //Rescale so that BoundingBox won't be neither to big nor too small.
755 752
        while(bb.height()*_scale>1000||bb.width()*_scale>1000) _scale/=10;
756 753
        while(bb.height()*_scale<100||bb.width()*_scale<100) _scale*=10;
757 754
      }
758 755

	
759 756
      os << "%%BoundingBox: "
760 757
         << int(floor(bb.left()   * _scale - _xBorder)) << ' '
761 758
         << int(floor(bb.bottom() * _scale - _yBorder)) << ' '
762 759
         << int(ceil(bb.right()  * _scale + _xBorder)) << ' '
763 760
         << int(ceil(bb.top()    * _scale + _yBorder)) << '\n';
764 761
    }
765 762

	
766 763
    os << "%%EndComments\n";
767 764

	
768 765
    //x1 y1 x2 y2 x3 y3 cr cg cb w
769 766
    os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
770 767
       << "      4 2 roll 1 index 1 index curveto stroke } bind def\n";
771 768
    os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke }"
772 769
       << " bind def\n";
773 770
    //x y r
774 771
    os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath }"
775 772
       << " bind def\n";
776 773
    //x y r
777 774
    os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
778 775
       << "      2 index 1 index sub 2 index 2 index add lineto\n"
779 776
       << "      2 index 1 index sub 2 index 2 index sub lineto\n"
780 777
       << "      2 index 1 index add 2 index 2 index sub lineto\n"
781 778
       << "      closepath pop pop pop} bind def\n";
782 779
    //x y r
783 780
    os << "/di { newpath 2 index 1 index add 2 index moveto\n"
784 781
       << "      2 index             2 index 2 index add lineto\n"
785 782
       << "      2 index 1 index sub 2 index             lineto\n"
786 783
       << "      2 index             2 index 2 index sub lineto\n"
787 784
       << "      closepath pop pop pop} bind def\n";
788 785
    // x y r cr cg cb
789 786
    os << "/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill\n"
790 787
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
791 788
       << "   } bind def\n";
792 789
    os << "/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill\n"
793 790
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div sq fill\n"
794 791
       << "   } bind def\n";
795 792
    os << "/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill\n"
796 793
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div di fill\n"
797 794
       << "   } bind def\n";
798 795
    os << "/nfemale { 0 0 0 setrgbcolor 3 index "
799 796
       << _nodeBorderQuotient/(1+_nodeBorderQuotient)
800 797
       << " 1.5 mul mul setlinewidth\n"
801 798
       << "  newpath 5 index 5 index moveto "
802 799
       << "5 index 5 index 5 index 3.01 mul sub\n"
803 800
       << "  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub"
804 801
       << " moveto\n"
805 802
       << "  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto "
806 803
       << "stroke\n"
807 804
       << "  5 index 5 index 5 index c fill\n"
808 805
       << "  setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
809 806
       << "  } bind def\n";
810 807
    os << "/nmale {\n"
811 808
       << "  0 0 0 setrgbcolor 3 index "
812 809
       << _nodeBorderQuotient/(1+_nodeBorderQuotient)
813 810
       <<" 1.5 mul mul setlinewidth\n"
814 811
       << "  newpath 5 index 5 index moveto\n"
815 812
       << "  5 index 4 index 1 mul 1.5 mul add\n"
816 813
       << "  5 index 5 index 3 sqrt 1.5 mul mul add\n"
817 814
       << "  1 index 1 index lineto\n"
818 815
       << "  1 index 1 index 7 index sub moveto\n"
819 816
       << "  1 index 1 index lineto\n"
820 817
       << "  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub"
821 818
       << " lineto\n"
822 819
       << "  stroke\n"
823 820
       << "  5 index 5 index 5 index c fill\n"
824 821
       << "  setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
825 822
       << "  } bind def\n";
826 823

	
827 824

	
828 825
    os << "/arrl " << _arrowLength << " def\n";
829 826
    os << "/arrw " << _arrowWidth << " def\n";
830 827
    // l dx_norm dy_norm
831 828
    os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
832 829
    //len w dx_norm dy_norm x1 y1 cr cg cb
833 830
    os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx "
834 831
       << "exch def\n"
835 832
       << "       /w exch def /len exch def\n"
836 833
      //<< "0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
837 834
       << "       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
838 835
       << "       len w sub arrl sub dx dy lrl\n"
839 836
       << "       arrw dy dx neg lrl\n"
840 837
       << "       dx arrl w add mul dy w 2 div arrw add mul sub\n"
841 838
       << "       dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
842 839
       << "       dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
843 840
       << "       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
844 841
       << "       arrw dy dx neg lrl\n"
845 842
       << "       len w sub arrl sub neg dx dy lrl\n"
846 843
       << "       closepath fill } bind def\n";
847 844
    os << "/cshow { 2 index 2 index moveto dup stringwidth pop\n"
848 845
       << "         neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n";
849 846

	
850 847
    os << "\ngsave\n";
851 848
    if(_scaleToA4)
852 849
      if(bb.height()>bb.width()) {
853 850
        double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.height(),
854 851
                  (A4WIDTH-2*A4BORDER)/bb.width());
855 852
        os << ((A4WIDTH -2*A4BORDER)-sc*bb.width())/2 + A4BORDER << ' '
856 853
           << ((A4HEIGHT-2*A4BORDER)-sc*bb.height())/2 + A4BORDER
857 854
           << " translate\n"
858 855
           << sc << " dup scale\n"
859 856
           << -bb.left() << ' ' << -bb.bottom() << " translate\n";
860 857
      }
861 858
      else {
862 859
        double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.width(),
863 860
                  (A4WIDTH-2*A4BORDER)/bb.height());
864 861
        os << ((A4WIDTH -2*A4BORDER)-sc*bb.height())/2 + A4BORDER << ' '
865 862
           << ((A4HEIGHT-2*A4BORDER)-sc*bb.width())/2 + A4BORDER
866 863
           << " translate\n"
867 864
           << sc << " dup scale\n90 rotate\n"
868 865
           << -bb.left() << ' ' << -bb.top() << " translate\n";
869 866
        }
870 867
    else if(_scale!=1.0) os << _scale << " dup scale\n";
871 868

	
872 869
    if(_showArcs) {
873 870
      os << "%Arcs:\ngsave\n";
874 871
      if(_enableParallel) {
875 872
        std::vector<Arc> el;
876 873
        for(ArcIt e(g);e!=INVALID;++e)
877 874
          if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
878 875
             &&g.source(e)!=g.target(e))
879 876
            el.push_back(e);
880 877
        std::sort(el.begin(),el.end(),arcLess(g));
881 878

	
882 879
        typename std::vector<Arc>::iterator j;
883 880
        for(typename std::vector<Arc>::iterator i=el.begin();i!=el.end();i=j) {
884 881
          for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ;
885 882

	
886 883
          double sw=0;
887 884
          for(typename std::vector<Arc>::iterator e=i;e!=j;++e)
888 885
            sw+=_arcWidths[*e]*_arcWidthScale+_parArcDist;
889 886
          sw-=_parArcDist;
890 887
          sw/=-2.0;
891 888
          dim2::Point<double>
892 889
            dvec(mycoords[g.target(*i)]-mycoords[g.source(*i)]);
893 890
          double l=std::sqrt(dvec.normSquare());
894 891
          dim2::Point<double> d(dvec/std::max(l,EPSILON));
895 892
          dim2::Point<double> m;
896 893
//           m=dim2::Point<double>(mycoords[g.target(*i)]+
897 894
//                                 mycoords[g.source(*i)])/2.0;
898 895

	
899 896
//            m=dim2::Point<double>(mycoords[g.source(*i)])+
900 897
//             dvec*(double(_nodeSizes[g.source(*i)])/
901 898
//                (_nodeSizes[g.source(*i)]+_nodeSizes[g.target(*i)]));
902 899

	
903 900
          m=dim2::Point<double>(mycoords[g.source(*i)])+
904 901
            d*(l+_nodeSizes[g.source(*i)]-_nodeSizes[g.target(*i)])/2.0;
905 902

	
906 903
          for(typename std::vector<Arc>::iterator e=i;e!=j;++e) {
907 904
            sw+=_arcWidths[*e]*_arcWidthScale/2.0;
908 905
            dim2::Point<double> mm=m+rot90(d)*sw/.75;
909 906
            if(_drawArrows) {
910 907
              int node_shape;
911 908
              dim2::Point<double> s=mycoords[g.source(*e)];
912 909
              dim2::Point<double> t=mycoords[g.target(*e)];
913 910
              double rn=_nodeSizes[g.target(*e)]*_nodeScale;
914 911
              node_shape=_nodeShapes[g.target(*e)];
915 912
              dim2::Bezier3 bez(s,mm,mm,t);
916 913
              double t1=0,t2=1;
917 914
              for(int ii=0;ii<INTERPOL_PREC;++ii)
918 915
                if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t2=(t1+t2)/2;
919 916
                else t1=(t1+t2)/2;
920 917
              dim2::Point<double> apoint=bez((t1+t2)/2);
921 918
              rn = _arrowLength+_arcWidths[*e]*_arcWidthScale;
922 919
              rn*=rn;
923 920
              t2=(t1+t2)/2;t1=0;
924 921
              for(int ii=0;ii<INTERPOL_PREC;++ii)
925 922
                if((bez((t1+t2)/2)-apoint).normSquare()>rn) t1=(t1+t2)/2;
926 923
                else t2=(t1+t2)/2;
927 924
              dim2::Point<double> linend=bez((t1+t2)/2);
928 925
              bez=bez.before((t1+t2)/2);
929 926
//               rn=_nodeSizes[g.source(*e)]*_nodeScale;
930 927
//               node_shape=_nodeShapes[g.source(*e)];
931 928
//               t1=0;t2=1;
932 929
//               for(int i=0;i<INTERPOL_PREC;++i)
933 930
//                 if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape))
934 931
//                   t1=(t1+t2)/2;
935 932
//                 else t2=(t1+t2)/2;
936 933
//               bez=bez.after((t1+t2)/2);
937 934
              os << _arcWidths[*e]*_arcWidthScale << " setlinewidth "
938 935
                 << _arcColors[*e].red() << ' '
939 936
                 << _arcColors[*e].green() << ' '
940 937
                 << _arcColors[*e].blue() << " setrgbcolor newpath\n"
941 938
                 << bez.p1.x << ' ' <<  bez.p1.y << " moveto\n"
942 939
                 << bez.p2.x << ' ' << bez.p2.y << ' '
943 940
                 << bez.p3.x << ' ' << bez.p3.y << ' '
944 941
                 << bez.p4.x << ' ' << bez.p4.y << " curveto stroke\n";
945 942
              dim2::Point<double> dd(rot90(linend-apoint));
946 943
              dd*=(.5*_arcWidths[*e]*_arcWidthScale+_arrowWidth)/
947 944
                std::sqrt(dd.normSquare());
948 945
              os << "newpath " << psOut(apoint) << " moveto "
949 946
                 << psOut(linend+dd) << " lineto "
950 947
                 << psOut(linend-dd) << " lineto closepath fill\n";
951 948
            }
952 949
            else {
953 950
              os << mycoords[g.source(*e)].x << ' '
954 951
                 << mycoords[g.source(*e)].y << ' '
955 952
                 << mm.x << ' ' << mm.y << ' '
956 953
                 << mycoords[g.target(*e)].x << ' '
957 954
                 << mycoords[g.target(*e)].y << ' '
958 955
                 << _arcColors[*e].red() << ' '
959 956
                 << _arcColors[*e].green() << ' '
960 957
                 << _arcColors[*e].blue() << ' '
961 958
                 << _arcWidths[*e]*_arcWidthScale << " lb\n";
962 959
            }
963 960
            sw+=_arcWidths[*e]*_arcWidthScale/2.0+_parArcDist;
964 961
          }
965 962
        }
966 963
      }
967 964
      else for(ArcIt e(g);e!=INVALID;++e)
968 965
        if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
969 966
           &&g.source(e)!=g.target(e)) {
970 967
          if(_drawArrows) {
971 968
            dim2::Point<double> d(mycoords[g.target(e)]-mycoords[g.source(e)]);
972 969
            double rn=_nodeSizes[g.target(e)]*_nodeScale;
973 970
            int node_shape=_nodeShapes[g.target(e)];
974 971
            double t1=0,t2=1;
975 972
            for(int i=0;i<INTERPOL_PREC;++i)
976 973
              if(isInsideNode((-(t1+t2)/2)*d,rn,node_shape)) t1=(t1+t2)/2;
977 974
              else t2=(t1+t2)/2;
978 975
            double l=std::sqrt(d.normSquare());
979 976
            d/=l;
980 977

	
981 978
            os << l*(1-(t1+t2)/2) << ' '
982 979
               << _arcWidths[e]*_arcWidthScale << ' '
983 980
               << d.x << ' ' << d.y << ' '
984 981
               << mycoords[g.source(e)].x << ' '
985 982
               << mycoords[g.source(e)].y << ' '
986 983
               << _arcColors[e].red() << ' '
987 984
               << _arcColors[e].green() << ' '
988 985
               << _arcColors[e].blue() << " arr\n";
989 986
          }
990 987
          else os << mycoords[g.source(e)].x << ' '
991 988
                  << mycoords[g.source(e)].y << ' '
992 989
                  << mycoords[g.target(e)].x << ' '
993 990
                  << mycoords[g.target(e)].y << ' '
994 991
                  << _arcColors[e].red() << ' '
995 992
                  << _arcColors[e].green() << ' '
996 993
                  << _arcColors[e].blue() << ' '
997 994
                  << _arcWidths[e]*_arcWidthScale << " l\n";
998 995
        }
999 996
      os << "grestore\n";
1000 997
    }
1001 998
    if(_showNodes) {
1002 999
      os << "%Nodes:\ngsave\n";
1003 1000
      for(NodeIt n(g);n!=INVALID;++n) {
1004 1001
        os << mycoords[n].x << ' ' << mycoords[n].y << ' '
1005 1002
           << _nodeSizes[n]*_nodeScale << ' '
1006 1003
           << _nodeColors[n].red() << ' '
1007 1004
           << _nodeColors[n].green() << ' '
1008 1005
           << _nodeColors[n].blue() << ' ';
1009 1006
        switch(_nodeShapes[n]) {
1010 1007
        case CIRCLE:
1011 1008
          os<< "nc";break;
1012 1009
        case SQUARE:
1013 1010
          os<< "nsq";break;
1014 1011
        case DIAMOND:
1015 1012
          os<< "ndi";break;
1016 1013
        case MALE:
1017 1014
          os<< "nmale";break;
1018 1015
        case FEMALE:
1019 1016
          os<< "nfemale";break;
1020 1017
        }
1021 1018
        os<<'\n';
1022 1019
      }
1023 1020
      os << "grestore\n";
1024 1021
    }
1025 1022
    if(_showNodeText) {
1026 1023
      os << "%Node texts:\ngsave\n";
1027 1024
      os << "/fosi " << _nodeTextSize << " def\n";
1028 1025
      os << "(Helvetica) findfont fosi scalefont setfont\n";
1029 1026
      for(NodeIt n(g);n!=INVALID;++n) {
1030 1027
        switch(_nodeTextColorType) {
1031 1028
        case DIST_COL:
1032 1029
          os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
1033 1030
          break;
1034 1031
        case DIST_BW:
1035 1032
          os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
1036 1033
          break;
1037 1034
        case CUST_COL:
1038 1035
          os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
1039 1036
          break;
1040 1037
        default:
1041 1038
          os << "0 0 0 setrgbcolor\n";
1042 1039
        }
1043 1040
        os << mycoords[n].x << ' ' << mycoords[n].y
1044 1041
           << " (" << _nodeTexts[n] << ") cshow\n";
1045 1042
      }
1046 1043
      os << "grestore\n";
1047 1044
    }
1048 1045
    if(_showNodePsText) {
1049 1046
      os << "%Node PS blocks:\ngsave\n";
1050 1047
      for(NodeIt n(g);n!=INVALID;++n)
1051 1048
        os << mycoords[n].x << ' ' << mycoords[n].y
1052 1049
           << " moveto\n" << _nodePsTexts[n] << "\n";
1053 1050
      os << "grestore\n";
1054 1051
    }
1055 1052

	
1056 1053
    os << "grestore\nshowpage\n";
1057 1054

	
1058 1055
    //CleanUp:
1059 1056
    if(_pleaseRemoveOsStream) {delete &os;}
1060 1057
  }
1061 1058

	
1062 1059
  ///\name Aliases
1063 1060
  ///These are just some aliases to other parameter setting functions.
1064 1061

	
1065 1062
  ///@{
1066 1063

	
1067 1064
  ///An alias for arcWidths()
1068 1065
  template<class X> GraphToEps<ArcWidthsTraits<X> > edgeWidths(const X &x)
1069 1066
  {
1070 1067
    return arcWidths(x);
1071 1068
  }
1072 1069

	
1073 1070
  ///An alias for arcColors()
1074 1071
  template<class X> GraphToEps<ArcColorsTraits<X> >
1075 1072
  edgeColors(const X &x)
1076 1073
  {
1077 1074
    return arcColors(x);
1078 1075
  }
1079 1076

	
1080 1077
  ///An alias for arcWidthScale()
1081 1078
  GraphToEps<T> &edgeWidthScale(double d) {return arcWidthScale(d);}
1082 1079

	
1083 1080
  ///An alias for autoArcWidthScale()
1084 1081
  GraphToEps<T> &autoEdgeWidthScale(bool b=true)
1085 1082
  {
1086 1083
    return autoArcWidthScale(b);
1087 1084
  }
1088 1085

	
1089 1086
  ///An alias for absoluteArcWidths()
1090 1087
  GraphToEps<T> &absoluteEdgeWidths(bool b=true)
1091 1088
  {
1092 1089
    return absoluteArcWidths(b);
1093 1090
  }
1094 1091

	
1095 1092
  ///An alias for parArcDist()
1096 1093
  GraphToEps<T> &parEdgeDist(double d) {return parArcDist(d);}
1097 1094

	
1098 1095
  ///An alias for hideArcs()
1099 1096
  GraphToEps<T> &hideEdges(bool b=true) {return hideArcs(b);}
1100 1097

	
1101 1098
  ///@}
1102 1099
};
1103 1100

	
1104 1101
template<class T>
1105 1102
const int GraphToEps<T>::INTERPOL_PREC = 20;
1106 1103
template<class T>
1107 1104
const double GraphToEps<T>::A4HEIGHT = 841.8897637795276;
1108 1105
template<class T>
1109 1106
const double GraphToEps<T>::A4WIDTH  = 595.275590551181;
1110 1107
template<class T>
1111 1108
const double GraphToEps<T>::A4BORDER = 15;
1112 1109

	
1113 1110

	
1114 1111
///Generates an EPS file from a graph
1115 1112

	
1116 1113
///\ingroup eps_io
1117 1114
///Generates an EPS file from a graph.
1118 1115
///\param g Reference to the graph to be printed.
1119 1116
///\param os Reference to the output stream.
1120 1117
///By default it is <tt>std::cout</tt>.
1121 1118
///
1122 1119
///This function also has a lot of
1123 1120
///\ref named-templ-func-param "named parameters",
1124 1121
///they are declared as the members of class \ref GraphToEps. The following
1125 1122
///example shows how to use these parameters.
1126 1123
///\code
1127 1124
/// graphToEps(g,os).scale(10).coords(coords)
1128 1125
///              .nodeScale(2).nodeSizes(sizes)
1129 1126
///              .arcWidthScale(.4).run();
1130 1127
///\endcode
1131 1128
///
1132 1129
///For more detailed examples see the \ref graph_to_eps_demo.cc demo file.
1133 1130
///
1134 1131
///\warning Don't forget to put the \ref GraphToEps::run() "run()"
1135 1132
///to the end of the parameter list.
1136 1133
///\sa GraphToEps
1137
///\sa graphToEps(G &g, const char *file_name)
1138
template<class G>
1139
GraphToEps<DefaultGraphToEpsTraits<G> >
1140
graphToEps(G &g, std::ostream& os=std::cout)
1134
///\sa graphToEps(GR &g, const char *file_name)
1135
template<class GR>
1136
GraphToEps<DefaultGraphToEpsTraits<GR> >
1137
graphToEps(GR &g, std::ostream& os=std::cout)
1141 1138
{
1142 1139
  return
1143
    GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
1140
    GraphToEps<DefaultGraphToEpsTraits<GR> >(DefaultGraphToEpsTraits<GR>(g,os));
1144 1141
}
1145 1142

	
1146 1143
///Generates an EPS file from a graph
1147 1144

	
1148 1145
///\ingroup eps_io
1149 1146
///This function does the same as
1150
///\ref graphToEps(G &g,std::ostream& os)
1147
///\ref graphToEps(GR &g,std::ostream& os)
1151 1148
///but it writes its output into the file \c file_name
1152 1149
///instead of a stream.
1153
///\sa graphToEps(G &g, std::ostream& os)
1154
template<class G>
1155
GraphToEps<DefaultGraphToEpsTraits<G> >
1156
graphToEps(G &g,const char *file_name)
1150
///\sa graphToEps(GR &g, std::ostream& os)
1151
template<class GR>
1152
GraphToEps<DefaultGraphToEpsTraits<GR> >
1153
graphToEps(GR &g,const char *file_name)
1157 1154
{
1158 1155
  std::ostream* os = new std::ofstream(file_name);
1159 1156
  if (!(*os)) {
1160 1157
    delete os;
1161 1158
    throw IoError("Cannot write file", file_name);
1162 1159
  }
1163
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1164
    (DefaultGraphToEpsTraits<G>(g,*os,true));
1160
  return GraphToEps<DefaultGraphToEpsTraits<GR> >
1161
    (DefaultGraphToEpsTraits<GR>(g,*os,true));
1165 1162
}
1166 1163

	
1167 1164
///Generates an EPS file from a graph
1168 1165

	
1169 1166
///\ingroup eps_io
1170 1167
///This function does the same as
1171
///\ref graphToEps(G &g,std::ostream& os)
1168
///\ref graphToEps(GR &g,std::ostream& os)
1172 1169
///but it writes its output into the file \c file_name
1173 1170
///instead of a stream.
1174
///\sa graphToEps(G &g, std::ostream& os)
1175
template<class G>
1176
GraphToEps<DefaultGraphToEpsTraits<G> >
1177
graphToEps(G &g,const std::string& file_name)
1171
///\sa graphToEps(GR &g, std::ostream& os)
1172
template<class GR>
1173
GraphToEps<DefaultGraphToEpsTraits<GR> >
1174
graphToEps(GR &g,const std::string& file_name)
1178 1175
{
1179 1176
  std::ostream* os = new std::ofstream(file_name.c_str());
1180 1177
  if (!(*os)) {
1181 1178
    delete os;
1182 1179
    throw IoError("Cannot write file", file_name);
1183 1180
  }
1184
  return GraphToEps<DefaultGraphToEpsTraits<G> >
1185
    (DefaultGraphToEpsTraits<G>(g,*os,true));
1181
  return GraphToEps<DefaultGraphToEpsTraits<GR> >
1182
    (DefaultGraphToEpsTraits<GR>(g,*os,true));
1186 1183
}
1187 1184

	
1188 1185
} //END OF NAMESPACE LEMON
1189 1186

	
1190 1187
#endif // LEMON_GRAPH_TO_EPS_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_KRUSKAL_H
20 20
#define LEMON_KRUSKAL_H
21 21

	
22 22
#include <algorithm>
23 23
#include <vector>
24 24
#include <lemon/unionfind.h>
25 25
#include <lemon/maps.h>
26 26

	
27 27
#include <lemon/core.h>
28 28
#include <lemon/bits/traits.h>
29 29

	
30 30
///\ingroup spantree
31 31
///\file
32 32
///\brief Kruskal's algorithm to compute a minimum cost spanning tree
33 33
///
34 34
///Kruskal's algorithm to compute a minimum cost spanning tree.
35 35
///
36 36

	
37 37
namespace lemon {
38 38

	
39 39
  namespace _kruskal_bits {
40 40

	
41 41
    // Kruskal for directed graphs.
42 42

	
43 43
    template <typename Digraph, typename In, typename Out>
44 44
    typename disable_if<lemon::UndirectedTagIndicator<Digraph>,
45 45
                       typename In::value_type::second_type >::type
46 46
    kruskal(const Digraph& digraph, const In& in, Out& out,dummy<0> = 0) {
47 47
      typedef typename In::value_type::second_type Value;
48 48
      typedef typename Digraph::template NodeMap<int> IndexMap;
49 49
      typedef typename Digraph::Node Node;
50 50

	
51 51
      IndexMap index(digraph);
52 52
      UnionFind<IndexMap> uf(index);
53 53
      for (typename Digraph::NodeIt it(digraph); it != INVALID; ++it) {
54 54
        uf.insert(it);
55 55
      }
56 56

	
57 57
      Value tree_value = 0;
58 58
      for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) {
59 59
        if (uf.join(digraph.target(it->first),digraph.source(it->first))) {
60 60
          out.set(it->first, true);
61 61
          tree_value += it->second;
62 62
        }
63 63
        else {
64 64
          out.set(it->first, false);
65 65
        }
66 66
      }
67 67
      return tree_value;
68 68
    }
69 69

	
70 70
    // Kruskal for undirected graphs.
71 71

	
72 72
    template <typename Graph, typename In, typename Out>
73 73
    typename enable_if<lemon::UndirectedTagIndicator<Graph>,
74 74
                       typename In::value_type::second_type >::type
75 75
    kruskal(const Graph& graph, const In& in, Out& out,dummy<1> = 1) {
76 76
      typedef typename In::value_type::second_type Value;
77 77
      typedef typename Graph::template NodeMap<int> IndexMap;
78 78
      typedef typename Graph::Node Node;
79 79

	
80 80
      IndexMap index(graph);
81 81
      UnionFind<IndexMap> uf(index);
82 82
      for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
83 83
        uf.insert(it);
84 84
      }
85 85

	
86 86
      Value tree_value = 0;
87 87
      for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) {
88 88
        if (uf.join(graph.u(it->first),graph.v(it->first))) {
89 89
          out.set(it->first, true);
90 90
          tree_value += it->second;
91 91
        }
92 92
        else {
93 93
          out.set(it->first, false);
94 94
        }
95 95
      }
96 96
      return tree_value;
97 97
    }
98 98

	
99 99

	
100 100
    template <typename Sequence>
101 101
    struct PairComp {
102 102
      typedef typename Sequence::value_type Value;
103 103
      bool operator()(const Value& left, const Value& right) {
104 104
        return left.second < right.second;
105 105
      }
106 106
    };
107 107

	
108 108
    template <typename In, typename Enable = void>
109 109
    struct SequenceInputIndicator {
110 110
      static const bool value = false;
111 111
    };
112 112

	
113 113
    template <typename In>
114 114
    struct SequenceInputIndicator<In,
115 115
      typename exists<typename In::value_type::first_type>::type> {
116 116
      static const bool value = true;
117 117
    };
118 118

	
119 119
    template <typename In, typename Enable = void>
120 120
    struct MapInputIndicator {
121 121
      static const bool value = false;
122 122
    };
123 123

	
124 124
    template <typename In>
125 125
    struct MapInputIndicator<In,
126 126
      typename exists<typename In::Value>::type> {
127 127
      static const bool value = true;
128 128
    };
129 129

	
130 130
    template <typename In, typename Enable = void>
131 131
    struct SequenceOutputIndicator {
132 132
      static const bool value = false;
133 133
    };
134 134

	
135 135
    template <typename Out>
136 136
    struct SequenceOutputIndicator<Out,
137 137
      typename exists<typename Out::value_type>::type> {
138 138
      static const bool value = true;
139 139
    };
140 140

	
141 141
    template <typename Out, typename Enable = void>
142 142
    struct MapOutputIndicator {
143 143
      static const bool value = false;
144 144
    };
145 145

	
146 146
    template <typename Out>
147 147
    struct MapOutputIndicator<Out,
148 148
      typename exists<typename Out::Value>::type> {
149 149
      static const bool value = true;
150 150
    };
151 151

	
152 152
    template <typename In, typename InEnable = void>
153 153
    struct KruskalValueSelector {};
154 154

	
155 155
    template <typename In>
156 156
    struct KruskalValueSelector<In,
157 157
      typename enable_if<SequenceInputIndicator<In>, void>::type>
158 158
    {
159 159
      typedef typename In::value_type::second_type Value;
160 160
    };
161 161

	
162 162
    template <typename In>
163 163
    struct KruskalValueSelector<In,
164 164
      typename enable_if<MapInputIndicator<In>, void>::type>
165 165
    {
166 166
      typedef typename In::Value Value;
167 167
    };
168 168

	
169 169
    template <typename Graph, typename In, typename Out,
170 170
              typename InEnable = void>
171 171
    struct KruskalInputSelector {};
172 172

	
173 173
    template <typename Graph, typename In, typename Out,
174 174
              typename InEnable = void>
175 175
    struct KruskalOutputSelector {};
176 176

	
177 177
    template <typename Graph, typename In, typename Out>
178 178
    struct KruskalInputSelector<Graph, In, Out,
179 179
      typename enable_if<SequenceInputIndicator<In>, void>::type >
180 180
    {
181 181
      typedef typename In::value_type::second_type Value;
182 182

	
183 183
      static Value kruskal(const Graph& graph, const In& in, Out& out) {
184 184
        return KruskalOutputSelector<Graph, In, Out>::
185 185
          kruskal(graph, in, out);
186 186
      }
187 187

	
188 188
    };
189 189

	
190 190
    template <typename Graph, typename In, typename Out>
191 191
    struct KruskalInputSelector<Graph, In, Out,
192 192
      typename enable_if<MapInputIndicator<In>, void>::type >
193 193
    {
194 194
      typedef typename In::Value Value;
195 195
      static Value kruskal(const Graph& graph, const In& in, Out& out) {
196 196
        typedef typename In::Key MapArc;
197 197
        typedef typename In::Value Value;
198 198
        typedef typename ItemSetTraits<Graph, MapArc>::ItemIt MapArcIt;
199 199
        typedef std::vector<std::pair<MapArc, Value> > Sequence;
200 200
        Sequence seq;
201 201

	
202 202
        for (MapArcIt it(graph); it != INVALID; ++it) {
203 203
          seq.push_back(std::make_pair(it, in[it]));
204 204
        }
205 205

	
206 206
        std::sort(seq.begin(), seq.end(), PairComp<Sequence>());
207 207
        return KruskalOutputSelector<Graph, Sequence, Out>::
208 208
          kruskal(graph, seq, out);
209 209
      }
210 210
    };
211 211

	
212 212
    template <typename T>
213 213
    struct RemoveConst {
214 214
      typedef T type;
215 215
    };
216 216

	
217 217
    template <typename T>
218 218
    struct RemoveConst<const T> {
219 219
      typedef T type;
220 220
    };
221 221

	
222 222
    template <typename Graph, typename In, typename Out>
223 223
    struct KruskalOutputSelector<Graph, In, Out,
224 224
      typename enable_if<SequenceOutputIndicator<Out>, void>::type >
225 225
    {
226 226
      typedef typename In::value_type::second_type Value;
227 227

	
228 228
      static Value kruskal(const Graph& graph, const In& in, Out& out) {
229 229
        typedef LoggerBoolMap<typename RemoveConst<Out>::type> Map;
230 230
        Map map(out);
231 231
        return _kruskal_bits::kruskal(graph, in, map);
232 232
      }
233 233

	
234 234
    };
235 235

	
236 236
    template <typename Graph, typename In, typename Out>
237 237
    struct KruskalOutputSelector<Graph, In, Out,
238 238
      typename enable_if<MapOutputIndicator<Out>, void>::type >
239 239
    {
240 240
      typedef typename In::value_type::second_type Value;
241 241

	
242 242
      static Value kruskal(const Graph& graph, const In& in, Out& out) {
243 243
        return _kruskal_bits::kruskal(graph, in, out);
244 244
      }
245 245
    };
246 246

	
247 247
  }
248 248

	
249 249
  /// \ingroup spantree
250 250
  ///
251
  /// \brief Kruskal algorithm to find a minimum cost spanning tree of
251
  /// \brief Kruskal's algorithm for finding a minimum cost spanning tree of
252 252
  /// a graph.
253 253
  ///
254 254
  /// This function runs Kruskal's algorithm to find a minimum cost
255
  /// spanning tree.
255
  /// spanning tree of a graph.
256 256
  /// Due to some C++ hacking, it accepts various input and output types.
257 257
  ///
258 258
  /// \param g The graph the algorithm runs on.
259 259
  /// It can be either \ref concepts::Digraph "directed" or
260 260
  /// \ref concepts::Graph "undirected".
261 261
  /// If the graph is directed, the algorithm consider it to be
262 262
  /// undirected by disregarding the direction of the arcs.
263 263
  ///
264 264
  /// \param in This object is used to describe the arc/edge costs.
265 265
  /// It can be one of the following choices.
266 266
  /// - An STL compatible 'Forward Container' with
267
  /// <tt>std::pair<GR::Arc,X></tt> or
268
  /// <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, where
269
  /// \c X is the type of the costs. The pairs indicates the arcs/edges
267
  /// <tt>std::pair<GR::Arc,C></tt> or
268
  /// <tt>std::pair<GR::Edge,C></tt> as its <tt>value_type</tt>, where
269
  /// \c C is the type of the costs. The pairs indicates the arcs/edges
270 270
  /// along with the assigned cost. <em>They must be in a
271 271
  /// cost-ascending order.</em>
272 272
  /// - Any readable arc/edge map. The values of the map indicate the
273 273
  /// arc/edge costs.
274 274
  ///
275 275
  /// \retval out Here we also have a choice.
276
  /// - It can be a writable \c bool arc/edge map. After running the
277
  /// algorithm it will contain the found minimum cost spanning
276
  /// - It can be a writable arc/edge map with \c bool value type. After
277
  /// running the algorithm it will contain the found minimum cost spanning
278 278
  /// tree: the value of an arc/edge will be set to \c true if it belongs
279 279
  /// to the tree, otherwise it will be set to \c false. The value of
280 280
  /// each arc/edge will be set exactly once.
281 281
  /// - It can also be an iteraror of an STL Container with
282 282
  /// <tt>GR::Arc</tt> or <tt>GR::Edge</tt> as its
283 283
  /// <tt>value_type</tt>.  The algorithm copies the elements of the
284 284
  /// found tree into this sequence.  For example, if we know that the
285 285
  /// spanning tree of the graph \c g has say 53 arcs, then we can
286 286
  /// put its arcs into an STL vector \c tree with a code like this.
287 287
  ///\code
288 288
  /// std::vector<Arc> tree(53);
289 289
  /// kruskal(g,cost,tree.begin());
290 290
  ///\endcode
291 291
  /// Or if we don't know in advance the size of the tree, we can
292 292
  /// write this.
293 293
  ///\code
294 294
  /// std::vector<Arc> tree;
295 295
  /// kruskal(g,cost,std::back_inserter(tree));
296 296
  ///\endcode
297 297
  ///
298 298
  /// \return The total cost of the found spanning tree.
299 299
  ///
300 300
  /// \note If the input graph is not (weakly) connected, a spanning
301 301
  /// forest is calculated instead of a spanning tree.
302 302

	
303 303
#ifdef DOXYGEN
304
  template <class Graph, class In, class Out>
305
  Value kruskal(GR const& g, const In& in, Out& out)
304
  template <typename Graph, typename In, typename Out>
305
  Value kruskal(const Graph& g, const In& in, Out& out)
306 306
#else
307 307
  template <class Graph, class In, class Out>
308 308
  inline typename _kruskal_bits::KruskalValueSelector<In>::Value
309 309
  kruskal(const Graph& graph, const In& in, Out& out)
310 310
#endif
311 311
  {
312 312
    return _kruskal_bits::KruskalInputSelector<Graph, In, Out>::
313 313
      kruskal(graph, in, out);
314 314
  }
315 315

	
316 316

	
317

	
318

	
319 317
  template <class Graph, class In, class Out>
320 318
  inline typename _kruskal_bits::KruskalValueSelector<In>::Value
321 319
  kruskal(const Graph& graph, const In& in, const Out& out)
322 320
  {
323 321
    return _kruskal_bits::KruskalInputSelector<Graph, In, const Out>::
324 322
      kruskal(graph, in, out);
325 323
  }
326 324

	
327 325
} //namespace lemon
328 326

	
329 327
#endif //LEMON_KRUSKAL_H
Ignore white space 6 line context
1 1
prefix=@prefix@
2 2
exec_prefix=@exec_prefix@
3 3
libdir=@libdir@
4 4
includedir=@includedir@
5 5

	
6 6
Name: @PACKAGE_NAME@
7
Description: Library of Efficient Models and Optimization in Networks
7
Description: Library for Efficient Modeling and Optimization in Networks
8 8
Version: @PACKAGE_VERSION@
9
Libs: -L${libdir} -lemon
9
Libs: -L${libdir} -lemon @GLPK_LIBS@ @CPLEX_LIBS@ @SOPLEX_LIBS@ @CLP_LIBS@ @CBC_LIBS@
10 10
Cflags: -I${includedir}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
///\ingroup lemon_io
20 20
///\file
21 21
///\brief \ref lgf-format "LEMON Graph Format" reader.
22 22

	
23 23

	
24 24
#ifndef LEMON_LGF_READER_H
25 25
#define LEMON_LGF_READER_H
26 26

	
27 27
#include <iostream>
28 28
#include <fstream>
29 29
#include <sstream>
30 30

	
31 31
#include <set>
32 32
#include <map>
33 33

	
34 34
#include <lemon/core.h>
35 35

	
36 36
#include <lemon/lgf_writer.h>
37 37

	
38 38
#include <lemon/concept_check.h>
39 39
#include <lemon/concepts/maps.h>
40 40

	
41 41
namespace lemon {
42 42

	
43 43
  namespace _reader_bits {
44 44

	
45 45
    template <typename Value>
46 46
    struct DefaultConverter {
47 47
      Value operator()(const std::string& str) {
48 48
        std::istringstream is(str);
49 49
        Value value;
50 50
        if (!(is >> value)) {
51 51
          throw FormatError("Cannot read token");
52 52
        }
53 53

	
54 54
        char c;
55 55
        if (is >> std::ws >> c) {
56 56
          throw FormatError("Remaining characters in token");
57 57
        }
58 58
        return value;
59 59
      }
60 60
    };
61 61

	
62 62
    template <>
63 63
    struct DefaultConverter<std::string> {
64 64
      std::string operator()(const std::string& str) {
65 65
        return str;
66 66
      }
67 67
    };
68 68

	
69 69
    template <typename _Item>
70 70
    class MapStorageBase {
71 71
    public:
72 72
      typedef _Item Item;
73 73

	
74 74
    public:
75 75
      MapStorageBase() {}
76 76
      virtual ~MapStorageBase() {}
77 77

	
78 78
      virtual void set(const Item& item, const std::string& value) = 0;
79 79

	
80 80
    };
81 81

	
82 82
    template <typename _Item, typename _Map,
83 83
              typename _Converter = DefaultConverter<typename _Map::Value> >
84 84
    class MapStorage : public MapStorageBase<_Item> {
85 85
    public:
86 86
      typedef _Map Map;
87 87
      typedef _Converter Converter;
88 88
      typedef _Item Item;
89 89

	
90 90
    private:
91 91
      Map& _map;
92 92
      Converter _converter;
93 93

	
94 94
    public:
95 95
      MapStorage(Map& map, const Converter& converter = Converter())
96 96
        : _map(map), _converter(converter) {}
97 97
      virtual ~MapStorage() {}
98 98

	
99 99
      virtual void set(const Item& item ,const std::string& value) {
100 100
        _map.set(item, _converter(value));
101 101
      }
102 102
    };
103 103

	
104
    template <typename _Graph, bool _dir, typename _Map,
104
    template <typename _GR, bool _dir, typename _Map,
105 105
              typename _Converter = DefaultConverter<typename _Map::Value> >
106
    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
106
    class GraphArcMapStorage : public MapStorageBase<typename _GR::Edge> {
107 107
    public:
108 108
      typedef _Map Map;
109 109
      typedef _Converter Converter;
110
      typedef _Graph Graph;
111
      typedef typename Graph::Edge Item;
110
      typedef _GR GR;
111
      typedef typename GR::Edge Item;
112 112
      static const bool dir = _dir;
113 113

	
114 114
    private:
115
      const Graph& _graph;
115
      const GR& _graph;
116 116
      Map& _map;
117 117
      Converter _converter;
118 118

	
119 119
    public:
120
      GraphArcMapStorage(const Graph& graph, Map& map,
120
      GraphArcMapStorage(const GR& graph, Map& map,
121 121
                         const Converter& converter = Converter())
122 122
        : _graph(graph), _map(map), _converter(converter) {}
123 123
      virtual ~GraphArcMapStorage() {}
124 124

	
125 125
      virtual void set(const Item& item ,const std::string& value) {
126 126
        _map.set(_graph.direct(item, dir), _converter(value));
127 127
      }
128 128
    };
129 129

	
130 130
    class ValueStorageBase {
131 131
    public:
132 132
      ValueStorageBase() {}
133 133
      virtual ~ValueStorageBase() {}
134 134

	
135 135
      virtual void set(const std::string&) = 0;
136 136
    };
137 137

	
138 138
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
139 139
    class ValueStorage : public ValueStorageBase {
140 140
    public:
141 141
      typedef _Value Value;
142 142
      typedef _Converter Converter;
143 143

	
144 144
    private:
145 145
      Value& _value;
146 146
      Converter _converter;
147 147

	
148 148
    public:
149 149
      ValueStorage(Value& value, const Converter& converter = Converter())
150 150
        : _value(value), _converter(converter) {}
151 151

	
152 152
      virtual void set(const std::string& value) {
153 153
        _value = _converter(value);
154 154
      }
155 155
    };
156 156

	
157 157
    template <typename Value>
158 158
    struct MapLookUpConverter {
159 159
      const std::map<std::string, Value>& _map;
160 160

	
161 161
      MapLookUpConverter(const std::map<std::string, Value>& map)
162 162
        : _map(map) {}
163 163

	
164 164
      Value operator()(const std::string& str) {
165 165
        typename std::map<std::string, Value>::const_iterator it =
166 166
          _map.find(str);
167 167
        if (it == _map.end()) {
168 168
          std::ostringstream msg;
169 169
          msg << "Item not found: " << str;
170 170
          throw FormatError(msg.str());
171 171
        }
172 172
        return it->second;
173 173
      }
174 174
    };
175 175

	
176
    template <typename Graph>
176
    template <typename GR>
177 177
    struct GraphArcLookUpConverter {
178
      const Graph& _graph;
179
      const std::map<std::string, typename Graph::Edge>& _map;
180

	
181
      GraphArcLookUpConverter(const Graph& graph,
178
      const GR& _graph;
179
      const std::map<std::string, typename GR::Edge>& _map;
180

	
181
      GraphArcLookUpConverter(const GR& graph,
182 182
                              const std::map<std::string,
183
                                             typename Graph::Edge>& map)
183
                                             typename GR::Edge>& map)
184 184
        : _graph(graph), _map(map) {}
185 185

	
186
      typename Graph::Arc operator()(const std::string& str) {
186
      typename GR::Arc operator()(const std::string& str) {
187 187
        if (str.empty() || (str[0] != '+' && str[0] != '-')) {
188 188
          throw FormatError("Item must start with '+' or '-'");
189 189
        }
190
        typename std::map<std::string, typename Graph::Edge>
190
        typename std::map<std::string, typename GR::Edge>
191 191
          ::const_iterator it = _map.find(str.substr(1));
192 192
        if (it == _map.end()) {
193 193
          throw FormatError("Item not found");
194 194
        }
195 195
        return _graph.direct(it->second, str[0] == '+');
196 196
      }
197 197
    };
198 198

	
199 199
    inline bool isWhiteSpace(char c) {
200 200
      return c == ' ' || c == '\t' || c == '\v' ||
201 201
        c == '\n' || c == '\r' || c == '\f';
202 202
    }
203 203

	
204 204
    inline bool isOct(char c) {
205 205
      return '0' <= c && c <='7';
206 206
    }
207 207

	
208 208
    inline int valueOct(char c) {
209 209
      LEMON_ASSERT(isOct(c), "The character is not octal.");
210 210
      return c - '0';
211 211
    }
212 212

	
213 213
    inline bool isHex(char c) {
214 214
      return ('0' <= c && c <= '9') ||
215 215
        ('a' <= c && c <= 'z') ||
216 216
        ('A' <= c && c <= 'Z');
217 217
    }
218 218

	
219 219
    inline int valueHex(char c) {
220 220
      LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
221 221
      if ('0' <= c && c <= '9') return c - '0';
222 222
      if ('a' <= c && c <= 'z') return c - 'a' + 10;
223 223
      return c - 'A' + 10;
224 224
    }
225 225

	
226 226
    inline bool isIdentifierFirstChar(char c) {
227 227
      return ('a' <= c && c <= 'z') ||
228 228
        ('A' <= c && c <= 'Z') || c == '_';
229 229
    }
230 230

	
231 231
    inline bool isIdentifierChar(char c) {
232 232
      return isIdentifierFirstChar(c) ||
233 233
        ('0' <= c && c <= '9');
234 234
    }
235 235

	
236 236
    inline char readEscape(std::istream& is) {
237 237
      char c;
238 238
      if (!is.get(c))
239 239
        throw FormatError("Escape format error");
240 240

	
241 241
      switch (c) {
242 242
      case '\\':
243 243
        return '\\';
244 244
      case '\"':
245 245
        return '\"';
246 246
      case '\'':
247 247
        return '\'';
248 248
      case '\?':
249 249
        return '\?';
250 250
      case 'a':
251 251
        return '\a';
252 252
      case 'b':
253 253
        return '\b';
254 254
      case 'f':
255 255
        return '\f';
256 256
      case 'n':
257 257
        return '\n';
258 258
      case 'r':
259 259
        return '\r';
260 260
      case 't':
261 261
        return '\t';
262 262
      case 'v':
263 263
        return '\v';
264 264
      case 'x':
265 265
        {
266 266
          int code;
267 267
          if (!is.get(c) || !isHex(c))
268 268
            throw FormatError("Escape format error");
269 269
          else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
270 270
          else code = code * 16 + valueHex(c);
271 271
          return code;
272 272
        }
273 273
      default:
274 274
        {
275 275
          int code;
276 276
          if (!isOct(c))
277 277
            throw FormatError("Escape format error");
278 278
          else if (code = valueOct(c), !is.get(c) || !isOct(c))
279 279
            is.putback(c);
280 280
          else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
281 281
            is.putback(c);
282 282
          else code = code * 8 + valueOct(c);
283 283
          return code;
284 284
        }
285 285
      }
286 286
    }
287 287

	
288 288
    inline std::istream& readToken(std::istream& is, std::string& str) {
289 289
      std::ostringstream os;
290 290

	
291 291
      char c;
292 292
      is >> std::ws;
293 293

	
294 294
      if (!is.get(c))
295 295
        return is;
296 296

	
297 297
      if (c == '\"') {
298 298
        while (is.get(c) && c != '\"') {
299 299
          if (c == '\\')
300 300
            c = readEscape(is);
301 301
          os << c;
302 302
        }
303 303
        if (!is)
304 304
          throw FormatError("Quoted format error");
305 305
      } else {
306 306
        is.putback(c);
307 307
        while (is.get(c) && !isWhiteSpace(c)) {
308 308
          if (c == '\\')
309 309
            c = readEscape(is);
310 310
          os << c;
311 311
        }
312 312
        if (!is) {
313 313
          is.clear();
314 314
        } else {
315 315
          is.putback(c);
316 316
        }
317 317
      }
318 318
      str = os.str();
319 319
      return is;
320 320
    }
321 321

	
322 322
    class Section {
323 323
    public:
324 324
      virtual ~Section() {}
325 325
      virtual void process(std::istream& is, int& line_num) = 0;
326 326
    };
327 327

	
328 328
    template <typename Functor>
329 329
    class LineSection : public Section {
330 330
    private:
331 331

	
332 332
      Functor _functor;
333 333

	
334 334
    public:
335 335

	
336 336
      LineSection(const Functor& functor) : _functor(functor) {}
337 337
      virtual ~LineSection() {}
338 338

	
339 339
      virtual void process(std::istream& is, int& line_num) {
340 340
        char c;
341 341
        std::string line;
342 342
        while (is.get(c) && c != '@') {
343 343
          if (c == '\n') {
344 344
            ++line_num;
345 345
          } else if (c == '#') {
346 346
            getline(is, line);
347 347
            ++line_num;
348 348
          } else if (!isWhiteSpace(c)) {
349 349
            is.putback(c);
350 350
            getline(is, line);
351 351
            _functor(line);
352 352
            ++line_num;
353 353
          }
354 354
        }
355 355
        if (is) is.putback(c);
356 356
        else if (is.eof()) is.clear();
357 357
      }
358 358
    };
359 359

	
360 360
    template <typename Functor>
361 361
    class StreamSection : public Section {
362 362
    private:
363 363

	
364 364
      Functor _functor;
365 365

	
366 366
    public:
367 367

	
368 368
      StreamSection(const Functor& functor) : _functor(functor) {}
369 369
      virtual ~StreamSection() {}
370 370

	
371 371
      virtual void process(std::istream& is, int& line_num) {
372 372
        _functor(is, line_num);
373 373
        char c;
374 374
        std::string line;
375 375
        while (is.get(c) && c != '@') {
376 376
          if (c == '\n') {
377 377
            ++line_num;
378 378
          } else if (!isWhiteSpace(c)) {
379 379
            getline(is, line);
380 380
            ++line_num;
381 381
          }
382 382
        }
383 383
        if (is) is.putback(c);
384 384
        else if (is.eof()) is.clear();
385 385
      }
386 386
    };
387 387

	
388 388
  }
389 389

	
390
  template <typename Digraph>
390
  template <typename DGR>
391 391
  class DigraphReader;
392 392

	
393
  template <typename Digraph>
394
  DigraphReader<Digraph> digraphReader(Digraph& digraph, 
395
                                       std::istream& is = std::cin);
396
  template <typename Digraph>
397
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const std::string& fn);
398
  template <typename Digraph>
399
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char *fn);
393
  template <typename TDGR>
394
  DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is = std::cin);
395
  template <typename TDGR>
396
  DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn);
397
  template <typename TDGR>
398
  DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
400 399

	
401 400
  /// \ingroup lemon_io
402 401
  ///
403 402
  /// \brief \ref lgf-format "LGF" reader for directed graphs
404 403
  ///
405 404
  /// This utility reads an \ref lgf-format "LGF" file.
406 405
  ///
407 406
  /// The reading method does a batch processing. The user creates a
408 407
  /// reader object, then various reading rules can be added to the
409 408
  /// reader, and eventually the reading is executed with the \c run()
410 409
  /// member function. A map reading rule can be added to the reader
411 410
  /// with the \c nodeMap() or \c arcMap() members. An optional
412 411
  /// converter parameter can also be added as a standard functor
413 412
  /// converting from \c std::string to the value type of the map. If it
414 413
  /// is set, it will determine how the tokens in the file should be
415 414
  /// converted to the value type of the map. If the functor is not set,
416 415
  /// then a default conversion will be used. One map can be read into
417 416
  /// multiple map objects at the same time. The \c attribute(), \c
418 417
  /// node() and \c arc() functions are used to add attribute reading
419 418
  /// rules.
420 419
  ///
421 420
  ///\code
422
  /// DigraphReader<Digraph>(digraph, std::cin).
421
  /// DigraphReader<DGR>(digraph, std::cin).
423 422
  ///   nodeMap("coordinates", coord_map).
424 423
  ///   arcMap("capacity", cap_map).
425 424
  ///   node("source", src).
426 425
  ///   node("target", trg).
427 426
  ///   attribute("caption", caption).
428 427
  ///   run();
429 428
  ///\endcode
430 429
  ///
431 430
  /// By default the reader uses the first section in the file of the
432 431
  /// proper type. If a section has an optional name, then it can be
433 432
  /// selected for reading by giving an optional name parameter to the
434 433
  /// \c nodes(), \c arcs() or \c attributes() functions.
435 434
  ///
436 435
  /// The \c useNodes() and \c useArcs() functions are used to tell the reader
437 436
  /// that the nodes or arcs should not be constructed (added to the
438 437
  /// graph) during the reading, but instead the label map of the items
439 438
  /// are given as a parameter of these functions. An
440 439
  /// application of these functions is multipass reading, which is
441 440
  /// important if two \c \@arcs sections must be read from the
442 441
  /// file. In this case the first phase would read the node set and one
443 442
  /// of the arc sets, while the second phase would read the second arc
444 443
  /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
445 444
  /// The previously read label node map should be passed to the \c
446 445
  /// useNodes() functions. Another application of multipass reading when
447 446
  /// paths are given as a node map or an arc map.
448 447
  /// It is impossible to read this in
449 448
  /// a single pass, because the arcs are not constructed when the node
450 449
  /// maps are read.
451
  template <typename _Digraph>
450
  template <typename DGR>
452 451
  class DigraphReader {
453 452
  public:
454 453

	
455
    typedef _Digraph Digraph;
456
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
454
    typedef DGR Digraph;
457 455

	
458 456
  private:
459 457

	
458
    TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
460 459

	
461 460
    std::istream* _is;
462 461
    bool local_is;
463 462
    std::string _filename;
464 463

	
465
    Digraph& _digraph;
464
    DGR& _digraph;
466 465

	
467 466
    std::string _nodes_caption;
468 467
    std::string _arcs_caption;
469 468
    std::string _attributes_caption;
470 469

	
471 470
    typedef std::map<std::string, Node> NodeIndex;
472 471
    NodeIndex _node_index;
473 472
    typedef std::map<std::string, Arc> ArcIndex;
474 473
    ArcIndex _arc_index;
475 474

	
476 475
    typedef std::vector<std::pair<std::string,
477 476
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
478 477
    NodeMaps _node_maps;
479 478

	
480 479
    typedef std::vector<std::pair<std::string,
481 480
      _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
482 481
    ArcMaps _arc_maps;
483 482

	
484 483
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
485 484
      Attributes;
486 485
    Attributes _attributes;
487 486

	
488 487
    bool _use_nodes;
489 488
    bool _use_arcs;
490 489

	
491 490
    bool _skip_nodes;
492 491
    bool _skip_arcs;
493 492

	
494 493
    int line_num;
495 494
    std::istringstream line;
496 495

	
497 496
  public:
498 497

	
499 498
    /// \brief Constructor
500 499
    ///
501 500
    /// Construct a directed graph reader, which reads from the given
502 501
    /// input stream.
503
    DigraphReader(Digraph& digraph, std::istream& is = std::cin)
502
    DigraphReader(DGR& digraph, std::istream& is = std::cin)
504 503
      : _is(&is), local_is(false), _digraph(digraph),
505 504
        _use_nodes(false), _use_arcs(false),
506 505
        _skip_nodes(false), _skip_arcs(false) {}
507 506

	
508 507
    /// \brief Constructor
509 508
    ///
510 509
    /// Construct a directed graph reader, which reads from the given
511 510
    /// file.
512
    DigraphReader(Digraph& digraph, const std::string& fn)
511
    DigraphReader(DGR& digraph, const std::string& fn)
513 512
      : _is(new std::ifstream(fn.c_str())), local_is(true),
514 513
        _filename(fn), _digraph(digraph),
515 514
        _use_nodes(false), _use_arcs(false),
516 515
        _skip_nodes(false), _skip_arcs(false) {
517 516
      if (!(*_is)) {
518 517
        delete _is;
519 518
        throw IoError("Cannot open file", fn);
520 519
      }
521 520
    }
522 521

	
523 522
    /// \brief Constructor
524 523
    ///
525 524
    /// Construct a directed graph reader, which reads from the given
526 525
    /// file.
527
    DigraphReader(Digraph& digraph, const char* fn)
526
    DigraphReader(DGR& digraph, const char* fn)
528 527
      : _is(new std::ifstream(fn)), local_is(true),
529 528
        _filename(fn), _digraph(digraph),
530 529
        _use_nodes(false), _use_arcs(false),
531 530
        _skip_nodes(false), _skip_arcs(false) {
532 531
      if (!(*_is)) {
533 532
        delete _is;
534 533
        throw IoError("Cannot open file", fn);
535 534
      }
536 535
    }
537 536

	
538 537
    /// \brief Destructor
539 538
    ~DigraphReader() {
540 539
      for (typename NodeMaps::iterator it = _node_maps.begin();
541 540
           it != _node_maps.end(); ++it) {
542 541
        delete it->second;
543 542
      }
544 543

	
545 544
      for (typename ArcMaps::iterator it = _arc_maps.begin();
546 545
           it != _arc_maps.end(); ++it) {
547 546
        delete it->second;
548 547
      }
549 548

	
550 549
      for (typename Attributes::iterator it = _attributes.begin();
551 550
           it != _attributes.end(); ++it) {
552 551
        delete it->second;
553 552
      }
554 553

	
555 554
      if (local_is) {
556 555
        delete _is;
557 556
      }
558 557

	
559 558
    }
560 559

	
561 560
  private:
562 561

	
563
    template <typename DGR>
564
    friend DigraphReader<DGR> digraphReader(DGR& digraph, std::istream& is);
565
    template <typename DGR>
566
    friend DigraphReader<DGR> digraphReader(DGR& digraph, 
567
                                            const std::string& fn);
568
    template <typename DGR>
569
    friend DigraphReader<DGR> digraphReader(DGR& digraph, const char *fn);
562
    template <typename TDGR>
563
    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is);
564
    template <typename TDGR>
565
    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, 
566
                                             const std::string& fn);
567
    template <typename TDGR>
568
    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
570 569

	
571 570
    DigraphReader(DigraphReader& other)
572 571
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
573 572
        _use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
574 573
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
575 574

	
576 575
      other._is = 0;
577 576
      other.local_is = false;
578 577

	
579 578
      _node_index.swap(other._node_index);
580 579
      _arc_index.swap(other._arc_index);
581 580

	
582 581
      _node_maps.swap(other._node_maps);
583 582
      _arc_maps.swap(other._arc_maps);
584 583
      _attributes.swap(other._attributes);
585 584

	
586 585
      _nodes_caption = other._nodes_caption;
587 586
      _arcs_caption = other._arcs_caption;
588 587
      _attributes_caption = other._attributes_caption;
589 588

	
590 589
    }
591 590

	
592 591
    DigraphReader& operator=(const DigraphReader&);
593 592

	
594 593
  public:
595 594

	
596
    /// \name Reading rules
595
    /// \name Reading Rules
597 596
    /// @{
598 597

	
599 598
    /// \brief Node map reading rule
600 599
    ///
601 600
    /// Add a node map reading rule to the reader.
602 601
    template <typename Map>
603 602
    DigraphReader& nodeMap(const std::string& caption, Map& map) {
604 603
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
605 604
      _reader_bits::MapStorageBase<Node>* storage =
606 605
        new _reader_bits::MapStorage<Node, Map>(map);
607 606
      _node_maps.push_back(std::make_pair(caption, storage));
608 607
      return *this;
609 608
    }
610 609

	
611 610
    /// \brief Node map reading rule
612 611
    ///
613 612
    /// Add a node map reading rule with specialized converter to the
614 613
    /// reader.
615 614
    template <typename Map, typename Converter>
616 615
    DigraphReader& nodeMap(const std::string& caption, Map& map,
617 616
                           const Converter& converter = Converter()) {
618 617
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
619 618
      _reader_bits::MapStorageBase<Node>* storage =
620 619
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
621 620
      _node_maps.push_back(std::make_pair(caption, storage));
622 621
      return *this;
623 622
    }
624 623

	
625 624
    /// \brief Arc map reading rule
626 625
    ///
627 626
    /// Add an arc map reading rule to the reader.
628 627
    template <typename Map>
629 628
    DigraphReader& arcMap(const std::string& caption, Map& map) {
630 629
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
631 630
      _reader_bits::MapStorageBase<Arc>* storage =
632 631
        new _reader_bits::MapStorage<Arc, Map>(map);
633 632
      _arc_maps.push_back(std::make_pair(caption, storage));
634 633
      return *this;
635 634
    }
636 635

	
637 636
    /// \brief Arc map reading rule
638 637
    ///
639 638
    /// Add an arc map reading rule with specialized converter to the
640 639
    /// reader.
641 640
    template <typename Map, typename Converter>
642 641
    DigraphReader& arcMap(const std::string& caption, Map& map,
643 642
                          const Converter& converter = Converter()) {
644 643
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
645 644
      _reader_bits::MapStorageBase<Arc>* storage =
646 645
        new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
647 646
      _arc_maps.push_back(std::make_pair(caption, storage));
648 647
      return *this;
649 648
    }
650 649

	
651 650
    /// \brief Attribute reading rule
652 651
    ///
653 652
    /// Add an attribute reading rule to the reader.
654 653
    template <typename Value>
655 654
    DigraphReader& attribute(const std::string& caption, Value& value) {
656 655
      _reader_bits::ValueStorageBase* storage =
657 656
        new _reader_bits::ValueStorage<Value>(value);
658 657
      _attributes.insert(std::make_pair(caption, storage));
659 658
      return *this;
660 659
    }
661 660

	
662 661
    /// \brief Attribute reading rule
663 662
    ///
664 663
    /// Add an attribute reading rule with specialized converter to the
665 664
    /// reader.
666 665
    template <typename Value, typename Converter>
667 666
    DigraphReader& attribute(const std::string& caption, Value& value,
668 667
                             const Converter& converter = Converter()) {
669 668
      _reader_bits::ValueStorageBase* storage =
670 669
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
671 670
      _attributes.insert(std::make_pair(caption, storage));
672 671
      return *this;
673 672
    }
674 673

	
675 674
    /// \brief Node reading rule
676 675
    ///
677 676
    /// Add a node reading rule to reader.
678 677
    DigraphReader& node(const std::string& caption, Node& node) {
679 678
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
680 679
      Converter converter(_node_index);
681 680
      _reader_bits::ValueStorageBase* storage =
682 681
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
683 682
      _attributes.insert(std::make_pair(caption, storage));
684 683
      return *this;
685 684
    }
686 685

	
687 686
    /// \brief Arc reading rule
688 687
    ///
689 688
    /// Add an arc reading rule to reader.
690 689
    DigraphReader& arc(const std::string& caption, Arc& arc) {
691 690
      typedef _reader_bits::MapLookUpConverter<Arc> Converter;
692 691
      Converter converter(_arc_index);
693 692
      _reader_bits::ValueStorageBase* storage =
694 693
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
695 694
      _attributes.insert(std::make_pair(caption, storage));
696 695
      return *this;
697 696
    }
698 697

	
699 698
    /// @}
700 699

	
701
    /// \name Select section by name
700
    /// \name Select Section by Name
702 701
    /// @{
703 702

	
704 703
    /// \brief Set \c \@nodes section to be read
705 704
    ///
706 705
    /// Set \c \@nodes section to be read
707 706
    DigraphReader& nodes(const std::string& caption) {
708 707
      _nodes_caption = caption;
709 708
      return *this;
710 709
    }
711 710

	
712 711
    /// \brief Set \c \@arcs section to be read
713 712
    ///
714 713
    /// Set \c \@arcs section to be read
715 714
    DigraphReader& arcs(const std::string& caption) {
716 715
      _arcs_caption = caption;
717 716
      return *this;
718 717
    }
719 718

	
720 719
    /// \brief Set \c \@attributes section to be read
721 720
    ///
722 721
    /// Set \c \@attributes section to be read
723 722
    DigraphReader& attributes(const std::string& caption) {
724 723
      _attributes_caption = caption;
725 724
      return *this;
726 725
    }
727 726

	
728 727
    /// @}
729 728

	
730
    /// \name Using previously constructed node or arc set
729
    /// \name Using Previously Constructed Node or Arc Set
731 730
    /// @{
732 731

	
733 732
    /// \brief Use previously constructed node set
734 733
    ///
735 734
    /// Use previously constructed node set, and specify the node
736 735
    /// label map.
737 736
    template <typename Map>
738 737
    DigraphReader& useNodes(const Map& map) {
739 738
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
740 739
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
741 740
      _use_nodes = true;
742 741
      _writer_bits::DefaultConverter<typename Map::Value> converter;
743 742
      for (NodeIt n(_digraph); n != INVALID; ++n) {
744 743
        _node_index.insert(std::make_pair(converter(map[n]), n));
745 744
      }
746 745
      return *this;
747 746
    }
748 747

	
749 748
    /// \brief Use previously constructed node set
750 749
    ///
751 750
    /// Use previously constructed node set, and specify the node
752 751
    /// label map and a functor which converts the label map values to
753 752
    /// \c std::string.
754 753
    template <typename Map, typename Converter>
755 754
    DigraphReader& useNodes(const Map& map,
756 755
                            const Converter& converter = Converter()) {
757 756
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
758 757
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
759 758
      _use_nodes = true;
760 759
      for (NodeIt n(_digraph); n != INVALID; ++n) {
761 760
        _node_index.insert(std::make_pair(converter(map[n]), n));
762 761
      }
763 762
      return *this;
764 763
    }
765 764

	
766 765
    /// \brief Use previously constructed arc set
767 766
    ///
768 767
    /// Use previously constructed arc set, and specify the arc
769 768
    /// label map.
770 769
    template <typename Map>
771 770
    DigraphReader& useArcs(const Map& map) {
772 771
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
773 772
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
774 773
      _use_arcs = true;
775 774
      _writer_bits::DefaultConverter<typename Map::Value> converter;
776 775
      for (ArcIt a(_digraph); a != INVALID; ++a) {
777 776
        _arc_index.insert(std::make_pair(converter(map[a]), a));
778 777
      }
779 778
      return *this;
780 779
    }
781 780

	
782 781
    /// \brief Use previously constructed arc set
783 782
    ///
784 783
    /// Use previously constructed arc set, and specify the arc
785 784
    /// label map and a functor which converts the label map values to
786 785
    /// \c std::string.
787 786
    template <typename Map, typename Converter>
788 787
    DigraphReader& useArcs(const Map& map,
789 788
                           const Converter& converter = Converter()) {
790 789
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
791 790
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
792 791
      _use_arcs = true;
793 792
      for (ArcIt a(_digraph); a != INVALID; ++a) {
794 793
        _arc_index.insert(std::make_pair(converter(map[a]), a));
795 794
      }
796 795
      return *this;
797 796
    }
798 797

	
799 798
    /// \brief Skips the reading of node section
800 799
    ///
801 800
    /// Omit the reading of the node section. This implies that each node
802 801
    /// map reading rule will be abandoned, and the nodes of the graph
803 802
    /// will not be constructed, which usually cause that the arc set
804 803
    /// could not be read due to lack of node name resolving.
805 804
    /// Therefore \c skipArcs() function should also be used, or
806 805
    /// \c useNodes() should be used to specify the label of the nodes.
807 806
    DigraphReader& skipNodes() {
808 807
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
809 808
      _skip_nodes = true;
810 809
      return *this;
811 810
    }
812 811

	
813 812
    /// \brief Skips the reading of arc section
814 813
    ///
815 814
    /// Omit the reading of the arc section. This implies that each arc
816 815
    /// map reading rule will be abandoned, and the arcs of the graph
817 816
    /// will not be constructed.
818 817
    DigraphReader& skipArcs() {
819 818
      LEMON_ASSERT(!_skip_arcs, "Skip arcs already set");
820 819
      _skip_arcs = true;
821 820
      return *this;
822 821
    }
823 822

	
824 823
    /// @}
825 824

	
826 825
  private:
827 826

	
828 827
    bool readLine() {
829 828
      std::string str;
830 829
      while(++line_num, std::getline(*_is, str)) {
831 830
        line.clear(); line.str(str);
832 831
        char c;
833 832
        if (line >> std::ws >> c && c != '#') {
834 833
          line.putback(c);
835 834
          return true;
836 835
        }
837 836
      }
838 837
      return false;
839 838
    }
840 839

	
841 840
    bool readSuccess() {
842 841
      return static_cast<bool>(*_is);
843 842
    }
844 843

	
845 844
    void skipSection() {
846 845
      char c;
847 846
      while (readSuccess() && line >> c && c != '@') {
848 847
        readLine();
849 848
      }
850
      line.putback(c);
849
      if (readSuccess()) {
850
        line.putback(c);
851
      }
851 852
    }
852 853

	
853 854
    void readNodes() {
854 855

	
855 856
      std::vector<int> map_index(_node_maps.size());
856 857
      int map_num, label_index;
857 858

	
858 859
      char c;
859 860
      if (!readLine() || !(line >> c) || c == '@') {
860 861
        if (readSuccess() && line) line.putback(c);
861 862
        if (!_node_maps.empty())
862 863
          throw FormatError("Cannot find map names");
863 864
        return;
864 865
      }
865 866
      line.putback(c);
866 867

	
867 868
      {
868 869
        std::map<std::string, int> maps;
869 870

	
870 871
        std::string map;
871 872
        int index = 0;
872 873
        while (_reader_bits::readToken(line, map)) {
873 874
          if (maps.find(map) != maps.end()) {
874 875
            std::ostringstream msg;
875 876
            msg << "Multiple occurence of node map: " << map;
876 877
            throw FormatError(msg.str());
877 878
          }
878 879
          maps.insert(std::make_pair(map, index));
879 880
          ++index;
880 881
        }
881 882

	
882 883
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
883 884
          std::map<std::string, int>::iterator jt =
884 885
            maps.find(_node_maps[i].first);
885 886
          if (jt == maps.end()) {
886 887
            std::ostringstream msg;
887 888
            msg << "Map not found: " << _node_maps[i].first;
888 889
            throw FormatError(msg.str());
889 890
          }
890 891
          map_index[i] = jt->second;
891 892
        }
892 893

	
893 894
        {
894 895
          std::map<std::string, int>::iterator jt = maps.find("label");
895 896
          if (jt != maps.end()) {
896 897
            label_index = jt->second;
897 898
          } else {
898 899
            label_index = -1;
899 900
          }
900 901
        }
901 902
        map_num = maps.size();
902 903
      }
903 904

	
904 905
      while (readLine() && line >> c && c != '@') {
905 906
        line.putback(c);
906 907

	
907 908
        std::vector<std::string> tokens(map_num);
908 909
        for (int i = 0; i < map_num; ++i) {
909 910
          if (!_reader_bits::readToken(line, tokens[i])) {
910 911
            std::ostringstream msg;
911 912
            msg << "Column not found (" << i + 1 << ")";
912 913
            throw FormatError(msg.str());
913 914
          }
914 915
        }
915 916
        if (line >> std::ws >> c)
916 917
          throw FormatError("Extra character at the end of line");
917 918

	
918 919
        Node n;
919 920
        if (!_use_nodes) {
920 921
          n = _digraph.addNode();
921 922
          if (label_index != -1)
922 923
            _node_index.insert(std::make_pair(tokens[label_index], n));
923 924
        } else {
924 925
          if (label_index == -1)
925 926
            throw FormatError("Label map not found");
926 927
          typename std::map<std::string, Node>::iterator it =
927 928
            _node_index.find(tokens[label_index]);
928 929
          if (it == _node_index.end()) {
929 930
            std::ostringstream msg;
930 931
            msg << "Node with label not found: " << tokens[label_index];
931 932
            throw FormatError(msg.str());
932 933
          }
933 934
          n = it->second;
934 935
        }
935 936

	
936 937
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
937 938
          _node_maps[i].second->set(n, tokens[map_index[i]]);
938 939
        }
939 940

	
940 941
      }
941 942
      if (readSuccess()) {
942 943
        line.putback(c);
943 944
      }
944 945
    }
945 946

	
946 947
    void readArcs() {
947 948

	
948 949
      std::vector<int> map_index(_arc_maps.size());
949 950
      int map_num, label_index;
950 951

	
951 952
      char c;
952 953
      if (!readLine() || !(line >> c) || c == '@') {
953 954
        if (readSuccess() && line) line.putback(c);
954 955
        if (!_arc_maps.empty())
955 956
          throw FormatError("Cannot find map names");
956 957
        return;
957 958
      }
958 959
      line.putback(c);
959 960

	
960 961
      {
961 962
        std::map<std::string, int> maps;
962 963

	
963 964
        std::string map;
964 965
        int index = 0;
965 966
        while (_reader_bits::readToken(line, map)) {
966 967
          if (maps.find(map) != maps.end()) {
967 968
            std::ostringstream msg;
968 969
            msg << "Multiple occurence of arc map: " << map;
969 970
            throw FormatError(msg.str());
970 971
          }
971 972
          maps.insert(std::make_pair(map, index));
972 973
          ++index;
973 974
        }
974 975

	
975 976
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
976 977
          std::map<std::string, int>::iterator jt =
977 978
            maps.find(_arc_maps[i].first);
978 979
          if (jt == maps.end()) {
979 980
            std::ostringstream msg;
980 981
            msg << "Map not found: " << _arc_maps[i].first;
981 982
            throw FormatError(msg.str());
982 983
          }
983 984
          map_index[i] = jt->second;
984 985
        }
985 986

	
986 987
        {
987 988
          std::map<std::string, int>::iterator jt = maps.find("label");
988 989
          if (jt != maps.end()) {
989 990
            label_index = jt->second;
990 991
          } else {
991 992
            label_index = -1;
992 993
          }
993 994
        }
994 995
        map_num = maps.size();
995 996
      }
996 997

	
997 998
      while (readLine() && line >> c && c != '@') {
998 999
        line.putback(c);
999 1000

	
1000 1001
        std::string source_token;
1001 1002
        std::string target_token;
1002 1003

	
1003 1004
        if (!_reader_bits::readToken(line, source_token))
1004 1005
          throw FormatError("Source not found");
1005 1006

	
1006 1007
        if (!_reader_bits::readToken(line, target_token))
1007 1008
          throw FormatError("Target not found");
1008 1009

	
1009 1010
        std::vector<std::string> tokens(map_num);
1010 1011
        for (int i = 0; i < map_num; ++i) {
1011 1012
          if (!_reader_bits::readToken(line, tokens[i])) {
1012 1013
            std::ostringstream msg;
1013 1014
            msg << "Column not found (" << i + 1 << ")";
1014 1015
            throw FormatError(msg.str());
1015 1016
          }
1016 1017
        }
1017 1018
        if (line >> std::ws >> c)
1018 1019
          throw FormatError("Extra character at the end of line");
1019 1020

	
1020 1021
        Arc a;
1021 1022
        if (!_use_arcs) {
1022 1023

	
1023 1024
          typename NodeIndex::iterator it;
1024 1025

	
1025 1026
          it = _node_index.find(source_token);
1026 1027
          if (it == _node_index.end()) {
1027 1028
            std::ostringstream msg;
1028 1029
            msg << "Item not found: " << source_token;
1029 1030
            throw FormatError(msg.str());
1030 1031
          }
1031 1032
          Node source = it->second;
1032 1033

	
1033 1034
          it = _node_index.find(target_token);
1034 1035
          if (it == _node_index.end()) {
1035 1036
            std::ostringstream msg;
1036 1037
            msg << "Item not found: " << target_token;
1037 1038
            throw FormatError(msg.str());
1038 1039
          }
1039 1040
          Node target = it->second;
1040 1041

	
1041 1042
          a = _digraph.addArc(source, target);
1042 1043
          if (label_index != -1)
1043 1044
            _arc_index.insert(std::make_pair(tokens[label_index], a));
1044 1045
        } else {
1045 1046
          if (label_index == -1)
1046 1047
            throw FormatError("Label map not found");
1047 1048
          typename std::map<std::string, Arc>::iterator it =
1048 1049
            _arc_index.find(tokens[label_index]);
1049 1050
          if (it == _arc_index.end()) {
1050 1051
            std::ostringstream msg;
1051 1052
            msg << "Arc with label not found: " << tokens[label_index];
1052 1053
            throw FormatError(msg.str());
1053 1054
          }
1054 1055
          a = it->second;
1055 1056
        }
1056 1057

	
1057 1058
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1058 1059
          _arc_maps[i].second->set(a, tokens[map_index[i]]);
1059 1060
        }
1060 1061

	
1061 1062
      }
1062 1063
      if (readSuccess()) {
1063 1064
        line.putback(c);
1064 1065
      }
1065 1066
    }
1066 1067

	
1067 1068
    void readAttributes() {
1068 1069

	
1069 1070
      std::set<std::string> read_attr;
1070 1071

	
1071 1072
      char c;
1072 1073
      while (readLine() && line >> c && c != '@') {
1073 1074
        line.putback(c);
1074 1075

	
1075 1076
        std::string attr, token;
1076 1077
        if (!_reader_bits::readToken(line, attr))
1077 1078
          throw FormatError("Attribute name not found");
1078 1079
        if (!_reader_bits::readToken(line, token))
1079 1080
          throw FormatError("Attribute value not found");
1080 1081
        if (line >> c)
1081 1082
          throw FormatError("Extra character at the end of line");
1082 1083

	
1083 1084
        {
1084 1085
          std::set<std::string>::iterator it = read_attr.find(attr);
1085 1086
          if (it != read_attr.end()) {
1086 1087
            std::ostringstream msg;
1087 1088
            msg << "Multiple occurence of attribute: " << attr;
1088 1089
            throw FormatError(msg.str());
1089 1090
          }
1090 1091
          read_attr.insert(attr);
1091 1092
        }
1092 1093

	
1093 1094
        {
1094 1095
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1095 1096
          while (it != _attributes.end() && it->first == attr) {
1096 1097
            it->second->set(token);
1097 1098
            ++it;
1098 1099
          }
1099 1100
        }
1100 1101

	
1101 1102
      }
1102 1103
      if (readSuccess()) {
1103 1104
        line.putback(c);
1104 1105
      }
1105 1106
      for (typename Attributes::iterator it = _attributes.begin();
1106 1107
           it != _attributes.end(); ++it) {
1107 1108
        if (read_attr.find(it->first) == read_attr.end()) {
1108 1109
          std::ostringstream msg;
1109 1110
          msg << "Attribute not found: " << it->first;
1110 1111
          throw FormatError(msg.str());
1111 1112
        }
1112 1113
      }
1113 1114
    }
1114 1115

	
1115 1116
  public:
1116 1117

	
1117
    /// \name Execution of the reader
1118
    /// \name Execution of the Reader
1118 1119
    /// @{
1119 1120

	
1120 1121
    /// \brief Start the batch processing
1121 1122
    ///
1122 1123
    /// This function starts the batch processing
1123 1124
    void run() {
1124 1125
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1125 1126

	
1126 1127
      bool nodes_done = _skip_nodes;
1127 1128
      bool arcs_done = _skip_arcs;
1128 1129
      bool attributes_done = false;
1129 1130

	
1130 1131
      line_num = 0;
1131 1132
      readLine();
1132 1133
      skipSection();
1133 1134

	
1134 1135
      while (readSuccess()) {
1135 1136
        try {
1136 1137
          char c;
1137 1138
          std::string section, caption;
1138 1139
          line >> c;
1139 1140
          _reader_bits::readToken(line, section);
1140 1141
          _reader_bits::readToken(line, caption);
1141 1142

	
1142 1143
          if (line >> c)
1143 1144
            throw FormatError("Extra character at the end of line");
1144 1145

	
1145 1146
          if (section == "nodes" && !nodes_done) {
1146 1147
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1147 1148
              readNodes();
1148 1149
              nodes_done = true;
1149 1150
            }
1150 1151
          } else if ((section == "arcs" || section == "edges") &&
1151 1152
                     !arcs_done) {
1152 1153
            if (_arcs_caption.empty() || _arcs_caption == caption) {
1153 1154
              readArcs();
1154 1155
              arcs_done = true;
1155 1156
            }
1156 1157
          } else if (section == "attributes" && !attributes_done) {
1157 1158
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1158 1159
              readAttributes();
1159 1160
              attributes_done = true;
1160 1161
            }
1161 1162
          } else {
1162 1163
            readLine();
1163 1164
            skipSection();
1164 1165
          }
1165 1166
        } catch (FormatError& error) {
1166 1167
          error.line(line_num);
1167 1168
          error.file(_filename);
1168 1169
          throw;
1169 1170
        }
1170 1171
      }
1171 1172

	
1172 1173
      if (!nodes_done) {
1173 1174
        throw FormatError("Section @nodes not found");
1174 1175
      }
1175 1176

	
1176 1177
      if (!arcs_done) {
1177 1178
        throw FormatError("Section @arcs not found");
1178 1179
      }
1179 1180

	
1180 1181
      if (!attributes_done && !_attributes.empty()) {
1181 1182
        throw FormatError("Section @attributes not found");
1182 1183
      }
1183 1184

	
1184 1185
    }
1185 1186

	
1186 1187
    /// @}
1187 1188

	
1188 1189
  };
1190
  
1191
  /// \ingroup lemon_io
1192
  ///
1193
  /// \brief Return a \ref DigraphReader class
1194
  ///
1195
  /// This function just returns a \ref DigraphReader class.
1196
  ///
1197
  /// With this function a digraph can be read from an 
1198
  /// \ref lgf-format "LGF" file or input stream with several maps and
1199
  /// attributes. For example, there is network flow problem on a
1200
  /// digraph, i.e. a digraph with a \e capacity map on the arcs and
1201
  /// \e source and \e target nodes. This digraph can be read with the
1202
  /// following code:
1203
  ///
1204
  ///\code
1205
  ///ListDigraph digraph;
1206
  ///ListDigraph::ArcMap<int> cm(digraph);
1207
  ///ListDigraph::Node src, trg;
1208
  ///digraphReader(digraph, std::cin).
1209
  ///  arcMap("capacity", cap).
1210
  ///  node("source", src).
1211
  ///  node("target", trg).
1212
  ///  run();
1213
  ///\endcode
1214
  ///
1215
  /// For a complete documentation, please see the \ref DigraphReader
1216
  /// class documentation.
1217
  /// \warning Don't forget to put the \ref DigraphReader::run() "run()"
1218
  /// to the end of the parameter list.
1219
  /// \relates DigraphReader
1220
  /// \sa digraphReader(TDGR& digraph, const std::string& fn)
1221
  /// \sa digraphReader(TDGR& digraph, const char* fn)
1222
  template <typename TDGR>
1223
  DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is) {
1224
    DigraphReader<TDGR> tmp(digraph, is);
1225
    return tmp;
1226
  }
1189 1227

	
1190 1228
  /// \brief Return a \ref DigraphReader class
1191 1229
  ///
1192 1230
  /// This function just returns a \ref DigraphReader class.
1193 1231
  /// \relates DigraphReader
1194
  template <typename Digraph>
1195
  DigraphReader<Digraph> digraphReader(Digraph& digraph, std::istream& is) {
1196
    DigraphReader<Digraph> tmp(digraph, is);
1232
  /// \sa digraphReader(TDGR& digraph, std::istream& is)
1233
  template <typename TDGR>
1234
  DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn) {
1235
    DigraphReader<TDGR> tmp(digraph, fn);
1197 1236
    return tmp;
1198 1237
  }
1199 1238

	
1200 1239
  /// \brief Return a \ref DigraphReader class
1201 1240
  ///
1202 1241
  /// This function just returns a \ref DigraphReader class.
1203 1242
  /// \relates DigraphReader
1204
  template <typename Digraph>
1205
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
1206
                                       const std::string& fn) {
1207
    DigraphReader<Digraph> tmp(digraph, fn);
1243
  /// \sa digraphReader(TDGR& digraph, std::istream& is)
1244
  template <typename TDGR>
1245
  DigraphReader<TDGR> digraphReader(TDGR& digraph, const char* fn) {
1246
    DigraphReader<TDGR> tmp(digraph, fn);
1208 1247
    return tmp;
1209 1248
  }
1210 1249

	
1211
  /// \brief Return a \ref DigraphReader class
1212
  ///
1213
  /// This function just returns a \ref DigraphReader class.
1214
  /// \relates DigraphReader
1215
  template <typename Digraph>
1216
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
1217
    DigraphReader<Digraph> tmp(digraph, fn);
1218
    return tmp;
1219
  }
1220

	
1221
  template <typename Graph>
1250
  template <typename GR>
1222 1251
  class GraphReader;
1223 1252
 
1224
  template <typename Graph>
1225
  GraphReader<Graph> graphReader(Graph& graph, 
1226
                                 std::istream& is = std::cin);
1227
  template <typename Graph>
1228
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
1229
  template <typename Graph>
1230
  GraphReader<Graph> graphReader(Graph& graph, const char *fn);
1253
  template <typename TGR>
1254
  GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin);
1255
  template <typename TGR>
1256
  GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
1257
  template <typename TGR>
1258
  GraphReader<TGR> graphReader(TGR& graph, const char *fn);
1231 1259

	
1232 1260
  /// \ingroup lemon_io
1233 1261
  ///
1234 1262
  /// \brief \ref lgf-format "LGF" reader for undirected graphs
1235 1263
  ///
1236 1264
  /// This utility reads an \ref lgf-format "LGF" file.
1237 1265
  ///
1238 1266
  /// It can be used almost the same way as \c DigraphReader.
1239 1267
  /// The only difference is that this class can handle edges and
1240 1268
  /// edge maps as well as arcs and arc maps.
1241 1269
  ///
1242 1270
  /// The columns in the \c \@edges (or \c \@arcs) section are the
1243 1271
  /// edge maps. However, if there are two maps with the same name
1244 1272
  /// prefixed with \c '+' and \c '-', then these can be read into an
1245 1273
  /// arc map.  Similarly, an attribute can be read into an arc, if
1246 1274
  /// it's value is an edge label prefixed with \c '+' or \c '-'.
1247
  template <typename _Graph>
1275
  template <typename GR>
1248 1276
  class GraphReader {
1249 1277
  public:
1250 1278

	
1251
    typedef _Graph Graph;
1252
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1279
    typedef GR Graph;
1253 1280

	
1254 1281
  private:
1255 1282

	
1283
    TEMPLATE_GRAPH_TYPEDEFS(GR);
1284

	
1256 1285
    std::istream* _is;
1257 1286
    bool local_is;
1258 1287
    std::string _filename;
1259 1288

	
1260
    Graph& _graph;
1289
    GR& _graph;
1261 1290

	
1262 1291
    std::string _nodes_caption;
1263 1292
    std::string _edges_caption;
1264 1293
    std::string _attributes_caption;
1265 1294

	
1266 1295
    typedef std::map<std::string, Node> NodeIndex;
1267 1296
    NodeIndex _node_index;
1268 1297
    typedef std::map<std::string, Edge> EdgeIndex;
1269 1298
    EdgeIndex _edge_index;
1270 1299

	
1271 1300
    typedef std::vector<std::pair<std::string,
1272 1301
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1273 1302
    NodeMaps _node_maps;
1274 1303

	
1275 1304
    typedef std::vector<std::pair<std::string,
1276 1305
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1277 1306
    EdgeMaps _edge_maps;
1278 1307

	
1279 1308
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1280 1309
      Attributes;
1281 1310
    Attributes _attributes;
1282 1311

	
1283 1312
    bool _use_nodes;
1284 1313
    bool _use_edges;
1285 1314

	
1286 1315
    bool _skip_nodes;
1287 1316
    bool _skip_edges;
1288 1317

	
1289 1318
    int line_num;
1290 1319
    std::istringstream line;
1291 1320

	
1292 1321
  public:
1293 1322

	
1294 1323
    /// \brief Constructor
1295 1324
    ///
1296 1325
    /// Construct an undirected graph reader, which reads from the given
1297 1326
    /// input stream.
1298
    GraphReader(Graph& graph, std::istream& is = std::cin)
1327
    GraphReader(GR& graph, std::istream& is = std::cin)
1299 1328
      : _is(&is), local_is(false), _graph(graph),
1300 1329
        _use_nodes(false), _use_edges(false),
1301 1330
        _skip_nodes(false), _skip_edges(false) {}
1302 1331

	
1303 1332
    /// \brief Constructor
1304 1333
    ///
1305 1334
    /// Construct an undirected graph reader, which reads from the given
1306 1335
    /// file.
1307
    GraphReader(Graph& graph, const std::string& fn)
1336
    GraphReader(GR& graph, const std::string& fn)
1308 1337
      : _is(new std::ifstream(fn.c_str())), local_is(true),
1309 1338
        _filename(fn), _graph(graph),
1310 1339
        _use_nodes(false), _use_edges(false),
1311 1340
        _skip_nodes(false), _skip_edges(false) {
1312 1341
      if (!(*_is)) {
1313 1342
        delete _is;
1314 1343
        throw IoError("Cannot open file", fn);
1315 1344
      }
1316 1345
    }
1317 1346

	
1318 1347
    /// \brief Constructor
1319 1348
    ///
1320 1349
    /// Construct an undirected graph reader, which reads from the given
1321 1350
    /// file.
1322
    GraphReader(Graph& graph, const char* fn)
1351
    GraphReader(GR& graph, const char* fn)
1323 1352
      : _is(new std::ifstream(fn)), local_is(true),
1324 1353
        _filename(fn), _graph(graph),
1325 1354
        _use_nodes(false), _use_edges(false),
1326 1355
        _skip_nodes(false), _skip_edges(false) {
1327 1356
      if (!(*_is)) {
1328 1357
        delete _is;
1329 1358
        throw IoError("Cannot open file", fn);
1330 1359
      }
1331 1360
    }
1332 1361

	
1333 1362
    /// \brief Destructor
1334 1363
    ~GraphReader() {
1335 1364
      for (typename NodeMaps::iterator it = _node_maps.begin();
1336 1365
           it != _node_maps.end(); ++it) {
1337 1366
        delete it->second;
1338 1367
      }
1339 1368

	
1340 1369
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1341 1370
           it != _edge_maps.end(); ++it) {
1342 1371
        delete it->second;
1343 1372
      }
1344 1373

	
1345 1374
      for (typename Attributes::iterator it = _attributes.begin();
1346 1375
           it != _attributes.end(); ++it) {
1347 1376
        delete it->second;
1348 1377
      }
1349 1378

	
1350 1379
      if (local_is) {
1351 1380
        delete _is;
1352 1381
      }
1353 1382

	
1354 1383
    }
1355 1384

	
1356 1385
  private:
1357
    template <typename GR>
1358
    friend GraphReader<GR> graphReader(GR& graph, std::istream& is);
1359
    template <typename GR>
1360
    friend GraphReader<GR> graphReader(GR& graph, const std::string& fn); 
1361
    template <typename GR>
1362
    friend GraphReader<GR> graphReader(GR& graph, const char *fn);
1386
    template <typename TGR>
1387
    friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is);
1388
    template <typename TGR>
1389
    friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn); 
1390
    template <typename TGR>
1391
    friend GraphReader<TGR> graphReader(TGR& graph, const char *fn);
1363 1392

	
1364 1393
    GraphReader(GraphReader& other)
1365 1394
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1366 1395
        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
1367 1396
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1368 1397

	
1369 1398
      other._is = 0;
1370 1399
      other.local_is = false;
1371 1400

	
1372 1401
      _node_index.swap(other._node_index);
1373 1402
      _edge_index.swap(other._edge_index);
1374 1403

	
1375 1404
      _node_maps.swap(other._node_maps);
1376 1405
      _edge_maps.swap(other._edge_maps);
1377 1406
      _attributes.swap(other._attributes);
1378 1407

	
1379 1408
      _nodes_caption = other._nodes_caption;
1380 1409
      _edges_caption = other._edges_caption;
1381 1410
      _attributes_caption = other._attributes_caption;
1382 1411

	
1383 1412
    }
1384 1413

	
1385 1414
    GraphReader& operator=(const GraphReader&);
1386 1415

	
1387 1416
  public:
1388 1417

	
1389
    /// \name Reading rules
1418
    /// \name Reading Rules
1390 1419
    /// @{
1391 1420

	
1392 1421
    /// \brief Node map reading rule
1393 1422
    ///
1394 1423
    /// Add a node map reading rule to the reader.
1395 1424
    template <typename Map>
1396 1425
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1397 1426
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1398 1427
      _reader_bits::MapStorageBase<Node>* storage =
1399 1428
        new _reader_bits::MapStorage<Node, Map>(map);
1400 1429
      _node_maps.push_back(std::make_pair(caption, storage));
1401 1430
      return *this;
1402 1431
    }
1403 1432

	
1404 1433
    /// \brief Node map reading rule
1405 1434
    ///
1406 1435
    /// Add a node map reading rule with specialized converter to the
1407 1436
    /// reader.
1408 1437
    template <typename Map, typename Converter>
1409 1438
    GraphReader& nodeMap(const std::string& caption, Map& map,
1410 1439
                           const Converter& converter = Converter()) {
1411 1440
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1412 1441
      _reader_bits::MapStorageBase<Node>* storage =
1413 1442
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1414 1443
      _node_maps.push_back(std::make_pair(caption, storage));
1415 1444
      return *this;
1416 1445
    }
1417 1446

	
1418 1447
    /// \brief Edge map reading rule
1419 1448
    ///
1420 1449
    /// Add an edge map reading rule to the reader.
1421 1450
    template <typename Map>
1422 1451
    GraphReader& edgeMap(const std::string& caption, Map& map) {
1423 1452
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1424 1453
      _reader_bits::MapStorageBase<Edge>* storage =
1425 1454
        new _reader_bits::MapStorage<Edge, Map>(map);
1426 1455
      _edge_maps.push_back(std::make_pair(caption, storage));
1427 1456
      return *this;
1428 1457
    }
1429 1458

	
1430 1459
    /// \brief Edge map reading rule
1431 1460
    ///
1432 1461
    /// Add an edge map reading rule with specialized converter to the
1433 1462
    /// reader.
1434 1463
    template <typename Map, typename Converter>
1435 1464
    GraphReader& edgeMap(const std::string& caption, Map& map,
1436 1465
                          const Converter& converter = Converter()) {
1437 1466
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1438 1467
      _reader_bits::MapStorageBase<Edge>* storage =
1439 1468
        new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1440 1469
      _edge_maps.push_back(std::make_pair(caption, storage));
1441 1470
      return *this;
1442 1471
    }
1443 1472

	
1444 1473
    /// \brief Arc map reading rule
1445 1474
    ///
1446 1475
    /// Add an arc map reading rule to the reader.
1447 1476
    template <typename Map>
1448 1477
    GraphReader& arcMap(const std::string& caption, Map& map) {
1449 1478
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1450 1479
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1451 1480
        new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1452 1481
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1453 1482
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1454
        new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1483
        new _reader_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
1455 1484
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1456 1485
      return *this;
1457 1486
    }
1458 1487

	
1459 1488
    /// \brief Arc map reading rule
1460 1489
    ///
1461 1490
    /// Add an arc map reading rule with specialized converter to the
1462 1491
    /// reader.
1463 1492
    template <typename Map, typename Converter>
1464 1493
    GraphReader& arcMap(const std::string& caption, Map& map,
1465 1494
                          const Converter& converter = Converter()) {
1466 1495
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1467 1496
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1468
        new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1497
        new _reader_bits::GraphArcMapStorage<GR, true, Map, Converter>
1469 1498
        (_graph, map, converter);
1470 1499
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1471 1500
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1472
        new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1501
        new _reader_bits::GraphArcMapStorage<GR, false, Map, Converter>
1473 1502
        (_graph, map, converter);
1474 1503
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1475 1504
      return *this;
1476 1505
    }
1477 1506

	
1478 1507
    /// \brief Attribute reading rule
1479 1508
    ///
1480 1509
    /// Add an attribute reading rule to the reader.
1481 1510
    template <typename Value>
1482 1511
    GraphReader& attribute(const std::string& caption, Value& value) {
1483 1512
      _reader_bits::ValueStorageBase* storage =
1484 1513
        new _reader_bits::ValueStorage<Value>(value);
1485 1514
      _attributes.insert(std::make_pair(caption, storage));
1486 1515
      return *this;
1487 1516
    }
1488 1517

	
1489 1518
    /// \brief Attribute reading rule
1490 1519
    ///
1491 1520
    /// Add an attribute reading rule with specialized converter to the
1492 1521
    /// reader.
1493 1522
    template <typename Value, typename Converter>
1494 1523
    GraphReader& attribute(const std::string& caption, Value& value,
1495 1524
                             const Converter& converter = Converter()) {
1496 1525
      _reader_bits::ValueStorageBase* storage =
1497 1526
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1498 1527
      _attributes.insert(std::make_pair(caption, storage));
1499 1528
      return *this;
1500 1529
    }
1501 1530

	
1502 1531
    /// \brief Node reading rule
1503 1532
    ///
1504 1533
    /// Add a node reading rule to reader.
1505 1534
    GraphReader& node(const std::string& caption, Node& node) {
1506 1535
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
1507 1536
      Converter converter(_node_index);
1508 1537
      _reader_bits::ValueStorageBase* storage =
1509 1538
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1510 1539
      _attributes.insert(std::make_pair(caption, storage));
1511 1540
      return *this;
1512 1541
    }
1513 1542

	
1514 1543
    /// \brief Edge reading rule
1515 1544
    ///
1516 1545
    /// Add an edge reading rule to reader.
1517 1546
    GraphReader& edge(const std::string& caption, Edge& edge) {
1518 1547
      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1519 1548
      Converter converter(_edge_index);
1520 1549
      _reader_bits::ValueStorageBase* storage =
1521 1550
        new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1522 1551
      _attributes.insert(std::make_pair(caption, storage));
1523 1552
      return *this;
1524 1553
    }
1525 1554

	
1526 1555
    /// \brief Arc reading rule
1527 1556
    ///
1528 1557
    /// Add an arc reading rule to reader.
1529 1558
    GraphReader& arc(const std::string& caption, Arc& arc) {
1530
      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
1559
      typedef _reader_bits::GraphArcLookUpConverter<GR> Converter;
1531 1560
      Converter converter(_graph, _edge_index);
1532 1561
      _reader_bits::ValueStorageBase* storage =
1533 1562
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1534 1563
      _attributes.insert(std::make_pair(caption, storage));
1535 1564
      return *this;
1536 1565
    }
1537 1566

	
1538 1567
    /// @}
1539 1568

	
1540
    /// \name Select section by name
1569
    /// \name Select Section by Name
1541 1570
    /// @{
1542 1571

	
1543 1572
    /// \brief Set \c \@nodes section to be read
1544 1573
    ///
1545 1574
    /// Set \c \@nodes section to be read.
1546 1575
    GraphReader& nodes(const std::string& caption) {
1547 1576
      _nodes_caption = caption;
1548 1577
      return *this;
1549 1578
    }
1550 1579

	
1551 1580
    /// \brief Set \c \@edges section to be read
1552 1581
    ///
1553 1582
    /// Set \c \@edges section to be read.
1554 1583
    GraphReader& edges(const std::string& caption) {
1555 1584
      _edges_caption = caption;
1556 1585
      return *this;
1557 1586
    }
1558 1587

	
1559 1588
    /// \brief Set \c \@attributes section to be read
1560 1589
    ///
1561 1590
    /// Set \c \@attributes section to be read.
1562 1591
    GraphReader& attributes(const std::string& caption) {
1563 1592
      _attributes_caption = caption;
1564 1593
      return *this;
1565 1594
    }
1566 1595

	
1567 1596
    /// @}
1568 1597

	
1569
    /// \name Using previously constructed node or edge set
1598
    /// \name Using Previously Constructed Node or Edge Set
1570 1599
    /// @{
1571 1600

	
1572 1601
    /// \brief Use previously constructed node set
1573 1602
    ///
1574 1603
    /// Use previously constructed node set, and specify the node
1575 1604
    /// label map.
1576 1605
    template <typename Map>
1577 1606
    GraphReader& useNodes(const Map& map) {
1578 1607
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1579 1608
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1580 1609
      _use_nodes = true;
1581 1610
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1582 1611
      for (NodeIt n(_graph); n != INVALID; ++n) {
1583 1612
        _node_index.insert(std::make_pair(converter(map[n]), n));
1584 1613
      }
1585 1614
      return *this;
1586 1615
    }
1587 1616

	
1588 1617
    /// \brief Use previously constructed node set
1589 1618
    ///
1590 1619
    /// Use previously constructed node set, and specify the node
1591 1620
    /// label map and a functor which converts the label map values to
1592 1621
    /// \c std::string.
1593 1622
    template <typename Map, typename Converter>
1594 1623
    GraphReader& useNodes(const Map& map,
1595 1624
                            const Converter& converter = Converter()) {
1596 1625
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1597 1626
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1598 1627
      _use_nodes = true;
1599 1628
      for (NodeIt n(_graph); n != INVALID; ++n) {
1600 1629
        _node_index.insert(std::make_pair(converter(map[n]), n));
1601 1630
      }
1602 1631
      return *this;
1603 1632
    }
1604 1633

	
1605 1634
    /// \brief Use previously constructed edge set
1606 1635
    ///
1607 1636
    /// Use previously constructed edge set, and specify the edge
1608 1637
    /// label map.
1609 1638
    template <typename Map>
1610 1639
    GraphReader& useEdges(const Map& map) {
1611 1640
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1612 1641
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1613 1642
      _use_edges = true;
1614 1643
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1615 1644
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1616 1645
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1617 1646
      }
1618 1647
      return *this;
1619 1648
    }
1620 1649

	
1621 1650
    /// \brief Use previously constructed edge set
1622 1651
    ///
1623 1652
    /// Use previously constructed edge set, and specify the edge
1624 1653
    /// label map and a functor which converts the label map values to
1625 1654
    /// \c std::string.
1626 1655
    template <typename Map, typename Converter>
1627 1656
    GraphReader& useEdges(const Map& map,
1628 1657
                            const Converter& converter = Converter()) {
1629 1658
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1630 1659
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1631 1660
      _use_edges = true;
1632 1661
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1633 1662
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1634 1663
      }
1635 1664
      return *this;
1636 1665
    }
1637 1666

	
1638 1667
    /// \brief Skip the reading of node section
1639 1668
    ///
1640 1669
    /// Omit the reading of the node section. This implies that each node
1641 1670
    /// map reading rule will be abandoned, and the nodes of the graph
1642 1671
    /// will not be constructed, which usually cause that the edge set
1643 1672
    /// could not be read due to lack of node name
1644 1673
    /// could not be read due to lack of node name resolving.
1645 1674
    /// Therefore \c skipEdges() function should also be used, or
1646 1675
    /// \c useNodes() should be used to specify the label of the nodes.
1647 1676
    GraphReader& skipNodes() {
1648 1677
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
1649 1678
      _skip_nodes = true;
1650 1679
      return *this;
1651 1680
    }
1652 1681

	
1653 1682
    /// \brief Skip the reading of edge section
1654 1683
    ///
1655 1684
    /// Omit the reading of the edge section. This implies that each edge
1656 1685
    /// map reading rule will be abandoned, and the edges of the graph
1657 1686
    /// will not be constructed.
1658 1687
    GraphReader& skipEdges() {
1659 1688
      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
1660 1689
      _skip_edges = true;
1661 1690
      return *this;
1662 1691
    }
1663 1692

	
1664 1693
    /// @}
1665 1694

	
1666 1695
  private:
1667 1696

	
1668 1697
    bool readLine() {
1669 1698
      std::string str;
1670 1699
      while(++line_num, std::getline(*_is, str)) {
1671 1700
        line.clear(); line.str(str);
1672 1701
        char c;
1673 1702
        if (line >> std::ws >> c && c != '#') {
1674 1703
          line.putback(c);
1675 1704
          return true;
1676 1705
        }
1677 1706
      }
1678 1707
      return false;
1679 1708
    }
1680 1709

	
1681 1710
    bool readSuccess() {
1682 1711
      return static_cast<bool>(*_is);
1683 1712
    }
1684 1713

	
1685 1714
    void skipSection() {
1686 1715
      char c;
1687 1716
      while (readSuccess() && line >> c && c != '@') {
1688 1717
        readLine();
1689 1718
      }
1690
      line.putback(c);
1719
      if (readSuccess()) {
1720
        line.putback(c);
1721
      }
1691 1722
    }
1692 1723

	
1693 1724
    void readNodes() {
1694 1725

	
1695 1726
      std::vector<int> map_index(_node_maps.size());
1696 1727
      int map_num, label_index;
1697 1728

	
1698 1729
      char c;
1699 1730
      if (!readLine() || !(line >> c) || c == '@') {
1700 1731
        if (readSuccess() && line) line.putback(c);
1701 1732
        if (!_node_maps.empty())
1702 1733
          throw FormatError("Cannot find map names");
1703 1734
        return;
1704 1735
      }
1705 1736
      line.putback(c);
1706 1737

	
1707 1738
      {
1708 1739
        std::map<std::string, int> maps;
1709 1740

	
1710 1741
        std::string map;
1711 1742
        int index = 0;
1712 1743
        while (_reader_bits::readToken(line, map)) {
1713 1744
          if (maps.find(map) != maps.end()) {
1714 1745
            std::ostringstream msg;
1715 1746
            msg << "Multiple occurence of node map: " << map;
1716 1747
            throw FormatError(msg.str());
1717 1748
          }
1718 1749
          maps.insert(std::make_pair(map, index));
1719 1750
          ++index;
1720 1751
        }
1721 1752

	
1722 1753
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1723 1754
          std::map<std::string, int>::iterator jt =
1724 1755
            maps.find(_node_maps[i].first);
1725 1756
          if (jt == maps.end()) {
1726 1757
            std::ostringstream msg;
1727 1758
            msg << "Map not found: " << _node_maps[i].first;
1728 1759
            throw FormatError(msg.str());
1729 1760
          }
1730 1761
          map_index[i] = jt->second;
1731 1762
        }
1732 1763

	
1733 1764
        {
1734 1765
          std::map<std::string, int>::iterator jt = maps.find("label");
1735 1766
          if (jt != maps.end()) {
1736 1767
            label_index = jt->second;
1737 1768
          } else {
1738 1769
            label_index = -1;
1739 1770
          }
1740 1771
        }
1741 1772
        map_num = maps.size();
1742 1773
      }
1743 1774

	
1744 1775
      while (readLine() && line >> c && c != '@') {
1745 1776
        line.putback(c);
1746 1777

	
1747 1778
        std::vector<std::string> tokens(map_num);
1748 1779
        for (int i = 0; i < map_num; ++i) {
1749 1780
          if (!_reader_bits::readToken(line, tokens[i])) {
1750 1781
            std::ostringstream msg;
1751 1782
            msg << "Column not found (" << i + 1 << ")";
1752 1783
            throw FormatError(msg.str());
1753 1784
          }
1754 1785
        }
1755 1786
        if (line >> std::ws >> c)
1756 1787
          throw FormatError("Extra character at the end of line");
1757 1788

	
1758 1789
        Node n;
1759 1790
        if (!_use_nodes) {
1760 1791
          n = _graph.addNode();
1761 1792
          if (label_index != -1)
1762 1793
            _node_index.insert(std::make_pair(tokens[label_index], n));
1763 1794
        } else {
1764 1795
          if (label_index == -1)
1765 1796
            throw FormatError("Label map not found");
1766 1797
          typename std::map<std::string, Node>::iterator it =
1767 1798
            _node_index.find(tokens[label_index]);
1768 1799
          if (it == _node_index.end()) {
1769 1800
            std::ostringstream msg;
1770 1801
            msg << "Node with label not found: " << tokens[label_index];
1771 1802
            throw FormatError(msg.str());
1772 1803
          }
1773 1804
          n = it->second;
1774 1805
        }
1775 1806

	
1776 1807
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1777 1808
          _node_maps[i].second->set(n, tokens[map_index[i]]);
1778 1809
        }
1779 1810

	
1780 1811
      }
1781 1812
      if (readSuccess()) {
1782 1813
        line.putback(c);
1783 1814
      }
1784 1815
    }
1785 1816

	
1786 1817
    void readEdges() {
1787 1818

	
1788 1819
      std::vector<int> map_index(_edge_maps.size());
1789 1820
      int map_num, label_index;
1790 1821

	
1791 1822
      char c;
1792 1823
      if (!readLine() || !(line >> c) || c == '@') {
1793 1824
        if (readSuccess() && line) line.putback(c);
1794 1825
        if (!_edge_maps.empty())
1795 1826
          throw FormatError("Cannot find map names");
1796 1827
        return;
1797 1828
      }
1798 1829
      line.putback(c);
1799 1830

	
1800 1831
      {
1801 1832
        std::map<std::string, int> maps;
1802 1833

	
1803 1834
        std::string map;
1804 1835
        int index = 0;
1805 1836
        while (_reader_bits::readToken(line, map)) {
1806 1837
          if (maps.find(map) != maps.end()) {
1807 1838
            std::ostringstream msg;
1808 1839
            msg << "Multiple occurence of edge map: " << map;
1809 1840
            throw FormatError(msg.str());
1810 1841
          }
1811 1842
          maps.insert(std::make_pair(map, index));
1812 1843
          ++index;
1813 1844
        }
1814 1845

	
1815 1846
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1816 1847
          std::map<std::string, int>::iterator jt =
1817 1848
            maps.find(_edge_maps[i].first);
1818 1849
          if (jt == maps.end()) {
1819 1850
            std::ostringstream msg;
1820 1851
            msg << "Map not found: " << _edge_maps[i].first;
1821 1852
            throw FormatError(msg.str());
1822 1853
          }
1823 1854
          map_index[i] = jt->second;
1824 1855
        }
1825 1856

	
1826 1857
        {
1827 1858
          std::map<std::string, int>::iterator jt = maps.find("label");
1828 1859
          if (jt != maps.end()) {
1829 1860
            label_index = jt->second;
1830 1861
          } else {
1831 1862
            label_index = -1;
1832 1863
          }
1833 1864
        }
1834 1865
        map_num = maps.size();
1835 1866
      }
1836 1867

	
1837 1868
      while (readLine() && line >> c && c != '@') {
1838 1869
        line.putback(c);
1839 1870

	
1840 1871
        std::string source_token;
1841 1872
        std::string target_token;
1842 1873

	
1843 1874
        if (!_reader_bits::readToken(line, source_token))
1844 1875
          throw FormatError("Node u not found");
1845 1876

	
1846 1877
        if (!_reader_bits::readToken(line, target_token))
1847 1878
          throw FormatError("Node v not found");
1848 1879

	
1849 1880
        std::vector<std::string> tokens(map_num);
1850 1881
        for (int i = 0; i < map_num; ++i) {
1851 1882
          if (!_reader_bits::readToken(line, tokens[i])) {
1852 1883
            std::ostringstream msg;
1853 1884
            msg << "Column not found (" << i + 1 << ")";
1854 1885
            throw FormatError(msg.str());
1855 1886
          }
1856 1887
        }
1857 1888
        if (line >> std::ws >> c)
1858 1889
          throw FormatError("Extra character at the end of line");
1859 1890

	
1860 1891
        Edge e;
1861 1892
        if (!_use_edges) {
1862 1893

	
1863 1894
          typename NodeIndex::iterator it;
1864 1895

	
1865 1896
          it = _node_index.find(source_token);
1866 1897
          if (it == _node_index.end()) {
1867 1898
            std::ostringstream msg;
1868 1899
            msg << "Item not found: " << source_token;
1869 1900
            throw FormatError(msg.str());
1870 1901
          }
1871 1902
          Node source = it->second;
1872 1903

	
1873 1904
          it = _node_index.find(target_token);
1874 1905
          if (it == _node_index.end()) {
1875 1906
            std::ostringstream msg;
1876 1907
            msg << "Item not found: " << target_token;
1877 1908
            throw FormatError(msg.str());
1878 1909
          }
1879 1910
          Node target = it->second;
1880 1911

	
1881 1912
          e = _graph.addEdge(source, target);
1882 1913
          if (label_index != -1)
1883 1914
            _edge_index.insert(std::make_pair(tokens[label_index], e));
1884 1915
        } else {
1885 1916
          if (label_index == -1)
1886 1917
            throw FormatError("Label map not found");
1887 1918
          typename std::map<std::string, Edge>::iterator it =
1888 1919
            _edge_index.find(tokens[label_index]);
1889 1920
          if (it == _edge_index.end()) {
1890 1921
            std::ostringstream msg;
1891 1922
            msg << "Edge with label not found: " << tokens[label_index];
1892 1923
            throw FormatError(msg.str());
1893 1924
          }
1894 1925
          e = it->second;
1895 1926
        }
1896 1927

	
1897 1928
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1898 1929
          _edge_maps[i].second->set(e, tokens[map_index[i]]);
1899 1930
        }
1900 1931

	
1901 1932
      }
1902 1933
      if (readSuccess()) {
1903 1934
        line.putback(c);
1904 1935
      }
1905 1936
    }
1906 1937

	
1907 1938
    void readAttributes() {
1908 1939

	
1909 1940
      std::set<std::string> read_attr;
1910 1941

	
1911 1942
      char c;
1912 1943
      while (readLine() && line >> c && c != '@') {
1913 1944
        line.putback(c);
1914 1945

	
1915 1946
        std::string attr, token;
1916 1947
        if (!_reader_bits::readToken(line, attr))
1917 1948
          throw FormatError("Attribute name not found");
1918 1949
        if (!_reader_bits::readToken(line, token))
1919 1950
          throw FormatError("Attribute value not found");
1920 1951
        if (line >> c)
1921 1952
          throw FormatError("Extra character at the end of line");
1922 1953

	
1923 1954
        {
1924 1955
          std::set<std::string>::iterator it = read_attr.find(attr);
1925 1956
          if (it != read_attr.end()) {
1926 1957
            std::ostringstream msg;
1927 1958
            msg << "Multiple occurence of attribute: " << attr;
1928 1959
            throw FormatError(msg.str());
1929 1960
          }
1930 1961
          read_attr.insert(attr);
1931 1962
        }
1932 1963

	
1933 1964
        {
1934 1965
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1935 1966
          while (it != _attributes.end() && it->first == attr) {
1936 1967
            it->second->set(token);
1937 1968
            ++it;
1938 1969
          }
1939 1970
        }
1940 1971

	
1941 1972
      }
1942 1973
      if (readSuccess()) {
1943 1974
        line.putback(c);
1944 1975
      }
1945 1976
      for (typename Attributes::iterator it = _attributes.begin();
1946 1977
           it != _attributes.end(); ++it) {
1947 1978
        if (read_attr.find(it->first) == read_attr.end()) {
1948 1979
          std::ostringstream msg;
1949 1980
          msg << "Attribute not found: " << it->first;
1950 1981
          throw FormatError(msg.str());
1951 1982
        }
1952 1983
      }
1953 1984
    }
1954 1985

	
1955 1986
  public:
1956 1987

	
1957
    /// \name Execution of the reader
1988
    /// \name Execution of the Reader
1958 1989
    /// @{
1959 1990

	
1960 1991
    /// \brief Start the batch processing
1961 1992
    ///
1962 1993
    /// This function starts the batch processing
1963 1994
    void run() {
1964 1995

	
1965 1996
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1966 1997

	
1967 1998
      bool nodes_done = _skip_nodes;
1968 1999
      bool edges_done = _skip_edges;
1969 2000
      bool attributes_done = false;
1970 2001

	
1971 2002
      line_num = 0;
1972 2003
      readLine();
1973 2004
      skipSection();
1974 2005

	
1975 2006
      while (readSuccess()) {
1976 2007
        try {
1977 2008
          char c;
1978 2009
          std::string section, caption;
1979 2010
          line >> c;
1980 2011
          _reader_bits::readToken(line, section);
1981 2012
          _reader_bits::readToken(line, caption);
1982 2013

	
1983 2014
          if (line >> c)
1984 2015
            throw FormatError("Extra character at the end of line");
1985 2016

	
1986 2017
          if (section == "nodes" && !nodes_done) {
1987 2018
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1988 2019
              readNodes();
1989 2020
              nodes_done = true;
1990 2021
            }
1991 2022
          } else if ((section == "edges" || section == "arcs") &&
1992 2023
                     !edges_done) {
1993 2024
            if (_edges_caption.empty() || _edges_caption == caption) {
1994 2025
              readEdges();
1995 2026
              edges_done = true;
1996 2027
            }
1997 2028
          } else if (section == "attributes" && !attributes_done) {
1998 2029
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1999 2030
              readAttributes();
2000 2031
              attributes_done = true;
2001 2032
            }
2002 2033
          } else {
2003 2034
            readLine();
2004 2035
            skipSection();
2005 2036
          }
2006 2037
        } catch (FormatError& error) {
2007 2038
          error.line(line_num);
2008 2039
          error.file(_filename);
2009 2040
          throw;
2010 2041
        }
2011 2042
      }
2012 2043

	
2013 2044
      if (!nodes_done) {
2014 2045
        throw FormatError("Section @nodes not found");
2015 2046
      }
2016 2047

	
2017 2048
      if (!edges_done) {
2018 2049
        throw FormatError("Section @edges not found");
2019 2050
      }
2020 2051

	
2021 2052
      if (!attributes_done && !_attributes.empty()) {
2022 2053
        throw FormatError("Section @attributes not found");
2023 2054
      }
2024 2055

	
2025 2056
    }
2026 2057

	
2027 2058
    /// @}
2028 2059

	
2029 2060
  };
2030 2061

	
2062
  /// \ingroup lemon_io
2063
  ///
2064
  /// \brief Return a \ref GraphReader class
2065
  ///
2066
  /// This function just returns a \ref GraphReader class. 
2067
  ///
2068
  /// With this function a graph can be read from an 
2069
  /// \ref lgf-format "LGF" file or input stream with several maps and
2070
  /// attributes. For example, there is weighted matching problem on a
2071
  /// graph, i.e. a graph with a \e weight map on the edges. This
2072
  /// graph can be read with the following code:
2073
  ///
2074
  ///\code
2075
  ///ListGraph graph;
2076
  ///ListGraph::EdgeMap<int> weight(graph);
2077
  ///graphReader(graph, std::cin).
2078
  ///  edgeMap("weight", weight).
2079
  ///  run();
2080
  ///\endcode
2081
  ///
2082
  /// For a complete documentation, please see the \ref GraphReader
2083
  /// class documentation.
2084
  /// \warning Don't forget to put the \ref GraphReader::run() "run()"
2085
  /// to the end of the parameter list.
2086
  /// \relates GraphReader
2087
  /// \sa graphReader(TGR& graph, const std::string& fn)
2088
  /// \sa graphReader(TGR& graph, const char* fn)
2089
  template <typename TGR>
2090
  GraphReader<TGR> graphReader(TGR& graph, std::istream& is) {
2091
    GraphReader<TGR> tmp(graph, is);
2092
    return tmp;
2093
  }
2094

	
2031 2095
  /// \brief Return a \ref GraphReader class
2032 2096
  ///
2033 2097
  /// This function just returns a \ref GraphReader class.
2034 2098
  /// \relates GraphReader
2035
  template <typename Graph>
2036
  GraphReader<Graph> graphReader(Graph& graph, std::istream& is) {
2037
    GraphReader<Graph> tmp(graph, is);
2099
  /// \sa graphReader(TGR& graph, std::istream& is)
2100
  template <typename TGR>
2101
  GraphReader<TGR> graphReader(TGR& graph, const std::string& fn) {
2102
    GraphReader<TGR> tmp(graph, fn);
2038 2103
    return tmp;
2039 2104
  }
2040 2105

	
2041 2106
  /// \brief Return a \ref GraphReader class
2042 2107
  ///
2043 2108
  /// This function just returns a \ref GraphReader class.
2044 2109
  /// \relates GraphReader
2045
  template <typename Graph>
2046
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
2047
    GraphReader<Graph> tmp(graph, fn);
2048
    return tmp;
2049
  }
2050

	
2051
  /// \brief Return a \ref GraphReader class
2052
  ///
2053
  /// This function just returns a \ref GraphReader class.
2054
  /// \relates GraphReader
2055
  template <typename Graph>
2056
  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
2057
    GraphReader<Graph> tmp(graph, fn);
2110
  /// \sa graphReader(TGR& graph, std::istream& is)
2111
  template <typename TGR>
2112
  GraphReader<TGR> graphReader(TGR& graph, const char* fn) {
2113
    GraphReader<TGR> tmp(graph, fn);
2058 2114
    return tmp;
2059 2115
  }
2060 2116

	
2061 2117
  class SectionReader;
2062 2118

	
2063 2119
  SectionReader sectionReader(std::istream& is);
2064 2120
  SectionReader sectionReader(const std::string& fn);
2065 2121
  SectionReader sectionReader(const char* fn);
2066 2122

	
2067 2123
  /// \ingroup lemon_io
2068 2124
  ///
2069 2125
  /// \brief Section reader class
2070 2126
  ///
2071 2127
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
2072 2128
  /// which contain any data in arbitrary format. Such sections can be
2073 2129
  /// read with this class. A reading rule can be added to the class
2074 2130
  /// with two different functions. With the \c sectionLines() function a
2075 2131
  /// functor can process the section line-by-line, while with the \c
2076 2132
  /// sectionStream() member the section can be read from an input
2077 2133
  /// stream.
2078 2134
  class SectionReader {
2079 2135
  private:
2080 2136

	
2081 2137
    std::istream* _is;
2082 2138
    bool local_is;
2083 2139
    std::string _filename;
2084 2140

	
2085 2141
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2086 2142
    Sections _sections;
2087 2143

	
2088 2144
    int line_num;
2089 2145
    std::istringstream line;
2090 2146

	
2091 2147
  public:
2092 2148

	
2093 2149
    /// \brief Constructor
2094 2150
    ///
2095 2151
    /// Construct a section reader, which reads from the given input
2096 2152
    /// stream.
2097 2153
    SectionReader(std::istream& is)
2098 2154
      : _is(&is), local_is(false) {}
2099 2155

	
2100 2156
    /// \brief Constructor
2101 2157
    ///
2102 2158
    /// Construct a section reader, which reads from the given file.
2103 2159
    SectionReader(const std::string& fn)
2104 2160
      : _is(new std::ifstream(fn.c_str())), local_is(true),
2105 2161
        _filename(fn) {
2106 2162
      if (!(*_is)) {
2107 2163
        delete _is;
2108 2164
        throw IoError("Cannot open file", fn);
2109 2165
      }
2110 2166
    }
2111 2167

	
2112 2168
    /// \brief Constructor
2113 2169
    ///
2114 2170
    /// Construct a section reader, which reads from the given file.
2115 2171
    SectionReader(const char* fn)
2116 2172
      : _is(new std::ifstream(fn)), local_is(true),
2117 2173
        _filename(fn) {
2118 2174
      if (!(*_is)) {
2119 2175
        delete _is;
2120 2176
        throw IoError("Cannot open file", fn);
2121 2177
      }
2122 2178
    }
2123 2179

	
2124 2180
    /// \brief Destructor
2125 2181
    ~SectionReader() {
2126 2182
      for (Sections::iterator it = _sections.begin();
2127 2183
           it != _sections.end(); ++it) {
2128 2184
        delete it->second;
2129 2185
      }
2130 2186

	
2131 2187
      if (local_is) {
2132 2188
        delete _is;
2133 2189
      }
2134 2190

	
2135 2191
    }
2136 2192

	
2137 2193
  private:
2138 2194

	
2139 2195
    friend SectionReader sectionReader(std::istream& is);
2140 2196
    friend SectionReader sectionReader(const std::string& fn);
2141 2197
    friend SectionReader sectionReader(const char* fn);
2142 2198

	
2143 2199
    SectionReader(SectionReader& other)
2144 2200
      : _is(other._is), local_is(other.local_is) {
2145 2201

	
2146 2202
      other._is = 0;
2147 2203
      other.local_is = false;
2148 2204

	
2149 2205
      _sections.swap(other._sections);
2150 2206
    }
2151 2207

	
2152 2208
    SectionReader& operator=(const SectionReader&);
2153 2209

	
2154 2210
  public:
2155 2211

	
2156
    /// \name Section readers
2212
    /// \name Section Readers
2157 2213
    /// @{
2158 2214

	
2159 2215
    /// \brief Add a section processor with line oriented reading
2160 2216
    ///
2161 2217
    /// The first parameter is the type descriptor of the section, the
2162 2218
    /// second is a functor, which takes just one \c std::string
2163 2219
    /// parameter. At the reading process, each line of the section
2164 2220
    /// will be given to the functor object. However, the empty lines
2165 2221
    /// and the comment lines are filtered out, and the leading
2166 2222
    /// whitespaces are trimmed from each processed string.
2167 2223
    ///
2168 2224
    /// For example let's see a section, which contain several
2169 2225
    /// integers, which should be inserted into a vector.
2170 2226
    ///\code
2171 2227
    ///  @numbers
2172 2228
    ///  12 45 23
2173 2229
    ///  4
2174 2230
    ///  23 6
2175 2231
    ///\endcode
2176 2232
    ///
2177 2233
    /// The functor is implemented as a struct:
2178 2234
    ///\code
2179 2235
    ///  struct NumberSection {
2180 2236
    ///    std::vector<int>& _data;
2181 2237
    ///    NumberSection(std::vector<int>& data) : _data(data) {}
2182 2238
    ///    void operator()(const std::string& line) {
2183 2239
    ///      std::istringstream ls(line);
2184 2240
    ///      int value;
2185 2241
    ///      while (ls >> value) _data.push_back(value);
2186 2242
    ///    }
2187 2243
    ///  };
2188 2244
    ///
2189 2245
    ///  // ...
2190 2246
    ///
2191 2247
    ///  reader.sectionLines("numbers", NumberSection(vec));
2192 2248
    ///\endcode
2193 2249
    template <typename Functor>
2194 2250
    SectionReader& sectionLines(const std::string& type, Functor functor) {
2195 2251
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2196 2252
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2197 2253
                   "Multiple reading of section.");
2198 2254
      _sections.insert(std::make_pair(type,
2199 2255
        new _reader_bits::LineSection<Functor>(functor)));
2200 2256
      return *this;
2201 2257
    }
2202 2258

	
2203 2259

	
2204 2260
    /// \brief Add a section processor with stream oriented reading
2205 2261
    ///
2206 2262
    /// The first parameter is the type of the section, the second is
2207 2263
    /// a functor, which takes an \c std::istream& and an \c int&
2208 2264
    /// parameter, the latter regard to the line number of stream. The
2209 2265
    /// functor can read the input while the section go on, and the
2210 2266
    /// line number should be modified accordingly.
2211 2267
    template <typename Functor>
2212 2268
    SectionReader& sectionStream(const std::string& type, Functor functor) {
2213 2269
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2214 2270
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2215 2271
                   "Multiple reading of section.");
2216 2272
      _sections.insert(std::make_pair(type,
2217 2273
         new _reader_bits::StreamSection<Functor>(functor)));
2218 2274
      return *this;
2219 2275
    }
2220 2276

	
2221 2277
    /// @}
2222 2278

	
2223 2279
  private:
2224 2280

	
2225 2281
    bool readLine() {
2226 2282
      std::string str;
2227 2283
      while(++line_num, std::getline(*_is, str)) {
2228 2284
        line.clear(); line.str(str);
2229 2285
        char c;
2230 2286
        if (line >> std::ws >> c && c != '#') {
2231 2287
          line.putback(c);
2232 2288
          return true;
2233 2289
        }
2234 2290
      }
2235 2291
      return false;
2236 2292
    }
2237 2293

	
2238 2294
    bool readSuccess() {
2239 2295
      return static_cast<bool>(*_is);
2240 2296
    }
2241 2297

	
2242 2298
    void skipSection() {
2243 2299
      char c;
2244 2300
      while (readSuccess() && line >> c && c != '@') {
2245 2301
        readLine();
2246 2302
      }
2247
      line.putback(c);
2303
      if (readSuccess()) {
2304
        line.putback(c);
2305
      }
2248 2306
    }
2249 2307

	
2250 2308
  public:
2251 2309

	
2252 2310

	
2253
    /// \name Execution of the reader
2311
    /// \name Execution of the Reader
2254 2312
    /// @{
2255 2313

	
2256 2314
    /// \brief Start the batch processing
2257 2315
    ///
2258 2316
    /// This function starts the batch processing.
2259 2317
    void run() {
2260 2318

	
2261 2319
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2262 2320

	
2263 2321
      std::set<std::string> extra_sections;
2264 2322

	
2265 2323
      line_num = 0;
2266 2324
      readLine();
2267 2325
      skipSection();
2268 2326

	
2269 2327
      while (readSuccess()) {
2270 2328
        try {
2271 2329
          char c;
2272 2330
          std::string section, caption;
2273 2331
          line >> c;
2274 2332
          _reader_bits::readToken(line, section);
2275 2333
          _reader_bits::readToken(line, caption);
2276 2334

	
2277 2335
          if (line >> c)
2278 2336
            throw FormatError("Extra character at the end of line");
2279 2337

	
2280 2338
          if (extra_sections.find(section) != extra_sections.end()) {
2281 2339
            std::ostringstream msg;
2282 2340
            msg << "Multiple occurence of section: " << section;
2283 2341
            throw FormatError(msg.str());
2284 2342
          }
2285 2343
          Sections::iterator it = _sections.find(section);
2286 2344
          if (it != _sections.end()) {
2287 2345
            extra_sections.insert(section);
2288 2346
            it->second->process(*_is, line_num);
2289 2347
          }
2290 2348
          readLine();
2291 2349
          skipSection();
2292 2350
        } catch (FormatError& error) {
2293 2351
          error.line(line_num);
2294 2352
          error.file(_filename);
2295 2353
          throw;
2296 2354
        }
2297 2355
      }
2298 2356
      for (Sections::iterator it = _sections.begin();
2299 2357
           it != _sections.end(); ++it) {
2300 2358
        if (extra_sections.find(it->first) == extra_sections.end()) {
2301 2359
          std::ostringstream os;
2302 2360
          os << "Cannot find section: " << it->first;
2303 2361
          throw FormatError(os.str());
2304 2362
        }
2305 2363
      }
2306 2364
    }
2307 2365

	
2308 2366
    /// @}
2309 2367

	
2310 2368
  };
2311 2369

	
2370
  /// \ingroup lemon_io
2371
  ///
2372
  /// \brief Return a \ref SectionReader class
2373
  ///
2374
  /// This function just returns a \ref SectionReader class.
2375
  ///
2376
  /// Please see SectionReader documentation about the custom section
2377
  /// input.
2378
  ///
2379
  /// \relates SectionReader
2380
  /// \sa sectionReader(const std::string& fn)
2381
  /// \sa sectionReader(const char *fn)
2382
  inline SectionReader sectionReader(std::istream& is) {
2383
    SectionReader tmp(is);
2384
    return tmp;
2385
  }
2386

	
2312 2387
  /// \brief Return a \ref SectionReader class
2313 2388
  ///
2314 2389
  /// This function just returns a \ref SectionReader class.
2315 2390
  /// \relates SectionReader
2316
  inline SectionReader sectionReader(std::istream& is) {
2317
    SectionReader tmp(is);
2391
  /// \sa sectionReader(std::istream& is)
2392
  inline SectionReader sectionReader(const std::string& fn) {
2393
    SectionReader tmp(fn);
2318 2394
    return tmp;
2319 2395
  }
2320 2396

	
2321 2397
  /// \brief Return a \ref SectionReader class
2322 2398
  ///
2323 2399
  /// This function just returns a \ref SectionReader class.
2324 2400
  /// \relates SectionReader
2325
  inline SectionReader sectionReader(const std::string& fn) {
2326
    SectionReader tmp(fn);
2327
    return tmp;
2328
  }
2329

	
2330
  /// \brief Return a \ref SectionReader class
2331
  ///
2332
  /// This function just returns a \ref SectionReader class.
2333
  /// \relates SectionReader
2401
  /// \sa sectionReader(std::istream& is)
2334 2402
  inline SectionReader sectionReader(const char* fn) {
2335 2403
    SectionReader tmp(fn);
2336 2404
    return tmp;
2337 2405
  }
2338 2406

	
2339 2407
  /// \ingroup lemon_io
2340 2408
  ///
2341 2409
  /// \brief Reader for the contents of the \ref lgf-format "LGF" file
2342 2410
  ///
2343 2411
  /// This class can be used to read the sections, the map names and
2344 2412
  /// the attributes from a file. Usually, the LEMON programs know
2345 2413
  /// that, which type of graph, which maps and which attributes
2346 2414
  /// should be read from a file, but in general tools (like glemon)
2347 2415
  /// the contents of an LGF file should be guessed somehow. This class
2348 2416
  /// reads the graph and stores the appropriate information for
2349 2417
  /// reading the graph.
2350 2418
  ///
2351 2419
  ///\code
2352 2420
  /// LgfContents contents("graph.lgf");
2353 2421
  /// contents.run();
2354 2422
  ///
2355 2423
  /// // Does it contain any node section and arc section?
2356 2424
  /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
2357 2425
  ///   std::cerr << "Failure, cannot find graph." << std::endl;
2358 2426
  ///   return -1;
2359 2427
  /// }
2360 2428
  /// std::cout << "The name of the default node section: "
2361 2429
  ///           << contents.nodeSection(0) << std::endl;
2362 2430
  /// std::cout << "The number of the arc maps: "
2363 2431
  ///           << contents.arcMaps(0).size() << std::endl;
2364 2432
  /// std::cout << "The name of second arc map: "
2365 2433
  ///           << contents.arcMaps(0)[1] << std::endl;
2366 2434
  ///\endcode
2367 2435
  class LgfContents {
2368 2436
  private:
2369 2437

	
2370 2438
    std::istream* _is;
2371 2439
    bool local_is;
2372 2440

	
2373 2441
    std::vector<std::string> _node_sections;
2374 2442
    std::vector<std::string> _edge_sections;
2375 2443
    std::vector<std::string> _attribute_sections;
2376 2444
    std::vector<std::string> _extra_sections;
2377 2445

	
2378 2446
    std::vector<bool> _arc_sections;
2379 2447

	
2380 2448
    std::vector<std::vector<std::string> > _node_maps;
2381 2449
    std::vector<std::vector<std::string> > _edge_maps;
2382 2450

	
2383 2451
    std::vector<std::vector<std::string> > _attributes;
2384 2452

	
2385 2453

	
2386 2454
    int line_num;
2387 2455
    std::istringstream line;
2388 2456

	
2389 2457
  public:
2390 2458

	
2391 2459
    /// \brief Constructor
2392 2460
    ///
2393 2461
    /// Construct an \e LGF contents reader, which reads from the given
2394 2462
    /// input stream.
2395 2463
    LgfContents(std::istream& is)
2396 2464
      : _is(&is), local_is(false) {}
2397 2465

	
2398 2466
    /// \brief Constructor
2399 2467
    ///
2400 2468
    /// Construct an \e LGF contents reader, which reads from the given
2401 2469
    /// file.
2402 2470
    LgfContents(const std::string& fn)
2403 2471
      : _is(new std::ifstream(fn.c_str())), local_is(true) {
2404 2472
      if (!(*_is)) {
2405 2473
        delete _is;
2406 2474
        throw IoError("Cannot open file", fn);
2407 2475
      }
2408 2476
    }
2409 2477

	
2410 2478
    /// \brief Constructor
2411 2479
    ///
2412 2480
    /// Construct an \e LGF contents reader, which reads from the given
2413 2481
    /// file.
2414 2482
    LgfContents(const char* fn)
2415 2483
      : _is(new std::ifstream(fn)), local_is(true) {
2416 2484
      if (!(*_is)) {
2417 2485
        delete _is;
2418 2486
        throw IoError("Cannot open file", fn);
2419 2487
      }
2420 2488
    }
2421 2489

	
2422 2490
    /// \brief Destructor
2423 2491
    ~LgfContents() {
2424 2492
      if (local_is) delete _is;
2425 2493
    }
2426 2494

	
2427 2495
  private:
2428 2496

	
2429 2497
    LgfContents(const LgfContents&);
2430 2498
    LgfContents& operator=(const LgfContents&);
2431 2499

	
2432 2500
  public:
2433 2501

	
2434 2502

	
2435
    /// \name Node sections
2503
    /// \name Node Sections
2436 2504
    /// @{
2437 2505

	
2438 2506
    /// \brief Gives back the number of node sections in the file.
2439 2507
    ///
2440 2508
    /// Gives back the number of node sections in the file.
2441 2509
    int nodeSectionNum() const {
2442 2510
      return _node_sections.size();
2443 2511
    }
2444 2512

	
2445 2513
    /// \brief Returns the node section name at the given position.
2446 2514
    ///
2447 2515
    /// Returns the node section name at the given position.
2448 2516
    const std::string& nodeSection(int i) const {
2449 2517
      return _node_sections[i];
2450 2518
    }
2451 2519

	
2452 2520
    /// \brief Gives back the node maps for the given section.
2453 2521
    ///
2454 2522
    /// Gives back the node maps for the given section.
2455 2523
    const std::vector<std::string>& nodeMapNames(int i) const {
2456 2524
      return _node_maps[i];
2457 2525
    }
2458 2526

	
2459 2527
    /// @}
2460 2528

	
2461
    /// \name Arc/Edge sections
2529
    /// \name Arc/Edge Sections
2462 2530
    /// @{
2463 2531

	
2464 2532
    /// \brief Gives back the number of arc/edge sections in the file.
2465 2533
    ///
2466 2534
    /// Gives back the number of arc/edge sections in the file.
2467 2535
    /// \note It is synonym of \c edgeSectionNum().
2468 2536
    int arcSectionNum() const {
2469 2537
      return _edge_sections.size();
2470 2538
    }
2471 2539

	
2472 2540
    /// \brief Returns the arc/edge section name at the given position.
2473 2541
    ///
2474 2542
    /// Returns the arc/edge section name at the given position.
2475 2543
    /// \note It is synonym of \c edgeSection().
2476 2544
    const std::string& arcSection(int i) const {
2477 2545
      return _edge_sections[i];
2478 2546
    }
2479 2547

	
2480 2548
    /// \brief Gives back the arc/edge maps for the given section.
2481 2549
    ///
2482 2550
    /// Gives back the arc/edge maps for the given section.
2483 2551
    /// \note It is synonym of \c edgeMapNames().
2484 2552
    const std::vector<std::string>& arcMapNames(int i) const {
2485 2553
      return _edge_maps[i];
2486 2554
    }
2487 2555

	
2488 2556
    /// @}
2489 2557

	
2490 2558
    /// \name Synonyms
2491 2559
    /// @{
2492 2560

	
2493 2561
    /// \brief Gives back the number of arc/edge sections in the file.
2494 2562
    ///
2495 2563
    /// Gives back the number of arc/edge sections in the file.
2496 2564
    /// \note It is synonym of \c arcSectionNum().
2497 2565
    int edgeSectionNum() const {
2498 2566
      return _edge_sections.size();
2499 2567
    }
2500 2568

	
2501 2569
    /// \brief Returns the section name at the given position.
2502 2570
    ///
2503 2571
    /// Returns the section name at the given position.
2504 2572
    /// \note It is synonym of \c arcSection().
2505 2573
    const std::string& edgeSection(int i) const {
2506 2574
      return _edge_sections[i];
2507 2575
    }
2508 2576

	
2509 2577
    /// \brief Gives back the edge maps for the given section.
2510 2578
    ///
2511 2579
    /// Gives back the edge maps for the given section.
2512 2580
    /// \note It is synonym of \c arcMapNames().
2513 2581
    const std::vector<std::string>& edgeMapNames(int i) const {
2514 2582
      return _edge_maps[i];
2515 2583
    }
2516 2584

	
2517 2585
    /// @}
2518 2586

	
2519
    /// \name Attribute sections
2587
    /// \name Attribute Sections
2520 2588
    /// @{
2521 2589

	
2522 2590
    /// \brief Gives back the number of attribute sections in the file.
2523 2591
    ///
2524 2592
    /// Gives back the number of attribute sections in the file.
2525 2593
    int attributeSectionNum() const {
2526 2594
      return _attribute_sections.size();
2527 2595
    }
2528 2596

	
2529 2597
    /// \brief Returns the attribute section name at the given position.
2530 2598
    ///
2531 2599
    /// Returns the attribute section name at the given position.
2532 2600
    const std::string& attributeSectionNames(int i) const {
2533 2601
      return _attribute_sections[i];
2534 2602
    }
2535 2603

	
2536 2604
    /// \brief Gives back the attributes for the given section.
2537 2605
    ///
2538 2606
    /// Gives back the attributes for the given section.
2539 2607
    const std::vector<std::string>& attributes(int i) const {
2540 2608
      return _attributes[i];
2541 2609
    }
2542 2610

	
2543 2611
    /// @}
2544 2612

	
2545
    /// \name Extra sections
2613
    /// \name Extra Sections
2546 2614
    /// @{
2547 2615

	
2548 2616
    /// \brief Gives back the number of extra sections in the file.
2549 2617
    ///
2550 2618
    /// Gives back the number of extra sections in the file.
2551 2619
    int extraSectionNum() const {
2552 2620
      return _extra_sections.size();
2553 2621
    }
2554 2622

	
2555 2623
    /// \brief Returns the extra section type at the given position.
2556 2624
    ///
2557 2625
    /// Returns the section type at the given position.
2558 2626
    const std::string& extraSection(int i) const {
2559 2627
      return _extra_sections[i];
2560 2628
    }
2561 2629

	
2562 2630
    /// @}
2563 2631

	
2564 2632
  private:
2565 2633

	
2566 2634
    bool readLine() {
2567 2635
      std::string str;
2568 2636
      while(++line_num, std::getline(*_is, str)) {
2569 2637
        line.clear(); line.str(str);
2570 2638
        char c;
2571 2639
        if (line >> std::ws >> c && c != '#') {
2572 2640
          line.putback(c);
2573 2641
          return true;
2574 2642
        }
2575 2643
      }
2576 2644
      return false;
2577 2645
    }
2578 2646

	
2579 2647
    bool readSuccess() {
2580 2648
      return static_cast<bool>(*_is);
2581 2649
    }
2582 2650

	
2583 2651
    void skipSection() {
2584 2652
      char c;
2585 2653
      while (readSuccess() && line >> c && c != '@') {
2586 2654
        readLine();
2587 2655
      }
2588
      line.putback(c);
2656
      if (readSuccess()) {
2657
        line.putback(c);
2658
      }
2589 2659
    }
2590 2660

	
2591 2661
    void readMaps(std::vector<std::string>& maps) {
2592 2662
      char c;
2593 2663
      if (!readLine() || !(line >> c) || c == '@') {
2594 2664
        if (readSuccess() && line) line.putback(c);
2595 2665
        return;
2596 2666
      }
2597 2667
      line.putback(c);
2598 2668
      std::string map;
2599 2669
      while (_reader_bits::readToken(line, map)) {
2600 2670
        maps.push_back(map);
2601 2671
      }
2602 2672
    }
2603 2673

	
2604 2674
    void readAttributes(std::vector<std::string>& attrs) {
2605 2675
      readLine();
2606 2676
      char c;
2607 2677
      while (readSuccess() && line >> c && c != '@') {
2608 2678
        line.putback(c);
2609 2679
        std::string attr;
2610 2680
        _reader_bits::readToken(line, attr);
2611 2681
        attrs.push_back(attr);
2612 2682
        readLine();
2613 2683
      }
2614 2684
      line.putback(c);
2615 2685
    }
2616 2686

	
2617 2687
  public:
2618 2688

	
2619
    /// \name Execution of the contents reader
2689
    /// \name Execution of the Contents Reader
2620 2690
    /// @{
2621 2691

	
2622 2692
    /// \brief Starts the reading
2623 2693
    ///
2624 2694
    /// This function starts the reading.
2625 2695
    void run() {
2626 2696

	
2627 2697
      readLine();
2628 2698
      skipSection();
2629 2699

	
2630 2700
      while (readSuccess()) {
2631 2701

	
2632 2702
        char c;
2633 2703
        line >> c;
2634 2704

	
2635 2705
        std::string section, caption;
2636 2706
        _reader_bits::readToken(line, section);
2637 2707
        _reader_bits::readToken(line, caption);
2638 2708

	
2639 2709
        if (section == "nodes") {
2640 2710
          _node_sections.push_back(caption);
2641 2711
          _node_maps.push_back(std::vector<std::string>());
2642 2712
          readMaps(_node_maps.back());
2643 2713
          readLine(); skipSection();
2644 2714
        } else if (section == "arcs" || section == "edges") {
2645 2715
          _edge_sections.push_back(caption);
2646 2716
          _arc_sections.push_back(section == "arcs");
2647 2717
          _edge_maps.push_back(std::vector<std::string>());
2648 2718
          readMaps(_edge_maps.back());
2649 2719
          readLine(); skipSection();
2650 2720
        } else if (section == "attributes") {
2651 2721
          _attribute_sections.push_back(caption);
2652 2722
          _attributes.push_back(std::vector<std::string>());
2653 2723
          readAttributes(_attributes.back());
2654 2724
        } else {
2655 2725
          _extra_sections.push_back(section);
2656 2726
          readLine(); skipSection();
2657 2727
        }
2658 2728
      }
2659 2729
    }
2660 2730

	
2661 2731
    /// @}
2662 2732

	
2663 2733
  };
2664 2734
}
2665 2735

	
2666 2736
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
///\ingroup lemon_io
20 20
///\file
21 21
///\brief \ref lgf-format "LEMON Graph Format" writer.
22 22

	
23 23

	
24 24
#ifndef LEMON_LGF_WRITER_H
25 25
#define LEMON_LGF_WRITER_H
26 26

	
27 27
#include <iostream>
28 28
#include <fstream>
29 29
#include <sstream>
30 30

	
31 31
#include <algorithm>
32 32

	
33 33
#include <vector>
34 34
#include <functional>
35 35

	
36 36
#include <lemon/core.h>
37 37
#include <lemon/maps.h>
38 38

	
39 39
#include <lemon/concept_check.h>
40 40
#include <lemon/concepts/maps.h>
41 41

	
42 42
namespace lemon {
43 43

	
44 44
  namespace _writer_bits {
45 45

	
46 46
    template <typename Value>
47 47
    struct DefaultConverter {
48 48
      std::string operator()(const Value& value) {
49 49
        std::ostringstream os;
50 50
        os << value;
51 51
        return os.str();
52 52
      }
53 53
    };
54 54

	
55 55
    template <typename T>
56 56
    bool operator<(const T&, const T&) {
57 57
      throw FormatError("Label map is not comparable");
58 58
    }
59 59

	
60 60
    template <typename _Map>
61 61
    class MapLess {
62 62
    public:
63 63
      typedef _Map Map;
64 64
      typedef typename Map::Key Item;
65 65

	
66 66
    private:
67 67
      const Map& _map;
68 68

	
69 69
    public:
70 70
      MapLess(const Map& map) : _map(map) {}
71 71

	
72 72
      bool operator()(const Item& left, const Item& right) {
73 73
        return _map[left] < _map[right];
74 74
      }
75 75
    };
76 76

	
77 77
    template <typename _Graph, bool _dir, typename _Map>
78 78
    class GraphArcMapLess {
79 79
    public:
80 80
      typedef _Map Map;
81 81
      typedef _Graph Graph;
82 82
      typedef typename Graph::Edge Item;
83 83

	
84 84
    private:
85 85
      const Graph& _graph;
86 86
      const Map& _map;
87 87

	
88 88
    public:
89 89
      GraphArcMapLess(const Graph& graph, const Map& map)
90 90
        : _graph(graph), _map(map) {}
91 91

	
92 92
      bool operator()(const Item& left, const Item& right) {
93 93
        return _map[_graph.direct(left, _dir)] <
94 94
          _map[_graph.direct(right, _dir)];
95 95
      }
96 96
    };
97 97

	
98 98
    template <typename _Item>
99 99
    class MapStorageBase {
100 100
    public:
101 101
      typedef _Item Item;
102 102

	
103 103
    public:
104 104
      MapStorageBase() {}
105 105
      virtual ~MapStorageBase() {}
106 106

	
107 107
      virtual std::string get(const Item& item) = 0;
108 108
      virtual void sort(std::vector<Item>&) = 0;
109 109
    };
110 110

	
111 111
    template <typename _Item, typename _Map,
112 112
              typename _Converter = DefaultConverter<typename _Map::Value> >
113 113
    class MapStorage : public MapStorageBase<_Item> {
114 114
    public:
115 115
      typedef _Map Map;
116 116
      typedef _Converter Converter;
117 117
      typedef _Item Item;
118 118

	
119 119
    private:
120 120
      const Map& _map;
121 121
      Converter _converter;
122 122

	
123 123
    public:
124 124
      MapStorage(const Map& map, const Converter& converter = Converter())
125 125
        : _map(map), _converter(converter) {}
126 126
      virtual ~MapStorage() {}
127 127

	
128 128
      virtual std::string get(const Item& item) {
129 129
        return _converter(_map[item]);
130 130
      }
131 131
      virtual void sort(std::vector<Item>& items) {
132 132
        MapLess<Map> less(_map);
133 133
        std::sort(items.begin(), items.end(), less);
134 134
      }
135 135
    };
136 136

	
137 137
    template <typename _Graph, bool _dir, typename _Map,
138 138
              typename _Converter = DefaultConverter<typename _Map::Value> >
139 139
    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
140 140
    public:
141 141
      typedef _Map Map;
142 142
      typedef _Converter Converter;
143 143
      typedef _Graph Graph;
144 144
      typedef typename Graph::Edge Item;
145 145
      static const bool dir = _dir;
146 146

	
147 147
    private:
148 148
      const Graph& _graph;
149 149
      const Map& _map;
150 150
      Converter _converter;
151 151

	
152 152
    public:
153 153
      GraphArcMapStorage(const Graph& graph, const Map& map,
154 154
                         const Converter& converter = Converter())
155 155
        : _graph(graph), _map(map), _converter(converter) {}
156 156
      virtual ~GraphArcMapStorage() {}
157 157

	
158 158
      virtual std::string get(const Item& item) {
159 159
        return _converter(_map[_graph.direct(item, dir)]);
160 160
      }
161 161
      virtual void sort(std::vector<Item>& items) {
162 162
        GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
163 163
        std::sort(items.begin(), items.end(), less);
164 164
      }
165 165
    };
166 166

	
167 167
    class ValueStorageBase {
168 168
    public:
169 169
      ValueStorageBase() {}
170 170
      virtual ~ValueStorageBase() {}
171 171

	
172 172
      virtual std::string get() = 0;
173 173
    };
174 174

	
175 175
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
176 176
    class ValueStorage : public ValueStorageBase {
177 177
    public:
178 178
      typedef _Value Value;
179 179
      typedef _Converter Converter;
180 180

	
181 181
    private:
182 182
      const Value& _value;
183 183
      Converter _converter;
184 184

	
185 185
    public:
186 186
      ValueStorage(const Value& value, const Converter& converter = Converter())
187 187
        : _value(value), _converter(converter) {}
188 188

	
189 189
      virtual std::string get() {
190 190
        return _converter(_value);
191 191
      }
192 192
    };
193 193

	
194 194
    template <typename Value>
195 195
    struct MapLookUpConverter {
196 196
      const std::map<Value, std::string>& _map;
197 197

	
198 198
      MapLookUpConverter(const std::map<Value, std::string>& map)
199 199
        : _map(map) {}
200 200

	
201 201
      std::string operator()(const Value& str) {
202 202
        typename std::map<Value, std::string>::const_iterator it =
203 203
          _map.find(str);
204 204
        if (it == _map.end()) {
205 205
          throw FormatError("Item not found");
206 206
        }
207 207
        return it->second;
208 208
      }
209 209
    };
210 210

	
211 211
    template <typename Graph>
212 212
    struct GraphArcLookUpConverter {
213 213
      const Graph& _graph;
214 214
      const std::map<typename Graph::Edge, std::string>& _map;
215 215

	
216 216
      GraphArcLookUpConverter(const Graph& graph,
217 217
                              const std::map<typename Graph::Edge,
218 218
                                             std::string>& map)
219 219
        : _graph(graph), _map(map) {}
220 220

	
221 221
      std::string operator()(const typename Graph::Arc& val) {
222 222
        typename std::map<typename Graph::Edge, std::string>
223 223
          ::const_iterator it = _map.find(val);
224 224
        if (it == _map.end()) {
225 225
          throw FormatError("Item not found");
226 226
        }
227 227
        return (_graph.direction(val) ? '+' : '-') + it->second;
228 228
      }
229 229
    };
230 230

	
231 231
    inline bool isWhiteSpace(char c) {
232 232
      return c == ' ' || c == '\t' || c == '\v' ||
233 233
        c == '\n' || c == '\r' || c == '\f';
234 234
    }
235 235

	
236 236
    inline bool isEscaped(char c) {
237 237
      return c == '\\' || c == '\"' || c == '\'' ||
238 238
        c == '\a' || c == '\b';
239 239
    }
240 240

	
241 241
    inline static void writeEscape(std::ostream& os, char c) {
242 242
      switch (c) {
243 243
      case '\\':
244 244
        os << "\\\\";
245 245
        return;
246 246
      case '\"':
247 247
        os << "\\\"";
248 248
        return;
249 249
      case '\a':
250 250
        os << "\\a";
251 251
        return;
252 252
      case '\b':
253 253
        os << "\\b";
254 254
        return;
255 255
      case '\f':
256 256
        os << "\\f";
257 257
        return;
258 258
      case '\r':
259 259
        os << "\\r";
260 260
        return;
261 261
      case '\n':
262 262
        os << "\\n";
263 263
        return;
264 264
      case '\t':
265 265
        os << "\\t";
266 266
        return;
267 267
      case '\v':
268 268
        os << "\\v";
269 269
        return;
270 270
      default:
271 271
        if (c < 0x20) {
272 272
          std::ios::fmtflags flags = os.flags();
273 273
          os << '\\' << std::oct << static_cast<int>(c);
274 274
          os.flags(flags);
275 275
        } else {
276 276
          os << c;
277 277
        }
278 278
        return;
279 279
      }
280 280
    }
281 281

	
282 282
    inline bool requireEscape(const std::string& str) {
283 283
      if (str.empty() || str[0] == '@') return true;
284 284
      std::istringstream is(str);
285 285
      char c;
286 286
      while (is.get(c)) {
287 287
        if (isWhiteSpace(c) || isEscaped(c)) {
288 288
          return true;
289 289
        }
290 290
      }
291 291
      return false;
292 292
    }
293 293

	
294 294
    inline std::ostream& writeToken(std::ostream& os, const std::string& str) {
295 295

	
296 296
      if (requireEscape(str)) {
297 297
        os << '\"';
298 298
        for (std::string::const_iterator it = str.begin();
299 299
             it != str.end(); ++it) {
300 300
          writeEscape(os, *it);
301 301
        }
302 302
        os << '\"';
303 303
      } else {
304 304
        os << str;
305 305
      }
306 306
      return os;
307 307
    }
308 308

	
309 309
    class Section {
310 310
    public:
311 311
      virtual ~Section() {}
312 312
      virtual void process(std::ostream& os) = 0;
313 313
    };
314 314

	
315 315
    template <typename Functor>
316 316
    class LineSection : public Section {
317 317
    private:
318 318

	
319 319
      Functor _functor;
320 320

	
321 321
    public:
322 322

	
323 323
      LineSection(const Functor& functor) : _functor(functor) {}
324 324
      virtual ~LineSection() {}
325 325

	
326 326
      virtual void process(std::ostream& os) {
327 327
        std::string line;
328 328
        while (!(line = _functor()).empty()) os << line << std::endl;
329 329
      }
330 330
    };
331 331

	
332 332
    template <typename Functor>
333 333
    class StreamSection : public Section {
334 334
    private:
335 335

	
336 336
      Functor _functor;
337 337

	
338 338
    public:
339 339

	
340 340
      StreamSection(const Functor& functor) : _functor(functor) {}
341 341
      virtual ~StreamSection() {}
342 342

	
343 343
      virtual void process(std::ostream& os) {
344 344
        _functor(os);
345 345
      }
346 346
    };
347 347

	
348 348
  }
349 349

	
350
  template <typename Digraph>
350
  template <typename DGR>
351 351
  class DigraphWriter;
352 352

	
353
  template <typename Digraph>
354
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
355
                                       std::ostream& os = std::cout);
356
  template <typename Digraph>
357
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
358
                                       const std::string& fn);
353
  template <typename TDGR>
354
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
355
                                   std::ostream& os = std::cout);
356
  template <typename TDGR>
357
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const std::string& fn);
359 358

	
360
  template <typename Digraph>
361
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
362
                                       const char* fn);
359
  template <typename TDGR>
360
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn);
363 361

	
364 362

	
365 363
  /// \ingroup lemon_io
366 364
  ///
367 365
  /// \brief \ref lgf-format "LGF" writer for directed graphs
368 366
  ///
369 367
  /// This utility writes an \ref lgf-format "LGF" file.
370 368
  ///
371 369
  /// The writing method does a batch processing. The user creates a
372 370
  /// writer object, then various writing rules can be added to the
373 371
  /// writer, and eventually the writing is executed with the \c run()
374 372
  /// member function. A map writing rule can be added to the writer
375 373
  /// with the \c nodeMap() or \c arcMap() members. An optional
376 374
  /// converter parameter can also be added as a standard functor
377 375
  /// converting from the value type of the map to \c std::string. If it
378 376
  /// is set, it will determine how the value type of the map is written to
379 377
  /// the output stream. If the functor is not set, then a default
380 378
  /// conversion will be used. The \c attribute(), \c node() and \c
381 379
  /// arc() functions are used to add attribute writing rules.
382 380
  ///
383 381
  ///\code
384
  /// DigraphWriter<Digraph>(digraph, std::cout).
382
  /// DigraphWriter<DGR>(digraph, std::cout).
385 383
  ///   nodeMap("coordinates", coord_map).
386 384
  ///   nodeMap("size", size).
387 385
  ///   nodeMap("title", title).
388 386
  ///   arcMap("capacity", cap_map).
389 387
  ///   node("source", src).
390 388
  ///   node("target", trg).
391 389
  ///   attribute("caption", caption).
392 390
  ///   run();
393 391
  ///\endcode
394 392
  ///
395 393
  ///
396 394
  /// By default, the writer does not write additional captions to the
397 395
  /// sections, but they can be give as an optional parameter of
398 396
  /// the \c nodes(), \c arcs() or \c
399 397
  /// attributes() functions.
400 398
  ///
401 399
  /// The \c skipNodes() and \c skipArcs() functions forbid the
402 400
  /// writing of the sections. If two arc sections should be written
403 401
  /// to the output, it can be done in two passes, the first pass
404 402
  /// writes the node section and the first arc section, then the
405 403
  /// second pass skips the node section and writes just the arc
406 404
  /// section to the stream. The output stream can be retrieved with
407 405
  /// the \c ostream() function, hence the second pass can append its
408 406
  /// output to the output of the first pass.
409
  template <typename _Digraph>
407
  template <typename DGR>
410 408
  class DigraphWriter {
411 409
  public:
412 410

	
413
    typedef _Digraph Digraph;
414
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
411
    typedef DGR Digraph;
412
    TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
415 413

	
416 414
  private:
417 415

	
418 416

	
419 417
    std::ostream* _os;
420 418
    bool local_os;
421 419

	
422
    const Digraph& _digraph;
420
    const DGR& _digraph;
423 421

	
424 422
    std::string _nodes_caption;
425 423
    std::string _arcs_caption;
426 424
    std::string _attributes_caption;
427 425

	
428 426
    typedef std::map<Node, std::string> NodeIndex;
429 427
    NodeIndex _node_index;
430 428
    typedef std::map<Arc, std::string> ArcIndex;
431 429
    ArcIndex _arc_index;
432 430

	
433 431
    typedef std::vector<std::pair<std::string,
434 432
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
435 433
    NodeMaps _node_maps;
436 434

	
437 435
    typedef std::vector<std::pair<std::string,
438 436
      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
439 437
    ArcMaps _arc_maps;
440 438

	
441 439
    typedef std::vector<std::pair<std::string,
442 440
      _writer_bits::ValueStorageBase*> > Attributes;
443 441
    Attributes _attributes;
444 442

	
445 443
    bool _skip_nodes;
446 444
    bool _skip_arcs;
447 445

	
448 446
  public:
449 447

	
450 448
    /// \brief Constructor
451 449
    ///
452 450
    /// Construct a directed graph writer, which writes to the given
453 451
    /// output stream.
454
    DigraphWriter(const Digraph& digraph, std::ostream& os = std::cout)
452
    DigraphWriter(const DGR& digraph, std::ostream& os = std::cout)
455 453
      : _os(&os), local_os(false), _digraph(digraph),
456 454
        _skip_nodes(false), _skip_arcs(false) {}
457 455

	
458 456
    /// \brief Constructor
459 457
    ///
460 458
    /// Construct a directed graph writer, which writes to the given
461 459
    /// output file.
462
    DigraphWriter(const Digraph& digraph, const std::string& fn)
460
    DigraphWriter(const DGR& digraph, const std::string& fn)
463 461
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
464 462
        _skip_nodes(false), _skip_arcs(false) {
465 463
      if (!(*_os)) {
466 464
        delete _os;
467 465
        throw IoError("Cannot write file", fn);
468 466
      }
469 467
    }
470 468

	
471 469
    /// \brief Constructor
472 470
    ///
473 471
    /// Construct a directed graph writer, which writes to the given
474 472
    /// output file.
475
    DigraphWriter(const Digraph& digraph, const char* fn)
473
    DigraphWriter(const DGR& digraph, const char* fn)
476 474
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
477 475
        _skip_nodes(false), _skip_arcs(false) {
478 476
      if (!(*_os)) {
479 477
        delete _os;
480 478
        throw IoError("Cannot write file", fn);
481 479
      }
482 480
    }
483 481

	
484 482
    /// \brief Destructor
485 483
    ~DigraphWriter() {
486 484
      for (typename NodeMaps::iterator it = _node_maps.begin();
487 485
           it != _node_maps.end(); ++it) {
488 486
        delete it->second;
489 487
      }
490 488

	
491 489
      for (typename ArcMaps::iterator it = _arc_maps.begin();
492 490
           it != _arc_maps.end(); ++it) {
493 491
        delete it->second;
494 492
      }
495 493

	
496 494
      for (typename Attributes::iterator it = _attributes.begin();
497 495
           it != _attributes.end(); ++it) {
498 496
        delete it->second;
499 497
      }
500 498

	
501 499
      if (local_os) {
502 500
        delete _os;
503 501
      }
504 502
    }
505 503

	
506 504
  private:
507 505

	
508
    template <typename DGR>
509
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph, 
510
                                            std::ostream& os);
511
    template <typename DGR>
512
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
513
                                            const std::string& fn);
514
    template <typename DGR>
515
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
516
                                            const char *fn);
506
    template <typename TDGR>
507
    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
508
                                             std::ostream& os);
509
    template <typename TDGR>
510
    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
511
                                             const std::string& fn);
512
    template <typename TDGR>
513
    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
514
                                             const char *fn);
517 515

	
518 516
    DigraphWriter(DigraphWriter& other)
519 517
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
520 518
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
521 519

	
522 520
      other._os = 0;
523 521
      other.local_os = false;
524 522

	
525 523
      _node_index.swap(other._node_index);
526 524
      _arc_index.swap(other._arc_index);
527 525

	
528 526
      _node_maps.swap(other._node_maps);
529 527
      _arc_maps.swap(other._arc_maps);
530 528
      _attributes.swap(other._attributes);
531 529

	
532 530
      _nodes_caption = other._nodes_caption;
533 531
      _arcs_caption = other._arcs_caption;
534 532
      _attributes_caption = other._attributes_caption;
535 533
    }
536 534

	
537 535
    DigraphWriter& operator=(const DigraphWriter&);
538 536

	
539 537
  public:
540 538

	
541
    /// \name Writing rules
539
    /// \name Writing Rules
542 540
    /// @{
543 541

	
544 542
    /// \brief Node map writing rule
545 543
    ///
546 544
    /// Add a node map writing rule to the writer.
547 545
    template <typename Map>
548 546
    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
549 547
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
550 548
      _writer_bits::MapStorageBase<Node>* storage =
551 549
        new _writer_bits::MapStorage<Node, Map>(map);
552 550
      _node_maps.push_back(std::make_pair(caption, storage));
553 551
      return *this;
554 552
    }
555 553

	
556 554
    /// \brief Node map writing rule
557 555
    ///
558 556
    /// Add a node map writing rule with specialized converter to the
559 557
    /// writer.
560 558
    template <typename Map, typename Converter>
561 559
    DigraphWriter& nodeMap(const std::string& caption, const Map& map,
562 560
                           const Converter& converter = Converter()) {
563 561
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
564 562
      _writer_bits::MapStorageBase<Node>* storage =
565 563
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
566 564
      _node_maps.push_back(std::make_pair(caption, storage));
567 565
      return *this;
568 566
    }
569 567

	
570 568
    /// \brief Arc map writing rule
571 569
    ///
572 570
    /// Add an arc map writing rule to the writer.
573 571
    template <typename Map>
574 572
    DigraphWriter& arcMap(const std::string& caption, const Map& map) {
575 573
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
576 574
      _writer_bits::MapStorageBase<Arc>* storage =
577 575
        new _writer_bits::MapStorage<Arc, Map>(map);
578 576
      _arc_maps.push_back(std::make_pair(caption, storage));
579 577
      return *this;
580 578
    }
581 579

	
582 580
    /// \brief Arc map writing rule
583 581
    ///
584 582
    /// Add an arc map writing rule with specialized converter to the
585 583
    /// writer.
586 584
    template <typename Map, typename Converter>
587 585
    DigraphWriter& arcMap(const std::string& caption, const Map& map,
588 586
                          const Converter& converter = Converter()) {
589 587
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
590 588
      _writer_bits::MapStorageBase<Arc>* storage =
591 589
        new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
592 590
      _arc_maps.push_back(std::make_pair(caption, storage));
593 591
      return *this;
594 592
    }
595 593

	
596 594
    /// \brief Attribute writing rule
597 595
    ///
598 596
    /// Add an attribute writing rule to the writer.
599 597
    template <typename Value>
600 598
    DigraphWriter& attribute(const std::string& caption, const Value& value) {
601 599
      _writer_bits::ValueStorageBase* storage =
602 600
        new _writer_bits::ValueStorage<Value>(value);
603 601
      _attributes.push_back(std::make_pair(caption, storage));
604 602
      return *this;
605 603
    }
606 604

	
607 605
    /// \brief Attribute writing rule
608 606
    ///
609 607
    /// Add an attribute writing rule with specialized converter to the
610 608
    /// writer.
611 609
    template <typename Value, typename Converter>
612 610
    DigraphWriter& attribute(const std::string& caption, const Value& value,
613 611
                             const Converter& converter = Converter()) {
614 612
      _writer_bits::ValueStorageBase* storage =
615 613
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
616 614
      _attributes.push_back(std::make_pair(caption, storage));
617 615
      return *this;
618 616
    }
619 617

	
620 618
    /// \brief Node writing rule
621 619
    ///
622 620
    /// Add a node writing rule to the writer.
623 621
    DigraphWriter& node(const std::string& caption, const Node& node) {
624 622
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
625 623
      Converter converter(_node_index);
626 624
      _writer_bits::ValueStorageBase* storage =
627 625
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
628 626
      _attributes.push_back(std::make_pair(caption, storage));
629 627
      return *this;
630 628
    }
631 629

	
632 630
    /// \brief Arc writing rule
633 631
    ///
634 632
    /// Add an arc writing rule to writer.
635 633
    DigraphWriter& arc(const std::string& caption, const Arc& arc) {
636 634
      typedef _writer_bits::MapLookUpConverter<Arc> Converter;
637 635
      Converter converter(_arc_index);
638 636
      _writer_bits::ValueStorageBase* storage =
639 637
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
640 638
      _attributes.push_back(std::make_pair(caption, storage));
641 639
      return *this;
642 640
    }
643 641

	
644
    /// \name Section captions
642
    /// \name Section Captions
645 643
    /// @{
646 644

	
647 645
    /// \brief Add an additional caption to the \c \@nodes section
648 646
    ///
649 647
    /// Add an additional caption to the \c \@nodes section.
650 648
    DigraphWriter& nodes(const std::string& caption) {
651 649
      _nodes_caption = caption;
652 650
      return *this;
653 651
    }
654 652

	
655 653
    /// \brief Add an additional caption to the \c \@arcs section
656 654
    ///
657 655
    /// Add an additional caption to the \c \@arcs section.
658 656
    DigraphWriter& arcs(const std::string& caption) {
659 657
      _arcs_caption = caption;
660 658
      return *this;
661 659
    }
662 660

	
663 661
    /// \brief Add an additional caption to the \c \@attributes section
664 662
    ///
665 663
    /// Add an additional caption to the \c \@attributes section.
666 664
    DigraphWriter& attributes(const std::string& caption) {
667 665
      _attributes_caption = caption;
668 666
      return *this;
669 667
    }
670 668

	
671
    /// \name Skipping section
669
    /// \name Skipping Section
672 670
    /// @{
673 671

	
674 672
    /// \brief Skip writing the node set
675 673
    ///
676 674
    /// The \c \@nodes section will not be written to the stream.
677 675
    DigraphWriter& skipNodes() {
678 676
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
679 677
      _skip_nodes = true;
680 678
      return *this;
681 679
    }
682 680

	
683 681
    /// \brief Skip writing arc set
684 682
    ///
685 683
    /// The \c \@arcs section will not be written to the stream.
686 684
    DigraphWriter& skipArcs() {
687 685
      LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
688 686
      _skip_arcs = true;
689 687
      return *this;
690 688
    }
691 689

	
692 690
    /// @}
693 691

	
694 692
  private:
695 693

	
696 694
    void writeNodes() {
697 695
      _writer_bits::MapStorageBase<Node>* label = 0;
698 696
      for (typename NodeMaps::iterator it = _node_maps.begin();
699 697
           it != _node_maps.end(); ++it) {
700 698
        if (it->first == "label") {
701 699
          label = it->second;
702 700
          break;
703 701
        }
704 702
      }
705 703

	
706 704
      *_os << "@nodes";
707 705
      if (!_nodes_caption.empty()) {
708 706
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
709 707
      }
710 708
      *_os << std::endl;
711 709

	
712 710
      if (label == 0) {
713 711
        *_os << "label" << '\t';
714 712
      }
715 713
      for (typename NodeMaps::iterator it = _node_maps.begin();
716 714
           it != _node_maps.end(); ++it) {
717 715
        _writer_bits::writeToken(*_os, it->first) << '\t';
718 716
      }
719 717
      *_os << std::endl;
720 718

	
721 719
      std::vector<Node> nodes;
722 720
      for (NodeIt n(_digraph); n != INVALID; ++n) {
723 721
        nodes.push_back(n);
724 722
      }
725 723

	
726 724
      if (label == 0) {
727
        IdMap<Digraph, Node> id_map(_digraph);
728
        _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
725
        IdMap<DGR, Node> id_map(_digraph);
726
        _writer_bits::MapLess<IdMap<DGR, Node> > id_less(id_map);
729 727
        std::sort(nodes.begin(), nodes.end(), id_less);
730 728
      } else {
731 729
        label->sort(nodes);
732 730
      }
733 731

	
734 732
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
735 733
        Node n = nodes[i];
736 734
        if (label == 0) {
737 735
          std::ostringstream os;
738 736
          os << _digraph.id(n);
739 737
          _writer_bits::writeToken(*_os, os.str());
740 738
          *_os << '\t';
741 739
          _node_index.insert(std::make_pair(n, os.str()));
742 740
        }
743 741
        for (typename NodeMaps::iterator it = _node_maps.begin();
744 742
             it != _node_maps.end(); ++it) {
745 743
          std::string value = it->second->get(n);
746 744
          _writer_bits::writeToken(*_os, value);
747 745
          if (it->first == "label") {
748 746
            _node_index.insert(std::make_pair(n, value));
749 747
          }
750 748
          *_os << '\t';
751 749
        }
752 750
        *_os << std::endl;
753 751
      }
754 752
    }
755 753

	
756 754
    void createNodeIndex() {
757 755
      _writer_bits::MapStorageBase<Node>* label = 0;
758 756
      for (typename NodeMaps::iterator it = _node_maps.begin();
759 757
           it != _node_maps.end(); ++it) {
760 758
        if (it->first == "label") {
761 759
          label = it->second;
762 760
          break;
763 761
        }
764 762
      }
765 763

	
766 764
      if (label == 0) {
767 765
        for (NodeIt n(_digraph); n != INVALID; ++n) {
768 766
          std::ostringstream os;
769 767
          os << _digraph.id(n);
770 768
          _node_index.insert(std::make_pair(n, os.str()));
771 769
        }
772 770
      } else {
773 771
        for (NodeIt n(_digraph); n != INVALID; ++n) {
774 772
          std::string value = label->get(n);
775 773
          _node_index.insert(std::make_pair(n, value));
776 774
        }
777 775
      }
778 776
    }
779 777

	
780 778
    void writeArcs() {
781 779
      _writer_bits::MapStorageBase<Arc>* label = 0;
782 780
      for (typename ArcMaps::iterator it = _arc_maps.begin();
783 781
           it != _arc_maps.end(); ++it) {
784 782
        if (it->first == "label") {
785 783
          label = it->second;
786 784
          break;
787 785
        }
788 786
      }
789 787

	
790 788
      *_os << "@arcs";
791 789
      if (!_arcs_caption.empty()) {
792 790
        _writer_bits::writeToken(*_os << ' ', _arcs_caption);
793 791
      }
794 792
      *_os << std::endl;
795 793

	
796 794
      *_os << '\t' << '\t';
797 795
      if (label == 0) {
798 796
        *_os << "label" << '\t';
799 797
      }
800 798
      for (typename ArcMaps::iterator it = _arc_maps.begin();
801 799
           it != _arc_maps.end(); ++it) {
802 800
        _writer_bits::writeToken(*_os, it->first) << '\t';
803 801
      }
804 802
      *_os << std::endl;
805 803

	
806 804
      std::vector<Arc> arcs;
807 805
      for (ArcIt n(_digraph); n != INVALID; ++n) {
808 806
        arcs.push_back(n);
809 807
      }
810 808

	
811 809
      if (label == 0) {
812
        IdMap<Digraph, Arc> id_map(_digraph);
813
        _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
810
        IdMap<DGR, Arc> id_map(_digraph);
811
        _writer_bits::MapLess<IdMap<DGR, Arc> > id_less(id_map);
814 812
        std::sort(arcs.begin(), arcs.end(), id_less);
815 813
      } else {
816 814
        label->sort(arcs);
817 815
      }
818 816

	
819 817
      for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
820 818
        Arc a = arcs[i];
821 819
        _writer_bits::writeToken(*_os, _node_index.
822 820
                                 find(_digraph.source(a))->second);
823 821
        *_os << '\t';
824 822
        _writer_bits::writeToken(*_os, _node_index.
825 823
                                 find(_digraph.target(a))->second);
826 824
        *_os << '\t';
827 825
        if (label == 0) {
828 826
          std::ostringstream os;
829 827
          os << _digraph.id(a);
830 828
          _writer_bits::writeToken(*_os, os.str());
831 829
          *_os << '\t';
832 830
          _arc_index.insert(std::make_pair(a, os.str()));
833 831
        }
834 832
        for (typename ArcMaps::iterator it = _arc_maps.begin();
835 833
             it != _arc_maps.end(); ++it) {
836 834
          std::string value = it->second->get(a);
837 835
          _writer_bits::writeToken(*_os, value);
838 836
          if (it->first == "label") {
839 837
            _arc_index.insert(std::make_pair(a, value));
840 838
          }
841 839
          *_os << '\t';
842 840
        }
843 841
        *_os << std::endl;
844 842
      }
845 843
    }
846 844

	
847 845
    void createArcIndex() {
848 846
      _writer_bits::MapStorageBase<Arc>* label = 0;
849 847
      for (typename ArcMaps::iterator it = _arc_maps.begin();
850 848
           it != _arc_maps.end(); ++it) {
851 849
        if (it->first == "label") {
852 850
          label = it->second;
853 851
          break;
854 852
        }
855 853
      }
856 854

	
857 855
      if (label == 0) {
858 856
        for (ArcIt a(_digraph); a != INVALID; ++a) {
859 857
          std::ostringstream os;
860 858
          os << _digraph.id(a);
861 859
          _arc_index.insert(std::make_pair(a, os.str()));
862 860
        }
863 861
      } else {
864 862
        for (ArcIt a(_digraph); a != INVALID; ++a) {
865 863
          std::string value = label->get(a);
866 864
          _arc_index.insert(std::make_pair(a, value));
867 865
        }
868 866
      }
869 867
    }
870 868

	
871 869
    void writeAttributes() {
872 870
      if (_attributes.empty()) return;
873 871
      *_os << "@attributes";
874 872
      if (!_attributes_caption.empty()) {
875 873
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
876 874
      }
877 875
      *_os << std::endl;
878 876
      for (typename Attributes::iterator it = _attributes.begin();
879 877
           it != _attributes.end(); ++it) {
880 878
        _writer_bits::writeToken(*_os, it->first) << ' ';
881 879
        _writer_bits::writeToken(*_os, it->second->get());
882 880
        *_os << std::endl;
883 881
      }
884 882
    }
885 883

	
886 884
  public:
887 885

	
888
    /// \name Execution of the writer
886
    /// \name Execution of the Writer
889 887
    /// @{
890 888

	
891 889
    /// \brief Start the batch processing
892 890
    ///
893 891
    /// This function starts the batch processing.
894 892
    void run() {
895 893
      if (!_skip_nodes) {
896 894
        writeNodes();
897 895
      } else {
898 896
        createNodeIndex();
899 897
      }
900 898
      if (!_skip_arcs) {
901 899
        writeArcs();
902 900
      } else {
903 901
        createArcIndex();
904 902
      }
905 903
      writeAttributes();
906 904
    }
907 905

	
908 906
    /// \brief Give back the stream of the writer
909 907
    ///
910 908
    /// Give back the stream of the writer.
911 909
    std::ostream& ostream() {
912 910
      return *_os;
913 911
    }
914 912

	
915 913
    /// @}
916 914
  };
917 915

	
916
  /// \ingroup lemon_io
917
  ///
918 918
  /// \brief Return a \ref DigraphWriter class
919 919
  ///
920
  /// This function just returns a \ref DigraphWriter class.
920
  /// This function just returns a \ref DigraphWriter class. 
921
  ///
922
  /// With this function a digraph can be write to a file or output
923
  /// stream in \ref lgf-format "LGF" format with several maps and
924
  /// attributes. For example, with the following code a network flow
925
  /// problem can be written to the standard output, i.e. a digraph
926
  /// with a \e capacity map on the arcs and \e source and \e target
927
  /// nodes:
928
  ///
929
  ///\code
930
  ///ListDigraph digraph;
931
  ///ListDigraph::ArcMap<int> cap(digraph);
932
  ///ListDigraph::Node src, trg;
933
  ///  // Setting the capacity map and source and target nodes
934
  ///digraphWriter(digraph, std::cout).
935
  ///  arcMap("capacity", cap).
936
  ///  node("source", src).
937
  ///  node("target", trg).
938
  ///  run();
939
  ///\endcode
940
  ///
941
  /// For a complete documentation, please see the \ref DigraphWriter
942
  /// class documentation.
943
  /// \warning Don't forget to put the \ref DigraphWriter::run() "run()"
944
  /// to the end of the parameter list.
921 945
  /// \relates DigraphWriter
922
  template <typename Digraph>
923
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
924
                                       std::ostream& os) {
925
    DigraphWriter<Digraph> tmp(digraph, os);
946
  /// \sa digraphWriter(const TDGR& digraph, const std::string& fn)
947
  /// \sa digraphWriter(const TDGR& digraph, const char* fn)
948
  template <typename TDGR>
949
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, std::ostream& os) {
950
    DigraphWriter<TDGR> tmp(digraph, os);
926 951
    return tmp;
927 952
  }
928 953

	
929 954
  /// \brief Return a \ref DigraphWriter class
930 955
  ///
931 956
  /// This function just returns a \ref DigraphWriter class.
932 957
  /// \relates DigraphWriter
933
  template <typename Digraph>
934
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
935
                                       const std::string& fn) {
936
    DigraphWriter<Digraph> tmp(digraph, fn);
958
  /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
959
  template <typename TDGR>
960
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
961
                                    const std::string& fn) {
962
    DigraphWriter<TDGR> tmp(digraph, fn);
937 963
    return tmp;
938 964
  }
939 965

	
940 966
  /// \brief Return a \ref DigraphWriter class
941 967
  ///
942 968
  /// This function just returns a \ref DigraphWriter class.
943 969
  /// \relates DigraphWriter
944
  template <typename Digraph>
945
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
946
                                       const char* fn) {
947
    DigraphWriter<Digraph> tmp(digraph, fn);
970
  /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
971
  template <typename TDGR>
972
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn) {
973
    DigraphWriter<TDGR> tmp(digraph, fn);
948 974
    return tmp;
949 975
  }
950 976

	
951
  template <typename Graph>
977
  template <typename GR>
952 978
  class GraphWriter;
953 979

	
954
  template <typename Graph>
955
  GraphWriter<Graph> graphWriter(const Graph& graph,
956
                                 std::ostream& os = std::cout);
957
  template <typename Graph>
958
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn);
959
  template <typename Graph>
960
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn);
980
  template <typename TGR>
981
  GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os = std::cout);
982
  template <typename TGR>
983
  GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn);
984
  template <typename TGR>
985
  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn);
961 986

	
962 987
  /// \ingroup lemon_io
963 988
  ///
964 989
  /// \brief \ref lgf-format "LGF" writer for directed graphs
965 990
  ///
966 991
  /// This utility writes an \ref lgf-format "LGF" file.
967 992
  ///
968 993
  /// It can be used almost the same way as \c DigraphWriter.
969 994
  /// The only difference is that this class can handle edges and
970 995
  /// edge maps as well as arcs and arc maps.
971 996
  ///
972 997
  /// The arc maps are written into the file as two columns, the
973 998
  /// caption of the columns are the name of the map prefixed with \c
974 999
  /// '+' and \c '-'. The arcs are written into the \c \@attributes
975 1000
  /// section as a \c '+' or a \c '-' prefix (depends on the direction
976 1001
  /// of the arc) and the label of corresponding edge.
977
  template <typename _Graph>
1002
  template <typename GR>
978 1003
  class GraphWriter {
979 1004
  public:
980 1005

	
981
    typedef _Graph Graph;
982
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1006
    typedef GR Graph;
1007
    TEMPLATE_GRAPH_TYPEDEFS(GR);
983 1008

	
984 1009
  private:
985 1010

	
986 1011

	
987 1012
    std::ostream* _os;
988 1013
    bool local_os;
989 1014

	
990
    const Graph& _graph;
1015
    const GR& _graph;
991 1016

	
992 1017
    std::string _nodes_caption;
993 1018
    std::string _edges_caption;
994 1019
    std::string _attributes_caption;
995 1020

	
996 1021
    typedef std::map<Node, std::string> NodeIndex;
997 1022
    NodeIndex _node_index;
998 1023
    typedef std::map<Edge, std::string> EdgeIndex;
999 1024
    EdgeIndex _edge_index;
1000 1025

	
1001 1026
    typedef std::vector<std::pair<std::string,
1002 1027
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
1003 1028
    NodeMaps _node_maps;
1004 1029

	
1005 1030
    typedef std::vector<std::pair<std::string,
1006 1031
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
1007 1032
    EdgeMaps _edge_maps;
1008 1033

	
1009 1034
    typedef std::vector<std::pair<std::string,
1010 1035
      _writer_bits::ValueStorageBase*> > Attributes;
1011 1036
    Attributes _attributes;
1012 1037

	
1013 1038
    bool _skip_nodes;
1014 1039
    bool _skip_edges;
1015 1040

	
1016 1041
  public:
1017 1042

	
1018 1043
    /// \brief Constructor
1019 1044
    ///
1020 1045
    /// Construct a directed graph writer, which writes to the given
1021 1046
    /// output stream.
1022
    GraphWriter(const Graph& graph, std::ostream& os = std::cout)
1047
    GraphWriter(const GR& graph, std::ostream& os = std::cout)
1023 1048
      : _os(&os), local_os(false), _graph(graph),
1024 1049
        _skip_nodes(false), _skip_edges(false) {}
1025 1050

	
1026 1051
    /// \brief Constructor
1027 1052
    ///
1028 1053
    /// Construct a directed graph writer, which writes to the given
1029 1054
    /// output file.
1030
    GraphWriter(const Graph& graph, const std::string& fn)
1055
    GraphWriter(const GR& graph, const std::string& fn)
1031 1056
      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
1032 1057
        _skip_nodes(false), _skip_edges(false) {
1033 1058
      if (!(*_os)) {
1034 1059
        delete _os;
1035 1060
        throw IoError("Cannot write file", fn);
1036 1061
      }
1037 1062
    }
1038 1063

	
1039 1064
    /// \brief Constructor
1040 1065
    ///
1041 1066
    /// Construct a directed graph writer, which writes to the given
1042 1067
    /// output file.
1043
    GraphWriter(const Graph& graph, const char* fn)
1068
    GraphWriter(const GR& graph, const char* fn)
1044 1069
      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
1045 1070
        _skip_nodes(false), _skip_edges(false) {
1046 1071
      if (!(*_os)) {
1047 1072
        delete _os;
1048 1073
        throw IoError("Cannot write file", fn);
1049 1074
      }
1050 1075
    }
1051 1076

	
1052 1077
    /// \brief Destructor
1053 1078
    ~GraphWriter() {
1054 1079
      for (typename NodeMaps::iterator it = _node_maps.begin();
1055 1080
           it != _node_maps.end(); ++it) {
1056 1081
        delete it->second;
1057 1082
      }
1058 1083

	
1059 1084
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1060 1085
           it != _edge_maps.end(); ++it) {
1061 1086
        delete it->second;
1062 1087
      }
1063 1088

	
1064 1089
      for (typename Attributes::iterator it = _attributes.begin();
1065 1090
           it != _attributes.end(); ++it) {
1066 1091
        delete it->second;
1067 1092
      }
1068 1093

	
1069 1094
      if (local_os) {
1070 1095
        delete _os;
1071 1096
      }
1072 1097
    }
1073 1098

	
1074 1099
  private:
1075 1100

	
1076
    template <typename GR>
1077
    friend GraphWriter<GR> graphWriter(const GR& graph,
1078
                                       std::ostream& os);
1079
    template <typename GR>
1080
    friend GraphWriter<GR> graphWriter(const GR& graph,
1081
                                       const std::string& fn);
1082
    template <typename GR>
1083
    friend GraphWriter<GR> graphWriter(const GR& graph,
1084
                                       const char *fn);
1101
    template <typename TGR>
1102
    friend GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os);
1103
    template <typename TGR>
1104
    friend GraphWriter<TGR> graphWriter(const TGR& graph, 
1105
                                        const std::string& fn);
1106
    template <typename TGR>
1107
    friend GraphWriter<TGR> graphWriter(const TGR& graph, const char *fn);
1085 1108
    
1086 1109
    GraphWriter(GraphWriter& other)
1087 1110
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
1088 1111
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1089 1112

	
1090 1113
      other._os = 0;
1091 1114
      other.local_os = false;
1092 1115

	
1093 1116
      _node_index.swap(other._node_index);
1094 1117
      _edge_index.swap(other._edge_index);
1095 1118

	
1096 1119
      _node_maps.swap(other._node_maps);
1097 1120
      _edge_maps.swap(other._edge_maps);
1098 1121
      _attributes.swap(other._attributes);
1099 1122

	
1100 1123
      _nodes_caption = other._nodes_caption;
1101 1124
      _edges_caption = other._edges_caption;
1102 1125
      _attributes_caption = other._attributes_caption;
1103 1126
    }
1104 1127

	
1105 1128
    GraphWriter& operator=(const GraphWriter&);
1106 1129

	
1107 1130
  public:
1108 1131

	
1109
    /// \name Writing rules
1132
    /// \name Writing Rules
1110 1133
    /// @{
1111 1134

	
1112 1135
    /// \brief Node map writing rule
1113 1136
    ///
1114 1137
    /// Add a node map writing rule to the writer.
1115 1138
    template <typename Map>
1116 1139
    GraphWriter& nodeMap(const std::string& caption, const Map& map) {
1117 1140
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1118 1141
      _writer_bits::MapStorageBase<Node>* storage =
1119 1142
        new _writer_bits::MapStorage<Node, Map>(map);
1120 1143
      _node_maps.push_back(std::make_pair(caption, storage));
1121 1144
      return *this;
1122 1145
    }
1123 1146

	
1124 1147
    /// \brief Node map writing rule
1125 1148
    ///
1126 1149
    /// Add a node map writing rule with specialized converter to the
1127 1150
    /// writer.
1128 1151
    template <typename Map, typename Converter>
1129 1152
    GraphWriter& nodeMap(const std::string& caption, const Map& map,
1130 1153
                           const Converter& converter = Converter()) {
1131 1154
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1132 1155
      _writer_bits::MapStorageBase<Node>* storage =
1133 1156
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1134 1157
      _node_maps.push_back(std::make_pair(caption, storage));
1135 1158
      return *this;
1136 1159
    }
1137 1160

	
1138 1161
    /// \brief Edge map writing rule
1139 1162
    ///
1140 1163
    /// Add an edge map writing rule to the writer.
1141 1164
    template <typename Map>
1142 1165
    GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1143 1166
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1144 1167
      _writer_bits::MapStorageBase<Edge>* storage =
1145 1168
        new _writer_bits::MapStorage<Edge, Map>(map);
1146 1169
      _edge_maps.push_back(std::make_pair(caption, storage));
1147 1170
      return *this;
1148 1171
    }
1149 1172

	
1150 1173
    /// \brief Edge map writing rule
1151 1174
    ///
1152 1175
    /// Add an edge map writing rule with specialized converter to the
1153 1176
    /// writer.
1154 1177
    template <typename Map, typename Converter>
1155 1178
    GraphWriter& edgeMap(const std::string& caption, const Map& map,
1156 1179
                          const Converter& converter = Converter()) {
1157 1180
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1158 1181
      _writer_bits::MapStorageBase<Edge>* storage =
1159 1182
        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1160 1183
      _edge_maps.push_back(std::make_pair(caption, storage));
1161 1184
      return *this;
1162 1185
    }
1163 1186

	
1164 1187
    /// \brief Arc map writing rule
1165 1188
    ///
1166 1189
    /// Add an arc map writing rule to the writer.
1167 1190
    template <typename Map>
1168 1191
    GraphWriter& arcMap(const std::string& caption, const Map& map) {
1169 1192
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1170 1193
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1171
        new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1194
        new _writer_bits::GraphArcMapStorage<GR, true, Map>(_graph, map);
1172 1195
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1173 1196
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1174
        new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1197
        new _writer_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
1175 1198
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1176 1199
      return *this;
1177 1200
    }
1178 1201

	
1179 1202
    /// \brief Arc map writing rule
1180 1203
    ///
1181 1204
    /// Add an arc map writing rule with specialized converter to the
1182 1205
    /// writer.
1183 1206
    template <typename Map, typename Converter>
1184 1207
    GraphWriter& arcMap(const std::string& caption, const Map& map,
1185 1208
                          const Converter& converter = Converter()) {
1186 1209
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1187 1210
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1188
        new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1211
        new _writer_bits::GraphArcMapStorage<GR, true, Map, Converter>
1189 1212
        (_graph, map, converter);
1190 1213
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1191 1214
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1192
        new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1215
        new _writer_bits::GraphArcMapStorage<GR, false, Map, Converter>
1193 1216
        (_graph, map, converter);
1194 1217
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1195 1218
      return *this;
1196 1219
    }
1197 1220

	
1198 1221
    /// \brief Attribute writing rule
1199 1222
    ///
1200 1223
    /// Add an attribute writing rule to the writer.
1201 1224
    template <typename Value>
1202 1225
    GraphWriter& attribute(const std::string& caption, const Value& value) {
1203 1226
      _writer_bits::ValueStorageBase* storage =
1204 1227
        new _writer_bits::ValueStorage<Value>(value);
1205 1228
      _attributes.push_back(std::make_pair(caption, storage));
1206 1229
      return *this;
1207 1230
    }
1208 1231

	
1209 1232
    /// \brief Attribute writing rule
1210 1233
    ///
1211 1234
    /// Add an attribute writing rule with specialized converter to the
1212 1235
    /// writer.
1213 1236
    template <typename Value, typename Converter>
1214 1237
    GraphWriter& attribute(const std::string& caption, const Value& value,
1215 1238
                             const Converter& converter = Converter()) {
1216 1239
      _writer_bits::ValueStorageBase* storage =
1217 1240
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1218 1241
      _attributes.push_back(std::make_pair(caption, storage));
1219 1242
      return *this;
1220 1243
    }
1221 1244

	
1222 1245
    /// \brief Node writing rule
1223 1246
    ///
1224 1247
    /// Add a node writing rule to the writer.
1225 1248
    GraphWriter& node(const std::string& caption, const Node& node) {
1226 1249
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
1227 1250
      Converter converter(_node_index);
1228 1251
      _writer_bits::ValueStorageBase* storage =
1229 1252
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1230 1253
      _attributes.push_back(std::make_pair(caption, storage));
1231 1254
      return *this;
1232 1255
    }
1233 1256

	
1234 1257
    /// \brief Edge writing rule
1235 1258
    ///
1236 1259
    /// Add an edge writing rule to writer.
1237 1260
    GraphWriter& edge(const std::string& caption, const Edge& edge) {
1238 1261
      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1239 1262
      Converter converter(_edge_index);
1240 1263
      _writer_bits::ValueStorageBase* storage =
1241 1264
        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1242 1265
      _attributes.push_back(std::make_pair(caption, storage));
1243 1266
      return *this;
1244 1267
    }
1245 1268

	
1246 1269
    /// \brief Arc writing rule
1247 1270
    ///
1248 1271
    /// Add an arc writing rule to writer.
1249 1272
    GraphWriter& arc(const std::string& caption, const Arc& arc) {
1250
      typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1273
      typedef _writer_bits::GraphArcLookUpConverter<GR> Converter;
1251 1274
      Converter converter(_graph, _edge_index);
1252 1275
      _writer_bits::ValueStorageBase* storage =
1253 1276
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1254 1277
      _attributes.push_back(std::make_pair(caption, storage));
1255 1278
      return *this;
1256 1279
    }
1257 1280

	
1258
    /// \name Section captions
1281
    /// \name Section Captions
1259 1282
    /// @{
1260 1283

	
1261 1284
    /// \brief Add an additional caption to the \c \@nodes section
1262 1285
    ///
1263 1286
    /// Add an additional caption to the \c \@nodes section.
1264 1287
    GraphWriter& nodes(const std::string& caption) {
1265 1288
      _nodes_caption = caption;
1266 1289
      return *this;
1267 1290
    }
1268 1291

	
1269 1292
    /// \brief Add an additional caption to the \c \@arcs section
1270 1293
    ///
1271 1294
    /// Add an additional caption to the \c \@arcs section.
1272 1295
    GraphWriter& edges(const std::string& caption) {
1273 1296
      _edges_caption = caption;
1274 1297
      return *this;
1275 1298
    }
1276 1299

	
1277 1300
    /// \brief Add an additional caption to the \c \@attributes section
1278 1301
    ///
1279 1302
    /// Add an additional caption to the \c \@attributes section.
1280 1303
    GraphWriter& attributes(const std::string& caption) {
1281 1304
      _attributes_caption = caption;
1282 1305
      return *this;
1283 1306
    }
1284 1307

	
1285
    /// \name Skipping section
1308
    /// \name Skipping Section
1286 1309
    /// @{
1287 1310

	
1288 1311
    /// \brief Skip writing the node set
1289 1312
    ///
1290 1313
    /// The \c \@nodes section will not be written to the stream.
1291 1314
    GraphWriter& skipNodes() {
1292 1315
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1293 1316
      _skip_nodes = true;
1294 1317
      return *this;
1295 1318
    }
1296 1319

	
1297 1320
    /// \brief Skip writing edge set
1298 1321
    ///
1299 1322
    /// The \c \@edges section will not be written to the stream.
1300 1323
    GraphWriter& skipEdges() {
1301 1324
      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1302 1325
      _skip_edges = true;
1303 1326
      return *this;
1304 1327
    }
1305 1328

	
1306 1329
    /// @}
1307 1330

	
1308 1331
  private:
1309 1332

	
1310 1333
    void writeNodes() {
1311 1334
      _writer_bits::MapStorageBase<Node>* label = 0;
1312 1335
      for (typename NodeMaps::iterator it = _node_maps.begin();
1313 1336
           it != _node_maps.end(); ++it) {
1314 1337
        if (it->first == "label") {
1315 1338
          label = it->second;
1316 1339
          break;
1317 1340
        }
1318 1341
      }
1319 1342

	
1320 1343
      *_os << "@nodes";
1321 1344
      if (!_nodes_caption.empty()) {
1322 1345
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1323 1346
      }
1324 1347
      *_os << std::endl;
1325 1348

	
1326 1349
      if (label == 0) {
1327 1350
        *_os << "label" << '\t';
1328 1351
      }
1329 1352
      for (typename NodeMaps::iterator it = _node_maps.begin();
1330 1353
           it != _node_maps.end(); ++it) {
1331 1354
        _writer_bits::writeToken(*_os, it->first) << '\t';
1332 1355
      }
1333 1356
      *_os << std::endl;
1334 1357

	
1335 1358
      std::vector<Node> nodes;
1336 1359
      for (NodeIt n(_graph); n != INVALID; ++n) {
1337 1360
        nodes.push_back(n);
1338 1361
      }
1339 1362

	
1340 1363
      if (label == 0) {
1341
        IdMap<Graph, Node> id_map(_graph);
1342
        _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1364
        IdMap<GR, Node> id_map(_graph);
1365
        _writer_bits::MapLess<IdMap<GR, Node> > id_less(id_map);
1343 1366
        std::sort(nodes.begin(), nodes.end(), id_less);
1344 1367
      } else {
1345 1368
        label->sort(nodes);
1346 1369
      }
1347 1370

	
1348 1371
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1349 1372
        Node n = nodes[i];
1350 1373
        if (label == 0) {
1351 1374
          std::ostringstream os;
1352 1375
          os << _graph.id(n);
1353 1376
          _writer_bits::writeToken(*_os, os.str());
1354 1377
          *_os << '\t';
1355 1378
          _node_index.insert(std::make_pair(n, os.str()));
1356 1379
        }
1357 1380
        for (typename NodeMaps::iterator it = _node_maps.begin();
1358 1381
             it != _node_maps.end(); ++it) {
1359 1382
          std::string value = it->second->get(n);
1360 1383
          _writer_bits::writeToken(*_os, value);
1361 1384
          if (it->first == "label") {
1362 1385
            _node_index.insert(std::make_pair(n, value));
1363 1386
          }
1364 1387
          *_os << '\t';
1365 1388
        }
1366 1389
        *_os << std::endl;
1367 1390
      }
1368 1391
    }
1369 1392

	
1370 1393
    void createNodeIndex() {
1371 1394
      _writer_bits::MapStorageBase<Node>* label = 0;
1372 1395
      for (typename NodeMaps::iterator it = _node_maps.begin();
1373 1396
           it != _node_maps.end(); ++it) {
1374 1397
        if (it->first == "label") {
1375 1398
          label = it->second;
1376 1399
          break;
1377 1400
        }
1378 1401
      }
1379 1402

	
1380 1403
      if (label == 0) {
1381 1404
        for (NodeIt n(_graph); n != INVALID; ++n) {
1382 1405
          std::ostringstream os;
1383 1406
          os << _graph.id(n);
1384 1407
          _node_index.insert(std::make_pair(n, os.str()));
1385 1408
        }
1386 1409
      } else {
1387 1410
        for (NodeIt n(_graph); n != INVALID; ++n) {
1388 1411
          std::string value = label->get(n);
1389 1412
          _node_index.insert(std::make_pair(n, value));
1390 1413
        }
1391 1414
      }
1392 1415
    }
1393 1416

	
1394 1417
    void writeEdges() {
1395 1418
      _writer_bits::MapStorageBase<Edge>* label = 0;
1396 1419
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1397 1420
           it != _edge_maps.end(); ++it) {
1398 1421
        if (it->first == "label") {
1399 1422
          label = it->second;
1400 1423
          break;
1401 1424
        }
1402 1425
      }
1403 1426

	
1404 1427
      *_os << "@edges";
1405 1428
      if (!_edges_caption.empty()) {
1406 1429
        _writer_bits::writeToken(*_os << ' ', _edges_caption);
1407 1430
      }
1408 1431
      *_os << std::endl;
1409 1432

	
1410 1433
      *_os << '\t' << '\t';
1411 1434
      if (label == 0) {
1412 1435
        *_os << "label" << '\t';
1413 1436
      }
1414 1437
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1415 1438
           it != _edge_maps.end(); ++it) {
1416 1439
        _writer_bits::writeToken(*_os, it->first) << '\t';
1417 1440
      }
1418 1441
      *_os << std::endl;
1419 1442

	
1420 1443
      std::vector<Edge> edges;
1421 1444
      for (EdgeIt n(_graph); n != INVALID; ++n) {
1422 1445
        edges.push_back(n);
1423 1446
      }
1424 1447

	
1425 1448
      if (label == 0) {
1426
        IdMap<Graph, Edge> id_map(_graph);
1427
        _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1449
        IdMap<GR, Edge> id_map(_graph);
1450
        _writer_bits::MapLess<IdMap<GR, Edge> > id_less(id_map);
1428 1451
        std::sort(edges.begin(), edges.end(), id_less);
1429 1452
      } else {
1430 1453
        label->sort(edges);
1431 1454
      }
1432 1455

	
1433 1456
      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1434 1457
        Edge e = edges[i];
1435 1458
        _writer_bits::writeToken(*_os, _node_index.
1436 1459
                                 find(_graph.u(e))->second);
1437 1460
        *_os << '\t';
1438 1461
        _writer_bits::writeToken(*_os, _node_index.
1439 1462
                                 find(_graph.v(e))->second);
1440 1463
        *_os << '\t';
1441 1464
        if (label == 0) {
1442 1465
          std::ostringstream os;
1443 1466
          os << _graph.id(e);
1444 1467
          _writer_bits::writeToken(*_os, os.str());
1445 1468
          *_os << '\t';
1446 1469
          _edge_index.insert(std::make_pair(e, os.str()));
1447 1470
        }
1448 1471
        for (typename EdgeMaps::iterator it = _edge_maps.begin();
1449 1472
             it != _edge_maps.end(); ++it) {
1450 1473
          std::string value = it->second->get(e);
1451 1474
          _writer_bits::writeToken(*_os, value);
1452 1475
          if (it->first == "label") {
1453 1476
            _edge_index.insert(std::make_pair(e, value));
1454 1477
          }
1455 1478
          *_os << '\t';
1456 1479
        }
1457 1480
        *_os << std::endl;
1458 1481
      }
1459 1482
    }
1460 1483

	
1461 1484
    void createEdgeIndex() {
1462 1485
      _writer_bits::MapStorageBase<Edge>* label = 0;
1463 1486
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1464 1487
           it != _edge_maps.end(); ++it) {
1465 1488
        if (it->first == "label") {
1466 1489
          label = it->second;
1467 1490
          break;
1468 1491
        }
1469 1492
      }
1470 1493

	
1471 1494
      if (label == 0) {
1472 1495
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1473 1496
          std::ostringstream os;
1474 1497
          os << _graph.id(e);
1475 1498
          _edge_index.insert(std::make_pair(e, os.str()));
1476 1499
        }
1477 1500
      } else {
1478 1501
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1479 1502
          std::string value = label->get(e);
1480 1503
          _edge_index.insert(std::make_pair(e, value));
1481 1504
        }
1482 1505
      }
1483 1506
    }
1484 1507

	
1485 1508
    void writeAttributes() {
1486 1509
      if (_attributes.empty()) return;
1487 1510
      *_os << "@attributes";
1488 1511
      if (!_attributes_caption.empty()) {
1489 1512
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1490 1513
      }
1491 1514
      *_os << std::endl;
1492 1515
      for (typename Attributes::iterator it = _attributes.begin();
1493 1516
           it != _attributes.end(); ++it) {
1494 1517
        _writer_bits::writeToken(*_os, it->first) << ' ';
1495 1518
        _writer_bits::writeToken(*_os, it->second->get());
1496 1519
        *_os << std::endl;
1497 1520
      }
1498 1521
    }
1499 1522

	
1500 1523
  public:
1501 1524

	
1502
    /// \name Execution of the writer
1525
    /// \name Execution of the Writer
1503 1526
    /// @{
1504 1527

	
1505 1528
    /// \brief Start the batch processing
1506 1529
    ///
1507 1530
    /// This function starts the batch processing.
1508 1531
    void run() {
1509 1532
      if (!_skip_nodes) {
1510 1533
        writeNodes();
1511 1534
      } else {
1512 1535
        createNodeIndex();
1513 1536
      }
1514 1537
      if (!_skip_edges) {
1515 1538
        writeEdges();
1516 1539
      } else {
1517 1540
        createEdgeIndex();
1518 1541
      }
1519 1542
      writeAttributes();
1520 1543
    }
1521 1544

	
1522 1545
    /// \brief Give back the stream of the writer
1523 1546
    ///
1524 1547
    /// Give back the stream of the writer
1525 1548
    std::ostream& ostream() {
1526 1549
      return *_os;
1527 1550
    }
1528 1551

	
1529 1552
    /// @}
1530 1553
  };
1531 1554

	
1555
  /// \ingroup lemon_io
1556
  ///
1532 1557
  /// \brief Return a \ref GraphWriter class
1533 1558
  ///
1534
  /// This function just returns a \ref GraphWriter class.
1559
  /// This function just returns a \ref GraphWriter class. 
1560
  ///
1561
  /// With this function a graph can be write to a file or output
1562
  /// stream in \ref lgf-format "LGF" format with several maps and
1563
  /// attributes. For example, with the following code a weighted
1564
  /// matching problem can be written to the standard output, i.e. a
1565
  /// graph with a \e weight map on the edges:
1566
  ///
1567
  ///\code
1568
  ///ListGraph graph;
1569
  ///ListGraph::EdgeMap<int> weight(graph);
1570
  ///  // Setting the weight map
1571
  ///graphWriter(graph, std::cout).
1572
  ///  edgeMap("weight", weight).
1573
  ///  run();
1574
  ///\endcode
1575
  ///
1576
  /// For a complete documentation, please see the \ref GraphWriter
1577
  /// class documentation.
1578
  /// \warning Don't forget to put the \ref GraphWriter::run() "run()"
1579
  /// to the end of the parameter list.
1535 1580
  /// \relates GraphWriter
1536
  template <typename Graph>
1537
  GraphWriter<Graph> graphWriter(const Graph& graph,
1538
                                 std::ostream& os) {
1539
    GraphWriter<Graph> tmp(graph, os);
1581
  /// \sa graphWriter(const TGR& graph, const std::string& fn)
1582
  /// \sa graphWriter(const TGR& graph, const char* fn)
1583
  template <typename TGR>
1584
  GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os) {
1585
    GraphWriter<TGR> tmp(graph, os);
1540 1586
    return tmp;
1541 1587
  }
1542 1588

	
1543 1589
  /// \brief Return a \ref GraphWriter class
1544 1590
  ///
1545 1591
  /// This function just returns a \ref GraphWriter class.
1546 1592
  /// \relates GraphWriter
1547
  template <typename Graph>
1548
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
1549
    GraphWriter<Graph> tmp(graph, fn);
1593
  /// \sa graphWriter(const TGR& graph, std::ostream& os)
1594
  template <typename TGR>
1595
  GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn) {
1596
    GraphWriter<TGR> tmp(graph, fn);
1550 1597
    return tmp;
1551 1598
  }
1552 1599

	
1553 1600
  /// \brief Return a \ref GraphWriter class
1554 1601
  ///
1555 1602
  /// This function just returns a \ref GraphWriter class.
1556 1603
  /// \relates GraphWriter
1557
  template <typename Graph>
1558
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
1559
    GraphWriter<Graph> tmp(graph, fn);
1604
  /// \sa graphWriter(const TGR& graph, std::ostream& os)
1605
  template <typename TGR>
1606
  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) {
1607
    GraphWriter<TGR> tmp(graph, fn);
1560 1608
    return tmp;
1561 1609
  }
1562 1610

	
1563 1611
  class SectionWriter;
1564 1612

	
1565 1613
  SectionWriter sectionWriter(std::istream& is);
1566 1614
  SectionWriter sectionWriter(const std::string& fn);
1567 1615
  SectionWriter sectionWriter(const char* fn);
1568 1616

	
1569 1617
  /// \ingroup lemon_io
1570 1618
  ///
1571 1619
  /// \brief Section writer class
1572 1620
  ///
1573 1621
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
1574 1622
  /// which contain any data in arbitrary format. Such sections can be
1575 1623
  /// written with this class. A writing rule can be added to the
1576 1624
  /// class with two different functions. With the \c sectionLines()
1577 1625
  /// function a generator can write the section line-by-line, while
1578 1626
  /// with the \c sectionStream() member the section can be written to
1579 1627
  /// an output stream.
1580 1628
  class SectionWriter {
1581 1629
  private:
1582 1630

	
1583 1631
    std::ostream* _os;
1584 1632
    bool local_os;
1585 1633

	
1586 1634
    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
1587 1635
    Sections;
1588 1636

	
1589 1637
    Sections _sections;
1590 1638

	
1591 1639
  public:
1592 1640

	
1593 1641
    /// \brief Constructor
1594 1642
    ///
1595 1643
    /// Construct a section writer, which writes to the given output
1596 1644
    /// stream.
1597 1645
    SectionWriter(std::ostream& os)
1598 1646
      : _os(&os), local_os(false) {}
1599 1647

	
1600 1648
    /// \brief Constructor
1601 1649
    ///
1602 1650
    /// Construct a section writer, which writes into the given file.
1603 1651
    SectionWriter(const std::string& fn)
1604 1652
      : _os(new std::ofstream(fn.c_str())), local_os(true) {
1605 1653
      if (!(*_os)) {
1606 1654
        delete _os;
1607 1655
        throw IoError("Cannot write file", fn);
1608 1656
      }
1609 1657
    }
1610 1658

	
1611 1659
    /// \brief Constructor
1612 1660
    ///
1613 1661
    /// Construct a section writer, which writes into the given file.
1614 1662
    SectionWriter(const char* fn)
1615 1663
      : _os(new std::ofstream(fn)), local_os(true) {
1616 1664
      if (!(*_os)) {
1617 1665
        delete _os;
1618 1666
        throw IoError("Cannot write file", fn);
1619 1667
      }
1620 1668
    }
1621 1669

	
1622 1670
    /// \brief Destructor
1623 1671
    ~SectionWriter() {
1624 1672
      for (Sections::iterator it = _sections.begin();
1625 1673
           it != _sections.end(); ++it) {
1626 1674
        delete it->second;
1627 1675
      }
1628 1676

	
1629 1677
      if (local_os) {
1630 1678
        delete _os;
1631 1679
      }
1632 1680

	
1633 1681
    }
1634 1682

	
1635 1683
  private:
1636 1684

	
1637 1685
    friend SectionWriter sectionWriter(std::ostream& os);
1638 1686
    friend SectionWriter sectionWriter(const std::string& fn);
1639 1687
    friend SectionWriter sectionWriter(const char* fn);
1640 1688

	
1641 1689
    SectionWriter(SectionWriter& other)
1642 1690
      : _os(other._os), local_os(other.local_os) {
1643 1691

	
1644 1692
      other._os = 0;
1645 1693
      other.local_os = false;
1646 1694

	
1647 1695
      _sections.swap(other._sections);
1648 1696
    }
1649 1697

	
1650 1698
    SectionWriter& operator=(const SectionWriter&);
1651 1699

	
1652 1700
  public:
1653 1701

	
1654
    /// \name Section writers
1702
    /// \name Section Writers
1655 1703
    /// @{
1656 1704

	
1657 1705
    /// \brief Add a section writer with line oriented writing
1658 1706
    ///
1659 1707
    /// The first parameter is the type descriptor of the section, the
1660 1708
    /// second is a generator with std::string values. At the writing
1661 1709
    /// process, the returned \c std::string will be written into the
1662 1710
    /// output file until it is an empty string.
1663 1711
    ///
1664 1712
    /// For example, an integer vector is written into a section.
1665 1713
    ///\code
1666 1714
    ///  @numbers
1667 1715
    ///  12 45 23 78
1668 1716
    ///  4 28 38 28
1669 1717
    ///  23 6 16
1670 1718
    ///\endcode
1671 1719
    ///
1672 1720
    /// The generator is implemented as a struct.
1673 1721
    ///\code
1674 1722
    ///  struct NumberSection {
1675 1723
    ///    std::vector<int>::const_iterator _it, _end;
1676 1724
    ///    NumberSection(const std::vector<int>& data)
1677 1725
    ///      : _it(data.begin()), _end(data.end()) {}
1678 1726
    ///    std::string operator()() {
1679 1727
    ///      int rem_in_line = 4;
1680 1728
    ///      std::ostringstream ls;
1681 1729
    ///      while (rem_in_line > 0 && _it != _end) {
1682 1730
    ///        ls << *(_it++) << ' ';
1683 1731
    ///        --rem_in_line;
1684 1732
    ///      }
1685 1733
    ///      return ls.str();
1686 1734
    ///    }
1687 1735
    ///  };
1688 1736
    ///
1689 1737
    ///  // ...
1690 1738
    ///
1691 1739
    ///  writer.sectionLines("numbers", NumberSection(vec));
1692 1740
    ///\endcode
1693 1741
    template <typename Functor>
1694 1742
    SectionWriter& sectionLines(const std::string& type, Functor functor) {
1695 1743
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1696 1744
      _sections.push_back(std::make_pair(type,
1697 1745
        new _writer_bits::LineSection<Functor>(functor)));
1698 1746
      return *this;
1699 1747
    }
1700 1748

	
1701 1749

	
1702 1750
    /// \brief Add a section writer with stream oriented writing
1703 1751
    ///
1704 1752
    /// The first parameter is the type of the section, the second is
1705 1753
    /// a functor, which takes a \c std::ostream& parameter. The
1706 1754
    /// functor writes the section to the output stream.
1707 1755
    /// \warning The last line must be closed with end-line character.
1708 1756
    template <typename Functor>
1709 1757
    SectionWriter& sectionStream(const std::string& type, Functor functor) {
1710 1758
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1711 1759
      _sections.push_back(std::make_pair(type,
1712 1760
         new _writer_bits::StreamSection<Functor>(functor)));
1713 1761
      return *this;
1714 1762
    }
1715 1763

	
1716 1764
    /// @}
1717 1765

	
1718 1766
  public:
1719 1767

	
1720 1768

	
1721
    /// \name Execution of the writer
1769
    /// \name Execution of the Writer
1722 1770
    /// @{
1723 1771

	
1724 1772
    /// \brief Start the batch processing
1725 1773
    ///
1726 1774
    /// This function starts the batch processing.
1727 1775
    void run() {
1728 1776

	
1729 1777
      LEMON_ASSERT(_os != 0, "This writer is assigned to an other writer");
1730 1778

	
1731 1779
      for (Sections::iterator it = _sections.begin();
1732 1780
           it != _sections.end(); ++it) {
1733 1781
        (*_os) << '@' << it->first << std::endl;
1734 1782
        it->second->process(*_os);
1735 1783
      }
1736 1784
    }
1737 1785

	
1738 1786
    /// \brief Give back the stream of the writer
1739 1787
    ///
1740 1788
    /// Returns the stream of the writer
1741 1789
    std::ostream& ostream() {
1742 1790
      return *_os;
1743 1791
    }
1744 1792

	
1745 1793
    /// @}
1746 1794

	
1747 1795
  };
1748 1796

	
1797
  /// \ingroup lemon_io
1798
  ///
1749 1799
  /// \brief Return a \ref SectionWriter class
1750 1800
  ///
1751 1801
  /// This function just returns a \ref SectionWriter class.
1802
  ///
1803
  /// Please see SectionWriter documentation about the custom section
1804
  /// output.
1805
  ///
1752 1806
  /// \relates SectionWriter
1807
  /// \sa sectionWriter(const std::string& fn)
1808
  /// \sa sectionWriter(const char *fn)
1753 1809
  inline SectionWriter sectionWriter(std::ostream& os) {
1754 1810
    SectionWriter tmp(os);
1755 1811
    return tmp;
1756 1812
  }
1757 1813

	
1758 1814
  /// \brief Return a \ref SectionWriter class
1759 1815
  ///
1760 1816
  /// This function just returns a \ref SectionWriter class.
1761 1817
  /// \relates SectionWriter
1818
  /// \sa sectionWriter(std::ostream& os)
1762 1819
  inline SectionWriter sectionWriter(const std::string& fn) {
1763 1820
    SectionWriter tmp(fn);
1764 1821
    return tmp;
1765 1822
  }
1766 1823

	
1767 1824
  /// \brief Return a \ref SectionWriter class
1768 1825
  ///
1769 1826
  /// This function just returns a \ref SectionWriter class.
1770 1827
  /// \relates SectionWriter
1828
  /// \sa sectionWriter(std::ostream& os)
1771 1829
  inline SectionWriter sectionWriter(const char* fn) {
1772 1830
    SectionWriter tmp(fn);
1773 1831
    return tmp;
1774 1832
  }
1775 1833
}
1776 1834

	
1777 1835
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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/core.h>
27 27
#include <lemon/error.h>
28 28
#include <lemon/bits/graph_extender.h>
29 29

	
30 30
#include <vector>
31 31
#include <list>
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  class ListDigraphBase {
36 36

	
37 37
  protected:
38 38
    struct NodeT {
39 39
      int first_in, first_out;
40 40
      int prev, next;
41 41
    };
42 42

	
43 43
    struct ArcT {
44 44
      int target, source;
45 45
      int prev_in, prev_out;
46 46
      int next_in, next_out;
47 47
    };
48 48

	
49 49
    std::vector<NodeT> nodes;
50 50

	
51 51
    int first_node;
52 52

	
53 53
    int first_free_node;
54 54

	
55 55
    std::vector<ArcT> arcs;
56 56

	
57 57
    int first_free_arc;
58 58

	
59 59
  public:
60 60

	
61 61
    typedef ListDigraphBase Digraph;
62 62

	
63 63
    class Node {
64 64
      friend class ListDigraphBase;
65 65
    protected:
66 66

	
67 67
      int id;
68 68
      explicit Node(int pid) { id = pid;}
69 69

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

	
78 78
    class Arc {
79 79
      friend class ListDigraphBase;
80 80
    protected:
81 81

	
82 82
      int id;
83 83
      explicit Arc(int pid) { id = pid;}
84 84

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

	
93 93

	
94 94

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

	
99 99

	
100 100
    int maxNodeId() const { return nodes.size()-1; }
101 101
    int maxArcId() const { return arcs.size()-1; }
102 102

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

	
106 106

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

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

	
115 115

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

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

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

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

	
150 150

	
151 151
    static int id(Node v) { return v.id; }
152 152
    static int id(Arc e) { return e.id; }
153 153

	
154 154
    static Node nodeFromId(int id) { return Node(id);}
155 155
    static Arc arcFromId(int id) { return Arc(id);}
156 156

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

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

	
167 167
    Node addNode() {
168 168
      int n;
169 169

	
170 170
      if(first_free_node==-1) {
171 171
        n = nodes.size();
172 172
        nodes.push_back(NodeT());
173 173
      } else {
174 174
        n = first_free_node;
175 175
        first_free_node = nodes[n].next;
176 176
      }
177 177

	
178 178
      nodes[n].next = first_node;
179 179
      if(first_node != -1) nodes[first_node].prev = n;
180 180
      first_node = n;
181 181
      nodes[n].prev = -1;
182 182

	
183 183
      nodes[n].first_in = nodes[n].first_out = -1;
184 184

	
185 185
      return Node(n);
186 186
    }
187 187

	
188 188
    Arc addArc(Node u, Node v) {
189 189
      int n;
190 190

	
191 191
      if (first_free_arc == -1) {
192 192
        n = arcs.size();
193 193
        arcs.push_back(ArcT());
194 194
      } else {
195 195
        n = first_free_arc;
196 196
        first_free_arc = arcs[n].next_in;
197 197
      }
198 198

	
199 199
      arcs[n].source = u.id;
200 200
      arcs[n].target = v.id;
201 201

	
202 202
      arcs[n].next_out = nodes[u.id].first_out;
203 203
      if(nodes[u.id].first_out != -1) {
204 204
        arcs[nodes[u.id].first_out].prev_out = n;
205 205
      }
206 206

	
207 207
      arcs[n].next_in = nodes[v.id].first_in;
208 208
      if(nodes[v.id].first_in != -1) {
209 209
        arcs[nodes[v.id].first_in].prev_in = n;
210 210
      }
211 211

	
212 212
      arcs[n].prev_in = arcs[n].prev_out = -1;
213 213

	
214 214
      nodes[u.id].first_out = nodes[v.id].first_in = n;
215 215

	
216 216
      return Arc(n);
217 217
    }
218 218

	
219 219
    void erase(const Node& node) {
220 220
      int n = node.id;
221 221

	
222 222
      if(nodes[n].next != -1) {
223 223
        nodes[nodes[n].next].prev = nodes[n].prev;
224 224
      }
225 225

	
226 226
      if(nodes[n].prev != -1) {
227 227
        nodes[nodes[n].prev].next = nodes[n].next;
228 228
      } else {
229 229
        first_node = nodes[n].next;
230 230
      }
231 231

	
232 232
      nodes[n].next = first_free_node;
233 233
      first_free_node = n;
234 234
      nodes[n].prev = -2;
235 235

	
236 236
    }
237 237

	
238 238
    void erase(const Arc& arc) {
239 239
      int n = arc.id;
240 240

	
241 241
      if(arcs[n].next_in!=-1) {
242 242
        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
243 243
      }
244 244

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

	
251 251

	
252 252
      if(arcs[n].next_out!=-1) {
253 253
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
254 254
      }
255 255

	
256 256
      if(arcs[n].prev_out!=-1) {
257 257
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
258 258
      } else {
259 259
        nodes[arcs[n].source].first_out = arcs[n].next_out;
260 260
      }
261 261

	
262 262
      arcs[n].next_in = first_free_arc;
263 263
      first_free_arc = n;
264 264
      arcs[n].prev_in = -2;
265 265
    }
266 266

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

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

	
305 305
  };
306 306

	
307 307
  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
308 308

	
309 309
  /// \addtogroup graphs
310 310
  /// @{
311 311

	
312 312
  ///A general directed graph structure.
313 313

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

	
328 325
  class ListDigraph : public ExtendedListDigraphBase {
326
    typedef ExtendedListDigraphBase Parent;
327

	
329 328
  private:
330 329
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
331 330

	
332 331
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
333 332
    ///
334 333
    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
335 334
    ///\brief Assignment of ListDigraph to another one is \e not allowed.
336 335
    ///Use copyDigraph() instead.
337 336

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

	
343
    typedef ExtendedListDigraphBase Parent;
344

	
345 342
    /// Constructor
346 343

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

	
351 348
    ///Add a new node to the digraph.
352 349

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

	
357 354
    ///Add a new arc to the digraph.
358 355

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

	
366 363
    ///\brief Erase a node from the digraph.
367 364
    ///
368 365
    ///Erase a node from the digraph.
369 366
    ///
370 367
    void erase(const Node& n) { Parent::erase(n); }
371 368

	
372 369
    ///\brief Erase an arc from the digraph.
373 370
    ///
374 371
    ///Erase an arc from the digraph.
375 372
    ///
376 373
    void erase(const Arc& a) { Parent::erase(a); }
377 374

	
378 375
    /// Node validity check
379 376

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

	
388 385
    /// Arc validity check
389 386

	
390 387
    /// This function gives back true if the given arc is valid,
391 388
    /// ie. it is a real arc of the graph.
392 389
    ///
393 390
    /// \warning An Arc pointing to a removed item
394 391
    /// could become valid again later if new nodes are
395 392
    /// added to the graph.
396 393
    bool valid(Arc a) const { return Parent::valid(a); }
397 394

	
398 395
    /// Change the target of \c a to \c n
399 396

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

	
413 410
    /// Change the source of \c a to \c n
414 411
    ///
415 412
    ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
416 413
    ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
417 414
    ///invalidated.
418 415
    ///
419 416
    ///\warning This functionality cannot be used together with the Snapshot
420 417
    ///feature.
421 418
    void changeSource(Arc a, Node n) {
422 419
      Parent::changeSource(a,n);
423 420
    }
424 421

	
425 422
    /// Invert the direction of an arc.
426 423

	
427 424
    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
428 425
    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
429 426
    ///invalidated.
430 427
    ///
431 428
    ///\warning This functionality cannot be used together with the Snapshot
432 429
    ///feature.
433 430
    void reverseArc(Arc e) {
434 431
      Node t=target(e);
435 432
      changeTarget(e,source(e));
436 433
      changeSource(e,t);
437 434
    }
438 435

	
439 436
    /// Reserve memory for nodes.
440 437

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

	
449 446
    /// Reserve memory for arcs.
450 447

	
451 448
    /// Using this function it is possible to avoid the superfluous memory
452 449
    /// allocation: if you know that the digraph you want to build will
453 450
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
454 451
    /// then it is worth reserving space for this amount before starting
455 452
    /// to build the digraph.
456 453
    /// \sa reserveNode
457 454
    void reserveArc(int m) { arcs.reserve(m); };
458 455

	
459 456
    ///Contract two nodes.
460 457

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

	
492 489
    ///Split a node.
493 490

	
494 491
    ///This function splits a node. First a new node is added to the digraph,
495 492
    ///then the source of each outgoing arc of \c n is moved to this new node.
496 493
    ///If \c connect is \c true (this is the default value), then a new arc
497 494
    ///from \c n to the newly created node is also added.
498 495
    ///\return The newly created node.
499 496
    ///
500 497
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
501 498
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
502 499
    ///be invalidated.
503 500
    ///
504 501
    ///\warning This functionality cannot be used in conjunction with the
505 502
    ///Snapshot feature.
506 503
    Node split(Node n, bool connect = true) {
507 504
      Node b = addNode();
508 505
      for(OutArcIt e(*this,n);e!=INVALID;) {
509 506
        OutArcIt f=e;
510 507
        ++f;
511 508
        changeSource(e,b);
512 509
        e=f;
513 510
      }
514 511
      if (connect) addArc(n,b);
515 512
      return b;
516 513
    }
517 514

	
518 515
    ///Split an arc.
519 516

	
520 517
    ///This function splits an arc. First a new node \c b is added to
521 518
    ///the digraph, then the original arc is re-targeted to \c
522 519
    ///b. Finally an arc from \c b to the original target is added.
523 520
    ///
524 521
    ///\return The newly created node.
525 522
    ///
526 523
    ///\warning This functionality cannot be used together with the
527 524
    ///Snapshot feature.
528 525
    Node split(Arc e) {
529 526
      Node b = addNode();
530 527
      addArc(b,target(e));
531 528
      changeTarget(e,b);
532 529
      return b;
533 530
    }
534 531

	
535 532
    /// \brief Class to make a snapshot of the digraph and restore
536 533
    /// it later.
537 534
    ///
538 535
    /// Class to make a snapshot of the digraph and restore it later.
539 536
    ///
540 537
    /// The newly added nodes and arcs can be removed using the
541 538
    /// restore() function.
542 539
    ///
543 540
    /// \warning Arc and node deletions and other modifications (e.g.
544 541
    /// contracting, splitting, reversing arcs or nodes) cannot be
545 542
    /// restored. These events invalidate the snapshot.
546 543
    class Snapshot {
547 544
    protected:
548 545

	
549 546
      typedef Parent::NodeNotifier NodeNotifier;
550 547

	
551 548
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
552 549
      public:
553 550

	
554 551
        NodeObserverProxy(Snapshot& _snapshot)
555 552
          : snapshot(_snapshot) {}
556 553

	
557 554
        using NodeNotifier::ObserverBase::attach;
558 555
        using NodeNotifier::ObserverBase::detach;
559 556
        using NodeNotifier::ObserverBase::attached;
560 557

	
561 558
      protected:
562 559

	
563 560
        virtual void add(const Node& node) {
564 561
          snapshot.addNode(node);
565 562
        }
566 563
        virtual void add(const std::vector<Node>& nodes) {
567 564
          for (int i = nodes.size() - 1; i >= 0; ++i) {
568 565
            snapshot.addNode(nodes[i]);
569 566
          }
570 567
        }
571 568
        virtual void erase(const Node& node) {
572 569
          snapshot.eraseNode(node);
573 570
        }
574 571
        virtual void erase(const std::vector<Node>& nodes) {
575 572
          for (int i = 0; i < int(nodes.size()); ++i) {
576 573
            snapshot.eraseNode(nodes[i]);
577 574
          }
578 575
        }
579 576
        virtual void build() {
580 577
          Node node;
581 578
          std::vector<Node> nodes;
582 579
          for (notifier()->first(node); node != INVALID;
583 580
               notifier()->next(node)) {
584 581
            nodes.push_back(node);
585 582
          }
586 583
          for (int i = nodes.size() - 1; i >= 0; --i) {
587 584
            snapshot.addNode(nodes[i]);
588 585
          }
589 586
        }
590 587
        virtual void clear() {
591 588
          Node node;
592 589
          for (notifier()->first(node); node != INVALID;
593 590
               notifier()->next(node)) {
594 591
            snapshot.eraseNode(node);
595 592
          }
596 593
        }
597 594

	
598 595
        Snapshot& snapshot;
599 596
      };
600 597

	
601 598
      class ArcObserverProxy : public ArcNotifier::ObserverBase {
602 599
      public:
603 600

	
604 601
        ArcObserverProxy(Snapshot& _snapshot)
605 602
          : snapshot(_snapshot) {}
606 603

	
607 604
        using ArcNotifier::ObserverBase::attach;
608 605
        using ArcNotifier::ObserverBase::detach;
609 606
        using ArcNotifier::ObserverBase::attached;
610 607

	
611 608
      protected:
612 609

	
613 610
        virtual void add(const Arc& arc) {
614 611
          snapshot.addArc(arc);
615 612
        }
616 613
        virtual void add(const std::vector<Arc>& arcs) {
617 614
          for (int i = arcs.size() - 1; i >= 0; ++i) {
618 615
            snapshot.addArc(arcs[i]);
619 616
          }
620 617
        }
621 618
        virtual void erase(const Arc& arc) {
622 619
          snapshot.eraseArc(arc);
623 620
        }
624 621
        virtual void erase(const std::vector<Arc>& arcs) {
625 622
          for (int i = 0; i < int(arcs.size()); ++i) {
626 623
            snapshot.eraseArc(arcs[i]);
627 624
          }
628 625
        }
629 626
        virtual void build() {
630 627
          Arc arc;
631 628
          std::vector<Arc> arcs;
632 629
          for (notifier()->first(arc); arc != INVALID;
633 630
               notifier()->next(arc)) {
634 631
            arcs.push_back(arc);
635 632
          }
636 633
          for (int i = arcs.size() - 1; i >= 0; --i) {
637 634
            snapshot.addArc(arcs[i]);
638 635
          }
639 636
        }
640 637
        virtual void clear() {
641 638
          Arc arc;
642 639
          for (notifier()->first(arc); arc != INVALID;
643 640
               notifier()->next(arc)) {
644 641
            snapshot.eraseArc(arc);
645 642
          }
646 643
        }
647 644

	
648 645
        Snapshot& snapshot;
649 646
      };
650 647

	
651 648
      ListDigraph *digraph;
652 649

	
653 650
      NodeObserverProxy node_observer_proxy;
654 651
      ArcObserverProxy arc_observer_proxy;
655 652

	
656 653
      std::list<Node> added_nodes;
657 654
      std::list<Arc> added_arcs;
658 655

	
659 656

	
660 657
      void addNode(const Node& node) {
661 658
        added_nodes.push_front(node);
662 659
      }
663 660
      void eraseNode(const Node& node) {
664 661
        std::list<Node>::iterator it =
665 662
          std::find(added_nodes.begin(), added_nodes.end(), node);
666 663
        if (it == added_nodes.end()) {
667 664
          clear();
668 665
          arc_observer_proxy.detach();
669 666
          throw NodeNotifier::ImmediateDetach();
670 667
        } else {
671 668
          added_nodes.erase(it);
672 669
        }
673 670
      }
674 671

	
675 672
      void addArc(const Arc& arc) {
676 673
        added_arcs.push_front(arc);
677 674
      }
678 675
      void eraseArc(const Arc& arc) {
679 676
        std::list<Arc>::iterator it =
680 677
          std::find(added_arcs.begin(), added_arcs.end(), arc);
681 678
        if (it == added_arcs.end()) {
682 679
          clear();
683 680
          node_observer_proxy.detach();
684 681
          throw ArcNotifier::ImmediateDetach();
685 682
        } else {
686 683
          added_arcs.erase(it);
687 684
        }
688 685
      }
689 686

	
690 687
      void attach(ListDigraph &_digraph) {
691 688
        digraph = &_digraph;
692 689
        node_observer_proxy.attach(digraph->notifier(Node()));
693 690
        arc_observer_proxy.attach(digraph->notifier(Arc()));
694 691
      }
695 692

	
696 693
      void detach() {
697 694
        node_observer_proxy.detach();
698 695
        arc_observer_proxy.detach();
699 696
      }
700 697

	
701 698
      bool attached() const {
702 699
        return node_observer_proxy.attached();
703 700
      }
704 701

	
705 702
      void clear() {
706 703
        added_nodes.clear();
707 704
        added_arcs.clear();
708 705
      }
709 706

	
710 707
    public:
711 708

	
712 709
      /// \brief Default constructor.
713 710
      ///
714 711
      /// Default constructor.
715 712
      /// To actually make a snapshot you must call save().
716 713
      Snapshot()
717 714
        : digraph(0), node_observer_proxy(*this),
718 715
          arc_observer_proxy(*this) {}
719 716

	
720 717
      /// \brief Constructor that immediately makes a snapshot.
721 718
      ///
722 719
      /// This constructor immediately makes a snapshot of the digraph.
723 720
      /// \param _digraph The digraph we make a snapshot of.
724 721
      Snapshot(ListDigraph &_digraph)
725 722
        : node_observer_proxy(*this),
726 723
          arc_observer_proxy(*this) {
727 724
        attach(_digraph);
728 725
      }
729 726

	
730 727
      /// \brief Make a snapshot.
731 728
      ///
732 729
      /// Make a snapshot of the digraph.
733 730
      ///
734 731
      /// This function can be called more than once. In case of a repeated
735 732
      /// call, the previous snapshot gets lost.
736 733
      /// \param _digraph The digraph we make the snapshot of.
737 734
      void save(ListDigraph &_digraph) {
738 735
        if (attached()) {
739 736
          detach();
740 737
          clear();
741 738
        }
742 739
        attach(_digraph);
743 740
      }
744 741

	
745 742
      /// \brief Undo the changes until the last snapshot.
746 743
      //
747 744
      /// Undo the changes until the last snapshot created by save().
748 745
      void restore() {
749 746
        detach();
750 747
        for(std::list<Arc>::iterator it = added_arcs.begin();
751 748
            it != added_arcs.end(); ++it) {
752 749
          digraph->erase(*it);
753 750
        }
754 751
        for(std::list<Node>::iterator it = added_nodes.begin();
755 752
            it != added_nodes.end(); ++it) {
756 753
          digraph->erase(*it);
757 754
        }
758 755
        clear();
759 756
      }
760 757

	
761 758
      /// \brief Gives back true when the snapshot is valid.
762 759
      ///
763 760
      /// Gives back true when the snapshot is valid.
764 761
      bool valid() const {
765 762
        return attached();
766 763
      }
767 764
    };
768 765

	
769 766
  };
770 767

	
771 768
  ///@}
772 769

	
773 770
  class ListGraphBase {
774 771

	
775 772
  protected:
776 773

	
777 774
    struct NodeT {
778 775
      int first_out;
779 776
      int prev, next;
780 777
    };
781 778

	
782 779
    struct ArcT {
783 780
      int target;
784 781
      int prev_out, next_out;
785 782
    };
786 783

	
787 784
    std::vector<NodeT> nodes;
788 785

	
789 786
    int first_node;
790 787

	
791 788
    int first_free_node;
792 789

	
793 790
    std::vector<ArcT> arcs;
794 791

	
795 792
    int first_free_arc;
796 793

	
797 794
  public:
798 795

	
799
    typedef ListGraphBase Digraph;
796
    typedef ListGraphBase Graph;
800 797

	
801 798
    class Node;
802 799
    class Arc;
803 800
    class Edge;
804 801

	
805 802
    class Node {
806 803
      friend class ListGraphBase;
807 804
    protected:
808 805

	
809 806
      int id;
810 807
      explicit Node(int pid) { id = pid;}
811 808

	
812 809
    public:
813 810
      Node() {}
814 811
      Node (Invalid) { id = -1; }
815 812
      bool operator==(const Node& node) const {return id == node.id;}
816 813
      bool operator!=(const Node& node) const {return id != node.id;}
817 814
      bool operator<(const Node& node) const {return id < node.id;}
818 815
    };
819 816

	
820 817
    class Edge {
821 818
      friend class ListGraphBase;
822 819
    protected:
823 820

	
824 821
      int id;
825 822
      explicit Edge(int pid) { id = pid;}
826 823

	
827 824
    public:
828 825
      Edge() {}
829 826
      Edge (Invalid) { id = -1; }
830 827
      bool operator==(const Edge& edge) const {return id == edge.id;}
831 828
      bool operator!=(const Edge& edge) const {return id != edge.id;}
832 829
      bool operator<(const Edge& edge) const {return id < edge.id;}
833 830
    };
834 831

	
835 832
    class Arc {
836 833
      friend class ListGraphBase;
837 834
    protected:
838 835

	
839 836
      int id;
840 837
      explicit Arc(int pid) { id = pid;}
841 838

	
842 839
    public:
843
      operator Edge() const { 
844
        return id != -1 ? edgeFromId(id / 2) : INVALID; 
840
      operator Edge() const {
841
        return id != -1 ? edgeFromId(id / 2) : INVALID;
845 842
      }
846 843

	
847 844
      Arc() {}
848 845
      Arc (Invalid) { id = -1; }
849 846
      bool operator==(const Arc& arc) const {return id == arc.id;}
850 847
      bool operator!=(const Arc& arc) const {return id != arc.id;}
851 848
      bool operator<(const Arc& arc) const {return id < arc.id;}
852 849
    };
853 850

	
854 851

	
855 852

	
856 853
    ListGraphBase()
857 854
      : nodes(), first_node(-1),
858 855
        first_free_node(-1), arcs(), first_free_arc(-1) {}
859 856

	
860 857

	
861 858
    int maxNodeId() const { return nodes.size()-1; }
862 859
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
863 860
    int maxArcId() const { return arcs.size()-1; }
864 861

	
865 862
    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
866 863
    Node target(Arc e) const { return Node(arcs[e.id].target); }
867 864

	
868 865
    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
869 866
    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
870 867

	
871 868
    static bool direction(Arc e) {
872 869
      return (e.id & 1) == 1;
873 870
    }
874 871

	
875 872
    static Arc direct(Edge e, bool d) {
876 873
      return Arc(e.id * 2 + (d ? 1 : 0));
877 874
    }
878 875

	
879 876
    void first(Node& node) const {
880 877
      node.id = first_node;
881 878
    }
882 879

	
883 880
    void next(Node& node) const {
884 881
      node.id = nodes[node.id].next;
885 882
    }
886 883

	
887 884
    void first(Arc& e) const {
888 885
      int n = first_node;
889 886
      while (n != -1 && nodes[n].first_out == -1) {
890 887
        n = nodes[n].next;
891 888
      }
892 889
      e.id = (n == -1) ? -1 : nodes[n].first_out;
893 890
    }
894 891

	
895 892
    void next(Arc& e) const {
896 893
      if (arcs[e.id].next_out != -1) {
897 894
        e.id = arcs[e.id].next_out;
898 895
      } else {
899 896
        int n = nodes[arcs[e.id ^ 1].target].next;
900 897
        while(n != -1 && nodes[n].first_out == -1) {
901 898
          n = nodes[n].next;
902 899
        }
903 900
        e.id = (n == -1) ? -1 : nodes[n].first_out;
904 901
      }
905 902
    }
906 903

	
907 904
    void first(Edge& e) const {
908 905
      int n = first_node;
909 906
      while (n != -1) {
910 907
        e.id = nodes[n].first_out;
911 908
        while ((e.id & 1) != 1) {
912 909
          e.id = arcs[e.id].next_out;
913 910
        }
914 911
        if (e.id != -1) {
915 912
          e.id /= 2;
916 913
          return;
917 914
        }
918 915
        n = nodes[n].next;
919 916
      }
920 917
      e.id = -1;
921 918
    }
922 919

	
923 920
    void next(Edge& e) const {
924 921
      int n = arcs[e.id * 2].target;
925 922
      e.id = arcs[(e.id * 2) | 1].next_out;
926 923
      while ((e.id & 1) != 1) {
927 924
        e.id = arcs[e.id].next_out;
928 925
      }
929 926
      if (e.id != -1) {
930 927
        e.id /= 2;
931 928
        return;
932 929
      }
933 930
      n = nodes[n].next;
934 931
      while (n != -1) {
935 932
        e.id = nodes[n].first_out;
936 933
        while ((e.id & 1) != 1) {
937 934
          e.id = arcs[e.id].next_out;
938 935
        }
939 936
        if (e.id != -1) {
940 937
          e.id /= 2;
941 938
          return;
942 939
        }
943 940
        n = nodes[n].next;
944 941
      }
945 942
      e.id = -1;
946 943
    }
947 944

	
948 945
    void firstOut(Arc &e, const Node& v) const {
949 946
      e.id = nodes[v.id].first_out;
950 947
    }
951 948
    void nextOut(Arc &e) const {
952 949
      e.id = arcs[e.id].next_out;
953 950
    }
954 951

	
955 952
    void firstIn(Arc &e, const Node& v) const {
956 953
      e.id = ((nodes[v.id].first_out) ^ 1);
957 954
      if (e.id == -2) e.id = -1;
958 955
    }
959 956
    void nextIn(Arc &e) const {
960 957
      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
961 958
      if (e.id == -2) e.id = -1;
962 959
    }
963 960

	
964 961
    void firstInc(Edge &e, bool& d, const Node& v) const {
965 962
      int a = nodes[v.id].first_out;
966 963
      if (a != -1 ) {
967 964
        e.id = a / 2;
968 965
        d = ((a & 1) == 1);
969 966
      } else {
970 967
        e.id = -1;
971 968
        d = true;
972 969
      }
973 970
    }
974 971
    void nextInc(Edge &e, bool& d) const {
975 972
      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
976 973
      if (a != -1 ) {
977 974
        e.id = a / 2;
978 975
        d = ((a & 1) == 1);
979 976
      } else {
980 977
        e.id = -1;
981 978
        d = true;
982 979
      }
983 980
    }
984 981

	
985 982
    static int id(Node v) { return v.id; }
986 983
    static int id(Arc e) { return e.id; }
987 984
    static int id(Edge e) { return e.id; }
988 985

	
989 986
    static Node nodeFromId(int id) { return Node(id);}
990 987
    static Arc arcFromId(int id) { return Arc(id);}
991 988
    static Edge edgeFromId(int id) { return Edge(id);}
992 989

	
993 990
    bool valid(Node n) const {
994 991
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
995 992
        nodes[n.id].prev != -2;
996 993
    }
997 994

	
998 995
    bool valid(Arc a) const {
999 996
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
1000 997
        arcs[a.id].prev_out != -2;
1001 998
    }
1002 999

	
1003 1000
    bool valid(Edge e) const {
1004 1001
      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
1005 1002
        arcs[2 * e.id].prev_out != -2;
1006 1003
    }
1007 1004

	
1008 1005
    Node addNode() {
1009 1006
      int n;
1010 1007

	
1011 1008
      if(first_free_node==-1) {
1012 1009
        n = nodes.size();
1013 1010
        nodes.push_back(NodeT());
1014 1011
      } else {
1015 1012
        n = first_free_node;
1016 1013
        first_free_node = nodes[n].next;
1017 1014
      }
1018 1015

	
1019 1016
      nodes[n].next = first_node;
1020 1017
      if (first_node != -1) nodes[first_node].prev = n;
1021 1018
      first_node = n;
1022 1019
      nodes[n].prev = -1;
1023 1020

	
1024 1021
      nodes[n].first_out = -1;
1025 1022

	
1026 1023
      return Node(n);
1027 1024
    }
1028 1025

	
1029 1026
    Edge addEdge(Node u, Node v) {
1030 1027
      int n;
1031 1028

	
1032 1029
      if (first_free_arc == -1) {
1033 1030
        n = arcs.size();
1034 1031
        arcs.push_back(ArcT());
1035 1032
        arcs.push_back(ArcT());
1036 1033
      } else {
1037 1034
        n = first_free_arc;
1038 1035
        first_free_arc = arcs[n].next_out;
1039 1036
      }
1040 1037

	
1041 1038
      arcs[n].target = u.id;
1042 1039
      arcs[n | 1].target = v.id;
1043 1040

	
1044 1041
      arcs[n].next_out = nodes[v.id].first_out;
1045 1042
      if (nodes[v.id].first_out != -1) {
1046 1043
        arcs[nodes[v.id].first_out].prev_out = n;
1047 1044
      }
1048 1045
      arcs[n].prev_out = -1;
1049 1046
      nodes[v.id].first_out = n;
1050 1047

	
1051 1048
      arcs[n | 1].next_out = nodes[u.id].first_out;
1052 1049
      if (nodes[u.id].first_out != -1) {
1053 1050
        arcs[nodes[u.id].first_out].prev_out = (n | 1);
1054 1051
      }
1055 1052
      arcs[n | 1].prev_out = -1;
1056 1053
      nodes[u.id].first_out = (n | 1);
1057 1054

	
1058 1055
      return Edge(n / 2);
1059 1056
    }
1060 1057

	
1061 1058
    void erase(const Node& node) {
1062 1059
      int n = node.id;
1063 1060

	
1064 1061
      if(nodes[n].next != -1) {
1065 1062
        nodes[nodes[n].next].prev = nodes[n].prev;
1066 1063
      }
1067 1064

	
1068 1065
      if(nodes[n].prev != -1) {
1069 1066
        nodes[nodes[n].prev].next = nodes[n].next;
1070 1067
      } else {
1071 1068
        first_node = nodes[n].next;
1072 1069
      }
1073 1070

	
1074 1071
      nodes[n].next = first_free_node;
1075 1072
      first_free_node = n;
1076 1073
      nodes[n].prev = -2;
1077 1074
    }
1078 1075

	
1079 1076
    void erase(const Edge& edge) {
1080 1077
      int n = edge.id * 2;
1081 1078

	
1082 1079
      if (arcs[n].next_out != -1) {
1083 1080
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1084 1081
      }
1085 1082

	
1086 1083
      if (arcs[n].prev_out != -1) {
1087 1084
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1088 1085
      } else {
1089 1086
        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1090 1087
      }
1091 1088

	
1092 1089
      if (arcs[n | 1].next_out != -1) {
1093 1090
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1094 1091
      }
1095 1092

	
1096 1093
      if (arcs[n | 1].prev_out != -1) {
1097 1094
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1098 1095
      } else {
1099 1096
        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1100 1097
      }
1101 1098

	
1102 1099
      arcs[n].next_out = first_free_arc;
1103 1100
      first_free_arc = n;
1104 1101
      arcs[n].prev_out = -2;
1105 1102
      arcs[n | 1].prev_out = -2;
1106 1103

	
1107 1104
    }
1108 1105

	
1109 1106
    void clear() {
1110 1107
      arcs.clear();
1111 1108
      nodes.clear();
1112 1109
      first_node = first_free_node = first_free_arc = -1;
1113 1110
    }
1114 1111

	
1115 1112
  protected:
1116 1113

	
1117 1114
    void changeV(Edge e, Node n) {
1118 1115
      if(arcs[2 * e.id].next_out != -1) {
1119 1116
        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1120 1117
      }
1121 1118
      if(arcs[2 * e.id].prev_out != -1) {
1122 1119
        arcs[arcs[2 * e.id].prev_out].next_out =
1123 1120
          arcs[2 * e.id].next_out;
1124 1121
      } else {
1125 1122
        nodes[arcs[(2 * e.id) | 1].target].first_out =
1126 1123
          arcs[2 * e.id].next_out;
1127 1124
      }
1128 1125

	
1129 1126
      if (nodes[n.id].first_out != -1) {
1130 1127
        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1131 1128
      }
1132 1129
      arcs[(2 * e.id) | 1].target = n.id;
1133 1130
      arcs[2 * e.id].prev_out = -1;
1134 1131
      arcs[2 * e.id].next_out = nodes[n.id].first_out;
1135 1132
      nodes[n.id].first_out = 2 * e.id;
1136 1133
    }
1137 1134

	
1138 1135
    void changeU(Edge e, Node n) {
1139 1136
      if(arcs[(2 * e.id) | 1].next_out != -1) {
1140 1137
        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1141 1138
          arcs[(2 * e.id) | 1].prev_out;
1142 1139
      }
1143 1140
      if(arcs[(2 * e.id) | 1].prev_out != -1) {
1144 1141
        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1145 1142
          arcs[(2 * e.id) | 1].next_out;
1146 1143
      } else {
1147 1144
        nodes[arcs[2 * e.id].target].first_out =
1148 1145
          arcs[(2 * e.id) | 1].next_out;
1149 1146
      }
1150 1147

	
1151 1148
      if (nodes[n.id].first_out != -1) {
1152 1149
        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1153 1150
      }
1154 1151
      arcs[2 * e.id].target = n.id;
1155 1152
      arcs[(2 * e.id) | 1].prev_out = -1;
1156 1153
      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1157 1154
      nodes[n.id].first_out = ((2 * e.id) | 1);
1158 1155
    }
1159 1156

	
1160 1157
  };
1161 1158

	
1162 1159
  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1163 1160

	
1164 1161

	
1165 1162
  /// \addtogroup graphs
1166 1163
  /// @{
1167 1164

	
1168 1165
  ///A general undirected graph structure.
1169 1166

	
1170 1167
  ///\ref ListGraph is a simple and fast <em>undirected graph</em>
1171 1168
  ///implementation based on static linked lists that are stored in
1172 1169
  ///\c std::vector structures.
1173 1170
  ///
1174 1171
  ///It conforms to the \ref concepts::Graph "Graph concept" and it
1175 1172
  ///also provides several useful additional functionalities.
1176 1173
  ///Most of the member functions and nested classes are documented
1177 1174
  ///only in the concept class.
1178 1175
  ///
1179
  ///An important extra feature of this graph implementation is that
1180
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1181
  ///
1182 1176
  ///\sa concepts::Graph
1183 1177

	
1184 1178
  class ListGraph : public ExtendedListGraphBase {
1179
    typedef ExtendedListGraphBase Parent;
1180

	
1185 1181
  private:
1186 1182
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1187 1183

	
1188 1184
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1189 1185
    ///
1190 1186
    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
1191 1187
    ///\brief Assignment of ListGraph to another one is \e not allowed.
1192 1188
    ///Use copyGraph() instead.
1193 1189

	
1194 1190
    ///Assignment of ListGraph to another one is \e not allowed.
1195 1191
    ///Use copyGraph() instead.
1196 1192
    void operator=(const ListGraph &) {}
1197 1193
  public:
1198 1194
    /// Constructor
1199 1195

	
1200 1196
    /// Constructor.
1201 1197
    ///
1202 1198
    ListGraph() {}
1203 1199

	
1204
    typedef ExtendedListGraphBase Parent;
1205

	
1206 1200
    typedef Parent::OutArcIt IncEdgeIt;
1207 1201

	
1208 1202
    /// \brief Add a new node to the graph.
1209 1203
    ///
1210 1204
    /// Add a new node to the graph.
1211
    /// \return the new node.
1205
    /// \return The new node.
1212 1206
    Node addNode() { return Parent::addNode(); }
1213 1207

	
1214 1208
    /// \brief Add a new edge to the graph.
1215 1209
    ///
1216 1210
    /// Add a new edge to the graph with source node \c s
1217 1211
    /// and target node \c t.
1218
    /// \return the new edge.
1212
    /// \return The new edge.
1219 1213
    Edge addEdge(const Node& s, const Node& t) {
1220 1214
      return Parent::addEdge(s, t);
1221 1215
    }
1222 1216

	
1223 1217
    /// \brief Erase a node from the graph.
1224 1218
    ///
1225 1219
    /// Erase a node from the graph.
1226 1220
    ///
1227 1221
    void erase(const Node& n) { Parent::erase(n); }
1228 1222

	
1229 1223
    /// \brief Erase an edge from the graph.
1230 1224
    ///
1231 1225
    /// Erase an edge from the graph.
1232 1226
    ///
1233 1227
    void erase(const Edge& e) { Parent::erase(e); }
1234 1228
    /// Node validity check
1235 1229

	
1236 1230
    /// This function gives back true if the given node is valid,
1237 1231
    /// ie. it is a real node of the graph.
1238 1232
    ///
1239 1233
    /// \warning A Node pointing to a removed item
1240 1234
    /// could become valid again later if new nodes are
1241 1235
    /// added to the graph.
1242 1236
    bool valid(Node n) const { return Parent::valid(n); }
1243 1237
    /// Arc validity check
1244 1238

	
1245 1239
    /// This function gives back true if the given arc is valid,
1246 1240
    /// ie. it is a real arc of the graph.
1247 1241
    ///
1248 1242
    /// \warning An Arc pointing to a removed item
1249 1243
    /// could become valid again later if new edges are
1250 1244
    /// added to the graph.
1251 1245
    bool valid(Arc a) const { return Parent::valid(a); }
1252 1246
    /// Edge validity check
1253 1247

	
1254 1248
    /// This function gives back true if the given edge is valid,
1255 1249
    /// ie. it is a real arc of the graph.
1256 1250
    ///
1257 1251
    /// \warning A Edge pointing to a removed item
1258 1252
    /// could become valid again later if new edges are
1259 1253
    /// added to the graph.
1260 1254
    bool valid(Edge e) const { return Parent::valid(e); }
1261 1255
    /// \brief Change the end \c u of \c e to \c n
1262 1256
    ///
1263 1257
    /// This function changes the end \c u of \c e to node \c n.
1264 1258
    ///
1265 1259
    ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
1266 1260
    ///changed edge are invalidated and if the changed node is the
1267 1261
    ///base node of an iterator then this iterator is also
1268 1262
    ///invalidated.
1269 1263
    ///
1270 1264
    ///\warning This functionality cannot be used together with the
1271 1265
    ///Snapshot feature.
1272 1266
    void changeU(Edge e, Node n) {
1273 1267
      Parent::changeU(e,n);
1274 1268
    }
1275 1269
    /// \brief Change the end \c v of \c e to \c n
1276 1270
    ///
1277 1271
    /// This function changes the end \c v of \c e to \c n.
1278 1272
    ///
1279 1273
    ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
1280 1274
    ///valid, however <tt>ArcIt</tt>s and if the changed node is the
1281 1275
    ///base node of an iterator then this iterator is invalidated.
1282 1276
    ///
1283 1277
    ///\warning This functionality cannot be used together with the
1284 1278
    ///Snapshot feature.
1285 1279
    void changeV(Edge e, Node n) {
1286 1280
      Parent::changeV(e,n);
1287 1281
    }
1288 1282
    /// \brief Contract two nodes.
1289 1283
    ///
1290 1284
    /// This function contracts two nodes.
1291 1285
    /// Node \p b will be removed but instead of deleting
1292 1286
    /// its neighboring arcs, they will be joined to \p a.
1293 1287
    /// The last parameter \p r controls whether to remove loops. \c true
1294 1288
    /// means that loops will be removed.
1295 1289
    ///
1296 1290
    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
1297 1291
    /// valid.
1298 1292
    ///
1299 1293
    ///\warning This functionality cannot be used together with the
1300 1294
    ///Snapshot feature.
1301 1295
    void contract(Node a, Node b, bool r = true) {
1302 1296
      for(IncEdgeIt e(*this, b); e!=INVALID;) {
1303 1297
        IncEdgeIt f = e; ++f;
1304 1298
        if (r && runningNode(e) == a) {
1305 1299
          erase(e);
1306 1300
        } else if (u(e) == b) {
1307 1301
          changeU(e, a);
1308 1302
        } else {
1309 1303
          changeV(e, a);
1310 1304
        }
1311 1305
        e = f;
1312 1306
      }
1313 1307
      erase(b);
1314 1308
    }
1315 1309

	
1316 1310

	
1317 1311
    /// \brief Class to make a snapshot of the graph and restore
1318 1312
    /// it later.
1319 1313
    ///
1320 1314
    /// Class to make a snapshot of the graph and restore it later.
1321 1315
    ///
1322 1316
    /// The newly added nodes and edges can be removed
1323 1317
    /// using the restore() function.
1324 1318
    ///
1325 1319
    /// \warning Edge and node deletions and other modifications
1326 1320
    /// (e.g. changing nodes of edges, contracting nodes) cannot be
1327 1321
    /// restored. These events invalidate the snapshot.
1328 1322
    class Snapshot {
1329 1323
    protected:
1330 1324

	
1331 1325
      typedef Parent::NodeNotifier NodeNotifier;
1332 1326

	
1333 1327
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
1334 1328
      public:
1335 1329

	
1336 1330
        NodeObserverProxy(Snapshot& _snapshot)
1337 1331
          : snapshot(_snapshot) {}
1338 1332

	
1339 1333
        using NodeNotifier::ObserverBase::attach;
1340 1334
        using NodeNotifier::ObserverBase::detach;
1341 1335
        using NodeNotifier::ObserverBase::attached;
1342 1336

	
1343 1337
      protected:
1344 1338

	
1345 1339
        virtual void add(const Node& node) {
1346 1340
          snapshot.addNode(node);
1347 1341
        }
1348 1342
        virtual void add(const std::vector<Node>& nodes) {
1349 1343
          for (int i = nodes.size() - 1; i >= 0; ++i) {
1350 1344
            snapshot.addNode(nodes[i]);
1351 1345
          }
1352 1346
        }
1353 1347
        virtual void erase(const Node& node) {
1354 1348
          snapshot.eraseNode(node);
1355 1349
        }
1356 1350
        virtual void erase(const std::vector<Node>& nodes) {
1357 1351
          for (int i = 0; i < int(nodes.size()); ++i) {
1358 1352
            snapshot.eraseNode(nodes[i]);
1359 1353
          }
1360 1354
        }
1361 1355
        virtual void build() {
1362 1356
          Node node;
1363 1357
          std::vector<Node> nodes;
1364 1358
          for (notifier()->first(node); node != INVALID;
1365 1359
               notifier()->next(node)) {
1366 1360
            nodes.push_back(node);
1367 1361
          }
1368 1362
          for (int i = nodes.size() - 1; i >= 0; --i) {
1369 1363
            snapshot.addNode(nodes[i]);
1370 1364
          }
1371 1365
        }
1372 1366
        virtual void clear() {
1373 1367
          Node node;
1374 1368
          for (notifier()->first(node); node != INVALID;
1375 1369
               notifier()->next(node)) {
1376 1370
            snapshot.eraseNode(node);
1377 1371
          }
1378 1372
        }
1379 1373

	
1380 1374
        Snapshot& snapshot;
1381 1375
      };
1382 1376

	
1383 1377
      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1384 1378
      public:
1385 1379

	
1386 1380
        EdgeObserverProxy(Snapshot& _snapshot)
1387 1381
          : snapshot(_snapshot) {}
1388 1382

	
1389 1383
        using EdgeNotifier::ObserverBase::attach;
1390 1384
        using EdgeNotifier::ObserverBase::detach;
1391 1385
        using EdgeNotifier::ObserverBase::attached;
1392 1386

	
1393 1387
      protected:
1394 1388

	
1395 1389
        virtual void add(const Edge& edge) {
1396 1390
          snapshot.addEdge(edge);
1397 1391
        }
1398 1392
        virtual void add(const std::vector<Edge>& edges) {
1399 1393
          for (int i = edges.size() - 1; i >= 0; ++i) {
1400 1394
            snapshot.addEdge(edges[i]);
1401 1395
          }
1402 1396
        }
1403 1397
        virtual void erase(const Edge& edge) {
1404 1398
          snapshot.eraseEdge(edge);
1405 1399
        }
1406 1400
        virtual void erase(const std::vector<Edge>& edges) {
1407 1401
          for (int i = 0; i < int(edges.size()); ++i) {
1408 1402
            snapshot.eraseEdge(edges[i]);
1409 1403
          }
1410 1404
        }
1411 1405
        virtual void build() {
1412 1406
          Edge edge;
1413 1407
          std::vector<Edge> edges;
1414 1408
          for (notifier()->first(edge); edge != INVALID;
1415 1409
               notifier()->next(edge)) {
1416 1410
            edges.push_back(edge);
1417 1411
          }
1418 1412
          for (int i = edges.size() - 1; i >= 0; --i) {
1419 1413
            snapshot.addEdge(edges[i]);
1420 1414
          }
1421 1415
        }
1422 1416
        virtual void clear() {
1423 1417
          Edge edge;
1424 1418
          for (notifier()->first(edge); edge != INVALID;
1425 1419
               notifier()->next(edge)) {
1426 1420
            snapshot.eraseEdge(edge);
1427 1421
          }
1428 1422
        }
1429 1423

	
1430 1424
        Snapshot& snapshot;
1431 1425
      };
1432 1426

	
1433 1427
      ListGraph *graph;
1434 1428

	
1435 1429
      NodeObserverProxy node_observer_proxy;
1436 1430
      EdgeObserverProxy edge_observer_proxy;
1437 1431

	
1438 1432
      std::list<Node> added_nodes;
1439 1433
      std::list<Edge> added_edges;
1440 1434

	
1441 1435

	
1442 1436
      void addNode(const Node& node) {
1443 1437
        added_nodes.push_front(node);
1444 1438
      }
1445 1439
      void eraseNode(const Node& node) {
1446 1440
        std::list<Node>::iterator it =
1447 1441
          std::find(added_nodes.begin(), added_nodes.end(), node);
1448 1442
        if (it == added_nodes.end()) {
1449 1443
          clear();
1450 1444
          edge_observer_proxy.detach();
1451 1445
          throw NodeNotifier::ImmediateDetach();
1452 1446
        } else {
1453 1447
          added_nodes.erase(it);
1454 1448
        }
1455 1449
      }
1456 1450

	
1457 1451
      void addEdge(const Edge& edge) {
1458 1452
        added_edges.push_front(edge);
1459 1453
      }
1460 1454
      void eraseEdge(const Edge& edge) {
1461 1455
        std::list<Edge>::iterator it =
1462 1456
          std::find(added_edges.begin(), added_edges.end(), edge);
1463 1457
        if (it == added_edges.end()) {
1464 1458
          clear();
1465 1459
          node_observer_proxy.detach();
1466 1460
          throw EdgeNotifier::ImmediateDetach();
1467 1461
        } else {
1468 1462
          added_edges.erase(it);
1469 1463
        }
1470 1464
      }
1471 1465

	
1472 1466
      void attach(ListGraph &_graph) {
1473 1467
        graph = &_graph;
1474 1468
        node_observer_proxy.attach(graph->notifier(Node()));
1475 1469
        edge_observer_proxy.attach(graph->notifier(Edge()));
1476 1470
      }
1477 1471

	
1478 1472
      void detach() {
1479 1473
        node_observer_proxy.detach();
1480 1474
        edge_observer_proxy.detach();
1481 1475
      }
1482 1476

	
1483 1477
      bool attached() const {
1484 1478
        return node_observer_proxy.attached();
1485 1479
      }
1486 1480

	
1487 1481
      void clear() {
1488 1482
        added_nodes.clear();
1489 1483
        added_edges.clear();
1490 1484
      }
1491 1485

	
1492 1486
    public:
1493 1487

	
1494 1488
      /// \brief Default constructor.
1495 1489
      ///
1496 1490
      /// Default constructor.
1497 1491
      /// To actually make a snapshot you must call save().
1498 1492
      Snapshot()
1499 1493
        : graph(0), node_observer_proxy(*this),
1500 1494
          edge_observer_proxy(*this) {}
1501 1495

	
1502 1496
      /// \brief Constructor that immediately makes a snapshot.
1503 1497
      ///
1504 1498
      /// This constructor immediately makes a snapshot of the graph.
1505 1499
      /// \param _graph The graph we make a snapshot of.
1506 1500
      Snapshot(ListGraph &_graph)
1507 1501
        : node_observer_proxy(*this),
1508 1502
          edge_observer_proxy(*this) {
1509 1503
        attach(_graph);
1510 1504
      }
1511 1505

	
1512 1506
      /// \brief Make a snapshot.
1513 1507
      ///
1514 1508
      /// Make a snapshot of the graph.
1515 1509
      ///
1516 1510
      /// This function can be called more than once. In case of a repeated
1517 1511
      /// call, the previous snapshot gets lost.
1518 1512
      /// \param _graph The graph we make the snapshot of.
1519 1513
      void save(ListGraph &_graph) {
1520 1514
        if (attached()) {
1521 1515
          detach();
1522 1516
          clear();
1523 1517
        }
1524 1518
        attach(_graph);
1525 1519
      }
1526 1520

	
1527 1521
      /// \brief Undo the changes until the last snapshot.
1528 1522
      //
1529 1523
      /// Undo the changes until the last snapshot created by save().
1530 1524
      void restore() {
1531 1525
        detach();
1532 1526
        for(std::list<Edge>::iterator it = added_edges.begin();
1533 1527
            it != added_edges.end(); ++it) {
1534 1528
          graph->erase(*it);
1535 1529
        }
1536 1530
        for(std::list<Node>::iterator it = added_nodes.begin();
1537 1531
            it != added_nodes.end(); ++it) {
1538 1532
          graph->erase(*it);
1539 1533
        }
1540 1534
        clear();
1541 1535
      }
1542 1536

	
1543 1537
      /// \brief Gives back true when the snapshot is valid.
1544 1538
      ///
1545 1539
      /// Gives back true when the snapshot is valid.
1546 1540
      bool valid() const {
1547 1541
        return attached();
1548 1542
      }
1549 1543
    };
1550 1544
  };
1551 1545

	
1552 1546
  /// @}
1553 1547
} //namespace lemon
1554 1548

	
1555 1549

	
1556 1550
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_MAPS_H
20 20
#define LEMON_MAPS_H
21 21

	
22 22
#include <iterator>
23 23
#include <functional>
24 24
#include <vector>
25 25

	
26 26
#include <lemon/core.h>
27 27

	
28 28
///\file
29 29
///\ingroup maps
30 30
///\brief Miscellaneous property maps
31 31

	
32 32
#include <map>
33 33

	
34 34
namespace lemon {
35 35

	
36 36
  /// \addtogroup maps
37 37
  /// @{
38 38

	
39 39
  /// Base class of maps.
40 40

	
41 41
  /// Base class of maps. It provides the necessary type definitions
42 42
  /// required by the map %concepts.
43 43
  template<typename K, typename V>
44 44
  class MapBase {
45 45
  public:
46 46
    /// \brief The key type of the map.
47 47
    typedef K Key;
48 48
    /// \brief The value type of the map.
49 49
    /// (The type of objects associated with the keys).
50 50
    typedef V Value;
51 51
  };
52 52

	
53 53

	
54 54
  /// Null map. (a.k.a. DoNothingMap)
55 55

	
56 56
  /// This map can be used if you have to provide a map only for
57 57
  /// its type definitions, or if you have to provide a writable map,
58 58
  /// but data written to it is not required (i.e. it will be sent to
59 59
  /// <tt>/dev/null</tt>).
60 60
  /// It conforms the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
61 61
  ///
62 62
  /// \sa ConstMap
63 63
  template<typename K, typename V>
64 64
  class NullMap : public MapBase<K, V> {
65 65
  public:
66
    typedef MapBase<K, V> Parent;
67
    typedef typename Parent::Key Key;
68
    typedef typename Parent::Value Value;
66
    ///\e
67
    typedef K Key;
68
    ///\e
69
    typedef V Value;
69 70

	
70 71
    /// Gives back a default constructed element.
71 72
    Value operator[](const Key&) const { return Value(); }
72 73
    /// Absorbs the value.
73 74
    void set(const Key&, const Value&) {}
74 75
  };
75 76

	
76 77
  /// Returns a \c NullMap class
77 78

	
78 79
  /// This function just returns a \c NullMap class.
79 80
  /// \relates NullMap
80 81
  template <typename K, typename V>
81 82
  NullMap<K, V> nullMap() {
82 83
    return NullMap<K, V>();
83 84
  }
84 85

	
85 86

	
86 87
  /// Constant map.
87 88

	
88 89
  /// This \ref concepts::ReadMap "readable map" assigns a specified
89 90
  /// value to each key.
90 91
  ///
91 92
  /// In other aspects it is equivalent to \c NullMap.
92 93
  /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
93 94
  /// concept, but it absorbs the data written to it.
94 95
  ///
95 96
  /// The simplest way of using this map is through the constMap()
96 97
  /// function.
97 98
  ///
98 99
  /// \sa NullMap
99 100
  /// \sa IdentityMap
100 101
  template<typename K, typename V>
101 102
  class ConstMap : public MapBase<K, V> {
102 103
  private:
103 104
    V _value;
104 105
  public:
105
    typedef MapBase<K, V> Parent;
106
    typedef typename Parent::Key Key;
107
    typedef typename Parent::Value Value;
106
    ///\e
107
    typedef K Key;
108
    ///\e
109
    typedef V Value;
108 110

	
109 111
    /// Default constructor
110 112

	
111 113
    /// Default constructor.
112 114
    /// The value of the map will be default constructed.
113 115
    ConstMap() {}
114 116

	
115 117
    /// Constructor with specified initial value
116 118

	
117 119
    /// Constructor with specified initial value.
118 120
    /// \param v The initial value of the map.
119 121
    ConstMap(const Value &v) : _value(v) {}
120 122

	
121 123
    /// Gives back the specified value.
122 124
    Value operator[](const Key&) const { return _value; }
123 125

	
124 126
    /// Absorbs the value.
125 127
    void set(const Key&, const Value&) {}
126 128

	
127 129
    /// Sets the value that is assigned to each key.
128 130
    void setAll(const Value &v) {
129 131
      _value = v;
130 132
    }
131 133

	
132 134
    template<typename V1>
133 135
    ConstMap(const ConstMap<K, V1> &, const Value &v) : _value(v) {}
134 136
  };
135 137

	
136 138
  /// Returns a \c ConstMap class
137 139

	
138 140
  /// This function just returns a \c ConstMap class.
139 141
  /// \relates ConstMap
140 142
  template<typename K, typename V>
141 143
  inline ConstMap<K, V> constMap(const V &v) {
142 144
    return ConstMap<K, V>(v);
143 145
  }
144 146

	
145 147
  template<typename K, typename V>
146 148
  inline ConstMap<K, V> constMap() {
147 149
    return ConstMap<K, V>();
148 150
  }
149 151

	
150 152

	
151 153
  template<typename T, T v>
152 154
  struct Const {};
153 155

	
154 156
  /// Constant map with inlined constant value.
155 157

	
156 158
  /// This \ref concepts::ReadMap "readable map" assigns a specified
157 159
  /// value to each key.
158 160
  ///
159 161
  /// In other aspects it is equivalent to \c NullMap.
160 162
  /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
161 163
  /// concept, but it absorbs the data written to it.
162 164
  ///
163 165
  /// The simplest way of using this map is through the constMap()
164 166
  /// function.
165 167
  ///
166 168
  /// \sa NullMap
167 169
  /// \sa IdentityMap
168 170
  template<typename K, typename V, V v>
169 171
  class ConstMap<K, Const<V, v> > : public MapBase<K, V> {
170 172
  public:
171
    typedef MapBase<K, V> Parent;
172
    typedef typename Parent::Key Key;
173
    typedef typename Parent::Value Value;
173
    ///\e
174
    typedef K Key;
175
    ///\e
176
    typedef V Value;
174 177

	
175 178
    /// Constructor.
176 179
    ConstMap() {}
177 180

	
178 181
    /// Gives back the specified value.
179 182
    Value operator[](const Key&) const { return v; }
180 183

	
181 184
    /// Absorbs the value.
182 185
    void set(const Key&, const Value&) {}
183 186
  };
184 187

	
185 188
  /// Returns a \c ConstMap class with inlined constant value
186 189

	
187 190
  /// This function just returns a \c ConstMap class with inlined
188 191
  /// constant value.
189 192
  /// \relates ConstMap
190 193
  template<typename K, typename V, V v>
191 194
  inline ConstMap<K, Const<V, v> > constMap() {
192 195
    return ConstMap<K, Const<V, v> >();
193 196
  }
194 197

	
195 198

	
196 199
  /// Identity map.
197 200

	
198 201
  /// This \ref concepts::ReadMap "read-only map" gives back the given
199 202
  /// key as value without any modification.
200 203
  ///
201 204
  /// \sa ConstMap
202 205
  template <typename T>
203 206
  class IdentityMap : public MapBase<T, T> {
204 207
  public:
205
    typedef MapBase<T, T> Parent;
206
    typedef typename Parent::Key Key;
207
    typedef typename Parent::Value Value;
208
    ///\e
209
    typedef T Key;
210
    ///\e
211
    typedef T Value;
208 212

	
209 213
    /// Gives back the given value without any modification.
210 214
    Value operator[](const Key &k) const {
211 215
      return k;
212 216
    }
213 217
  };
214 218

	
215 219
  /// Returns an \c IdentityMap class
216 220

	
217 221
  /// This function just returns an \c IdentityMap class.
218 222
  /// \relates IdentityMap
219 223
  template<typename T>
220 224
  inline IdentityMap<T> identityMap() {
221 225
    return IdentityMap<T>();
222 226
  }
223 227

	
224 228

	
225 229
  /// \brief Map for storing values for integer keys from the range
226 230
  /// <tt>[0..size-1]</tt>.
227 231
  ///
228 232
  /// This map is essentially a wrapper for \c std::vector. It assigns
229 233
  /// values to integer keys from the range <tt>[0..size-1]</tt>.
230 234
  /// It can be used with some data structures, for example
231 235
  /// \c UnionFind, \c BinHeap, when the used items are small
232 236
  /// integers. This map conforms the \ref concepts::ReferenceMap
233 237
  /// "ReferenceMap" concept.
234 238
  ///
235 239
  /// The simplest way of using this map is through the rangeMap()
236 240
  /// function.
237 241
  template <typename V>
238 242
  class RangeMap : public MapBase<int, V> {
239 243
    template <typename V1>
240 244
    friend class RangeMap;
241 245
  private:
242 246

	
243 247
    typedef std::vector<V> Vector;
244 248
    Vector _vector;
245 249

	
246 250
  public:
247 251

	
248
    typedef MapBase<int, V> Parent;
249 252
    /// Key type
250
    typedef typename Parent::Key Key;
253
    typedef int Key;
251 254
    /// Value type
252
    typedef typename Parent::Value Value;
255
    typedef V Value;
253 256
    /// Reference type
254 257
    typedef typename Vector::reference Reference;
255 258
    /// Const reference type
256 259
    typedef typename Vector::const_reference ConstReference;
257 260

	
258 261
    typedef True ReferenceMapTag;
259 262

	
260 263
  public:
261 264

	
262 265
    /// Constructor with specified default value.
263 266
    RangeMap(int size = 0, const Value &value = Value())
264 267
      : _vector(size, value) {}
265 268

	
266 269
    /// Constructs the map from an appropriate \c std::vector.
267 270
    template <typename V1>
268 271
    RangeMap(const std::vector<V1>& vector)
269 272
      : _vector(vector.begin(), vector.end()) {}
270 273

	
271 274
    /// Constructs the map from another \c RangeMap.
272 275
    template <typename V1>
273 276
    RangeMap(const RangeMap<V1> &c)
274 277
      : _vector(c._vector.begin(), c._vector.end()) {}
275 278

	
276 279
    /// Returns the size of the map.
277 280
    int size() {
278 281
      return _vector.size();
279 282
    }
280 283

	
281 284
    /// Resizes the map.
282 285

	
283 286
    /// Resizes the underlying \c std::vector container, so changes the
284 287
    /// keyset of the map.
285 288
    /// \param size The new size of the map. The new keyset will be the
286 289
    /// range <tt>[0..size-1]</tt>.
287 290
    /// \param value The default value to assign to the new keys.
288 291
    void resize(int size, const Value &value = Value()) {
289 292
      _vector.resize(size, value);
290 293
    }
291 294

	
292 295
  private:
293 296

	
294 297
    RangeMap& operator=(const RangeMap&);
295 298

	
296 299
  public:
297 300

	
298 301
    ///\e
299 302
    Reference operator[](const Key &k) {
300 303
      return _vector[k];
301 304
    }
302 305

	
303 306
    ///\e
304 307
    ConstReference operator[](const Key &k) const {
305 308
      return _vector[k];
306 309
    }
307 310

	
308 311
    ///\e
309 312
    void set(const Key &k, const Value &v) {
310 313
      _vector[k] = v;
311 314
    }
312 315
  };
313 316

	
314 317
  /// Returns a \c RangeMap class
315 318

	
316 319
  /// This function just returns a \c RangeMap class.
317 320
  /// \relates RangeMap
318 321
  template<typename V>
319 322
  inline RangeMap<V> rangeMap(int size = 0, const V &value = V()) {
320 323
    return RangeMap<V>(size, value);
321 324
  }
322 325

	
323 326
  /// \brief Returns a \c RangeMap class created from an appropriate
324 327
  /// \c std::vector
325 328

	
326 329
  /// This function just returns a \c RangeMap class created from an
327 330
  /// appropriate \c std::vector.
328 331
  /// \relates RangeMap
329 332
  template<typename V>
330 333
  inline RangeMap<V> rangeMap(const std::vector<V> &vector) {
331 334
    return RangeMap<V>(vector);
332 335
  }
333 336

	
334 337

	
335 338
  /// Map type based on \c std::map
336 339

	
337 340
  /// This map is essentially a wrapper for \c std::map with addition
338 341
  /// that you can specify a default value for the keys that are not
339 342
  /// stored actually. This value can be different from the default
340 343
  /// contructed value (i.e. \c %Value()).
341 344
  /// This type conforms the \ref concepts::ReferenceMap "ReferenceMap"
342 345
  /// concept.
343 346
  ///
344 347
  /// This map is useful if a default value should be assigned to most of
345 348
  /// the keys and different values should be assigned only to a few
346 349
  /// keys (i.e. the map is "sparse").
347 350
  /// The name of this type also refers to this important usage.
348 351
  ///
349 352
  /// Apart form that this map can be used in many other cases since it
350 353
  /// is based on \c std::map, which is a general associative container.
351 354
  /// However keep in mind that it is usually not as efficient as other
352 355
  /// maps.
353 356
  ///
354 357
  /// The simplest way of using this map is through the sparseMap()
355 358
  /// function.
356
  template <typename K, typename V, typename Compare = std::less<K> >
359
  template <typename K, typename V, typename Comp = std::less<K> >
357 360
  class SparseMap : public MapBase<K, V> {
358 361
    template <typename K1, typename V1, typename C1>
359 362
    friend class SparseMap;
360 363
  public:
361 364

	
362
    typedef MapBase<K, V> Parent;
363 365
    /// Key type
364
    typedef typename Parent::Key Key;
366
    typedef K Key;
365 367
    /// Value type
366
    typedef typename Parent::Value Value;
368
    typedef V Value;
367 369
    /// Reference type
368 370
    typedef Value& Reference;
369 371
    /// Const reference type
370 372
    typedef const Value& ConstReference;
371 373

	
372 374
    typedef True ReferenceMapTag;
373 375

	
374 376
  private:
375 377

	
376
    typedef std::map<K, V, Compare> Map;
378
    typedef std::map<K, V, Comp> Map;
377 379
    Map _map;
378 380
    Value _value;
379 381

	
380 382
  public:
381 383

	
382 384
    /// \brief Constructor with specified default value.
383 385
    SparseMap(const Value &value = Value()) : _value(value) {}
384 386
    /// \brief Constructs the map from an appropriate \c std::map, and
385 387
    /// explicitly specifies a default value.
386 388
    template <typename V1, typename Comp1>
387 389
    SparseMap(const std::map<Key, V1, Comp1> &map,
388 390
              const Value &value = Value())
389 391
      : _map(map.begin(), map.end()), _value(value) {}
390 392

	
391 393
    /// \brief Constructs the map from another \c SparseMap.
392 394
    template<typename V1, typename Comp1>
393 395
    SparseMap(const SparseMap<Key, V1, Comp1> &c)
394 396
      : _map(c._map.begin(), c._map.end()), _value(c._value) {}
395 397

	
396 398
  private:
397 399

	
398 400
    SparseMap& operator=(const SparseMap&);
399 401

	
400 402
  public:
401 403

	
402 404
    ///\e
403 405
    Reference operator[](const Key &k) {
404 406
      typename Map::iterator it = _map.lower_bound(k);
405 407
      if (it != _map.end() && !_map.key_comp()(k, it->first))
406 408
        return it->second;
407 409
      else
408 410
        return _map.insert(it, std::make_pair(k, _value))->second;
409 411
    }
410 412

	
411 413
    ///\e
412 414
    ConstReference operator[](const Key &k) const {
413 415
      typename Map::const_iterator it = _map.find(k);
414 416
      if (it != _map.end())
415 417
        return it->second;
416 418
      else
417 419
        return _value;
418 420
    }
419 421

	
420 422
    ///\e
421 423
    void set(const Key &k, const Value &v) {
422 424
      typename Map::iterator it = _map.lower_bound(k);
423 425
      if (it != _map.end() && !_map.key_comp()(k, it->first))
424 426
        it->second = v;
425 427
      else
426 428
        _map.insert(it, std::make_pair(k, v));
427 429
    }
428 430

	
429 431
    ///\e
430 432
    void setAll(const Value &v) {
431 433
      _value = v;
432 434
      _map.clear();
433 435
    }
434 436
  };
435 437

	
436 438
  /// Returns a \c SparseMap class
437 439

	
438 440
  /// This function just returns a \c SparseMap class with specified
439 441
  /// default value.
440 442
  /// \relates SparseMap
441 443
  template<typename K, typename V, typename Compare>
442 444
  inline SparseMap<K, V, Compare> sparseMap(const V& value = V()) {
443 445
    return SparseMap<K, V, Compare>(value);
444 446
  }
445 447

	
446 448
  template<typename K, typename V>
447 449
  inline SparseMap<K, V, std::less<K> > sparseMap(const V& value = V()) {
448 450
    return SparseMap<K, V, std::less<K> >(value);
449 451
  }
450 452

	
451 453
  /// \brief Returns a \c SparseMap class created from an appropriate
452 454
  /// \c std::map
453 455

	
454 456
  /// This function just returns a \c SparseMap class created from an
455 457
  /// appropriate \c std::map.
456 458
  /// \relates SparseMap
457 459
  template<typename K, typename V, typename Compare>
458 460
  inline SparseMap<K, V, Compare>
459 461
    sparseMap(const std::map<K, V, Compare> &map, const V& value = V())
460 462
  {
461 463
    return SparseMap<K, V, Compare>(map, value);
462 464
  }
463 465

	
464 466
  /// @}
465 467

	
466 468
  /// \addtogroup map_adaptors
467 469
  /// @{
468 470

	
469 471
  /// Composition of two maps
470 472

	
471 473
  /// This \ref concepts::ReadMap "read-only map" returns the
472 474
  /// composition of two given maps. That is to say, if \c m1 is of
473 475
  /// type \c M1 and \c m2 is of \c M2, then for
474 476
  /// \code
475 477
  ///   ComposeMap<M1, M2> cm(m1,m2);
476 478
  /// \endcode
477 479
  /// <tt>cm[x]</tt> will be equal to <tt>m1[m2[x]]</tt>.
478 480
  ///
479 481
  /// The \c Key type of the map is inherited from \c M2 and the
480 482
  /// \c Value type is from \c M1.
481 483
  /// \c M2::Value must be convertible to \c M1::Key.
482 484
  ///
483 485
  /// The simplest way of using this map is through the composeMap()
484 486
  /// function.
485 487
  ///
486 488
  /// \sa CombineMap
487 489
  template <typename M1, typename M2>
488 490
  class ComposeMap : public MapBase<typename M2::Key, typename M1::Value> {
489 491
    const M1 &_m1;
490 492
    const M2 &_m2;
491 493
  public:
492
    typedef MapBase<typename M2::Key, typename M1::Value> Parent;
493
    typedef typename Parent::Key Key;
494
    typedef typename Parent::Value Value;
494
    ///\e
495
    typedef typename M2::Key Key;
496
    ///\e
497
    typedef typename M1::Value Value;
495 498

	
496 499
    /// Constructor
497 500
    ComposeMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
498 501

	
499
    /// \e
502
    ///\e
500 503
    typename MapTraits<M1>::ConstReturnValue
501 504
    operator[](const Key &k) const { return _m1[_m2[k]]; }
502 505
  };
503 506

	
504 507
  /// Returns a \c ComposeMap class
505 508

	
506 509
  /// This function just returns a \c ComposeMap class.
507 510
  ///
508 511
  /// If \c m1 and \c m2 are maps and the \c Value type of \c m2 is
509 512
  /// convertible to the \c Key of \c m1, then <tt>composeMap(m1,m2)[x]</tt>
510 513
  /// will be equal to <tt>m1[m2[x]]</tt>.
511 514
  ///
512 515
  /// \relates ComposeMap
513 516
  template <typename M1, typename M2>
514 517
  inline ComposeMap<M1, M2> composeMap(const M1 &m1, const M2 &m2) {
515 518
    return ComposeMap<M1, M2>(m1, m2);
516 519
  }
517 520

	
518 521

	
519 522
  /// Combination of two maps using an STL (binary) functor.
520 523

	
521 524
  /// This \ref concepts::ReadMap "read-only map" takes two maps and a
522 525
  /// binary functor and returns the combination of the two given maps
523 526
  /// using the functor.
524 527
  /// That is to say, if \c m1 is of type \c M1 and \c m2 is of \c M2
525 528
  /// and \c f is of \c F, then for
526 529
  /// \code
527 530
  ///   CombineMap<M1,M2,F,V> cm(m1,m2,f);
528 531
  /// \endcode
529 532
  /// <tt>cm[x]</tt> will be equal to <tt>f(m1[x],m2[x])</tt>.
530 533
  ///
531 534
  /// The \c Key type of the map is inherited from \c M1 (\c M1::Key
532 535
  /// must be convertible to \c M2::Key) and the \c Value type is \c V.
533 536
  /// \c M2::Value and \c M1::Value must be convertible to the
534 537
  /// corresponding input parameter of \c F and the return type of \c F
535 538
  /// must be convertible to \c V.
536 539
  ///
537 540
  /// The simplest way of using this map is through the combineMap()
538 541
  /// function.
539 542
  ///
540 543
  /// \sa ComposeMap
541 544
  template<typename M1, typename M2, typename F,
542 545
           typename V = typename F::result_type>
543 546
  class CombineMap : public MapBase<typename M1::Key, V> {
544 547
    const M1 &_m1;
545 548
    const M2 &_m2;
546 549
    F _f;
547 550
  public:
548
    typedef MapBase<typename M1::Key, V> Parent;
549
    typedef typename Parent::Key Key;
550
    typedef typename Parent::Value Value;
551
    ///\e
552
    typedef typename M1::Key Key;
553
    ///\e
554
    typedef V Value;
551 555

	
552 556
    /// Constructor
553 557
    CombineMap(const M1 &m1, const M2 &m2, const F &f = F())
554 558
      : _m1(m1), _m2(m2), _f(f) {}
555
    /// \e
559
    ///\e
556 560
    Value operator[](const Key &k) const { return _f(_m1[k],_m2[k]); }
557 561
  };
558 562

	
559 563
  /// Returns a \c CombineMap class
560 564

	
561 565
  /// This function just returns a \c CombineMap class.
562 566
  ///
563 567
  /// For example, if \c m1 and \c m2 are both maps with \c double
564 568
  /// values, then
565 569
  /// \code
566 570
  ///   combineMap(m1,m2,std::plus<double>())
567 571
  /// \endcode
568 572
  /// is equivalent to
569 573
  /// \code
570 574
  ///   addMap(m1,m2)
571 575
  /// \endcode
572 576
  ///
573 577
  /// This function is specialized for adaptable binary function
574 578
  /// classes and C++ functions.
575 579
  ///
576 580
  /// \relates CombineMap
577 581
  template<typename M1, typename M2, typename F, typename V>
578 582
  inline CombineMap<M1, M2, F, V>
579 583
  combineMap(const M1 &m1, const M2 &m2, const F &f) {
580 584
    return CombineMap<M1, M2, F, V>(m1,m2,f);
581 585
  }
582 586

	
583 587
  template<typename M1, typename M2, typename F>
584 588
  inline CombineMap<M1, M2, F, typename F::result_type>
585 589
  combineMap(const M1 &m1, const M2 &m2, const F &f) {
586 590
    return combineMap<M1, M2, F, typename F::result_type>(m1,m2,f);
587 591
  }
588 592

	
589 593
  template<typename M1, typename M2, typename K1, typename K2, typename V>
590 594
  inline CombineMap<M1, M2, V (*)(K1, K2), V>
591 595
  combineMap(const M1 &m1, const M2 &m2, V (*f)(K1, K2)) {
592 596
    return combineMap<M1, M2, V (*)(K1, K2), V>(m1,m2,f);
593 597
  }
594 598

	
595 599

	
596 600
  /// Converts an STL style (unary) functor to a map
597 601

	
598 602
  /// This \ref concepts::ReadMap "read-only map" returns the value
599 603
  /// of a given functor. Actually, it just wraps the functor and
600 604
  /// provides the \c Key and \c Value typedefs.
601 605
  ///
602 606
  /// Template parameters \c K and \c V will become its \c Key and
603 607
  /// \c Value. In most cases they have to be given explicitly because
604 608
  /// a functor typically does not provide \c argument_type and
605 609
  /// \c result_type typedefs.
606 610
  /// Parameter \c F is the type of the used functor.
607 611
  ///
608 612
  /// The simplest way of using this map is through the functorToMap()
609 613
  /// function.
610 614
  ///
611 615
  /// \sa MapToFunctor
612 616
  template<typename F,
613 617
           typename K = typename F::argument_type,
614 618
           typename V = typename F::result_type>
615 619
  class FunctorToMap : public MapBase<K, V> {
616 620
    F _f;
617 621
  public:
618
    typedef MapBase<K, V> Parent;
619
    typedef typename Parent::Key Key;
620
    typedef typename Parent::Value Value;
622
    ///\e
623
    typedef K Key;
624
    ///\e
625
    typedef V Value;
621 626

	
622 627
    /// Constructor
623 628
    FunctorToMap(const F &f = F()) : _f(f) {}
624
    /// \e
629
    ///\e
625 630
    Value operator[](const Key &k) const { return _f(k); }
626 631
  };
627 632

	
628 633
  /// Returns a \c FunctorToMap class
629 634

	
630 635
  /// This function just returns a \c FunctorToMap class.
631 636
  ///
632 637
  /// This function is specialized for adaptable binary function
633 638
  /// classes and C++ functions.
634 639
  ///
635 640
  /// \relates FunctorToMap
636 641
  template<typename K, typename V, typename F>
637 642
  inline FunctorToMap<F, K, V> functorToMap(const F &f) {
638 643
    return FunctorToMap<F, K, V>(f);
639 644
  }
640 645

	
641 646
  template <typename F>
642 647
  inline FunctorToMap<F, typename F::argument_type, typename F::result_type>
643 648
    functorToMap(const F &f)
644 649
  {
645 650
    return FunctorToMap<F, typename F::argument_type,
646 651
      typename F::result_type>(f);
647 652
  }
648 653

	
649 654
  template <typename K, typename V>
650 655
  inline FunctorToMap<V (*)(K), K, V> functorToMap(V (*f)(K)) {
651 656
    return FunctorToMap<V (*)(K), K, V>(f);
652 657
  }
653 658

	
654 659

	
655 660
  /// Converts a map to an STL style (unary) functor
656 661

	
657 662
  /// This class converts a map to an STL style (unary) functor.
658 663
  /// That is it provides an <tt>operator()</tt> to read its values.
659 664
  ///
660 665
  /// For the sake of convenience it also works as a usual
661 666
  /// \ref concepts::ReadMap "readable map", i.e. <tt>operator[]</tt>
662 667
  /// and the \c Key and \c Value typedefs also exist.
663 668
  ///
664 669
  /// The simplest way of using this map is through the mapToFunctor()
665 670
  /// function.
666 671
  ///
667 672
  ///\sa FunctorToMap
668 673
  template <typename M>
669 674
  class MapToFunctor : public MapBase<typename M::Key, typename M::Value> {
670 675
    const M &_m;
671 676
  public:
672
    typedef MapBase<typename M::Key, typename M::Value> Parent;
673
    typedef typename Parent::Key Key;
674
    typedef typename Parent::Value Value;
675

	
676
    typedef typename Parent::Key argument_type;
677
    typedef typename Parent::Value result_type;
677
    ///\e
678
    typedef typename M::Key Key;
679
    ///\e
680
    typedef typename M::Value Value;
681

	
682
    typedef typename M::Key argument_type;
683
    typedef typename M::Value result_type;
678 684

	
679 685
    /// Constructor
680 686
    MapToFunctor(const M &m) : _m(m) {}
681
    /// \e
687
    ///\e
682 688
    Value operator()(const Key &k) const { return _m[k]; }
683
    /// \e
689
    ///\e
684 690
    Value operator[](const Key &k) const { return _m[k]; }
685 691
  };
686 692

	
687 693
  /// Returns a \c MapToFunctor class
688 694

	
689 695
  /// This function just returns a \c MapToFunctor class.
690 696
  /// \relates MapToFunctor
691 697
  template<typename M>
692 698
  inline MapToFunctor<M> mapToFunctor(const M &m) {
693 699
    return MapToFunctor<M>(m);
694 700
  }
695 701

	
696 702

	
697 703
  /// \brief Map adaptor to convert the \c Value type of a map to
698 704
  /// another type using the default conversion.
699 705

	
700 706
  /// Map adaptor to convert the \c Value type of a \ref concepts::ReadMap
701 707
  /// "readable map" to another type using the default conversion.
702 708
  /// The \c Key type of it is inherited from \c M and the \c Value
703 709
  /// type is \c V.
704 710
  /// This type conforms the \ref concepts::ReadMap "ReadMap" concept.
705 711
  ///
706 712
  /// The simplest way of using this map is through the convertMap()
707 713
  /// function.
708 714
  template <typename M, typename V>
709 715
  class ConvertMap : public MapBase<typename M::Key, V> {
710 716
    const M &_m;
711 717
  public:
712
    typedef MapBase<typename M::Key, V> Parent;
713
    typedef typename Parent::Key Key;
714
    typedef typename Parent::Value Value;
718
    ///\e
719
    typedef typename M::Key Key;
720
    ///\e
721
    typedef V Value;
715 722

	
716 723
    /// Constructor
717 724

	
718 725
    /// Constructor.
719 726
    /// \param m The underlying map.
720 727
    ConvertMap(const M &m) : _m(m) {}
721 728

	
722
    /// \e
729
    ///\e
723 730
    Value operator[](const Key &k) const { return _m[k]; }
724 731
  };
725 732

	
726 733
  /// Returns a \c ConvertMap class
727 734

	
728 735
  /// This function just returns a \c ConvertMap class.
729 736
  /// \relates ConvertMap
730 737
  template<typename V, typename M>
731 738
  inline ConvertMap<M, V> convertMap(const M &map) {
732 739
    return ConvertMap<M, V>(map);
733 740
  }
734 741

	
735 742

	
736 743
  /// Applies all map setting operations to two maps
737 744

	
738 745
  /// This map has two \ref concepts::WriteMap "writable map" parameters
739 746
  /// and each write request will be passed to both of them.
740 747
  /// If \c M1 is also \ref concepts::ReadMap "readable", then the read
741 748
  /// operations will return the corresponding values of \c M1.
742 749
  ///
743 750
  /// The \c Key and \c Value types are inherited from \c M1.
744 751
  /// The \c Key and \c Value of \c M2 must be convertible from those
745 752
  /// of \c M1.
746 753
  ///
747 754
  /// The simplest way of using this map is through the forkMap()
748 755
  /// function.
749 756
  template<typename  M1, typename M2>
750 757
  class ForkMap : public MapBase<typename M1::Key, typename M1::Value> {
751 758
    M1 &_m1;
752 759
    M2 &_m2;
753 760
  public:
754
    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
755
    typedef typename Parent::Key Key;
756
    typedef typename Parent::Value Value;
761
    ///\e
762
    typedef typename M1::Key Key;
763
    ///\e
764
    typedef typename M1::Value Value;
757 765

	
758 766
    /// Constructor
759 767
    ForkMap(M1 &m1, M2 &m2) : _m1(m1), _m2(m2) {}
760 768
    /// Returns the value associated with the given key in the first map.
761 769
    Value operator[](const Key &k) const { return _m1[k]; }
762 770
    /// Sets the value associated with the given key in both maps.
763 771
    void set(const Key &k, const Value &v) { _m1.set(k,v); _m2.set(k,v); }
764 772
  };
765 773

	
766 774
  /// Returns a \c ForkMap class
767 775

	
768 776
  /// This function just returns a \c ForkMap class.
769 777
  /// \relates ForkMap
770 778
  template <typename M1, typename M2>
771 779
  inline ForkMap<M1,M2> forkMap(M1 &m1, M2 &m2) {
772 780
    return ForkMap<M1,M2>(m1,m2);
773 781
  }
774 782

	
775 783

	
776 784
  /// Sum of two maps
777 785

	
778 786
  /// This \ref concepts::ReadMap "read-only map" returns the sum
779 787
  /// of the values of the two given maps.
780 788
  /// Its \c Key and \c Value types are inherited from \c M1.
781 789
  /// The \c Key and \c Value of \c M2 must be convertible to those of
782 790
  /// \c M1.
783 791
  ///
784 792
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
785 793
  /// \code
786 794
  ///   AddMap<M1,M2> am(m1,m2);
787 795
  /// \endcode
788 796
  /// <tt>am[x]</tt> will be equal to <tt>m1[x]+m2[x]</tt>.
789 797
  ///
790 798
  /// The simplest way of using this map is through the addMap()
791 799
  /// function.
792 800
  ///
793 801
  /// \sa SubMap, MulMap, DivMap
794 802
  /// \sa ShiftMap, ShiftWriteMap
795 803
  template<typename M1, typename M2>
796 804
  class AddMap : public MapBase<typename M1::Key, typename M1::Value> {
797 805
    const M1 &_m1;
798 806
    const M2 &_m2;
799 807
  public:
800
    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
801
    typedef typename Parent::Key Key;
802
    typedef typename Parent::Value Value;
808
    ///\e
809
    typedef typename M1::Key Key;
810
    ///\e
811
    typedef typename M1::Value Value;
803 812

	
804 813
    /// Constructor
805 814
    AddMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
806
    /// \e
815
    ///\e
807 816
    Value operator[](const Key &k) const { return _m1[k]+_m2[k]; }
808 817
  };
809 818

	
810 819
  /// Returns an \c AddMap class
811 820

	
812 821
  /// This function just returns an \c AddMap class.
813 822
  ///
814 823
  /// For example, if \c m1 and \c m2 are both maps with \c double
815 824
  /// values, then <tt>addMap(m1,m2)[x]</tt> will be equal to
816 825
  /// <tt>m1[x]+m2[x]</tt>.
817 826
  ///
818 827
  /// \relates AddMap
819 828
  template<typename M1, typename M2>
820 829
  inline AddMap<M1, M2> addMap(const M1 &m1, const M2 &m2) {
821 830
    return AddMap<M1, M2>(m1,m2);
822 831
  }
823 832

	
824 833

	
825 834
  /// Difference of two maps
826 835

	
827 836
  /// This \ref concepts::ReadMap "read-only map" returns the difference
828 837
  /// of the values of the two given maps.
829 838
  /// Its \c Key and \c Value types are inherited from \c M1.
830 839
  /// The \c Key and \c Value of \c M2 must be convertible to those of
831 840
  /// \c M1.
832 841
  ///
833 842
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
834 843
  /// \code
835 844
  ///   SubMap<M1,M2> sm(m1,m2);
836 845
  /// \endcode
837 846
  /// <tt>sm[x]</tt> will be equal to <tt>m1[x]-m2[x]</tt>.
838 847
  ///
839 848
  /// The simplest way of using this map is through the subMap()
840 849
  /// function.
841 850
  ///
842 851
  /// \sa AddMap, MulMap, DivMap
843 852
  template<typename M1, typename M2>
844 853
  class SubMap : public MapBase<typename M1::Key, typename M1::Value> {
845 854
    const M1 &_m1;
846 855
    const M2 &_m2;
847 856
  public:
848
    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
849
    typedef typename Parent::Key Key;
850
    typedef typename Parent::Value Value;
857
    ///\e
858
    typedef typename M1::Key Key;
859
    ///\e
860
    typedef typename M1::Value Value;
851 861

	
852 862
    /// Constructor
853 863
    SubMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
854
    /// \e
864
    ///\e
855 865
    Value operator[](const Key &k) const { return _m1[k]-_m2[k]; }
856 866
  };
857 867

	
858 868
  /// Returns a \c SubMap class
859 869

	
860 870
  /// This function just returns a \c SubMap class.
861 871
  ///
862 872
  /// For example, if \c m1 and \c m2 are both maps with \c double
863 873
  /// values, then <tt>subMap(m1,m2)[x]</tt> will be equal to
864 874
  /// <tt>m1[x]-m2[x]</tt>.
865 875
  ///
866 876
  /// \relates SubMap
867 877
  template<typename M1, typename M2>
868 878
  inline SubMap<M1, M2> subMap(const M1 &m1, const M2 &m2) {
869 879
    return SubMap<M1, M2>(m1,m2);
870 880
  }
871 881

	
872 882

	
873 883
  /// Product of two maps
874 884

	
875 885
  /// This \ref concepts::ReadMap "read-only map" returns the product
876 886
  /// of the values of the two given maps.
877 887
  /// Its \c Key and \c Value types are inherited from \c M1.
878 888
  /// The \c Key and \c Value of \c M2 must be convertible to those of
879 889
  /// \c M1.
880 890
  ///
881 891
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
882 892
  /// \code
883 893
  ///   MulMap<M1,M2> mm(m1,m2);
884 894
  /// \endcode
885 895
  /// <tt>mm[x]</tt> will be equal to <tt>m1[x]*m2[x]</tt>.
886 896
  ///
887 897
  /// The simplest way of using this map is through the mulMap()
888 898
  /// function.
889 899
  ///
890 900
  /// \sa AddMap, SubMap, DivMap
891 901
  /// \sa ScaleMap, ScaleWriteMap
892 902
  template<typename M1, typename M2>
893 903
  class MulMap : public MapBase<typename M1::Key, typename M1::Value> {
894 904
    const M1 &_m1;
895 905
    const M2 &_m2;
896 906
  public:
897
    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
898
    typedef typename Parent::Key Key;
899
    typedef typename Parent::Value Value;
907
    ///\e
908
    typedef typename M1::Key Key;
909
    ///\e
910
    typedef typename M1::Value Value;
900 911

	
901 912
    /// Constructor
902 913
    MulMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
903
    /// \e
914
    ///\e
904 915
    Value operator[](const Key &k) const { return _m1[k]*_m2[k]; }
905 916
  };
906 917

	
907 918
  /// Returns a \c MulMap class
908 919

	
909 920
  /// This function just returns a \c MulMap class.
910 921
  ///
911 922
  /// For example, if \c m1 and \c m2 are both maps with \c double
912 923
  /// values, then <tt>mulMap(m1,m2)[x]</tt> will be equal to
913 924
  /// <tt>m1[x]*m2[x]</tt>.
914 925
  ///
915 926
  /// \relates MulMap
916 927
  template<typename M1, typename M2>
917 928
  inline MulMap<M1, M2> mulMap(const M1 &m1,const M2 &m2) {
918 929
    return MulMap<M1, M2>(m1,m2);
919 930
  }
920 931

	
921 932

	
922 933
  /// Quotient of two maps
923 934

	
924 935
  /// This \ref concepts::ReadMap "read-only map" returns the quotient
925 936
  /// of the values of the two given maps.
926 937
  /// Its \c Key and \c Value types are inherited from \c M1.
927 938
  /// The \c Key and \c Value of \c M2 must be convertible to those of
928 939
  /// \c M1.
929 940
  ///
930 941
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
931 942
  /// \code
932 943
  ///   DivMap<M1,M2> dm(m1,m2);
933 944
  /// \endcode
934 945
  /// <tt>dm[x]</tt> will be equal to <tt>m1[x]/m2[x]</tt>.
935 946
  ///
936 947
  /// The simplest way of using this map is through the divMap()
937 948
  /// function.
938 949
  ///
939 950
  /// \sa AddMap, SubMap, MulMap
940 951
  template<typename M1, typename M2>
941 952
  class DivMap : public MapBase<typename M1::Key, typename M1::Value> {
942 953
    const M1 &_m1;
943 954
    const M2 &_m2;
944 955
  public:
945
    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
946
    typedef typename Parent::Key Key;
947
    typedef typename Parent::Value Value;
956
    ///\e
957
    typedef typename M1::Key Key;
958
    ///\e
959
    typedef typename M1::Value Value;
948 960

	
949 961
    /// Constructor
950 962
    DivMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
951
    /// \e
963
    ///\e
952 964
    Value operator[](const Key &k) const { return _m1[k]/_m2[k]; }
953 965
  };
954 966

	
955 967
  /// Returns a \c DivMap class
956 968

	
957 969
  /// This function just returns a \c DivMap class.
958 970
  ///
959 971
  /// For example, if \c m1 and \c m2 are both maps with \c double
960 972
  /// values, then <tt>divMap(m1,m2)[x]</tt> will be equal to
961 973
  /// <tt>m1[x]/m2[x]</tt>.
962 974
  ///
963 975
  /// \relates DivMap
964 976
  template<typename M1, typename M2>
965 977
  inline DivMap<M1, M2> divMap(const M1 &m1,const M2 &m2) {
966 978
    return DivMap<M1, M2>(m1,m2);
967 979
  }
968 980

	
969 981

	
970 982
  /// Shifts a map with a constant.
971 983

	
972 984
  /// This \ref concepts::ReadMap "read-only map" returns the sum of
973 985
  /// the given map and a constant value (i.e. it shifts the map with
974 986
  /// the constant). Its \c Key and \c Value are inherited from \c M.
975 987
  ///
976 988
  /// Actually,
977 989
  /// \code
978 990
  ///   ShiftMap<M> sh(m,v);
979 991
  /// \endcode
980 992
  /// is equivalent to
981 993
  /// \code
982 994
  ///   ConstMap<M::Key, M::Value> cm(v);
983 995
  ///   AddMap<M, ConstMap<M::Key, M::Value> > sh(m,cm);
984 996
  /// \endcode
985 997
  ///
986 998
  /// The simplest way of using this map is through the shiftMap()
987 999
  /// function.
988 1000
  ///
989 1001
  /// \sa ShiftWriteMap
990 1002
  template<typename M, typename C = typename M::Value>
991 1003
  class ShiftMap : public MapBase<typename M::Key, typename M::Value> {
992 1004
    const M &_m;
993 1005
    C _v;
994 1006
  public:
995
    typedef MapBase<typename M::Key, typename M::Value> Parent;
996
    typedef typename Parent::Key Key;
997
    typedef typename Parent::Value Value;
1007
    ///\e
1008
    typedef typename M::Key Key;
1009
    ///\e
1010
    typedef typename M::Value Value;
998 1011

	
999 1012
    /// Constructor
1000 1013

	
1001 1014
    /// Constructor.
1002 1015
    /// \param m The undelying map.
1003 1016
    /// \param v The constant value.
1004 1017
    ShiftMap(const M &m, const C &v) : _m(m), _v(v) {}
1005
    /// \e
1018
    ///\e
1006 1019
    Value operator[](const Key &k) const { return _m[k]+_v; }
1007 1020
  };
1008 1021

	
1009 1022
  /// Shifts a map with a constant (read-write version).
1010 1023

	
1011 1024
  /// This \ref concepts::ReadWriteMap "read-write map" returns the sum
1012 1025
  /// of the given map and a constant value (i.e. it shifts the map with
1013 1026
  /// the constant). Its \c Key and \c Value are inherited from \c M.
1014 1027
  /// It makes also possible to write the map.
1015 1028
  ///
1016 1029
  /// The simplest way of using this map is through the shiftWriteMap()
1017 1030
  /// function.
1018 1031
  ///
1019 1032
  /// \sa ShiftMap
1020 1033
  template<typename M, typename C = typename M::Value>
1021 1034
  class ShiftWriteMap : public MapBase<typename M::Key, typename M::Value> {
1022 1035
    M &_m;
1023 1036
    C _v;
1024 1037
  public:
1025
    typedef MapBase<typename M::Key, typename M::Value> Parent;
1026
    typedef typename Parent::Key Key;
1027
    typedef typename Parent::Value Value;
1038
    ///\e
1039
    typedef typename M::Key Key;
1040
    ///\e
1041
    typedef typename M::Value Value;
1028 1042

	
1029 1043
    /// Constructor
1030 1044

	
1031 1045
    /// Constructor.
1032 1046
    /// \param m The undelying map.
1033 1047
    /// \param v The constant value.
1034 1048
    ShiftWriteMap(M &m, const C &v) : _m(m), _v(v) {}
1035
    /// \e
1049
    ///\e
1036 1050
    Value operator[](const Key &k) const { return _m[k]+_v; }
1037
    /// \e
1051
    ///\e
1038 1052
    void set(const Key &k, const Value &v) { _m.set(k, v-_v); }
1039 1053
  };
1040 1054

	
1041 1055
  /// Returns a \c ShiftMap class
1042 1056

	
1043 1057
  /// This function just returns a \c ShiftMap class.
1044 1058
  ///
1045 1059
  /// For example, if \c m is a map with \c double values and \c v is
1046 1060
  /// \c double, then <tt>shiftMap(m,v)[x]</tt> will be equal to
1047 1061
  /// <tt>m[x]+v</tt>.
1048 1062
  ///
1049 1063
  /// \relates ShiftMap
1050 1064
  template<typename M, typename C>
1051 1065
  inline ShiftMap<M, C> shiftMap(const M &m, const C &v) {
1052 1066
    return ShiftMap<M, C>(m,v);
1053 1067
  }
1054 1068

	
1055 1069
  /// Returns a \c ShiftWriteMap class
1056 1070

	
1057 1071
  /// This function just returns a \c ShiftWriteMap class.
1058 1072
  ///
1059 1073
  /// For example, if \c m is a map with \c double values and \c v is
1060 1074
  /// \c double, then <tt>shiftWriteMap(m,v)[x]</tt> will be equal to
1061 1075
  /// <tt>m[x]+v</tt>.
1062 1076
  /// Moreover it makes also possible to write the map.
1063 1077
  ///
1064 1078
  /// \relates ShiftWriteMap
1065 1079
  template<typename M, typename C>
1066 1080
  inline ShiftWriteMap<M, C> shiftWriteMap(M &m, const C &v) {
1067 1081
    return ShiftWriteMap<M, C>(m,v);
1068 1082
  }
1069 1083

	
1070 1084

	
1071 1085
  /// Scales a map with a constant.
1072 1086

	
1073 1087
  /// This \ref concepts::ReadMap "read-only map" returns the value of
1074 1088
  /// the given map multiplied from the left side with a constant value.
1075 1089
  /// Its \c Key and \c Value are inherited from \c M.
1076 1090
  ///
1077 1091
  /// Actually,
1078 1092
  /// \code
1079 1093
  ///   ScaleMap<M> sc(m,v);
1080 1094
  /// \endcode
1081 1095
  /// is equivalent to
1082 1096
  /// \code
1083 1097
  ///   ConstMap<M::Key, M::Value> cm(v);
1084 1098
  ///   MulMap<ConstMap<M::Key, M::Value>, M> sc(cm,m);
1085 1099
  /// \endcode
1086 1100
  ///
1087 1101
  /// The simplest way of using this map is through the scaleMap()
1088 1102
  /// function.
1089 1103
  ///
1090 1104
  /// \sa ScaleWriteMap
1091 1105
  template<typename M, typename C = typename M::Value>
1092 1106
  class ScaleMap : public MapBase<typename M::Key, typename M::Value> {
1093 1107
    const M &_m;
1094 1108
    C _v;
1095 1109
  public:
1096
    typedef MapBase<typename M::Key, typename M::Value> Parent;
1097
    typedef typename Parent::Key Key;
1098
    typedef typename Parent::Value Value;
1110
    ///\e
1111
    typedef typename M::Key Key;
1112
    ///\e
1113
    typedef typename M::Value Value;
1099 1114

	
1100 1115
    /// Constructor
1101 1116

	
1102 1117
    /// Constructor.
1103 1118
    /// \param m The undelying map.
1104 1119
    /// \param v The constant value.
1105 1120
    ScaleMap(const M &m, const C &v) : _m(m), _v(v) {}
1106
    /// \e
1121
    ///\e
1107 1122
    Value operator[](const Key &k) const { return _v*_m[k]; }
1108 1123
  };
1109 1124

	
1110 1125
  /// Scales a map with a constant (read-write version).
1111 1126

	
1112 1127
  /// This \ref concepts::ReadWriteMap "read-write map" returns the value of
1113 1128
  /// the given map multiplied from the left side with a constant value.
1114 1129
  /// Its \c Key and \c Value are inherited from \c M.
1115 1130
  /// It can also be used as write map if the \c / operator is defined
1116 1131
  /// between \c Value and \c C and the given multiplier is not zero.
1117 1132
  ///
1118 1133
  /// The simplest way of using this map is through the scaleWriteMap()
1119 1134
  /// function.
1120 1135
  ///
1121 1136
  /// \sa ScaleMap
1122 1137
  template<typename M, typename C = typename M::Value>
1123 1138
  class ScaleWriteMap : public MapBase<typename M::Key, typename M::Value> {
1124 1139
    M &_m;
1125 1140
    C _v;
1126 1141
  public:
1127
    typedef MapBase<typename M::Key, typename M::Value> Parent;
1128
    typedef typename Parent::Key Key;
1129
    typedef typename Parent::Value Value;
1142
    ///\e
1143
    typedef typename M::Key Key;
1144
    ///\e
1145
    typedef typename M::Value Value;
1130 1146

	
1131 1147
    /// Constructor
1132 1148

	
1133 1149
    /// Constructor.
1134 1150
    /// \param m The undelying map.
1135 1151
    /// \param v The constant value.
1136 1152
    ScaleWriteMap(M &m, const C &v) : _m(m), _v(v) {}
1137
    /// \e
1153
    ///\e
1138 1154
    Value operator[](const Key &k) const { return _v*_m[k]; }
1139
    /// \e
1155
    ///\e
1140 1156
    void set(const Key &k, const Value &v) { _m.set(k, v/_v); }
1141 1157
  };
1142 1158

	
1143 1159
  /// Returns a \c ScaleMap class
1144 1160

	
1145 1161
  /// This function just returns a \c ScaleMap class.
1146 1162
  ///
1147 1163
  /// For example, if \c m is a map with \c double values and \c v is
1148 1164
  /// \c double, then <tt>scaleMap(m,v)[x]</tt> will be equal to
1149 1165
  /// <tt>v*m[x]</tt>.
1150 1166
  ///
1151 1167
  /// \relates ScaleMap
1152 1168
  template<typename M, typename C>
1153 1169
  inline ScaleMap<M, C> scaleMap(const M &m, const C &v) {
1154 1170
    return ScaleMap<M, C>(m,v);
1155 1171
  }
1156 1172

	
1157 1173
  /// Returns a \c ScaleWriteMap class
1158 1174

	
1159 1175
  /// This function just returns a \c ScaleWriteMap class.
1160 1176
  ///
1161 1177
  /// For example, if \c m is a map with \c double values and \c v is
1162 1178
  /// \c double, then <tt>scaleWriteMap(m,v)[x]</tt> will be equal to
1163 1179
  /// <tt>v*m[x]</tt>.
1164 1180
  /// Moreover it makes also possible to write the map.
1165 1181
  ///
1166 1182
  /// \relates ScaleWriteMap
1167 1183
  template<typename M, typename C>
1168 1184
  inline ScaleWriteMap<M, C> scaleWriteMap(M &m, const C &v) {
1169 1185
    return ScaleWriteMap<M, C>(m,v);
1170 1186
  }
1171 1187

	
1172 1188

	
1173 1189
  /// Negative of a map
1174 1190

	
1175 1191
  /// This \ref concepts::ReadMap "read-only map" returns the negative
1176 1192
  /// of the values of the given map (using the unary \c - operator).
1177 1193
  /// Its \c Key and \c Value are inherited from \c M.
1178 1194
  ///
1179 1195
  /// If M::Value is \c int, \c double etc., then
1180 1196
  /// \code
1181 1197
  ///   NegMap<M> neg(m);
1182 1198
  /// \endcode
1183 1199
  /// is equivalent to
1184 1200
  /// \code
1185 1201
  ///   ScaleMap<M> neg(m,-1);
1186 1202
  /// \endcode
1187 1203
  ///
1188 1204
  /// The simplest way of using this map is through the negMap()
1189 1205
  /// function.
1190 1206
  ///
1191 1207
  /// \sa NegWriteMap
1192 1208
  template<typename M>
1193 1209
  class NegMap : public MapBase<typename M::Key, typename M::Value> {
1194 1210
    const M& _m;
1195 1211
  public:
1196
    typedef MapBase<typename M::Key, typename M::Value> Parent;
1197
    typedef typename Parent::Key Key;
1198
    typedef typename Parent::Value Value;
1212
    ///\e
1213
    typedef typename M::Key Key;
1214
    ///\e
1215
    typedef typename M::Value Value;
1199 1216

	
1200 1217
    /// Constructor
1201 1218
    NegMap(const M &m) : _m(m) {}
1202
    /// \e
1219
    ///\e
1203 1220
    Value operator[](const Key &k) const { return -_m[k]; }
1204 1221
  };
1205 1222

	
1206 1223
  /// Negative of a map (read-write version)
1207 1224

	
1208 1225
  /// This \ref concepts::ReadWriteMap "read-write map" returns the
1209 1226
  /// negative of the values of the given map (using the unary \c -
1210 1227
  /// operator).
1211 1228
  /// Its \c Key and \c Value are inherited from \c M.
1212 1229
  /// It makes also possible to write the map.
1213 1230
  ///
1214 1231
  /// If M::Value is \c int, \c double etc., then
1215 1232
  /// \code
1216 1233
  ///   NegWriteMap<M> neg(m);
1217 1234
  /// \endcode
1218 1235
  /// is equivalent to
1219 1236
  /// \code
1220 1237
  ///   ScaleWriteMap<M> neg(m,-1);
1221 1238
  /// \endcode
1222 1239
  ///
1223 1240
  /// The simplest way of using this map is through the negWriteMap()
1224 1241
  /// function.
1225 1242
  ///
1226 1243
  /// \sa NegMap
1227 1244
  template<typename M>
1228 1245
  class NegWriteMap : public MapBase<typename M::Key, typename M::Value> {
1229 1246
    M &_m;
1230 1247
  public:
1231
    typedef MapBase<typename M::Key, typename M::Value> Parent;
1232
    typedef typename Parent::Key Key;
1233
    typedef typename Parent::Value Value;
1248
    ///\e
1249
    typedef typename M::Key Key;
1250
    ///\e
1251
    typedef typename M::Value Value;
1234 1252

	
1235 1253
    /// Constructor
1236 1254
    NegWriteMap(M &m) : _m(m) {}
1237
    /// \e
1255
    ///\e
1238 1256
    Value operator[](const Key &k) const { return -_m[k]; }
1239
    /// \e
1257
    ///\e
1240 1258
    void set(const Key &k, const Value &v) { _m.set(k, -v); }
1241 1259
  };
1242 1260

	
1243 1261
  /// Returns a \c NegMap class
1244 1262

	
1245 1263
  /// This function just returns a \c NegMap class.
1246 1264
  ///
1247 1265
  /// For example, if \c m is a map with \c double values, then
1248 1266
  /// <tt>negMap(m)[x]</tt> will be equal to <tt>-m[x]</tt>.
1249 1267
  ///
1250 1268
  /// \relates NegMap
1251 1269
  template <typename M>
1252 1270
  inline NegMap<M> negMap(const M &m) {
1253 1271
    return NegMap<M>(m);
1254 1272
  }
1255 1273

	
1256 1274
  /// Returns a \c NegWriteMap class
1257 1275

	
1258 1276
  /// This function just returns a \c NegWriteMap class.
1259 1277
  ///
1260 1278
  /// For example, if \c m is a map with \c double values, then
1261 1279
  /// <tt>negWriteMap(m)[x]</tt> will be equal to <tt>-m[x]</tt>.
1262 1280
  /// Moreover it makes also possible to write the map.
1263 1281
  ///
1264 1282
  /// \relates NegWriteMap
1265 1283
  template <typename M>
1266 1284
  inline NegWriteMap<M> negWriteMap(M &m) {
1267 1285
    return NegWriteMap<M>(m);
1268 1286
  }
1269 1287

	
1270 1288

	
1271 1289
  /// Absolute value of a map
1272 1290

	
1273 1291
  /// This \ref concepts::ReadMap "read-only map" returns the absolute
1274 1292
  /// value of the values of the given map.
1275 1293
  /// Its \c Key and \c Value are inherited from \c M.
1276 1294
  /// \c Value must be comparable to \c 0 and the unary \c -
1277 1295
  /// operator must be defined for it, of course.
1278 1296
  ///
1279 1297
  /// The simplest way of using this map is through the absMap()
1280 1298
  /// function.
1281 1299
  template<typename M>
1282 1300
  class AbsMap : public MapBase<typename M::Key, typename M::Value> {
1283 1301
    const M &_m;
1284 1302
  public:
1285
    typedef MapBase<typename M::Key, typename M::Value> Parent;
1286
    typedef typename Parent::Key Key;
1287
    typedef typename Parent::Value Value;
1303
    ///\e
1304
    typedef typename M::Key Key;
1305
    ///\e
1306
    typedef typename M::Value Value;
1288 1307

	
1289 1308
    /// Constructor
1290 1309
    AbsMap(const M &m) : _m(m) {}
1291
    /// \e
1310
    ///\e
1292 1311
    Value operator[](const Key &k) const {
1293 1312
      Value tmp = _m[k];
1294 1313
      return tmp >= 0 ? tmp : -tmp;
1295 1314
    }
1296 1315

	
1297 1316
  };
1298 1317

	
1299 1318
  /// Returns an \c AbsMap class
1300 1319

	
1301 1320
  /// This function just returns an \c AbsMap class.
1302 1321
  ///
1303 1322
  /// For example, if \c m is a map with \c double values, then
1304 1323
  /// <tt>absMap(m)[x]</tt> will be equal to <tt>m[x]</tt> if
1305 1324
  /// it is positive or zero and <tt>-m[x]</tt> if <tt>m[x]</tt> is
1306 1325
  /// negative.
1307 1326
  ///
1308 1327
  /// \relates AbsMap
1309 1328
  template<typename M>
1310 1329
  inline AbsMap<M> absMap(const M &m) {
1311 1330
    return AbsMap<M>(m);
1312 1331
  }
1313 1332

	
1314 1333
  /// @}
1315 1334

	
1316 1335
  // Logical maps and map adaptors:
1317 1336

	
1318 1337
  /// \addtogroup maps
1319 1338
  /// @{
1320 1339

	
1321 1340
  /// Constant \c true map.
1322 1341

	
1323 1342
  /// This \ref concepts::ReadMap "read-only map" assigns \c true to
1324 1343
  /// each key.
1325 1344
  ///
1326 1345
  /// Note that
1327 1346
  /// \code
1328 1347
  ///   TrueMap<K> tm;
1329 1348
  /// \endcode
1330 1349
  /// is equivalent to
1331 1350
  /// \code
1332 1351
  ///   ConstMap<K,bool> tm(true);
1333 1352
  /// \endcode
1334 1353
  ///
1335 1354
  /// \sa FalseMap
1336 1355
  /// \sa ConstMap
1337 1356
  template <typename K>
1338 1357
  class TrueMap : public MapBase<K, bool> {
1339 1358
  public:
1340
    typedef MapBase<K, bool> Parent;
1341
    typedef typename Parent::Key Key;
1342
    typedef typename Parent::Value Value;
1359
    ///\e
1360
    typedef K Key;
1361
    ///\e
1362
    typedef bool Value;
1343 1363

	
1344 1364
    /// Gives back \c true.
1345 1365
    Value operator[](const Key&) const { return true; }
1346 1366
  };
1347 1367

	
1348 1368
  /// Returns a \c TrueMap class
1349 1369

	
1350 1370
  /// This function just returns a \c TrueMap class.
1351 1371
  /// \relates TrueMap
1352 1372
  template<typename K>
1353 1373
  inline TrueMap<K> trueMap() {
1354 1374
    return TrueMap<K>();
1355 1375
  }
1356 1376

	
1357 1377

	
1358 1378
  /// Constant \c false map.
1359 1379

	
1360 1380
  /// This \ref concepts::ReadMap "read-only map" assigns \c false to
1361 1381
  /// each key.
1362 1382
  ///
1363 1383
  /// Note that
1364 1384
  /// \code
1365 1385
  ///   FalseMap<K> fm;
1366 1386
  /// \endcode
1367 1387
  /// is equivalent to
1368 1388
  /// \code
1369 1389
  ///   ConstMap<K,bool> fm(false);
1370 1390
  /// \endcode
1371 1391
  ///
1372 1392
  /// \sa TrueMap
1373 1393
  /// \sa ConstMap
1374 1394
  template <typename K>
1375 1395
  class FalseMap : public MapBase<K, bool> {
1376 1396
  public:
1377
    typedef MapBase<K, bool> Parent;
1378
    typedef typename Parent::Key Key;
1379
    typedef typename Parent::Value Value;
1397
    ///\e
1398
    typedef K Key;
1399
    ///\e
1400
    typedef bool Value;
1380 1401

	
1381 1402
    /// Gives back \c false.
1382 1403
    Value operator[](const Key&) const { return false; }
1383 1404
  };
1384 1405

	
1385 1406
  /// Returns a \c FalseMap class
1386 1407

	
1387 1408
  /// This function just returns a \c FalseMap class.
1388 1409
  /// \relates FalseMap
1389 1410
  template<typename K>
1390 1411
  inline FalseMap<K> falseMap() {
1391 1412
    return FalseMap<K>();
1392 1413
  }
1393 1414

	
1394 1415
  /// @}
1395 1416

	
1396 1417
  /// \addtogroup map_adaptors
1397 1418
  /// @{
1398 1419

	
1399 1420
  /// Logical 'and' of two maps
1400 1421

	
1401 1422
  /// This \ref concepts::ReadMap "read-only map" returns the logical
1402 1423
  /// 'and' of the values of the two given maps.
1403 1424
  /// Its \c Key type is inherited from \c M1 and its \c Value type is
1404 1425
  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
1405 1426
  ///
1406 1427
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
1407 1428
  /// \code
1408 1429
  ///   AndMap<M1,M2> am(m1,m2);
1409 1430
  /// \endcode
1410 1431
  /// <tt>am[x]</tt> will be equal to <tt>m1[x]&&m2[x]</tt>.
1411 1432
  ///
1412 1433
  /// The simplest way of using this map is through the andMap()
1413 1434
  /// function.
1414 1435
  ///
1415 1436
  /// \sa OrMap
1416 1437
  /// \sa NotMap, NotWriteMap
1417 1438
  template<typename M1, typename M2>
1418 1439
  class AndMap : public MapBase<typename M1::Key, bool> {
1419 1440
    const M1 &_m1;
1420 1441
    const M2 &_m2;
1421 1442
  public:
1422
    typedef MapBase<typename M1::Key, bool> Parent;
1423
    typedef typename Parent::Key Key;
1424
    typedef typename Parent::Value Value;
1443
    ///\e
1444
    typedef typename M1::Key Key;
1445
    ///\e
1446
    typedef bool Value;
1425 1447

	
1426 1448
    /// Constructor
1427 1449
    AndMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
1428
    /// \e
1450
    ///\e
1429 1451
    Value operator[](const Key &k) const { return _m1[k]&&_m2[k]; }
1430 1452
  };
1431 1453

	
1432 1454
  /// Returns an \c AndMap class
1433 1455

	
1434 1456
  /// This function just returns an \c AndMap class.
1435 1457
  ///
1436 1458
  /// For example, if \c m1 and \c m2 are both maps with \c bool values,
1437 1459
  /// then <tt>andMap(m1,m2)[x]</tt> will be equal to
1438 1460
  /// <tt>m1[x]&&m2[x]</tt>.
1439 1461
  ///
1440 1462
  /// \relates AndMap
1441 1463
  template<typename M1, typename M2>
1442 1464
  inline AndMap<M1, M2> andMap(const M1 &m1, const M2 &m2) {
1443 1465
    return AndMap<M1, M2>(m1,m2);
1444 1466
  }
1445 1467

	
1446 1468

	
1447 1469
  /// Logical 'or' of two maps
1448 1470

	
1449 1471
  /// This \ref concepts::ReadMap "read-only map" returns the logical
1450 1472
  /// 'or' of the values of the two given maps.
1451 1473
  /// Its \c Key type is inherited from \c M1 and its \c Value type is
1452 1474
  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
1453 1475
  ///
1454 1476
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
1455 1477
  /// \code
1456 1478
  ///   OrMap<M1,M2> om(m1,m2);
1457 1479
  /// \endcode
1458 1480
  /// <tt>om[x]</tt> will be equal to <tt>m1[x]||m2[x]</tt>.
1459 1481
  ///
1460 1482
  /// The simplest way of using this map is through the orMap()
1461 1483
  /// function.
1462 1484
  ///
1463 1485
  /// \sa AndMap
1464 1486
  /// \sa NotMap, NotWriteMap
1465 1487
  template<typename M1, typename M2>
1466 1488
  class OrMap : public MapBase<typename M1::Key, bool> {
1467 1489
    const M1 &_m1;
1468 1490
    const M2 &_m2;
1469 1491
  public:
1470
    typedef MapBase<typename M1::Key, bool> Parent;
1471
    typedef typename Parent::Key Key;
1472
    typedef typename Parent::Value Value;
1492
    ///\e
1493
    typedef typename M1::Key Key;
1494
    ///\e
1495
    typedef bool Value;
1473 1496

	
1474 1497
    /// Constructor
1475 1498
    OrMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
1476
    /// \e
1499
    ///\e
1477 1500
    Value operator[](const Key &k) const { return _m1[k]||_m2[k]; }
1478 1501
  };
1479 1502

	
1480 1503
  /// Returns an \c OrMap class
1481 1504

	
1482 1505
  /// This function just returns an \c OrMap class.
1483 1506
  ///
1484 1507
  /// For example, if \c m1 and \c m2 are both maps with \c bool values,
1485 1508
  /// then <tt>orMap(m1,m2)[x]</tt> will be equal to
1486 1509
  /// <tt>m1[x]||m2[x]</tt>.
1487 1510
  ///
1488 1511
  /// \relates OrMap
1489 1512
  template<typename M1, typename M2>
1490 1513
  inline OrMap<M1, M2> orMap(const M1 &m1, const M2 &m2) {
1491 1514
    return OrMap<M1, M2>(m1,m2);
1492 1515
  }
1493 1516

	
1494 1517

	
1495 1518
  /// Logical 'not' of a map
1496 1519

	
1497 1520
  /// This \ref concepts::ReadMap "read-only map" returns the logical
1498 1521
  /// negation of the values of the given map.
1499 1522
  /// Its \c Key is inherited from \c M and its \c Value is \c bool.
1500 1523
  ///
1501 1524
  /// The simplest way of using this map is through the notMap()
1502 1525
  /// function.
1503 1526
  ///
1504 1527
  /// \sa NotWriteMap
1505 1528
  template <typename M>
1506 1529
  class NotMap : public MapBase<typename M::Key, bool> {
1507 1530
    const M &_m;
1508 1531
  public:
1509
    typedef MapBase<typename M::Key, bool> Parent;
1510
    typedef typename Parent::Key Key;
1511
    typedef typename Parent::Value Value;
1532
    ///\e
1533
    typedef typename M::Key Key;
1534
    ///\e
1535
    typedef bool Value;
1512 1536

	
1513 1537
    /// Constructor
1514 1538
    NotMap(const M &m) : _m(m) {}
1515
    /// \e
1539
    ///\e
1516 1540
    Value operator[](const Key &k) const { return !_m[k]; }
1517 1541
  };
1518 1542

	
1519 1543
  /// Logical 'not' of a map (read-write version)
1520 1544

	
1521 1545
  /// This \ref concepts::ReadWriteMap "read-write map" returns the
1522 1546
  /// logical negation of the values of the given map.
1523 1547
  /// Its \c Key is inherited from \c M and its \c Value is \c bool.
1524 1548
  /// It makes also possible to write the map. When a value is set,
1525 1549
  /// the opposite value is set to the original map.
1526 1550
  ///
1527 1551
  /// The simplest way of using this map is through the notWriteMap()
1528 1552
  /// function.
1529 1553
  ///
1530 1554
  /// \sa NotMap
1531 1555
  template <typename M>
1532 1556
  class NotWriteMap : public MapBase<typename M::Key, bool> {
1533 1557
    M &_m;
1534 1558
  public:
1535
    typedef MapBase<typename M::Key, bool> Parent;
1536
    typedef typename Parent::Key Key;
1537
    typedef typename Parent::Value Value;
1559
    ///\e
1560
    typedef typename M::Key Key;
1561
    ///\e
1562
    typedef bool Value;
1538 1563

	
1539 1564
    /// Constructor
1540 1565
    NotWriteMap(M &m) : _m(m) {}
1541
    /// \e
1566
    ///\e
1542 1567
    Value operator[](const Key &k) const { return !_m[k]; }
1543
    /// \e
1568
    ///\e
1544 1569
    void set(const Key &k, bool v) { _m.set(k, !v); }
1545 1570
  };
1546 1571

	
1547 1572
  /// Returns a \c NotMap class
1548 1573

	
1549 1574
  /// This function just returns a \c NotMap class.
1550 1575
  ///
1551 1576
  /// For example, if \c m is a map with \c bool values, then
1552 1577
  /// <tt>notMap(m)[x]</tt> will be equal to <tt>!m[x]</tt>.
1553 1578
  ///
1554 1579
  /// \relates NotMap
1555 1580
  template <typename M>
1556 1581
  inline NotMap<M> notMap(const M &m) {
1557 1582
    return NotMap<M>(m);
1558 1583
  }
1559 1584

	
1560 1585
  /// Returns a \c NotWriteMap class
1561 1586

	
1562 1587
  /// This function just returns a \c NotWriteMap class.
1563 1588
  ///
1564 1589
  /// For example, if \c m is a map with \c bool values, then
1565 1590
  /// <tt>notWriteMap(m)[x]</tt> will be equal to <tt>!m[x]</tt>.
1566 1591
  /// Moreover it makes also possible to write the map.
1567 1592
  ///
1568 1593
  /// \relates NotWriteMap
1569 1594
  template <typename M>
1570 1595
  inline NotWriteMap<M> notWriteMap(M &m) {
1571 1596
    return NotWriteMap<M>(m);
1572 1597
  }
1573 1598

	
1574 1599

	
1575 1600
  /// Combination of two maps using the \c == operator
1576 1601

	
1577 1602
  /// This \ref concepts::ReadMap "read-only map" assigns \c true to
1578 1603
  /// the keys for which the corresponding values of the two maps are
1579 1604
  /// equal.
1580 1605
  /// Its \c Key type is inherited from \c M1 and its \c Value type is
1581 1606
  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
1582 1607
  ///
1583 1608
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
1584 1609
  /// \code
1585 1610
  ///   EqualMap<M1,M2> em(m1,m2);
1586 1611
  /// \endcode
1587 1612
  /// <tt>em[x]</tt> will be equal to <tt>m1[x]==m2[x]</tt>.
1588 1613
  ///
1589 1614
  /// The simplest way of using this map is through the equalMap()
1590 1615
  /// function.
1591 1616
  ///
1592 1617
  /// \sa LessMap
1593 1618
  template<typename M1, typename M2>
1594 1619
  class EqualMap : public MapBase<typename M1::Key, bool> {
1595 1620
    const M1 &_m1;
1596 1621
    const M2 &_m2;
1597 1622
  public:
1598
    typedef MapBase<typename M1::Key, bool> Parent;
1599
    typedef typename Parent::Key Key;
1600
    typedef typename Parent::Value Value;
1623
    ///\e
1624
    typedef typename M1::Key Key;
1625
    ///\e
1626
    typedef bool Value;
1601 1627

	
1602 1628
    /// Constructor
1603 1629
    EqualMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
1604
    /// \e
1630
    ///\e
1605 1631
    Value operator[](const Key &k) const { return _m1[k]==_m2[k]; }
1606 1632
  };
1607 1633

	
1608 1634
  /// Returns an \c EqualMap class
1609 1635

	
1610 1636
  /// This function just returns an \c EqualMap class.
1611 1637
  ///
1612 1638
  /// For example, if \c m1 and \c m2 are maps with keys and values of
1613 1639
  /// the same type, then <tt>equalMap(m1,m2)[x]</tt> will be equal to
1614 1640
  /// <tt>m1[x]==m2[x]</tt>.
1615 1641
  ///
1616 1642
  /// \relates EqualMap
1617 1643
  template<typename M1, typename M2>
1618 1644
  inline EqualMap<M1, M2> equalMap(const M1 &m1, const M2 &m2) {
1619 1645
    return EqualMap<M1, M2>(m1,m2);
1620 1646
  }
1621 1647

	
1622 1648

	
1623 1649
  /// Combination of two maps using the \c < operator
1624 1650

	
1625 1651
  /// This \ref concepts::ReadMap "read-only map" assigns \c true to
1626 1652
  /// the keys for which the corresponding value of the first map is
1627 1653
  /// less then the value of the second map.
1628 1654
  /// Its \c Key type is inherited from \c M1 and its \c Value type is
1629 1655
  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
1630 1656
  ///
1631 1657
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
1632 1658
  /// \code
1633 1659
  ///   LessMap<M1,M2> lm(m1,m2);
1634 1660
  /// \endcode
1635 1661
  /// <tt>lm[x]</tt> will be equal to <tt>m1[x]<m2[x]</tt>.
1636 1662
  ///
1637 1663
  /// The simplest way of using this map is through the lessMap()
1638 1664
  /// function.
1639 1665
  ///
1640 1666
  /// \sa EqualMap
1641 1667
  template<typename M1, typename M2>
1642 1668
  class LessMap : public MapBase<typename M1::Key, bool> {
1643 1669
    const M1 &_m1;
1644 1670
    const M2 &_m2;
1645 1671
  public:
1646
    typedef MapBase<typename M1::Key, bool> Parent;
1647
    typedef typename Parent::Key Key;
1648
    typedef typename Parent::Value Value;
1672
    ///\e
1673
    typedef typename M1::Key Key;
1674
    ///\e
1675
    typedef bool Value;
1649 1676

	
1650 1677
    /// Constructor
1651 1678
    LessMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
1652
    /// \e
1679
    ///\e
1653 1680
    Value operator[](const Key &k) const { return _m1[k]<_m2[k]; }
1654 1681
  };
1655 1682

	
1656 1683
  /// Returns an \c LessMap class
1657 1684

	
1658 1685
  /// This function just returns an \c LessMap class.
1659 1686
  ///
1660 1687
  /// For example, if \c m1 and \c m2 are maps with keys and values of
1661 1688
  /// the same type, then <tt>lessMap(m1,m2)[x]</tt> will be equal to
1662 1689
  /// <tt>m1[x]<m2[x]</tt>.
1663 1690
  ///
1664 1691
  /// \relates LessMap
1665 1692
  template<typename M1, typename M2>
1666 1693
  inline LessMap<M1, M2> lessMap(const M1 &m1, const M2 &m2) {
1667 1694
    return LessMap<M1, M2>(m1,m2);
1668 1695
  }
1669 1696

	
1670 1697
  namespace _maps_bits {
1671 1698

	
1672 1699
    template <typename _Iterator, typename Enable = void>
1673 1700
    struct IteratorTraits {
1674 1701
      typedef typename std::iterator_traits<_Iterator>::value_type Value;
1675 1702
    };
1676 1703

	
1677 1704
    template <typename _Iterator>
1678 1705
    struct IteratorTraits<_Iterator,
1679 1706
      typename exists<typename _Iterator::container_type>::type>
1680 1707
    {
1681 1708
      typedef typename _Iterator::container_type::value_type Value;
1682 1709
    };
1683 1710

	
1684 1711
  }
1685 1712

	
1686 1713
  /// @}
1687 1714

	
1688 1715
  /// \addtogroup maps
1689 1716
  /// @{
1690 1717

	
1691 1718
  /// \brief Writable bool map for logging each \c true assigned element
1692 1719
  ///
1693 1720
  /// A \ref concepts::WriteMap "writable" bool map for logging
1694 1721
  /// each \c true assigned element, i.e it copies subsequently each
1695 1722
  /// keys set to \c true to the given iterator.
1696 1723
  /// The most important usage of it is storing certain nodes or arcs
1697 1724
  /// that were marked \c true by an algorithm.
1698 1725
  ///
1699 1726
  /// There are several algorithms that provide solutions through bool
1700 1727
  /// maps and most of them assign \c true at most once for each key.
1701 1728
  /// In these cases it is a natural request to store each \c true
1702 1729
  /// assigned elements (in order of the assignment), which can be
1703 1730
  /// easily done with LoggerBoolMap.
1704 1731
  ///
1705 1732
  /// The simplest way of using this map is through the loggerBoolMap()
1706 1733
  /// function.
1707 1734
  ///
1708
  /// \tparam It The type of the iterator.
1709
  /// \tparam Ke The key type of the map. The default value set
1735
  /// \tparam IT The type of the iterator.
1736
  /// \tparam KEY The key type of the map. The default value set
1710 1737
  /// according to the iterator type should work in most cases.
1711 1738
  ///
1712 1739
  /// \note The container of the iterator must contain enough space
1713 1740
  /// for the elements or the iterator should be an inserter iterator.
1714 1741
#ifdef DOXYGEN
1715
  template <typename It, typename Ke>
1742
  template <typename IT, typename KEY>
1716 1743
#else
1717
  template <typename It,
1718
            typename Ke=typename _maps_bits::IteratorTraits<It>::Value>
1744
  template <typename IT,
1745
            typename KEY = typename _maps_bits::IteratorTraits<IT>::Value>
1719 1746
#endif
1720
  class LoggerBoolMap {
1747
  class LoggerBoolMap : public MapBase<KEY, bool> {
1721 1748
  public:
1722
    typedef It Iterator;
1723

	
1724
    typedef Ke Key;
1749

	
1750
    ///\e
1751
    typedef KEY Key;
1752
    ///\e
1725 1753
    typedef bool Value;
1754
    ///\e
1755
    typedef IT Iterator;
1726 1756

	
1727 1757
    /// Constructor
1728 1758
    LoggerBoolMap(Iterator it)
1729 1759
      : _begin(it), _end(it) {}
1730 1760

	
1731 1761
    /// Gives back the given iterator set for the first key
1732 1762
    Iterator begin() const {
1733 1763
      return _begin;
1734 1764
    }
1735 1765

	
1736 1766
    /// Gives back the the 'after the last' iterator
1737 1767
    Iterator end() const {
1738 1768
      return _end;
1739 1769
    }
1740 1770

	
1741 1771
    /// The set function of the map
1742 1772
    void set(const Key& key, Value value) {
1743 1773
      if (value) {
1744 1774
        *_end++ = key;
1745 1775
      }
1746 1776
    }
1747 1777

	
1748 1778
  private:
1749 1779
    Iterator _begin;
1750 1780
    Iterator _end;
1751 1781
  };
1752 1782

	
1753 1783
  /// Returns a \c LoggerBoolMap class
1754 1784

	
1755 1785
  /// This function just returns a \c LoggerBoolMap class.
1756 1786
  ///
1757 1787
  /// The most important usage of it is storing certain nodes or arcs
1758 1788
  /// that were marked \c true by an algorithm.
1759 1789
  /// For example it makes easier to store the nodes in the processing
1760 1790
  /// order of Dfs algorithm, as the following examples show.
1761 1791
  /// \code
1762 1792
  ///   std::vector<Node> v;
1763 1793
  ///   dfs(g,s).processedMap(loggerBoolMap(std::back_inserter(v))).run();
1764 1794
  /// \endcode
1765 1795
  /// \code
1766 1796
  ///   std::vector<Node> v(countNodes(g));
1767 1797
  ///   dfs(g,s).processedMap(loggerBoolMap(v.begin())).run();
1768 1798
  /// \endcode
1769 1799
  ///
1770 1800
  /// \note The container of the iterator must contain enough space
1771 1801
  /// for the elements or the iterator should be an inserter iterator.
1772 1802
  ///
1773 1803
  /// \note LoggerBoolMap is just \ref concepts::WriteMap "writable", so
1774 1804
  /// it cannot be used when a readable map is needed, for example as
1775 1805
  /// \c ReachedMap for \c Bfs, \c Dfs and \c Dijkstra algorithms.
1776 1806
  ///
1777 1807
  /// \relates LoggerBoolMap
1778 1808
  template<typename Iterator>
1779 1809
  inline LoggerBoolMap<Iterator> loggerBoolMap(Iterator it) {
1780 1810
    return LoggerBoolMap<Iterator>(it);
1781 1811
  }
1782 1812

	
1783 1813
  /// @}
1784 1814

	
1785 1815
  /// \addtogroup graph_maps
1786 1816
  /// @{
1787 1817

	
1788
  /// Provides an immutable and unique id for each item in the graph.
1789

	
1790
  /// The IdMap class provides a unique and immutable id for each item of the
1791
  /// same type (e.g. node) in the graph. This id is <ul><li>\b unique:
1792
  /// different items (nodes) get different ids <li>\b immutable: the id of an
1793
  /// item (node) does not change (even if you delete other nodes).  </ul>
1794
  /// Through this map you get access (i.e. can read) the inner id values of
1795
  /// the items stored in the graph. This map can be inverted with its member
1818
  /// \brief Provides an immutable and unique id for each item in a graph.
1819
  ///
1820
  /// IdMap provides a unique and immutable id for each item of the
1821
  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is 
1822
  ///  - \b unique: different items get different ids,
1823
  ///  - \b immutable: the id of an item does not change (even if you
1824
  ///    delete other nodes).
1825
  ///
1826
  /// Using this map you get access (i.e. can read) the inner id values of
1827
  /// the items stored in the graph, which is returned by the \c id()
1828
  /// function of the graph. This map can be inverted with its member
1796 1829
  /// class \c InverseMap or with the \c operator() member.
1797 1830
  ///
1798
  template <typename _Graph, typename _Item>
1799
  class IdMap {
1831
  /// \tparam GR The graph type.
1832
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
1833
  /// \c GR::Edge).
1834
  ///
1835
  /// \see RangeIdMap
1836
  template <typename GR, typename K>
1837
  class IdMap : public MapBase<K, int> {
1800 1838
  public:
1801
    typedef _Graph Graph;
1839
    /// The graph type of IdMap.
1840
    typedef GR Graph;
1841
    typedef GR Digraph;
1842
    /// The key type of IdMap (\c Node, \c Arc or \c Edge).
1843
    typedef K Item;
1844
    /// The key type of IdMap (\c Node, \c Arc or \c Edge).
1845
    typedef K Key;
1846
    /// The value type of IdMap.
1802 1847
    typedef int Value;
1803
    typedef _Item Item;
1804
    typedef _Item Key;
1805 1848

	
1806 1849
    /// \brief Constructor.
1807 1850
    ///
1808 1851
    /// Constructor of the map.
1809 1852
    explicit IdMap(const Graph& graph) : _graph(&graph) {}
1810 1853

	
1811 1854
    /// \brief Gives back the \e id of the item.
1812 1855
    ///
1813 1856
    /// Gives back the immutable and unique \e id of the item.
1814 1857
    int operator[](const Item& item) const { return _graph->id(item);}
1815 1858

	
1816
    /// \brief Gives back the item by its id.
1859
    /// \brief Gives back the \e item by its id.
1817 1860
    ///
1818
    /// Gives back the item by its id.
1861
    /// Gives back the \e item by its id.
1819 1862
    Item operator()(int id) { return _graph->fromId(id, Item()); }
1820 1863

	
1821 1864
  private:
1822 1865
    const Graph* _graph;
1823 1866

	
1824 1867
  public:
1825 1868

	
1826
    /// \brief The class represents the inverse of its owner (IdMap).
1869
    /// \brief This class represents the inverse of its owner (IdMap).
1827 1870
    ///
1828
    /// The class represents the inverse of its owner (IdMap).
1871
    /// This class represents the inverse of its owner (IdMap).
1829 1872
    /// \see inverse()
1830 1873
    class InverseMap {
1831 1874
    public:
1832 1875

	
1833 1876
      /// \brief Constructor.
1834 1877
      ///
1835 1878
      /// Constructor for creating an id-to-item map.
1836 1879
      explicit InverseMap(const Graph& graph) : _graph(&graph) {}
1837 1880

	
1838 1881
      /// \brief Constructor.
1839 1882
      ///
1840 1883
      /// Constructor for creating an id-to-item map.
1841 1884
      explicit InverseMap(const IdMap& map) : _graph(map._graph) {}
1842 1885

	
1843 1886
      /// \brief Gives back the given item from its id.
1844 1887
      ///
1845 1888
      /// Gives back the given item from its id.
1846
      ///
1847 1889
      Item operator[](int id) const { return _graph->fromId(id, Item());}
1848 1890

	
1849 1891
    private:
1850 1892
      const Graph* _graph;
1851 1893
    };
1852 1894

	
1853 1895
    /// \brief Gives back the inverse of the map.
1854 1896
    ///
1855 1897
    /// Gives back the inverse of the IdMap.
1856 1898
    InverseMap inverse() const { return InverseMap(*_graph);}
1857

	
1858 1899
  };
1859 1900

	
1860 1901

	
1861
  /// \brief General invertable graph-map type.
1862

	
1863
  /// This type provides simple invertable graph-maps.
1864
  /// The InvertableMap wraps an arbitrary ReadWriteMap
1902
  /// \brief General cross reference graph map type.
1903

	
1904
  /// This class provides simple invertable graph maps.
1905
  /// It wraps an arbitrary \ref concepts::ReadWriteMap "ReadWriteMap"
1865 1906
  /// and if a key is set to a new value then store it
1866 1907
  /// in the inverse map.
1867 1908
  ///
1868 1909
  /// The values of the map can be accessed
1869 1910
  /// with stl compatible forward iterator.
1870 1911
  ///
1871
  /// \tparam _Graph The graph type.
1872
  /// \tparam _Item The item type of the graph.
1873
  /// \tparam _Value The value type of the map.
1912
  /// \tparam GR The graph type.
1913
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
1914
  /// \c GR::Edge).
1915
  /// \tparam V The value type of the map.
1874 1916
  ///
1875 1917
  /// \see IterableValueMap
1876
  template <typename _Graph, typename _Item, typename _Value>
1877
  class InvertableMap
1878
    : protected ItemSetTraits<_Graph, _Item>::template Map<_Value>::Type {
1918
  template <typename GR, typename K, typename V>
1919
  class CrossRefMap
1920
    : protected ItemSetTraits<GR, K>::template Map<V>::Type {
1879 1921
  private:
1880 1922

	
1881
    typedef typename ItemSetTraits<_Graph, _Item>::
1882
    template Map<_Value>::Type Map;
1883
    typedef _Graph Graph;
1884

	
1885
    typedef std::map<_Value, _Item> Container;
1923
    typedef typename ItemSetTraits<GR, K>::
1924
      template Map<V>::Type Map;
1925

	
1926
    typedef std::map<V, K> Container;
1886 1927
    Container _inv_map;
1887 1928

	
1888 1929
  public:
1889 1930

	
1890
    /// The key type of InvertableMap (Node, Arc, Edge).
1891
    typedef typename Map::Key Key;
1892
    /// The value type of the InvertableMap.
1893
    typedef typename Map::Value Value;
1931
    /// The graph type of CrossRefMap.
1932
    typedef GR Graph;
1933
    typedef GR Digraph;
1934
    /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
1935
    typedef K Item;
1936
    /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
1937
    typedef K Key;
1938
    /// The value type of CrossRefMap.
1939
    typedef V Value;
1894 1940

	
1895 1941
    /// \brief Constructor.
1896 1942
    ///
1897
    /// Construct a new InvertableMap for the graph.
1898
    ///
1899
    explicit InvertableMap(const Graph& graph) : Map(graph) {}
1943
    /// Construct a new CrossRefMap for the given graph.
1944
    explicit CrossRefMap(const Graph& graph) : Map(graph) {}
1900 1945

	
1901 1946
    /// \brief Forward iterator for values.
1902 1947
    ///
1903 1948
    /// This iterator is an stl compatible forward
1904 1949
    /// iterator on the values of the map. The values can
1905
    /// be accessed in the [beginValue, endValue) range.
1906
    ///
1950
    /// be accessed in the <tt>[beginValue, endValue)</tt> range.
1907 1951
    class ValueIterator
1908 1952
      : public std::iterator<std::forward_iterator_tag, Value> {
1909
      friend class InvertableMap;
1953
      friend class CrossRefMap;
1910 1954
    private:
1911 1955
      ValueIterator(typename Container::const_iterator _it)
1912 1956
        : it(_it) {}
1913 1957
    public:
1914 1958

	
1915 1959
      ValueIterator() {}
1916 1960

	
1917 1961
      ValueIterator& operator++() { ++it; return *this; }
1918 1962
      ValueIterator operator++(int) {
1919 1963
        ValueIterator tmp(*this);
1920 1964
        operator++();
1921 1965
        return tmp;
1922 1966
      }
1923 1967

	
1924 1968
      const Value& operator*() const { return it->first; }
1925 1969
      const Value* operator->() const { return &(it->first); }
1926 1970

	
1927 1971
      bool operator==(ValueIterator jt) const { return it == jt.it; }
1928 1972
      bool operator!=(ValueIterator jt) const { return it != jt.it; }
1929 1973

	
1930 1974
    private:
1931 1975
      typename Container::const_iterator it;
1932 1976
    };
1933 1977

	
1934 1978
    /// \brief Returns an iterator to the first value.
1935 1979
    ///
1936 1980
    /// Returns an stl compatible iterator to the
1937 1981
    /// first value of the map. The values of the
1938
    /// map can be accessed in the [beginValue, endValue)
1982
    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
1939 1983
    /// range.
1940 1984
    ValueIterator beginValue() const {
1941 1985
      return ValueIterator(_inv_map.begin());
1942 1986
    }
1943 1987

	
1944 1988
    /// \brief Returns an iterator after the last value.
1945 1989
    ///
1946 1990
    /// Returns an stl compatible iterator after the
1947 1991
    /// last value of the map. The values of the
1948
    /// map can be accessed in the [beginValue, endValue)
1992
    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
1949 1993
    /// range.
1950 1994
    ValueIterator endValue() const {
1951 1995
      return ValueIterator(_inv_map.end());
1952 1996
    }
1953 1997

	
1954
    /// \brief The setter function of the map.
1998
    /// \brief Sets the value associated with the given key.
1955 1999
    ///
1956
    /// Sets the mapped value.
2000
    /// Sets the value associated with the given key.
1957 2001
    void set(const Key& key, const Value& val) {
1958 2002
      Value oldval = Map::operator[](key);
1959 2003
      typename Container::iterator it = _inv_map.find(oldval);
1960 2004
      if (it != _inv_map.end() && it->second == key) {
1961 2005
        _inv_map.erase(it);
1962 2006
      }
1963 2007
      _inv_map.insert(make_pair(val, key));
1964 2008
      Map::set(key, val);
1965 2009
    }
1966 2010

	
1967
    /// \brief The getter function of the map.
2011
    /// \brief Returns the value associated with the given key.
1968 2012
    ///
1969
    /// It gives back the value associated with the key.
2013
    /// Returns the value associated with the given key.
1970 2014
    typename MapTraits<Map>::ConstReturnValue
1971 2015
    operator[](const Key& key) const {
1972 2016
      return Map::operator[](key);
1973 2017
    }
1974 2018

	
1975 2019
    /// \brief Gives back the item by its value.
1976 2020
    ///
1977 2021
    /// Gives back the item by its value.
1978 2022
    Key operator()(const Value& key) const {
1979 2023
      typename Container::const_iterator it = _inv_map.find(key);
1980 2024
      return it != _inv_map.end() ? it->second : INVALID;
1981 2025
    }
1982 2026

	
1983 2027
  protected:
1984 2028

	
1985
    /// \brief Erase the key from the map.
2029
    /// \brief Erase the key from the map and the inverse map.
1986 2030
    ///
1987
    /// Erase the key to the map. It is called by the
2031
    /// Erase the key from the map and the inverse map. It is called by the
1988 2032
    /// \c AlterationNotifier.
1989 2033
    virtual void erase(const Key& key) {
1990 2034
      Value val = Map::operator[](key);
1991 2035
      typename Container::iterator it = _inv_map.find(val);
1992 2036
      if (it != _inv_map.end() && it->second == key) {
1993 2037
        _inv_map.erase(it);
1994 2038
      }
1995 2039
      Map::erase(key);
1996 2040
    }
1997 2041

	
1998
    /// \brief Erase more keys from the map.
2042
    /// \brief Erase more keys from the map and the inverse map.
1999 2043
    ///
2000
    /// Erase more keys from the map. It is called by the
2044
    /// Erase more keys from the map and the inverse map. It is called by the
2001 2045
    /// \c AlterationNotifier.
2002 2046
    virtual void erase(const std::vector<Key>& keys) {
2003 2047
      for (int i = 0; i < int(keys.size()); ++i) {
2004 2048
        Value val = Map::operator[](keys[i]);
2005 2049
        typename Container::iterator it = _inv_map.find(val);
2006 2050
        if (it != _inv_map.end() && it->second == keys[i]) {
2007 2051
          _inv_map.erase(it);
2008 2052
        }
2009 2053
      }
2010 2054
      Map::erase(keys);
2011 2055
    }
2012 2056

	
2013
    /// \brief Clear the keys from the map and inverse map.
2057
    /// \brief Clear the keys from the map and the inverse map.
2014 2058
    ///
2015
    /// Clear the keys from the map and inverse map. It is called by the
2059
    /// Clear the keys from the map and the inverse map. It is called by the
2016 2060
    /// \c AlterationNotifier.
2017 2061
    virtual void clear() {
2018 2062
      _inv_map.clear();
2019 2063
      Map::clear();
2020 2064
    }
2021 2065

	
2022 2066
  public:
2023 2067

	
2024 2068
    /// \brief The inverse map type.
2025 2069
    ///
2026 2070
    /// The inverse of this map. The subscript operator of the map
2027
    /// gives back always the item what was last assigned to the value.
2071
    /// gives back the item that was last assigned to the value.
2028 2072
    class InverseMap {
2029 2073
    public:
2030
      /// \brief Constructor of the InverseMap.
2074
      /// \brief Constructor
2031 2075
      ///
2032 2076
      /// Constructor of the InverseMap.
2033
      explicit InverseMap(const InvertableMap& inverted)
2077
      explicit InverseMap(const CrossRefMap& inverted)
2034 2078
        : _inverted(inverted) {}
2035 2079

	
2036 2080
      /// The value type of the InverseMap.
2037
      typedef typename InvertableMap::Key Value;
2081
      typedef typename CrossRefMap::Key Value;
2038 2082
      /// The key type of the InverseMap.
2039
      typedef typename InvertableMap::Value Key;
2083
      typedef typename CrossRefMap::Value Key;
2040 2084

	
2041 2085
      /// \brief Subscript operator.
2042 2086
      ///
2043
      /// Subscript operator. It gives back always the item
2044
      /// what was last assigned to the value.
2087
      /// Subscript operator. It gives back the item
2088
      /// that was last assigned to the given value.
2045 2089
      Value operator[](const Key& key) const {
2046 2090
        return _inverted(key);
2047 2091
      }
2048 2092

	
2049 2093
    private:
2050
      const InvertableMap& _inverted;
2094
      const CrossRefMap& _inverted;
2051 2095
    };
2052 2096

	
2053
    /// \brief It gives back the just readable inverse map.
2097
    /// \brief It gives back the read-only inverse map.
2054 2098
    ///
2055
    /// It gives back the just readable inverse map.
2099
    /// It gives back the read-only inverse map.
2056 2100
    InverseMap inverse() const {
2057 2101
      return InverseMap(*this);
2058 2102
    }
2059 2103

	
2060 2104
  };
2061 2105

	
2062
  /// \brief Provides a mutable, continuous and unique descriptor for each
2063
  /// item in the graph.
2106
  /// \brief Provides continuous and unique ID for the
2107
  /// items of a graph.
2064 2108
  ///
2065
  /// The DescriptorMap class provides a unique and continuous (but mutable)
2066
  /// descriptor (id) for each item of the same type (e.g. node) in the
2067
  /// graph. This id is <ul><li>\b unique: different items (nodes) get
2068
  /// different ids <li>\b continuous: the range of the ids is the set of
2069
  /// integers between 0 and \c n-1, where \c n is the number of the items of
2070
  /// this type (e.g. nodes) (so the id of a node can change if you delete an
2071
  /// other node, i.e. this id is mutable).  </ul> This map can be inverted
2072
  /// with its member class \c InverseMap, or with the \c operator() member.
2109
  /// RangeIdMap provides a unique and continuous
2110
  /// ID for each item of a given type (\c Node, \c Arc or
2111
  /// \c Edge) in a graph. This id is
2112
  ///  - \b unique: different items get different ids,
2113
  ///  - \b continuous: the range of the ids is the set of integers
2114
  ///    between 0 and \c n-1, where \c n is the number of the items of
2115
  ///    this type (\c Node, \c Arc or \c Edge).
2116
  ///  - So, the ids can change when deleting an item of the same type.
2073 2117
  ///
2074
  /// \tparam _Graph The graph class the \c DescriptorMap belongs to.
2075
  /// \tparam _Item The Item is the Key of the Map. It may be Node, Arc or
2076
  /// Edge.
2077
  template <typename _Graph, typename _Item>
2078
  class DescriptorMap
2079
    : protected ItemSetTraits<_Graph, _Item>::template Map<int>::Type {
2080

	
2081
    typedef _Item Item;
2082
    typedef typename ItemSetTraits<_Graph, _Item>::template Map<int>::Type Map;
2118
  /// Thus this id is not (necessarily) the same as what can get using
2119
  /// the \c id() function of the graph or \ref IdMap.
2120
  /// This map can be inverted with its member class \c InverseMap,
2121
  /// or with the \c operator() member.
2122
  ///
2123
  /// \tparam GR The graph type.
2124
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
2125
  /// \c GR::Edge).
2126
  ///
2127
  /// \see IdMap
2128
  template <typename GR, typename K>
2129
  class RangeIdMap
2130
    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
2131

	
2132
    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Map;
2083 2133

	
2084 2134
  public:
2085
    /// The graph class of DescriptorMap.
2086
    typedef _Graph Graph;
2087

	
2088
    /// The key type of DescriptorMap (Node, Arc, Edge).
2089
    typedef typename Map::Key Key;
2090
    /// The value type of DescriptorMap.
2091
    typedef typename Map::Value Value;
2135
    /// The graph type of RangeIdMap.
2136
    typedef GR Graph;
2137
    typedef GR Digraph;
2138
    /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
2139
    typedef K Item;
2140
    /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
2141
    typedef K Key;
2142
    /// The value type of RangeIdMap.
2143
    typedef int Value;
2092 2144

	
2093 2145
    /// \brief Constructor.
2094 2146
    ///
2095
    /// Constructor for descriptor map.
2096
    explicit DescriptorMap(const Graph& _graph) : Map(_graph) {
2147
    /// Constructor.
2148
    explicit RangeIdMap(const Graph& gr) : Map(gr) {
2097 2149
      Item it;
2098 2150
      const typename Map::Notifier* nf = Map::notifier();
2099 2151
      for (nf->first(it); it != INVALID; nf->next(it)) {
2100 2152
        Map::set(it, _inv_map.size());
2101 2153
        _inv_map.push_back(it);
2102 2154
      }
2103 2155
    }
2104 2156

	
2105 2157
  protected:
2106 2158

	
2107
    /// \brief Add a new key to the map.
2159
    /// \brief Adds a new key to the map.
2108 2160
    ///
2109 2161
    /// Add a new key to the map. It is called by the
2110 2162
    /// \c AlterationNotifier.
2111 2163
    virtual void add(const Item& item) {
2112 2164
      Map::add(item);
2113 2165
      Map::set(item, _inv_map.size());
2114 2166
      _inv_map.push_back(item);
2115 2167
    }
2116 2168

	
2117 2169
    /// \brief Add more new keys to the map.
2118 2170
    ///
2119 2171
    /// Add more new keys to the map. It is called by the
2120 2172
    /// \c AlterationNotifier.
2121 2173
    virtual void add(const std::vector<Item>& items) {
2122 2174
      Map::add(items);
2123 2175
      for (int i = 0; i < int(items.size()); ++i) {
2124 2176
        Map::set(items[i], _inv_map.size());
2125 2177
        _inv_map.push_back(items[i]);
2126 2178
      }
2127 2179
    }
2128 2180

	
2129 2181
    /// \brief Erase the key from the map.
2130 2182
    ///
2131 2183
    /// Erase the key from the map. It is called by the
2132 2184
    /// \c AlterationNotifier.
2133 2185
    virtual void erase(const Item& item) {
2134 2186
      Map::set(_inv_map.back(), Map::operator[](item));
2135 2187
      _inv_map[Map::operator[](item)] = _inv_map.back();
2136 2188
      _inv_map.pop_back();
2137 2189
      Map::erase(item);
2138 2190
    }
2139 2191

	
2140 2192
    /// \brief Erase more keys from the map.
2141 2193
    ///
2142 2194
    /// Erase more keys from the map. It is called by the
2143 2195
    /// \c AlterationNotifier.
2144 2196
    virtual void erase(const std::vector<Item>& items) {
2145 2197
      for (int i = 0; i < int(items.size()); ++i) {
2146 2198
        Map::set(_inv_map.back(), Map::operator[](items[i]));
2147 2199
        _inv_map[Map::operator[](items[i])] = _inv_map.back();
2148 2200
        _inv_map.pop_back();
2149 2201
      }
2150 2202
      Map::erase(items);
2151 2203
    }
2152 2204

	
2153 2205
    /// \brief Build the unique map.
2154 2206
    ///
2155 2207
    /// Build the unique map. It is called by the
2156 2208
    /// \c AlterationNotifier.
2157 2209
    virtual void build() {
2158 2210
      Map::build();
2159 2211
      Item it;
2160 2212
      const typename Map::Notifier* nf = Map::notifier();
2161 2213
      for (nf->first(it); it != INVALID; nf->next(it)) {
2162 2214
        Map::set(it, _inv_map.size());
2163 2215
        _inv_map.push_back(it);
2164 2216
      }
2165 2217
    }
2166 2218

	
2167 2219
    /// \brief Clear the keys from the map.
2168 2220
    ///
2169 2221
    /// Clear the keys from the map. It is called by the
2170 2222
    /// \c AlterationNotifier.
2171 2223
    virtual void clear() {
2172 2224
      _inv_map.clear();
2173 2225
      Map::clear();
2174 2226
    }
2175 2227

	
2176 2228
  public:
2177 2229

	
2178 2230
    /// \brief Returns the maximal value plus one.
2179 2231
    ///
2180 2232
    /// Returns the maximal value plus one in the map.
2181 2233
    unsigned int size() const {
2182 2234
      return _inv_map.size();
2183 2235
    }
2184 2236

	
2185 2237
    /// \brief Swaps the position of the two items in the map.
2186 2238
    ///
2187 2239
    /// Swaps the position of the two items in the map.
2188 2240
    void swap(const Item& p, const Item& q) {
2189 2241
      int pi = Map::operator[](p);
2190 2242
      int qi = Map::operator[](q);
2191 2243
      Map::set(p, qi);
2192 2244
      _inv_map[qi] = p;
2193 2245
      Map::set(q, pi);
2194 2246
      _inv_map[pi] = q;
2195 2247
    }
2196 2248

	
2197
    /// \brief Gives back the \e descriptor of the item.
2249
    /// \brief Gives back the \e RangeId of the item
2198 2250
    ///
2199
    /// Gives back the mutable and unique \e descriptor of the map.
2251
    /// Gives back the \e RangeId of the item.
2200 2252
    int operator[](const Item& item) const {
2201 2253
      return Map::operator[](item);
2202 2254
    }
2203 2255

	
2204
    /// \brief Gives back the item by its descriptor.
2205
    ///
2206
    /// Gives back th item by its descriptor.
2256
    /// \brief Gives back the item belonging to a \e RangeId
2257
    /// 
2258
    /// Gives back the item belonging to a \e RangeId.
2207 2259
    Item operator()(int id) const {
2208 2260
      return _inv_map[id];
2209 2261
    }
2210 2262

	
2211 2263
  private:
2212 2264

	
2213 2265
    typedef std::vector<Item> Container;
2214 2266
    Container _inv_map;
2215 2267

	
2216 2268
  public:
2217
    /// \brief The inverse map type of DescriptorMap.
2269

	
2270
    /// \brief The inverse map type of RangeIdMap.
2218 2271
    ///
2219
    /// The inverse map type of DescriptorMap.
2272
    /// The inverse map type of RangeIdMap.
2220 2273
    class InverseMap {
2221 2274
    public:
2222
      /// \brief Constructor of the InverseMap.
2275
      /// \brief Constructor
2223 2276
      ///
2224 2277
      /// Constructor of the InverseMap.
2225
      explicit InverseMap(const DescriptorMap& inverted)
2278
      explicit InverseMap(const RangeIdMap& inverted)
2226 2279
        : _inverted(inverted) {}
2227 2280

	
2228 2281

	
2229 2282
      /// The value type of the InverseMap.
2230
      typedef typename DescriptorMap::Key Value;
2283
      typedef typename RangeIdMap::Key Value;
2231 2284
      /// The key type of the InverseMap.
2232
      typedef typename DescriptorMap::Value Key;
2285
      typedef typename RangeIdMap::Value Key;
2233 2286

	
2234 2287
      /// \brief Subscript operator.
2235 2288
      ///
2236 2289
      /// Subscript operator. It gives back the item
2237
      /// that the descriptor belongs to currently.
2290
      /// that the descriptor currently belongs to.
2238 2291
      Value operator[](const Key& key) const {
2239 2292
        return _inverted(key);
2240 2293
      }
2241 2294

	
2242 2295
      /// \brief Size of the map.
2243 2296
      ///
2244 2297
      /// Returns the size of the map.
2245 2298
      unsigned int size() const {
2246 2299
        return _inverted.size();
2247 2300
      }
2248 2301

	
2249 2302
    private:
2250
      const DescriptorMap& _inverted;
2303
      const RangeIdMap& _inverted;
2251 2304
    };
2252 2305

	
2253 2306
    /// \brief Gives back the inverse of the map.
2254 2307
    ///
2255 2308
    /// Gives back the inverse of the map.
2256 2309
    const InverseMap inverse() const {
2257 2310
      return InverseMap(*this);
2258 2311
    }
2259 2312
  };
2260 2313

	
2261
  /// \brief Returns the source of the given arc.
2314
  /// \brief Map of the source nodes of arcs in a digraph.
2262 2315
  ///
2263
  /// The SourceMap gives back the source Node of the given arc.
2316
  /// SourceMap provides access for the source node of each arc in a digraph,
2317
  /// which is returned by the \c source() function of the digraph.
2318
  /// \tparam GR The digraph type.
2264 2319
  /// \see TargetMap
2265
  template <typename Digraph>
2320
  template <typename GR>
2266 2321
  class SourceMap {
2267 2322
  public:
2268 2323

	
2269
    typedef typename Digraph::Node Value;
2270
    typedef typename Digraph::Arc Key;
2324
    ///\e
2325
    typedef typename GR::Arc Key;
2326
    ///\e
2327
    typedef typename GR::Node Value;
2271 2328

	
2272 2329
    /// \brief Constructor
2273 2330
    ///
2274
    /// Constructor
2331
    /// Constructor.
2275 2332
    /// \param digraph The digraph that the map belongs to.
2276
    explicit SourceMap(const Digraph& digraph) : _digraph(digraph) {}
2277

	
2278
    /// \brief The subscript operator.
2333
    explicit SourceMap(const GR& digraph) : _graph(digraph) {}
2334

	
2335
    /// \brief Returns the source node of the given arc.
2279 2336
    ///
2280
    /// The subscript operator.
2281
    /// \param arc The arc
2282
    /// \return The source of the arc
2337
    /// Returns the source node of the given arc.
2283 2338
    Value operator[](const Key& arc) const {
2284
      return _digraph.source(arc);
2339
      return _graph.source(arc);
2285 2340
    }
2286 2341

	
2287 2342
  private:
2288
    const Digraph& _digraph;
2343
    const GR& _graph;
2289 2344
  };
2290 2345

	
2291 2346
  /// \brief Returns a \c SourceMap class.
2292 2347
  ///
2293 2348
  /// This function just returns an \c SourceMap class.
2294 2349
  /// \relates SourceMap
2295
  template <typename Digraph>
2296
  inline SourceMap<Digraph> sourceMap(const Digraph& digraph) {
2297
    return SourceMap<Digraph>(digraph);
2350
  template <typename GR>
2351
  inline SourceMap<GR> sourceMap(const GR& graph) {
2352
    return SourceMap<GR>(graph);
2298 2353
  }
2299 2354

	
2300
  /// \brief Returns the target of the given arc.
2355
  /// \brief Map of the target nodes of arcs in a digraph.
2301 2356
  ///
2302
  /// The TargetMap gives back the target Node of the given arc.
2357
  /// TargetMap provides access for the target node of each arc in a digraph,
2358
  /// which is returned by the \c target() function of the digraph.
2359
  /// \tparam GR The digraph type.
2303 2360
  /// \see SourceMap
2304
  template <typename Digraph>
2361
  template <typename GR>
2305 2362
  class TargetMap {
2306 2363
  public:
2307 2364

	
2308
    typedef typename Digraph::Node Value;
2309
    typedef typename Digraph::Arc Key;
2365
    ///\e
2366
    typedef typename GR::Arc Key;
2367
    ///\e
2368
    typedef typename GR::Node Value;
2310 2369

	
2311 2370
    /// \brief Constructor
2312 2371
    ///
2313
    /// Constructor
2372
    /// Constructor.
2314 2373
    /// \param digraph The digraph that the map belongs to.
2315
    explicit TargetMap(const Digraph& digraph) : _digraph(digraph) {}
2316

	
2317
    /// \brief The subscript operator.
2374
    explicit TargetMap(const GR& digraph) : _graph(digraph) {}
2375

	
2376
    /// \brief Returns the target node of the given arc.
2318 2377
    ///
2319
    /// The subscript operator.
2320
    /// \param e The arc
2321
    /// \return The target of the arc
2378
    /// Returns the target node of the given arc.
2322 2379
    Value operator[](const Key& e) const {
2323
      return _digraph.target(e);
2380
      return _graph.target(e);
2324 2381
    }
2325 2382

	
2326 2383
  private:
2327
    const Digraph& _digraph;
2384
    const GR& _graph;
2328 2385
  };
2329 2386

	
2330 2387
  /// \brief Returns a \c TargetMap class.
2331 2388
  ///
2332 2389
  /// This function just returns a \c TargetMap class.
2333 2390
  /// \relates TargetMap
2334
  template <typename Digraph>
2335
  inline TargetMap<Digraph> targetMap(const Digraph& digraph) {
2336
    return TargetMap<Digraph>(digraph);
2391
  template <typename GR>
2392
  inline TargetMap<GR> targetMap(const GR& graph) {
2393
    return TargetMap<GR>(graph);
2337 2394
  }
2338 2395

	
2339
  /// \brief Returns the "forward" directed arc view of an edge.
2396
  /// \brief Map of the "forward" directed arc view of edges in a graph.
2340 2397
  ///
2341
  /// Returns the "forward" directed arc view of an edge.
2398
  /// ForwardMap provides access for the "forward" directed arc view of
2399
  /// each edge in a graph, which is returned by the \c direct() function
2400
  /// of the graph with \c true parameter.
2401
  /// \tparam GR The graph type.
2342 2402
  /// \see BackwardMap
2343
  template <typename Graph>
2403
  template <typename GR>
2344 2404
  class ForwardMap {
2345 2405
  public:
2346 2406

	
2347
    typedef typename Graph::Arc Value;
2348
    typedef typename Graph::Edge Key;
2407
    typedef typename GR::Arc Value;
2408
    typedef typename GR::Edge Key;
2349 2409

	
2350 2410
    /// \brief Constructor
2351 2411
    ///
2352
    /// Constructor
2412
    /// Constructor.
2353 2413
    /// \param graph The graph that the map belongs to.
2354
    explicit ForwardMap(const Graph& graph) : _graph(graph) {}
2355

	
2356
    /// \brief The subscript operator.
2414
    explicit ForwardMap(const GR& graph) : _graph(graph) {}
2415

	
2416
    /// \brief Returns the "forward" directed arc view of the given edge.
2357 2417
    ///
2358
    /// The subscript operator.
2359
    /// \param key An edge
2360
    /// \return The "forward" directed arc view of edge
2418
    /// Returns the "forward" directed arc view of the given edge.
2361 2419
    Value operator[](const Key& key) const {
2362 2420
      return _graph.direct(key, true);
2363 2421
    }
2364 2422

	
2365 2423
  private:
2366
    const Graph& _graph;
2424
    const GR& _graph;
2367 2425
  };
2368 2426

	
2369 2427
  /// \brief Returns a \c ForwardMap class.
2370 2428
  ///
2371 2429
  /// This function just returns an \c ForwardMap class.
2372 2430
  /// \relates ForwardMap
2373
  template <typename Graph>
2374
  inline ForwardMap<Graph> forwardMap(const Graph& graph) {
2375
    return ForwardMap<Graph>(graph);
2431
  template <typename GR>
2432
  inline ForwardMap<GR> forwardMap(const GR& graph) {
2433
    return ForwardMap<GR>(graph);
2376 2434
  }
2377 2435

	
2378
  /// \brief Returns the "backward" directed arc view of an edge.
2436
  /// \brief Map of the "backward" directed arc view of edges in a graph.
2379 2437
  ///
2380
  /// Returns the "backward" directed arc view of an edge.
2438
  /// BackwardMap provides access for the "backward" directed arc view of
2439
  /// each edge in a graph, which is returned by the \c direct() function
2440
  /// of the graph with \c false parameter.
2441
  /// \tparam GR The graph type.
2381 2442
  /// \see ForwardMap
2382
  template <typename Graph>
2443
  template <typename GR>
2383 2444
  class BackwardMap {
2384 2445
  public:
2385 2446

	
2386
    typedef typename Graph::Arc Value;
2387
    typedef typename Graph::Edge Key;
2447
    typedef typename GR::Arc Value;
2448
    typedef typename GR::Edge Key;
2388 2449

	
2389 2450
    /// \brief Constructor
2390 2451
    ///
2391
    /// Constructor
2452
    /// Constructor.
2392 2453
    /// \param graph The graph that the map belongs to.
2393
    explicit BackwardMap(const Graph& graph) : _graph(graph) {}
2394

	
2395
    /// \brief The subscript operator.
2454
    explicit BackwardMap(const GR& graph) : _graph(graph) {}
2455

	
2456
    /// \brief Returns the "backward" directed arc view of the given edge.
2396 2457
    ///
2397
    /// The subscript operator.
2398
    /// \param key An edge
2399
    /// \return The "backward" directed arc view of edge
2458
    /// Returns the "backward" directed arc view of the given edge.
2400 2459
    Value operator[](const Key& key) const {
2401 2460
      return _graph.direct(key, false);
2402 2461
    }
2403 2462

	
2404 2463
  private:
2405
    const Graph& _graph;
2464
    const GR& _graph;
2406 2465
  };
2407 2466

	
2408 2467
  /// \brief Returns a \c BackwardMap class
2409 2468

	
2410 2469
  /// This function just returns a \c BackwardMap class.
2411 2470
  /// \relates BackwardMap
2412
  template <typename Graph>
2413
  inline BackwardMap<Graph> backwardMap(const Graph& graph) {
2414
    return BackwardMap<Graph>(graph);
2471
  template <typename GR>
2472
  inline BackwardMap<GR> backwardMap(const GR& graph) {
2473
    return BackwardMap<GR>(graph);
2415 2474
  }
2416 2475

	
2417
  /// \brief Potential difference map
2418
  ///
2419
  /// If there is an potential map on the nodes then we
2420
  /// can get an arc map as we get the substraction of the
2421
  /// values of the target and source.
2422
  template <typename Digraph, typename NodeMap>
2423
  class PotentialDifferenceMap {
2424
  public:
2425
    typedef typename Digraph::Arc Key;
2426
    typedef typename NodeMap::Value Value;
2427

	
2428
    /// \brief Constructor
2429
    ///
2430
    /// Contructor of the map
2431
    explicit PotentialDifferenceMap(const Digraph& digraph,
2432
                                    const NodeMap& potential)
2433
      : _digraph(digraph), _potential(potential) {}
2434

	
2435
    /// \brief Const subscription operator
2436
    ///
2437
    /// Const subscription operator
2438
    Value operator[](const Key& arc) const {
2439
      return _potential[_digraph.target(arc)] -
2440
        _potential[_digraph.source(arc)];
2441
    }
2442

	
2443
  private:
2444
    const Digraph& _digraph;
2445
    const NodeMap& _potential;
2446
  };
2447

	
2448
  /// \brief Returns a PotentialDifferenceMap.
2449
  ///
2450
  /// This function just returns a PotentialDifferenceMap.
2451
  /// \relates PotentialDifferenceMap
2452
  template <typename Digraph, typename NodeMap>
2453
  PotentialDifferenceMap<Digraph, NodeMap>
2454
  potentialDifferenceMap(const Digraph& digraph, const NodeMap& potential) {
2455
    return PotentialDifferenceMap<Digraph, NodeMap>(digraph, potential);
2456
  }
2457

	
2458
  /// \brief Map of the node in-degrees.
2476
  /// \brief Map of the in-degrees of nodes in a digraph.
2459 2477
  ///
2460 2478
  /// This map returns the in-degree of a node. Once it is constructed,
2461
  /// the degrees are stored in a standard NodeMap, so each query is done
2479
  /// the degrees are stored in a standard \c NodeMap, so each query is done
2462 2480
  /// in constant time. On the other hand, the values are updated automatically
2463 2481
  /// whenever the digraph changes.
2464 2482
  ///
2465
  /// \warning Besides addNode() and addArc(), a digraph structure may provide
2466
  /// alternative ways to modify the digraph. The correct behavior of InDegMap
2467
  /// is not guarantied if these additional features are used. For example
2468
  /// the functions \ref ListDigraph::changeSource() "changeSource()",
2483
  /// \warning Besides \c addNode() and \c addArc(), a digraph structure 
2484
  /// may provide alternative ways to modify the digraph.
2485
  /// The correct behavior of InDegMap is not guarantied if these additional
2486
  /// features are used. For example the functions
2487
  /// \ref ListDigraph::changeSource() "changeSource()",
2469 2488
  /// \ref ListDigraph::changeTarget() "changeTarget()" and
2470 2489
  /// \ref ListDigraph::reverseArc() "reverseArc()"
2471 2490
  /// of \ref ListDigraph will \e not update the degree values correctly.
2472 2491
  ///
2473 2492
  /// \sa OutDegMap
2474

	
2475
  template <typename _Digraph>
2493
  template <typename GR>
2476 2494
  class InDegMap
2477
    : protected ItemSetTraits<_Digraph, typename _Digraph::Arc>
2495
    : protected ItemSetTraits<GR, typename GR::Arc>
2478 2496
      ::ItemNotifier::ObserverBase {
2479 2497

	
2480 2498
  public:
2481

	
2482
    typedef _Digraph Digraph;
2499
    
2500
    /// The graph type of InDegMap
2501
    typedef GR Graph;
2502
    typedef GR Digraph;
2503
    /// The key type
2504
    typedef typename Digraph::Node Key;
2505
    /// The value type
2483 2506
    typedef int Value;
2484
    typedef typename Digraph::Node Key;
2485 2507

	
2486 2508
    typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
2487 2509
    ::ItemNotifier::ObserverBase Parent;
2488 2510

	
2489 2511
  private:
2490 2512

	
2491 2513
    class AutoNodeMap
2492 2514
      : public ItemSetTraits<Digraph, Key>::template Map<int>::Type {
2493 2515
    public:
2494 2516

	
2495 2517
      typedef typename ItemSetTraits<Digraph, Key>::
2496 2518
      template Map<int>::Type Parent;
2497 2519

	
2498 2520
      AutoNodeMap(const Digraph& digraph) : Parent(digraph, 0) {}
2499 2521

	
2500 2522
      virtual void add(const Key& key) {
2501 2523
        Parent::add(key);
2502 2524
        Parent::set(key, 0);
2503 2525
      }
2504 2526

	
2505 2527
      virtual void add(const std::vector<Key>& keys) {
2506 2528
        Parent::add(keys);
2507 2529
        for (int i = 0; i < int(keys.size()); ++i) {
2508 2530
          Parent::set(keys[i], 0);
2509 2531
        }
2510 2532
      }
2511 2533

	
2512 2534
      virtual void build() {
2513 2535
        Parent::build();
2514 2536
        Key it;
2515 2537
        typename Parent::Notifier* nf = Parent::notifier();
2516 2538
        for (nf->first(it); it != INVALID; nf->next(it)) {
2517 2539
          Parent::set(it, 0);
2518 2540
        }
2519 2541
      }
2520 2542
    };
2521 2543

	
2522 2544
  public:
2523 2545

	
2524 2546
    /// \brief Constructor.
2525 2547
    ///
2526
    /// Constructor for creating in-degree map.
2527
    explicit InDegMap(const Digraph& digraph)
2528
      : _digraph(digraph), _deg(digraph) {
2548
    /// Constructor for creating an in-degree map.
2549
    explicit InDegMap(const Digraph& graph)
2550
      : _digraph(graph), _deg(graph) {
2529 2551
      Parent::attach(_digraph.notifier(typename Digraph::Arc()));
2530 2552

	
2531 2553
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2532 2554
        _deg[it] = countInArcs(_digraph, it);
2533 2555
      }
2534 2556
    }
2535 2557

	
2558
    /// \brief Gives back the in-degree of a Node.
2559
    ///
2536 2560
    /// Gives back the in-degree of a Node.
2537 2561
    int operator[](const Key& key) const {
2538 2562
      return _deg[key];
2539 2563
    }
2540 2564

	
2541 2565
  protected:
2542 2566

	
2543 2567
    typedef typename Digraph::Arc Arc;
2544 2568

	
2545 2569
    virtual void add(const Arc& arc) {
2546 2570
      ++_deg[_digraph.target(arc)];
2547 2571
    }
2548 2572

	
2549 2573
    virtual void add(const std::vector<Arc>& arcs) {
2550 2574
      for (int i = 0; i < int(arcs.size()); ++i) {
2551 2575
        ++_deg[_digraph.target(arcs[i])];
2552 2576
      }
2553 2577
    }
2554 2578

	
2555 2579
    virtual void erase(const Arc& arc) {
2556 2580
      --_deg[_digraph.target(arc)];
2557 2581
    }
2558 2582

	
2559 2583
    virtual void erase(const std::vector<Arc>& arcs) {
2560 2584
      for (int i = 0; i < int(arcs.size()); ++i) {
2561 2585
        --_deg[_digraph.target(arcs[i])];
2562 2586
      }
2563 2587
    }
2564 2588

	
2565 2589
    virtual void build() {
2566 2590
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2567 2591
        _deg[it] = countInArcs(_digraph, it);
2568 2592
      }
2569 2593
    }
2570 2594

	
2571 2595
    virtual void clear() {
2572 2596
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2573 2597
        _deg[it] = 0;
2574 2598
      }
2575 2599
    }
2576 2600
  private:
2577 2601

	
2578 2602
    const Digraph& _digraph;
2579 2603
    AutoNodeMap _deg;
2580 2604
  };
2581 2605

	
2582
  /// \brief Map of the node out-degrees.
2606
  /// \brief Map of the out-degrees of nodes in a digraph.
2583 2607
  ///
2584 2608
  /// This map returns the out-degree of a node. Once it is constructed,
2585
  /// the degrees are stored in a standard NodeMap, so each query is done
2609
  /// the degrees are stored in a standard \c NodeMap, so each query is done
2586 2610
  /// in constant time. On the other hand, the values are updated automatically
2587 2611
  /// whenever the digraph changes.
2588 2612
  ///
2589
  /// \warning Besides addNode() and addArc(), a digraph structure may provide
2590
  /// alternative ways to modify the digraph. The correct behavior of OutDegMap
2591
  /// is not guarantied if these additional features are used. For example
2592
  /// the functions \ref ListDigraph::changeSource() "changeSource()",
2613
  /// \warning Besides \c addNode() and \c addArc(), a digraph structure 
2614
  /// may provide alternative ways to modify the digraph.
2615
  /// The correct behavior of OutDegMap is not guarantied if these additional
2616
  /// features are used. For example the functions
2617
  /// \ref ListDigraph::changeSource() "changeSource()",
2593 2618
  /// \ref ListDigraph::changeTarget() "changeTarget()" and
2594 2619
  /// \ref ListDigraph::reverseArc() "reverseArc()"
2595 2620
  /// of \ref ListDigraph will \e not update the degree values correctly.
2596 2621
  ///
2597 2622
  /// \sa InDegMap
2598

	
2599
  template <typename _Digraph>
2623
  template <typename GR>
2600 2624
  class OutDegMap
2601
    : protected ItemSetTraits<_Digraph, typename _Digraph::Arc>
2625
    : protected ItemSetTraits<GR, typename GR::Arc>
2602 2626
      ::ItemNotifier::ObserverBase {
2603 2627

	
2604 2628
  public:
2605 2629

	
2606
    typedef _Digraph Digraph;
2630
    /// The graph type of OutDegMap
2631
    typedef GR Graph;
2632
    typedef GR Digraph;
2633
    /// The key type
2634
    typedef typename Digraph::Node Key;
2635
    /// The value type
2607 2636
    typedef int Value;
2608
    typedef typename Digraph::Node Key;
2609 2637

	
2610 2638
    typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
2611 2639
    ::ItemNotifier::ObserverBase Parent;
2612 2640

	
2613 2641
  private:
2614 2642

	
2615 2643
    class AutoNodeMap
2616 2644
      : public ItemSetTraits<Digraph, Key>::template Map<int>::Type {
2617 2645
    public:
2618 2646

	
2619 2647
      typedef typename ItemSetTraits<Digraph, Key>::
2620 2648
      template Map<int>::Type Parent;
2621 2649

	
2622 2650
      AutoNodeMap(const Digraph& digraph) : Parent(digraph, 0) {}
2623 2651

	
2624 2652
      virtual void add(const Key& key) {
2625 2653
        Parent::add(key);
2626 2654
        Parent::set(key, 0);
2627 2655
      }
2628 2656
      virtual void add(const std::vector<Key>& keys) {
2629 2657
        Parent::add(keys);
2630 2658
        for (int i = 0; i < int(keys.size()); ++i) {
2631 2659
          Parent::set(keys[i], 0);
2632 2660
        }
2633 2661
      }
2634 2662
      virtual void build() {
2635 2663
        Parent::build();
2636 2664
        Key it;
2637 2665
        typename Parent::Notifier* nf = Parent::notifier();
2638 2666
        for (nf->first(it); it != INVALID; nf->next(it)) {
2639 2667
          Parent::set(it, 0);
2640 2668
        }
2641 2669
      }
2642 2670
    };
2643 2671

	
2644 2672
  public:
2645 2673

	
2646 2674
    /// \brief Constructor.
2647 2675
    ///
2648
    /// Constructor for creating out-degree map.
2649
    explicit OutDegMap(const Digraph& digraph)
2650
      : _digraph(digraph), _deg(digraph) {
2676
    /// Constructor for creating an out-degree map.
2677
    explicit OutDegMap(const Digraph& graph)
2678
      : _digraph(graph), _deg(graph) {
2651 2679
      Parent::attach(_digraph.notifier(typename Digraph::Arc()));
2652 2680

	
2653 2681
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2654 2682
        _deg[it] = countOutArcs(_digraph, it);
2655 2683
      }
2656 2684
    }
2657 2685

	
2686
    /// \brief Gives back the out-degree of a Node.
2687
    ///
2658 2688
    /// Gives back the out-degree of a Node.
2659 2689
    int operator[](const Key& key) const {
2660 2690
      return _deg[key];
2661 2691
    }
2662 2692

	
2663 2693
  protected:
2664 2694

	
2665 2695
    typedef typename Digraph::Arc Arc;
2666 2696

	
2667 2697
    virtual void add(const Arc& arc) {
2668 2698
      ++_deg[_digraph.source(arc)];
2669 2699
    }
2670 2700

	
2671 2701
    virtual void add(const std::vector<Arc>& arcs) {
2672 2702
      for (int i = 0; i < int(arcs.size()); ++i) {
2673 2703
        ++_deg[_digraph.source(arcs[i])];
2674 2704
      }
2675 2705
    }
2676 2706

	
2677 2707
    virtual void erase(const Arc& arc) {
2678 2708
      --_deg[_digraph.source(arc)];
2679 2709
    }
2680 2710

	
2681 2711
    virtual void erase(const std::vector<Arc>& arcs) {
2682 2712
      for (int i = 0; i < int(arcs.size()); ++i) {
2683 2713
        --_deg[_digraph.source(arcs[i])];
2684 2714
      }
2685 2715
    }
2686 2716

	
2687 2717
    virtual void build() {
2688 2718
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2689 2719
        _deg[it] = countOutArcs(_digraph, it);
2690 2720
      }
2691 2721
    }
2692 2722

	
2693 2723
    virtual void clear() {
2694 2724
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2695 2725
        _deg[it] = 0;
2696 2726
      }
2697 2727
    }
2698 2728
  private:
2699 2729

	
2700 2730
    const Digraph& _digraph;
2701 2731
    AutoNodeMap _deg;
2702 2732
  };
2703 2733

	
2734
  /// \brief Potential difference map
2735
  ///
2736
  /// PotentialDifferenceMap returns the difference between the potentials of
2737
  /// the source and target nodes of each arc in a digraph, i.e. it returns
2738
  /// \code
2739
  ///   potential[gr.target(arc)] - potential[gr.source(arc)].
2740
  /// \endcode
2741
  /// \tparam GR The digraph type.
2742
  /// \tparam POT A node map storing the potentials.
2743
  template <typename GR, typename POT>
2744
  class PotentialDifferenceMap {
2745
  public:
2746
    /// Key type
2747
    typedef typename GR::Arc Key;
2748
    /// Value type
2749
    typedef typename POT::Value Value;
2750

	
2751
    /// \brief Constructor
2752
    ///
2753
    /// Contructor of the map.
2754
    explicit PotentialDifferenceMap(const GR& gr,
2755
                                    const POT& potential)
2756
      : _digraph(gr), _potential(potential) {}
2757

	
2758
    /// \brief Returns the potential difference for the given arc.
2759
    ///
2760
    /// Returns the potential difference for the given arc, i.e.
2761
    /// \code
2762
    ///   potential[gr.target(arc)] - potential[gr.source(arc)].
2763
    /// \endcode
2764
    Value operator[](const Key& arc) const {
2765
      return _potential[_digraph.target(arc)] -
2766
        _potential[_digraph.source(arc)];
2767
    }
2768

	
2769
  private:
2770
    const GR& _digraph;
2771
    const POT& _potential;
2772
  };
2773

	
2774
  /// \brief Returns a PotentialDifferenceMap.
2775
  ///
2776
  /// This function just returns a PotentialDifferenceMap.
2777
  /// \relates PotentialDifferenceMap
2778
  template <typename GR, typename POT>
2779
  PotentialDifferenceMap<GR, POT>
2780
  potentialDifferenceMap(const GR& gr, const POT& potential) {
2781
    return PotentialDifferenceMap<GR, POT>(gr, potential);
2782
  }
2783

	
2704 2784
  /// @}
2705 2785
}
2706 2786

	
2707 2787
#endif // LEMON_MAPS_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_MATH_H
20 20
#define LEMON_MATH_H
21 21

	
22 22
///\ingroup misc
23 23
///\file
24 24
///\brief Some extensions to the standard \c cmath library.
25 25
///
26 26
///Some extensions to the standard \c cmath library.
27 27
///
28 28
///This file includes the standard math library (cmath).
29 29

	
30 30
#include<cmath>
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  /// \addtogroup misc
35 35
  /// @{
36 36

	
37 37
  /// The Euler constant
38 38
  const long double E       = 2.7182818284590452353602874713526625L;
39 39
  /// log_2(e)
40 40
  const long double LOG2E   = 1.4426950408889634073599246810018921L;
41 41
  /// log_10(e)
42 42
  const long double LOG10E  = 0.4342944819032518276511289189166051L;
43 43
  /// ln(2)
44 44
  const long double LN2     = 0.6931471805599453094172321214581766L;
45 45
  /// ln(10)
46 46
  const long double LN10    = 2.3025850929940456840179914546843642L;
47 47
  /// pi
48 48
  const long double PI      = 3.1415926535897932384626433832795029L;
49 49
  /// pi/2
50 50
  const long double PI_2    = 1.5707963267948966192313216916397514L;
51 51
  /// pi/4
52 52
  const long double PI_4    = 0.7853981633974483096156608458198757L;
53 53
  /// sqrt(2)
54 54
  const long double SQRT2   = 1.4142135623730950488016887242096981L;
55 55
  /// 1/sqrt(2)
56 56
  const long double SQRT1_2 = 0.7071067811865475244008443621048490L;
57 57

	
58
  ///Check whether the parameter is NaN or not
59
  
60
  ///This function checks whether the parameter is NaN or not.
61
  ///Is should be equivalent with std::isnan(), but it is not
62
  ///provided by all compilers.
63
  inline bool isNaN(double v)
64
    {
65
      return v!=v;
66
    }
58 67

	
59 68
  /// @}
60 69

	
61 70
} //namespace lemon
62 71

	
63 72
#endif //LEMON_TOLERANCE_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
///\ingroup paths
20 20
///\file
21 21
///\brief Classes for representing paths in digraphs.
22 22
///
23 23

	
24 24
#ifndef LEMON_PATH_H
25 25
#define LEMON_PATH_H
26 26

	
27 27
#include <vector>
28 28
#include <algorithm>
29 29

	
30 30
#include <lemon/error.h>
31 31
#include <lemon/core.h>
32 32
#include <lemon/concepts/path.h>
33 33

	
34 34
namespace lemon {
35 35

	
36 36
  /// \addtogroup paths
37 37
  /// @{
38 38

	
39 39

	
40 40
  /// \brief A structure for representing directed paths in a digraph.
41 41
  ///
42 42
  /// A structure for representing directed path in a digraph.
43
  /// \tparam _Digraph The digraph type in which the path is.
43
  /// \tparam GR The digraph type in which the path is.
44 44
  ///
45 45
  /// In a sense, the path can be treated as a list of arcs. The
46 46
  /// lemon path type stores just this list. As a consequence, it
47 47
  /// cannot enumerate the nodes of the path and the source node of
48 48
  /// a zero length path is undefined.
49 49
  ///
50 50
  /// This implementation is a back and front insertable and erasable
51 51
  /// path type. It can be indexed in O(1) time. The front and back
52 52
  /// insertion and erase is done in O(1) (amortized) time. The
53 53
  /// implementation uses two vectors for storing the front and back
54 54
  /// insertions.
55
  template <typename _Digraph>
55
  template <typename GR>
56 56
  class Path {
57 57
  public:
58 58

	
59
    typedef _Digraph Digraph;
59
    typedef GR Digraph;
60 60
    typedef typename Digraph::Arc Arc;
61 61

	
62 62
    /// \brief Default constructor
63 63
    ///
64 64
    /// Default constructor
65 65
    Path() {}
66 66

	
67 67
    /// \brief Template copy constructor
68 68
    ///
69 69
    /// This constuctor initializes the path from any other path type.
70 70
    /// It simply makes a copy of the given path.
71 71
    template <typename CPath>
72 72
    Path(const CPath& cpath) {
73 73
      pathCopy(cpath, *this);
74 74
    }
75 75

	
76 76
    /// \brief Template copy assignment
77 77
    ///
78 78
    /// This operator makes a copy of a path of any other type.
79 79
    template <typename CPath>
80 80
    Path& operator=(const CPath& cpath) {
81 81
      pathCopy(cpath, *this);
82 82
      return *this;
83 83
    }
84 84

	
85 85
    /// \brief LEMON style iterator for path arcs
86 86
    ///
87 87
    /// This class is used to iterate on the arcs of the paths.
88 88
    class ArcIt {
89 89
      friend class Path;
90 90
    public:
91 91
      /// \brief Default constructor
92 92
      ArcIt() {}
93 93
      /// \brief Invalid constructor
94 94
      ArcIt(Invalid) : path(0), idx(-1) {}
95 95
      /// \brief Initializate the iterator to the first arc of path
96 96
      ArcIt(const Path &_path)
97 97
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
98 98

	
99 99
    private:
100 100

	
101 101
      ArcIt(const Path &_path, int _idx)
102 102
        : path(&_path), idx(_idx) {}
103 103

	
104 104
    public:
105 105

	
106 106
      /// \brief Conversion to Arc
107 107
      operator const Arc&() const {
108 108
        return path->nth(idx);
109 109
      }
110 110

	
111 111
      /// \brief Next arc
112 112
      ArcIt& operator++() {
113 113
        ++idx;
114 114
        if (idx >= path->length()) idx = -1;
115 115
        return *this;
116 116
      }
117 117

	
118 118
      /// \brief Comparison operator
119 119
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
120 120
      /// \brief Comparison operator
121 121
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
122 122
      /// \brief Comparison operator
123 123
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
124 124

	
125 125
    private:
126 126
      const Path *path;
127 127
      int idx;
128 128
    };
129 129

	
130 130
    /// \brief Length of the path.
131 131
    int length() const { return head.size() + tail.size(); }
132 132
    /// \brief Return whether the path is empty.
133 133
    bool empty() const { return head.empty() && tail.empty(); }
134 134

	
135 135
    /// \brief Reset the path to an empty one.
136 136
    void clear() { head.clear(); tail.clear(); }
137 137

	
138 138
    /// \brief The nth arc.
139 139
    ///
140
    /// \pre n is in the [0..length() - 1] range
140
    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
141 141
    const Arc& nth(int n) const {
142 142
      return n < int(head.size()) ? *(head.rbegin() + n) :
143 143
        *(tail.begin() + (n - head.size()));
144 144
    }
145 145

	
146 146
    /// \brief Initialize arc iterator to point to the nth arc
147 147
    ///
148
    /// \pre n is in the [0..length() - 1] range
148
    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
149 149
    ArcIt nthIt(int n) const {
150 150
      return ArcIt(*this, n);
151 151
    }
152 152

	
153 153
    /// \brief The first arc of the path
154 154
    const Arc& front() const {
155 155
      return head.empty() ? tail.front() : head.back();
156 156
    }
157 157

	
158 158
    /// \brief Add a new arc before the current path
159 159
    void addFront(const Arc& arc) {
160 160
      head.push_back(arc);
161 161
    }
162 162

	
163 163
    /// \brief Erase the first arc of the path
164 164
    void eraseFront() {
165 165
      if (!head.empty()) {
166 166
        head.pop_back();
167 167
      } else {
168 168
        head.clear();
169 169
        int halfsize = tail.size() / 2;
170 170
        head.resize(halfsize);
171 171
        std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
172 172
                  head.rbegin());
173 173
        std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
174 174
        tail.resize(tail.size() - halfsize - 1);
175 175
      }
176 176
    }
177 177

	
178 178
    /// \brief The last arc of the path
179 179
    const Arc& back() const {
180 180
      return tail.empty() ? head.front() : tail.back();
181 181
    }
182 182

	
183 183
    /// \brief Add a new arc behind the current path
184 184
    void addBack(const Arc& arc) {
185 185
      tail.push_back(arc);
186 186
    }
187 187

	
188 188
    /// \brief Erase the last arc of the path
189 189
    void eraseBack() {
190 190
      if (!tail.empty()) {
191 191
        tail.pop_back();
192 192
      } else {
193 193
        int halfsize = head.size() / 2;
194 194
        tail.resize(halfsize);
195 195
        std::copy(head.begin() + 1, head.begin() + halfsize + 1,
196 196
                  tail.rbegin());
197 197
        std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
198 198
        head.resize(head.size() - halfsize - 1);
199 199
      }
200 200
    }
201 201

	
202 202
    typedef True BuildTag;
203 203

	
204 204
    template <typename CPath>
205 205
    void build(const CPath& path) {
206 206
      int len = path.length();
207 207
      tail.reserve(len);
208 208
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
209 209
        tail.push_back(it);
210 210
      }
211 211
    }
212 212

	
213 213
    template <typename CPath>
214 214
    void buildRev(const CPath& path) {
215 215
      int len = path.length();
216 216
      head.reserve(len);
217 217
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
218 218
        head.push_back(it);
219 219
      }
220 220
    }
221 221

	
222 222
  protected:
223 223
    typedef std::vector<Arc> Container;
224 224
    Container head, tail;
225 225

	
226 226
  };
227 227

	
228 228
  /// \brief A structure for representing directed paths in a digraph.
229 229
  ///
230 230
  /// A structure for representing directed path in a digraph.
231
  /// \tparam _Digraph The digraph type in which the path is.
231
  /// \tparam GR The digraph type in which the path is.
232 232
  ///
233 233
  /// In a sense, the path can be treated as a list of arcs. The
234 234
  /// lemon path type stores just this list. As a consequence it
235 235
  /// cannot enumerate the nodes in the path and the zero length paths
236 236
  /// cannot store the source.
237 237
  ///
238 238
  /// This implementation is a just back insertable and erasable path
239 239
  /// type. It can be indexed in O(1) time. The back insertion and
240 240
  /// erasure is amortized O(1) time. This implementation is faster
241 241
  /// then the \c Path type because it use just one vector for the
242 242
  /// arcs.
243
  template <typename _Digraph>
243
  template <typename GR>
244 244
  class SimplePath {
245 245
  public:
246 246

	
247
    typedef _Digraph Digraph;
247
    typedef GR Digraph;
248 248
    typedef typename Digraph::Arc Arc;
249 249

	
250 250
    /// \brief Default constructor
251 251
    ///
252 252
    /// Default constructor
253 253
    SimplePath() {}
254 254

	
255 255
    /// \brief Template copy constructor
256 256
    ///
257 257
    /// This path can be initialized with any other path type. It just
258 258
    /// makes a copy of the given path.
259 259
    template <typename CPath>
260 260
    SimplePath(const CPath& cpath) {
261 261
      pathCopy(cpath, *this);
262 262
    }
263 263

	
264 264
    /// \brief Template copy assignment
265 265
    ///
266 266
    /// This path can be initialized with any other path type. It just
267 267
    /// makes a copy of the given path.
268 268
    template <typename CPath>
269 269
    SimplePath& operator=(const CPath& cpath) {
270 270
      pathCopy(cpath, *this);
271 271
      return *this;
272 272
    }
273 273

	
274 274
    /// \brief Iterator class to iterate on the arcs of the paths
275 275
    ///
276 276
    /// This class is used to iterate on the arcs of the paths
277 277
    ///
278 278
    /// Of course it converts to Digraph::Arc
279 279
    class ArcIt {
280 280
      friend class SimplePath;
281 281
    public:
282 282
      /// Default constructor
283 283
      ArcIt() {}
284 284
      /// Invalid constructor
285 285
      ArcIt(Invalid) : path(0), idx(-1) {}
286 286
      /// \brief Initializate the constructor to the first arc of path
287 287
      ArcIt(const SimplePath &_path)
288 288
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
289 289

	
290 290
    private:
291 291

	
292 292
      /// Constructor with starting point
293 293
      ArcIt(const SimplePath &_path, int _idx)
294 294
        : idx(_idx), path(&_path) {}
295 295

	
296 296
    public:
297 297

	
298 298
      ///Conversion to Digraph::Arc
299 299
      operator const Arc&() const {
300 300
        return path->nth(idx);
301 301
      }
302 302

	
303 303
      /// Next arc
304 304
      ArcIt& operator++() {
305 305
        ++idx;
306 306
        if (idx >= path->length()) idx = -1;
307 307
        return *this;
308 308
      }
309 309

	
310 310
      /// Comparison operator
311 311
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
312 312
      /// Comparison operator
313 313
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
314 314
      /// Comparison operator
315 315
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
316 316

	
317 317
    private:
318 318
      const SimplePath *path;
319 319
      int idx;
320 320
    };
321 321

	
322 322
    /// \brief Length of the path.
323 323
    int length() const { return data.size(); }
324 324
    /// \brief Return true if the path is empty.
325 325
    bool empty() const { return data.empty(); }
326 326

	
327 327
    /// \brief Reset the path to an empty one.
328 328
    void clear() { data.clear(); }
329 329

	
330 330
    /// \brief The nth arc.
331 331
    ///
332
    /// \pre n is in the [0..length() - 1] range
332
    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
333 333
    const Arc& nth(int n) const {
334 334
      return data[n];
335 335
    }
336 336

	
337 337
    /// \brief  Initializes arc iterator to point to the nth arc.
338 338
    ArcIt nthIt(int n) const {
339 339
      return ArcIt(*this, n);
340 340
    }
341 341

	
342 342
    /// \brief The first arc of the path.
343 343
    const Arc& front() const {
344 344
      return data.front();
345 345
    }
346 346

	
347 347
    /// \brief The last arc of the path.
348 348
    const Arc& back() const {
349 349
      return data.back();
350 350
    }
351 351

	
352 352
    /// \brief Add a new arc behind the current path.
353 353
    void addBack(const Arc& arc) {
354 354
      data.push_back(arc);
355 355
    }
356 356

	
357 357
    /// \brief Erase the last arc of the path
358 358
    void eraseBack() {
359 359
      data.pop_back();
360 360
    }
361 361

	
362 362
    typedef True BuildTag;
363 363

	
364 364
    template <typename CPath>
365 365
    void build(const CPath& path) {
366 366
      int len = path.length();
367 367
      data.resize(len);
368 368
      int index = 0;
369 369
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
370 370
        data[index] = it;;
371 371
        ++index;
372 372
      }
373 373
    }
374 374

	
375 375
    template <typename CPath>
376 376
    void buildRev(const CPath& path) {
377 377
      int len = path.length();
378 378
      data.resize(len);
379 379
      int index = len;
380 380
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
381 381
        --index;
382 382
        data[index] = it;;
383 383
      }
384 384
    }
385 385

	
386 386
  protected:
387 387
    typedef std::vector<Arc> Container;
388 388
    Container data;
389 389

	
390 390
  };
391 391

	
392 392
  /// \brief A structure for representing directed paths in a digraph.
393 393
  ///
394 394
  /// A structure for representing directed path in a digraph.
395
  /// \tparam _Digraph The digraph type in which the path is.
395
  /// \tparam GR The digraph type in which the path is.
396 396
  ///
397 397
  /// In a sense, the path can be treated as a list of arcs. The
398 398
  /// lemon path type stores just this list. As a consequence it
399 399
  /// cannot enumerate the nodes in the path and the zero length paths
400 400
  /// cannot store the source.
401 401
  ///
402 402
  /// This implementation is a back and front insertable and erasable
403 403
  /// path type. It can be indexed in O(k) time, where k is the rank
404 404
  /// of the arc in the path. The length can be computed in O(n)
405 405
  /// time. The front and back insertion and erasure is O(1) time
406 406
  /// and it can be splited and spliced in O(1) time.
407
  template <typename _Digraph>
407
  template <typename GR>
408 408
  class ListPath {
409 409
  public:
410 410

	
411
    typedef _Digraph Digraph;
411
    typedef GR Digraph;
412 412
    typedef typename Digraph::Arc Arc;
413 413

	
414 414
  protected:
415 415

	
416 416
    // the std::list<> is incompatible
417 417
    // hard to create invalid iterator
418 418
    struct Node {
419 419
      Arc arc;
420 420
      Node *next, *prev;
421 421
    };
422 422

	
423 423
    Node *first, *last;
424 424

	
425 425
    std::allocator<Node> alloc;
426 426

	
427 427
  public:
428 428

	
429 429
    /// \brief Default constructor
430 430
    ///
431 431
    /// Default constructor
432 432
    ListPath() : first(0), last(0) {}
433 433

	
434 434
    /// \brief Template copy constructor
435 435
    ///
436 436
    /// This path can be initialized with any other path type. It just
437 437
    /// makes a copy of the given path.
438 438
    template <typename CPath>
439 439
    ListPath(const CPath& cpath) : first(0), last(0) {
440 440
      pathCopy(cpath, *this);
441 441
    }
442 442

	
443 443
    /// \brief Destructor of the path
444 444
    ///
445 445
    /// Destructor of the path
446 446
    ~ListPath() {
447 447
      clear();
448 448
    }
449 449

	
450 450
    /// \brief Template copy assignment
451 451
    ///
452 452
    /// This path can be initialized with any other path type. It just
453 453
    /// makes a copy of the given path.
454 454
    template <typename CPath>
455 455
    ListPath& operator=(const CPath& cpath) {
456 456
      pathCopy(cpath, *this);
457 457
      return *this;
458 458
    }
459 459

	
460 460
    /// \brief Iterator class to iterate on the arcs of the paths
461 461
    ///
462 462
    /// This class is used to iterate on the arcs of the paths
463 463
    ///
464 464
    /// Of course it converts to Digraph::Arc
465 465
    class ArcIt {
466 466
      friend class ListPath;
467 467
    public:
468 468
      /// Default constructor
469 469
      ArcIt() {}
470 470
      /// Invalid constructor
471 471
      ArcIt(Invalid) : path(0), node(0) {}
472 472
      /// \brief Initializate the constructor to the first arc of path
473 473
      ArcIt(const ListPath &_path)
474 474
        : path(&_path), node(_path.first) {}
475 475

	
476 476
    protected:
477 477

	
478 478
      ArcIt(const ListPath &_path, Node *_node)
479 479
        : path(&_path), node(_node) {}
480 480

	
481 481

	
482 482
    public:
483 483

	
484 484
      ///Conversion to Digraph::Arc
485 485
      operator const Arc&() const {
486 486
        return node->arc;
487 487
      }
488 488

	
489 489
      /// Next arc
490 490
      ArcIt& operator++() {
491 491
        node = node->next;
492 492
        return *this;
493 493
      }
494 494

	
495 495
      /// Comparison operator
496 496
      bool operator==(const ArcIt& e) const { return node==e.node; }
497 497
      /// Comparison operator
498 498
      bool operator!=(const ArcIt& e) const { return node!=e.node; }
499 499
      /// Comparison operator
500 500
      bool operator<(const ArcIt& e) const { return node<e.node; }
501 501

	
502 502
    private:
503 503
      const ListPath *path;
504 504
      Node *node;
505 505
    };
506 506

	
507 507
    /// \brief The nth arc.
508 508
    ///
509 509
    /// This function looks for the nth arc in O(n) time.
510
    /// \pre n is in the [0..length() - 1] range
510
    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
511 511
    const Arc& nth(int n) const {
512 512
      Node *node = first;
513 513
      for (int i = 0; i < n; ++i) {
514 514
        node = node->next;
515 515
      }
516 516
      return node->arc;
517 517
    }
518 518

	
519 519
    /// \brief Initializes arc iterator to point to the nth arc.
520 520
    ArcIt nthIt(int n) const {
521 521
      Node *node = first;
522 522
      for (int i = 0; i < n; ++i) {
523 523
        node = node->next;
524 524
      }
525 525
      return ArcIt(*this, node);
526 526
    }
527 527

	
528 528
    /// \brief Length of the path.
529 529
    int length() const {
530 530
      int len = 0;
531 531
      Node *node = first;
532 532
      while (node != 0) {
533 533
        node = node->next;
534 534
        ++len;
535 535
      }
536 536
      return len;
537 537
    }
538 538

	
539 539
    /// \brief Return true if the path is empty.
540 540
    bool empty() const { return first == 0; }
541 541

	
542 542
    /// \brief Reset the path to an empty one.
543 543
    void clear() {
544 544
      while (first != 0) {
545 545
        last = first->next;
546 546
        alloc.destroy(first);
547 547
        alloc.deallocate(first, 1);
548 548
        first = last;
549 549
      }
550 550
    }
551 551

	
552 552
    /// \brief The first arc of the path
553 553
    const Arc& front() const {
554 554
      return first->arc;
555 555
    }
556 556

	
557 557
    /// \brief Add a new arc before the current path
558 558
    void addFront(const Arc& arc) {
559 559
      Node *node = alloc.allocate(1);
560 560
      alloc.construct(node, Node());
561 561
      node->prev = 0;
562 562
      node->next = first;
563 563
      node->arc = arc;
564 564
      if (first) {
565 565
        first->prev = node;
566 566
        first = node;
567 567
      } else {
568 568
        first = last = node;
569 569
      }
570 570
    }
571 571

	
572 572
    /// \brief Erase the first arc of the path
573 573
    void eraseFront() {
574 574
      Node *node = first;
575 575
      first = first->next;
576 576
      if (first) {
577 577
        first->prev = 0;
578 578
      } else {
579 579
        last = 0;
580 580
      }
581 581
      alloc.destroy(node);
582 582
      alloc.deallocate(node, 1);
583 583
    }
584 584

	
585 585
    /// \brief The last arc of the path.
586 586
    const Arc& back() const {
587 587
      return last->arc;
588 588
    }
589 589

	
590 590
    /// \brief Add a new arc behind the current path.
591 591
    void addBack(const Arc& arc) {
592 592
      Node *node = alloc.allocate(1);
593 593
      alloc.construct(node, Node());
594 594
      node->next = 0;
595 595
      node->prev = last;
596 596
      node->arc = arc;
597 597
      if (last) {
598 598
        last->next = node;
599 599
        last = node;
600 600
      } else {
601 601
        last = first = node;
602 602
      }
603 603
    }
604 604

	
605 605
    /// \brief Erase the last arc of the path
606 606
    void eraseBack() {
607 607
      Node *node = last;
608 608
      last = last->prev;
609 609
      if (last) {
610 610
        last->next = 0;
611 611
      } else {
612 612
        first = 0;
613 613
      }
614 614
      alloc.destroy(node);
615 615
      alloc.deallocate(node, 1);
616 616
    }
617 617

	
618 618
    /// \brief Splice a path to the back of the current path.
619 619
    ///
620 620
    /// It splices \c tpath to the back of the current path and \c
621 621
    /// tpath becomes empty. The time complexity of this function is
622 622
    /// O(1).
623 623
    void spliceBack(ListPath& tpath) {
624 624
      if (first) {
625 625
        if (tpath.first) {
626 626
          last->next = tpath.first;
627 627
          tpath.first->prev = last;
628 628
          last = tpath.last;
629 629
        }
630 630
      } else {
631 631
        first = tpath.first;
632 632
        last = tpath.last;
633 633
      }
634 634
      tpath.first = tpath.last = 0;
635 635
    }
636 636

	
637 637
    /// \brief Splice a path to the front of the current path.
638 638
    ///
639 639
    /// It splices \c tpath before the current path and \c tpath
640 640
    /// becomes empty. The time complexity of this function
641 641
    /// is O(1).
642 642
    void spliceFront(ListPath& tpath) {
643 643
      if (first) {
644 644
        if (tpath.first) {
645 645
          first->prev = tpath.last;
646 646
          tpath.last->next = first;
647 647
          first = tpath.first;
648 648
        }
649 649
      } else {
650 650
        first = tpath.first;
651 651
        last = tpath.last;
652 652
      }
653 653
      tpath.first = tpath.last = 0;
654 654
    }
655 655

	
656 656
    /// \brief Splice a path into the current path.
657 657
    ///
658 658
    /// It splices the \c tpath into the current path before the
659 659
    /// position of \c it iterator and \c tpath becomes empty. The
660 660
    /// time complexity of this function is O(1). If the \c it is
661 661
    /// \c INVALID then it will splice behind the current path.
662 662
    void splice(ArcIt it, ListPath& tpath) {
663 663
      if (it.node) {
664 664
        if (tpath.first) {
665 665
          tpath.first->prev = it.node->prev;
666 666
          if (it.node->prev) {
667 667
            it.node->prev->next = tpath.first;
668 668
          } else {
669 669
            first = tpath.first;
670 670
          }
671 671
          it.node->prev = tpath.last;
672 672
          tpath.last->next = it.node;
673 673
        }
674 674
      } else {
675 675
        if (first) {
676 676
          if (tpath.first) {
677 677
            last->next = tpath.first;
678 678
            tpath.first->prev = last;
679 679
            last = tpath.last;
680 680
          }
681 681
        } else {
682 682
          first = tpath.first;
683 683
          last = tpath.last;
684 684
        }
685 685
      }
686 686
      tpath.first = tpath.last = 0;
687 687
    }
688 688

	
689 689
    /// \brief Split the current path.
690 690
    ///
691 691
    /// It splits the current path into two parts. The part before
692 692
    /// the iterator \c it will remain in the current path and the part
693 693
    /// starting with
694 694
    /// \c it will put into \c tpath. If \c tpath have arcs
695 695
    /// before the operation they are removed first.  The time
696 696
    /// complexity of this function is O(1) plus the the time of emtying
697 697
    /// \c tpath. If \c it is \c INVALID then it just clears \c tpath
698 698
    void split(ArcIt it, ListPath& tpath) {
699 699
      tpath.clear();
700 700
      if (it.node) {
701 701
        tpath.first = it.node;
702 702
        tpath.last = last;
703 703
        if (it.node->prev) {
704 704
          last = it.node->prev;
705 705
          last->next = 0;
706 706
        } else {
707 707
          first = last = 0;
708 708
        }
709 709
        it.node->prev = 0;
710 710
      }
711 711
    }
712 712

	
713 713

	
714 714
    typedef True BuildTag;
715 715

	
716 716
    template <typename CPath>
717 717
    void build(const CPath& path) {
718 718
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
719 719
        addBack(it);
720 720
      }
721 721
    }
722 722

	
723 723
    template <typename CPath>
724 724
    void buildRev(const CPath& path) {
725 725
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
726 726
        addFront(it);
727 727
      }
728 728
    }
729 729

	
730 730
  };
731 731

	
732 732
  /// \brief A structure for representing directed paths in a digraph.
733 733
  ///
734 734
  /// A structure for representing directed path in a digraph.
735
  /// \tparam _Digraph The digraph type in which the path is.
735
  /// \tparam GR The digraph type in which the path is.
736 736
  ///
737 737
  /// In a sense, the path can be treated as a list of arcs. The
738 738
  /// lemon path type stores just this list. As a consequence it
739 739
  /// cannot enumerate the nodes in the path and the source node of
740 740
  /// a zero length path is undefined.
741 741
  ///
742 742
  /// This implementation is completly static, i.e. it can be copy constucted
743 743
  /// or copy assigned from another path, but otherwise it cannot be
744 744
  /// modified.
745 745
  ///
746 746
  /// Being the the most memory efficient path type in LEMON,
747 747
  /// it is intented to be
748 748
  /// used when you want to store a large number of paths.
749
  template <typename _Digraph>
749
  template <typename GR>
750 750
  class StaticPath {
751 751
  public:
752 752

	
753
    typedef _Digraph Digraph;
753
    typedef GR Digraph;
754 754
    typedef typename Digraph::Arc Arc;
755 755

	
756 756
    /// \brief Default constructor
757 757
    ///
758 758
    /// Default constructor
759 759
    StaticPath() : len(0), arcs(0) {}
760 760

	
761 761
    /// \brief Template copy constructor
762 762
    ///
763 763
    /// This path can be initialized from any other path type.
764 764
    template <typename CPath>
765 765
    StaticPath(const CPath& cpath) : arcs(0) {
766 766
      pathCopy(cpath, *this);
767 767
    }
768 768

	
769 769
    /// \brief Destructor of the path
770 770
    ///
771 771
    /// Destructor of the path
772 772
    ~StaticPath() {
773 773
      if (arcs) delete[] arcs;
774 774
    }
775 775

	
776 776
    /// \brief Template copy assignment
777 777
    ///
778 778
    /// This path can be made equal to any other path type. It simply
779 779
    /// makes a copy of the given path.
780 780
    template <typename CPath>
781 781
    StaticPath& operator=(const CPath& cpath) {
782 782
      pathCopy(cpath, *this);
783 783
      return *this;
784 784
    }
785 785

	
786 786
    /// \brief Iterator class to iterate on the arcs of the paths
787 787
    ///
788 788
    /// This class is used to iterate on the arcs of the paths
789 789
    ///
790 790
    /// Of course it converts to Digraph::Arc
791 791
    class ArcIt {
792 792
      friend class StaticPath;
793 793
    public:
794 794
      /// Default constructor
795 795
      ArcIt() {}
796 796
      /// Invalid constructor
797 797
      ArcIt(Invalid) : path(0), idx(-1) {}
798 798
      /// Initializate the constructor to the first arc of path
799 799
      ArcIt(const StaticPath &_path)
800 800
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
801 801

	
802 802
    private:
803 803

	
804 804
      /// Constructor with starting point
805 805
      ArcIt(const StaticPath &_path, int _idx)
806 806
        : idx(_idx), path(&_path) {}
807 807

	
808 808
    public:
809 809

	
810 810
      ///Conversion to Digraph::Arc
811 811
      operator const Arc&() const {
812 812
        return path->nth(idx);
813 813
      }
814 814

	
815 815
      /// Next arc
816 816
      ArcIt& operator++() {
817 817
        ++idx;
818 818
        if (idx >= path->length()) idx = -1;
819 819
        return *this;
820 820
      }
821 821

	
822 822
      /// Comparison operator
823 823
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
824 824
      /// Comparison operator
825 825
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
826 826
      /// Comparison operator
827 827
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
828 828

	
829 829
    private:
830 830
      const StaticPath *path;
831 831
      int idx;
832 832
    };
833 833

	
834 834
    /// \brief The nth arc.
835 835
    ///
836
    /// \pre n is in the [0..length() - 1] range
836
    /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
837 837
    const Arc& nth(int n) const {
838 838
      return arcs[n];
839 839
    }
840 840

	
841 841
    /// \brief The arc iterator pointing to the nth arc.
842 842
    ArcIt nthIt(int n) const {
843 843
      return ArcIt(*this, n);
844 844
    }
845 845

	
846 846
    /// \brief The length of the path.
847 847
    int length() const { return len; }
848 848

	
849 849
    /// \brief Return true when the path is empty.
850 850
    int empty() const { return len == 0; }
851 851

	
852 852
    /// \brief Erase all arcs in the digraph.
853 853
    void clear() {
854 854
      len = 0;
855 855
      if (arcs) delete[] arcs;
856 856
      arcs = 0;
857 857
    }
858 858

	
859 859
    /// \brief The first arc of the path.
860 860
    const Arc& front() const {
861 861
      return arcs[0];
862 862
    }
863 863

	
864 864
    /// \brief The last arc of the path.
865 865
    const Arc& back() const {
866 866
      return arcs[len - 1];
867 867
    }
868 868

	
869 869

	
870 870
    typedef True BuildTag;
871 871

	
872 872
    template <typename CPath>
873 873
    void build(const CPath& path) {
874 874
      len = path.length();
875 875
      arcs = new Arc[len];
876 876
      int index = 0;
877 877
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
878 878
        arcs[index] = it;
879 879
        ++index;
880 880
      }
881 881
    }
882 882

	
883 883
    template <typename CPath>
884 884
    void buildRev(const CPath& path) {
885 885
      len = path.length();
886 886
      arcs = new Arc[len];
887 887
      int index = len;
888 888
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
889 889
        --index;
890 890
        arcs[index] = it;
891 891
      }
892 892
    }
893 893

	
894 894
  private:
895 895
    int len;
896 896
    Arc* arcs;
897 897
  };
898 898

	
899 899
  ///////////////////////////////////////////////////////////////////////
900 900
  // Additional utilities
901 901
  ///////////////////////////////////////////////////////////////////////
902 902

	
903 903
  namespace _path_bits {
904 904

	
905 905
    template <typename Path, typename Enable = void>
906 906
    struct RevPathTagIndicator {
907 907
      static const bool value = false;
908 908
    };
909 909

	
910 910
    template <typename Path>
911 911
    struct RevPathTagIndicator<
912 912
      Path,
913 913
      typename enable_if<typename Path::RevPathTag, void>::type
914 914
      > {
915 915
      static const bool value = true;
916 916
    };
917 917

	
918 918
    template <typename Path, typename Enable = void>
919 919
    struct BuildTagIndicator {
920 920
      static const bool value = false;
921 921
    };
922 922

	
923 923
    template <typename Path>
924 924
    struct BuildTagIndicator<
925 925
      Path,
926 926
      typename enable_if<typename Path::BuildTag, void>::type
927 927
    > {
928 928
      static const bool value = true;
929 929
    };
930 930

	
931 931
    template <typename From, typename To,
932 932
              bool buildEnable = BuildTagIndicator<To>::value>
933 933
    struct PathCopySelectorForward {
934 934
      static void copy(const From& from, To& to) {
935 935
        to.clear();
936 936
        for (typename From::ArcIt it(from); it != INVALID; ++it) {
937 937
          to.addBack(it);
938 938
        }
939 939
      }
940 940
    };
941 941

	
942 942
    template <typename From, typename To>
943 943
    struct PathCopySelectorForward<From, To, true> {
944 944
      static void copy(const From& from, To& to) {
945 945
        to.clear();
946 946
        to.build(from);
947 947
      }
948 948
    };
949 949

	
950 950
    template <typename From, typename To,
951 951
              bool buildEnable = BuildTagIndicator<To>::value>
952 952
    struct PathCopySelectorBackward {
953 953
      static void copy(const From& from, To& to) {
954 954
        to.clear();
955 955
        for (typename From::RevArcIt it(from); it != INVALID; ++it) {
956 956
          to.addFront(it);
957 957
        }
958 958
      }
959 959
    };
960 960

	
961 961
    template <typename From, typename To>
962 962
    struct PathCopySelectorBackward<From, To, true> {
963 963
      static void copy(const From& from, To& to) {
964 964
        to.clear();
965 965
        to.buildRev(from);
966 966
      }
967 967
    };
968 968

	
969 969
    
970 970
    template <typename From, typename To,
971 971
              bool revEnable = RevPathTagIndicator<From>::value>
972 972
    struct PathCopySelector {
973 973
      static void copy(const From& from, To& to) {
974 974
        PathCopySelectorForward<From, To>::copy(from, to);
975 975
      }      
976 976
    };
977 977

	
978 978
    template <typename From, typename To>
979 979
    struct PathCopySelector<From, To, true> {
980 980
      static void copy(const From& from, To& to) {
981 981
        PathCopySelectorBackward<From, To>::copy(from, to);
982 982
      }      
983 983
    };
984 984

	
985 985
  }
986 986

	
987 987

	
988 988
  /// \brief Make a copy of a path.
989 989
  ///
990 990
  /// This function makes a copy of a path.
991 991
  template <typename From, typename To>
992 992
  void pathCopy(const From& from, To& to) {
993 993
    checkConcept<concepts::PathDumper<typename From::Digraph>, From>();
994 994
    _path_bits::PathCopySelector<From, To>::copy(from, to);
995 995
  }
996 996

	
997 997
  /// \brief Deprecated version of \ref pathCopy().
998 998
  ///
999 999
  /// Deprecated version of \ref pathCopy() (only for reverse compatibility).
1000 1000
  template <typename To, typename From>
1001 1001
  void copyPath(To& to, const From& from) {
1002 1002
    pathCopy(from, to);
1003 1003
  }
1004 1004

	
1005 1005
  /// \brief Check the consistency of a path.
1006 1006
  ///
1007 1007
  /// This function checks that the target of each arc is the same
1008 1008
  /// as the source of the next one.
1009 1009
  ///
1010 1010
  template <typename Digraph, typename Path>
1011 1011
  bool checkPath(const Digraph& digraph, const Path& path) {
1012 1012
    typename Path::ArcIt it(path);
1013 1013
    if (it == INVALID) return true;
1014 1014
    typename Digraph::Node node = digraph.target(it);
1015 1015
    ++it;
1016 1016
    while (it != INVALID) {
1017 1017
      if (digraph.source(it) != node) return false;
1018 1018
      node = digraph.target(it);
1019 1019
      ++it;
1020 1020
    }
1021 1021
    return true;
1022 1022
  }
1023 1023

	
1024 1024
  /// \brief The source of a path
1025 1025
  ///
1026 1026
  /// This function returns the source node of the given path.
1027 1027
  /// If the path is empty, then it returns \c INVALID.
1028 1028
  template <typename Digraph, typename Path>
1029 1029
  typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
1030 1030
    return path.empty() ? INVALID : digraph.source(path.front());
1031 1031
  }
1032 1032

	
1033 1033
  /// \brief The target of a path
1034 1034
  ///
1035 1035
  /// This function returns the target node of the given path.
1036 1036
  /// If the path is empty, then it returns \c INVALID.
1037 1037
  template <typename Digraph, typename Path>
1038 1038
  typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1039 1039
    return path.empty() ? INVALID : digraph.target(path.back());
1040 1040
  }
1041 1041

	
1042 1042
  /// \brief Class which helps to iterate through the nodes of a path
1043 1043
  ///
1044 1044
  /// In a sense, the path can be treated as a list of arcs. The
1045 1045
  /// lemon path type stores only this list. As a consequence, it
1046 1046
  /// cannot enumerate the nodes in the path and the zero length paths
1047 1047
  /// cannot have a source node.
1048 1048
  ///
1049 1049
  /// This class implements the node iterator of a path structure. To
1050 1050
  /// provide this feature, the underlying digraph should be passed to
1051 1051
  /// the constructor of the iterator.
1052 1052
  template <typename Path>
1053 1053
  class PathNodeIt {
1054 1054
  private:
1055 1055
    const typename Path::Digraph *_digraph;
1056 1056
    typename Path::ArcIt _it;
1057 1057
    typename Path::Digraph::Node _nd;
1058 1058

	
1059 1059
  public:
1060 1060

	
1061 1061
    typedef typename Path::Digraph Digraph;
1062 1062
    typedef typename Digraph::Node Node;
1063 1063

	
1064 1064
    /// Default constructor
1065 1065
    PathNodeIt() {}
1066 1066
    /// Invalid constructor
1067 1067
    PathNodeIt(Invalid)
1068 1068
      : _digraph(0), _it(INVALID), _nd(INVALID) {}
1069 1069
    /// Constructor
1070 1070
    PathNodeIt(const Digraph& digraph, const Path& path)
1071 1071
      : _digraph(&digraph), _it(path) {
1072 1072
      _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1073 1073
    }
1074 1074
    /// Constructor
1075 1075
    PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
1076 1076
      : _digraph(&digraph), _it(path), _nd(src) {}
1077 1077

	
1078 1078
    ///Conversion to Digraph::Node
1079 1079
    operator Node() const {
1080 1080
      return _nd;
1081 1081
    }
1082 1082

	
1083 1083
    /// Next node
1084 1084
    PathNodeIt& operator++() {
1085 1085
      if (_it == INVALID) _nd = INVALID;
1086 1086
      else {
1087 1087
        _nd = _digraph->target(_it);
1088 1088
        ++_it;
1089 1089
      }
1090 1090
      return *this;
1091 1091
    }
1092 1092

	
1093 1093
    /// Comparison operator
1094 1094
    bool operator==(const PathNodeIt& n) const {
1095 1095
      return _it == n._it && _nd == n._nd;
1096 1096
    }
1097 1097
    /// Comparison operator
1098 1098
    bool operator!=(const PathNodeIt& n) const {
1099 1099
      return _it != n._it || _nd != n._nd;
1100 1100
    }
1101 1101
    /// Comparison operator
1102 1102
    bool operator<(const PathNodeIt& n) const {
1103 1103
      return (_it < n._it && _nd != INVALID);
1104 1104
    }
1105 1105

	
1106 1106
  };
1107 1107

	
1108 1108
  ///@}
1109 1109

	
1110 1110
} // namespace lemon
1111 1111

	
1112 1112
#endif // LEMON_PATH_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
///\file
20 20
///\brief Instantiation of the Random class.
21 21

	
22 22
#include <lemon/random.h>
23 23

	
24 24
namespace lemon {
25 25
  /// \brief Global random number generator instance
26 26
  ///
27 27
  /// A global Mersenne Twister random number generator instance.
28 28
  Random rnd;
29 29
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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
/*
20 20
 * This file contains the reimplemented version of the Mersenne Twister
21 21
 * Generator of Matsumoto and Nishimura.
22 22
 *
23 23
 * See the appropriate copyright notice below.
24 24
 *
25 25
 * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
26 26
 * All rights reserved.
27 27
 *
28 28
 * Redistribution and use in source and binary forms, with or without
29 29
 * modification, are permitted provided that the following conditions
30 30
 * are met:
31 31
 *
32 32
 * 1. Redistributions of source code must retain the above copyright
33 33
 *    notice, this list of conditions and the following disclaimer.
34 34
 *
35 35
 * 2. Redistributions in binary form must reproduce the above copyright
36 36
 *    notice, this list of conditions and the following disclaimer in the
37 37
 *    documentation and/or other materials provided with the distribution.
38 38
 *
39 39
 * 3. The names of its contributors may not be used to endorse or promote
40 40
 *    products derived from this software without specific prior written
41 41
 *    permission.
42 42
 *
43 43
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 44
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 45
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
46 46
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
47 47
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
48 48
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49 49
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
50 50
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 51
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
52 52
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53 53
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
54 54
 * OF THE POSSIBILITY OF SUCH DAMAGE.
55 55
 *
56 56
 *
57 57
 * Any feedback is very welcome.
58 58
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
59 59
 * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
60 60
 */
61 61

	
62 62
#ifndef LEMON_RANDOM_H
63 63
#define LEMON_RANDOM_H
64 64

	
65 65
#include <algorithm>
66 66
#include <iterator>
67 67
#include <vector>
68 68
#include <limits>
69 69
#include <fstream>
70 70

	
71 71
#include <lemon/math.h>
72 72
#include <lemon/dim2.h>
73 73

	
74 74
#ifndef WIN32
75 75
#include <sys/time.h>
76 76
#include <ctime>
77 77
#include <sys/types.h>
78 78
#include <unistd.h>
79 79
#else
80 80
#include <lemon/bits/windows.h>
81 81
#endif
82 82

	
83 83
///\ingroup misc
84 84
///\file
85 85
///\brief Mersenne Twister random number generator
86 86

	
87 87
namespace lemon {
88 88

	
89 89
  namespace _random_bits {
90 90

	
91 91
    template <typename _Word, int _bits = std::numeric_limits<_Word>::digits>
92 92
    struct RandomTraits {};
93 93

	
94 94
    template <typename _Word>
95 95
    struct RandomTraits<_Word, 32> {
96 96

	
97 97
      typedef _Word Word;
98 98
      static const int bits = 32;
99 99

	
100 100
      static const int length = 624;
101 101
      static const int shift = 397;
102 102

	
103 103
      static const Word mul = 0x6c078965u;
104 104
      static const Word arrayInit = 0x012BD6AAu;
105 105
      static const Word arrayMul1 = 0x0019660Du;
106 106
      static const Word arrayMul2 = 0x5D588B65u;
107 107

	
108 108
      static const Word mask = 0x9908B0DFu;
109 109
      static const Word loMask = (1u << 31) - 1;
110 110
      static const Word hiMask = ~loMask;
111 111

	
112 112

	
113 113
      static Word tempering(Word rnd) {
114 114
        rnd ^= (rnd >> 11);
115 115
        rnd ^= (rnd << 7) & 0x9D2C5680u;
116 116
        rnd ^= (rnd << 15) & 0xEFC60000u;
117 117
        rnd ^= (rnd >> 18);
118 118
        return rnd;
119 119
      }
120 120

	
121 121
    };
122 122

	
123 123
    template <typename _Word>
124 124
    struct RandomTraits<_Word, 64> {
125 125

	
126 126
      typedef _Word Word;
127 127
      static const int bits = 64;
128 128

	
129 129
      static const int length = 312;
130 130
      static const int shift = 156;
131 131

	
132 132
      static const Word mul = Word(0x5851F42Du) << 32 | Word(0x4C957F2Du);
133 133
      static const Word arrayInit = Word(0x00000000u) << 32 |Word(0x012BD6AAu);
134 134
      static const Word arrayMul1 = Word(0x369DEA0Fu) << 32 |Word(0x31A53F85u);
135 135
      static const Word arrayMul2 = Word(0x27BB2EE6u) << 32 |Word(0x87B0B0FDu);
136 136

	
137 137
      static const Word mask = Word(0xB5026F5Au) << 32 | Word(0xA96619E9u);
138 138
      static const Word loMask = (Word(1u) << 31) - 1;
139 139
      static const Word hiMask = ~loMask;
140 140

	
141 141
      static Word tempering(Word rnd) {
142 142
        rnd ^= (rnd >> 29) & (Word(0x55555555u) << 32 | Word(0x55555555u));
143 143
        rnd ^= (rnd << 17) & (Word(0x71D67FFFu) << 32 | Word(0xEDA60000u));
144 144
        rnd ^= (rnd << 37) & (Word(0xFFF7EEE0u) << 32 | Word(0x00000000u));
145 145
        rnd ^= (rnd >> 43);
146 146
        return rnd;
147 147
      }
148 148

	
149 149
    };
150 150

	
151 151
    template <typename _Word>
152 152
    class RandomCore {
153 153
    public:
154 154

	
155 155
      typedef _Word Word;
156 156

	
157 157
    private:
158 158

	
159 159
      static const int bits = RandomTraits<Word>::bits;
160 160

	
161 161
      static const int length = RandomTraits<Word>::length;
162 162
      static const int shift = RandomTraits<Word>::shift;
163 163

	
164 164
    public:
165 165

	
166 166
      void initState() {
167 167
        static const Word seedArray[4] = {
168 168
          0x12345u, 0x23456u, 0x34567u, 0x45678u
169 169
        };
170 170

	
171 171
        initState(seedArray, seedArray + 4);
172 172
      }
173 173

	
174 174
      void initState(Word seed) {
175 175

	
176 176
        static const Word mul = RandomTraits<Word>::mul;
177 177

	
178 178
        current = state;
179 179

	
180 180
        Word *curr = state + length - 1;
181 181
        curr[0] = seed; --curr;
182 182
        for (int i = 1; i < length; ++i) {
183 183
          curr[0] = (mul * ( curr[1] ^ (curr[1] >> (bits - 2)) ) + i);
184 184
          --curr;
185 185
        }
186 186
      }
187 187

	
188 188
      template <typename Iterator>
189 189
      void initState(Iterator begin, Iterator end) {
190 190

	
191 191
        static const Word init = RandomTraits<Word>::arrayInit;
192 192
        static const Word mul1 = RandomTraits<Word>::arrayMul1;
193 193
        static const Word mul2 = RandomTraits<Word>::arrayMul2;
194 194

	
195 195

	
196 196
        Word *curr = state + length - 1; --curr;
197 197
        Iterator it = begin; int cnt = 0;
198 198
        int num;
199 199

	
200 200
        initState(init);
201 201

	
202 202
        num = length > end - begin ? length : end - begin;
203 203
        while (num--) {
204 204
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1))
205 205
            + *it + cnt;
206 206
          ++it; ++cnt;
207 207
          if (it == end) {
208 208
            it = begin; cnt = 0;
209 209
          }
210 210
          if (curr == state) {
211 211
            curr = state + length - 1; curr[0] = state[0];
212 212
          }
213 213
          --curr;
214 214
        }
215 215

	
216 216
        num = length - 1; cnt = length - (curr - state) - 1;
217 217
        while (num--) {
218 218
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2))
219 219
            - cnt;
220 220
          --curr; ++cnt;
221 221
          if (curr == state) {
222 222
            curr = state + length - 1; curr[0] = state[0]; --curr;
223 223
            cnt = 1;
224 224
          }
225 225
        }
226 226

	
227 227
        state[length - 1] = Word(1) << (bits - 1);
228 228
      }
229 229

	
230 230
      void copyState(const RandomCore& other) {
231 231
        std::copy(other.state, other.state + length, state);
232 232
        current = state + (other.current - other.state);
233 233
      }
234 234

	
235 235
      Word operator()() {
236 236
        if (current == state) fillState();
237 237
        --current;
238 238
        Word rnd = *current;
239 239
        return RandomTraits<Word>::tempering(rnd);
240 240
      }
241 241

	
242 242
    private:
243 243

	
244 244

	
245 245
      void fillState() {
246 246
        static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
247 247
        static const Word loMask = RandomTraits<Word>::loMask;
248 248
        static const Word hiMask = RandomTraits<Word>::hiMask;
249 249

	
250 250
        current = state + length;
251 251

	
252 252
        register Word *curr = state + length - 1;
253 253
        register long num;
254 254

	
255 255
        num = length - shift;
256 256
        while (num--) {
257 257
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
258 258
            curr[- shift] ^ mask[curr[-1] & 1ul];
259 259
          --curr;
260 260
        }
261 261
        num = shift - 1;
262 262
        while (num--) {
263 263
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
264 264
            curr[length - shift] ^ mask[curr[-1] & 1ul];
265 265
          --curr;
266 266
        }
267 267
        state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
268 268
          curr[length - shift] ^ mask[curr[length - 1] & 1ul];
269 269

	
270 270
      }
271 271

	
272 272

	
273 273
      Word *current;
274 274
      Word state[length];
275 275

	
276 276
    };
277 277

	
278 278

	
279 279
    template <typename Result,
280 280
              int shift = (std::numeric_limits<Result>::digits + 1) / 2>
281 281
    struct Masker {
282 282
      static Result mask(const Result& result) {
283 283
        return Masker<Result, (shift + 1) / 2>::
284 284
          mask(static_cast<Result>(result | (result >> shift)));
285 285
      }
286 286
    };
287 287

	
288 288
    template <typename Result>
289 289
    struct Masker<Result, 1> {
290 290
      static Result mask(const Result& result) {
291 291
        return static_cast<Result>(result | (result >> 1));
292 292
      }
293 293
    };
294 294

	
295 295
    template <typename Result, typename Word,
296 296
              int rest = std::numeric_limits<Result>::digits, int shift = 0,
297 297
              bool last = rest <= std::numeric_limits<Word>::digits>
298 298
    struct IntConversion {
299 299
      static const int bits = std::numeric_limits<Word>::digits;
300 300

	
301 301
      static Result convert(RandomCore<Word>& rnd) {
302 302
        return static_cast<Result>(rnd() >> (bits - rest)) << shift;
303 303
      }
304 304

	
305 305
    };
306 306

	
307 307
    template <typename Result, typename Word, int rest, int shift>
308 308
    struct IntConversion<Result, Word, rest, shift, false> {
309 309
      static const int bits = std::numeric_limits<Word>::digits;
310 310

	
311 311
      static Result convert(RandomCore<Word>& rnd) {
312 312
        return (static_cast<Result>(rnd()) << shift) |
313 313
          IntConversion<Result, Word, rest - bits, shift + bits>::convert(rnd);
314 314
      }
315 315
    };
316 316

	
317 317

	
318 318
    template <typename Result, typename Word,
319 319
              bool one_word = (std::numeric_limits<Word>::digits <
320 320
                               std::numeric_limits<Result>::digits) >
321 321
    struct Mapping {
322 322
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
323 323
        Word max = Word(bound - 1);
324 324
        Result mask = Masker<Result>::mask(bound - 1);
325 325
        Result num;
326 326
        do {
327 327
          num = IntConversion<Result, Word>::convert(rnd) & mask;
328 328
        } while (num > max);
329 329
        return num;
330 330
      }
331 331
    };
332 332

	
333 333
    template <typename Result, typename Word>
334 334
    struct Mapping<Result, Word, false> {
335 335
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
336 336
        Word max = Word(bound - 1);
337 337
        Word mask = Masker<Word, (std::numeric_limits<Result>::digits + 1) / 2>
338 338
          ::mask(max);
339 339
        Word num;
340 340
        do {
341 341
          num = rnd() & mask;
342 342
        } while (num > max);
343 343
        return num;
344 344
      }
345 345
    };
346 346

	
347 347
    template <typename Result, int exp>
348 348
    struct ShiftMultiplier {
349 349
      static const Result multiplier() {
350 350
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
351 351
        res *= res;
352 352
        if ((exp & 1) == 1) res *= static_cast<Result>(0.5);
353 353
        return res;
354 354
      }
355 355
    };
356 356

	
357 357
    template <typename Result>
358 358
    struct ShiftMultiplier<Result, 0> {
359 359
      static const Result multiplier() {
360 360
        return static_cast<Result>(1.0);
361 361
      }
362 362
    };
363 363

	
364 364
    template <typename Result>
365 365
    struct ShiftMultiplier<Result, 20> {
366 366
      static const Result multiplier() {
367 367
        return static_cast<Result>(1.0/1048576.0);
368 368
      }
369 369
    };
370 370

	
371 371
    template <typename Result>
372 372
    struct ShiftMultiplier<Result, 32> {
373 373
      static const Result multiplier() {
374 374
        return static_cast<Result>(1.0/4294967296.0);
375 375
      }
376 376
    };
377 377

	
378 378
    template <typename Result>
379 379
    struct ShiftMultiplier<Result, 53> {
380 380
      static const Result multiplier() {
381 381
        return static_cast<Result>(1.0/9007199254740992.0);
382 382
      }
383 383
    };
384 384

	
385 385
    template <typename Result>
386 386
    struct ShiftMultiplier<Result, 64> {
387 387
      static const Result multiplier() {
388 388
        return static_cast<Result>(1.0/18446744073709551616.0);
389 389
      }
390 390
    };
391 391

	
392 392
    template <typename Result, int exp>
393 393
    struct Shifting {
394 394
      static Result shift(const Result& result) {
395 395
        return result * ShiftMultiplier<Result, exp>::multiplier();
396 396
      }
397 397
    };
398 398

	
399 399
    template <typename Result, typename Word,
400 400
              int rest = std::numeric_limits<Result>::digits, int shift = 0,
401 401
              bool last = rest <= std::numeric_limits<Word>::digits>
402 402
    struct RealConversion{
403 403
      static const int bits = std::numeric_limits<Word>::digits;
404 404

	
405 405
      static Result convert(RandomCore<Word>& rnd) {
406 406
        return Shifting<Result, shift + rest>::
407 407
          shift(static_cast<Result>(rnd() >> (bits - rest)));
408 408
      }
409 409
    };
410 410

	
411 411
    template <typename Result, typename Word, int rest, int shift>
412 412
    struct RealConversion<Result, Word, rest, shift, false> {
413 413
      static const int bits = std::numeric_limits<Word>::digits;
414 414

	
415 415
      static Result convert(RandomCore<Word>& rnd) {
416 416
        return Shifting<Result, shift + bits>::
417 417
          shift(static_cast<Result>(rnd())) +
418 418
          RealConversion<Result, Word, rest-bits, shift + bits>::
419 419
          convert(rnd);
420 420
      }
421 421
    };
422 422

	
423 423
    template <typename Result, typename Word>
424 424
    struct Initializer {
425 425

	
426 426
      template <typename Iterator>
427 427
      static void init(RandomCore<Word>& rnd, Iterator begin, Iterator end) {
428 428
        std::vector<Word> ws;
429 429
        for (Iterator it = begin; it != end; ++it) {
430 430
          ws.push_back(Word(*it));
431 431
        }
432 432
        rnd.initState(ws.begin(), ws.end());
433 433
      }
434 434

	
435 435
      static void init(RandomCore<Word>& rnd, Result seed) {
436 436
        rnd.initState(seed);
437 437
      }
438 438
    };
439 439

	
440 440
    template <typename Word>
441 441
    struct BoolConversion {
442 442
      static bool convert(RandomCore<Word>& rnd) {
443 443
        return (rnd() & 1) == 1;
444 444
      }
445 445
    };
446 446

	
447 447
    template <typename Word>
448 448
    struct BoolProducer {
449 449
      Word buffer;
450 450
      int num;
451 451

	
452 452
      BoolProducer() : num(0) {}
453 453

	
454 454
      bool convert(RandomCore<Word>& rnd) {
455 455
        if (num == 0) {
456 456
          buffer = rnd();
457 457
          num = RandomTraits<Word>::bits;
458 458
        }
459 459
        bool r = (buffer & 1);
460 460
        buffer >>= 1;
461 461
        --num;
462 462
        return r;
463 463
      }
464 464
    };
465 465

	
466 466
  }
467 467

	
468 468
  /// \ingroup misc
469 469
  ///
470 470
  /// \brief Mersenne Twister random number generator
471 471
  ///
472 472
  /// The Mersenne Twister is a twisted generalized feedback
473 473
  /// shift-register generator of Matsumoto and Nishimura. The period
474 474
  /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
475 475
  /// equi-distributed in 623 dimensions for 32-bit numbers. The time
476 476
  /// performance of this generator is comparable to the commonly used
477 477
  /// generators.
478 478
  ///
479 479
  /// This implementation is specialized for both 32-bit and 64-bit
480 480
  /// architectures. The generators differ sligthly in the
481 481
  /// initialization and generation phase so they produce two
482 482
  /// completly different sequences.
483 483
  ///
484 484
  /// The generator gives back random numbers of serveral types. To
485 485
  /// get a random number from a range of a floating point type you
486 486
  /// can use one form of the \c operator() or the \c real() member
487 487
  /// function. If you want to get random number from the {0, 1, ...,
488 488
  /// n-1} integer range use the \c operator[] or the \c integer()
489 489
  /// method. And to get random number from the whole range of an
490 490
  /// integer type you can use the argumentless \c integer() or \c
491 491
  /// uinteger() functions. After all you can get random bool with
492 492
  /// equal chance of true and false or given probability of true
493 493
  /// result with the \c boolean() member functions.
494 494
  ///
495 495
  ///\code
496 496
  /// // The commented code is identical to the other
497 497
  /// double a = rnd();                     // [0.0, 1.0)
498 498
  /// // double a = rnd.real();             // [0.0, 1.0)
499 499
  /// double b = rnd(100.0);                // [0.0, 100.0)
500 500
  /// // double b = rnd.real(100.0);        // [0.0, 100.0)
501 501
  /// double c = rnd(1.0, 2.0);             // [1.0, 2.0)
502 502
  /// // double c = rnd.real(1.0, 2.0);     // [1.0, 2.0)
503 503
  /// int d = rnd[100000];                  // 0..99999
504 504
  /// // int d = rnd.integer(100000);       // 0..99999
505 505
  /// int e = rnd[6] + 1;                   // 1..6
506 506
  /// // int e = rnd.integer(1, 1 + 6);     // 1..6
507 507
  /// int b = rnd.uinteger<int>();          // 0 .. 2^31 - 1
508 508
  /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
509 509
  /// bool g = rnd.boolean();               // P(g = true) = 0.5
510 510
  /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
511 511
  ///\endcode
512 512
  ///
513 513
  /// LEMON provides a global instance of the random number
514 514
  /// generator which name is \ref lemon::rnd "rnd". Usually it is a
515 515
  /// good programming convenience to use this global generator to get
516 516
  /// random numbers.
517 517
  class Random {
518 518
  private:
519 519

	
520 520
    // Architecture word
521 521
    typedef unsigned long Word;
522 522

	
523 523
    _random_bits::RandomCore<Word> core;
524 524
    _random_bits::BoolProducer<Word> bool_producer;
525 525

	
526 526

	
527 527
  public:
528 528

	
529 529
    ///\name Initialization
530 530
    ///
531 531
    /// @{
532 532

	
533
    ///\name Initialization
534
    ///
535
    /// @{
536

	
537 533
    /// \brief Default constructor
538 534
    ///
539 535
    /// Constructor with constant seeding.
540 536
    Random() { core.initState(); }
541 537

	
542 538
    /// \brief Constructor with seed
543 539
    ///
544 540
    /// Constructor with seed. The current number type will be converted
545 541
    /// to the architecture word type.
546 542
    template <typename Number>
547 543
    Random(Number seed) {
548 544
      _random_bits::Initializer<Number, Word>::init(core, seed);
549 545
    }
550 546

	
551 547
    /// \brief Constructor with array seeding
552 548
    ///
553 549
    /// Constructor with array seeding. The given range should contain
554 550
    /// any number type and the numbers will be converted to the
555 551
    /// architecture word type.
556 552
    template <typename Iterator>
557 553
    Random(Iterator begin, Iterator end) {
558 554
      typedef typename std::iterator_traits<Iterator>::value_type Number;
559 555
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
560 556
    }
561 557

	
562 558
    /// \brief Copy constructor
563 559
    ///
564 560
    /// Copy constructor. The generated sequence will be identical to
565 561
    /// the other sequence. It can be used to save the current state
566 562
    /// of the generator and later use it to generate the same
567 563
    /// sequence.
568 564
    Random(const Random& other) {
569 565
      core.copyState(other.core);
570 566
    }
571 567

	
572 568
    /// \brief Assign operator
573 569
    ///
574 570
    /// Assign operator. The generated sequence will be identical to
575 571
    /// the other sequence. It can be used to save the current state
576 572
    /// of the generator and later use it to generate the same
577 573
    /// sequence.
578 574
    Random& operator=(const Random& other) {
579 575
      if (&other != this) {
580 576
        core.copyState(other.core);
581 577
      }
582 578
      return *this;
583 579
    }
584 580

	
585 581
    /// \brief Seeding random sequence
586 582
    ///
587 583
    /// Seeding the random sequence. The current number type will be
588 584
    /// converted to the architecture word type.
589 585
    template <typename Number>
590 586
    void seed(Number seed) {
591 587
      _random_bits::Initializer<Number, Word>::init(core, seed);
592 588
    }
593 589

	
594 590
    /// \brief Seeding random sequence
595 591
    ///
596 592
    /// Seeding the random sequence. The given range should contain
597 593
    /// any number type and the numbers will be converted to the
598 594
    /// architecture word type.
599 595
    template <typename Iterator>
600 596
    void seed(Iterator begin, Iterator end) {
601 597
      typedef typename std::iterator_traits<Iterator>::value_type Number;
602 598
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
603 599
    }
604 600

	
605 601
    /// \brief Seeding from file or from process id and time
606 602
    ///
607 603
    /// By default, this function calls the \c seedFromFile() member
608 604
    /// function with the <tt>/dev/urandom</tt> file. If it does not success,
609 605
    /// it uses the \c seedFromTime().
610
    /// \return Currently always true.
606
    /// \return Currently always \c true.
611 607
    bool seed() {
612 608
#ifndef WIN32
613 609
      if (seedFromFile("/dev/urandom", 0)) return true;
614 610
#endif
615 611
      if (seedFromTime()) return true;
616 612
      return false;
617 613
    }
618 614

	
619 615
    /// \brief Seeding from file
620 616
    ///
621 617
    /// Seeding the random sequence from file. The linux kernel has two
622 618
    /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
623 619
    /// could give good seed values for pseudo random generators (The
624 620
    /// difference between two devices is that the <tt>random</tt> may
625 621
    /// block the reading operation while the kernel can give good
626 622
    /// source of randomness, while the <tt>urandom</tt> does not
627 623
    /// block the input, but it could give back bytes with worse
628 624
    /// entropy).
629 625
    /// \param file The source file
630 626
    /// \param offset The offset, from the file read.
631
    /// \return True when the seeding successes.
627
    /// \return \c true when the seeding successes.
632 628
#ifndef WIN32
633 629
    bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
634 630
#else
635 631
    bool seedFromFile(const std::string& file = "", int offset = 0)
636 632
#endif
637 633
    {
638 634
      std::ifstream rs(file.c_str());
639 635
      const int size = 4;
640 636
      Word buf[size];
641 637
      if (offset != 0 && !rs.seekg(offset)) return false;
642 638
      if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
643 639
      seed(buf, buf + size);
644 640
      return true;
645 641
    }
646 642

	
647 643
    /// \brief Seding from process id and time
648 644
    ///
649 645
    /// Seding from process id and time. This function uses the
650 646
    /// current process id and the current time for initialize the
651 647
    /// random sequence.
652
    /// \return Currently always true.
648
    /// \return Currently always \c true.
653 649
    bool seedFromTime() {
654 650
#ifndef WIN32
655 651
      timeval tv;
656 652
      gettimeofday(&tv, 0);
657 653
      seed(getpid() + tv.tv_sec + tv.tv_usec);
658 654
#else
659 655
      seed(bits::getWinRndSeed());
660 656
#endif
661 657
      return true;
662 658
    }
663 659

	
664 660
    /// @}
665 661

	
666
    ///\name Uniform distributions
662
    ///\name Uniform Distributions
667 663
    ///
668 664
    /// @{
669 665

	
670 666
    /// \brief Returns a random real number from the range [0, 1)
671 667
    ///
672 668
    /// It returns a random real number from the range [0, 1). The
673 669
    /// default Number type is \c double.
674 670
    template <typename Number>
675 671
    Number real() {
676 672
      return _random_bits::RealConversion<Number, Word>::convert(core);
677 673
    }
678 674

	
679 675
    double real() {
680 676
      return real<double>();
681 677
    }
682 678

	
683
    /// @}
684

	
685
    ///\name Uniform distributions
686
    ///
687
    /// @{
688

	
689 679
    /// \brief Returns a random real number from the range [0, 1)
690 680
    ///
691 681
    /// It returns a random double from the range [0, 1).
692 682
    double operator()() {
693 683
      return real<double>();
694 684
    }
695 685

	
696 686
    /// \brief Returns a random real number from the range [0, b)
697 687
    ///
698 688
    /// It returns a random real number from the range [0, b).
699 689
    double operator()(double b) {
700 690
      return real<double>() * b;
701 691
    }
702 692

	
703 693
    /// \brief Returns a random real number from the range [a, b)
704 694
    ///
705 695
    /// It returns a random real number from the range [a, b).
706 696
    double operator()(double a, double b) {
707 697
      return real<double>() * (b - a) + a;
708 698
    }
709 699

	
710 700
    /// \brief Returns a random integer from a range
711 701
    ///
712 702
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
713 703
    template <typename Number>
714 704
    Number integer(Number b) {
715 705
      return _random_bits::Mapping<Number, Word>::map(core, b);
716 706
    }
717 707

	
718 708
    /// \brief Returns a random integer from a range
719 709
    ///
720 710
    /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
721 711
    template <typename Number>
722 712
    Number integer(Number a, Number b) {
723 713
      return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
724 714
    }
725 715

	
726 716
    /// \brief Returns a random integer from a range
727 717
    ///
728 718
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
729 719
    template <typename Number>
730 720
    Number operator[](Number b) {
731 721
      return _random_bits::Mapping<Number, Word>::map(core, b);
732 722
    }
733 723

	
734 724
    /// \brief Returns a random non-negative integer
735 725
    ///
736 726
    /// It returns a random non-negative integer uniformly from the
737 727
    /// whole range of the current \c Number type. The default result
738 728
    /// type of this function is <tt>unsigned int</tt>.
739 729
    template <typename Number>
740 730
    Number uinteger() {
741 731
      return _random_bits::IntConversion<Number, Word>::convert(core);
742 732
    }
743 733

	
744
    /// @}
745

	
746 734
    unsigned int uinteger() {
747 735
      return uinteger<unsigned int>();
748 736
    }
749 737

	
750 738
    /// \brief Returns a random integer
751 739
    ///
752 740
    /// It returns a random integer uniformly from the whole range of
753 741
    /// the current \c Number type. The default result type of this
754 742
    /// function is \c int.
755 743
    template <typename Number>
756 744
    Number integer() {
757 745
      static const int nb = std::numeric_limits<Number>::digits +
758 746
        (std::numeric_limits<Number>::is_signed ? 1 : 0);
759 747
      return _random_bits::IntConversion<Number, Word, nb>::convert(core);
760 748
    }
761 749

	
762 750
    int integer() {
763 751
      return integer<int>();
764 752
    }
765 753

	
766 754
    /// \brief Returns a random bool
767 755
    ///
768 756
    /// It returns a random bool. The generator holds a buffer for
769 757
    /// random bits. Every time when it become empty the generator makes
770 758
    /// a new random word and fill the buffer up.
771 759
    bool boolean() {
772 760
      return bool_producer.convert(core);
773 761
    }
774 762

	
775 763
    /// @}
776 764

	
777
    ///\name Non-uniform distributions
765
    ///\name Non-uniform Distributions
778 766
    ///
779

	
780 767
    ///@{
781 768

	
782
    /// \brief Returns a random bool
769
    /// \brief Returns a random bool with given probability of true result.
783 770
    ///
784 771
    /// It returns a random bool with given probability of true result.
785 772
    bool boolean(double p) {
786 773
      return operator()() < p;
787 774
    }
788 775

	
789
    /// Standard Gauss distribution
776
    /// Standard normal (Gauss) distribution
790 777

	
791
    /// Standard Gauss distribution.
778
    /// Standard normal (Gauss) distribution.
792 779
    /// \note The Cartesian form of the Box-Muller
793 780
    /// transformation is used to generate a random normal distribution.
794 781
    double gauss()
795 782
    {
796 783
      double V1,V2,S;
797 784
      do {
798 785
        V1=2*real<double>()-1;
799 786
        V2=2*real<double>()-1;
800 787
        S=V1*V1+V2*V2;
801 788
      } while(S>=1);
802 789
      return std::sqrt(-2*std::log(S)/S)*V1;
803 790
    }
804
    /// Gauss distribution with given mean and standard deviation
791
    /// Normal (Gauss) distribution with given mean and standard deviation
805 792

	
806
    /// Gauss distribution with given mean and standard deviation.
793
    /// Normal (Gauss) distribution with given mean and standard deviation.
807 794
    /// \sa gauss()
808 795
    double gauss(double mean,double std_dev)
809 796
    {
810 797
      return gauss()*std_dev+mean;
811 798
    }
812 799

	
800
    /// Lognormal distribution
801

	
802
    /// Lognormal distribution. The parameters are the mean and the standard
803
    /// deviation of <tt>exp(X)</tt>.
804
    ///
805
    double lognormal(double n_mean,double n_std_dev)
806
    {
807
      return std::exp(gauss(n_mean,n_std_dev));
808
    }
809
    /// Lognormal distribution
810

	
811
    /// Lognormal distribution. The parameter is an <tt>std::pair</tt> of
812
    /// the mean and the standard deviation of <tt>exp(X)</tt>.
813
    ///
814
    double lognormal(const std::pair<double,double> &params)
815
    {
816
      return std::exp(gauss(params.first,params.second));
817
    }
818
    /// Compute the lognormal parameters from mean and standard deviation
819

	
820
    /// This function computes the lognormal parameters from mean and
821
    /// standard deviation. The return value can direcly be passed to
822
    /// lognormal().
823
    std::pair<double,double> lognormalParamsFromMD(double mean,
824
                                                   double std_dev)
825
    {
826
      double fr=std_dev/mean;
827
      fr*=fr;
828
      double lg=std::log(1+fr);
829
      return std::pair<double,double>(std::log(mean)-lg/2.0,std::sqrt(lg));
830
    }
831
    /// Lognormal distribution with given mean and standard deviation
832

	
833
    /// Lognormal distribution with given mean and standard deviation.
834
    ///
835
    double lognormalMD(double mean,double std_dev)
836
    {
837
      return lognormal(lognormalParamsFromMD(mean,std_dev));
838
    }
839

	
813 840
    /// Exponential distribution with given mean
814 841

	
815 842
    /// This function generates an exponential distribution random number
816 843
    /// with mean <tt>1/lambda</tt>.
817 844
    ///
818 845
    double exponential(double lambda=1.0)
819 846
    {
820 847
      return -std::log(1.0-real<double>())/lambda;
821 848
    }
822 849

	
823 850
    /// Gamma distribution with given integer shape
824 851

	
825 852
    /// This function generates a gamma distribution random number.
826 853
    ///
827 854
    ///\param k shape parameter (<tt>k>0</tt> integer)
828 855
    double gamma(int k)
829 856
    {
830 857
      double s = 0;
831 858
      for(int i=0;i<k;i++) s-=std::log(1.0-real<double>());
832 859
      return s;
833 860
    }
834 861

	
835 862
    /// Gamma distribution with given shape and scale parameter
836 863

	
837 864
    /// This function generates a gamma distribution random number.
838 865
    ///
839 866
    ///\param k shape parameter (<tt>k>0</tt>)
840 867
    ///\param theta scale parameter
841 868
    ///
842 869
    double gamma(double k,double theta=1.0)
843 870
    {
844 871
      double xi,nu;
845 872
      const double delta = k-std::floor(k);
846 873
      const double v0=E/(E-delta);
847 874
      do {
848 875
        double V0=1.0-real<double>();
849 876
        double V1=1.0-real<double>();
850 877
        double V2=1.0-real<double>();
851 878
        if(V2<=v0)
852 879
          {
853 880
            xi=std::pow(V1,1.0/delta);
854 881
            nu=V0*std::pow(xi,delta-1.0);
855 882
          }
856 883
        else
857 884
          {
858 885
            xi=1.0-std::log(V1);
859 886
            nu=V0*std::exp(-xi);
860 887
          }
861 888
      } while(nu>std::pow(xi,delta-1.0)*std::exp(-xi));
862 889
      return theta*(xi+gamma(int(std::floor(k))));
863 890
    }
864 891

	
865 892
    /// Weibull distribution
866 893

	
867 894
    /// This function generates a Weibull distribution random number.
868 895
    ///
869 896
    ///\param k shape parameter (<tt>k>0</tt>)
870 897
    ///\param lambda scale parameter (<tt>lambda>0</tt>)
871 898
    ///
872 899
    double weibull(double k,double lambda)
873 900
    {
874 901
      return lambda*pow(-std::log(1.0-real<double>()),1.0/k);
875 902
    }
876 903

	
877 904
    /// Pareto distribution
878 905

	
879 906
    /// This function generates a Pareto distribution random number.
880 907
    ///
881 908
    ///\param k shape parameter (<tt>k>0</tt>)
882 909
    ///\param x_min location parameter (<tt>x_min>0</tt>)
883 910
    ///
884 911
    double pareto(double k,double x_min)
885 912
    {
886 913
      return exponential(gamma(k,1.0/x_min))+x_min;
887 914
    }
888 915

	
889 916
    /// Poisson distribution
890 917

	
891 918
    /// This function generates a Poisson distribution random number with
892 919
    /// parameter \c lambda.
893 920
    ///
894 921
    /// The probability mass function of this distribusion is
895 922
    /// \f[ \frac{e^{-\lambda}\lambda^k}{k!} \f]
896 923
    /// \note The algorithm is taken from the book of Donald E. Knuth titled
897 924
    /// ''Seminumerical Algorithms'' (1969). Its running time is linear in the
898 925
    /// return value.
899 926

	
900 927
    int poisson(double lambda)
901 928
    {
902 929
      const double l = std::exp(-lambda);
903 930
      int k=0;
904 931
      double p = 1.0;
905 932
      do {
906 933
        k++;
907 934
        p*=real<double>();
908 935
      } while (p>=l);
909 936
      return k-1;
910 937
    }
911 938

	
912 939
    ///@}
913 940

	
914
    ///\name Two dimensional distributions
941
    ///\name Two Dimensional Distributions
915 942
    ///
916

	
917 943
    ///@{
918 944

	
919 945
    /// Uniform distribution on the full unit circle
920 946

	
921 947
    /// Uniform distribution on the full unit circle.
922 948
    ///
923 949
    dim2::Point<double> disc()
924 950
    {
925 951
      double V1,V2;
926 952
      do {
927 953
        V1=2*real<double>()-1;
928 954
        V2=2*real<double>()-1;
929 955

	
930 956
      } while(V1*V1+V2*V2>=1);
931 957
      return dim2::Point<double>(V1,V2);
932 958
    }
933
    /// A kind of two dimensional Gauss distribution
959
    /// A kind of two dimensional normal (Gauss) distribution
934 960

	
935 961
    /// This function provides a turning symmetric two-dimensional distribution.
936 962
    /// Both coordinates are of standard normal distribution, but they are not
937 963
    /// independent.
938 964
    ///
939 965
    /// \note The coordinates are the two random variables provided by
940 966
    /// the Box-Muller method.
941 967
    dim2::Point<double> gauss2()
942 968
    {
943 969
      double V1,V2,S;
944 970
      do {
945 971
        V1=2*real<double>()-1;
946 972
        V2=2*real<double>()-1;
947 973
        S=V1*V1+V2*V2;
948 974
      } while(S>=1);
949 975
      double W=std::sqrt(-2*std::log(S)/S);
950 976
      return dim2::Point<double>(W*V1,W*V2);
951 977
    }
952 978
    /// A kind of two dimensional exponential distribution
953 979

	
954 980
    /// This function provides a turning symmetric two-dimensional distribution.
955 981
    /// The x-coordinate is of conditionally exponential distribution
956 982
    /// with the condition that x is positive and y=0. If x is negative and
957 983
    /// y=0 then, -x is of exponential distribution. The same is true for the
958 984
    /// y-coordinate.
959 985
    dim2::Point<double> exponential2()
960 986
    {
961 987
      double V1,V2,S;
962 988
      do {
963 989
        V1=2*real<double>()-1;
964 990
        V2=2*real<double>()-1;
965 991
        S=V1*V1+V2*V2;
966 992
      } while(S>=1);
967 993
      double W=-std::log(S)/S;
968 994
      return dim2::Point<double>(W*V1,W*V2);
969 995
    }
970 996

	
971 997
    ///@}
972 998
  };
973 999

	
974 1000

	
975 1001
  extern Random rnd;
976 1002

	
977 1003
}
978 1004

	
979 1005
#endif
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_SMART_GRAPH_H
20 20
#define LEMON_SMART_GRAPH_H
21 21

	
22 22
///\ingroup graphs
23 23
///\file
24 24
///\brief SmartDigraph and SmartGraph classes.
25 25

	
26 26
#include <vector>
27 27

	
28 28
#include <lemon/core.h>
29 29
#include <lemon/error.h>
30 30
#include <lemon/bits/graph_extender.h>
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  class SmartDigraph;
35 35
  ///Base of SmartDigraph
36 36

	
37 37
  ///Base of SmartDigraph
38 38
  ///
39 39
  class SmartDigraphBase {
40 40
  protected:
41 41

	
42 42
    struct NodeT
43 43
    {
44 44
      int first_in, first_out;
45 45
      NodeT() {}
46 46
    };
47 47
    struct ArcT
48 48
    {
49 49
      int target, source, next_in, next_out;
50 50
      ArcT() {}
51 51
    };
52 52

	
53 53
    std::vector<NodeT> nodes;
54 54
    std::vector<ArcT> arcs;
55 55

	
56 56
  public:
57 57

	
58
    typedef SmartDigraphBase Graph;
58
    typedef SmartDigraphBase Digraph;
59 59

	
60 60
    class Node;
61 61
    class Arc;
62 62

	
63 63
  public:
64 64

	
65 65
    SmartDigraphBase() : nodes(), arcs() { }
66 66
    SmartDigraphBase(const SmartDigraphBase &_g)
67 67
      : nodes(_g.nodes), arcs(_g.arcs) { }
68 68

	
69 69
    typedef True NodeNumTag;
70
    typedef True EdgeNumTag;
70
    typedef True ArcNumTag;
71 71

	
72 72
    int nodeNum() const { return nodes.size(); }
73 73
    int arcNum() const { return arcs.size(); }
74 74

	
75 75
    int maxNodeId() const { return nodes.size()-1; }
76 76
    int maxArcId() const { return arcs.size()-1; }
77 77

	
78 78
    Node addNode() {
79 79
      int n = nodes.size();
80 80
      nodes.push_back(NodeT());
81 81
      nodes[n].first_in = -1;
82 82
      nodes[n].first_out = -1;
83 83
      return Node(n);
84 84
    }
85 85

	
86 86
    Arc addArc(Node u, Node v) {
87 87
      int n = arcs.size();
88 88
      arcs.push_back(ArcT());
89 89
      arcs[n].source = u._id;
90 90
      arcs[n].target = v._id;
91 91
      arcs[n].next_out = nodes[u._id].first_out;
92 92
      arcs[n].next_in = nodes[v._id].first_in;
93 93
      nodes[u._id].first_out = nodes[v._id].first_in = n;
94 94

	
95 95
      return Arc(n);
96 96
    }
97 97

	
98 98
    void clear() {
99 99
      arcs.clear();
100 100
      nodes.clear();
101 101
    }
102 102

	
103 103
    Node source(Arc a) const { return Node(arcs[a._id].source); }
104 104
    Node target(Arc a) const { return Node(arcs[a._id].target); }
105 105

	
106 106
    static int id(Node v) { return v._id; }
107 107
    static int id(Arc a) { return a._id; }
108 108

	
109 109
    static Node nodeFromId(int id) { return Node(id);}
110 110
    static Arc arcFromId(int id) { return Arc(id);}
111 111

	
112 112
    bool valid(Node n) const {
113 113
      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
114 114
    }
115 115
    bool valid(Arc a) const {
116 116
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
117 117
    }
118 118

	
119 119
    class Node {
120 120
      friend class SmartDigraphBase;
121 121
      friend class SmartDigraph;
122 122

	
123 123
    protected:
124 124
      int _id;
125 125
      explicit Node(int id) : _id(id) {}
126 126
    public:
127 127
      Node() {}
128 128
      Node (Invalid) : _id(-1) {}
129 129
      bool operator==(const Node i) const {return _id == i._id;}
130 130
      bool operator!=(const Node i) const {return _id != i._id;}
131 131
      bool operator<(const Node i) const {return _id < i._id;}
132 132
    };
133 133

	
134 134

	
135 135
    class Arc {
136 136
      friend class SmartDigraphBase;
137 137
      friend class SmartDigraph;
138 138

	
139 139
    protected:
140 140
      int _id;
141 141
      explicit Arc(int id) : _id(id) {}
142 142
    public:
143 143
      Arc() { }
144 144
      Arc (Invalid) : _id(-1) {}
145 145
      bool operator==(const Arc i) const {return _id == i._id;}
146 146
      bool operator!=(const Arc i) const {return _id != i._id;}
147 147
      bool operator<(const Arc i) const {return _id < i._id;}
148 148
    };
149 149

	
150 150
    void first(Node& node) const {
151 151
      node._id = nodes.size() - 1;
152 152
    }
153 153

	
154 154
    static void next(Node& node) {
155 155
      --node._id;
156 156
    }
157 157

	
158 158
    void first(Arc& arc) const {
159 159
      arc._id = arcs.size() - 1;
160 160
    }
161 161

	
162 162
    static void next(Arc& arc) {
163 163
      --arc._id;
164 164
    }
165 165

	
166 166
    void firstOut(Arc& arc, const Node& node) const {
167 167
      arc._id = nodes[node._id].first_out;
168 168
    }
169 169

	
170 170
    void nextOut(Arc& arc) const {
171 171
      arc._id = arcs[arc._id].next_out;
172 172
    }
173 173

	
174 174
    void firstIn(Arc& arc, const Node& node) const {
175 175
      arc._id = nodes[node._id].first_in;
176 176
    }
177 177

	
178 178
    void nextIn(Arc& arc) const {
179 179
      arc._id = arcs[arc._id].next_in;
180 180
    }
181 181

	
182 182
  };
183 183

	
184 184
  typedef DigraphExtender<SmartDigraphBase> ExtendedSmartDigraphBase;
185 185

	
186 186
  ///\ingroup graphs
187 187
  ///
188 188
  ///\brief A smart directed graph class.
189 189
  ///
190 190
  ///This is a simple and fast digraph implementation.
191 191
  ///It is also quite memory efficient, but at the price
192 192
  ///that <b> it does support only limited (only stack-like)
193 193
  ///node and arc deletions</b>.
194
  ///It conforms to the \ref concepts::Digraph "Digraph concept" with
195
  ///an important extra feature that its maps are real \ref
196
  ///concepts::ReferenceMap "reference map"s.
194
  ///It fully conforms to the \ref concepts::Digraph "Digraph concept".
197 195
  ///
198 196
  ///\sa concepts::Digraph.
199 197
  class SmartDigraph : public ExtendedSmartDigraphBase {
200
  public:
201

	
202 198
    typedef ExtendedSmartDigraphBase Parent;
203 199

	
204 200
  private:
205 201

	
206 202
    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
207 203

	
208 204
    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
209 205
    ///
210 206
    SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
211 207
    ///\brief Assignment of SmartDigraph to another one is \e not allowed.
212 208
    ///Use DigraphCopy() instead.
213 209

	
214 210
    ///Assignment of SmartDigraph to another one is \e not allowed.
215 211
    ///Use DigraphCopy() instead.
216 212
    void operator=(const SmartDigraph &) {}
217 213

	
218 214
  public:
219 215

	
220 216
    /// Constructor
221 217

	
222 218
    /// Constructor.
223 219
    ///
224 220
    SmartDigraph() {};
225 221

	
226 222
    ///Add a new node to the digraph.
227 223

	
228
    /// \return the new node.
229
    ///
224
    /// Add a new node to the digraph.
225
    /// \return The new node.
230 226
    Node addNode() { return Parent::addNode(); }
231 227

	
232 228
    ///Add a new arc to the digraph.
233 229

	
234 230
    ///Add a new arc to the digraph with source node \c s
235 231
    ///and target node \c t.
236
    ///\return the new arc.
232
    ///\return The new arc.
237 233
    Arc addArc(const Node& s, const Node& t) {
238 234
      return Parent::addArc(s, t);
239 235
    }
240 236

	
241 237
    /// \brief Using this it is possible to avoid the superfluous memory
242 238
    /// allocation.
243 239

	
244 240
    /// Using this it is possible to avoid the superfluous memory
245 241
    /// allocation: if you know that the digraph you want to build will
246 242
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
247 243
    /// then it is worth reserving space for this amount before starting
248 244
    /// to build the digraph.
249 245
    /// \sa reserveArc
250 246
    void reserveNode(int n) { nodes.reserve(n); };
251 247

	
252 248
    /// \brief Using this it is possible to avoid the superfluous memory
253 249
    /// allocation.
254 250

	
255 251
    /// Using this it is possible to avoid the superfluous memory
256 252
    /// allocation: if you know that the digraph you want to build will
257 253
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
258 254
    /// then it is worth reserving space for this amount before starting
259 255
    /// to build the digraph.
260 256
    /// \sa reserveNode
261 257
    void reserveArc(int m) { arcs.reserve(m); };
262 258

	
263 259
    /// \brief Node validity check
264 260
    ///
265 261
    /// This function gives back true if the given node is valid,
266 262
    /// ie. it is a real node of the graph.
267 263
    ///
268 264
    /// \warning A removed node (using Snapshot) could become valid again
269 265
    /// when new nodes are added to the graph.
270 266
    bool valid(Node n) const { return Parent::valid(n); }
271 267

	
272 268
    /// \brief Arc validity check
273 269
    ///
274 270
    /// This function gives back true if the given arc is valid,
275 271
    /// ie. it is a real arc of the graph.
276 272
    ///
277 273
    /// \warning A removed arc (using Snapshot) could become valid again
278 274
    /// when new arcs are added to the graph.
279 275
    bool valid(Arc a) const { return Parent::valid(a); }
280 276

	
281 277
    ///Clear the digraph.
282 278

	
283 279
    ///Erase all the nodes and arcs from the digraph.
284 280
    ///
285 281
    void clear() {
286 282
      Parent::clear();
287 283
    }
288 284

	
289 285
    ///Split a node.
290 286

	
291 287
    ///This function splits a node. First a new node is added to the digraph,
292 288
    ///then the source of each outgoing arc of \c n is moved to this new node.
293 289
    ///If \c connect is \c true (this is the default value), then a new arc
294 290
    ///from \c n to the newly created node is also added.
295 291
    ///\return The newly created node.
296 292
    ///
297 293
    ///\note The <tt>Arc</tt>s
298 294
    ///referencing a moved arc remain
299 295
    ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
300 296
    ///may be invalidated.
301 297
    ///\warning This functionality cannot be used together with the Snapshot
302 298
    ///feature.
303 299
    Node split(Node n, bool connect = true)
304 300
    {
305 301
      Node b = addNode();
306 302
      nodes[b._id].first_out=nodes[n._id].first_out;
307 303
      nodes[n._id].first_out=-1;
308
      for(int i=nodes[b._id].first_out;i!=-1;i++) arcs[i].source=b._id;
304
      for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {
305
        arcs[i].source=b._id;
306
      }
309 307
      if(connect) addArc(n,b);
310 308
      return b;
311 309
    }
312 310

	
313 311
  public:
314 312

	
315 313
    class Snapshot;
316 314

	
317 315
  protected:
318 316

	
319 317
    void restoreSnapshot(const Snapshot &s)
320 318
    {
321 319
      while(s.arc_num<arcs.size()) {
322 320
        Arc arc = arcFromId(arcs.size()-1);
323 321
        Parent::notifier(Arc()).erase(arc);
324 322
        nodes[arcs.back().source].first_out=arcs.back().next_out;
325 323
        nodes[arcs.back().target].first_in=arcs.back().next_in;
326 324
        arcs.pop_back();
327 325
      }
328 326
      while(s.node_num<nodes.size()) {
329 327
        Node node = nodeFromId(nodes.size()-1);
330 328
        Parent::notifier(Node()).erase(node);
331 329
        nodes.pop_back();
332 330
      }
333 331
    }
334 332

	
335 333
  public:
336 334

	
337 335
    ///Class to make a snapshot of the digraph and to restrore to it later.
338 336

	
339 337
    ///Class to make a snapshot of the digraph and to restrore to it later.
340 338
    ///
341 339
    ///The newly added nodes and arcs can be removed using the
342 340
    ///restore() function.
343 341
    ///\note After you restore a state, you cannot restore
344 342
    ///a later state, in other word you cannot add again the arcs deleted
345 343
    ///by restore() using another one Snapshot instance.
346 344
    ///
347 345
    ///\warning If you do not use correctly the snapshot that can cause
348 346
    ///either broken program, invalid state of the digraph, valid but
349 347
    ///not the restored digraph or no change. Because the runtime performance
350 348
    ///the validity of the snapshot is not stored.
351 349
    class Snapshot
352 350
    {
353 351
      SmartDigraph *_graph;
354 352
    protected:
355 353
      friend class SmartDigraph;
356 354
      unsigned int node_num;
357 355
      unsigned int arc_num;
358 356
    public:
359 357
      ///Default constructor.
360 358

	
361 359
      ///Default constructor.
362 360
      ///To actually make a snapshot you must call save().
363 361
      ///
364 362
      Snapshot() : _graph(0) {}
365 363
      ///Constructor that immediately makes a snapshot
366 364

	
367 365
      ///This constructor immediately makes a snapshot of the digraph.
368 366
      ///\param graph The digraph we make a snapshot of.
369 367
      Snapshot(SmartDigraph &graph) : _graph(&graph) {
370 368
        node_num=_graph->nodes.size();
371 369
        arc_num=_graph->arcs.size();
372 370
      }
373 371

	
374 372
      ///Make a snapshot.
375 373

	
376 374
      ///Make a snapshot of the digraph.
377 375
      ///
378 376
      ///This function can be called more than once. In case of a repeated
379 377
      ///call, the previous snapshot gets lost.
380 378
      ///\param graph The digraph we make the snapshot of.
381 379
      void save(SmartDigraph &graph)
382 380
      {
383 381
        _graph=&graph;
384 382
        node_num=_graph->nodes.size();
385 383
        arc_num=_graph->arcs.size();
386 384
      }
387 385

	
388 386
      ///Undo the changes until a snapshot.
389 387

	
390 388
      ///Undo the changes until a snapshot created by save().
391 389
      ///
392 390
      ///\note After you restored a state, you cannot restore
393 391
      ///a later state, in other word you cannot add again the arcs deleted
394 392
      ///by restore().
395 393
      void restore()
396 394
      {
397 395
        _graph->restoreSnapshot(*this);
398 396
      }
399 397
    };
400 398
  };
401 399

	
402 400

	
403 401
  class SmartGraphBase {
404 402

	
405 403
  protected:
406 404

	
407 405
    struct NodeT {
408 406
      int first_out;
409 407
    };
410 408

	
411 409
    struct ArcT {
412 410
      int target;
413 411
      int next_out;
414 412
    };
415 413

	
416 414
    std::vector<NodeT> nodes;
417 415
    std::vector<ArcT> arcs;
418 416

	
419 417
    int first_free_arc;
420 418

	
421 419
  public:
422 420

	
423
    typedef SmartGraphBase Digraph;
421
    typedef SmartGraphBase Graph;
424 422

	
425 423
    class Node;
426 424
    class Arc;
427 425
    class Edge;
428 426

	
429 427
    class Node {
430 428
      friend class SmartGraphBase;
431 429
    protected:
432 430

	
433 431
      int _id;
434 432
      explicit Node(int id) { _id = id;}
435 433

	
436 434
    public:
437 435
      Node() {}
438 436
      Node (Invalid) { _id = -1; }
439 437
      bool operator==(const Node& node) const {return _id == node._id;}
440 438
      bool operator!=(const Node& node) const {return _id != node._id;}
441 439
      bool operator<(const Node& node) const {return _id < node._id;}
442 440
    };
443 441

	
444 442
    class Edge {
445 443
      friend class SmartGraphBase;
446 444
    protected:
447 445

	
448 446
      int _id;
449 447
      explicit Edge(int id) { _id = id;}
450 448

	
451 449
    public:
452 450
      Edge() {}
453 451
      Edge (Invalid) { _id = -1; }
454 452
      bool operator==(const Edge& arc) const {return _id == arc._id;}
455 453
      bool operator!=(const Edge& arc) const {return _id != arc._id;}
456 454
      bool operator<(const Edge& arc) const {return _id < arc._id;}
457 455
    };
458 456

	
459 457
    class Arc {
460 458
      friend class SmartGraphBase;
461 459
    protected:
462 460

	
463 461
      int _id;
464 462
      explicit Arc(int id) { _id = id;}
465 463

	
466 464
    public:
467
      operator Edge() const { 
468
        return _id != -1 ? edgeFromId(_id / 2) : INVALID; 
465
      operator Edge() const {
466
        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
469 467
      }
470 468

	
471 469
      Arc() {}
472 470
      Arc (Invalid) { _id = -1; }
473 471
      bool operator==(const Arc& arc) const {return _id == arc._id;}
474 472
      bool operator!=(const Arc& arc) const {return _id != arc._id;}
475 473
      bool operator<(const Arc& arc) const {return _id < arc._id;}
476 474
    };
477 475

	
478 476

	
479 477

	
480 478
    SmartGraphBase()
481 479
      : nodes(), arcs() {}
482 480

	
481
    typedef True NodeNumTag;
482
    typedef True EdgeNumTag;
483
    typedef True ArcNumTag;
484

	
485
    int nodeNum() const { return nodes.size(); }
486
    int edgeNum() const { return arcs.size() / 2; }
487
    int arcNum() const { return arcs.size(); }
483 488

	
484 489
    int maxNodeId() const { return nodes.size()-1; }
485 490
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
486 491
    int maxArcId() const { return arcs.size()-1; }
487 492

	
488 493
    Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
489 494
    Node target(Arc e) const { return Node(arcs[e._id].target); }
490 495

	
491 496
    Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
492 497
    Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
493 498

	
494 499
    static bool direction(Arc e) {
495 500
      return (e._id & 1) == 1;
496 501
    }
497 502

	
498 503
    static Arc direct(Edge e, bool d) {
499 504
      return Arc(e._id * 2 + (d ? 1 : 0));
500 505
    }
501 506

	
502 507
    void first(Node& node) const {
503 508
      node._id = nodes.size() - 1;
504 509
    }
505 510

	
506 511
    void next(Node& node) const {
507 512
      --node._id;
508 513
    }
509 514

	
510 515
    void first(Arc& arc) const {
511 516
      arc._id = arcs.size() - 1;
512 517
    }
513 518

	
514 519
    void next(Arc& arc) const {
515 520
      --arc._id;
516 521
    }
517 522

	
518 523
    void first(Edge& arc) const {
519 524
      arc._id = arcs.size() / 2 - 1;
520 525
    }
521 526

	
522 527
    void next(Edge& arc) const {
523 528
      --arc._id;
524 529
    }
525 530

	
526 531
    void firstOut(Arc &arc, const Node& v) const {
527 532
      arc._id = nodes[v._id].first_out;
528 533
    }
529 534
    void nextOut(Arc &arc) const {
530 535
      arc._id = arcs[arc._id].next_out;
531 536
    }
532 537

	
533 538
    void firstIn(Arc &arc, const Node& v) const {
534 539
      arc._id = ((nodes[v._id].first_out) ^ 1);
535 540
      if (arc._id == -2) arc._id = -1;
536 541
    }
537 542
    void nextIn(Arc &arc) const {
538 543
      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
539 544
      if (arc._id == -2) arc._id = -1;
540 545
    }
541 546

	
542 547
    void firstInc(Edge &arc, bool& d, const Node& v) const {
543 548
      int de = nodes[v._id].first_out;
544 549
      if (de != -1) {
545 550
        arc._id = de / 2;
546 551
        d = ((de & 1) == 1);
547 552
      } else {
548 553
        arc._id = -1;
549 554
        d = true;
550 555
      }
551 556
    }
552 557
    void nextInc(Edge &arc, bool& d) const {
553 558
      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
554 559
      if (de != -1) {
555 560
        arc._id = de / 2;
556 561
        d = ((de & 1) == 1);
557 562
      } else {
558 563
        arc._id = -1;
559 564
        d = true;
560 565
      }
561 566
    }
562 567

	
563 568
    static int id(Node v) { return v._id; }
564 569
    static int id(Arc e) { return e._id; }
565 570
    static int id(Edge e) { return e._id; }
566 571

	
567 572
    static Node nodeFromId(int id) { return Node(id);}
568 573
    static Arc arcFromId(int id) { return Arc(id);}
569 574
    static Edge edgeFromId(int id) { return Edge(id);}
570 575

	
571 576
    bool valid(Node n) const {
572 577
      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
573 578
    }
574 579
    bool valid(Arc a) const {
575 580
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
576 581
    }
577 582
    bool valid(Edge e) const {
578 583
      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
579 584
    }
580 585

	
581 586
    Node addNode() {
582 587
      int n = nodes.size();
583 588
      nodes.push_back(NodeT());
584 589
      nodes[n].first_out = -1;
585 590

	
586 591
      return Node(n);
587 592
    }
588 593

	
589 594
    Edge addEdge(Node u, Node v) {
590 595
      int n = arcs.size();
591 596
      arcs.push_back(ArcT());
592 597
      arcs.push_back(ArcT());
593 598

	
594 599
      arcs[n].target = u._id;
595 600
      arcs[n | 1].target = v._id;
596 601

	
597 602
      arcs[n].next_out = nodes[v._id].first_out;
598 603
      nodes[v._id].first_out = n;
599 604

	
600 605
      arcs[n | 1].next_out = nodes[u._id].first_out;
601 606
      nodes[u._id].first_out = (n | 1);
602 607

	
603 608
      return Edge(n / 2);
604 609
    }
605 610

	
606 611
    void clear() {
607 612
      arcs.clear();
608 613
      nodes.clear();
609 614
    }
610 615

	
611 616
  };
612 617

	
613 618
  typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
614 619

	
615 620
  /// \ingroup graphs
616 621
  ///
617 622
  /// \brief A smart undirected graph class.
618 623
  ///
619 624
  /// This is a simple and fast graph implementation.
620 625
  /// It is also quite memory efficient, but at the price
621 626
  /// that <b> it does support only limited (only stack-like)
622 627
  /// node and arc deletions</b>.
623
  /// Except from this it conforms to
624
  /// the \ref concepts::Graph "Graph concept".
625
  ///
626
  /// It also has an
627
  /// important extra feature that
628
  /// its maps are real \ref concepts::ReferenceMap "reference map"s.
628
  /// It fully conforms to the \ref concepts::Graph "Graph concept".
629 629
  ///
630 630
  /// \sa concepts::Graph.
631
  ///
632 631
  class SmartGraph : public ExtendedSmartGraphBase {
632
    typedef ExtendedSmartGraphBase Parent;
633

	
633 634
  private:
634 635

	
635 636
    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
636 637

	
637 638
    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
638 639
    ///
639 640
    SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
640 641

	
641 642
    ///\brief Assignment of SmartGraph to another one is \e not allowed.
642 643
    ///Use GraphCopy() instead.
643 644

	
644 645
    ///Assignment of SmartGraph to another one is \e not allowed.
645 646
    ///Use GraphCopy() instead.
646 647
    void operator=(const SmartGraph &) {}
647 648

	
648 649
  public:
649 650

	
650
    typedef ExtendedSmartGraphBase Parent;
651

	
652 651
    /// Constructor
653 652

	
654 653
    /// Constructor.
655 654
    ///
656 655
    SmartGraph() {}
657 656

	
658 657
    ///Add a new node to the graph.
659 658

	
660
    /// \return the new node.
661
    ///
659
    /// Add a new node to the graph.
660
    /// \return The new node.
662 661
    Node addNode() { return Parent::addNode(); }
663 662

	
664 663
    ///Add a new edge to the graph.
665 664

	
666 665
    ///Add a new edge to the graph with node \c s
667 666
    ///and \c t.
668
    ///\return the new edge.
667
    ///\return The new edge.
669 668
    Edge addEdge(const Node& s, const Node& t) {
670 669
      return Parent::addEdge(s, t);
671 670
    }
672 671

	
673 672
    /// \brief Node validity check
674 673
    ///
675 674
    /// This function gives back true if the given node is valid,
676 675
    /// ie. it is a real node of the graph.
677 676
    ///
678 677
    /// \warning A removed node (using Snapshot) could become valid again
679 678
    /// when new nodes are added to the graph.
680 679
    bool valid(Node n) const { return Parent::valid(n); }
681 680

	
682 681
    /// \brief Arc validity check
683 682
    ///
684 683
    /// This function gives back true if the given arc is valid,
685 684
    /// ie. it is a real arc of the graph.
686 685
    ///
687 686
    /// \warning A removed arc (using Snapshot) could become valid again
688 687
    /// when new edges are added to the graph.
689 688
    bool valid(Arc a) const { return Parent::valid(a); }
690 689

	
691 690
    /// \brief Edge validity check
692 691
    ///
693 692
    /// This function gives back true if the given edge is valid,
694 693
    /// ie. it is a real edge of the graph.
695 694
    ///
696 695
    /// \warning A removed edge (using Snapshot) could become valid again
697 696
    /// when new edges are added to the graph.
698 697
    bool valid(Edge e) const { return Parent::valid(e); }
699 698

	
700 699
    ///Clear the graph.
701 700

	
702 701
    ///Erase all the nodes and edges from the graph.
703 702
    ///
704 703
    void clear() {
705 704
      Parent::clear();
706 705
    }
707 706

	
708 707
  public:
709 708

	
710 709
    class Snapshot;
711 710

	
712 711
  protected:
713 712

	
714 713
    void saveSnapshot(Snapshot &s)
715 714
    {
716 715
      s._graph = this;
717 716
      s.node_num = nodes.size();
718 717
      s.arc_num = arcs.size();
719 718
    }
720 719

	
721 720
    void restoreSnapshot(const Snapshot &s)
722 721
    {
723 722
      while(s.arc_num<arcs.size()) {
724 723
        int n=arcs.size()-1;
725 724
        Edge arc=edgeFromId(n/2);
726 725
        Parent::notifier(Edge()).erase(arc);
727 726
        std::vector<Arc> dir;
728 727
        dir.push_back(arcFromId(n));
729 728
        dir.push_back(arcFromId(n-1));
730 729
        Parent::notifier(Arc()).erase(dir);
731
        nodes[arcs[n].target].first_out=arcs[n].next_out;
732
        nodes[arcs[n-1].target].first_out=arcs[n-1].next_out;
730
        nodes[arcs[n-1].target].first_out=arcs[n].next_out;
731
        nodes[arcs[n].target].first_out=arcs[n-1].next_out;
733 732
        arcs.pop_back();
734 733
        arcs.pop_back();
735 734
      }
736 735
      while(s.node_num<nodes.size()) {
737 736
        int n=nodes.size()-1;
738 737
        Node node = nodeFromId(n);
739 738
        Parent::notifier(Node()).erase(node);
740 739
        nodes.pop_back();
741 740
      }
742 741
    }
743 742

	
744 743
  public:
745 744

	
746 745
    ///Class to make a snapshot of the digraph and to restrore to it later.
747 746

	
748 747
    ///Class to make a snapshot of the digraph and to restrore to it later.
749 748
    ///
750 749
    ///The newly added nodes and arcs can be removed using the
751 750
    ///restore() function.
752 751
    ///
753 752
    ///\note After you restore a state, you cannot restore
754 753
    ///a later state, in other word you cannot add again the arcs deleted
755 754
    ///by restore() using another one Snapshot instance.
756 755
    ///
757 756
    ///\warning If you do not use correctly the snapshot that can cause
758 757
    ///either broken program, invalid state of the digraph, valid but
759 758
    ///not the restored digraph or no change. Because the runtime performance
760 759
    ///the validity of the snapshot is not stored.
761 760
    class Snapshot
762 761
    {
763 762
      SmartGraph *_graph;
764 763
    protected:
765 764
      friend class SmartGraph;
766 765
      unsigned int node_num;
767 766
      unsigned int arc_num;
768 767
    public:
769 768
      ///Default constructor.
770 769

	
771 770
      ///Default constructor.
772 771
      ///To actually make a snapshot you must call save().
773 772
      ///
774 773
      Snapshot() : _graph(0) {}
775 774
      ///Constructor that immediately makes a snapshot
776 775

	
777 776
      ///This constructor immediately makes a snapshot of the digraph.
778 777
      ///\param graph The digraph we make a snapshot of.
779 778
      Snapshot(SmartGraph &graph) {
780 779
        graph.saveSnapshot(*this);
781 780
      }
782 781

	
783 782
      ///Make a snapshot.
784 783

	
785 784
      ///Make a snapshot of the graph.
786 785
      ///
787 786
      ///This function can be called more than once. In case of a repeated
788 787
      ///call, the previous snapshot gets lost.
789 788
      ///\param graph The digraph we make the snapshot of.
790 789
      void save(SmartGraph &graph)
791 790
      {
792 791
        graph.saveSnapshot(*this);
793 792
      }
794 793

	
795 794
      ///Undo the changes until a snapshot.
796 795

	
797 796
      ///Undo the changes until a snapshot created by save().
798 797
      ///
799 798
      ///\note After you restored a state, you cannot restore
800 799
      ///a later state, in other word you cannot add again the arcs deleted
801 800
      ///by restore().
802 801
      void restore()
803 802
      {
804 803
        _graph->restoreSnapshot(*this);
805 804
      }
806 805
    };
807 806
  };
808 807

	
809 808
} //namespace lemon
810 809

	
811 810

	
812 811
#endif //LEMON_SMART_GRAPH_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_TIME_MEASURE_H
20 20
#define LEMON_TIME_MEASURE_H
21 21

	
22 22
///\ingroup timecount
23 23
///\file
24 24
///\brief Tools for measuring cpu usage
25 25

	
26 26
#ifdef WIN32
27 27
#include <lemon/bits/windows.h>
28 28
#else
29 29
#include <unistd.h>
30 30
#include <sys/times.h>
31 31
#include <sys/time.h>
32 32
#endif
33 33

	
34 34
#include <string>
35 35
#include <fstream>
36 36
#include <iostream>
37 37

	
38 38
namespace lemon {
39 39

	
40 40
  /// \addtogroup timecount
41 41
  /// @{
42 42

	
43 43
  /// A class to store (cpu)time instances.
44 44

	
45 45
  /// This class stores five time values.
46 46
  /// - a real time
47 47
  /// - a user cpu time
48 48
  /// - a system cpu time
49 49
  /// - a user cpu time of children
50 50
  /// - a system cpu time of children
51 51
  ///
52 52
  /// TimeStamp's can be added to or substracted from each other and
53 53
  /// they can be pushed to a stream.
54 54
  ///
55 55
  /// In most cases, perhaps the \ref Timer or the \ref TimeReport
56 56
  /// class is what you want to use instead.
57 57

	
58 58
  class TimeStamp
59 59
  {
60 60
    double utime;
61 61
    double stime;
62 62
    double cutime;
63 63
    double cstime;
64 64
    double rtime;
65 65

	
66 66
    void _reset() {
67 67
      utime = stime = cutime = cstime = rtime = 0;
68 68
    }
69 69

	
70 70
  public:
71 71

	
72 72
    ///Read the current time values of the process
73 73
    void stamp()
74 74
    {
75 75
#ifndef WIN32
76 76
      timeval tv;
77 77
      gettimeofday(&tv, 0);
78 78
      rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
79 79

	
80 80
      tms ts;
81 81
      double tck=sysconf(_SC_CLK_TCK);
82 82
      times(&ts);
83 83
      utime=ts.tms_utime/tck;
84 84
      stime=ts.tms_stime/tck;
85 85
      cutime=ts.tms_cutime/tck;
86 86
      cstime=ts.tms_cstime/tck;
87 87
#else
88 88
      bits::getWinProcTimes(rtime, utime, stime, cutime, cstime);
89 89
#endif
90 90
    }
91 91

	
92 92
    /// Constructor initializing with zero
93 93
    TimeStamp()
94 94
    { _reset(); }
95 95
    ///Constructor initializing with the current time values of the process
96 96
    TimeStamp(void *) { stamp();}
97 97

	
98 98
    ///Set every time value to zero
99 99
    TimeStamp &reset() {_reset();return *this;}
100 100

	
101 101
    ///\e
102 102
    TimeStamp &operator+=(const TimeStamp &b)
103 103
    {
104 104
      utime+=b.utime;
105 105
      stime+=b.stime;
106 106
      cutime+=b.cutime;
107 107
      cstime+=b.cstime;
108 108
      rtime+=b.rtime;
109 109
      return *this;
110 110
    }
111 111
    ///\e
112 112
    TimeStamp operator+(const TimeStamp &b) const
113 113
    {
114 114
      TimeStamp t(*this);
115 115
      return t+=b;
116 116
    }
117 117
    ///\e
118 118
    TimeStamp &operator-=(const TimeStamp &b)
119 119
    {
120 120
      utime-=b.utime;
121 121
      stime-=b.stime;
122 122
      cutime-=b.cutime;
123 123
      cstime-=b.cstime;
124 124
      rtime-=b.rtime;
125 125
      return *this;
126 126
    }
127 127
    ///\e
128 128
    TimeStamp operator-(const TimeStamp &b) const
129 129
    {
130 130
      TimeStamp t(*this);
131 131
      return t-=b;
132 132
    }
133 133
    ///\e
134 134
    TimeStamp &operator*=(double b)
135 135
    {
136 136
      utime*=b;
137 137
      stime*=b;
138 138
      cutime*=b;
139 139
      cstime*=b;
140 140
      rtime*=b;
141 141
      return *this;
142 142
    }
143 143
    ///\e
144 144
    TimeStamp operator*(double b) const
145 145
    {
146 146
      TimeStamp t(*this);
147 147
      return t*=b;
148 148
    }
149 149
    friend TimeStamp operator*(double b,const TimeStamp &t);
150 150
    ///\e
151 151
    TimeStamp &operator/=(double b)
152 152
    {
153 153
      utime/=b;
154 154
      stime/=b;
155 155
      cutime/=b;
156 156
      cstime/=b;
157 157
      rtime/=b;
158 158
      return *this;
159 159
    }
160 160
    ///\e
161 161
    TimeStamp operator/(double b) const
162 162
    {
163 163
      TimeStamp t(*this);
164 164
      return t/=b;
165 165
    }
166 166
    ///The time ellapsed since the last call of stamp()
167 167
    TimeStamp ellapsed() const
168 168
    {
169 169
      TimeStamp t(NULL);
170 170
      return t-*this;
171 171
    }
172 172

	
173 173
    friend std::ostream& operator<<(std::ostream& os,const TimeStamp &t);
174 174

	
175 175
    ///Gives back the user time of the process
176 176
    double userTime() const
177 177
    {
178 178
      return utime;
179 179
    }
180 180
    ///Gives back the system time of the process
181 181
    double systemTime() const
182 182
    {
183 183
      return stime;
184 184
    }
185 185
    ///Gives back the user time of the process' children
186 186

	
187 187
    ///\note On <tt>WIN32</tt> platform this value is not calculated.
188 188
    ///
189 189
    double cUserTime() const
190 190
    {
191 191
      return cutime;
192 192
    }
193 193
    ///Gives back the user time of the process' children
194 194

	
195 195
    ///\note On <tt>WIN32</tt> platform this value is not calculated.
196 196
    ///
197 197
    double cSystemTime() const
198 198
    {
199 199
      return cstime;
200 200
    }
201 201
    ///Gives back the real time
202 202
    double realTime() const {return rtime;}
203 203
  };
204 204

	
205 205
  inline TimeStamp operator*(double b,const TimeStamp &t)
206 206
  {
207 207
    return t*b;
208 208
  }
209 209

	
210 210
  ///Prints the time counters
211 211

	
212 212
  ///Prints the time counters in the following form:
213 213
  ///
214 214
  /// <tt>u: XX.XXs s: XX.XXs cu: XX.XXs cs: XX.XXs real: XX.XXs</tt>
215 215
  ///
216 216
  /// where the values are the
217 217
  /// \li \c u: user cpu time,
218 218
  /// \li \c s: system cpu time,
219 219
  /// \li \c cu: user cpu time of children,
220 220
  /// \li \c cs: system cpu time of children,
221 221
  /// \li \c real: real time.
222 222
  /// \relates TimeStamp
223 223
  /// \note On <tt>WIN32</tt> platform the cummulative values are not
224 224
  /// calculated.
225 225
  inline std::ostream& operator<<(std::ostream& os,const TimeStamp &t)
226 226
  {
227 227
    os << "u: " << t.userTime() <<
228 228
      "s, s: " << t.systemTime() <<
229 229
      "s, cu: " << t.cUserTime() <<
230 230
      "s, cs: " << t.cSystemTime() <<
231 231
      "s, real: " << t.realTime() << "s";
232 232
    return os;
233 233
  }
234 234

	
235 235
  ///Class for measuring the cpu time and real time usage of the process
236 236

	
237 237
  ///Class for measuring the cpu time and real time usage of the process.
238 238
  ///It is quite easy-to-use, here is a short example.
239 239
  ///\code
240 240
  /// #include<lemon/time_measure.h>
241 241
  /// #include<iostream>
242 242
  ///
243 243
  /// int main()
244 244
  /// {
245 245
  ///
246 246
  ///   ...
247 247
  ///
248 248
  ///   Timer t;
249 249
  ///   doSomething();
250 250
  ///   std::cout << t << '\n';
251 251
  ///   t.restart();
252 252
  ///   doSomethingElse();
253 253
  ///   std::cout << t << '\n';
254 254
  ///
255 255
  ///   ...
256 256
  ///
257 257
  /// }
258 258
  ///\endcode
259 259
  ///
260 260
  ///The \ref Timer can also be \ref stop() "stopped" and
261 261
  ///\ref start() "started" again, so it is possible to compute collected
262 262
  ///running times.
263 263
  ///
264 264
  ///\warning Depending on the operation system and its actual configuration
265 265
  ///the time counters have a certain (10ms on a typical Linux system)
266 266
  ///granularity.
267 267
  ///Therefore this tool is not appropriate to measure very short times.
268 268
  ///Also, if you start and stop the timer very frequently, it could lead to
269 269
  ///distorted results.
270 270
  ///
271 271
  ///\note If you want to measure the running time of the execution of a certain
272 272
  ///function, consider the usage of \ref TimeReport instead.
273 273
  ///
274 274
  ///\sa TimeReport
275 275
  class Timer
276 276
  {
277 277
    int _running; //Timer is running iff _running>0; (_running>=0 always holds)
278 278
    TimeStamp start_time; //This is the relativ start-time if the timer
279 279
                          //is _running, the collected _running time otherwise.
280 280

	
281 281
    void _reset() {if(_running) start_time.stamp(); else start_time.reset();}
282 282

	
283 283
  public:
284 284
    ///Constructor.
285 285

	
286 286
    ///\param run indicates whether or not the timer starts immediately.
287 287
    ///
288 288
    Timer(bool run=true) :_running(run) {_reset();}
289 289

	
290
    ///\name Control the state of the timer
290
    ///\name Control the State of the Timer
291 291
    ///Basically a Timer can be either running or stopped,
292 292
    ///but it provides a bit finer control on the execution.
293 293
    ///The \ref lemon::Timer "Timer" also counts the number of
294 294
    ///\ref lemon::Timer::start() "start()" executions, and it stops
295 295
    ///only after the same amount (or more) \ref lemon::Timer::stop()
296 296
    ///"stop()"s. This can be useful e.g. to compute the running time
297 297
    ///of recursive functions.
298 298

	
299 299
    ///@{
300 300

	
301 301
    ///Reset and stop the time counters
302 302

	
303 303
    ///This function resets and stops the time counters
304 304
    ///\sa restart()
305 305
    void reset()
306 306
    {
307 307
      _running=0;
308 308
      _reset();
309 309
    }
310 310

	
311 311
    ///Start the time counters
312 312

	
313 313
    ///This function starts the time counters.
314 314
    ///
315 315
    ///If the timer is started more than ones, it will remain running
316 316
    ///until the same amount of \ref stop() is called.
317 317
    ///\sa stop()
318 318
    void start()
319 319
    {
320 320
      if(_running) _running++;
321 321
      else {
322 322
        _running=1;
323 323
        TimeStamp t;
324 324
        t.stamp();
325 325
        start_time=t-start_time;
326 326
      }
327 327
    }
328 328

	
329 329

	
330 330
    ///Stop the time counters
331 331

	
332 332
    ///This function stops the time counters. If start() was executed more than
333 333
    ///once, then the same number of stop() execution is necessary the really
334 334
    ///stop the timer.
335 335
    ///
336 336
    ///\sa halt()
337 337
    ///\sa start()
338 338
    ///\sa restart()
339 339
    ///\sa reset()
340 340

	
341 341
    void stop()
342 342
    {
343 343
      if(_running && !--_running) {
344 344
        TimeStamp t;
345 345
        t.stamp();
346 346
        start_time=t-start_time;
347 347
      }
348 348
    }
349 349

	
350 350
    ///Halt (i.e stop immediately) the time counters
351 351

	
352 352
    ///This function stops immediately the time counters, i.e. <tt>t.halt()</tt>
353 353
    ///is a faster
354 354
    ///equivalent of the following.
355 355
    ///\code
356 356
    ///  while(t.running()) t.stop()
357 357
    ///\endcode
358 358
    ///
359 359
    ///
360 360
    ///\sa stop()
361 361
    ///\sa restart()
362 362
    ///\sa reset()
363 363

	
364 364
    void halt()
365 365
    {
366 366
      if(_running) {
367 367
        _running=0;
368 368
        TimeStamp t;
369 369
        t.stamp();
370 370
        start_time=t-start_time;
371 371
      }
372 372
    }
373 373

	
374 374
    ///Returns the running state of the timer
375 375

	
376 376
    ///This function returns the number of stop() exections that is
377 377
    ///necessary to really stop the timer.
378 378
    ///For example the timer
379 379
    ///is running if and only if the return value is \c true
380 380
    ///(i.e. greater than
381 381
    ///zero).
382 382
    int running()  { return _running; }
383 383

	
384 384

	
385 385
    ///Restart the time counters
386 386

	
387 387
    ///This function is a shorthand for
388 388
    ///a reset() and a start() calls.
389 389
    ///
390 390
    void restart()
391 391
    {
392 392
      reset();
393 393
      start();
394 394
    }
395 395

	
396 396
    ///@}
397 397

	
398
    ///\name Query Functions for the ellapsed time
398
    ///\name Query Functions for the Ellapsed Time
399 399

	
400 400
    ///@{
401 401

	
402 402
    ///Gives back the ellapsed user time of the process
403 403
    double userTime() const
404 404
    {
405 405
      return operator TimeStamp().userTime();
406 406
    }
407 407
    ///Gives back the ellapsed system time of the process
408 408
    double systemTime() const
409 409
    {
410 410
      return operator TimeStamp().systemTime();
411 411
    }
412 412
    ///Gives back the ellapsed user time of the process' children
413 413

	
414 414
    ///\note On <tt>WIN32</tt> platform this value is not calculated.
415 415
    ///
416 416
    double cUserTime() const
417 417
    {
418 418
      return operator TimeStamp().cUserTime();
419 419
    }
420 420
    ///Gives back the ellapsed user time of the process' children
421 421

	
422 422
    ///\note On <tt>WIN32</tt> platform this value is not calculated.
423 423
    ///
424 424
    double cSystemTime() const
425 425
    {
426 426
      return operator TimeStamp().cSystemTime();
427 427
    }
428 428
    ///Gives back the ellapsed real time
429 429
    double realTime() const
430 430
    {
431 431
      return operator TimeStamp().realTime();
432 432
    }
433 433
    ///Computes the ellapsed time
434 434

	
435 435
    ///This conversion computes the ellapsed time, therefore you can print
436 436
    ///the ellapsed time like this.
437 437
    ///\code
438 438
    ///  Timer t;
439 439
    ///  doSomething();
440 440
    ///  std::cout << t << '\n';
441 441
    ///\endcode
442 442
    operator TimeStamp () const
443 443
    {
444 444
      TimeStamp t;
445 445
      t.stamp();
446 446
      return _running?t-start_time:start_time;
447 447
    }
448 448

	
449 449

	
450 450
    ///@}
451 451
  };
452 452

	
453 453
  ///Same as Timer but prints a report on destruction.
454 454

	
455 455
  ///Same as \ref Timer but prints a report on destruction.
456 456
  ///This example shows its usage.
457 457
  ///\code
458 458
  ///  void myAlg(ListGraph &g,int n)
459 459
  ///  {
460 460
  ///    TimeReport tr("Running time of myAlg: ");
461 461
  ///    ... //Here comes the algorithm
462 462
  ///  }
463 463
  ///\endcode
464 464
  ///
465 465
  ///\sa Timer
466 466
  ///\sa NoTimeReport
467 467
  class TimeReport : public Timer
468 468
  {
469 469
    std::string _title;
470 470
    std::ostream &_os;
471 471
  public:
472 472
    ///Constructor
473 473

	
474 474
    ///Constructor.
475 475
    ///\param title This text will be printed before the ellapsed time.
476 476
    ///\param os The stream to print the report to.
477 477
    ///\param run Sets whether the timer should start immediately.
478 478
    TimeReport(std::string title,std::ostream &os=std::cerr,bool run=true)
479 479
      : Timer(run), _title(title), _os(os){}
480 480
    ///Destructor that prints the ellapsed time
481 481
    ~TimeReport()
482 482
    {
483 483
      _os << _title << *this << std::endl;
484 484
    }
485 485
  };
486 486

	
487 487
  ///'Do nothing' version of TimeReport
488 488

	
489 489
  ///\sa TimeReport
490 490
  ///
491 491
  class NoTimeReport
492 492
  {
493 493
  public:
494 494
    ///\e
495 495
    NoTimeReport(std::string,std::ostream &,bool) {}
496 496
    ///\e
497 497
    NoTimeReport(std::string,std::ostream &) {}
498 498
    ///\e
499 499
    NoTimeReport(std::string) {}
500 500
    ///\e Do nothing.
501 501
    ~NoTimeReport() {}
502 502

	
503 503
    operator TimeStamp () const { return TimeStamp(); }
504 504
    void reset() {}
505 505
    void start() {}
506 506
    void stop() {}
507 507
    void halt() {}
508 508
    int running() { return 0; }
509 509
    void restart() {}
510 510
    double userTime() const { return 0; }
511 511
    double systemTime() const { return 0; }
512 512
    double cUserTime() const { return 0; }
513 513
    double cSystemTime() const { return 0; }
514 514
    double realTime() const { return 0; }
515 515
  };
516 516

	
517 517
  ///Tool to measure the running time more exactly.
518 518

	
519 519
  ///This function calls \c f several times and returns the average
520 520
  ///running time. The number of the executions will be choosen in such a way
521 521
  ///that the full real running time will be roughly between \c min_time
522 522
  ///and <tt>2*min_time</tt>.
523 523
  ///\param f the function object to be measured.
524 524
  ///\param min_time the minimum total running time.
525 525
  ///\retval num if it is not \c NULL, then the actual
526 526
  ///        number of execution of \c f will be written into <tt>*num</tt>.
527 527
  ///\retval full_time if it is not \c NULL, then the actual
528 528
  ///        total running time will be written into <tt>*full_time</tt>.
529 529
  ///\return The average running time of \c f.
530 530

	
531 531
  template<class F>
532 532
  TimeStamp runningTimeTest(F f,double min_time=10,unsigned int *num = NULL,
533 533
                            TimeStamp *full_time=NULL)
534 534
  {
535 535
    TimeStamp full;
536 536
    unsigned int total=0;
537 537
    Timer t;
538 538
    for(unsigned int tn=1;tn <= 1U<<31 && full.realTime()<=min_time; tn*=2) {
539 539
      for(;total<tn;total++) f();
540 540
      full=t;
541 541
    }
542 542
    if(num) *num=total;
543 543
    if(full_time) *full_time=full;
544 544
    return full/total;
545 545
  }
546 546

	
547 547
  /// @}
548 548

	
549 549

	
550 550
} //namespace lemon
551 551

	
552 552
#endif //LEMON_TIME_MEASURE_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_TOLERANCE_H
20 20
#define LEMON_TOLERANCE_H
21 21

	
22 22
///\ingroup misc
23 23
///\file
24 24
///\brief A basic tool to handle the anomalies of calculation with
25 25
///floating point numbers.
26 26
///
27 27

	
28 28
namespace lemon {
29 29

	
30 30
  /// \addtogroup misc
31 31
  /// @{
32 32

	
33 33
  ///\brief A class to provide a basic way to
34 34
  ///handle the comparison of numbers that are obtained
35 35
  ///as a result of a probably inexact computation.
36 36
  ///
37 37
  ///\ref Tolerance is a class to provide a basic way to
38 38
  ///handle the comparison of numbers that are obtained
39 39
  ///as a result of a probably inexact computation.
40 40
  ///
41 41
  ///The general implementation is suitable only if the data type is exact,
42 42
  ///like the integer types, otherwise a specialized version must be
43 43
  ///implemented. These specialized classes like
44 44
  ///Tolerance<double> may offer additional tuning parameters.
45 45
  ///
46 46
  ///\sa Tolerance<float>
47 47
  ///\sa Tolerance<double>
48 48
  ///\sa Tolerance<long double>
49 49

	
50 50
  template<class T>
51 51
  class Tolerance
52 52
  {
53 53
  public:
54 54
    typedef T Value;
55 55

	
56 56
    ///\name Comparisons
57 57
    ///The concept is that these bool functions return \c true only if
58 58
    ///the related comparisons hold even if some numerical error appeared
59 59
    ///during the computations.
60 60

	
61 61
    ///@{
62 62

	
63 63
    ///Returns \c true if \c a is \e surely strictly less than \c b
64 64
    static bool less(Value a,Value b) {return a<b;}
65 65
    ///Returns \c true if \c a is \e surely different from \c b
66 66
    static bool different(Value a,Value b) {return a!=b;}
67 67
    ///Returns \c true if \c a is \e surely positive
68 68
    static bool positive(Value a) {return static_cast<Value>(0) < a;}
69 69
    ///Returns \c true if \c a is \e surely negative
70 70
    static bool negative(Value a) {return a < static_cast<Value>(0);}
71 71
    ///Returns \c true if \c a is \e surely non-zero
72 72
    static bool nonZero(Value a) {return a != static_cast<Value>(0);}
73 73

	
74 74
    ///@}
75 75

	
76 76
    ///Returns the zero value.
77 77
    static Value zero() {return static_cast<Value>(0);}
78 78

	
79 79
    //   static bool finite(Value a) {}
80 80
    //   static Value big() {}
81 81
    //   static Value negativeBig() {}
82 82
  };
83 83

	
84 84

	
85 85
  ///Float specialization of Tolerance.
86 86

	
87 87
  ///Float specialization of Tolerance.
88 88
  ///\sa Tolerance
89 89
  ///\relates Tolerance
90 90
  template<>
91 91
  class Tolerance<float>
92 92
  {
93 93
    static float def_epsilon;
94 94
    float _epsilon;
95 95
  public:
96 96
    ///\e
97 97
    typedef float Value;
98 98

	
99 99
    ///Constructor setting the epsilon tolerance to the default value.
100 100
    Tolerance() : _epsilon(def_epsilon) {}
101 101
    ///Constructor setting the epsilon tolerance to the given value.
102 102
    Tolerance(float e) : _epsilon(e) {}
103 103

	
104 104
    ///Returns the epsilon value.
105 105
    Value epsilon() const {return _epsilon;}
106 106
    ///Sets the epsilon value.
107 107
    void epsilon(Value e) {_epsilon=e;}
108 108

	
109 109
    ///Returns the default epsilon value.
110 110
    static Value defaultEpsilon() {return def_epsilon;}
111 111
    ///Sets the default epsilon value.
112 112
    static void defaultEpsilon(Value e) {def_epsilon=e;}
113 113

	
114 114
    ///\name Comparisons
115 115
    ///See \ref lemon::Tolerance "Tolerance" for more details.
116 116

	
117 117
    ///@{
118 118

	
119 119
    ///Returns \c true if \c a is \e surely strictly less than \c b
120 120
    bool less(Value a,Value b) const {return a+_epsilon<b;}
121 121
    ///Returns \c true if \c a is \e surely different from \c b
122 122
    bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
123 123
    ///Returns \c true if \c a is \e surely positive
124 124
    bool positive(Value a) const { return _epsilon<a; }
125 125
    ///Returns \c true if \c a is \e surely negative
126 126
    bool negative(Value a) const { return -_epsilon>a; }
127 127
    ///Returns \c true if \c a is \e surely non-zero
128 128
    bool nonZero(Value a) const { return positive(a)||negative(a); }
129 129

	
130 130
    ///@}
131 131

	
132 132
    ///Returns zero
133 133
    static Value zero() {return 0;}
134 134
  };
135 135

	
136 136
  ///Double specialization of Tolerance.
137 137

	
138 138
  ///Double specialization of Tolerance.
139 139
  ///\sa Tolerance
140 140
  ///\relates Tolerance
141 141
  template<>
142 142
  class Tolerance<double>
143 143
  {
144 144
    static double def_epsilon;
145 145
    double _epsilon;
146 146
  public:
147 147
    ///\e
148 148
    typedef double Value;
149 149

	
150 150
    ///Constructor setting the epsilon tolerance to the default value.
151 151
    Tolerance() : _epsilon(def_epsilon) {}
152 152
    ///Constructor setting the epsilon tolerance to the given value.
153 153
    Tolerance(double e) : _epsilon(e) {}
154 154

	
155 155
    ///Returns the epsilon value.
156 156
    Value epsilon() const {return _epsilon;}
157 157
    ///Sets the epsilon value.
158 158
    void epsilon(Value e) {_epsilon=e;}
159 159

	
160 160
    ///Returns the default epsilon value.
161 161
    static Value defaultEpsilon() {return def_epsilon;}
162 162
    ///Sets the default epsilon value.
163 163
    static void defaultEpsilon(Value e) {def_epsilon=e;}
164 164

	
165 165
    ///\name Comparisons
166 166
    ///See \ref lemon::Tolerance "Tolerance" for more details.
167 167

	
168 168
    ///@{
169 169

	
170 170
    ///Returns \c true if \c a is \e surely strictly less than \c b
171 171
    bool less(Value a,Value b) const {return a+_epsilon<b;}
172 172
    ///Returns \c true if \c a is \e surely different from \c b
173 173
    bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
174 174
    ///Returns \c true if \c a is \e surely positive
175 175
    bool positive(Value a) const { return _epsilon<a; }
176 176
    ///Returns \c true if \c a is \e surely negative
177 177
    bool negative(Value a) const { return -_epsilon>a; }
178 178
    ///Returns \c true if \c a is \e surely non-zero
179 179
    bool nonZero(Value a) const { return positive(a)||negative(a); }
180 180

	
181 181
    ///@}
182 182

	
183 183
    ///Returns zero
184 184
    static Value zero() {return 0;}
185 185
  };
186 186

	
187 187
  ///Long double specialization of Tolerance.
188 188

	
189 189
  ///Long double specialization of Tolerance.
190 190
  ///\sa Tolerance
191 191
  ///\relates Tolerance
192 192
  template<>
193 193
  class Tolerance<long double>
194 194
  {
195 195
    static long double def_epsilon;
196 196
    long double _epsilon;
197 197
  public:
198 198
    ///\e
199 199
    typedef long double Value;
200 200

	
201 201
    ///Constructor setting the epsilon tolerance to the default value.
202 202
    Tolerance() : _epsilon(def_epsilon) {}
203 203
    ///Constructor setting the epsilon tolerance to the given value.
204 204
    Tolerance(long double e) : _epsilon(e) {}
205 205

	
206 206
    ///Returns the epsilon value.
207 207
    Value epsilon() const {return _epsilon;}
208 208
    ///Sets the epsilon value.
209 209
    void epsilon(Value e) {_epsilon=e;}
210 210

	
211 211
    ///Returns the default epsilon value.
212 212
    static Value defaultEpsilon() {return def_epsilon;}
213 213
    ///Sets the default epsilon value.
214 214
    static void defaultEpsilon(Value e) {def_epsilon=e;}
215 215

	
216 216
    ///\name Comparisons
217 217
    ///See \ref lemon::Tolerance "Tolerance" for more details.
218 218

	
219 219
    ///@{
220 220

	
221 221
    ///Returns \c true if \c a is \e surely strictly less than \c b
222 222
    bool less(Value a,Value b) const {return a+_epsilon<b;}
223 223
    ///Returns \c true if \c a is \e surely different from \c b
224 224
    bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
225 225
    ///Returns \c true if \c a is \e surely positive
226 226
    bool positive(Value a) const { return _epsilon<a; }
227 227
    ///Returns \c true if \c a is \e surely negative
228 228
    bool negative(Value a) const { return -_epsilon>a; }
229 229
    ///Returns \c true if \c a is \e surely non-zero
230 230
    bool nonZero(Value a) const { return positive(a)||negative(a); }
231 231

	
232 232
    ///@}
233 233

	
234 234
    ///Returns zero
235 235
    static Value zero() {return 0;}
236 236
  };
237 237

	
238 238
  /// @}
239 239

	
240 240
} //namespace lemon
241 241

	
242 242
#endif //LEMON_TOLERANCE_H
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_UNION_FIND_H
20 20
#define LEMON_UNION_FIND_H
21 21

	
22 22
//!\ingroup auxdat
23 23
//!\file
24 24
//!\brief Union-Find data structures.
25 25
//!
26 26

	
27 27
#include <vector>
28 28
#include <list>
29 29
#include <utility>
30 30
#include <algorithm>
31 31
#include <functional>
32 32

	
33 33
#include <lemon/core.h>
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  /// \ingroup auxdat
38 38
  ///
39 39
  /// \brief A \e Union-Find data structure implementation
40 40
  ///
41 41
  /// The class implements the \e Union-Find data structure.
42 42
  /// The union operation uses rank heuristic, while
43 43
  /// the find operation uses path compression.
44 44
  /// This is a very simple but efficient implementation, providing
45 45
  /// only four methods: join (union), find, insert and size.
46 46
  /// For more features see the \ref UnionFindEnum class.
47 47
  ///
48 48
  /// It is primarily used in Kruskal algorithm for finding minimal
49 49
  /// cost spanning tree in a graph.
50 50
  /// \sa kruskal()
51 51
  ///
52 52
  /// \pre You need to add all the elements by the \ref insert()
53 53
  /// method.
54
  template <typename _ItemIntMap>
54
  template <typename IM>
55 55
  class UnionFind {
56 56
  public:
57 57

	
58
    typedef _ItemIntMap ItemIntMap;
58
    ///\e
59
    typedef IM ItemIntMap;
60
    ///\e
59 61
    typedef typename ItemIntMap::Key Item;
60 62

	
61 63
  private:
62 64
    // If the items vector stores negative value for an item then
63 65
    // that item is root item and it has -items[it] component size.
64 66
    // Else the items[it] contains the index of the parent.
65 67
    std::vector<int> items;
66 68
    ItemIntMap& index;
67 69

	
68 70
    bool rep(int idx) const {
69 71
      return items[idx] < 0;
70 72
    }
71 73

	
72 74
    int repIndex(int idx) const {
73 75
      int k = idx;
74 76
      while (!rep(k)) {
75 77
        k = items[k] ;
76 78
      }
77 79
      while (idx != k) {
78 80
        int next = items[idx];
79 81
        const_cast<int&>(items[idx]) = k;
80 82
        idx = next;
81 83
      }
82 84
      return k;
83 85
    }
84 86

	
85 87
  public:
86 88

	
87 89
    /// \brief Constructor
88 90
    ///
89 91
    /// Constructor of the UnionFind class. You should give an item to
90 92
    /// integer map which will be used from the data structure. If you
91 93
    /// modify directly this map that may cause segmentation fault,
92 94
    /// invalid data structure, or infinite loop when you use again
93 95
    /// the union-find.
94 96
    UnionFind(ItemIntMap& m) : index(m) {}
95 97

	
96 98
    /// \brief Returns the index of the element's component.
97 99
    ///
98 100
    /// The method returns the index of the element's component.
99 101
    /// This is an integer between zero and the number of inserted elements.
100 102
    ///
101 103
    int find(const Item& a) {
102 104
      return repIndex(index[a]);
103 105
    }
104 106

	
105 107
    /// \brief Clears the union-find data structure
106 108
    ///
107 109
    /// Erase each item from the data structure.
108 110
    void clear() {
109 111
      items.clear();
110 112
    }
111 113

	
112 114
    /// \brief Inserts a new element into the structure.
113 115
    ///
114 116
    /// This method inserts a new element into the data structure.
115 117
    ///
116 118
    /// The method returns the index of the new component.
117 119
    int insert(const Item& a) {
118 120
      int n = items.size();
119 121
      items.push_back(-1);
120 122
      index.set(a,n);
121 123
      return n;
122 124
    }
123 125

	
124 126
    /// \brief Joining the components of element \e a and element \e b.
125 127
    ///
126 128
    /// This is the \e union operation of the Union-Find structure.
127 129
    /// Joins the component of element \e a and component of
128 130
    /// element \e b. If \e a and \e b are in the same component then
129 131
    /// it returns false otherwise it returns true.
130 132
    bool join(const Item& a, const Item& b) {
131 133
      int ka = repIndex(index[a]);
132 134
      int kb = repIndex(index[b]);
133 135

	
134 136
      if ( ka == kb )
135 137
        return false;
136 138

	
137 139
      if (items[ka] < items[kb]) {
138 140
        items[ka] += items[kb];
139 141
        items[kb] = ka;
140 142
      } else {
141 143
        items[kb] += items[ka];
142 144
        items[ka] = kb;
143 145
      }
144 146
      return true;
145 147
    }
146 148

	
147 149
    /// \brief Returns the size of the component of element \e a.
148 150
    ///
149 151
    /// Returns the size of the component of element \e a.
150 152
    int size(const Item& a) {
151 153
      int k = repIndex(index[a]);
152 154
      return - items[k];
153 155
    }
154 156

	
155 157
  };
156 158

	
157 159
  /// \ingroup auxdat
158 160
  ///
159 161
  /// \brief A \e Union-Find data structure implementation which
160 162
  /// is able to enumerate the components.
161 163
  ///
162 164
  /// The class implements a \e Union-Find data structure
163 165
  /// which is able to enumerate the components and the items in
164 166
  /// a component. If you don't need this feature then perhaps it's
165 167
  /// better to use the \ref UnionFind class which is more efficient.
166 168
  ///
167 169
  /// The union operation uses rank heuristic, while
168 170
  /// the find operation uses path compression.
169 171
  ///
170 172
  /// \pre You need to add all the elements by the \ref insert()
171 173
  /// method.
172 174
  ///
173
  template <typename _ItemIntMap>
175
  template <typename IM>
174 176
  class UnionFindEnum {
175 177
  public:
176 178

	
177
    typedef _ItemIntMap ItemIntMap;
179
    ///\e
180
    typedef IM ItemIntMap;
181
    ///\e
178 182
    typedef typename ItemIntMap::Key Item;
179 183

	
180 184
  private:
181 185

	
182 186
    ItemIntMap& index;
183 187

	
184 188
    // If the parent stores negative value for an item then that item
185 189
    // is root item and it has ~(items[it].parent) component id.  Else
186 190
    // the items[it].parent contains the index of the parent.
187 191
    //
188 192
    // The \c next and \c prev provides the double-linked
189 193
    // cyclic list of one component's items.
190 194
    struct ItemT {
191 195
      int parent;
192 196
      Item item;
193 197

	
194 198
      int next, prev;
195 199
    };
196 200

	
197 201
    std::vector<ItemT> items;
198 202
    int firstFreeItem;
199 203

	
200 204
    struct ClassT {
201 205
      int size;
202 206
      int firstItem;
203 207
      int next, prev;
204 208
    };
205 209

	
206 210
    std::vector<ClassT> classes;
207 211
    int firstClass, firstFreeClass;
208 212

	
209 213
    int newClass() {
210 214
      if (firstFreeClass == -1) {
211 215
        int cdx = classes.size();
212 216
        classes.push_back(ClassT());
213 217
        return cdx;
214 218
      } else {
215 219
        int cdx = firstFreeClass;
216 220
        firstFreeClass = classes[firstFreeClass].next;
217 221
        return cdx;
218 222
      }
219 223
    }
220 224

	
221 225
    int newItem() {
222 226
      if (firstFreeItem == -1) {
223 227
        int idx = items.size();
224 228
        items.push_back(ItemT());
225 229
        return idx;
226 230
      } else {
227 231
        int idx = firstFreeItem;
228 232
        firstFreeItem = items[firstFreeItem].next;
229 233
        return idx;
230 234
      }
231 235
    }
232 236

	
233 237

	
234 238
    bool rep(int idx) const {
235 239
      return items[idx].parent < 0;
236 240
    }
237 241

	
238 242
    int repIndex(int idx) const {
239 243
      int k = idx;
240 244
      while (!rep(k)) {
241 245
        k = items[k].parent;
242 246
      }
243 247
      while (idx != k) {
244 248
        int next = items[idx].parent;
245 249
        const_cast<int&>(items[idx].parent) = k;
246 250
        idx = next;
247 251
      }
248 252
      return k;
249 253
    }
250 254

	
251 255
    int classIndex(int idx) const {
252 256
      return ~(items[repIndex(idx)].parent);
253 257
    }
254 258

	
255 259
    void singletonItem(int idx) {
256 260
      items[idx].next = idx;
257 261
      items[idx].prev = idx;
258 262
    }
259 263

	
260 264
    void laceItem(int idx, int rdx) {
261 265
      items[idx].prev = rdx;
262 266
      items[idx].next = items[rdx].next;
263 267
      items[items[rdx].next].prev = idx;
264 268
      items[rdx].next = idx;
265 269
    }
266 270

	
267 271
    void unlaceItem(int idx) {
268 272
      items[items[idx].prev].next = items[idx].next;
269 273
      items[items[idx].next].prev = items[idx].prev;
270 274

	
271 275
      items[idx].next = firstFreeItem;
272 276
      firstFreeItem = idx;
273 277
    }
274 278

	
275 279
    void spliceItems(int ak, int bk) {
276 280
      items[items[ak].prev].next = bk;
277 281
      items[items[bk].prev].next = ak;
278 282
      int tmp = items[ak].prev;
279 283
      items[ak].prev = items[bk].prev;
280 284
      items[bk].prev = tmp;
281 285

	
282 286
    }
283 287

	
284 288
    void laceClass(int cls) {
285 289
      if (firstClass != -1) {
286 290
        classes[firstClass].prev = cls;
287 291
      }
288 292
      classes[cls].next = firstClass;
289 293
      classes[cls].prev = -1;
290 294
      firstClass = cls;
291 295
    }
292 296

	
293 297
    void unlaceClass(int cls) {
294 298
      if (classes[cls].prev != -1) {
295 299
        classes[classes[cls].prev].next = classes[cls].next;
296 300
      } else {
297 301
        firstClass = classes[cls].next;
298 302
      }
299 303
      if (classes[cls].next != -1) {
300 304
        classes[classes[cls].next].prev = classes[cls].prev;
301 305
      }
302 306

	
303 307
      classes[cls].next = firstFreeClass;
304 308
      firstFreeClass = cls;
305 309
    }
306 310

	
307 311
  public:
308 312

	
309 313
    UnionFindEnum(ItemIntMap& _index)
310 314
      : index(_index), items(), firstFreeItem(-1),
311 315
        firstClass(-1), firstFreeClass(-1) {}
312 316

	
313 317
    /// \brief Inserts the given element into a new component.
314 318
    ///
315 319
    /// This method creates a new component consisting only of the
316 320
    /// given element.
317 321
    ///
318 322
    int insert(const Item& item) {
319 323
      int idx = newItem();
320 324

	
321 325
      index.set(item, idx);
322 326

	
323 327
      singletonItem(idx);
324 328
      items[idx].item = item;
325 329

	
326 330
      int cdx = newClass();
327 331

	
328 332
      items[idx].parent = ~cdx;
329 333

	
330 334
      laceClass(cdx);
331 335
      classes[cdx].size = 1;
332 336
      classes[cdx].firstItem = idx;
333 337

	
334 338
      firstClass = cdx;
335 339

	
336 340
      return cdx;
337 341
    }
338 342

	
339 343
    /// \brief Inserts the given element into the component of the others.
340 344
    ///
341 345
    /// This methods inserts the element \e a into the component of the
342 346
    /// element \e comp.
343 347
    void insert(const Item& item, int cls) {
344 348
      int rdx = classes[cls].firstItem;
345 349
      int idx = newItem();
346 350

	
347 351
      index.set(item, idx);
348 352

	
349 353
      laceItem(idx, rdx);
350 354

	
351 355
      items[idx].item = item;
352 356
      items[idx].parent = rdx;
353 357

	
354 358
      ++classes[~(items[rdx].parent)].size;
355 359
    }
356 360

	
357 361
    /// \brief Clears the union-find data structure
358 362
    ///
359 363
    /// Erase each item from the data structure.
360 364
    void clear() {
361 365
      items.clear();
362 366
      firstClass = -1;
363 367
      firstFreeItem = -1;
364 368
    }
365 369

	
366 370
    /// \brief Finds the component of the given element.
367 371
    ///
368 372
    /// The method returns the component id of the given element.
369 373
    int find(const Item &item) const {
370 374
      return ~(items[repIndex(index[item])].parent);
371 375
    }
372 376

	
373 377
    /// \brief Joining the component of element \e a and element \e b.
374 378
    ///
375 379
    /// This is the \e union operation of the Union-Find structure.
376 380
    /// Joins the component of element \e a and component of
377 381
    /// element \e b. If \e a and \e b are in the same component then
378 382
    /// returns -1 else returns the remaining class.
379 383
    int join(const Item& a, const Item& b) {
380 384

	
381 385
      int ak = repIndex(index[a]);
382 386
      int bk = repIndex(index[b]);
383 387

	
384 388
      if (ak == bk) {
385 389
        return -1;
386 390
      }
387 391

	
388 392
      int acx = ~(items[ak].parent);
389 393
      int bcx = ~(items[bk].parent);
390 394

	
391 395
      int rcx;
392 396

	
393 397
      if (classes[acx].size > classes[bcx].size) {
394 398
        classes[acx].size += classes[bcx].size;
395 399
        items[bk].parent = ak;
396 400
        unlaceClass(bcx);
397 401
        rcx = acx;
398 402
      } else {
399 403
        classes[bcx].size += classes[acx].size;
400 404
        items[ak].parent = bk;
401 405
        unlaceClass(acx);
402 406
        rcx = bcx;
403 407
      }
404 408
      spliceItems(ak, bk);
405 409

	
406 410
      return rcx;
407 411
    }
408 412

	
409 413
    /// \brief Returns the size of the class.
410 414
    ///
411 415
    /// Returns the size of the class.
412 416
    int size(int cls) const {
413 417
      return classes[cls].size;
414 418
    }
415 419

	
416 420
    /// \brief Splits up the component.
417 421
    ///
418 422
    /// Splitting the component into singleton components (component
419 423
    /// of size one).
420 424
    void split(int cls) {
421 425
      int fdx = classes[cls].firstItem;
422 426
      int idx = items[fdx].next;
423 427
      while (idx != fdx) {
424 428
        int next = items[idx].next;
425 429

	
426 430
        singletonItem(idx);
427 431

	
428 432
        int cdx = newClass();
429 433
        items[idx].parent = ~cdx;
430 434

	
431 435
        laceClass(cdx);
432 436
        classes[cdx].size = 1;
433 437
        classes[cdx].firstItem = idx;
434 438

	
435 439
        idx = next;
436 440
      }
437 441

	
438 442
      items[idx].prev = idx;
439 443
      items[idx].next = idx;
440 444

	
441 445
      classes[~(items[idx].parent)].size = 1;
442 446

	
443 447
    }
444 448

	
445 449
    /// \brief Removes the given element from the structure.
446 450
    ///
447 451
    /// Removes the element from its component and if the component becomes
448 452
    /// empty then removes that component from the component list.
449 453
    ///
450 454
    /// \warning It is an error to remove an element which is not in
451 455
    /// the structure.
452 456
    /// \warning This running time of this operation is proportional to the
453 457
    /// number of the items in this class.
454 458
    void erase(const Item& item) {
455 459
      int idx = index[item];
456 460
      int fdx = items[idx].next;
457 461

	
458 462
      int cdx = classIndex(idx);
459 463
      if (idx == fdx) {
460 464
        unlaceClass(cdx);
461 465
        items[idx].next = firstFreeItem;
462 466
        firstFreeItem = idx;
463 467
        return;
464 468
      } else {
465 469
        classes[cdx].firstItem = fdx;
466 470
        --classes[cdx].size;
467 471
        items[fdx].parent = ~cdx;
468 472

	
469 473
        unlaceItem(idx);
470 474
        idx = items[fdx].next;
471 475
        while (idx != fdx) {
472 476
          items[idx].parent = fdx;
473 477
          idx = items[idx].next;
474 478
        }
475 479

	
476 480
      }
477 481

	
478 482
    }
479 483

	
480 484
    /// \brief Gives back a representant item of the component.
481 485
    ///
482 486
    /// Gives back a representant item of the component.
483 487
    Item item(int cls) const {
484 488
      return items[classes[cls].firstItem].item;
485 489
    }
486 490

	
487 491
    /// \brief Removes the component of the given element from the structure.
488 492
    ///
489 493
    /// Removes the component of the given element from the structure.
490 494
    ///
491 495
    /// \warning It is an error to give an element which is not in the
492 496
    /// structure.
493 497
    void eraseClass(int cls) {
494 498
      int fdx = classes[cls].firstItem;
495 499
      unlaceClass(cls);
496 500
      items[items[fdx].prev].next = firstFreeItem;
497 501
      firstFreeItem = fdx;
498 502
    }
499 503

	
500 504
    /// \brief LEMON style iterator for the representant items.
501 505
    ///
502 506
    /// ClassIt is a lemon style iterator for the components. It iterates
503 507
    /// on the ids of the classes.
504 508
    class ClassIt {
505 509
    public:
506 510
      /// \brief Constructor of the iterator
507 511
      ///
508 512
      /// Constructor of the iterator
509 513
      ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) {
510 514
        cdx = unionFind->firstClass;
511 515
      }
512 516

	
513 517
      /// \brief Constructor to get invalid iterator
514 518
      ///
515 519
      /// Constructor to get invalid iterator
516 520
      ClassIt(Invalid) : unionFind(0), cdx(-1) {}
517 521

	
518 522
      /// \brief Increment operator
519 523
      ///
520 524
      /// It steps to the next representant item.
521 525
      ClassIt& operator++() {
522 526
        cdx = unionFind->classes[cdx].next;
523 527
        return *this;
524 528
      }
525 529

	
526 530
      /// \brief Conversion operator
527 531
      ///
528 532
      /// It converts the iterator to the current representant item.
529 533
      operator int() const {
530 534
        return cdx;
531 535
      }
532 536

	
533 537
      /// \brief Equality operator
534 538
      ///
535 539
      /// Equality operator
536 540
      bool operator==(const ClassIt& i) {
537 541
        return i.cdx == cdx;
538 542
      }
539 543

	
540 544
      /// \brief Inequality operator
541 545
      ///
542 546
      /// Inequality operator
543 547
      bool operator!=(const ClassIt& i) {
544 548
        return i.cdx != cdx;
545 549
      }
546 550

	
547 551
    private:
548 552
      const UnionFindEnum* unionFind;
549 553
      int cdx;
550 554
    };
551 555

	
552 556
    /// \brief LEMON style iterator for the items of a component.
553 557
    ///
554 558
    /// ClassIt is a lemon style iterator for the components. It iterates
555 559
    /// on the items of a class. By example if you want to iterate on
556 560
    /// each items of each classes then you may write the next code.
557 561
    ///\code
558 562
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
559 563
    ///   std::cout << "Class: ";
560 564
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
561 565
    ///     std::cout << toString(iit) << ' ' << std::endl;
562 566
    ///   }
563 567
    ///   std::cout << std::endl;
564 568
    /// }
565 569
    ///\endcode
566 570
    class ItemIt {
567 571
    public:
568 572
      /// \brief Constructor of the iterator
569 573
      ///
570 574
      /// Constructor of the iterator. The iterator iterates
571 575
      /// on the class of the \c item.
572 576
      ItemIt(const UnionFindEnum& ufe, int cls) : unionFind(&ufe) {
573 577
        fdx = idx = unionFind->classes[cls].firstItem;
574 578
      }
575 579

	
576 580
      /// \brief Constructor to get invalid iterator
577 581
      ///
578 582
      /// Constructor to get invalid iterator
579 583
      ItemIt(Invalid) : unionFind(0), idx(-1) {}
580 584

	
581 585
      /// \brief Increment operator
582 586
      ///
583 587
      /// It steps to the next item in the class.
584 588
      ItemIt& operator++() {
585 589
        idx = unionFind->items[idx].next;
586 590
        if (idx == fdx) idx = -1;
587 591
        return *this;
588 592
      }
589 593

	
590 594
      /// \brief Conversion operator
591 595
      ///
592 596
      /// It converts the iterator to the current item.
593 597
      operator const Item&() const {
594 598
        return unionFind->items[idx].item;
595 599
      }
596 600

	
597 601
      /// \brief Equality operator
598 602
      ///
599 603
      /// Equality operator
600 604
      bool operator==(const ItemIt& i) {
601 605
        return i.idx == idx;
602 606
      }
603 607

	
604 608
      /// \brief Inequality operator
605 609
      ///
606 610
      /// Inequality operator
607 611
      bool operator!=(const ItemIt& i) {
608 612
        return i.idx != idx;
609 613
      }
610 614

	
611 615
    private:
612 616
      const UnionFindEnum* unionFind;
613 617
      int idx, fdx;
614 618
    };
615 619

	
616 620
  };
617 621

	
618 622
  /// \ingroup auxdat
619 623
  ///
620 624
  /// \brief A \e Extend-Find data structure implementation which
621 625
  /// is able to enumerate the components.
622 626
  ///
623 627
  /// The class implements an \e Extend-Find data structure which is
624 628
  /// able to enumerate the components and the items in a
625 629
  /// component. The data structure is a simplification of the
626 630
  /// Union-Find structure, and it does not allow to merge two components.
627 631
  ///
628 632
  /// \pre You need to add all the elements by the \ref insert()
629 633
  /// method.
630
  template <typename _ItemIntMap>
634
  template <typename IM>
631 635
  class ExtendFindEnum {
632 636
  public:
633 637

	
634
    typedef _ItemIntMap ItemIntMap;
638
    ///\e
639
    typedef IM ItemIntMap;
640
    ///\e
635 641
    typedef typename ItemIntMap::Key Item;
636 642

	
637 643
  private:
638 644

	
639 645
    ItemIntMap& index;
640 646

	
641 647
    struct ItemT {
642 648
      int cls;
643 649
      Item item;
644 650
      int next, prev;
645 651
    };
646 652

	
647 653
    std::vector<ItemT> items;
648 654
    int firstFreeItem;
649 655

	
650 656
    struct ClassT {
651 657
      int firstItem;
652 658
      int next, prev;
653 659
    };
654 660

	
655 661
    std::vector<ClassT> classes;
656 662

	
657 663
    int firstClass, firstFreeClass;
658 664

	
659 665
    int newClass() {
660 666
      if (firstFreeClass != -1) {
661 667
        int cdx = firstFreeClass;
662 668
        firstFreeClass = classes[cdx].next;
663 669
        return cdx;
664 670
      } else {
665 671
        classes.push_back(ClassT());
666 672
        return classes.size() - 1;
667 673
      }
668 674
    }
669 675

	
670 676
    int newItem() {
671 677
      if (firstFreeItem != -1) {
672 678
        int idx = firstFreeItem;
673 679
        firstFreeItem = items[idx].next;
674 680
        return idx;
675 681
      } else {
676 682
        items.push_back(ItemT());
677 683
        return items.size() - 1;
678 684
      }
679 685
    }
680 686

	
681 687
  public:
682 688

	
683 689
    /// \brief Constructor
684 690
    ExtendFindEnum(ItemIntMap& _index)
685 691
      : index(_index), items(), firstFreeItem(-1),
686 692
        classes(), firstClass(-1), firstFreeClass(-1) {}
687 693

	
688 694
    /// \brief Inserts the given element into a new component.
689 695
    ///
690 696
    /// This method creates a new component consisting only of the
691 697
    /// given element.
692 698
    int insert(const Item& item) {
693 699
      int cdx = newClass();
694 700
      classes[cdx].prev = -1;
695 701
      classes[cdx].next = firstClass;
696 702
      if (firstClass != -1) {
697 703
        classes[firstClass].prev = cdx;
698 704
      }
699 705
      firstClass = cdx;
700 706

	
701 707
      int idx = newItem();
702 708
      items[idx].item = item;
703 709
      items[idx].cls = cdx;
704 710
      items[idx].prev = idx;
705 711
      items[idx].next = idx;
706 712

	
707 713
      classes[cdx].firstItem = idx;
708 714

	
709 715
      index.set(item, idx);
710 716

	
711 717
      return cdx;
712 718
    }
713 719

	
714 720
    /// \brief Inserts the given element into the given component.
715 721
    ///
716 722
    /// This methods inserts the element \e item a into the \e cls class.
717 723
    void insert(const Item& item, int cls) {
718 724
      int idx = newItem();
719 725
      int rdx = classes[cls].firstItem;
720 726
      items[idx].item = item;
721 727
      items[idx].cls = cls;
722 728

	
723 729
      items[idx].prev = rdx;
724 730
      items[idx].next = items[rdx].next;
725 731
      items[items[rdx].next].prev = idx;
726 732
      items[rdx].next = idx;
727 733

	
728 734
      index.set(item, idx);
729 735
    }
730 736

	
731 737
    /// \brief Clears the union-find data structure
732 738
    ///
733 739
    /// Erase each item from the data structure.
734 740
    void clear() {
735 741
      items.clear();
736 742
      classes.clear;
737 743
      firstClass = firstFreeClass = firstFreeItem = -1;
738 744
    }
739 745

	
740 746
    /// \brief Gives back the class of the \e item.
741 747
    ///
742 748
    /// Gives back the class of the \e item.
743 749
    int find(const Item &item) const {
744 750
      return items[index[item]].cls;
745 751
    }
746 752

	
747 753
    /// \brief Gives back a representant item of the component.
748 754
    ///
749 755
    /// Gives back a representant item of the component.
750 756
    Item item(int cls) const {
751 757
      return items[classes[cls].firstItem].item;
752 758
    }
753 759

	
754 760
    /// \brief Removes the given element from the structure.
755 761
    ///
756 762
    /// Removes the element from its component and if the component becomes
757 763
    /// empty then removes that component from the component list.
758 764
    ///
759 765
    /// \warning It is an error to remove an element which is not in
760 766
    /// the structure.
761 767
    void erase(const Item &item) {
762 768
      int idx = index[item];
763 769
      int cdx = items[idx].cls;
764 770

	
765 771
      if (idx == items[idx].next) {
766 772
        if (classes[cdx].prev != -1) {
767 773
          classes[classes[cdx].prev].next = classes[cdx].next;
768 774
        } else {
769 775
          firstClass = classes[cdx].next;
770 776
        }
771 777
        if (classes[cdx].next != -1) {
772 778
          classes[classes[cdx].next].prev = classes[cdx].prev;
773 779
        }
774 780
        classes[cdx].next = firstFreeClass;
775 781
        firstFreeClass = cdx;
776 782
      } else {
777 783
        classes[cdx].firstItem = items[idx].next;
778 784
        items[items[idx].next].prev = items[idx].prev;
779 785
        items[items[idx].prev].next = items[idx].next;
780 786
      }
781 787
      items[idx].next = firstFreeItem;
782 788
      firstFreeItem = idx;
783 789

	
784 790
    }
785 791

	
786 792

	
787 793
    /// \brief Removes the component of the given element from the structure.
788 794
    ///
789 795
    /// Removes the component of the given element from the structure.
790 796
    ///
791 797
    /// \warning It is an error to give an element which is not in the
792 798
    /// structure.
793 799
    void eraseClass(int cdx) {
794 800
      int idx = classes[cdx].firstItem;
795 801
      items[items[idx].prev].next = firstFreeItem;
796 802
      firstFreeItem = idx;
797 803

	
798 804
      if (classes[cdx].prev != -1) {
799 805
        classes[classes[cdx].prev].next = classes[cdx].next;
800 806
      } else {
801 807
        firstClass = classes[cdx].next;
802 808
      }
803 809
      if (classes[cdx].next != -1) {
804 810
        classes[classes[cdx].next].prev = classes[cdx].prev;
805 811
      }
806 812
      classes[cdx].next = firstFreeClass;
807 813
      firstFreeClass = cdx;
808 814
    }
809 815

	
810 816
    /// \brief LEMON style iterator for the classes.
811 817
    ///
812 818
    /// ClassIt is a lemon style iterator for the components. It iterates
813 819
    /// on the ids of classes.
814 820
    class ClassIt {
815 821
    public:
816 822
      /// \brief Constructor of the iterator
817 823
      ///
818 824
      /// Constructor of the iterator
819 825
      ClassIt(const ExtendFindEnum& ufe) : extendFind(&ufe) {
820 826
        cdx = extendFind->firstClass;
821 827
      }
822 828

	
823 829
      /// \brief Constructor to get invalid iterator
824 830
      ///
825 831
      /// Constructor to get invalid iterator
826 832
      ClassIt(Invalid) : extendFind(0), cdx(-1) {}
827 833

	
828 834
      /// \brief Increment operator
829 835
      ///
830 836
      /// It steps to the next representant item.
831 837
      ClassIt& operator++() {
832 838
        cdx = extendFind->classes[cdx].next;
833 839
        return *this;
834 840
      }
835 841

	
836 842
      /// \brief Conversion operator
837 843
      ///
838 844
      /// It converts the iterator to the current class id.
839 845
      operator int() const {
840 846
        return cdx;
841 847
      }
842 848

	
843 849
      /// \brief Equality operator
844 850
      ///
845 851
      /// Equality operator
846 852
      bool operator==(const ClassIt& i) {
847 853
        return i.cdx == cdx;
848 854
      }
849 855

	
850 856
      /// \brief Inequality operator
851 857
      ///
852 858
      /// Inequality operator
853 859
      bool operator!=(const ClassIt& i) {
854 860
        return i.cdx != cdx;
855 861
      }
856 862

	
857 863
    private:
858 864
      const ExtendFindEnum* extendFind;
859 865
      int cdx;
860 866
    };
861 867

	
862 868
    /// \brief LEMON style iterator for the items of a component.
863 869
    ///
864 870
    /// ClassIt is a lemon style iterator for the components. It iterates
865 871
    /// on the items of a class. By example if you want to iterate on
866 872
    /// each items of each classes then you may write the next code.
867 873
    ///\code
868 874
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
869 875
    ///   std::cout << "Class: ";
870 876
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
871 877
    ///     std::cout << toString(iit) << ' ' << std::endl;
872 878
    ///   }
873 879
    ///   std::cout << std::endl;
874 880
    /// }
875 881
    ///\endcode
876 882
    class ItemIt {
877 883
    public:
878 884
      /// \brief Constructor of the iterator
879 885
      ///
880 886
      /// Constructor of the iterator. The iterator iterates
881 887
      /// on the class of the \c item.
882 888
      ItemIt(const ExtendFindEnum& ufe, int cls) : extendFind(&ufe) {
883 889
        fdx = idx = extendFind->classes[cls].firstItem;
884 890
      }
885 891

	
886 892
      /// \brief Constructor to get invalid iterator
887 893
      ///
888 894
      /// Constructor to get invalid iterator
889 895
      ItemIt(Invalid) : extendFind(0), idx(-1) {}
890 896

	
891 897
      /// \brief Increment operator
892 898
      ///
893 899
      /// It steps to the next item in the class.
894 900
      ItemIt& operator++() {
895 901
        idx = extendFind->items[idx].next;
896 902
        if (fdx == idx) idx = -1;
897 903
        return *this;
898 904
      }
899 905

	
900 906
      /// \brief Conversion operator
901 907
      ///
902 908
      /// It converts the iterator to the current item.
903 909
      operator const Item&() const {
904 910
        return extendFind->items[idx].item;
905 911
      }
906 912

	
907 913
      /// \brief Equality operator
908 914
      ///
909 915
      /// Equality operator
910 916
      bool operator==(const ItemIt& i) {
911 917
        return i.idx == idx;
912 918
      }
913 919

	
914 920
      /// \brief Inequality operator
915 921
      ///
916 922
      /// Inequality operator
917 923
      bool operator!=(const ItemIt& i) {
918 924
        return i.idx != idx;
919 925
      }
920 926

	
921 927
    private:
922 928
      const ExtendFindEnum* extendFind;
923 929
      int idx, fdx;
924 930
    };
925 931

	
926 932
  };
927 933

	
928 934
  /// \ingroup auxdat
929 935
  ///
930 936
  /// \brief A \e Union-Find data structure implementation which
931 937
  /// is able to store a priority for each item and retrieve the minimum of
932 938
  /// each class.
933 939
  ///
934 940
  /// A \e Union-Find data structure implementation which is able to
935 941
  /// store a priority for each item and retrieve the minimum of each
936 942
  /// class. In addition, it supports the joining and splitting the
937 943
  /// components. If you don't need this feature then you makes
938 944
  /// better to use the \ref UnionFind class which is more efficient.
939 945
  ///
940 946
  /// The union-find data strcuture based on a (2, 16)-tree with a
941 947
  /// tournament minimum selection on the internal nodes. The insert
942 948
  /// operation takes O(1), the find, set, decrease and increase takes
943 949
  /// O(log(n)), where n is the number of nodes in the current
944 950
  /// component.  The complexity of join and split is O(log(n)*k),
945 951
  /// where n is the sum of the number of the nodes and k is the
946 952
  /// number of joined components or the number of the components
947 953
  /// after the split.
948 954
  ///
949 955
  /// \pre You need to add all the elements by the \ref insert()
950 956
  /// method.
951
  ///
952
  template <typename _Value, typename _ItemIntMap,
953
            typename _Comp = std::less<_Value> >
957
  template <typename V, typename IM, typename Comp = std::less<V> >
954 958
  class HeapUnionFind {
955 959
  public:
956 960

	
957
    typedef _Value Value;
958
    typedef typename _ItemIntMap::Key Item;
959

	
960
    typedef _ItemIntMap ItemIntMap;
961

	
962
    typedef _Comp Comp;
961
    ///\e
962
    typedef V Value;
963
    ///\e
964
    typedef typename IM::Key Item;
965
    ///\e
966
    typedef IM ItemIntMap;
967
    ///\e
968
    typedef Comp Compare;
963 969

	
964 970
  private:
965 971

	
966 972
    static const int cmax = 16;
967 973

	
968 974
    ItemIntMap& index;
969 975

	
970 976
    struct ClassNode {
971 977
      int parent;
972 978
      int depth;
973 979

	
974 980
      int left, right;
975 981
      int next, prev;
976 982
    };
977 983

	
978 984
    int first_class;
979 985
    int first_free_class;
980 986
    std::vector<ClassNode> classes;
981 987

	
982 988
    int newClass() {
983 989
      if (first_free_class < 0) {
984 990
        int id = classes.size();
985 991
        classes.push_back(ClassNode());
986 992
        return id;
987 993
      } else {
988 994
        int id = first_free_class;
989 995
        first_free_class = classes[id].next;
990 996
        return id;
991 997
      }
992 998
    }
993 999

	
994 1000
    void deleteClass(int id) {
995 1001
      classes[id].next = first_free_class;
996 1002
      first_free_class = id;
997 1003
    }
998 1004

	
999 1005
    struct ItemNode {
1000 1006
      int parent;
1001 1007
      Item item;
1002 1008
      Value prio;
1003 1009
      int next, prev;
1004 1010
      int left, right;
1005 1011
      int size;
1006 1012
    };
1007 1013

	
1008 1014
    int first_free_node;
1009 1015
    std::vector<ItemNode> nodes;
1010 1016

	
1011 1017
    int newNode() {
1012 1018
      if (first_free_node < 0) {
1013 1019
        int id = nodes.size();
1014 1020
        nodes.push_back(ItemNode());
1015 1021
        return id;
1016 1022
      } else {
1017 1023
        int id = first_free_node;
1018 1024
        first_free_node = nodes[id].next;
1019 1025
        return id;
1020 1026
      }
1021 1027
    }
1022 1028

	
1023 1029
    void deleteNode(int id) {
1024 1030
      nodes[id].next = first_free_node;
1025 1031
      first_free_node = id;
1026 1032
    }
1027 1033

	
1028 1034
    Comp comp;
1029 1035

	
1030 1036
    int findClass(int id) const {
1031 1037
      int kd = id;
1032 1038
      while (kd >= 0) {
1033 1039
        kd = nodes[kd].parent;
1034 1040
      }
1035 1041
      return ~kd;
1036 1042
    }
1037 1043

	
1038 1044
    int leftNode(int id) const {
1039 1045
      int kd = ~(classes[id].parent);
1040 1046
      for (int i = 0; i < classes[id].depth; ++i) {
1041 1047
        kd = nodes[kd].left;
1042 1048
      }
1043 1049
      return kd;
1044 1050
    }
1045 1051

	
1046 1052
    int nextNode(int id) const {
1047 1053
      int depth = 0;
1048 1054
      while (id >= 0 && nodes[id].next == -1) {
1049 1055
        id = nodes[id].parent;
1050 1056
        ++depth;
1051 1057
      }
1052 1058
      if (id < 0) {
1053 1059
        return -1;
1054 1060
      }
1055 1061
      id = nodes[id].next;
1056 1062
      while (depth--) {
1057 1063
        id = nodes[id].left;
1058 1064
      }
1059 1065
      return id;
1060 1066
    }
1061 1067

	
1062 1068

	
1063 1069
    void setPrio(int id) {
1064 1070
      int jd = nodes[id].left;
1065 1071
      nodes[id].prio = nodes[jd].prio;
1066 1072
      nodes[id].item = nodes[jd].item;
1067 1073
      jd = nodes[jd].next;
1068 1074
      while (jd != -1) {
1069 1075
        if (comp(nodes[jd].prio, nodes[id].prio)) {
1070 1076
          nodes[id].prio = nodes[jd].prio;
1071 1077
          nodes[id].item = nodes[jd].item;
1072 1078
        }
1073 1079
        jd = nodes[jd].next;
1074 1080
      }
1075 1081
    }
1076 1082

	
1077 1083
    void push(int id, int jd) {
1078 1084
      nodes[id].size = 1;
1079 1085
      nodes[id].left = nodes[id].right = jd;
1080 1086
      nodes[jd].next = nodes[jd].prev = -1;
1081 1087
      nodes[jd].parent = id;
1082 1088
    }
1083 1089

	
1084 1090
    void pushAfter(int id, int jd) {
1085 1091
      int kd = nodes[id].parent;
1086 1092
      if (nodes[id].next != -1) {
1087 1093
        nodes[nodes[id].next].prev = jd;
1088 1094
        if (kd >= 0) {
1089 1095
          nodes[kd].size += 1;
1090 1096
        }
1091 1097
      } else {
1092 1098
        if (kd >= 0) {
1093 1099
          nodes[kd].right = jd;
1094 1100
          nodes[kd].size += 1;
1095 1101
        }
1096 1102
      }
1097 1103
      nodes[jd].next = nodes[id].next;
1098 1104
      nodes[jd].prev = id;
1099 1105
      nodes[id].next = jd;
1100 1106
      nodes[jd].parent = kd;
1101 1107
    }
1102 1108

	
1103 1109
    void pushRight(int id, int jd) {
1104 1110
      nodes[id].size += 1;
1105 1111
      nodes[jd].prev = nodes[id].right;
1106 1112
      nodes[jd].next = -1;
1107 1113
      nodes[nodes[id].right].next = jd;
1108 1114
      nodes[id].right = jd;
1109 1115
      nodes[jd].parent = id;
1110 1116
    }
1111 1117

	
1112 1118
    void popRight(int id) {
1113 1119
      nodes[id].size -= 1;
1114 1120
      int jd = nodes[id].right;
1115 1121
      nodes[nodes[jd].prev].next = -1;
1116 1122
      nodes[id].right = nodes[jd].prev;
1117 1123
    }
1118 1124

	
1119 1125
    void splice(int id, int jd) {
1120 1126
      nodes[id].size += nodes[jd].size;
1121 1127
      nodes[nodes[id].right].next = nodes[jd].left;
1122 1128
      nodes[nodes[jd].left].prev = nodes[id].right;
1123 1129
      int kd = nodes[jd].left;
1124 1130
      while (kd != -1) {
1125 1131
        nodes[kd].parent = id;
1126 1132
        kd = nodes[kd].next;
1127 1133
      }
1128 1134
      nodes[id].right = nodes[jd].right;
1129 1135
    }
1130 1136

	
1131 1137
    void split(int id, int jd) {
1132 1138
      int kd = nodes[id].parent;
1133 1139
      nodes[kd].right = nodes[id].prev;
1134 1140
      nodes[nodes[id].prev].next = -1;
1135 1141

	
1136 1142
      nodes[jd].left = id;
1137 1143
      nodes[id].prev = -1;
1138 1144
      int num = 0;
1139 1145
      while (id != -1) {
1140 1146
        nodes[id].parent = jd;
1141 1147
        nodes[jd].right = id;
1142 1148
        id = nodes[id].next;
1143 1149
        ++num;
1144 1150
      }
1145 1151
      nodes[kd].size -= num;
1146 1152
      nodes[jd].size = num;
1147 1153
    }
1148 1154

	
1149 1155
    void pushLeft(int id, int jd) {
1150 1156
      nodes[id].size += 1;
1151 1157
      nodes[jd].next = nodes[id].left;
1152 1158
      nodes[jd].prev = -1;
1153 1159
      nodes[nodes[id].left].prev = jd;
1154 1160
      nodes[id].left = jd;
1155 1161
      nodes[jd].parent = id;
1156 1162
    }
1157 1163

	
1158 1164
    void popLeft(int id) {
1159 1165
      nodes[id].size -= 1;
1160 1166
      int jd = nodes[id].left;
1161 1167
      nodes[nodes[jd].next].prev = -1;
1162 1168
      nodes[id].left = nodes[jd].next;
1163 1169
    }
1164 1170

	
1165 1171
    void repairLeft(int id) {
1166 1172
      int jd = ~(classes[id].parent);
1167 1173
      while (nodes[jd].left != -1) {
1168 1174
        int kd = nodes[jd].left;
1169 1175
        if (nodes[jd].size == 1) {
1170 1176
          if (nodes[jd].parent < 0) {
1171 1177
            classes[id].parent = ~kd;
1172 1178
            classes[id].depth -= 1;
1173 1179
            nodes[kd].parent = ~id;
1174 1180
            deleteNode(jd);
1175 1181
            jd = kd;
1176 1182
          } else {
1177 1183
            int pd = nodes[jd].parent;
1178 1184
            if (nodes[nodes[jd].next].size < cmax) {
1179 1185
              pushLeft(nodes[jd].next, nodes[jd].left);
1180 1186
              if (less(jd, nodes[jd].next) ||
1181 1187
                  nodes[jd].item == nodes[pd].item) {
1182 1188
                nodes[nodes[jd].next].prio = nodes[jd].prio;
1183 1189
                nodes[nodes[jd].next].item = nodes[jd].item;
1184 1190
              }
1185 1191
              popLeft(pd);
1186 1192
              deleteNode(jd);
1187 1193
              jd = pd;
1188 1194
            } else {
1189 1195
              int ld = nodes[nodes[jd].next].left;
1190 1196
              popLeft(nodes[jd].next);
1191 1197
              pushRight(jd, ld);
1192
              if (less(ld, nodes[jd].left) || 
1198
              if (less(ld, nodes[jd].left) ||
1193 1199
                  nodes[ld].item == nodes[pd].item) {
1194 1200
                nodes[jd].item = nodes[ld].item;
1195 1201
                nodes[jd].prio = nodes[ld].prio;
1196 1202
              }
1197 1203
              if (nodes[nodes[jd].next].item == nodes[ld].item) {
1198 1204
                setPrio(nodes[jd].next);
1199 1205
              }
1200 1206
              jd = nodes[jd].left;
1201 1207
            }
1202 1208
          }
1203 1209
        } else {
1204 1210
          jd = nodes[jd].left;
1205 1211
        }
1206 1212
      }
1207 1213
    }
1208 1214

	
1209 1215
    void repairRight(int id) {
1210 1216
      int jd = ~(classes[id].parent);
1211 1217
      while (nodes[jd].right != -1) {
1212 1218
        int kd = nodes[jd].right;
1213 1219
        if (nodes[jd].size == 1) {
1214 1220
          if (nodes[jd].parent < 0) {
1215 1221
            classes[id].parent = ~kd;
1216 1222
            classes[id].depth -= 1;
1217 1223
            nodes[kd].parent = ~id;
1218 1224
            deleteNode(jd);
1219 1225
            jd = kd;
1220 1226
          } else {
1221 1227
            int pd = nodes[jd].parent;
1222 1228
            if (nodes[nodes[jd].prev].size < cmax) {
1223 1229
              pushRight(nodes[jd].prev, nodes[jd].right);
1224 1230
              if (less(jd, nodes[jd].prev) ||
1225 1231
                  nodes[jd].item == nodes[pd].item) {
1226 1232
                nodes[nodes[jd].prev].prio = nodes[jd].prio;
1227 1233
                nodes[nodes[jd].prev].item = nodes[jd].item;
1228 1234
              }
1229 1235
              popRight(pd);
1230 1236
              deleteNode(jd);
1231 1237
              jd = pd;
1232 1238
            } else {
1233 1239
              int ld = nodes[nodes[jd].prev].right;
1234 1240
              popRight(nodes[jd].prev);
1235 1241
              pushLeft(jd, ld);
1236 1242
              if (less(ld, nodes[jd].right) ||
1237 1243
                  nodes[ld].item == nodes[pd].item) {
1238 1244
                nodes[jd].item = nodes[ld].item;
1239 1245
                nodes[jd].prio = nodes[ld].prio;
1240 1246
              }
1241 1247
              if (nodes[nodes[jd].prev].item == nodes[ld].item) {
1242 1248
                setPrio(nodes[jd].prev);
1243 1249
              }
1244 1250
              jd = nodes[jd].right;
1245 1251
            }
1246 1252
          }
1247 1253
        } else {
1248 1254
          jd = nodes[jd].right;
1249 1255
        }
1250 1256
      }
1251 1257
    }
1252 1258

	
1253 1259

	
1254 1260
    bool less(int id, int jd) const {
1255 1261
      return comp(nodes[id].prio, nodes[jd].prio);
1256 1262
    }
1257 1263

	
1258 1264
  public:
1259 1265

	
1260 1266
    /// \brief Returns true when the given class is alive.
1261 1267
    ///
1262 1268
    /// Returns true when the given class is alive, ie. the class is
1263 1269
    /// not nested into other class.
1264 1270
    bool alive(int cls) const {
1265 1271
      return classes[cls].parent < 0;
1266 1272
    }
1267 1273

	
1268 1274
    /// \brief Returns true when the given class is trivial.
1269 1275
    ///
1270 1276
    /// Returns true when the given class is trivial, ie. the class
1271 1277
    /// contains just one item directly.
1272 1278
    bool trivial(int cls) const {
1273 1279
      return classes[cls].left == -1;
1274 1280
    }
1275 1281

	
1276 1282
    /// \brief Constructs the union-find.
1277 1283
    ///
1278 1284
    /// Constructs the union-find.
1279 1285
    /// \brief _index The index map of the union-find. The data
1280 1286
    /// structure uses internally for store references.
1281 1287
    HeapUnionFind(ItemIntMap& _index)
1282 1288
      : index(_index), first_class(-1),
1283 1289
        first_free_class(-1), first_free_node(-1) {}
1284 1290

	
1285 1291
    /// \brief Insert a new node into a new component.
1286 1292
    ///
1287 1293
    /// Insert a new node into a new component.
1288 1294
    /// \param item The item of the new node.
1289 1295
    /// \param prio The priority of the new node.
1290 1296
    /// \return The class id of the one-item-heap.
1291 1297
    int insert(const Item& item, const Value& prio) {
1292 1298
      int id = newNode();
1293 1299
      nodes[id].item = item;
1294 1300
      nodes[id].prio = prio;
1295 1301
      nodes[id].size = 0;
1296 1302

	
1297 1303
      nodes[id].prev = -1;
1298 1304
      nodes[id].next = -1;
1299 1305

	
1300 1306
      nodes[id].left = -1;
1301 1307
      nodes[id].right = -1;
1302 1308

	
1303 1309
      nodes[id].item = item;
1304 1310
      index[item] = id;
1305 1311

	
1306 1312
      int class_id = newClass();
1307 1313
      classes[class_id].parent = ~id;
1308 1314
      classes[class_id].depth = 0;
1309 1315

	
1310 1316
      classes[class_id].left = -1;
1311 1317
      classes[class_id].right = -1;
1312 1318

	
1313 1319
      if (first_class != -1) {
1314 1320
        classes[first_class].prev = class_id;
1315 1321
      }
1316 1322
      classes[class_id].next = first_class;
1317 1323
      classes[class_id].prev = -1;
1318 1324
      first_class = class_id;
1319 1325

	
1320 1326
      nodes[id].parent = ~class_id;
1321 1327

	
1322 1328
      return class_id;
1323 1329
    }
1324 1330

	
1325 1331
    /// \brief The class of the item.
1326 1332
    ///
1327 1333
    /// \return The alive class id of the item, which is not nested into
1328 1334
    /// other classes.
1329 1335
    ///
1330 1336
    /// The time complexity is O(log(n)).
1331 1337
    int find(const Item& item) const {
1332 1338
      return findClass(index[item]);
1333 1339
    }
1334 1340

	
1335 1341
    /// \brief Joins the classes.
1336 1342
    ///
1337 1343
    /// The current function joins the given classes. The parameter is
1338 1344
    /// an STL range which should be contains valid class ids. The
1339 1345
    /// time complexity is O(log(n)*k) where n is the overall number
1340 1346
    /// of the joined nodes and k is the number of classes.
1341 1347
    /// \return The class of the joined classes.
1342 1348
    /// \pre The range should contain at least two class ids.
1343 1349
    template <typename Iterator>
1344 1350
    int join(Iterator begin, Iterator end) {
1345 1351
      std::vector<int> cs;
1346 1352
      for (Iterator it = begin; it != end; ++it) {
1347 1353
        cs.push_back(*it);
1348 1354
      }
1349 1355

	
1350 1356
      int class_id = newClass();
1351 1357
      { // creation union-find
1352 1358

	
1353 1359
        if (first_class != -1) {
1354 1360
          classes[first_class].prev = class_id;
1355 1361
        }
1356 1362
        classes[class_id].next = first_class;
1357 1363
        classes[class_id].prev = -1;
1358 1364
        first_class = class_id;
1359 1365

	
1360 1366
        classes[class_id].depth = classes[cs[0]].depth;
1361 1367
        classes[class_id].parent = classes[cs[0]].parent;
1362 1368
        nodes[~(classes[class_id].parent)].parent = ~class_id;
1363 1369

	
1364 1370
        int l = cs[0];
1365 1371

	
1366 1372
        classes[class_id].left = l;
1367 1373
        classes[class_id].right = l;
1368 1374

	
1369 1375
        if (classes[l].next != -1) {
1370 1376
          classes[classes[l].next].prev = classes[l].prev;
1371 1377
        }
1372 1378
        classes[classes[l].prev].next = classes[l].next;
1373 1379

	
1374 1380
        classes[l].prev = -1;
1375 1381
        classes[l].next = -1;
1376 1382

	
1377 1383
        classes[l].depth = leftNode(l);
1378 1384
        classes[l].parent = class_id;
1379 1385

	
1380 1386
      }
1381 1387

	
1382 1388
      { // merging of heap
1383 1389
        int l = class_id;
1384 1390
        for (int ci = 1; ci < int(cs.size()); ++ci) {
1385 1391
          int r = cs[ci];
1386 1392
          int rln = leftNode(r);
1387 1393
          if (classes[l].depth > classes[r].depth) {
1388 1394
            int id = ~(classes[l].parent);
1389 1395
            for (int i = classes[r].depth + 1; i < classes[l].depth; ++i) {
1390 1396
              id = nodes[id].right;
1391 1397
            }
1392 1398
            while (id >= 0 && nodes[id].size == cmax) {
1393 1399
              int new_id = newNode();
1394 1400
              int right_id = nodes[id].right;
1395 1401

	
1396 1402
              popRight(id);
1397 1403
              if (nodes[id].item == nodes[right_id].item) {
1398 1404
                setPrio(id);
1399 1405
              }
1400 1406
              push(new_id, right_id);
1401 1407
              pushRight(new_id, ~(classes[r].parent));
1402 1408

	
1403 1409
              if (less(~classes[r].parent, right_id)) {
1404 1410
                nodes[new_id].item = nodes[~classes[r].parent].item;
1405 1411
                nodes[new_id].prio = nodes[~classes[r].parent].prio;
1406 1412
              } else {
1407 1413
                nodes[new_id].item = nodes[right_id].item;
1408 1414
                nodes[new_id].prio = nodes[right_id].prio;
1409 1415
              }
1410 1416

	
1411 1417
              id = nodes[id].parent;
1412 1418
              classes[r].parent = ~new_id;
1413 1419
            }
1414 1420
            if (id < 0) {
1415 1421
              int new_parent = newNode();
1416 1422
              nodes[new_parent].next = -1;
1417 1423
              nodes[new_parent].prev = -1;
1418 1424
              nodes[new_parent].parent = ~l;
1419 1425

	
1420 1426
              push(new_parent, ~(classes[l].parent));
1421 1427
              pushRight(new_parent, ~(classes[r].parent));
1422 1428
              setPrio(new_parent);
1423 1429

	
1424 1430
              classes[l].parent = ~new_parent;
1425 1431
              classes[l].depth += 1;
1426 1432
            } else {
1427 1433
              pushRight(id, ~(classes[r].parent));
1428 1434
              while (id >= 0 && less(~(classes[r].parent), id)) {
1429 1435
                nodes[id].prio = nodes[~(classes[r].parent)].prio;
1430 1436
                nodes[id].item = nodes[~(classes[r].parent)].item;
1431 1437
                id = nodes[id].parent;
1432 1438
              }
1433 1439
            }
1434 1440
          } else if (classes[r].depth > classes[l].depth) {
1435 1441
            int id = ~(classes[r].parent);
1436 1442
            for (int i = classes[l].depth + 1; i < classes[r].depth; ++i) {
1437 1443
              id = nodes[id].left;
1438 1444
            }
1439 1445
            while (id >= 0 && nodes[id].size == cmax) {
1440 1446
              int new_id = newNode();
1441 1447
              int left_id = nodes[id].left;
1442 1448

	
1443 1449
              popLeft(id);
1444 1450
              if (nodes[id].prio == nodes[left_id].prio) {
1445 1451
                setPrio(id);
1446 1452
              }
1447 1453
              push(new_id, left_id);
1448 1454
              pushLeft(new_id, ~(classes[l].parent));
1449 1455

	
1450 1456
              if (less(~classes[l].parent, left_id)) {
1451 1457
                nodes[new_id].item = nodes[~classes[l].parent].item;
1452 1458
                nodes[new_id].prio = nodes[~classes[l].parent].prio;
1453 1459
              } else {
1454 1460
                nodes[new_id].item = nodes[left_id].item;
1455 1461
                nodes[new_id].prio = nodes[left_id].prio;
1456 1462
              }
1457 1463

	
1458 1464
              id = nodes[id].parent;
1459 1465
              classes[l].parent = ~new_id;
1460 1466

	
1461 1467
            }
1462 1468
            if (id < 0) {
1463 1469
              int new_parent = newNode();
1464 1470
              nodes[new_parent].next = -1;
1465 1471
              nodes[new_parent].prev = -1;
1466 1472
              nodes[new_parent].parent = ~l;
1467 1473

	
1468 1474
              push(new_parent, ~(classes[r].parent));
1469 1475
              pushLeft(new_parent, ~(classes[l].parent));
1470 1476
              setPrio(new_parent);
1471 1477

	
1472 1478
              classes[r].parent = ~new_parent;
1473 1479
              classes[r].depth += 1;
1474 1480
            } else {
1475 1481
              pushLeft(id, ~(classes[l].parent));
1476 1482
              while (id >= 0 && less(~(classes[l].parent), id)) {
1477 1483
                nodes[id].prio = nodes[~(classes[l].parent)].prio;
1478 1484
                nodes[id].item = nodes[~(classes[l].parent)].item;
1479 1485
                id = nodes[id].parent;
1480 1486
              }
1481 1487
            }
1482 1488
            nodes[~(classes[r].parent)].parent = ~l;
1483 1489
            classes[l].parent = classes[r].parent;
1484 1490
            classes[l].depth = classes[r].depth;
1485 1491
          } else {
1486 1492
            if (classes[l].depth != 0 &&
1487 1493
                nodes[~(classes[l].parent)].size +
1488 1494
                nodes[~(classes[r].parent)].size <= cmax) {
1489 1495
              splice(~(classes[l].parent), ~(classes[r].parent));
1490 1496
              deleteNode(~(classes[r].parent));
1491 1497
              if (less(~(classes[r].parent), ~(classes[l].parent))) {
1492 1498
                nodes[~(classes[l].parent)].prio =
1493 1499
                  nodes[~(classes[r].parent)].prio;
1494 1500
                nodes[~(classes[l].parent)].item =
1495 1501
                  nodes[~(classes[r].parent)].item;
1496 1502
              }
1497 1503
            } else {
1498 1504
              int new_parent = newNode();
1499 1505
              nodes[new_parent].next = nodes[new_parent].prev = -1;
1500 1506
              push(new_parent, ~(classes[l].parent));
1501 1507
              pushRight(new_parent, ~(classes[r].parent));
1502 1508
              setPrio(new_parent);
1503 1509

	
1504 1510
              classes[l].parent = ~new_parent;
1505 1511
              classes[l].depth += 1;
1506 1512
              nodes[new_parent].parent = ~l;
1507 1513
            }
1508 1514
          }
1509 1515
          if (classes[r].next != -1) {
1510 1516
            classes[classes[r].next].prev = classes[r].prev;
1511 1517
          }
1512 1518
          classes[classes[r].prev].next = classes[r].next;
1513 1519

	
1514 1520
          classes[r].prev = classes[l].right;
1515 1521
          classes[classes[l].right].next = r;
1516 1522
          classes[l].right = r;
1517 1523
          classes[r].parent = l;
1518 1524

	
1519 1525
          classes[r].next = -1;
1520 1526
          classes[r].depth = rln;
1521 1527
        }
1522 1528
      }
1523 1529
      return class_id;
1524 1530
    }
1525 1531

	
1526 1532
    /// \brief Split the class to subclasses.
1527 1533
    ///
1528 1534
    /// The current function splits the given class. The join, which
1529 1535
    /// made the current class, stored a reference to the
1530 1536
    /// subclasses. The \c splitClass() member restores the classes
1531 1537
    /// and creates the heaps. The parameter is an STL output iterator
1532 1538
    /// which will be filled with the subclass ids. The time
1533 1539
    /// complexity is O(log(n)*k) where n is the overall number of
1534 1540
    /// nodes in the splitted classes and k is the number of the
1535 1541
    /// classes.
1536 1542
    template <typename Iterator>
1537 1543
    void split(int cls, Iterator out) {
1538 1544
      std::vector<int> cs;
1539 1545
      { // splitting union-find
1540 1546
        int id = cls;
1541 1547
        int l = classes[id].left;
1542 1548

	
1543 1549
        classes[l].parent = classes[id].parent;
1544 1550
        classes[l].depth = classes[id].depth;
1545 1551

	
1546 1552
        nodes[~(classes[l].parent)].parent = ~l;
1547 1553

	
1548 1554
        *out++ = l;
1549 1555

	
1550 1556
        while (l != -1) {
1551 1557
          cs.push_back(l);
1552 1558
          l = classes[l].next;
1553 1559
        }
1554 1560

	
1555 1561
        classes[classes[id].right].next = first_class;
1556 1562
        classes[first_class].prev = classes[id].right;
1557 1563
        first_class = classes[id].left;
1558 1564

	
1559 1565
        if (classes[id].next != -1) {
1560 1566
          classes[classes[id].next].prev = classes[id].prev;
1561 1567
        }
1562 1568
        classes[classes[id].prev].next = classes[id].next;
1563 1569

	
1564 1570
        deleteClass(id);
1565 1571
      }
1566 1572

	
1567 1573
      {
1568 1574
        for (int i = 1; i < int(cs.size()); ++i) {
1569 1575
          int l = classes[cs[i]].depth;
1570 1576
          while (nodes[nodes[l].parent].left == l) {
1571 1577
            l = nodes[l].parent;
1572 1578
          }
1573 1579
          int r = l;
1574 1580
          while (nodes[l].parent >= 0) {
1575 1581
            l = nodes[l].parent;
1576 1582
            int new_node = newNode();
1577 1583

	
1578 1584
            nodes[new_node].prev = -1;
1579 1585
            nodes[new_node].next = -1;
1580 1586

	
1581 1587
            split(r, new_node);
1582 1588
            pushAfter(l, new_node);
1583 1589
            setPrio(l);
1584 1590
            setPrio(new_node);
1585 1591
            r = new_node;
1586 1592
          }
1587 1593
          classes[cs[i]].parent = ~r;
1588 1594
          classes[cs[i]].depth = classes[~(nodes[l].parent)].depth;
1589 1595
          nodes[r].parent = ~cs[i];
1590 1596

	
1591 1597
          nodes[l].next = -1;
1592 1598
          nodes[r].prev = -1;
1593 1599

	
1594 1600
          repairRight(~(nodes[l].parent));
1595 1601
          repairLeft(cs[i]);
1596 1602

	
1597 1603
          *out++ = cs[i];
1598 1604
        }
1599 1605
      }
1600 1606
    }
1601 1607

	
1602 1608
    /// \brief Gives back the priority of the current item.
1603 1609
    ///
1604
    /// \return Gives back the priority of the current item.
1610
    /// Gives back the priority of the current item.
1605 1611
    const Value& operator[](const Item& item) const {
1606 1612
      return nodes[index[item]].prio;
1607 1613
    }
1608 1614

	
1609 1615
    /// \brief Sets the priority of the current item.
1610 1616
    ///
1611 1617
    /// Sets the priority of the current item.
1612 1618
    void set(const Item& item, const Value& prio) {
1613 1619
      if (comp(prio, nodes[index[item]].prio)) {
1614 1620
        decrease(item, prio);
1615 1621
      } else if (!comp(prio, nodes[index[item]].prio)) {
1616 1622
        increase(item, prio);
1617 1623
      }
1618 1624
    }
1619 1625

	
1620 1626
    /// \brief Increase the priority of the current item.
1621 1627
    ///
1622 1628
    /// Increase the priority of the current item.
1623 1629
    void increase(const Item& item, const Value& prio) {
1624 1630
      int id = index[item];
1625 1631
      int kd = nodes[id].parent;
1626 1632
      nodes[id].prio = prio;
1627 1633
      while (kd >= 0 && nodes[kd].item == item) {
1628 1634
        setPrio(kd);
1629 1635
        kd = nodes[kd].parent;
1630 1636
      }
1631 1637
    }
1632 1638

	
1633 1639
    /// \brief Increase the priority of the current item.
1634 1640
    ///
1635 1641
    /// Increase the priority of the current item.
1636 1642
    void decrease(const Item& item, const Value& prio) {
1637 1643
      int id = index[item];
1638 1644
      int kd = nodes[id].parent;
1639 1645
      nodes[id].prio = prio;
1640 1646
      while (kd >= 0 && less(id, kd)) {
1641 1647
        nodes[kd].prio = prio;
1642 1648
        nodes[kd].item = item;
1643 1649
        kd = nodes[kd].parent;
1644 1650
      }
1645 1651
    }
1646 1652

	
1647 1653
    /// \brief Gives back the minimum priority of the class.
1648 1654
    ///
1649
    /// \return Gives back the minimum priority of the class.
1655
    /// Gives back the minimum priority of the class.
1650 1656
    const Value& classPrio(int cls) const {
1651 1657
      return nodes[~(classes[cls].parent)].prio;
1652 1658
    }
1653 1659

	
1654 1660
    /// \brief Gives back the minimum priority item of the class.
1655 1661
    ///
1656 1662
    /// \return Gives back the minimum priority item of the class.
1657 1663
    const Item& classTop(int cls) const {
1658 1664
      return nodes[~(classes[cls].parent)].item;
1659 1665
    }
1660 1666

	
1661 1667
    /// \brief Gives back a representant item of the class.
1662 1668
    ///
1669
    /// Gives back a representant item of the class.
1663 1670
    /// The representant is indpendent from the priorities of the
1664 1671
    /// items.
1665
    /// \return Gives back a representant item of the class.
1666 1672
    const Item& classRep(int id) const {
1667 1673
      int parent = classes[id].parent;
1668 1674
      return nodes[parent >= 0 ? classes[id].depth : leftNode(id)].item;
1669 1675
    }
1670 1676

	
1671 1677
    /// \brief LEMON style iterator for the items of a class.
1672 1678
    ///
1673 1679
    /// ClassIt is a lemon style iterator for the components. It iterates
1674 1680
    /// on the items of a class. By example if you want to iterate on
1675 1681
    /// each items of each classes then you may write the next code.
1676 1682
    ///\code
1677 1683
    /// for (ClassIt cit(huf); cit != INVALID; ++cit) {
1678 1684
    ///   std::cout << "Class: ";
1679 1685
    ///   for (ItemIt iit(huf, cit); iit != INVALID; ++iit) {
1680 1686
    ///     std::cout << toString(iit) << ' ' << std::endl;
1681 1687
    ///   }
1682 1688
    ///   std::cout << std::endl;
1683 1689
    /// }
1684 1690
    ///\endcode
1685 1691
    class ItemIt {
1686 1692
    private:
1687 1693

	
1688 1694
      const HeapUnionFind* _huf;
1689 1695
      int _id, _lid;
1690 1696

	
1691 1697
    public:
1692 1698

	
1693 1699
      /// \brief Default constructor
1694 1700
      ///
1695 1701
      /// Default constructor
1696 1702
      ItemIt() {}
1697 1703

	
1698 1704
      ItemIt(const HeapUnionFind& huf, int cls) : _huf(&huf) {
1699 1705
        int id = cls;
1700 1706
        int parent = _huf->classes[id].parent;
1701 1707
        if (parent >= 0) {
1702 1708
          _id = _huf->classes[id].depth;
1703 1709
          if (_huf->classes[id].next != -1) {
1704 1710
            _lid = _huf->classes[_huf->classes[id].next].depth;
1705 1711
          } else {
1706 1712
            _lid = -1;
1707 1713
          }
1708 1714
        } else {
1709 1715
          _id = _huf->leftNode(id);
1710 1716
          _lid = -1;
1711 1717
        }
1712 1718
      }
1713 1719

	
1714 1720
      /// \brief Increment operator
1715 1721
      ///
1716 1722
      /// It steps to the next item in the class.
1717 1723
      ItemIt& operator++() {
1718 1724
        _id = _huf->nextNode(_id);
1719 1725
        return *this;
1720 1726
      }
1721 1727

	
1722 1728
      /// \brief Conversion operator
1723 1729
      ///
1724 1730
      /// It converts the iterator to the current item.
1725 1731
      operator const Item&() const {
1726 1732
        return _huf->nodes[_id].item;
1727 1733
      }
1728 1734

	
1729 1735
      /// \brief Equality operator
1730 1736
      ///
1731 1737
      /// Equality operator
1732 1738
      bool operator==(const ItemIt& i) {
1733 1739
        return i._id == _id;
1734 1740
      }
1735 1741

	
1736 1742
      /// \brief Inequality operator
1737 1743
      ///
1738 1744
      /// Inequality operator
1739 1745
      bool operator!=(const ItemIt& i) {
1740 1746
        return i._id != _id;
1741 1747
      }
1742 1748

	
1743 1749
      /// \brief Equality operator
1744 1750
      ///
1745 1751
      /// Equality operator
1746 1752
      bool operator==(Invalid) {
1747 1753
        return _id == _lid;
1748 1754
      }
1749 1755

	
1750 1756
      /// \brief Inequality operator
1751 1757
      ///
1752 1758
      /// Inequality operator
1753 1759
      bool operator!=(Invalid) {
1754 1760
        return _id != _lid;
1755 1761
      }
1756 1762

	
1757 1763
    };
1758 1764

	
1759 1765
    /// \brief Class iterator
1760 1766
    ///
1761 1767
    /// The iterator stores
1762 1768
    class ClassIt {
1763 1769
    private:
1764 1770

	
1765 1771
      const HeapUnionFind* _huf;
1766 1772
      int _id;
1767 1773

	
1768 1774
    public:
1769 1775

	
1770 1776
      ClassIt(const HeapUnionFind& huf)
1771 1777
        : _huf(&huf), _id(huf.first_class) {}
1772 1778

	
1773 1779
      ClassIt(const HeapUnionFind& huf, int cls)
1774 1780
        : _huf(&huf), _id(huf.classes[cls].left) {}
1775 1781

	
1776 1782
      ClassIt(Invalid) : _huf(0), _id(-1) {}
1777 1783

	
1778 1784
      const ClassIt& operator++() {
1779 1785
        _id = _huf->classes[_id].next;
1780 1786
        return *this;
1781 1787
      }
1782 1788

	
1783 1789
      /// \brief Equality operator
1784 1790
      ///
1785 1791
      /// Equality operator
1786 1792
      bool operator==(const ClassIt& i) {
1787 1793
        return i._id == _id;
1788 1794
      }
1789 1795

	
1790 1796
      /// \brief Inequality operator
1791 1797
      ///
1792 1798
      /// Inequality operator
1793 1799
      bool operator!=(const ClassIt& i) {
1794 1800
        return i._id != _id;
1795 1801
      }
1796 1802

	
1797 1803
      operator int() const {
1798 1804
        return _id;
1799 1805
      }
1800 1806

	
1801 1807
    };
1802 1808

	
1803 1809
  };
1804 1810

	
1805 1811
  //! @}
1806 1812

	
1807 1813
} //namespace lemon
1808 1814

	
1809 1815
#endif //LEMON_UNION_FIND_H
Ignore white space 6 line context
1 1
AC_DEFUN([LX_CHECK_CPLEX],
2 2
[
3 3
  AC_ARG_WITH([cplex],
4 4
AS_HELP_STRING([--with-cplex@<:@=PREFIX@:>@], [search for CPLEX under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
5 5
AS_HELP_STRING([--without-cplex], [disable checking for CPLEX]),
6 6
              [], [with_cplex=yes])
7 7

	
8 8
  AC_ARG_WITH([cplex-includedir],
9 9
AS_HELP_STRING([--with-cplex-includedir=DIR], [search for CPLEX headers in DIR]),
10 10
              [], [with_cplex_includedir=no])
11 11

	
12 12
  AC_ARG_WITH([cplex-libdir],
13 13
AS_HELP_STRING([--with-cplex-libdir=DIR], [search for CPLEX libraries in DIR]),
14 14
              [], [with_cplex_libdir=no])
15 15

	
16 16
  lx_cplex_found=no
17 17
  if test x"$with_cplex" != x"no"; then
18 18
    AC_MSG_CHECKING([for CPLEX])
19 19

	
20 20
    if test x"$with_cplex_includedir" != x"no"; then
21 21
      CPLEX_CFLAGS="-I$with_cplex_includedir"
22 22
    elif test x"$with_cplex" != x"yes"; then
23 23
      CPLEX_CFLAGS="-I$with_cplex/include"
24 24
    elif test x"$CPLEX_INCLUDEDIR" != x; then
25 25
      CPLEX_CFLAGS="-I$CPLEX_INCLUDEDIR"
26 26
    fi
27 27

	
28 28
    if test x"$with_cplex_libdir" != x"no"; then
29 29
      CPLEX_LDFLAGS="-L$with_cplex_libdir"
30 30
    elif test x"$with_cplex" != x"yes"; then
31 31
      CPLEX_LDFLAGS="-L$with_cplex/lib"
32 32
    elif test x"$CPLEX_LIBDIR" != x; then
33 33
      CPLEX_LDFLAGS="-L$CPLEX_LIBDIR"
34 34
    fi
35 35
    CPLEX_LIBS="-lcplex -lm -lpthread"
36 36

	
37 37
    lx_save_cxxflags="$CXXFLAGS"
38 38
    lx_save_ldflags="$LDFLAGS"
39 39
    lx_save_libs="$LIBS"
40 40
    CXXFLAGS="$CPLEX_CFLAGS"
41 41
    LDFLAGS="$CPLEX_LDFLAGS"
42 42
    LIBS="$CPLEX_LIBS"
43 43

	
44 44
    lx_cplex_test_prog='
45 45
      extern "C" {
46 46
      #include <ilcplex/cplex.h>
47 47
      }
48 48

	
49 49
      int main(int argc, char** argv)
50 50
      {
51 51
        CPXENVptr env = NULL;
52 52
        return 0;
53 53
      }'
54 54

	
55 55
    AC_LANG_PUSH(C++)
56 56
    AC_LINK_IFELSE([$lx_cplex_test_prog], [lx_cplex_found=yes], [lx_cplex_found=no])
57 57
    AC_LANG_POP(C++)
58 58

	
59 59
    CXXFLAGS="$lx_save_cxxflags"
60 60
    LDFLAGS="$lx_save_ldflags"
61 61
    LIBS="$lx_save_libs"
62 62

	
63 63
    if test x"$lx_cplex_found" = x"yes"; then
64 64
      AC_DEFINE([LEMON_HAVE_CPLEX], [1], [Define to 1 if you have CPLEX.])
65
      lx_lp_found=yes
66
      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
67
      lx_mip_found=yes
68
      AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
65 69
      AC_MSG_RESULT([yes])
66 70
    else
67 71
      CPLEX_CFLAGS=""
68 72
      CPLEX_LDFLAGS=""
69 73
      CPLEX_LIBS=""
70 74
      AC_MSG_RESULT([no])
71 75
    fi
72 76
  fi
73 77
  CPLEX_LIBS="$CPLEX_LDFLAGS $CPLEX_LIBS"
74 78
  AC_SUBST(CPLEX_CFLAGS)
75 79
  AC_SUBST(CPLEX_LIBS)
76 80
  AM_CONDITIONAL([HAVE_CPLEX], [test x"$lx_cplex_found" = x"yes"])
77 81
])
Ignore white space 6 line context
1 1
AC_DEFUN([LX_CHECK_GLPK],
2 2
[
3 3
  AC_ARG_WITH([glpk],
4 4
AS_HELP_STRING([--with-glpk@<:@=PREFIX@:>@], [search for GLPK under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
5 5
AS_HELP_STRING([--without-glpk], [disable checking for GLPK]),
6 6
              [], [with_glpk=yes])
7 7

	
8 8
  AC_ARG_WITH([glpk-includedir],
9 9
AS_HELP_STRING([--with-glpk-includedir=DIR], [search for GLPK headers in DIR]),
10 10
              [], [with_glpk_includedir=no])
11 11

	
12 12
  AC_ARG_WITH([glpk-libdir],
13 13
AS_HELP_STRING([--with-glpk-libdir=DIR], [search for GLPK libraries in DIR]),
14 14
              [], [with_glpk_libdir=no])
15 15

	
16 16
  lx_glpk_found=no
17 17
  if test x"$with_glpk" != x"no"; then
18 18
    AC_MSG_CHECKING([for GLPK])
19 19

	
20 20
    if test x"$with_glpk_includedir" != x"no"; then
21 21
      GLPK_CFLAGS="-I$with_glpk_includedir"
22 22
    elif test x"$with_glpk" != x"yes"; then
23 23
      GLPK_CFLAGS="-I$with_glpk/include"
24 24
    fi
25 25

	
26 26
    if test x"$with_glpk_libdir" != x"no"; then
27 27
      GLPK_LDFLAGS="-L$with_glpk_libdir"
28 28
    elif test x"$with_glpk" != x"yes"; then
29 29
      GLPK_LDFLAGS="-L$with_glpk/lib"
30 30
    fi
31 31
    GLPK_LIBS="-lglpk"
32 32

	
33 33
    lx_save_cxxflags="$CXXFLAGS"
34 34
    lx_save_ldflags="$LDFLAGS"
35 35
    lx_save_libs="$LIBS"
36 36
    CXXFLAGS="$GLPK_CFLAGS"
37 37
    LDFLAGS="$GLPK_LDFLAGS"
38 38
    LIBS="$GLPK_LIBS"
39 39

	
40 40
    lx_glpk_test_prog='
41 41
      extern "C" {
42 42
      #include <glpk.h>
43 43
      }
44 44

	
45
      #if (GLP_MAJOR_VERSION < 4) \
46
         || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION < 33)
47
      #error Supported GLPK versions: 4.33 or above
48
      #endif
49

	
45 50
      int main(int argc, char** argv)
46 51
      {
47 52
        LPX *lp;
48 53
        lp = lpx_create_prob();
49 54
        lpx_delete_prob(lp);
50 55
        return 0;
51 56
      }'
52 57

	
53 58
    AC_LANG_PUSH(C++)
54 59
    AC_LINK_IFELSE([$lx_glpk_test_prog], [lx_glpk_found=yes], [lx_glpk_found=no])
55 60
    AC_LANG_POP(C++)
56 61

	
57 62
    CXXFLAGS="$lx_save_cxxflags"
58 63
    LDFLAGS="$lx_save_ldflags"
59 64
    LIBS="$lx_save_libs"
60 65

	
61 66
    if test x"$lx_glpk_found" = x"yes"; then
62 67
      AC_DEFINE([LEMON_HAVE_GLPK], [1], [Define to 1 if you have GLPK.])
68
      lx_lp_found=yes
69
      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
70
      lx_mip_found=yes
71
      AC_DEFINE([LEMON_HAVE_MIP], [1], [Define to 1 if you have any MIP solver.])
63 72
      AC_MSG_RESULT([yes])
64 73
    else
65 74
      GLPK_CFLAGS=""
66 75
      GLPK_LDFLAGS=""
67 76
      GLPK_LIBS=""
68 77
      AC_MSG_RESULT([no])
69 78
    fi
70 79
  fi
71 80
  GLPK_LIBS="$GLPK_LDFLAGS $GLPK_LIBS"
72 81
  AC_SUBST(GLPK_CFLAGS)
73 82
  AC_SUBST(GLPK_LIBS)
74 83
  AM_CONDITIONAL([HAVE_GLPK], [test x"$lx_glpk_found" = x"yes"])
75 84
])
Ignore white space 6 line context
1 1
AC_DEFUN([LX_CHECK_SOPLEX],
2 2
[
3 3
  AC_ARG_WITH([soplex],
4 4
AS_HELP_STRING([--with-soplex@<:@=PREFIX@:>@], [search for SOPLEX under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@])
5 5
AS_HELP_STRING([--without-soplex], [disable checking for SOPLEX]),
6 6
              [], [with_soplex=yes])
7 7

	
8 8
  AC_ARG_WITH([soplex-includedir],
9 9
AS_HELP_STRING([--with-soplex-includedir=DIR], [search for SOPLEX headers in DIR]),
10 10
              [], [with_soplex_includedir=no])
11 11

	
12 12
  AC_ARG_WITH([soplex-libdir],
13 13
AS_HELP_STRING([--with-soplex-libdir=DIR], [search for SOPLEX libraries in DIR]),
14 14
              [], [with_soplex_libdir=no])
15 15

	
16 16
  lx_soplex_found=no
17 17
  if test x"$with_soplex" != x"no"; then
18 18
    AC_MSG_CHECKING([for SOPLEX])
19 19

	
20 20
    if test x"$with_soplex_includedir" != x"no"; then
21 21
      SOPLEX_CXXFLAGS="-I$with_soplex_includedir"
22 22
    elif test x"$with_soplex" != x"yes"; then
23
      SOPLEX_CXXFLAGS="-I$with_soplex/include"
23
      SOPLEX_CXXFLAGS="-I$with_soplex/src"
24 24
    fi
25 25

	
26 26
    if test x"$with_soplex_libdir" != x"no"; then
27 27
      SOPLEX_LDFLAGS="-L$with_soplex_libdir"
28 28
    elif test x"$with_soplex" != x"yes"; then
29 29
      SOPLEX_LDFLAGS="-L$with_soplex/lib"
30 30
    fi
31 31
    SOPLEX_LIBS="-lsoplex -lz"
32 32

	
33 33
    lx_save_cxxflags="$CXXFLAGS"
34 34
    lx_save_ldflags="$LDFLAGS"
35 35
    lx_save_libs="$LIBS"
36 36
    CXXFLAGS="$SOPLEX_CXXFLAGS"
37 37
    LDFLAGS="$SOPLEX_LDFLAGS"
38 38
    LIBS="$SOPLEX_LIBS"
39 39

	
40 40
    lx_soplex_test_prog='
41
      #include <soplex/soplex.h>
41
      #include <soplex.h>
42 42

	
43 43
      int main(int argc, char** argv)
44 44
      {
45 45
        soplex::SoPlex soplex;
46 46
        return 0;
47 47
      }'
48 48

	
49 49
    AC_LANG_PUSH(C++)
50 50
    AC_LINK_IFELSE([$lx_soplex_test_prog], [lx_soplex_found=yes], [lx_soplex_found=no])
51 51
    AC_LANG_POP(C++)
52 52

	
53 53
    CXXFLAGS="$lx_save_cxxflags"
54 54
    LDFLAGS="$lx_save_ldflags"
55 55
    LIBS="$lx_save_libs"
56 56

	
57 57
    if test x"$lx_soplex_found" = x"yes"; then
58 58
      AC_DEFINE([LEMON_HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.])
59
      lx_lp_found=yes
60
      AC_DEFINE([LEMON_HAVE_LP], [1], [Define to 1 if you have any LP solver.])
59 61
      AC_MSG_RESULT([yes])
60 62
    else
61 63
      SOPLEX_CXXFLAGS=""
62 64
      SOPLEX_LDFLAGS=""
63 65
      SOPLEX_LIBS=""
64 66
      AC_MSG_RESULT([no])
65 67
    fi
66 68
  fi
67 69
  SOPLEX_LIBS="$SOPLEX_LDFLAGS $SOPLEX_LIBS"
68 70
  AC_SUBST(SOPLEX_CXXFLAGS)
69 71
  AC_SUBST(SOPLEX_LIBS)
70 72
  AM_CONDITIONAL([HAVE_SOPLEX], [test x"$lx_soplex_found" = x"yes"])
71 73
])
Ignore white space 6 line context
1 1
#! /usr/bin/env python
2 2

	
3 3
import sys
4
import os
4

	
5
from mercurial import ui, hg
6
from mercurial import util
7

	
8
util.rcpath = lambda : []
5 9

	
6 10
if len(sys.argv)>1 and sys.argv[1] in ["-h","--help"]:
7 11
    print """
8 12
This utility just prints the length of the longest path
9 13
in the revision graph from revison 0 to the current one.
10 14
"""
11 15
    exit(0)
12
plist = os.popen("HGRCPATH='' hg parents --template='{rev}\n'").readlines()
13
if len(plist)>1:
14
    print "You are in the process of merging"
15
    exit(1)
16
PAR = int(plist[0])
17 16

	
18
f = os.popen("HGRCPATH='' hg log -r 0:tip --template='{rev} {parents}\n'").\
19
    readlines()
20
REV = -1
21
lengths=[]
22
for l in f:
23
    REV+=1
24
    s = l.split()
25
    rev = int(s[0])
26
    if REV != rev:
27
        print "Something is seriously wrong"
28
        exit(1)
29
    if len(s) == 1:
30
        par1 = par2 = rev - 1
31
    elif len(s) == 2:
32
        par1 = par2 = int(s[1].split(":")[0])
17
u = ui.ui()
18
r = hg.repository(u, ".")
19
N = r.changectx(".").rev()
20
lengths=[0]*(N+1)
21
for i in range(N+1):
22
    p=r.changectx(i).parents()
23
    if p[0]:
24
        p0=lengths[p[0].rev()]
33 25
    else:
34
        par1 = int(s[1].split(":")[0])
35
        par2 = int(s[2].split(":")[0])
36
    if rev == 0:
37
        lengths.append(0)
26
        p0=-1
27
    if len(p)>1 and p[1]:
28
        p1=lengths[p[1].rev()]
38 29
    else:
39
        lengths.append(max(lengths[par1],lengths[par2])+1)
40
print lengths[PAR]
30
        p1=-1
31
    lengths[i]=max(p0,p1)+1
32
print lengths[N]
Ignore white space 6 line context
1 1
#!/bin/bash
2 2

	
3 3
set -e
4 4

	
5 5
if [ $# = 0 ]; then
6 6
    echo "Usage: $0 release-id"
7 7
    exit 1
8 8
else
9 9
    export LEMON_VERSION=$1
10 10
fi
11 11

	
12 12
echo '*****************************************************************'
13 13
echo ' Start making release tarballs for version '${LEMON_VERSION}
14 14
echo '*****************************************************************'
15 15

	
16 16
autoreconf -vif
17
./configure --enable-demo
17
./configure
18 18

	
19 19
make
20 20
make html
21 21
make distcheck
22 22
tar xf lemon-${LEMON_VERSION}.tar.gz
23 23
zip -r lemon-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
24 24
mv lemon-${LEMON_VERSION}/doc/html lemon-doc-${LEMON_VERSION}
25 25
tar czf lemon-doc-${LEMON_VERSION}.tar.gz lemon-doc-${LEMON_VERSION}
26 26
zip -r lemon-doc-${LEMON_VERSION}.zip lemon-doc-${LEMON_VERSION}
27 27
tar czf lemon-nodoc-${LEMON_VERSION}.tar.gz lemon-${LEMON_VERSION}
28 28
zip -r lemon-nodoc-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
29 29
hg tag -m 'LEMON '${LEMON_VERSION}' released ('$(hg par --template="{node|short}")' tagged as r'${LEMON_VERSION}')' r${LEMON_VERSION}
30 30

	
31 31
rm -rf lemon-${LEMON_VERSION} lemon-doc-${LEMON_VERSION}
32 32

	
33 33
echo '*****************************************************************'
34 34
echo '  Release '${LEMON_VERSION}' has been created' 
35 35
echo '*****************************************************************'
Ignore white space 6 line context
1 1
#!/bin/bash
2 2

	
3
YEAR=`date +2003-%Y`
3
YEAR=`date +%Y`
4 4
HGROOT=`hg root`
5 5

	
6
function update_header() {
6
function hg_year() {
7
    if [ -n "$(hg st $1)" ]; then
8
        echo $YEAR
9
    else
10
        hg log -l 1 --template='{date|isodate}\n' $1 |
11
        cut -d '-' -f 1
12
    fi
13
}
14

	
15
# file enumaration modes
16

	
17
function all_files() {
18
    hg status -a -m -c |
19
    cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
20
    while read file; do echo $HGROOT/$file; done
21
}
22

	
23
function modified_files() {
24
    hg status -a -m |
25
    cut -d ' ' -f 2 | grep -E  '(\.(cc|h|dox)$|Makefile\.am$)' |
26
    while read file; do echo $HGROOT/$file; done
27
}
28

	
29
function changed_files() {
30
    {
31
        if [ -n "$HG_PARENT1" ]
32
        then
33
            hg status --rev $HG_PARENT1:$HG_NODE -a -m
34
        fi
35
        if [ -n "$HG_PARENT2" ]
36
        then
37
            hg status --rev $HG_PARENT2:$HG_NODE -a -m
38
        fi
39
    } | cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' | 
40
    sort | uniq |
41
    while read file; do echo $HGROOT/$file; done
42
}
43

	
44
function given_files() {
45
    for file in $GIVEN_FILES
46
    do
47
	echo $file
48
    done
49
}
50

	
51
# actions
52

	
53
function update_action() {
54
    if ! diff -q $1 $2 >/dev/null
55
    then
56
	echo -n " [$3 updated]"
57
	rm $2
58
	mv $1 $2
59
	CHANGED=YES
60
    fi
61
}
62

	
63
function update_warning() {
64
    echo -n " [$2 warning]"
65
    WARNED=YES
66
}
67

	
68
function update_init() {
69
    echo Update source files...
70
    TOTAL_FILES=0
71
    CHANGED_FILES=0
72
    WARNED_FILES=0
73
}
74

	
75
function update_done() {
76
    echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
77
    echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
78
}
79

	
80
function update_begin() {
81
    ((TOTAL_FILES++))
82
    CHANGED=NO
83
    WARNED=NO
84
}
85

	
86
function update_end() {
87
    if [ $CHANGED == YES ]
88
    then
89
	((++CHANGED_FILES))
90
    fi
91
    if [ $WARNED == YES ]
92
    then
93
	((++WARNED_FILES))
94
    fi
95
}
96

	
97
function check_action() {
98
    if [ "$3" == 'tabs' ]
99
    then
100
        if echo $2 | grep -q -v -E 'Makefile\.am$'
101
        then
102
            PATTERN=$(echo -e '\t')
103
        else
104
            PATTERN='        '
105
        fi
106
    elif [ "$3" == 'trailing spaces' ]
107
    then
108
        PATTERN='\ +$'
109
    else
110
        PATTERN='*'
111
    fi
112

	
113
    if ! diff -q $1 $2 >/dev/null
114
    then
115
        if [ "$PATTERN" == '*' ]
116
        then
117
            diff $1 $2 | grep '^[0-9]' | sed "s|^\(.*\)c.*$|$2:\1: check failed: $3|g" |
118
              sed "s/:\([0-9]*\),\([0-9]*\):\(.*\)$/:\1:\3 (until line \2)/g"
119
        else
120
            grep -n -E "$PATTERN" $2 | sed "s|^\([0-9]*\):.*$|$2:\1: check failed: $3|g"
121
        fi
122
        FAILED=YES
123
    fi
124
}
125

	
126
function check_warning() {
127
    if [ "$2" == 'long lines' ]
128
    then
129
        grep -n -E '.{81,}' $1 | sed "s|^\([0-9]*\):.*$|$1:\1: warning: $2|g"
130
    else
131
        echo "$1: warning: $2"
132
    fi
133
    WARNED=YES
134
}
135

	
136
function check_init() {
137
    echo Check source files...
138
    FAILED_FILES=0
139
    WARNED_FILES=0
140
    TOTAL_FILES=0
141
}
142

	
143
function check_done() {
144
    echo $FAILED_FILES out of $TOTAL_FILES files has been failed.
145
    echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
146

	
147
    if [ $WARNED_FILES -gt 0 -o $FAILED_FILES -gt 0 ]
148
    then
149
	if [ "$WARNING" == 'INTERACTIVE' ]
150
	then
151
	    echo -n "Are the files with errors/warnings acceptable? (yes/no) "
152
	    while read answer
153
	    do
154
		if [ "$answer" == 'yes' ]
155
		then
156
		    return 0
157
		elif [ "$answer" == 'no' ]
158
		then
159
		    return 1
160
		fi
161
		echo -n "Are the files with errors/warnings acceptable? (yes/no) "
162
	    done
163
	elif [ "$WARNING" == 'WERROR' ]
164
	then
165
	    return 1
166
	fi
167
    fi
168
}
169

	
170
function check_begin() {
171
    ((TOTAL_FILES++))
172
    FAILED=NO
173
    WARNED=NO
174
}
175

	
176
function check_end() {
177
    if [ $FAILED == YES ]
178
    then
179
	((++FAILED_FILES))
180
    fi
181
    if [ $WARNED == YES ]
182
    then
183
	((++WARNED_FILES))
184
    fi
185
}
186

	
187

	
188

	
189
# checks
190

	
191
function header_check() {
192
    if echo $1 | grep -q -E 'Makefile\.am$'
193
    then
194
	return
195
    fi
196

	
7 197
    TMP_FILE=`mktemp`
8
    FILE_NAME=$1
9 198

	
10 199
    (echo "/* -*- mode: C++; indent-tabs-mode: nil; -*-
11 200
 *
12 201
 * This file is a part of LEMON, a generic C++ optimization library.
13 202
 *
14
 * Copyright (C) "$YEAR"
203
 * Copyright (C) 2003-"$(hg_year $1)"
15 204
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
16 205
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
17 206
 *
18 207
 * Permission to use, modify and distribute this software is granted
19 208
 * provided that this copyright notice appears in all copies. For
20 209
 * precise terms see the accompanying LICENSE file.
21 210
 *
22 211
 * This software is provided \"AS IS\" with no warranty of any kind,
23 212
 * express or implied, and with no claim as to its suitability for any
24 213
 * purpose.
25 214
 *
26 215
 */
27 216
"
28
	awk 'BEGIN { pm=0; }
217
    awk 'BEGIN { pm=0; }
29 218
     pm==3 { print }
30 219
     /\/\* / && pm==0 { pm=1;}
31 220
     /[^:blank:]/ && (pm==0 || pm==2) { pm=3; print;}
32 221
     /\*\// && pm==1 { pm=2;}
33 222
    ' $1
34
	) >$TMP_FILE
223
    ) >$TMP_FILE
35 224

	
36
    HEADER_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
37

	
38
    rm $FILE_NAME
39
    mv $TMP_FILE $FILE_NAME
225
    "$ACTION"_action "$TMP_FILE" "$1" header
40 226
}
41 227

	
42
function update_tabs() {
228
function tabs_check() {
229
    if echo $1 | grep -q -v -E 'Makefile\.am$'
230
    then
231
        OLD_PATTERN=$(echo -e '\t')
232
        NEW_PATTERN='        '
233
    else
234
        OLD_PATTERN='        '
235
        NEW_PATTERN=$(echo -e '\t')
236
    fi
43 237
    TMP_FILE=`mktemp`
44
    FILE_NAME=$1
238
    cat $1 | sed -e "s/$OLD_PATTERN/$NEW_PATTERN/g" >$TMP_FILE
45 239

	
46
    cat $1 |
47
    sed -e 's/\t/        /g' >$TMP_FILE
48

	
49
    TABS_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
50

	
51
    rm $FILE_NAME
52
    mv $TMP_FILE $FILE_NAME
240
    "$ACTION"_action "$TMP_FILE" "$1" 'tabs'
53 241
}
54 242

	
55
function remove_trailing_space() {
243
function spaces_check() {
56 244
    TMP_FILE=`mktemp`
57
    FILE_NAME=$1
245
    cat $1 | sed -e 's/ \+$//g' >$TMP_FILE
58 246

	
59
    cat $1 |
60
    sed -e 's/ \+$//g' >$TMP_FILE
61

	
62
    SPACES_CH=`diff -q $TMP_FILE $FILE_NAME >/dev/null&&echo NO||echo YES`
63

	
64
    rm $FILE_NAME
65
    mv $TMP_FILE $FILE_NAME
247
    "$ACTION"_action "$TMP_FILE" "$1" 'trailing spaces'
66 248
}
67 249

	
68
function long_line_test() {
69
    cat $1 |grep -q -E '.{81,}'
70
}
71

	
72
function update_file() {
73
    echo -n '    update' $i ...
74

	
75
    update_header $1
76
    update_tabs $1
77
    remove_trailing_space $1
78

	
79
    CHANGED=NO;
80
    if [[ $HEADER_CH = YES ]];
250
function long_lines_check() {
251
    if cat $1 | grep -q -E '.{81,}'
81 252
    then
82
	echo -n '  [header updated]'
83
	CHANGED=YES;
84
    fi
85
    if [[ $TABS_CH = YES ]];
86
    then
87
	echo -n ' [tabs removed]'
88
	CHANGED=YES;
89
    fi
90
    if [[ $SPACES_CH = YES ]];
91
    then
92
	echo -n ' [trailing spaces removed]'
93
	CHANGED=YES;
94
    fi
95
    if long_line_test $1 ;
96
    then
97
	echo -n ' [LONG LINES]'
98
	((LONG_LINE_FILES++))
99
    fi
100
    echo
101
    if [[ $CHANGED = YES ]];
102
    then
103
	((CHANGED_FILES++))
253
	"$ACTION"_warning $1 'long lines'
104 254
    fi
105 255
}
106 256

	
107
CHANGED_FILES=0
108
TOTAL_FILES=0
109
LONG_LINE_FILES=0
110
if [ $# == 0 ]; then
111
    echo Update all source files...
112
    for i in `hg manifest|grep -E  '\.(cc|h|dox)$'`
257
# process the file
258

	
259
function process_file() {
260
    if [ "$ACTION" == 'update' ]
261
    then
262
        echo -n "    $ACTION $1..."
263
    else
264
        echo "	  $ACTION $1..."
265
    fi
266

	
267
    CHECKING="header tabs spaces long_lines"
268

	
269
    "$ACTION"_begin $1
270
    for check in $CHECKING
113 271
    do
114
	update_file $HGROOT/$i
115
	((TOTAL_FILES++))
272
	"$check"_check $1
116 273
    done
117
    echo '  done.'
118
else
119
    for i in $*
274
    "$ACTION"_end $1
275
    if [ "$ACTION" == 'update' ]
276
    then
277
        echo
278
    fi
279
}
280

	
281
function process_all {
282
    "$ACTION"_init
283
    while read file
120 284
    do
121
	update_file $i
122
	((TOTAL_FILES++))
123
    done
285
	process_file $file
286
    done < <($FILES)
287
    "$ACTION"_done
288
}
289

	
290
while [ $# -gt 0 ]
291
do
292
    
293
    if [ "$1" == '--help' ] || [ "$1" == '-h' ]
294
    then
295
	echo -n \
296
"Usage:
297
  $0 [OPTIONS] [files]
298
Options:
299
  --dry-run|-n
300
     Check the files, but do not modify them.
301
  --interactive|-i
302
     If --dry-run is specified and the checker emits warnings,
303
     then the user is asked if the warnings should be considered
304
     errors.
305
  --werror|-w
306
     Make all warnings into errors.
307
  --all|-a
308
     Check all source files in the repository.
309
  --modified|-m
310
     Check only the modified (and new) source files. This option is
311
     useful to check the modification before making a commit.
312
  --changed|-c
313
     Check only the changed source files compared to the parent(s) of
314
     the current hg node.  This option is useful as hg hook script.
315
     To automatically check all your changes before making a commit,
316
     add the following section to the appropriate .hg/hgrc file.
317

	
318
       [hooks]
319
       pretxncommit.checksources = scripts/unify-sources.sh -c -n -i
320

	
321
  --help|-h
322
     Print this help message.
323
  files
324
     The files to check/unify. If no file names are given, the modified
325
     source files will be checked/unified (just like using the
326
     --modified|-m option).
327
"
328
        exit 0
329
    elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ]
330
    then
331
	[ -n "$ACTION" ] && echo "Conflicting action options" >&2 && exit 1
332
	ACTION=check
333
    elif [ "$1" == "--all" ] || [ "$1" == '-a' ]
334
    then
335
	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
336
	FILES=all_files
337
    elif [ "$1" == "--changed" ] || [ "$1" == '-c' ]
338
    then
339
	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
340
	FILES=changed_files
341
    elif [ "$1" == "--modified" ] || [ "$1" == '-m' ]
342
    then
343
	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
344
	FILES=modified_files
345
    elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ]
346
    then
347
	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
348
	WARNING='INTERACTIVE'
349
    elif [ "$1" == "--werror" ] || [ "$1" == "-w" ]
350
    then
351
	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
352
	WARNING='WERROR'
353
    elif [ $(echo x$1 | cut -c 2) == '-' ]
354
    then
355
	echo "Invalid option $1" >&2 && exit 1
356
    else
357
	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
358
	GIVEN_FILES=$@
359
	FILES=given_files
360
	break
361
    fi
362
    
363
    shift
364
done
365

	
366
if [ -z $FILES ]
367
then
368
    FILES=modified_files
124 369
fi
125
echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
126
if [[ $LONG_LINE_FILES -gt 1 ]]; then
127
    echo
128
    echo WARNING: $LONG_LINE_FILES files contains long lines!    
129
    echo
130
elif [[ $LONG_LINE_FILES -gt 0 ]]; then
131
    echo
132
    echo WARNING: a file contains long lines!
133
    echo
370

	
371
if [ -z $ACTION ]
372
then
373
    ACTION=update
134 374
fi
375

	
376
process_all
Ignore white space 6 line context
1 1
INCLUDE_DIRECTORIES(
2
  ${CMAKE_SOURCE_DIR}
2
  ${PROJECT_SOURCE_DIR}
3 3
  ${PROJECT_BINARY_DIR}
4 4
)
5 5

	
6
LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/lemon)
6
LINK_DIRECTORIES(
7
  ${PROJECT_BINARY_DIR}/lemon
8
)
7 9

	
8 10
SET(TESTS
11
  adaptors_test
9 12
  bfs_test
13
  circulation_test
14
  connectivity_test
10 15
  counter_test
11 16
  dfs_test
12 17
  digraph_test
13 18
  dijkstra_test
14 19
  dim_test
20
  edge_set_test
15 21
  error_test
22
  euler_test
23
  gomory_hu_test
16 24
  graph_copy_test
17 25
  graph_test
18 26
  graph_utils_test
27
  hao_orlin_test
19 28
  heap_test
20 29
  kruskal_test
21 30
  maps_test
31
  matching_test
32
  min_cost_arborescence_test
33
  min_cost_flow_test
34
  path_test
35
  preflow_test
36
  radix_sort_test
22 37
  random_test
23
  path_test
38
  suurballe_test
24 39
  time_measure_test
25
  unionfind_test)
40
  unionfind_test
41
)
42

	
43
IF(LEMON_HAVE_LP)
44
  ADD_EXECUTABLE(lp_test lp_test.cc)
45
  SET(LP_TEST_LIBS lemon)
46

	
47
  IF(LEMON_HAVE_GLPK)
48
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
49
  ENDIF()
50
  IF(LEMON_HAVE_CPLEX)
51
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
52
  ENDIF()
53
  IF(LEMON_HAVE_CLP)
54
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
55
  ENDIF()
56

	
57
  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
58
  ADD_TEST(lp_test lp_test)
59

	
60
  IF(WIN32 AND LEMON_HAVE_GLPK)
61
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
62
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
63
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
64
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
65
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
66
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
67
    )
68
  ENDIF()
69

	
70
  IF(WIN32 AND LEMON_HAVE_CPLEX)
71
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
72
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
73
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
74
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
75
    )
76
  ENDIF()
77
ENDIF()
78

	
79
IF(LEMON_HAVE_MIP)
80
  ADD_EXECUTABLE(mip_test mip_test.cc)
81
  SET(MIP_TEST_LIBS lemon)
82

	
83
  IF(LEMON_HAVE_GLPK)
84
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
85
  ENDIF()
86
  IF(LEMON_HAVE_CPLEX)
87
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
88
  ENDIF()
89
  IF(LEMON_HAVE_CBC)
90
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
91
  ENDIF()
92

	
93
  TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
94
  ADD_TEST(mip_test mip_test)
95

	
96
  IF(WIN32 AND LEMON_HAVE_GLPK)
97
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
98
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
99
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
100
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
101
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
102
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
103
    )
104
  ENDIF()
105

	
106
  IF(WIN32 AND LEMON_HAVE_CPLEX)
107
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
108
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
109
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
110
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
111
    )
112
  ENDIF()
113
ENDIF()
26 114

	
27 115
FOREACH(TEST_NAME ${TESTS})
28 116
  ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
29 117
  TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
30 118
  ADD_TEST(${TEST_NAME} ${TEST_NAME})
31
ENDFOREACH(TEST_NAME)
119
ENDFOREACH()
Ignore white space 6 line context
1 1
EXTRA_DIST += \
2 2
	test/CMakeLists.txt
3 3

	
4 4
noinst_HEADERS += \
5 5
	test/graph_test.h \
6
        test/test_tools.h
6
	test/test_tools.h
7 7

	
8 8
check_PROGRAMS += \
9
	test/adaptors_test \
9 10
	test/bfs_test \
10
        test/counter_test \
11
	test/circulation_test \
12
	test/connectivity_test \
13
	test/counter_test \
11 14
	test/dfs_test \
12 15
	test/digraph_test \
13 16
	test/dijkstra_test \
14
        test/dim_test \
17
	test/dim_test \
18
	test/edge_set_test \
15 19
	test/error_test \
20
	test/euler_test \
21
	test/gomory_hu_test \
16 22
	test/graph_copy_test \
17 23
	test/graph_test \
18 24
	test/graph_utils_test \
25
	test/hao_orlin_test \
19 26
	test/heap_test \
20 27
	test/kruskal_test \
21
        test/maps_test \
22
        test/random_test \
23
        test/path_test \
24
        test/test_tools_fail \
25
        test/test_tools_pass \
26
        test/time_measure_test \
28
	test/maps_test \
29
	test/matching_test \
30
	test/min_cost_arborescence_test \
31
	test/min_cost_flow_test \
32
	test/path_test \
33
	test/preflow_test \
34
	test/radix_sort_test \
35
	test/random_test \
36
	test/suurballe_test \
37
	test/test_tools_fail \
38
	test/test_tools_pass \
39
	test/time_measure_test \
27 40
	test/unionfind_test
28 41

	
42
test_test_tools_pass_DEPENDENCIES = demo
43

	
44
if HAVE_LP
45
check_PROGRAMS += test/lp_test
46
endif HAVE_LP
47
if HAVE_MIP
48
check_PROGRAMS += test/mip_test
49
endif HAVE_MIP
50

	
29 51
TESTS += $(check_PROGRAMS)
30 52
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
31 53

	
54
test_adaptors_test_SOURCES = test/adaptors_test.cc
32 55
test_bfs_test_SOURCES = test/bfs_test.cc
56
test_circulation_test_SOURCES = test/circulation_test.cc
33 57
test_counter_test_SOURCES = test/counter_test.cc
58
test_connectivity_test_SOURCES = test/connectivity_test.cc
34 59
test_dfs_test_SOURCES = test/dfs_test.cc
35 60
test_digraph_test_SOURCES = test/digraph_test.cc
36 61
test_dijkstra_test_SOURCES = test/dijkstra_test.cc
37 62
test_dim_test_SOURCES = test/dim_test.cc
63
test_edge_set_test_SOURCES = test/edge_set_test.cc
38 64
test_error_test_SOURCES = test/error_test.cc
65
test_euler_test_SOURCES = test/euler_test.cc
66
test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
39 67
test_graph_copy_test_SOURCES = test/graph_copy_test.cc
40 68
test_graph_test_SOURCES = test/graph_test.cc
41 69
test_graph_utils_test_SOURCES = test/graph_utils_test.cc
42 70
test_heap_test_SOURCES = test/heap_test.cc
43 71
test_kruskal_test_SOURCES = test/kruskal_test.cc
72
test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
73
test_lp_test_SOURCES = test/lp_test.cc
44 74
test_maps_test_SOURCES = test/maps_test.cc
75
test_mip_test_SOURCES = test/mip_test.cc
76
test_matching_test_SOURCES = test/matching_test.cc
77
test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
78
test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
45 79
test_path_test_SOURCES = test/path_test.cc
80
test_preflow_test_SOURCES = test/preflow_test.cc
81
test_radix_sort_test_SOURCES = test/radix_sort_test.cc
82
test_suurballe_test_SOURCES = test/suurballe_test.cc
46 83
test_random_test_SOURCES = test/random_test.cc
47 84
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
48 85
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
49 86
test_time_measure_test_SOURCES = test/time_measure_test.cc
50 87
test_unionfind_test_SOURCES = test/unionfind_test.cc
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/smart_graph.h>
21 21
#include <lemon/list_graph.h>
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/bfs.h>
24 24
#include <lemon/path.h>
25 25

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

	
29 29
using namespace lemon;
30 30

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

	
53 53
void checkBfsCompile()
54 54
{
55 55
  typedef concepts::Digraph Digraph;
56 56
  typedef Bfs<Digraph> BType;
57 57
  typedef Digraph::Node Node;
58 58
  typedef Digraph::Arc Arc;
59 59

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

	
69 70
  {
70 71
    BType bfs_test(G);
72
    const BType& const_bfs_test = bfs_test;
71 73

	
72 74
    bfs_test.run(s);
73 75
    bfs_test.run(s,t);
74 76
    bfs_test.run();
75 77

	
76
    l  = bfs_test.dist(t);
77
    e  = bfs_test.predArc(t);
78
    s  = bfs_test.predNode(t);
79
    b  = bfs_test.reached(t);
80
    d  = bfs_test.distMap();
81
    p  = bfs_test.predMap();
82
    pp = bfs_test.path(t);
78
    bfs_test.init();
79
    bfs_test.addSource(s);
80
    n = bfs_test.processNextNode();
81
    n = bfs_test.processNextNode(t, b);
82
    n = bfs_test.processNextNode(nm, n);
83
    n = const_bfs_test.nextNode();
84
    b = const_bfs_test.emptyQueue();
85
    i = const_bfs_test.queueSize();
86
    
87
    bfs_test.start();
88
    bfs_test.start(t);
89
    bfs_test.start(nm);
90

	
91
    l  = const_bfs_test.dist(t);
92
    e  = const_bfs_test.predArc(t);
93
    s  = const_bfs_test.predNode(t);
94
    b  = const_bfs_test.reached(t);
95
    d  = const_bfs_test.distMap();
96
    p  = const_bfs_test.predMap();
97
    pp = const_bfs_test.path(t);
83 98
  }
84 99
  {
85 100
    BType
86 101
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
87 102
      ::SetDistMap<concepts::ReadWriteMap<Node,int> >
88 103
      ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
104
      ::SetStandardProcessedMap
89 105
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
90
      ::SetStandardProcessedMap
91 106
      ::Create bfs_test(G);
107
      
108
    concepts::ReadWriteMap<Node,Arc> pred_map;
109
    concepts::ReadWriteMap<Node,int> dist_map;
110
    concepts::ReadWriteMap<Node,bool> reached_map;
111
    concepts::WriteMap<Node,bool> processed_map;
112
    
113
    bfs_test
114
      .predMap(pred_map)
115
      .distMap(dist_map)
116
      .reachedMap(reached_map)
117
      .processedMap(processed_map);
92 118

	
93 119
    bfs_test.run(s);
94 120
    bfs_test.run(s,t);
95 121
    bfs_test.run();
122
    
123
    bfs_test.init();
124
    bfs_test.addSource(s);
125
    n = bfs_test.processNextNode();
126
    n = bfs_test.processNextNode(t, b);
127
    n = bfs_test.processNextNode(nm, n);
128
    n = bfs_test.nextNode();
129
    b = bfs_test.emptyQueue();
130
    i = bfs_test.queueSize();
131
    
132
    bfs_test.start();
133
    bfs_test.start(t);
134
    bfs_test.start(nm);
96 135

	
97 136
    l  = bfs_test.dist(t);
98 137
    e  = bfs_test.predArc(t);
99 138
    s  = bfs_test.predNode(t);
100 139
    b  = bfs_test.reached(t);
101 140
    pp = bfs_test.path(t);
102 141
  }
103 142
}
104 143

	
105 144
void checkBfsFunctionCompile()
106 145
{
107 146
  typedef int VType;
108 147
  typedef concepts::Digraph Digraph;
109 148
  typedef Digraph::Arc Arc;
110 149
  typedef Digraph::Node Node;
111 150

	
112 151
  Digraph g;
113 152
  bool b;
114 153
  bfs(g).run(Node());
115 154
  b=bfs(g).run(Node(),Node());
116 155
  bfs(g).run();
117 156
  bfs(g)
118 157
    .predMap(concepts::ReadWriteMap<Node,Arc>())
119 158
    .distMap(concepts::ReadWriteMap<Node,VType>())
120 159
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
121 160
    .processedMap(concepts::WriteMap<Node,bool>())
122 161
    .run(Node());
123 162
  b=bfs(g)
124 163
    .predMap(concepts::ReadWriteMap<Node,Arc>())
125 164
    .distMap(concepts::ReadWriteMap<Node,VType>())
126 165
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
127 166
    .processedMap(concepts::WriteMap<Node,bool>())
128 167
    .path(concepts::Path<Digraph>())
129 168
    .dist(VType())
130 169
    .run(Node(),Node());
131 170
  bfs(g)
132 171
    .predMap(concepts::ReadWriteMap<Node,Arc>())
133 172
    .distMap(concepts::ReadWriteMap<Node,VType>())
134 173
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
135 174
    .processedMap(concepts::WriteMap<Node,bool>())
136 175
    .run();
137 176
}
138 177

	
139 178
template <class Digraph>
140 179
void checkBfs() {
141 180
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
142 181

	
143 182
  Digraph G;
144 183
  Node s, t;
145 184

	
146 185
  std::istringstream input(test_lgf);
147 186
  digraphReader(G, input).
148 187
    node("source", s).
149 188
    node("target", t).
150 189
    run();
151 190

	
152 191
  Bfs<Digraph> bfs_test(G);
153 192
  bfs_test.run(s);
154 193

	
155 194
  check(bfs_test.dist(t)==2,"Bfs found a wrong path.");
156 195

	
157 196
  Path<Digraph> p = bfs_test.path(t);
158 197
  check(p.length()==2,"path() found a wrong path.");
159 198
  check(checkPath(G, p),"path() found a wrong path.");
160 199
  check(pathSource(G, p) == s,"path() found a wrong path.");
161 200
  check(pathTarget(G, p) == t,"path() found a wrong path.");
162 201

	
163 202

	
164 203
  for(ArcIt a(G); a!=INVALID; ++a) {
165 204
    Node u=G.source(a);
166 205
    Node v=G.target(a);
167 206
    check( !bfs_test.reached(u) ||
168 207
           (bfs_test.dist(v) <= bfs_test.dist(u)+1),
169 208
           "Wrong output. " << G.id(u) << "->" << G.id(v));
170 209
  }
171 210

	
172 211
  for(NodeIt v(G); v!=INVALID; ++v) {
173 212
    if (bfs_test.reached(v)) {
174 213
      check(v==s || bfs_test.predArc(v)!=INVALID, "Wrong tree.");
175 214
      if (bfs_test.predArc(v)!=INVALID ) {
176 215
        Arc a=bfs_test.predArc(v);
177 216
        Node u=G.source(a);
178 217
        check(u==bfs_test.predNode(v),"Wrong tree.");
179 218
        check(bfs_test.dist(v) - bfs_test.dist(u) == 1,
180 219
              "Wrong distance. Difference: "
181 220
              << std::abs(bfs_test.dist(v) - bfs_test.dist(u) - 1));
182 221
      }
183 222
    }
184 223
  }
185 224

	
186 225
  {
187 226
    NullMap<Node,Arc> myPredMap;
188 227
    bfs(G).predMap(myPredMap).run(s);
189 228
  }
190 229
}
191 230

	
192 231
int main()
193 232
{
194 233
  checkBfs<ListDigraph>();
195 234
  checkBfs<SmartDigraph>();
196 235
  return 0;
197 236
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/counter.h>
20 20
#include <vector>
21
#include <sstream>
22

	
23
#include "test/test_tools.h"
21 24

	
22 25
using namespace lemon;
23 26

	
24 27
template <typename T>
25 28
void bubbleSort(std::vector<T>& v) {
26
  Counter op("Bubble Sort - Operations: ");
27
  Counter::NoSubCounter as(op, "Assignments: ");
28
  Counter::NoSubCounter co(op, "Comparisons: ");
29
  for (int i = v.size()-1; i > 0; --i) {
30
    for (int j = 0; j < i; ++j) {
31
      if (v[j] > v[j+1]) {
32
        T tmp = v[j];
33
        v[j] = v[j+1];
34
        v[j+1] = tmp;
35
        as += 3;
29
  std::stringstream s1, s2, s3;
30
  {
31
    Counter op("Bubble Sort - Operations: ", s1);
32
    Counter::SubCounter as(op, "Assignments: ", s2);
33
    Counter::SubCounter co(op, "Comparisons: ", s3);
34
    for (int i = v.size()-1; i > 0; --i) {
35
      for (int j = 0; j < i; ++j) {
36
        if (v[j] > v[j+1]) {
37
          T tmp = v[j];
38
          v[j] = v[j+1];
39
          v[j+1] = tmp;
40
          as += 3;
41
        }
42
        ++co;
36 43
      }
37
      ++co;
38 44
    }
39 45
  }
46
  check(s1.str() == "Bubble Sort - Operations: 102\n", "Wrong counter");
47
  check(s2.str() == "Assignments: 57\n", "Wrong subcounter");
48
  check(s3.str() == "Comparisons: 45\n", "Wrong subcounter");
40 49
}
41 50

	
42 51
template <typename T>
43 52
void insertionSort(std::vector<T>& v) {
44
  Counter op("Insertion Sort - Operations: ");
45
  Counter::NoSubCounter as(op, "Assignments: ");
46
  Counter::NoSubCounter co(op, "Comparisons: ");
47
  for (int i = 1; i < int(v.size()); ++i) {
48
    T value = v[i];
49
    ++as;
50
    int j = i;
51
    while (j > 0 && v[j-1] > value) {
52
      v[j] = v[j-1];
53
      --j;
54
      ++co; ++as;
53
  std::stringstream s1, s2, s3;
54
  {
55
    Counter op("Insertion Sort - Operations: ", s1);
56
    Counter::SubCounter as(op, "Assignments: ", s2);
57
    Counter::SubCounter co(op, "Comparisons: ", s3);
58
    for (int i = 1; i < int(v.size()); ++i) {
59
      T value = v[i];
60
      ++as;
61
      int j = i;
62
      while (j > 0 && v[j-1] > value) {
63
        v[j] = v[j-1];
64
        --j;
65
        ++co; ++as;
66
      }
67
      v[j] = value;
68
      ++as;
55 69
    }
56
    v[j] = value;
57
    ++as;
58 70
  }
71
  check(s1.str() == "Insertion Sort - Operations: 56\n", "Wrong counter");
72
  check(s2.str() == "Assignments: 37\n", "Wrong subcounter");
73
  check(s3.str() == "Comparisons: 19\n", "Wrong subcounter");
59 74
}
60 75

	
61 76
template <typename MyCounter>
62
void counterTest() {
63
  MyCounter c("Main Counter: ");
64
  c++;
65
  typename MyCounter::SubCounter d(c, "SubCounter: ");
66
  d++;
67
  typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ");
68
  e++;
69
  d+=3;
70
  c-=4;
71
  e-=2;
72
  c.reset(2);
73
  c.reset();
77
void counterTest(bool output) {
78
  std::stringstream s1, s2, s3;
79
  {
80
    MyCounter c("Main Counter: ", s1);
81
    c++;
82
    typename MyCounter::SubCounter d(c, "SubCounter: ", s2);
83
    d++;
84
    typename MyCounter::SubCounter::NoSubCounter e(d, "SubSubCounter: ", s3);
85
    e++;
86
    d+=3;
87
    c-=4;
88
    e-=2;
89
    c.reset(2);
90
    c.reset();
91
  }
92
  if (output) {
93
    check(s1.str() == "Main Counter: 3\n", "Wrong Counter");
94
    check(s2.str() == "SubCounter: 3\n", "Wrong SubCounter");
95
    check(s3.str() == "", "Wrong NoSubCounter");
96
  } else {
97
    check(s1.str() == "", "Wrong NoCounter");
98
    check(s2.str() == "", "Wrong SubCounter");
99
    check(s3.str() == "", "Wrong NoSubCounter");
100
  }
74 101
}
75 102

	
76 103
void init(std::vector<int>& v) {
77 104
  v[0] = 10; v[1] = 60; v[2] = 20; v[3] = 90; v[4] = 100;
78 105
  v[5] = 80; v[6] = 40; v[7] = 30; v[8] = 50; v[9] = 70;
79 106
}
80 107

	
81 108
int main()
82 109
{
83
  counterTest<Counter>();
84
  counterTest<NoCounter>();
110
  counterTest<Counter>(true);
111
  counterTest<NoCounter>(false);
85 112

	
86 113
  std::vector<int> x(10);
87 114
  init(x); bubbleSort(x);
88 115
  init(x); insertionSort(x);
89 116

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

	
19 19
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/smart_graph.h>
21 21
#include <lemon/list_graph.h>
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/dfs.h>
24 24
#include <lemon/path.h>
25 25

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

	
29 29
using namespace lemon;
30 30

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

	
55 55
void checkDfsCompile()
56 56
{
57 57
  typedef concepts::Digraph Digraph;
58 58
  typedef Dfs<Digraph> DType;
59 59
  typedef Digraph::Node Node;
60 60
  typedef Digraph::Arc Arc;
61 61

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

	
71 72
  {
72 73
    DType dfs_test(G);
74
    const DType& const_dfs_test = dfs_test;
73 75

	
74 76
    dfs_test.run(s);
75 77
    dfs_test.run(s,t);
76 78
    dfs_test.run();
77 79

	
78
    l  = dfs_test.dist(t);
79
    e  = dfs_test.predArc(t);
80
    s  = dfs_test.predNode(t);
81
    b  = dfs_test.reached(t);
82
    d  = dfs_test.distMap();
83
    p  = dfs_test.predMap();
84
    pp = dfs_test.path(t);
80
    dfs_test.init();
81
    dfs_test.addSource(s);
82
    e = dfs_test.processNextArc();
83
    e = const_dfs_test.nextArc();
84
    b = const_dfs_test.emptyQueue();
85
    i = const_dfs_test.queueSize();
86
    
87
    dfs_test.start();
88
    dfs_test.start(t);
89
    dfs_test.start(am);
90

	
91
    l  = const_dfs_test.dist(t);
92
    e  = const_dfs_test.predArc(t);
93
    s  = const_dfs_test.predNode(t);
94
    b  = const_dfs_test.reached(t);
95
    d  = const_dfs_test.distMap();
96
    p  = const_dfs_test.predMap();
97
    pp = const_dfs_test.path(t);
85 98
  }
86 99
  {
87 100
    DType
88 101
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
89 102
      ::SetDistMap<concepts::ReadWriteMap<Node,int> >
90 103
      ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
104
      ::SetStandardProcessedMap
91 105
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
92
      ::SetStandardProcessedMap
93 106
      ::Create dfs_test(G);
94 107

	
108
    concepts::ReadWriteMap<Node,Arc> pred_map;
109
    concepts::ReadWriteMap<Node,int> dist_map;
110
    concepts::ReadWriteMap<Node,bool> reached_map;
111
    concepts::WriteMap<Node,bool> processed_map;
112
    
113
    dfs_test
114
      .predMap(pred_map)
115
      .distMap(dist_map)
116
      .reachedMap(reached_map)
117
      .processedMap(processed_map);
118

	
95 119
    dfs_test.run(s);
96 120
    dfs_test.run(s,t);
97 121
    dfs_test.run();
122
    dfs_test.init();
123

	
124
    dfs_test.addSource(s);
125
    e = dfs_test.processNextArc();
126
    e = dfs_test.nextArc();
127
    b = dfs_test.emptyQueue();
128
    i = dfs_test.queueSize();
129
    
130
    dfs_test.start();
131
    dfs_test.start(t);
132
    dfs_test.start(am);
98 133

	
99 134
    l  = dfs_test.dist(t);
100 135
    e  = dfs_test.predArc(t);
101 136
    s  = dfs_test.predNode(t);
102 137
    b  = dfs_test.reached(t);
103 138
    pp = dfs_test.path(t);
104 139
  }
105 140
}
106 141

	
107 142
void checkDfsFunctionCompile()
108 143
{
109 144
  typedef int VType;
110 145
  typedef concepts::Digraph Digraph;
111 146
  typedef Digraph::Arc Arc;
112 147
  typedef Digraph::Node Node;
113 148

	
114 149
  Digraph g;
115 150
  bool b;
116 151
  dfs(g).run(Node());
117 152
  b=dfs(g).run(Node(),Node());
118 153
  dfs(g).run();
119 154
  dfs(g)
120 155
    .predMap(concepts::ReadWriteMap<Node,Arc>())
121 156
    .distMap(concepts::ReadWriteMap<Node,VType>())
122 157
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
123 158
    .processedMap(concepts::WriteMap<Node,bool>())
124 159
    .run(Node());
125 160
  b=dfs(g)
126 161
    .predMap(concepts::ReadWriteMap<Node,Arc>())
127 162
    .distMap(concepts::ReadWriteMap<Node,VType>())
128 163
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
129 164
    .processedMap(concepts::WriteMap<Node,bool>())
130 165
    .path(concepts::Path<Digraph>())
131 166
    .dist(VType())
132 167
    .run(Node(),Node());
133 168
  dfs(g)
134 169
    .predMap(concepts::ReadWriteMap<Node,Arc>())
135 170
    .distMap(concepts::ReadWriteMap<Node,VType>())
136 171
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
137 172
    .processedMap(concepts::WriteMap<Node,bool>())
138 173
    .run();
139 174
}
140 175

	
141 176
template <class Digraph>
142 177
void checkDfs() {
143 178
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
144 179

	
145 180
  Digraph G;
146 181
  Node s, t;
147 182

	
148 183
  std::istringstream input(test_lgf);
149 184
  digraphReader(G, input).
150 185
    node("source", s).
151 186
    node("target", t).
152 187
    run();
153 188

	
154 189
  Dfs<Digraph> dfs_test(G);
155 190
  dfs_test.run(s);
156 191

	
157 192
  Path<Digraph> p = dfs_test.path(t);
158 193
  check(p.length() == dfs_test.dist(t),"path() found a wrong path.");
159 194
  check(checkPath(G, p),"path() found a wrong path.");
160 195
  check(pathSource(G, p) == s,"path() found a wrong path.");
161 196
  check(pathTarget(G, p) == t,"path() found a wrong path.");
162 197

	
163 198
  for(NodeIt v(G); v!=INVALID; ++v) {
164 199
    if (dfs_test.reached(v)) {
165 200
      check(v==s || dfs_test.predArc(v)!=INVALID, "Wrong tree.");
166 201
      if (dfs_test.predArc(v)!=INVALID ) {
167 202
        Arc e=dfs_test.predArc(v);
168 203
        Node u=G.source(e);
169 204
        check(u==dfs_test.predNode(v),"Wrong tree.");
170 205
        check(dfs_test.dist(v) - dfs_test.dist(u) == 1,
171 206
              "Wrong distance. (" << dfs_test.dist(u) << "->"
172 207
              << dfs_test.dist(v) << ")");
173 208
      }
174 209
    }
175 210
  }
176 211

	
177 212
  {
178 213
    NullMap<Node,Arc> myPredMap;
179 214
    dfs(G).predMap(myPredMap).run(s);
180 215
  }
181 216
}
182 217

	
183 218
int main()
184 219
{
185 220
  checkDfs<ListDigraph>();
186 221
  checkDfs<SmartDigraph>();
187 222
  return 0;
188 223
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/smart_graph.h>
22
//#include <lemon/full_graph.h>
23
//#include <lemon/hypercube_graph.h>
22
#include <lemon/full_graph.h>
24 23

	
25 24
#include "test_tools.h"
26 25
#include "graph_test.h"
27 26

	
28 27
using namespace lemon;
29 28
using namespace lemon::concepts;
30 29

	
31 30
template <class Digraph>
32
void checkDigraph() {
31
void checkDigraphBuild() {
33 32
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
34 33
  Digraph G;
35 34

	
36 35
  checkGraphNodeList(G, 0);
37 36
  checkGraphArcList(G, 0);
38 37

	
39 38
  Node
40 39
    n1 = G.addNode(),
41 40
    n2 = G.addNode(),
42 41
    n3 = G.addNode();
43 42
  checkGraphNodeList(G, 3);
44 43
  checkGraphArcList(G, 0);
45 44

	
46 45
  Arc a1 = G.addArc(n1, n2);
47 46
  check(G.source(a1) == n1 && G.target(a1) == n2, "Wrong arc");
48 47
  checkGraphNodeList(G, 3);
49 48
  checkGraphArcList(G, 1);
50 49

	
51 50
  checkGraphOutArcList(G, n1, 1);
52 51
  checkGraphOutArcList(G, n2, 0);
53 52
  checkGraphOutArcList(G, n3, 0);
54 53

	
55 54
  checkGraphInArcList(G, n1, 0);
56 55
  checkGraphInArcList(G, n2, 1);
57 56
  checkGraphInArcList(G, n3, 0);
58 57

	
59 58
  checkGraphConArcList(G, 1);
60 59

	
61
  Arc a2 = G.addArc(n2, n1), a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
60
  Arc a2 = G.addArc(n2, n1),
61
      a3 = G.addArc(n2, n3),
62
      a4 = G.addArc(n2, n3);
63

	
64
  checkGraphNodeList(G, 3);
65
  checkGraphArcList(G, 4);
66

	
67
  checkGraphOutArcList(G, n1, 1);
68
  checkGraphOutArcList(G, n2, 3);
69
  checkGraphOutArcList(G, n3, 0);
70

	
71
  checkGraphInArcList(G, n1, 1);
72
  checkGraphInArcList(G, n2, 1);
73
  checkGraphInArcList(G, n3, 2);
74

	
75
  checkGraphConArcList(G, 4);
76

	
77
  checkNodeIds(G);
78
  checkArcIds(G);
79
  checkGraphNodeMap(G);
80
  checkGraphArcMap(G);
81
}
82

	
83
template <class Digraph>
84
void checkDigraphSplit() {
85
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
86

	
87
  Digraph G;
88
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
89
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
90
      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
91

	
92
  Node n4 = G.split(n2);
93

	
94
  check(G.target(OutArcIt(G, n2)) == n4 &&
95
        G.source(InArcIt(G, n4)) == n2,
96
        "Wrong split.");
97

	
98
  checkGraphNodeList(G, 4);
99
  checkGraphArcList(G, 5);
100

	
101
  checkGraphOutArcList(G, n1, 1);
102
  checkGraphOutArcList(G, n2, 1);
103
  checkGraphOutArcList(G, n3, 0);
104
  checkGraphOutArcList(G, n4, 3);
105

	
106
  checkGraphInArcList(G, n1, 1);
107
  checkGraphInArcList(G, n2, 1);
108
  checkGraphInArcList(G, n3, 2);
109
  checkGraphInArcList(G, n4, 1);
110

	
111
  checkGraphConArcList(G, 5);
112
}
113

	
114
template <class Digraph>
115
void checkDigraphAlter() {
116
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
117

	
118
  Digraph G;
119
  Node n1 = G.addNode(), n2 = G.addNode(),
120
       n3 = G.addNode(), n4 = G.addNode();
121
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
122
      a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
123
      a5 = G.addArc(n2, n4);
124

	
125
  checkGraphNodeList(G, 4);
126
  checkGraphArcList(G, 5);
127

	
128
  // Check changeSource() and changeTarget()
129
  G.changeTarget(a4, n1);
130

	
131
  checkGraphNodeList(G, 4);
132
  checkGraphArcList(G, 5);
133

	
134
  checkGraphOutArcList(G, n1, 1);
135
  checkGraphOutArcList(G, n2, 1);
136
  checkGraphOutArcList(G, n3, 0);
137
  checkGraphOutArcList(G, n4, 3);
138

	
139
  checkGraphInArcList(G, n1, 2);
140
  checkGraphInArcList(G, n2, 1);
141
  checkGraphInArcList(G, n3, 1);
142
  checkGraphInArcList(G, n4, 1);
143

	
144
  checkGraphConArcList(G, 5);
145

	
146
  G.changeSource(a4, n3);
147

	
148
  checkGraphNodeList(G, 4);
149
  checkGraphArcList(G, 5);
150

	
151
  checkGraphOutArcList(G, n1, 1);
152
  checkGraphOutArcList(G, n2, 1);
153
  checkGraphOutArcList(G, n3, 1);
154
  checkGraphOutArcList(G, n4, 2);
155

	
156
  checkGraphInArcList(G, n1, 2);
157
  checkGraphInArcList(G, n2, 1);
158
  checkGraphInArcList(G, n3, 1);
159
  checkGraphInArcList(G, n4, 1);
160

	
161
  checkGraphConArcList(G, 5);
162

	
163
  // Check contract()
164
  G.contract(n2, n4, false);
165

	
166
  checkGraphNodeList(G, 3);
167
  checkGraphArcList(G, 5);
168

	
169
  checkGraphOutArcList(G, n1, 1);
170
  checkGraphOutArcList(G, n2, 3);
171
  checkGraphOutArcList(G, n3, 1);
172

	
173
  checkGraphInArcList(G, n1, 2);
174
  checkGraphInArcList(G, n2, 2);
175
  checkGraphInArcList(G, n3, 1);
176

	
177
  checkGraphConArcList(G, 5);
178

	
179
  G.contract(n2, n1);
180

	
181
  checkGraphNodeList(G, 2);
182
  checkGraphArcList(G, 3);
183

	
184
  checkGraphOutArcList(G, n2, 2);
185
  checkGraphOutArcList(G, n3, 1);
186

	
187
  checkGraphInArcList(G, n2, 2);
188
  checkGraphInArcList(G, n3, 1);
189

	
190
  checkGraphConArcList(G, 3);
191
}
192

	
193
template <class Digraph>
194
void checkDigraphErase() {
195
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
196

	
197
  Digraph G;
198
  Node n1 = G.addNode(), n2 = G.addNode(),
199
       n3 = G.addNode(), n4 = G.addNode();
200
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
201
      a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
202
      a5 = G.addArc(n2, n4);
203

	
204
  // Check arc deletion
205
  G.erase(a1);
206

	
207
  checkGraphNodeList(G, 4);
208
  checkGraphArcList(G, 4);
209

	
210
  checkGraphOutArcList(G, n1, 0);
211
  checkGraphOutArcList(G, n2, 1);
212
  checkGraphOutArcList(G, n3, 1);
213
  checkGraphOutArcList(G, n4, 2);
214

	
215
  checkGraphInArcList(G, n1, 2);
216
  checkGraphInArcList(G, n2, 0);
217
  checkGraphInArcList(G, n3, 1);
218
  checkGraphInArcList(G, n4, 1);
219

	
220
  checkGraphConArcList(G, 4);
221

	
222
  // Check node deletion
223
  G.erase(n4);
224

	
225
  checkGraphNodeList(G, 3);
226
  checkGraphArcList(G, 1);
227

	
228
  checkGraphOutArcList(G, n1, 0);
229
  checkGraphOutArcList(G, n2, 0);
230
  checkGraphOutArcList(G, n3, 1);
231
  checkGraphOutArcList(G, n4, 0);
232

	
233
  checkGraphInArcList(G, n1, 1);
234
  checkGraphInArcList(G, n2, 0);
235
  checkGraphInArcList(G, n3, 0);
236
  checkGraphInArcList(G, n4, 0);
237

	
238
  checkGraphConArcList(G, 1);
239
}
240

	
241

	
242
template <class Digraph>
243
void checkDigraphSnapshot() {
244
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
245

	
246
  Digraph G;
247
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
248
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
249
      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
250

	
251
  typename Digraph::Snapshot snapshot(G);
252

	
253
  Node n = G.addNode();
254
  G.addArc(n3, n);
255
  G.addArc(n, n3);
256

	
257
  checkGraphNodeList(G, 4);
258
  checkGraphArcList(G, 6);
259

	
260
  snapshot.restore();
261

	
62 262
  checkGraphNodeList(G, 3);
63 263
  checkGraphArcList(G, 4);
64 264

	
65 265
  checkGraphOutArcList(G, n1, 1);
66 266
  checkGraphOutArcList(G, n2, 3);
67 267
  checkGraphOutArcList(G, n3, 0);
68 268

	
69 269
  checkGraphInArcList(G, n1, 1);
70 270
  checkGraphInArcList(G, n2, 1);
71 271
  checkGraphInArcList(G, n3, 2);
72 272

	
73 273
  checkGraphConArcList(G, 4);
74 274

	
75 275
  checkNodeIds(G);
76 276
  checkArcIds(G);
77 277
  checkGraphNodeMap(G);
78 278
  checkGraphArcMap(G);
79 279

	
280
  G.addNode();
281
  snapshot.save(G);
282

	
283
  G.addArc(G.addNode(), G.addNode());
284

	
285
  snapshot.restore();
286

	
287
  checkGraphNodeList(G, 4);
288
  checkGraphArcList(G, 4);
80 289
}
81 290

	
82

	
83 291
void checkConcepts() {
84 292
  { // Checking digraph components
85 293
    checkConcept<BaseDigraphComponent, BaseDigraphComponent >();
86 294

	
87 295
    checkConcept<IDableDigraphComponent<>,
88 296
      IDableDigraphComponent<> >();
89 297

	
90 298
    checkConcept<IterableDigraphComponent<>,
91 299
      IterableDigraphComponent<> >();
92 300

	
93 301
    checkConcept<MappableDigraphComponent<>,
94 302
      MappableDigraphComponent<> >();
95 303
  }
96 304
  { // Checking skeleton digraph
97 305
    checkConcept<Digraph, Digraph>();
98 306
  }
99 307
  { // Checking ListDigraph
100 308
    checkConcept<Digraph, ListDigraph>();
101 309
    checkConcept<AlterableDigraphComponent<>, ListDigraph>();
102 310
    checkConcept<ExtendableDigraphComponent<>, ListDigraph>();
103 311
    checkConcept<ClearableDigraphComponent<>, ListDigraph>();
104 312
    checkConcept<ErasableDigraphComponent<>, ListDigraph>();
105 313
  }
106 314
  { // Checking SmartDigraph
107 315
    checkConcept<Digraph, SmartDigraph>();
108 316
    checkConcept<AlterableDigraphComponent<>, SmartDigraph>();
109 317
    checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
110 318
    checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
111 319
  }
112
//  { // Checking FullDigraph
113
//    checkConcept<Digraph, FullDigraph>();
114
//  }
115
//  { // Checking HyperCubeDigraph
116
//    checkConcept<Digraph, HyperCubeDigraph>();
117
//  }
320
  { // Checking FullDigraph
321
    checkConcept<Digraph, FullDigraph>();
322
  }
118 323
}
119 324

	
120 325
template <typename Digraph>
121 326
void checkDigraphValidity() {
122 327
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
123 328
  Digraph g;
124 329

	
125 330
  Node
126 331
    n1 = g.addNode(),
127 332
    n2 = g.addNode(),
128 333
    n3 = g.addNode();
129 334

	
130 335
  Arc
131 336
    e1 = g.addArc(n1, n2),
132 337
    e2 = g.addArc(n2, n3);
133 338

	
134 339
  check(g.valid(n1), "Wrong validity check");
135 340
  check(g.valid(e1), "Wrong validity check");
136 341

	
137 342
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
138 343
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
139 344
}
140 345

	
141 346
template <typename Digraph>
142 347
void checkDigraphValidityErase() {
143 348
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
144 349
  Digraph g;
145 350

	
146 351
  Node
147 352
    n1 = g.addNode(),
148 353
    n2 = g.addNode(),
149 354
    n3 = g.addNode();
150 355

	
151 356
  Arc
152 357
    e1 = g.addArc(n1, n2),
153 358
    e2 = g.addArc(n2, n3);
154 359

	
155 360
  check(g.valid(n1), "Wrong validity check");
156 361
  check(g.valid(e1), "Wrong validity check");
157 362

	
158 363
  g.erase(n1);
159 364

	
160 365
  check(!g.valid(n1), "Wrong validity check");
161 366
  check(g.valid(n2), "Wrong validity check");
162 367
  check(g.valid(n3), "Wrong validity check");
163 368
  check(!g.valid(e1), "Wrong validity check");
164 369
  check(g.valid(e2), "Wrong validity check");
165 370

	
166 371
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
167 372
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
168 373
}
169 374

	
375
void checkFullDigraph(int num) {
376
  typedef FullDigraph Digraph;
377
  DIGRAPH_TYPEDEFS(Digraph);
378
  Digraph G(num);
379

	
380
  checkGraphNodeList(G, num);
381
  checkGraphArcList(G, num * num);
382

	
383
  for (NodeIt n(G); n != INVALID; ++n) {
384
    checkGraphOutArcList(G, n, num);
385
    checkGraphInArcList(G, n, num);
386
  }
387

	
388
  checkGraphConArcList(G, num * num);
389

	
390
  checkNodeIds(G);
391
  checkArcIds(G);
392
  checkGraphNodeMap(G);
393
  checkGraphArcMap(G);
394

	
395
  for (int i = 0; i < G.nodeNum(); ++i) {
396
    check(G.index(G(i)) == i, "Wrong index");
397
  }
398

	
399
  for (NodeIt s(G); s != INVALID; ++s) {
400
    for (NodeIt t(G); t != INVALID; ++t) {
401
      Arc a = G.arc(s, t);
402
      check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
403
    }
404
  }
405
}
406

	
170 407
void checkDigraphs() {
171 408
  { // Checking ListDigraph
172
    checkDigraph<ListDigraph>();
409
    checkDigraphBuild<ListDigraph>();
410
    checkDigraphSplit<ListDigraph>();
411
    checkDigraphAlter<ListDigraph>();
412
    checkDigraphErase<ListDigraph>();
413
    checkDigraphSnapshot<ListDigraph>();
173 414
    checkDigraphValidityErase<ListDigraph>();
174 415
  }
175 416
  { // Checking SmartDigraph
176
    checkDigraph<SmartDigraph>();
417
    checkDigraphBuild<SmartDigraph>();
418
    checkDigraphSplit<SmartDigraph>();
419
    checkDigraphSnapshot<SmartDigraph>();
177 420
    checkDigraphValidity<SmartDigraph>();
178 421
  }
422
  { // Checking FullDigraph
423
    checkFullDigraph(8);
424
  }
179 425
}
180 426

	
181 427
int main() {
182 428
  checkDigraphs();
183 429
  checkConcepts();
184 430
  return 0;
185 431
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/smart_graph.h>
21 21
#include <lemon/list_graph.h>
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/dijkstra.h>
24 24
#include <lemon/path.h>
25 25
#include <lemon/bin_heap.h>
26 26

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

	
30 30
using namespace lemon;
31 31

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

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

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

	
72 74
  {
73 75
    DType dijkstra_test(G,length);
76
    const DType& const_dijkstra_test = dijkstra_test;
74 77

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

	
81
    dijkstra_test.init();
82
    dijkstra_test.addSource(s);
83
    dijkstra_test.addSource(s, 1);
84
    n = dijkstra_test.processNextNode();
85
    n = const_dijkstra_test.nextNode();
86
    b = const_dijkstra_test.emptyQueue();
87
    i = const_dijkstra_test.queueSize();
88
    
89
    dijkstra_test.start();
90
    dijkstra_test.start(t);
91
    dijkstra_test.start(nm);
92

	
93
    l  = const_dijkstra_test.dist(t);
94
    e  = const_dijkstra_test.predArc(t);
95
    s  = const_dijkstra_test.predNode(t);
96
    b  = const_dijkstra_test.reached(t);
97
    b  = const_dijkstra_test.processed(t);
98
    d  = const_dijkstra_test.distMap();
99
    p  = const_dijkstra_test.predMap();
100
    pp = const_dijkstra_test.path(t);
101
    l  = const_dijkstra_test.currentDist(t);
102
  }
103
  {
104
    DType
105
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
106
      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
107
      ::SetStandardProcessedMap
108
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
109
      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
110
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
111
      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
112
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >, 
113
                concepts::ReadWriteMap<Node,int> >
114
      ::Create dijkstra_test(G,length);
115

	
116
    LengthMap length_map;
117
    concepts::ReadWriteMap<Node,Arc> pred_map;
118
    concepts::ReadWriteMap<Node,VType> dist_map;
119
    concepts::WriteMap<Node,bool> processed_map;
120
    concepts::ReadWriteMap<Node,int> heap_cross_ref;
121
    BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
122
    
123
    dijkstra_test
124
      .lengthMap(length_map)
125
      .predMap(pred_map)
126
      .distMap(dist_map)
127
      .processedMap(processed_map)
128
      .heap(heap, heap_cross_ref);
129

	
130
    dijkstra_test.run(s);
131
    dijkstra_test.run(s,t);
132

	
133
    dijkstra_test.addSource(s);
134
    dijkstra_test.addSource(s, 1);
135
    n = dijkstra_test.processNextNode();
136
    n = dijkstra_test.nextNode();
137
    b = dijkstra_test.emptyQueue();
138
    i = dijkstra_test.queueSize();
139
    
140
    dijkstra_test.start();
141
    dijkstra_test.start(t);
142
    dijkstra_test.start(nm);
143

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

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

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

	
107 153
}
108 154

	
109 155
void checkDijkstraFunctionCompile()
110 156
{
111 157
  typedef int VType;
112 158
  typedef concepts::Digraph Digraph;
113 159
  typedef Digraph::Arc Arc;
114 160
  typedef Digraph::Node Node;
115 161
  typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
116 162

	
117 163
  Digraph g;
118 164
  bool b;
119 165
  dijkstra(g,LengthMap()).run(Node());
120 166
  b=dijkstra(g,LengthMap()).run(Node(),Node());
121 167
  dijkstra(g,LengthMap())
122 168
    .predMap(concepts::ReadWriteMap<Node,Arc>())
123 169
    .distMap(concepts::ReadWriteMap<Node,VType>())
124 170
    .processedMap(concepts::WriteMap<Node,bool>())
125 171
    .run(Node());
126 172
  b=dijkstra(g,LengthMap())
127 173
    .predMap(concepts::ReadWriteMap<Node,Arc>())
128 174
    .distMap(concepts::ReadWriteMap<Node,VType>())
129 175
    .processedMap(concepts::WriteMap<Node,bool>())
130 176
    .path(concepts::Path<Digraph>())
131 177
    .dist(VType())
132 178
    .run(Node(),Node());
133 179
}
134 180

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

	
140 186
  Digraph G;
141 187
  Node s, t;
142 188
  LengthMap length(G);
143 189

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

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

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

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

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

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

	
186 232
  {
187 233
    NullMap<Node,Arc> myPredMap;
188 234
    dijkstra(G,length).predMap(myPredMap).run(s);
189 235
  }
190 236
}
191 237

	
192 238
int main() {
193 239
  checkDijkstra<ListDigraph>();
194 240
  checkDijkstra<SmartDigraph>();
195 241
  return 0;
196 242
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/dim2.h>
20 20
#include <iostream>
21 21
#include "test_tools.h"
22 22

	
23 23
using namespace std;
24 24
using namespace lemon;
25 25

	
26 26
int main()
27 27
{
28 28
  typedef dim2::Point<int> Point;
29 29

	
30 30
  Point p;
31 31
  check(p.size()==2, "Wrong dim2::Point initialization.");
32 32

	
33 33
  Point a(1,2);
34 34
  Point b(3,4);
35 35
  check(a[0]==1 && a[1]==2, "Wrong dim2::Point initialization.");
36 36

	
37 37
  p = a+b;
38 38
  check(p.x==4 && p.y==6, "Wrong dim2::Point addition.");
39 39

	
40 40
  p = a-b;
41 41
  check(p.x==-2 && p.y==-2, "Wrong dim2::Point subtraction.");
42 42

	
43 43
  check(a.normSquare()==5,"Wrong dim2::Point norm calculation.");
44 44
  check(a*b==11, "Wrong dim2::Point scalar product.");
45 45

	
46 46
  int l=2;
47 47
  p = a*l;
48 48
  check(p.x==2 && p.y==4, "Wrong dim2::Point multiplication by a scalar.");
49 49

	
50 50
  p = b/l;
51 51
  check(p.x==1 && p.y==2, "Wrong dim2::Point division by a scalar.");
52 52

	
53 53
  typedef dim2::Box<int> Box;
54 54
  Box box1;
55 55
  check(box1.empty(), "Wrong empty() in dim2::Box.");
56 56

	
57 57
  box1.add(a);
58 58
  check(!box1.empty(), "Wrong empty() in dim2::Box.");
59 59
  box1.add(b);
60 60

	
61 61
  check(box1.left()==1 && box1.bottom()==2 &&
62 62
        box1.right()==3 && box1.top()==4,
63 63
        "Wrong addition of points to dim2::Box.");
64 64

	
65 65
  check(box1.inside(Point(2,3)), "Wrong inside() in dim2::Box.");
66 66
  check(box1.inside(Point(1,3)), "Wrong inside() in dim2::Box.");
67 67
  check(!box1.inside(Point(0,3)), "Wrong inside() in dim2::Box.");
68 68

	
69 69
  Box box2(Point(2,2));
70 70
  check(!box2.empty(), "Wrong empty() in dim2::Box.");
71 71

	
72 72
  box2.bottomLeft(Point(2,0));
73 73
  box2.topRight(Point(5,3));
74 74
  Box box3 = box1 & box2;
75 75
  check(!box3.empty() &&
76 76
        box3.left()==2 && box3.bottom()==2 &&
77 77
        box3.right()==3 && box3.top()==3,
78 78
        "Wrong intersection of two dim2::Box objects.");
79 79

	
80 80
  box1.add(box2);
81 81
  check(!box1.empty() &&
82 82
        box1.left()==1 && box1.bottom()==0 &&
83 83
        box1.right()==5 && box1.top()==4,
84 84
        "Wrong addition of two dim2::Box objects.");
85 85

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

	
19 19
#include <iostream>
20 20

	
21 21
#include <lemon/error.h>
22 22
#include "test_tools.h"
23 23

	
24 24
using namespace lemon;
25 25

	
26 26
#ifdef LEMON_ENABLE_ASSERTS
27 27
#undef LEMON_ENABLE_ASSERTS
28 28
#endif
29 29

	
30 30
#ifdef LEMON_DISABLE_ASSERTS
31 31
#undef LEMON_DISABLE_ASSERTS
32 32
#endif
33 33

	
34 34
#ifdef NDEBUG
35 35
#undef NDEBUG
36 36
#endif
37 37

	
38 38
//checking disabled asserts
39 39
#define LEMON_DISABLE_ASSERTS
40 40
#include <lemon/assert.h>
41 41

	
42 42
void no_assertion_text_disable() {
43 43
  LEMON_ASSERT(true, "This is a fault message");
44 44
}
45 45

	
46 46
void assertion_text_disable() {
47 47
  LEMON_ASSERT(false, "This is a fault message");
48 48
}
49 49

	
50 50
void check_assertion_disable() {
51 51
  no_assertion_text_disable();
52 52
  assertion_text_disable();
53 53
}
54 54
#undef LEMON_DISABLE_ASSERTS
55 55

	
56 56
//checking custom assert handler
57 57
#define LEMON_ASSERT_CUSTOM
58 58

	
59 59
static int cnt = 0;
60 60
void my_assert_handler(const char*, int, const char*,
61 61
                       const char*, const char*) {
62 62
  ++cnt;
63 63
}
64 64

	
65 65
#define LEMON_CUSTOM_ASSERT_HANDLER my_assert_handler
66 66
#include <lemon/assert.h>
67 67

	
68 68
void no_assertion_text_custom() {
69 69
  LEMON_ASSERT(true, "This is a fault message");
70 70
}
71 71

	
72 72
void assertion_text_custom() {
73 73
  LEMON_ASSERT(false, "This is a fault message");
74 74
}
75 75

	
76 76
void check_assertion_custom() {
77 77
  no_assertion_text_custom();
78 78
  assertion_text_custom();
79 79
  check(cnt == 1, "The custom assert handler does not work");
80 80
}
81 81

	
82 82
#undef LEMON_ASSERT_CUSTOM
83 83

	
84 84

	
85 85
int main() {
86 86
  check_assertion_disable();
87 87
  check_assertion_custom();
88 88

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

	
19 19
#include <lemon/smart_graph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/lgf_reader.h>
22 22
#include <lemon/error.h>
23 23

	
24 24
#include "test_tools.h"
25 25

	
26 26
using namespace std;
27 27
using namespace lemon;
28 28

	
29 29
void digraph_copy_test() {
30 30
  const int nn = 10;
31 31

	
32 32
  SmartDigraph from;
33 33
  SmartDigraph::NodeMap<int> fnm(from);
34 34
  SmartDigraph::ArcMap<int> fam(from);
35 35
  SmartDigraph::Node fn = INVALID;
36 36
  SmartDigraph::Arc fa = INVALID;
37 37

	
38 38
  std::vector<SmartDigraph::Node> fnv;
39 39
  for (int i = 0; i < nn; ++i) {
40 40
    SmartDigraph::Node node = from.addNode();
41 41
    fnv.push_back(node);
42 42
    fnm[node] = i * i;
43 43
    if (i == 0) fn = node;
44 44
  }
45 45

	
46 46
  for (int i = 0; i < nn; ++i) {
47 47
    for (int j = 0; j < nn; ++j) {
48 48
      SmartDigraph::Arc arc = from.addArc(fnv[i], fnv[j]);
49 49
      fam[arc] = i + j * j;
50 50
      if (i == 0 && j == 0) fa = arc;
51 51
    }
52 52
  }
53 53

	
54 54
  ListDigraph to;
55 55
  ListDigraph::NodeMap<int> tnm(to);
56 56
  ListDigraph::ArcMap<int> tam(to);
57 57
  ListDigraph::Node tn;
58 58
  ListDigraph::Arc ta;
59 59

	
60 60
  SmartDigraph::NodeMap<ListDigraph::Node> nr(from);
61 61
  SmartDigraph::ArcMap<ListDigraph::Arc> er(from);
62 62

	
63 63
  ListDigraph::NodeMap<SmartDigraph::Node> ncr(to);
64 64
  ListDigraph::ArcMap<SmartDigraph::Arc> ecr(to);
65 65

	
66 66
  digraphCopy(from, to).
67 67
    nodeMap(fnm, tnm).arcMap(fam, tam).
68 68
    nodeRef(nr).arcRef(er).
69 69
    nodeCrossRef(ncr).arcCrossRef(ecr).
70 70
    node(fn, tn).arc(fa, ta).run();
71 71

	
72 72
  for (SmartDigraph::NodeIt it(from); it != INVALID; ++it) {
73 73
    check(ncr[nr[it]] == it, "Wrong copy.");
74 74
    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
75 75
  }
76 76

	
77 77
  for (SmartDigraph::ArcIt it(from); it != INVALID; ++it) {
78 78
    check(ecr[er[it]] == it, "Wrong copy.");
79 79
    check(fam[it] == tam[er[it]], "Wrong copy.");
80 80
    check(nr[from.source(it)] == to.source(er[it]), "Wrong copy.");
81 81
    check(nr[from.target(it)] == to.target(er[it]), "Wrong copy.");
82 82
  }
83 83

	
84 84
  for (ListDigraph::NodeIt it(to); it != INVALID; ++it) {
85 85
    check(nr[ncr[it]] == it, "Wrong copy.");
86 86
  }
87 87

	
88 88
  for (ListDigraph::ArcIt it(to); it != INVALID; ++it) {
89 89
    check(er[ecr[it]] == it, "Wrong copy.");
90 90
  }
91 91
  check(tn == nr[fn], "Wrong copy.");
92 92
  check(ta == er[fa], "Wrong copy.");
93 93
}
94 94

	
95 95
void graph_copy_test() {
96 96
  const int nn = 10;
97 97

	
98 98
  SmartGraph from;
99 99
  SmartGraph::NodeMap<int> fnm(from);
100 100
  SmartGraph::ArcMap<int> fam(from);
101 101
  SmartGraph::EdgeMap<int> fem(from);
102 102
  SmartGraph::Node fn = INVALID;
103 103
  SmartGraph::Arc fa = INVALID;
104 104
  SmartGraph::Edge fe = INVALID;
105 105

	
106 106
  std::vector<SmartGraph::Node> fnv;
107 107
  for (int i = 0; i < nn; ++i) {
108 108
    SmartGraph::Node node = from.addNode();
109 109
    fnv.push_back(node);
110 110
    fnm[node] = i * i;
111 111
    if (i == 0) fn = node;
112 112
  }
113 113

	
114 114
  for (int i = 0; i < nn; ++i) {
115 115
    for (int j = 0; j < nn; ++j) {
116 116
      SmartGraph::Edge edge = from.addEdge(fnv[i], fnv[j]);
117 117
      fem[edge] = i * i + j * j;
118 118
      fam[from.direct(edge, true)] = i + j * j;
119 119
      fam[from.direct(edge, false)] = i * i + j;
120 120
      if (i == 0 && j == 0) fa = from.direct(edge, true);
121 121
      if (i == 0 && j == 0) fe = edge;
122 122
    }
123 123
  }
124 124

	
125 125
  ListGraph to;
126 126
  ListGraph::NodeMap<int> tnm(to);
127 127
  ListGraph::ArcMap<int> tam(to);
128 128
  ListGraph::EdgeMap<int> tem(to);
129 129
  ListGraph::Node tn;
130 130
  ListGraph::Arc ta;
131 131
  ListGraph::Edge te;
132 132

	
133 133
  SmartGraph::NodeMap<ListGraph::Node> nr(from);
134 134
  SmartGraph::ArcMap<ListGraph::Arc> ar(from);
135 135
  SmartGraph::EdgeMap<ListGraph::Edge> er(from);
136 136

	
137 137
  ListGraph::NodeMap<SmartGraph::Node> ncr(to);
138 138
  ListGraph::ArcMap<SmartGraph::Arc> acr(to);
139 139
  ListGraph::EdgeMap<SmartGraph::Edge> ecr(to);
140 140

	
141 141
  graphCopy(from, to).
142 142
    nodeMap(fnm, tnm).arcMap(fam, tam).edgeMap(fem, tem).
143 143
    nodeRef(nr).arcRef(ar).edgeRef(er).
144 144
    nodeCrossRef(ncr).arcCrossRef(acr).edgeCrossRef(ecr).
145 145
    node(fn, tn).arc(fa, ta).edge(fe, te).run();
146 146

	
147 147
  for (SmartGraph::NodeIt it(from); it != INVALID; ++it) {
148 148
    check(ncr[nr[it]] == it, "Wrong copy.");
149 149
    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
150 150
  }
151 151

	
152 152
  for (SmartGraph::ArcIt it(from); it != INVALID; ++it) {
153 153
    check(acr[ar[it]] == it, "Wrong copy.");
154 154
    check(fam[it] == tam[ar[it]], "Wrong copy.");
155 155
    check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy.");
156 156
    check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy.");
157 157
  }
158 158

	
159 159
  for (SmartGraph::EdgeIt it(from); it != INVALID; ++it) {
160 160
    check(ecr[er[it]] == it, "Wrong copy.");
161 161
    check(fem[it] == tem[er[it]], "Wrong copy.");
162 162
    check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]),
163 163
          "Wrong copy.");
164 164
    check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]),
165 165
          "Wrong copy.");
166 166
    check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])),
167 167
          "Wrong copy.");
168 168
  }
169 169

	
170 170
  for (ListGraph::NodeIt it(to); it != INVALID; ++it) {
171 171
    check(nr[ncr[it]] == it, "Wrong copy.");
172 172
  }
173 173

	
174 174
  for (ListGraph::ArcIt it(to); it != INVALID; ++it) {
175 175
    check(ar[acr[it]] == it, "Wrong copy.");
176 176
  }
177 177
  for (ListGraph::EdgeIt it(to); it != INVALID; ++it) {
178 178
    check(er[ecr[it]] == it, "Wrong copy.");
179 179
  }
180 180
  check(tn == nr[fn], "Wrong copy.");
181 181
  check(ta == ar[fa], "Wrong copy.");
182 182
  check(te == er[fe], "Wrong copy.");
183 183
}
184 184

	
185 185

	
186 186
int main() {
187 187
  digraph_copy_test();
188 188
  graph_copy_test();
189 189

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

	
19 19
#include <lemon/concepts/graph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/smart_graph.h>
22
// #include <lemon/full_graph.h>
23
// #include <lemon/grid_graph.h>
22
#include <lemon/full_graph.h>
23
#include <lemon/grid_graph.h>
24
#include <lemon/hypercube_graph.h>
24 25

	
25 26
#include "test_tools.h"
26 27
#include "graph_test.h"
27 28

	
28 29
using namespace lemon;
29 30
using namespace lemon::concepts;
30 31

	
31 32
template <class Graph>
32
void checkGraph() {
33
void checkGraphBuild() {
33 34
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
34 35

	
35 36
  Graph G;
36 37
  checkGraphNodeList(G, 0);
37 38
  checkGraphEdgeList(G, 0);
39
  checkGraphArcList(G, 0);
38 40

	
39 41
  Node
40 42
    n1 = G.addNode(),
41 43
    n2 = G.addNode(),
42 44
    n3 = G.addNode();
43 45
  checkGraphNodeList(G, 3);
44 46
  checkGraphEdgeList(G, 0);
47
  checkGraphArcList(G, 0);
45 48

	
46 49
  Edge e1 = G.addEdge(n1, n2);
47 50
  check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
48 51
        "Wrong edge");
52

	
49 53
  checkGraphNodeList(G, 3);
54
  checkGraphEdgeList(G, 1);
50 55
  checkGraphArcList(G, 2);
51
  checkGraphEdgeList(G, 1);
52 56

	
53
  checkGraphOutArcList(G, n1, 1);
54
  checkGraphOutArcList(G, n2, 1);
55
  checkGraphOutArcList(G, n3, 0);
57
  checkGraphIncEdgeArcLists(G, n1, 1);
58
  checkGraphIncEdgeArcLists(G, n2, 1);
59
  checkGraphIncEdgeArcLists(G, n3, 0);
56 60

	
57
  checkGraphInArcList(G, n1, 1);
58
  checkGraphInArcList(G, n2, 1);
59
  checkGraphInArcList(G, n3, 0);
61
  checkGraphConEdgeList(G, 1);
62
  checkGraphConArcList(G, 2);
60 63

	
61
  checkGraphIncEdgeList(G, n1, 1);
62
  checkGraphIncEdgeList(G, n2, 1);
63
  checkGraphIncEdgeList(G, n3, 0);
64
  Edge e2 = G.addEdge(n2, n1),
65
       e3 = G.addEdge(n2, n3);
64 66

	
65
  checkGraphConArcList(G, 2);
66
  checkGraphConEdgeList(G, 1);
67
  checkGraphNodeList(G, 3);
68
  checkGraphEdgeList(G, 3);
69
  checkGraphArcList(G, 6);
67 70

	
68
  Edge e2 = G.addEdge(n2, n1), e3 = G.addEdge(n2, n3);
69
  checkGraphNodeList(G, 3);
70
  checkGraphArcList(G, 6);
71
  checkGraphEdgeList(G, 3);
71
  checkGraphIncEdgeArcLists(G, n1, 2);
72
  checkGraphIncEdgeArcLists(G, n2, 3);
73
  checkGraphIncEdgeArcLists(G, n3, 1);
72 74

	
73
  checkGraphOutArcList(G, n1, 2);
74
  checkGraphOutArcList(G, n2, 3);
75
  checkGraphOutArcList(G, n3, 1);
76

	
77
  checkGraphInArcList(G, n1, 2);
78
  checkGraphInArcList(G, n2, 3);
79
  checkGraphInArcList(G, n3, 1);
80

	
81
  checkGraphIncEdgeList(G, n1, 2);
82
  checkGraphIncEdgeList(G, n2, 3);
83
  checkGraphIncEdgeList(G, n3, 1);
84

	
75
  checkGraphConEdgeList(G, 3);
85 76
  checkGraphConArcList(G, 6);
86
  checkGraphConEdgeList(G, 3);
87 77

	
88 78
  checkArcDirections(G);
89 79

	
90 80
  checkNodeIds(G);
91 81
  checkArcIds(G);
92 82
  checkEdgeIds(G);
93 83
  checkGraphNodeMap(G);
94 84
  checkGraphArcMap(G);
95 85
  checkGraphEdgeMap(G);
96 86
}
97 87

	
88
template <class Graph>
89
void checkGraphAlter() {
90
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
91

	
92
  Graph G;
93
  Node n1 = G.addNode(), n2 = G.addNode(),
94
       n3 = G.addNode(), n4 = G.addNode();
95
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
96
       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
97
       e5 = G.addEdge(n4, n3);
98

	
99
  checkGraphNodeList(G, 4);
100
  checkGraphEdgeList(G, 5);
101
  checkGraphArcList(G, 10);
102

	
103
  // Check changeU() and changeV()
104
  if (G.u(e2) == n2) {
105
    G.changeU(e2, n3);
106
  } else {
107
    G.changeV(e2, n3);
108
  }
109

	
110
  checkGraphNodeList(G, 4);
111
  checkGraphEdgeList(G, 5);
112
  checkGraphArcList(G, 10);
113

	
114
  checkGraphIncEdgeArcLists(G, n1, 3);
115
  checkGraphIncEdgeArcLists(G, n2, 2);
116
  checkGraphIncEdgeArcLists(G, n3, 3);
117
  checkGraphIncEdgeArcLists(G, n4, 2);
118

	
119
  checkGraphConEdgeList(G, 5);
120
  checkGraphConArcList(G, 10);
121

	
122
  if (G.u(e2) == n1) {
123
    G.changeU(e2, n2);
124
  } else {
125
    G.changeV(e2, n2);
126
  }
127

	
128
  checkGraphNodeList(G, 4);
129
  checkGraphEdgeList(G, 5);
130
  checkGraphArcList(G, 10);
131

	
132
  checkGraphIncEdgeArcLists(G, n1, 2);
133
  checkGraphIncEdgeArcLists(G, n2, 3);
134
  checkGraphIncEdgeArcLists(G, n3, 3);
135
  checkGraphIncEdgeArcLists(G, n4, 2);
136

	
137
  checkGraphConEdgeList(G, 5);
138
  checkGraphConArcList(G, 10);
139

	
140
  // Check contract()
141
  G.contract(n1, n4, false);
142

	
143
  checkGraphNodeList(G, 3);
144
  checkGraphEdgeList(G, 5);
145
  checkGraphArcList(G, 10);
146

	
147
  checkGraphIncEdgeArcLists(G, n1, 4);
148
  checkGraphIncEdgeArcLists(G, n2, 3);
149
  checkGraphIncEdgeArcLists(G, n3, 3);
150

	
151
  checkGraphConEdgeList(G, 5);
152
  checkGraphConArcList(G, 10);
153

	
154
  G.contract(n2, n3);
155

	
156
  checkGraphNodeList(G, 2);
157
  checkGraphEdgeList(G, 3);
158
  checkGraphArcList(G, 6);
159

	
160
  checkGraphIncEdgeArcLists(G, n1, 4);
161
  checkGraphIncEdgeArcLists(G, n2, 2);
162

	
163
  checkGraphConEdgeList(G, 3);
164
  checkGraphConArcList(G, 6);
165
}
166

	
167
template <class Graph>
168
void checkGraphErase() {
169
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
170

	
171
  Graph G;
172
  Node n1 = G.addNode(), n2 = G.addNode(),
173
       n3 = G.addNode(), n4 = G.addNode();
174
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
175
       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
176
       e5 = G.addEdge(n4, n3);
177

	
178
  // Check edge deletion
179
  G.erase(e2);
180

	
181
  checkGraphNodeList(G, 4);
182
  checkGraphEdgeList(G, 4);
183
  checkGraphArcList(G, 8);
184

	
185
  checkGraphIncEdgeArcLists(G, n1, 2);
186
  checkGraphIncEdgeArcLists(G, n2, 2);
187
  checkGraphIncEdgeArcLists(G, n3, 2);
188
  checkGraphIncEdgeArcLists(G, n4, 2);
189

	
190
  checkGraphConEdgeList(G, 4);
191
  checkGraphConArcList(G, 8);
192

	
193
  // Check node deletion
194
  G.erase(n3);
195

	
196
  checkGraphNodeList(G, 3);
197
  checkGraphEdgeList(G, 2);
198
  checkGraphArcList(G, 4);
199

	
200
  checkGraphIncEdgeArcLists(G, n1, 2);
201
  checkGraphIncEdgeArcLists(G, n2, 1);
202
  checkGraphIncEdgeArcLists(G, n4, 1);
203

	
204
  checkGraphConEdgeList(G, 2);
205
  checkGraphConArcList(G, 4);
206
}
207

	
208

	
209
template <class Graph>
210
void checkGraphSnapshot() {
211
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
212

	
213
  Graph G;
214
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
215
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
216
       e3 = G.addEdge(n2, n3);
217

	
218
  checkGraphNodeList(G, 3);
219
  checkGraphEdgeList(G, 3);
220
  checkGraphArcList(G, 6);
221

	
222
  typename Graph::Snapshot snapshot(G);
223

	
224
  Node n = G.addNode();
225
  G.addEdge(n3, n);
226
  G.addEdge(n, n3);
227
  G.addEdge(n3, n2);
228

	
229
  checkGraphNodeList(G, 4);
230
  checkGraphEdgeList(G, 6);
231
  checkGraphArcList(G, 12);
232

	
233
  snapshot.restore();
234

	
235
  checkGraphNodeList(G, 3);
236
  checkGraphEdgeList(G, 3);
237
  checkGraphArcList(G, 6);
238

	
239
  checkGraphIncEdgeArcLists(G, n1, 2);
240
  checkGraphIncEdgeArcLists(G, n2, 3);
241
  checkGraphIncEdgeArcLists(G, n3, 1);
242

	
243
  checkGraphConEdgeList(G, 3);
244
  checkGraphConArcList(G, 6);
245

	
246
  checkNodeIds(G);
247
  checkEdgeIds(G);
248
  checkArcIds(G);
249
  checkGraphNodeMap(G);
250
  checkGraphEdgeMap(G);
251
  checkGraphArcMap(G);
252

	
253
  G.addNode();
254
  snapshot.save(G);
255

	
256
  G.addEdge(G.addNode(), G.addNode());
257

	
258
  snapshot.restore();
259

	
260
  checkGraphNodeList(G, 4);
261
  checkGraphEdgeList(G, 3);
262
  checkGraphArcList(G, 6);
263
}
264

	
265
void checkFullGraph(int num) {
266
  typedef FullGraph Graph;
267
  GRAPH_TYPEDEFS(Graph);
268

	
269
  Graph G(num);
270
  checkGraphNodeList(G, num);
271
  checkGraphEdgeList(G, num * (num - 1) / 2);
272

	
273
  for (NodeIt n(G); n != INVALID; ++n) {
274
    checkGraphOutArcList(G, n, num - 1);
275
    checkGraphInArcList(G, n, num - 1);
276
    checkGraphIncEdgeList(G, n, num - 1);
277
  }
278

	
279
  checkGraphConArcList(G, num * (num - 1));
280
  checkGraphConEdgeList(G, num * (num - 1) / 2);
281

	
282
  checkArcDirections(G);
283

	
284
  checkNodeIds(G);
285
  checkArcIds(G);
286
  checkEdgeIds(G);
287
  checkGraphNodeMap(G);
288
  checkGraphArcMap(G);
289
  checkGraphEdgeMap(G);
290

	
291

	
292
  for (int i = 0; i < G.nodeNum(); ++i) {
293
    check(G.index(G(i)) == i, "Wrong index");
294
  }
295

	
296
  for (NodeIt u(G); u != INVALID; ++u) {
297
    for (NodeIt v(G); v != INVALID; ++v) {
298
      Edge e = G.edge(u, v);
299
      Arc a = G.arc(u, v);
300
      if (u == v) {
301
        check(e == INVALID, "Wrong edge lookup");
302
        check(a == INVALID, "Wrong arc lookup");
303
      } else {
304
        check((G.u(e) == u && G.v(e) == v) ||
305
              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
306
        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
307
      }
308
    }
309
  }
310
}
311

	
98 312
void checkConcepts() {
99 313
  { // Checking graph components
100 314
    checkConcept<BaseGraphComponent, BaseGraphComponent >();
101 315

	
102 316
    checkConcept<IDableGraphComponent<>,
103 317
      IDableGraphComponent<> >();
104 318

	
105 319
    checkConcept<IterableGraphComponent<>,
106 320
      IterableGraphComponent<> >();
107 321

	
108 322
    checkConcept<MappableGraphComponent<>,
109 323
      MappableGraphComponent<> >();
110 324
  }
111 325
  { // Checking skeleton graph
112 326
    checkConcept<Graph, Graph>();
113 327
  }
114 328
  { // Checking ListGraph
115 329
    checkConcept<Graph, ListGraph>();
116 330
    checkConcept<AlterableGraphComponent<>, ListGraph>();
117 331
    checkConcept<ExtendableGraphComponent<>, ListGraph>();
118 332
    checkConcept<ClearableGraphComponent<>, ListGraph>();
119 333
    checkConcept<ErasableGraphComponent<>, ListGraph>();
120 334
  }
121 335
  { // Checking SmartGraph
122 336
    checkConcept<Graph, SmartGraph>();
123 337
    checkConcept<AlterableGraphComponent<>, SmartGraph>();
124 338
    checkConcept<ExtendableGraphComponent<>, SmartGraph>();
125 339
    checkConcept<ClearableGraphComponent<>, SmartGraph>();
126 340
  }
127
//  { // Checking FullGraph
128
//    checkConcept<Graph, FullGraph>();
129
//    checkGraphIterators<FullGraph>();
130
//  }
131
//  { // Checking GridGraph
132
//    checkConcept<Graph, GridGraph>();
133
//    checkGraphIterators<GridGraph>();
134
//  }
341
  { // Checking FullGraph
342
    checkConcept<Graph, FullGraph>();
343
  }
344
  { // Checking GridGraph
345
    checkConcept<Graph, GridGraph>();
346
  }
347
  { // Checking HypercubeGraph
348
    checkConcept<Graph, HypercubeGraph>();
349
  }
135 350
}
136 351

	
137 352
template <typename Graph>
138 353
void checkGraphValidity() {
139 354
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
140 355
  Graph g;
141 356

	
142 357
  Node
143 358
    n1 = g.addNode(),
144 359
    n2 = g.addNode(),
145 360
    n3 = g.addNode();
146 361

	
147 362
  Edge
148 363
    e1 = g.addEdge(n1, n2),
149 364
    e2 = g.addEdge(n2, n3);
150 365

	
151 366
  check(g.valid(n1), "Wrong validity check");
152 367
  check(g.valid(e1), "Wrong validity check");
153 368
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
154 369

	
155 370
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
156 371
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
157 372
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
158 373
}
159 374

	
160 375
template <typename Graph>
161 376
void checkGraphValidityErase() {
162 377
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
163 378
  Graph g;
164 379

	
165 380
  Node
166 381
    n1 = g.addNode(),
167 382
    n2 = g.addNode(),
168 383
    n3 = g.addNode();
169 384

	
170 385
  Edge
171 386
    e1 = g.addEdge(n1, n2),
172 387
    e2 = g.addEdge(n2, n3);
173 388

	
174 389
  check(g.valid(n1), "Wrong validity check");
175 390
  check(g.valid(e1), "Wrong validity check");
176 391
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
177 392

	
178 393
  g.erase(n1);
179 394

	
180 395
  check(!g.valid(n1), "Wrong validity check");
181 396
  check(g.valid(n2), "Wrong validity check");
182 397
  check(g.valid(n3), "Wrong validity check");
183 398
  check(!g.valid(e1), "Wrong validity check");
184 399
  check(g.valid(e2), "Wrong validity check");
185 400

	
186 401
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
187 402
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
188 403
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
189 404
}
190 405

	
191
// void checkGridGraph(const GridGraph& g, int w, int h) {
192
//   check(g.width() == w, "Wrong width");
193
//   check(g.height() == h, "Wrong height");
406
void checkGridGraph(int width, int height) {
407
  typedef GridGraph Graph;
408
  GRAPH_TYPEDEFS(Graph);
409
  Graph G(width, height);
194 410

	
195
//   for (int i = 0; i < w; ++i) {
196
//     for (int j = 0; j < h; ++j) {
197
//       check(g.col(g(i, j)) == i, "Wrong col");
198
//       check(g.row(g(i, j)) == j, "Wrong row");
199
//     }
200
//   }
411
  check(G.width() == width, "Wrong column number");
412
  check(G.height() == height, "Wrong row number");
201 413

	
202
//   for (int i = 0; i < w; ++i) {
203
//     for (int j = 0; j < h - 1; ++j) {
204
//       check(g.source(g.down(g(i, j))) == g(i, j), "Wrong down");
205
//       check(g.target(g.down(g(i, j))) == g(i, j + 1), "Wrong down");
206
//     }
207
//     check(g.down(g(i, h - 1)) == INVALID, "Wrong down");
208
//   }
414
  for (int i = 0; i < width; ++i) {
415
    for (int j = 0; j < height; ++j) {
416
      check(G.col(G(i, j)) == i, "Wrong column");
417
      check(G.row(G(i, j)) == j, "Wrong row");
418
      check(G.pos(G(i, j)).x == i, "Wrong column");
419
      check(G.pos(G(i, j)).y == j, "Wrong row");
420
    }
421
  }
209 422

	
210
//   for (int i = 0; i < w; ++i) {
211
//     for (int j = 1; j < h; ++j) {
212
//       check(g.source(g.up(g(i, j))) == g(i, j), "Wrong up");
213
//       check(g.target(g.up(g(i, j))) == g(i, j - 1), "Wrong up");
214
//     }
215
//     check(g.up(g(i, 0)) == INVALID, "Wrong up");
216
//   }
423
  for (int j = 0; j < height; ++j) {
424
    for (int i = 0; i < width - 1; ++i) {
425
      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
426
      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
427
    }
428
    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
429
  }
217 430

	
218
//   for (int j = 0; j < h; ++j) {
219
//     for (int i = 0; i < w - 1; ++i) {
220
//       check(g.source(g.right(g(i, j))) == g(i, j), "Wrong right");
221
//       check(g.target(g.right(g(i, j))) == g(i + 1, j), "Wrong right");
222
//     }
223
//     check(g.right(g(w - 1, j)) == INVALID, "Wrong right");
224
//   }
431
  for (int j = 0; j < height; ++j) {
432
    for (int i = 1; i < width; ++i) {
433
      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
434
      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
435
    }
436
    check(G.left(G(0, j)) == INVALID, "Wrong left");
437
  }
225 438

	
226
//   for (int j = 0; j < h; ++j) {
227
//     for (int i = 1; i < w; ++i) {
228
//       check(g.source(g.left(g(i, j))) == g(i, j), "Wrong left");
229
//       check(g.target(g.left(g(i, j))) == g(i - 1, j), "Wrong left");
230
//     }
231
//     check(g.left(g(0, j)) == INVALID, "Wrong left");
232
//   }
233
// }
439
  for (int i = 0; i < width; ++i) {
440
    for (int j = 0; j < height - 1; ++j) {
441
      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
442
      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
443
    }
444
    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
445
  }
446

	
447
  for (int i = 0; i < width; ++i) {
448
    for (int j = 1; j < height; ++j) {
449
      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
450
      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
451
    }
452
    check(G.down(G(i, 0)) == INVALID, "Wrong down");
453
  }
454

	
455
  checkGraphNodeList(G, width * height);
456
  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
457
  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
458

	
459
  for (NodeIt n(G); n != INVALID; ++n) {
460
    int nb = 4;
461
    if (G.col(n) == 0) --nb;
462
    if (G.col(n) == width - 1) --nb;
463
    if (G.row(n) == 0) --nb;
464
    if (G.row(n) == height - 1) --nb;
465

	
466
    checkGraphOutArcList(G, n, nb);
467
    checkGraphInArcList(G, n, nb);
468
    checkGraphIncEdgeList(G, n, nb);
469
  }
470

	
471
  checkArcDirections(G);
472

	
473
  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
474
  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
475

	
476
  checkNodeIds(G);
477
  checkArcIds(G);
478
  checkEdgeIds(G);
479
  checkGraphNodeMap(G);
480
  checkGraphArcMap(G);
481
  checkGraphEdgeMap(G);
482

	
483
}
484

	
485
void checkHypercubeGraph(int dim) {
486
  GRAPH_TYPEDEFS(HypercubeGraph);
487

	
488
  HypercubeGraph G(dim);
489
  checkGraphNodeList(G, 1 << dim);
490
  checkGraphEdgeList(G, dim * (1 << (dim-1)));
491
  checkGraphArcList(G, dim * (1 << dim));
492

	
493
  Node n = G.nodeFromId(dim);
494

	
495
  for (NodeIt n(G); n != INVALID; ++n) {
496
    checkGraphIncEdgeList(G, n, dim);
497
    for (IncEdgeIt e(G, n); e != INVALID; ++e) {
498
      check( (G.u(e) == n &&
499
              G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
500
             (G.v(e) == n &&
501
              G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
502
             "Wrong edge or wrong dimension");
503
    }
504

	
505
    checkGraphOutArcList(G, n, dim);
506
    for (OutArcIt a(G, n); a != INVALID; ++a) {
507
      check(G.source(a) == n &&
508
            G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
509
            "Wrong arc or wrong dimension");
510
    }
511

	
512
    checkGraphInArcList(G, n, dim);
513
    for (InArcIt a(G, n); a != INVALID; ++a) {
514
      check(G.target(a) == n &&
515
            G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
516
            "Wrong arc or wrong dimension");
517
    }
518
  }
519

	
520
  checkGraphConArcList(G, (1 << dim) * dim);
521
  checkGraphConEdgeList(G, dim * (1 << (dim-1)));
522

	
523
  checkArcDirections(G);
524

	
525
  checkNodeIds(G);
526
  checkArcIds(G);
527
  checkEdgeIds(G);
528
  checkGraphNodeMap(G);
529
  checkGraphArcMap(G);
530
  checkGraphEdgeMap(G);
531
}
234 532

	
235 533
void checkGraphs() {
236 534
  { // Checking ListGraph
237
    checkGraph<ListGraph>();
535
    checkGraphBuild<ListGraph>();
536
    checkGraphAlter<ListGraph>();
537
    checkGraphErase<ListGraph>();
538
    checkGraphSnapshot<ListGraph>();
238 539
    checkGraphValidityErase<ListGraph>();
239 540
  }
240 541
  { // Checking SmartGraph
241
    checkGraph<SmartGraph>();
542
    checkGraphBuild<SmartGraph>();
543
    checkGraphSnapshot<SmartGraph>();
242 544
    checkGraphValidity<SmartGraph>();
243 545
  }
244
//   { // Checking FullGraph
245
//     FullGraph g(5);
246
//     checkGraphNodeList(g, 5);
247
//     checkGraphEdgeList(g, 10);
248
//   }
249
//   { // Checking GridGraph
250
//     GridGraph g(5, 6);
251
//     checkGraphNodeList(g, 30);
252
//     checkGraphEdgeList(g, 49);
253
//     checkGridGraph(g, 5, 6);
254
//   }
546
  { // Checking FullGraph
547
    checkFullGraph(7);
548
    checkFullGraph(8);
549
  }
550
  { // Checking GridGraph
551
    checkGridGraph(5, 8);
552
    checkGridGraph(8, 5);
553
    checkGridGraph(5, 5);
554
    checkGridGraph(0, 0);
555
    checkGridGraph(1, 1);
556
  }
557
  { // Checking HypercubeGraph
558
    checkHypercubeGraph(1);
559
    checkHypercubeGraph(2);
560
    checkHypercubeGraph(3);
561
    checkHypercubeGraph(4);
562
  }
255 563
}
256 564

	
257 565
int main() {
258 566
  checkConcepts();
259 567
  checkGraphs();
260 568
  return 0;
261 569
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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_GRAPH_TEST_H
20 20
#define LEMON_TEST_GRAPH_TEST_H
21 21

	
22 22
#include <set>
23 23

	
24 24
#include <lemon/core.h>
25 25
#include <lemon/maps.h>
26 26

	
27 27
#include "test_tools.h"
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  template<class Graph>
32 32
  void checkGraphNodeList(const Graph &G, int cnt)
33 33
  {
34 34
    typename Graph::NodeIt n(G);
35 35
    for(int i=0;i<cnt;i++) {
36 36
      check(n!=INVALID,"Wrong Node list linking.");
37 37
      ++n;
38 38
    }
39 39
    check(n==INVALID,"Wrong Node list linking.");
40 40
    check(countNodes(G)==cnt,"Wrong Node number.");
41 41
  }
42 42

	
43 43
  template<class Graph>
44 44
  void checkGraphArcList(const Graph &G, int cnt)
45 45
  {
46 46
    typename Graph::ArcIt e(G);
47 47
    for(int i=0;i<cnt;i++) {
48 48
      check(e!=INVALID,"Wrong Arc list linking.");
49 49
      check(G.oppositeNode(G.source(e), e) == G.target(e),
50 50
            "Wrong opposite node");
51 51
      check(G.oppositeNode(G.target(e), e) == G.source(e),
52 52
            "Wrong opposite node");
53 53
      ++e;
54 54
    }
55 55
    check(e==INVALID,"Wrong Arc list linking.");
56 56
    check(countArcs(G)==cnt,"Wrong Arc number.");
57 57
  }
58 58

	
59 59
  template<class Graph>
60 60
  void checkGraphOutArcList(const Graph &G, typename Graph::Node n, int cnt)
61 61
  {
62 62
    typename Graph::OutArcIt e(G,n);
63 63
    for(int i=0;i<cnt;i++) {
64 64
      check(e!=INVALID,"Wrong OutArc list linking.");
65 65
      check(n==G.source(e),"Wrong OutArc list linking.");
66 66
      check(n==G.baseNode(e),"Wrong OutArc list linking.");
67 67
      check(G.target(e)==G.runningNode(e),"Wrong OutArc list linking.");
68 68
      ++e;
69 69
    }
70 70
    check(e==INVALID,"Wrong OutArc list linking.");
71 71
    check(countOutArcs(G,n)==cnt,"Wrong OutArc number.");
72 72
  }
73 73

	
74 74
  template<class Graph>
75 75
  void checkGraphInArcList(const Graph &G, typename Graph::Node n, int cnt)
76 76
  {
77 77
    typename Graph::InArcIt e(G,n);
78 78
    for(int i=0;i<cnt;i++) {
79 79
      check(e!=INVALID,"Wrong InArc list linking.");
80 80
      check(n==G.target(e),"Wrong InArc list linking.");
81 81
      check(n==G.baseNode(e),"Wrong OutArc list linking.");
82 82
      check(G.source(e)==G.runningNode(e),"Wrong OutArc list linking.");
83 83
      ++e;
84 84
    }
85 85
    check(e==INVALID,"Wrong InArc list linking.");
86 86
    check(countInArcs(G,n)==cnt,"Wrong InArc number.");
87 87
  }
88 88

	
89 89
  template<class Graph>
90 90
  void checkGraphEdgeList(const Graph &G, int cnt)
91 91
  {
92 92
    typename Graph::EdgeIt e(G);
93 93
    for(int i=0;i<cnt;i++) {
94 94
      check(e!=INVALID,"Wrong Edge list linking.");
95 95
      check(G.oppositeNode(G.u(e), e) == G.v(e), "Wrong opposite node");
96 96
      check(G.oppositeNode(G.v(e), e) == G.u(e), "Wrong opposite node");
97 97
      ++e;
98 98
    }
99 99
    check(e==INVALID,"Wrong Edge list linking.");
100 100
    check(countEdges(G)==cnt,"Wrong Edge number.");
101 101
  }
102 102

	
103 103
  template<class Graph>
104 104
  void checkGraphIncEdgeList(const Graph &G, typename Graph::Node n, int cnt)
105 105
  {
106 106
    typename Graph::IncEdgeIt e(G,n);
107 107
    for(int i=0;i<cnt;i++) {
108 108
      check(e!=INVALID,"Wrong IncEdge list linking.");
109 109
      check(n==G.u(e) || n==G.v(e),"Wrong IncEdge list linking.");
110 110
      check(n==G.baseNode(e),"Wrong OutArc list linking.");
111 111
      check(G.u(e)==G.runningNode(e) || G.v(e)==G.runningNode(e),
112 112
            "Wrong OutArc list linking.");
113 113
      ++e;
114 114
    }
115 115
    check(e==INVALID,"Wrong IncEdge list linking.");
116 116
    check(countIncEdges(G,n)==cnt,"Wrong IncEdge number.");
117 117
  }
118 118

	
119 119
  template <class Graph>
120
  void checkGraphIncEdgeArcLists(const Graph &G, typename Graph::Node n,
121
                                 int cnt)
122
  {
123
    checkGraphIncEdgeList(G, n, cnt);
124
    checkGraphOutArcList(G, n, cnt);
125
    checkGraphInArcList(G, n, cnt);
126
  }
127

	
128
  template <class Graph>
120 129
  void checkGraphConArcList(const Graph &G, int cnt) {
121 130
    int i = 0;
122 131
    for (typename Graph::NodeIt u(G); u != INVALID; ++u) {
123 132
      for (typename Graph::NodeIt v(G); v != INVALID; ++v) {
124 133
        for (ConArcIt<Graph> a(G, u, v); a != INVALID; ++a) {
125 134
          check(G.source(a) == u, "Wrong iterator.");
126 135
          check(G.target(a) == v, "Wrong iterator.");
127 136
          ++i;
128 137
        }
129 138
      }
130 139
    }
131 140
    check(cnt == i, "Wrong iterator.");
132 141
  }
133 142

	
134 143
  template <class Graph>
135 144
  void checkGraphConEdgeList(const Graph &G, int cnt) {
136 145
    int i = 0;
137 146
    for (typename Graph::NodeIt u(G); u != INVALID; ++u) {
138 147
      for (typename Graph::NodeIt v(G); v != INVALID; ++v) {
139 148
        for (ConEdgeIt<Graph> e(G, u, v); e != INVALID; ++e) {
140 149
          check((G.u(e) == u && G.v(e) == v) ||
141 150
                (G.u(e) == v && G.v(e) == u), "Wrong iterator.");
142 151
          i += u == v ? 2 : 1;
143 152
        }
144 153
      }
145 154
    }
146 155
    check(2 * cnt == i, "Wrong iterator.");
147 156
  }
148 157

	
149 158
  template <typename Graph>
150 159
  void checkArcDirections(const Graph& G) {
151 160
    for (typename Graph::ArcIt a(G); a != INVALID; ++a) {
152 161
      check(G.source(a) == G.target(G.oppositeArc(a)), "Wrong direction");
153 162
      check(G.target(a) == G.source(G.oppositeArc(a)), "Wrong direction");
154 163
      check(G.direct(a, G.direction(a)) == a, "Wrong direction");
155 164
    }
156 165
  }
157 166

	
158 167
  template <typename Graph>
159 168
  void checkNodeIds(const Graph& G) {
160 169
    std::set<int> values;
161 170
    for (typename Graph::NodeIt n(G); n != INVALID; ++n) {
162 171
      check(G.nodeFromId(G.id(n)) == n, "Wrong id");
163 172
      check(values.find(G.id(n)) == values.end(), "Wrong id");
164 173
      check(G.id(n) <= G.maxNodeId(), "Wrong maximum id");
165 174
      values.insert(G.id(n));
166 175
    }
167 176
  }
168 177

	
169 178
  template <typename Graph>
170 179
  void checkArcIds(const Graph& G) {
171 180
    std::set<int> values;
172 181
    for (typename Graph::ArcIt a(G); a != INVALID; ++a) {
173 182
      check(G.arcFromId(G.id(a)) == a, "Wrong id");
174 183
      check(values.find(G.id(a)) == values.end(), "Wrong id");
175 184
      check(G.id(a) <= G.maxArcId(), "Wrong maximum id");
176 185
      values.insert(G.id(a));
177 186
    }
178 187
  }
179 188

	
180 189
  template <typename Graph>
181 190
  void checkEdgeIds(const Graph& G) {
182 191
    std::set<int> values;
183 192
    for (typename Graph::EdgeIt e(G); e != INVALID; ++e) {
184 193
      check(G.edgeFromId(G.id(e)) == e, "Wrong id");
185 194
      check(values.find(G.id(e)) == values.end(), "Wrong id");
186 195
      check(G.id(e) <= G.maxEdgeId(), "Wrong maximum id");
187 196
      values.insert(G.id(e));
188 197
    }
189 198
  }
190 199

	
191 200
  template <typename Graph>
192 201
  void checkGraphNodeMap(const Graph& G) {
193 202
    typedef typename Graph::Node Node;
194 203
    typedef typename Graph::NodeIt NodeIt;
195 204

	
196 205
    typedef typename Graph::template NodeMap<int> IntNodeMap;
197 206
    IntNodeMap map(G, 42);
198 207
    for (NodeIt it(G); it != INVALID; ++it) {
199 208
      check(map[it] == 42, "Wrong map constructor.");
200 209
    }
201 210
    int s = 0;
202 211
    for (NodeIt it(G); it != INVALID; ++it) {
203 212
      map[it] = 0;
204 213
      check(map[it] == 0, "Wrong operator[].");
205 214
      map.set(it, s);
206 215
      check(map[it] == s, "Wrong set.");
207 216
      ++s;
208 217
    }
209 218
    s = s * (s - 1) / 2;
210 219
    for (NodeIt it(G); it != INVALID; ++it) {
211 220
      s -= map[it];
212 221
    }
213 222
    check(s == 0, "Wrong sum.");
214 223

	
215 224
    // map = constMap<Node>(12);
216 225
    // for (NodeIt it(G); it != INVALID; ++it) {
217 226
    //   check(map[it] == 12, "Wrong operator[].");
218 227
    // }
219 228
  }
220 229

	
221 230
  template <typename Graph>
222 231
  void checkGraphArcMap(const Graph& G) {
223 232
    typedef typename Graph::Arc Arc;
224 233
    typedef typename Graph::ArcIt ArcIt;
225 234

	
226 235
    typedef typename Graph::template ArcMap<int> IntArcMap;
227 236
    IntArcMap map(G, 42);
228 237
    for (ArcIt it(G); it != INVALID; ++it) {
229 238
      check(map[it] == 42, "Wrong map constructor.");
230 239
    }
231 240
    int s = 0;
232 241
    for (ArcIt it(G); it != INVALID; ++it) {
233 242
      map[it] = 0;
234 243
      check(map[it] == 0, "Wrong operator[].");
235 244
      map.set(it, s);
236 245
      check(map[it] == s, "Wrong set.");
237 246
      ++s;
238 247
    }
239 248
    s = s * (s - 1) / 2;
240 249
    for (ArcIt it(G); it != INVALID; ++it) {
241 250
      s -= map[it];
242 251
    }
243 252
    check(s == 0, "Wrong sum.");
244 253

	
245 254
    // map = constMap<Arc>(12);
246 255
    // for (ArcIt it(G); it != INVALID; ++it) {
247 256
    //   check(map[it] == 12, "Wrong operator[].");
248 257
    // }
249 258
  }
250 259

	
251 260
  template <typename Graph>
252 261
  void checkGraphEdgeMap(const Graph& G) {
253 262
    typedef typename Graph::Edge Edge;
254 263
    typedef typename Graph::EdgeIt EdgeIt;
255 264

	
256 265
    typedef typename Graph::template EdgeMap<int> IntEdgeMap;
257 266
    IntEdgeMap map(G, 42);
258 267
    for (EdgeIt it(G); it != INVALID; ++it) {
259 268
      check(map[it] == 42, "Wrong map constructor.");
260 269
    }
261 270
    int s = 0;
262 271
    for (EdgeIt it(G); it != INVALID; ++it) {
263 272
      map[it] = 0;
264 273
      check(map[it] == 0, "Wrong operator[].");
265 274
      map.set(it, s);
266 275
      check(map[it] == s, "Wrong set.");
267 276
      ++s;
268 277
    }
269 278
    s = s * (s - 1) / 2;
270 279
    for (EdgeIt it(G); it != INVALID; ++it) {
271 280
      s -= map[it];
272 281
    }
273 282
    check(s == 0, "Wrong sum.");
274 283

	
275 284
    // map = constMap<Edge>(12);
276 285
    // for (EdgeIt it(G); it != INVALID; ++it) {
277 286
    //   check(map[it] == 12, "Wrong operator[].");
278 287
    // }
279 288
  }
280 289

	
281 290

	
282 291
} //namespace lemon
283 292

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

	
19 19
#include <cstdlib>
20 20
#include <ctime>
21 21

	
22 22
#include <lemon/random.h>
23 23
#include <lemon/list_graph.h>
24 24
#include <lemon/smart_graph.h>
25 25
#include <lemon/maps.h>
26 26

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

	
30 30
using namespace lemon;
31 31

	
32 32
template <typename Digraph>
33 33
void checkFindArcs() {
34 34
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
35 35

	
36 36
  {
37 37
    Digraph digraph;
38 38
    for (int i = 0; i < 10; ++i) {
39 39
      digraph.addNode();
40 40
    }
41
    DescriptorMap<Digraph, Node> nodes(digraph);
42
    typename DescriptorMap<Digraph, Node>::InverseMap invNodes(nodes);
41
    RangeIdMap<Digraph, Node> nodes(digraph);
42
    typename RangeIdMap<Digraph, Node>::InverseMap invNodes(nodes);
43 43
    for (int i = 0; i < 100; ++i) {
44 44
      int src = rnd[invNodes.size()];
45 45
      int trg = rnd[invNodes.size()];
46 46
      digraph.addArc(invNodes[src], invNodes[trg]);
47 47
    }
48 48
    typename Digraph::template ArcMap<bool> found(digraph, false);
49
    DescriptorMap<Digraph, Arc> arcs(digraph);
49
    RangeIdMap<Digraph, Arc> arcs(digraph);
50 50
    for (NodeIt src(digraph); src != INVALID; ++src) {
51 51
      for (NodeIt trg(digraph); trg != INVALID; ++trg) {
52 52
        for (ConArcIt<Digraph> con(digraph, src, trg); con != INVALID; ++con) {
53 53
          check(digraph.source(con) == src, "Wrong source.");
54 54
          check(digraph.target(con) == trg, "Wrong target.");
55 55
          check(found[con] == false, "The arc found already.");
56 56
          found[con] = true;
57 57
        }
58 58
      }
59 59
    }
60 60
    for (ArcIt it(digraph); it != INVALID; ++it) {
61 61
      check(found[it] == true, "The arc is not found.");
62 62
    }
63 63
  }
64 64

	
65 65
  {
66 66
    int num = 5;
67 67
    Digraph fg;
68 68
    std::vector<Node> nodes;
69 69
    for (int i = 0; i < num; ++i) {
70 70
      nodes.push_back(fg.addNode());
71 71
    }
72 72
    for (int i = 0; i < num * num; ++i) {
73 73
      fg.addArc(nodes[i / num], nodes[i % num]);
74 74
    }
75 75
    check(countNodes(fg) == num, "Wrong node number.");
76 76
    check(countArcs(fg) == num*num, "Wrong arc number.");
77 77
    for (NodeIt src(fg); src != INVALID; ++src) {
78 78
      for (NodeIt trg(fg); trg != INVALID; ++trg) {
79 79
        ConArcIt<Digraph> con(fg, src, trg);
80 80
        check(con != INVALID, "There is no connecting arc.");
81 81
        check(fg.source(con) == src, "Wrong source.");
82 82
        check(fg.target(con) == trg, "Wrong target.");
83 83
        check(++con == INVALID, "There is more connecting arc.");
84 84
      }
85 85
    }
86 86
    ArcLookUp<Digraph> al1(fg);
87 87
    DynArcLookUp<Digraph> al2(fg);
88 88
    AllArcLookUp<Digraph> al3(fg);
89 89
    for (NodeIt src(fg); src != INVALID; ++src) {
90 90
      for (NodeIt trg(fg); trg != INVALID; ++trg) {
91 91
        Arc con1 = al1(src, trg);
92 92
        Arc con2 = al2(src, trg);
93 93
        Arc con3 = al3(src, trg);
94 94
        Arc con4 = findArc(fg, src, trg);
95 95
        check(con1 == con2 && con2 == con3 && con3 == con4,
96 96
              "Different results.")
97 97
        check(con1 != INVALID, "There is no connecting arc.");
98 98
        check(fg.source(con1) == src, "Wrong source.");
99 99
        check(fg.target(con1) == trg, "Wrong target.");
100 100
        check(al3(src, trg, con3) == INVALID,
101 101
              "There is more connecting arc.");
102 102
        check(findArc(fg, src, trg, con4) == INVALID,
103 103
              "There is more connecting arc.");
104 104
      }
105 105
    }
106 106
  }
107 107
}
108 108

	
109 109
template <typename Graph>
110 110
void checkFindEdges() {
111 111
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
112 112
  Graph graph;
113 113
  for (int i = 0; i < 10; ++i) {
114 114
    graph.addNode();
115 115
  }
116
  DescriptorMap<Graph, Node> nodes(graph);
117
  typename DescriptorMap<Graph, Node>::InverseMap invNodes(nodes);
116
  RangeIdMap<Graph, Node> nodes(graph);
117
  typename RangeIdMap<Graph, Node>::InverseMap invNodes(nodes);
118 118
  for (int i = 0; i < 100; ++i) {
119 119
    int src = rnd[invNodes.size()];
120 120
    int trg = rnd[invNodes.size()];
121 121
    graph.addEdge(invNodes[src], invNodes[trg]);
122 122
  }
123 123
  typename Graph::template EdgeMap<int> found(graph, 0);
124
  DescriptorMap<Graph, Edge> edges(graph);
124
  RangeIdMap<Graph, Edge> edges(graph);
125 125
  for (NodeIt src(graph); src != INVALID; ++src) {
126 126
    for (NodeIt trg(graph); trg != INVALID; ++trg) {
127 127
      for (ConEdgeIt<Graph> con(graph, src, trg); con != INVALID; ++con) {
128 128
        check( (graph.u(con) == src && graph.v(con) == trg) ||
129 129
               (graph.v(con) == src && graph.u(con) == trg),
130 130
               "Wrong end nodes.");
131 131
        ++found[con];
132 132
        check(found[con] <= 2, "The edge found more than twice.");
133 133
      }
134 134
    }
135 135
  }
136 136
  for (EdgeIt it(graph); it != INVALID; ++it) {
137 137
    check( (graph.u(it) != graph.v(it) && found[it] == 2) ||
138 138
           (graph.u(it) == graph.v(it) && found[it] == 1),
139 139
           "The edge is not found correctly.");
140 140
  }
141 141
}
142 142

	
143 143
template <class Digraph>
144 144
void checkDeg()
145 145
{
146 146
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
147 147

	
148 148
  const int nodeNum = 10;
149 149
  const int arcNum = 100;
150 150
  Digraph digraph;
151 151
  InDegMap<Digraph> inDeg(digraph);
152 152
  OutDegMap<Digraph> outDeg(digraph);
153 153
  std::vector<Node> nodes(nodeNum);
154 154
  for (int i = 0; i < nodeNum; ++i) {
155 155
    nodes[i] = digraph.addNode();
156 156
  }
157 157
  std::vector<Arc> arcs(arcNum);
158 158
  for (int i = 0; i < arcNum; ++i) {
159 159
    arcs[i] = digraph.addArc(nodes[rnd[nodeNum]], nodes[rnd[nodeNum]]);
160 160
  }
161 161
  for (int i = 0; i < nodeNum; ++i) {
162 162
    check(inDeg[nodes[i]] == countInArcs(digraph, nodes[i]),
163 163
          "Wrong in degree map");
164 164
  }
165 165
  for (int i = 0; i < nodeNum; ++i) {
166 166
    check(outDeg[nodes[i]] == countOutArcs(digraph, nodes[i]),
167 167
          "Wrong out degree map");
168 168
  }
169 169
}
170 170

	
171 171
template <class Digraph>
172 172
void checkSnapDeg()
173 173
{
174 174
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
175 175

	
176 176
  Digraph g;
177 177
  Node n1=g.addNode();
178 178
  Node n2=g.addNode();
179 179

	
180 180
  InDegMap<Digraph> ind(g);
181 181

	
182 182
  g.addArc(n1,n2);
183 183

	
184 184
  typename Digraph::Snapshot snap(g);
185 185

	
186 186
  OutDegMap<Digraph> outd(g);
187 187

	
188 188
  check(ind[n1]==0 && ind[n2]==1, "Wrong InDegMap value.");
189 189
  check(outd[n1]==1 && outd[n2]==0, "Wrong OutDegMap value.");
190 190

	
191 191
  g.addArc(n1,n2);
192 192
  g.addArc(n2,n1);
193 193

	
194 194
  check(ind[n1]==1 && ind[n2]==2, "Wrong InDegMap value.");
195 195
  check(outd[n1]==2 && outd[n2]==1, "Wrong OutDegMap value.");
196 196

	
197 197
  snap.restore();
198 198

	
199 199
  check(ind[n1]==0 && ind[n2]==1, "Wrong InDegMap value.");
200 200
  check(outd[n1]==1 && outd[n2]==0, "Wrong OutDegMap value.");
201 201
}
202 202

	
203 203
int main() {
204 204
  // Checking ConArcIt, ConEdgeIt, ArcLookUp, AllArcLookUp, and DynArcLookUp
205 205
  checkFindArcs<ListDigraph>();
206 206
  checkFindArcs<SmartDigraph>();
207 207
  checkFindEdges<ListGraph>();
208 208
  checkFindEdges<SmartGraph>();
209 209

	
210 210
  // Checking In/OutDegMap (and Snapshot feature)
211 211
  checkDeg<ListDigraph>();
212 212
  checkDeg<SmartDigraph>();
213 213
  checkSnapDeg<ListDigraph>();
214 214
  checkSnapDeg<SmartDigraph>();
215 215

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

	
19 19
#include <iostream>
20 20
#include <fstream>
21 21
#include <string>
22 22
#include <vector>
23 23

	
24 24
#include <lemon/concept_check.h>
25 25
#include <lemon/concepts/heap.h>
26 26

	
27 27
#include <lemon/smart_graph.h>
28 28

	
29 29
#include <lemon/lgf_reader.h>
30 30
#include <lemon/dijkstra.h>
31 31
#include <lemon/maps.h>
32 32

	
33 33
#include <lemon/bin_heap.h>
34
#include <lemon/fib_heap.h>
35
#include <lemon/radix_heap.h>
36
#include <lemon/bucket_heap.h>
34 37

	
35 38
#include "test_tools.h"
36 39

	
37 40
using namespace lemon;
38 41
using namespace lemon::concepts;
39 42

	
40 43
typedef ListDigraph Digraph;
41 44
DIGRAPH_TYPEDEFS(Digraph);
42 45

	
43 46
char test_lgf[] =
44 47
  "@nodes\n"
45 48
  "label\n"
46 49
  "0\n"
47 50
  "1\n"
48 51
  "2\n"
49 52
  "3\n"
50 53
  "4\n"
51 54
  "5\n"
52 55
  "6\n"
53 56
  "7\n"
54 57
  "8\n"
55 58
  "9\n"
56 59
  "@arcs\n"
57 60
  "                label   capacity\n"
58 61
  "0       5       0       94\n"
59 62
  "3       9       1       11\n"
60 63
  "8       7       2       83\n"
61 64
  "1       2       3       94\n"
62 65
  "5       7       4       35\n"
63 66
  "7       4       5       84\n"
64 67
  "9       5       6       38\n"
65 68
  "0       4       7       96\n"
66 69
  "6       7       8       6\n"
67 70
  "3       1       9       27\n"
68 71
  "5       2       10      77\n"
69 72
  "5       6       11      69\n"
70 73
  "6       5       12      41\n"
71 74
  "4       6       13      70\n"
72 75
  "3       2       14      45\n"
73 76
  "7       9       15      93\n"
74 77
  "5       9       16      50\n"
75 78
  "9       0       17      94\n"
76 79
  "9       6       18      67\n"
77 80
  "0       9       19      86\n"
78 81
  "@attributes\n"
79 82
  "source 3\n";
80 83

	
81 84
int test_seq[] = { 2, 28, 19, 27, 33, 25, 13, 41, 10, 26,  1,  9,  4, 34};
82 85
int test_inc[] = {20, 28, 34, 16,  0, 46, 44,  0, 42, 32, 14,  8,  6, 37};
83 86

	
84 87
int test_len = sizeof(test_seq) / sizeof(test_seq[0]);
85 88

	
86 89
template <typename Heap>
87 90
void heapSortTest() {
88 91
  RangeMap<int> map(test_len, -1);
89 92

	
90 93
  Heap heap(map);
91 94

	
92 95
  std::vector<int> v(test_len);
93 96

	
94 97
  for (int i = 0; i < test_len; ++i) {
95 98
    v[i] = test_seq[i];
96 99
    heap.push(i, v[i]);
97 100
  }
98 101
  std::sort(v.begin(), v.end());
99 102
  for (int i = 0; i < test_len; ++i) {
100 103
    check(v[i] == heap.prio() ,"Wrong order in heap sort.");
101 104
    heap.pop();
102 105
  }
103 106
}
104 107

	
105 108
template <typename Heap>
106 109
void heapIncreaseTest() {
107 110
  RangeMap<int> map(test_len, -1);
108 111

	
109 112
  Heap heap(map);
110 113

	
111 114
  std::vector<int> v(test_len);
112 115

	
113 116
  for (int i = 0; i < test_len; ++i) {
114 117
    v[i] = test_seq[i];
115 118
    heap.push(i, v[i]);
116 119
  }
117 120
  for (int i = 0; i < test_len; ++i) {
118 121
    v[i] += test_inc[i];
119 122
    heap.increase(i, v[i]);
120 123
  }
121 124
  std::sort(v.begin(), v.end());
122 125
  for (int i = 0; i < test_len; ++i) {
123 126
    check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
124 127
    heap.pop();
125 128
  }
126 129
}
127 130

	
128 131

	
129 132

	
130 133
template <typename Heap>
131 134
void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
132 135
                      Node source) {
133 136

	
134 137
  typename Dijkstra<Digraph, IntArcMap>::template SetStandardHeap<Heap>::
135 138
    Create dijkstra(digraph, length);
136 139

	
137 140
  dijkstra.run(source);
138 141

	
139 142
  for(ArcIt a(digraph); a != INVALID; ++a) {
140 143
    Node s = digraph.source(a);
141 144
    Node t = digraph.target(a);
142 145
    if (dijkstra.reached(s)) {
143 146
      check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
144 147
             "Error in a shortest path tree!");
145 148
    }
146 149
  }
147 150

	
148 151
  for(NodeIt n(digraph); n != INVALID; ++n) {
149 152
    if ( dijkstra.reached(n) && dijkstra.predArc(n) != INVALID ) {
150 153
      Arc a = dijkstra.predArc(n);
151 154
      Node s = digraph.source(a);
152 155
      check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
153 156
             "Error in a shortest path tree!");
154 157
    }
155 158
  }
156 159

	
157 160
}
158 161

	
159 162
int main() {
160 163

	
161 164
  typedef int Item;
162 165
  typedef int Prio;
163 166
  typedef RangeMap<int> ItemIntMap;
164 167

	
165 168
  Digraph digraph;
166 169
  IntArcMap length(digraph);
167 170
  Node source;
168 171

	
169 172
  std::istringstream input(test_lgf);
170 173
  digraphReader(digraph, input).
171 174
    arcMap("capacity", length).
172 175
    node("source", source).
173 176
    run();
174 177

	
175 178
  {
176 179
    typedef BinHeap<Prio, ItemIntMap> IntHeap;
177 180
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
178 181
    heapSortTest<IntHeap>();
179 182
    heapIncreaseTest<IntHeap>();
180 183

	
181 184
    typedef BinHeap<Prio, IntNodeMap > NodeHeap;
182 185
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
183 186
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
184 187
  }
185 188

	
189
  {
190
    typedef FibHeap<Prio, ItemIntMap> IntHeap;
191
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
192
    heapSortTest<IntHeap>();
193
    heapIncreaseTest<IntHeap>();
194

	
195
    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
196
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
197
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
198
  }
199

	
200
  {
201
    typedef RadixHeap<ItemIntMap> IntHeap;
202
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
203
    heapSortTest<IntHeap>();
204
    heapIncreaseTest<IntHeap>();
205

	
206
    typedef RadixHeap<IntNodeMap > NodeHeap;
207
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
208
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
209
  }
210

	
211
  {
212
    typedef BucketHeap<ItemIntMap> IntHeap;
213
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
214
    heapSortTest<IntHeap>();
215
    heapIncreaseTest<IntHeap>();
216

	
217
    typedef BucketHeap<IntNodeMap > NodeHeap;
218
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
219
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
220
  }
221

	
222

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

	
19 19
#include <iostream>
20 20
#include <vector>
21 21

	
22 22
#include "test_tools.h"
23 23
#include <lemon/maps.h>
24 24
#include <lemon/kruskal.h>
25 25
#include <lemon/list_graph.h>
26 26

	
27 27
#include <lemon/concepts/maps.h>
28 28
#include <lemon/concepts/digraph.h>
29 29
#include <lemon/concepts/graph.h>
30 30

	
31 31
using namespace std;
32 32
using namespace lemon;
33 33

	
34 34
void checkCompileKruskal()
35 35
{
36 36
  concepts::WriteMap<concepts::Digraph::Arc,bool> w;
37 37
  concepts::WriteMap<concepts::Graph::Edge,bool> uw;
38 38

	
39 39
  concepts::ReadMap<concepts::Digraph::Arc,int> r;
40 40
  concepts::ReadMap<concepts::Graph::Edge,int> ur;
41 41

	
42 42
  concepts::Digraph g;
43 43
  concepts::Graph ug;
44 44

	
45 45
  kruskal(g, r, w);
46 46
  kruskal(ug, ur, uw);
47 47

	
48 48
  std::vector<std::pair<concepts::Digraph::Arc, int> > rs;
49 49
  std::vector<std::pair<concepts::Graph::Edge, int> > urs;
50 50

	
51 51
  kruskal(g, rs, w);
52 52
  kruskal(ug, urs, uw);
53 53

	
54 54
  std::vector<concepts::Digraph::Arc> ws;
55 55
  std::vector<concepts::Graph::Edge> uws;
56 56

	
57 57
  kruskal(g, r, ws.begin());
58 58
  kruskal(ug, ur, uws.begin());
59 59
}
60 60

	
61 61
int main() {
62 62

	
63 63
  typedef ListGraph::Node Node;
64 64
  typedef ListGraph::Edge Edge;
65 65
  typedef ListGraph::NodeIt NodeIt;
66 66
  typedef ListGraph::ArcIt ArcIt;
67 67

	
68 68
  ListGraph G;
69 69

	
70 70
  Node s=G.addNode();
71 71
  Node v1=G.addNode();
72 72
  Node v2=G.addNode();
73 73
  Node v3=G.addNode();
74 74
  Node v4=G.addNode();
75 75
  Node t=G.addNode();
76 76

	
77 77
  Edge e1 = G.addEdge(s, v1);
78 78
  Edge e2 = G.addEdge(s, v2);
79 79
  Edge e3 = G.addEdge(v1, v2);
80 80
  Edge e4 = G.addEdge(v2, v1);
81 81
  Edge e5 = G.addEdge(v1, v3);
82 82
  Edge e6 = G.addEdge(v3, v2);
83 83
  Edge e7 = G.addEdge(v2, v4);
84 84
  Edge e8 = G.addEdge(v4, v3);
85 85
  Edge e9 = G.addEdge(v3, t);
86 86
  Edge e10 = G.addEdge(v4, t);
87 87

	
88 88
  typedef ListGraph::EdgeMap<int> ECostMap;
89 89
  typedef ListGraph::EdgeMap<bool> EBoolMap;
90 90

	
91 91
  ECostMap edge_cost_map(G, 2);
92 92
  EBoolMap tree_map(G);
93 93

	
94 94

	
95 95
  //Test with const map.
96 96
  check(kruskal(G, ConstMap<ListGraph::Edge,int>(2), tree_map)==10,
97 97
        "Total cost should be 10");
98 98
  //Test with an edge map (filled with uniform costs).
99 99
  check(kruskal(G, edge_cost_map, tree_map)==10,
100 100
        "Total cost should be 10");
101 101

	
102
  edge_cost_map.set(e1, -10);
103
  edge_cost_map.set(e2, -9);
104
  edge_cost_map.set(e3, -8);
105
  edge_cost_map.set(e4, -7);
106
  edge_cost_map.set(e5, -6);
107
  edge_cost_map.set(e6, -5);
108
  edge_cost_map.set(e7, -4);
109
  edge_cost_map.set(e8, -3);
110
  edge_cost_map.set(e9, -2);
111
  edge_cost_map.set(e10, -1);
102
  edge_cost_map[e1] = -10;
103
  edge_cost_map[e2] = -9;
104
  edge_cost_map[e3] = -8;
105
  edge_cost_map[e4] = -7;
106
  edge_cost_map[e5] = -6;
107
  edge_cost_map[e6] = -5;
108
  edge_cost_map[e7] = -4;
109
  edge_cost_map[e8] = -3;
110
  edge_cost_map[e9] = -2;
111
  edge_cost_map[e10] = -1;
112 112

	
113 113
  vector<Edge> tree_edge_vec(5);
114 114

	
115 115
  //Test with a edge map and inserter.
116 116
  check(kruskal(G, edge_cost_map,
117 117
                 tree_edge_vec.begin())
118 118
        ==-31,
119 119
        "Total cost should be -31.");
120 120

	
121 121
  tree_edge_vec.clear();
122 122

	
123 123
  check(kruskal(G, edge_cost_map,
124 124
                back_inserter(tree_edge_vec))
125 125
        ==-31,
126 126
        "Total cost should be -31.");
127 127

	
128 128
//   tree_edge_vec.clear();
129 129

	
130 130
//   //The above test could also be coded like this:
131 131
//   check(kruskal(G,
132 132
//                 makeKruskalMapInput(G, edge_cost_map),
133 133
//                 makeKruskalSequenceOutput(back_inserter(tree_edge_vec)))
134 134
//         ==-31,
135 135
//         "Total cost should be -31.");
136 136

	
137 137
  check(tree_edge_vec.size()==5,"The tree should have 5 edges.");
138 138

	
139 139
  check(tree_edge_vec[0]==e1 &&
140 140
        tree_edge_vec[1]==e2 &&
141 141
        tree_edge_vec[2]==e5 &&
142 142
        tree_edge_vec[3]==e7 &&
143 143
        tree_edge_vec[4]==e9,
144 144
        "Wrong tree.");
145 145

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

	
19 19
#include <deque>
20 20
#include <set>
21 21

	
22 22
#include <lemon/concept_check.h>
23 23
#include <lemon/concepts/maps.h>
24 24
#include <lemon/maps.h>
25 25

	
26 26
#include "test_tools.h"
27 27

	
28 28
using namespace lemon;
29 29
using namespace lemon::concepts;
30 30

	
31 31
struct A {};
32 32
inline bool operator<(A, A) { return true; }
33 33
struct B {};
34 34

	
35 35
class C {
36 36
  int x;
37 37
public:
38 38
  C(int _x) : x(_x) {}
39 39
};
40 40

	
41 41
class F {
42 42
public:
43 43
  typedef A argument_type;
44 44
  typedef B result_type;
45 45

	
46 46
  B operator()(const A&) const { return B(); }
47 47
private:
48 48
  F& operator=(const F&);
49 49
};
50 50

	
51 51
int func(A) { return 3; }
52 52

	
53 53
int binc(int a, B) { return a+1; }
54 54

	
55 55
typedef ReadMap<A, double> DoubleMap;
56 56
typedef ReadWriteMap<A, double> DoubleWriteMap;
57 57
typedef ReferenceMap<A, double, double&, const double&> DoubleRefMap;
58 58

	
59 59
typedef ReadMap<A, bool> BoolMap;
60 60
typedef ReadWriteMap<A, bool> BoolWriteMap;
61 61
typedef ReferenceMap<A, bool, bool&, const bool&> BoolRefMap;
62 62

	
63 63
int main()
64 64
{
65 65
  // Map concepts
66 66
  checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
67 67
  checkConcept<ReadMap<A,C>, ReadMap<A,C> >();
68 68
  checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
69 69
  checkConcept<WriteMap<A,C>, WriteMap<A,C> >();
70 70
  checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
71 71
  checkConcept<ReadWriteMap<A,C>, ReadWriteMap<A,C> >();
72 72
  checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();
73 73
  checkConcept<ReferenceMap<A,C,C&,const C&>, ReferenceMap<A,C,C&,const C&> >();
74 74

	
75 75
  // NullMap
76 76
  {
77 77
    checkConcept<ReadWriteMap<A,B>, NullMap<A,B> >();
78 78
    NullMap<A,B> map1;
79 79
    NullMap<A,B> map2 = map1;
80 80
    map1 = nullMap<A,B>();
81 81
  }
82 82

	
83 83
  // ConstMap
84 84
  {
85 85
    checkConcept<ReadWriteMap<A,B>, ConstMap<A,B> >();
86 86
    checkConcept<ReadWriteMap<A,C>, ConstMap<A,C> >();
87 87
    ConstMap<A,B> map1;
88 88
    ConstMap<A,B> map2 = B();
89 89
    ConstMap<A,B> map3 = map1;
90 90
    map1 = constMap<A>(B());
91 91
    map1 = constMap<A,B>();
92 92
    map1.setAll(B());
93 93
    ConstMap<A,C> map4(C(1));
94 94
    ConstMap<A,C> map5 = map4;
95 95
    map4 = constMap<A>(C(2));
96 96
    map4.setAll(C(3));
97 97

	
98 98
    checkConcept<ReadWriteMap<A,int>, ConstMap<A,int> >();
99 99
    check(constMap<A>(10)[A()] == 10, "Something is wrong with ConstMap");
100 100

	
101 101
    checkConcept<ReadWriteMap<A,int>, ConstMap<A,Const<int,10> > >();
102 102
    ConstMap<A,Const<int,10> > map6;
103 103
    ConstMap<A,Const<int,10> > map7 = map6;
104 104
    map6 = constMap<A,int,10>();
105 105
    map7 = constMap<A,Const<int,10> >();
106 106
    check(map6[A()] == 10 && map7[A()] == 10,
107 107
          "Something is wrong with ConstMap");
108 108
  }
109 109

	
110 110
  // IdentityMap
111 111
  {
112 112
    checkConcept<ReadMap<A,A>, IdentityMap<A> >();
113 113
    IdentityMap<A> map1;
114 114
    IdentityMap<A> map2 = map1;
115 115
    map1 = identityMap<A>();
116 116

	
117 117
    checkConcept<ReadMap<double,double>, IdentityMap<double> >();
118 118
    check(identityMap<double>()[1.0] == 1.0 &&
119 119
          identityMap<double>()[3.14] == 3.14,
120 120
          "Something is wrong with IdentityMap");
121 121
  }
122 122

	
123 123
  // RangeMap
124 124
  {
125 125
    checkConcept<ReferenceMap<int,B,B&,const B&>, RangeMap<B> >();
126 126
    RangeMap<B> map1;
127 127
    RangeMap<B> map2(10);
128 128
    RangeMap<B> map3(10,B());
129 129
    RangeMap<B> map4 = map1;
130 130
    RangeMap<B> map5 = rangeMap<B>();
131 131
    RangeMap<B> map6 = rangeMap<B>(10);
132 132
    RangeMap<B> map7 = rangeMap(10,B());
133 133

	
134 134
    checkConcept< ReferenceMap<int, double, double&, const double&>,
135 135
                  RangeMap<double> >();
136 136
    std::vector<double> v(10, 0);
137 137
    v[5] = 100;
138 138
    RangeMap<double> map8(v);
139 139
    RangeMap<double> map9 = rangeMap(v);
140 140
    check(map9.size() == 10 && map9[2] == 0 && map9[5] == 100,
141 141
          "Something is wrong with RangeMap");
142 142
  }
143 143

	
144 144
  // SparseMap
145 145
  {
146 146
    checkConcept<ReferenceMap<A,B,B&,const B&>, SparseMap<A,B> >();
147 147
    SparseMap<A,B> map1;
148 148
    SparseMap<A,B> map2 = B();
149 149
    SparseMap<A,B> map3 = sparseMap<A,B>();
150 150
    SparseMap<A,B> map4 = sparseMap<A>(B());
151 151

	
152 152
    checkConcept< ReferenceMap<double, int, int&, const int&>,
153 153
                  SparseMap<double, int> >();
154 154
    std::map<double, int> m;
155 155
    SparseMap<double, int> map5(m);
156 156
    SparseMap<double, int> map6(m,10);
157 157
    SparseMap<double, int> map7 = sparseMap(m);
158 158
    SparseMap<double, int> map8 = sparseMap(m,10);
159 159

	
160 160
    check(map5[1.0] == 0 && map5[3.14] == 0 &&
161 161
          map6[1.0] == 10 && map6[3.14] == 10,
162 162
          "Something is wrong with SparseMap");
163 163
    map5[1.0] = map6[3.14] = 100;
164 164
    check(map5[1.0] == 100 && map5[3.14] == 0 &&
165 165
          map6[1.0] == 10 && map6[3.14] == 100,
166 166
          "Something is wrong with SparseMap");
167 167
  }
168 168

	
169 169
  // ComposeMap
170 170
  {
171 171
    typedef ComposeMap<DoubleMap, ReadMap<B,A> > CompMap;
172 172
    checkConcept<ReadMap<B,double>, CompMap>();
173
    CompMap map1(DoubleMap(),ReadMap<B,A>());
173
    CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
174 174
    CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
175 175

	
176 176
    SparseMap<double, bool> m1(false); m1[3.14] = true;
177 177
    RangeMap<double> m2(2); m2[0] = 3.0; m2[1] = 3.14;
178 178
    check(!composeMap(m1,m2)[0] && composeMap(m1,m2)[1],
179 179
          "Something is wrong with ComposeMap")
180 180
  }
181 181

	
182 182
  // CombineMap
183 183
  {
184 184
    typedef CombineMap<DoubleMap, DoubleMap, std::plus<double> > CombMap;
185 185
    checkConcept<ReadMap<A,double>, CombMap>();
186
    CombMap map1(DoubleMap(), DoubleMap());
186
    CombMap map1 = CombMap(DoubleMap(), DoubleMap());
187 187
    CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
188 188

	
189 189
    check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
190 190
          "Something is wrong with CombineMap");
191 191
  }
192 192

	
193 193
  // FunctorToMap, MapToFunctor
194 194
  {
195 195
    checkConcept<ReadMap<A,B>, FunctorToMap<F,A,B> >();
196 196
    checkConcept<ReadMap<A,B>, FunctorToMap<F> >();
197 197
    FunctorToMap<F> map1;
198
    FunctorToMap<F> map2(F());
198
    FunctorToMap<F> map2 = FunctorToMap<F>(F());
199 199
    B b = functorToMap(F())[A()];
200 200

	
201 201
    checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
202
    MapToFunctor<ReadMap<A,B> > map(ReadMap<A,B>());
202
    MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
203 203

	
204 204
    check(functorToMap(&func)[A()] == 3,
205 205
          "Something is wrong with FunctorToMap");
206 206
    check(mapToFunctor(constMap<A,int>(2))(A()) == 2,
207 207
          "Something is wrong with MapToFunctor");
208 208
    check(mapToFunctor(functorToMap(&func))(A()) == 3 &&
209 209
          mapToFunctor(functorToMap(&func))[A()] == 3,
210 210
          "Something is wrong with FunctorToMap or MapToFunctor");
211 211
    check(functorToMap(mapToFunctor(constMap<A,int>(2)))[A()] == 2,
212 212
          "Something is wrong with FunctorToMap or MapToFunctor");
213 213
  }
214 214

	
215 215
  // ConvertMap
216 216
  {
217 217
    checkConcept<ReadMap<double,double>,
218 218
      ConvertMap<ReadMap<double, int>, double> >();
219 219
    ConvertMap<RangeMap<bool>, int> map1(rangeMap(1, true));
220 220
    ConvertMap<RangeMap<bool>, int> map2 = convertMap<int>(rangeMap(2, false));
221 221
  }
222 222

	
223 223
  // ForkMap
224 224
  {
225 225
    checkConcept<DoubleWriteMap, ForkMap<DoubleWriteMap, DoubleWriteMap> >();
226 226

	
227 227
    typedef RangeMap<double> RM;
228 228
    typedef SparseMap<int, double> SM;
229 229
    RM m1(10, -1);
230 230
    SM m2(-1);
231 231
    checkConcept<ReadWriteMap<int, double>, ForkMap<RM, SM> >();
232 232
    checkConcept<ReadWriteMap<int, double>, ForkMap<SM, RM> >();
233 233
    ForkMap<RM, SM> map1(m1,m2);
234 234
    ForkMap<SM, RM> map2 = forkMap(m2,m1);
235 235
    map2.set(5, 10);
236 236
    check(m1[1] == -1 && m1[5] == 10 && m2[1] == -1 &&
237 237
          m2[5] == 10 && map2[1] == -1 && map2[5] == 10,
238 238
          "Something is wrong with ForkMap");
239 239
  }
240 240

	
241 241
  // Arithmetic maps:
242 242
  // - AddMap, SubMap, MulMap, DivMap
243 243
  // - ShiftMap, ShiftWriteMap, ScaleMap, ScaleWriteMap
244 244
  // - NegMap, NegWriteMap, AbsMap
245 245
  {
246 246
    checkConcept<DoubleMap, AddMap<DoubleMap,DoubleMap> >();
247 247
    checkConcept<DoubleMap, SubMap<DoubleMap,DoubleMap> >();
248 248
    checkConcept<DoubleMap, MulMap<DoubleMap,DoubleMap> >();
249 249
    checkConcept<DoubleMap, DivMap<DoubleMap,DoubleMap> >();
250 250

	
251 251
    ConstMap<int, double> c1(1.0), c2(3.14);
252 252
    IdentityMap<int> im;
253 253
    ConvertMap<IdentityMap<int>, double> id(im);
254 254
    check(addMap(c1,id)[0] == 1.0  && addMap(c1,id)[10] == 11.0,
255 255
          "Something is wrong with AddMap");
256 256
    check(subMap(id,c1)[0] == -1.0 && subMap(id,c1)[10] == 9.0,
257 257
          "Something is wrong with SubMap");
258 258
    check(mulMap(id,c2)[0] == 0    && mulMap(id,c2)[2]  == 6.28,
259 259
          "Something is wrong with MulMap");
260 260
    check(divMap(c2,id)[1] == 3.14 && divMap(c2,id)[2]  == 1.57,
261 261
          "Something is wrong with DivMap");
262 262

	
263 263
    checkConcept<DoubleMap, ShiftMap<DoubleMap> >();
264 264
    checkConcept<DoubleWriteMap, ShiftWriteMap<DoubleWriteMap> >();
265 265
    checkConcept<DoubleMap, ScaleMap<DoubleMap> >();
266 266
    checkConcept<DoubleWriteMap, ScaleWriteMap<DoubleWriteMap> >();
267 267
    checkConcept<DoubleMap, NegMap<DoubleMap> >();
268 268
    checkConcept<DoubleWriteMap, NegWriteMap<DoubleWriteMap> >();
269 269
    checkConcept<DoubleMap, AbsMap<DoubleMap> >();
270 270

	
271 271
    check(shiftMap(id, 2.0)[1] == 3.0 && shiftMap(id, 2.0)[10] == 12.0,
272 272
          "Something is wrong with ShiftMap");
273 273
    check(shiftWriteMap(id, 2.0)[1] == 3.0 &&
274 274
          shiftWriteMap(id, 2.0)[10] == 12.0,
275 275
          "Something is wrong with ShiftWriteMap");
276 276
    check(scaleMap(id, 2.0)[1] == 2.0 && scaleMap(id, 2.0)[10] == 20.0,
277 277
          "Something is wrong with ScaleMap");
278 278
    check(scaleWriteMap(id, 2.0)[1] == 2.0 &&
279 279
          scaleWriteMap(id, 2.0)[10] == 20.0,
280 280
          "Something is wrong with ScaleWriteMap");
281 281
    check(negMap(id)[1] == -1.0 && negMap(id)[-10] == 10.0,
282 282
          "Something is wrong with NegMap");
283 283
    check(negWriteMap(id)[1] == -1.0 && negWriteMap(id)[-10] == 10.0,
284 284
          "Something is wrong with NegWriteMap");
285 285
    check(absMap(id)[1] == 1.0 && absMap(id)[-10] == 10.0,
286 286
          "Something is wrong with AbsMap");
287 287
  }
288 288

	
289 289
  // Logical maps:
290 290
  // - TrueMap, FalseMap
291 291
  // - AndMap, OrMap
292 292
  // - NotMap, NotWriteMap
293 293
  // - EqualMap, LessMap
294 294
  {
295 295
    checkConcept<BoolMap, TrueMap<A> >();
296 296
    checkConcept<BoolMap, FalseMap<A> >();
297 297
    checkConcept<BoolMap, AndMap<BoolMap,BoolMap> >();
298 298
    checkConcept<BoolMap, OrMap<BoolMap,BoolMap> >();
299 299
    checkConcept<BoolMap, NotMap<BoolMap> >();
300 300
    checkConcept<BoolWriteMap, NotWriteMap<BoolWriteMap> >();
301 301
    checkConcept<BoolMap, EqualMap<DoubleMap,DoubleMap> >();
302 302
    checkConcept<BoolMap, LessMap<DoubleMap,DoubleMap> >();
303 303

	
304 304
    TrueMap<int> tm;
305 305
    FalseMap<int> fm;
306 306
    RangeMap<bool> rm(2);
307 307
    rm[0] = true; rm[1] = false;
308 308
    check(andMap(tm,rm)[0] && !andMap(tm,rm)[1] &&
309 309
          !andMap(fm,rm)[0] && !andMap(fm,rm)[1],
310 310
          "Something is wrong with AndMap");
311 311
    check(orMap(tm,rm)[0] && orMap(tm,rm)[1] &&
312 312
          orMap(fm,rm)[0] && !orMap(fm,rm)[1],
313 313
          "Something is wrong with OrMap");
314 314
    check(!notMap(rm)[0] && notMap(rm)[1],
315 315
          "Something is wrong with NotMap");
316 316
    check(!notWriteMap(rm)[0] && notWriteMap(rm)[1],
317 317
          "Something is wrong with NotWriteMap");
318 318

	
319 319
    ConstMap<int, double> cm(2.0);
320 320
    IdentityMap<int> im;
321 321
    ConvertMap<IdentityMap<int>, double> id(im);
322 322
    check(lessMap(id,cm)[1] && !lessMap(id,cm)[2] && !lessMap(id,cm)[3],
323 323
          "Something is wrong with LessMap");
324 324
    check(!equalMap(id,cm)[1] && equalMap(id,cm)[2] && !equalMap(id,cm)[3],
325 325
          "Something is wrong with EqualMap");
326 326
  }
327 327

	
328 328
  // LoggerBoolMap
329 329
  {
330 330
    typedef std::vector<int> vec;
331 331
    vec v1;
332 332
    vec v2(10);
333 333
    LoggerBoolMap<std::back_insert_iterator<vec> >
334 334
      map1(std::back_inserter(v1));
335 335
    LoggerBoolMap<vec::iterator> map2(v2.begin());
336 336
    map1.set(10, false);
337 337
    map1.set(20, true);   map2.set(20, true);
338 338
    map1.set(30, false);  map2.set(40, false);
339 339
    map1.set(50, true);   map2.set(50, true);
340 340
    map1.set(60, true);   map2.set(60, true);
341 341
    check(v1.size() == 3 && v2.size() == 10 &&
342 342
          v1[0]==20 && v1[1]==50 && v1[2]==60 &&
343 343
          v2[0]==20 && v2[1]==50 && v2[2]==60,
344 344
          "Something is wrong with LoggerBoolMap");
345 345

	
346 346
    int i = 0;
347 347
    for ( LoggerBoolMap<vec::iterator>::Iterator it = map2.begin();
348 348
          it != map2.end(); ++it )
349 349
      check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
350 350
  }
351 351

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

	
19 19
#include <string>
20 20
#include <iostream>
21 21

	
22 22
#include <lemon/concepts/path.h>
23 23
#include <lemon/concepts/digraph.h>
24 24

	
25 25
#include <lemon/path.h>
26 26
#include <lemon/list_graph.h>
27 27

	
28 28
#include "test_tools.h"
29 29

	
30 30
using namespace std;
31 31
using namespace lemon;
32 32

	
33 33
void check_concepts() {
34 34
  checkConcept<concepts::Path<ListDigraph>, concepts::Path<ListDigraph> >();
35 35
  checkConcept<concepts::Path<ListDigraph>, Path<ListDigraph> >();
36 36
  checkConcept<concepts::Path<ListDigraph>, SimplePath<ListDigraph> >();
37 37
  checkConcept<concepts::Path<ListDigraph>, StaticPath<ListDigraph> >();
38 38
  checkConcept<concepts::Path<ListDigraph>, ListPath<ListDigraph> >();
39 39
}
40 40

	
41 41
int main() {
42 42
  check_concepts();
43 43
  return 0;
44 44
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/random.h>
20 20
#include "test_tools.h"
21 21

	
22 22
int seed_array[] = {1, 2};
23 23

	
24 24
int main()
25 25
{
26 26
  double a=lemon::rnd();
27 27
  check(a<1.0&&a>0.0,"This should be in [0,1)");
28 28
  a=lemon::rnd.gauss();
29 29
  a=lemon::rnd.gamma(3.45,0);
30 30
  a=lemon::rnd.gamma(4);
31 31
  //Does gamma work with integer k?
32 32
  a=lemon::rnd.gamma(4.0,0);
33 33
  a=lemon::rnd.poisson(.5);
34 34

	
35 35
  lemon::rnd.seed(100);
36 36
  lemon::rnd.seed(seed_array, seed_array +
37 37
                  (sizeof(seed_array) / sizeof(seed_array[0])));
38 38

	
39 39
  return 0;
40 40
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
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 27
#include <stdlib.h>
28 28

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

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

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

	
19 19
#include "test_tools.h"
20 20

	
21 21
int main()
22 22
{
23 23
  check(false, "Don't panic. Failing is the right behaviour here.");
24 24
  return 0;
25 25
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include "test_tools.h"
20 20

	
21 21
int main()
22 22
{
23 23
  check(true, "It should pass.");
24 24
  return 0;
25 25
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/time_measure.h>
20 20

	
21 21
using namespace lemon;
22 22

	
23 23
void f()
24 24
{
25 25
  double d=0;
26 26
  for(int i=0;i<1000;i++)
27 27
    d+=0.1;
28 28
}
29 29

	
30 30
void g()
31 31
{
32 32
  static Timer T;
33 33

	
34 34
  for(int i=0;i<1000;i++)
35 35
    TimeStamp x(T);
36 36
}
37 37

	
38 38
int main()
39 39
{
40 40
  Timer T;
41 41
  unsigned int n;
42
  for(n=0;T.realTime()<1.0;n++) ;
42
  for(n=0;T.realTime()<0.1;n++) ;
43 43
  std::cout << T << " (" << n << " time queries)\n";
44
  T.restart();
45
  while(T.realTime()<2.0) ;
46
  std::cout << T << '\n';
44

	
47 45
  TimeStamp full;
48 46
  TimeStamp t;
49
  t=runningTimeTest(f,1,&n,&full);
47
  t=runningTimeTest(f,0.1,&n,&full);
50 48
  std::cout << t << " (" << n << " tests)\n";
51 49
  std::cout << "Total: " << full << "\n";
52 50

	
53
  t=runningTimeTest(g,1,&n,&full);
51
  t=runningTimeTest(g,0.1,&n,&full);
54 52
  std::cout << t << " (" << n << " tests)\n";
55 53
  std::cout << "Total: " << full << "\n";
56 54

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

	
19 19
#include <lemon/list_graph.h>
20 20
#include <lemon/maps.h>
21 21
#include <lemon/unionfind.h>
22 22
#include "test_tools.h"
23 23

	
24 24
using namespace lemon;
25 25
using namespace std;
26 26

	
27 27
typedef UnionFindEnum<ListGraph::NodeMap<int> > UFE;
28 28

	
29 29
int main() {
30 30
  ListGraph g;
31 31
  ListGraph::NodeMap<int> base(g);
32 32
  UFE U(base);
33 33
  vector<ListGraph::Node> n;
34 34

	
35 35
  for(int i=0;i<20;i++) n.push_back(g.addNode());
36 36

	
37 37
  U.insert(n[1]);
38 38
  U.insert(n[2]);
39 39

	
40 40
  check(U.join(n[1],n[2]) != -1, "Something is wrong with UnionFindEnum");
41 41

	
42 42
  U.insert(n[3]);
43 43
  U.insert(n[4]);
44 44
  U.insert(n[5]);
45 45
  U.insert(n[6]);
46 46
  U.insert(n[7]);
47 47

	
48 48

	
49 49
  check(U.join(n[1],n[4]) != -1, "Something is wrong with UnionFindEnum");
50 50
  check(U.join(n[2],n[4]) == -1, "Something is wrong with UnionFindEnum");
51 51
  check(U.join(n[3],n[5]) != -1, "Something is wrong with UnionFindEnum");
52 52

	
53 53

	
54 54
  U.insert(n[8],U.find(n[5]));
55 55

	
56 56

	
57 57
  check(U.size(U.find(n[4])) == 3, "Something is wrong with UnionFindEnum");
58 58
  check(U.size(U.find(n[5])) == 3, "Something is wrong with UnionFindEnum");
59 59
  check(U.size(U.find(n[6])) == 1, "Something is wrong with UnionFindEnum");
60 60
  check(U.size(U.find(n[2])) == 3, "Something is wrong with UnionFindEnum");
61 61

	
62 62

	
63 63
  U.insert(n[9]);
64 64
  U.insert(n[10],U.find(n[9]));
65 65

	
66 66

	
67 67
  check(U.join(n[8],n[10])  != -1, "Something is wrong with UnionFindEnum");
68 68

	
69 69

	
70 70
  check(U.size(U.find(n[4])) == 3, "Something is wrong with UnionFindEnum");
71 71
  check(U.size(U.find(n[9])) == 5, "Something is wrong with UnionFindEnum");
72 72

	
73 73
  check(U.size(U.find(n[8])) == 5, "Something is wrong with UnionFindEnum");
74 74

	
75 75
  U.erase(n[9]);
76 76
  U.erase(n[1]);
77 77

	
78 78
  check(U.size(U.find(n[10])) == 4, "Something is wrong with UnionFindEnum");
79 79
  check(U.size(U.find(n[2]))  == 2, "Something is wrong with UnionFindEnum");
80 80

	
81 81
  U.erase(n[6]);
82 82
  U.split(U.find(n[8]));
83 83

	
84 84

	
85 85
  check(U.size(U.find(n[4])) == 2, "Something is wrong with UnionFindEnum");
86 86
  check(U.size(U.find(n[3])) == 1, "Something is wrong with UnionFindEnum");
87 87
  check(U.size(U.find(n[2])) == 2, "Something is wrong with UnionFindEnum");
88 88

	
89 89

	
90 90
  check(U.join(n[3],n[4]) != -1, "Something is wrong with UnionFindEnum");
91 91
  check(U.join(n[2],n[4]) == -1, "Something is wrong with UnionFindEnum");
92 92

	
93 93

	
94 94
  check(U.size(U.find(n[4])) == 3, "Something is wrong with UnionFindEnum");
95 95
  check(U.size(U.find(n[3])) == 3, "Something is wrong with UnionFindEnum");
96 96
  check(U.size(U.find(n[2])) == 3, "Something is wrong with UnionFindEnum");
97 97

	
98 98
  U.eraseClass(U.find(n[4]));
99 99
  U.eraseClass(U.find(n[7]));
100 100

	
101 101
  return 0;
102 102
}
Ignore white space 6 line context
1
EXTRA_DIST += \
2
	tools/CMakeLists.txt
3

	
1 4
if WANT_TOOLS
2 5

	
3
bin_PROGRAMS +=
6
bin_PROGRAMS += \
7
	tools/dimacs-solver \
8
	tools/dimacs-to-lgf \
9
	tools/lgf-gen
10

	
4 11
dist_bin_SCRIPTS += tools/lemon-0.x-to-1.x.sh
5 12

	
6 13
endif WANT_TOOLS
14

	
15
tools_dimacs_solver_SOURCES = tools/dimacs-solver.cc
16
tools_dimacs_to_lgf_SOURCES = tools/dimacs-to-lgf.cc
17
tools_lgf_gen_SOURCES = tools/lgf-gen.cc
Ignore white space 6 line context
1 1
#!/bin/bash
2 2

	
3 3
set -e
4 4

	
5 5
if [ $# -eq 0 -o x$1 = "x-h" -o x$1 = "x-help" -o x$1 = "x--help" ]; then
6
	echo "Usage:"
7
	echo "  $0 source-file"
8
	exit
6
    echo "Usage:"
7
    echo "  $0 source-file(s)"
8
    exit
9 9
fi
10 10

	
11
TMP=`mktemp`
12

	
13
sed	-e "s/undirected graph/_gr_aph_label_/g"\
14
	-e "s/undirected edge/_ed_ge_label_/g"\
15
	-e "s/graph_/_gr_aph_label__/g"\
16
	-e "s/_graph/__gr_aph_label_/g"\
17
	-e "s/UGraph/_Gr_aph_label_/g"\
18
	-e "s/uGraph/_gr_aph_label_/g"\
19
	-e "s/ugraph/_gr_aph_label_/g"\
20
	-e "s/Graph/_Digr_aph_label_/g"\
21
	-e "s/graph/_digr_aph_label_/g"\
22
	-e "s/UEdge/_Ed_ge_label_/g"\
23
	-e "s/uEdge/_ed_ge_label_/g"\
24
	-e "s/uedge/_ed_ge_label_/g"\
25
	-e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
26
	-e "s/Edge/_Ar_c_label_/g"\
27
	-e "s/edge/_ar_c_label_/g"\
28
	-e "s/ANode/_Re_d_label_/g"\
29
	-e "s/BNode/_Blu_e_label_/g"\
30
	-e "s/A-Node/_Re_d_label_/g"\
31
	-e "s/B-Node/_Blu_e_label_/g"\
32
	-e "s/anode/_re_d_label_/g"\
33
	-e "s/bnode/_blu_e_label_/g"\
34
	-e "s/aNode/_re_d_label_/g"\
35
	-e "s/bNode/_blu_e_label_/g"\
36
	-e "s/_Digr_aph_label_/Digraph/g"\
37
	-e "s/_digr_aph_label_/digraph/g"\
38
	-e "s/_Gr_aph_label_/Graph/g"\
39
	-e "s/_gr_aph_label_/graph/g"\
40
	-e "s/_Ar_c_label_/Arc/g"\
41
	-e "s/_ar_c_label_/arc/g"\
42
	-e "s/_Ed_ge_label_/Edge/g"\
43
	-e "s/_ed_ge_label_/edge/g"\
44
	-e "s/_In_cEd_geIt_label_/IncEdgeIt/g"\
45
	-e "s/_Re_d_label_/Red/g"\
46
	-e "s/_Blu_e_label_/Blue/g"\
47
	-e "s/_re_d_label_/red/g"\
48
	-e "s/_blu_e_label_/blue/g"\
49
	-e "s/\(\W\)DefPredMap\(\W\)/\1SetPredMap\2/g"\
50
	-e "s/\(\W\)DefPredMap$/\1SetPredMap/g"\
51
	-e "s/^DefPredMap\(\W\)/SetPredMap\1/g"\
52
	-e "s/^DefPredMap$/SetPredMap/g"\
53
	-e "s/\(\W\)DefDistMap\(\W\)/\1SetDistMap\2/g"\
54
	-e "s/\(\W\)DefDistMap$/\1SetDistMap/g"\
55
	-e "s/^DefDistMap\(\W\)/SetDistMap\1/g"\
56
	-e "s/^DefDistMap$/SetDistMap/g"\
57
	-e "s/\(\W\)DefReachedMap\(\W\)/\1SetReachedMap\2/g"\
58
	-e "s/\(\W\)DefReachedMap$/\1SetReachedMap/g"\
59
	-e "s/^DefReachedMap\(\W\)/SetReachedMap\1/g"\
60
	-e "s/^DefReachedMap$/SetReachedMap/g"\
61
	-e "s/\(\W\)DefProcessedMap\(\W\)/\1SetProcessedMap\2/g"\
62
	-e "s/\(\W\)DefProcessedMap$/\1SetProcessedMap/g"\
63
	-e "s/^DefProcessedMap\(\W\)/SetProcessedMap\1/g"\
64
	-e "s/^DefProcessedMap$/SetProcessedMap/g"\
65
	-e "s/\(\W\)DefHeap\(\W\)/\1SetHeap\2/g"\
66
	-e "s/\(\W\)DefHeap$/\1SetHeap/g"\
67
	-e "s/^DefHeap\(\W\)/SetHeap\1/g"\
68
	-e "s/^DefHeap$/SetHeap/g"\
69
	-e "s/\(\W\)DefStandardHeap\(\W\)/\1SetStandradHeap\2/g"\
70
	-e "s/\(\W\)DefStandardHeap$/\1SetStandradHeap/g"\
71
	-e "s/^DefStandardHeap\(\W\)/SetStandradHeap\1/g"\
72
	-e "s/^DefStandardHeap$/SetStandradHeap/g"\
73
	-e "s/\(\W\)DefOperationTraits\(\W\)/\1SetOperationTraits\2/g"\
74
	-e "s/\(\W\)DefOperationTraits$/\1SetOperationTraits/g"\
75
	-e "s/^DefOperationTraits\(\W\)/SetOperationTraits\1/g"\
76
	-e "s/^DefOperationTraits$/SetOperationTraits/g"\
77
	-e "s/\(\W\)DefProcessedMapToBeDefaultMap\(\W\)/\1SetStandardProcessedMap\2/g"\
78
	-e "s/\(\W\)DefProcessedMapToBeDefaultMap$/\1SetStandardProcessedMap/g"\
79
	-e "s/^DefProcessedMapToBeDefaultMap\(\W\)/SetStandardProcessedMap\1/g"\
80
	-e "s/^DefProcessedMapToBeDefaultMap$/SetStandardProcessedMap/g"\
81
	-e "s/\(\W\)IntegerMap\(\W\)/\1RangeMap\2/g"\
82
	-e "s/\(\W\)IntegerMap$/\1RangeMap/g"\
83
	-e "s/^IntegerMap\(\W\)/RangeMap\1/g"\
84
	-e "s/^IntegerMap$/RangeMap/g"\
85
	-e "s/\(\W\)integerMap\(\W\)/\1rangeMap\2/g"\
86
	-e "s/\(\W\)integerMap$/\1rangeMap/g"\
87
	-e "s/^integerMap\(\W\)/rangeMap\1/g"\
88
	-e "s/^integerMap$/rangeMap/g"\
89
	-e "s/\(\W\)copyGraph\(\W\)/\1graphCopy\2/g"\
90
	-e "s/\(\W\)copyGraph$/\1graphCopy/g"\
91
	-e "s/^copyGraph\(\W\)/graphCopy\1/g"\
92
	-e "s/^copyGraph$/graphCopy/g"\
93
	-e "s/\(\W\)copyDigraph\(\W\)/\1digraphCopy\2/g"\
94
	-e "s/\(\W\)copyDigraph$/\1digraphCopy/g"\
95
	-e "s/^copyDigraph\(\W\)/digraphCopy\1/g"\
96
	-e "s/^copyDigraph$/digraphCopy/g"\
97
	-e "s/\(\W\)\([sS]\)tdMap\(\W\)/\1\2parseMap\3/g"\
98
	-e "s/\(\W\)\([sS]\)tdMap$/\1\2parseMap/g"\
99
	-e "s/^\([sS]\)tdMap\(\W\)/\1parseMap\2/g"\
100
	-e "s/^\([sS]\)tdMap$/\1parseMap/g"\
101
	-e "s/\(\W\)\([Ff]\)unctorMap\(\W\)/\1\2unctorToMap\3/g"\
102
	-e "s/\(\W\)\([Ff]\)unctorMap$/\1\2unctorToMap/g"\
103
	-e "s/^\([Ff]\)unctorMap\(\W\)/\1unctorToMap\2/g"\
104
	-e "s/^\([Ff]\)unctorMap$/\1unctorToMap/g"\
105
	-e "s/\(\W\)\([Mm]\)apFunctor\(\W\)/\1\2apToFunctor\3/g"\
106
	-e "s/\(\W\)\([Mm]\)apFunctor$/\1\2apToFunctor/g"\
107
	-e "s/^\([Mm]\)apFunctor\(\W\)/\1apToFunctor\2/g"\
108
	-e "s/^\([Mm]\)apFunctor$/\1apToFunctor/g"\
109
	-e "s/\(\W\)\([Ff]\)orkWriteMap\(\W\)/\1\2orkMap\3/g"\
110
	-e "s/\(\W\)\([Ff]\)orkWriteMap$/\1\2orkMap/g"\
111
	-e "s/^\([Ff]\)orkWriteMap\(\W\)/\1orkMap\2/g"\
112
	-e "s/^\([Ff]\)orkWriteMap$/\1orkMap/g"\
113
	-e "s/\(\W\)StoreBoolMap\(\W\)/\1LoggerBoolMap\2/g"\
114
	-e "s/\(\W\)StoreBoolMap$/\1LoggerBoolMap/g"\
115
	-e "s/^StoreBoolMap\(\W\)/LoggerBoolMap\1/g"\
116
	-e "s/^StoreBoolMap$/LoggerBoolMap/g"\
117
	-e "s/\(\W\)storeBoolMap\(\W\)/\1loggerBoolMap\2/g"\
118
	-e "s/\(\W\)storeBoolMap$/\1loggerBoolMap/g"\
119
	-e "s/^storeBoolMap\(\W\)/loggerBoolMap\1/g"\
120
	-e "s/^storeBoolMap$/loggerBoolMap/g"\
121
	-e "s/\(\W\)BoundingBox\(\W\)/\1Box\2/g"\
122
	-e "s/\(\W\)BoundingBox$/\1Box/g"\
123
	-e "s/^BoundingBox\(\W\)/Box\1/g"\
124
	-e "s/^BoundingBox$/Box/g"\
125
<$1 > $TMP
126

	
127
mv $TMP $1
... ...
 No newline at end of file
11
for i in $@
12
do
13
    echo Update $i...
14
    TMP=`mktemp`
15
    sed -e "s/\<undirected graph\>/_gr_aph_label_/g"\
16
        -e "s/\<undirected graphs\>/_gr_aph_label_s/g"\
17
        -e "s/\<undirected edge\>/_ed_ge_label_/g"\
18
        -e "s/\<undirected edges\>/_ed_ge_label_s/g"\
19
        -e "s/\<directed graph\>/_digr_aph_label_/g"\
20
        -e "s/\<directed graphs\>/_digr_aph_label_s/g"\
21
        -e "s/\<directed edge\>/_ar_c_label_/g"\
22
        -e "s/\<directed edges\>/_ar_c_label_s/g"\
23
        -e "s/UGraph/_Gr_aph_label_/g"\
24
        -e "s/u[Gg]raph/_gr_aph_label_/g"\
25
        -e "s/Graph\>/_Digr_aph_label_/g"\
26
        -e "s/\<graph\>/_digr_aph_label_/g"\
27
        -e "s/Graphs\>/_Digr_aph_label_s/g"\
28
        -e "s/\<graphs\>/_digr_aph_label_s/g"\
29
        -e "s/\([Gg]\)raph\([a-z]\)/_\1r_aph_label_\2/g"\
30
        -e "s/\([a-z_]\)graph/\1_gr_aph_label_/g"\
31
        -e "s/Graph/_Digr_aph_label_/g"\
32
        -e "s/graph/_digr_aph_label_/g"\
33
        -e "s/UEdge/_Ed_ge_label_/g"\
34
        -e "s/u[Ee]dge/_ed_ge_label_/g"\
35
        -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
36
        -e "s/Edge\>/_Ar_c_label_/g"\
37
        -e "s/\<edge\>/_ar_c_label_/g"\
38
        -e "s/_edge\>/_ar_c_label_/g"\
39
        -e "s/Edges\>/_Ar_c_label_s/g"\
40
        -e "s/\<edges\>/_ar_c_label_s/g"\
41
        -e "s/_edges\>/_ar_c_label_s/g"\
42
        -e "s/\([Ee]\)dge\([a-z]\)/_\1d_ge_label_\2/g"\
43
        -e "s/\([a-z]\)edge/\1_ed_ge_label_/g"\
44
        -e "s/Edge/_Ar_c_label_/g"\
45
        -e "s/edge/_ar_c_label_/g"\
46
        -e "s/A[Nn]ode/_Re_d_label_/g"\
47
        -e "s/B[Nn]ode/_Blu_e_label_/g"\
48
        -e "s/A-[Nn]ode/_Re_d_label_/g"\
49
        -e "s/B-[Nn]ode/_Blu_e_label_/g"\
50
        -e "s/a[Nn]ode/_re_d_label_/g"\
51
        -e "s/b[Nn]ode/_blu_e_label_/g"\
52
        -e "s/\<UGRAPH_TYPEDEFS\([ \t]*([ \t]*\)typename[ \t]/TEMPLATE__GR_APH_TY_PEDE_FS_label_\1/g"\
53
        -e "s/\<GRAPH_TYPEDEFS\([ \t]*([ \t]*\)typename[ \t]/TEMPLATE__DIGR_APH_TY_PEDE_FS_label_\1/g"\
54
        -e "s/\<UGRAPH_TYPEDEFS\>/_GR_APH_TY_PEDE_FS_label_/g"\
55
        -e "s/\<GRAPH_TYPEDEFS\>/_DIGR_APH_TY_PEDE_FS_label_/g"\
56
        -e "s/_Digr_aph_label_/Digraph/g"\
57
        -e "s/_digr_aph_label_/digraph/g"\
58
        -e "s/_Gr_aph_label_/Graph/g"\
59
        -e "s/_gr_aph_label_/graph/g"\
60
        -e "s/_Ar_c_label_/Arc/g"\
61
        -e "s/_ar_c_label_/arc/g"\
62
        -e "s/_Ed_ge_label_/Edge/g"\
63
        -e "s/_ed_ge_label_/edge/g"\
64
        -e "s/_In_cEd_geIt_label_/IncEdgeIt/g"\
65
        -e "s/_Re_d_label_/Red/g"\
66
        -e "s/_Blu_e_label_/Blue/g"\
67
        -e "s/_re_d_label_/red/g"\
68
        -e "s/_blu_e_label_/blue/g"\
69
        -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\
70
        -e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\
71
        -e "s/DigraphToEps/GraphToEps/g"\
72
        -e "s/digraphToEps/graphToEps/g"\
73
        -e "s/\<DefPredMap\>/SetPredMap/g"\
74
        -e "s/\<DefDistMap\>/SetDistMap/g"\
75
        -e "s/\<DefReachedMap\>/SetReachedMap/g"\
76
        -e "s/\<DefProcessedMap\>/SetProcessedMap/g"\
77
        -e "s/\<DefHeap\>/SetHeap/g"\
78
        -e "s/\<DefStandardHeap\>/SetStandradHeap/g"\
79
        -e "s/\<DefOperationTraits\>/SetOperationTraits/g"\
80
        -e "s/\<DefProcessedMapToBeDefaultMap\>/SetStandardProcessedMap/g"\
81
        -e "s/\<copyGraph\>/graphCopy/g"\
82
        -e "s/\<copyDigraph\>/digraphCopy/g"\
83
        -e "s/\<HyperCubeDigraph\>/HypercubeGraph/g"\
84
        -e "s/\<IntegerMap\>/RangeMap/g"\
85
        -e "s/\<integerMap\>/rangeMap/g"\
86
        -e "s/\<\([sS]\)tdMap\>/\1parseMap/g"\
87
        -e "s/\<\([Ff]\)unctorMap\>/\1unctorToMap/g"\
88
        -e "s/\<\([Mm]\)apFunctor\>/\1apToFunctor/g"\
89
        -e "s/\<\([Ff]\)orkWriteMap\>/\1orkMap/g"\
90
        -e "s/\<StoreBoolMap\>/LoggerBoolMap/g"\
91
        -e "s/\<storeBoolMap\>/loggerBoolMap/g"\
92
        -e "s/\<InvertableMap\>/CrossRefMap/g"\
93
        -e "s/\<invertableMap\>/crossRefMap/g"\
94
        -e "s/\<DescriptorMap\>/RangeIdMap/g"\
95
        -e "s/\<descriptorMap\>/rangeIdMap/g"\
96
        -e "s/\<BoundingBox\>/Box/g"\
97
        -e "s/\<readNauty\>/readNautyGraph/g"\
98
        -e "s/\<RevDigraphAdaptor\>/ReverseDigraph/g"\
99
        -e "s/\<revDigraphAdaptor\>/reverseDigraph/g"\
100
        -e "s/\<SubDigraphAdaptor\>/SubDigraph/g"\
101
        -e "s/\<subDigraphAdaptor\>/subDigraph/g"\
102
        -e "s/\<SubGraphAdaptor\>/SubGraph/g"\
103
        -e "s/\<subGraphAdaptor\>/subGraph/g"\
104
        -e "s/\<NodeSubDigraphAdaptor\>/FilterNodes/g"\
105
        -e "s/\<nodeSubDigraphAdaptor\>/filterNodes/g"\
106
        -e "s/\<ArcSubDigraphAdaptor\>/FilterArcs/g"\
107
        -e "s/\<arcSubDigraphAdaptor\>/filterArcs/g"\
108
        -e "s/\<UndirDigraphAdaptor\>/Undirector/g"\
109
        -e "s/\<undirDigraphAdaptor\>/undirector/g"\
110
        -e "s/\<ResDigraphAdaptor\>/ResidualDigraph/g"\
111
        -e "s/\<resDigraphAdaptor\>/residualDigraph/g"\
112
        -e "s/\<SplitDigraphAdaptor\>/SplitNodes/g"\
113
        -e "s/\<splitDigraphAdaptor\>/splitNodes/g"\
114
        -e "s/\<SubGraphAdaptor\>/SubGraph/g"\
115
        -e "s/\<subGraphAdaptor\>/subGraph/g"\
116
        -e "s/\<NodeSubGraphAdaptor\>/FilterNodes/g"\
117
        -e "s/\<nodeSubGraphAdaptor\>/filterNodes/g"\
118
        -e "s/\<ArcSubGraphAdaptor\>/FilterEdges/g"\
119
        -e "s/\<arcSubGraphAdaptor\>/filterEdges/g"\
120
        -e "s/\<DirGraphAdaptor\>/Orienter/g"\
121
        -e "s/\<dirGraphAdaptor\>/orienter/g"\
122
        -e "s/\<LpCplex\>/CplexLp/g"\
123
        -e "s/\<MipCplex\>/CplexMip/g"\
124
        -e "s/\<LpGlpk\>/GlpkLp/g"\
125
        -e "s/\<MipGlpk\>/GlpkMip/g"\
126
        -e "s/\<LpSoplex\>/SoplexLp/g"\
127
    <$i > $TMP
128
    mv $TMP $i
129
done
Ignore white space 6 line context
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library.
4
 *
5
 * Copyright (C) 2003-2008
6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
 *
9
 * Permission to use, modify and distribute this software is granted
10
 * provided that this copyright notice appears in all copies. For
11
 * precise terms see the accompanying LICENSE file.
12
 *
13
 * This software is provided "AS IS" with no warranty of any kind,
14
 * express or implied, and with no claim as to its suitability for any
15
 * purpose.
16
 *
17
 */
18

	
19
#ifndef LEMON_BITS_BASE_EXTENDER_H
20
#define LEMON_BITS_BASE_EXTENDER_H
21

	
22
#include <lemon/core.h>
23
#include <lemon/error.h>
24

	
25
#include <lemon/bits/map_extender.h>
26
#include <lemon/bits/default_map.h>
27

	
28
#include <lemon/concept_check.h>
29
#include <lemon/concepts/maps.h>
30

	
31
//\ingroup digraphbits
32
//\file
33
//\brief Extenders for the digraph types
34
namespace lemon {
35

	
36
  // \ingroup digraphbits
37
  //
38
  // \brief BaseDigraph to BaseGraph extender
39
  template <typename Base>
40
  class UndirDigraphExtender : public Base {
41

	
42
  public:
43

	
44
    typedef Base Parent;
45
    typedef typename Parent::Arc Edge;
46
    typedef typename Parent::Node Node;
47

	
48
    typedef True UndirectedTag;
49

	
50
    class Arc : public Edge {
51
      friend class UndirDigraphExtender;
52

	
53
    protected:
54
      bool forward;
55

	
56
      Arc(const Edge &ue, bool _forward) :
57
        Edge(ue), forward(_forward) {}
58

	
59
    public:
60
      Arc() {}
61

	
62
      // Invalid arc constructor
63
      Arc(Invalid i) : Edge(i), forward(true) {}
64

	
65
      bool operator==(const Arc &that) const {
66
        return forward==that.forward && Edge(*this)==Edge(that);
67
      }
68
      bool operator!=(const Arc &that) const {
69
        return forward!=that.forward || Edge(*this)!=Edge(that);
70
      }
71
      bool operator<(const Arc &that) const {
72
        return forward<that.forward ||
73
          (!(that.forward<forward) && Edge(*this)<Edge(that));
74
      }
75
    };
76

	
77
    // First node of the edge
78
    Node u(const Edge &e) const {
79
      return Parent::source(e);
80
    }
81

	
82
    // Source of the given arc
83
    Node source(const Arc &e) const {
84
      return e.forward ? Parent::source(e) : Parent::target(e);
85
    }
86

	
87
    // Second node of the edge
88
    Node v(const Edge &e) const {
89
      return Parent::target(e);
90
    }
91

	
92
    // Target of the given arc
93
    Node target(const Arc &e) const {
94
      return e.forward ? Parent::target(e) : Parent::source(e);
95
    }
96

	
97
    // \brief Directed arc from an edge.
98
    //
99
    // Returns a directed arc corresponding to the specified edge.
100
    // If the given bool is true, the first node of the given edge and
101
    // the source node of the returned arc are the same.
102
    static Arc direct(const Edge &e, bool d) {
103
      return Arc(e, d);
104
    }
105

	
106
    // Returns whether the given directed arc has the same orientation
107
    // as the corresponding edge.
108
    static bool direction(const Arc &a) { return a.forward; }
109

	
110
    using Parent::first;
111
    using Parent::next;
112

	
113
    void first(Arc &e) const {
114
      Parent::first(e);
115
      e.forward=true;
116
    }
117

	
118
    void next(Arc &e) const {
119
      if( e.forward ) {
120
        e.forward = false;
121
      }
122
      else {
123
        Parent::next(e);
124
        e.forward = true;
125
      }
126
    }
127

	
128
    void firstOut(Arc &e, const Node &n) const {
129
      Parent::firstIn(e,n);
130
      if( Edge(e) != INVALID ) {
131
        e.forward = false;
132
      }
133
      else {
134
        Parent::firstOut(e,n);
135
        e.forward = true;
136
      }
137
    }
138
    void nextOut(Arc &e) const {
139
      if( ! e.forward ) {
140
        Node n = Parent::target(e);
141
        Parent::nextIn(e);
142
        if( Edge(e) == INVALID ) {
143
          Parent::firstOut(e, n);
144
          e.forward = true;
145
        }
146
      }
147
      else {
148
        Parent::nextOut(e);
149
      }
150
    }
151

	
152
    void firstIn(Arc &e, const Node &n) const {
153
      Parent::firstOut(e,n);
154
      if( Edge(e) != INVALID ) {
155
        e.forward = false;
156
      }
157
      else {
158
        Parent::firstIn(e,n);
159
        e.forward = true;
160
      }
161
    }
162
    void nextIn(Arc &e) const {
163
      if( ! e.forward ) {
164
        Node n = Parent::source(e);
165
        Parent::nextOut(e);
166
        if( Edge(e) == INVALID ) {
167
          Parent::firstIn(e, n);
168
          e.forward = true;
169
        }
170
      }
171
      else {
172
        Parent::nextIn(e);
173
      }
174
    }
175

	
176
    void firstInc(Edge &e, bool &d, const Node &n) const {
177
      d = true;
178
      Parent::firstOut(e, n);
179
      if (e != INVALID) return;
180
      d = false;
181
      Parent::firstIn(e, n);
182
    }
183

	
184
    void nextInc(Edge &e, bool &d) const {
185
      if (d) {
186
        Node s = Parent::source(e);
187
        Parent::nextOut(e);
188
        if (e != INVALID) return;
189
        d = false;
190
        Parent::firstIn(e, s);
191
      } else {
192
        Parent::nextIn(e);
193
      }
194
    }
195

	
196
    Node nodeFromId(int ix) const {
197
      return Parent::nodeFromId(ix);
198
    }
199

	
200
    Arc arcFromId(int ix) const {
201
      return direct(Parent::arcFromId(ix >> 1), bool(ix & 1));
202
    }
203

	
204
    Edge edgeFromId(int ix) const {
205
      return Parent::arcFromId(ix);
206
    }
207

	
208
    int id(const Node &n) const {
209
      return Parent::id(n);
210
    }
211

	
212
    int id(const Edge &e) const {
213
      return Parent::id(e);
214
    }
215

	
216
    int id(const Arc &e) const {
217
      return 2 * Parent::id(e) + int(e.forward);
218
    }
219

	
220
    int maxNodeId() const {
221
      return Parent::maxNodeId();
222
    }
223

	
224
    int maxArcId() const {
225
      return 2 * Parent::maxArcId() + 1;
226
    }
227

	
228
    int maxEdgeId() const {
229
      return Parent::maxArcId();
230
    }
231

	
232
    int arcNum() const {
233
      return 2 * Parent::arcNum();
234
    }
235

	
236
    int edgeNum() const {
237
      return Parent::arcNum();
238
    }
239

	
240
    Arc findArc(Node s, Node t, Arc p = INVALID) const {
241
      if (p == INVALID) {
242
        Edge arc = Parent::findArc(s, t);
243
        if (arc != INVALID) return direct(arc, true);
244
        arc = Parent::findArc(t, s);
245
        if (arc != INVALID) return direct(arc, false);
246
      } else if (direction(p)) {
247
        Edge arc = Parent::findArc(s, t, p);
248
        if (arc != INVALID) return direct(arc, true);
249
        arc = Parent::findArc(t, s);
250
        if (arc != INVALID) return direct(arc, false);
251
      } else {
252
        Edge arc = Parent::findArc(t, s, p);
253
        if (arc != INVALID) return direct(arc, false);
254
      }
255
      return INVALID;
256
    }
257

	
258
    Edge findEdge(Node s, Node t, Edge p = INVALID) const {
259
      if (s != t) {
260
        if (p == INVALID) {
261
          Edge arc = Parent::findArc(s, t);
262
          if (arc != INVALID) return arc;
263
          arc = Parent::findArc(t, s);
264
          if (arc != INVALID) return arc;
265
        } else if (Parent::s(p) == s) {
266
          Edge arc = Parent::findArc(s, t, p);
267
          if (arc != INVALID) return arc;
268
          arc = Parent::findArc(t, s);
269
          if (arc != INVALID) return arc;
270
        } else {
271
          Edge arc = Parent::findArc(t, s, p);
272
          if (arc != INVALID) return arc;
273
        }
274
      } else {
275
        return Parent::findArc(s, t, p);
276
      }
277
      return INVALID;
278
    }
279
  };
280

	
281
  template <typename Base>
282
  class BidirBpGraphExtender : public Base {
283
  public:
284
    typedef Base Parent;
285
    typedef BidirBpGraphExtender Digraph;
286

	
287
    typedef typename Parent::Node Node;
288
    typedef typename Parent::Edge Edge;
289

	
290

	
291
    using Parent::first;
292
    using Parent::next;
293

	
294
    using Parent::id;
295

	
296
    class Red : public Node {
297
      friend class BidirBpGraphExtender;
298
    public:
299
      Red() {}
300
      Red(const Node& node) : Node(node) {
301
        LEMON_DEBUG(Parent::red(node) || node == INVALID,
302
                    typename Parent::NodeSetError());
303
      }
304
      Red& operator=(const Node& node) {
305
        LEMON_DEBUG(Parent::red(node) || node == INVALID,
306
                    typename Parent::NodeSetError());
307
        Node::operator=(node);
308
        return *this;
309
      }
310
      Red(Invalid) : Node(INVALID) {}
311
      Red& operator=(Invalid) {
312
        Node::operator=(INVALID);
313
        return *this;
314
      }
315
    };
316

	
317
    void first(Red& node) const {
318
      Parent::firstRed(static_cast<Node&>(node));
319
    }
320
    void next(Red& node) const {
321
      Parent::nextRed(static_cast<Node&>(node));
322
    }
323

	
324
    int id(const Red& node) const {
325
      return Parent::redId(node);
326
    }
327

	
328
    class Blue : public Node {
329
      friend class BidirBpGraphExtender;
330
    public:
331
      Blue() {}
332
      Blue(const Node& node) : Node(node) {
333
        LEMON_DEBUG(Parent::blue(node) || node == INVALID,
334
                    typename Parent::NodeSetError());
335
      }
336
      Blue& operator=(const Node& node) {
337
        LEMON_DEBUG(Parent::blue(node) || node == INVALID,
338
                    typename Parent::NodeSetError());
339
        Node::operator=(node);
340
        return *this;
341
      }
342
      Blue(Invalid) : Node(INVALID) {}
343
      Blue& operator=(Invalid) {
344
        Node::operator=(INVALID);
345
        return *this;
346
      }
347
    };
348

	
349
    void first(Blue& node) const {
350
      Parent::firstBlue(static_cast<Node&>(node));
351
    }
352
    void next(Blue& node) const {
353
      Parent::nextBlue(static_cast<Node&>(node));
354
    }
355

	
356
    int id(const Blue& node) const {
357
      return Parent::redId(node);
358
    }
359

	
360
    Node source(const Edge& arc) const {
361
      return red(arc);
362
    }
363
    Node target(const Edge& arc) const {
364
      return blue(arc);
365
    }
366

	
367
    void firstInc(Edge& arc, bool& dir, const Node& node) const {
368
      if (Parent::red(node)) {
369
        Parent::firstFromRed(arc, node);
370
        dir = true;
371
      } else {
372
        Parent::firstFromBlue(arc, node);
373
        dir = static_cast<Edge&>(arc) == INVALID;
374
      }
375
    }
376
    void nextInc(Edge& arc, bool& dir) const {
377
      if (dir) {
378
        Parent::nextFromRed(arc);
379
      } else {
380
        Parent::nextFromBlue(arc);
381
        if (arc == INVALID) dir = true;
382
      }
383
    }
384

	
385
    class Arc : public Edge {
386
      friend class BidirBpGraphExtender;
387
    protected:
388
      bool forward;
389

	
390
      Arc(const Edge& arc, bool _forward)
391
        : Edge(arc), forward(_forward) {}
392

	
393
    public:
394
      Arc() {}
395
      Arc (Invalid) : Edge(INVALID), forward(true) {}
396
      bool operator==(const Arc& i) const {
397
        return Edge::operator==(i) && forward == i.forward;
398
      }
399
      bool operator!=(const Arc& i) const {
400
        return Edge::operator!=(i) || forward != i.forward;
401
      }
402
      bool operator<(const Arc& i) const {
403
        return Edge::operator<(i) ||
404
          (!(i.forward<forward) && Edge(*this)<Edge(i));
405
      }
406
    };
407

	
408
    void first(Arc& arc) const {
409
      Parent::first(static_cast<Edge&>(arc));
410
      arc.forward = true;
411
    }
412

	
413
    void next(Arc& arc) const {
414
      if (!arc.forward) {
415
        Parent::next(static_cast<Edge&>(arc));
416
      }
417
      arc.forward = !arc.forward;
418
    }
419

	
420
    void firstOut(Arc& arc, const Node& node) const {
421
      if (Parent::red(node)) {
422
        Parent::firstFromRed(arc, node);
423
        arc.forward = true;
424
      } else {
425
        Parent::firstFromBlue(arc, node);
426
        arc.forward = static_cast<Edge&>(arc) == INVALID;
427
      }
428
    }
429
    void nextOut(Arc& arc) const {
430
      if (arc.forward) {
431
        Parent::nextFromRed(arc);
432
      } else {
433
        Parent::nextFromBlue(arc);
434
        arc.forward = static_cast<Edge&>(arc) == INVALID;
435
      }
436
    }
437

	
438
    void firstIn(Arc& arc, const Node& node) const {
439
      if (Parent::blue(node)) {
440
        Parent::firstFromBlue(arc, node);
441
        arc.forward = true;
442
      } else {
443
        Parent::firstFromRed(arc, node);
444
        arc.forward = static_cast<Edge&>(arc) == INVALID;
445
      }
446
    }
447
    void nextIn(Arc& arc) const {
448
      if (arc.forward) {
449
        Parent::nextFromBlue(arc);
450
      } else {
451
        Parent::nextFromRed(arc);
452
        arc.forward = static_cast<Edge&>(arc) == INVALID;
453
      }
454
    }
455

	
456
    Node source(const Arc& arc) const {
457
      return arc.forward ? Parent::red(arc) : Parent::blue(arc);
458
    }
459
    Node target(const Arc& arc) const {
460
      return arc.forward ? Parent::blue(arc) : Parent::red(arc);
461
    }
462

	
463
    int id(const Arc& arc) const {
464
      return (Parent::id(static_cast<const Edge&>(arc)) << 1) +
465
        (arc.forward ? 0 : 1);
466
    }
467
    Arc arcFromId(int ix) const {
468
      return Arc(Parent::fromEdgeId(ix >> 1), (ix & 1) == 0);
469
    }
470
    int maxArcId() const {
471
      return (Parent::maxEdgeId() << 1) + 1;
472
    }
473

	
474
    bool direction(const Arc& arc) const {
475
      return arc.forward;
476
    }
477

	
478
    Arc direct(const Edge& arc, bool dir) const {
479
      return Arc(arc, dir);
480
    }
481

	
482
    int arcNum() const {
483
      return 2 * Parent::edgeNum();
484
    }
485

	
486
    int edgeNum() const {
487
      return Parent::edgeNum();
488
    }
489

	
490

	
491
  };
492
}
493

	
494
#endif
0 comments (0 inline)