gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge #321
1 109 87
merge default
2 files changed with 53745 insertions and 4767 deletions:
25
10
1
1
87
3
3
180
184
129
110
193
199
1491
428
↑ 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 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
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 \ref amo93networkflows.
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
%%%%% Defining LEMON %%%%%
2

	
3
@misc{lemon,
4
  key =          {LEMON},
5
  title =        {{LEMON} -- {L}ibrary for {E}fficient {M}odeling and
6
                  {O}ptimization in {N}etworks},
7
  howpublished = {\url{http://lemon.cs.elte.hu/}},
8
  year =         2009
9
}
10

	
11
@misc{egres,
12
  key =          {EGRES},
13
  title =        {{EGRES} -- {E}gerv{\'a}ry {R}esearch {G}roup on
14
                  {C}ombinatorial {O}ptimization},
15
  url =          {http://www.cs.elte.hu/egres/}
16
}
17

	
18
@misc{coinor,
19
  key =          {COIN-OR},
20
  title =        {{COIN-OR} -- {C}omputational {I}nfrastructure for
21
                  {O}perations {R}esearch},
22
  url =          {http://www.coin-or.org/}
23
}
24

	
25

	
26
%%%%% Other libraries %%%%%%
27

	
28
@misc{boost,
29
  key =          {Boost},
30
  title =        {{B}oost {C++} {L}ibraries},
31
  url =          {http://www.boost.org/}
32
}
33

	
34
@book{bglbook,
35
  author =       {Jeremy G. Siek and Lee-Quan Lee and Andrew
36
                  Lumsdaine},
37
  title =        {The Boost Graph Library: User Guide and Reference
38
                  Manual},
39
  publisher =    {Addison-Wesley},
40
  year =         2002
41
}
42

	
43
@misc{leda,
44
  key =          {LEDA},
45
  title =        {{LEDA} -- {L}ibrary of {E}fficient {D}ata {T}ypes and
46
                  {A}lgorithms},
47
  url =          {http://www.algorithmic-solutions.com/}
48
}
49

	
50
@book{ledabook,
51
  author =       {Kurt Mehlhorn and Stefan N{\"a}her},
52
  title =        {{LEDA}: {A} platform for combinatorial and geometric
53
                  computing},
54
  isbn =         {0-521-56329-1},
55
  publisher =    {Cambridge University Press},
56
  address =      {New York, NY, USA},
57
  year =         1999
58
}
59

	
60

	
61
%%%%% Tools that LEMON depends on %%%%%
62

	
63
@misc{cmake,
64
  key =          {CMake},
65
  title =        {{CMake} -- {C}ross {P}latform {M}ake},
66
  url =          {http://www.cmake.org/}
67
}
68

	
69
@misc{doxygen,
70
  key =          {Doxygen},
71
  title =        {{Doxygen} -- {S}ource code documentation generator
72
                  tool},
73
  url =          {http://www.doxygen.org/}
74
}
75

	
76

	
77
%%%%% LP/MIP libraries %%%%%
78

	
79
@misc{glpk,
80
  key =          {GLPK},
81
  title =        {{GLPK} -- {GNU} {L}inear {P}rogramming {K}it},
82
  url =          {http://www.gnu.org/software/glpk/}
83
}
84

	
85
@misc{clp,
86
  key =          {Clp},
87
  title =        {{Clp} -- {Coin-Or} {L}inear {P}rogramming},
88
  url =          {http://projects.coin-or.org/Clp/}
89
}
90

	
91
@misc{cbc,
92
  key =          {Cbc},
93
  title =        {{Cbc} -- {Coin-Or} {B}ranch and {C}ut},
94
  url =          {http://projects.coin-or.org/Cbc/}
95
}
96

	
97
@misc{cplex,
98
  key =          {CPLEX},
99
  title =        {{ILOG} {CPLEX}},
100
  url =          {http://www.ilog.com/}
101
}
102

	
103
@misc{soplex,
104
  key =          {SoPlex},
105
  title =        {{SoPlex} -- {T}he {S}equential {O}bject-{O}riented
106
                  {S}implex},
107
  url =          {http://soplex.zib.de/}
108
}
109

	
110

	
111
%%%%% General books %%%%%
112

	
113
@book{amo93networkflows,
114
  author =       {Ravindra K. Ahuja and Thomas L. Magnanti and James
115
                  B. Orlin},
116
  title =        {Network Flows: Theory, Algorithms, and Applications},
117
  publisher =    {Prentice-Hall, Inc.},
118
  year =         1993,
119
  month =        feb,
120
  isbn =         {978-0136175490}
121
}
122

	
123
@book{schrijver03combinatorial,
124
  author =       {Alexander Schrijver},
125
  title =        {Combinatorial Optimization: Polyhedra and Efficiency},
126
  publisher =    {Springer-Verlag},
127
  year =         2003,
128
  isbn =         {978-3540443896}
129
}
130

	
131
@book{clrs01algorithms,
132
  author =       {Thomas H. Cormen and Charles E. Leiserson and Ronald
133
                  L. Rivest and Clifford Stein},
134
  title =        {Introduction to Algorithms},
135
  publisher =    {The MIT Press},
136
  year =         2001,
137
  edition =      {2nd}
138
}
139

	
140
@book{stroustrup00cpp,
141
  author =       {Bjarne Stroustrup},
142
  title =        {The C++ Programming Language},
143
  edition =      {3rd},
144
  publisher =    {Addison-Wesley Professional},
145
  isbn =         0201700735,
146
  month =        {February},
147
  year =         2000
148
}
149

	
150

	
151
%%%%% Maximum flow algorithms %%%%%
152

	
153
@article{edmondskarp72theoretical,
154
  author =       {Jack Edmonds and Richard M. Karp},
155
  title =        {Theoretical improvements in algorithmic efficiency
156
                  for network flow problems},
157
  journal =      {Journal of the ACM},
158
  year =         1972,
159
  volume =       19,
160
  number =       2,
161
  pages =        {248-264}
162
}
163

	
164
@article{goldberg88newapproach,
165
  author =       {Andrew V. Goldberg and Robert E. Tarjan},
166
  title =        {A new approach to the maximum flow problem},
167
  journal =      {Journal of the ACM},
168
  year =         1988,
169
  volume =       35,
170
  number =       4,
171
  pages =        {921-940}
172
}
173

	
174
@article{dinic70algorithm,
175
  author =       {E. A. Dinic},
176
  title =        {Algorithm for solution of a problem of maximum flow
177
                  in a network with power estimation},
178
  journal =      {Soviet Math. Doklady},
179
  year =         1970,
180
  volume =       11,
181
  pages =        {1277-1280}
182
}
183

	
184
@article{goldberg08partial,
185
  author =       {Andrew V. Goldberg},
186
  title =        {The Partial Augment-Relabel Algorithm for the
187
                  Maximum Flow Problem},
188
  journal =      {16th Annual European Symposium on Algorithms},
189
  year =         2008,
190
  pages =        {466-477}
191
}
192

	
193
@article{sleator83dynamic,
194
  author =       {Daniel D. Sleator and Robert E. Tarjan},
195
  title =        {A data structure for dynamic trees},
196
  journal =      {Journal of Computer and System Sciences},
197
  year =         1983,
198
  volume =       26,
199
  number =       3,
200
  pages =        {362-391}
201
}
202

	
203

	
204
%%%%% Minimum mean cycle algorithms %%%%%
205

	
206
@article{karp78characterization,
207
  author =       {Richard M. Karp},
208
  title =        {A characterization of the minimum cycle mean in a
209
                  digraph},
210
  journal =      {Discrete Math.},
211
  year =         1978,
212
  volume =       23,
213
  pages =        {309-311}
214
}
215

	
216
@article{dasdan98minmeancycle,
217
  author =       {Ali Dasdan and Rajesh K. Gupta},
218
  title =        {Faster Maximum and Minimum Mean Cycle Alogrithms for
219
                  System Performance Analysis},
220
  journal =      {IEEE Transactions on Computer-Aided Design of
221
                  Integrated Circuits and Systems},
222
  year =         1998,
223
  volume =       17,
224
  number =       10,
225
  pages =        {889-899}
226
}
227

	
228

	
229
%%%%% Minimum cost flow algorithms %%%%%
230

	
231
@article{klein67primal,
232
  author =       {Morton Klein},
233
  title =        {A primal method for minimal cost flows with
234
                  applications to the assignment and transportation
235
                  problems},
236
  journal =      {Management Science},
237
  year =         1967,
238
  volume =       14,
239
  pages =        {205-220}
240
}
241

	
242
@article{goldberg89cyclecanceling,
243
  author =       {Andrew V. Goldberg and Robert E. Tarjan},
244
  title =        {Finding minimum-cost circulations by canceling
245
                  negative cycles},
246
  journal =      {Journal of the ACM},
247
  year =         1989,
248
  volume =       36,
249
  number =       4,
250
  pages =        {873-886}
251
}
252

	
253
@article{goldberg90approximation,
254
  author =       {Andrew V. Goldberg and Robert E. Tarjan},
255
  title =        {Finding Minimum-Cost Circulations by Successive
256
                  Approximation},
257
  journal =      {Mathematics of Operations Research},
258
  year =         1990,
259
  volume =       15,
260
  number =       3,
261
  pages =        {430-466}
262
}
263

	
264
@article{goldberg97efficient,
265
  author =       {Andrew V. Goldberg},
266
  title =        {An Efficient Implementation of a Scaling
267
                  Minimum-Cost Flow Algorithm},
268
  journal =      {Journal of Algorithms},
269
  year =         1997,
270
  volume =       22,
271
  number =       1,
272
  pages =        {1-29}
273
}
274

	
275
@article{bunnagel98efficient,
276
  author =       {Ursula B{\"u}nnagel and Bernhard Korte and Jens
277
                  Vygen},
278
  title =        {Efficient implementation of the {G}oldberg-{T}arjan
279
                  minimum-cost flow algorithm},
280
  journal =      {Optimization Methods and Software},
281
  year =         1998,
282
  volume =       10,
283
  pages =        {157-174}
284
}
285

	
286
@book{dantzig63linearprog,
287
  author =       {George B. Dantzig},
288
  title =        {Linear Programming and Extensions},
289
  publisher =    {Princeton University Press},
290
  year =         1963
291
}
292

	
293
@mastersthesis{kellyoneill91netsimplex,
294
  author =       {Damian J. Kelly and Garrett M. O'Neill},
295
  title =        {The Minimum Cost Flow Problem and The Network
296
                  Simplex Method},
297
  school =       {University College},
298
  address =      {Dublin, Ireland},
299
  year =         1991,
300
  month =        sep,
301
}
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_BELLMAN_FORD_H
20
#define LEMON_BELLMAN_FORD_H
21

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

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

	
33
#include <limits>
34

	
35
namespace lemon {
36

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

	
69
  template <typename V>
70
  struct BellmanFordDefaultOperationTraits<V, false> {
71
    typedef V Value;
72
    static Value zero() {
73
      return static_cast<Value>(0);
74
    }
75
    static Value infinity() {
76
      return std::numeric_limits<Value>::max();
77
    }
78
    static Value plus(const Value& left, const Value& right) {
79
      if (left == infinity() || right == infinity()) return infinity();
80
      return left + right;
81
    }
82
    static bool less(const Value& left, const Value& right) {
83
      return left < right;
84
    }
85
  };
86
  
87
  /// \brief Default traits class of BellmanFord class.
88
  ///
89
  /// Default traits class of BellmanFord class.
90
  /// \param GR The type of the digraph.
91
  /// \param LEN The type of the length map.
92
  template<typename GR, typename LEN>
93
  struct BellmanFordDefaultTraits {
94
    /// The type of the digraph the algorithm runs on. 
95
    typedef GR Digraph;
96

	
97
    /// \brief The type of the map that stores the arc lengths.
98
    ///
99
    /// The type of the map that stores the arc lengths.
100
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
101
    typedef LEN LengthMap;
102

	
103
    /// The type of the arc lengths.
104
    typedef typename LEN::Value Value;
105

	
106
    /// \brief Operation traits for Bellman-Ford algorithm.
107
    ///
108
    /// It defines the used operations and the infinity value for the
109
    /// given \c Value type.
110
    /// \see BellmanFordDefaultOperationTraits
111
    typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
112
 
113
    /// \brief The type of the map that stores the last arcs of the 
114
    /// shortest paths.
115
    /// 
116
    /// The type of the map that stores the last
117
    /// arcs of the shortest paths.
118
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
119
    typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
120

	
121
    /// \brief Instantiates a \c PredMap.
122
    /// 
123
    /// This function instantiates a \ref PredMap. 
124
    /// \param g is the digraph to which we would like to define the
125
    /// \ref PredMap.
126
    static PredMap *createPredMap(const GR& g) {
127
      return new PredMap(g);
128
    }
129

	
130
    /// \brief The type of the map that stores the distances of the nodes.
131
    ///
132
    /// The type of the map that stores the distances of the nodes.
133
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
134
    typedef typename GR::template NodeMap<typename LEN::Value> DistMap;
135

	
136
    /// \brief Instantiates a \c DistMap.
137
    ///
138
    /// This function instantiates a \ref DistMap. 
139
    /// \param g is the digraph to which we would like to define the 
140
    /// \ref DistMap.
141
    static DistMap *createDistMap(const GR& g) {
142
      return new DistMap(g);
143
    }
144

	
145
  };
146
  
147
  /// \brief %BellmanFord algorithm class.
148
  ///
149
  /// \ingroup shortest_path
150
  /// This class provides an efficient implementation of the Bellman-Ford 
151
  /// algorithm. The maximum time complexity of the algorithm is
152
  /// <tt>O(ne)</tt>.
153
  ///
154
  /// The Bellman-Ford algorithm solves the single-source shortest path
155
  /// problem when the arcs can have negative lengths, but the digraph
156
  /// should not contain directed cycles with negative total length.
157
  /// If all arc costs are non-negative, consider to use the Dijkstra
158
  /// algorithm instead, since it is more efficient.
159
  ///
160
  /// The arc lengths are passed to the algorithm using a
161
  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any 
162
  /// kind of length. The type of the length values is determined by the
163
  /// \ref concepts::ReadMap::Value "Value" type of the length map.
164
  ///
165
  /// There is also a \ref bellmanFord() "function-type interface" for the
166
  /// Bellman-Ford algorithm, which is convenient in the simplier cases and
167
  /// it can be used easier.
168
  ///
169
  /// \tparam GR The type of the digraph the algorithm runs on.
170
  /// The default type is \ref ListDigraph.
171
  /// \tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
172
  /// the lengths of the arcs. The default map type is
173
  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
174
#ifdef DOXYGEN
175
  template <typename GR, typename LEN, typename TR>
176
#else
177
  template <typename GR=ListDigraph,
178
            typename LEN=typename GR::template ArcMap<int>,
179
            typename TR=BellmanFordDefaultTraits<GR,LEN> >
180
#endif
181
  class BellmanFord {
182
  public:
183

	
184
    ///The type of the underlying digraph.
185
    typedef typename TR::Digraph Digraph;
186
    
187
    /// \brief The type of the arc lengths.
188
    typedef typename TR::LengthMap::Value Value;
189
    /// \brief The type of the map that stores the arc lengths.
190
    typedef typename TR::LengthMap LengthMap;
191
    /// \brief The type of the map that stores the last
192
    /// arcs of the shortest paths.
193
    typedef typename TR::PredMap PredMap;
194
    /// \brief The type of the map that stores the distances of the nodes.
195
    typedef typename TR::DistMap DistMap;
196
    /// The type of the paths.
197
    typedef PredMapPath<Digraph, PredMap> Path;
198
    ///\brief The \ref BellmanFordDefaultOperationTraits
199
    /// "operation traits class" of the algorithm.
200
    typedef typename TR::OperationTraits OperationTraits;
201

	
202
    ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm.
203
    typedef TR Traits;
204

	
205
  private:
206

	
207
    typedef typename Digraph::Node Node;
208
    typedef typename Digraph::NodeIt NodeIt;
209
    typedef typename Digraph::Arc Arc;
210
    typedef typename Digraph::OutArcIt OutArcIt;
211

	
212
    // Pointer to the underlying digraph.
213
    const Digraph *_gr;
214
    // Pointer to the length map
215
    const LengthMap *_length;
216
    // Pointer to the map of predecessors arcs.
217
    PredMap *_pred;
218
    // Indicates if _pred is locally allocated (true) or not.
219
    bool _local_pred;
220
    // Pointer to the map of distances.
221
    DistMap *_dist;
222
    // Indicates if _dist is locally allocated (true) or not.
223
    bool _local_dist;
224

	
225
    typedef typename Digraph::template NodeMap<bool> MaskMap;
226
    MaskMap *_mask;
227

	
228
    std::vector<Node> _process;
229

	
230
    // Creates the maps if necessary.
231
    void create_maps() {
232
      if(!_pred) {
233
	_local_pred = true;
234
	_pred = Traits::createPredMap(*_gr);
235
      }
236
      if(!_dist) {
237
	_local_dist = true;
238
	_dist = Traits::createDistMap(*_gr);
239
      }
240
      _mask = new MaskMap(*_gr, false);
241
    }
242
    
243
  public :
244
 
245
    typedef BellmanFord Create;
246

	
247
    /// \name Named Template Parameters
248

	
249
    ///@{
250

	
251
    template <class T>
252
    struct SetPredMapTraits : public Traits {
253
      typedef T PredMap;
254
      static PredMap *createPredMap(const Digraph&) {
255
        LEMON_ASSERT(false, "PredMap is not initialized");
256
        return 0; // ignore warnings
257
      }
258
    };
259

	
260
    /// \brief \ref named-templ-param "Named parameter" for setting
261
    /// \c PredMap type.
262
    ///
263
    /// \ref named-templ-param "Named parameter" for setting
264
    /// \c PredMap type.
265
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
266
    template <class T>
267
    struct SetPredMap 
268
      : public BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > {
269
      typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > Create;
270
    };
271
    
272
    template <class T>
273
    struct SetDistMapTraits : public Traits {
274
      typedef T DistMap;
275
      static DistMap *createDistMap(const Digraph&) {
276
        LEMON_ASSERT(false, "DistMap is not initialized");
277
        return 0; // ignore warnings
278
      }
279
    };
280

	
281
    /// \brief \ref named-templ-param "Named parameter" for setting
282
    /// \c DistMap type.
283
    ///
284
    /// \ref named-templ-param "Named parameter" for setting
285
    /// \c DistMap type.
286
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
287
    template <class T>
288
    struct SetDistMap 
289
      : public BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > {
290
      typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > Create;
291
    };
292

	
293
    template <class T>
294
    struct SetOperationTraitsTraits : public Traits {
295
      typedef T OperationTraits;
296
    };
297
    
298
    /// \brief \ref named-templ-param "Named parameter" for setting 
299
    /// \c OperationTraits type.
300
    ///
301
    /// \ref named-templ-param "Named parameter" for setting
302
    /// \c OperationTraits type.
303
    /// For more information see \ref BellmanFordDefaultOperationTraits.
304
    template <class T>
305
    struct SetOperationTraits
306
      : public BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> > {
307
      typedef BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> >
308
      Create;
309
    };
310
    
311
    ///@}
312

	
313
  protected:
314
    
315
    BellmanFord() {}
316

	
317
  public:      
318
    
319
    /// \brief Constructor.
320
    ///
321
    /// Constructor.
322
    /// \param g The digraph the algorithm runs on.
323
    /// \param length The length map used by the algorithm.
324
    BellmanFord(const Digraph& g, const LengthMap& length) :
325
      _gr(&g), _length(&length),
326
      _pred(0), _local_pred(false),
327
      _dist(0), _local_dist(false), _mask(0) {}
328
    
329
    ///Destructor.
330
    ~BellmanFord() {
331
      if(_local_pred) delete _pred;
332
      if(_local_dist) delete _dist;
333
      if(_mask) delete _mask;
334
    }
335

	
336
    /// \brief Sets the length map.
337
    ///
338
    /// Sets the length map.
339
    /// \return <tt>(*this)</tt>
340
    BellmanFord &lengthMap(const LengthMap &map) {
341
      _length = &map;
342
      return *this;
343
    }
344

	
345
    /// \brief Sets the map that stores the predecessor arcs.
346
    ///
347
    /// Sets the map that stores the predecessor arcs.
348
    /// If you don't use this function before calling \ref run()
349
    /// or \ref init(), an instance will be allocated automatically.
350
    /// The destructor deallocates this automatically allocated map,
351
    /// of course.
352
    /// \return <tt>(*this)</tt>
353
    BellmanFord &predMap(PredMap &map) {
354
      if(_local_pred) {
355
	delete _pred;
356
	_local_pred=false;
357
      }
358
      _pred = &map;
359
      return *this;
360
    }
361

	
362
    /// \brief Sets the map that stores the distances of the nodes.
363
    ///
364
    /// Sets the map that stores the distances of the nodes calculated
365
    /// by the algorithm.
366
    /// If you don't use this function before calling \ref run()
367
    /// or \ref init(), an instance will be allocated automatically.
368
    /// The destructor deallocates this automatically allocated map,
369
    /// of course.
370
    /// \return <tt>(*this)</tt>
371
    BellmanFord &distMap(DistMap &map) {
372
      if(_local_dist) {
373
	delete _dist;
374
	_local_dist=false;
375
      }
376
      _dist = &map;
377
      return *this;
378
    }
379

	
380
    /// \name Execution Control
381
    /// The simplest way to execute the Bellman-Ford algorithm is to use
382
    /// one of the member functions called \ref run().\n
383
    /// If you need better control on the execution, you have to call
384
    /// \ref init() first, then you can add several source nodes
385
    /// with \ref addSource(). Finally the actual path computation can be
386
    /// performed with \ref start(), \ref checkedStart() or
387
    /// \ref limitedStart().
388

	
389
    ///@{
390

	
391
    /// \brief Initializes the internal data structures.
392
    /// 
393
    /// Initializes the internal data structures. The optional parameter
394
    /// is the initial distance of each node.
395
    void init(const Value value = OperationTraits::infinity()) {
396
      create_maps();
397
      for (NodeIt it(*_gr); it != INVALID; ++it) {
398
	_pred->set(it, INVALID);
399
	_dist->set(it, value);
400
      }
401
      _process.clear();
402
      if (OperationTraits::less(value, OperationTraits::infinity())) {
403
	for (NodeIt it(*_gr); it != INVALID; ++it) {
404
	  _process.push_back(it);
405
	  _mask->set(it, true);
406
	}
407
      }
408
    }
409
    
410
    /// \brief Adds a new source node.
411
    ///
412
    /// This function adds a new source node. The optional second parameter
413
    /// is the initial distance of the node.
414
    void addSource(Node source, Value dst = OperationTraits::zero()) {
415
      _dist->set(source, dst);
416
      if (!(*_mask)[source]) {
417
	_process.push_back(source);
418
	_mask->set(source, true);
419
      }
420
    }
421

	
422
    /// \brief Executes one round from the Bellman-Ford algorithm.
423
    ///
424
    /// If the algoritm calculated the distances in the previous round
425
    /// exactly for the paths of at most \c k arcs, then this function
426
    /// will calculate the distances exactly for the paths of at most
427
    /// <tt>k+1</tt> arcs. Performing \c k iterations using this function
428
    /// calculates the shortest path distances exactly for the paths
429
    /// consisting of at most \c k arcs.
430
    ///
431
    /// \warning The paths with limited arc number cannot be retrieved
432
    /// easily with \ref path() or \ref predArc() functions. If you also
433
    /// need the shortest paths and not only the distances, you should
434
    /// store the \ref predMap() "predecessor map" after each iteration
435
    /// and build the path manually.
436
    ///
437
    /// \return \c true when the algorithm have not found more shorter
438
    /// paths.
439
    ///
440
    /// \see ActiveIt
441
    bool processNextRound() {
442
      for (int i = 0; i < int(_process.size()); ++i) {
443
	_mask->set(_process[i], false);
444
      }
445
      std::vector<Node> nextProcess;
446
      std::vector<Value> values(_process.size());
447
      for (int i = 0; i < int(_process.size()); ++i) {
448
	values[i] = (*_dist)[_process[i]];
449
      }
450
      for (int i = 0; i < int(_process.size()); ++i) {
451
	for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
452
	  Node target = _gr->target(it);
453
	  Value relaxed = OperationTraits::plus(values[i], (*_length)[it]);
454
	  if (OperationTraits::less(relaxed, (*_dist)[target])) {
455
	    _pred->set(target, it);
456
	    _dist->set(target, relaxed);
457
	    if (!(*_mask)[target]) {
458
	      _mask->set(target, true);
459
	      nextProcess.push_back(target);
460
	    }
461
	  }	  
462
	}
463
      }
464
      _process.swap(nextProcess);
465
      return _process.empty();
466
    }
467

	
468
    /// \brief Executes one weak round from the Bellman-Ford algorithm.
469
    ///
470
    /// If the algorithm calculated the distances in the previous round
471
    /// at least for the paths of at most \c k arcs, then this function
472
    /// will calculate the distances at least for the paths of at most
473
    /// <tt>k+1</tt> arcs.
474
    /// This function does not make it possible to calculate the shortest
475
    /// path distances exactly for paths consisting of at most \c k arcs,
476
    /// this is why it is called weak round.
477
    ///
478
    /// \return \c true when the algorithm have not found more shorter
479
    /// paths.
480
    ///
481
    /// \see ActiveIt
482
    bool processNextWeakRound() {
483
      for (int i = 0; i < int(_process.size()); ++i) {
484
	_mask->set(_process[i], false);
485
      }
486
      std::vector<Node> nextProcess;
487
      for (int i = 0; i < int(_process.size()); ++i) {
488
	for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
489
	  Node target = _gr->target(it);
490
	  Value relaxed = 
491
	    OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]);
492
	  if (OperationTraits::less(relaxed, (*_dist)[target])) {
493
	    _pred->set(target, it);
494
	    _dist->set(target, relaxed);
495
	    if (!(*_mask)[target]) {
496
	      _mask->set(target, true);
497
	      nextProcess.push_back(target);
498
	    }
499
	  }	  
500
	}
501
      }
502
      _process.swap(nextProcess);
503
      return _process.empty();
504
    }
505

	
506
    /// \brief Executes the algorithm.
507
    ///
508
    /// Executes the algorithm.
509
    ///
510
    /// This method runs the Bellman-Ford algorithm from the root node(s)
511
    /// in order to compute the shortest path to each node.
512
    ///
513
    /// The algorithm computes
514
    /// - the shortest path tree (forest),
515
    /// - the distance of each node from the root(s).
516
    ///
517
    /// \pre init() must be called and at least one root node should be
518
    /// added with addSource() before using this function.
519
    void start() {
520
      int num = countNodes(*_gr) - 1;
521
      for (int i = 0; i < num; ++i) {
522
	if (processNextWeakRound()) break;
523
      }
524
    }
525

	
526
    /// \brief Executes the algorithm and checks the negative cycles.
527
    ///
528
    /// Executes the algorithm and checks the negative cycles.
529
    ///
530
    /// This method runs the Bellman-Ford algorithm from the root node(s)
531
    /// in order to compute the shortest path to each node and also checks
532
    /// if the digraph contains cycles with negative total length.
533
    ///
534
    /// The algorithm computes 
535
    /// - the shortest path tree (forest),
536
    /// - the distance of each node from the root(s).
537
    /// 
538
    /// \return \c false if there is a negative cycle in the digraph.
539
    ///
540
    /// \pre init() must be called and at least one root node should be
541
    /// added with addSource() before using this function. 
542
    bool checkedStart() {
543
      int num = countNodes(*_gr);
544
      for (int i = 0; i < num; ++i) {
545
	if (processNextWeakRound()) return true;
546
      }
547
      return _process.empty();
548
    }
549

	
550
    /// \brief Executes the algorithm with arc number limit.
551
    ///
552
    /// Executes the algorithm with arc number limit.
553
    ///
554
    /// This method runs the Bellman-Ford algorithm from the root node(s)
555
    /// in order to compute the shortest path distance for each node
556
    /// using only the paths consisting of at most \c num arcs.
557
    ///
558
    /// The algorithm computes
559
    /// - the limited distance of each node from the root(s),
560
    /// - the predecessor arc for each node.
561
    ///
562
    /// \warning The paths with limited arc number cannot be retrieved
563
    /// easily with \ref path() or \ref predArc() functions. If you also
564
    /// need the shortest paths and not only the distances, you should
565
    /// store the \ref predMap() "predecessor map" after each iteration
566
    /// and build the path manually.
567
    ///
568
    /// \pre init() must be called and at least one root node should be
569
    /// added with addSource() before using this function. 
570
    void limitedStart(int num) {
571
      for (int i = 0; i < num; ++i) {
572
	if (processNextRound()) break;
573
      }
574
    }
575
    
576
    /// \brief Runs the algorithm from the given root node.
577
    ///    
578
    /// This method runs the Bellman-Ford algorithm from the given root
579
    /// node \c s in order to compute the shortest path to each node.
580
    ///
581
    /// The algorithm computes
582
    /// - the shortest path tree (forest),
583
    /// - the distance of each node from the root(s).
584
    ///
585
    /// \note bf.run(s) is just a shortcut of the following code.
586
    /// \code
587
    ///   bf.init();
588
    ///   bf.addSource(s);
589
    ///   bf.start();
590
    /// \endcode
591
    void run(Node s) {
592
      init();
593
      addSource(s);
594
      start();
595
    }
596
    
597
    /// \brief Runs the algorithm from the given root node with arc
598
    /// number limit.
599
    ///    
600
    /// This method runs the Bellman-Ford algorithm from the given root
601
    /// node \c s in order to compute the shortest path distance for each
602
    /// node using only the paths consisting of at most \c num arcs.
603
    ///
604
    /// The algorithm computes
605
    /// - the limited distance of each node from the root(s),
606
    /// - the predecessor arc for each node.
607
    ///
608
    /// \warning The paths with limited arc number cannot be retrieved
609
    /// easily with \ref path() or \ref predArc() functions. If you also
610
    /// need the shortest paths and not only the distances, you should
611
    /// store the \ref predMap() "predecessor map" after each iteration
612
    /// and build the path manually.
613
    ///
614
    /// \note bf.run(s, num) is just a shortcut of the following code.
615
    /// \code
616
    ///   bf.init();
617
    ///   bf.addSource(s);
618
    ///   bf.limitedStart(num);
619
    /// \endcode
620
    void run(Node s, int num) {
621
      init();
622
      addSource(s);
623
      limitedStart(num);
624
    }
625
    
626
    ///@}
627

	
628
    /// \brief LEMON iterator for getting the active nodes.
629
    ///
630
    /// This class provides a common style LEMON iterator that traverses
631
    /// the active nodes of the Bellman-Ford algorithm after the last
632
    /// phase. These nodes should be checked in the next phase to
633
    /// find augmenting arcs outgoing from them.
634
    class ActiveIt {
635
    public:
636

	
637
      /// \brief Constructor.
638
      ///
639
      /// Constructor for getting the active nodes of the given BellmanFord
640
      /// instance. 
641
      ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm)
642
      {
643
        _index = _algorithm->_process.size() - 1;
644
      }
645

	
646
      /// \brief Invalid constructor.
647
      ///
648
      /// Invalid constructor.
649
      ActiveIt(Invalid) : _algorithm(0), _index(-1) {}
650

	
651
      /// \brief Conversion to \c Node.
652
      ///
653
      /// Conversion to \c Node.
654
      operator Node() const { 
655
        return _index >= 0 ? _algorithm->_process[_index] : INVALID;
656
      }
657

	
658
      /// \brief Increment operator.
659
      ///
660
      /// Increment operator.
661
      ActiveIt& operator++() {
662
        --_index;
663
        return *this; 
664
      }
665

	
666
      bool operator==(const ActiveIt& it) const { 
667
        return static_cast<Node>(*this) == static_cast<Node>(it); 
668
      }
669
      bool operator!=(const ActiveIt& it) const { 
670
        return static_cast<Node>(*this) != static_cast<Node>(it); 
671
      }
672
      bool operator<(const ActiveIt& it) const { 
673
        return static_cast<Node>(*this) < static_cast<Node>(it); 
674
      }
675
      
676
    private:
677
      const BellmanFord* _algorithm;
678
      int _index;
679
    };
680
    
681
    /// \name Query Functions
682
    /// The result of the Bellman-Ford algorithm can be obtained using these
683
    /// functions.\n
684
    /// Either \ref run() or \ref init() should be called before using them.
685
    
686
    ///@{
687

	
688
    /// \brief The shortest path to the given node.
689
    ///    
690
    /// Gives back the shortest path to the given node from the root(s).
691
    ///
692
    /// \warning \c t should be reached from the root(s).
693
    ///
694
    /// \pre Either \ref run() or \ref init() must be called before
695
    /// using this function.
696
    Path path(Node t) const
697
    {
698
      return Path(*_gr, *_pred, t);
699
    }
700
	  
701
    /// \brief The distance of the given node from the root(s).
702
    ///
703
    /// Returns the distance of the given node from the root(s).
704
    ///
705
    /// \warning If node \c v is not reached from the root(s), then
706
    /// the return value of this function is undefined.
707
    ///
708
    /// \pre Either \ref run() or \ref init() must be called before
709
    /// using this function.
710
    Value dist(Node v) const { return (*_dist)[v]; }
711

	
712
    /// \brief Returns the 'previous arc' of the shortest path tree for
713
    /// the given node.
714
    ///
715
    /// This function returns the 'previous arc' of the shortest path
716
    /// tree for node \c v, i.e. it returns the last arc of a
717
    /// shortest path from a root to \c v. It is \c INVALID if \c v
718
    /// is not reached from the root(s) or if \c v is a root.
719
    ///
720
    /// The shortest path tree used here is equal to the shortest path
721
    /// tree used in \ref predNode() and \predMap().
722
    ///
723
    /// \pre Either \ref run() or \ref init() must be called before
724
    /// using this function.
725
    Arc predArc(Node v) const { return (*_pred)[v]; }
726

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

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

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

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

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

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

	
839
    /// \brief Instantiates a \c PredMap.
840
    /// 
841
    /// This function instantiates a \ref PredMap.
842
    /// \param g is the digraph to which we would like to define the
843
    /// \ref PredMap.
844
    static PredMap *createPredMap(const GR &g) {
845
      return new PredMap(g);
846
    }
847

	
848
    /// \brief The type of the map that stores the distances of the nodes.
849
    ///
850
    /// The type of the map that stores the distances of the nodes.
851
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
852
    typedef typename GR::template NodeMap<Value> DistMap;
853

	
854
    /// \brief Instantiates a \c DistMap.
855
    ///
856
    /// This function instantiates a \ref DistMap. 
857
    /// \param g is the digraph to which we would like to define the
858
    /// \ref DistMap.
859
    static DistMap *createDistMap(const GR &g) {
860
      return new DistMap(g);
861
    }
862

	
863
    ///The type of the shortest paths.
864

	
865
    ///The type of the shortest paths.
866
    ///It must meet the \ref concepts::Path "Path" concept.
867
    typedef lemon::Path<Digraph> Path;
868
  };
869
  
870
  /// \brief Default traits class used by BellmanFordWizard.
871
  ///
872
  /// Default traits class used by BellmanFordWizard.
873
  /// \tparam GR The type of the digraph.
874
  /// \tparam LEN The type of the length map.
875
  template <typename GR, typename LEN>
876
  class BellmanFordWizardBase 
877
    : public BellmanFordWizardDefaultTraits<GR, LEN> {
878

	
879
    typedef BellmanFordWizardDefaultTraits<GR, LEN> Base;
880
  protected:
881
    // Type of the nodes in the digraph.
882
    typedef typename Base::Digraph::Node Node;
883

	
884
    // Pointer to the underlying digraph.
885
    void *_graph;
886
    // Pointer to the length map
887
    void *_length;
888
    // Pointer to the map of predecessors arcs.
889
    void *_pred;
890
    // Pointer to the map of distances.
891
    void *_dist;
892
    //Pointer to the shortest path to the target node.
893
    void *_path;
894
    //Pointer to the distance of the target node.
895
    void *_di;
896

	
897
    public:
898
    /// Constructor.
899
    
900
    /// This constructor does not require parameters, it initiates
901
    /// all of the attributes to default values \c 0.
902
    BellmanFordWizardBase() :
903
      _graph(0), _length(0), _pred(0), _dist(0), _path(0), _di(0) {}
904

	
905
    /// Constructor.
906
    
907
    /// This constructor requires two parameters,
908
    /// others are initiated to \c 0.
909
    /// \param gr The digraph the algorithm runs on.
910
    /// \param len The length map.
911
    BellmanFordWizardBase(const GR& gr, 
912
			  const LEN& len) :
913
      _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))), 
914
      _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))), 
915
      _pred(0), _dist(0), _path(0), _di(0) {}
916

	
917
  };
918
  
919
  /// \brief Auxiliary class for the function-type interface of the
920
  /// \ref BellmanFord "Bellman-Ford" algorithm.
921
  ///
922
  /// This auxiliary class is created to implement the
923
  /// \ref bellmanFord() "function-type interface" of the
924
  /// \ref BellmanFord "Bellman-Ford" algorithm.
925
  /// It does not have own \ref run() method, it uses the
926
  /// functions and features of the plain \ref BellmanFord.
927
  ///
928
  /// This class should only be used through the \ref bellmanFord()
929
  /// function, which makes it easier to use the algorithm.
930
  template<class TR>
931
  class BellmanFordWizard : public TR {
932
    typedef TR Base;
933

	
934
    typedef typename TR::Digraph Digraph;
935

	
936
    typedef typename Digraph::Node Node;
937
    typedef typename Digraph::NodeIt NodeIt;
938
    typedef typename Digraph::Arc Arc;
939
    typedef typename Digraph::OutArcIt ArcIt;
940
    
941
    typedef typename TR::LengthMap LengthMap;
942
    typedef typename LengthMap::Value Value;
943
    typedef typename TR::PredMap PredMap;
944
    typedef typename TR::DistMap DistMap;
945
    typedef typename TR::Path Path;
946

	
947
  public:
948
    /// Constructor.
949
    BellmanFordWizard() : TR() {}
950

	
951
    /// \brief Constructor that requires parameters.
952
    ///
953
    /// Constructor that requires parameters.
954
    /// These parameters will be the default values for the traits class.
955
    /// \param gr The digraph the algorithm runs on.
956
    /// \param len The length map.
957
    BellmanFordWizard(const Digraph& gr, const LengthMap& len) 
958
      : TR(gr, len) {}
959

	
960
    /// \brief Copy constructor
961
    BellmanFordWizard(const TR &b) : TR(b) {}
962

	
963
    ~BellmanFordWizard() {}
964

	
965
    /// \brief Runs the Bellman-Ford algorithm from the given source node.
966
    ///    
967
    /// This method runs the Bellman-Ford algorithm from the given source
968
    /// node in order to compute the shortest path to each node.
969
    void run(Node s) {
970
      BellmanFord<Digraph,LengthMap,TR> 
971
	bf(*reinterpret_cast<const Digraph*>(Base::_graph), 
972
           *reinterpret_cast<const LengthMap*>(Base::_length));
973
      if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
974
      if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
975
      bf.run(s);
976
    }
977

	
978
    /// \brief Runs the Bellman-Ford algorithm to find the shortest path
979
    /// between \c s and \c t.
980
    ///
981
    /// This method runs the Bellman-Ford algorithm from node \c s
982
    /// in order to compute the shortest path to node \c t.
983
    /// Actually, it computes the shortest path to each node, but using
984
    /// this function you can retrieve the distance and the shortest path
985
    /// for a single target node easier.
986
    ///
987
    /// \return \c true if \c t is reachable form \c s.
988
    bool run(Node s, Node t) {
989
      BellmanFord<Digraph,LengthMap,TR>
990
        bf(*reinterpret_cast<const Digraph*>(Base::_graph),
991
           *reinterpret_cast<const LengthMap*>(Base::_length));
992
      if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
993
      if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
994
      bf.run(s);
995
      if (Base::_path) *reinterpret_cast<Path*>(Base::_path) = bf.path(t);
996
      if (Base::_di) *reinterpret_cast<Value*>(Base::_di) = bf.dist(t);
997
      return bf.reached(t);
998
    }
999

	
1000
    template<class T>
1001
    struct SetPredMapBase : public Base {
1002
      typedef T PredMap;
1003
      static PredMap *createPredMap(const Digraph &) { return 0; };
1004
      SetPredMapBase(const TR &b) : TR(b) {}
1005
    };
1006
    
1007
    /// \brief \ref named-templ-param "Named parameter" for setting
1008
    /// the predecessor map.
1009
    ///
1010
    /// \ref named-templ-param "Named parameter" for setting
1011
    /// the map that stores the predecessor arcs of the nodes.
1012
    template<class T>
1013
    BellmanFordWizard<SetPredMapBase<T> > predMap(const T &t) {
1014
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1015
      return BellmanFordWizard<SetPredMapBase<T> >(*this);
1016
    }
1017
    
1018
    template<class T>
1019
    struct SetDistMapBase : public Base {
1020
      typedef T DistMap;
1021
      static DistMap *createDistMap(const Digraph &) { return 0; };
1022
      SetDistMapBase(const TR &b) : TR(b) {}
1023
    };
1024
    
1025
    /// \brief \ref named-templ-param "Named parameter" for setting
1026
    /// the distance map.
1027
    ///
1028
    /// \ref named-templ-param "Named parameter" for setting
1029
    /// the map that stores the distances of the nodes calculated
1030
    /// by the algorithm.
1031
    template<class T>
1032
    BellmanFordWizard<SetDistMapBase<T> > distMap(const T &t) {
1033
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1034
      return BellmanFordWizard<SetDistMapBase<T> >(*this);
1035
    }
1036

	
1037
    template<class T>
1038
    struct SetPathBase : public Base {
1039
      typedef T Path;
1040
      SetPathBase(const TR &b) : TR(b) {}
1041
    };
1042

	
1043
    /// \brief \ref named-func-param "Named parameter" for getting
1044
    /// the shortest path to the target node.
1045
    ///
1046
    /// \ref named-func-param "Named parameter" for getting
1047
    /// the shortest path to the target node.
1048
    template<class T>
1049
    BellmanFordWizard<SetPathBase<T> > path(const T &t)
1050
    {
1051
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1052
      return BellmanFordWizard<SetPathBase<T> >(*this);
1053
    }
1054

	
1055
    /// \brief \ref named-func-param "Named parameter" for getting
1056
    /// the distance of the target node.
1057
    ///
1058
    /// \ref named-func-param "Named parameter" for getting
1059
    /// the distance of the target node.
1060
    BellmanFordWizard dist(const Value &d)
1061
    {
1062
      Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
1063
      return *this;
1064
    }
1065
    
1066
  };
1067
  
1068
  /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford"
1069
  /// algorithm.
1070
  ///
1071
  /// \ingroup shortest_path
1072
  /// Function type interface for the \ref BellmanFord "Bellman-Ford"
1073
  /// algorithm.
1074
  ///
1075
  /// This function also has several \ref named-templ-func-param 
1076
  /// "named parameters", they are declared as the members of class 
1077
  /// \ref BellmanFordWizard.
1078
  /// The following examples show how to use these parameters.
1079
  /// \code
1080
  ///   // Compute shortest path from node s to each node
1081
  ///   bellmanFord(g,length).predMap(preds).distMap(dists).run(s);
1082
  ///
1083
  ///   // Compute shortest path from s to t
1084
  ///   bool reached = bellmanFord(g,length).path(p).dist(d).run(s,t);
1085
  /// \endcode
1086
  /// \warning Don't forget to put the \ref BellmanFordWizard::run() "run()"
1087
  /// to the end of the parameter list.
1088
  /// \sa BellmanFordWizard
1089
  /// \sa BellmanFord
1090
  template<typename GR, typename LEN>
1091
  BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >
1092
  bellmanFord(const GR& digraph,
1093
	      const LEN& length)
1094
  {
1095
    return BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >(digraph, length);
1096
  }
1097

	
1098
} //END OF NAMESPACE LEMON
1099

	
1100
#endif
1101

	
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_BINOM_HEAP_H
20
#define LEMON_BINOM_HEAP_H
21

	
22
///\file
23
///\ingroup heaps
24
///\brief Binomial Heap implementation.
25

	
26
#include <vector>
27
#include <utility>
28
#include <functional>
29
#include <lemon/math.h>
30
#include <lemon/counter.h>
31

	
32
namespace lemon {
33

	
34
  /// \ingroup heaps
35
  ///
36
  ///\brief Binomial heap data structure.
37
  ///
38
  /// This class implements the \e binomial \e heap data structure.
39
  /// It fully conforms to the \ref concepts::Heap "heap concept".
40
  ///
41
  /// The methods \ref increase() and \ref erase() are not efficient
42
  /// in a binomial heap. In case of many calls of these operations,
43
  /// it is better to use other heap structure, e.g. \ref BinHeap
44
  /// "binary heap".
45
  ///
46
  /// \tparam PR Type of the priorities of the items.
47
  /// \tparam IM A read-writable item map with \c int values, used
48
  /// internally to handle the cross references.
49
  /// \tparam CMP A functor class for comparing the priorities.
50
  /// The default is \c std::less<PR>.
51
#ifdef DOXYGEN
52
  template <typename PR, typename IM, typename CMP>
53
#else
54
  template <typename PR, typename IM, typename CMP = std::less<PR> >
55
#endif
56
  class BinomHeap {
57
  public:
58
    /// Type of the item-int map.
59
    typedef IM ItemIntMap;
60
    /// Type of the priorities.
61
    typedef PR Prio;
62
    /// Type of the items stored in the heap.
63
    typedef typename ItemIntMap::Key Item;
64
    /// Functor type for comparing the priorities.
65
    typedef CMP Compare;
66

	
67
    /// \brief Type to represent the states of the items.
68
    ///
69
    /// Each item has a state associated to it. It can be "in heap",
70
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
71
    /// heap's point of view, but may be useful to the user.
72
    ///
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.
75
    enum State {
76
      IN_HEAP = 0,    ///< = 0.
77
      PRE_HEAP = -1,  ///< = -1.
78
      POST_HEAP = -2  ///< = -2.
79
    };
80

	
81
  private:
82
    class Store;
83

	
84
    std::vector<Store> _data;
85
    int _min, _head;
86
    ItemIntMap &_iim;
87
    Compare _comp;
88
    int _num_items;
89

	
90
  public:
91
    /// \brief Constructor.
92
    ///
93
    /// Constructor.
94
    /// \param map A map that assigns \c int values to the items.
95
    /// It is used internally to handle the cross references.
96
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
97
    explicit BinomHeap(ItemIntMap &map)
98
      : _min(0), _head(-1), _iim(map), _num_items(0) {}
99

	
100
    /// \brief Constructor.
101
    ///
102
    /// Constructor.
103
    /// \param map A map that assigns \c int values to the items.
104
    /// It is used internally to handle the cross references.
105
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
106
    /// \param comp The function object used for comparing the priorities.
107
    BinomHeap(ItemIntMap &map, const Compare &comp)
108
      : _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {}
109

	
110
    /// \brief The number of items stored in the heap.
111
    ///
112
    /// This function returns the number of items stored in the heap.
113
    int size() const { return _num_items; }
114

	
115
    /// \brief Check if the heap is empty.
116
    ///
117
    /// This function returns \c true if the heap is empty.
118
    bool empty() const { return _num_items==0; }
119

	
120
    /// \brief Make the heap empty.
121
    ///
122
    /// This functon makes the heap empty.
123
    /// It does not change the cross reference map. If you want to reuse
124
    /// a heap that is not surely empty, you should first clear it and
125
    /// then you should set the cross reference map to \c PRE_HEAP
126
    /// for each item.
127
    void clear() {
128
      _data.clear(); _min=0; _num_items=0; _head=-1;
129
    }
130

	
131
    /// \brief Set the priority of an item or insert it, if it is
132
    /// not stored in the heap.
133
    ///
134
    /// This method sets the priority of the given item if it is
135
    /// already stored in the heap. Otherwise it inserts the given
136
    /// item into the heap with the given priority.
137
    /// \param item The item.
138
    /// \param value The priority.
139
    void set (const Item& item, const Prio& value) {
140
      int i=_iim[item];
141
      if ( i >= 0 && _data[i].in ) {
142
        if ( _comp(value, _data[i].prio) ) decrease(item, value);
143
        if ( _comp(_data[i].prio, value) ) increase(item, value);
144
      } else push(item, value);
145
    }
146

	
147
    /// \brief Insert an item into the heap with the given priority.
148
    ///
149
    /// This function inserts the given item into the heap with the
150
    /// given priority.
151
    /// \param item The item to insert.
152
    /// \param value The priority of the item.
153
    /// \pre \e item must not be stored in the heap.
154
    void push (const Item& item, const Prio& value) {
155
      int i=_iim[item];
156
      if ( i<0 ) {
157
        int s=_data.size();
158
        _iim.set( item,s );
159
        Store st;
160
        st.name=item;
161
        st.prio=value;
162
        _data.push_back(st);
163
        i=s;
164
      }
165
      else {
166
        _data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
167
        _data[i].degree=0;
168
        _data[i].in=true;
169
        _data[i].prio=value;
170
      }
171

	
172
      if( 0==_num_items ) {
173
        _head=i;
174
        _min=i;
175
      } else {
176
        merge(i);
177
        if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
178
      }
179
      ++_num_items;
180
    }
181

	
182
    /// \brief Return the item having minimum priority.
183
    ///
184
    /// This function returns the item having minimum priority.
185
    /// \pre The heap must be non-empty.
186
    Item top() const { return _data[_min].name; }
187

	
188
    /// \brief The minimum priority.
189
    ///
190
    /// This function returns the minimum priority.
191
    /// \pre The heap must be non-empty.
192
    Prio prio() const { return _data[_min].prio; }
193

	
194
    /// \brief The priority of the given item.
195
    ///
196
    /// This function returns the priority of the given item.
197
    /// \param item The item.
198
    /// \pre \e item must be in the heap.
199
    const Prio& operator[](const Item& item) const {
200
      return _data[_iim[item]].prio;
201
    }
202

	
203
    /// \brief Remove the item having minimum priority.
204
    ///
205
    /// This function removes the item having minimum priority.
206
    /// \pre The heap must be non-empty.
207
    void pop() {
208
      _data[_min].in=false;
209

	
210
      int head_child=-1;
211
      if ( _data[_min].child!=-1 ) {
212
        int child=_data[_min].child;
213
        int neighb;
214
        while( child!=-1 ) {
215
          neighb=_data[child].right_neighbor;
216
          _data[child].parent=-1;
217
          _data[child].right_neighbor=head_child;
218
          head_child=child;
219
          child=neighb;
220
        }
221
      }
222

	
223
      if ( _data[_head].right_neighbor==-1 ) {
224
        // there was only one root
225
        _head=head_child;
226
      }
227
      else {
228
        // there were more roots
229
        if( _head!=_min )  { unlace(_min); }
230
        else { _head=_data[_head].right_neighbor; }
231
        merge(head_child);
232
      }
233
      _min=findMin();
234
      --_num_items;
235
    }
236

	
237
    /// \brief Remove the given item from the heap.
238
    ///
239
    /// This function removes the given item from the heap if it is
240
    /// already stored.
241
    /// \param item The item to delete.
242
    /// \pre \e item must be in the heap.
243
    void erase (const Item& item) {
244
      int i=_iim[item];
245
      if ( i >= 0 && _data[i].in ) {
246
        decrease( item, _data[_min].prio-1 );
247
        pop();
248
      }
249
    }
250

	
251
    /// \brief Decrease the priority of an item to the given value.
252
    ///
253
    /// This function decreases the priority of an item to the given value.
254
    /// \param item The item.
255
    /// \param value The priority.
256
    /// \pre \e item must be stored in the heap with priority at least \e value.
257
    void decrease (Item item, const Prio& value) {
258
      int i=_iim[item];
259
      int p=_data[i].parent;
260
      _data[i].prio=value;
261
      
262
      while( p!=-1 && _comp(value, _data[p].prio) ) {
263
        _data[i].name=_data[p].name;
264
        _data[i].prio=_data[p].prio;
265
        _data[p].name=item;
266
        _data[p].prio=value;
267
        _iim[_data[i].name]=i;
268
        i=p;
269
        p=_data[p].parent;
270
      }
271
      _iim[item]=i;
272
      if ( _comp(value, _data[_min].prio) ) _min=i;
273
    }
274

	
275
    /// \brief Increase the priority of an item to the given value.
276
    ///
277
    /// This function increases the priority of an item to the given value.
278
    /// \param item The item.
279
    /// \param value The priority.
280
    /// \pre \e item must be stored in the heap with priority at most \e value.
281
    void increase (Item item, const Prio& value) {
282
      erase(item);
283
      push(item, value);
284
    }
285

	
286
    /// \brief Return the state of an item.
287
    ///
288
    /// This method returns \c PRE_HEAP if the given item has never
289
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
290
    /// and \c POST_HEAP otherwise.
291
    /// In the latter case it is possible that the item will get back
292
    /// to the heap again.
293
    /// \param item The item.
294
    State state(const Item &item) const {
295
      int i=_iim[item];
296
      if( i>=0 ) {
297
        if ( _data[i].in ) i=0;
298
        else i=-2;
299
      }
300
      return State(i);
301
    }
302

	
303
    /// \brief Set the state of an item in the heap.
304
    ///
305
    /// This function sets the state of the given item in the heap.
306
    /// It can be used to manually clear the heap when it is important
307
    /// to achive better time complexity.
308
    /// \param i The item.
309
    /// \param st The state. It should not be \c IN_HEAP.
310
    void state(const Item& i, State st) {
311
      switch (st) {
312
      case POST_HEAP:
313
      case PRE_HEAP:
314
        if (state(i) == IN_HEAP) {
315
          erase(i);
316
        }
317
        _iim[i] = st;
318
        break;
319
      case IN_HEAP:
320
        break;
321
      }
322
    }
323

	
324
  private:
325
    
326
    // Find the minimum of the roots
327
    int findMin() {
328
      if( _head!=-1 ) {
329
        int min_loc=_head, min_val=_data[_head].prio;
330
        for( int x=_data[_head].right_neighbor; x!=-1;
331
             x=_data[x].right_neighbor ) {
332
          if( _comp( _data[x].prio,min_val ) ) {
333
            min_val=_data[x].prio;
334
            min_loc=x;
335
          }
336
        }
337
        return min_loc;
338
      }
339
      else return -1;
340
    }
341

	
342
    // Merge the heap with another heap starting at the given position
343
    void merge(int a) {
344
      if( _head==-1 || a==-1 ) return;
345
      if( _data[a].right_neighbor==-1 &&
346
          _data[a].degree<=_data[_head].degree ) {
347
        _data[a].right_neighbor=_head;
348
        _head=a;
349
      } else {
350
        interleave(a);
351
      }
352
      if( _data[_head].right_neighbor==-1 ) return;
353
      
354
      int x=_head;
355
      int x_prev=-1, x_next=_data[x].right_neighbor;
356
      while( x_next!=-1 ) {
357
        if( _data[x].degree!=_data[x_next].degree ||
358
            ( _data[x_next].right_neighbor!=-1 &&
359
              _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
360
          x_prev=x;
361
          x=x_next;
362
        }
363
        else {
364
          if( _comp(_data[x_next].prio,_data[x].prio) ) {
365
            if( x_prev==-1 ) {
366
              _head=x_next;
367
            } else {
368
              _data[x_prev].right_neighbor=x_next;
369
            }
370
            fuse(x,x_next);
371
            x=x_next;
372
          }
373
          else {
374
            _data[x].right_neighbor=_data[x_next].right_neighbor;
375
            fuse(x_next,x);
376
          }
377
        }
378
        x_next=_data[x].right_neighbor;
379
      }
380
    }
381

	
382
    // Interleave the elements of the given list into the list of the roots
383
    void interleave(int a) {
384
      int p=_head, q=a;
385
      int curr=_data.size();
386
      _data.push_back(Store());
387
      
388
      while( p!=-1 || q!=-1 ) {
389
        if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
390
          _data[curr].right_neighbor=p;
391
          curr=p;
392
          p=_data[p].right_neighbor;
393
        }
394
        else {
395
          _data[curr].right_neighbor=q;
396
          curr=q;
397
          q=_data[q].right_neighbor;
398
        }
399
      }
400
      
401
      _head=_data.back().right_neighbor;
402
      _data.pop_back();
403
    }
404

	
405
    // Lace node a under node b
406
    void fuse(int a, int b) {
407
      _data[a].parent=b;
408
      _data[a].right_neighbor=_data[b].child;
409
      _data[b].child=a;
410

	
411
      ++_data[b].degree;
412
    }
413

	
414
    // Unlace node a (if it has siblings)
415
    void unlace(int a) {
416
      int neighb=_data[a].right_neighbor;
417
      int other=_head;
418

	
419
      while( _data[other].right_neighbor!=a )
420
        other=_data[other].right_neighbor;
421
      _data[other].right_neighbor=neighb;
422
    }
423

	
424
  private:
425

	
426
    class Store {
427
      friend class BinomHeap;
428

	
429
      Item name;
430
      int parent;
431
      int right_neighbor;
432
      int child;
433
      int degree;
434
      bool in;
435
      Prio prio;
436

	
437
      Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
438
        in(true) {}
439
    };
440
  };
441

	
442
} //namespace lemon
443

	
444
#endif //LEMON_BINOM_HEAP_H
445

	
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
      explicit 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
      explicit 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 heaps
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 heaps
57
  ///
58
  /// \brief Bucket heap data structure.
59
  ///
60
  /// This class implements the \e bucket \e heap data structure.
61
  /// It practically conforms to the \ref concepts::Heap "heap concept",
62
  /// but it has some limitations.
63
  ///
64
  /// The bucket heap is a very simple structure. It can store only
65
  /// \c int priorities and it maintains a list of items for each priority
66
  /// in the range <tt>[0..C)</tt>. So it should only be used when the
67
  /// priorities are small. It is not intended to use as a Dijkstra heap.
68
  ///
69
  /// \tparam IM A read-writable item map with \c int values, used
70
  /// internally to handle the cross references.
71
  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
72
  /// The default is \e min-heap. If this parameter is set to \c false,
73
  /// then the comparison is reversed, so the top(), prio() and pop()
74
  /// functions deal with the item having maximum priority instead of the
75
  /// minimum.
76
  ///
77
  /// \sa SimpleBucketHeap
78
  template <typename IM, bool MIN = true>
79
  class BucketHeap {
80

	
81
  public:
82

	
83
    /// Type of the item-int map.
84
    typedef IM ItemIntMap;
85
    /// Type of the priorities.
86
    typedef int Prio;
87
    /// Type of the items stored in the heap.
88
    typedef typename ItemIntMap::Key Item;
89
    /// Type of the item-priority pairs.
90
    typedef std::pair<Item,Prio> Pair;
91

	
92
  private:
93

	
94
    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
95

	
96
  public:
97

	
98
    /// \brief Type to represent the states of the items.
99
    ///
100
    /// Each item has a state associated to it. It can be "in heap",
101
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
102
    /// heap's point of view, but may be useful to the user.
103
    ///
104
    /// The item-int map must be initialized in such way that it assigns
105
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
106
    enum State {
107
      IN_HEAP = 0,    ///< = 0.
108
      PRE_HEAP = -1,  ///< = -1.
109
      POST_HEAP = -2  ///< = -2.
110
    };
111

	
112
  public:
113

	
114
    /// \brief Constructor.
115
    ///
116
    /// Constructor.
117
    /// \param map A map that assigns \c int values to the items.
118
    /// It is used internally to handle the cross references.
119
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
120
    explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
121

	
122
    /// \brief The number of items stored in the heap.
123
    ///
124
    /// This function returns the number of items stored in the heap.
125
    int size() const { return _data.size(); }
126

	
127
    /// \brief Check if the heap is empty.
128
    ///
129
    /// This function returns \c true if the heap is empty.
130
    bool empty() const { return _data.empty(); }
131

	
132
    /// \brief Make the heap empty.
133
    ///
134
    /// This functon makes the heap empty.
135
    /// It does not change the cross reference map. If you want to reuse
136
    /// a heap that is not surely empty, you should first clear it and
137
    /// then you should set the cross reference map to \c PRE_HEAP
138
    /// for each item.
139
    void clear() {
140
      _data.clear(); _first.clear(); _minimum = 0;
141
    }
142

	
143
  private:
144

	
145
    void relocateLast(int idx) {
146
      if (idx + 1 < int(_data.size())) {
147
        _data[idx] = _data.back();
148
        if (_data[idx].prev != -1) {
149
          _data[_data[idx].prev].next = idx;
150
        } else {
151
          _first[_data[idx].value] = idx;
152
        }
153
        if (_data[idx].next != -1) {
154
          _data[_data[idx].next].prev = idx;
155
        }
156
        _iim[_data[idx].item] = idx;
157
      }
158
      _data.pop_back();
159
    }
160

	
161
    void unlace(int idx) {
162
      if (_data[idx].prev != -1) {
163
        _data[_data[idx].prev].next = _data[idx].next;
164
      } else {
165
        _first[_data[idx].value] = _data[idx].next;
166
      }
167
      if (_data[idx].next != -1) {
168
        _data[_data[idx].next].prev = _data[idx].prev;
169
      }
170
    }
171

	
172
    void lace(int idx) {
173
      if (int(_first.size()) <= _data[idx].value) {
174
        _first.resize(_data[idx].value + 1, -1);
175
      }
176
      _data[idx].next = _first[_data[idx].value];
177
      if (_data[idx].next != -1) {
178
        _data[_data[idx].next].prev = idx;
179
      }
180
      _first[_data[idx].value] = idx;
181
      _data[idx].prev = -1;
182
    }
183

	
184
  public:
185

	
186
    /// \brief Insert a pair of item and priority into the heap.
187
    ///
188
    /// This function inserts \c p.first to the heap with priority
189
    /// \c p.second.
190
    /// \param p The pair to insert.
191
    /// \pre \c p.first must not be stored in the heap.
192
    void push(const Pair& p) {
193
      push(p.first, p.second);
194
    }
195

	
196
    /// \brief Insert an item into the heap with the given priority.
197
    ///
198
    /// This function inserts the given item into the heap with the
199
    /// given priority.
200
    /// \param i The item to insert.
201
    /// \param p The priority of the item.
202
    /// \pre \e i must not be stored in the heap.
203
    void push(const Item &i, const Prio &p) {
204
      int idx = _data.size();
205
      _iim[i] = idx;
206
      _data.push_back(BucketItem(i, p));
207
      lace(idx);
208
      if (Direction::less(p, _minimum)) {
209
        _minimum = p;
210
      }
211
    }
212

	
213
    /// \brief Return the item having minimum priority.
214
    ///
215
    /// This function returns the item having minimum priority.
216
    /// \pre The heap must be non-empty.
217
    Item top() const {
218
      while (_first[_minimum] == -1) {
219
        Direction::increase(_minimum);
220
      }
221
      return _data[_first[_minimum]].item;
222
    }
223

	
224
    /// \brief The minimum priority.
225
    ///
226
    /// This function returns the minimum priority.
227
    /// \pre The heap must be non-empty.
228
    Prio prio() const {
229
      while (_first[_minimum] == -1) {
230
        Direction::increase(_minimum);
231
      }
232
      return _minimum;
233
    }
234

	
235
    /// \brief Remove the item having minimum priority.
236
    ///
237
    /// This function removes the item having minimum priority.
238
    /// \pre The heap must be non-empty.
239
    void pop() {
240
      while (_first[_minimum] == -1) {
241
        Direction::increase(_minimum);
242
      }
243
      int idx = _first[_minimum];
244
      _iim[_data[idx].item] = -2;
245
      unlace(idx);
246
      relocateLast(idx);
247
    }
248

	
249
    /// \brief Remove the given item from the heap.
250
    ///
251
    /// This function removes the given item from the heap if it is
252
    /// already stored.
253
    /// \param i The item to delete.
254
    /// \pre \e i must be in the heap.
255
    void erase(const Item &i) {
256
      int idx = _iim[i];
257
      _iim[_data[idx].item] = -2;
258
      unlace(idx);
259
      relocateLast(idx);
260
    }
261

	
262
    /// \brief The priority of the given item.
263
    ///
264
    /// This function returns the priority of the given item.
265
    /// \param i The item.
266
    /// \pre \e i must be in the heap.
267
    Prio operator[](const Item &i) const {
268
      int idx = _iim[i];
269
      return _data[idx].value;
270
    }
271

	
272
    /// \brief Set the priority of an item or insert it, if it is
273
    /// not stored in the heap.
274
    ///
275
    /// This method sets the priority of the given item if it is
276
    /// already stored in the heap. Otherwise it inserts the given
277
    /// item into the heap with the given priority.
278
    /// \param i The item.
279
    /// \param p The priority.
280
    void set(const Item &i, const Prio &p) {
281
      int idx = _iim[i];
282
      if (idx < 0) {
283
        push(i, p);
284
      } else if (Direction::less(p, _data[idx].value)) {
285
        decrease(i, p);
286
      } else {
287
        increase(i, p);
288
      }
289
    }
290

	
291
    /// \brief Decrease the priority of an item to the given value.
292
    ///
293
    /// This function decreases the priority of an item to the given value.
294
    /// \param i The item.
295
    /// \param p The priority.
296
    /// \pre \e i must be stored in the heap with priority at least \e p.
297
    void decrease(const Item &i, const Prio &p) {
298
      int idx = _iim[i];
299
      unlace(idx);
300
      _data[idx].value = p;
301
      if (Direction::less(p, _minimum)) {
302
        _minimum = p;
303
      }
304
      lace(idx);
305
    }
306

	
307
    /// \brief Increase the priority of an item to the given value.
308
    ///
309
    /// This function increases the priority of an item to the given value.
310
    /// \param i The item.
311
    /// \param p The priority.
312
    /// \pre \e i must be stored in the heap with priority at most \e p.
313
    void increase(const Item &i, const Prio &p) {
314
      int idx = _iim[i];
315
      unlace(idx);
316
      _data[idx].value = p;
317
      lace(idx);
318
    }
319

	
320
    /// \brief Return the state of an item.
321
    ///
322
    /// This method returns \c PRE_HEAP if the given item has never
323
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
324
    /// and \c POST_HEAP otherwise.
325
    /// In the latter case it is possible that the item will get back
326
    /// to the heap again.
327
    /// \param i The item.
328
    State state(const Item &i) const {
329
      int idx = _iim[i];
330
      if (idx >= 0) idx = 0;
331
      return State(idx);
332
    }
333

	
334
    /// \brief Set the state of an item in the heap.
335
    ///
336
    /// This function sets the state of the given item in the heap.
337
    /// It can be used to manually clear the heap when it is important
338
    /// to achive better time complexity.
339
    /// \param i The item.
340
    /// \param st The state. It should not be \c IN_HEAP.
341
    void state(const Item& i, State st) {
342
      switch (st) {
343
      case POST_HEAP:
344
      case PRE_HEAP:
345
        if (state(i) == IN_HEAP) {
346
          erase(i);
347
        }
348
        _iim[i] = st;
349
        break;
350
      case IN_HEAP:
351
        break;
352
      }
353
    }
354

	
355
  private:
356

	
357
    struct BucketItem {
358
      BucketItem(const Item& _item, int _value)
359
        : item(_item), value(_value) {}
360

	
361
      Item item;
362
      int value;
363

	
364
      int prev, next;
365
    };
366

	
367
    ItemIntMap& _iim;
368
    std::vector<int> _first;
369
    std::vector<BucketItem> _data;
370
    mutable int _minimum;
371

	
372
  }; // class BucketHeap
373

	
374
  /// \ingroup heaps
375
  ///
376
  /// \brief Simplified bucket heap data structure.
377
  ///
378
  /// This class implements a simplified \e bucket \e heap data
379
  /// structure. It does not provide some functionality, but it is
380
  /// faster and simpler than BucketHeap. The main difference is
381
  /// that BucketHeap stores a doubly-linked list for each key while
382
  /// this class stores only simply-linked lists. It supports erasing
383
  /// only for the item having minimum priority and it does not support
384
  /// key increasing and decreasing.
385
  ///
386
  /// Note that this implementation does not conform to the
387
  /// \ref concepts::Heap "heap concept" due to the lack of some 
388
  /// functionality.
389
  ///
390
  /// \tparam IM A read-writable item map with \c int values, used
391
  /// internally to handle the cross references.
392
  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
393
  /// The default is \e min-heap. If this parameter is set to \c false,
394
  /// then the comparison is reversed, so the top(), prio() and pop()
395
  /// functions deal with the item having maximum priority instead of the
396
  /// minimum.
397
  ///
398
  /// \sa BucketHeap
399
  template <typename IM, bool MIN = true >
400
  class SimpleBucketHeap {
401

	
402
  public:
403

	
404
    /// Type of the item-int map.
405
    typedef IM ItemIntMap;
406
    /// Type of the priorities.
407
    typedef int Prio;
408
    /// Type of the items stored in the heap.
409
    typedef typename ItemIntMap::Key Item;
410
    /// Type of the item-priority pairs.
411
    typedef std::pair<Item,Prio> Pair;
412

	
413
  private:
414

	
415
    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
416

	
417
  public:
418

	
419
    /// \brief Type to represent the states of the items.
420
    ///
421
    /// Each item has a state associated to it. It can be "in heap",
422
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
423
    /// heap's point of view, but may be useful to the user.
424
    ///
425
    /// The item-int map must be initialized in such way that it assigns
426
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
427
    enum State {
428
      IN_HEAP = 0,    ///< = 0.
429
      PRE_HEAP = -1,  ///< = -1.
430
      POST_HEAP = -2  ///< = -2.
431
    };
432

	
433
  public:
434

	
435
    /// \brief Constructor.
436
    ///
437
    /// Constructor.
438
    /// \param map A map that assigns \c int values to the items.
439
    /// It is used internally to handle the cross references.
440
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
441
    explicit SimpleBucketHeap(ItemIntMap &map)
442
      : _iim(map), _free(-1), _num(0), _minimum(0) {}
443

	
444
    /// \brief The number of items stored in the heap.
445
    ///
446
    /// This function returns the number of items stored in the heap.
447
    int size() const { return _num; }
448

	
449
    /// \brief Check if the heap is empty.
450
    ///
451
    /// This function returns \c true if the heap is empty.
452
    bool empty() const { return _num == 0; }
453

	
454
    /// \brief Make the heap empty.
455
    ///
456
    /// This functon makes the heap empty.
457
    /// It does not change the cross reference map. If you want to reuse
458
    /// a heap that is not surely empty, you should first clear it and
459
    /// then you should set the cross reference map to \c PRE_HEAP
460
    /// for each item.
461
    void clear() {
462
      _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
463
    }
464

	
465
    /// \brief Insert a pair of item and priority into the heap.
466
    ///
467
    /// This function inserts \c p.first to the heap with priority
468
    /// \c p.second.
469
    /// \param p The pair to insert.
470
    /// \pre \c p.first must not be stored in the heap.
471
    void push(const Pair& p) {
472
      push(p.first, p.second);
473
    }
474

	
475
    /// \brief Insert an item into the heap with the given priority.
476
    ///
477
    /// This function inserts the given item into the heap with the
478
    /// given priority.
479
    /// \param i The item to insert.
480
    /// \param p The priority of the item.
481
    /// \pre \e i must not be stored in the heap.
482
    void push(const Item &i, const Prio &p) {
483
      int idx;
484
      if (_free == -1) {
485
        idx = _data.size();
486
        _data.push_back(BucketItem(i));
487
      } else {
488
        idx = _free;
489
        _free = _data[idx].next;
490
        _data[idx].item = i;
491
      }
492
      _iim[i] = idx;
493
      if (p >= int(_first.size())) _first.resize(p + 1, -1);
494
      _data[idx].next = _first[p];
495
      _first[p] = idx;
496
      if (Direction::less(p, _minimum)) {
497
        _minimum = p;
498
      }
499
      ++_num;
500
    }
501

	
502
    /// \brief Return the item having minimum priority.
503
    ///
504
    /// This function returns the item having minimum priority.
505
    /// \pre The heap must be non-empty.
506
    Item top() const {
507
      while (_first[_minimum] == -1) {
508
        Direction::increase(_minimum);
509
      }
510
      return _data[_first[_minimum]].item;
511
    }
512

	
513
    /// \brief The minimum priority.
514
    ///
515
    /// This function returns the minimum priority.
516
    /// \pre The heap must be non-empty.
517
    Prio prio() const {
518
      while (_first[_minimum] == -1) {
519
        Direction::increase(_minimum);
520
      }
521
      return _minimum;
522
    }
523

	
524
    /// \brief Remove the item having minimum priority.
525
    ///
526
    /// This function removes the item having minimum priority.
527
    /// \pre The heap must be non-empty.
528
    void pop() {
529
      while (_first[_minimum] == -1) {
530
        Direction::increase(_minimum);
531
      }
532
      int idx = _first[_minimum];
533
      _iim[_data[idx].item] = -2;
534
      _first[_minimum] = _data[idx].next;
535
      _data[idx].next = _free;
536
      _free = idx;
537
      --_num;
538
    }
539

	
540
    /// \brief The priority of the given item.
541
    ///
542
    /// This function returns the priority of the given item.
543
    /// \param i The item.
544
    /// \pre \e i must be in the heap.
545
    /// \warning This operator is not a constant time function because
546
    /// it scans the whole data structure to find the proper value.
547
    Prio operator[](const Item &i) const {
548
      for (int k = 0; k < int(_first.size()); ++k) {
549
        int idx = _first[k];
550
        while (idx != -1) {
551
          if (_data[idx].item == i) {
552
            return k;
553
          }
554
          idx = _data[idx].next;
555
        }
556
      }
557
      return -1;
558
    }
559

	
560
    /// \brief Return the state of an item.
561
    ///
562
    /// This method returns \c PRE_HEAP if the given item has never
563
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
564
    /// and \c POST_HEAP otherwise.
565
    /// In the latter case it is possible that the item will get back
566
    /// to the heap again.
567
    /// \param i The item.
568
    State state(const Item &i) const {
569
      int idx = _iim[i];
570
      if (idx >= 0) idx = 0;
571
      return State(idx);
572
    }
573

	
574
  private:
575

	
576
    struct BucketItem {
577
      BucketItem(const Item& _item)
578
        : item(_item) {}
579

	
580
      Item item;
581
      int next;
582
    };
583

	
584
    ItemIntMap& _iim;
585
    std::vector<int> _first;
586
    std::vector<BucketItem> _data;
587
    int _free, _num;
588
    mutable int _minimum;
589

	
590
  }; // class SimpleBucketHeap
591

	
592
}
593

	
594
#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
  int CbcMip::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
98
    std::vector<int> indexes;
99
    std::vector<Value> values;
100

	
101
    for(ExprIterator it = b; it != e; ++it) {
102
      indexes.push_back(it->first);
103
      values.push_back(it->second);
104
    }
105

	
106
    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
107
    return _prob->numberRows() - 1;
108
  }
109

	
110
  void CbcMip::_eraseCol(int i) {
111
    _prob->deleteColumn(i);
112
  }
113

	
114
  void CbcMip::_eraseRow(int i) {
115
    _prob->deleteRow(i);
116
  }
117

	
118
  void CbcMip::_eraseColId(int i) {
119
    cols.eraseIndex(i);
120
  }
121

	
122
  void CbcMip::_eraseRowId(int i) {
123
    rows.eraseIndex(i);
124
  }
125

	
126
  void CbcMip::_getColName(int c, std::string& name) const {
127
    name = _prob->getColumnName(c);
128
  }
129

	
130
  void CbcMip::_setColName(int c, const std::string& name) {
131
    _prob->setColumnName(c, name.c_str());
132
  }
133

	
134
  int CbcMip::_colByName(const std::string& name) const {
135
    return _prob->column(name.c_str());
136
  }
137

	
138
  void CbcMip::_getRowName(int r, std::string& name) const {
139
    name = _prob->getRowName(r);
140
  }
141

	
142
  void CbcMip::_setRowName(int r, const std::string& name) {
143
    _prob->setRowName(r, name.c_str());
144
  }
145

	
146
  int CbcMip::_rowByName(const std::string& name) const {
147
    return _prob->row(name.c_str());
148
  }
149

	
150
  void CbcMip::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
151
    for (ExprIterator it = b; it != e; ++it) {
152
      _prob->setElement(i, it->first, it->second);
153
    }
154
  }
155

	
156
  void CbcMip::_getRowCoeffs(int ix, InsertIterator b) const {
157
    int length = _prob->numberRows();
158

	
159
    std::vector<int> indices(length);
160
    std::vector<Value> values(length);
161

	
162
    length = _prob->getRow(ix, &indices[0], &values[0]);
163

	
164
    for (int i = 0; i < length; ++i) {
165
      *b = std::make_pair(indices[i], values[i]);
166
      ++b;
167
    }
168
  }
169

	
170
  void CbcMip::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
171
    for (ExprIterator it = b; it != e; ++it) {
172
      _prob->setElement(it->first, ix, it->second);
173
    }
174
  }
175

	
176
  void CbcMip::_getColCoeffs(int ix, InsertIterator b) const {
177
    int length = _prob->numberColumns();
178

	
179
    std::vector<int> indices(length);
180
    std::vector<Value> values(length);
181

	
182
    length = _prob->getColumn(ix, &indices[0], &values[0]);
183

	
184
    for (int i = 0; i < length; ++i) {
185
      *b = std::make_pair(indices[i], values[i]);
186
      ++b;
187
    }
188
  }
189

	
190
  void CbcMip::_setCoeff(int ix, int jx, Value value) {
191
    _prob->setElement(ix, jx, value);
192
  }
193

	
194
  CbcMip::Value CbcMip::_getCoeff(int ix, int jx) const {
195
    return _prob->getElement(ix, jx);
196
  }
197

	
198

	
199
  void CbcMip::_setColLowerBound(int i, Value lo) {
200
    LEMON_ASSERT(lo != INF, "Invalid bound");
201
    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
202
  }
203

	
204
  CbcMip::Value CbcMip::_getColLowerBound(int i) const {
205
    double val = _prob->getColumnLower(i);
206
    return val == - COIN_DBL_MAX ? - INF : val;
207
  }
208

	
209
  void CbcMip::_setColUpperBound(int i, Value up) {
210
    LEMON_ASSERT(up != -INF, "Invalid bound");
211
    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
212
  }
213

	
214
  CbcMip::Value CbcMip::_getColUpperBound(int i) const {
215
    double val = _prob->getColumnUpper(i);
216
    return val == COIN_DBL_MAX ? INF : val;
217
  }
218

	
219
  void CbcMip::_setRowLowerBound(int i, Value lo) {
220
    LEMON_ASSERT(lo != INF, "Invalid bound");
221
    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
222
  }
223

	
224
  CbcMip::Value CbcMip::_getRowLowerBound(int i) const {
225
    double val = _prob->getRowLower(i);
226
    return val == - COIN_DBL_MAX ? - INF : val;
227
  }
228

	
229
  void CbcMip::_setRowUpperBound(int i, Value up) {
230
    LEMON_ASSERT(up != -INF, "Invalid bound");
231
    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
232
  }
233

	
234
  CbcMip::Value CbcMip::_getRowUpperBound(int i) const {
235
    double val = _prob->getRowUpper(i);
236
    return val == COIN_DBL_MAX ? INF : val;
237
  }
238

	
239
  void CbcMip::_setObjCoeffs(ExprIterator b, ExprIterator e) {
240
    int num = _prob->numberColumns();
241
    for (int i = 0; i < num; ++i) {
242
      _prob->setColumnObjective(i, 0.0);
243
    }
244
    for (ExprIterator it = b; it != e; ++it) {
245
      _prob->setColumnObjective(it->first, it->second);
246
    }
247
  }
248

	
249
  void CbcMip::_getObjCoeffs(InsertIterator b) const {
250
    int num = _prob->numberColumns();
251
    for (int i = 0; i < num; ++i) {
252
      Value coef = _prob->getColumnObjective(i);
253
      if (coef != 0.0) {
254
        *b = std::make_pair(i, coef);
255
        ++b;
256
      }
257
    }
258
  }
259

	
260
  void CbcMip::_setObjCoeff(int i, Value obj_coef) {
261
    _prob->setColumnObjective(i, obj_coef);
262
  }
263

	
264
  CbcMip::Value CbcMip::_getObjCoeff(int i) const {
265
    return _prob->getColumnObjective(i);
266
  }
267

	
268
  CbcMip::SolveExitStatus CbcMip::_solve() {
269

	
270
    if (_osi_solver) {
271
      delete _osi_solver;
272
    }
273
#ifdef COIN_HAS_CLP
274
    _osi_solver = new OsiClpSolverInterface();
275
#elif COIN_HAS_OSL
276
    _osi_solver = new OsiOslSolverInterface();
277
#else
278
#error Cannot instantiate Osi solver
279
#endif
280

	
281
    _osi_solver->loadFromCoinModel(*_prob);
282

	
283
    if (_cbc_model) {
284
      delete _cbc_model;
285
    }
286
    _cbc_model= new CbcModel(*_osi_solver);
287

	
288
    _osi_solver->messageHandler()->setLogLevel(_message_level);
289
    _cbc_model->setLogLevel(_message_level);
290

	
291
    _cbc_model->initialSolve();
292
    _cbc_model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
293

	
294
    if (!_cbc_model->isInitialSolveAbandoned() &&
295
        _cbc_model->isInitialSolveProvenOptimal() &&
296
        !_cbc_model->isInitialSolveProvenPrimalInfeasible() &&
297
        !_cbc_model->isInitialSolveProvenDualInfeasible()) {
298

	
299
      CglProbing generator1;
300
      generator1.setUsingObjective(true);
301
      generator1.setMaxPass(3);
302
      generator1.setMaxProbe(100);
303
      generator1.setMaxLook(50);
304
      generator1.setRowCuts(3);
305
      _cbc_model->addCutGenerator(&generator1, -1, "Probing");
306

	
307
      CglGomory generator2;
308
      generator2.setLimit(300);
309
      _cbc_model->addCutGenerator(&generator2, -1, "Gomory");
310

	
311
      CglKnapsackCover generator3;
312
      _cbc_model->addCutGenerator(&generator3, -1, "Knapsack");
313

	
314
      CglOddHole generator4;
315
      generator4.setMinimumViolation(0.005);
316
      generator4.setMinimumViolationPer(0.00002);
317
      generator4.setMaximumEntries(200);
318
      _cbc_model->addCutGenerator(&generator4, -1, "OddHole");
319

	
320
      CglClique generator5;
321
      generator5.setStarCliqueReport(false);
322
      generator5.setRowCliqueReport(false);
323
      _cbc_model->addCutGenerator(&generator5, -1, "Clique");
324

	
325
      CglMixedIntegerRounding mixedGen;
326
      _cbc_model->addCutGenerator(&mixedGen, -1, "MixedIntegerRounding");
327

	
328
      CglFlowCover flowGen;
329
      _cbc_model->addCutGenerator(&flowGen, -1, "FlowCover");
330

	
331
#ifdef COIN_HAS_CLP
332
      OsiClpSolverInterface* osiclp =
333
        dynamic_cast<OsiClpSolverInterface*>(_cbc_model->solver());
334
      if (osiclp->getNumRows() < 300 && osiclp->getNumCols() < 500) {
335
        osiclp->setupForRepeatedUse(2, 0);
336
      }
337
#endif
338

	
339
      CbcRounding heuristic1(*_cbc_model);
340
      heuristic1.setWhen(3);
341
      _cbc_model->addHeuristic(&heuristic1);
342

	
343
      CbcHeuristicLocal heuristic2(*_cbc_model);
344
      heuristic2.setWhen(3);
345
      _cbc_model->addHeuristic(&heuristic2);
346

	
347
      CbcHeuristicGreedyCover heuristic3(*_cbc_model);
348
      heuristic3.setAlgorithm(11);
349
      heuristic3.setWhen(3);
350
      _cbc_model->addHeuristic(&heuristic3);
351

	
352
      CbcHeuristicFPump heuristic4(*_cbc_model);
353
      heuristic4.setWhen(3);
354
      _cbc_model->addHeuristic(&heuristic4);
355

	
356
      CbcHeuristicRINS heuristic5(*_cbc_model);
357
      heuristic5.setWhen(3);
358
      _cbc_model->addHeuristic(&heuristic5);
359

	
360
      if (_cbc_model->getNumCols() < 500) {
361
        _cbc_model->setMaximumCutPassesAtRoot(-100);
362
      } else if (_cbc_model->getNumCols() < 5000) {
363
        _cbc_model->setMaximumCutPassesAtRoot(100);
364
      } else {
365
        _cbc_model->setMaximumCutPassesAtRoot(20);
366
      }
367

	
368
      if (_cbc_model->getNumCols() < 5000) {
369
        _cbc_model->setNumberStrong(10);
370
      }
371

	
372
      _cbc_model->solver()->setIntParam(OsiMaxNumIterationHotStart, 100);
373
      _cbc_model->branchAndBound();
374
    }
375

	
376
    if (_cbc_model->isAbandoned()) {
377
      return UNSOLVED;
378
    } else {
379
      return SOLVED;
380
    }
381
  }
382

	
383
  CbcMip::Value CbcMip::_getSol(int i) const {
384
    return _cbc_model->getColSolution()[i];
385
  }
386

	
387
  CbcMip::Value CbcMip::_getSolValue() const {
388
    return _cbc_model->getObjValue();
389
  }
390

	
391
  CbcMip::ProblemType CbcMip::_getType() const {
392
    if (_cbc_model->isProvenOptimal()) {
393
      return OPTIMAL;
394
    } else if (_cbc_model->isContinuousUnbounded()) {
395
      return UNBOUNDED;
396
    }
397
    return FEASIBLE;
398
  }
399

	
400
  void CbcMip::_setSense(Sense sense) {
401
    switch (sense) {
402
    case MIN:
403
      _prob->setOptimizationDirection(1.0);
404
      break;
405
    case MAX:
406
      _prob->setOptimizationDirection(- 1.0);
407
      break;
408
    }
409
  }
410

	
411
  CbcMip::Sense CbcMip::_getSense() const {
412
    if (_prob->optimizationDirection() > 0.0) {
413
      return MIN;
414
    } else if (_prob->optimizationDirection() < 0.0) {
415
      return MAX;
416
    } else {
417
      LEMON_ASSERT(false, "Wrong sense");
418
      return CbcMip::Sense();
419
    }
420
  }
421

	
422
  void CbcMip::_setColType(int i, CbcMip::ColTypes col_type) {
423
    switch (col_type){
424
    case INTEGER:
425
      _prob->setInteger(i);
426
      break;
427
    case REAL:
428
      _prob->setContinuous(i);
429
      break;
430
    default:;
431
      LEMON_ASSERT(false, "Wrong sense");
432
    }
433
  }
434

	
435
  CbcMip::ColTypes CbcMip::_getColType(int i) const {
436
    return _prob->getColumnIsInteger(i) ? INTEGER : REAL;
437
  }
438

	
439
  void CbcMip::_clear() {
440
    delete _prob;
441
    if (_osi_solver) {
442
      delete _osi_solver;
443
      _osi_solver = 0;
444
    }
445
    if (_cbc_model) {
446
      delete _cbc_model;
447
      _cbc_model = 0;
448
    }
449

	
450
    _prob = new CoinModel();
451
    rows.clear();
452
    cols.clear();
453
  }
454

	
455
  void CbcMip::_messageLevel(MessageLevel level) {
456
    switch (level) {
457
    case MESSAGE_NOTHING:
458
      _message_level = 0;
459
      break;
460
    case MESSAGE_ERROR:
461
      _message_level = 1;
462
      break;
463
    case MESSAGE_WARNING:
464
      _message_level = 1;
465
      break;
466
    case MESSAGE_NORMAL:
467
      _message_level = 2;
468
      break;
469
    case MESSAGE_VERBOSE:
470
      _message_level = 3;
471
      break;
472
    }
473
  }
474

	
475
} //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
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
66

	
67
    virtual void _eraseCol(int i);
68
    virtual void _eraseRow(int i);
69

	
70
    virtual void _eraseColId(int i);
71
    virtual void _eraseRowId(int i);
72

	
73
    virtual void _getColName(int col, std::string& name) const;
74
    virtual void _setColName(int col, const std::string& name);
75
    virtual int _colByName(const std::string& name) const;
76

	
77
    virtual void _getRowName(int row, std::string& name) const;
78
    virtual void _setRowName(int row, const std::string& name);
79
    virtual int _rowByName(const std::string& name) const;
80

	
81
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
82
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
83

	
84
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
85
    virtual void _getColCoeffs(int i, InsertIterator b) const;
86

	
87
    virtual void _setCoeff(int row, int col, Value value);
88
    virtual Value _getCoeff(int row, int col) const;
89

	
90
    virtual void _setColLowerBound(int i, Value value);
91
    virtual Value _getColLowerBound(int i) const;
92
    virtual void _setColUpperBound(int i, Value value);
93
    virtual Value _getColUpperBound(int i) const;
94

	
95
    virtual void _setRowLowerBound(int i, Value value);
96
    virtual Value _getRowLowerBound(int i) const;
97
    virtual void _setRowUpperBound(int i, Value value);
98
    virtual Value _getRowUpperBound(int i) const;
99

	
100
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
101
    virtual void _getObjCoeffs(InsertIterator b) const;
102

	
103
    virtual void _setObjCoeff(int i, Value obj_coef);
104
    virtual Value _getObjCoeff(int i) const;
105

	
106
    virtual void _setSense(Sense sense);
107
    virtual Sense _getSense() const;
108

	
109
    virtual ColTypes _getColType(int col) const;
110
    virtual void _setColType(int col, ColTypes col_type);
111

	
112
    virtual SolveExitStatus _solve();
113
    virtual ProblemType _getType() const;
114
    virtual Value _getSol(int i) const;
115
    virtual Value _getSolValue() const;
116

	
117
    virtual void _clear();
118

	
119
    virtual void _messageLevel(MessageLevel level);
120
    void _applyMessageLevel();
121

	
122
    int _message_level;
123

	
124
    
125

	
126
  };
127

	
128
}
129

	
130
#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
#ifdef DOXYGEN
76
    typedef GR::ArcMap<Value> FlowMap;
77
#else
78
    typedef typename Digraph::template ArcMap<Value> FlowMap;
79
#endif
80

	
81
    /// \brief Instantiates a FlowMap.
82
    ///
83
    /// This function instantiates a \ref FlowMap.
84
    /// \param digraph The digraph for which we would like to define
85
    /// the flow map.
86
    static FlowMap* createFlowMap(const Digraph& digraph) {
87
      return new FlowMap(digraph);
88
    }
89

	
90
    /// \brief The elevator type used by the algorithm.
91
    ///
92
    /// The elevator type used by the algorithm.
93
    ///
94
    /// \sa Elevator, LinkedElevator
95
#ifdef DOXYGEN
96
    typedef lemon::Elevator<GR, GR::Node> Elevator;
97
#else
98
    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
99
#endif
100

	
101
    /// \brief Instantiates an Elevator.
102
    ///
103
    /// This function instantiates an \ref Elevator.
104
    /// \param digraph The digraph for which we would like to define
105
    /// the elevator.
106
    /// \param max_level The maximum level of the elevator.
107
    static Elevator* createElevator(const Digraph& digraph, int max_level) {
108
      return new Elevator(digraph, max_level);
109
    }
110

	
111
    /// \brief The tolerance used by the algorithm
112
    ///
113
    /// The tolerance used by the algorithm to handle inexact computation.
114
    typedef lemon::Tolerance<Value> Tolerance;
115

	
116
  };
117

	
118
  /**
119
     \brief Push-relabel algorithm for the network circulation problem.
120

	
121
     \ingroup max_flow
122
     This class implements a push-relabel algorithm for the \e network
123
     \e circulation problem.
124
     It is to find a feasible circulation when lower and upper bounds
125
     are given for the flow values on the arcs and lower bounds are
126
     given for the difference between the outgoing and incoming flow
127
     at the nodes.
128

	
129
     The exact formulation of this problem is the following.
130
     Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$
131
     \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and
132
     upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$
133
     holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
134
     denotes the signed supply values of the nodes.
135
     If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
136
     supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
137
     \f$-sup(u)\f$ demand.
138
     A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$
139
     solution of the following problem.
140

	
141
     \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
142
     \geq sup(u) \quad \forall u\in V, \f]
143
     \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
144
     
145
     The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
146
     zero or negative in order to have a feasible solution (since the sum
147
     of the expressions on the left-hand side of the inequalities is zero).
148
     It means that the total demand must be greater or equal to the total
149
     supply and all the supplies have to be carried out from the supply nodes,
150
     but there could be demands that are not satisfied.
151
     If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
152
     constraints have to be satisfied with equality, i.e. all demands
153
     have to be satisfied and all supplies have to be used.
154
     
155
     If you need the opposite inequalities in the supply/demand constraints
156
     (i.e. the total demand is less than the total supply and all the demands
157
     have to be satisfied while there could be supplies that are not used),
158
     then you could easily transform the problem to the above form by reversing
159
     the direction of the arcs and taking the negative of the supply values
160
     (e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
161

	
162
     This algorithm either calculates a feasible circulation, or provides
163
     a \ref barrier() "barrier", which prooves that a feasible soultion
164
     cannot exist.
165

	
166
     Note that this algorithm also provides a feasible solution for the
167
     \ref min_cost_flow "minimum cost flow problem".
168

	
169
     \tparam GR The type of the digraph the algorithm runs on.
170
     \tparam LM The type of the lower bound map. The default
171
     map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
172
     \tparam UM The type of the upper bound (capacity) map.
173
     The default map type is \c LM.
174
     \tparam SM The type of the supply map. The default map type is
175
     \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
176
  */
177
#ifdef DOXYGEN
178
template< typename GR,
179
          typename LM,
180
          typename UM,
181
          typename SM,
182
          typename TR >
183
#else
184
template< typename GR,
185
          typename LM = typename GR::template ArcMap<int>,
186
          typename UM = LM,
187
          typename SM = typename GR::template NodeMap<typename UM::Value>,
188
          typename TR = CirculationDefaultTraits<GR, LM, UM, SM> >
189
#endif
190
  class Circulation {
191
  public:
192

	
193
    ///The \ref CirculationDefaultTraits "traits class" of the algorithm.
194
    typedef TR Traits;
195
    ///The type of the digraph the algorithm runs on.
196
    typedef typename Traits::Digraph Digraph;
197
    ///The type of the flow and supply values.
198
    typedef typename Traits::Value Value;
199

	
200
    ///The type of the lower bound map.
201
    typedef typename Traits::LowerMap LowerMap;
202
    ///The type of the upper bound (capacity) map.
203
    typedef typename Traits::UpperMap UpperMap;
204
    ///The type of the supply map.
205
    typedef typename Traits::SupplyMap SupplyMap;
206
    ///The type of the flow map.
207
    typedef typename Traits::FlowMap FlowMap;
208

	
209
    ///The type of the elevator.
210
    typedef typename Traits::Elevator Elevator;
211
    ///The type of the tolerance.
212
    typedef typename Traits::Tolerance Tolerance;
213

	
214
  private:
215

	
216
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
217

	
218
    const Digraph &_g;
219
    int _node_num;
220

	
221
    const LowerMap *_lo;
222
    const UpperMap *_up;
223
    const SupplyMap *_supply;
224

	
225
    FlowMap *_flow;
226
    bool _local_flow;
227

	
228
    Elevator* _level;
229
    bool _local_level;
230

	
231
    typedef typename Digraph::template NodeMap<Value> ExcessMap;
232
    ExcessMap* _excess;
233

	
234
    Tolerance _tol;
235
    int _el;
236

	
237
  public:
238

	
239
    typedef Circulation Create;
240

	
241
    ///\name Named Template Parameters
242

	
243
    ///@{
244

	
245
    template <typename T>
246
    struct SetFlowMapTraits : public Traits {
247
      typedef T FlowMap;
248
      static FlowMap *createFlowMap(const Digraph&) {
249
        LEMON_ASSERT(false, "FlowMap is not initialized");
250
        return 0; // ignore warnings
251
      }
252
    };
253

	
254
    /// \brief \ref named-templ-param "Named parameter" for setting
255
    /// FlowMap type
256
    ///
257
    /// \ref named-templ-param "Named parameter" for setting FlowMap
258
    /// type.
259
    template <typename T>
260
    struct SetFlowMap
261
      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
262
                           SetFlowMapTraits<T> > {
263
      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
264
                          SetFlowMapTraits<T> > Create;
265
    };
266

	
267
    template <typename T>
268
    struct SetElevatorTraits : public Traits {
269
      typedef T Elevator;
270
      static Elevator *createElevator(const Digraph&, int) {
271
        LEMON_ASSERT(false, "Elevator is not initialized");
272
        return 0; // ignore warnings
273
      }
274
    };
275

	
276
    /// \brief \ref named-templ-param "Named parameter" for setting
277
    /// Elevator type
278
    ///
279
    /// \ref named-templ-param "Named parameter" for setting Elevator
280
    /// type. If this named parameter is used, then an external
281
    /// elevator object must be passed to the algorithm using the
282
    /// \ref elevator(Elevator&) "elevator()" function before calling
283
    /// \ref run() or \ref init().
284
    /// \sa SetStandardElevator
285
    template <typename T>
286
    struct SetElevator
287
      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
288
                           SetElevatorTraits<T> > {
289
      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
290
                          SetElevatorTraits<T> > Create;
291
    };
292

	
293
    template <typename T>
294
    struct SetStandardElevatorTraits : public Traits {
295
      typedef T Elevator;
296
      static Elevator *createElevator(const Digraph& digraph, int max_level) {
297
        return new Elevator(digraph, max_level);
298
      }
299
    };
300

	
301
    /// \brief \ref named-templ-param "Named parameter" for setting
302
    /// Elevator type with automatic allocation
303
    ///
304
    /// \ref named-templ-param "Named parameter" for setting Elevator
305
    /// type with automatic allocation.
306
    /// The Elevator should have standard constructor interface to be
307
    /// able to automatically created by the algorithm (i.e. the
308
    /// digraph and the maximum level should be passed to it).
309
    /// However an external elevator object could also be passed to the
310
    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
311
    /// before calling \ref run() or \ref init().
312
    /// \sa SetElevator
313
    template <typename T>
314
    struct SetStandardElevator
315
      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
316
                       SetStandardElevatorTraits<T> > {
317
      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
318
                      SetStandardElevatorTraits<T> > Create;
319
    };
320

	
321
    /// @}
322

	
323
  protected:
324

	
325
    Circulation() {}
326

	
327
  public:
328

	
329
    /// Constructor.
330

	
331
    /// The constructor of the class.
332
    ///
333
    /// \param graph The digraph the algorithm runs on.
334
    /// \param lower The lower bounds for the flow values on the arcs.
335
    /// \param upper The upper bounds (capacities) for the flow values 
336
    /// on the arcs.
337
    /// \param supply The signed supply values of the nodes.
338
    Circulation(const Digraph &graph, const LowerMap &lower,
339
                const UpperMap &upper, const SupplyMap &supply)
340
      : _g(graph), _lo(&lower), _up(&upper), _supply(&supply),
341
        _flow(NULL), _local_flow(false), _level(NULL), _local_level(false),
342
        _excess(NULL) {}
343

	
344
    /// Destructor.
345
    ~Circulation() {
346
      destroyStructures();
347
    }
348

	
349

	
350
  private:
351

	
352
    bool checkBoundMaps() {
353
      for (ArcIt e(_g);e!=INVALID;++e) {
354
        if (_tol.less((*_up)[e], (*_lo)[e])) return false;
355
      }
356
      return true;
357
    }
358

	
359
    void createStructures() {
360
      _node_num = _el = countNodes(_g);
361

	
362
      if (!_flow) {
363
        _flow = Traits::createFlowMap(_g);
364
        _local_flow = true;
365
      }
366
      if (!_level) {
367
        _level = Traits::createElevator(_g, _node_num);
368
        _local_level = true;
369
      }
370
      if (!_excess) {
371
        _excess = new ExcessMap(_g);
372
      }
373
    }
374

	
375
    void destroyStructures() {
376
      if (_local_flow) {
377
        delete _flow;
378
      }
379
      if (_local_level) {
380
        delete _level;
381
      }
382
      if (_excess) {
383
        delete _excess;
384
      }
385
    }
386

	
387
  public:
388

	
389
    /// Sets the lower bound map.
390

	
391
    /// Sets the lower bound map.
392
    /// \return <tt>(*this)</tt>
393
    Circulation& lowerMap(const LowerMap& map) {
394
      _lo = &map;
395
      return *this;
396
    }
397

	
398
    /// Sets the upper bound (capacity) map.
399

	
400
    /// Sets the upper bound (capacity) map.
401
    /// \return <tt>(*this)</tt>
402
    Circulation& upperMap(const UpperMap& map) {
403
      _up = &map;
404
      return *this;
405
    }
406

	
407
    /// Sets the supply map.
408

	
409
    /// Sets the supply map.
410
    /// \return <tt>(*this)</tt>
411
    Circulation& supplyMap(const SupplyMap& map) {
412
      _supply = &map;
413
      return *this;
414
    }
415

	
416
    /// \brief Sets the flow map.
417
    ///
418
    /// Sets the flow map.
419
    /// If you don't use this function before calling \ref run() or
420
    /// \ref init(), an instance will be allocated automatically.
421
    /// The destructor deallocates this automatically allocated map,
422
    /// of course.
423
    /// \return <tt>(*this)</tt>
424
    Circulation& flowMap(FlowMap& map) {
425
      if (_local_flow) {
426
        delete _flow;
427
        _local_flow = false;
428
      }
429
      _flow = &map;
430
      return *this;
431
    }
432

	
433
    /// \brief Sets the elevator used by algorithm.
434
    ///
435
    /// Sets the elevator used by algorithm.
436
    /// If you don't use this function before calling \ref run() or
437
    /// \ref init(), an instance will be allocated automatically.
438
    /// The destructor deallocates this automatically allocated elevator,
439
    /// of course.
440
    /// \return <tt>(*this)</tt>
441
    Circulation& elevator(Elevator& elevator) {
442
      if (_local_level) {
443
        delete _level;
444
        _local_level = false;
445
      }
446
      _level = &elevator;
447
      return *this;
448
    }
449

	
450
    /// \brief Returns a const reference to the elevator.
451
    ///
452
    /// Returns a const reference to the elevator.
453
    ///
454
    /// \pre Either \ref run() or \ref init() must be called before
455
    /// using this function.
456
    const Elevator& elevator() const {
457
      return *_level;
458
    }
459

	
460
    /// \brief Sets the tolerance used by the algorithm.
461
    ///
462
    /// Sets the tolerance object used by the algorithm.
463
    /// \return <tt>(*this)</tt>
464
    Circulation& tolerance(const Tolerance& tolerance) {
465
      _tol = tolerance;
466
      return *this;
467
    }
468

	
469
    /// \brief Returns a const reference to the tolerance.
470
    ///
471
    /// Returns a const reference to the tolerance object used by
472
    /// the algorithm.
473
    const Tolerance& tolerance() const {
474
      return _tol;
475
    }
476

	
477
    /// \name Execution Control
478
    /// The simplest way to execute the algorithm is to call \ref run().\n
479
    /// If you need better control on the initial solution or the execution,
480
    /// you have to call one of the \ref init() functions first, then
481
    /// the \ref start() function.
482

	
483
    ///@{
484

	
485
    /// Initializes the internal data structures.
486

	
487
    /// Initializes the internal data structures and sets all flow values
488
    /// to the lower bound.
489
    void init()
490
    {
491
      LEMON_DEBUG(checkBoundMaps(),
492
        "Upper bounds must be greater or equal to the lower bounds");
493

	
494
      createStructures();
495

	
496
      for(NodeIt n(_g);n!=INVALID;++n) {
497
        (*_excess)[n] = (*_supply)[n];
498
      }
499

	
500
      for (ArcIt e(_g);e!=INVALID;++e) {
501
        _flow->set(e, (*_lo)[e]);
502
        (*_excess)[_g.target(e)] += (*_flow)[e];
503
        (*_excess)[_g.source(e)] -= (*_flow)[e];
504
      }
505

	
506
      // global relabeling tested, but in general case it provides
507
      // worse performance for random digraphs
508
      _level->initStart();
509
      for(NodeIt n(_g);n!=INVALID;++n)
510
        _level->initAddItem(n);
511
      _level->initFinish();
512
      for(NodeIt n(_g);n!=INVALID;++n)
513
        if(_tol.positive((*_excess)[n]))
514
          _level->activate(n);
515
    }
516

	
517
    /// Initializes the internal data structures using a greedy approach.
518

	
519
    /// Initializes the internal data structures using a greedy approach
520
    /// to construct the initial solution.
521
    void greedyInit()
522
    {
523
      LEMON_DEBUG(checkBoundMaps(),
524
        "Upper bounds must be greater or equal to the lower bounds");
525

	
526
      createStructures();
527

	
528
      for(NodeIt n(_g);n!=INVALID;++n) {
529
        (*_excess)[n] = (*_supply)[n];
530
      }
531

	
532
      for (ArcIt e(_g);e!=INVALID;++e) {
533
        if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) {
534
          _flow->set(e, (*_up)[e]);
535
          (*_excess)[_g.target(e)] += (*_up)[e];
536
          (*_excess)[_g.source(e)] -= (*_up)[e];
537
        } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) {
538
          _flow->set(e, (*_lo)[e]);
539
          (*_excess)[_g.target(e)] += (*_lo)[e];
540
          (*_excess)[_g.source(e)] -= (*_lo)[e];
541
        } else {
542
          Value fc = -(*_excess)[_g.target(e)];
543
          _flow->set(e, fc);
544
          (*_excess)[_g.target(e)] = 0;
545
          (*_excess)[_g.source(e)] -= fc;
546
        }
547
      }
548

	
549
      _level->initStart();
550
      for(NodeIt n(_g);n!=INVALID;++n)
551
        _level->initAddItem(n);
552
      _level->initFinish();
553
      for(NodeIt n(_g);n!=INVALID;++n)
554
        if(_tol.positive((*_excess)[n]))
555
          _level->activate(n);
556
    }
557

	
558
    ///Executes the algorithm
559

	
560
    ///This function executes the algorithm.
561
    ///
562
    ///\return \c true if a feasible circulation is found.
563
    ///
564
    ///\sa barrier()
565
    ///\sa barrierMap()
566
    bool start()
567
    {
568

	
569
      Node act;
570
      Node bact=INVALID;
571
      Node last_activated=INVALID;
572
      while((act=_level->highestActive())!=INVALID) {
573
        int actlevel=(*_level)[act];
574
        int mlevel=_node_num;
575
        Value exc=(*_excess)[act];
576

	
577
        for(OutArcIt e(_g,act);e!=INVALID; ++e) {
578
          Node v = _g.target(e);
579
          Value fc=(*_up)[e]-(*_flow)[e];
580
          if(!_tol.positive(fc)) continue;
581
          if((*_level)[v]<actlevel) {
582
            if(!_tol.less(fc, exc)) {
583
              _flow->set(e, (*_flow)[e] + exc);
584
              (*_excess)[v] += exc;
585
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
586
                _level->activate(v);
587
              (*_excess)[act] = 0;
588
              _level->deactivate(act);
589
              goto next_l;
590
            }
591
            else {
592
              _flow->set(e, (*_up)[e]);
593
              (*_excess)[v] += fc;
594
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
595
                _level->activate(v);
596
              exc-=fc;
597
            }
598
          }
599
          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
600
        }
601
        for(InArcIt e(_g,act);e!=INVALID; ++e) {
602
          Node v = _g.source(e);
603
          Value fc=(*_flow)[e]-(*_lo)[e];
604
          if(!_tol.positive(fc)) continue;
605
          if((*_level)[v]<actlevel) {
606
            if(!_tol.less(fc, exc)) {
607
              _flow->set(e, (*_flow)[e] - exc);
608
              (*_excess)[v] += exc;
609
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
610
                _level->activate(v);
611
              (*_excess)[act] = 0;
612
              _level->deactivate(act);
613
              goto next_l;
614
            }
615
            else {
616
              _flow->set(e, (*_lo)[e]);
617
              (*_excess)[v] += fc;
618
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
619
                _level->activate(v);
620
              exc-=fc;
621
            }
622
          }
623
          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
624
        }
625

	
626
        (*_excess)[act] = exc;
627
        if(!_tol.positive(exc)) _level->deactivate(act);
628
        else if(mlevel==_node_num) {
629
          _level->liftHighestActiveToTop();
630
          _el = _node_num;
631
          return false;
632
        }
633
        else {
634
          _level->liftHighestActive(mlevel+1);
635
          if(_level->onLevel(actlevel)==0) {
636
            _el = actlevel;
637
            return false;
638
          }
639
        }
640
      next_l:
641
        ;
642
      }
643
      return true;
644
    }
645

	
646
    /// Runs the algorithm.
647

	
648
    /// This function runs the algorithm.
649
    ///
650
    /// \return \c true if a feasible circulation is found.
651
    ///
652
    /// \note Apart from the return value, c.run() is just a shortcut of
653
    /// the following code.
654
    /// \code
655
    ///   c.greedyInit();
656
    ///   c.start();
657
    /// \endcode
658
    bool run() {
659
      greedyInit();
660
      return start();
661
    }
662

	
663
    /// @}
664

	
665
    /// \name Query Functions
666
    /// The results of the circulation algorithm can be obtained using
667
    /// these functions.\n
668
    /// Either \ref run() or \ref start() should be called before
669
    /// using them.
670

	
671
    ///@{
672

	
673
    /// \brief Returns the flow value on the given arc.
674
    ///
675
    /// Returns the flow value on the given arc.
676
    ///
677
    /// \pre Either \ref run() or \ref init() must be called before
678
    /// using this function.
679
    Value flow(const Arc& arc) const {
680
      return (*_flow)[arc];
681
    }
682

	
683
    /// \brief Returns a const reference to the flow map.
684
    ///
685
    /// Returns a const reference to the arc map storing the found flow.
686
    ///
687
    /// \pre Either \ref run() or \ref init() must be called before
688
    /// using this function.
689
    const FlowMap& flowMap() const {
690
      return *_flow;
691
    }
692

	
693
    /**
694
       \brief Returns \c true if the given node is in a barrier.
695

	
696
       Barrier is a set \e B of nodes for which
697

	
698
       \f[ \sum_{uv\in A: u\in B} upper(uv) -
699
           \sum_{uv\in A: v\in B} lower(uv) < \sum_{v\in B} sup(v) \f]
700

	
701
       holds. The existence of a set with this property prooves that a
702
       feasible circualtion cannot exist.
703

	
704
       This function returns \c true if the given node is in the found
705
       barrier. If a feasible circulation is found, the function
706
       gives back \c false for every node.
707

	
708
       \pre Either \ref run() or \ref init() must be called before
709
       using this function.
710

	
711
       \sa barrierMap()
712
       \sa checkBarrier()
713
    */
714
    bool barrier(const Node& node) const
715
    {
716
      return (*_level)[node] >= _el;
717
    }
718

	
719
    /// \brief Gives back a barrier.
720
    ///
721
    /// This function sets \c bar to the characteristic vector of the
722
    /// found barrier. \c bar should be a \ref concepts::WriteMap "writable"
723
    /// node map with \c bool (or convertible) value type.
724
    ///
725
    /// If a feasible circulation is found, the function gives back an
726
    /// empty set, so \c bar[v] will be \c false for all nodes \c v.
727
    ///
728
    /// \note This function calls \ref barrier() for each node,
729
    /// so it runs in O(n) time.
730
    ///
731
    /// \pre Either \ref run() or \ref init() must be called before
732
    /// using this function.
733
    ///
734
    /// \sa barrier()
735
    /// \sa checkBarrier()
736
    template<class BarrierMap>
737
    void barrierMap(BarrierMap &bar) const
738
    {
739
      for(NodeIt n(_g);n!=INVALID;++n)
740
        bar.set(n, (*_level)[n] >= _el);
741
    }
742

	
743
    /// @}
744

	
745
    /// \name Checker Functions
746
    /// The feasibility of the results can be checked using
747
    /// these functions.\n
748
    /// Either \ref run() or \ref start() should be called before
749
    /// using them.
750

	
751
    ///@{
752

	
753
    ///Check if the found flow is a feasible circulation
754

	
755
    ///Check if the found flow is a feasible circulation,
756
    ///
757
    bool checkFlow() const {
758
      for(ArcIt e(_g);e!=INVALID;++e)
759
        if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
760
      for(NodeIt n(_g);n!=INVALID;++n)
761
        {
762
          Value dif=-(*_supply)[n];
763
          for(InArcIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
764
          for(OutArcIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
765
          if(_tol.negative(dif)) return false;
766
        }
767
      return true;
768
    }
769

	
770
    ///Check whether or not the last execution provides a barrier
771

	
772
    ///Check whether or not the last execution provides a barrier.
773
    ///\sa barrier()
774
    ///\sa barrierMap()
775
    bool checkBarrier() const
776
    {
777
      Value delta=0;
778
      Value inf_cap = std::numeric_limits<Value>::has_infinity ?
779
        std::numeric_limits<Value>::infinity() :
780
        std::numeric_limits<Value>::max();
781
      for(NodeIt n(_g);n!=INVALID;++n)
782
        if(barrier(n))
783
          delta-=(*_supply)[n];
784
      for(ArcIt e(_g);e!=INVALID;++e)
785
        {
786
          Node s=_g.source(e);
787
          Node t=_g.target(e);
788
          if(barrier(s)&&!barrier(t)) {
789
            if (_tol.less(inf_cap - (*_up)[e], delta)) return false;
790
            delta+=(*_up)[e];
791
          }
792
          else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
793
        }
794
      return _tol.negative(delta);
795
    }
796

	
797
    /// @}
798

	
799
  };
800

	
801
}
802

	
803
#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
  int ClpLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
82
    std::vector<int> indexes;
83
    std::vector<Value> values;
84

	
85
    for(ExprIterator it = b; it != e; ++it) {
86
      indexes.push_back(it->first);
87
      values.push_back(it->second);
88
    }
89

	
90
    _prob->addRow(values.size(), &indexes.front(), &values.front(), l, u);
91
    return _prob->numberRows() - 1;
92
  }
93

	
94

	
95
  void ClpLp::_eraseCol(int c) {
96
    _col_names_ref.erase(_prob->getColumnName(c));
97
    _prob->deleteColumns(1, &c);
98
  }
99

	
100
  void ClpLp::_eraseRow(int r) {
101
    _row_names_ref.erase(_prob->getRowName(r));
102
    _prob->deleteRows(1, &r);
103
  }
104

	
105
  void ClpLp::_eraseColId(int i) {
106
    cols.eraseIndex(i);
107
    cols.shiftIndices(i);
108
  }
109

	
110
  void ClpLp::_eraseRowId(int i) {
111
    rows.eraseIndex(i);
112
    rows.shiftIndices(i);
113
  }
114

	
115
  void ClpLp::_getColName(int c, std::string& name) const {
116
    name = _prob->getColumnName(c);
117
  }
118

	
119
  void ClpLp::_setColName(int c, const std::string& name) {
120
    _prob->setColumnName(c, const_cast<std::string&>(name));
121
    _col_names_ref[name] = c;
122
  }
123

	
124
  int ClpLp::_colByName(const std::string& name) const {
125
    std::map<std::string, int>::const_iterator it = _col_names_ref.find(name);
126
    return it != _col_names_ref.end() ? it->second : -1;
127
  }
128

	
129
  void ClpLp::_getRowName(int r, std::string& name) const {
130
    name = _prob->getRowName(r);
131
  }
132

	
133
  void ClpLp::_setRowName(int r, const std::string& name) {
134
    _prob->setRowName(r, const_cast<std::string&>(name));
135
    _row_names_ref[name] = r;
136
  }
137

	
138
  int ClpLp::_rowByName(const std::string& name) const {
139
    std::map<std::string, int>::const_iterator it = _row_names_ref.find(name);
140
    return it != _row_names_ref.end() ? it->second : -1;
141
  }
142

	
143

	
144
  void ClpLp::_setRowCoeffs(int ix, ExprIterator b, ExprIterator e) {
145
    std::map<int, Value> coeffs;
146

	
147
    int n = _prob->clpMatrix()->getNumCols();
148

	
149
    const int* indices = _prob->clpMatrix()->getIndices();
150
    const double* elements = _prob->clpMatrix()->getElements();
151

	
152
    for (int i = 0; i < n; ++i) {
153
      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
154
      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
155

	
156
      const int* it = std::lower_bound(indices + begin, indices + end, ix);
157
      if (it != indices + end && *it == ix && elements[it - indices] != 0.0) {
158
        coeffs[i] = 0.0;
159
      }
160
    }
161

	
162
    for (ExprIterator it = b; it != e; ++it) {
163
      coeffs[it->first] = it->second;
164
    }
165

	
166
    for (std::map<int, Value>::iterator it = coeffs.begin();
167
         it != coeffs.end(); ++it) {
168
      _prob->modifyCoefficient(ix, it->first, it->second);
169
    }
170
  }
171

	
172
  void ClpLp::_getRowCoeffs(int ix, InsertIterator b) const {
173
    int n = _prob->clpMatrix()->getNumCols();
174

	
175
    const int* indices = _prob->clpMatrix()->getIndices();
176
    const double* elements = _prob->clpMatrix()->getElements();
177

	
178
    for (int i = 0; i < n; ++i) {
179
      CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[i];
180
      CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[i];
181

	
182
      const int* it = std::lower_bound(indices + begin, indices + end, ix);
183
      if (it != indices + end && *it == ix) {
184
        *b = std::make_pair(i, elements[it - indices]);
185
      }
186
    }
187
  }
188

	
189
  void ClpLp::_setColCoeffs(int ix, ExprIterator b, ExprIterator e) {
190
    std::map<int, Value> coeffs;
191

	
192
    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
193
    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
194

	
195
    const int* indices = _prob->clpMatrix()->getIndices();
196
    const double* elements = _prob->clpMatrix()->getElements();
197

	
198
    for (CoinBigIndex i = begin; i != end; ++i) {
199
      if (elements[i] != 0.0) {
200
        coeffs[indices[i]] = 0.0;
201
      }
202
    }
203
    for (ExprIterator it = b; it != e; ++it) {
204
      coeffs[it->first] = it->second;
205
    }
206
    for (std::map<int, Value>::iterator it = coeffs.begin();
207
         it != coeffs.end(); ++it) {
208
      _prob->modifyCoefficient(it->first, ix, it->second);
209
    }
210
  }
211

	
212
  void ClpLp::_getColCoeffs(int ix, InsertIterator b) const {
213
    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
214
    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
215

	
216
    const int* indices = _prob->clpMatrix()->getIndices();
217
    const double* elements = _prob->clpMatrix()->getElements();
218

	
219
    for (CoinBigIndex i = begin; i != end; ++i) {
220
      *b = std::make_pair(indices[i], elements[i]);
221
      ++b;
222
    }
223
  }
224

	
225
  void ClpLp::_setCoeff(int ix, int jx, Value value) {
226
    _prob->modifyCoefficient(ix, jx, value);
227
  }
228

	
229
  ClpLp::Value ClpLp::_getCoeff(int ix, int jx) const {
230
    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
231
    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
232

	
233
    const int* indices = _prob->clpMatrix()->getIndices();
234
    const double* elements = _prob->clpMatrix()->getElements();
235

	
236
    const int* it = std::lower_bound(indices + begin, indices + end, jx);
237
    if (it != indices + end && *it == jx) {
238
      return elements[it - indices];
239
    } else {
240
      return 0.0;
241
    }
242
  }
243

	
244
  void ClpLp::_setColLowerBound(int i, Value lo) {
245
    _prob->setColumnLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
246
  }
247

	
248
  ClpLp::Value ClpLp::_getColLowerBound(int i) const {
249
    double val = _prob->getColLower()[i];
250
    return val == - COIN_DBL_MAX ? - INF : val;
251
  }
252

	
253
  void ClpLp::_setColUpperBound(int i, Value up) {
254
    _prob->setColumnUpper(i, up == INF ? COIN_DBL_MAX : up);
255
  }
256

	
257
  ClpLp::Value ClpLp::_getColUpperBound(int i) const {
258
    double val = _prob->getColUpper()[i];
259
    return val == COIN_DBL_MAX ? INF : val;
260
  }
261

	
262
  void ClpLp::_setRowLowerBound(int i, Value lo) {
263
    _prob->setRowLower(i, lo == - INF ? - COIN_DBL_MAX : lo);
264
  }
265

	
266
  ClpLp::Value ClpLp::_getRowLowerBound(int i) const {
267
    double val = _prob->getRowLower()[i];
268
    return val == - COIN_DBL_MAX ? - INF : val;
269
  }
270

	
271
  void ClpLp::_setRowUpperBound(int i, Value up) {
272
    _prob->setRowUpper(i, up == INF ? COIN_DBL_MAX : up);
273
  }
274

	
275
  ClpLp::Value ClpLp::_getRowUpperBound(int i) const {
276
    double val = _prob->getRowUpper()[i];
277
    return val == COIN_DBL_MAX ? INF : val;
278
  }
279

	
280
  void ClpLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
281
    int num = _prob->clpMatrix()->getNumCols();
282
    for (int i = 0; i < num; ++i) {
283
      _prob->setObjectiveCoefficient(i, 0.0);
284
    }
285
    for (ExprIterator it = b; it != e; ++it) {
286
      _prob->setObjectiveCoefficient(it->first, it->second);
287
    }
288
  }
289

	
290
  void ClpLp::_getObjCoeffs(InsertIterator b) const {
291
    int num = _prob->clpMatrix()->getNumCols();
292
    for (int i = 0; i < num; ++i) {
293
      Value coef = _prob->getObjCoefficients()[i];
294
      if (coef != 0.0) {
295
        *b = std::make_pair(i, coef);
296
        ++b;
297
      }
298
    }
299
  }
300

	
301
  void ClpLp::_setObjCoeff(int i, Value obj_coef) {
302
    _prob->setObjectiveCoefficient(i, obj_coef);
303
  }
304

	
305
  ClpLp::Value ClpLp::_getObjCoeff(int i) const {
306
    return _prob->getObjCoefficients()[i];
307
  }
308

	
309
  ClpLp::SolveExitStatus ClpLp::_solve() {
310
    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
311
  }
312

	
313
  ClpLp::SolveExitStatus ClpLp::solvePrimal() {
314
    return _prob->primal() >= 0 ? SOLVED : UNSOLVED;
315
  }
316

	
317
  ClpLp::SolveExitStatus ClpLp::solveDual() {
318
    return _prob->dual() >= 0 ? SOLVED : UNSOLVED;
319
  }
320

	
321
  ClpLp::SolveExitStatus ClpLp::solveBarrier() {
322
    return _prob->barrier() >= 0 ? SOLVED : UNSOLVED;
323
  }
324

	
325
  ClpLp::Value ClpLp::_getPrimal(int i) const {
326
    return _prob->primalColumnSolution()[i];
327
  }
328
  ClpLp::Value ClpLp::_getPrimalValue() const {
329
    return _prob->objectiveValue();
330
  }
331

	
332
  ClpLp::Value ClpLp::_getDual(int i) const {
333
    return _prob->dualRowSolution()[i];
334
  }
335

	
336
  ClpLp::Value ClpLp::_getPrimalRay(int i) const {
337
    if (!_primal_ray) {
338
      _primal_ray = _prob->unboundedRay();
339
      LEMON_ASSERT(_primal_ray != 0, "Primal ray is not provided");
340
    }
341
    return _primal_ray[i];
342
  }
343

	
344
  ClpLp::Value ClpLp::_getDualRay(int i) const {
345
    if (!_dual_ray) {
346
      _dual_ray = _prob->infeasibilityRay();
347
      LEMON_ASSERT(_dual_ray != 0, "Dual ray is not provided");
348
    }
349
    return _dual_ray[i];
350
  }
351

	
352
  ClpLp::VarStatus ClpLp::_getColStatus(int i) const {
353
    switch (_prob->getColumnStatus(i)) {
354
    case ClpSimplex::basic:
355
      return BASIC;
356
    case ClpSimplex::isFree:
357
      return FREE;
358
    case ClpSimplex::atUpperBound:
359
      return UPPER;
360
    case ClpSimplex::atLowerBound:
361
      return LOWER;
362
    case ClpSimplex::isFixed:
363
      return FIXED;
364
    case ClpSimplex::superBasic:
365
      return FREE;
366
    default:
367
      LEMON_ASSERT(false, "Wrong column status");
368
      return VarStatus();
369
    }
370
  }
371

	
372
  ClpLp::VarStatus ClpLp::_getRowStatus(int i) const {
373
    switch (_prob->getColumnStatus(i)) {
374
    case ClpSimplex::basic:
375
      return BASIC;
376
    case ClpSimplex::isFree:
377
      return FREE;
378
    case ClpSimplex::atUpperBound:
379
      return UPPER;
380
    case ClpSimplex::atLowerBound:
381
      return LOWER;
382
    case ClpSimplex::isFixed:
383
      return FIXED;
384
    case ClpSimplex::superBasic:
385
      return FREE;
386
    default:
387
      LEMON_ASSERT(false, "Wrong row status");
388
      return VarStatus();
389
    }
390
  }
391

	
392

	
393
  ClpLp::ProblemType ClpLp::_getPrimalType() const {
394
    if (_prob->isProvenOptimal()) {
395
      return OPTIMAL;
396
    } else if (_prob->isProvenPrimalInfeasible()) {
397
      return INFEASIBLE;
398
    } else if (_prob->isProvenDualInfeasible()) {
399
      return UNBOUNDED;
400
    } else {
401
      return UNDEFINED;
402
    }
403
  }
404

	
405
  ClpLp::ProblemType ClpLp::_getDualType() const {
406
    if (_prob->isProvenOptimal()) {
407
      return OPTIMAL;
408
    } else if (_prob->isProvenDualInfeasible()) {
409
      return INFEASIBLE;
410
    } else if (_prob->isProvenPrimalInfeasible()) {
411
      return INFEASIBLE;
412
    } else {
413
      return UNDEFINED;
414
    }
415
  }
416

	
417
  void ClpLp::_setSense(ClpLp::Sense sense) {
418
    switch (sense) {
419
    case MIN:
420
      _prob->setOptimizationDirection(1);
421
      break;
422
    case MAX:
423
      _prob->setOptimizationDirection(-1);
424
      break;
425
    }
426
  }
427

	
428
  ClpLp::Sense ClpLp::_getSense() const {
429
    double dir = _prob->optimizationDirection();
430
    if (dir > 0.0) {
431
      return MIN;
432
    } else {
433
      return MAX;
434
    }
435
  }
436

	
437
  void ClpLp::_clear() {
438
    delete _prob;
439
    _prob = new ClpSimplex();
440
    rows.clear();
441
    cols.clear();
442
    _col_names_ref.clear();
443
    _clear_temporals();
444
  }
445

	
446
  void ClpLp::_messageLevel(MessageLevel level) {
447
    switch (level) {
448
    case MESSAGE_NOTHING:
449
      _prob->setLogLevel(0);
450
      break;
451
    case MESSAGE_ERROR:
452
      _prob->setLogLevel(1);
453
      break;
454
    case MESSAGE_WARNING:
455
      _prob->setLogLevel(2);
456
      break;
457
    case MESSAGE_NORMAL:
458
      _prob->setLogLevel(3);
459
      break;
460
    case MESSAGE_VERBOSE:
461
      _prob->setLogLevel(4);
462
      break;
463
    }
464
  }
465

	
466
} //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
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
79

	
80
    virtual void _eraseCol(int i);
81
    virtual void _eraseRow(int i);
82

	
83
    virtual void _eraseColId(int i);
84
    virtual void _eraseRowId(int i);
85

	
86
    virtual void _getColName(int col, std::string& name) const;
87
    virtual void _setColName(int col, const std::string& name);
88
    virtual int _colByName(const std::string& name) const;
89

	
90
    virtual void _getRowName(int row, std::string& name) const;
91
    virtual void _setRowName(int row, const std::string& name);
92
    virtual int _rowByName(const std::string& name) const;
93

	
94
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
95
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
96

	
97
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
98
    virtual void _getColCoeffs(int i, InsertIterator b) const;
99

	
100
    virtual void _setCoeff(int row, int col, Value value);
101
    virtual Value _getCoeff(int row, int col) const;
102

	
103
    virtual void _setColLowerBound(int i, Value value);
104
    virtual Value _getColLowerBound(int i) const;
105
    virtual void _setColUpperBound(int i, Value value);
106
    virtual Value _getColUpperBound(int i) const;
107

	
108
    virtual void _setRowLowerBound(int i, Value value);
109
    virtual Value _getRowLowerBound(int i) const;
110
    virtual void _setRowUpperBound(int i, Value value);
111
    virtual Value _getRowUpperBound(int i) const;
112

	
113
    virtual void _setObjCoeffs(ExprIterator, ExprIterator);
114
    virtual void _getObjCoeffs(InsertIterator) const;
115

	
116
    virtual void _setObjCoeff(int i, Value obj_coef);
117
    virtual Value _getObjCoeff(int i) const;
118

	
119
    virtual void _setSense(Sense sense);
120
    virtual Sense _getSense() const;
121

	
122
    virtual SolveExitStatus _solve();
123

	
124
    virtual Value _getPrimal(int i) const;
125
    virtual Value _getDual(int i) const;
126

	
127
    virtual Value _getPrimalValue() const;
128

	
129
    virtual Value _getPrimalRay(int i) const;
130
    virtual Value _getDualRay(int i) const;
131

	
132
    virtual VarStatus _getColStatus(int i) const;
133
    virtual VarStatus _getRowStatus(int i) const;
134

	
135
    virtual ProblemType _getPrimalType() const;
136
    virtual ProblemType _getDualType() const;
137

	
138
    virtual void _clear();
139

	
140
    virtual void _messageLevel(MessageLevel);
141
    
142
  public:
143

	
144
    ///Solves LP with primal simplex method.
145
    SolveExitStatus solvePrimal();
146

	
147
    ///Solves LP with dual simplex method.
148
    SolveExitStatus solveDual();
149

	
150
    ///Solves LP with barrier method.
151
    SolveExitStatus solveBarrier();
152

	
153
    ///Returns the constraint identifier understood by CLP.
154
    int clpRow(Row r) const { return rows(id(r)); }
155

	
156
    ///Returns the variable identifier understood by CLP.
157
    int clpCol(Col c) const { return cols(id(c)); }
158

	
159
  };
160

	
161
} //END OF NAMESPACE LEMON
162

	
163
#endif //LEMON_CLP_H
164

	
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
  int CplexBase::_addRow(Value lb, ExprIterator b, 
115
                         ExprIterator e, Value ub) {
116
    int i = CPXgetnumrows(cplexEnv(), _prob);
117
    if (lb == -INF) {
118
      const char s = 'L';
119
      CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
120
    } else if (ub == INF) {
121
      const char s = 'G';
122
      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
123
    } else if (lb == ub){
124
      const char s = 'E';
125
      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, 0, 0);
126
    } else {
127
      const char s = 'R';
128
      double len = ub - lb;
129
      CPXnewrows(cplexEnv(), _prob, 1, &lb, &s, &len, 0);
130
    }
131

	
132
    std::vector<int> indices;
133
    std::vector<int> rowlist;
134
    std::vector<Value> values;
135

	
136
    for(ExprIterator it=b; it!=e; ++it) {
137
      indices.push_back(it->first);
138
      values.push_back(it->second);
139
      rowlist.push_back(i);
140
    }
141

	
142
    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
143
                   &rowlist.front(), &indices.front(), &values.front());
144

	
145
    return i;
146
  }
147

	
148
  void CplexBase::_eraseCol(int i) {
149
    CPXdelcols(cplexEnv(), _prob, i, i);
150
  }
151

	
152
  void CplexBase::_eraseRow(int i) {
153
    CPXdelrows(cplexEnv(), _prob, i, i);
154
  }
155

	
156
  void CplexBase::_eraseColId(int i) {
157
    cols.eraseIndex(i);
158
    cols.shiftIndices(i);
159
  }
160
  void CplexBase::_eraseRowId(int i) {
161
    rows.eraseIndex(i);
162
    rows.shiftIndices(i);
163
  }
164

	
165
  void CplexBase::_getColName(int col, std::string &name) const {
166
    int size;
167
    CPXgetcolname(cplexEnv(), _prob, 0, 0, 0, &size, col, col);
168
    if (size == 0) {
169
      name.clear();
170
      return;
171
    }
172

	
173
    size *= -1;
174
    std::vector<char> buf(size);
175
    char *cname;
176
    int tmp;
177
    CPXgetcolname(cplexEnv(), _prob, &cname, &buf.front(), size,
178
                  &tmp, col, col);
179
    name = cname;
180
  }
181

	
182
  void CplexBase::_setColName(int col, const std::string &name) {
183
    char *cname;
184
    cname = const_cast<char*>(name.c_str());
185
    CPXchgcolname(cplexEnv(), _prob, 1, &col, &cname);
186
  }
187

	
188
  int CplexBase::_colByName(const std::string& name) const {
189
    int index;
190
    if (CPXgetcolindex(cplexEnv(), _prob,
191
                       const_cast<char*>(name.c_str()), &index) == 0) {
192
      return index;
193
    }
194
    return -1;
195
  }
196

	
197
  void CplexBase::_getRowName(int row, std::string &name) const {
198
    int size;
199
    CPXgetrowname(cplexEnv(), _prob, 0, 0, 0, &size, row, row);
200
    if (size == 0) {
201
      name.clear();
202
      return;
203
    }
204

	
205
    size *= -1;
206
    std::vector<char> buf(size);
207
    char *cname;
208
    int tmp;
209
    CPXgetrowname(cplexEnv(), _prob, &cname, &buf.front(), size,
210
                  &tmp, row, row);
211
    name = cname;
212
  }
213

	
214
  void CplexBase::_setRowName(int row, const std::string &name) {
215
    char *cname;
216
    cname = const_cast<char*>(name.c_str());
217
    CPXchgrowname(cplexEnv(), _prob, 1, &row, &cname);
218
  }
219

	
220
  int CplexBase::_rowByName(const std::string& name) const {
221
    int index;
222
    if (CPXgetrowindex(cplexEnv(), _prob,
223
                       const_cast<char*>(name.c_str()), &index) == 0) {
224
      return index;
225
    }
226
    return -1;
227
  }
228

	
229
  void CplexBase::_setRowCoeffs(int i, ExprIterator b,
230
                                      ExprIterator e)
231
  {
232
    std::vector<int> indices;
233
    std::vector<int> rowlist;
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
      rowlist.push_back(i);
240
    }
241

	
242
    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
243
                   &rowlist.front(), &indices.front(), &values.front());
244
  }
245

	
246
  void CplexBase::_getRowCoeffs(int i, InsertIterator b) const {
247
    int tmp1, tmp2, tmp3, length;
248
    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
249

	
250
    length = -length;
251
    std::vector<int> indices(length);
252
    std::vector<double> values(length);
253

	
254
    CPXgetrows(cplexEnv(), _prob, &tmp1, &tmp2,
255
               &indices.front(), &values.front(),
256
               length, &tmp3, i, i);
257

	
258
    for (int i = 0; i < length; ++i) {
259
      *b = std::make_pair(indices[i], values[i]);
260
      ++b;
261
    }
262
  }
263

	
264
  void CplexBase::_setColCoeffs(int i, ExprIterator b, ExprIterator e) {
265
    std::vector<int> indices;
266
    std::vector<int> collist;
267
    std::vector<Value> values;
268

	
269
    for(ExprIterator it=b; it!=e; ++it) {
270
      indices.push_back(it->first);
271
      values.push_back(it->second);
272
      collist.push_back(i);
273
    }
274

	
275
    CPXchgcoeflist(cplexEnv(), _prob, values.size(),
276
                   &indices.front(), &collist.front(), &values.front());
277
  }
278

	
279
  void CplexBase::_getColCoeffs(int i, InsertIterator b) const {
280

	
281
    int tmp1, tmp2, tmp3, length;
282
    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
283

	
284
    length = -length;
285
    std::vector<int> indices(length);
286
    std::vector<double> values(length);
287

	
288
    CPXgetcols(cplexEnv(), _prob, &tmp1, &tmp2,
289
               &indices.front(), &values.front(),
290
               length, &tmp3, i, i);
291

	
292
    for (int i = 0; i < length; ++i) {
293
      *b = std::make_pair(indices[i], values[i]);
294
      ++b;
295
    }
296

	
297
  }
298

	
299
  void CplexBase::_setCoeff(int row, int col, Value value) {
300
    CPXchgcoef(cplexEnv(), _prob, row, col, value);
301
  }
302

	
303
  CplexBase::Value CplexBase::_getCoeff(int row, int col) const {
304
    CplexBase::Value value;
305
    CPXgetcoef(cplexEnv(), _prob, row, col, &value);
306
    return value;
307
  }
308

	
309
  void CplexBase::_setColLowerBound(int i, Value value) {
310
    const char s = 'L';
311
    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
312
  }
313

	
314
  CplexBase::Value CplexBase::_getColLowerBound(int i) const {
315
    CplexBase::Value res;
316
    CPXgetlb(cplexEnv(), _prob, &res, i, i);
317
    return res <= -CPX_INFBOUND ? -INF : res;
318
  }
319

	
320
  void CplexBase::_setColUpperBound(int i, Value value)
321
  {
322
    const char s = 'U';
323
    CPXchgbds(cplexEnv(), _prob, 1, &i, &s, &value);
324
  }
325

	
326
  CplexBase::Value CplexBase::_getColUpperBound(int i) const {
327
    CplexBase::Value res;
328
    CPXgetub(cplexEnv(), _prob, &res, i, i);
329
    return res >= CPX_INFBOUND ? INF : res;
330
  }
331

	
332
  CplexBase::Value CplexBase::_getRowLowerBound(int i) const {
333
    char s;
334
    CPXgetsense(cplexEnv(), _prob, &s, i, i);
335
    CplexBase::Value res;
336

	
337
    switch (s) {
338
    case 'G':
339
    case 'R':
340
    case 'E':
341
      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
342
      return res <= -CPX_INFBOUND ? -INF : res;
343
    default:
344
      return -INF;
345
    }
346
  }
347

	
348
  CplexBase::Value CplexBase::_getRowUpperBound(int i) const {
349
    char s;
350
    CPXgetsense(cplexEnv(), _prob, &s, i, i);
351
    CplexBase::Value res;
352

	
353
    switch (s) {
354
    case 'L':
355
    case 'E':
356
      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
357
      return res >= CPX_INFBOUND ? INF : res;
358
    case 'R':
359
      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
360
      {
361
        double rng;
362
        CPXgetrngval(cplexEnv(), _prob, &rng, i, i);
363
        res += rng;
364
      }
365
      return res >= CPX_INFBOUND ? INF : res;
366
    default:
367
      return INF;
368
    }
369
  }
370

	
371
  //This is easier to implement
372
  void CplexBase::_set_row_bounds(int i, Value lb, Value ub) {
373
    if (lb == -INF) {
374
      const char s = 'L';
375
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
376
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &ub);
377
    } else if (ub == INF) {
378
      const char s = 'G';
379
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
380
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
381
    } else if (lb == ub){
382
      const char s = 'E';
383
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
384
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
385
    } else {
386
      const char s = 'R';
387
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
388
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
389
      double len = ub - lb;
390
      CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
391
    }
392
  }
393

	
394
  void CplexBase::_setRowLowerBound(int i, Value lb)
395
  {
396
    LEMON_ASSERT(lb != INF, "Invalid bound");
397
    _set_row_bounds(i, lb, CplexBase::_getRowUpperBound(i));
398
  }
399

	
400
  void CplexBase::_setRowUpperBound(int i, Value ub)
401
  {
402

	
403
    LEMON_ASSERT(ub != -INF, "Invalid bound");
404
    _set_row_bounds(i, CplexBase::_getRowLowerBound(i), ub);
405
  }
406

	
407
  void CplexBase::_setObjCoeffs(ExprIterator b, ExprIterator e)
408
  {
409
    std::vector<int> indices;
410
    std::vector<Value> values;
411
    for(ExprIterator it=b; it!=e; ++it) {
412
      indices.push_back(it->first);
413
      values.push_back(it->second);
414
    }
415
    CPXchgobj(cplexEnv(), _prob, values.size(),
416
              &indices.front(), &values.front());
417

	
418
  }
419

	
420
  void CplexBase::_getObjCoeffs(InsertIterator b) const
421
  {
422
    int num = CPXgetnumcols(cplexEnv(), _prob);
423
    std::vector<Value> x(num);
424

	
425
    CPXgetobj(cplexEnv(), _prob, &x.front(), 0, num - 1);
426
    for (int i = 0; i < num; ++i) {
427
      if (x[i] != 0.0) {
428
        *b = std::make_pair(i, x[i]);
429
        ++b;
430
      }
431
    }
432
  }
433

	
434
  void CplexBase::_setObjCoeff(int i, Value obj_coef)
435
  {
436
    CPXchgobj(cplexEnv(), _prob, 1, &i, &obj_coef);
437
  }
438

	
439
  CplexBase::Value CplexBase::_getObjCoeff(int i) const
440
  {
441
    Value x;
442
    CPXgetobj(cplexEnv(), _prob, &x, i, i);
443
    return x;
444
  }
445

	
446
  void CplexBase::_setSense(CplexBase::Sense sense) {
447
    switch (sense) {
448
    case MIN:
449
      CPXchgobjsen(cplexEnv(), _prob, CPX_MIN);
450
      break;
451
    case MAX:
452
      CPXchgobjsen(cplexEnv(), _prob, CPX_MAX);
453
      break;
454
    }
455
  }
456

	
457
  CplexBase::Sense CplexBase::_getSense() const {
458
    switch (CPXgetobjsen(cplexEnv(), _prob)) {
459
    case CPX_MIN:
460
      return MIN;
461
    case CPX_MAX:
462
      return MAX;
463
    default:
464
      LEMON_ASSERT(false, "Invalid sense");
465
      return CplexBase::Sense();
466
    }
467
  }
468

	
469
  void CplexBase::_clear() {
470
    CPXfreeprob(cplexEnv(),&_prob);
471
    int status;
472
    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
473
    rows.clear();
474
    cols.clear();
475
  }
476

	
477
  void CplexBase::_messageLevel(MessageLevel level) {
478
    switch (level) {
479
    case MESSAGE_NOTHING:
480
      _message_enabled = false;
481
      break;
482
    case MESSAGE_ERROR:
483
    case MESSAGE_WARNING:
484
    case MESSAGE_NORMAL:
485
    case MESSAGE_VERBOSE:
486
      _message_enabled = true;
487
      break;
488
    }
489
  }
490

	
491
  void CplexBase::_applyMessageLevel() {
492
    CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND, 
493
                   _message_enabled ? CPX_ON : CPX_OFF);
494
  }
495

	
496
  // CplexLp members
497

	
498
  CplexLp::CplexLp()
499
    : LpBase(), LpSolver(), CplexBase() {}
500

	
501
  CplexLp::CplexLp(const CplexEnv& env)
502
    : LpBase(), LpSolver(), CplexBase(env) {}
503

	
504
  CplexLp::CplexLp(const CplexLp& other)
505
    : LpBase(), LpSolver(), CplexBase(other) {}
506

	
507
  CplexLp::~CplexLp() {}
508

	
509
  CplexLp* CplexLp::newSolver() const { return new CplexLp; }
510
  CplexLp* CplexLp::cloneSolver() const {return new CplexLp(*this); }
511

	
512
  const char* CplexLp::_solverName() const { return "CplexLp"; }
513

	
514
  void CplexLp::_clear_temporals() {
515
    _col_status.clear();
516
    _row_status.clear();
517
    _primal_ray.clear();
518
    _dual_ray.clear();
519
  }
520

	
521
  // The routine returns zero unless an error occurred during the
522
  // optimization. Examples of errors include exhausting available
523
  // memory (CPXERR_NO_MEMORY) or encountering invalid data in the
524
  // CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a
525
  // user-specified CPLEX limit, or proving the model infeasible or
526
  // unbounded, are not considered errors. Note that a zero return
527
  // value does not necessarily mean that a solution exists. Use query
528
  // routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain
529
  // further information about the status of the optimization.
530
  CplexLp::SolveExitStatus CplexLp::convertStatus(int status) {
531
#if CPX_VERSION >= 800
532
    if (status == 0) {
533
      switch (CPXgetstat(cplexEnv(), _prob)) {
534
      case CPX_STAT_OPTIMAL:
535
      case CPX_STAT_INFEASIBLE:
536
      case CPX_STAT_UNBOUNDED:
537
        return SOLVED;
538
      default:
539
        return UNSOLVED;
540
      }
541
    } else {
542
      return UNSOLVED;
543
    }
544
#else
545
    if (status == 0) {
546
      //We want to exclude some cases
547
      switch (CPXgetstat(cplexEnv(), _prob)) {
548
      case CPX_OBJ_LIM:
549
      case CPX_IT_LIM_FEAS:
550
      case CPX_IT_LIM_INFEAS:
551
      case CPX_TIME_LIM_FEAS:
552
      case CPX_TIME_LIM_INFEAS:
553
        return UNSOLVED;
554
      default:
555
        return SOLVED;
556
      }
557
    } else {
558
      return UNSOLVED;
559
    }
560
#endif
561
  }
562

	
563
  CplexLp::SolveExitStatus CplexLp::_solve() {
564
    _clear_temporals();
565
    _applyMessageLevel();
566
    return convertStatus(CPXlpopt(cplexEnv(), _prob));
567
  }
568

	
569
  CplexLp::SolveExitStatus CplexLp::solvePrimal() {
570
    _clear_temporals();
571
    _applyMessageLevel();
572
    return convertStatus(CPXprimopt(cplexEnv(), _prob));
573
  }
574

	
575
  CplexLp::SolveExitStatus CplexLp::solveDual() {
576
    _clear_temporals();
577
    _applyMessageLevel();
578
    return convertStatus(CPXdualopt(cplexEnv(), _prob));
579
  }
580

	
581
  CplexLp::SolveExitStatus CplexLp::solveBarrier() {
582
    _clear_temporals();
583
    _applyMessageLevel();
584
    return convertStatus(CPXbaropt(cplexEnv(), _prob));
585
  }
586

	
587
  CplexLp::Value CplexLp::_getPrimal(int i) const {
588
    Value x;
589
    CPXgetx(cplexEnv(), _prob, &x, i, i);
590
    return x;
591
  }
592

	
593
  CplexLp::Value CplexLp::_getDual(int i) const {
594
    Value y;
595
    CPXgetpi(cplexEnv(), _prob, &y, i, i);
596
    return y;
597
  }
598

	
599
  CplexLp::Value CplexLp::_getPrimalValue() const {
600
    Value objval;
601
    CPXgetobjval(cplexEnv(), _prob, &objval);
602
    return objval;
603
  }
604

	
605
  CplexLp::VarStatus CplexLp::_getColStatus(int i) const {
606
    if (_col_status.empty()) {
607
      _col_status.resize(CPXgetnumcols(cplexEnv(), _prob));
608
      CPXgetbase(cplexEnv(), _prob, &_col_status.front(), 0);
609
    }
610
    switch (_col_status[i]) {
611
    case CPX_BASIC:
612
      return BASIC;
613
    case CPX_FREE_SUPER:
614
      return FREE;
615
    case CPX_AT_LOWER:
616
      return LOWER;
617
    case CPX_AT_UPPER:
618
      return UPPER;
619
    default:
620
      LEMON_ASSERT(false, "Wrong column status");
621
      return CplexLp::VarStatus();
622
    }
623
  }
624

	
625
  CplexLp::VarStatus CplexLp::_getRowStatus(int i) const {
626
    if (_row_status.empty()) {
627
      _row_status.resize(CPXgetnumrows(cplexEnv(), _prob));
628
      CPXgetbase(cplexEnv(), _prob, 0, &_row_status.front());
629
    }
630
    switch (_row_status[i]) {
631
    case CPX_BASIC:
632
      return BASIC;
633
    case CPX_AT_LOWER:
634
      {
635
        char s;
636
        CPXgetsense(cplexEnv(), _prob, &s, i, i);
637
        return s != 'L' ? LOWER : UPPER;
638
      }
639
    case CPX_AT_UPPER:
640
      return UPPER;
641
    default:
642
      LEMON_ASSERT(false, "Wrong row status");
643
      return CplexLp::VarStatus();
644
    }
645
  }
646

	
647
  CplexLp::Value CplexLp::_getPrimalRay(int i) const {
648
    if (_primal_ray.empty()) {
649
      _primal_ray.resize(CPXgetnumcols(cplexEnv(), _prob));
650
      CPXgetray(cplexEnv(), _prob, &_primal_ray.front());
651
    }
652
    return _primal_ray[i];
653
  }
654

	
655
  CplexLp::Value CplexLp::_getDualRay(int i) const {
656
    if (_dual_ray.empty()) {
657

	
658
    }
659
    return _dual_ray[i];
660
  }
661

	
662
  // Cplex 7.0 status values
663
  // This table lists the statuses, returned by the CPXgetstat()
664
  // routine, for solutions to LP problems or mixed integer problems. If
665
  // no solution exists, the return value is zero.
666

	
667
  // For Simplex, Barrier
668
  // 1          CPX_OPTIMAL
669
  //          Optimal solution found
670
  // 2          CPX_INFEASIBLE
671
  //          Problem infeasible
672
  // 3    CPX_UNBOUNDED
673
  //          Problem unbounded
674
  // 4          CPX_OBJ_LIM
675
  //          Objective limit exceeded in Phase II
676
  // 5          CPX_IT_LIM_FEAS
677
  //          Iteration limit exceeded in Phase II
678
  // 6          CPX_IT_LIM_INFEAS
679
  //          Iteration limit exceeded in Phase I
680
  // 7          CPX_TIME_LIM_FEAS
681
  //          Time limit exceeded in Phase II
682
  // 8          CPX_TIME_LIM_INFEAS
683
  //          Time limit exceeded in Phase I
684
  // 9          CPX_NUM_BEST_FEAS
685
  //          Problem non-optimal, singularities in Phase II
686
  // 10         CPX_NUM_BEST_INFEAS
687
  //          Problem non-optimal, singularities in Phase I
688
  // 11         CPX_OPTIMAL_INFEAS
689
  //          Optimal solution found, unscaled infeasibilities
690
  // 12         CPX_ABORT_FEAS
691
  //          Aborted in Phase II
692
  // 13         CPX_ABORT_INFEAS
693
  //          Aborted in Phase I
694
  // 14          CPX_ABORT_DUAL_INFEAS
695
  //          Aborted in barrier, dual infeasible
696
  // 15          CPX_ABORT_PRIM_INFEAS
697
  //          Aborted in barrier, primal infeasible
698
  // 16          CPX_ABORT_PRIM_DUAL_INFEAS
699
  //          Aborted in barrier, primal and dual infeasible
700
  // 17          CPX_ABORT_PRIM_DUAL_FEAS
701
  //          Aborted in barrier, primal and dual feasible
702
  // 18          CPX_ABORT_CROSSOVER
703
  //          Aborted in crossover
704
  // 19          CPX_INForUNBD
705
  //          Infeasible or unbounded
706
  // 20   CPX_PIVOT
707
  //       User pivot used
708
  //
709
  // Pending return values
710
  // ??case CPX_ABORT_DUAL_INFEAS
711
  // ??case CPX_ABORT_CROSSOVER
712
  // ??case CPX_INForUNBD
713
  // ??case CPX_PIVOT
714

	
715
  //Some more interesting stuff:
716

	
717
  // CPX_PARAM_PROBMETHOD  1062  int  LPMETHOD
718
  // 0 Automatic
719
  // 1 Primal Simplex
720
  // 2 Dual Simplex
721
  // 3 Network Simplex
722
  // 4 Standard Barrier
723
  // Default: 0
724
  // Description: Method for linear optimization.
725
  // Determines which algorithm is used when CPXlpopt() (or "optimize"
726
  // in the Interactive Optimizer) is called. Currently the behavior of
727
  // the "Automatic" setting is that CPLEX simply invokes the dual
728
  // simplex method, but this capability may be expanded in the future
729
  // so that CPLEX chooses the method based on problem characteristics
730
#if CPX_VERSION < 900
731
  void statusSwitch(CPXENVptr cplexEnv(),int& stat){
732
    int lpmethod;
733
    CPXgetintparam (cplexEnv(),CPX_PARAM_PROBMETHOD,&lpmethod);
734
    if (lpmethod==2){
735
      if (stat==CPX_UNBOUNDED){
736
        stat=CPX_INFEASIBLE;
737
      }
738
      else{
739
        if (stat==CPX_INFEASIBLE)
740
          stat=CPX_UNBOUNDED;
741
      }
742
    }
743
  }
744
#else
745
  void statusSwitch(CPXENVptr,int&){}
746
#endif
747

	
748
  CplexLp::ProblemType CplexLp::_getPrimalType() const {
749
    // Unboundedness not treated well: the following is from cplex 9.0 doc
750
    // About Unboundedness
751

	
752
    // The treatment of models that are unbounded involves a few
753
    // subtleties. Specifically, a declaration of unboundedness means that
754
    // ILOG CPLEX has determined that the model has an unbounded
755
    // ray. Given any feasible solution x with objective z, a multiple of
756
    // the unbounded ray can be added to x to give a feasible solution
757
    // with objective z-1 (or z+1 for maximization models). Thus, if a
758
    // feasible solution exists, then the optimal objective is
759
    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
760
    // a feasible solution exists. Users can call the routine CPXsolninfo
761
    // to determine whether ILOG CPLEX has also concluded that the model
762
    // has a feasible solution.
763

	
764
    int stat = CPXgetstat(cplexEnv(), _prob);
765
#if CPX_VERSION >= 800
766
    switch (stat)
767
      {
768
      case CPX_STAT_OPTIMAL:
769
        return OPTIMAL;
770
      case CPX_STAT_UNBOUNDED:
771
        return UNBOUNDED;
772
      case CPX_STAT_INFEASIBLE:
773
        return INFEASIBLE;
774
      default:
775
        return UNDEFINED;
776
      }
777
#else
778
    statusSwitch(cplexEnv(),stat);
779
    //CPXgetstat(cplexEnv(), _prob);
780
    switch (stat) {
781
    case 0:
782
      return UNDEFINED; //Undefined
783
    case CPX_OPTIMAL://Optimal
784
      return OPTIMAL;
785
    case CPX_UNBOUNDED://Unbounded
786
      return INFEASIBLE;//In case of dual simplex
787
      //return UNBOUNDED;
788
    case CPX_INFEASIBLE://Infeasible
789
      //    case CPX_IT_LIM_INFEAS:
790
      //     case CPX_TIME_LIM_INFEAS:
791
      //     case CPX_NUM_BEST_INFEAS:
792
      //     case CPX_OPTIMAL_INFEAS:
793
      //     case CPX_ABORT_INFEAS:
794
      //     case CPX_ABORT_PRIM_INFEAS:
795
      //     case CPX_ABORT_PRIM_DUAL_INFEAS:
796
      return UNBOUNDED;//In case of dual simplex
797
      //return INFEASIBLE;
798
      //     case CPX_OBJ_LIM:
799
      //     case CPX_IT_LIM_FEAS:
800
      //     case CPX_TIME_LIM_FEAS:
801
      //     case CPX_NUM_BEST_FEAS:
802
      //     case CPX_ABORT_FEAS:
803
      //     case CPX_ABORT_PRIM_DUAL_FEAS:
804
      //       return FEASIBLE;
805
    default:
806
      return UNDEFINED; //Everything else comes here
807
      //FIXME error
808
    }
809
#endif
810
  }
811

	
812
  // Cplex 9.0 status values
813
  // CPX_STAT_ABORT_DUAL_OBJ_LIM
814
  // CPX_STAT_ABORT_IT_LIM
815
  // CPX_STAT_ABORT_OBJ_LIM
816
  // CPX_STAT_ABORT_PRIM_OBJ_LIM
817
  // CPX_STAT_ABORT_TIME_LIM
818
  // CPX_STAT_ABORT_USER
819
  // CPX_STAT_FEASIBLE_RELAXED
820
  // CPX_STAT_INFEASIBLE
821
  // CPX_STAT_INForUNBD
822
  // CPX_STAT_NUM_BEST
823
  // CPX_STAT_OPTIMAL
824
  // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
825
  // CPX_STAT_OPTIMAL_INFEAS
826
  // CPX_STAT_OPTIMAL_RELAXED
827
  // CPX_STAT_UNBOUNDED
828

	
829
  CplexLp::ProblemType CplexLp::_getDualType() const {
830
    int stat = CPXgetstat(cplexEnv(), _prob);
831
#if CPX_VERSION >= 800
832
    switch (stat) {
833
    case CPX_STAT_OPTIMAL:
834
      return OPTIMAL;
835
    case CPX_STAT_UNBOUNDED:
836
      return INFEASIBLE;
837
    default:
838
      return UNDEFINED;
839
    }
840
#else
841
    statusSwitch(cplexEnv(),stat);
842
    switch (stat) {
843
    case 0:
844
      return UNDEFINED; //Undefined
845
    case CPX_OPTIMAL://Optimal
846
      return OPTIMAL;
847
    case CPX_UNBOUNDED:
848
      return INFEASIBLE;
849
    default:
850
      return UNDEFINED; //Everything else comes here
851
      //FIXME error
852
    }
853
#endif
854
  }
855

	
856
  // CplexMip members
857

	
858
  CplexMip::CplexMip()
859
    : LpBase(), MipSolver(), CplexBase() {
860

	
861
#if CPX_VERSION < 800
862
    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
863
#else
864
    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
865
#endif
866
  }
867

	
868
  CplexMip::CplexMip(const CplexEnv& env)
869
    : LpBase(), MipSolver(), CplexBase(env) {
870

	
871
#if CPX_VERSION < 800
872
    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
873
#else
874
    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
875
#endif
876

	
877
  }
878

	
879
  CplexMip::CplexMip(const CplexMip& other)
880
    : LpBase(), MipSolver(), CplexBase(other) {}
881

	
882
  CplexMip::~CplexMip() {}
883

	
884
  CplexMip* CplexMip::newSolver() const { return new CplexMip; }
885
  CplexMip* CplexMip::cloneSolver() const {return new CplexMip(*this); }
886

	
887
  const char* CplexMip::_solverName() const { return "CplexMip"; }
888

	
889
  void CplexMip::_setColType(int i, CplexMip::ColTypes col_type) {
890

	
891
    // Note If a variable is to be changed to binary, a call to CPXchgbds
892
    // should also be made to change the bounds to 0 and 1.
893

	
894
    switch (col_type){
895
    case INTEGER: {
896
      const char t = 'I';
897
      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
898
    } break;
899
    case REAL: {
900
      const char t = 'C';
901
      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
902
    } break;
903
    default:
904
      break;
905
    }
906
  }
907

	
908
  CplexMip::ColTypes CplexMip::_getColType(int i) const {
909
    char t;
910
    CPXgetctype (cplexEnv(), _prob, &t, i, i);
911
    switch (t) {
912
    case 'I':
913
      return INTEGER;
914
    case 'C':
915
      return REAL;
916
    default:
917
      LEMON_ASSERT(false, "Invalid column type");
918
      return ColTypes();
919
    }
920

	
921
  }
922

	
923
  CplexMip::SolveExitStatus CplexMip::_solve() {
924
    int status;
925
    _applyMessageLevel();
926
    status = CPXmipopt (cplexEnv(), _prob);
927
    if (status==0)
928
      return SOLVED;
929
    else
930
      return UNSOLVED;
931

	
932
  }
933

	
934

	
935
  CplexMip::ProblemType CplexMip::_getType() const {
936

	
937
    int stat = CPXgetstat(cplexEnv(), _prob);
938

	
939
    //Fortunately, MIP statuses did not change for cplex 8.0
940
    switch (stat) {
941
    case CPXMIP_OPTIMAL:
942
      // Optimal integer solution has been found.
943
    case CPXMIP_OPTIMAL_TOL:
944
      // Optimal soluton with the tolerance defined by epgap or epagap has
945
      // been found.
946
      return OPTIMAL;
947
      //This also exists in later issues
948
      //    case CPXMIP_UNBOUNDED:
949
      //return UNBOUNDED;
950
      case CPXMIP_INFEASIBLE:
951
        return INFEASIBLE;
952
    default:
953
      return UNDEFINED;
954
    }
955
    //Unboundedness not treated well: the following is from cplex 9.0 doc
956
    // About Unboundedness
957

	
958
    // The treatment of models that are unbounded involves a few
959
    // subtleties. Specifically, a declaration of unboundedness means that
960
    // ILOG CPLEX has determined that the model has an unbounded
961
    // ray. Given any feasible solution x with objective z, a multiple of
962
    // the unbounded ray can be added to x to give a feasible solution
963
    // with objective z-1 (or z+1 for maximization models). Thus, if a
964
    // feasible solution exists, then the optimal objective is
965
    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
966
    // a feasible solution exists. Users can call the routine CPXsolninfo
967
    // to determine whether ILOG CPLEX has also concluded that the model
968
    // has a feasible solution.
969
  }
970

	
971
  CplexMip::Value CplexMip::_getSol(int i) const {
972
    Value x;
973
    CPXgetmipx(cplexEnv(), _prob, &x, i, i);
974
    return x;
975
  }
976

	
977
  CplexMip::Value CplexMip::_getSolValue() const {
978
    Value objval;
979
    CPXgetmipobjval(cplexEnv(), _prob, &objval);
980
    return objval;
981
  }
982

	
983
} //namespace lemon
984

	
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
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
97

	
98
    virtual void _eraseCol(int i);
99
    virtual void _eraseRow(int i);
100

	
101
    virtual void _eraseColId(int i);
102
    virtual void _eraseRowId(int i);
103

	
104
    virtual void _getColName(int col, std::string& name) const;
105
    virtual void _setColName(int col, const std::string& name);
106
    virtual int _colByName(const std::string& name) const;
107

	
108
    virtual void _getRowName(int row, std::string& name) const;
109
    virtual void _setRowName(int row, const std::string& name);
110
    virtual int _rowByName(const std::string& name) const;
111

	
112
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
113
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
114

	
115
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
116
    virtual void _getColCoeffs(int i, InsertIterator b) const;
117

	
118
    virtual void _setCoeff(int row, int col, Value value);
119
    virtual Value _getCoeff(int row, int col) const;
120

	
121
    virtual void _setColLowerBound(int i, Value value);
122
    virtual Value _getColLowerBound(int i) const;
123

	
124
    virtual void _setColUpperBound(int i, Value value);
125
    virtual Value _getColUpperBound(int i) const;
126

	
127
  private:
128
    void _set_row_bounds(int i, Value lb, Value ub);
129
  protected:
130

	
131
    virtual void _setRowLowerBound(int i, Value value);
132
    virtual Value _getRowLowerBound(int i) const;
133

	
134
    virtual void _setRowUpperBound(int i, Value value);
135
    virtual Value _getRowUpperBound(int i) const;
136

	
137
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
138
    virtual void _getObjCoeffs(InsertIterator b) const;
139

	
140
    virtual void _setObjCoeff(int i, Value obj_coef);
141
    virtual Value _getObjCoeff(int i) const;
142

	
143
    virtual void _setSense(Sense sense);
144
    virtual Sense _getSense() const;
145

	
146
    virtual void _clear();
147

	
148
    virtual void _messageLevel(MessageLevel level);
149
    void _applyMessageLevel();
150

	
151
    bool _message_enabled;
152

	
153
  public:
154

	
155
    /// Returns the used \c CplexEnv instance
156
    const CplexEnv& env() const { return _env; }
157

	
158
    /// \brief Returns the const cpxenv pointer
159
    ///
160
    /// \note The cpxenv might be destructed with the solver.
161
    const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
162

	
163
    /// \brief Returns the const cpxenv pointer
164
    ///
165
    /// \note The cpxenv might be destructed with the solver.
166
    cpxenv* cplexEnv() { return _env.cplexEnv(); }
167

	
168
    /// Returns the cplex problem object
169
    cpxlp* cplexLp() { return _prob; }
170
    /// Returns the cplex problem object
171
    const cpxlp* cplexLp() const { return _prob; }
172

	
173
  };
174

	
175
  /// \brief Interface for the CPLEX LP solver
176
  ///
177
  /// This class implements an interface for the CPLEX LP solver.
178
  ///\ingroup lp_group
179
  class CplexLp : public LpSolver, public CplexBase {
180
  public:
181
    /// \e
182
    CplexLp();
183
    /// \e
184
    CplexLp(const CplexEnv&);
185
    /// \e
186
    CplexLp(const CplexLp&);
187
    /// \e
188
    virtual ~CplexLp();
189

	
190
    /// \e
191
    virtual CplexLp* cloneSolver() const;
192
    /// \e
193
    virtual CplexLp* newSolver() const;
194

	
195
  private:
196

	
197
    // these values cannot retrieved element by element
198
    mutable std::vector<int> _col_status;
199
    mutable std::vector<int> _row_status;
200

	
201
    mutable std::vector<Value> _primal_ray;
202
    mutable std::vector<Value> _dual_ray;
203

	
204
    void _clear_temporals();
205

	
206
    SolveExitStatus convertStatus(int status);
207

	
208
  protected:
209

	
210
    virtual const char* _solverName() const;
211

	
212
    virtual SolveExitStatus _solve();
213
    virtual Value _getPrimal(int i) const;
214
    virtual Value _getDual(int i) const;
215
    virtual Value _getPrimalValue() const;
216

	
217
    virtual VarStatus _getColStatus(int i) const;
218
    virtual VarStatus _getRowStatus(int i) const;
219

	
220
    virtual Value _getPrimalRay(int i) const;
221
    virtual Value _getDualRay(int i) const;
222

	
223
    virtual ProblemType _getPrimalType() const;
224
    virtual ProblemType _getDualType() const;
225

	
226
  public:
227

	
228
    /// Solve with primal simplex method
229
    SolveExitStatus solvePrimal();
230

	
231
    /// Solve with dual simplex method
232
    SolveExitStatus solveDual();
233

	
234
    /// Solve with barrier method
235
    SolveExitStatus solveBarrier();
236

	
237
  };
238

	
239
  /// \brief Interface for the CPLEX MIP solver
240
  ///
241
  /// This class implements an interface for the CPLEX MIP solver.
242
  ///\ingroup lp_group
243
  class CplexMip : public MipSolver, public CplexBase {
244
  public:
245
    /// \e
246
    CplexMip();
247
    /// \e
248
    CplexMip(const CplexEnv&);
249
    /// \e
250
    CplexMip(const CplexMip&);
251
    /// \e
252
    virtual ~CplexMip();
253

	
254
    /// \e
255
    virtual CplexMip* cloneSolver() const;
256
    /// \e
257
    virtual CplexMip* newSolver() const;
258

	
259
  protected:
260

	
261

	
262
    virtual const char* _solverName() const;
263

	
264
    virtual ColTypes _getColType(int col) const;
265
    virtual void _setColType(int col, ColTypes col_type);
266

	
267
    virtual SolveExitStatus _solve();
268
    virtual ProblemType _getType() const;
269
    virtual Value _getSol(int i) const;
270
    virtual Value _getSolValue() const;
271

	
272
  };
273

	
274
} //END OF NAMESPACE LEMON
275

	
276
#endif //LEMON_CPLEX_H
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
#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
    static void next(Arc& arc) {
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
    static void next(Arc& arc) {
1177
      --arc.id;
1178
    }
1179

	
1180
    void first(Edge& arc) const {
1181
      arc.id = arcs.size() / 2 - 1;
1182
    }
1183

	
1184
    static void next(Edge& arc) {
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 heaps
24
///\brief Fibonacci heap implementation.
25

	
26
#include <vector>
27
#include <utility>
28
#include <functional>
29
#include <lemon/math.h>
30

	
31
namespace lemon {
32

	
33
  /// \ingroup heaps
34
  ///
35
  /// \brief Fibonacci heap data structure.
36
  ///
37
  /// This class implements the \e Fibonacci \e heap data structure.
38
  /// It fully conforms to the \ref concepts::Heap "heap concept".
39
  ///
40
  /// The methods \ref increase() and \ref erase() are not efficient in a
41
  /// Fibonacci heap. In case of many calls of these operations, it is
42
  /// better to use other heap structure, e.g. \ref BinHeap "binary heap".
43
  ///
44
  /// \tparam PR Type of the priorities of the items.
45
  /// \tparam IM A read-writable item map with \c int values, used
46
  /// internally to handle the cross references.
47
  /// \tparam CMP A functor class for comparing the priorities.
48
  /// The default is \c std::less<PR>.
49
#ifdef DOXYGEN
50
  template <typename PR, typename IM, typename CMP>
51
#else
52
  template <typename PR, typename IM, typename CMP = std::less<PR> >
53
#endif
54
  class FibHeap {
55
  public:
56

	
57
    /// Type of the item-int map.
58
    typedef IM ItemIntMap;
59
    /// Type of the priorities.
60
    typedef PR Prio;
61
    /// Type of the items stored in the heap.
62
    typedef typename ItemIntMap::Key Item;
63
    /// Type of the item-priority pairs.
64
    typedef std::pair<Item,Prio> Pair;
65
    /// Functor type for comparing the priorities.
66
    typedef CMP Compare;
67

	
68
  private:
69
    class Store;
70

	
71
    std::vector<Store> _data;
72
    int _minimum;
73
    ItemIntMap &_iim;
74
    Compare _comp;
75
    int _num;
76

	
77
  public:
78

	
79
    /// \brief Type to represent the states of the items.
80
    ///
81
    /// Each item has a state associated to it. It can be "in heap",
82
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
83
    /// heap's point of view, but may be useful to the user.
84
    ///
85
    /// The item-int map must be initialized in such way that it assigns
86
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
87
    enum State {
88
      IN_HEAP = 0,    ///< = 0.
89
      PRE_HEAP = -1,  ///< = -1.
90
      POST_HEAP = -2  ///< = -2.
91
    };
92

	
93
    /// \brief Constructor.
94
    ///
95
    /// Constructor.
96
    /// \param map A map that assigns \c int values to the items.
97
    /// It is used internally to handle the cross references.
98
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
99
    explicit FibHeap(ItemIntMap &map)
100
      : _minimum(0), _iim(map), _num() {}
101

	
102
    /// \brief Constructor.
103
    ///
104
    /// Constructor.
105
    /// \param map A map that assigns \c int values to the items.
106
    /// It is used internally to handle the cross references.
107
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
108
    /// \param comp The function object used for comparing 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
    /// This function returns the number of items stored in the heap.
115
    int size() const { return _num; }
116

	
117
    /// \brief Check if the heap is empty.
118
    ///
119
    /// This function returns \c true if the heap is empty.
120
    bool empty() const { return _num==0; }
121

	
122
    /// \brief Make the heap empty.
123
    ///
124
    /// This functon makes the heap empty.
125
    /// It does not change the cross reference map. If you want to reuse
126
    /// a heap that is not surely empty, you should first clear it and
127
    /// then you should set the cross reference map to \c PRE_HEAP
128
    /// for each item.
129
    void clear() {
130
      _data.clear(); _minimum = 0; _num = 0;
131
    }
132

	
133
    /// \brief Insert an item into the heap with the given priority.
134
    ///
135
    /// This function inserts the given item into the heap with the
136
    /// given priority.
137
    /// \param item The item to insert.
138
    /// \param prio The priority of the item.
139
    /// \pre \e item must not be stored in the heap.
140
    void push (const Item& item, const Prio& prio) {
141
      int i=_iim[item];
142
      if ( i < 0 ) {
143
        int s=_data.size();
144
        _iim.set( item, s );
145
        Store st;
146
        st.name=item;
147
        _data.push_back(st);
148
        i=s;
149
      } else {
150
        _data[i].parent=_data[i].child=-1;
151
        _data[i].degree=0;
152
        _data[i].in=true;
153
        _data[i].marked=false;
154
      }
155

	
156
      if ( _num ) {
157
        _data[_data[_minimum].right_neighbor].left_neighbor=i;
158
        _data[i].right_neighbor=_data[_minimum].right_neighbor;
159
        _data[_minimum].right_neighbor=i;
160
        _data[i].left_neighbor=_minimum;
161
        if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
162
      } else {
163
        _data[i].right_neighbor=_data[i].left_neighbor=i;
164
        _minimum=i;
165
      }
166
      _data[i].prio=prio;
167
      ++_num;
168
    }
169

	
170
    /// \brief Return the item having minimum priority.
171
    ///
172
    /// This function returns the item having minimum priority.
173
    /// \pre The heap must be non-empty.
174
    Item top() const { return _data[_minimum].name; }
175

	
176
    /// \brief The minimum priority.
177
    ///
178
    /// This function returns the minimum priority.
179
    /// \pre The heap must be non-empty.
180
    Prio prio() const { return _data[_minimum].prio; }
181

	
182
    /// \brief Remove the item having minimum priority.
183
    ///
184
    /// This function removes the item having minimum priority.
185
    /// \pre The heap must be non-empty.
186
    void pop() {
187
      /*The first case is that there are only one root.*/
188
      if ( _data[_minimum].left_neighbor==_minimum ) {
189
        _data[_minimum].in=false;
190
        if ( _data[_minimum].degree!=0 ) {
191
          makeRoot(_data[_minimum].child);
192
          _minimum=_data[_minimum].child;
193
          balance();
194
        }
195
      } else {
196
        int right=_data[_minimum].right_neighbor;
197
        unlace(_minimum);
198
        _data[_minimum].in=false;
199
        if ( _data[_minimum].degree > 0 ) {
200
          int left=_data[_minimum].left_neighbor;
201
          int child=_data[_minimum].child;
202
          int last_child=_data[child].left_neighbor;
203

	
204
          makeRoot(child);
205

	
206
          _data[left].right_neighbor=child;
207
          _data[child].left_neighbor=left;
208
          _data[right].left_neighbor=last_child;
209
          _data[last_child].right_neighbor=right;
210
        }
211
        _minimum=right;
212
        balance();
213
      } // the case where there are more roots
214
      --_num;
215
    }
216

	
217
    /// \brief Remove the given item from the heap.
218
    ///
219
    /// This function removes the given item from the heap if it is
220
    /// already stored.
221
    /// \param item The item to delete.
222
    /// \pre \e item must be in the heap.
223
    void erase (const Item& item) {
224
      int i=_iim[item];
225

	
226
      if ( i >= 0 && _data[i].in ) {
227
        if ( _data[i].parent!=-1 ) {
228
          int p=_data[i].parent;
229
          cut(i,p);
230
          cascade(p);
231
        }
232
        _minimum=i;     //As if its prio would be -infinity
233
        pop();
234
      }
235
    }
236

	
237
    /// \brief The priority of the given item.
238
    ///
239
    /// This function returns the priority of the given item.
240
    /// \param item The item.
241
    /// \pre \e item must be in the heap.
242
    Prio operator[](const Item& item) const {
243
      return _data[_iim[item]].prio;
244
    }
245

	
246
    /// \brief Set the priority of an item or insert it, if it is
247
    /// not stored in the heap.
248
    ///
249
    /// This method sets the priority of the given item if it is
250
    /// already stored in the heap. Otherwise it inserts the given
251
    /// item into the heap with the given priority.
252
    /// \param item The item.
253
    /// \param prio The priority.
254
    void set (const Item& item, const Prio& prio) {
255
      int i=_iim[item];
256
      if ( i >= 0 && _data[i].in ) {
257
        if ( _comp(prio, _data[i].prio) ) decrease(item, prio);
258
        if ( _comp(_data[i].prio, prio) ) increase(item, prio);
259
      } else push(item, prio);
260
    }
261

	
262
    /// \brief Decrease the priority of an item to the given value.
263
    ///
264
    /// This function decreases the priority of an item to the given value.
265
    /// \param item The item.
266
    /// \param prio The priority.
267
    /// \pre \e item must be stored in the heap with priority at least \e prio.
268
    void decrease (const Item& item, const Prio& prio) {
269
      int i=_iim[item];
270
      _data[i].prio=prio;
271
      int p=_data[i].parent;
272

	
273
      if ( p!=-1 && _comp(prio, _data[p].prio) ) {
274
        cut(i,p);
275
        cascade(p);
276
      }
277
      if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
278
    }
279

	
280
    /// \brief Increase the priority of an item to the given value.
281
    ///
282
    /// This function increases the priority of an item to the given value.
283
    /// \param item The item.
284
    /// \param prio The priority.
285
    /// \pre \e item must be stored in the heap with priority at most \e prio.
286
    void increase (const Item& item, const Prio& prio) {
287
      erase(item);
288
      push(item, prio);
289
    }
290

	
291
    /// \brief Return the state of an item.
292
    ///
293
    /// This method returns \c PRE_HEAP if the given item has never
294
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
295
    /// and \c POST_HEAP otherwise.
296
    /// In the latter case it is possible that the item will get back
297
    /// to the heap again.
298
    /// \param item The item.
299
    State state(const Item &item) const {
300
      int i=_iim[item];
301
      if( i>=0 ) {
302
        if ( _data[i].in ) i=0;
303
        else i=-2;
304
      }
305
      return State(i);
306
    }
307

	
308
    /// \brief Set the state of an item in the heap.
309
    ///
310
    /// This function sets the state of the given item in the heap.
311
    /// It can be used to manually clear the heap when it is important
312
    /// to achive better time complexity.
313
    /// \param i The item.
314
    /// \param st The state. It should not be \c IN_HEAP.
315
    void state(const Item& i, State st) {
316
      switch (st) {
317
      case POST_HEAP:
318
      case PRE_HEAP:
319
        if (state(i) == IN_HEAP) {
320
          erase(i);
321
        }
322
        _iim[i] = st;
323
        break;
324
      case IN_HEAP:
325
        break;
326
      }
327
    }
328

	
329
  private:
330

	
331
    void balance() {
332

	
333
      int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
334

	
335
      std::vector<int> A(maxdeg,-1);
336

	
337
      /*
338
       *Recall that now minimum does not point to the minimum prio element.
339
       *We set minimum to this during balance().
340
       */
341
      int anchor=_data[_minimum].left_neighbor;
342
      int next=_minimum;
343
      bool end=false;
344

	
345
      do {
346
        int active=next;
347
        if ( anchor==active ) end=true;
348
        int d=_data[active].degree;
349
        next=_data[active].right_neighbor;
350

	
351
        while (A[d]!=-1) {
352
          if( _comp(_data[active].prio, _data[A[d]].prio) ) {
353
            fuse(active,A[d]);
354
          } else {
355
            fuse(A[d],active);
356
            active=A[d];
357
          }
358
          A[d]=-1;
359
          ++d;
360
        }
361
        A[d]=active;
362
      } while ( !end );
363

	
364

	
365
      while ( _data[_minimum].parent >=0 )
366
        _minimum=_data[_minimum].parent;
367
      int s=_minimum;
368
      int m=_minimum;
369
      do {
370
        if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
371
        s=_data[s].right_neighbor;
372
      } while ( s != m );
373
    }
374

	
375
    void makeRoot(int c) {
376
      int s=c;
377
      do {
378
        _data[s].parent=-1;
379
        s=_data[s].right_neighbor;
380
      } while ( s != c );
381
    }
382

	
383
    void cut(int a, int b) {
384
      /*
385
       *Replacing a from the children of b.
386
       */
387
      --_data[b].degree;
388

	
389
      if ( _data[b].degree !=0 ) {
390
        int child=_data[b].child;
391
        if ( child==a )
392
          _data[b].child=_data[child].right_neighbor;
393
        unlace(a);
394
      }
395

	
396

	
397
      /*Lacing a to the roots.*/
398
      int right=_data[_minimum].right_neighbor;
399
      _data[_minimum].right_neighbor=a;
400
      _data[a].left_neighbor=_minimum;
401
      _data[a].right_neighbor=right;
402
      _data[right].left_neighbor=a;
403

	
404
      _data[a].parent=-1;
405
      _data[a].marked=false;
406
    }
407

	
408
    void cascade(int a) {
409
      if ( _data[a].parent!=-1 ) {
410
        int p=_data[a].parent;
411

	
412
        if ( _data[a].marked==false ) _data[a].marked=true;
413
        else {
414
          cut(a,p);
415
          cascade(p);
416
        }
417
      }
418
    }
419

	
420
    void fuse(int a, int b) {
421
      unlace(b);
422

	
423
      /*Lacing b under a.*/
424
      _data[b].parent=a;
425

	
426
      if (_data[a].degree==0) {
427
        _data[b].left_neighbor=b;
428
        _data[b].right_neighbor=b;
429
        _data[a].child=b;
430
      } else {
431
        int child=_data[a].child;
432
        int last_child=_data[child].left_neighbor;
433
        _data[child].left_neighbor=b;
434
        _data[b].right_neighbor=child;
435
        _data[last_child].right_neighbor=b;
436
        _data[b].left_neighbor=last_child;
437
      }
438

	
439
      ++_data[a].degree;
440

	
441
      _data[b].marked=false;
442
    }
443

	
444
    /*
445
     *It is invoked only if a has siblings.
446
     */
447
    void unlace(int a) {
448
      int leftn=_data[a].left_neighbor;
449
      int rightn=_data[a].right_neighbor;
450
      _data[leftn].right_neighbor=rightn;
451
      _data[rightn].left_neighbor=leftn;
452
    }
453

	
454

	
455
    class Store {
456
      friend class FibHeap;
457

	
458
      Item name;
459
      int parent;
460
      int left_neighbor;
461
      int right_neighbor;
462
      int child;
463
      int degree;
464
      bool marked;
465
      bool in;
466
      Prio prio;
467

	
468
      Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
469
    };
470
  };
471

	
472
} //namespace lemon
473

	
474
#endif //LEMON_FIB_HEAP_H
475

	
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_FOURARY_HEAP_H
20
#define LEMON_FOURARY_HEAP_H
21

	
22
///\ingroup heaps
23
///\file
24
///\brief Fourary heap implementation.
25

	
26
#include <vector>
27
#include <utility>
28
#include <functional>
29

	
30
namespace lemon {
31

	
32
  /// \ingroup heaps
33
  ///
34
  ///\brief Fourary heap data structure.
35
  ///
36
  /// This class implements the \e fourary \e heap data structure.
37
  /// It fully conforms to the \ref concepts::Heap "heap concept".
38
  ///
39
  /// The fourary heap is a specialization of the \ref KaryHeap "K-ary heap"
40
  /// for <tt>K=4</tt>. It is similar to the \ref BinHeap "binary heap",
41
  /// but its nodes have at most four children, instead of two.
42
  ///
43
  /// \tparam PR Type of the priorities of the items.
44
  /// \tparam IM A read-writable item map with \c int values, used
45
  /// internally to handle the cross references.
46
  /// \tparam CMP A functor class for comparing the priorities.
47
  /// The default is \c std::less<PR>.
48
  ///
49
  ///\sa BinHeap
50
  ///\sa KaryHeap
51
#ifdef DOXYGEN
52
  template <typename PR, typename IM, typename CMP>
53
#else
54
  template <typename PR, typename IM, typename CMP = std::less<PR> >
55
#endif
56
  class FouraryHeap {
57
  public:
58
    /// Type of the item-int map.
59
    typedef IM ItemIntMap;
60
    /// Type of the priorities.
61
    typedef PR Prio;
62
    /// Type of the items stored in the heap.
63
    typedef typename ItemIntMap::Key Item;
64
    /// Type of the item-priority pairs.
65
    typedef std::pair<Item,Prio> Pair;
66
    /// Functor type for comparing the priorities.
67
    typedef CMP Compare;
68

	
69
    /// \brief Type to represent the states of the items.
70
    ///
71
    /// Each item has a state associated to it. It can be "in heap",
72
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
73
    /// heap's point of view, but may be useful to the user.
74
    ///
75
    /// The item-int map must be initialized in such way that it assigns
76
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
77
    enum State {
78
      IN_HEAP = 0,    ///< = 0.
79
      PRE_HEAP = -1,  ///< = -1.
80
      POST_HEAP = -2  ///< = -2.
81
    };
82

	
83
  private:
84
    std::vector<Pair> _data;
85
    Compare _comp;
86
    ItemIntMap &_iim;
87

	
88
  public:
89
    /// \brief Constructor.
90
    ///
91
    /// Constructor.
92
    /// \param map A map that assigns \c int values to the items.
93
    /// It is used internally to handle the cross references.
94
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
95
    explicit FouraryHeap(ItemIntMap &map) : _iim(map) {}
96

	
97
    /// \brief Constructor.
98
    ///
99
    /// Constructor.
100
    /// \param map A map that assigns \c int values to the items.
101
    /// It is used internally to handle the cross references.
102
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
103
    /// \param comp The function object used for comparing the priorities.
104
    FouraryHeap(ItemIntMap &map, const Compare &comp)
105
      : _iim(map), _comp(comp) {}
106

	
107
    /// \brief The number of items stored in the heap.
108
    ///
109
    /// This function returns the number of items stored in the heap.
110
    int size() const { return _data.size(); }
111

	
112
    /// \brief Check if the heap is empty.
113
    ///
114
    /// This function returns \c true if the heap is empty.
115
    bool empty() const { return _data.empty(); }
116

	
117
    /// \brief Make the heap empty.
118
    ///
119
    /// This functon makes the heap empty.
120
    /// It does not change the cross reference map. If you want to reuse
121
    /// a heap that is not surely empty, you should first clear it and
122
    /// then you should set the cross reference map to \c PRE_HEAP
123
    /// for each item.
124
    void clear() { _data.clear(); }
125

	
126
  private:
127
    static int parent(int i) { return (i-1)/4; }
128
    static int firstChild(int i) { return 4*i+1; }
129

	
130
    bool less(const Pair &p1, const Pair &p2) const {
131
      return _comp(p1.second, p2.second);
132
    }
133

	
134
    void bubbleUp(int hole, Pair p) {
135
      int par = parent(hole);
136
      while( hole>0 && less(p,_data[par]) ) {
137
        move(_data[par],hole);
138
        hole = par;
139
        par = parent(hole);
140
      }
141
      move(p, hole);
142
    }
143

	
144
    void bubbleDown(int hole, Pair p, int length) {
145
      if( length>1 ) {
146
        int child = firstChild(hole);
147
        while( child+3<length ) {
148
          int min=child;
149
          if( less(_data[++child], _data[min]) ) min=child;
150
          if( less(_data[++child], _data[min]) ) min=child;
151
          if( less(_data[++child], _data[min]) ) min=child;
152
          if( !less(_data[min], p) )
153
            goto ok;
154
          move(_data[min], hole);
155
          hole = min;
156
          child = firstChild(hole);
157
        }
158
        if ( child<length ) {
159
          int min = child;
160
          if( ++child<length && less(_data[child], _data[min]) ) min=child;
161
          if( ++child<length && less(_data[child], _data[min]) ) min=child;
162
          if( less(_data[min], p) ) {
163
            move(_data[min], hole);
164
            hole = min;
165
          }
166
        }
167
      }
168
    ok:
169
      move(p, hole);
170
    }
171

	
172
    void move(const Pair &p, int i) {
173
      _data[i] = p;
174
      _iim.set(p.first, i);
175
    }
176

	
177
  public:
178
    /// \brief Insert a pair of item and priority into the heap.
179
    ///
180
    /// This function inserts \c p.first to the heap with priority
181
    /// \c p.second.
182
    /// \param p The pair to insert.
183
    /// \pre \c p.first must not be stored in the heap.
184
    void push(const Pair &p) {
185
      int n = _data.size();
186
      _data.resize(n+1);
187
      bubbleUp(n, p);
188
    }
189

	
190
    /// \brief Insert an item into the heap with the given priority.
191
    ///
192
    /// This function inserts the given item into the heap with the
193
    /// given priority.
194
    /// \param i The item to insert.
195
    /// \param p The priority of the item.
196
    /// \pre \e i must not be stored in the heap.
197
    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
198

	
199
    /// \brief Return the item having minimum priority.
200
    ///
201
    /// This function returns the item having minimum priority.
202
    /// \pre The heap must be non-empty.
203
    Item top() const { return _data[0].first; }
204

	
205
    /// \brief The minimum priority.
206
    ///
207
    /// This function returns the minimum priority.
208
    /// \pre The heap must be non-empty.
209
    Prio prio() const { return _data[0].second; }
210

	
211
    /// \brief Remove the item having minimum priority.
212
    ///
213
    /// This function removes the item having minimum priority.
214
    /// \pre The heap must be non-empty.
215
    void pop() {
216
      int n = _data.size()-1;
217
      _iim.set(_data[0].first, POST_HEAP);
218
      if (n>0) bubbleDown(0, _data[n], n);
219
      _data.pop_back();
220
    }
221

	
222
    /// \brief Remove the given item from the heap.
223
    ///
224
    /// This function removes the given item from the heap if it is
225
    /// already stored.
226
    /// \param i The item to delete.
227
    /// \pre \e i must be in the heap.
228
    void erase(const Item &i) {
229
      int h = _iim[i];
230
      int n = _data.size()-1;
231
      _iim.set(_data[h].first, POST_HEAP);
232
      if( h<n ) {
233
        if( less(_data[parent(h)], _data[n]) )
234
          bubbleDown(h, _data[n], n);
235
        else
236
          bubbleUp(h, _data[n]);
237
      }
238
      _data.pop_back();
239
    }
240

	
241
    /// \brief The priority of the given item.
242
    ///
243
    /// This function returns the priority of the given item.
244
    /// \param i The item.
245
    /// \pre \e i must be in the heap.
246
    Prio operator[](const Item &i) const {
247
      int idx = _iim[i];
248
      return _data[idx].second;
249
    }
250

	
251
    /// \brief Set the priority of an item or insert it, if it is
252
    /// not stored in the heap.
253
    ///
254
    /// This method sets the priority of the given item if it is
255
    /// already stored in the heap. Otherwise it inserts the given
256
    /// item into the heap with the given priority.
257
    /// \param i The item.
258
    /// \param p The priority.
259
    void set(const Item &i, const Prio &p) {
260
      int idx = _iim[i];
261
      if( idx < 0 )
262
        push(i,p);
263
      else if( _comp(p, _data[idx].second) )
264
        bubbleUp(idx, Pair(i,p));
265
      else
266
        bubbleDown(idx, Pair(i,p), _data.size());
267
    }
268

	
269
    /// \brief Decrease the priority of an item to the given value.
270
    ///
271
    /// This function decreases the priority of an item to the given value.
272
    /// \param i The item.
273
    /// \param p The priority.
274
    /// \pre \e i must be stored in the heap with priority at least \e p.
275
    void decrease(const Item &i, const Prio &p) {
276
      int idx = _iim[i];
277
      bubbleUp(idx, Pair(i,p));
278
    }
279

	
280
    /// \brief Increase the priority of an item to the given value.
281
    ///
282
    /// This function increases the priority of an item to the given value.
283
    /// \param i The item.
284
    /// \param p The priority.
285
    /// \pre \e i must be stored in the heap with priority at most \e p.
286
    void increase(const Item &i, const Prio &p) {
287
      int idx = _iim[i];
288
      bubbleDown(idx, Pair(i,p), _data.size());
289
    }
290

	
291
    /// \brief Return the state of an item.
292
    ///
293
    /// This method returns \c PRE_HEAP if the given item has never
294
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
295
    /// and \c POST_HEAP otherwise.
296
    /// In the latter case it is possible that the item will get back
297
    /// to the heap again.
298
    /// \param i The item.
299
    State state(const Item &i) const {
300
      int s = _iim[i];
301
      if (s>=0) s=0;
302
      return State(s);
303
    }
304

	
305
    /// \brief Set the state of an item in the heap.
306
    ///
307
    /// This function sets the state of the given item in the heap.
308
    /// It can be used to manually clear the heap when it is important
309
    /// to achive better time complexity.
310
    /// \param i The item.
311
    /// \param st The state. It should not be \c IN_HEAP.
312
    void state(const Item& i, State st) {
313
      switch (st) {
314
        case POST_HEAP:
315
        case PRE_HEAP:
316
          if (state(i) == IN_HEAP) erase(i);
317
          _iim[i] = st;
318
          break;
319
        case IN_HEAP:
320
          break;
321
      }
322
    }
323

	
324
    /// \brief Replace an item in the heap.
325
    ///
326
    /// This function replaces item \c i with item \c j.
327
    /// Item \c i must be in the heap, while \c j must be out of the heap.
328
    /// After calling this method, item \c i will be out of the
329
    /// heap and \c j will be in the heap with the same prioriority
330
    /// as item \c i had before.
331
    void replace(const Item& i, const Item& j) {
332
      int idx = _iim[i];
333
      _iim.set(i, _iim[j]);
334
      _iim.set(j, idx);
335
      _data[idx].first = j;
336
    }
337

	
338
  }; // class FouraryHeap
339

	
340
} // namespace lemon
341

	
342
#endif // LEMON_FOURARY_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 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 FullDigraph and FullGraph 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
    static int index(const Node& node) { 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 directed full graph class.
152
  ///
153
  /// FullDigraph is a simple and fast implmenetation of directed full
154
  /// (complete) graphs. It contains an arc from each node to each node
155
  /// (including a loop for each node), therefore the number of arcs
156
  /// is the square of the number of nodes.
157
  /// This class is completely static and it needs constant memory space.
158
  /// Thus you can neither add nor delete nodes or arcs, however
159
  /// the structure can be resized using resize().
160
  ///
161
  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
162
  /// Most of its member functions and nested classes are documented
163
  /// only in the concept class.
164
  ///
165
  /// \note FullDigraph and FullGraph classes are very similar,
166
  /// but there are two differences. While this class conforms only
167
  /// to the \ref concepts::Digraph "Digraph" concept, FullGraph
168
  /// conforms to the \ref concepts::Graph "Graph" concept,
169
  /// moreover FullGraph does not contain a loop for each
170
  /// node as this class does.
171
  ///
172
  /// \sa FullGraph
173
  class FullDigraph : public ExtendedFullDigraphBase {
174
    typedef ExtendedFullDigraphBase Parent;
175

	
176
  public:
177

	
178
    /// \brief Default constructor.
179
    ///
180
    /// Default constructor. The number of nodes and arcs will be zero.
181
    FullDigraph() { construct(0); }
182

	
183
    /// \brief Constructor
184
    ///
185
    /// Constructor.
186
    /// \param n The number of the nodes.
187
    FullDigraph(int n) { construct(n); }
188

	
189
    /// \brief Resizes the digraph
190
    ///
191
    /// This function resizes the digraph. It fully destroys and
192
    /// rebuilds the structure, therefore the maps of the digraph will be
193
    /// reallocated automatically and the previous values will be lost.
194
    void resize(int n) {
195
      Parent::notifier(Arc()).clear();
196
      Parent::notifier(Node()).clear();
197
      construct(n);
198
      Parent::notifier(Node()).build();
199
      Parent::notifier(Arc()).build();
200
    }
201

	
202
    /// \brief Returns the node with the given index.
203
    ///
204
    /// Returns the node with the given index. Since this structure is 
205
    /// completely static, the nodes can be indexed with integers from
206
    /// the range <tt>[0..nodeNum()-1]</tt>.
207
    /// \sa index()
208
    Node operator()(int ix) const { return Parent::operator()(ix); }
209

	
210
    /// \brief Returns the index of the given node.
211
    ///
212
    /// Returns the index of the given node. Since this structure is 
213
    /// completely static, the nodes can be indexed with integers from
214
    /// the range <tt>[0..nodeNum()-1]</tt>.
215
    /// \sa operator()()
216
    static int index(const Node& node) { return Parent::index(node); }
217

	
218
    /// \brief Returns the arc connecting the given nodes.
219
    ///
220
    /// Returns the arc connecting the given nodes.
221
    Arc arc(Node u, Node v) const {
222
      return Parent::arc(u, v);
223
    }
224

	
225
    /// \brief Number of nodes.
226
    int nodeNum() const { return Parent::nodeNum(); }
227
    /// \brief Number of arcs.
228
    int arcNum() const { return Parent::arcNum(); }
229
  };
230

	
231

	
232
  class FullGraphBase {
233
  public:
234

	
235
    typedef FullGraphBase Graph;
236

	
237
    class Node;
238
    class Arc;
239
    class Edge;
240

	
241
  protected:
242

	
243
    int _node_num;
244
    int _edge_num;
245

	
246
    FullGraphBase() {}
247

	
248
    void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; }
249

	
250
    int _uid(int e) const {
251
      int u = e / _node_num;
252
      int v = e % _node_num;
253
      return u < v ? u : _node_num - 2 - u;
254
    }
255

	
256
    int _vid(int e) const {
257
      int u = e / _node_num;
258
      int v = e % _node_num;
259
      return u < v ? v : _node_num - 1 - v;
260
    }
261

	
262
    void _uvid(int e, int& u, int& v) const {
263
      u = e / _node_num;
264
      v = e % _node_num;
265
      if  (u >= v) {
266
        u = _node_num - 2 - u;
267
        v = _node_num - 1 - v;
268
      }
269
    }
270

	
271
    void _stid(int a, int& s, int& t) const {
272
      if ((a & 1) == 1) {
273
        _uvid(a >> 1, s, t);
274
      } else {
275
        _uvid(a >> 1, t, s);
276
      }
277
    }
278

	
279
    int _eid(int u, int v) const {
280
      if (u < (_node_num - 1) / 2) {
281
        return u * _node_num + v;
282
      } else {
283
        return (_node_num - 1 - u) * _node_num - v - 1;
284
      }
285
    }
286

	
287
  public:
288

	
289
    Node operator()(int ix) const { return Node(ix); }
290
    static int index(const Node& node) { return node._id; }
291

	
292
    Edge edge(const Node& u, const Node& v) const {
293
      if (u._id < v._id) {
294
        return Edge(_eid(u._id, v._id));
295
      } else if (u._id != v._id) {
296
        return Edge(_eid(v._id, u._id));
297
      } else {
298
        return INVALID;
299
      }
300
    }
301

	
302
    Arc arc(const Node& s, const Node& t) const {
303
      if (s._id < t._id) {
304
        return Arc((_eid(s._id, t._id) << 1) | 1);
305
      } else if (s._id != t._id) {
306
        return Arc(_eid(t._id, s._id) << 1);
307
      } else {
308
        return INVALID;
309
      }
310
    }
311

	
312
    typedef True NodeNumTag;
313
    typedef True ArcNumTag;
314
    typedef True EdgeNumTag;
315

	
316
    int nodeNum() const { return _node_num; }
317
    int arcNum() const { return 2 * _edge_num; }
318
    int edgeNum() const { return _edge_num; }
319

	
320
    static int id(Node node) { return node._id; }
321
    static int id(Arc arc) { return arc._id; }
322
    static int id(Edge edge) { return edge._id; }
323

	
324
    int maxNodeId() const { return _node_num-1; }
325
    int maxArcId() const { return 2 * _edge_num-1; }
326
    int maxEdgeId() const { return _edge_num-1; }
327

	
328
    static Node nodeFromId(int id) { return Node(id);}
329
    static Arc arcFromId(int id) { return Arc(id);}
330
    static Edge edgeFromId(int id) { return Edge(id);}
331

	
332
    Node u(Edge edge) const {
333
      return Node(_uid(edge._id));
334
    }
335

	
336
    Node v(Edge edge) const {
337
      return Node(_vid(edge._id));
338
    }
339

	
340
    Node source(Arc arc) const {
341
      return Node((arc._id & 1) == 1 ?
342
                  _uid(arc._id >> 1) : _vid(arc._id >> 1));
343
    }
344

	
345
    Node target(Arc arc) const {
346
      return Node((arc._id & 1) == 1 ?
347
                  _vid(arc._id >> 1) : _uid(arc._id >> 1));
348
    }
349

	
350
    typedef True FindEdgeTag;
351
    typedef True FindArcTag;
352

	
353
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
354
      return prev != INVALID ? INVALID : edge(u, v);
355
    }
356

	
357
    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
358
      return prev != INVALID ? INVALID : arc(s, t);
359
    }
360

	
361
    class Node {
362
      friend class FullGraphBase;
363

	
364
    protected:
365
      int _id;
366
      Node(int id) : _id(id) {}
367
    public:
368
      Node() {}
369
      Node (Invalid) { _id = -1; }
370
      bool operator==(const Node node) const {return _id == node._id;}
371
      bool operator!=(const Node node) const {return _id != node._id;}
372
      bool operator<(const Node node) const {return _id < node._id;}
373
    };
374

	
375
    class Edge {
376
      friend class FullGraphBase;
377
      friend class Arc;
378

	
379
    protected:
380
      int _id;
381

	
382
      Edge(int id) : _id(id) {}
383

	
384
    public:
385
      Edge() { }
386
      Edge (Invalid) { _id = -1; }
387

	
388
      bool operator==(const Edge edge) const {return _id == edge._id;}
389
      bool operator!=(const Edge edge) const {return _id != edge._id;}
390
      bool operator<(const Edge edge) const {return _id < edge._id;}
391
    };
392

	
393
    class Arc {
394
      friend class FullGraphBase;
395

	
396
    protected:
397
      int _id;
398

	
399
      Arc(int id) : _id(id) {}
400

	
401
    public:
402
      Arc() { }
403
      Arc (Invalid) { _id = -1; }
404

	
405
      operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -1); }
406

	
407
      bool operator==(const Arc arc) const {return _id == arc._id;}
408
      bool operator!=(const Arc arc) const {return _id != arc._id;}
409
      bool operator<(const Arc arc) const {return _id < arc._id;}
410
    };
411

	
412
    static bool direction(Arc arc) {
413
      return (arc._id & 1) == 1;
414
    }
415

	
416
    static Arc direct(Edge edge, bool dir) {
417
      return Arc((edge._id << 1) | (dir ? 1 : 0));
418
    }
419

	
420
    void first(Node& node) const {
421
      node._id = _node_num - 1;
422
    }
423

	
424
    static void next(Node& node) {
425
      --node._id;
426
    }
427

	
428
    void first(Arc& arc) const {
429
      arc._id = (_edge_num << 1) - 1;
430
    }
431

	
432
    static void next(Arc& arc) {
433
      --arc._id;
434
    }
435

	
436
    void first(Edge& edge) const {
437
      edge._id = _edge_num - 1;
438
    }
439

	
440
    static void next(Edge& edge) {
441
      --edge._id;
442
    }
443

	
444
    void firstOut(Arc& arc, const Node& node) const {
445
      int s = node._id, t = _node_num - 1;
446
      if (s < t) {
447
        arc._id = (_eid(s, t) << 1) | 1;
448
      } else {
449
        --t;
450
        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
451
      }
452
    }
453

	
454
    void nextOut(Arc& arc) const {
455
      int s, t;
456
      _stid(arc._id, s, t);
457
      --t;
458
      if (s < t) {
459
        arc._id = (_eid(s, t) << 1) | 1;
460
      } else {
461
        if (s == t) --t;
462
        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
463
      }
464
    }
465

	
466
    void firstIn(Arc& arc, const Node& node) const {
467
      int s = _node_num - 1, t = node._id;
468
      if (s > t) {
469
        arc._id = (_eid(t, s) << 1);
470
      } else {
471
        --s;
472
        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
473
      }
474
    }
475

	
476
    void nextIn(Arc& arc) const {
477
      int s, t;
478
      _stid(arc._id, s, t);
479
      --s;
480
      if (s > t) {
481
        arc._id = (_eid(t, s) << 1);
482
      } else {
483
        if (s == t) --s;
484
        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
485
      }
486
    }
487

	
488
    void firstInc(Edge& edge, bool& dir, const Node& node) const {
489
      int u = node._id, v = _node_num - 1;
490
      if (u < v) {
491
        edge._id = _eid(u, v);
492
        dir = true;
493
      } else {
494
        --v;
495
        edge._id = (v != -1 ? _eid(v, u) : -1);
496
        dir = false;
497
      }
498
    }
499

	
500
    void nextInc(Edge& edge, bool& dir) const {
501
      int u, v;
502
      if (dir) {
503
        _uvid(edge._id, u, v);
504
        --v;
505
        if (u < v) {
506
          edge._id = _eid(u, v);
507
        } else {
508
          --v;
509
          edge._id = (v != -1 ? _eid(v, u) : -1);
510
          dir = false;
511
        }
512
      } else {
513
        _uvid(edge._id, v, u);
514
        --v;
515
        edge._id = (v != -1 ? _eid(v, u) : -1);
516
      }
517
    }
518

	
519
  };
520

	
521
  typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
522

	
523
  /// \ingroup graphs
524
  ///
525
  /// \brief An undirected full graph class.
526
  ///
527
  /// FullGraph is a simple and fast implmenetation of undirected full
528
  /// (complete) graphs. It contains an edge between every distinct pair
529
  /// of nodes, therefore the number of edges is <tt>n(n-1)/2</tt>.
530
  /// This class is completely static and it needs constant memory space.
531
  /// Thus you can neither add nor delete nodes or edges, however
532
  /// the structure can be resized using resize().
533
  ///
534
  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
535
  /// Most of its member functions and nested classes are documented
536
  /// only in the concept class.
537
  ///
538
  /// \note FullDigraph and FullGraph classes are very similar,
539
  /// but there are two differences. While FullDigraph
540
  /// conforms only to the \ref concepts::Digraph "Digraph" concept,
541
  /// this class conforms to the \ref concepts::Graph "Graph" concept,
542
  /// moreover this class does not contain a loop for each
543
  /// node as FullDigraph does.
544
  ///
545
  /// \sa FullDigraph
546
  class FullGraph : public ExtendedFullGraphBase {
547
    typedef ExtendedFullGraphBase Parent;
548

	
549
  public:
550

	
551
    /// \brief Default constructor.
552
    ///
553
    /// Default constructor. The number of nodes and edges will be zero.
554
    FullGraph() { construct(0); }
555

	
556
    /// \brief Constructor
557
    ///
558
    /// Constructor.
559
    /// \param n The number of the nodes.
560
    FullGraph(int n) { construct(n); }
561

	
562
    /// \brief Resizes the graph
563
    ///
564
    /// This function resizes the graph. It fully destroys and
565
    /// rebuilds the structure, therefore the maps of the graph will be
566
    /// reallocated automatically and the previous values will be lost.
567
    void resize(int n) {
568
      Parent::notifier(Arc()).clear();
569
      Parent::notifier(Edge()).clear();
570
      Parent::notifier(Node()).clear();
571
      construct(n);
572
      Parent::notifier(Node()).build();
573
      Parent::notifier(Edge()).build();
574
      Parent::notifier(Arc()).build();
575
    }
576

	
577
    /// \brief Returns the node with the given index.
578
    ///
579
    /// Returns the node with the given index. Since this structure is 
580
    /// completely static, the nodes can be indexed with integers from
581
    /// the range <tt>[0..nodeNum()-1]</tt>.
582
    /// \sa index()
583
    Node operator()(int ix) const { return Parent::operator()(ix); }
584

	
585
    /// \brief Returns the index of the given node.
586
    ///
587
    /// Returns the index of the given node. Since this structure is 
588
    /// completely static, the nodes can be indexed with integers from
589
    /// the range <tt>[0..nodeNum()-1]</tt>.
590
    /// \sa operator()()
591
    static int index(const Node& node) { return Parent::index(node); }
592

	
593
    /// \brief Returns the arc connecting the given nodes.
594
    ///
595
    /// Returns the arc connecting the given nodes.
596
    Arc arc(Node s, Node t) const {
597
      return Parent::arc(s, t);
598
    }
599

	
600
    /// \brief Returns the edge connecting the given nodes.
601
    ///
602
    /// Returns the edge connecting the given nodes.
603
    Edge edge(Node u, Node v) const {
604
      return Parent::edge(u, v);
605
    }
606

	
607
    /// \brief Number of nodes.
608
    int nodeNum() const { return Parent::nodeNum(); }
609
    /// \brief Number of arcs.
610
    int arcNum() const { return Parent::arcNum(); }
611
    /// \brief Number of edges.
612
    int edgeNum() const { return Parent::edgeNum(); }
613

	
614
  };
615

	
616

	
617
} //namespace lemon
618

	
619

	
620
#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
  int GlpkBase::_addRow(Value lo, ExprIterator b, 
63
                        ExprIterator e, Value up) {
64
    int i = glp_add_rows(lp, 1);
65

	
66
    if (lo == -INF) {
67
      if (up == INF) {
68
        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
69
      } else {
70
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
71
      }    
72
    } else {
73
      if (up == INF) {
74
        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
75
      } else if (lo != up) {        
76
        glp_set_row_bnds(lp, i, GLP_DB, lo, up);
77
      } else {
78
        glp_set_row_bnds(lp, i, GLP_FX, lo, up);
79
      }
80
    }
81

	
82
    std::vector<int> indexes;
83
    std::vector<Value> values;
84

	
85
    indexes.push_back(0);
86
    values.push_back(0);
87

	
88
    for(ExprIterator it = b; it != e; ++it) {
89
      indexes.push_back(it->first);
90
      values.push_back(it->second);
91
    }
92

	
93
    glp_set_mat_row(lp, i, values.size() - 1,
94
                    &indexes.front(), &values.front());
95
    return i;
96
  }
97

	
98
  void GlpkBase::_eraseCol(int i) {
99
    int ca[2];
100
    ca[1] = i;
101
    glp_del_cols(lp, 1, ca);
102
  }
103

	
104
  void GlpkBase::_eraseRow(int i) {
105
    int ra[2];
106
    ra[1] = i;
107
    glp_del_rows(lp, 1, ra);
108
  }
109

	
110
  void GlpkBase::_eraseColId(int i) {
111
    cols.eraseIndex(i);
112
    cols.shiftIndices(i);
113
  }
114

	
115
  void GlpkBase::_eraseRowId(int i) {
116
    rows.eraseIndex(i);
117
    rows.shiftIndices(i);
118
  }
119

	
120
  void GlpkBase::_getColName(int c, std::string& name) const {
121
    const char *str = glp_get_col_name(lp, c);
122
    if (str) name = str;
123
    else name.clear();
124
  }
125

	
126
  void GlpkBase::_setColName(int c, const std::string & name) {
127
    glp_set_col_name(lp, c, const_cast<char*>(name.c_str()));
128

	
129
  }
130

	
131
  int GlpkBase::_colByName(const std::string& name) const {
132
    int k = glp_find_col(lp, const_cast<char*>(name.c_str()));
133
    return k > 0 ? k : -1;
134
  }
135

	
136
  void GlpkBase::_getRowName(int r, std::string& name) const {
137
    const char *str = glp_get_row_name(lp, r);
138
    if (str) name = str;
139
    else name.clear();
140
  }
141

	
142
  void GlpkBase::_setRowName(int r, const std::string & name) {
143
    glp_set_row_name(lp, r, const_cast<char*>(name.c_str()));
144

	
145
  }
146

	
147
  int GlpkBase::_rowByName(const std::string& name) const {
148
    int k = glp_find_row(lp, const_cast<char*>(name.c_str()));
149
    return k > 0 ? k : -1;
150
  }
151

	
152
  void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
153
    std::vector<int> indexes;
154
    std::vector<Value> values;
155

	
156
    indexes.push_back(0);
157
    values.push_back(0);
158

	
159
    for(ExprIterator it = b; it != e; ++it) {
160
      indexes.push_back(it->first);
161
      values.push_back(it->second);
162
    }
163

	
164
    glp_set_mat_row(lp, i, values.size() - 1,
165
                    &indexes.front(), &values.front());
166
  }
167

	
168
  void GlpkBase::_getRowCoeffs(int ix, InsertIterator b) const {
169
    int length = glp_get_mat_row(lp, ix, 0, 0);
170

	
171
    std::vector<int> indexes(length + 1);
172
    std::vector<Value> values(length + 1);
173

	
174
    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
175

	
176
    for (int i = 1; i <= length; ++i) {
177
      *b = std::make_pair(indexes[i], values[i]);
178
      ++b;
179
    }
180
  }
181

	
182
  void GlpkBase::_setColCoeffs(int ix, ExprIterator b,
183
                                     ExprIterator e) {
184

	
185
    std::vector<int> indexes;
186
    std::vector<Value> values;
187

	
188
    indexes.push_back(0);
189
    values.push_back(0);
190

	
191
    for(ExprIterator it = b; it != e; ++it) {
192
      indexes.push_back(it->first);
193
      values.push_back(it->second);
194
    }
195

	
196
    glp_set_mat_col(lp, ix, values.size() - 1,
197
                    &indexes.front(), &values.front());
198
  }
199

	
200
  void GlpkBase::_getColCoeffs(int ix, InsertIterator b) const {
201
    int length = glp_get_mat_col(lp, ix, 0, 0);
202

	
203
    std::vector<int> indexes(length + 1);
204
    std::vector<Value> values(length + 1);
205

	
206
    glp_get_mat_col(lp, ix, &indexes.front(), &values.front());
207

	
208
    for (int i = 1; i  <= length; ++i) {
209
      *b = std::make_pair(indexes[i], values[i]);
210
      ++b;
211
    }
212
  }
213

	
214
  void GlpkBase::_setCoeff(int ix, int jx, Value value) {
215

	
216
    if (glp_get_num_cols(lp) < glp_get_num_rows(lp)) {
217

	
218
      int length = glp_get_mat_row(lp, ix, 0, 0);
219

	
220
      std::vector<int> indexes(length + 2);
221
      std::vector<Value> values(length + 2);
222

	
223
      glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
224

	
225
      //The following code does not suppose that the elements of the
226
      //array indexes are sorted
227
      bool found = false;
228
      for (int i = 1; i  <= length; ++i) {
229
        if (indexes[i] == jx) {
230
          found = true;
231
          values[i] = value;
232
          break;
233
        }
234
      }
235
      if (!found) {
236
        ++length;
237
        indexes[length] = jx;
238
        values[length] = value;
239
      }
240

	
241
      glp_set_mat_row(lp, ix, length, &indexes.front(), &values.front());
242

	
243
    } else {
244

	
245
      int length = glp_get_mat_col(lp, jx, 0, 0);
246

	
247
      std::vector<int> indexes(length + 2);
248
      std::vector<Value> values(length + 2);
249

	
250
      glp_get_mat_col(lp, jx, &indexes.front(), &values.front());
251

	
252
      //The following code does not suppose that the elements of the
253
      //array indexes are sorted
254
      bool found = false;
255
      for (int i = 1; i <= length; ++i) {
256
        if (indexes[i] == ix) {
257
          found = true;
258
          values[i] = value;
259
          break;
260
        }
261
      }
262
      if (!found) {
263
        ++length;
264
        indexes[length] = ix;
265
        values[length] = value;
266
      }
267

	
268
      glp_set_mat_col(lp, jx, length, &indexes.front(), &values.front());
269
    }
270

	
271
  }
272

	
273
  GlpkBase::Value GlpkBase::_getCoeff(int ix, int jx) const {
274

	
275
    int length = glp_get_mat_row(lp, ix, 0, 0);
276

	
277
    std::vector<int> indexes(length + 1);
278
    std::vector<Value> values(length + 1);
279

	
280
    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
281

	
282
    for (int i = 1; i  <= length; ++i) {
283
      if (indexes[i] == jx) {
284
        return values[i];
285
      }
286
    }
287

	
288
    return 0;
289
  }
290

	
291
  void GlpkBase::_setColLowerBound(int i, Value lo) {
292
    LEMON_ASSERT(lo != INF, "Invalid bound");
293

	
294
    int b = glp_get_col_type(lp, i);
295
    double up = glp_get_col_ub(lp, i);
296
    if (lo == -INF) {
297
      switch (b) {
298
      case GLP_FR:
299
      case GLP_LO:
300
        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
301
        break;
302
      case GLP_UP:
303
        break;
304
      case GLP_DB:
305
      case GLP_FX:
306
        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
307
        break;
308
      default:
309
        break;
310
      }
311
    } else {
312
      switch (b) {
313
      case GLP_FR:
314
      case GLP_LO:
315
        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
316
        break;
317
      case GLP_UP:
318
      case GLP_DB:
319
      case GLP_FX:
320
        if (lo == up)
321
          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
322
        else
323
          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
324
        break;
325
      default:
326
        break;
327
      }
328
    }
329
  }
330

	
331
  GlpkBase::Value GlpkBase::_getColLowerBound(int i) const {
332
    int b = glp_get_col_type(lp, i);
333
    switch (b) {
334
    case GLP_LO:
335
    case GLP_DB:
336
    case GLP_FX:
337
      return glp_get_col_lb(lp, i);
338
    default:
339
      return -INF;
340
    }
341
  }
342

	
343
  void GlpkBase::_setColUpperBound(int i, Value up) {
344
    LEMON_ASSERT(up != -INF, "Invalid bound");
345

	
346
    int b = glp_get_col_type(lp, i);
347
    double lo = glp_get_col_lb(lp, i);
348
    if (up == INF) {
349
      switch (b) {
350
      case GLP_FR:
351
      case GLP_LO:
352
        break;
353
      case GLP_UP:
354
        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
355
        break;
356
      case GLP_DB:
357
      case GLP_FX:
358
        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
359
        break;
360
      default:
361
        break;
362
      }
363
    } else {
364
      switch (b) {
365
      case GLP_FR:
366
        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
367
        break;
368
      case GLP_UP:
369
        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
370
        break;
371
      case GLP_LO:
372
      case GLP_DB:
373
      case GLP_FX:
374
        if (lo == up)
375
          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
376
        else
377
          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
378
        break;
379
      default:
380
        break;
381
      }
382
    }
383

	
384
  }
385

	
386
  GlpkBase::Value GlpkBase::_getColUpperBound(int i) const {
387
    int b = glp_get_col_type(lp, i);
388
      switch (b) {
389
      case GLP_UP:
390
      case GLP_DB:
391
      case GLP_FX:
392
        return glp_get_col_ub(lp, i);
393
      default:
394
        return INF;
395
      }
396
  }
397

	
398
  void GlpkBase::_setRowLowerBound(int i, Value lo) {
399
    LEMON_ASSERT(lo != INF, "Invalid bound");
400

	
401
    int b = glp_get_row_type(lp, i);
402
    double up = glp_get_row_ub(lp, i);
403
    if (lo == -INF) {
404
      switch (b) {
405
      case GLP_FR:
406
      case GLP_LO:
407
        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
408
        break;
409
      case GLP_UP:
410
        break;
411
      case GLP_DB:
412
      case GLP_FX:
413
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
414
        break;
415
      default:
416
        break;
417
      }
418
    } else {
419
      switch (b) {
420
      case GLP_FR:
421
      case GLP_LO:
422
        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
423
        break;
424
      case GLP_UP:
425
      case GLP_DB:
426
      case GLP_FX:
427
        if (lo == up)
428
          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
429
        else
430
          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
431
        break;
432
      default:
433
        break;
434
      }
435
    }
436

	
437
  }
438

	
439
  GlpkBase::Value GlpkBase::_getRowLowerBound(int i) const {
440
    int b = glp_get_row_type(lp, i);
441
    switch (b) {
442
    case GLP_LO:
443
    case GLP_DB:
444
    case GLP_FX:
445
      return glp_get_row_lb(lp, i);
446
    default:
447
      return -INF;
448
    }
449
  }
450

	
451
  void GlpkBase::_setRowUpperBound(int i, Value up) {
452
    LEMON_ASSERT(up != -INF, "Invalid bound");
453

	
454
    int b = glp_get_row_type(lp, i);
455
    double lo = glp_get_row_lb(lp, i);
456
    if (up == INF) {
457
      switch (b) {
458
      case GLP_FR:
459
      case GLP_LO:
460
        break;
461
      case GLP_UP:
462
        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
463
        break;
464
      case GLP_DB:
465
      case GLP_FX:
466
        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
467
        break;
468
      default:
469
        break;
470
      }
471
    } else {
472
      switch (b) {
473
      case GLP_FR:
474
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
475
        break;
476
      case GLP_UP:
477
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
478
        break;
479
      case GLP_LO:
480
      case GLP_DB:
481
      case GLP_FX:
482
        if (lo == up)
483
          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
484
        else
485
          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
486
        break;
487
      default:
488
        break;
489
      }
490
    }
491
  }
492

	
493
  GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const {
494
    int b = glp_get_row_type(lp, i);
495
    switch (b) {
496
    case GLP_UP:
497
    case GLP_DB:
498
    case GLP_FX:
499
      return glp_get_row_ub(lp, i);
500
    default:
501
      return INF;
502
    }
503
  }
504

	
505
  void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) {
506
    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
507
      glp_set_obj_coef(lp, i, 0.0);
508
    }
509
    for (ExprIterator it = b; it != e; ++it) {
510
      glp_set_obj_coef(lp, it->first, it->second);
511
    }
512
  }
513

	
514
  void GlpkBase::_getObjCoeffs(InsertIterator b) const {
515
    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
516
      Value val = glp_get_obj_coef(lp, i);
517
      if (val != 0.0) {
518
        *b = std::make_pair(i, val);
519
        ++b;
520
      }
521
    }
522
  }
523

	
524
  void GlpkBase::_setObjCoeff(int i, Value obj_coef) {
525
    //i = 0 means the constant term (shift)
526
    glp_set_obj_coef(lp, i, obj_coef);
527
  }
528

	
529
  GlpkBase::Value GlpkBase::_getObjCoeff(int i) const {
530
    //i = 0 means the constant term (shift)
531
    return glp_get_obj_coef(lp, i);
532
  }
533

	
534
  void GlpkBase::_setSense(GlpkBase::Sense sense) {
535
    switch (sense) {
536
    case MIN:
537
      glp_set_obj_dir(lp, GLP_MIN);
538
      break;
539
    case MAX:
540
      glp_set_obj_dir(lp, GLP_MAX);
541
      break;
542
    }
543
  }
544

	
545
  GlpkBase::Sense GlpkBase::_getSense() const {
546
    switch(glp_get_obj_dir(lp)) {
547
    case GLP_MIN:
548
      return MIN;
549
    case GLP_MAX:
550
      return MAX;
551
    default:
552
      LEMON_ASSERT(false, "Wrong sense");
553
      return GlpkBase::Sense();
554
    }
555
  }
556

	
557
  void GlpkBase::_clear() {
558
    glp_erase_prob(lp);
559
    rows.clear();
560
    cols.clear();
561
  }
562

	
563
  void GlpkBase::freeEnv() {
564
    glp_free_env();
565
  }
566

	
567
  void GlpkBase::_messageLevel(MessageLevel level) {
568
    switch (level) {
569
    case MESSAGE_NOTHING:
570
      _message_level = GLP_MSG_OFF;
571
      break;
572
    case MESSAGE_ERROR:
573
      _message_level = GLP_MSG_ERR;
574
      break;
575
    case MESSAGE_WARNING:
576
      _message_level = GLP_MSG_ERR;
577
      break;
578
    case MESSAGE_NORMAL:
579
      _message_level = GLP_MSG_ON;
580
      break;
581
    case MESSAGE_VERBOSE:
582
      _message_level = GLP_MSG_ALL;
583
      break;
584
    }
585
  }
586

	
587
  GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
588

	
589
  // GlpkLp members
590

	
591
  GlpkLp::GlpkLp()
592
    : LpBase(), LpSolver(), GlpkBase() {
593
    presolver(false);
594
  }
595

	
596
  GlpkLp::GlpkLp(const GlpkLp& other)
597
    : LpBase(other), LpSolver(other), GlpkBase(other) {
598
    presolver(false);
599
  }
600

	
601
  GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
602
  GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
603

	
604
  const char* GlpkLp::_solverName() const { return "GlpkLp"; }
605

	
606
  void GlpkLp::_clear_temporals() {
607
    _primal_ray.clear();
608
    _dual_ray.clear();
609
  }
610

	
611
  GlpkLp::SolveExitStatus GlpkLp::_solve() {
612
    return solvePrimal();
613
  }
614

	
615
  GlpkLp::SolveExitStatus GlpkLp::solvePrimal() {
616
    _clear_temporals();
617

	
618
    glp_smcp smcp;
619
    glp_init_smcp(&smcp);
620

	
621
    smcp.msg_lev = _message_level;
622
    smcp.presolve = _presolve;
623

	
624
    // If the basis is not valid we get an error return value.
625
    // In this case we can try to create a new basis.
626
    switch (glp_simplex(lp, &smcp)) {
627
    case 0:
628
      break;
629
    case GLP_EBADB:
630
    case GLP_ESING:
631
    case GLP_ECOND:
632
      glp_term_out(false);
633
      glp_adv_basis(lp, 0);
634
      glp_term_out(true);
635
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
636
      break;
637
    default:
638
      return UNSOLVED;
639
    }
640

	
641
    return SOLVED;
642
  }
643

	
644
  GlpkLp::SolveExitStatus GlpkLp::solveDual() {
645
    _clear_temporals();
646

	
647
    glp_smcp smcp;
648
    glp_init_smcp(&smcp);
649

	
650
    smcp.msg_lev = _message_level;
651
    smcp.meth = GLP_DUAL;
652
    smcp.presolve = _presolve;
653

	
654
    // If the basis is not valid we get an error return value.
655
    // In this case we can try to create a new basis.
656
    switch (glp_simplex(lp, &smcp)) {
657
    case 0:
658
      break;
659
    case GLP_EBADB:
660
    case GLP_ESING:
661
    case GLP_ECOND:
662
      glp_term_out(false);
663
      glp_adv_basis(lp, 0);
664
      glp_term_out(true);
665
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
666
      break;
667
    default:
668
      return UNSOLVED;
669
    }
670
    return SOLVED;
671
  }
672

	
673
  GlpkLp::Value GlpkLp::_getPrimal(int i) const {
674
    return glp_get_col_prim(lp, i);
675
  }
676

	
677
  GlpkLp::Value GlpkLp::_getDual(int i) const {
678
    return glp_get_row_dual(lp, i);
679
  }
680

	
681
  GlpkLp::Value GlpkLp::_getPrimalValue() const {
682
    return glp_get_obj_val(lp);
683
  }
684

	
685
  GlpkLp::VarStatus GlpkLp::_getColStatus(int i) const {
686
    switch (glp_get_col_stat(lp, i)) {
687
    case GLP_BS:
688
      return BASIC;
689
    case GLP_UP:
690
      return UPPER;
691
    case GLP_LO:
692
      return LOWER;
693
    case GLP_NF:
694
      return FREE;
695
    case GLP_NS:
696
      return FIXED;
697
    default:
698
      LEMON_ASSERT(false, "Wrong column status");
699
      return GlpkLp::VarStatus();
700
    }
701
  }
702

	
703
  GlpkLp::VarStatus GlpkLp::_getRowStatus(int i) const {
704
    switch (glp_get_row_stat(lp, i)) {
705
    case GLP_BS:
706
      return BASIC;
707
    case GLP_UP:
708
      return UPPER;
709
    case GLP_LO:
710
      return LOWER;
711
    case GLP_NF:
712
      return FREE;
713
    case GLP_NS:
714
      return FIXED;
715
    default:
716
      LEMON_ASSERT(false, "Wrong row status");
717
      return GlpkLp::VarStatus();
718
    }
719
  }
720

	
721
  GlpkLp::Value GlpkLp::_getPrimalRay(int i) const {
722
    if (_primal_ray.empty()) {
723
      int row_num = glp_get_num_rows(lp);
724
      int col_num = glp_get_num_cols(lp);
725

	
726
      _primal_ray.resize(col_num + 1, 0.0);
727

	
728
      int index = glp_get_unbnd_ray(lp);
729
      if (index != 0) {
730
        // The primal ray is found in primal simplex second phase
731
        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
732
                      glp_get_col_stat(lp, index - row_num)) != GLP_BS,
733
                     "Wrong primal ray");
734

	
735
        bool negate = glp_get_obj_dir(lp) == GLP_MAX;
736

	
737
        if (index > row_num) {
738
          _primal_ray[index - row_num] = 1.0;
739
          if (glp_get_col_dual(lp, index - row_num) > 0) {
740
            negate = !negate;
741
          }
742
        } else {
743
          if (glp_get_row_dual(lp, index) > 0) {
744
            negate = !negate;
745
          }
746
        }
747

	
748
        std::vector<int> ray_indexes(row_num + 1);
749
        std::vector<Value> ray_values(row_num + 1);
750
        int ray_length = glp_eval_tab_col(lp, index, &ray_indexes.front(),
751
                                          &ray_values.front());
752

	
753
        for (int i = 1; i <= ray_length; ++i) {
754
          if (ray_indexes[i] > row_num) {
755
            _primal_ray[ray_indexes[i] - row_num] = ray_values[i];
756
          }
757
        }
758

	
759
        if (negate) {
760
          for (int i = 1; i <= col_num; ++i) {
761
            _primal_ray[i] = - _primal_ray[i];
762
          }
763
        }
764
      } else {
765
        for (int i = 1; i <= col_num; ++i) {
766
          _primal_ray[i] = glp_get_col_prim(lp, i);
767
        }
768
      }
769
    }
770
    return _primal_ray[i];
771
  }
772

	
773
  GlpkLp::Value GlpkLp::_getDualRay(int i) const {
774
    if (_dual_ray.empty()) {
775
      int row_num = glp_get_num_rows(lp);
776

	
777
      _dual_ray.resize(row_num + 1, 0.0);
778

	
779
      int index = glp_get_unbnd_ray(lp);
780
      if (index != 0) {
781
        // The dual ray is found in dual simplex second phase
782
        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
783
                      glp_get_col_stat(lp, index - row_num)) == GLP_BS,
784

	
785
                     "Wrong dual ray");
786

	
787
        int idx;
788
        bool negate = false;
789

	
790
        if (index > row_num) {
791
          idx = glp_get_col_bind(lp, index - row_num);
792
          if (glp_get_col_prim(lp, index - row_num) >
793
              glp_get_col_ub(lp, index - row_num)) {
794
            negate = true;
795
          }
796
        } else {
797
          idx = glp_get_row_bind(lp, index);
798
          if (glp_get_row_prim(lp, index) > glp_get_row_ub(lp, index)) {
799
            negate = true;
800
          }
801
        }
802

	
803
        _dual_ray[idx] = negate ?  - 1.0 : 1.0;
804

	
805
        glp_btran(lp, &_dual_ray.front());
806
      } else {
807
        double eps = 1e-7;
808
        // The dual ray is found in primal simplex first phase
809
        // We assume that the glpk minimizes the slack to get feasible solution
810
        for (int i = 1; i <= row_num; ++i) {
811
          int index = glp_get_bhead(lp, i);
812
          if (index <= row_num) {
813
            double res = glp_get_row_prim(lp, index);
814
            if (res > glp_get_row_ub(lp, index) + eps) {
815
              _dual_ray[i] = -1;
816
            } else if (res < glp_get_row_lb(lp, index) - eps) {
817
              _dual_ray[i] = 1;
818
            } else {
819
              _dual_ray[i] = 0;
820
            }
821
            _dual_ray[i] *= glp_get_rii(lp, index);
822
          } else {
823
            double res = glp_get_col_prim(lp, index - row_num);
824
            if (res > glp_get_col_ub(lp, index - row_num) + eps) {
825
              _dual_ray[i] = -1;
826
            } else if (res < glp_get_col_lb(lp, index - row_num) - eps) {
827
              _dual_ray[i] = 1;
828
            } else {
829
              _dual_ray[i] = 0;
830
            }
831
            _dual_ray[i] /= glp_get_sjj(lp, index - row_num);
832
          }
833
        }
834

	
835
        glp_btran(lp, &_dual_ray.front());
836

	
837
        for (int i = 1; i <= row_num; ++i) {
838
          _dual_ray[i] /= glp_get_rii(lp, i);
839
        }
840
      }
841
    }
842
    return _dual_ray[i];
843
  }
844

	
845
  GlpkLp::ProblemType GlpkLp::_getPrimalType() const {
846
    if (glp_get_status(lp) == GLP_OPT)
847
      return OPTIMAL;
848
    switch (glp_get_prim_stat(lp)) {
849
    case GLP_UNDEF:
850
      return UNDEFINED;
851
    case GLP_FEAS:
852
    case GLP_INFEAS:
853
      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
854
        return UNBOUNDED;
855
      } else {
856
        return UNDEFINED;
857
      }
858
    case GLP_NOFEAS:
859
      return INFEASIBLE;
860
    default:
861
      LEMON_ASSERT(false, "Wrong primal type");
862
      return  GlpkLp::ProblemType();
863
    }
864
  }
865

	
866
  GlpkLp::ProblemType GlpkLp::_getDualType() const {
867
    if (glp_get_status(lp) == GLP_OPT)
868
      return OPTIMAL;
869
    switch (glp_get_dual_stat(lp)) {
870
    case GLP_UNDEF:
871
      return UNDEFINED;
872
    case GLP_FEAS:
873
    case GLP_INFEAS:
874
      if (glp_get_prim_stat(lp) == GLP_NOFEAS) {
875
        return UNBOUNDED;
876
      } else {
877
        return UNDEFINED;
878
      }
879
    case GLP_NOFEAS:
880
      return INFEASIBLE;
881
    default:
882
      LEMON_ASSERT(false, "Wrong primal type");
883
      return  GlpkLp::ProblemType();
884
    }
885
  }
886

	
887
  void GlpkLp::presolver(bool presolve) {
888
    _presolve = presolve;
889
  }
890

	
891
  // GlpkMip members
892

	
893
  GlpkMip::GlpkMip()
894
    : LpBase(), MipSolver(), GlpkBase() {
895
  }
896

	
897
  GlpkMip::GlpkMip(const GlpkMip& other)
898
    : LpBase(), MipSolver(), GlpkBase(other) {
899
  }
900

	
901
  void GlpkMip::_setColType(int i, GlpkMip::ColTypes col_type) {
902
    switch (col_type) {
903
    case INTEGER:
904
      glp_set_col_kind(lp, i, GLP_IV);
905
      break;
906
    case REAL:
907
      glp_set_col_kind(lp, i, GLP_CV);
908
      break;
909
    }
910
  }
911

	
912
  GlpkMip::ColTypes GlpkMip::_getColType(int i) const {
913
    switch (glp_get_col_kind(lp, i)) {
914
    case GLP_IV:
915
    case GLP_BV:
916
      return INTEGER;
917
    default:
918
      return REAL;
919
    }
920

	
921
  }
922

	
923
  GlpkMip::SolveExitStatus GlpkMip::_solve() {
924
    glp_smcp smcp;
925
    glp_init_smcp(&smcp);
926

	
927
    smcp.msg_lev = _message_level;
928
    smcp.meth = GLP_DUAL;
929

	
930
    // If the basis is not valid we get an error return value.
931
    // In this case we can try to create a new basis.
932
    switch (glp_simplex(lp, &smcp)) {
933
    case 0:
934
      break;
935
    case GLP_EBADB:
936
    case GLP_ESING:
937
    case GLP_ECOND:
938
      glp_term_out(false);
939
      glp_adv_basis(lp, 0);
940
      glp_term_out(true);
941
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
942
      break;
943
    default:
944
      return UNSOLVED;
945
    }
946

	
947
    if (glp_get_status(lp) != GLP_OPT) return SOLVED;
948

	
949
    glp_iocp iocp;
950
    glp_init_iocp(&iocp);
951

	
952
    iocp.msg_lev = _message_level;
953

	
954
    if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
955
    return SOLVED;
956
  }
957

	
958

	
959
  GlpkMip::ProblemType GlpkMip::_getType() const {
960
    switch (glp_get_status(lp)) {
961
    case GLP_OPT:
962
      switch (glp_mip_status(lp)) {
963
      case GLP_UNDEF:
964
        return UNDEFINED;
965
      case GLP_NOFEAS:
966
        return INFEASIBLE;
967
      case GLP_FEAS:
968
        return FEASIBLE;
969
      case GLP_OPT:
970
        return OPTIMAL;
971
      default:
972
        LEMON_ASSERT(false, "Wrong problem type.");
973
        return GlpkMip::ProblemType();
974
      }
975
    case GLP_NOFEAS:
976
      return INFEASIBLE;
977
    case GLP_INFEAS:
978
    case GLP_FEAS:
979
      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
980
        return UNBOUNDED;
981
      } else {
982
        return UNDEFINED;
983
      }
984
    default:
985
      LEMON_ASSERT(false, "Wrong problem type.");
986
      return GlpkMip::ProblemType();
987
    }
988
  }
989

	
990
  GlpkMip::Value GlpkMip::_getSol(int i) const {
991
    return glp_mip_col_val(lp, i);
992
  }
993

	
994
  GlpkMip::Value GlpkMip::_getSolValue() const {
995
    return glp_mip_obj_val(lp);
996
  }
997

	
998
  GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; }
999
  GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); }
1000

	
1001
  const char* GlpkMip::_solverName() const { return "GlpkMip"; }
1002

	
1003
} //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
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
58

	
59
    virtual void _eraseCol(int i);
60
    virtual void _eraseRow(int i);
61

	
62
    virtual void _eraseColId(int i);
63
    virtual void _eraseRowId(int i);
64

	
65
    virtual void _getColName(int col, std::string& name) const;
66
    virtual void _setColName(int col, const std::string& name);
67
    virtual int _colByName(const std::string& name) const;
68

	
69
    virtual void _getRowName(int row, std::string& name) const;
70
    virtual void _setRowName(int row, const std::string& name);
71
    virtual int _rowByName(const std::string& name) const;
72

	
73
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
74
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
75

	
76
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
77
    virtual void _getColCoeffs(int i, InsertIterator b) const;
78

	
79
    virtual void _setCoeff(int row, int col, Value value);
80
    virtual Value _getCoeff(int row, int col) const;
81

	
82
    virtual void _setColLowerBound(int i, Value value);
83
    virtual Value _getColLowerBound(int i) const;
84

	
85
    virtual void _setColUpperBound(int i, Value value);
86
    virtual Value _getColUpperBound(int i) const;
87

	
88
    virtual void _setRowLowerBound(int i, Value value);
89
    virtual Value _getRowLowerBound(int i) const;
90

	
91
    virtual void _setRowUpperBound(int i, Value value);
92
    virtual Value _getRowUpperBound(int i) const;
93

	
94
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
95
    virtual void _getObjCoeffs(InsertIterator b) const;
96

	
97
    virtual void _setObjCoeff(int i, Value obj_coef);
98
    virtual Value _getObjCoeff(int i) const;
99

	
100
    virtual void _setSense(Sense);
101
    virtual Sense _getSense() const;
102

	
103
    virtual void _clear();
104

	
105
    virtual void _messageLevel(MessageLevel level);
106

	
107
  private:
108

	
109
    static void freeEnv();
110

	
111
    struct FreeEnvHelper {
112
      ~FreeEnvHelper() {
113
        freeEnv();
114
      }
115
    };
116
    
117
    static FreeEnvHelper freeEnvHelper;
118

	
119
  protected:
120
    
121
    int _message_level;
122
    
123
  public:
124

	
125
    ///Pointer to the underlying GLPK data structure.
126
    LPX *lpx() {return lp;}
127
    ///Const pointer to the underlying GLPK data structure.
128
    const LPX *lpx() const {return lp;}
129

	
130
    ///Returns the constraint identifier understood by GLPK.
131
    int lpxRow(Row r) const { return rows(id(r)); }
132

	
133
    ///Returns the variable identifier understood by GLPK.
134
    int lpxCol(Col c) const { return cols(id(c)); }
135

	
136
  };
137

	
138
  /// \brief Interface for the GLPK LP solver
139
  ///
140
  /// This class implements an interface for the GLPK LP solver.
141
  ///\ingroup lp_group
142
  class GlpkLp : public LpSolver, public GlpkBase {
143
  public:
144

	
145
    ///\e
146
    GlpkLp();
147
    ///\e
148
    GlpkLp(const GlpkLp&);
149

	
150
    ///\e
151
    virtual GlpkLp* cloneSolver() const;
152
    ///\e
153
    virtual GlpkLp* newSolver() const;
154

	
155
  private:
156

	
157
    mutable std::vector<double> _primal_ray;
158
    mutable std::vector<double> _dual_ray;
159

	
160
    void _clear_temporals();
161

	
162
  protected:
163

	
164
    virtual const char* _solverName() const;
165

	
166
    virtual SolveExitStatus _solve();
167
    virtual Value _getPrimal(int i) const;
168
    virtual Value _getDual(int i) const;
169

	
170
    virtual Value _getPrimalValue() const;
171

	
172
    virtual VarStatus _getColStatus(int i) const;
173
    virtual VarStatus _getRowStatus(int i) const;
174

	
175
    virtual Value _getPrimalRay(int i) const;
176
    virtual Value _getDualRay(int i) const;
177

	
178
    virtual ProblemType _getPrimalType() const;
179
    virtual ProblemType _getDualType() const;
180

	
181
  public:
182

	
183
    ///Solve with primal simplex
184
    SolveExitStatus solvePrimal();
185

	
186
    ///Solve with dual simplex
187
    SolveExitStatus solveDual();
188

	
189
  private:
190

	
191
    bool _presolve;
192

	
193
  public:
194

	
195
    ///Turns on or off the presolver
196

	
197
    ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
198
    ///
199
    ///The presolver is off by default.
200
    void presolver(bool presolve);
201

	
202
  };
203

	
204
  /// \brief Interface for the GLPK MIP solver
205
  ///
206
  /// This class implements an interface for the GLPK MIP solver.
207
  ///\ingroup lp_group
208
  class GlpkMip : public MipSolver, public GlpkBase {
209
  public:
210

	
211
    ///\e
212
    GlpkMip();
213
    ///\e
214
    GlpkMip(const GlpkMip&);
215

	
216
    virtual GlpkMip* cloneSolver() const;
217
    virtual GlpkMip* newSolver() const;
218

	
219
  protected:
220

	
221
    virtual const char* _solverName() const;
222

	
223
    virtual ColTypes _getColType(int col) const;
224
    virtual void _setColType(int col, ColTypes col_type);
225

	
226
    virtual SolveExitStatus _solve();
227
    virtual ProblemType _getType() const;
228
    virtual Value _getSol(int i) const;
229
    virtual Value _getSolValue() const;
230

	
231
  };
232

	
233

	
234
} //END OF NAMESPACE LEMON
235

	
236
#endif //LEMON_GLPK_H
237

	
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
    /// GomoryHu<Graph> gom(g, capacities);
363
    /// gom.run();
364
    /// int cnt=0;
365
    /// for(GomoryHu<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
    /// GomoryHu<Graph> gom(g, capacities);
460
    /// gom.run();
461
    /// int value=0;
462
    /// for(GomoryHu<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
  /// GridGraph implements a special graph type. The nodes of the
474
  /// graph can be indexed by two integer values \c (i,j) where \c i is
475
  /// in the range <tt>[0..width()-1]</tt> and j is in the range
476
  /// <tt>[0..height()-1]</tt>. Two nodes are connected in the graph if
477
  /// the indices differ exactly on one position and the difference is
478
  /// also exactly one. The nodes of the graph can be obtained by position
479
  /// using the \c operator()() function and the indices of the nodes can
480
  /// be obtained using \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
  /// This class is completely static and it needs constant memory space.
486
  /// Thus you can neither add nor delete nodes or edges, however
487
  /// the structure can be resized using resize().
488
  ///
489
  /// \image html grid_graph.png
490
  /// \image latex grid_graph.eps "Grid graph" width=\textwidth
491
  ///
492
  /// A short example about the basic usage:
493
  ///\code
494
  /// GridGraph graph(rows, cols);
495
  /// GridGraph::NodeMap<int> val(graph);
496
  /// for (int i = 0; i < graph.width(); ++i) {
497
  ///   for (int j = 0; j < graph.height(); ++j) {
498
  ///     val[graph(i, j)] = i + j;
499
  ///   }
500
  /// }
501
  ///\endcode
502
  ///
503
  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
504
  /// Most of its member functions and nested classes are documented
505
  /// only in the concept class.
506
  class GridGraph : public ExtendedGridGraphBase {
507
    typedef ExtendedGridGraphBase Parent;
508

	
509
  public:
510

	
511
    /// \brief Map to get the indices of the nodes as \ref dim2::Point
512
    /// "dim2::Point<int>".
513
    ///
514
    /// Map to get the indices of the nodes as \ref dim2::Point
515
    /// "dim2::Point<int>".
516
    class IndexMap {
517
    public:
518
      /// \brief The key type of the map
519
      typedef GridGraph::Node Key;
520
      /// \brief The value type of the map
521
      typedef dim2::Point<int> Value;
522

	
523
      /// \brief Constructor
524
      IndexMap(const GridGraph& graph) : _graph(graph) {}
525

	
526
      /// \brief The subscript operator
527
      Value operator[](Key key) const {
528
        return _graph.pos(key);
529
      }
530

	
531
    private:
532
      const GridGraph& _graph;
533
    };
534

	
535
    /// \brief Map to get the column of the nodes.
536
    ///
537
    /// Map to get the column of the nodes.
538
    class ColMap {
539
    public:
540
      /// \brief The key type of the map
541
      typedef GridGraph::Node Key;
542
      /// \brief The value type of the map
543
      typedef int Value;
544

	
545
      /// \brief Constructor
546
      ColMap(const GridGraph& graph) : _graph(graph) {}
547

	
548
      /// \brief The subscript operator
549
      Value operator[](Key key) const {
550
        return _graph.col(key);
551
      }
552

	
553
    private:
554
      const GridGraph& _graph;
555
    };
556

	
557
    /// \brief Map to get the row of the nodes.
558
    ///
559
    /// Map to get the row of the nodes.
560
    class RowMap {
561
    public:
562
      /// \brief The key type of the map
563
      typedef GridGraph::Node Key;
564
      /// \brief The value type of the map
565
      typedef int Value;
566

	
567
      /// \brief Constructor
568
      RowMap(const GridGraph& graph) : _graph(graph) {}
569

	
570
      /// \brief The subscript operator
571
      Value operator[](Key key) const {
572
        return _graph.row(key);
573
      }
574

	
575
    private:
576
      const GridGraph& _graph;
577
    };
578

	
579
    /// \brief Constructor
580
    ///
581
    /// Construct a grid graph with the given size.
582
    GridGraph(int width, int height) { construct(width, height); }
583

	
584
    /// \brief Resizes the graph
585
    ///
586
    /// This function resizes the graph. It fully destroys and
587
    /// rebuilds the structure, therefore the maps of the graph will be
588
    /// reallocated automatically and the previous values will be lost.
589
    void resize(int width, int height) {
590
      Parent::notifier(Arc()).clear();
591
      Parent::notifier(Edge()).clear();
592
      Parent::notifier(Node()).clear();
593
      construct(width, height);
594
      Parent::notifier(Node()).build();
595
      Parent::notifier(Edge()).build();
596
      Parent::notifier(Arc()).build();
597
    }
598

	
599
    /// \brief The node on the given position.
600
    ///
601
    /// Gives back the node on the given position.
602
    Node operator()(int i, int j) const {
603
      return Parent::operator()(i, j);
604
    }
605

	
606
    /// \brief The column index of the node.
607
    ///
608
    /// Gives back the column index of the node.
609
    int col(Node n) const {
610
      return Parent::col(n);
611
    }
612

	
613
    /// \brief The row index of the node.
614
    ///
615
    /// Gives back the row index of the node.
616
    int row(Node n) const {
617
      return Parent::row(n);
618
    }
619

	
620
    /// \brief The position of the node.
621
    ///
622
    /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
623
    dim2::Point<int> pos(Node n) const {
624
      return Parent::pos(n);
625
    }
626

	
627
    /// \brief The number of the columns.
628
    ///
629
    /// Gives back the number of the columns.
630
    int width() const {
631
      return Parent::width();
632
    }
633

	
634
    /// \brief The number of the rows.
635
    ///
636
    /// Gives back the number of the rows.
637
    int height() const {
638
      return Parent::height();
639
    }
640

	
641
    /// \brief The arc goes right from the node.
642
    ///
643
    /// Gives back the arc goes right from the node. If there is not
644
    /// outgoing arc then it gives back INVALID.
645
    Arc right(Node n) const {
646
      return Parent::right(n);
647
    }
648

	
649
    /// \brief The arc goes left from the node.
650
    ///
651
    /// Gives back the arc goes left from the node. If there is not
652
    /// outgoing arc then it gives back INVALID.
653
    Arc left(Node n) const {
654
      return Parent::left(n);
655
    }
656

	
657
    /// \brief The arc goes up from the node.
658
    ///
659
    /// Gives back the arc goes up from the node. If there is not
660
    /// outgoing arc then it gives back INVALID.
661
    Arc up(Node n) const {
662
      return Parent::up(n);
663
    }
664

	
665
    /// \brief The arc goes down from the node.
666
    ///
667
    /// Gives back the arc goes down from the node. If there is not
668
    /// outgoing arc then it gives back INVALID.
669
    Arc down(Node n) const {
670
      return Parent::down(n);
671
    }
672

	
673
    /// \brief Index map of the grid graph
674
    ///
675
    /// Just returns an IndexMap for the grid graph.
676
    IndexMap indexMap() const {
677
      return IndexMap(*this);
678
    }
679

	
680
    /// \brief Row map of the grid graph
681
    ///
682
    /// Just returns a RowMap for the grid graph.
683
    RowMap rowMap() const {
684
      return RowMap(*this);
685
    }
686

	
687
    /// \brief Column map of the grid graph
688
    ///
689
    /// Just returns a ColMap for the grid graph.
690
    ColMap colMap() const {
691
      return ColMap(*this);
692
    }
693

	
694
  };
695

	
696
}
697
#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
/* -*- 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_HARTMANN_ORLIN_H
20
#define LEMON_HARTMANN_ORLIN_H
21

	
22
/// \ingroup min_mean_cycle
23
///
24
/// \file
25
/// \brief Hartmann-Orlin's algorithm for finding a minimum mean cycle.
26

	
27
#include <vector>
28
#include <limits>
29
#include <lemon/core.h>
30
#include <lemon/path.h>
31
#include <lemon/tolerance.h>
32
#include <lemon/connectivity.h>
33

	
34
namespace lemon {
35

	
36
  /// \brief Default traits class of HartmannOrlin algorithm.
37
  ///
38
  /// Default traits class of HartmannOrlin algorithm.
39
  /// \tparam GR The type of the digraph.
40
  /// \tparam LEN The type of the length map.
41
  /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
42
#ifdef DOXYGEN
43
  template <typename GR, typename LEN>
44
#else
45
  template <typename GR, typename LEN,
46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
47
#endif
48
  struct HartmannOrlinDefaultTraits
49
  {
50
    /// The type of the digraph
51
    typedef GR Digraph;
52
    /// The type of the length map
53
    typedef LEN LengthMap;
54
    /// The type of the arc lengths
55
    typedef typename LengthMap::Value Value;
56

	
57
    /// \brief The large value type used for internal computations
58
    ///
59
    /// The large value type used for internal computations.
60
    /// It is \c long \c long if the \c Value type is integer,
61
    /// otherwise it is \c double.
62
    /// \c Value must be convertible to \c LargeValue.
63
    typedef double LargeValue;
64

	
65
    /// The tolerance type used for internal computations
66
    typedef lemon::Tolerance<LargeValue> Tolerance;
67

	
68
    /// \brief The path type of the found cycles
69
    ///
70
    /// The path type of the found cycles.
71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
72
    /// and it must have an \c addFront() function.
73
    typedef lemon::Path<Digraph> Path;
74
  };
75

	
76
  // Default traits class for integer value types
77
  template <typename GR, typename LEN>
78
  struct HartmannOrlinDefaultTraits<GR, LEN, true>
79
  {
80
    typedef GR Digraph;
81
    typedef LEN LengthMap;
82
    typedef typename LengthMap::Value Value;
83
#ifdef LEMON_HAVE_LONG_LONG
84
    typedef long long LargeValue;
85
#else
86
    typedef long LargeValue;
87
#endif
88
    typedef lemon::Tolerance<LargeValue> Tolerance;
89
    typedef lemon::Path<Digraph> Path;
90
  };
91

	
92

	
93
  /// \addtogroup min_mean_cycle
94
  /// @{
95

	
96
  /// \brief Implementation of the Hartmann-Orlin algorithm for finding
97
  /// a minimum mean cycle.
98
  ///
99
  /// This class implements the Hartmann-Orlin algorithm for finding
100
  /// a directed cycle of minimum mean length (cost) in a digraph
101
  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
102
  /// It is an improved version of \ref Karp "Karp"'s original algorithm,
103
  /// it applies an efficient early termination scheme.
104
  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
105
  ///
106
  /// \tparam GR The type of the digraph the algorithm runs on.
107
  /// \tparam LEN The type of the length map. The default
108
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
109
#ifdef DOXYGEN
110
  template <typename GR, typename LEN, typename TR>
111
#else
112
  template < typename GR,
113
             typename LEN = typename GR::template ArcMap<int>,
114
             typename TR = HartmannOrlinDefaultTraits<GR, LEN> >
115
#endif
116
  class HartmannOrlin
117
  {
118
  public:
119

	
120
    /// The type of the digraph
121
    typedef typename TR::Digraph Digraph;
122
    /// The type of the length map
123
    typedef typename TR::LengthMap LengthMap;
124
    /// The type of the arc lengths
125
    typedef typename TR::Value Value;
126

	
127
    /// \brief The large value type
128
    ///
129
    /// The large value type used for internal computations.
130
    /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
131
    /// it is \c long \c long if the \c Value type is integer,
132
    /// otherwise it is \c double.
133
    typedef typename TR::LargeValue LargeValue;
134

	
135
    /// The tolerance type
136
    typedef typename TR::Tolerance Tolerance;
137

	
138
    /// \brief The path type of the found cycles
139
    ///
140
    /// The path type of the found cycles.
141
    /// Using the \ref HartmannOrlinDefaultTraits "default traits class",
142
    /// it is \ref lemon::Path "Path<Digraph>".
143
    typedef typename TR::Path Path;
144

	
145
    /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm
146
    typedef TR Traits;
147

	
148
  private:
149

	
150
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
151

	
152
    // Data sturcture for path data
153
    struct PathData
154
    {
155
      LargeValue dist;
156
      Arc pred;
157
      PathData(LargeValue d, Arc p = INVALID) :
158
        dist(d), pred(p) {}
159
    };
160

	
161
    typedef typename Digraph::template NodeMap<std::vector<PathData> >
162
      PathDataNodeMap;
163

	
164
  private:
165

	
166
    // The digraph the algorithm runs on
167
    const Digraph &_gr;
168
    // The length of the arcs
169
    const LengthMap &_length;
170

	
171
    // Data for storing the strongly connected components
172
    int _comp_num;
173
    typename Digraph::template NodeMap<int> _comp;
174
    std::vector<std::vector<Node> > _comp_nodes;
175
    std::vector<Node>* _nodes;
176
    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
177

	
178
    // Data for the found cycles
179
    bool _curr_found, _best_found;
180
    LargeValue _curr_length, _best_length;
181
    int _curr_size, _best_size;
182
    Node _curr_node, _best_node;
183
    int _curr_level, _best_level;
184

	
185
    Path *_cycle_path;
186
    bool _local_path;
187

	
188
    // Node map for storing path data
189
    PathDataNodeMap _data;
190
    // The processed nodes in the last round
191
    std::vector<Node> _process;
192

	
193
    Tolerance _tolerance;
194

	
195
    // Infinite constant
196
    const LargeValue INF;
197

	
198
  public:
199

	
200
    /// \name Named Template Parameters
201
    /// @{
202

	
203
    template <typename T>
204
    struct SetLargeValueTraits : public Traits {
205
      typedef T LargeValue;
206
      typedef lemon::Tolerance<T> Tolerance;
207
    };
208

	
209
    /// \brief \ref named-templ-param "Named parameter" for setting
210
    /// \c LargeValue type.
211
    ///
212
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
213
    /// type. It is used for internal computations in the algorithm.
214
    template <typename T>
215
    struct SetLargeValue
216
      : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > {
217
      typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > Create;
218
    };
219

	
220
    template <typename T>
221
    struct SetPathTraits : public Traits {
222
      typedef T Path;
223
    };
224

	
225
    /// \brief \ref named-templ-param "Named parameter" for setting
226
    /// \c %Path type.
227
    ///
228
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
229
    /// type of the found cycles.
230
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
231
    /// and it must have an \c addFront() function.
232
    template <typename T>
233
    struct SetPath
234
      : public HartmannOrlin<GR, LEN, SetPathTraits<T> > {
235
      typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create;
236
    };
237

	
238
    /// @}
239

	
240
  public:
241

	
242
    /// \brief Constructor.
243
    ///
244
    /// The constructor of the class.
245
    ///
246
    /// \param digraph The digraph the algorithm runs on.
247
    /// \param length The lengths (costs) of the arcs.
248
    HartmannOrlin( const Digraph &digraph,
249
                   const LengthMap &length ) :
250
      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
251
      _best_found(false), _best_length(0), _best_size(1),
252
      _cycle_path(NULL), _local_path(false), _data(digraph),
253
      INF(std::numeric_limits<LargeValue>::has_infinity ?
254
          std::numeric_limits<LargeValue>::infinity() :
255
          std::numeric_limits<LargeValue>::max())
256
    {}
257

	
258
    /// Destructor.
259
    ~HartmannOrlin() {
260
      if (_local_path) delete _cycle_path;
261
    }
262

	
263
    /// \brief Set the path structure for storing the found cycle.
264
    ///
265
    /// This function sets an external path structure for storing the
266
    /// found cycle.
267
    ///
268
    /// If you don't call this function before calling \ref run() or
269
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
270
    /// structure. The destuctor deallocates this automatically
271
    /// allocated object, of course.
272
    ///
273
    /// \note The algorithm calls only the \ref lemon::Path::addFront()
274
    /// "addFront()" function of the given path structure.
275
    ///
276
    /// \return <tt>(*this)</tt>
277
    HartmannOrlin& cycle(Path &path) {
278
      if (_local_path) {
279
        delete _cycle_path;
280
        _local_path = false;
281
      }
282
      _cycle_path = &path;
283
      return *this;
284
    }
285

	
286
    /// \brief Set the tolerance used by the algorithm.
287
    ///
288
    /// This function sets the tolerance object used by the algorithm.
289
    ///
290
    /// \return <tt>(*this)</tt>
291
    HartmannOrlin& tolerance(const Tolerance& tolerance) {
292
      _tolerance = tolerance;
293
      return *this;
294
    }
295

	
296
    /// \brief Return a const reference to the tolerance.
297
    ///
298
    /// This function returns a const reference to the tolerance object
299
    /// used by the algorithm.
300
    const Tolerance& tolerance() const {
301
      return _tolerance;
302
    }
303

	
304
    /// \name Execution control
305
    /// The simplest way to execute the algorithm is to call the \ref run()
306
    /// function.\n
307
    /// If you only need the minimum mean length, you may call
308
    /// \ref findMinMean().
309

	
310
    /// @{
311

	
312
    /// \brief Run the algorithm.
313
    ///
314
    /// This function runs the algorithm.
315
    /// It can be called more than once (e.g. if the underlying digraph
316
    /// and/or the arc lengths have been modified).
317
    ///
318
    /// \return \c true if a directed cycle exists in the digraph.
319
    ///
320
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
321
    /// \code
322
    ///   return mmc.findMinMean() && mmc.findCycle();
323
    /// \endcode
324
    bool run() {
325
      return findMinMean() && findCycle();
326
    }
327

	
328
    /// \brief Find the minimum cycle mean.
329
    ///
330
    /// This function finds the minimum mean length of the directed
331
    /// cycles in the digraph.
332
    ///
333
    /// \return \c true if a directed cycle exists in the digraph.
334
    bool findMinMean() {
335
      // Initialization and find strongly connected components
336
      init();
337
      findComponents();
338
      
339
      // Find the minimum cycle mean in the components
340
      for (int comp = 0; comp < _comp_num; ++comp) {
341
        if (!initComponent(comp)) continue;
342
        processRounds();
343
        
344
        // Update the best cycle (global minimum mean cycle)
345
        if ( _curr_found && (!_best_found || 
346
             _curr_length * _best_size < _best_length * _curr_size) ) {
347
          _best_found = true;
348
          _best_length = _curr_length;
349
          _best_size = _curr_size;
350
          _best_node = _curr_node;
351
          _best_level = _curr_level;
352
        }
353
      }
354
      return _best_found;
355
    }
356

	
357
    /// \brief Find a minimum mean directed cycle.
358
    ///
359
    /// This function finds a directed cycle of minimum mean length
360
    /// in the digraph using the data computed by findMinMean().
361
    ///
362
    /// \return \c true if a directed cycle exists in the digraph.
363
    ///
364
    /// \pre \ref findMinMean() must be called before using this function.
365
    bool findCycle() {
366
      if (!_best_found) return false;
367
      IntNodeMap reached(_gr, -1);
368
      int r = _best_level + 1;
369
      Node u = _best_node;
370
      while (reached[u] < 0) {
371
        reached[u] = --r;
372
        u = _gr.source(_data[u][r].pred);
373
      }
374
      r = reached[u];
375
      Arc e = _data[u][r].pred;
376
      _cycle_path->addFront(e);
377
      _best_length = _length[e];
378
      _best_size = 1;
379
      Node v;
380
      while ((v = _gr.source(e)) != u) {
381
        e = _data[v][--r].pred;
382
        _cycle_path->addFront(e);
383
        _best_length += _length[e];
384
        ++_best_size;
385
      }
386
      return true;
387
    }
388

	
389
    /// @}
390

	
391
    /// \name Query Functions
392
    /// The results of the algorithm can be obtained using these
393
    /// functions.\n
394
    /// The algorithm should be executed before using them.
395

	
396
    /// @{
397

	
398
    /// \brief Return the total length of the found cycle.
399
    ///
400
    /// This function returns the total length of the found cycle.
401
    ///
402
    /// \pre \ref run() or \ref findMinMean() must be called before
403
    /// using this function.
404
    LargeValue cycleLength() const {
405
      return _best_length;
406
    }
407

	
408
    /// \brief Return the number of arcs on the found cycle.
409
    ///
410
    /// This function returns the number of arcs on the found cycle.
411
    ///
412
    /// \pre \ref run() or \ref findMinMean() must be called before
413
    /// using this function.
414
    int cycleArcNum() const {
415
      return _best_size;
416
    }
417

	
418
    /// \brief Return the mean length of the found cycle.
419
    ///
420
    /// This function returns the mean length of the found cycle.
421
    ///
422
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
423
    /// following code.
424
    /// \code
425
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
426
    /// \endcode
427
    ///
428
    /// \pre \ref run() or \ref findMinMean() must be called before
429
    /// using this function.
430
    double cycleMean() const {
431
      return static_cast<double>(_best_length) / _best_size;
432
    }
433

	
434
    /// \brief Return the found cycle.
435
    ///
436
    /// This function returns a const reference to the path structure
437
    /// storing the found cycle.
438
    ///
439
    /// \pre \ref run() or \ref findCycle() must be called before using
440
    /// this function.
441
    const Path& cycle() const {
442
      return *_cycle_path;
443
    }
444

	
445
    ///@}
446

	
447
  private:
448

	
449
    // Initialization
450
    void init() {
451
      if (!_cycle_path) {
452
        _local_path = true;
453
        _cycle_path = new Path;
454
      }
455
      _cycle_path->clear();
456
      _best_found = false;
457
      _best_length = 0;
458
      _best_size = 1;
459
      _cycle_path->clear();
460
      for (NodeIt u(_gr); u != INVALID; ++u)
461
        _data[u].clear();
462
    }
463

	
464
    // Find strongly connected components and initialize _comp_nodes
465
    // and _out_arcs
466
    void findComponents() {
467
      _comp_num = stronglyConnectedComponents(_gr, _comp);
468
      _comp_nodes.resize(_comp_num);
469
      if (_comp_num == 1) {
470
        _comp_nodes[0].clear();
471
        for (NodeIt n(_gr); n != INVALID; ++n) {
472
          _comp_nodes[0].push_back(n);
473
          _out_arcs[n].clear();
474
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
475
            _out_arcs[n].push_back(a);
476
          }
477
        }
478
      } else {
479
        for (int i = 0; i < _comp_num; ++i)
480
          _comp_nodes[i].clear();
481
        for (NodeIt n(_gr); n != INVALID; ++n) {
482
          int k = _comp[n];
483
          _comp_nodes[k].push_back(n);
484
          _out_arcs[n].clear();
485
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
486
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
487
          }
488
        }
489
      }
490
    }
491

	
492
    // Initialize path data for the current component
493
    bool initComponent(int comp) {
494
      _nodes = &(_comp_nodes[comp]);
495
      int n = _nodes->size();
496
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
497
        return false;
498
      }      
499
      for (int i = 0; i < n; ++i) {
500
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
501
      }
502
      return true;
503
    }
504

	
505
    // Process all rounds of computing path data for the current component.
506
    // _data[v][k] is the length of a shortest directed walk from the root
507
    // node to node v containing exactly k arcs.
508
    void processRounds() {
509
      Node start = (*_nodes)[0];
510
      _data[start][0] = PathData(0);
511
      _process.clear();
512
      _process.push_back(start);
513

	
514
      int k, n = _nodes->size();
515
      int next_check = 4;
516
      bool terminate = false;
517
      for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
518
        processNextBuildRound(k);
519
        if (k == next_check || k == n) {
520
          terminate = checkTermination(k);
521
          next_check = next_check * 3 / 2;
522
        }
523
      }
524
      for ( ; k <= n && !terminate; ++k) {
525
        processNextFullRound(k);
526
        if (k == next_check || k == n) {
527
          terminate = checkTermination(k);
528
          next_check = next_check * 3 / 2;
529
        }
530
      }
531
    }
532

	
533
    // Process one round and rebuild _process
534
    void processNextBuildRound(int k) {
535
      std::vector<Node> next;
536
      Node u, v;
537
      Arc e;
538
      LargeValue d;
539
      for (int i = 0; i < int(_process.size()); ++i) {
540
        u = _process[i];
541
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
542
          e = _out_arcs[u][j];
543
          v = _gr.target(e);
544
          d = _data[u][k-1].dist + _length[e];
545
          if (_tolerance.less(d, _data[v][k].dist)) {
546
            if (_data[v][k].dist == INF) next.push_back(v);
547
            _data[v][k] = PathData(d, e);
548
          }
549
        }
550
      }
551
      _process.swap(next);
552
    }
553

	
554
    // Process one round using _nodes instead of _process
555
    void processNextFullRound(int k) {
556
      Node u, v;
557
      Arc e;
558
      LargeValue d;
559
      for (int i = 0; i < int(_nodes->size()); ++i) {
560
        u = (*_nodes)[i];
561
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
562
          e = _out_arcs[u][j];
563
          v = _gr.target(e);
564
          d = _data[u][k-1].dist + _length[e];
565
          if (_tolerance.less(d, _data[v][k].dist)) {
566
            _data[v][k] = PathData(d, e);
567
          }
568
        }
569
      }
570
    }
571
    
572
    // Check early termination
573
    bool checkTermination(int k) {
574
      typedef std::pair<int, int> Pair;
575
      typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
576
      typename GR::template NodeMap<LargeValue> pi(_gr);
577
      int n = _nodes->size();
578
      LargeValue length;
579
      int size;
580
      Node u;
581
      
582
      // Search for cycles that are already found
583
      _curr_found = false;
584
      for (int i = 0; i < n; ++i) {
585
        u = (*_nodes)[i];
586
        if (_data[u][k].dist == INF) continue;
587
        for (int j = k; j >= 0; --j) {
588
          if (level[u].first == i && level[u].second > 0) {
589
            // A cycle is found
590
            length = _data[u][level[u].second].dist - _data[u][j].dist;
591
            size = level[u].second - j;
592
            if (!_curr_found || length * _curr_size < _curr_length * size) {
593
              _curr_length = length;
594
              _curr_size = size;
595
              _curr_node = u;
596
              _curr_level = level[u].second;
597
              _curr_found = true;
598
            }
599
          }
600
          level[u] = Pair(i, j);
601
          u = _gr.source(_data[u][j].pred);
602
        }
603
      }
604

	
605
      // If at least one cycle is found, check the optimality condition
606
      LargeValue d;
607
      if (_curr_found && k < n) {
608
        // Find node potentials
609
        for (int i = 0; i < n; ++i) {
610
          u = (*_nodes)[i];
611
          pi[u] = INF;
612
          for (int j = 0; j <= k; ++j) {
613
            if (_data[u][j].dist < INF) {
614
              d = _data[u][j].dist * _curr_size - j * _curr_length;
615
              if (_tolerance.less(d, pi[u])) pi[u] = d;
616
            }
617
          }
618
        }
619

	
620
        // Check the optimality condition for all arcs
621
        bool done = true;
622
        for (ArcIt a(_gr); a != INVALID; ++a) {
623
          if (_tolerance.less(_length[a] * _curr_size - _curr_length,
624
                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
625
            done = false;
626
            break;
627
          }
628
        }
629
        return done;
630
      }
631
      return (k == n);
632
    }
633

	
634
  }; //class HartmannOrlin
635

	
636
  ///@}
637

	
638
} //namespace lemon
639

	
640
#endif //LEMON_HARTMANN_ORLIN_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_HOWARD_H
20
#define LEMON_HOWARD_H
21

	
22
/// \ingroup min_mean_cycle
23
///
24
/// \file
25
/// \brief Howard's algorithm for finding a minimum mean cycle.
26

	
27
#include <vector>
28
#include <limits>
29
#include <lemon/core.h>
30
#include <lemon/path.h>
31
#include <lemon/tolerance.h>
32
#include <lemon/connectivity.h>
33

	
34
namespace lemon {
35

	
36
  /// \brief Default traits class of Howard class.
37
  ///
38
  /// Default traits class of Howard class.
39
  /// \tparam GR The type of the digraph.
40
  /// \tparam LEN The type of the length map.
41
  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
42
#ifdef DOXYGEN
43
  template <typename GR, typename LEN>
44
#else
45
  template <typename GR, typename LEN,
46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
47
#endif
48
  struct HowardDefaultTraits
49
  {
50
    /// The type of the digraph
51
    typedef GR Digraph;
52
    /// The type of the length map
53
    typedef LEN LengthMap;
54
    /// The type of the arc lengths
55
    typedef typename LengthMap::Value Value;
56

	
57
    /// \brief The large value type used for internal computations
58
    ///
59
    /// The large value type used for internal computations.
60
    /// It is \c long \c long if the \c Value type is integer,
61
    /// otherwise it is \c double.
62
    /// \c Value must be convertible to \c LargeValue.
63
    typedef double LargeValue;
64

	
65
    /// The tolerance type used for internal computations
66
    typedef lemon::Tolerance<LargeValue> Tolerance;
67

	
68
    /// \brief The path type of the found cycles
69
    ///
70
    /// The path type of the found cycles.
71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
72
    /// and it must have an \c addBack() function.
73
    typedef lemon::Path<Digraph> Path;
74
  };
75

	
76
  // Default traits class for integer value types
77
  template <typename GR, typename LEN>
78
  struct HowardDefaultTraits<GR, LEN, true>
79
  {
80
    typedef GR Digraph;
81
    typedef LEN LengthMap;
82
    typedef typename LengthMap::Value Value;
83
#ifdef LEMON_HAVE_LONG_LONG
84
    typedef long long LargeValue;
85
#else
86
    typedef long LargeValue;
87
#endif
88
    typedef lemon::Tolerance<LargeValue> Tolerance;
89
    typedef lemon::Path<Digraph> Path;
90
  };
91

	
92

	
93
  /// \addtogroup min_mean_cycle
94
  /// @{
95

	
96
  /// \brief Implementation of Howard's algorithm for finding a minimum
97
  /// mean cycle.
98
  ///
99
  /// This class implements Howard's policy iteration algorithm for finding
100
  /// a directed cycle of minimum mean length (cost) in a digraph
101
  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
102
  /// This class provides the most efficient algorithm for the
103
  /// minimum mean cycle problem, though the best known theoretical
104
  /// bound on its running time is exponential.
105
  ///
106
  /// \tparam GR The type of the digraph the algorithm runs on.
107
  /// \tparam LEN The type of the length map. The default
108
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
109
#ifdef DOXYGEN
110
  template <typename GR, typename LEN, typename TR>
111
#else
112
  template < typename GR,
113
             typename LEN = typename GR::template ArcMap<int>,
114
             typename TR = HowardDefaultTraits<GR, LEN> >
115
#endif
116
  class Howard
117
  {
118
  public:
119
  
120
    /// The type of the digraph
121
    typedef typename TR::Digraph Digraph;
122
    /// The type of the length map
123
    typedef typename TR::LengthMap LengthMap;
124
    /// The type of the arc lengths
125
    typedef typename TR::Value Value;
126

	
127
    /// \brief The large value type
128
    ///
129
    /// The large value type used for internal computations.
130
    /// Using the \ref HowardDefaultTraits "default traits class",
131
    /// it is \c long \c long if the \c Value type is integer,
132
    /// otherwise it is \c double.
133
    typedef typename TR::LargeValue LargeValue;
134

	
135
    /// The tolerance type
136
    typedef typename TR::Tolerance Tolerance;
137

	
138
    /// \brief The path type of the found cycles
139
    ///
140
    /// The path type of the found cycles.
141
    /// Using the \ref HowardDefaultTraits "default traits class",
142
    /// it is \ref lemon::Path "Path<Digraph>".
143
    typedef typename TR::Path Path;
144

	
145
    /// The \ref HowardDefaultTraits "traits class" of the algorithm
146
    typedef TR Traits;
147

	
148
  private:
149

	
150
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
151
  
152
    // The digraph the algorithm runs on
153
    const Digraph &_gr;
154
    // The length of the arcs
155
    const LengthMap &_length;
156

	
157
    // Data for the found cycles
158
    bool _curr_found, _best_found;
159
    LargeValue _curr_length, _best_length;
160
    int _curr_size, _best_size;
161
    Node _curr_node, _best_node;
162

	
163
    Path *_cycle_path;
164
    bool _local_path;
165

	
166
    // Internal data used by the algorithm
167
    typename Digraph::template NodeMap<Arc> _policy;
168
    typename Digraph::template NodeMap<bool> _reached;
169
    typename Digraph::template NodeMap<int> _level;
170
    typename Digraph::template NodeMap<LargeValue> _dist;
171

	
172
    // Data for storing the strongly connected components
173
    int _comp_num;
174
    typename Digraph::template NodeMap<int> _comp;
175
    std::vector<std::vector<Node> > _comp_nodes;
176
    std::vector<Node>* _nodes;
177
    typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
178
    
179
    // Queue used for BFS search
180
    std::vector<Node> _queue;
181
    int _qfront, _qback;
182

	
183
    Tolerance _tolerance;
184
  
185
    // Infinite constant
186
    const LargeValue INF;
187

	
188
  public:
189
  
190
    /// \name Named Template Parameters
191
    /// @{
192

	
193
    template <typename T>
194
    struct SetLargeValueTraits : public Traits {
195
      typedef T LargeValue;
196
      typedef lemon::Tolerance<T> Tolerance;
197
    };
198

	
199
    /// \brief \ref named-templ-param "Named parameter" for setting
200
    /// \c LargeValue type.
201
    ///
202
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
203
    /// type. It is used for internal computations in the algorithm.
204
    template <typename T>
205
    struct SetLargeValue
206
      : public Howard<GR, LEN, SetLargeValueTraits<T> > {
207
      typedef Howard<GR, LEN, SetLargeValueTraits<T> > Create;
208
    };
209

	
210
    template <typename T>
211
    struct SetPathTraits : public Traits {
212
      typedef T Path;
213
    };
214

	
215
    /// \brief \ref named-templ-param "Named parameter" for setting
216
    /// \c %Path type.
217
    ///
218
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
219
    /// type of the found cycles.
220
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
221
    /// and it must have an \c addBack() function.
222
    template <typename T>
223
    struct SetPath
224
      : public Howard<GR, LEN, SetPathTraits<T> > {
225
      typedef Howard<GR, LEN, SetPathTraits<T> > Create;
226
    };
227
    
228
    /// @}
229

	
230
  public:
231

	
232
    /// \brief Constructor.
233
    ///
234
    /// The constructor of the class.
235
    ///
236
    /// \param digraph The digraph the algorithm runs on.
237
    /// \param length The lengths (costs) of the arcs.
238
    Howard( const Digraph &digraph,
239
            const LengthMap &length ) :
240
      _gr(digraph), _length(length), _best_found(false),
241
      _best_length(0), _best_size(1), _cycle_path(NULL), _local_path(false),
242
      _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
243
      _comp(digraph), _in_arcs(digraph),
244
      INF(std::numeric_limits<LargeValue>::has_infinity ?
245
          std::numeric_limits<LargeValue>::infinity() :
246
          std::numeric_limits<LargeValue>::max())
247
    {}
248

	
249
    /// Destructor.
250
    ~Howard() {
251
      if (_local_path) delete _cycle_path;
252
    }
253

	
254
    /// \brief Set the path structure for storing the found cycle.
255
    ///
256
    /// This function sets an external path structure for storing the
257
    /// found cycle.
258
    ///
259
    /// If you don't call this function before calling \ref run() or
260
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
261
    /// structure. The destuctor deallocates this automatically
262
    /// allocated object, of course.
263
    ///
264
    /// \note The algorithm calls only the \ref lemon::Path::addBack()
265
    /// "addBack()" function of the given path structure.
266
    ///
267
    /// \return <tt>(*this)</tt>
268
    Howard& cycle(Path &path) {
269
      if (_local_path) {
270
        delete _cycle_path;
271
        _local_path = false;
272
      }
273
      _cycle_path = &path;
274
      return *this;
275
    }
276

	
277
    /// \brief Set the tolerance used by the algorithm.
278
    ///
279
    /// This function sets the tolerance object used by the algorithm.
280
    ///
281
    /// \return <tt>(*this)</tt>
282
    Howard& tolerance(const Tolerance& tolerance) {
283
      _tolerance = tolerance;
284
      return *this;
285
    }
286

	
287
    /// \brief Return a const reference to the tolerance.
288
    ///
289
    /// This function returns a const reference to the tolerance object
290
    /// used by the algorithm.
291
    const Tolerance& tolerance() const {
292
      return _tolerance;
293
    }
294

	
295
    /// \name Execution control
296
    /// The simplest way to execute the algorithm is to call the \ref run()
297
    /// function.\n
298
    /// If you only need the minimum mean length, you may call
299
    /// \ref findMinMean().
300

	
301
    /// @{
302

	
303
    /// \brief Run the algorithm.
304
    ///
305
    /// This function runs the algorithm.
306
    /// It can be called more than once (e.g. if the underlying digraph
307
    /// and/or the arc lengths have been modified).
308
    ///
309
    /// \return \c true if a directed cycle exists in the digraph.
310
    ///
311
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
312
    /// \code
313
    ///   return mmc.findMinMean() && mmc.findCycle();
314
    /// \endcode
315
    bool run() {
316
      return findMinMean() && findCycle();
317
    }
318

	
319
    /// \brief Find the minimum cycle mean.
320
    ///
321
    /// This function finds the minimum mean length of the directed
322
    /// cycles in the digraph.
323
    ///
324
    /// \return \c true if a directed cycle exists in the digraph.
325
    bool findMinMean() {
326
      // Initialize and find strongly connected components
327
      init();
328
      findComponents();
329
      
330
      // Find the minimum cycle mean in the components
331
      for (int comp = 0; comp < _comp_num; ++comp) {
332
        // Find the minimum mean cycle in the current component
333
        if (!buildPolicyGraph(comp)) continue;
334
        while (true) {
335
          findPolicyCycle();
336
          if (!computeNodeDistances()) break;
337
        }
338
        // Update the best cycle (global minimum mean cycle)
339
        if ( _curr_found && (!_best_found ||
340
             _curr_length * _best_size < _best_length * _curr_size) ) {
341
          _best_found = true;
342
          _best_length = _curr_length;
343
          _best_size = _curr_size;
344
          _best_node = _curr_node;
345
        }
346
      }
347
      return _best_found;
348
    }
349

	
350
    /// \brief Find a minimum mean directed cycle.
351
    ///
352
    /// This function finds a directed cycle of minimum mean length
353
    /// in the digraph using the data computed by findMinMean().
354
    ///
355
    /// \return \c true if a directed cycle exists in the digraph.
356
    ///
357
    /// \pre \ref findMinMean() must be called before using this function.
358
    bool findCycle() {
359
      if (!_best_found) return false;
360
      _cycle_path->addBack(_policy[_best_node]);
361
      for ( Node v = _best_node;
362
            (v = _gr.target(_policy[v])) != _best_node; ) {
363
        _cycle_path->addBack(_policy[v]);
364
      }
365
      return true;
366
    }
367

	
368
    /// @}
369

	
370
    /// \name Query Functions
371
    /// The results of the algorithm can be obtained using these
372
    /// functions.\n
373
    /// The algorithm should be executed before using them.
374

	
375
    /// @{
376

	
377
    /// \brief Return the total length of the found cycle.
378
    ///
379
    /// This function returns the total length of the found cycle.
380
    ///
381
    /// \pre \ref run() or \ref findMinMean() must be called before
382
    /// using this function.
383
    LargeValue cycleLength() const {
384
      return _best_length;
385
    }
386

	
387
    /// \brief Return the number of arcs on the found cycle.
388
    ///
389
    /// This function returns the number of arcs on the found cycle.
390
    ///
391
    /// \pre \ref run() or \ref findMinMean() must be called before
392
    /// using this function.
393
    int cycleArcNum() const {
394
      return _best_size;
395
    }
396

	
397
    /// \brief Return the mean length of the found cycle.
398
    ///
399
    /// This function returns the mean length of the found cycle.
400
    ///
401
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
402
    /// following code.
403
    /// \code
404
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
405
    /// \endcode
406
    ///
407
    /// \pre \ref run() or \ref findMinMean() must be called before
408
    /// using this function.
409
    double cycleMean() const {
410
      return static_cast<double>(_best_length) / _best_size;
411
    }
412

	
413
    /// \brief Return the found cycle.
414
    ///
415
    /// This function returns a const reference to the path structure
416
    /// storing the found cycle.
417
    ///
418
    /// \pre \ref run() or \ref findCycle() must be called before using
419
    /// this function.
420
    const Path& cycle() const {
421
      return *_cycle_path;
422
    }
423

	
424
    ///@}
425

	
426
  private:
427

	
428
    // Initialize
429
    void init() {
430
      if (!_cycle_path) {
431
        _local_path = true;
432
        _cycle_path = new Path;
433
      }
434
      _queue.resize(countNodes(_gr));
435
      _best_found = false;
436
      _best_length = 0;
437
      _best_size = 1;
438
      _cycle_path->clear();
439
    }
440
    
441
    // Find strongly connected components and initialize _comp_nodes
442
    // and _in_arcs
443
    void findComponents() {
444
      _comp_num = stronglyConnectedComponents(_gr, _comp);
445
      _comp_nodes.resize(_comp_num);
446
      if (_comp_num == 1) {
447
        _comp_nodes[0].clear();
448
        for (NodeIt n(_gr); n != INVALID; ++n) {
449
          _comp_nodes[0].push_back(n);
450
          _in_arcs[n].clear();
451
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
452
            _in_arcs[n].push_back(a);
453
          }
454
        }
455
      } else {
456
        for (int i = 0; i < _comp_num; ++i)
457
          _comp_nodes[i].clear();
458
        for (NodeIt n(_gr); n != INVALID; ++n) {
459
          int k = _comp[n];
460
          _comp_nodes[k].push_back(n);
461
          _in_arcs[n].clear();
462
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
463
            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
464
          }
465
        }
466
      }
467
    }
468

	
469
    // Build the policy graph in the given strongly connected component
470
    // (the out-degree of every node is 1)
471
    bool buildPolicyGraph(int comp) {
472
      _nodes = &(_comp_nodes[comp]);
473
      if (_nodes->size() < 1 ||
474
          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
475
        return false;
476
      }
477
      for (int i = 0; i < int(_nodes->size()); ++i) {
478
        _dist[(*_nodes)[i]] = INF;
479
      }
480
      Node u, v;
481
      Arc e;
482
      for (int i = 0; i < int(_nodes->size()); ++i) {
483
        v = (*_nodes)[i];
484
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
485
          e = _in_arcs[v][j];
486
          u = _gr.source(e);
487
          if (_length[e] < _dist[u]) {
488
            _dist[u] = _length[e];
489
            _policy[u] = e;
490
          }
491
        }
492
      }
493
      return true;
494
    }
495

	
496
    // Find the minimum mean cycle in the policy graph
497
    void findPolicyCycle() {
498
      for (int i = 0; i < int(_nodes->size()); ++i) {
499
        _level[(*_nodes)[i]] = -1;
500
      }
501
      LargeValue clength;
502
      int csize;
503
      Node u, v;
504
      _curr_found = false;
505
      for (int i = 0; i < int(_nodes->size()); ++i) {
506
        u = (*_nodes)[i];
507
        if (_level[u] >= 0) continue;
508
        for (; _level[u] < 0; u = _gr.target(_policy[u])) {
509
          _level[u] = i;
510
        }
511
        if (_level[u] == i) {
512
          // A cycle is found
513
          clength = _length[_policy[u]];
514
          csize = 1;
515
          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
516
            clength += _length[_policy[v]];
517
            ++csize;
518
          }
519
          if ( !_curr_found ||
520
               (clength * _curr_size < _curr_length * csize) ) {
521
            _curr_found = true;
522
            _curr_length = clength;
523
            _curr_size = csize;
524
            _curr_node = u;
525
          }
526
        }
527
      }
528
    }
529

	
530
    // Contract the policy graph and compute node distances
531
    bool computeNodeDistances() {
532
      // Find the component of the main cycle and compute node distances
533
      // using reverse BFS
534
      for (int i = 0; i < int(_nodes->size()); ++i) {
535
        _reached[(*_nodes)[i]] = false;
536
      }
537
      _qfront = _qback = 0;
538
      _queue[0] = _curr_node;
539
      _reached[_curr_node] = true;
540
      _dist[_curr_node] = 0;
541
      Node u, v;
542
      Arc e;
543
      while (_qfront <= _qback) {
544
        v = _queue[_qfront++];
545
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
546
          e = _in_arcs[v][j];
547
          u = _gr.source(e);
548
          if (_policy[u] == e && !_reached[u]) {
549
            _reached[u] = true;
550
            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
551
            _queue[++_qback] = u;
552
          }
553
        }
554
      }
555

	
556
      // Connect all other nodes to this component and compute node
557
      // distances using reverse BFS
558
      _qfront = 0;
559
      while (_qback < int(_nodes->size())-1) {
560
        v = _queue[_qfront++];
561
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
562
          e = _in_arcs[v][j];
563
          u = _gr.source(e);
564
          if (!_reached[u]) {
565
            _reached[u] = true;
566
            _policy[u] = e;
567
            _dist[u] = _dist[v] + _length[e] * _curr_size - _curr_length;
568
            _queue[++_qback] = u;
569
          }
570
        }
571
      }
572

	
573
      // Improve node distances
574
      bool improved = false;
575
      for (int i = 0; i < int(_nodes->size()); ++i) {
576
        v = (*_nodes)[i];
577
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
578
          e = _in_arcs[v][j];
579
          u = _gr.source(e);
580
          LargeValue delta = _dist[v] + _length[e] * _curr_size - _curr_length;
581
          if (_tolerance.less(delta, _dist[u])) {
582
            _dist[u] = delta;
583
            _policy[u] = e;
584
            improved = true;
585
          }
586
        }
587
      }
588
      return improved;
589
    }
590

	
591
  }; //class Howard
592

	
593
  ///@}
594

	
595
} //namespace lemon
596

	
597
#endif //LEMON_HOWARD_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
    static int index(Node node) {
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
  /// HypercubeGraph implements a special graph type. The nodes of the
286
  /// graph are indexed with integers having 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
  /// This class is completely static and it needs constant memory space.
290
  /// Thus you can neither add nor delete nodes or edges, however 
291
  /// the structure can be resized using resize().
292
  ///
293
  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
294
  /// Most of its member functions and nested classes are documented
295
  /// only in the concept class.
296
  ///
297
  /// \note The type of the indices is chosen to \c int for efficiency
298
  /// reasons. Thus the maximum dimension of this implementation is 26
299
  /// (assuming that the size of \c int is 32 bit).
300
  class HypercubeGraph : public ExtendedHypercubeGraphBase {
301
    typedef ExtendedHypercubeGraphBase Parent;
302

	
303
  public:
304

	
305
    /// \brief Constructs a hypercube graph with \c dim dimensions.
306
    ///
307
    /// Constructs a hypercube graph with \c dim dimensions.
308
    HypercubeGraph(int dim) { construct(dim); }
309

	
310
    /// \brief Resizes the graph
311
    ///
312
    /// This function resizes the graph. It fully destroys and
313
    /// rebuilds the structure, therefore the maps of the graph will be
314
    /// reallocated automatically and the previous values will be lost.
315
    void resize(int dim) {
316
      Parent::notifier(Arc()).clear();
317
      Parent::notifier(Edge()).clear();
318
      Parent::notifier(Node()).clear();
319
      construct(dim);
320
      Parent::notifier(Node()).build();
321
      Parent::notifier(Edge()).build();
322
      Parent::notifier(Arc()).build();
323
    }
324

	
325
    /// \brief The number of dimensions.
326
    ///
327
    /// Gives back the number of dimensions.
328
    int dimension() const {
329
      return Parent::dimension();
330
    }
331

	
332
    /// \brief Returns \c true if the n'th bit of the node is one.
333
    ///
334
    /// Returns \c true if the n'th bit of the node is one.
335
    bool projection(Node node, int n) const {
336
      return Parent::projection(node, n);
337
    }
338

	
339
    /// \brief The dimension id of an edge.
340
    ///
341
    /// Gives back the dimension id of the given edge.
342
    /// It is in the range <tt>[0..dim-1]</tt>.
343
    int dimension(Edge edge) const {
344
      return Parent::dimension(edge);
345
    }
346

	
347
    /// \brief The dimension id of an arc.
348
    ///
349
    /// Gives back the dimension id of the given arc.
350
    /// It is in the range <tt>[0..dim-1]</tt>.
351
    int dimension(Arc arc) const {
352
      return Parent::dimension(arc);
353
    }
354

	
355
    /// \brief The index of a node.
356
    ///
357
    /// Gives back the index of the given node.
358
    /// The lower bits of the integer describes the node.
359
    static int index(Node node) {
360
      return Parent::index(node);
361
    }
362

	
363
    /// \brief Gives back a node by its index.
364
    ///
365
    /// Gives back a node by its index.
366
    Node operator()(int ix) const {
367
      return Parent::operator()(ix);
368
    }
369

	
370
    /// \brief Number of nodes.
371
    int nodeNum() const { return Parent::nodeNum(); }
372
    /// \brief Number of edges.
373
    int edgeNum() const { return Parent::edgeNum(); }
374
    /// \brief Number of arcs.
375
    int arcNum() const { return Parent::arcNum(); }
376

	
377
    /// \brief Linear combination map.
378
    ///
379
    /// This map makes possible to give back a linear combination
380
    /// for each node. It works like the \c std::accumulate function,
381
    /// so it accumulates the \c bf binary function with the \c fv first
382
    /// value. The map accumulates only on that positions (dimensions)
383
    /// where the index of the node is one. The values that have to be
384
    /// accumulated should be given by the \c begin and \c end iterators
385
    /// and the length of this range should be equal to the dimension
386
    /// number of the graph.
387
    ///
388
    ///\code
389
    /// const int DIM = 3;
390
    /// HypercubeGraph graph(DIM);
391
    /// dim2::Point<double> base[DIM];
392
    /// for (int k = 0; k < DIM; ++k) {
393
    ///   base[k].x = rnd();
394
    ///   base[k].y = rnd();
395
    /// }
396
    /// HypercubeGraph::HyperMap<dim2::Point<double> >
397
    ///   pos(graph, base, base + DIM, dim2::Point<double>(0.0, 0.0));
398
    ///\endcode
399
    ///
400
    /// \see HypercubeGraph
401
    template <typename T, typename BF = std::plus<T> >
402
    class HyperMap {
403
    public:
404

	
405
      /// \brief The key type of the map
406
      typedef Node Key;
407
      /// \brief The value type of the map
408
      typedef T Value;
409

	
410
      /// \brief Constructor for HyperMap.
411
      ///
412
      /// Construct a HyperMap for the given graph. The values that have
413
      /// to be accumulated should be given by the \c begin and \c end
414
      /// iterators and the length of this range should be equal to the
415
      /// dimension number of the graph.
416
      ///
417
      /// This map accumulates the \c bf binary function with the \c fv
418
      /// first value on that positions (dimensions) where the index of
419
      /// the node is one.
420
      template <typename It>
421
      HyperMap(const Graph& graph, It begin, It end,
422
               T fv = 0, const BF& bf = BF())
423
        : _graph(graph), _values(begin, end), _first_value(fv), _bin_func(bf)
424
      {
425
        LEMON_ASSERT(_values.size() == graph.dimension(),
426
                     "Wrong size of range");
427
      }
428

	
429
      /// \brief The partial accumulated value.
430
      ///
431
      /// Gives back the partial accumulated value.
432
      Value operator[](const Key& k) const {
433
        Value val = _first_value;
434
        int id = _graph.index(k);
435
        int n = 0;
436
        while (id != 0) {
437
          if (id & 1) {
438
            val = _bin_func(val, _values[n]);
439
          }
440
          id >>= 1;
441
          ++n;
442
        }
443
        return val;
444
      }
445

	
446
    private:
447
      const Graph& _graph;
448
      std::vector<T> _values;
449
      T _first_value;
450
      BF _bin_func;
451
    };
452

	
453
  };
454

	
455
}
456

	
457
#endif
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_KARP_H
20
#define LEMON_KARP_H
21

	
22
/// \ingroup min_mean_cycle
23
///
24
/// \file
25
/// \brief Karp's algorithm for finding a minimum mean cycle.
26

	
27
#include <vector>
28
#include <limits>
29
#include <lemon/core.h>
30
#include <lemon/path.h>
31
#include <lemon/tolerance.h>
32
#include <lemon/connectivity.h>
33

	
34
namespace lemon {
35

	
36
  /// \brief Default traits class of Karp algorithm.
37
  ///
38
  /// Default traits class of Karp algorithm.
39
  /// \tparam GR The type of the digraph.
40
  /// \tparam LEN The type of the length map.
41
  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
42
#ifdef DOXYGEN
43
  template <typename GR, typename LEN>
44
#else
45
  template <typename GR, typename LEN,
46
    bool integer = std::numeric_limits<typename LEN::Value>::is_integer>
47
#endif
48
  struct KarpDefaultTraits
49
  {
50
    /// The type of the digraph
51
    typedef GR Digraph;
52
    /// The type of the length map
53
    typedef LEN LengthMap;
54
    /// The type of the arc lengths
55
    typedef typename LengthMap::Value Value;
56

	
57
    /// \brief The large value type used for internal computations
58
    ///
59
    /// The large value type used for internal computations.
60
    /// It is \c long \c long if the \c Value type is integer,
61
    /// otherwise it is \c double.
62
    /// \c Value must be convertible to \c LargeValue.
63
    typedef double LargeValue;
64

	
65
    /// The tolerance type used for internal computations
66
    typedef lemon::Tolerance<LargeValue> Tolerance;
67

	
68
    /// \brief The path type of the found cycles
69
    ///
70
    /// The path type of the found cycles.
71
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
72
    /// and it must have an \c addFront() function.
73
    typedef lemon::Path<Digraph> Path;
74
  };
75

	
76
  // Default traits class for integer value types
77
  template <typename GR, typename LEN>
78
  struct KarpDefaultTraits<GR, LEN, true>
79
  {
80
    typedef GR Digraph;
81
    typedef LEN LengthMap;
82
    typedef typename LengthMap::Value Value;
83
#ifdef LEMON_HAVE_LONG_LONG
84
    typedef long long LargeValue;
85
#else
86
    typedef long LargeValue;
87
#endif
88
    typedef lemon::Tolerance<LargeValue> Tolerance;
89
    typedef lemon::Path<Digraph> Path;
90
  };
91

	
92

	
93
  /// \addtogroup min_mean_cycle
94
  /// @{
95

	
96
  /// \brief Implementation of Karp's algorithm for finding a minimum
97
  /// mean cycle.
98
  ///
99
  /// This class implements Karp's algorithm for finding a directed
100
  /// cycle of minimum mean length (cost) in a digraph
101
  /// \ref amo93networkflows, \ref dasdan98minmeancycle.
102
  /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e).
103
  ///
104
  /// \tparam GR The type of the digraph the algorithm runs on.
105
  /// \tparam LEN The type of the length map. The default
106
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
107
#ifdef DOXYGEN
108
  template <typename GR, typename LEN, typename TR>
109
#else
110
  template < typename GR,
111
             typename LEN = typename GR::template ArcMap<int>,
112
             typename TR = KarpDefaultTraits<GR, LEN> >
113
#endif
114
  class Karp
115
  {
116
  public:
117

	
118
    /// The type of the digraph
119
    typedef typename TR::Digraph Digraph;
120
    /// The type of the length map
121
    typedef typename TR::LengthMap LengthMap;
122
    /// The type of the arc lengths
123
    typedef typename TR::Value Value;
124

	
125
    /// \brief The large value type
126
    ///
127
    /// The large value type used for internal computations.
128
    /// Using the \ref KarpDefaultTraits "default traits class",
129
    /// it is \c long \c long if the \c Value type is integer,
130
    /// otherwise it is \c double.
131
    typedef typename TR::LargeValue LargeValue;
132

	
133
    /// The tolerance type
134
    typedef typename TR::Tolerance Tolerance;
135

	
136
    /// \brief The path type of the found cycles
137
    ///
138
    /// The path type of the found cycles.
139
    /// Using the \ref KarpDefaultTraits "default traits class",
140
    /// it is \ref lemon::Path "Path<Digraph>".
141
    typedef typename TR::Path Path;
142

	
143
    /// The \ref KarpDefaultTraits "traits class" of the algorithm
144
    typedef TR Traits;
145

	
146
  private:
147

	
148
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
149

	
150
    // Data sturcture for path data
151
    struct PathData
152
    {
153
      LargeValue dist;
154
      Arc pred;
155
      PathData(LargeValue d, Arc p = INVALID) :
156
        dist(d), pred(p) {}
157
    };
158

	
159
    typedef typename Digraph::template NodeMap<std::vector<PathData> >
160
      PathDataNodeMap;
161

	
162
  private:
163

	
164
    // The digraph the algorithm runs on
165
    const Digraph &_gr;
166
    // The length of the arcs
167
    const LengthMap &_length;
168

	
169
    // Data for storing the strongly connected components
170
    int _comp_num;
171
    typename Digraph::template NodeMap<int> _comp;
172
    std::vector<std::vector<Node> > _comp_nodes;
173
    std::vector<Node>* _nodes;
174
    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
175

	
176
    // Data for the found cycle
177
    LargeValue _cycle_length;
178
    int _cycle_size;
179
    Node _cycle_node;
180

	
181
    Path *_cycle_path;
182
    bool _local_path;
183

	
184
    // Node map for storing path data
185
    PathDataNodeMap _data;
186
    // The processed nodes in the last round
187
    std::vector<Node> _process;
188

	
189
    Tolerance _tolerance;
190
    
191
    // Infinite constant
192
    const LargeValue INF;
193

	
194
  public:
195

	
196
    /// \name Named Template Parameters
197
    /// @{
198

	
199
    template <typename T>
200
    struct SetLargeValueTraits : public Traits {
201
      typedef T LargeValue;
202
      typedef lemon::Tolerance<T> Tolerance;
203
    };
204

	
205
    /// \brief \ref named-templ-param "Named parameter" for setting
206
    /// \c LargeValue type.
207
    ///
208
    /// \ref named-templ-param "Named parameter" for setting \c LargeValue
209
    /// type. It is used for internal computations in the algorithm.
210
    template <typename T>
211
    struct SetLargeValue
212
      : public Karp<GR, LEN, SetLargeValueTraits<T> > {
213
      typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create;
214
    };
215

	
216
    template <typename T>
217
    struct SetPathTraits : public Traits {
218
      typedef T Path;
219
    };
220

	
221
    /// \brief \ref named-templ-param "Named parameter" for setting
222
    /// \c %Path type.
223
    ///
224
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
225
    /// type of the found cycles.
226
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
227
    /// and it must have an \c addFront() function.
228
    template <typename T>
229
    struct SetPath
230
      : public Karp<GR, LEN, SetPathTraits<T> > {
231
      typedef Karp<GR, LEN, SetPathTraits<T> > Create;
232
    };
233

	
234
    /// @}
235

	
236
  public:
237

	
238
    /// \brief Constructor.
239
    ///
240
    /// The constructor of the class.
241
    ///
242
    /// \param digraph The digraph the algorithm runs on.
243
    /// \param length The lengths (costs) of the arcs.
244
    Karp( const Digraph &digraph,
245
          const LengthMap &length ) :
246
      _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
247
      _cycle_length(0), _cycle_size(1), _cycle_node(INVALID),
248
      _cycle_path(NULL), _local_path(false), _data(digraph),
249
      INF(std::numeric_limits<LargeValue>::has_infinity ?
250
          std::numeric_limits<LargeValue>::infinity() :
251
          std::numeric_limits<LargeValue>::max())
252
    {}
253

	
254
    /// Destructor.
255
    ~Karp() {
256
      if (_local_path) delete _cycle_path;
257
    }
258

	
259
    /// \brief Set the path structure for storing the found cycle.
260
    ///
261
    /// This function sets an external path structure for storing the
262
    /// found cycle.
263
    ///
264
    /// If you don't call this function before calling \ref run() or
265
    /// \ref findMinMean(), it will allocate a local \ref Path "path"
266
    /// structure. The destuctor deallocates this automatically
267
    /// allocated object, of course.
268
    ///
269
    /// \note The algorithm calls only the \ref lemon::Path::addFront()
270
    /// "addFront()" function of the given path structure.
271
    ///
272
    /// \return <tt>(*this)</tt>
273
    Karp& cycle(Path &path) {
274
      if (_local_path) {
275
        delete _cycle_path;
276
        _local_path = false;
277
      }
278
      _cycle_path = &path;
279
      return *this;
280
    }
281

	
282
    /// \brief Set the tolerance used by the algorithm.
283
    ///
284
    /// This function sets the tolerance object used by the algorithm.
285
    ///
286
    /// \return <tt>(*this)</tt>
287
    Karp& tolerance(const Tolerance& tolerance) {
288
      _tolerance = tolerance;
289
      return *this;
290
    }
291

	
292
    /// \brief Return a const reference to the tolerance.
293
    ///
294
    /// This function returns a const reference to the tolerance object
295
    /// used by the algorithm.
296
    const Tolerance& tolerance() const {
297
      return _tolerance;
298
    }
299

	
300
    /// \name Execution control
301
    /// The simplest way to execute the algorithm is to call the \ref run()
302
    /// function.\n
303
    /// If you only need the minimum mean length, you may call
304
    /// \ref findMinMean().
305

	
306
    /// @{
307

	
308
    /// \brief Run the algorithm.
309
    ///
310
    /// This function runs the algorithm.
311
    /// It can be called more than once (e.g. if the underlying digraph
312
    /// and/or the arc lengths have been modified).
313
    ///
314
    /// \return \c true if a directed cycle exists in the digraph.
315
    ///
316
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
317
    /// \code
318
    ///   return mmc.findMinMean() && mmc.findCycle();
319
    /// \endcode
320
    bool run() {
321
      return findMinMean() && findCycle();
322
    }
323

	
324
    /// \brief Find the minimum cycle mean.
325
    ///
326
    /// This function finds the minimum mean length of the directed
327
    /// cycles in the digraph.
328
    ///
329
    /// \return \c true if a directed cycle exists in the digraph.
330
    bool findMinMean() {
331
      // Initialization and find strongly connected components
332
      init();
333
      findComponents();
334
      
335
      // Find the minimum cycle mean in the components
336
      for (int comp = 0; comp < _comp_num; ++comp) {
337
        if (!initComponent(comp)) continue;
338
        processRounds();
339
        updateMinMean();
340
      }
341
      return (_cycle_node != INVALID);
342
    }
343

	
344
    /// \brief Find a minimum mean directed cycle.
345
    ///
346
    /// This function finds a directed cycle of minimum mean length
347
    /// in the digraph using the data computed by findMinMean().
348
    ///
349
    /// \return \c true if a directed cycle exists in the digraph.
350
    ///
351
    /// \pre \ref findMinMean() must be called before using this function.
352
    bool findCycle() {
353
      if (_cycle_node == INVALID) return false;
354
      IntNodeMap reached(_gr, -1);
355
      int r = _data[_cycle_node].size();
356
      Node u = _cycle_node;
357
      while (reached[u] < 0) {
358
        reached[u] = --r;
359
        u = _gr.source(_data[u][r].pred);
360
      }
361
      r = reached[u];
362
      Arc e = _data[u][r].pred;
363
      _cycle_path->addFront(e);
364
      _cycle_length = _length[e];
365
      _cycle_size = 1;
366
      Node v;
367
      while ((v = _gr.source(e)) != u) {
368
        e = _data[v][--r].pred;
369
        _cycle_path->addFront(e);
370
        _cycle_length += _length[e];
371
        ++_cycle_size;
372
      }
373
      return true;
374
    }
375

	
376
    /// @}
377

	
378
    /// \name Query Functions
379
    /// The results of the algorithm can be obtained using these
380
    /// functions.\n
381
    /// The algorithm should be executed before using them.
382

	
383
    /// @{
384

	
385
    /// \brief Return the total length of the found cycle.
386
    ///
387
    /// This function returns the total length of the found cycle.
388
    ///
389
    /// \pre \ref run() or \ref findMinMean() must be called before
390
    /// using this function.
391
    LargeValue cycleLength() const {
392
      return _cycle_length;
393
    }
394

	
395
    /// \brief Return the number of arcs on the found cycle.
396
    ///
397
    /// This function returns the number of arcs on the found cycle.
398
    ///
399
    /// \pre \ref run() or \ref findMinMean() must be called before
400
    /// using this function.
401
    int cycleArcNum() const {
402
      return _cycle_size;
403
    }
404

	
405
    /// \brief Return the mean length of the found cycle.
406
    ///
407
    /// This function returns the mean length of the found cycle.
408
    ///
409
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
410
    /// following code.
411
    /// \code
412
    ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
413
    /// \endcode
414
    ///
415
    /// \pre \ref run() or \ref findMinMean() must be called before
416
    /// using this function.
417
    double cycleMean() const {
418
      return static_cast<double>(_cycle_length) / _cycle_size;
419
    }
420

	
421
    /// \brief Return the found cycle.
422
    ///
423
    /// This function returns a const reference to the path structure
424
    /// storing the found cycle.
425
    ///
426
    /// \pre \ref run() or \ref findCycle() must be called before using
427
    /// this function.
428
    const Path& cycle() const {
429
      return *_cycle_path;
430
    }
431

	
432
    ///@}
433

	
434
  private:
435

	
436
    // Initialization
437
    void init() {
438
      if (!_cycle_path) {
439
        _local_path = true;
440
        _cycle_path = new Path;
441
      }
442
      _cycle_path->clear();
443
      _cycle_length = 0;
444
      _cycle_size = 1;
445
      _cycle_node = INVALID;
446
      for (NodeIt u(_gr); u != INVALID; ++u)
447
        _data[u].clear();
448
    }
449

	
450
    // Find strongly connected components and initialize _comp_nodes
451
    // and _out_arcs
452
    void findComponents() {
453
      _comp_num = stronglyConnectedComponents(_gr, _comp);
454
      _comp_nodes.resize(_comp_num);
455
      if (_comp_num == 1) {
456
        _comp_nodes[0].clear();
457
        for (NodeIt n(_gr); n != INVALID; ++n) {
458
          _comp_nodes[0].push_back(n);
459
          _out_arcs[n].clear();
460
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
461
            _out_arcs[n].push_back(a);
462
          }
463
        }
464
      } else {
465
        for (int i = 0; i < _comp_num; ++i)
466
          _comp_nodes[i].clear();
467
        for (NodeIt n(_gr); n != INVALID; ++n) {
468
          int k = _comp[n];
469
          _comp_nodes[k].push_back(n);
470
          _out_arcs[n].clear();
471
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
472
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
473
          }
474
        }
475
      }
476
    }
477

	
478
    // Initialize path data for the current component
479
    bool initComponent(int comp) {
480
      _nodes = &(_comp_nodes[comp]);
481
      int n = _nodes->size();
482
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
483
        return false;
484
      }      
485
      for (int i = 0; i < n; ++i) {
486
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
487
      }
488
      return true;
489
    }
490

	
491
    // Process all rounds of computing path data for the current component.
492
    // _data[v][k] is the length of a shortest directed walk from the root
493
    // node to node v containing exactly k arcs.
494
    void processRounds() {
495
      Node start = (*_nodes)[0];
496
      _data[start][0] = PathData(0);
497
      _process.clear();
498
      _process.push_back(start);
499

	
500
      int k, n = _nodes->size();
501
      for (k = 1; k <= n && int(_process.size()) < n; ++k) {
502
        processNextBuildRound(k);
503
      }
504
      for ( ; k <= n; ++k) {
505
        processNextFullRound(k);
506
      }
507
    }
508

	
509
    // Process one round and rebuild _process
510
    void processNextBuildRound(int k) {
511
      std::vector<Node> next;
512
      Node u, v;
513
      Arc e;
514
      LargeValue d;
515
      for (int i = 0; i < int(_process.size()); ++i) {
516
        u = _process[i];
517
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
518
          e = _out_arcs[u][j];
519
          v = _gr.target(e);
520
          d = _data[u][k-1].dist + _length[e];
521
          if (_tolerance.less(d, _data[v][k].dist)) {
522
            if (_data[v][k].dist == INF) next.push_back(v);
523
            _data[v][k] = PathData(d, e);
524
          }
525
        }
526
      }
527
      _process.swap(next);
528
    }
529

	
530
    // Process one round using _nodes instead of _process
531
    void processNextFullRound(int k) {
532
      Node u, v;
533
      Arc e;
534
      LargeValue d;
535
      for (int i = 0; i < int(_nodes->size()); ++i) {
536
        u = (*_nodes)[i];
537
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
538
          e = _out_arcs[u][j];
539
          v = _gr.target(e);
540
          d = _data[u][k-1].dist + _length[e];
541
          if (_tolerance.less(d, _data[v][k].dist)) {
542
            _data[v][k] = PathData(d, e);
543
          }
544
        }
545
      }
546
    }
547

	
548
    // Update the minimum cycle mean
549
    void updateMinMean() {
550
      int n = _nodes->size();
551
      for (int i = 0; i < n; ++i) {
552
        Node u = (*_nodes)[i];
553
        if (_data[u][n].dist == INF) continue;
554
        LargeValue length, max_length = 0;
555
        int size, max_size = 1;
556
        bool found_curr = false;
557
        for (int k = 0; k < n; ++k) {
558
          if (_data[u][k].dist == INF) continue;
559
          length = _data[u][n].dist - _data[u][k].dist;
560
          size = n - k;
561
          if (!found_curr || length * max_size > max_length * size) {
562
            found_curr = true;
563
            max_length = length;
564
            max_size = size;
565
          }
566
        }
567
        if ( found_curr && (_cycle_node == INVALID ||
568
             max_length * _cycle_size < _cycle_length * max_size) ) {
569
          _cycle_length = max_length;
570
          _cycle_size = max_size;
571
          _cycle_node = u;
572
        }
573
      }
574
    }
575

	
576
  }; //class Karp
577

	
578
  ///@}
579

	
580
} //namespace lemon
581

	
582
#endif //LEMON_KARP_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_KARY_HEAP_H
20
#define LEMON_KARY_HEAP_H
21

	
22
///\ingroup heaps
23
///\file
24
///\brief Fourary heap implementation.
25

	
26
#include <vector>
27
#include <utility>
28
#include <functional>
29

	
30
namespace lemon {
31

	
32
  /// \ingroup heaps
33
  ///
34
  ///\brief K-ary heap data structure.
35
  ///
36
  /// This class implements the \e K-ary \e heap data structure.
37
  /// It fully conforms to the \ref concepts::Heap "heap concept".
38
  ///
39
  /// The \ref KaryHeap "K-ary heap" is a generalization of the
40
  /// \ref BinHeap "binary heap" structure, its nodes have at most
41
  /// \c K children, instead of two.
42
  /// \ref BinHeap and \ref FouraryHeap are specialized implementations
43
  /// of this structure for <tt>K=2</tt> and <tt>K=4</tt>, respectively.
44
  ///
45
  /// \tparam PR Type of the priorities of the items.
46
  /// \tparam IM A read-writable item map with \c int values, used
47
  /// internally to handle the cross references.
48
  /// \tparam K The degree of the heap, each node have at most \e K
49
  /// children. The default is 16. Powers of two are suggested to use
50
  /// so that the multiplications and divisions needed to traverse the
51
  /// nodes of the heap could be performed faster.
52
  /// \tparam CMP A functor class for comparing the priorities.
53
  /// The default is \c std::less<PR>.
54
  ///
55
  ///\sa BinHeap
56
  ///\sa FouraryHeap
57
#ifdef DOXYGEN
58
  template <typename PR, typename IM, int K, typename CMP>
59
#else
60
  template <typename PR, typename IM, int K = 16,
61
            typename CMP = std::less<PR> >
62
#endif
63
  class KaryHeap {
64
  public:
65
    /// Type of the item-int map.
66
    typedef IM ItemIntMap;
67
    /// Type of the priorities.
68
    typedef PR Prio;
69
    /// Type of the items stored in the heap.
70
    typedef typename ItemIntMap::Key Item;
71
    /// Type of the item-priority pairs.
72
    typedef std::pair<Item,Prio> Pair;
73
    /// Functor type for comparing the priorities.
74
    typedef CMP Compare;
75

	
76
    /// \brief Type to represent the states of the items.
77
    ///
78
    /// Each item has a state associated to it. It can be "in heap",
79
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
80
    /// heap's point of view, but may be useful to the user.
81
    ///
82
    /// The item-int map must be initialized in such way that it assigns
83
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
84
    enum State {
85
      IN_HEAP = 0,    ///< = 0.
86
      PRE_HEAP = -1,  ///< = -1.
87
      POST_HEAP = -2  ///< = -2.
88
    };
89

	
90
  private:
91
    std::vector<Pair> _data;
92
    Compare _comp;
93
    ItemIntMap &_iim;
94

	
95
  public:
96
    /// \brief Constructor.
97
    ///
98
    /// Constructor.
99
    /// \param map A map that assigns \c int values to the items.
100
    /// It is used internally to handle the cross references.
101
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
102
    explicit KaryHeap(ItemIntMap &map) : _iim(map) {}
103

	
104
    /// \brief Constructor.
105
    ///
106
    /// Constructor.
107
    /// \param map A map that assigns \c int values to the items.
108
    /// It is used internally to handle the cross references.
109
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
110
    /// \param comp The function object used for comparing the priorities.
111
    KaryHeap(ItemIntMap &map, const Compare &comp)
112
      : _iim(map), _comp(comp) {}
113

	
114
    /// \brief The number of items stored in the heap.
115
    ///
116
    /// This function returns the number of items stored in the heap.
117
    int size() const { return _data.size(); }
118

	
119
    /// \brief Check if the heap is empty.
120
    ///
121
    /// This function returns \c true if the heap is empty.
122
    bool empty() const { return _data.empty(); }
123

	
124
    /// \brief Make the heap empty.
125
    ///
126
    /// This functon makes the heap empty.
127
    /// It does not change the cross reference map. If you want to reuse
128
    /// a heap that is not surely empty, you should first clear it and
129
    /// then you should set the cross reference map to \c PRE_HEAP
130
    /// for each item.
131
    void clear() { _data.clear(); }
132

	
133
  private:
134
    int parent(int i) { return (i-1)/K; }
135
    int firstChild(int i) { return K*i+1; }
136

	
137
    bool less(const Pair &p1, const Pair &p2) const {
138
      return _comp(p1.second, p2.second);
139
    }
140

	
141
    void bubbleUp(int hole, Pair p) {
142
      int par = parent(hole);
143
      while( hole>0 && less(p,_data[par]) ) {
144
        move(_data[par],hole);
145
        hole = par;
146
        par = parent(hole);
147
      }
148
      move(p, hole);
149
    }
150

	
151
    void bubbleDown(int hole, Pair p, int length) {
152
      if( length>1 ) {
153
        int child = firstChild(hole);
154
        while( child+K<=length ) {
155
          int min=child;
156
          for (int i=1; i<K; ++i) {
157
            if( less(_data[child+i], _data[min]) )
158
              min=child+i;
159
          }
160
          if( !less(_data[min], p) )
161
            goto ok;
162
          move(_data[min], hole);
163
          hole = min;
164
          child = firstChild(hole);
165
        }
166
        if ( child<length ) {
167
          int min = child;
168
          while (++child < length) {
169
            if( less(_data[child], _data[min]) )
170
              min=child;
171
          }
172
          if( less(_data[min], p) ) {
173
            move(_data[min], hole);
174
            hole = min;
175
          }
176
        }
177
      }
178
    ok:
179
      move(p, hole);
180
    }
181

	
182
    void move(const Pair &p, int i) {
183
      _data[i] = p;
184
      _iim.set(p.first, i);
185
    }
186

	
187
  public:
188
    /// \brief Insert a pair of item and priority into the heap.
189
    ///
190
    /// This function inserts \c p.first to the heap with priority
191
    /// \c p.second.
192
    /// \param p The pair to insert.
193
    /// \pre \c p.first must not be stored in the heap.
194
    void push(const Pair &p) {
195
      int n = _data.size();
196
      _data.resize(n+1);
197
      bubbleUp(n, p);
198
    }
199

	
200
    /// \brief Insert an item into the heap with the given priority.
201
    ///
202
    /// This function inserts the given item into the heap with the
203
    /// given priority.
204
    /// \param i The item to insert.
205
    /// \param p The priority of the item.
206
    /// \pre \e i must not be stored in the heap.
207
    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
208

	
209
    /// \brief Return the item having minimum priority.
210
    ///
211
    /// This function returns the item having minimum priority.
212
    /// \pre The heap must be non-empty.
213
    Item top() const { return _data[0].first; }
214

	
215
    /// \brief The minimum priority.
216
    ///
217
    /// This function returns the minimum priority.
218
    /// \pre The heap must be non-empty.
219
    Prio prio() const { return _data[0].second; }
220

	
221
    /// \brief Remove the item having minimum priority.
222
    ///
223
    /// This function removes the item having minimum priority.
224
    /// \pre The heap must be non-empty.
225
    void pop() {
226
      int n = _data.size()-1;
227
      _iim.set(_data[0].first, POST_HEAP);
228
      if (n>0) bubbleDown(0, _data[n], n);
229
      _data.pop_back();
230
    }
231

	
232
    /// \brief Remove the given item from the heap.
233
    ///
234
    /// This function removes the given item from the heap if it is
235
    /// already stored.
236
    /// \param i The item to delete.
237
    /// \pre \e i must be in the heap.
238
    void erase(const Item &i) {
239
      int h = _iim[i];
240
      int n = _data.size()-1;
241
      _iim.set(_data[h].first, POST_HEAP);
242
      if( h<n ) {
243
        if( less(_data[parent(h)], _data[n]) )
244
          bubbleDown(h, _data[n], n);
245
        else
246
          bubbleUp(h, _data[n]);
247
      }
248
      _data.pop_back();
249
    }
250

	
251
    /// \brief The priority of the given item.
252
    ///
253
    /// This function returns the priority of the given item.
254
    /// \param i The item.
255
    /// \pre \e i must be in the heap.
256
    Prio operator[](const Item &i) const {
257
      int idx = _iim[i];
258
      return _data[idx].second;
259
    }
260

	
261
    /// \brief Set the priority of an item or insert it, if it is
262
    /// not stored in the heap.
263
    ///
264
    /// This method sets the priority of the given item if it is
265
    /// already stored in the heap. Otherwise it inserts the given
266
    /// item into the heap with the given priority.
267
    /// \param i The item.
268
    /// \param p The priority.
269
    void set(const Item &i, const Prio &p) {
270
      int idx = _iim[i];
271
      if( idx<0 )
272
        push(i,p);
273
      else if( _comp(p, _data[idx].second) )
274
        bubbleUp(idx, Pair(i,p));
275
      else
276
        bubbleDown(idx, Pair(i,p), _data.size());
277
    }
278

	
279
    /// \brief Decrease the priority of an item to the given value.
280
    ///
281
    /// This function decreases the priority of an item to the given value.
282
    /// \param i The item.
283
    /// \param p The priority.
284
    /// \pre \e i must be stored in the heap with priority at least \e p.
285
    void decrease(const Item &i, const Prio &p) {
286
      int idx = _iim[i];
287
      bubbleUp(idx, Pair(i,p));
288
    }
289

	
290
    /// \brief Increase the priority of an item to the given value.
291
    ///
292
    /// This function increases the priority of an item to the given value.
293
    /// \param i The item.
294
    /// \param p The priority.
295
    /// \pre \e i must be stored in the heap with priority at most \e p.
296
    void increase(const Item &i, const Prio &p) {
297
      int idx = _iim[i];
298
      bubbleDown(idx, Pair(i,p), _data.size());
299
    }
300

	
301
    /// \brief Return the state of an item.
302
    ///
303
    /// This method returns \c PRE_HEAP if the given item has never
304
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
305
    /// and \c POST_HEAP otherwise.
306
    /// In the latter case it is possible that the item will get back
307
    /// to the heap again.
308
    /// \param i The item.
309
    State state(const Item &i) const {
310
      int s = _iim[i];
311
      if (s>=0) s=0;
312
      return State(s);
313
    }
314

	
315
    /// \brief Set the state of an item in the heap.
316
    ///
317
    /// This function sets the state of the given item in the heap.
318
    /// It can be used to manually clear the heap when it is important
319
    /// to achive better time complexity.
320
    /// \param i The item.
321
    /// \param st The state. It should not be \c IN_HEAP.
322
    void state(const Item& i, State st) {
323
      switch (st) {
324
        case POST_HEAP:
325
        case PRE_HEAP:
326
          if (state(i) == IN_HEAP) erase(i);
327
          _iim[i] = st;
328
          break;
329
        case IN_HEAP:
330
          break;
331
      }
332
    }
333

	
334
    /// \brief Replace an item in the heap.
335
    ///
336
    /// This function replaces item \c i with item \c j.
337
    /// Item \c i must be in the heap, while \c j must be out of the heap.
338
    /// After calling this method, item \c i will be out of the
339
    /// heap and \c j will be in the heap with the same prioriority
340
    /// as item \c i had before.
341
    void replace(const Item& i, const Item& j) {
342
      int idx=_iim[i];
343
      _iim.set(i, _iim[j]);
344
      _iim.set(j, idx);
345
      _data[idx].first=j;
346
    }
347

	
348
  }; // class KaryHeap
349

	
350
} // namespace lemon
351

	
352
#endif // LEMON_KARY_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-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 int _addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
947
      int row = _addRow();
948
      _setRowCoeffs(row, b, e);
949
      _setRowLowerBound(row, l);
950
      _setRowUpperBound(row, u);
951
      return row;
952
    }
953

	
954
    virtual void _eraseCol(int col) = 0;
955
    virtual void _eraseRow(int row) = 0;
956

	
957
    virtual void _getColName(int col, std::string& name) const = 0;
958
    virtual void _setColName(int col, const std::string& name) = 0;
959
    virtual int _colByName(const std::string& name) const = 0;
960

	
961
    virtual void _getRowName(int row, std::string& name) const = 0;
962
    virtual void _setRowName(int row, const std::string& name) = 0;
963
    virtual int _rowByName(const std::string& name) const = 0;
964

	
965
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
966
    virtual void _getRowCoeffs(int i, InsertIterator b) const = 0;
967

	
968
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
969
    virtual void _getColCoeffs(int i, InsertIterator b) const = 0;
970

	
971
    virtual void _setCoeff(int row, int col, Value value) = 0;
972
    virtual Value _getCoeff(int row, int col) const = 0;
973

	
974
    virtual void _setColLowerBound(int i, Value value) = 0;
975
    virtual Value _getColLowerBound(int i) const = 0;
976

	
977
    virtual void _setColUpperBound(int i, Value value) = 0;
978
    virtual Value _getColUpperBound(int i) const = 0;
979

	
980
    virtual void _setRowLowerBound(int i, Value value) = 0;
981
    virtual Value _getRowLowerBound(int i) const = 0;
982

	
983
    virtual void _setRowUpperBound(int i, Value value) = 0;
984
    virtual Value _getRowUpperBound(int i) const = 0;
985

	
986
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
987
    virtual void _getObjCoeffs(InsertIterator b) const = 0;
988

	
989
    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
990
    virtual Value _getObjCoeff(int i) const = 0;
991

	
992
    virtual void _setSense(Sense) = 0;
993
    virtual Sense _getSense() const = 0;
994

	
995
    virtual void _clear() = 0;
996

	
997
    virtual const char* _solverName() const = 0;
998

	
999
    virtual void _messageLevel(MessageLevel level) = 0;
1000

	
1001
    //Own protected stuff
1002

	
1003
    //Constant component of the objective function
1004
    Value obj_const_comp;
1005

	
1006
    LpBase() : rows(), cols(), obj_const_comp(0) {}
1007

	
1008
  public:
1009

	
1010
    /// Virtual destructor
1011
    virtual ~LpBase() {}
1012

	
1013
    ///Gives back the name of the solver.
1014
    const char* solverName() const {return _solverName();}
1015

	
1016
    ///\name Build Up and Modify the LP
1017

	
1018
    ///@{
1019

	
1020
    ///Add a new empty column (i.e a new variable) to the LP
1021
    Col addCol() { Col c; c._id = _addColId(_addCol()); return c;}
1022

	
1023
    ///\brief Adds several new columns (i.e variables) at once
1024
    ///
1025
    ///This magic function takes a container as its argument and fills
1026
    ///its elements with new columns (i.e. variables)
1027
    ///\param t can be
1028
    ///- a standard STL compatible iterable container with
1029
    ///\ref Col as its \c values_type like
1030
    ///\code
1031
    ///std::vector<LpBase::Col>
1032
    ///std::list<LpBase::Col>
1033
    ///\endcode
1034
    ///- a standard STL compatible iterable container with
1035
    ///\ref Col as its \c mapped_type like
1036
    ///\code
1037
    ///std::map<AnyType,LpBase::Col>
1038
    ///\endcode
1039
    ///- an iterable lemon \ref concepts::WriteMap "write map" like
1040
    ///\code
1041
    ///ListGraph::NodeMap<LpBase::Col>
1042
    ///ListGraph::ArcMap<LpBase::Col>
1043
    ///\endcode
1044
    ///\return The number of the created column.
1045
#ifdef DOXYGEN
1046
    template<class T>
1047
    int addColSet(T &t) { return 0;}
1048
#else
1049
    template<class T>
1050
    typename enable_if<typename T::value_type::LpCol,int>::type
1051
    addColSet(T &t,dummy<0> = 0) {
1052
      int s=0;
1053
      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
1054
      return s;
1055
    }
1056
    template<class T>
1057
    typename enable_if<typename T::value_type::second_type::LpCol,
1058
                       int>::type
1059
    addColSet(T &t,dummy<1> = 1) {
1060
      int s=0;
1061
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1062
        i->second=addCol();
1063
        s++;
1064
      }
1065
      return s;
1066
    }
1067
    template<class T>
1068
    typename enable_if<typename T::MapIt::Value::LpCol,
1069
                       int>::type
1070
    addColSet(T &t,dummy<2> = 2) {
1071
      int s=0;
1072
      for(typename T::MapIt i(t); i!=INVALID; ++i)
1073
        {
1074
          i.set(addCol());
1075
          s++;
1076
        }
1077
      return s;
1078
    }
1079
#endif
1080

	
1081
    ///Set a column (i.e a dual constraint) of the LP
1082

	
1083
    ///\param c is the column to be modified
1084
    ///\param e is a dual linear expression (see \ref DualExpr)
1085
    ///a better one.
1086
    void col(Col c, const DualExpr &e) {
1087
      e.simplify();
1088
      _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), rows),
1089
                    ExprIterator(e.comps.end(), rows));
1090
    }
1091

	
1092
    ///Get a column (i.e a dual constraint) of the LP
1093

	
1094
    ///\param c is the column to get
1095
    ///\return the dual expression associated to the column
1096
    DualExpr col(Col c) const {
1097
      DualExpr e;
1098
      _getColCoeffs(cols(id(c)), InsertIterator(e.comps, rows));
1099
      return e;
1100
    }
1101

	
1102
    ///Add a new column to the LP
1103

	
1104
    ///\param e is a dual linear expression (see \ref DualExpr)
1105
    ///\param o is the corresponding component of the objective
1106
    ///function. It is 0 by default.
1107
    ///\return The created column.
1108
    Col addCol(const DualExpr &e, Value o = 0) {
1109
      Col c=addCol();
1110
      col(c,e);
1111
      objCoeff(c,o);
1112
      return c;
1113
    }
1114

	
1115
    ///Add a new empty row (i.e a new constraint) to the LP
1116

	
1117
    ///This function adds a new empty row (i.e a new constraint) to the LP.
1118
    ///\return The created row
1119
    Row addRow() { Row r; r._id = _addRowId(_addRow()); return r;}
1120

	
1121
    ///\brief Add several new rows (i.e constraints) at once
1122
    ///
1123
    ///This magic function takes a container as its argument and fills
1124
    ///its elements with new row (i.e. variables)
1125
    ///\param t can be
1126
    ///- a standard STL compatible iterable container with
1127
    ///\ref Row as its \c values_type like
1128
    ///\code
1129
    ///std::vector<LpBase::Row>
1130
    ///std::list<LpBase::Row>
1131
    ///\endcode
1132
    ///- a standard STL compatible iterable container with
1133
    ///\ref Row as its \c mapped_type like
1134
    ///\code
1135
    ///std::map<AnyType,LpBase::Row>
1136
    ///\endcode
1137
    ///- an iterable lemon \ref concepts::WriteMap "write map" like
1138
    ///\code
1139
    ///ListGraph::NodeMap<LpBase::Row>
1140
    ///ListGraph::ArcMap<LpBase::Row>
1141
    ///\endcode
1142
    ///\return The number of rows created.
1143
#ifdef DOXYGEN
1144
    template<class T>
1145
    int addRowSet(T &t) { return 0;}
1146
#else
1147
    template<class T>
1148
    typename enable_if<typename T::value_type::LpRow,int>::type
1149
    addRowSet(T &t, dummy<0> = 0) {
1150
      int s=0;
1151
      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
1152
      return s;
1153
    }
1154
    template<class T>
1155
    typename enable_if<typename T::value_type::second_type::LpRow, int>::type
1156
    addRowSet(T &t, dummy<1> = 1) {
1157
      int s=0;
1158
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1159
        i->second=addRow();
1160
        s++;
1161
      }
1162
      return s;
1163
    }
1164
    template<class T>
1165
    typename enable_if<typename T::MapIt::Value::LpRow, int>::type
1166
    addRowSet(T &t, dummy<2> = 2) {
1167
      int s=0;
1168
      for(typename T::MapIt i(t); i!=INVALID; ++i)
1169
        {
1170
          i.set(addRow());
1171
          s++;
1172
        }
1173
      return s;
1174
    }
1175
#endif
1176

	
1177
    ///Set a row (i.e a constraint) of the LP
1178

	
1179
    ///\param r is the row to be modified
1180
    ///\param l is lower bound (-\ref INF means no bound)
1181
    ///\param e is a linear expression (see \ref Expr)
1182
    ///\param u is the upper bound (\ref INF means no bound)
1183
    void row(Row r, Value l, const Expr &e, Value u) {
1184
      e.simplify();
1185
      _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols),
1186
                    ExprIterator(e.comps.end(), cols));
1187
      _setRowLowerBound(rows(id(r)),l - *e);
1188
      _setRowUpperBound(rows(id(r)),u - *e);
1189
    }
1190

	
1191
    ///Set a row (i.e a constraint) of the LP
1192

	
1193
    ///\param r is the row to be modified
1194
    ///\param c is a linear expression (see \ref Constr)
1195
    void row(Row r, const Constr &c) {
1196
      row(r, c.lowerBounded()?c.lowerBound():-INF,
1197
          c.expr(), c.upperBounded()?c.upperBound():INF);
1198
    }
1199

	
1200

	
1201
    ///Get a row (i.e a constraint) of the LP
1202

	
1203
    ///\param r is the row to get
1204
    ///\return the expression associated to the row
1205
    Expr row(Row r) const {
1206
      Expr e;
1207
      _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols));
1208
      return e;
1209
    }
1210

	
1211
    ///Add a new row (i.e a new constraint) to the LP
1212

	
1213
    ///\param l is the lower bound (-\ref INF means no bound)
1214
    ///\param e is a linear expression (see \ref Expr)
1215
    ///\param u is the upper bound (\ref INF means no bound)
1216
    ///\return The created row.
1217
    Row addRow(Value l,const Expr &e, Value u) {
1218
      Row r;
1219
      e.simplify();
1220
      r._id = _addRowId(_addRow(l - *e, ExprIterator(e.comps.begin(), cols),
1221
                                ExprIterator(e.comps.end(), cols), u - *e));
1222
      return r;
1223
    }
1224

	
1225
    ///Add a new row (i.e a new constraint) to the LP
1226

	
1227
    ///\param c is a linear expression (see \ref Constr)
1228
    ///\return The created row.
1229
    Row addRow(const Constr &c) {
1230
      Row r;
1231
      c.expr().simplify();
1232
      r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound():-INF, 
1233
                                ExprIterator(c.expr().comps.begin(), cols),
1234
                                ExprIterator(c.expr().comps.end(), cols),
1235
                                c.upperBounded()?c.upperBound():INF));
1236
      return r;
1237
    }
1238
    ///Erase a column (i.e a variable) from the LP
1239

	
1240
    ///\param c is the column to be deleted
1241
    void erase(Col c) {
1242
      _eraseCol(cols(id(c)));
1243
      _eraseColId(cols(id(c)));
1244
    }
1245
    ///Erase a row (i.e a constraint) from the LP
1246

	
1247
    ///\param r is the row to be deleted
1248
    void erase(Row r) {
1249
      _eraseRow(rows(id(r)));
1250
      _eraseRowId(rows(id(r)));
1251
    }
1252

	
1253
    /// Get the name of a column
1254

	
1255
    ///\param c is the coresponding column
1256
    ///\return The name of the colunm
1257
    std::string colName(Col c) const {
1258
      std::string name;
1259
      _getColName(cols(id(c)), name);
1260
      return name;
1261
    }
1262

	
1263
    /// Set the name of a column
1264

	
1265
    ///\param c is the coresponding column
1266
    ///\param name The name to be given
1267
    void colName(Col c, const std::string& name) {
1268
      _setColName(cols(id(c)), name);
1269
    }
1270

	
1271
    /// Get the column by its name
1272

	
1273
    ///\param name The name of the column
1274
    ///\return the proper column or \c INVALID
1275
    Col colByName(const std::string& name) const {
1276
      int k = _colByName(name);
1277
      return k != -1 ? Col(cols[k]) : Col(INVALID);
1278
    }
1279

	
1280
    /// Get the name of a row
1281

	
1282
    ///\param r is the coresponding row
1283
    ///\return The name of the row
1284
    std::string rowName(Row r) const {
1285
      std::string name;
1286
      _getRowName(rows(id(r)), name);
1287
      return name;
1288
    }
1289

	
1290
    /// Set the name of a row
1291

	
1292
    ///\param r is the coresponding row
1293
    ///\param name The name to be given
1294
    void rowName(Row r, const std::string& name) {
1295
      _setRowName(rows(id(r)), name);
1296
    }
1297

	
1298
    /// Get the row by its name
1299

	
1300
    ///\param name The name of the row
1301
    ///\return the proper row or \c INVALID
1302
    Row rowByName(const std::string& name) const {
1303
      int k = _rowByName(name);
1304
      return k != -1 ? Row(rows[k]) : Row(INVALID);
1305
    }
1306

	
1307
    /// Set an element of the coefficient matrix of the LP
1308

	
1309
    ///\param r is the row of the element to be modified
1310
    ///\param c is the column of the element to be modified
1311
    ///\param val is the new value of the coefficient
1312
    void coeff(Row r, Col c, Value val) {
1313
      _setCoeff(rows(id(r)),cols(id(c)), val);
1314
    }
1315

	
1316
    /// Get an element of the coefficient matrix of the LP
1317

	
1318
    ///\param r is the row of the element
1319
    ///\param c is the column of the element
1320
    ///\return the corresponding coefficient
1321
    Value coeff(Row r, Col c) const {
1322
      return _getCoeff(rows(id(r)),cols(id(c)));
1323
    }
1324

	
1325
    /// Set the lower bound of a column (i.e a variable)
1326

	
1327
    /// The lower bound of a variable (column) has to be given by an
1328
    /// extended number of type Value, i.e. a finite number of type
1329
    /// Value or -\ref INF.
1330
    void colLowerBound(Col c, Value value) {
1331
      _setColLowerBound(cols(id(c)),value);
1332
    }
1333

	
1334
    /// Get the lower bound of a column (i.e a variable)
1335

	
1336
    /// This function returns the lower bound for column (variable) \c c
1337
    /// (this might be -\ref INF as well).
1338
    ///\return The lower bound for column \c c
1339
    Value colLowerBound(Col c) const {
1340
      return _getColLowerBound(cols(id(c)));
1341
    }
1342

	
1343
    ///\brief Set the lower bound of  several columns
1344
    ///(i.e variables) at once
1345
    ///
1346
    ///This magic function takes a container as its argument
1347
    ///and applies the function on all of its elements.
1348
    ///The lower bound of a variable (column) has to be given by an
1349
    ///extended number of type Value, i.e. a finite number of type
1350
    ///Value or -\ref INF.
1351
#ifdef DOXYGEN
1352
    template<class T>
1353
    void colLowerBound(T &t, Value value) { return 0;}
1354
#else
1355
    template<class T>
1356
    typename enable_if<typename T::value_type::LpCol,void>::type
1357
    colLowerBound(T &t, Value value,dummy<0> = 0) {
1358
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1359
        colLowerBound(*i, value);
1360
      }
1361
    }
1362
    template<class T>
1363
    typename enable_if<typename T::value_type::second_type::LpCol,
1364
                       void>::type
1365
    colLowerBound(T &t, Value value,dummy<1> = 1) {
1366
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1367
        colLowerBound(i->second, value);
1368
      }
1369
    }
1370
    template<class T>
1371
    typename enable_if<typename T::MapIt::Value::LpCol,
1372
                       void>::type
1373
    colLowerBound(T &t, Value value,dummy<2> = 2) {
1374
      for(typename T::MapIt i(t); i!=INVALID; ++i){
1375
        colLowerBound(*i, value);
1376
      }
1377
    }
1378
#endif
1379

	
1380
    /// Set the upper bound of a column (i.e a variable)
1381

	
1382
    /// The upper bound of a variable (column) has to be given by an
1383
    /// extended number of type Value, i.e. a finite number of type
1384
    /// Value or \ref INF.
1385
    void colUpperBound(Col c, Value value) {
1386
      _setColUpperBound(cols(id(c)),value);
1387
    };
1388

	
1389
    /// Get the upper bound of a column (i.e a variable)
1390

	
1391
    /// This function returns the upper bound for column (variable) \c c
1392
    /// (this might be \ref INF as well).
1393
    /// \return The upper bound for column \c c
1394
    Value colUpperBound(Col c) const {
1395
      return _getColUpperBound(cols(id(c)));
1396
    }
1397

	
1398
    ///\brief Set the upper bound of  several columns
1399
    ///(i.e variables) at once
1400
    ///
1401
    ///This magic function takes a container as its argument
1402
    ///and applies the function on all of its elements.
1403
    ///The upper bound of a variable (column) has to be given by an
1404
    ///extended number of type Value, i.e. a finite number of type
1405
    ///Value or \ref INF.
1406
#ifdef DOXYGEN
1407
    template<class T>
1408
    void colUpperBound(T &t, Value value) { return 0;}
1409
#else
1410
    template<class T1>
1411
    typename enable_if<typename T1::value_type::LpCol,void>::type
1412
    colUpperBound(T1 &t, Value value,dummy<0> = 0) {
1413
      for(typename T1::iterator i=t.begin();i!=t.end();++i) {
1414
        colUpperBound(*i, value);
1415
      }
1416
    }
1417
    template<class T1>
1418
    typename enable_if<typename T1::value_type::second_type::LpCol,
1419
                       void>::type
1420
    colUpperBound(T1 &t, Value value,dummy<1> = 1) {
1421
      for(typename T1::iterator i=t.begin();i!=t.end();++i) {
1422
        colUpperBound(i->second, value);
1423
      }
1424
    }
1425
    template<class T1>
1426
    typename enable_if<typename T1::MapIt::Value::LpCol,
1427
                       void>::type
1428
    colUpperBound(T1 &t, Value value,dummy<2> = 2) {
1429
      for(typename T1::MapIt i(t); i!=INVALID; ++i){
1430
        colUpperBound(*i, value);
1431
      }
1432
    }
1433
#endif
1434

	
1435
    /// Set the lower and the upper bounds of a column (i.e a variable)
1436

	
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
    void colBounds(Col c, Value lower, Value upper) {
1442
      _setColLowerBound(cols(id(c)),lower);
1443
      _setColUpperBound(cols(id(c)),upper);
1444
    }
1445

	
1446
    ///\brief Set the lower and the upper bound of several columns
1447
    ///(i.e variables) at once
1448
    ///
1449
    ///This magic function takes a container as its argument
1450
    ///and applies the function on all of its elements.
1451
    /// The lower and the upper bounds of
1452
    /// a variable (column) have to be given by an
1453
    /// extended number of type Value, i.e. a finite number of type
1454
    /// Value, -\ref INF or \ref INF.
1455
#ifdef DOXYGEN
1456
    template<class T>
1457
    void colBounds(T &t, Value lower, Value upper) { return 0;}
1458
#else
1459
    template<class T2>
1460
    typename enable_if<typename T2::value_type::LpCol,void>::type
1461
    colBounds(T2 &t, Value lower, Value upper,dummy<0> = 0) {
1462
      for(typename T2::iterator i=t.begin();i!=t.end();++i) {
1463
        colBounds(*i, lower, upper);
1464
      }
1465
    }
1466
    template<class T2>
1467
    typename enable_if<typename T2::value_type::second_type::LpCol, void>::type
1468
    colBounds(T2 &t, Value lower, Value upper,dummy<1> = 1) {
1469
      for(typename T2::iterator i=t.begin();i!=t.end();++i) {
1470
        colBounds(i->second, lower, upper);
1471
      }
1472
    }
1473
    template<class T2>
1474
    typename enable_if<typename T2::MapIt::Value::LpCol, void>::type
1475
    colBounds(T2 &t, Value lower, Value upper,dummy<2> = 2) {
1476
      for(typename T2::MapIt i(t); i!=INVALID; ++i){
1477
        colBounds(*i, lower, upper);
1478
      }
1479
    }
1480
#endif
1481

	
1482
    /// Set the lower bound of a row (i.e a constraint)
1483

	
1484
    /// The lower bound of a constraint (row) has to be given by an
1485
    /// extended number of type Value, i.e. a finite number of type
1486
    /// Value or -\ref INF.
1487
    void rowLowerBound(Row r, Value value) {
1488
      _setRowLowerBound(rows(id(r)),value);
1489
    }
1490

	
1491
    /// Get the lower bound of a row (i.e a constraint)
1492

	
1493
    /// This function returns the lower bound for row (constraint) \c c
1494
    /// (this might be -\ref INF as well).
1495
    ///\return The lower bound for row \c r
1496
    Value rowLowerBound(Row r) const {
1497
      return _getRowLowerBound(rows(id(r)));
1498
    }
1499

	
1500
    /// Set the upper bound of a row (i.e a constraint)
1501

	
1502
    /// The upper bound of a constraint (row) has to be given by an
1503
    /// extended number of type Value, i.e. a finite number of type
1504
    /// Value or -\ref INF.
1505
    void rowUpperBound(Row r, Value value) {
1506
      _setRowUpperBound(rows(id(r)),value);
1507
    }
1508

	
1509
    /// Get the upper bound of a row (i.e a constraint)
1510

	
1511
    /// This function returns the upper bound for row (constraint) \c c
1512
    /// (this might be -\ref INF as well).
1513
    ///\return The upper bound for row \c r
1514
    Value rowUpperBound(Row r) const {
1515
      return _getRowUpperBound(rows(id(r)));
1516
    }
1517

	
1518
    ///Set an element of the objective function
1519
    void objCoeff(Col c, Value v) {_setObjCoeff(cols(id(c)),v); };
1520

	
1521
    ///Get an element of the objective function
1522
    Value objCoeff(Col c) const { return _getObjCoeff(cols(id(c))); };
1523

	
1524
    ///Set the objective function
1525

	
1526
    ///\param e is a linear expression of type \ref Expr.
1527
    ///
1528
    void obj(const Expr& e) {
1529
      _setObjCoeffs(ExprIterator(e.comps.begin(), cols),
1530
                    ExprIterator(e.comps.end(), cols));
1531
      obj_const_comp = *e;
1532
    }
1533

	
1534
    ///Get the objective function
1535

	
1536
    ///\return the objective function as a linear expression of type
1537
    ///Expr.
1538
    Expr obj() const {
1539
      Expr e;
1540
      _getObjCoeffs(InsertIterator(e.comps, cols));
1541
      *e = obj_const_comp;
1542
      return e;
1543
    }
1544

	
1545

	
1546
    ///Set the direction of optimization
1547
    void sense(Sense sense) { _setSense(sense); }
1548

	
1549
    ///Query the direction of the optimization
1550
    Sense sense() const {return _getSense(); }
1551

	
1552
    ///Set the sense to maximization
1553
    void max() { _setSense(MAX); }
1554

	
1555
    ///Set the sense to maximization
1556
    void min() { _setSense(MIN); }
1557

	
1558
    ///Clears the problem
1559
    void clear() { _clear(); }
1560

	
1561
    /// Sets the message level of the solver
1562
    void messageLevel(MessageLevel level) { _messageLevel(level); }
1563

	
1564
    ///@}
1565

	
1566
  };
1567

	
1568
  /// Addition
1569

	
1570
  ///\relates LpBase::Expr
1571
  ///
1572
  inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) {
1573
    LpBase::Expr tmp(a);
1574
    tmp+=b;
1575
    return tmp;
1576
  }
1577
  ///Substraction
1578

	
1579
  ///\relates LpBase::Expr
1580
  ///
1581
  inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) {
1582
    LpBase::Expr tmp(a);
1583
    tmp-=b;
1584
    return tmp;
1585
  }
1586
  ///Multiply with constant
1587

	
1588
  ///\relates LpBase::Expr
1589
  ///
1590
  inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) {
1591
    LpBase::Expr tmp(a);
1592
    tmp*=b;
1593
    return tmp;
1594
  }
1595

	
1596
  ///Multiply with constant
1597

	
1598
  ///\relates LpBase::Expr
1599
  ///
1600
  inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) {
1601
    LpBase::Expr tmp(b);
1602
    tmp*=a;
1603
    return tmp;
1604
  }
1605
  ///Divide with constant
1606

	
1607
  ///\relates LpBase::Expr
1608
  ///
1609
  inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) {
1610
    LpBase::Expr tmp(a);
1611
    tmp/=b;
1612
    return tmp;
1613
  }
1614

	
1615
  ///Create constraint
1616

	
1617
  ///\relates LpBase::Constr
1618
  ///
1619
  inline LpBase::Constr operator<=(const LpBase::Expr &e,
1620
                                   const LpBase::Expr &f) {
1621
    return LpBase::Constr(0, f - e, LpBase::INF);
1622
  }
1623

	
1624
  ///Create constraint
1625

	
1626
  ///\relates LpBase::Constr
1627
  ///
1628
  inline LpBase::Constr operator<=(const LpBase::Value &e,
1629
                                   const LpBase::Expr &f) {
1630
    return LpBase::Constr(e, f, LpBase::NaN);
1631
  }
1632

	
1633
  ///Create constraint
1634

	
1635
  ///\relates LpBase::Constr
1636
  ///
1637
  inline LpBase::Constr operator<=(const LpBase::Expr &e,
1638
                                   const LpBase::Value &f) {
1639
    return LpBase::Constr(- LpBase::INF, e, f);
1640
  }
1641

	
1642
  ///Create constraint
1643

	
1644
  ///\relates LpBase::Constr
1645
  ///
1646
  inline LpBase::Constr operator>=(const LpBase::Expr &e,
1647
                                   const LpBase::Expr &f) {
1648
    return LpBase::Constr(0, e - f, LpBase::INF);
1649
  }
1650

	
1651

	
1652
  ///Create constraint
1653

	
1654
  ///\relates LpBase::Constr
1655
  ///
1656
  inline LpBase::Constr operator>=(const LpBase::Value &e,
1657
                                   const LpBase::Expr &f) {
1658
    return LpBase::Constr(LpBase::NaN, f, e);
1659
  }
1660

	
1661

	
1662
  ///Create constraint
1663

	
1664
  ///\relates LpBase::Constr
1665
  ///
1666
  inline LpBase::Constr operator>=(const LpBase::Expr &e,
1667
                                   const LpBase::Value &f) {
1668
    return LpBase::Constr(f, e, LpBase::INF);
1669
  }
1670

	
1671
  ///Create constraint
1672

	
1673
  ///\relates LpBase::Constr
1674
  ///
1675
  inline LpBase::Constr operator==(const LpBase::Expr &e,
1676
                                   const LpBase::Value &f) {
1677
    return LpBase::Constr(f, e, f);
1678
  }
1679

	
1680
  ///Create constraint
1681

	
1682
  ///\relates LpBase::Constr
1683
  ///
1684
  inline LpBase::Constr operator==(const LpBase::Expr &e,
1685
                                   const LpBase::Expr &f) {
1686
    return LpBase::Constr(0, f - e, 0);
1687
  }
1688

	
1689
  ///Create constraint
1690

	
1691
  ///\relates LpBase::Constr
1692
  ///
1693
  inline LpBase::Constr operator<=(const LpBase::Value &n,
1694
                                   const LpBase::Constr &c) {
1695
    LpBase::Constr tmp(c);
1696
    LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
1697
    tmp.lowerBound()=n;
1698
    return tmp;
1699
  }
1700
  ///Create constraint
1701

	
1702
  ///\relates LpBase::Constr
1703
  ///
1704
  inline LpBase::Constr operator<=(const LpBase::Constr &c,
1705
                                   const LpBase::Value &n)
1706
  {
1707
    LpBase::Constr tmp(c);
1708
    LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
1709
    tmp.upperBound()=n;
1710
    return tmp;
1711
  }
1712

	
1713
  ///Create constraint
1714

	
1715
  ///\relates LpBase::Constr
1716
  ///
1717
  inline LpBase::Constr operator>=(const LpBase::Value &n,
1718
                                   const LpBase::Constr &c) {
1719
    LpBase::Constr tmp(c);
1720
    LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
1721
    tmp.upperBound()=n;
1722
    return tmp;
1723
  }
1724
  ///Create constraint
1725

	
1726
  ///\relates LpBase::Constr
1727
  ///
1728
  inline LpBase::Constr operator>=(const LpBase::Constr &c,
1729
                                   const LpBase::Value &n)
1730
  {
1731
    LpBase::Constr tmp(c);
1732
    LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
1733
    tmp.lowerBound()=n;
1734
    return tmp;
1735
  }
1736

	
1737
  ///Addition
1738

	
1739
  ///\relates LpBase::DualExpr
1740
  ///
1741
  inline LpBase::DualExpr operator+(const LpBase::DualExpr &a,
1742
                                    const LpBase::DualExpr &b) {
1743
    LpBase::DualExpr tmp(a);
1744
    tmp+=b;
1745
    return tmp;
1746
  }
1747
  ///Substraction
1748

	
1749
  ///\relates LpBase::DualExpr
1750
  ///
1751
  inline LpBase::DualExpr operator-(const LpBase::DualExpr &a,
1752
                                    const LpBase::DualExpr &b) {
1753
    LpBase::DualExpr tmp(a);
1754
    tmp-=b;
1755
    return tmp;
1756
  }
1757
  ///Multiply with constant
1758

	
1759
  ///\relates LpBase::DualExpr
1760
  ///
1761
  inline LpBase::DualExpr operator*(const LpBase::DualExpr &a,
1762
                                    const LpBase::Value &b) {
1763
    LpBase::DualExpr tmp(a);
1764
    tmp*=b;
1765
    return tmp;
1766
  }
1767

	
1768
  ///Multiply with constant
1769

	
1770
  ///\relates LpBase::DualExpr
1771
  ///
1772
  inline LpBase::DualExpr operator*(const LpBase::Value &a,
1773
                                    const LpBase::DualExpr &b) {
1774
    LpBase::DualExpr tmp(b);
1775
    tmp*=a;
1776
    return tmp;
1777
  }
1778
  ///Divide with constant
1779

	
1780
  ///\relates LpBase::DualExpr
1781
  ///
1782
  inline LpBase::DualExpr operator/(const LpBase::DualExpr &a,
1783
                                    const LpBase::Value &b) {
1784
    LpBase::DualExpr tmp(a);
1785
    tmp/=b;
1786
    return tmp;
1787
  }
1788

	
1789
  /// \ingroup lp_group
1790
  ///
1791
  /// \brief Common base class for LP solvers
1792
  ///
1793
  /// This class is an abstract base class for LP solvers. This class
1794
  /// provides a full interface for set and modify an LP problem,
1795
  /// solve it and retrieve the solution. You can use one of the
1796
  /// descendants as a concrete implementation, or the \c Lp
1797
  /// default LP solver. However, if you would like to handle LP
1798
  /// solvers as reference or pointer in a generic way, you can use
1799
  /// this class directly.
1800
  class LpSolver : virtual public LpBase {
1801
  public:
1802

	
1803
    /// The problem types for primal and dual problems
1804
    enum ProblemType {
1805
      /// = 0. Feasible solution hasn't been found (but may exist).
1806
      UNDEFINED = 0,
1807
      /// = 1. The problem has no feasible solution.
1808
      INFEASIBLE = 1,
1809
      /// = 2. Feasible solution found.
1810
      FEASIBLE = 2,
1811
      /// = 3. Optimal solution exists and found.
1812
      OPTIMAL = 3,
1813
      /// = 4. The cost function is unbounded.
1814
      UNBOUNDED = 4
1815
    };
1816

	
1817
    ///The basis status of variables
1818
    enum VarStatus {
1819
      /// The variable is in the basis
1820
      BASIC, 
1821
      /// The variable is free, but not basic
1822
      FREE,
1823
      /// The variable has active lower bound 
1824
      LOWER,
1825
      /// The variable has active upper bound
1826
      UPPER,
1827
      /// The variable is non-basic and fixed
1828
      FIXED
1829
    };
1830

	
1831
  protected:
1832

	
1833
    virtual SolveExitStatus _solve() = 0;
1834

	
1835
    virtual Value _getPrimal(int i) const = 0;
1836
    virtual Value _getDual(int i) const = 0;
1837

	
1838
    virtual Value _getPrimalRay(int i) const = 0;
1839
    virtual Value _getDualRay(int i) const = 0;
1840

	
1841
    virtual Value _getPrimalValue() const = 0;
1842

	
1843
    virtual VarStatus _getColStatus(int i) const = 0;
1844
    virtual VarStatus _getRowStatus(int i) const = 0;
1845

	
1846
    virtual ProblemType _getPrimalType() const = 0;
1847
    virtual ProblemType _getDualType() const = 0;
1848

	
1849
  public:
1850

	
1851
    ///Allocate a new LP problem instance
1852
    virtual LpSolver* newSolver() const = 0;
1853
    ///Make a copy of the LP problem
1854
    virtual LpSolver* cloneSolver() const = 0;
1855

	
1856
    ///\name Solve the LP
1857

	
1858
    ///@{
1859

	
1860
    ///\e Solve the LP problem at hand
1861
    ///
1862
    ///\return The result of the optimization procedure. Possible
1863
    ///values and their meanings can be found in the documentation of
1864
    ///\ref SolveExitStatus.
1865
    SolveExitStatus solve() { return _solve(); }
1866

	
1867
    ///@}
1868

	
1869
    ///\name Obtain the Solution
1870

	
1871
    ///@{
1872

	
1873
    /// The type of the primal problem
1874
    ProblemType primalType() const {
1875
      return _getPrimalType();
1876
    }
1877

	
1878
    /// The type of the dual problem
1879
    ProblemType dualType() const {
1880
      return _getDualType();
1881
    }
1882

	
1883
    /// Return the primal value of the column
1884

	
1885
    /// Return the primal value of the column.
1886
    /// \pre The problem is solved.
1887
    Value primal(Col c) const { return _getPrimal(cols(id(c))); }
1888

	
1889
    /// Return the primal value of the expression
1890

	
1891
    /// Return the primal value of the expression, i.e. the dot
1892
    /// product of the primal solution and the expression.
1893
    /// \pre The problem is solved.
1894
    Value primal(const Expr& e) const {
1895
      double res = *e;
1896
      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
1897
        res += *c * primal(c);
1898
      }
1899
      return res;
1900
    }
1901
    /// Returns a component of the primal ray
1902
    
1903
    /// The primal ray is solution of the modified primal problem,
1904
    /// where we change each finite bound to 0, and we looking for a
1905
    /// negative objective value in case of minimization, and positive
1906
    /// objective value for maximization. If there is such solution,
1907
    /// that proofs the unsolvability of the dual problem, and if a
1908
    /// feasible primal solution exists, then the unboundness of
1909
    /// primal problem.
1910
    ///
1911
    /// \pre The problem is solved and the dual problem is infeasible.
1912
    /// \note Some solvers does not provide primal ray calculation
1913
    /// functions.
1914
    Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); }
1915

	
1916
    /// Return the dual value of the row
1917

	
1918
    /// Return the dual value of the row.
1919
    /// \pre The problem is solved.
1920
    Value dual(Row r) const { return _getDual(rows(id(r))); }
1921

	
1922
    /// Return the dual value of the dual expression
1923

	
1924
    /// Return the dual value of the dual expression, i.e. the dot
1925
    /// product of the dual solution and the dual expression.
1926
    /// \pre The problem is solved.
1927
    Value dual(const DualExpr& e) const {
1928
      double res = 0.0;
1929
      for (DualExpr::ConstCoeffIt r(e); r != INVALID; ++r) {
1930
        res += *r * dual(r);
1931
      }
1932
      return res;
1933
    }
1934

	
1935
    /// Returns a component of the dual ray
1936
    
1937
    /// The dual ray is solution of the modified primal problem, where
1938
    /// we change each finite bound to 0 (i.e. the objective function
1939
    /// coefficients in the primal problem), and we looking for a
1940
    /// ositive objective value. If there is such solution, that
1941
    /// proofs the unsolvability of the primal problem, and if a
1942
    /// feasible dual solution exists, then the unboundness of
1943
    /// dual problem.
1944
    ///
1945
    /// \pre The problem is solved and the primal problem is infeasible.
1946
    /// \note Some solvers does not provide dual ray calculation
1947
    /// functions.
1948
    Value dualRay(Row r) const { return _getDualRay(rows(id(r))); }
1949

	
1950
    /// Return the basis status of the column
1951

	
1952
    /// \see VarStatus
1953
    VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); }
1954

	
1955
    /// Return the basis status of the row
1956

	
1957
    /// \see VarStatus
1958
    VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); }
1959

	
1960
    ///The value of the objective function
1961

	
1962
    ///\return
1963
    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
1964
    /// of the primal problem, depending on whether we minimize or maximize.
1965
    ///- \ref NaN if no primal solution is found.
1966
    ///- The (finite) objective value if an optimal solution is found.
1967
    Value primal() const { return _getPrimalValue()+obj_const_comp;}
1968
    ///@}
1969

	
1970
  protected:
1971

	
1972
  };
1973

	
1974

	
1975
  /// \ingroup lp_group
1976
  ///
1977
  /// \brief Common base class for MIP solvers
1978
  ///
1979
  /// This class is an abstract base class for MIP solvers. This class
1980
  /// provides a full interface for set and modify an MIP problem,
1981
  /// solve it and retrieve the solution. You can use one of the
1982
  /// descendants as a concrete implementation, or the \c Lp
1983
  /// default MIP solver. However, if you would like to handle MIP
1984
  /// solvers as reference or pointer in a generic way, you can use
1985
  /// this class directly.
1986
  class MipSolver : virtual public LpBase {
1987
  public:
1988

	
1989
    /// The problem types for MIP problems
1990
    enum ProblemType {
1991
      /// = 0. Feasible solution hasn't been found (but may exist).
1992
      UNDEFINED = 0,
1993
      /// = 1. The problem has no feasible solution.
1994
      INFEASIBLE = 1,
1995
      /// = 2. Feasible solution found.
1996
      FEASIBLE = 2,
1997
      /// = 3. Optimal solution exists and found.
1998
      OPTIMAL = 3,
1999
      /// = 4. The cost function is unbounded.
2000
      ///The Mip or at least the relaxed problem is unbounded.
2001
      UNBOUNDED = 4
2002
    };
2003

	
2004
    ///Allocate a new MIP problem instance
2005
    virtual MipSolver* newSolver() const = 0;
2006
    ///Make a copy of the MIP problem
2007
    virtual MipSolver* cloneSolver() const = 0;
2008

	
2009
    ///\name Solve the MIP
2010

	
2011
    ///@{
2012

	
2013
    /// Solve the MIP problem at hand
2014
    ///
2015
    ///\return The result of the optimization procedure. Possible
2016
    ///values and their meanings can be found in the documentation of
2017
    ///\ref SolveExitStatus.
2018
    SolveExitStatus solve() { return _solve(); }
2019

	
2020
    ///@}
2021

	
2022
    ///\name Set Column Type
2023
    ///@{
2024

	
2025
    ///Possible variable (column) types (e.g. real, integer, binary etc.)
2026
    enum ColTypes {
2027
      /// = 0. Continuous variable (default).
2028
      REAL = 0,
2029
      /// = 1. Integer variable.
2030
      INTEGER = 1
2031
    };
2032

	
2033
    ///Sets the type of the given column to the given type
2034

	
2035
    ///Sets the type of the given column to the given type.
2036
    ///
2037
    void colType(Col c, ColTypes col_type) {
2038
      _setColType(cols(id(c)),col_type);
2039
    }
2040

	
2041
    ///Gives back the type of the column.
2042

	
2043
    ///Gives back the type of the column.
2044
    ///
2045
    ColTypes colType(Col c) const {
2046
      return _getColType(cols(id(c)));
2047
    }
2048
    ///@}
2049

	
2050
    ///\name Obtain the Solution
2051

	
2052
    ///@{
2053

	
2054
    /// The type of the MIP problem
2055
    ProblemType type() const {
2056
      return _getType();
2057
    }
2058

	
2059
    /// Return the value of the row in the solution
2060

	
2061
    ///  Return the value of the row in the solution.
2062
    /// \pre The problem is solved.
2063
    Value sol(Col c) const { return _getSol(cols(id(c))); }
2064

	
2065
    /// Return the value of the expression in the solution
2066

	
2067
    /// Return the value of the expression in the solution, i.e. the
2068
    /// dot product of the solution and the expression.
2069
    /// \pre The problem is solved.
2070
    Value sol(const Expr& e) const {
2071
      double res = *e;
2072
      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
2073
        res += *c * sol(c);
2074
      }
2075
      return res;
2076
    }
2077
    ///The value of the objective function
2078
    
2079
    ///\return
2080
    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
2081
    /// of the problem, depending on whether we minimize or maximize.
2082
    ///- \ref NaN if no primal solution is found.
2083
    ///- The (finite) objective value if an optimal solution is found.
2084
    Value solValue() const { return _getSolValue()+obj_const_comp;}
2085
    ///@}
2086

	
2087
  protected:
2088

	
2089
    virtual SolveExitStatus _solve() = 0;
2090
    virtual ColTypes _getColType(int col) const = 0;
2091
    virtual void _setColType(int col, ColTypes col_type) = 0;
2092
    virtual ProblemType _getType() const = 0;
2093
    virtual Value _getSol(int i) const = 0;
2094
    virtual Value _getSolValue() const = 0;
2095

	
2096
  };
2097

	
2098

	
2099

	
2100
} //namespace lemon
2101

	
2102
#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
  int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
36
  {
37
    return ++row_num;
38
  }
39

	
40
  void SkeletonSolverBase::_eraseCol(int) {}
41
  void SkeletonSolverBase::_eraseRow(int) {}
42

	
43
  void SkeletonSolverBase::_getColName(int, std::string &) const {}
44
  void SkeletonSolverBase::_setColName(int, const std::string &) {}
45
  int SkeletonSolverBase::_colByName(const std::string&) const { return -1; }
46

	
47
  void SkeletonSolverBase::_getRowName(int, std::string &) const {}
48
  void SkeletonSolverBase::_setRowName(int, const std::string &) {}
49
  int SkeletonSolverBase::_rowByName(const std::string&) const { return -1; }
50

	
51
  void SkeletonSolverBase::_setRowCoeffs(int, ExprIterator, ExprIterator) {}
52
  void SkeletonSolverBase::_getRowCoeffs(int, InsertIterator) const {}
53

	
54
  void SkeletonSolverBase::_setColCoeffs(int, ExprIterator, ExprIterator) {}
55
  void SkeletonSolverBase::_getColCoeffs(int, InsertIterator) const {}
56

	
57
  void SkeletonSolverBase::_setCoeff(int, int, Value) {}
58
  SkeletonSolverBase::Value SkeletonSolverBase::_getCoeff(int, int) const
59
  { return 0; }
60

	
61
  void SkeletonSolverBase::_setColLowerBound(int, Value) {}
62
  SkeletonSolverBase::Value SkeletonSolverBase::_getColLowerBound(int) const
63
  {  return 0; }
64

	
65
  void SkeletonSolverBase::_setColUpperBound(int, Value) {}
66
  SkeletonSolverBase::Value SkeletonSolverBase::_getColUpperBound(int) const
67
  {  return 0; }
68

	
69
  void SkeletonSolverBase::_setRowLowerBound(int, Value) {}
70
  SkeletonSolverBase::Value SkeletonSolverBase::_getRowLowerBound(int) const
71
  {  return 0; }
72

	
73
  void SkeletonSolverBase::_setRowUpperBound(int, Value) {}
74
  SkeletonSolverBase::Value SkeletonSolverBase::_getRowUpperBound(int) const
75
  {  return 0; }
76

	
77
  void SkeletonSolverBase::_setObjCoeffs(ExprIterator, ExprIterator) {}
78
  void SkeletonSolverBase::_getObjCoeffs(InsertIterator) const {};
79

	
80
  void SkeletonSolverBase::_setObjCoeff(int, Value) {}
81
  SkeletonSolverBase::Value SkeletonSolverBase::_getObjCoeff(int) const
82
  {  return 0; }
83

	
84
  void SkeletonSolverBase::_setSense(Sense) {}
85
  SkeletonSolverBase::Sense SkeletonSolverBase::_getSense() const
86
  { return MIN; }
87

	
88
  void SkeletonSolverBase::_clear() {
89
    row_num = col_num = 0;
90
  }
91

	
92
  void SkeletonSolverBase::_messageLevel(MessageLevel) {}
93

	
94
  LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
95

	
96
  LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
97
  LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; }
98
  LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; }
99

	
100
  LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; }
101
  LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; }
102

	
103
  LpSkeleton::ProblemType LpSkeleton::_getPrimalType() const
104
  { return UNDEFINED; }
105

	
106
  LpSkeleton::ProblemType LpSkeleton::_getDualType() const
107
  { return UNDEFINED; }
108

	
109
  LpSkeleton::VarStatus LpSkeleton::_getColStatus(int) const
110
  { return BASIC; }
111

	
112
  LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
113
  { return BASIC; }
114

	
115
  LpSkeleton* LpSkeleton::newSolver() const
116
  { return static_cast<LpSkeleton*>(0); }
117

	
118
  LpSkeleton* LpSkeleton::cloneSolver() const
119
  { return static_cast<LpSkeleton*>(0); }
120

	
121
  const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
122

	
123
  MipSkeleton::SolveExitStatus MipSkeleton::_solve()
124
  { return SOLVED; }
125

	
126
  MipSkeleton::Value MipSkeleton::_getSol(int) const { return 0; }
127
  MipSkeleton::Value MipSkeleton::_getSolValue() const { return 0; }
128

	
129
  MipSkeleton::ProblemType MipSkeleton::_getType() const
130
  { return UNDEFINED; }
131

	
132
  MipSkeleton* MipSkeleton::newSolver() const
133
  { return static_cast<MipSkeleton*>(0); }
134

	
135
  MipSkeleton* MipSkeleton::cloneSolver() const
136
  { return static_cast<MipSkeleton*>(0); }
137

	
138
  const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
139

	
140
} //namespace lemon
141

	
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 int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
49
    /// \e
50
    virtual void _eraseCol(int i);
51
    /// \e
52
    virtual void _eraseRow(int i);
53

	
54
    /// \e
55
    virtual void _getColName(int col, std::string& name) const;
56
    /// \e
57
    virtual void _setColName(int col, const std::string& name);
58
    /// \e
59
    virtual int _colByName(const std::string& name) const;
60

	
61
    /// \e
62
    virtual void _getRowName(int row, std::string& name) const;
63
    /// \e
64
    virtual void _setRowName(int row, const std::string& name);
65
    /// \e
66
    virtual int _rowByName(const std::string& name) const;
67

	
68
    /// \e
69
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
70
    /// \e
71
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
72
    /// \e
73
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
74
    /// \e
75
    virtual void _getColCoeffs(int i, InsertIterator b) const;
76

	
77
    /// Set one element of the coefficient matrix
78
    virtual void _setCoeff(int row, int col, Value value);
79

	
80
    /// Get one element of the coefficient matrix
81
    virtual Value _getCoeff(int row, int col) const;
82

	
83
    /// The lower bound of a variable (column) have to be given by an
84
    /// extended number of type Value, i.e. a finite number of type
85
    /// Value or -\ref INF.
86
    virtual void _setColLowerBound(int i, Value value);
87
    /// \e
88

	
89
    /// The lower bound of a variable (column) is an
90
    /// extended number of type Value, i.e. a finite number of type
91
    /// Value or -\ref INF.
92
    virtual Value _getColLowerBound(int i) const;
93

	
94
    /// The upper bound of a variable (column) have to be given by an
95
    /// extended number of type Value, i.e. a finite number of type
96
    /// Value or \ref INF.
97
    virtual void _setColUpperBound(int i, Value value);
98
    /// \e
99

	
100
    /// The upper bound of a variable (column) is an
101
    /// extended number of type Value, i.e. a finite number of type
102
    /// Value or \ref INF.
103
    virtual Value _getColUpperBound(int i) const;
104

	
105
    /// The lower bound of a constraint (row) have to be given by an
106
    /// extended number of type Value, i.e. a finite number of type
107
    /// Value or -\ref INF.
108
    virtual void _setRowLowerBound(int i, Value value);
109
    /// \e
110

	
111
    /// The lower bound of a constraint (row) is an
112
    /// extended number of type Value, i.e. a finite number of type
113
    /// Value or -\ref INF.
114
    virtual Value _getRowLowerBound(int i) const;
115

	
116
    /// The upper bound of a constraint (row) have to be given by an
117
    /// extended number of type Value, i.e. a finite number of type
118
    /// Value or \ref INF.
119
    virtual void _setRowUpperBound(int i, Value value);
120
    /// \e
121

	
122
    /// The upper bound of a constraint (row) is an
123
    /// extended number of type Value, i.e. a finite number of type
124
    /// Value or \ref INF.
125
    virtual Value _getRowUpperBound(int i) const;
126

	
127
    /// \e
128
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
129
    /// \e
130
    virtual void _getObjCoeffs(InsertIterator b) const;
131

	
132
    /// \e
133
    virtual void _setObjCoeff(int i, Value obj_coef);
134
    /// \e
135
    virtual Value _getObjCoeff(int i) const;
136

	
137
    ///\e
138
    virtual void _setSense(Sense);
139
    ///\e
140
    virtual Sense _getSense() const;
141

	
142
    ///\e
143
    virtual void _clear();
144

	
145
    ///\e
146
    virtual void _messageLevel(MessageLevel);
147
  };
148

	
149
  /// \brief Skeleton class for an LP solver interface
150
  ///
151
  ///This class does nothing, but it can serve as a skeleton when
152
  ///implementing an interface to new solvers.
153

	
154
  ///\ingroup lp_group
155
  class LpSkeleton : public LpSolver, public SkeletonSolverBase {
156
  public:
157
    ///\e
158
    LpSkeleton() : LpSolver(), SkeletonSolverBase() {}
159
    ///\e
160
    virtual LpSkeleton* newSolver() const;
161
    ///\e
162
    virtual LpSkeleton* cloneSolver() const;
163
  protected:
164

	
165
    ///\e
166
    virtual SolveExitStatus _solve();
167

	
168
    ///\e
169
    virtual Value _getPrimal(int i) const;
170
    ///\e
171
    virtual Value _getDual(int i) const;
172

	
173
    ///\e
174
    virtual Value _getPrimalValue() const;
175

	
176
    ///\e
177
    virtual Value _getPrimalRay(int i) const;
178
    ///\e
179
    virtual Value _getDualRay(int i) const;
180

	
181
    ///\e
182
    virtual ProblemType _getPrimalType() const;
183
    ///\e
184
    virtual ProblemType _getDualType() const;
185

	
186
    ///\e
187
    virtual VarStatus _getColStatus(int i) const;
188
    ///\e
189
    virtual VarStatus _getRowStatus(int i) const;
190

	
191
    ///\e
192
    virtual const char* _solverName() const;
193

	
194
  };
195

	
196
  /// \brief Skeleton class for a MIP solver interface
197
  ///
198
  ///This class does nothing, but it can serve as a skeleton when
199
  ///implementing an interface to new solvers.
200
  ///\ingroup lp_group
201
  class MipSkeleton : public MipSolver, public SkeletonSolverBase {
202
  public:
203
    ///\e
204
    MipSkeleton() : MipSolver(), SkeletonSolverBase() {}
205
    ///\e
206
    virtual MipSkeleton* newSolver() const;
207
    ///\e
208
    virtual MipSkeleton* cloneSolver() const;
209

	
210
  protected:
211
    ///\e
212
    virtual SolveExitStatus _solve();
213

	
214
    ///\e
215
    virtual Value _getSol(int i) const;
216

	
217
    ///\e
218
    virtual Value _getSolValue() const;
219

	
220
    ///\e
221
    virtual ProblemType _getType() const;
222

	
223
    ///\e
224
    virtual const char* _solverName() const;
225
  };
226

	
227
} //namespace lemon
228

	
229
#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 better control on the execution,
492
    /// you have to call \ref init() first, 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
  /// \ref amo93networkflows, \ref dantzig63linearprog,
45
  /// \ref kellyoneill91netsimplex.
46
  /// This algorithm is a specialized version of the linear programming
47
  /// simplex method directly for the minimum cost flow problem.
48
  /// It is one of the most efficient solution methods.
49
  ///
50
  /// In general this class is the fastest implementation available
51
  /// in LEMON for the minimum cost flow problem.
52
  /// Moreover it supports both directions of the supply/demand inequality
53
  /// constraints. For more information see \ref SupplyType.
54
  ///
55
  /// Most of the parameters of the problem (except for the digraph)
56
  /// can be given using separate functions, and the algorithm can be
57
  /// executed using the \ref run() function. If some parameters are not
58
  /// specified, then default values will be used.
59
  ///
60
  /// \tparam GR The digraph type the algorithm runs on.
61
  /// \tparam V The value type used for flow amounts, capacity bounds
62
  /// and supply values in the algorithm. By default it is \c int.
63
  /// \tparam C The value type used for costs and potentials in the
64
  /// algorithm. By default it is the same as \c V.
65
  ///
66
  /// \warning Both value types must be signed and all input data must
67
  /// be integer.
68
  ///
69
  /// \note %NetworkSimplex provides five different pivot rule
70
  /// implementations, from which the most efficient one is used
71
  /// by default. For more information see \ref PivotRule.
72
  template <typename GR, typename V = int, typename C = V>
73
  class NetworkSimplex
74
  {
75
  public:
76

	
77
    /// The type of the flow amounts, capacity bounds and supply values
78
    typedef V Value;
79
    /// The type of the arc costs
80
    typedef C Cost;
81

	
82
  public:
83

	
84
    /// \brief Problem type constants for the \c run() function.
85
    ///
86
    /// Enum type containing the problem type constants that can be
87
    /// returned by the \ref run() function of the algorithm.
88
    enum ProblemType {
89
      /// The problem has no feasible solution (flow).
90
      INFEASIBLE,
91
      /// The problem has optimal solution (i.e. it is feasible and
92
      /// bounded), and the algorithm has found optimal flow and node
93
      /// potentials (primal and dual solutions).
94
      OPTIMAL,
95
      /// The objective function of the problem is unbounded, i.e.
96
      /// there is a directed cycle having negative total cost and
97
      /// infinite upper bound.
98
      UNBOUNDED
99
    };
100
    
101
    /// \brief Constants for selecting the type of the supply constraints.
102
    ///
103
    /// Enum type containing constants for selecting the supply type,
104
    /// i.e. the direction of the inequalities in the supply/demand
105
    /// constraints of the \ref min_cost_flow "minimum cost flow problem".
106
    ///
107
    /// The default supply type is \c GEQ, the \c LEQ type can be
108
    /// selected using \ref supplyType().
109
    /// The equality form is a special case of both supply types.
110
    enum SupplyType {
111
      /// This option means that there are <em>"greater or equal"</em>
112
      /// supply/demand constraints in the definition of the problem.
113
      GEQ,
114
      /// This option means that there are <em>"less or equal"</em>
115
      /// supply/demand constraints in the definition of the problem.
116
      LEQ
117
    };
118
    
119
    /// \brief Constants for selecting the pivot rule.
120
    ///
121
    /// Enum type containing constants for selecting the pivot rule for
122
    /// the \ref run() function.
123
    ///
124
    /// \ref NetworkSimplex provides five different pivot rule
125
    /// implementations that significantly affect the running time
126
    /// of the algorithm.
127
    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
128
    /// proved to be the most efficient and the most robust on various
129
    /// test inputs according to our benchmark tests.
130
    /// However another pivot rule can be selected using the \ref run()
131
    /// function with the proper parameter.
132
    enum PivotRule {
133

	
134
      /// The First Eligible pivot rule.
135
      /// The next eligible arc is selected in a wraparound fashion
136
      /// in every iteration.
137
      FIRST_ELIGIBLE,
138

	
139
      /// The Best Eligible pivot rule.
140
      /// The best eligible arc is selected in every iteration.
141
      BEST_ELIGIBLE,
142

	
143
      /// The Block Search pivot rule.
144
      /// A specified number of arcs are examined in every iteration
145
      /// in a wraparound fashion and the best eligible arc is selected
146
      /// from this block.
147
      BLOCK_SEARCH,
148

	
149
      /// The Candidate List pivot rule.
150
      /// In a major iteration a candidate list is built from eligible arcs
151
      /// in a wraparound fashion and in the following minor iterations
152
      /// the best eligible arc is selected from this list.
153
      CANDIDATE_LIST,
154

	
155
      /// The Altering Candidate List pivot rule.
156
      /// It is a modified version of the Candidate List method.
157
      /// It keeps only the several best eligible arcs from the former
158
      /// candidate list and extends this list in every iteration.
159
      ALTERING_LIST
160
    };
161
    
162
  private:
163

	
164
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
165

	
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;
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
            _in_arc = e;
373
          }
374
          if (--cnt == 0) {
375
            if (min < 0) goto search_end;
376
            cnt = _block_size;
377
          }
378
        }
379
        for (e = 0; e < _next_arc; ++e) {
380
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
381
          if (c < min) {
382
            min = c;
383
            _in_arc = e;
384
          }
385
          if (--cnt == 0) {
386
            if (min < 0) goto search_end;
387
            cnt = _block_size;
388
          }
389
        }
390
        if (min >= 0) return false;
391

	
392
      search_end:
393
        _next_arc = e;
394
        return true;
395
      }
396

	
397
    }; //class BlockSearchPivotRule
398

	
399

	
400
    // Implementation of the Candidate List pivot rule
401
    class CandidateListPivotRule
402
    {
403
    private:
404

	
405
      // References to the NetworkSimplex class
406
      const IntVector  &_source;
407
      const IntVector  &_target;
408
      const CostVector &_cost;
409
      const IntVector  &_state;
410
      const CostVector &_pi;
411
      int &_in_arc;
412
      int _search_arc_num;
413

	
414
      // Pivot rule data
415
      IntVector _candidates;
416
      int _list_length, _minor_limit;
417
      int _curr_length, _minor_count;
418
      int _next_arc;
419

	
420
    public:
421

	
422
      /// Constructor
423
      CandidateListPivotRule(NetworkSimplex &ns) :
424
        _source(ns._source), _target(ns._target),
425
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
426
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
427
        _next_arc(0)
428
      {
429
        // The main parameters of the pivot rule
430
        const double LIST_LENGTH_FACTOR = 0.25;
431
        const int MIN_LIST_LENGTH = 10;
432
        const double MINOR_LIMIT_FACTOR = 0.1;
433
        const int MIN_MINOR_LIMIT = 3;
434

	
435
        _list_length = std::max( int(LIST_LENGTH_FACTOR *
436
                                     std::sqrt(double(_search_arc_num))),
437
                                 MIN_LIST_LENGTH );
438
        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
439
                                 MIN_MINOR_LIMIT );
440
        _curr_length = _minor_count = 0;
441
        _candidates.resize(_list_length);
442
      }
443

	
444
      /// Find next entering arc
445
      bool findEnteringArc() {
446
        Cost min, c;
447
        int e;
448
        if (_curr_length > 0 && _minor_count < _minor_limit) {
449
          // Minor iteration: select the best eligible arc from the
450
          // current candidate list
451
          ++_minor_count;
452
          min = 0;
453
          for (int i = 0; i < _curr_length; ++i) {
454
            e = _candidates[i];
455
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
456
            if (c < min) {
457
              min = c;
458
              _in_arc = e;
459
            }
460
            else if (c >= 0) {
461
              _candidates[i--] = _candidates[--_curr_length];
462
            }
463
          }
464
          if (min < 0) return true;
465
        }
466

	
467
        // Major iteration: build a new candidate list
468
        min = 0;
469
        _curr_length = 0;
470
        for (e = _next_arc; e < _search_arc_num; ++e) {
471
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
472
          if (c < 0) {
473
            _candidates[_curr_length++] = e;
474
            if (c < min) {
475
              min = c;
476
              _in_arc = e;
477
            }
478
            if (_curr_length == _list_length) goto search_end;
479
          }
480
        }
481
        for (e = 0; e < _next_arc; ++e) {
482
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
483
          if (c < 0) {
484
            _candidates[_curr_length++] = e;
485
            if (c < min) {
486
              min = c;
487
              _in_arc = e;
488
            }
489
            if (_curr_length == _list_length) goto search_end;
490
          }
491
        }
492
        if (_curr_length == 0) return false;
493
      
494
      search_end:        
495
        _minor_count = 1;
496
        _next_arc = e;
497
        return true;
498
      }
499

	
500
    }; //class CandidateListPivotRule
501

	
502

	
503
    // Implementation of the Altering Candidate List pivot rule
504
    class AlteringListPivotRule
505
    {
506
    private:
507

	
508
      // References to the NetworkSimplex class
509
      const IntVector  &_source;
510
      const IntVector  &_target;
511
      const CostVector &_cost;
512
      const IntVector  &_state;
513
      const CostVector &_pi;
514
      int &_in_arc;
515
      int _search_arc_num;
516

	
517
      // Pivot rule data
518
      int _block_size, _head_length, _curr_length;
519
      int _next_arc;
520
      IntVector _candidates;
521
      CostVector _cand_cost;
522

	
523
      // Functor class to compare arcs during sort of the candidate list
524
      class SortFunc
525
      {
526
      private:
527
        const CostVector &_map;
528
      public:
529
        SortFunc(const CostVector &map) : _map(map) {}
530
        bool operator()(int left, int right) {
531
          return _map[left] > _map[right];
532
        }
533
      };
534

	
535
      SortFunc _sort_func;
536

	
537
    public:
538

	
539
      // Constructor
540
      AlteringListPivotRule(NetworkSimplex &ns) :
541
        _source(ns._source), _target(ns._target),
542
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
543
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
544
        _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
545
      {
546
        // The main parameters of the pivot rule
547
        const double BLOCK_SIZE_FACTOR = 1.0;
548
        const int MIN_BLOCK_SIZE = 10;
549
        const double HEAD_LENGTH_FACTOR = 0.1;
550
        const int MIN_HEAD_LENGTH = 3;
551

	
552
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
553
                                    std::sqrt(double(_search_arc_num))),
554
                                MIN_BLOCK_SIZE );
555
        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
556
                                 MIN_HEAD_LENGTH );
557
        _candidates.resize(_head_length + _block_size);
558
        _curr_length = 0;
559
      }
560

	
561
      // Find next entering arc
562
      bool findEnteringArc() {
563
        // Check the current candidate list
564
        int e;
565
        for (int i = 0; i < _curr_length; ++i) {
566
          e = _candidates[i];
567
          _cand_cost[e] = _state[e] *
568
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
569
          if (_cand_cost[e] >= 0) {
570
            _candidates[i--] = _candidates[--_curr_length];
571
          }
572
        }
573

	
574
        // Extend the list
575
        int cnt = _block_size;
576
        int limit = _head_length;
577

	
578
        for (e = _next_arc; e < _search_arc_num; ++e) {
579
          _cand_cost[e] = _state[e] *
580
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
581
          if (_cand_cost[e] < 0) {
582
            _candidates[_curr_length++] = e;
583
          }
584
          if (--cnt == 0) {
585
            if (_curr_length > limit) goto search_end;
586
            limit = 0;
587
            cnt = _block_size;
588
          }
589
        }
590
        for (e = 0; e < _next_arc; ++e) {
591
          _cand_cost[e] = _state[e] *
592
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
593
          if (_cand_cost[e] < 0) {
594
            _candidates[_curr_length++] = e;
595
          }
596
          if (--cnt == 0) {
597
            if (_curr_length > limit) goto search_end;
598
            limit = 0;
599
            cnt = _block_size;
600
          }
601
        }
602
        if (_curr_length == 0) return false;
603
        
604
      search_end:
605

	
606
        // Make heap of the candidate list (approximating a partial sort)
607
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
608
                   _sort_func );
609

	
610
        // Pop the first element of the heap
611
        _in_arc = _candidates[0];
612
        _next_arc = e;
613
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
614
                  _sort_func );
615
        _curr_length = std::min(_head_length, _curr_length - 1);
616
        return true;
617
      }
618

	
619
    }; //class AlteringListPivotRule
620

	
621
  public:
622

	
623
    /// \brief Constructor.
624
    ///
625
    /// The constructor of the class.
626
    ///
627
    /// \param graph The digraph the algorithm runs on.
628
    /// \param arc_mixing Indicate if the arcs have to be stored in a
629
    /// mixed order in the internal data structure. 
630
    /// In special cases, it could lead to better overall performance,
631
    /// but it is usually slower. Therefore it is disabled by default.
632
    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
633
      _graph(graph), _node_id(graph), _arc_id(graph),
634
      INF(std::numeric_limits<Value>::has_infinity ?
635
          std::numeric_limits<Value>::infinity() :
636
          std::numeric_limits<Value>::max())
637
    {
638
      // Check the value types
639
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
640
        "The flow type of NetworkSimplex must be signed");
641
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
642
        "The cost type of NetworkSimplex must be signed");
643
        
644
      // Resize vectors
645
      _node_num = countNodes(_graph);
646
      _arc_num = countArcs(_graph);
647
      int all_node_num = _node_num + 1;
648
      int max_arc_num = _arc_num + 2 * _node_num;
649

	
650
      _source.resize(max_arc_num);
651
      _target.resize(max_arc_num);
652

	
653
      _lower.resize(_arc_num);
654
      _upper.resize(_arc_num);
655
      _cap.resize(max_arc_num);
656
      _cost.resize(max_arc_num);
657
      _supply.resize(all_node_num);
658
      _flow.resize(max_arc_num);
659
      _pi.resize(all_node_num);
660

	
661
      _parent.resize(all_node_num);
662
      _pred.resize(all_node_num);
663
      _forward.resize(all_node_num);
664
      _thread.resize(all_node_num);
665
      _rev_thread.resize(all_node_num);
666
      _succ_num.resize(all_node_num);
667
      _last_succ.resize(all_node_num);
668
      _state.resize(max_arc_num);
669

	
670
      // Copy the graph
671
      int i = 0;
672
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
673
        _node_id[n] = i;
674
      }
675
      if (arc_mixing) {
676
        // Store the arcs in a mixed order
677
        int k = std::max(int(std::sqrt(double(_arc_num))), 10);
678
        int i = 0, j = 0;
679
        for (ArcIt a(_graph); a != INVALID; ++a) {
680
          _arc_id[a] = i;
681
          _source[i] = _node_id[_graph.source(a)];
682
          _target[i] = _node_id[_graph.target(a)];
683
          if ((i += k) >= _arc_num) i = ++j;
684
        }
685
      } else {
686
        // Store the arcs in the original order
687
        int i = 0;
688
        for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
689
          _arc_id[a] = i;
690
          _source[i] = _node_id[_graph.source(a)];
691
          _target[i] = _node_id[_graph.target(a)];
692
        }
693
      }
694
      
695
      // Reset parameters
696
      reset();
697
    }
698

	
699
    /// \name Parameters
700
    /// The parameters of the algorithm can be specified using these
701
    /// functions.
702

	
703
    /// @{
704

	
705
    /// \brief Set the lower bounds on the arcs.
706
    ///
707
    /// This function sets the lower bounds on the arcs.
708
    /// If it is not used before calling \ref run(), the lower bounds
709
    /// will be set to zero on all arcs.
710
    ///
711
    /// \param map An arc map storing the lower bounds.
712
    /// Its \c Value type must be convertible to the \c Value type
713
    /// of the algorithm.
714
    ///
715
    /// \return <tt>(*this)</tt>
716
    template <typename LowerMap>
717
    NetworkSimplex& lowerMap(const LowerMap& map) {
718
      _have_lower = true;
719
      for (ArcIt a(_graph); a != INVALID; ++a) {
720
        _lower[_arc_id[a]] = map[a];
721
      }
722
      return *this;
723
    }
724

	
725
    /// \brief Set the upper bounds (capacities) on the arcs.
726
    ///
727
    /// This function sets the upper bounds (capacities) on the arcs.
728
    /// If it is not used before calling \ref run(), the upper bounds
729
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
730
    /// unbounded from above on each arc).
731
    ///
732
    /// \param map An arc map storing the upper bounds.
733
    /// Its \c Value type must be convertible to the \c Value type
734
    /// of the algorithm.
735
    ///
736
    /// \return <tt>(*this)</tt>
737
    template<typename UpperMap>
738
    NetworkSimplex& upperMap(const UpperMap& map) {
739
      for (ArcIt a(_graph); a != INVALID; ++a) {
740
        _upper[_arc_id[a]] = map[a];
741
      }
742
      return *this;
743
    }
744

	
745
    /// \brief Set the costs of the arcs.
746
    ///
747
    /// This function sets the costs of the arcs.
748
    /// If it is not used before calling \ref run(), the costs
749
    /// will be set to \c 1 on all arcs.
750
    ///
751
    /// \param map An arc map storing the costs.
752
    /// Its \c Value type must be convertible to the \c Cost type
753
    /// of the algorithm.
754
    ///
755
    /// \return <tt>(*this)</tt>
756
    template<typename CostMap>
757
    NetworkSimplex& costMap(const CostMap& map) {
758
      for (ArcIt a(_graph); a != INVALID; ++a) {
759
        _cost[_arc_id[a]] = map[a];
760
      }
761
      return *this;
762
    }
763

	
764
    /// \brief Set the supply values of the nodes.
765
    ///
766
    /// This function sets the supply values of the nodes.
767
    /// If neither this function nor \ref stSupply() is used before
768
    /// calling \ref run(), the supply of each node will be set to zero.
769
    ///
770
    /// \param map A node map storing the supply values.
771
    /// Its \c Value type must be convertible to the \c Value type
772
    /// of the algorithm.
773
    ///
774
    /// \return <tt>(*this)</tt>
775
    template<typename SupplyMap>
776
    NetworkSimplex& supplyMap(const SupplyMap& map) {
777
      for (NodeIt n(_graph); n != INVALID; ++n) {
778
        _supply[_node_id[n]] = map[n];
779
      }
780
      return *this;
781
    }
782

	
783
    /// \brief Set single source and target nodes and a supply value.
784
    ///
785
    /// This function sets a single source node and a single target node
786
    /// and the required flow value.
787
    /// If neither this function nor \ref supplyMap() is used before
788
    /// calling \ref run(), the supply of each node will be set to zero.
789
    ///
790
    /// Using this function has the same effect as using \ref supplyMap()
791
    /// with such a map in which \c k is assigned to \c s, \c -k is
792
    /// assigned to \c t and all other nodes have zero supply value.
793
    ///
794
    /// \param s The source node.
795
    /// \param t The target node.
796
    /// \param k The required amount of flow from node \c s to node \c t
797
    /// (i.e. the supply of \c s and the demand of \c t).
798
    ///
799
    /// \return <tt>(*this)</tt>
800
    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
801
      for (int i = 0; i != _node_num; ++i) {
802
        _supply[i] = 0;
803
      }
804
      _supply[_node_id[s]] =  k;
805
      _supply[_node_id[t]] = -k;
806
      return *this;
807
    }
808
    
809
    /// \brief Set the type of the supply constraints.
810
    ///
811
    /// This function sets the type of the supply/demand constraints.
812
    /// If it is not used before calling \ref run(), the \ref GEQ supply
813
    /// type will be used.
814
    ///
815
    /// For more information see \ref SupplyType.
816
    ///
817
    /// \return <tt>(*this)</tt>
818
    NetworkSimplex& supplyType(SupplyType supply_type) {
819
      _stype = supply_type;
820
      return *this;
821
    }
822

	
823
    /// @}
824

	
825
    /// \name Execution Control
826
    /// The algorithm can be executed using \ref run().
827

	
828
    /// @{
829

	
830
    /// \brief Run the algorithm.
831
    ///
832
    /// This function runs the algorithm.
833
    /// The paramters can be specified using functions \ref lowerMap(),
834
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 
835
    /// \ref supplyType().
836
    /// For example,
837
    /// \code
838
    ///   NetworkSimplex<ListDigraph> ns(graph);
839
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
840
    ///     .supplyMap(sup).run();
841
    /// \endcode
842
    ///
843
    /// This function can be called more than once. All the parameters
844
    /// that have been given are kept for the next call, unless
845
    /// \ref reset() is called, thus only the modified parameters
846
    /// have to be set again. See \ref reset() for examples.
847
    /// However the underlying digraph must not be modified after this
848
    /// class have been constructed, since it copies and extends the graph.
849
    ///
850
    /// \param pivot_rule The pivot rule that will be used during the
851
    /// algorithm. For more information see \ref PivotRule.
852
    ///
853
    /// \return \c INFEASIBLE if no feasible flow exists,
854
    /// \n \c OPTIMAL if the problem has optimal solution
855
    /// (i.e. it is feasible and bounded), and the algorithm has found
856
    /// optimal flow and node potentials (primal and dual solutions),
857
    /// \n \c UNBOUNDED if the objective function of the problem is
858
    /// unbounded, i.e. there is a directed cycle having negative total
859
    /// cost and infinite upper bound.
860
    ///
861
    /// \see ProblemType, PivotRule
862
    ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
863
      if (!init()) return INFEASIBLE;
864
      return start(pivot_rule);
865
    }
866

	
867
    /// \brief Reset all the parameters that have been given before.
868
    ///
869
    /// This function resets all the paramaters that have been given
870
    /// before using functions \ref lowerMap(), \ref upperMap(),
871
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
872
    ///
873
    /// It is useful for multiple run() calls. If this function is not
874
    /// used, all the parameters given before are kept for the next
875
    /// \ref run() call.
876
    /// However the underlying digraph must not be modified after this
877
    /// class have been constructed, since it copies and extends the graph.
878
    ///
879
    /// For example,
880
    /// \code
881
    ///   NetworkSimplex<ListDigraph> ns(graph);
882
    ///
883
    ///   // First run
884
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
885
    ///     .supplyMap(sup).run();
886
    ///
887
    ///   // Run again with modified cost map (reset() is not called,
888
    ///   // so only the cost map have to be set again)
889
    ///   cost[e] += 100;
890
    ///   ns.costMap(cost).run();
891
    ///
892
    ///   // Run again from scratch using reset()
893
    ///   // (the lower bounds will be set to zero on all arcs)
894
    ///   ns.reset();
895
    ///   ns.upperMap(capacity).costMap(cost)
896
    ///     .supplyMap(sup).run();
897
    /// \endcode
898
    ///
899
    /// \return <tt>(*this)</tt>
900
    NetworkSimplex& reset() {
901
      for (int i = 0; i != _node_num; ++i) {
902
        _supply[i] = 0;
903
      }
904
      for (int i = 0; i != _arc_num; ++i) {
905
        _lower[i] = 0;
906
        _upper[i] = INF;
907
        _cost[i] = 1;
908
      }
909
      _have_lower = false;
910
      _stype = GEQ;
911
      return *this;
912
    }
913

	
914
    /// @}
915

	
916
    /// \name Query Functions
917
    /// The results of the algorithm can be obtained using these
918
    /// functions.\n
919
    /// The \ref run() function must be called before using them.
920

	
921
    /// @{
922

	
923
    /// \brief Return the total cost of the found flow.
924
    ///
925
    /// This function returns the total cost of the found flow.
926
    /// Its complexity is O(e).
927
    ///
928
    /// \note The return type of the function can be specified as a
929
    /// template parameter. For example,
930
    /// \code
931
    ///   ns.totalCost<double>();
932
    /// \endcode
933
    /// It is useful if the total cost cannot be stored in the \c Cost
934
    /// type of the algorithm, which is the default return type of the
935
    /// function.
936
    ///
937
    /// \pre \ref run() must be called before using this function.
938
    template <typename Number>
939
    Number totalCost() const {
940
      Number c = 0;
941
      for (ArcIt a(_graph); a != INVALID; ++a) {
942
        int i = _arc_id[a];
943
        c += Number(_flow[i]) * Number(_cost[i]);
944
      }
945
      return c;
946
    }
947

	
948
#ifndef DOXYGEN
949
    Cost totalCost() const {
950
      return totalCost<Cost>();
951
    }
952
#endif
953

	
954
    /// \brief Return the flow on the given arc.
955
    ///
956
    /// This function returns the flow on the given arc.
957
    ///
958
    /// \pre \ref run() must be called before using this function.
959
    Value flow(const Arc& a) const {
960
      return _flow[_arc_id[a]];
961
    }
962

	
963
    /// \brief Return the flow map (the primal solution).
964
    ///
965
    /// This function copies the flow value on each arc into the given
966
    /// map. The \c Value type of the algorithm must be convertible to
967
    /// the \c Value type of the map.
968
    ///
969
    /// \pre \ref run() must be called before using this function.
970
    template <typename FlowMap>
971
    void flowMap(FlowMap &map) const {
972
      for (ArcIt a(_graph); a != INVALID; ++a) {
973
        map.set(a, _flow[_arc_id[a]]);
974
      }
975
    }
976

	
977
    /// \brief Return the potential (dual value) of the given node.
978
    ///
979
    /// This function returns the potential (dual value) of the
980
    /// given node.
981
    ///
982
    /// \pre \ref run() must be called before using this function.
983
    Cost potential(const Node& n) const {
984
      return _pi[_node_id[n]];
985
    }
986

	
987
    /// \brief Return the potential map (the dual solution).
988
    ///
989
    /// This function copies the potential (dual value) of each node
990
    /// into the given map.
991
    /// The \c Cost type of the algorithm must be convertible to the
992
    /// \c Value type of the map.
993
    ///
994
    /// \pre \ref run() must be called before using this function.
995
    template <typename PotentialMap>
996
    void potentialMap(PotentialMap &map) const {
997
      for (NodeIt n(_graph); n != INVALID; ++n) {
998
        map.set(n, _pi[_node_id[n]]);
999
      }
1000
    }
1001

	
1002
    /// @}
1003

	
1004
  private:
1005

	
1006
    // Initialize internal data structures
1007
    bool init() {
1008
      if (_node_num == 0) return false;
1009

	
1010
      // Check the sum of supply values
1011
      _sum_supply = 0;
1012
      for (int i = 0; i != _node_num; ++i) {
1013
        _sum_supply += _supply[i];
1014
      }
1015
      if ( !((_stype == GEQ && _sum_supply <= 0) ||
1016
             (_stype == LEQ && _sum_supply >= 0)) ) return false;
1017

	
1018
      // Remove non-zero lower bounds
1019
      if (_have_lower) {
1020
        for (int i = 0; i != _arc_num; ++i) {
1021
          Value c = _lower[i];
1022
          if (c >= 0) {
1023
            _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
1024
          } else {
1025
            _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
1026
          }
1027
          _supply[_source[i]] -= c;
1028
          _supply[_target[i]] += c;
1029
        }
1030
      } else {
1031
        for (int i = 0; i != _arc_num; ++i) {
1032
          _cap[i] = _upper[i];
1033
        }
1034
      }
1035

	
1036
      // Initialize artifical cost
1037
      Cost ART_COST;
1038
      if (std::numeric_limits<Cost>::is_exact) {
1039
        ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
1040
      } else {
1041
        ART_COST = std::numeric_limits<Cost>::min();
1042
        for (int i = 0; i != _arc_num; ++i) {
1043
          if (_cost[i] > ART_COST) ART_COST = _cost[i];
1044
        }
1045
        ART_COST = (ART_COST + 1) * _node_num;
1046
      }
1047

	
1048
      // Initialize arc maps
1049
      for (int i = 0; i != _arc_num; ++i) {
1050
        _flow[i] = 0;
1051
        _state[i] = STATE_LOWER;
1052
      }
1053
      
1054
      // Set data for the artificial root node
1055
      _root = _node_num;
1056
      _parent[_root] = -1;
1057
      _pred[_root] = -1;
1058
      _thread[_root] = 0;
1059
      _rev_thread[0] = _root;
1060
      _succ_num[_root] = _node_num + 1;
1061
      _last_succ[_root] = _root - 1;
1062
      _supply[_root] = -_sum_supply;
1063
      _pi[_root] = 0;
1064

	
1065
      // Add artificial arcs and initialize the spanning tree data structure
1066
      if (_sum_supply == 0) {
1067
        // EQ supply constraints
1068
        _search_arc_num = _arc_num;
1069
        _all_arc_num = _arc_num + _node_num;
1070
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1071
          _parent[u] = _root;
1072
          _pred[u] = e;
1073
          _thread[u] = u + 1;
1074
          _rev_thread[u + 1] = u;
1075
          _succ_num[u] = 1;
1076
          _last_succ[u] = u;
1077
          _cap[e] = INF;
1078
          _state[e] = STATE_TREE;
1079
          if (_supply[u] >= 0) {
1080
            _forward[u] = true;
1081
            _pi[u] = 0;
1082
            _source[e] = u;
1083
            _target[e] = _root;
1084
            _flow[e] = _supply[u];
1085
            _cost[e] = 0;
1086
          } else {
1087
            _forward[u] = false;
1088
            _pi[u] = ART_COST;
1089
            _source[e] = _root;
1090
            _target[e] = u;
1091
            _flow[e] = -_supply[u];
1092
            _cost[e] = ART_COST;
1093
          }
1094
        }
1095
      }
1096
      else if (_sum_supply > 0) {
1097
        // LEQ supply constraints
1098
        _search_arc_num = _arc_num + _node_num;
1099
        int f = _arc_num + _node_num;
1100
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1101
          _parent[u] = _root;
1102
          _thread[u] = u + 1;
1103
          _rev_thread[u + 1] = u;
1104
          _succ_num[u] = 1;
1105
          _last_succ[u] = u;
1106
          if (_supply[u] >= 0) {
1107
            _forward[u] = true;
1108
            _pi[u] = 0;
1109
            _pred[u] = e;
1110
            _source[e] = u;
1111
            _target[e] = _root;
1112
            _cap[e] = INF;
1113
            _flow[e] = _supply[u];
1114
            _cost[e] = 0;
1115
            _state[e] = STATE_TREE;
1116
          } else {
1117
            _forward[u] = false;
1118
            _pi[u] = ART_COST;
1119
            _pred[u] = f;
1120
            _source[f] = _root;
1121
            _target[f] = u;
1122
            _cap[f] = INF;
1123
            _flow[f] = -_supply[u];
1124
            _cost[f] = ART_COST;
1125
            _state[f] = STATE_TREE;
1126
            _source[e] = u;
1127
            _target[e] = _root;
1128
            _cap[e] = INF;
1129
            _flow[e] = 0;
1130
            _cost[e] = 0;
1131
            _state[e] = STATE_LOWER;
1132
            ++f;
1133
          }
1134
        }
1135
        _all_arc_num = f;
1136
      }
1137
      else {
1138
        // GEQ supply constraints
1139
        _search_arc_num = _arc_num + _node_num;
1140
        int f = _arc_num + _node_num;
1141
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1142
          _parent[u] = _root;
1143
          _thread[u] = u + 1;
1144
          _rev_thread[u + 1] = u;
1145
          _succ_num[u] = 1;
1146
          _last_succ[u] = u;
1147
          if (_supply[u] <= 0) {
1148
            _forward[u] = false;
1149
            _pi[u] = 0;
1150
            _pred[u] = e;
1151
            _source[e] = _root;
1152
            _target[e] = u;
1153
            _cap[e] = INF;
1154
            _flow[e] = -_supply[u];
1155
            _cost[e] = 0;
1156
            _state[e] = STATE_TREE;
1157
          } else {
1158
            _forward[u] = true;
1159
            _pi[u] = -ART_COST;
1160
            _pred[u] = f;
1161
            _source[f] = u;
1162
            _target[f] = _root;
1163
            _cap[f] = INF;
1164
            _flow[f] = _supply[u];
1165
            _state[f] = STATE_TREE;
1166
            _cost[f] = ART_COST;
1167
            _source[e] = _root;
1168
            _target[e] = u;
1169
            _cap[e] = INF;
1170
            _flow[e] = 0;
1171
            _cost[e] = 0;
1172
            _state[e] = STATE_LOWER;
1173
            ++f;
1174
          }
1175
        }
1176
        _all_arc_num = f;
1177
      }
1178

	
1179
      return true;
1180
    }
1181

	
1182
    // Find the join node
1183
    void findJoinNode() {
1184
      int u = _source[in_arc];
1185
      int v = _target[in_arc];
1186
      while (u != v) {
1187
        if (_succ_num[u] < _succ_num[v]) {
1188
          u = _parent[u];
1189
        } else {
1190
          v = _parent[v];
1191
        }
1192
      }
1193
      join = u;
1194
    }
1195

	
1196
    // Find the leaving arc of the cycle and returns true if the
1197
    // leaving arc is not the same as the entering arc
1198
    bool findLeavingArc() {
1199
      // Initialize first and second nodes according to the direction
1200
      // of the cycle
1201
      if (_state[in_arc] == STATE_LOWER) {
1202
        first  = _source[in_arc];
1203
        second = _target[in_arc];
1204
      } else {
1205
        first  = _target[in_arc];
1206
        second = _source[in_arc];
1207
      }
1208
      delta = _cap[in_arc];
1209
      int result = 0;
1210
      Value d;
1211
      int e;
1212

	
1213
      // Search the cycle along the path form the first node to the root
1214
      for (int u = first; u != join; u = _parent[u]) {
1215
        e = _pred[u];
1216
        d = _forward[u] ?
1217
          _flow[e] : (_cap[e] == INF ? INF : _cap[e] - _flow[e]);
1218
        if (d < delta) {
1219
          delta = d;
1220
          u_out = u;
1221
          result = 1;
1222
        }
1223
      }
1224
      // Search the cycle along the path form the second node to the root
1225
      for (int u = second; u != join; u = _parent[u]) {
1226
        e = _pred[u];
1227
        d = _forward[u] ? 
1228
          (_cap[e] == INF ? INF : _cap[e] - _flow[e]) : _flow[e];
1229
        if (d <= delta) {
1230
          delta = d;
1231
          u_out = u;
1232
          result = 2;
1233
        }
1234
      }
1235

	
1236
      if (result == 1) {
1237
        u_in = first;
1238
        v_in = second;
1239
      } else {
1240
        u_in = second;
1241
        v_in = first;
1242
      }
1243
      return result != 0;
1244
    }
1245

	
1246
    // Change _flow and _state vectors
1247
    void changeFlow(bool change) {
1248
      // Augment along the cycle
1249
      if (delta > 0) {
1250
        Value val = _state[in_arc] * delta;
1251
        _flow[in_arc] += val;
1252
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
1253
          _flow[_pred[u]] += _forward[u] ? -val : val;
1254
        }
1255
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
1256
          _flow[_pred[u]] += _forward[u] ? val : -val;
1257
        }
1258
      }
1259
      // Update the state of the entering and leaving arcs
1260
      if (change) {
1261
        _state[in_arc] = STATE_TREE;
1262
        _state[_pred[u_out]] =
1263
          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
1264
      } else {
1265
        _state[in_arc] = -_state[in_arc];
1266
      }
1267
    }
1268

	
1269
    // Update the tree structure
1270
    void updateTreeStructure() {
1271
      int u, w;
1272
      int old_rev_thread = _rev_thread[u_out];
1273
      int old_succ_num = _succ_num[u_out];
1274
      int old_last_succ = _last_succ[u_out];
1275
      v_out = _parent[u_out];
1276

	
1277
      u = _last_succ[u_in];  // the last successor of u_in
1278
      right = _thread[u];    // the node after it
1279

	
1280
      // Handle the case when old_rev_thread equals to v_in
1281
      // (it also means that join and v_out coincide)
1282
      if (old_rev_thread == v_in) {
1283
        last = _thread[_last_succ[u_out]];
1284
      } else {
1285
        last = _thread[v_in];
1286
      }
1287

	
1288
      // Update _thread and _parent along the stem nodes (i.e. the nodes
1289
      // between u_in and u_out, whose parent have to be changed)
1290
      _thread[v_in] = stem = u_in;
1291
      _dirty_revs.clear();
1292
      _dirty_revs.push_back(v_in);
1293
      par_stem = v_in;
1294
      while (stem != u_out) {
1295
        // Insert the next stem node into the thread list
1296
        new_stem = _parent[stem];
1297
        _thread[u] = new_stem;
1298
        _dirty_revs.push_back(u);
1299

	
1300
        // Remove the subtree of stem from the thread list
1301
        w = _rev_thread[stem];
1302
        _thread[w] = right;
1303
        _rev_thread[right] = w;
1304

	
1305
        // Change the parent node and shift stem nodes
1306
        _parent[stem] = par_stem;
1307
        par_stem = stem;
1308
        stem = new_stem;
1309

	
1310
        // Update u and right
1311
        u = _last_succ[stem] == _last_succ[par_stem] ?
1312
          _rev_thread[par_stem] : _last_succ[stem];
1313
        right = _thread[u];
1314
      }
1315
      _parent[u_out] = par_stem;
1316
      _thread[u] = last;
1317
      _rev_thread[last] = u;
1318
      _last_succ[u_out] = u;
1319

	
1320
      // Remove the subtree of u_out from the thread list except for
1321
      // the case when old_rev_thread equals to v_in
1322
      // (it also means that join and v_out coincide)
1323
      if (old_rev_thread != v_in) {
1324
        _thread[old_rev_thread] = right;
1325
        _rev_thread[right] = old_rev_thread;
1326
      }
1327

	
1328
      // Update _rev_thread using the new _thread values
1329
      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
1330
        u = _dirty_revs[i];
1331
        _rev_thread[_thread[u]] = u;
1332
      }
1333

	
1334
      // Update _pred, _forward, _last_succ and _succ_num for the
1335
      // stem nodes from u_out to u_in
1336
      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
1337
      u = u_out;
1338
      while (u != u_in) {
1339
        w = _parent[u];
1340
        _pred[u] = _pred[w];
1341
        _forward[u] = !_forward[w];
1342
        tmp_sc += _succ_num[u] - _succ_num[w];
1343
        _succ_num[u] = tmp_sc;
1344
        _last_succ[w] = tmp_ls;
1345
        u = w;
1346
      }
1347
      _pred[u_in] = in_arc;
1348
      _forward[u_in] = (u_in == _source[in_arc]);
1349
      _succ_num[u_in] = old_succ_num;
1350

	
1351
      // Set limits for updating _last_succ form v_in and v_out
1352
      // towards the root
1353
      int up_limit_in = -1;
1354
      int up_limit_out = -1;
1355
      if (_last_succ[join] == v_in) {
1356
        up_limit_out = join;
1357
      } else {
1358
        up_limit_in = join;
1359
      }
1360

	
1361
      // Update _last_succ from v_in towards the root
1362
      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
1363
           u = _parent[u]) {
1364
        _last_succ[u] = _last_succ[u_out];
1365
      }
1366
      // Update _last_succ from v_out towards the root
1367
      if (join != old_rev_thread && v_in != old_rev_thread) {
1368
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1369
             u = _parent[u]) {
1370
          _last_succ[u] = old_rev_thread;
1371
        }
1372
      } else {
1373
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1374
             u = _parent[u]) {
1375
          _last_succ[u] = _last_succ[u_out];
1376
        }
1377
      }
1378

	
1379
      // Update _succ_num from v_in to join
1380
      for (u = v_in; u != join; u = _parent[u]) {
1381
        _succ_num[u] += old_succ_num;
1382
      }
1383
      // Update _succ_num from v_out to join
1384
      for (u = v_out; u != join; u = _parent[u]) {
1385
        _succ_num[u] -= old_succ_num;
1386
      }
1387
    }
1388

	
1389
    // Update potentials
1390
    void updatePotential() {
1391
      Cost sigma = _forward[u_in] ?
1392
        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
1393
        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
1394
      // Update potentials in the subtree, which has been moved
1395
      int end = _thread[_last_succ[u_in]];
1396
      for (int u = u_in; u != end; u = _thread[u]) {
1397
        _pi[u] += sigma;
1398
      }
1399
    }
1400

	
1401
    // Execute the algorithm
1402
    ProblemType start(PivotRule pivot_rule) {
1403
      // Select the pivot rule implementation
1404
      switch (pivot_rule) {
1405
        case FIRST_ELIGIBLE:
1406
          return start<FirstEligiblePivotRule>();
1407
        case BEST_ELIGIBLE:
1408
          return start<BestEligiblePivotRule>();
1409
        case BLOCK_SEARCH:
1410
          return start<BlockSearchPivotRule>();
1411
        case CANDIDATE_LIST:
1412
          return start<CandidateListPivotRule>();
1413
        case ALTERING_LIST:
1414
          return start<AlteringListPivotRule>();
1415
      }
1416
      return INFEASIBLE; // avoid warning
1417
    }
1418

	
1419
    template <typename PivotRuleImpl>
1420
    ProblemType start() {
1421
      PivotRuleImpl pivot(*this);
1422

	
1423
      // Execute the Network Simplex algorithm
1424
      while (pivot.findEnteringArc()) {
1425
        findJoinNode();
1426
        bool change = findLeavingArc();
1427
        if (delta >= INF) return UNBOUNDED;
1428
        changeFlow(change);
1429
        if (change) {
1430
          updateTreeStructure();
1431
          updatePotential();
1432
        }
1433
      }
1434
      
1435
      // Check feasibility
1436
      for (int e = _search_arc_num; e != _all_arc_num; ++e) {
1437
        if (_flow[e] != 0) return INFEASIBLE;
1438
      }
1439

	
1440
      // Transform the solution and the supply map to the original form
1441
      if (_have_lower) {
1442
        for (int i = 0; i != _arc_num; ++i) {
1443
          Value c = _lower[i];
1444
          if (c != 0) {
1445
            _flow[i] += c;
1446
            _supply[_source[i]] += c;
1447
            _supply[_target[i]] -= c;
1448
          }
1449
        }
1450
      }
1451
      
1452
      // Shift potentials to meet the requirements of the GEQ/LEQ type
1453
      // optimality conditions
1454
      if (_sum_supply == 0) {
1455
        if (_stype == GEQ) {
1456
          Cost max_pot = std::numeric_limits<Cost>::min();
1457
          for (int i = 0; i != _node_num; ++i) {
1458
            if (_pi[i] > max_pot) max_pot = _pi[i];
1459
          }
1460
          if (max_pot > 0) {
1461
            for (int i = 0; i != _node_num; ++i)
1462
              _pi[i] -= max_pot;
1463
          }
1464
        } else {
1465
          Cost min_pot = std::numeric_limits<Cost>::max();
1466
          for (int i = 0; i != _node_num; ++i) {
1467
            if (_pi[i] < min_pot) min_pot = _pi[i];
1468
          }
1469
          if (min_pot < 0) {
1470
            for (int i = 0; i != _node_num; ++i)
1471
              _pi[i] -= min_pot;
1472
          }
1473
        }
1474
      }
1475

	
1476
      return OPTIMAL;
1477
    }
1478

	
1479
  }; //class NetworkSimplex
1480

	
1481
  ///@}
1482

	
1483
} //namespace lemon
1484

	
1485
#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_PAIRING_HEAP_H
20
#define LEMON_PAIRING_HEAP_H
21

	
22
///\file
23
///\ingroup heaps
24
///\brief Pairing heap implementation.
25

	
26
#include <vector>
27
#include <utility>
28
#include <functional>
29
#include <lemon/math.h>
30

	
31
namespace lemon {
32

	
33
  /// \ingroup heaps
34
  ///
35
  ///\brief Pairing Heap.
36
  ///
37
  /// This class implements the \e pairing \e heap data structure.
38
  /// It fully conforms to the \ref concepts::Heap "heap concept".
39
  ///
40
  /// The methods \ref increase() and \ref erase() are not efficient
41
  /// in a pairing heap. In case of many calls of these operations,
42
  /// it is better to use other heap structure, e.g. \ref BinHeap
43
  /// "binary heap".
44
  ///
45
  /// \tparam PR Type of the priorities of the items.
46
  /// \tparam IM A read-writable item map with \c int values, used
47
  /// internally to handle the cross references.
48
  /// \tparam CMP A functor class for comparing the priorities.
49
  /// The default is \c std::less<PR>.
50
#ifdef DOXYGEN
51
  template <typename PR, typename IM, typename CMP>
52
#else
53
  template <typename PR, typename IM, typename CMP = std::less<PR> >
54
#endif
55
  class PairingHeap {
56
  public:
57
    /// Type of the item-int map.
58
    typedef IM ItemIntMap;
59
    /// Type of the priorities.
60
    typedef PR Prio;
61
    /// Type of the items stored in the heap.
62
    typedef typename ItemIntMap::Key Item;
63
    /// Functor type for comparing the priorities.
64
    typedef CMP Compare;
65

	
66
    /// \brief Type to represent the states of the items.
67
    ///
68
    /// Each item has a state associated to it. It can be "in heap",
69
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
70
    /// heap's point of view, but may be useful to the user.
71
    ///
72
    /// The item-int map must be initialized in such way that it assigns
73
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
74
    enum State {
75
      IN_HEAP = 0,    ///< = 0.
76
      PRE_HEAP = -1,  ///< = -1.
77
      POST_HEAP = -2  ///< = -2.
78
    };
79

	
80
  private:
81
    class store;
82

	
83
    std::vector<store> _data;
84
    int _min;
85
    ItemIntMap &_iim;
86
    Compare _comp;
87
    int _num_items;
88

	
89
  public:
90
    /// \brief Constructor.
91
    ///
92
    /// Constructor.
93
    /// \param map A map that assigns \c int values to the items.
94
    /// It is used internally to handle the cross references.
95
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
96
    explicit PairingHeap(ItemIntMap &map)
97
      : _min(0), _iim(map), _num_items(0) {}
98

	
99
    /// \brief Constructor.
100
    ///
101
    /// Constructor.
102
    /// \param map A map that assigns \c int values to the items.
103
    /// It is used internally to handle the cross references.
104
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
105
    /// \param comp The function object used for comparing the priorities.
106
    PairingHeap(ItemIntMap &map, const Compare &comp)
107
      : _min(0), _iim(map), _comp(comp), _num_items(0) {}
108

	
109
    /// \brief The number of items stored in the heap.
110
    ///
111
    /// This function returns the number of items stored in the heap.
112
    int size() const { return _num_items; }
113

	
114
    /// \brief Check if the heap is empty.
115
    ///
116
    /// This function returns \c true if the heap is empty.
117
    bool empty() const { return _num_items==0; }
118

	
119
    /// \brief Make the heap empty.
120
    ///
121
    /// This functon makes the heap empty.
122
    /// It does not change the cross reference map. If you want to reuse
123
    /// a heap that is not surely empty, you should first clear it and
124
    /// then you should set the cross reference map to \c PRE_HEAP
125
    /// for each item.
126
    void clear() {
127
      _data.clear();
128
      _min = 0;
129
      _num_items = 0;
130
    }
131

	
132
    /// \brief Set the priority of an item or insert it, if it is
133
    /// not stored in the heap.
134
    ///
135
    /// This method sets the priority of the given item if it is
136
    /// already stored in the heap. Otherwise it inserts the given
137
    /// item into the heap with the given priority.
138
    /// \param item The item.
139
    /// \param value The priority.
140
    void set (const Item& item, const Prio& value) {
141
      int i=_iim[item];
142
      if ( i>=0 && _data[i].in ) {
143
        if ( _comp(value, _data[i].prio) ) decrease(item, value);
144
        if ( _comp(_data[i].prio, value) ) increase(item, value);
145
      } else push(item, value);
146
    }
147

	
148
    /// \brief Insert an item into the heap with the given priority.
149
    ///
150
    /// This function inserts the given item into the heap with the
151
    /// given priority.
152
    /// \param item The item to insert.
153
    /// \param value The priority of the item.
154
    /// \pre \e item must not be stored in the heap.
155
    void push (const Item& item, const Prio& value) {
156
      int i=_iim[item];
157
      if( i<0 ) {
158
        int s=_data.size();
159
        _iim.set(item, s);
160
        store st;
161
        st.name=item;
162
        _data.push_back(st);
163
        i=s;
164
      } else {
165
        _data[i].parent=_data[i].child=-1;
166
        _data[i].left_child=false;
167
        _data[i].degree=0;
168
        _data[i].in=true;
169
      }
170

	
171
      _data[i].prio=value;
172

	
173
      if ( _num_items!=0 ) {
174
        if ( _comp( value, _data[_min].prio) ) {
175
          fuse(i,_min);
176
          _min=i;
177
        }
178
        else fuse(_min,i);
179
      }
180
      else _min=i;
181

	
182
      ++_num_items;
183
    }
184

	
185
    /// \brief Return the item having minimum priority.
186
    ///
187
    /// This function returns the item having minimum priority.
188
    /// \pre The heap must be non-empty.
189
    Item top() const { return _data[_min].name; }
190

	
191
    /// \brief The minimum priority.
192
    ///
193
    /// This function returns the minimum priority.
194
    /// \pre The heap must be non-empty.
195
    const Prio& prio() const { return _data[_min].prio; }
196

	
197
    /// \brief The priority of the given item.
198
    ///
199
    /// This function returns the priority of the given item.
200
    /// \param item The item.
201
    /// \pre \e item must be in the heap.
202
    const Prio& operator[](const Item& item) const {
203
      return _data[_iim[item]].prio;
204
    }
205

	
206
    /// \brief Remove the item having minimum priority.
207
    ///
208
    /// This function removes the item having minimum priority.
209
    /// \pre The heap must be non-empty.
210
    void pop() {
211
      std::vector<int> trees;
212
      int i=0, child_right = 0;
213
      _data[_min].in=false;
214

	
215
      if( -1!=_data[_min].child ) {
216
        i=_data[_min].child;
217
        trees.push_back(i);
218
        _data[i].parent = -1;
219
        _data[_min].child = -1;
220

	
221
        int ch=-1;
222
        while( _data[i].child!=-1 ) {
223
          ch=_data[i].child;
224
          if( _data[ch].left_child && i==_data[ch].parent ) {
225
            break;
226
          } else {
227
            if( _data[ch].left_child ) {
228
              child_right=_data[ch].parent;
229
              _data[ch].parent = i;
230
              --_data[i].degree;
231
            }
232
            else {
233
              child_right=ch;
234
              _data[i].child=-1;
235
              _data[i].degree=0;
236
            }
237
            _data[child_right].parent = -1;
238
            trees.push_back(child_right);
239
            i = child_right;
240
          }
241
        }
242

	
243
        int num_child = trees.size();
244
        int other;
245
        for( i=0; i<num_child-1; i+=2 ) {
246
          if ( !_comp(_data[trees[i]].prio, _data[trees[i+1]].prio) ) {
247
            other=trees[i];
248
            trees[i]=trees[i+1];
249
            trees[i+1]=other;
250
          }
251
          fuse( trees[i], trees[i+1] );
252
        }
253

	
254
        i = (0==(num_child % 2)) ? num_child-2 : num_child-1;
255
        while(i>=2) {
256
          if ( _comp(_data[trees[i]].prio, _data[trees[i-2]].prio) ) {
257
            other=trees[i];
258
            trees[i]=trees[i-2];
259
            trees[i-2]=other;
260
          }
261
          fuse( trees[i-2], trees[i] );
262
          i-=2;
263
        }
264
        _min = trees[0];
265
      }
266
      else {
267
        _min = _data[_min].child;
268
      }
269

	
270
      if (_min >= 0) _data[_min].left_child = false;
271
      --_num_items;
272
    }
273

	
274
    /// \brief Remove the given item from the heap.
275
    ///
276
    /// This function removes the given item from the heap if it is
277
    /// already stored.
278
    /// \param item The item to delete.
279
    /// \pre \e item must be in the heap.
280
    void erase (const Item& item) {
281
      int i=_iim[item];
282
      if ( i>=0 && _data[i].in ) {
283
        decrease( item, _data[_min].prio-1 );
284
        pop();
285
      }
286
    }
287

	
288
    /// \brief Decrease the priority of an item to the given value.
289
    ///
290
    /// This function decreases the priority of an item to the given value.
291
    /// \param item The item.
292
    /// \param value The priority.
293
    /// \pre \e item must be stored in the heap with priority at least \e value.
294
    void decrease (Item item, const Prio& value) {
295
      int i=_iim[item];
296
      _data[i].prio=value;
297
      int p=_data[i].parent;
298

	
299
      if( _data[i].left_child && i!=_data[p].child ) {
300
        p=_data[p].parent;
301
      }
302

	
303
      if ( p!=-1 && _comp(value,_data[p].prio) ) {
304
        cut(i,p);
305
        if ( _comp(_data[_min].prio,value) ) {
306
          fuse(_min,i);
307
        } else {
308
          fuse(i,_min);
309
          _min=i;
310
        }
311
      }
312
    }
313

	
314
    /// \brief Increase the priority of an item to the given value.
315
    ///
316
    /// This function increases the priority of an item to the given value.
317
    /// \param item The item.
318
    /// \param value The priority.
319
    /// \pre \e item must be stored in the heap with priority at most \e value.
320
    void increase (Item item, const Prio& value) {
321
      erase(item);
322
      push(item,value);
323
    }
324

	
325
    /// \brief Return the state of an item.
326
    ///
327
    /// This method returns \c PRE_HEAP if the given item has never
328
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
329
    /// and \c POST_HEAP otherwise.
330
    /// In the latter case it is possible that the item will get back
331
    /// to the heap again.
332
    /// \param item The item.
333
    State state(const Item &item) const {
334
      int i=_iim[item];
335
      if( i>=0 ) {
336
        if( _data[i].in ) i=0;
337
        else i=-2;
338
      }
339
      return State(i);
340
    }
341

	
342
    /// \brief Set the state of an item in the heap.
343
    ///
344
    /// This function sets the state of the given item in the heap.
345
    /// It can be used to manually clear the heap when it is important
346
    /// to achive better time complexity.
347
    /// \param i The item.
348
    /// \param st The state. It should not be \c IN_HEAP.
349
    void state(const Item& i, State st) {
350
      switch (st) {
351
      case POST_HEAP:
352
      case PRE_HEAP:
353
        if (state(i) == IN_HEAP) erase(i);
354
        _iim[i]=st;
355
        break;
356
      case IN_HEAP:
357
        break;
358
      }
359
    }
360

	
361
  private:
362

	
363
    void cut(int a, int b) {
364
      int child_a;
365
      switch (_data[a].degree) {
366
        case 2:
367
          child_a = _data[_data[a].child].parent;
368
          if( _data[a].left_child ) {
369
            _data[child_a].left_child=true;
370
            _data[b].child=child_a;
371
            _data[child_a].parent=_data[a].parent;
372
          }
373
          else {
374
            _data[child_a].left_child=false;
375
            _data[child_a].parent=b;
376
            if( a!=_data[b].child )
377
              _data[_data[b].child].parent=child_a;
378
            else
379
              _data[b].child=child_a;
380
          }
381
          --_data[a].degree;
382
          _data[_data[a].child].parent=a;
383
          break;
384

	
385
        case 1:
386
          child_a = _data[a].child;
387
          if( !_data[child_a].left_child ) {
388
            --_data[a].degree;
389
            if( _data[a].left_child ) {
390
              _data[child_a].left_child=true;
391
              _data[child_a].parent=_data[a].parent;
392
              _data[b].child=child_a;
393
            }
394
            else {
395
              _data[child_a].left_child=false;
396
              _data[child_a].parent=b;
397
              if( a!=_data[b].child )
398
                _data[_data[b].child].parent=child_a;
399
              else
400
                _data[b].child=child_a;
401
            }
402
            _data[a].child=-1;
403
          }
404
          else {
405
            --_data[b].degree;
406
            if( _data[a].left_child ) {
407
              _data[b].child =
408
                (1==_data[b].degree) ? _data[a].parent : -1;
409
            } else {
410
              if (1==_data[b].degree)
411
                _data[_data[b].child].parent=b;
412
              else
413
                _data[b].child=-1;
414
            }
415
          }
416
          break;
417

	
418
        case 0:
419
          --_data[b].degree;
420
          if( _data[a].left_child ) {
421
            _data[b].child =
422
              (0!=_data[b].degree) ? _data[a].parent : -1;
423
          } else {
424
            if( 0!=_data[b].degree )
425
              _data[_data[b].child].parent=b;
426
            else
427
              _data[b].child=-1;
428
          }
429
          break;
430
      }
431
      _data[a].parent=-1;
432
      _data[a].left_child=false;
433
    }
434

	
435
    void fuse(int a, int b) {
436
      int child_a = _data[a].child;
437
      int child_b = _data[b].child;
438
      _data[a].child=b;
439
      _data[b].parent=a;
440
      _data[b].left_child=true;
441

	
442
      if( -1!=child_a ) {
443
        _data[b].child=child_a;
444
        _data[child_a].parent=b;
445
        _data[child_a].left_child=false;
446
        ++_data[b].degree;
447

	
448
        if( -1!=child_b ) {
449
           _data[b].child=child_b;
450
           _data[child_b].parent=child_a;
451
        }
452
      }
453
      else { ++_data[a].degree; }
454
    }
455

	
456
    class store {
457
      friend class PairingHeap;
458

	
459
      Item name;
460
      int parent;
461
      int child;
462
      bool left_child;
463
      int degree;
464
      bool in;
465
      Prio prio;
466

	
467
      store() : parent(-1), child(-1), left_child(false), degree(0), in(true) {}
468
    };
469
  };
470

	
471
} //namespace lemon
472

	
473
#endif //LEMON_PAIRING_HEAP_H
474

	
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
#ifdef DOXYGEN
56
    typedef GR::ArcMap<Value> FlowMap;
57
#else
58
    typedef typename Digraph::template ArcMap<Value> FlowMap;
59
#endif
60

	
61
    /// \brief Instantiates a FlowMap.
62
    ///
63
    /// This function instantiates a \ref FlowMap.
64
    /// \param digraph The digraph for which we would like to define
65
    /// the flow map.
66
    static FlowMap* createFlowMap(const Digraph& digraph) {
67
      return new FlowMap(digraph);
68
    }
69

	
70
    /// \brief The elevator type used by Preflow algorithm.
71
    ///
72
    /// The elevator type used by Preflow algorithm.
73
    ///
74
    /// \sa Elevator, LinkedElevator
75
#ifdef DOXYGEN
76
    typedef lemon::Elevator<GR, GR::Node> Elevator;
77
#else
78
    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
79
#endif
80

	
81
    /// \brief Instantiates an Elevator.
82
    ///
83
    /// This function instantiates an \ref Elevator.
84
    /// \param digraph The digraph for which we would like to define
85
    /// the elevator.
86
    /// \param max_level The maximum level of the elevator.
87
    static Elevator* createElevator(const Digraph& digraph, int max_level) {
88
      return new Elevator(digraph, max_level);
89
    }
90

	
91
    /// \brief The tolerance used by the algorithm
92
    ///
93
    /// The tolerance used by the algorithm to handle inexact computation.
94
    typedef lemon::Tolerance<Value> Tolerance;
95

	
96
  };
97

	
98

	
99
  /// \ingroup max_flow
100
  ///
101
  /// \brief %Preflow algorithm class.
102
  ///
103
  /// This class provides an implementation of Goldberg-Tarjan's \e preflow
104
  /// \e push-relabel algorithm producing a \ref max_flow
105
  /// "flow of maximum value" in a digraph \ref clrs01algorithms,
106
  /// \ref amo93networkflows, \ref goldberg88newapproach.
107
  /// The preflow algorithms are the fastest known maximum
108
  /// flow algorithms. The current implementation uses a mixture of the
109
  /// \e "highest label" and the \e "bound decrease" heuristics.
110
  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
111
  ///
112
  /// The algorithm consists of two phases. After the first phase
113
  /// the maximum flow value and the minimum cut is obtained. The
114
  /// second phase constructs a feasible maximum flow on each arc.
115
  ///
116
  /// \tparam GR The type of the digraph the algorithm runs on.
117
  /// \tparam CAP The type of the capacity map. The default map
118
  /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
119
#ifdef DOXYGEN
120
  template <typename GR, typename CAP, typename TR>
121
#else
122
  template <typename GR,
123
            typename CAP = typename GR::template ArcMap<int>,
124
            typename TR = PreflowDefaultTraits<GR, CAP> >
125
#endif
126
  class Preflow {
127
  public:
128

	
129
    ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
130
    typedef TR Traits;
131
    ///The type of the digraph the algorithm runs on.
132
    typedef typename Traits::Digraph Digraph;
133
    ///The type of the capacity map.
134
    typedef typename Traits::CapacityMap CapacityMap;
135
    ///The type of the flow values.
136
    typedef typename Traits::Value Value;
137

	
138
    ///The type of the flow map.
139
    typedef typename Traits::FlowMap FlowMap;
140
    ///The type of the elevator.
141
    typedef typename Traits::Elevator Elevator;
142
    ///The type of the tolerance.
143
    typedef typename Traits::Tolerance Tolerance;
144

	
145
  private:
146

	
147
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
148

	
149
    const Digraph& _graph;
150
    const CapacityMap* _capacity;
151

	
152
    int _node_num;
153

	
154
    Node _source, _target;
155

	
156
    FlowMap* _flow;
157
    bool _local_flow;
158

	
159
    Elevator* _level;
160
    bool _local_level;
161

	
162
    typedef typename Digraph::template NodeMap<Value> ExcessMap;
163
    ExcessMap* _excess;
164

	
165
    Tolerance _tolerance;
166

	
167
    bool _phase;
168

	
169

	
170
    void createStructures() {
171
      _node_num = countNodes(_graph);
172

	
173
      if (!_flow) {
174
        _flow = Traits::createFlowMap(_graph);
175
        _local_flow = true;
176
      }
177
      if (!_level) {
178
        _level = Traits::createElevator(_graph, _node_num);
179
        _local_level = true;
180
      }
181
      if (!_excess) {
182
        _excess = new ExcessMap(_graph);
183
      }
184
    }
185

	
186
    void destroyStructures() {
187
      if (_local_flow) {
188
        delete _flow;
189
      }
190
      if (_local_level) {
191
        delete _level;
192
      }
193
      if (_excess) {
194
        delete _excess;
195
      }
196
    }
197

	
198
  public:
199

	
200
    typedef Preflow Create;
201

	
202
    ///\name Named Template Parameters
203

	
204
    ///@{
205

	
206
    template <typename T>
207
    struct SetFlowMapTraits : public Traits {
208
      typedef T FlowMap;
209
      static FlowMap *createFlowMap(const Digraph&) {
210
        LEMON_ASSERT(false, "FlowMap is not initialized");
211
        return 0; // ignore warnings
212
      }
213
    };
214

	
215
    /// \brief \ref named-templ-param "Named parameter" for setting
216
    /// FlowMap type
217
    ///
218
    /// \ref named-templ-param "Named parameter" for setting FlowMap
219
    /// type.
220
    template <typename T>
221
    struct SetFlowMap
222
      : public Preflow<Digraph, CapacityMap, SetFlowMapTraits<T> > {
223
      typedef Preflow<Digraph, CapacityMap,
224
                      SetFlowMapTraits<T> > Create;
225
    };
226

	
227
    template <typename T>
228
    struct SetElevatorTraits : public Traits {
229
      typedef T Elevator;
230
      static Elevator *createElevator(const Digraph&, int) {
231
        LEMON_ASSERT(false, "Elevator is not initialized");
232
        return 0; // ignore warnings
233
      }
234
    };
235

	
236
    /// \brief \ref named-templ-param "Named parameter" for setting
237
    /// Elevator type
238
    ///
239
    /// \ref named-templ-param "Named parameter" for setting Elevator
240
    /// type. If this named parameter is used, then an external
241
    /// elevator object must be passed to the algorithm using the
242
    /// \ref elevator(Elevator&) "elevator()" function before calling
243
    /// \ref run() or \ref init().
244
    /// \sa SetStandardElevator
245
    template <typename T>
246
    struct SetElevator
247
      : public Preflow<Digraph, CapacityMap, SetElevatorTraits<T> > {
248
      typedef Preflow<Digraph, CapacityMap,
249
                      SetElevatorTraits<T> > Create;
250
    };
251

	
252
    template <typename T>
253
    struct SetStandardElevatorTraits : public Traits {
254
      typedef T Elevator;
255
      static Elevator *createElevator(const Digraph& digraph, int max_level) {
256
        return new Elevator(digraph, max_level);
257
      }
258
    };
259

	
260
    /// \brief \ref named-templ-param "Named parameter" for setting
261
    /// Elevator type with automatic allocation
262
    ///
263
    /// \ref named-templ-param "Named parameter" for setting Elevator
264
    /// type with automatic allocation.
265
    /// The Elevator should have standard constructor interface to be
266
    /// able to automatically created by the algorithm (i.e. the
267
    /// digraph and the maximum level should be passed to it).
268
    /// However an external elevator object could also be passed to the
269
    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
270
    /// before calling \ref run() or \ref init().
271
    /// \sa SetElevator
272
    template <typename T>
273
    struct SetStandardElevator
274
      : public Preflow<Digraph, CapacityMap,
275
                       SetStandardElevatorTraits<T> > {
276
      typedef Preflow<Digraph, CapacityMap,
277
                      SetStandardElevatorTraits<T> > Create;
278
    };
279

	
280
    /// @}
281

	
282
  protected:
283

	
284
    Preflow() {}
285

	
286
  public:
287

	
288

	
289
    /// \brief The constructor of the class.
290
    ///
291
    /// The constructor of the class.
292
    /// \param digraph The digraph the algorithm runs on.
293
    /// \param capacity The capacity of the arcs.
294
    /// \param source The source node.
295
    /// \param target The target node.
296
    Preflow(const Digraph& digraph, const CapacityMap& capacity,
297
            Node source, Node target)
298
      : _graph(digraph), _capacity(&capacity),
299
        _node_num(0), _source(source), _target(target),
300
        _flow(0), _local_flow(false),
301
        _level(0), _local_level(false),
302
        _excess(0), _tolerance(), _phase() {}
303

	
304
    /// \brief Destructor.
305
    ///
306
    /// Destructor.
307
    ~Preflow() {
308
      destroyStructures();
309
    }
310

	
311
    /// \brief Sets the capacity map.
312
    ///
313
    /// Sets the capacity map.
314
    /// \return <tt>(*this)</tt>
315
    Preflow& capacityMap(const CapacityMap& map) {
316
      _capacity = &map;
317
      return *this;
318
    }
319

	
320
    /// \brief Sets the flow map.
321
    ///
322
    /// Sets the flow map.
323
    /// If you don't use this function before calling \ref run() or
324
    /// \ref init(), an instance will be allocated automatically.
325
    /// The destructor deallocates this automatically allocated map,
326
    /// of course.
327
    /// \return <tt>(*this)</tt>
328
    Preflow& flowMap(FlowMap& map) {
329
      if (_local_flow) {
330
        delete _flow;
331
        _local_flow = false;
332
      }
333
      _flow = &map;
334
      return *this;
335
    }
336

	
337
    /// \brief Sets the source node.
338
    ///
339
    /// Sets the source node.
340
    /// \return <tt>(*this)</tt>
341
    Preflow& source(const Node& node) {
342
      _source = node;
343
      return *this;
344
    }
345

	
346
    /// \brief Sets the target node.
347
    ///
348
    /// Sets the target node.
349
    /// \return <tt>(*this)</tt>
350
    Preflow& target(const Node& node) {
351
      _target = node;
352
      return *this;
353
    }
354

	
355
    /// \brief Sets the elevator used by algorithm.
356
    ///
357
    /// Sets the elevator used by algorithm.
358
    /// If you don't use this function before calling \ref run() or
359
    /// \ref init(), an instance will be allocated automatically.
360
    /// The destructor deallocates this automatically allocated elevator,
361
    /// of course.
362
    /// \return <tt>(*this)</tt>
363
    Preflow& elevator(Elevator& elevator) {
364
      if (_local_level) {
365
        delete _level;
366
        _local_level = false;
367
      }
368
      _level = &elevator;
369
      return *this;
370
    }
371

	
372
    /// \brief Returns a const reference to the elevator.
373
    ///
374
    /// Returns a const reference to the elevator.
375
    ///
376
    /// \pre Either \ref run() or \ref init() must be called before
377
    /// using this function.
378
    const Elevator& elevator() const {
379
      return *_level;
380
    }
381

	
382
    /// \brief Sets the tolerance used by the algorithm.
383
    ///
384
    /// Sets the tolerance object used by the algorithm.
385
    /// \return <tt>(*this)</tt>
386
    Preflow& tolerance(const Tolerance& tolerance) {
387
      _tolerance = tolerance;
388
      return *this;
389
    }
390

	
391
    /// \brief Returns a const reference to the tolerance.
392
    ///
393
    /// Returns a const reference to the tolerance object used by
394
    /// the algorithm.
395
    const Tolerance& tolerance() const {
396
      return _tolerance;
397
    }
398

	
399
    /// \name Execution Control
400
    /// The simplest way to execute the preflow algorithm is to use
401
    /// \ref run() or \ref runMinCut().\n
402
    /// If you need better control on the initial solution or the execution,
403
    /// you have to call one of the \ref init() functions first, then
404
    /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
405

	
406
    ///@{
407

	
408
    /// \brief Initializes the internal data structures.
409
    ///
410
    /// Initializes the internal data structures and sets the initial
411
    /// flow to zero on each arc.
412
    void init() {
413
      createStructures();
414

	
415
      _phase = true;
416
      for (NodeIt n(_graph); n != INVALID; ++n) {
417
        (*_excess)[n] = 0;
418
      }
419

	
420
      for (ArcIt e(_graph); e != INVALID; ++e) {
421
        _flow->set(e, 0);
422
      }
423

	
424
      typename Digraph::template NodeMap<bool> reached(_graph, false);
425

	
426
      _level->initStart();
427
      _level->initAddItem(_target);
428

	
429
      std::vector<Node> queue;
430
      reached[_source] = true;
431

	
432
      queue.push_back(_target);
433
      reached[_target] = true;
434
      while (!queue.empty()) {
435
        _level->initNewLevel();
436
        std::vector<Node> nqueue;
437
        for (int i = 0; i < int(queue.size()); ++i) {
438
          Node n = queue[i];
439
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
440
            Node u = _graph.source(e);
441
            if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
442
              reached[u] = true;
443
              _level->initAddItem(u);
444
              nqueue.push_back(u);
445
            }
446
          }
447
        }
448
        queue.swap(nqueue);
449
      }
450
      _level->initFinish();
451

	
452
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
453
        if (_tolerance.positive((*_capacity)[e])) {
454
          Node u = _graph.target(e);
455
          if ((*_level)[u] == _level->maxLevel()) continue;
456
          _flow->set(e, (*_capacity)[e]);
457
          (*_excess)[u] += (*_capacity)[e];
458
          if (u != _target && !_level->active(u)) {
459
            _level->activate(u);
460
          }
461
        }
462
      }
463
    }
464

	
465
    /// \brief Initializes the internal data structures using the
466
    /// given flow map.
467
    ///
468
    /// Initializes the internal data structures and sets the initial
469
    /// flow to the given \c flowMap. The \c flowMap should contain a
470
    /// flow or at least a preflow, i.e. at each node excluding the
471
    /// source node the incoming flow should greater or equal to the
472
    /// outgoing flow.
473
    /// \return \c false if the given \c flowMap is not a preflow.
474
    template <typename FlowMap>
475
    bool init(const FlowMap& flowMap) {
476
      createStructures();
477

	
478
      for (ArcIt e(_graph); e != INVALID; ++e) {
479
        _flow->set(e, flowMap[e]);
480
      }
481

	
482
      for (NodeIt n(_graph); n != INVALID; ++n) {
483
        Value excess = 0;
484
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
485
          excess += (*_flow)[e];
486
        }
487
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
488
          excess -= (*_flow)[e];
489
        }
490
        if (excess < 0 && n != _source) return false;
491
        (*_excess)[n] = excess;
492
      }
493

	
494
      typename Digraph::template NodeMap<bool> reached(_graph, false);
495

	
496
      _level->initStart();
497
      _level->initAddItem(_target);
498

	
499
      std::vector<Node> queue;
500
      reached[_source] = true;
501

	
502
      queue.push_back(_target);
503
      reached[_target] = true;
504
      while (!queue.empty()) {
505
        _level->initNewLevel();
506
        std::vector<Node> nqueue;
507
        for (int i = 0; i < int(queue.size()); ++i) {
508
          Node n = queue[i];
509
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
510
            Node u = _graph.source(e);
511
            if (!reached[u] &&
512
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
513
              reached[u] = true;
514
              _level->initAddItem(u);
515
              nqueue.push_back(u);
516
            }
517
          }
518
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
519
            Node v = _graph.target(e);
520
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
521
              reached[v] = true;
522
              _level->initAddItem(v);
523
              nqueue.push_back(v);
524
            }
525
          }
526
        }
527
        queue.swap(nqueue);
528
      }
529
      _level->initFinish();
530

	
531
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
532
        Value rem = (*_capacity)[e] - (*_flow)[e];
533
        if (_tolerance.positive(rem)) {
534
          Node u = _graph.target(e);
535
          if ((*_level)[u] == _level->maxLevel()) continue;
536
          _flow->set(e, (*_capacity)[e]);
537
          (*_excess)[u] += rem;
538
          if (u != _target && !_level->active(u)) {
539
            _level->activate(u);
540
          }
541
        }
542
      }
543
      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
544
        Value rem = (*_flow)[e];
545
        if (_tolerance.positive(rem)) {
546
          Node v = _graph.source(e);
547
          if ((*_level)[v] == _level->maxLevel()) continue;
548
          _flow->set(e, 0);
549
          (*_excess)[v] += rem;
550
          if (v != _target && !_level->active(v)) {
551
            _level->activate(v);
552
          }
553
        }
554
      }
555
      return true;
556
    }
557

	
558
    /// \brief Starts the first phase of the preflow algorithm.
559
    ///
560
    /// The preflow algorithm consists of two phases, this method runs
561
    /// the first phase. After the first phase the maximum flow value
562
    /// and a minimum value cut can already be computed, although a
563
    /// maximum flow is not yet obtained. So after calling this method
564
    /// \ref flowValue() returns the value of a maximum flow and \ref
565
    /// minCut() returns a minimum cut.
566
    /// \pre One of the \ref init() functions must be called before
567
    /// using this function.
568
    void startFirstPhase() {
569
      _phase = true;
570

	
571
      Node n = _level->highestActive();
572
      int level = _level->highestActiveLevel();
573
      while (n != INVALID) {
574
        int num = _node_num;
575

	
576
        while (num > 0 && n != INVALID) {
577
          Value excess = (*_excess)[n];
578
          int new_level = _level->maxLevel();
579

	
580
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
581
            Value rem = (*_capacity)[e] - (*_flow)[e];
582
            if (!_tolerance.positive(rem)) continue;
583
            Node v = _graph.target(e);
584
            if ((*_level)[v] < level) {
585
              if (!_level->active(v) && v != _target) {
586
                _level->activate(v);
587
              }
588
              if (!_tolerance.less(rem, excess)) {
589
                _flow->set(e, (*_flow)[e] + excess);
590
                (*_excess)[v] += excess;
591
                excess = 0;
592
                goto no_more_push_1;
593
              } else {
594
                excess -= rem;
595
                (*_excess)[v] += rem;
596
                _flow->set(e, (*_capacity)[e]);
597
              }
598
            } else if (new_level > (*_level)[v]) {
599
              new_level = (*_level)[v];
600
            }
601
          }
602

	
603
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
604
            Value rem = (*_flow)[e];
605
            if (!_tolerance.positive(rem)) continue;
606
            Node v = _graph.source(e);
607
            if ((*_level)[v] < level) {
608
              if (!_level->active(v) && v != _target) {
609
                _level->activate(v);
610
              }
611
              if (!_tolerance.less(rem, excess)) {
612
                _flow->set(e, (*_flow)[e] - excess);
613
                (*_excess)[v] += excess;
614
                excess = 0;
615
                goto no_more_push_1;
616
              } else {
617
                excess -= rem;
618
                (*_excess)[v] += rem;
619
                _flow->set(e, 0);
620
              }
621
            } else if (new_level > (*_level)[v]) {
622
              new_level = (*_level)[v];
623
            }
624
          }
625

	
626
        no_more_push_1:
627

	
628
          (*_excess)[n] = excess;
629

	
630
          if (excess != 0) {
631
            if (new_level + 1 < _level->maxLevel()) {
632
              _level->liftHighestActive(new_level + 1);
633
            } else {
634
              _level->liftHighestActiveToTop();
635
            }
636
            if (_level->emptyLevel(level)) {
637
              _level->liftToTop(level);
638
            }
639
          } else {
640
            _level->deactivate(n);
641
          }
642

	
643
          n = _level->highestActive();
644
          level = _level->highestActiveLevel();
645
          --num;
646
        }
647

	
648
        num = _node_num * 20;
649
        while (num > 0 && n != INVALID) {
650
          Value excess = (*_excess)[n];
651
          int new_level = _level->maxLevel();
652

	
653
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
654
            Value rem = (*_capacity)[e] - (*_flow)[e];
655
            if (!_tolerance.positive(rem)) continue;
656
            Node v = _graph.target(e);
657
            if ((*_level)[v] < level) {
658
              if (!_level->active(v) && v != _target) {
659
                _level->activate(v);
660
              }
661
              if (!_tolerance.less(rem, excess)) {
662
                _flow->set(e, (*_flow)[e] + excess);
663
                (*_excess)[v] += excess;
664
                excess = 0;
665
                goto no_more_push_2;
666
              } else {
667
                excess -= rem;
668
                (*_excess)[v] += rem;
669
                _flow->set(e, (*_capacity)[e]);
670
              }
671
            } else if (new_level > (*_level)[v]) {
672
              new_level = (*_level)[v];
673
            }
674
          }
675

	
676
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
677
            Value rem = (*_flow)[e];
678
            if (!_tolerance.positive(rem)) continue;
679
            Node v = _graph.source(e);
680
            if ((*_level)[v] < level) {
681
              if (!_level->active(v) && v != _target) {
682
                _level->activate(v);
683
              }
684
              if (!_tolerance.less(rem, excess)) {
685
                _flow->set(e, (*_flow)[e] - excess);
686
                (*_excess)[v] += excess;
687
                excess = 0;
688
                goto no_more_push_2;
689
              } else {
690
                excess -= rem;
691
                (*_excess)[v] += rem;
692
                _flow->set(e, 0);
693
              }
694
            } else if (new_level > (*_level)[v]) {
695
              new_level = (*_level)[v];
696
            }
697
          }
698

	
699
        no_more_push_2:
700

	
701
          (*_excess)[n] = excess;
702

	
703
          if (excess != 0) {
704
            if (new_level + 1 < _level->maxLevel()) {
705
              _level->liftActiveOn(level, new_level + 1);
706
            } else {
707
              _level->liftActiveToTop(level);
708
            }
709
            if (_level->emptyLevel(level)) {
710
              _level->liftToTop(level);
711
            }
712
          } else {
713
            _level->deactivate(n);
714
          }
715

	
716
          while (level >= 0 && _level->activeFree(level)) {
717
            --level;
718
          }
719
          if (level == -1) {
720
            n = _level->highestActive();
721
            level = _level->highestActiveLevel();
722
          } else {
723
            n = _level->activeOn(level);
724
          }
725
          --num;
726
        }
727
      }
728
    }
729

	
730
    /// \brief Starts the second phase of the preflow algorithm.
731
    ///
732
    /// The preflow algorithm consists of two phases, this method runs
733
    /// the second phase. After calling one of the \ref init() functions
734
    /// and \ref startFirstPhase() and then \ref startSecondPhase(),
735
    /// \ref flowMap() returns a maximum flow, \ref flowValue() returns the
736
    /// value of a maximum flow, \ref minCut() returns a minimum cut
737
    /// \pre One of the \ref init() functions and \ref startFirstPhase()
738
    /// must be called before using this function.
739
    void startSecondPhase() {
740
      _phase = false;
741

	
742
      typename Digraph::template NodeMap<bool> reached(_graph);
743
      for (NodeIt n(_graph); n != INVALID; ++n) {
744
        reached[n] = (*_level)[n] < _level->maxLevel();
745
      }
746

	
747
      _level->initStart();
748
      _level->initAddItem(_source);
749

	
750
      std::vector<Node> queue;
751
      queue.push_back(_source);
752
      reached[_source] = true;
753

	
754
      while (!queue.empty()) {
755
        _level->initNewLevel();
756
        std::vector<Node> nqueue;
757
        for (int i = 0; i < int(queue.size()); ++i) {
758
          Node n = queue[i];
759
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
760
            Node v = _graph.target(e);
761
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
762
              reached[v] = true;
763
              _level->initAddItem(v);
764
              nqueue.push_back(v);
765
            }
766
          }
767
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
768
            Node u = _graph.source(e);
769
            if (!reached[u] &&
770
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
771
              reached[u] = true;
772
              _level->initAddItem(u);
773
              nqueue.push_back(u);
774
            }
775
          }
776
        }
777
        queue.swap(nqueue);
778
      }
779
      _level->initFinish();
780

	
781
      for (NodeIt n(_graph); n != INVALID; ++n) {
782
        if (!reached[n]) {
783
          _level->dirtyTopButOne(n);
784
        } else if ((*_excess)[n] > 0 && _target != n) {
785
          _level->activate(n);
786
        }
787
      }
788

	
789
      Node n;
790
      while ((n = _level->highestActive()) != INVALID) {
791
        Value excess = (*_excess)[n];
792
        int level = _level->highestActiveLevel();
793
        int new_level = _level->maxLevel();
794

	
795
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
796
          Value rem = (*_capacity)[e] - (*_flow)[e];
797
          if (!_tolerance.positive(rem)) continue;
798
          Node v = _graph.target(e);
799
          if ((*_level)[v] < level) {
800
            if (!_level->active(v) && v != _source) {
801
              _level->activate(v);
802
            }
803
            if (!_tolerance.less(rem, excess)) {
804
              _flow->set(e, (*_flow)[e] + excess);
805
              (*_excess)[v] += excess;
806
              excess = 0;
807
              goto no_more_push;
808
            } else {
809
              excess -= rem;
810
              (*_excess)[v] += rem;
811
              _flow->set(e, (*_capacity)[e]);
812
            }
813
          } else if (new_level > (*_level)[v]) {
814
            new_level = (*_level)[v];
815
          }
816
        }
817

	
818
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
819
          Value rem = (*_flow)[e];
820
          if (!_tolerance.positive(rem)) continue;
821
          Node v = _graph.source(e);
822
          if ((*_level)[v] < level) {
823
            if (!_level->active(v) && v != _source) {
824
              _level->activate(v);
825
            }
826
            if (!_tolerance.less(rem, excess)) {
827
              _flow->set(e, (*_flow)[e] - excess);
828
              (*_excess)[v] += excess;
829
              excess = 0;
830
              goto no_more_push;
831
            } else {
832
              excess -= rem;
833
              (*_excess)[v] += rem;
834
              _flow->set(e, 0);
835
            }
836
          } else if (new_level > (*_level)[v]) {
837
            new_level = (*_level)[v];
838
          }
839
        }
840

	
841
      no_more_push:
842

	
843
        (*_excess)[n] = excess;
844

	
845
        if (excess != 0) {
846
          if (new_level + 1 < _level->maxLevel()) {
847
            _level->liftHighestActive(new_level + 1);
848
          } else {
849
            // Calculation error
850
            _level->liftHighestActiveToTop();
851
          }
852
          if (_level->emptyLevel(level)) {
853
            // Calculation error
854
            _level->liftToTop(level);
855
          }
856
        } else {
857
          _level->deactivate(n);
858
        }
859

	
860
      }
861
    }
862

	
863
    /// \brief Runs the preflow algorithm.
864
    ///
865
    /// Runs the preflow algorithm.
866
    /// \note pf.run() is just a shortcut of the following code.
867
    /// \code
868
    ///   pf.init();
869
    ///   pf.startFirstPhase();
870
    ///   pf.startSecondPhase();
871
    /// \endcode
872
    void run() {
873
      init();
874
      startFirstPhase();
875
      startSecondPhase();
876
    }
877

	
878
    /// \brief Runs the preflow algorithm to compute the minimum cut.
879
    ///
880
    /// Runs the preflow algorithm to compute the minimum cut.
881
    /// \note pf.runMinCut() is just a shortcut of the following code.
882
    /// \code
883
    ///   pf.init();
884
    ///   pf.startFirstPhase();
885
    /// \endcode
886
    void runMinCut() {
887
      init();
888
      startFirstPhase();
889
    }
890

	
891
    /// @}
892

	
893
    /// \name Query Functions
894
    /// The results of the preflow algorithm can be obtained using these
895
    /// functions.\n
896
    /// Either one of the \ref run() "run*()" functions or one of the
897
    /// \ref startFirstPhase() "start*()" functions should be called
898
    /// before using them.
899

	
900
    ///@{
901

	
902
    /// \brief Returns the value of the maximum flow.
903
    ///
904
    /// Returns the value of the maximum flow by returning the excess
905
    /// of the target node. This value equals to the value of
906
    /// the maximum flow already after the first phase of the algorithm.
907
    ///
908
    /// \pre Either \ref run() or \ref init() must be called before
909
    /// using this function.
910
    Value flowValue() const {
911
      return (*_excess)[_target];
912
    }
913

	
914
    /// \brief Returns the flow value on the given arc.
915
    ///
916
    /// Returns the flow value on the given arc. This method can
917
    /// be called after the second phase of the algorithm.
918
    ///
919
    /// \pre Either \ref run() or \ref init() must be called before
920
    /// using this function.
921
    Value flow(const Arc& arc) const {
922
      return (*_flow)[arc];
923
    }
924

	
925
    /// \brief Returns a const reference to the flow map.
926
    ///
927
    /// Returns a const reference to the arc map storing the found flow.
928
    /// This method can be called after the second phase of the algorithm.
929
    ///
930
    /// \pre Either \ref run() or \ref init() must be called before
931
    /// using this function.
932
    const FlowMap& flowMap() const {
933
      return *_flow;
934
    }
935

	
936
    /// \brief Returns \c true when the node is on the source side of the
937
    /// minimum cut.
938
    ///
939
    /// Returns true when the node is on the source side of the found
940
    /// minimum cut. This method can be called both after running \ref
941
    /// startFirstPhase() and \ref startSecondPhase().
942
    ///
943
    /// \pre Either \ref run() or \ref init() must be called before
944
    /// using this function.
945
    bool minCut(const Node& node) const {
946
      return ((*_level)[node] == _level->maxLevel()) == _phase;
947
    }
948

	
949
    /// \brief Gives back a minimum value cut.
950
    ///
951
    /// Sets \c cutMap to the characteristic vector of a minimum value
952
    /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
953
    /// node map with \c bool (or convertible) value type.
954
    ///
955
    /// This method can be called both after running \ref startFirstPhase()
956
    /// and \ref startSecondPhase(). The result after the second phase
957
    /// could be slightly different if inexact computation is used.
958
    ///
959
    /// \note This function calls \ref minCut() for each node, so it runs in
960
    /// O(n) time.
961
    ///
962
    /// \pre Either \ref run() or \ref init() must be called before
963
    /// using this function.
964
    template <typename CutMap>
965
    void minCutMap(CutMap& cutMap) const {
966
      for (NodeIt n(_graph); n != INVALID; ++n) {
967
        cutMap.set(n, minCut(n));
968
      }
969
    }
970

	
971
    /// @}
972
  };
973
}
974

	
975
#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 heaps
23
///\file
24
///\brief Radix heap implementation.
25

	
26
#include <vector>
27
#include <lemon/error.h>
28

	
29
namespace lemon {
30

	
31

	
32
  /// \ingroup heaps
33
  ///
34
  /// \brief Radix heap data structure.
35
  ///
36
  /// This class implements the \e radix \e heap data structure.
37
  /// It practically conforms to the \ref concepts::Heap "heap concept",
38
  /// but it has some limitations due its special implementation.
39
  /// The type of the priorities must be \c int and the priority of an
40
  /// item cannot be decreased under the priority of the last removed item.
41
  ///
42
  /// \tparam IM A read-writable item map with \c int values, used
43
  /// internally to handle the cross references.
44
  template <typename IM>
45
  class RadixHeap {
46

	
47
  public:
48

	
49
    /// Type of the item-int map.
50
    typedef IM ItemIntMap;
51
    /// Type of the priorities.
52
    typedef int Prio;
53
    /// Type of the items stored in the heap.
54
    typedef typename ItemIntMap::Key Item;
55

	
56
    /// \brief Exception thrown by RadixHeap.
57
    ///
58
    /// This exception is thrown when an item is inserted into a
59
    /// RadixHeap with a priority smaller than the last erased one.
60
    /// \see RadixHeap
61
    class PriorityUnderflowError : public Exception {
62
    public:
63
      virtual const char* what() const throw() {
64
        return "lemon::RadixHeap::PriorityUnderflowError";
65
      }
66
    };
67

	
68
    /// \brief Type to represent the states of the items.
69
    ///
70
    /// Each item has a state associated to it. It can be "in heap",
71
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
72
    /// heap's point of view, but may be useful to the user.
73
    ///
74
    /// The item-int map must be initialized in such way that it assigns
75
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
76
    enum State {
77
      IN_HEAP = 0,    ///< = 0.
78
      PRE_HEAP = -1,  ///< = -1.
79
      POST_HEAP = -2  ///< = -2.
80
    };
81

	
82
  private:
83

	
84
    struct RadixItem {
85
      int prev, next, box;
86
      Item item;
87
      int prio;
88
      RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
89
    };
90

	
91
    struct RadixBox {
92
      int first;
93
      int min, size;
94
      RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
95
    };
96

	
97
    std::vector<RadixItem> _data;
98
    std::vector<RadixBox> _boxes;
99

	
100
    ItemIntMap &_iim;
101

	
102
  public:
103

	
104
    /// \brief Constructor.
105
    ///
106
    /// Constructor.
107
    /// \param map A map that assigns \c int values to the items.
108
    /// It is used internally to handle the cross references.
109
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
110
    /// \param minimum The initial minimum value of the heap.
111
    /// \param capacity The initial capacity of the heap.
112
    RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0)
113
      : _iim(map)
114
    {
115
      _boxes.push_back(RadixBox(minimum, 1));
116
      _boxes.push_back(RadixBox(minimum + 1, 1));
117
      while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
118
        extend();
119
      }
120
    }
121

	
122
    /// \brief The number of items stored in the heap.
123
    ///
124
    /// This function returns the number of items stored in the heap.
125
    int size() const { return _data.size(); }
126

	
127
    /// \brief Check if the heap is empty.
128
    ///
129
    /// This function returns \c true if the heap is empty.
130
    bool empty() const { return _data.empty(); }
131

	
132
    /// \brief Make the heap empty.
133
    ///
134
    /// This functon makes the heap empty.
135
    /// It does not change the cross reference map. If you want to reuse
136
    /// a heap that is not surely empty, you should first clear it and
137
    /// then you should set the cross reference map to \c PRE_HEAP
138
    /// for each item.
139
    /// \param minimum The minimum value of the heap.
140
    /// \param capacity The capacity of the heap.
141
    void clear(int minimum = 0, int capacity = 0) {
142
      _data.clear(); _boxes.clear();
143
      _boxes.push_back(RadixBox(minimum, 1));
144
      _boxes.push_back(RadixBox(minimum + 1, 1));
145
      while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
146
        extend();
147
      }
148
    }
149

	
150
  private:
151

	
152
    bool upper(int box, Prio pr) {
153
      return pr < _boxes[box].min;
154
    }
155

	
156
    bool lower(int box, Prio pr) {
157
      return pr >= _boxes[box].min + _boxes[box].size;
158
    }
159

	
160
    // Remove item from the box list
161
    void remove(int index) {
162
      if (_data[index].prev >= 0) {
163
        _data[_data[index].prev].next = _data[index].next;
164
      } else {
165
        _boxes[_data[index].box].first = _data[index].next;
166
      }
167
      if (_data[index].next >= 0) {
168
        _data[_data[index].next].prev = _data[index].prev;
169
      }
170
    }
171

	
172
    // Insert item into the box list
173
    void insert(int box, int index) {
174
      if (_boxes[box].first == -1) {
175
        _boxes[box].first = index;
176
        _data[index].next = _data[index].prev = -1;
177
      } else {
178
        _data[index].next = _boxes[box].first;
179
        _data[_boxes[box].first].prev = index;
180
        _data[index].prev = -1;
181
        _boxes[box].first = index;
182
      }
183
      _data[index].box = box;
184
    }
185

	
186
    // Add a new box to the box list
187
    void extend() {
188
      int min = _boxes.back().min + _boxes.back().size;
189
      int bs = 2 * _boxes.back().size;
190
      _boxes.push_back(RadixBox(min, bs));
191
    }
192

	
193
    // Move an item up into the proper box.
194
    void bubbleUp(int index) {
195
      if (!lower(_data[index].box, _data[index].prio)) return;
196
      remove(index);
197
      int box = findUp(_data[index].box, _data[index].prio);
198
      insert(box, index);
199
    }
200

	
201
    // Find up the proper box for the item with the given priority
202
    int findUp(int start, int pr) {
203
      while (lower(start, pr)) {
204
        if (++start == int(_boxes.size())) {
205
          extend();
206
        }
207
      }
208
      return start;
209
    }
210

	
211
    // Move an item down into the proper box
212
    void bubbleDown(int index) {
213
      if (!upper(_data[index].box, _data[index].prio)) return;
214
      remove(index);
215
      int box = findDown(_data[index].box, _data[index].prio);
216
      insert(box, index);
217
    }
218

	
219
    // Find down the proper box for the item with the given priority
220
    int findDown(int start, int pr) {
221
      while (upper(start, pr)) {
222
        if (--start < 0) throw PriorityUnderflowError();
223
      }
224
      return start;
225
    }
226

	
227
    // Find the first non-empty box
228
    int findFirst() {
229
      int first = 0;
230
      while (_boxes[first].first == -1) ++first;
231
      return first;
232
    }
233

	
234
    // Gives back the minimum priority of the given box
235
    int minValue(int box) {
236
      int min = _data[_boxes[box].first].prio;
237
      for (int k = _boxes[box].first; k != -1; k = _data[k].next) {
238
        if (_data[k].prio < min) min = _data[k].prio;
239
      }
240
      return min;
241
    }
242

	
243
    // Rearrange the items of the heap and make the first box non-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
        bubbleDown(curr);
256
        curr = next;
257
      }
258
    }
259

	
260
    void relocateLast(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
    /// This function inserts the given item into the heap with the
281
    /// given priority.
282
    /// \param i The item to insert.
283
    /// \param p The priority of the item.
284
    /// \pre \e i must not be stored in the heap.
285
    /// \warning This method may throw an \c UnderFlowPriorityException.
286
    void push(const Item &i, const Prio &p) {
287
      int n = _data.size();
288
      _iim.set(i, n);
289
      _data.push_back(RadixItem(i, p));
290
      while (lower(_boxes.size() - 1, p)) {
291
        extend();
292
      }
293
      int box = findDown(_boxes.size() - 1, p);
294
      insert(box, n);
295
    }
296

	
297
    /// \brief Return the item having minimum priority.
298
    ///
299
    /// This function returns the item having minimum priority.
300
    /// \pre The heap must be non-empty.
301
    Item top() const {
302
      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
303
      return _data[_boxes[0].first].item;
304
    }
305

	
306
    /// \brief The minimum priority.
307
    ///
308
    /// This function returns the minimum priority.
309
    /// \pre The heap must be non-empty.
310
    Prio prio() const {
311
      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
312
      return _data[_boxes[0].first].prio;
313
     }
314

	
315
    /// \brief Remove the item having minimum priority.
316
    ///
317
    /// This function removes the item having minimum priority.
318
    /// \pre The heap must be non-empty.
319
    void pop() {
320
      moveDown();
321
      int index = _boxes[0].first;
322
      _iim[_data[index].item] = POST_HEAP;
323
      remove(index);
324
      relocateLast(index);
325
    }
326

	
327
    /// \brief Remove the given item from the heap.
328
    ///
329
    /// This function removes the given item from the heap if it is
330
    /// already stored.
331
    /// \param i The item to delete.
332
    /// \pre \e i must be in the heap.
333
    void erase(const Item &i) {
334
      int index = _iim[i];
335
      _iim[i] = POST_HEAP;
336
      remove(index);
337
      relocateLast(index);
338
   }
339

	
340
    /// \brief The priority of the given item.
341
    ///
342
    /// This function returns the priority of the given item.
343
    /// \param i The item.
344
    /// \pre \e i must be in the heap.
345
    Prio operator[](const Item &i) const {
346
      int idx = _iim[i];
347
      return _data[idx].prio;
348
    }
349

	
350
    /// \brief Set the priority of an item or insert it, if it is
351
    /// not stored in the heap.
352
    ///
353
    /// This method sets the priority of the given item if it is
354
    /// already stored in the heap. Otherwise it inserts the given
355
    /// item into the heap with the given priority.
356
    /// \param i The item.
357
    /// \param p The priority.
358
    /// \pre \e i must be in the heap.
359
    /// \warning This method may throw an \c UnderFlowPriorityException.
360
    void set(const Item &i, const Prio &p) {
361
      int idx = _iim[i];
362
      if( idx < 0 ) {
363
        push(i, p);
364
      }
365
      else if( p >= _data[idx].prio ) {
366
        _data[idx].prio = p;
367
        bubbleUp(idx);
368
      } else {
369
        _data[idx].prio = p;
370
        bubbleDown(idx);
371
      }
372
    }
373

	
374
    /// \brief Decrease the priority of an item to the given value.
375
    ///
376
    /// This function decreases the priority of an item to the given value.
377
    /// \param i The item.
378
    /// \param p The priority.
379
    /// \pre \e i must be stored in the heap with priority at least \e p.
380
    /// \warning This method may throw an \c UnderFlowPriorityException.
381
    void decrease(const Item &i, const Prio &p) {
382
      int idx = _iim[i];
383
      _data[idx].prio = p;
384
      bubbleDown(idx);
385
    }
386

	
387
    /// \brief Increase the priority of an item to the given value.
388
    ///
389
    /// This function increases the priority of an item to the given value.
390
    /// \param i The item.
391
    /// \param p The priority.
392
    /// \pre \e i must be stored in the heap with priority at most \e p.
393
    void increase(const Item &i, const Prio &p) {
394
      int idx = _iim[i];
395
      _data[idx].prio = p;
396
      bubbleUp(idx);
397
    }
398

	
399
    /// \brief Return the state of an item.
400
    ///
401
    /// This method returns \c PRE_HEAP if the given item has never
402
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
403
    /// and \c POST_HEAP otherwise.
404
    /// In the latter case it is possible that the item will get back
405
    /// to the heap again.
406
    /// \param i The item.
407
    State state(const Item &i) const {
408
      int s = _iim[i];
409
      if( s >= 0 ) s = 0;
410
      return State(s);
411
    }
412

	
413
    /// \brief Set the state of an item in the heap.
414
    ///
415
    /// This function sets the state of the given item in the heap.
416
    /// It can be used to manually clear the heap when it is important
417
    /// to achive better time complexity.
418
    /// \param i The item.
419
    /// \param st The state. It should not be \c IN_HEAP.
420
    void state(const Item& i, State st) {
421
      switch (st) {
422
      case POST_HEAP:
423
      case PRE_HEAP:
424
        if (state(i) == IN_HEAP) {
425
          erase(i);
426
        }
427
        _iim[i] = st;
428
        break;
429
      case IN_HEAP:
430
        break;
431
      }
432
    }
433

	
434
  }; // class RadixHeap
435

	
436
} // namespace lemon
437

	
438
#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
  int SoplexLp::_addRow(Value l, ExprIterator b, ExprIterator e, Value u) {
95
    soplex::DSVector v;
96
    for (ExprIterator it = b; it != e; ++it) {
97
      v.add(it->first, it->second);
98
    }
99
    soplex::LPRow r(l, v, u);
100
    soplex->addRow(r);
101

	
102
    _row_names.push_back(std::string());
103

	
104
    return soplex->nRows() - 1;
105
  }
106

	
107

	
108
  void SoplexLp::_eraseCol(int i) {
109
    soplex->removeCol(i);
110
    _col_names_ref.erase(_col_names[i]);
111
    _col_names[i] = _col_names.back();
112
    _col_names_ref[_col_names.back()] = i;
113
    _col_names.pop_back();
114
  }
115

	
116
  void SoplexLp::_eraseRow(int i) {
117
    soplex->removeRow(i);
118
    _row_names_ref.erase(_row_names[i]);
119
    _row_names[i] = _row_names.back();
120
    _row_names_ref[_row_names.back()] = i;
121
    _row_names.pop_back();
122
  }
123

	
124
  void SoplexLp::_eraseColId(int i) {
125
    cols.eraseIndex(i);
126
    cols.relocateIndex(i, cols.maxIndex());
127
  }
128
  void SoplexLp::_eraseRowId(int i) {
129
    rows.eraseIndex(i);
130
    rows.relocateIndex(i, rows.maxIndex());
131
  }
132

	
133
  void SoplexLp::_getColName(int c, std::string &name) const {
134
    name = _col_names[c];
135
  }
136

	
137
  void SoplexLp::_setColName(int c, const std::string &name) {
138
    _col_names_ref.erase(_col_names[c]);
139
    _col_names[c] = name;
140
    if (!name.empty()) {
141
      _col_names_ref.insert(std::make_pair(name, c));
142
    }
143
  }
144

	
145
  int SoplexLp::_colByName(const std::string& name) const {
146
    std::map<std::string, int>::const_iterator it =
147
      _col_names_ref.find(name);
148
    if (it != _col_names_ref.end()) {
149
      return it->second;
150
    } else {
151
      return -1;
152
    }
153
  }
154

	
155
  void SoplexLp::_getRowName(int r, std::string &name) const {
156
    name = _row_names[r];
157
  }
158

	
159
  void SoplexLp::_setRowName(int r, const std::string &name) {
160
    _row_names_ref.erase(_row_names[r]);
161
    _row_names[r] = name;
162
    if (!name.empty()) {
163
      _row_names_ref.insert(std::make_pair(name, r));
164
    }
165
  }
166

	
167
  int SoplexLp::_rowByName(const std::string& name) const {
168
    std::map<std::string, int>::const_iterator it =
169
      _row_names_ref.find(name);
170
    if (it != _row_names_ref.end()) {
171
      return it->second;
172
    } else {
173
      return -1;
174
    }
175
  }
176

	
177

	
178
  void SoplexLp::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
179
    for (int j = 0; j < soplex->nCols(); ++j) {
180
      soplex->changeElement(i, j, 0.0);
181
    }
182
    for(ExprIterator it = b; it != e; ++it) {
183
      soplex->changeElement(i, it->first, it->second);
184
    }
185
  }
186

	
187
  void SoplexLp::_getRowCoeffs(int i, InsertIterator b) const {
188
    const soplex::SVector& vec = soplex->rowVector(i);
189
    for (int k = 0; k < vec.size(); ++k) {
190
      *b = std::make_pair(vec.index(k), vec.value(k));
191
      ++b;
192
    }
193
  }
194

	
195
  void SoplexLp::_setColCoeffs(int j, ExprIterator b, ExprIterator e) {
196
    for (int i = 0; i < soplex->nRows(); ++i) {
197
      soplex->changeElement(i, j, 0.0);
198
    }
199
    for(ExprIterator it = b; it != e; ++it) {
200
      soplex->changeElement(it->first, j, it->second);
201
    }
202
  }
203

	
204
  void SoplexLp::_getColCoeffs(int i, InsertIterator b) const {
205
    const soplex::SVector& vec = soplex->colVector(i);
206
    for (int k = 0; k < vec.size(); ++k) {
207
      *b = std::make_pair(vec.index(k), vec.value(k));
208
      ++b;
209
    }
210
  }
211

	
212
  void SoplexLp::_setCoeff(int i, int j, Value value) {
213
    soplex->changeElement(i, j, value);
214
  }
215

	
216
  SoplexLp::Value SoplexLp::_getCoeff(int i, int j) const {
217
    return soplex->rowVector(i)[j];
218
  }
219

	
220
  void SoplexLp::_setColLowerBound(int i, Value value) {
221
    LEMON_ASSERT(value != INF, "Invalid bound");
222
    soplex->changeLower(i, value != -INF ? value : -soplex::infinity);
223
  }
224

	
225
  SoplexLp::Value SoplexLp::_getColLowerBound(int i) const {
226
    double value = soplex->lower(i);
227
    return value != -soplex::infinity ? value : -INF;
228
  }
229

	
230
  void SoplexLp::_setColUpperBound(int i, Value value) {
231
    LEMON_ASSERT(value != -INF, "Invalid bound");
232
    soplex->changeUpper(i, value != INF ? value : soplex::infinity);
233
  }
234

	
235
  SoplexLp::Value SoplexLp::_getColUpperBound(int i) const {
236
    double value = soplex->upper(i);
237
    return value != soplex::infinity ? value : INF;
238
  }
239

	
240
  void SoplexLp::_setRowLowerBound(int i, Value lb) {
241
    LEMON_ASSERT(lb != INF, "Invalid bound");
242
    soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, soplex->rhs(i));
243
  }
244

	
245
  SoplexLp::Value SoplexLp::_getRowLowerBound(int i) const {
246
    double res = soplex->lhs(i);
247
    return res == -soplex::infinity ? -INF : res;
248
  }
249

	
250
  void SoplexLp::_setRowUpperBound(int i, Value ub) {
251
    LEMON_ASSERT(ub != -INF, "Invalid bound");
252
    soplex->changeRange(i, soplex->lhs(i), ub != INF ? ub : soplex::infinity);
253
  }
254

	
255
  SoplexLp::Value SoplexLp::_getRowUpperBound(int i) const {
256
    double res = soplex->rhs(i);
257
    return res == soplex::infinity ? INF : res;
258
  }
259

	
260
  void SoplexLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
261
    for (int j = 0; j < soplex->nCols(); ++j) {
262
      soplex->changeObj(j, 0.0);
263
    }
264
    for (ExprIterator it = b; it != e; ++it) {
265
      soplex->changeObj(it->first, it->second);
266
    }
267
  }
268

	
269
  void SoplexLp::_getObjCoeffs(InsertIterator b) const {
270
    for (int j = 0; j < soplex->nCols(); ++j) {
271
      Value coef = soplex->obj(j);
272
      if (coef != 0.0) {
273
        *b = std::make_pair(j, coef);
274
        ++b;
275
      }
276
    }
277
  }
278

	
279
  void SoplexLp::_setObjCoeff(int i, Value obj_coef) {
280
    soplex->changeObj(i, obj_coef);
281
  }
282

	
283
  SoplexLp::Value SoplexLp::_getObjCoeff(int i) const {
284
    return soplex->obj(i);
285
  }
286

	
287
  SoplexLp::SolveExitStatus SoplexLp::_solve() {
288

	
289
    _clear_temporals();
290
    
291
    _applyMessageLevel();
292

	
293
    soplex::SPxSolver::Status status = soplex->solve();
294

	
295
    switch (status) {
296
    case soplex::SPxSolver::OPTIMAL:
297
    case soplex::SPxSolver::INFEASIBLE:
298
    case soplex::SPxSolver::UNBOUNDED:
299
      return SOLVED;
300
    default:
301
      return UNSOLVED;
302
    }
303
  }
304

	
305
  SoplexLp::Value SoplexLp::_getPrimal(int i) const {
306
    if (_primal_values.empty()) {
307
      _primal_values.resize(soplex->nCols());
308
      soplex::Vector pv(_primal_values.size(), &_primal_values.front());
309
      soplex->getPrimal(pv);
310
    }
311
    return _primal_values[i];
312
  }
313

	
314
  SoplexLp::Value SoplexLp::_getDual(int i) const {
315
    if (_dual_values.empty()) {
316
      _dual_values.resize(soplex->nRows());
317
      soplex::Vector dv(_dual_values.size(), &_dual_values.front());
318
      soplex->getDual(dv);
319
    }
320
    return _dual_values[i];
321
  }
322

	
323
  SoplexLp::Value SoplexLp::_getPrimalValue() const {
324
    return soplex->objValue();
325
  }
326

	
327
  SoplexLp::VarStatus SoplexLp::_getColStatus(int i) const {
328
    switch (soplex->getBasisColStatus(i)) {
329
    case soplex::SPxSolver::BASIC:
330
      return BASIC;
331
    case soplex::SPxSolver::ON_UPPER:
332
      return UPPER;
333
    case soplex::SPxSolver::ON_LOWER:
334
      return LOWER;
335
    case soplex::SPxSolver::FIXED:
336
      return FIXED;
337
    case soplex::SPxSolver::ZERO:
338
      return FREE;
339
    default:
340
      LEMON_ASSERT(false, "Wrong column status");
341
      return VarStatus();
342
    }
343
  }
344

	
345
  SoplexLp::VarStatus SoplexLp::_getRowStatus(int i) const {
346
    switch (soplex->getBasisRowStatus(i)) {
347
    case soplex::SPxSolver::BASIC:
348
      return BASIC;
349
    case soplex::SPxSolver::ON_UPPER:
350
      return UPPER;
351
    case soplex::SPxSolver::ON_LOWER:
352
      return LOWER;
353
    case soplex::SPxSolver::FIXED:
354
      return FIXED;
355
    case soplex::SPxSolver::ZERO:
356
      return FREE;
357
    default:
358
      LEMON_ASSERT(false, "Wrong row status");
359
      return VarStatus();
360
    }
361
  }
362

	
363
  SoplexLp::Value SoplexLp::_getPrimalRay(int i) const {
364
    if (_primal_ray.empty()) {
365
      _primal_ray.resize(soplex->nCols());
366
      soplex::Vector pv(_primal_ray.size(), &_primal_ray.front());
367
      soplex->getDualfarkas(pv);
368
    }
369
    return _primal_ray[i];
370
  }
371

	
372
  SoplexLp::Value SoplexLp::_getDualRay(int i) const {
373
    if (_dual_ray.empty()) {
374
      _dual_ray.resize(soplex->nRows());
375
      soplex::Vector dv(_dual_ray.size(), &_dual_ray.front());
376
      soplex->getDualfarkas(dv);
377
    }
378
    return _dual_ray[i];
379
  }
380

	
381
  SoplexLp::ProblemType SoplexLp::_getPrimalType() 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
  SoplexLp::ProblemType SoplexLp::_getDualType() const {
395
    switch (soplex->status()) {
396
    case soplex::SPxSolver::OPTIMAL:
397
      return OPTIMAL;
398
    case soplex::SPxSolver::UNBOUNDED:
399
      return UNBOUNDED;
400
    case soplex::SPxSolver::INFEASIBLE:
401
      return INFEASIBLE;
402
    default:
403
      return UNDEFINED;
404
    }
405
  }
406

	
407
  void SoplexLp::_setSense(Sense sense) {
408
    switch (sense) {
409
    case MIN:
410
      soplex->changeSense(soplex::SPxSolver::MINIMIZE);
411
      break;
412
    case MAX:
413
      soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
414
    }
415
  }
416

	
417
  SoplexLp::Sense SoplexLp::_getSense() const {
418
    switch (soplex->spxSense()) {
419
    case soplex::SPxSolver::MAXIMIZE:
420
      return MAX;
421
    case soplex::SPxSolver::MINIMIZE:
422
      return MIN;
423
    default:
424
      LEMON_ASSERT(false, "Wrong sense.");
425
      return SoplexLp::Sense();
426
    }
427
  }
428

	
429
  void SoplexLp::_clear() {
430
    soplex->clear();
431
    _col_names.clear();
432
    _col_names_ref.clear();
433
    _row_names.clear();
434
    _row_names_ref.clear();
435
    cols.clear();
436
    rows.clear();
437
    _clear_temporals();
438
  }
439

	
440
  void SoplexLp::_messageLevel(MessageLevel level) {
441
    switch (level) {
442
    case MESSAGE_NOTHING:
443
      _message_level = -1;
444
      break;
445
    case MESSAGE_ERROR:
446
      _message_level = soplex::SPxOut::ERROR;
447
      break;
448
    case MESSAGE_WARNING:
449
      _message_level = soplex::SPxOut::WARNING;
450
      break;
451
    case MESSAGE_NORMAL:
452
      _message_level = soplex::SPxOut::INFO2;
453
      break;
454
    case MESSAGE_VERBOSE:
455
      _message_level = soplex::SPxOut::DEBUG;
456
      break;
457
    }
458
  }
459

	
460
  void SoplexLp::_applyMessageLevel() {
461
    soplex::Param::setVerbose(_message_level);
462
  }
463

	
464
} //namespace lemon
465

	
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
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
88

	
89
    virtual void _eraseCol(int i);
90
    virtual void _eraseRow(int i);
91

	
92
    virtual void _eraseColId(int i);
93
    virtual void _eraseRowId(int i);
94

	
95
    virtual void _getColName(int col, std::string& name) const;
96
    virtual void _setColName(int col, const std::string& name);
97
    virtual int _colByName(const std::string& name) const;
98

	
99
    virtual void _getRowName(int row, std::string& name) const;
100
    virtual void _setRowName(int row, const std::string& name);
101
    virtual int _rowByName(const std::string& name) const;
102

	
103
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
104
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
105

	
106
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
107
    virtual void _getColCoeffs(int i, InsertIterator b) const;
108

	
109
    virtual void _setCoeff(int row, int col, Value value);
110
    virtual Value _getCoeff(int row, int col) const;
111

	
112
    virtual void _setColLowerBound(int i, Value value);
113
    virtual Value _getColLowerBound(int i) const;
114
    virtual void _setColUpperBound(int i, Value value);
115
    virtual Value _getColUpperBound(int i) const;
116

	
117
    virtual void _setRowLowerBound(int i, Value value);
118
    virtual Value _getRowLowerBound(int i) const;
119
    virtual void _setRowUpperBound(int i, Value value);
120
    virtual Value _getRowUpperBound(int i) const;
121

	
122
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
123
    virtual void _getObjCoeffs(InsertIterator b) const;
124

	
125
    virtual void _setObjCoeff(int i, Value obj_coef);
126
    virtual Value _getObjCoeff(int i) const;
127

	
128
    virtual void _setSense(Sense sense);
129
    virtual Sense _getSense() const;
130

	
131
    virtual SolveExitStatus _solve();
132
    virtual Value _getPrimal(int i) const;
133
    virtual Value _getDual(int i) const;
134

	
135
    virtual Value _getPrimalValue() const;
136

	
137
    virtual Value _getPrimalRay(int i) const;
138
    virtual Value _getDualRay(int i) const;
139

	
140
    virtual VarStatus _getColStatus(int i) const;
141
    virtual VarStatus _getRowStatus(int i) const;
142

	
143
    virtual ProblemType _getPrimalType() const;
144
    virtual ProblemType _getDualType() const;
145

	
146
    virtual void _clear();
147

	
148
    void _messageLevel(MessageLevel m);
149
    void _applyMessageLevel();
150

	
151
    int _message_level;
152

	
153
  };
154

	
155
} //END OF NAMESPACE LEMON
156

	
157
#endif //LEMON_SOPLEX_H
158

	
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_STATIC_GRAPH_H
20
#define LEMON_STATIC_GRAPH_H
21

	
22
///\ingroup graphs
23
///\file
24
///\brief StaticDigraph class.
25

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

	
29
namespace lemon {
30

	
31
  class StaticDigraphBase {
32
  public:
33

	
34
    StaticDigraphBase() 
35
      : built(false), node_num(0), arc_num(0), 
36
        node_first_out(NULL), node_first_in(NULL),
37
        arc_source(NULL), arc_target(NULL), 
38
        arc_next_in(NULL), arc_next_out(NULL) {}
39
    
40
    ~StaticDigraphBase() {
41
      if (built) {
42
        delete[] node_first_out;
43
        delete[] node_first_in;
44
        delete[] arc_source;
45
        delete[] arc_target;
46
        delete[] arc_next_out;
47
        delete[] arc_next_in;
48
      }
49
    }
50

	
51
    class Node {
52
      friend class StaticDigraphBase;
53
    protected:
54
      int id;
55
      Node(int _id) : id(_id) {}
56
    public:
57
      Node() {}
58
      Node (Invalid) : id(-1) {}
59
      bool operator==(const Node& node) const { return id == node.id; }
60
      bool operator!=(const Node& node) const { return id != node.id; }
61
      bool operator<(const Node& node) const { return id < node.id; }
62
    };
63

	
64
    class Arc {
65
      friend class StaticDigraphBase;      
66
    protected:
67
      int id;
68
      Arc(int _id) : id(_id) {}
69
    public:
70
      Arc() { }
71
      Arc (Invalid) : id(-1) {}
72
      bool operator==(const Arc& arc) const { return id == arc.id; }
73
      bool operator!=(const Arc& arc) const { return id != arc.id; }
74
      bool operator<(const Arc& arc) const { return id < arc.id; }
75
    };
76

	
77
    Node source(const Arc& e) const { return Node(arc_source[e.id]); }
78
    Node target(const Arc& e) const { return Node(arc_target[e.id]); }
79

	
80
    void first(Node& n) const { n.id = node_num - 1; }
81
    static void next(Node& n) { --n.id; }
82

	
83
    void first(Arc& e) const { e.id = arc_num - 1; }
84
    static void next(Arc& e) { --e.id; }
85

	
86
    void firstOut(Arc& e, const Node& n) const { 
87
      e.id = node_first_out[n.id] != node_first_out[n.id + 1] ? 
88
        node_first_out[n.id] : -1;
89
    }
90
    void nextOut(Arc& e) const { e.id = arc_next_out[e.id]; }
91

	
92
    void firstIn(Arc& e, const Node& n) const { e.id = node_first_in[n.id]; }
93
    void nextIn(Arc& e) const { e.id = arc_next_in[e.id]; }
94

	
95
    static int id(const Node& n) { return n.id; }
96
    static Node nodeFromId(int id) { return Node(id); }
97
    int maxNodeId() const { return node_num - 1; }
98

	
99
    static int id(const Arc& e) { return e.id; }
100
    static Arc arcFromId(int id) { return Arc(id); }
101
    int maxArcId() const { return arc_num - 1; }
102

	
103
    typedef True NodeNumTag;
104
    typedef True ArcNumTag;
105

	
106
    int nodeNum() const { return node_num; }
107
    int arcNum() const { return arc_num; }
108

	
109
  private:
110

	
111
    template <typename Digraph, typename NodeRefMap>
112
    class ArcLess {
113
    public:
114
      typedef typename Digraph::Arc Arc;
115

	
116
      ArcLess(const Digraph &_graph, const NodeRefMap& _nodeRef) 
117
        : digraph(_graph), nodeRef(_nodeRef) {}
118
      
119
      bool operator()(const Arc& left, const Arc& right) const {
120
	return nodeRef[digraph.target(left)] < nodeRef[digraph.target(right)];
121
      }
122
    private:
123
      const Digraph& digraph;
124
      const NodeRefMap& nodeRef;
125
    };
126
    
127
  public:
128

	
129
    typedef True BuildTag;
130
    
131
    void clear() {
132
      if (built) {
133
        delete[] node_first_out;
134
        delete[] node_first_in;
135
        delete[] arc_source;
136
        delete[] arc_target;
137
        delete[] arc_next_out;
138
        delete[] arc_next_in;
139
      }
140
      built = false;
141
      node_num = 0;
142
      arc_num = 0;
143
    }
144
    
145
    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
146
    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
147
      typedef typename Digraph::Node GNode;
148
      typedef typename Digraph::Arc GArc;
149

	
150
      built = true;
151

	
152
      node_num = countNodes(digraph);
153
      arc_num = countArcs(digraph);
154

	
155
      node_first_out = new int[node_num + 1];
156
      node_first_in = new int[node_num];
157

	
158
      arc_source = new int[arc_num];
159
      arc_target = new int[arc_num];
160
      arc_next_out = new int[arc_num];
161
      arc_next_in = new int[arc_num];
162

	
163
      int node_index = 0;
164
      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
165
        nodeRef[n] = Node(node_index);
166
        node_first_in[node_index] = -1;
167
        ++node_index;
168
      }
169

	
170
      ArcLess<Digraph, NodeRefMap> arcLess(digraph, nodeRef);
171

	
172
      int arc_index = 0;
173
      for (typename Digraph::NodeIt n(digraph); n != INVALID; ++n) {
174
        int source = nodeRef[n].id;
175
        std::vector<GArc> arcs;
176
        for (typename Digraph::OutArcIt e(digraph, n); e != INVALID; ++e) {
177
          arcs.push_back(e);
178
        }
179
        if (!arcs.empty()) {
180
          node_first_out[source] = arc_index;
181
          std::sort(arcs.begin(), arcs.end(), arcLess);
182
          for (typename std::vector<GArc>::iterator it = arcs.begin();
183
               it != arcs.end(); ++it) {
184
            int target = nodeRef[digraph.target(*it)].id;
185
            arcRef[*it] = Arc(arc_index);
186
            arc_source[arc_index] = source; 
187
            arc_target[arc_index] = target;
188
            arc_next_in[arc_index] = node_first_in[target];
189
            node_first_in[target] = arc_index;
190
            arc_next_out[arc_index] = arc_index + 1;
191
            ++arc_index;
192
          }
193
          arc_next_out[arc_index - 1] = -1;
194
        } else {
195
          node_first_out[source] = arc_index;
196
        }
197
      }
198
      node_first_out[node_num] = arc_num;
199
    }
200
    
201
    template <typename ArcListIterator>
202
    void build(int n, ArcListIterator first, ArcListIterator last) {
203
      built = true;
204

	
205
      node_num = n;
206
      arc_num = std::distance(first, last);
207

	
208
      node_first_out = new int[node_num + 1];
209
      node_first_in = new int[node_num];
210

	
211
      arc_source = new int[arc_num];
212
      arc_target = new int[arc_num];
213
      arc_next_out = new int[arc_num];
214
      arc_next_in = new int[arc_num];
215
      
216
      for (int i = 0; i != node_num; ++i) {
217
        node_first_in[i] = -1;
218
      }      
219
      
220
      int arc_index = 0;
221
      for (int i = 0; i != node_num; ++i) {
222
        node_first_out[i] = arc_index;
223
        for ( ; first != last && (*first).first == i; ++first) {
224
          int j = (*first).second;
225
          LEMON_ASSERT(j >= 0 && j < node_num,
226
            "Wrong arc list for StaticDigraph::build()");
227
          arc_source[arc_index] = i;
228
          arc_target[arc_index] = j;
229
          arc_next_in[arc_index] = node_first_in[j];
230
          node_first_in[j] = arc_index;
231
          arc_next_out[arc_index] = arc_index + 1;
232
          ++arc_index;
233
        }
234
        if (arc_index > node_first_out[i])
235
          arc_next_out[arc_index - 1] = -1;
236
      }
237
      LEMON_ASSERT(first == last,
238
        "Wrong arc list for StaticDigraph::build()");
239
      node_first_out[node_num] = arc_num;
240
    }
241

	
242
  protected:
243

	
244
    void fastFirstOut(Arc& e, const Node& n) const {
245
      e.id = node_first_out[n.id];
246
    }
247

	
248
    static void fastNextOut(Arc& e) {
249
      ++e.id;
250
    }
251
    void fastLastOut(Arc& e, const Node& n) const {
252
      e.id = node_first_out[n.id + 1];
253
    }
254

	
255
  protected:
256
    bool built;
257
    int node_num;
258
    int arc_num;
259
    int *node_first_out;
260
    int *node_first_in;
261
    int *arc_source;
262
    int *arc_target;
263
    int *arc_next_in;
264
    int *arc_next_out;
265
  };
266

	
267
  typedef DigraphExtender<StaticDigraphBase> ExtendedStaticDigraphBase;
268

	
269

	
270
  /// \ingroup graphs
271
  ///
272
  /// \brief A static directed graph class.
273
  ///
274
  /// \ref StaticDigraph is a highly efficient digraph implementation,
275
  /// but it is fully static.
276
  /// It stores only two \c int values for each node and only four \c int
277
  /// values for each arc. Moreover it provides faster item iteration than
278
  /// \ref ListDigraph and \ref SmartDigraph, especially using \c OutArcIt
279
  /// iterators, since its arcs are stored in an appropriate order.
280
  /// However it only provides build() and clear() functions and does not
281
  /// support any other modification of the digraph.
282
  ///
283
  /// Since this digraph structure is completely static, its nodes and arcs
284
  /// can be indexed with integers from the ranges <tt>[0..nodeNum()-1]</tt>
285
  /// and <tt>[0..arcNum()-1]</tt>, respectively. 
286
  /// The index of an item is the same as its ID, it can be obtained
287
  /// using the corresponding \ref index() or \ref concepts::Digraph::id()
288
  /// "id()" function. A node or arc with a certain index can be obtained
289
  /// using node() or arc().
290
  ///
291
  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
292
  /// Most of its member functions and nested classes are documented
293
  /// only in the concept class.
294
  ///
295
  /// \sa concepts::Digraph
296
  class StaticDigraph : public ExtendedStaticDigraphBase {
297
  public:
298

	
299
    typedef ExtendedStaticDigraphBase Parent;
300
  
301
  public:
302
  
303
    /// \brief Constructor
304
    ///
305
    /// Default constructor.
306
    StaticDigraph() : Parent() {}
307

	
308
    /// \brief The node with the given index.
309
    ///
310
    /// This function returns the node with the given index.
311
    /// \sa index()
312
    static Node node(int ix) { return Parent::nodeFromId(ix); }
313

	
314
    /// \brief The arc with the given index.
315
    ///
316
    /// This function returns the arc with the given index.
317
    /// \sa index()
318
    static Arc arc(int ix) { return Parent::arcFromId(ix); }
319

	
320
    /// \brief The index of the given node.
321
    ///
322
    /// This function returns the index of the the given node.
323
    /// \sa node()
324
    static int index(Node node) { return Parent::id(node); }
325

	
326
    /// \brief The index of the given arc.
327
    ///
328
    /// This function returns the index of the the given arc.
329
    /// \sa arc()
330
    static int index(Arc arc) { return Parent::id(arc); }
331

	
332
    /// \brief Number of nodes.
333
    ///
334
    /// This function returns the number of nodes.
335
    int nodeNum() const { return node_num; }
336

	
337
    /// \brief Number of arcs.
338
    ///
339
    /// This function returns the number of arcs.
340
    int arcNum() const { return arc_num; }
341

	
342
    /// \brief Build the digraph copying another digraph.
343
    ///
344
    /// This function builds the digraph copying another digraph of any
345
    /// kind. It can be called more than once, but in such case, the whole
346
    /// structure and all maps will be cleared and rebuilt.
347
    ///
348
    /// This method also makes possible to copy a digraph to a StaticDigraph
349
    /// structure using \ref DigraphCopy.
350
    /// 
351
    /// \param digraph An existing digraph to be copied.
352
    /// \param nodeRef The node references will be copied into this map.
353
    /// Its key type must be \c Digraph::Node and its value type must be
354
    /// \c StaticDigraph::Node.
355
    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
356
    /// concept.
357
    /// \param arcRef The arc references will be copied into this map.
358
    /// Its key type must be \c Digraph::Arc and its value type must be
359
    /// \c StaticDigraph::Arc.
360
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
361
    ///
362
    /// \note If you do not need the arc references, then you could use
363
    /// \ref NullMap for the last parameter. However the node references
364
    /// are required by the function itself, thus they must be readable
365
    /// from the map.
366
    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
367
    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
368
      if (built) Parent::clear();
369
      Parent::build(digraph, nodeRef, arcRef);
370
    }
371
  
372
    /// \brief Build the digraph from an arc list.
373
    ///
374
    /// This function builds the digraph from the given arc list.
375
    /// It can be called more than once, but in such case, the whole
376
    /// structure and all maps will be cleared and rebuilt.
377
    ///
378
    /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
379
    /// specified by STL compatible itartors whose \c value_type must be
380
    /// <tt>std::pair<int,int></tt>.
381
    /// Each arc must be specified by a pair of integer indices
382
    /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
383
    /// non-decreasing order with respect to their first values.</i>
384
    /// If the k-th pair in the list is <tt>(i,j)</tt>, then
385
    /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
386
    ///
387
    /// \param n The number of nodes.
388
    /// \param begin An iterator pointing to the beginning of the arc list.
389
    /// \param end An iterator pointing to the end of the arc list.
390
    ///
391
    /// For example, a simple digraph can be constructed like this.
392
    /// \code
393
    ///   std::vector<std::pair<int,int> > arcs;
394
    ///   arcs.push_back(std::make_pair(0,1));
395
    ///   arcs.push_back(std::make_pair(0,2));
396
    ///   arcs.push_back(std::make_pair(1,3));
397
    ///   arcs.push_back(std::make_pair(1,2));
398
    ///   arcs.push_back(std::make_pair(3,0));
399
    ///   StaticDigraph gr;
400
    ///   gr.build(4, arcs.begin(), arcs.end());
401
    /// \endcode
402
    template <typename ArcListIterator>
403
    void build(int n, ArcListIterator begin, ArcListIterator end) {
404
      if (built) Parent::clear();
405
      StaticDigraphBase::build(n, begin, end);
406
      notifier(Node()).build();
407
      notifier(Arc()).build();
408
    }
409

	
410
    /// \brief Clear the digraph.
411
    ///
412
    /// This function erases all nodes and arcs from the digraph.
413
    void clear() {
414
      Parent::clear();
415
    }
416

	
417
  protected:
418

	
419
    using Parent::fastFirstOut;
420
    using Parent::fastNextOut;
421
    using Parent::fastLastOut;
422
    
423
  public:
424

	
425
    class OutArcIt : public Arc {
426
    public:
427

	
428
      OutArcIt() { }
429

	
430
      OutArcIt(Invalid i) : Arc(i) { }
431

	
432
      OutArcIt(const StaticDigraph& digraph, const Node& node) {
433
	digraph.fastFirstOut(*this, node);
434
	digraph.fastLastOut(last, node);
435
        if (last == *this) *this = INVALID;
436
      }
437

	
438
      OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) {
439
        if (arc != INVALID) {
440
          digraph.fastLastOut(last, digraph.source(arc));
441
        }
442
      }
443

	
444
      OutArcIt& operator++() { 
445
        StaticDigraph::fastNextOut(*this);
446
        if (last == *this) *this = INVALID;
447
        return *this; 
448
      }
449

	
450
    private:
451
      Arc last;
452
    };
453

	
454
    Node baseNode(const OutArcIt &arc) const {
455
      return Parent::source(static_cast<const Arc&>(arc));
456
    }
457

	
458
    Node runningNode(const OutArcIt &arc) const {
459
      return Parent::target(static_cast<const Arc&>(arc));
460
    }
461

	
462
    Node baseNode(const InArcIt &arc) const {
463
      return Parent::target(static_cast<const Arc&>(arc));
464
    }
465

	
466
    Node runningNode(const InArcIt &arc) const {
467
      return Parent::source(static_cast<const Arc&>(arc));
468
    }
469

	
470
  };
471

	
472
}
473

	
474
#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_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 -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
#!/usr/bin/env /usr/local/Python/bin/python2.1
2
"""
3
  BibTeX to Doxygen converter
4
  Usage: python bib2dox.py bibfile.bib > bibfile.dox
5

	
6
  This code is the modification of the BibTeX to XML converter
7
  by Vidar Bronken Gundersen et al. See the original copyright notices below. 
8

	
9
  **********************************************************************
10

	
11
  Decoder for bibliographic data, BibTeX
12
  Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
13

	
14
  v.8
15
  (c)2002-06-23 Vidar Bronken Gundersen
16
  http://bibtexml.sf.net/
17
  Reuse approved as long as this notification is kept.
18
  Licence: GPL.
19

	
20
  Contributions/thanks to:
21
  Egon Willighagen, http://sf.net/projects/jreferences/
22
  Richard Mahoney (for providing a test case)
23

	
24
  Editted by Sara Sprenkle to be more robust and handle more bibtex features.
25
  (c) 2003-01-15
26

	
27
  1.  Changed bibtex: tags to bibxml: tags.
28
  2.  Use xmlns:bibxml="http://bibtexml.sf.net/"
29
  3.  Allow spaces between @type and first {
30
  4.  "author" fields with multiple authors split by " and "
31
      are put in separate xml "bibxml:author" tags.
32
  5.  Option for Titles: words are capitalized
33
      only if first letter in title or capitalized inside braces
34
  6.  Removes braces from within field values
35
  7.  Ignores comments in bibtex file (including @comment{ or % )
36
  8.  Replaces some special latex tags, e.g., replaces ~ with '&#160;'
37
  9.  Handles bibtex @string abbreviations
38
        --> includes bibtex's default abbreviations for months
39
        --> does concatenation of abbr # " more " and " more " # abbr
40
  10. Handles @type( ... ) or @type{ ... }
41
  11. The keywords field is split on , or ; and put into separate xml
42
      "bibxml:keywords" tags
43
  12. Ignores @preamble
44

	
45
  Known Limitations
46
  1.  Does not transform Latex encoding like math mode and special
47
      latex symbols.
48
  2.  Does not parse author fields into first and last names.
49
      E.g., It does not do anything special to an author whose name is
50
      in the form LAST_NAME, FIRST_NAME
51
      In "author" tag, will show up as
52
      <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
53
  3.  Does not handle "crossref" fields other than to print
54
      <bibxml:crossref>...</bibxml:crossref>
55
  4.  Does not inform user of the input's format errors.  You just won't
56
      be able to transform the file later with XSL
57

	
58
  You will have to manually edit the XML output if you need to handle
59
  these (and unknown) limitations.
60

	
61
"""
62

	
63
import string, re
64

	
65
# set of valid name characters
66
valid_name_chars = '[\w\-:]'
67

	
68
#
69
# define global regular expression variables
70
#
71
author_rex = re.compile('\s+and\s+')
72
rembraces_rex = re.compile('[{}]')
73
capitalize_rex = re.compile('({[^}]*})')
74

	
75
# used by bibtexkeywords(data)
76
keywords_rex = re.compile('[,;]')
77

	
78
# used by concat_line(line)
79
concatsplit_rex = re.compile('\s*#\s*')
80

	
81
# split on {, }, or " in verify_out_of_braces
82
delimiter_rex = re.compile('([{}"])',re.I)
83

	
84
field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
85
data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
86

	
87
url_rex = re.compile('\\\url\{([^}]*)\}')
88

	
89
#
90
# styles for html formatting
91
#
92
divstyle = 'margin-top: -4ex; margin-left: 8em;'
93

	
94
#
95
# return the string parameter without braces
96
#
97
def transformurls(str):
98
    return url_rex.sub(r'<a href="\1">\1</a>', str)
99

	
100
#
101
# return the string parameter without braces
102
#
103
def removebraces(str):
104
    return rembraces_rex.sub('', str)
105

	
106
#
107
# latex-specific replacements
108
# (do this after braces were removed)
109
#
110
def latexreplacements(line):
111
    line = string.replace(line, '~', '&nbsp;')
112
    line = string.replace(line, '\\\'a', '&aacute;')
113
    line = string.replace(line, '\\"a', '&auml;')
114
    line = string.replace(line, '\\\'e', '&eacute;')
115
    line = string.replace(line, '\\"e', '&euml;')
116
    line = string.replace(line, '\\\'i', '&iacute;')
117
    line = string.replace(line, '\\"i', '&iuml;')
118
    line = string.replace(line, '\\\'o', '&oacute;')
119
    line = string.replace(line, '\\"o', '&ouml;')
120
    line = string.replace(line, '\\\'u', '&uacute;')
121
    line = string.replace(line, '\\"u', '&uuml;')
122
    line = string.replace(line, '\\H o', '&otilde;')
123
    line = string.replace(line, '\\H u', '&uuml;')   # &utilde; does not exist
124
    line = string.replace(line, '\\\'A', '&Aacute;')
125
    line = string.replace(line, '\\"A', '&Auml;')
126
    line = string.replace(line, '\\\'E', '&Eacute;')
127
    line = string.replace(line, '\\"E', '&Euml;')
128
    line = string.replace(line, '\\\'I', '&Iacute;')
129
    line = string.replace(line, '\\"I', '&Iuml;')
130
    line = string.replace(line, '\\\'O', '&Oacute;')
131
    line = string.replace(line, '\\"O', '&Ouml;')
132
    line = string.replace(line, '\\\'U', '&Uacute;')
133
    line = string.replace(line, '\\"U', '&Uuml;')
134
    line = string.replace(line, '\\H O', '&Otilde;')
135
    line = string.replace(line, '\\H U', '&Uuml;')   # &Utilde; does not exist
136

	
137
    return line
138

	
139
#
140
# copy characters form a string decoding html expressions (&xyz;)
141
#
142
def copychars(str, ifrom, count):
143
    result = ''
144
    i = ifrom
145
    c = 0
146
    html_spec = False
147
    while (i < len(str)) and (c < count):
148
        if str[i] == '&':
149
            html_spec = True;
150
            if i+1 < len(str):
151
                result += str[i+1]
152
            c += 1
153
            i += 2
154
        else:
155
            if not html_spec:
156
                if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
157
                   ((str[i] >= 'a') and (str[i] <= 'z')):
158
                    result += str[i]
159
                    c += 1
160
            elif str[i] == ';':
161
                html_spec = False;
162
            i += 1
163
    
164
    return result
165

	
166

	
167
# 
168
# Handle a list of authors (separated by 'and').
169
# It gives back an array of the follwing values:
170
#  - num: the number of authors,
171
#  - list: the list of the author names,
172
#  - text: the bibtex text (separated by commas and/or 'and')
173
#  - abbrev: abbreviation that can be used for indicate the
174
#    bibliography entries
175
#
176
def bibtexauthor(data):
177
    result = {}
178
    bibtex = ''
179
    result['list'] = author_rex.split(data)
180
    result['num'] = len(result['list'])
181
    for i, author in enumerate(result['list']):
182
        # general transformations
183
        author = latexreplacements(removebraces(author.strip()))
184
        # transform "Xyz, A. B." to "A. B. Xyz"
185
        pos = author.find(',')
186
        if pos != -1:
187
            author = author[pos+1:].strip() + ' ' + author[:pos].strip()
188
        result['list'][i] = author
189
        bibtex += author + '#'
190
    bibtex = bibtex[:-1]
191
    if result['num'] > 1:
192
        ix = bibtex.rfind('#')
193
        if result['num'] == 2:
194
            bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
195
        else:
196
            bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
197
    bibtex = bibtex.replace('#', ', ')
198
    result['text'] = bibtex
199
    
200
    result['abbrev'] = ''
201
    for author in result['list']:
202
        pos = author.rfind(' ') + 1
203
        count = 1
204
        if result['num'] == 1:
205
            count = 3
206
        result['abbrev'] += copychars(author, pos, count)
207

	
208
    return result
209

	
210

	
211
#
212
# data = title string
213
# @return the capitalized title (first letter is capitalized), rest are capitalized
214
# only if capitalized inside braces
215
#
216
def capitalizetitle(data):
217
    title_list = capitalize_rex.split(data)
218
    title = ''
219
    count = 0
220
    for phrase in title_list:
221
         check = string.lstrip(phrase)
222

	
223
         # keep phrase's capitalization the same
224
         if check.find('{') == 0:
225
              title += removebraces(phrase)
226
         else:
227
         # first word --> capitalize first letter (after spaces)
228
              if count == 0:
229
                  title += check.capitalize()
230
              else:
231
                  title += phrase.lower()
232
         count = count + 1
233

	
234
    return title
235

	
236

	
237
#
238
# @return the bibtex for the title
239
# @param data --> title string
240
# braces are removed from title
241
#
242
def bibtextitle(data, entrytype):
243
    if entrytype in ('book', 'inbook'):
244
        title = removebraces(data.strip())
245
    else:
246
        title = removebraces(capitalizetitle(data.strip()))
247
    bibtex = title
248
    return bibtex
249

	
250

	
251
#
252
# function to compare entry lists
253
#
254
def entry_cmp(x, y):
255
    return cmp(x[0], y[0])
256

	
257

	
258
#
259
# print the XML for the transformed "filecont_source"
260
#
261
def bibtexdecoder(filecont_source):
262
    filecont = []
263
    file = []
264
    
265
    # want @<alphanumeric chars><spaces>{<spaces><any chars>,
266
    pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
267
    endtype_rex = re.compile('}\s*$')
268
    endtag_rex = re.compile('^\s*}\s*$')
269

	
270
    bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
271
    bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
272

	
273
    quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
274
    quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
275

	
276
    for line in filecont_source:
277
        line = line[:-1]
278

	
279
        # encode character entities
280
        line = string.replace(line, '&', '&amp;')
281
        line = string.replace(line, '<', '&lt;')
282
        line = string.replace(line, '>', '&gt;')
283

	
284
        # start entry: publication type (store for later use)
285
        if pubtype_rex.match(line):
286
        # want @<alphanumeric chars><spaces>{<spaces><any chars>,
287
            entrycont = {}
288
            entry = []
289
            entrytype = pubtype_rex.sub('\g<1>',line)
290
            entrytype = string.lower(entrytype)
291
            entryid   = pubtype_rex.sub('\g<2>', line)
292

	
293
        # end entry if just a }
294
        elif endtype_rex.match(line):
295
            # generate doxygen code for the entry
296

	
297
            # enty type related formattings
298
            if entrytype in ('book', 'inbook'):
299
                entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
300
                if not entrycont.has_key('author'):
301
                    entrycont['author'] = entrycont['editor']
302
                    entrycont['author']['text'] += ', editors'
303
            elif entrytype == 'article':
304
                entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
305
            elif entrytype in ('inproceedings', 'incollection', 'conference'):
306
                entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
307
            elif entrytype == 'techreport':
308
                if not entrycont.has_key('type'):
309
                    entrycont['type'] = 'Technical report'
310
            elif entrytype == 'mastersthesis':
311
                entrycont['type'] = 'Master\'s thesis'
312
            elif entrytype == 'phdthesis':
313
                entrycont['type'] = 'PhD thesis'
314

	
315
            for eline in entrycont:
316
                if eline != '':
317
                    eline = latexreplacements(eline)
318

	
319
            if entrycont.has_key('pages') and (entrycont['pages'] != ''):
320
                entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
321

	
322
            if entrycont.has_key('author') and (entrycont['author'] != ''):
323
                entry.append(entrycont['author']['text'] + '.')
324
            if entrycont.has_key('title') and (entrycont['title'] != ''):
325
                entry.append(entrycont['title'] + '.')
326
            if entrycont.has_key('journal') and (entrycont['journal'] != ''):
327
                entry.append(entrycont['journal'] + ',')
328
            if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
329
                entry.append('In ' + entrycont['booktitle'] + ',')
330
            if entrycont.has_key('type') and (entrycont['type'] != ''):
331
                eline = entrycont['type']
332
                if entrycont.has_key('number') and (entrycont['number'] != ''):
333
                    eline += ' ' + entrycont['number']
334
                eline += ','
335
                entry.append(eline)
336
            if entrycont.has_key('institution') and (entrycont['institution'] != ''):
337
                entry.append(entrycont['institution'] + ',')
338
            if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
339
                entry.append(entrycont['publisher'] + ',')
340
            if entrycont.has_key('school') and (entrycont['school'] != ''):
341
                entry.append(entrycont['school'] + ',')
342
            if entrycont.has_key('address') and (entrycont['address'] != ''):
343
                entry.append(entrycont['address'] + ',')
344
            if entrycont.has_key('edition') and (entrycont['edition'] != ''):
345
                entry.append(entrycont['edition'] + ' edition,')
346
            if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
347
                entry.append(entrycont['howpublished'] + ',')
348
            if entrycont.has_key('volume') and (entrycont['volume'] != ''):
349
                eline = entrycont['volume'];
350
                if entrycont.has_key('number') and (entrycont['number'] != ''):
351
                    eline += '(' + entrycont['number'] + ')'
352
                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
353
                    eline += ':' + entrycont['pages']
354
                eline += ','
355
                entry.append(eline)
356
            else:
357
                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
358
                    entry.append('pages ' + entrycont['pages'] + ',')
359
            if entrycont.has_key('year') and (entrycont['year'] != ''):
360
                if entrycont.has_key('month') and (entrycont['month'] != ''):
361
                    entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
362
                else:
363
                    entry.append(entrycont['year'] + '.')
364
            if entrycont.has_key('note') and (entrycont['note'] != ''):
365
                entry.append(entrycont['note'] + '.')
366
            if entrycont.has_key('url') and (entrycont['url'] != ''):
367
                entry.append(entrycont['url'] + '.')
368

	
369
            # generate keys for sorting and for the output
370
            sortkey = ''
371
            bibkey = ''
372
            if entrycont.has_key('author'):
373
                for author in entrycont['author']['list']:
374
                    sortkey += copychars(author, author.rfind(' ')+1, len(author))
375
                bibkey = entrycont['author']['abbrev']
376
            else:
377
                bibkey = 'x'
378
            if entrycont.has_key('year'):
379
                sortkey += entrycont['year']
380
                bibkey += entrycont['year'][-2:]
381
            if entrycont.has_key('title'):
382
                sortkey += entrycont['title']
383
            if entrycont.has_key('key'):
384
                sortkey = entrycont['key'] + sortkey
385
                bibkey = entrycont['key']
386
            entry.insert(0, sortkey)
387
            entry.insert(1, bibkey)
388
            entry.insert(2, entryid)
389
           
390
            # add the entry to the file contents
391
            filecont.append(entry)
392

	
393
        else:
394
            # field, publication info
395
            field = ''
396
            data = ''
397
            
398
            # field = {data} entries
399
            if bracedata_rex.match(line):
400
                field = bracefield_rex.sub('\g<1>', line)
401
                field = string.lower(field)
402
                data =  bracedata_rex.sub('\g<2>', line)
403

	
404
            # field = "data" entries
405
            elif quotedata_rex.match(line):
406
                field = quotefield_rex.sub('\g<1>', line)
407
                field = string.lower(field)
408
                data =  quotedata_rex.sub('\g<2>', line)
409

	
410
            # field = data entries
411
            elif data_rex.match(line):
412
                field = field_rex.sub('\g<1>', line)
413
                field = string.lower(field)
414
                data =  data_rex.sub('\g<2>', line)
415

	
416
            if field == 'url':
417
                data = '\\url{' + data.strip() + '}'
418
            
419
            if field in ('author', 'editor'):
420
                entrycont[field] = bibtexauthor(data)
421
                line = ''
422
            elif field == 'title':
423
                line = bibtextitle(data, entrytype)
424
            elif field != '':
425
                line = removebraces(transformurls(data.strip()))
426

	
427
            if line != '':
428
                line = latexreplacements(line)
429
                entrycont[field] = line
430

	
431

	
432
    # sort entries
433
    filecont.sort(entry_cmp)
434
    
435
    # count the bibtex keys
436
    keytable = {}
437
    counttable = {}
438
    for entry in filecont:
439
        bibkey = entry[1]
440
        if not keytable.has_key(bibkey):
441
            keytable[bibkey] = 1
442
        else:
443
            keytable[bibkey] += 1
444

	
445
    for bibkey in keytable.keys():
446
        counttable[bibkey] = 0
447
    
448
    # generate output
449
    for entry in filecont:
450
        # generate output key form the bibtex key
451
        bibkey = entry[1]
452
        entryid = entry[2]
453
        if keytable[bibkey] == 1:
454
            outkey = bibkey
455
        else:
456
            outkey = bibkey + chr(97 + counttable[bibkey])
457
        counttable[bibkey] += 1
458
        
459
        # append the entry code to the output
460
        file.append('\\section ' + entryid + ' [' + outkey + ']')
461
        file.append('<div style="' + divstyle + '">')
462
        for line in entry[3:]:
463
            file.append(line)
464
        file.append('</div>')
465
        file.append('')
466

	
467
    return file
468

	
469

	
470
#
471
# return 1 iff abbr is in line but not inside braces or quotes
472
# assumes that abbr appears only once on the line (out of braces and quotes)
473
#
474
def verify_out_of_braces(line, abbr):
475

	
476
    phrase_split = delimiter_rex.split(line)
477

	
478
    abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
479

	
480
    open_brace = 0
481
    open_quote = 0
482

	
483
    for phrase in phrase_split:
484
        if phrase == "{":
485
            open_brace = open_brace + 1
486
        elif phrase == "}":
487
            open_brace = open_brace - 1
488
        elif phrase == '"':
489
            if open_quote == 1:
490
                open_quote = 0
491
            else:
492
                open_quote = 1
493
        elif abbr_rex.search(phrase):
494
            if open_brace == 0 and open_quote == 0:
495
                return 1
496

	
497
    return 0
498

	
499

	
500
#
501
# a line in the form phrase1 # phrase2 # ... # phrasen
502
# is returned as phrase1 phrase2 ... phrasen
503
# with the correct punctuation
504
# Bug: Doesn't always work with multiple abbreviations plugged in
505
#
506
def concat_line(line):
507
    # only look at part after equals
508
    field = field_rex.sub('\g<1>',line)
509
    rest = field_rex.sub('\g<2>',line)
510

	
511
    concat_line = field + ' ='
512

	
513
    pound_split = concatsplit_rex.split(rest)
514

	
515
    phrase_count = 0
516
    length = len(pound_split)
517

	
518
    for phrase in pound_split:
519
        phrase = phrase.strip()
520
        if phrase_count != 0:
521
            if phrase.startswith('"') or phrase.startswith('{'):
522
                phrase = phrase[1:]
523
        elif phrase.startswith('"'):
524
            phrase = phrase.replace('"','{',1)
525

	
526
        if phrase_count != length-1:
527
            if phrase.endswith('"') or phrase.endswith('}'):
528
                phrase = phrase[:-1]
529
        else:
530
            if phrase.endswith('"'):
531
                phrase = phrase[:-1]
532
                phrase = phrase + "}"
533
            elif phrase.endswith('",'):
534
                phrase = phrase[:-2]
535
                phrase = phrase + "},"
536

	
537
        # if phrase did have \#, add the \# back
538
        if phrase.endswith('\\'):
539
            phrase = phrase + "#"
540
        concat_line = concat_line + ' ' + phrase
541

	
542
        phrase_count = phrase_count + 1
543

	
544
    return concat_line
545

	
546

	
547
#
548
# substitute abbreviations into filecont
549
# @param filecont_source - string of data from file
550
#
551
def bibtex_replace_abbreviations(filecont_source):
552
    filecont = filecont_source.splitlines()
553

	
554
    #  These are defined in bibtex, so we'll define them too
555
    abbr_list = ['jan','feb','mar','apr','may','jun',
556
                 'jul','aug','sep','oct','nov','dec']
557
    value_list = ['January','February','March','April',
558
                  'May','June','July','August','September',
559
                  'October','November','December']
560

	
561
    abbr_rex = []
562
    total_abbr_count = 0
563

	
564
    front = '\\b'
565
    back = '(,?)\\b'
566

	
567
    for x in abbr_list:
568
        abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
569
        total_abbr_count = total_abbr_count + 1
570

	
571

	
572
    abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
573
                             re.I)
574

	
575
    comment_rex = re.compile('@comment\s*{',re.I)
576
    preamble_rex = re.compile('@preamble\s*{',re.I)
577

	
578
    waiting_for_end_string = 0
579
    i = 0
580
    filecont2 = ''
581

	
582
    for line in filecont:
583
        if line == ' ' or line == '':
584
            continue
585

	
586
        if waiting_for_end_string:
587
            if re.search('}',line):
588
                waiting_for_end_string = 0
589
                continue
590

	
591
        if abbrdef_rex.search(line):
592
            abbr = abbrdef_rex.sub('\g<1>', line)
593

	
594
            if abbr_list.count(abbr) == 0:
595
                val = abbrdef_rex.sub('\g<2>', line)
596
                abbr_list.append(abbr)
597
                value_list.append(string.strip(val))
598
                abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
599
                total_abbr_count = total_abbr_count + 1
600
            waiting_for_end_string = 1
601
            continue
602

	
603
        if comment_rex.search(line):
604
            waiting_for_end_string = 1
605
            continue
606

	
607
        if preamble_rex.search(line):
608
            waiting_for_end_string = 1
609
            continue
610

	
611

	
612
        # replace subsequent abbreviations with the value
613
        abbr_count = 0
614

	
615
        for x in abbr_list:
616

	
617
            if abbr_rex[abbr_count].search(line):
618
                if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
619
                    line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
620
                # Check for # concatenations
621
                if concatsplit_rex.search(line):
622
                    line = concat_line(line)
623
            abbr_count = abbr_count + 1
624

	
625

	
626
        filecont2 = filecont2 + line + '\n'
627
        i = i+1
628

	
629

	
630
    # Do one final pass over file
631

	
632
    # make sure that didn't end up with {" or }" after the substitution
633
    filecont2 = filecont2.replace('{"','{{')
634
    filecont2 = filecont2.replace('"}','}}')
635

	
636
    afterquotevalue_rex = re.compile('"\s*,\s*')
637
    afterbrace_rex = re.compile('"\s*}')
638
    afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
639

	
640
    # add new lines to data that changed because of abbreviation substitutions
641
    filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
642
    filecont2 = afterbrace_rex.sub('"\n}', filecont2)
643
    filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
644

	
645
    return filecont2
646

	
647
#
648
# convert @type( ... ) to @type{ ... }
649
#
650
def no_outer_parens(filecont):
651

	
652
    # do checking for open parens
653
    # will convert to braces
654
    paren_split = re.split('([(){}])',filecont)
655

	
656
    open_paren_count = 0
657
    open_type = 0
658
    look_next = 0
659

	
660
    # rebuild filecont
661
    filecont = ''
662

	
663
    at_rex = re.compile('@\w*')
664

	
665
    for phrase in paren_split:
666
        if look_next == 1:
667
            if phrase == '(':
668
                phrase = '{'
669
                open_paren_count = open_paren_count + 1
670
            else:
671
                open_type = 0
672
            look_next = 0
673

	
674
        if phrase == '(':
675
            open_paren_count = open_paren_count + 1
676

	
677
        elif phrase == ')':
678
            open_paren_count = open_paren_count - 1
679
            if open_type == 1 and open_paren_count == 0:
680
                phrase = '}'
681
                open_type = 0
682

	
683
        elif at_rex.search( phrase ):
684
            open_type = 1
685
            look_next = 1
686

	
687
        filecont = filecont + phrase
688

	
689
    return filecont
690

	
691

	
692
#
693
# make all whitespace into just one space
694
# format the bibtex file into a usable form.
695
#
696
def bibtexwasher(filecont_source):
697

	
698
    space_rex = re.compile('\s+')
699
    comment_rex = re.compile('\s*%')
700

	
701
    filecont = []
702

	
703
    # remove trailing and excessive whitespace
704
    # ignore comments
705
    for line in filecont_source:
706
        line = string.strip(line)
707
        line = space_rex.sub(' ', line)
708
        # ignore comments
709
        if not comment_rex.match(line) and line != '':
710
            filecont.append(' '+ line)
711

	
712
    filecont = string.join(filecont, '')
713

	
714
    # the file is in one long string
715

	
716
    filecont = no_outer_parens(filecont)
717

	
718
    #
719
    # split lines according to preferred syntax scheme
720
    #
721
    filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
722

	
723
    # add new lines after commas that are after values
724
    filecont = re.sub('"\s*,', '",\n', filecont)
725
    filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
726
    filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
727
                          '\n\n\g<1>\g<2>,\n', filecont)
728

	
729
    # add new lines after }
730
    filecont = re.sub('"\s*}','"\n}\n', filecont)
731
    filecont = re.sub('}\s*,','},\n', filecont)
732

	
733

	
734
    filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
735

	
736
    # character encoding, reserved latex characters
737
    filecont = re.sub('{\\\&}', '&', filecont)
738
    filecont = re.sub('\\\&', '&', filecont)
739

	
740
    # do checking for open braces to get format correct
741
    open_brace_count = 0
742
    brace_split = re.split('([{}])',filecont)
743

	
744
    # rebuild filecont
745
    filecont = ''
746

	
747
    for phrase in brace_split:
748
        if phrase == '{':
749
            open_brace_count = open_brace_count + 1
750
        elif phrase == '}':
751
            open_brace_count = open_brace_count - 1
752
            if open_brace_count == 0:
753
                filecont = filecont + '\n'
754

	
755
        filecont = filecont + phrase
756

	
757
    filecont2 = bibtex_replace_abbreviations(filecont)
758

	
759
    # gather
760
    filecont = filecont2.splitlines()
761
    i=0
762
    j=0         # count the number of blank lines
763
    for line in filecont:
764
        # ignore blank lines
765
        if line == '' or line == ' ':
766
            j = j+1
767
            continue
768
        filecont[i] = line + '\n'
769
        i = i+1
770

	
771
    # get rid of the extra stuff at the end of the array
772
    # (The extra stuff are duplicates that are in the array because
773
    # blank lines were removed.)
774
    length = len( filecont)
775
    filecont[length-j:length] = []
776

	
777
    return filecont
778

	
779

	
780
def filehandler(filepath):
781
    try:
782
        fd = open(filepath, 'r')
783
        filecont_source = fd.readlines()
784
        fd.close()
785
    except:
786
        print 'Could not open file:', filepath
787
    washeddata = bibtexwasher(filecont_source)
788
    outdata = bibtexdecoder(washeddata)
789
    print '/**'
790
    print '\page references References'
791
    print
792
    for line in outdata:
793
        print line
794
    print '*/'
795

	
796

	
797
# main program
798

	
799
def main():
800
    import sys
801
    if sys.argv[1:]:
802
        filepath = sys.argv[1]
803
    else:
804
        print "No input file"
805
        sys.exit()
806
    filehandler(filepath)
807

	
808
if __name__ == "__main__": main()
809

	
810

	
811
# end python script
Ignore white space 6 line context
1
#!/bin/bash
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
if [ ! -f ~/.lemon-bootstrap ]; then
19
    echo 'Create ~/.lemon-bootstrap'.
20
    cat >~/.lemon-bootstrap <<EOF
21
#
22
# Default settings for bootstraping the LEMON source code repository
23
#
24
EOF
25
fi
26

	
27
source ~/.lemon-bootstrap
28
if [ -f ../../../.lemon-bootstrap ]; then source ../../../.lemon-bootstrap; fi
29
if [ -f ../../.lemon-bootstrap ]; then source ../../.lemon-bootstrap; fi
30
if [ -f ../.lemon-bootstrap ]; then source ../.lemon-bootstrap; fi
31
if [ -f ./.lemon-bootstrap ]; then source ./.lemon-bootstrap; fi
32

	
33

	
34
function augment_config() { 
35
    if [ "x${!1}" == "x" ]; then
36
        eval $1=$2
37
        echo Add "'$1'" to '~/.lemon-bootstrap'.
38
        echo >>~/.lemon-bootstrap
39
        echo $3 >>~/.lemon-bootstrap
40
        echo $1=$2 >>~/.lemon-bootstrap
41
    fi
42
}
43

	
44
augment_config LEMON_INSTALL_PREFIX /usr/local \
45
    "# LEMON installation prefix"
46

	
47
augment_config COIN_OR_PREFIX /usr/local/coin-or \
48
    "# COIN-OR installation root prefix (used for CLP/CBC)"
49

	
50
augment_config SOPLEX_PREFIX /usr/local/soplex \
51
    "# Soplex build prefix"
52

	
53

	
54
function ask() {
55
echo -n "$1 [$2]? "
56
read _an
57
if [ "x$_an" == "x" ]; then
58
    ret="$2"
59
else
60
    ret=$_an
61
fi
62
}
63

	
64
function yesorno() {
65
    ret='rossz'
66
    while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do
67
        ask "$1" "$2"
68
    done
69
    if [ "$ret" != "y" -a "$ret" != "yes" ]; then
70
        return 1
71
    else
72
        return 0
73
    fi
74
}
75

	
76
if yesorno "External build" "n"
77
then
78
    CONFIGURE_PATH=".."
79
else
80
    CONFIGURE_PATH="."
81
    if yesorno "Autoreconf" "y"
82
    then
83
        AUTORE=yes
84
    else
85
        AUTORE=no
86
    fi
87
fi
88

	
89
if yesorno "Optimize" "n" 
90
then
91
    opt_flags=' -O2'
92
else
93
    opt_flags=''
94
fi
95

	
96
if yesorno "Stop on warning" "y" 
97
then
98
    werror_flags=' -Werror'
99
else
100
    werror_flags=''
101
fi
102

	
103
cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags"
104

	
105
if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
106
    if yesorno "Use COIN-OR (CBC/CLP)" "n"
107
    then
108
        coin_flag="--with-coin=$COIN_OR_PREFIX"
109
    else
110
        coin_flag=""
111
    fi
112
else
113
    coin_flag=""        
114
fi
115

	
116
if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then
117
    if yesorno "Use Soplex" "n"
118
    then
119
        soplex_flag="--with-soplex=$SOPLEX_PREFIX"
120
    else
121
        soplex_flag=""
122
    fi
123
else
124
    soplex_flag=""
125
fi
126

	
127
if [ "x$AUTORE" == "xyes" ]; then
128
    autoreconf -vif;
129
fi
130
${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \
131
"$cxx_flags" \
132
$coin_flag \
133
$soplex_flag \
134
$*
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<Orienter< const GridGraph, GridGraph::EdgeMap<bool> > >
1381
    SplitGridGraph;
1382
  typedef Undirector<const SplitGridGraph> USplitGridGraph;
1383
  checkConcept<concepts::Digraph, SplitGridGraph>();
1384
  checkConcept<concepts::Graph, USplitGridGraph>();
1385

	
1386
  SplitGridGraph adaptor = splitNodes(orienter(graph, dir_map));
1387
  USplitGridGraph uadaptor = undirector(adaptor);
1388

	
1389
  // Check adaptor
1390
  checkGraphNodeList(adaptor, 8);
1391
  checkGraphArcList(adaptor, 8);
1392
  checkGraphConArcList(adaptor, 8);
1393

	
1394
  checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
1395
  checkGraphOutArcList(adaptor, adaptor.outNode(n1), 1);
1396
  checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
1397
  checkGraphOutArcList(adaptor, adaptor.outNode(n2), 0);
1398
  checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
1399
  checkGraphOutArcList(adaptor, adaptor.outNode(n3), 1);
1400
  checkGraphOutArcList(adaptor, adaptor.inNode(n4), 1);
1401
  checkGraphOutArcList(adaptor, adaptor.outNode(n4), 2);
1402

	
1403
  checkGraphInArcList(adaptor, adaptor.inNode(n1), 1);
1404
  checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
1405
  checkGraphInArcList(adaptor, adaptor.inNode(n2), 2);
1406
  checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
1407
  checkGraphInArcList(adaptor, adaptor.inNode(n3), 1);
1408
  checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
1409
  checkGraphInArcList(adaptor, adaptor.inNode(n4), 0);
1410
  checkGraphInArcList(adaptor, adaptor.outNode(n4), 1);
1411

	
1412
  checkNodeIds(adaptor);
1413
  checkArcIds(adaptor);
1414

	
1415
  checkGraphNodeMap(adaptor);
1416
  checkGraphArcMap(adaptor);
1417

	
1418
  // Check uadaptor
1419
  checkGraphNodeList(uadaptor, 8);
1420
  checkGraphEdgeList(uadaptor, 8);
1421
  checkGraphArcList(uadaptor, 16);
1422
  checkGraphConEdgeList(uadaptor, 8);
1423
  checkGraphConArcList(uadaptor, 16);
1424

	
1425
  checkNodeIds(uadaptor);
1426
  checkEdgeIds(uadaptor);
1427
  checkArcIds(uadaptor);
1428

	
1429
  checkGraphNodeMap(uadaptor);
1430
  checkGraphEdgeMap(uadaptor);
1431
  checkGraphArcMap(uadaptor);
1432

	
1433
  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n1), 2);
1434
  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n1), 2);
1435
  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n2), 3);
1436
  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n2), 1);
1437
  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n3), 2);
1438
  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n3), 2);
1439
  checkGraphIncEdgeArcLists(uadaptor, adaptor.inNode(n4), 1);
1440
  checkGraphIncEdgeArcLists(uadaptor, adaptor.outNode(n4), 3);
1441
}
1442

	
1443
int main(int, const char **) {
1444
  // Check the digraph adaptors (using ListDigraph)
1445
  checkReverseDigraph();
1446
  checkSubDigraph();
1447
  checkFilterNodes1();
1448
  checkFilterArcs();
1449
  checkUndirector();
1450
  checkResidualDigraph();
1451
  checkSplitNodes();
1452

	
1453
  // Check the graph adaptors (using ListGraph)
1454
  checkSubGraph();
1455
  checkFilterNodes2();
1456
  checkFilterEdges();
1457
  checkOrienter();
1458

	
1459
  // Combine adaptors (using GridGraph)
1460
  checkCombiningAdaptors();
1461

	
1462
  return 0;
1463
}
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/concepts/digraph.h>
20
#include <lemon/smart_graph.h>
21
#include <lemon/list_graph.h>
22
#include <lemon/lgf_reader.h>
23
#include <lemon/bellman_ford.h>
24
#include <lemon/path.h>
25

	
26
#include "graph_test.h"
27
#include "test_tools.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
  "@arcs\n"
40
  "    length\n"
41
  "0 1 3\n"
42
  "1 2 -3\n"
43
  "1 2 -5\n"
44
  "1 3 -2\n"
45
  "0 2 -1\n"
46
  "1 2 -4\n"
47
  "0 3 2\n"
48
  "4 2 -5\n"
49
  "2 3 1\n"
50
  "@attributes\n"
51
  "source 0\n"
52
  "target 3\n";
53

	
54

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
164

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

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

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

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

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

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

	
202
  for(ArcIt e(gr); e!=INVALID; ++e) {
203
    Node u=gr.source(e);
204
    Node v=gr.target(e);
205
    check(!bf.reached(u) || (bf.dist(v) - bf.dist(u) <= length[e]),
206
          "Wrong output. dist(target)-dist(source)-arc_length=" <<
207
          bf.dist(v) - bf.dist(u) - length[e]);
208
  }
209

	
210
  for(NodeIt v(gr); v!=INVALID; ++v) {
211
    if (bf.reached(v)) {
212
      check(v==s || bf.predArc(v)!=INVALID, "Wrong tree.");
213
      if (bf.predArc(v)!=INVALID ) {
214
        Arc e=bf.predArc(v);
215
        Node u=gr.source(e);
216
        check(u==bf.predNode(v),"Wrong tree.");
217
        check(bf.dist(v) - bf.dist(u) == length[e],
218
              "Wrong distance! Difference: " <<
219
              bf.dist(v) - bf.dist(u) - length[e]);
220
      }
221
    }
222
  }
223
}
224

	
225
void checkBellmanFordNegativeCycle() {
226
  DIGRAPH_TYPEDEFS(SmartDigraph);
227

	
228
  SmartDigraph gr;
229
  IntArcMap length(gr);
230
  
231
  Node n1 = gr.addNode();
232
  Node n2 = gr.addNode();
233
  Node n3 = gr.addNode();
234
  Node n4 = gr.addNode();
235
  
236
  Arc a1 = gr.addArc(n1, n2);
237
  Arc a2 = gr.addArc(n2, n2);
238
  
239
  length[a1] = 2;
240
  length[a2] = -1;
241
  
242
  {
243
    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
244
    bf.run(n1);
245
    StaticPath<SmartDigraph> p = bf.negativeCycle();
246
    check(p.length() == 1 && p.front() == p.back() && p.front() == a2,
247
          "Wrong negative cycle.");
248
  }
249
 
250
  length[a2] = 0;
251
  
252
  {
253
    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
254
    bf.run(n1);
255
    check(bf.negativeCycle().empty(),
256
          "Negative cycle should not be found.");
257
  }
258
  
259
  length[gr.addArc(n1, n3)] = 5;
260
  length[gr.addArc(n4, n3)] = 1;
261
  length[gr.addArc(n2, n4)] = 2;
262
  length[gr.addArc(n3, n2)] = -4;
263
  
264
  {
265
    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
266
    bf.init();
267
    bf.addSource(n1);
268
    for (int i = 0; i < 4; ++i) {
269
      check(bf.negativeCycle().empty(),
270
            "Negative cycle should not be found.");
271
      bf.processNextRound();
272
    }
273
    StaticPath<SmartDigraph> p = bf.negativeCycle();
274
    check(p.length() == 3, "Wrong negative cycle.");
275
    check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1,
276
          "Wrong negative cycle.");
277
  }
278
}
279

	
280
int main() {
281
  checkBellmanFord<ListDigraph, int>();
282
  checkBellmanFord<SmartDigraph, double>();
283
  checkBellmanFordNegativeCycle();
284
  return 0;
285
}
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
  const CirculationType::Elevator& elev = const_circ_test.elevator();
92
  circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
93
  CirculationType::Tolerance tol = const_circ_test.tolerance();
94
  circ_test.tolerance(tol);
95

	
96
  circ_test.init();
97
  circ_test.greedyInit();
98
  circ_test.start();
99
  circ_test.run();
100

	
101
  v = const_circ_test.flow(a);
102
  const FlowMap& fm = const_circ_test.flowMap();
103
  b = const_circ_test.barrier(n);
104
  const_circ_test.barrierMap(bar);
105
  
106
  ignore_unused_variable_warning(fm);
107
}
108

	
109
template <class G, class LM, class UM, class DM>
110
void checkCirculation(const G& g, const LM& lm, const UM& um,
111
                      const DM& dm, bool find)
112
{
113
  Circulation<G, LM, UM, DM> circ(g, lm, um, dm);
114
  bool ret = circ.run();
115
  if (find) {
116
    check(ret, "A feasible solution should have been found.");
117
    check(circ.checkFlow(), "The found flow is corrupt.");
118
    check(!circ.checkBarrier(), "A barrier should not have been found.");
119
  } else {
120
    check(!ret, "A feasible solution should not have been found.");
121
    check(circ.checkBarrier(), "The found barrier is corrupt.");
122
  }
123
}
124

	
125
int main (int, char*[])
126
{
127
  typedef ListDigraph Digraph;
128
  DIGRAPH_TYPEDEFS(Digraph);
129

	
130
  Digraph g;
131
  IntArcMap lo(g), up(g);
132
  IntNodeMap delta(g, 0);
133
  Node s, t;
134

	
135
  std::istringstream input(test_lgf);
136
  DigraphReader<Digraph>(g,input).
137
    arcMap("lcap", lo).
138
    arcMap("ucap", up).
139
    node("source",s).
140
    node("sink",t).
141
    run();
142

	
143
  delta[s] = 7; delta[t] = -7;
144
  checkCirculation(g, lo, up, delta, true);
145

	
146
  delta[s] = 13; delta[t] = -13;
147
  checkCirculation(g, lo, up, delta, true);
148

	
149
  delta[s] = 6; delta[t] = -6;
150
  checkCirculation(g, lo, up, delta, false);
151

	
152
  delta[s] = 14; delta[t] = -14;
153
  checkCirculation(g, lo, up, delta, false);
154

	
155
  delta[s] = 7; delta[t] = -13;
156
  checkCirculation(g, lo, up, delta, true);
157

	
158
  delta[s] = 5; delta[t] = -15;
159
  checkCirculation(g, lo, up, delta, true);
160

	
161
  delta[s] = 10; delta[t] = -11;
162
  checkCirculation(g, lo, up, delta, true);
163

	
164
  delta[s] = 11; delta[t] = -10;
165
  checkCirculation(g, lo, up, delta, false);
166

	
167
  return 0;
168
}
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 <iostream>
20
#include <sstream>
21

	
22
#include <lemon/smart_graph.h>
23
#include <lemon/lgf_reader.h>
24
#include <lemon/path.h>
25
#include <lemon/concepts/digraph.h>
26
#include <lemon/concept_check.h>
27

	
28
#include <lemon/karp.h>
29
#include <lemon/hartmann_orlin.h>
30
#include <lemon/howard.h>
31

	
32
#include "test_tools.h"
33

	
34
using namespace lemon;
35

	
36
char test_lgf[] =
37
  "@nodes\n"
38
  "label\n"
39
  "1\n"
40
  "2\n"
41
  "3\n"
42
  "4\n"
43
  "5\n"
44
  "6\n"
45
  "7\n"
46
  "@arcs\n"
47
  "    len1 len2 len3 len4  c1 c2 c3 c4\n"
48
  "1 2    1    1    1    1   0  0  0  0\n"
49
  "2 4    5    5    5    5   1  0  0  0\n"
50
  "2 3    8    8    8    8   0  0  0  0\n"
51
  "3 2   -2    0    0    0   1  0  0  0\n"
52
  "3 4    4    4    4    4   0  0  0  0\n"
53
  "3 7   -4   -4   -4   -4   0  0  0  0\n"
54
  "4 1    2    2    2    2   0  0  0  0\n"
55
  "4 3    3    3    3    3   1  0  0  0\n"
56
  "4 4    3    3    0    0   0  0  1  0\n"
57
  "5 2    4    4    4    4   0  0  0  0\n"
58
  "5 6    3    3    3    3   0  1  0  0\n"
59
  "6 5    2    2    2    2   0  1  0  0\n"
60
  "6 4   -1   -1   -1   -1   0  0  0  0\n"
61
  "6 7    1    1    1    1   0  0  0  0\n"
62
  "7 7    4    4    4   -1   0  0  0  1\n";
63

	
64
                        
65
// Check the interface of an MMC algorithm
66
template <typename GR, typename Value>
67
struct MmcClassConcept
68
{
69
  template <typename MMC>
70
  struct Constraints {
71
    void constraints() {
72
      const Constraints& me = *this;
73

	
74
      typedef typename MMC
75
        ::template SetPath<ListPath<GR> >
76
        ::template SetLargeValue<Value>
77
        ::Create MmcAlg;
78
      MmcAlg mmc(me.g, me.length);
79
      const MmcAlg& const_mmc = mmc;
80
      
81
      typename MmcAlg::Tolerance tol = const_mmc.tolerance();
82
      mmc.tolerance(tol);
83
      
84
      b = mmc.cycle(p).run();
85
      b = mmc.findMinMean();
86
      b = mmc.findCycle();
87

	
88
      v = const_mmc.cycleLength();
89
      i = const_mmc.cycleArcNum();
90
      d = const_mmc.cycleMean();
91
      p = const_mmc.cycle();
92
    }
93

	
94
    typedef concepts::ReadMap<typename GR::Arc, Value> LM;
95
  
96
    GR g;
97
    LM length;
98
    ListPath<GR> p;
99
    Value v;
100
    int i;
101
    double d;
102
    bool b;
103
  };
104
};
105

	
106
// Perform a test with the given parameters
107
template <typename MMC>
108
void checkMmcAlg(const SmartDigraph& gr,
109
                 const SmartDigraph::ArcMap<int>& lm,
110
                 const SmartDigraph::ArcMap<int>& cm,
111
                 int length, int size) {
112
  MMC alg(gr, lm);
113
  alg.findMinMean();
114
  check(alg.cycleMean() == static_cast<double>(length) / size,
115
        "Wrong cycle mean");
116
  alg.findCycle();
117
  check(alg.cycleLength() == length && alg.cycleArcNum() == size,
118
        "Wrong path");
119
  SmartDigraph::ArcMap<int> cycle(gr, 0);
120
  for (typename MMC::Path::ArcIt a(alg.cycle()); a != INVALID; ++a) {
121
    ++cycle[a];
122
  }
123
  for (SmartDigraph::ArcIt a(gr); a != INVALID; ++a) {
124
    check(cm[a] == cycle[a], "Wrong path");
125
  }
126
}
127

	
128
// Class for comparing types
129
template <typename T1, typename T2>
130
struct IsSameType {
131
  static const int result = 0;
132
};
133

	
134
template <typename T>
135
struct IsSameType<T,T> {
136
  static const int result = 1;
137
};
138

	
139

	
140
int main() {
141
  #ifdef LEMON_HAVE_LONG_LONG
142
    typedef long long long_int;
143
  #else
144
    typedef long long_int;
145
  #endif
146

	
147
  // Check the interface
148
  {
149
    typedef concepts::Digraph GR;
150

	
151
    // Karp
152
    checkConcept< MmcClassConcept<GR, int>,
153
                  Karp<GR, concepts::ReadMap<GR::Arc, int> > >();
154
    checkConcept< MmcClassConcept<GR, float>,
155
                  Karp<GR, concepts::ReadMap<GR::Arc, float> > >();
156
    
157
    // HartmannOrlin
158
    checkConcept< MmcClassConcept<GR, int>,
159
                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, int> > >();
160
    checkConcept< MmcClassConcept<GR, float>,
161
                  HartmannOrlin<GR, concepts::ReadMap<GR::Arc, float> > >();
162
    
163
    // Howard
164
    checkConcept< MmcClassConcept<GR, int>,
165
                  Howard<GR, concepts::ReadMap<GR::Arc, int> > >();
166
    checkConcept< MmcClassConcept<GR, float>,
167
                  Howard<GR, concepts::ReadMap<GR::Arc, float> > >();
168

	
169
    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, int> >::LargeValue,
170
          long_int>::result == 0) check(false, "Wrong LargeValue type");
171
    if (IsSameType<Howard<GR, concepts::ReadMap<GR::Arc, float> >::LargeValue,
172
          double>::result == 0) check(false, "Wrong LargeValue type");
173
  }
174

	
175
  // Run various tests
176
  {
177
    typedef SmartDigraph GR;
178
    DIGRAPH_TYPEDEFS(GR);
179
    
180
    GR gr;
181
    IntArcMap l1(gr), l2(gr), l3(gr), l4(gr);
182
    IntArcMap c1(gr), c2(gr), c3(gr), c4(gr);
183
    
184
    std::istringstream input(test_lgf);
185
    digraphReader(gr, input).
186
      arcMap("len1", l1).
187
      arcMap("len2", l2).
188
      arcMap("len3", l3).
189
      arcMap("len4", l4).
190
      arcMap("c1", c1).
191
      arcMap("c2", c2).
192
      arcMap("c3", c3).
193
      arcMap("c4", c4).
194
      run();
195

	
196
    // Karp
197
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l1, c1,  6, 3);
198
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l2, c2,  5, 2);
199
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l3, c3,  0, 1);
200
    checkMmcAlg<Karp<GR, IntArcMap> >(gr, l4, c4, -1, 1);
201

	
202
    // HartmannOrlin
203
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l1, c1,  6, 3);
204
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l2, c2,  5, 2);
205
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l3, c3,  0, 1);
206
    checkMmcAlg<HartmannOrlin<GR, IntArcMap> >(gr, l4, c4, -1, 1);
207

	
208
    // Howard
209
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l1, c1,  6, 3);
210
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l2, c2,  5, 2);
211
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l3, c3,  0, 1);
212
    checkMmcAlg<Howard<GR, IntArcMap> >(gr, l4, c4, -1, 1);
213
  }
214

	
215
  return 0;
216
}
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
    sbuf << "Wrong optimal value ("<< mip.solValue()
54
         <<" instead of " << exp_opt << ")";
55
    check(std::abs(mip.solValue()-exp_opt) < 1e-3, sbuf.str());
56
    //+ecvt(exp_opt,2)
57
  }
58
}
59

	
60
void aTest(MipSolver& mip)
61
{
62
  //The following example is very simple
63

	
64

	
65
  typedef MipSolver::Row Row;
66
  typedef MipSolver::Col Col;
67

	
68

	
69
  Col x1 = mip.addCol();
70
  Col x2 = mip.addCol();
71

	
72

	
73
  //Objective function
74
  mip.obj(x1);
75

	
76
  mip.max();
77

	
78
  //Unconstrained optimization
79
  mip.solve();
80
  //Check it out!
81

	
82
  //Constraints
83
  mip.addRow(2 * x1 + x2 <= 2);
84
  Row y2 = mip.addRow(x1 - 2 * x2 <= 0);
85

	
86
  //Nonnegativity of the variable x1
87
  mip.colLowerBound(x1, 0);
88

	
89

	
90
  //Maximization of x1
91
  //over the triangle with vertices (0,0),(4/5,2/5),(0,2)
92
  double expected_opt=4.0/5.0;
93
  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
94

	
95

	
96
  //Restrict x2 to integer
97
  mip.colType(x2,MipSolver::INTEGER);
98
  expected_opt=1.0/2.0;
99
  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
100

	
101

	
102
  //Restrict both to integer
103
  mip.colType(x1,MipSolver::INTEGER);
104
  expected_opt=0;
105
  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
106

	
107
  //Erase a variable
108
  mip.erase(x2);
109
  mip.rowUpperBound(y2, 8);
110
  expected_opt=1;
111
  solveAndCheck(mip, MipSolver::OPTIMAL, expected_opt);
112

	
113
}
114

	
115

	
116
template<class MIP>
117
void cloneTest()
118
{
119

	
120
  MIP* mip = new MIP();
121
  MIP* mipnew = mip->newSolver();
122
  MIP* mipclone = mip->cloneSolver();
123
  delete mip;
124
  delete mipnew;
125
  delete mipclone;
126
}
127

	
128
int main()
129
{
130

	
131
#ifdef LEMON_HAVE_GLPK
132
  {
133
    GlpkMip mip1;
134
    aTest(mip1);
135
    cloneTest<GlpkMip>();
136
  }
137
#endif
138

	
139
#ifdef LEMON_HAVE_CPLEX
140
  try {
141
    CplexMip mip2;
142
    aTest(mip2);
143
    cloneTest<CplexMip>();
144
  } catch (CplexEnv::LicenseError& error) {
145
    check(false, error.what());
146
  }
147
#endif
148

	
149
#ifdef LEMON_HAVE_CBC
150
  {
151
    CbcMip mip1;
152
    aTest(mip1);
153
    cloneTest<CbcMip>();
154
  }
155
#endif
156

	
157
  return 0;
158

	
159
}
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
  const PreflowType::Elevator& elev = const_preflow_test.elevator();
99
  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
100
  PreflowType::Tolerance tol = const_preflow_test.tolerance();
101
  preflow_test.tolerance(tol);
102

	
103
  preflow_test
104
    .capacityMap(cap)
105
    .flowMap(flow)
106
    .source(n)
107
    .target(n);
108

	
109
  preflow_test.init();
110
  preflow_test.init(cap);
111
  preflow_test.startFirstPhase();
112
  preflow_test.startSecondPhase();
113
  preflow_test.run();
114
  preflow_test.runMinCut();
115

	
116
  v = const_preflow_test.flowValue();
117
  v = const_preflow_test.flow(e);
118
  const FlowMap& fm = const_preflow_test.flowMap();
119
  b = const_preflow_test.minCut(n);
120
  const_preflow_test.minCutMap(cut);
121
  
122
  ignore_unused_variable_warning(fm);
123
}
124

	
125
int cutValue (const SmartDigraph& g,
126
              const SmartDigraph::NodeMap<bool>& cut,
127
              const SmartDigraph::ArcMap<int>& cap) {
128

	
129
  int c=0;
130
  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
131
    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
132
  }
133
  return c;
134
}
135

	
136
bool checkFlow(const SmartDigraph& g,
137
               const SmartDigraph::ArcMap<int>& flow,
138
               const SmartDigraph::ArcMap<int>& cap,
139
               SmartDigraph::Node s, SmartDigraph::Node t) {
140

	
141
  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
142
    if (flow[e] < 0 || flow[e] > cap[e]) return false;
143
  }
144

	
145
  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
146
    if (n == s || n == t) continue;
147
    int sum = 0;
148
    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
149
      sum += flow[e];
150
    }
151
    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
152
      sum -= flow[e];
153
    }
154
    if (sum != 0) return false;
155
  }
156
  return true;
157
}
158

	
159
int main() {
160

	
161
  typedef SmartDigraph Digraph;
162

	
163
  typedef Digraph::Node Node;
164
  typedef Digraph::NodeIt NodeIt;
165
  typedef Digraph::ArcIt ArcIt;
166
  typedef Digraph::ArcMap<int> CapMap;
167
  typedef Digraph::ArcMap<int> FlowMap;
168
  typedef Digraph::NodeMap<bool> CutMap;
169

	
170
  typedef Preflow<Digraph, CapMap> PType;
171

	
172
  Digraph g;
173
  Node s, t;
174
  CapMap cap(g);
175
  std::istringstream input(test_lgf);
176
  DigraphReader<Digraph>(g,input).
177
    arcMap("capacity", cap).
178
    node("source",s).
179
    node("target",t).
180
    run();
181

	
182
  PType preflow_test(g, cap, s, t);
183
  preflow_test.run();
184

	
185
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
186
        "The flow is not feasible.");
187

	
188
  CutMap min_cut(g);
189
  preflow_test.minCutMap(min_cut);
190
  int min_cut_value=cutValue(g,min_cut,cap);
191

	
192
  check(preflow_test.flowValue() == min_cut_value,
193
        "The max flow value is not equal to the three min cut values.");
194

	
195
  FlowMap flow(g);
196
  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
197

	
198
  int flow_value=preflow_test.flowValue();
199

	
200
  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
201
  preflow_test.init(flow);
202
  preflow_test.startFirstPhase();
203

	
204
  CutMap min_cut1(g);
205
  preflow_test.minCutMap(min_cut1);
206
  min_cut_value=cutValue(g,min_cut1,cap);
207

	
208
  check(preflow_test.flowValue() == min_cut_value &&
209
        min_cut_value == 2*flow_value,
210
        "The max flow value or the min cut value is wrong.");
211

	
212
  preflow_test.startSecondPhase();
213

	
214
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
215
        "The flow is not feasible.");
216

	
217
  CutMap min_cut2(g);
218
  preflow_test.minCutMap(min_cut2);
219
  min_cut_value=cutValue(g,min_cut2,cap);
220

	
221
  check(preflow_test.flowValue() == min_cut_value &&
222
        min_cut_value == 2*flow_value,
223
        "The max flow value or the three min cut values were not doubled");
224

	
225

	
226
  preflow_test.flowMap(flow);
227

	
228
  NodeIt tmp1(g,s);
229
  ++tmp1;
230
  if ( tmp1 != INVALID ) s=tmp1;
231

	
232
  NodeIt tmp2(g,t);
233
  ++tmp2;
234
  if ( tmp2 != INVALID ) t=tmp2;
235

	
236
  preflow_test.source(s);
237
  preflow_test.target(t);
238

	
239
  preflow_test.run();
240

	
241
  CutMap min_cut3(g);
242
  preflow_test.minCutMap(min_cut3);
243
  min_cut_value=cutValue(g,min_cut3,cap);
244

	
245

	
246
  check(preflow_test.flowValue() == min_cut_value,
247
        "The max flow value or the three min cut values are incorrect.");
248

	
249
  return 0;
250
}
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})
37

	
38
INCLUDE(FindPythonInterp)
21 39

	
22 40
ENABLE_TESTING()
23 41

	
24 42
ADD_SUBDIRECTORY(lemon)
25
ADD_SUBDIRECTORY(demo)
26
ADD_SUBDIRECTORY(doc)
27
ADD_SUBDIRECTORY(test)
43
IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
44
  ADD_SUBDIRECTORY(demo)
45
  ADD_SUBDIRECTORY(tools)
46
  ADD_SUBDIRECTORY(doc)
47
  ADD_SUBDIRECTORY(test)
48
ENDIF()
28 49

	
29
IF(WIN32)
50
CONFIGURE_FILE(
51
  ${PROJECT_SOURCE_DIR}/cmake/LEMONConfig.cmake.in
52
  ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
53
  @ONLY
54
)
55
IF(UNIX)
56
  INSTALL(
57
    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
58
    DESTINATION share/lemon/cmake
59
  )
60
ELSEIF(WIN32)
61
  INSTALL(
62
    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
63
    DESTINATION cmake
64
  )
65
ENDIF()
66

	
67
IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR} AND WIN32)
30 68
  SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
31 69
  SET(CPACK_PACKAGE_VENDOR "EGRES")
32 70
  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")
71
    "LEMON - Library for Efficient Modeling and Optimization in Networks")
72
  SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
35 73

	
36 74
  SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
37 75

	
38 76
  SET(CPACK_PACKAGE_INSTALL_DIRECTORY
39 77
    "${PROJECT_NAME} ${PROJECT_VERSION}")
40 78
  SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
41 79
    "${PROJECT_NAME} ${PROJECT_VERSION}")
42 80

	
43
  SET(CPACK_COMPONENTS_ALL headers library html_documentation)
81
  SET(CPACK_COMPONENTS_ALL headers library html_documentation bin)
44 82

	
45 83
  SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
46 84
  SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
85
  SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities")
47 86
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
48 87

	
49 88
  SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
50 89
    "C++ header files")
51 90
  SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
52 91
    "DLL and import library")
92
  SET(CPACK_COMPONENT_BIN_DESCRIPTION
93
    "Command line utilities")
53 94
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
54 95
    "Doxygen generated documentation")
55 96

	
56 97
  SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
57 98

	
58 99
  SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
59 100
  SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
60 101
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
61 102

	
62 103
  SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
63 104
    "Components needed to develop software using LEMON")
64 105
  SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
65 106
    "Documentation of LEMON")
66 107

	
67 108
  SET(CPACK_ALL_INSTALL_TYPES Full Developer)
68 109

	
69 110
  SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
70 111
  SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
71 112
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
72 113

	
73 114
  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")
115
  SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis/lemon.ico")
116
  SET(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/cmake/nsis/uninstall.ico")
117
  #SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
77 118
  SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
78 119
  SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
79 120
  SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
80 121
  SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lemon.cs.elte.hu")
81 122
  SET(CPACK_NSIS_CONTACT "lemon-user@lemon.cs.elte.hu")
82 123
  SET(CPACK_NSIS_CREATE_ICONS_EXTRA "
83 124
    CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\share\\\\doc\\\\index.html\\\"
84 125
    ")
85 126
  SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
86 127
    !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
87 128
    Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Documentation.lnk\\\"
88 129
    ")
89 130

	
90 131
  INCLUDE(CPack)
91
ENDIF(WIN32)
132
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 \
20
	cmake/LEMONConfig.cmake.in \
14 21
	cmake/version.cmake.in \
15 22
	cmake/version.cmake \
16 23
	cmake/nsis/lemon.ico \
17 24
	cmake/nsis/uninstall.ico
18 25

	
19 26
pkgconfigdir = $(libdir)/pkgconfig
20 27
lemondir = $(pkgincludedir)
21 28
bitsdir = $(lemondir)/bits
22 29
conceptdir = $(lemondir)/concepts
23 30
pkgconfig_DATA =
24 31
lib_LTLIBRARIES =
25 32
lemon_HEADERS =
26 33
bits_HEADERS =
27 34
concept_HEADERS =
28 35
noinst_HEADERS =
29 36
noinst_PROGRAMS =
30 37
bin_PROGRAMS =
31 38
check_PROGRAMS =
32 39
dist_bin_SCRIPTS =
33 40
TESTS =
34 41
XFAIL_TESTS =
35 42

	
36 43
include lemon/Makefile.am
37 44
include test/Makefile.am
38 45
include doc/Makefile.am
39
include demo/Makefile.am
40 46
include tools/Makefile.am
41 47

	
48
DIST_SUBDIRS = demo
49

	
50
demo:
51
	$(MAKE) $(AM_MAKEFLAGS) -C demo
52

	
42 53
MRPROPERFILES = \
43 54
	aclocal.m4 \
44 55
	config.h.in \
45 56
	config.h.in~ \
46 57
	configure \
47 58
	Makefile.in \
48 59
	build-aux/config.guess \
49 60
	build-aux/config.sub \
50 61
	build-aux/depcomp \
51 62
	build-aux/install-sh \
52 63
	build-aux/ltmain.sh \
53 64
	build-aux/missing \
54 65
	doc/doxygen.log
55 66

	
56 67
mrproper:
57 68
	$(MAKE) $(AM_MAKEFLAGS) maintainer-clean
58 69
	-rm -f $(MRPROPERFILES)
59 70

	
60 71
dist-bz2: dist
61 72
	zcat $(PACKAGE)-$(VERSION).tar.gz | \
62 73
	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
63 74

	
64 75
distcheck-bz2: distcheck
65 76
	zcat $(PACKAGE)-$(VERSION).tar.gz | \
66 77
	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
67 78

	
68
.PHONY: mrproper dist-bz2 distcheck-bz2
79
.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])
44
AC_CHECK_PROG([python_found],[python],[yes],[no])
41 45
AC_CHECK_PROG([gs_found],[gs],[yes],[no])
42 46

	
43 47
dnl Detect Intel compiler.
44 48
AC_MSG_CHECKING([whether we are using the Intel C++ compiler])
45 49
AC_COMPILE_IFELSE([#ifndef __INTEL_COMPILER
46 50
choke me
47 51
#endif], [ICC=[yes]], [ICC=[no]])
48 52
if test x"$ICC" = x"yes"; then
49 53
  AC_MSG_RESULT([yes])
50 54
else
51 55
  AC_MSG_RESULT([no])
52 56
fi
53 57

	
54 58
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"
59
if test "$GXX" = yes -a "$ICC" = no; then
60
  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 61
fi
62
AC_SUBST([WARNINGCXXFLAGS])
58 63

	
59 64
dnl Checks for libraries.
60
#LX_CHECK_GLPK
61
#LX_CHECK_CPLEX
62
#LX_CHECK_SOPLEX
65
LX_CHECK_GLPK
66
LX_CHECK_CPLEX
67
LX_CHECK_SOPLEX
68
LX_CHECK_COIN
63 69

	
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"])
70
AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"])
71
AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"])
76 72

	
77 73
dnl Disable/enable building the binary tools.
78 74
AC_ARG_ENABLE([tools],
79 75
AS_HELP_STRING([--enable-tools], [build additional tools @<:@default@:>@])
80 76
AS_HELP_STRING([--disable-tools], [do not build additional tools]),
81 77
              [], [enable_tools=yes])
82 78
AC_MSG_CHECKING([whether to build the additional tools])
83 79
if test x"$enable_tools" != x"no"; then
84 80
  AC_MSG_RESULT([yes])
85 81
else
86 82
  AC_MSG_RESULT([no])
87 83
fi
88 84
AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
89 85

	
90 86
dnl Checks for header files.
91 87
AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
92 88

	
93 89
dnl Checks for typedefs, structures, and compiler characteristics.
94 90
AC_C_CONST
95 91
AC_C_INLINE
96 92
AC_TYPE_SIZE_T
97 93
AC_HEADER_TIME
98 94
AC_STRUCT_TM
99 95

	
100 96
dnl Checks for library functions.
101 97
AC_HEADER_STDC
102 98
AC_CHECK_FUNCS(gettimeofday times ctime_r)
103 99

	
104 100
dnl Add dependencies on files generated by configure.
105 101
AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
106 102
  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
107 103

	
108 104
AC_CONFIG_FILES([
109 105
Makefile
106
demo/Makefile
110 107
cmake/version.cmake
111 108
doc/Doxyfile
112 109
lemon/lemon.pc
113 110
])
114 111

	
115 112
AC_OUTPUT
116 113

	
117 114
echo
118 115
echo '****************************** SUMMARY ******************************'
119 116
echo
120 117
echo Package version............... : $PACKAGE-$VERSION
121 118
echo
122 119
echo C++ compiler.................. : $CXX
123
echo C++ compiles flags............ : $CXXFLAGS
120
echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS
124 121
echo
125 122
echo Compiler supports long long... : $long_long_found
126 123
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
124
echo GLPK support.................. : $lx_glpk_found
125
echo CPLEX support................. : $lx_cplex_found
126
echo SOPLEX support................ : $lx_soplex_found
127
echo CLP support................... : $lx_clp_found
128
echo CBC support................... : $lx_cbc_found
129
echo
132 130
echo Build additional tools........ : $enable_tools
133 131
echo
134 132
echo The packace will be installed in
135 133
echo -n '  '
136 134
echo $prefix.
137 135
echo
138 136
echo '*********************************************************************'
139 137

	
140 138
echo
141 139
echo Configure complete, now type \'make\' and then \'make install\'.
142 140
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
IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
12
IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND 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 ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
32
    COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
33
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
34
  )
35

	
36
  SET_TARGET_PROPERTIES(html PROPERTIES PROJECT_LABEL BUILD_DOC)
37

	
13 38
  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})
39
    INSTALL(
40
      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
41
      DESTINATION share/doc/lemon/html
42
      COMPONENT html_documentation
43
    )
25 44
  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)
45
    INSTALL(
46
      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
47
      DESTINATION doc
48
      COMPONENT html_documentation
49
    )
50
  ENDIF()
51

	
52
ENDIF()
Ignore white space 6 line context
1
# Doxyfile 1.5.7.1
1
# Doxyfile 1.5.9
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
DETAILS_AT_TOP         = YES
25 24
INHERIT_DOCS           = NO
26 25
SEPARATE_MEMBER_PAGES  = NO
27 26
TAB_SIZE               = 8
28 27
ALIASES                = 
29 28
OPTIMIZE_OUTPUT_FOR_C  = NO
30 29
OPTIMIZE_OUTPUT_JAVA   = NO
31 30
OPTIMIZE_FOR_FORTRAN   = NO
32 31
OPTIMIZE_OUTPUT_VHDL   = NO
33 32
BUILTIN_STL_SUPPORT    = YES
34 33
CPP_CLI_SUPPORT        = NO
35 34
SIP_SUPPORT            = NO
36 35
IDL_PROPERTY_SUPPORT   = YES
37 36
DISTRIBUTE_GROUP_DOC   = NO
38 37
SUBGROUPING            = YES
39 38
TYPEDEF_HIDES_STRUCT   = NO
40 39
SYMBOL_CACHE_SIZE      = 0
41 40
#---------------------------------------------------------------------------
42 41
# Build related configuration options
43 42
#---------------------------------------------------------------------------
44 43
EXTRACT_ALL            = NO
45 44
EXTRACT_PRIVATE        = YES
46 45
EXTRACT_STATIC         = YES
47 46
EXTRACT_LOCAL_CLASSES  = NO
48 47
EXTRACT_LOCAL_METHODS  = NO
49 48
EXTRACT_ANON_NSPACES   = NO
50 49
HIDE_UNDOC_MEMBERS     = YES
51 50
HIDE_UNDOC_CLASSES     = YES
52 51
HIDE_FRIEND_COMPOUNDS  = NO
53 52
HIDE_IN_BODY_DOCS      = NO
54 53
INTERNAL_DOCS          = NO
55 54
CASE_SENSE_NAMES       = YES
56 55
HIDE_SCOPE_NAMES       = YES
57 56
SHOW_INCLUDE_FILES     = YES
58 57
INLINE_INFO            = YES
59 58
SORT_MEMBER_DOCS       = NO
60 59
SORT_BRIEF_DOCS        = NO
61 60
SORT_GROUP_NAMES       = NO
62 61
SORT_BY_SCOPE_NAME     = NO
63 62
GENERATE_TODOLIST      = YES
64 63
GENERATE_TESTLIST      = YES
65 64
GENERATE_BUGLIST       = YES
66 65
GENERATE_DEPRECATEDLIST= YES
67 66
ENABLED_SECTIONS       = 
68 67
MAX_INITIALIZER_LINES  = 5
69
SHOW_USED_FILES        = YES
68
SHOW_USED_FILES        = NO
70 69
SHOW_DIRECTORIES       = YES
71 70
SHOW_FILES             = YES
72 71
SHOW_NAMESPACES        = YES
73 72
FILE_VERSION_FILTER    = 
74 73
LAYOUT_FILE            = DoxygenLayout.xml
75 74
#---------------------------------------------------------------------------
76 75
# configuration options related to warning and progress messages
77 76
#---------------------------------------------------------------------------
78 77
QUIET                  = NO
79 78
WARNINGS               = YES
80 79
WARN_IF_UNDOCUMENTED   = YES
81 80
WARN_IF_DOC_ERROR      = YES
82 81
WARN_NO_PARAMDOC       = NO
83 82
WARN_FORMAT            = "$file:$line: $text"
84 83
WARN_LOGFILE           = doxygen.log
85 84
#---------------------------------------------------------------------------
86 85
# configuration options related to the input files
87 86
#---------------------------------------------------------------------------
88 87
INPUT                  = "@abs_top_srcdir@/doc" \
89 88
                         "@abs_top_srcdir@/lemon" \
90 89
                         "@abs_top_srcdir@/lemon/bits" \
91 90
                         "@abs_top_srcdir@/lemon/concepts" \
92 91
                         "@abs_top_srcdir@/demo" \
93 92
                         "@abs_top_srcdir@/tools" \
94
                         "@abs_top_srcdir@/test/test_tools.h"
93
                         "@abs_top_srcdir@/test/test_tools.h" \
94
                         "@abs_top_builddir@/doc/references.dox"
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
# Configuration::additions related to external references   
226
# Options related to the search engine   
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

	
47
html-local: $(DOC_PNG_IMAGES)
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

	
69
references.dox: doc/references.bib
70
	if test ${python_found} = yes; then \
71
	  cd doc; \
72
	  python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \
73
	  cd ..; \
74
	else \
75
	  echo; \
76
	  echo "Python not found."; \
77
	  echo; \
78
	  exit 1; \
79
	fi
80

	
81
html-local: $(DOC_PNG_IMAGES) references.dox
48 82
	if test ${doxygen_found} = yes; then \
49 83
	  cd doc; \
50 84
	  doxygen Doxyfile; \
51 85
	  cd ..; \
52 86
	else \
53 87
	  echo; \
54 88
	  echo "Doxygen not found."; \
55 89
	  echo; \
56 90
	  exit 1; \
57 91
	fi
58 92

	
59 93
clean-local:
60 94
	-rm -rf doc/html
61 95
	-rm -f doc/doxygen.log
62 96
	-rm -f $(DOC_PNG_IMAGES)
63 97
	-rm -rf doc/gen-images
64 98

	
65 99
update-external-tags:
66 100
	wget -O doc/libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag && \
67 101
	mv doc/libstdc++.tag.tmp doc/libstdc++.tag || \
68 102
	rm doc/libstdc++.tag.tmp
69 103

	
70 104
install-html-local: doc/html
71 105
	@$(NORMAL_INSTALL)
72
	$(mkinstalldirs) $(DESTDIR)$(htmldir)/docs
106
	$(mkinstalldirs) $(DESTDIR)$(htmldir)/html
73 107
	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
74 108
	  f="`echo $$p | sed -e 's|^.*/||'`"; \
75
	  echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/docs/$$f"; \
76
	  $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/docs/$$f; \
109
	  echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \
110
	  $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \
77 111
	done
78 112

	
79 113
uninstall-local:
80 114
	@$(NORMAL_UNINSTALL)
81 115
	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
82 116
	  f="`echo $$p | sed -e 's|^.*/||'`"; \
83
	  echo " rm -f $(DESTDIR)$(htmldir)/docs/$$f"; \
84
	  rm -f $(DESTDIR)$(htmldir)/docs/$$f; \
117
	  echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \
118
	  rm -f $(DESTDIR)$(htmldir)/html/$$f; \
85 119
	done
86 120

	
87 121
.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
@defgroup matrices Matrices
159
@ingroup datas
160
\brief Two dimensional data storages implemented in LEMON.
161

	
162
This group describes two dimensional data storages implemented in LEMON.
163
*/
164

	
165
/**
166 229
@defgroup paths Path Structures
167 230
@ingroup datas
168 231
\brief %Path structures implemented in LEMON.
169 232

	
170
This group describes the path structures implemented in LEMON.
233
This group contains the path structures implemented in LEMON.
171 234

	
172 235
LEMON provides flexible data structures to work with paths.
173 236
All of them have similar interfaces and they can be copied easily with
174 237
assignment operators and copy constructors. This makes it easy and
175 238
efficient to have e.g. the Dijkstra algorithm to store its result in
176 239
any kind of path structure.
177 240

	
178
\sa lemon::concepts::Path
241
\sa \ref concepts::Path "Path concept"
242
*/
243

	
244
/**
245
@defgroup heaps Heap Structures
246
@ingroup datas
247
\brief %Heap structures implemented in LEMON.
248

	
249
This group contains the heap structures implemented in LEMON.
250

	
251
LEMON provides several heap classes. They are efficient implementations
252
of the abstract data type \e priority \e queue. They store items with
253
specified values called \e priorities in such a way that finding and
254
removing the item with minimum priority are efficient.
255
The basic operations are adding and erasing items, changing the priority
256
of an item, etc.
257

	
258
Heaps are crucial in several algorithms, such as Dijkstra and Prim.
259
The heap implementations have the same interface, thus any of them can be
260
used easily in such algorithms.
261

	
262
\sa \ref concepts::Heap "Heap concept"
263
*/
264

	
265
/**
266
@defgroup matrices Matrices
267
@ingroup datas
268
\brief Two dimensional data storages implemented in LEMON.
269

	
270
This group contains two dimensional data storages implemented in LEMON.
179 271
*/
180 272

	
181 273
/**
182 274
@defgroup auxdat Auxiliary Data Structures
183 275
@ingroup datas
184 276
\brief Auxiliary data structures implemented in LEMON.
185 277

	
186
This group describes some data structures implemented in LEMON in
278
This group contains some data structures implemented in LEMON in
187 279
order to make it easier to implement combinatorial algorithms.
188 280
*/
189 281

	
190 282
/**
283
@defgroup geomdat Geometric Data Structures
284
@ingroup auxdat
285
\brief Geometric data structures implemented in LEMON.
286

	
287
This group contains geometric data structures implemented in LEMON.
288

	
289
 - \ref lemon::dim2::Point "dim2::Point" implements a two dimensional
290
   vector with the usual operations.
291
 - \ref lemon::dim2::Box "dim2::Box" can be used to determine the
292
   rectangular bounding box of a set of \ref lemon::dim2::Point
293
   "dim2::Point"'s.
294
*/
295

	
296
/**
297
@defgroup matrices Matrices
298
@ingroup auxdat
299
\brief Two dimensional data storages implemented in LEMON.
300

	
301
This group contains two dimensional data storages implemented in LEMON.
302
*/
303

	
304
/**
191 305
@defgroup algs Algorithms
192
\brief This group describes the several algorithms
306
\brief This group contains the several algorithms
193 307
implemented in LEMON.
194 308

	
195
This group describes the several algorithms
309
This group contains the several algorithms
196 310
implemented in LEMON.
197 311
*/
198 312

	
199 313
/**
200 314
@defgroup search Graph Search
201 315
@ingroup algs
202 316
\brief Common graph search algorithms.
203 317

	
204
This group describes the common graph search algorithms like
205
Breadth-First Search (BFS) and Depth-First Search (DFS).
318
This group contains the common graph search algorithms, namely
319
\e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
320
\ref clrs01algorithms.
206 321
*/
207 322

	
208 323
/**
209 324
@defgroup shortest_path Shortest Path Algorithms
210 325
@ingroup algs
211 326
\brief Algorithms for finding shortest paths.
212 327

	
213
This group describes the algorithms for finding shortest paths in graphs.
328
This group contains the algorithms for finding shortest paths in digraphs
329
\ref clrs01algorithms.
330

	
331
 - \ref Dijkstra algorithm for finding shortest paths from a source node
332
   when all arc lengths are non-negative.
333
 - \ref BellmanFord "Bellman-Ford" algorithm for finding shortest paths
334
   from a source node when arc lenghts can be either positive or negative,
335
   but the digraph should not contain directed cycles with negative total
336
   length.
337
 - \ref FloydWarshall "Floyd-Warshall" and \ref Johnson "Johnson" algorithms
338
   for solving the \e all-pairs \e shortest \e paths \e problem when arc
339
   lenghts can be either positive or negative, but the digraph should
340
   not contain directed cycles with negative total length.
341
 - \ref Suurballe A successive shortest path algorithm for finding
342
   arc-disjoint paths between two nodes having minimum total length.
343
*/
344

	
345
/**
346
@defgroup spantree Minimum Spanning Tree Algorithms
347
@ingroup algs
348
\brief Algorithms for finding minimum cost spanning trees and arborescences.
349

	
350
This group contains the algorithms for finding minimum cost spanning
351
trees and arborescences \ref clrs01algorithms.
214 352
*/
215 353

	
216 354
/**
217 355
@defgroup max_flow Maximum Flow Algorithms
218 356
@ingroup algs
219 357
\brief Algorithms for finding maximum flows.
220 358

	
221
This group describes the algorithms for finding maximum flows and
222
feasible circulations.
359
This group contains the algorithms for finding maximum flows and
360
feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
223 361

	
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:
362
The \e maximum \e flow \e problem is to find a flow of maximum value between
363
a single source and a single target. Formally, there is a \f$G=(V,A)\f$
364
digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and
365
\f$s, t \in V\f$ source and target nodes.
366
A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the
367
following optimization problem.
229 368

	
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]
369
\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
370
\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
371
    \quad \forall u\in V\setminus\{s,t\} \f]
372
\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
234 373

	
235 374
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"
375
- \ref EdmondsKarp Edmonds-Karp algorithm
376
  \ref edmondskarp72theoretical.
377
- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm
378
  \ref goldberg88newapproach.
379
- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees
380
  \ref dinic70algorithm, \ref sleator83dynamic.
381
- \ref GoldbergTarjan !Preflow push-relabel algorithm with dynamic trees
382
  \ref goldberg88newapproach, \ref sleator83dynamic.
240 383

	
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.
384
In most cases the \ref Preflow algorithm provides the
385
fastest method for computing a maximum flow. All implementations
386
also provide functions to query the minimum cut, which is the dual
387
problem of maximum flow.
388

	
389
\ref Circulation is a preflow push-relabel algorithm implemented directly 
390
for finding feasible circulations, which is a somewhat different problem,
391
but it is strongly related to maximum flow.
392
For more information, see \ref Circulation.
245 393
*/
246 394

	
247 395
/**
248
@defgroup min_cost_flow Minimum Cost Flow Algorithms
396
@defgroup min_cost_flow_algs Minimum Cost Flow Algorithms
249 397
@ingroup algs
250 398

	
251 399
\brief Algorithms for finding minimum cost flows and circulations.
252 400

	
253
This group describes the algorithms for finding minimum cost flows and
254
circulations.
401
This group contains the algorithms for finding minimum cost flows and
402
circulations \ref amo93networkflows. For more information about this
403
problem and its dual solution, see \ref min_cost_flow
404
"Minimum Cost Flow Problem".
405

	
406
LEMON contains several algorithms for this problem.
407
 - \ref NetworkSimplex Primal Network Simplex algorithm with various
408
   pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
409
 - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
410
   cost scaling \ref goldberg90approximation, \ref goldberg97efficient,
411
   \ref bunnagel98efficient.
412
 - \ref CapacityScaling Successive Shortest %Path algorithm with optional
413
   capacity scaling \ref edmondskarp72theoretical.
414
 - \ref CancelAndTighten The Cancel and Tighten algorithm
415
   \ref goldberg89cyclecanceling.
416
 - \ref CycleCanceling Cycle-Canceling algorithms
417
   \ref klein67primal, \ref goldberg89cyclecanceling.
418

	
419
In general NetworkSimplex is the most efficient implementation,
420
but in special cases other algorithms could be faster.
421
For example, if the total supply and/or capacities are rather small,
422
CapacityScaling is usually the fastest algorithm (without effective scaling).
255 423
*/
256 424

	
257 425
/**
258 426
@defgroup min_cut Minimum Cut Algorithms
259 427
@ingroup algs
260 428

	
261 429
\brief Algorithms for finding minimum cut in graphs.
262 430

	
263
This group describes the algorithms for finding minimum cut in graphs.
431
This group contains the algorithms for finding minimum cut in graphs.
264 432

	
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
433
The \e minimum \e cut \e problem is to find a non-empty and non-complete
434
\f$X\f$ subset of the nodes with minimum overall capacity on
435
outgoing arcs. Formally, there is a \f$G=(V,A)\f$ digraph, a
436
\f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
269 437
cut is the \f$X\f$ solution of the next optimization problem:
270 438

	
271 439
\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]
440
    \sum_{uv\in A: u\in X, v\not\in X}cap(uv) \f]
273 441

	
274 442
LEMON contains several algorithms related to minimum cut problems:
275 443

	
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
444
- \ref HaoOrlin "Hao-Orlin algorithm" for calculating minimum cut
445
  in directed graphs.
446
- \ref NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
447
  calculating minimum cut in undirected graphs.
448
- \ref GomoryHu "Gomory-Hu tree computation" for calculating
449
  all-pairs minimum cut in undirected graphs.
282 450

	
283 451
If you want to find minimum cut just between two distinict nodes,
284
please see the \ref max_flow "Maximum Flow page".
452
see the \ref max_flow "maximum flow problem".
285 453
*/
286 454

	
287 455
/**
288
@defgroup graph_prop Connectivity and Other Graph Properties
456
@defgroup min_mean_cycle Minimum Mean Cycle Algorithms
457
@ingroup algs
458
\brief Algorithms for finding minimum mean cycles.
459

	
460
This group contains the algorithms for finding minimum mean cycles
461
\ref clrs01algorithms, \ref amo93networkflows.
462

	
463
The \e minimum \e mean \e cycle \e problem is to find a directed cycle
464
of minimum mean length (cost) in a digraph.
465
The mean length of a cycle is the average length of its arcs, i.e. the
466
ratio between the total length of the cycle and the number of arcs on it.
467

	
468
This problem has an important connection to \e conservative \e length
469
\e functions, too. A length function on the arcs of a digraph is called
470
conservative if and only if there is no directed cycle of negative total
471
length. For an arbitrary length function, the negative of the minimum
472
cycle mean is the smallest \f$\epsilon\f$ value so that increasing the
473
arc lengths uniformly by \f$\epsilon\f$ results in a conservative length
474
function.
475

	
476
LEMON contains three algorithms for solving the minimum mean cycle problem:
477
- \ref Karp "Karp"'s original algorithm \ref amo93networkflows,
478
  \ref dasdan98minmeancycle.
479
- \ref HartmannOrlin "Hartmann-Orlin"'s algorithm, which is an improved
480
  version of Karp's algorithm \ref dasdan98minmeancycle.
481
- \ref Howard "Howard"'s policy iteration algorithm
482
  \ref dasdan98minmeancycle.
483

	
484
In practice, the Howard algorithm proved to be by far the most efficient
485
one, though the best known theoretical bound on its running time is
486
exponential.
487
Both Karp and HartmannOrlin algorithms run in time O(ne) and use space
488
O(n<sup>2</sup>+e), but the latter one is typically faster due to the
489
applied early termination scheme.
490
*/
491

	
492
/**
493
@defgroup matching Matching Algorithms
494
@ingroup algs
495
\brief Algorithms for finding matchings in graphs and bipartite graphs.
496

	
497
This group contains the algorithms for calculating
498
matchings in graphs and bipartite graphs. The general matching problem is
499
finding a subset of the edges for which each node has at most one incident
500
edge.
501

	
502
There are several different algorithms for calculate matchings in
503
graphs.  The matching problems in bipartite graphs are generally
504
easier than in general graphs. The goal of the matching optimization
505
can be finding maximum cardinality, maximum weight or minimum cost
506
matching. The search can be constrained to find perfect or
507
maximum cardinality matching.
508

	
509
The matching algorithms implemented in LEMON:
510
- \ref MaxBipartiteMatching Hopcroft-Karp augmenting path algorithm
511
  for calculating maximum cardinality matching in bipartite graphs.
512
- \ref PrBipartiteMatching Push-relabel algorithm
513
  for calculating maximum cardinality matching in bipartite graphs.
514
- \ref MaxWeightedBipartiteMatching
515
  Successive shortest path algorithm for calculating maximum weighted
516
  matching and maximum weighted bipartite matching in bipartite graphs.
517
- \ref MinCostMaxBipartiteMatching
518
  Successive shortest path algorithm for calculating minimum cost maximum
519
  matching in bipartite graphs.
520
- \ref MaxMatching Edmond's blossom shrinking algorithm for calculating
521
  maximum cardinality matching in general graphs.
522
- \ref MaxWeightedMatching Edmond's blossom shrinking algorithm for calculating
523
  maximum weighted matching in general graphs.
524
- \ref MaxWeightedPerfectMatching
525
  Edmond's blossom shrinking algorithm for calculating maximum weighted
526
  perfect matching in general graphs.
527

	
528
\image html bipartite_matching.png
529
\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
530
*/
531

	
532
/**
533
@defgroup graph_properties Connectivity and Other Graph Properties
289 534
@ingroup algs
290 535
\brief Algorithms for discovering the graph properties
291 536

	
292
This group describes the algorithms for discovering the graph properties
537
This group contains the algorithms for discovering the graph properties
293 538
like connectivity, bipartiteness, euler property, simplicity etc.
294 539

	
295
\image html edge_biconnected_components.png
296
\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
540
\image html connected_components.png
541
\image latex connected_components.eps "Connected components" width=\textwidth
297 542
*/
298 543

	
299 544
/**
300 545
@defgroup planar Planarity Embedding and Drawing
301 546
@ingroup algs
302 547
\brief Algorithms for planarity checking, embedding and drawing
303 548

	
304
This group describes the algorithms for planarity checking,
549
This group contains the algorithms for planarity checking,
305 550
embedding and drawing.
306 551

	
307 552
\image html planar.png
308 553
\image latex planar.eps "Plane graph" width=\textwidth
309 554
*/
310 555

	
311 556
/**
312
@defgroup matching Matching Algorithms
557
@defgroup approx Approximation Algorithms
313 558
@ingroup algs
314
\brief Algorithms for finding matchings in graphs and bipartite graphs.
559
\brief Approximation algorithms.
315 560

	
316
This group contains algorithm objects and functions to calculate
317
matchings in graphs and bipartite graphs. The general matching problem is
318
finding a subset of the arcs which does not shares common endpoints.
319

	
320
There are several different algorithms for calculate matchings in
321
graphs.  The matching problems in bipartite graphs are generally
322
easier than in general graphs. The goal of the matching optimization
323
can be the finding maximum cardinality, maximum weight or minimum cost
324
matching. The search can be constrained to find perfect or
325
maximum cardinality matching.
326

	
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
347

	
348
\image html bipartite_matching.png
349
\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
350
*/
351

	
352
/**
353
@defgroup spantree Minimum Spanning Tree Algorithms
354
@ingroup algs
355
\brief Algorithms for finding a minimum cost spanning tree in a graph.
356

	
357
This group describes the algorithms for finding a minimum cost spanning
358
tree in a graph
561
This group contains the approximation and heuristic algorithms
562
implemented in LEMON.
359 563
*/
360 564

	
361 565
/**
362 566
@defgroup auxalg Auxiliary Algorithms
363 567
@ingroup algs
364 568
\brief Auxiliary algorithms implemented in LEMON.
365 569

	
366
This group describes some algorithms implemented in LEMON
570
This group contains some algorithms implemented in LEMON
367 571
in order to make it easier to implement complex algorithms.
368 572
*/
369 573

	
370 574
/**
371
@defgroup approx Approximation Algorithms
372
@ingroup algs
373
\brief Approximation algorithms.
575
@defgroup gen_opt_group General Optimization Tools
576
\brief This group contains some general optimization frameworks
577
implemented in LEMON.
374 578

	
375
This group describes the approximation and heuristic algorithms
579
This group contains some general optimization frameworks
376 580
implemented in LEMON.
377 581
*/
378 582

	
379 583
/**
380
@defgroup gen_opt_group General Optimization Tools
381
\brief This group describes some general optimization frameworks
382
implemented in LEMON.
584
@defgroup lp_group LP and MIP Solvers
585
@ingroup gen_opt_group
586
\brief LP and MIP solver interfaces for LEMON.
383 587

	
384
This group describes some general optimization frameworks
385
implemented in LEMON.
386
*/
588
This group contains LP and MIP solver interfaces for LEMON.
589
Various LP solvers could be used in the same manner with this
590
high-level interface.
387 591

	
388
/**
389
@defgroup lp_group Lp and Mip Solvers
390
@ingroup gen_opt_group
391
\brief Lp and Mip solver interfaces for LEMON.
392

	
393
This group describes Lp and Mip solver interfaces for LEMON. The
394
various LP solvers could be used in the same manner with this
395
interface.
592
The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
593
\ref cplex, \ref soplex.
396 594
*/
397 595

	
398 596
/**
399 597
@defgroup lp_utils Tools for Lp and Mip Solvers
400 598
@ingroup lp_group
401 599
\brief Helper tools to the Lp and Mip solvers.
402 600

	
403 601
This group adds some helper tools to general optimization framework
404 602
implemented in LEMON.
405 603
*/
406 604

	
407 605
/**
408 606
@defgroup metah Metaheuristics
409 607
@ingroup gen_opt_group
410 608
\brief Metaheuristics for LEMON library.
411 609

	
412
This group describes some metaheuristic optimization tools.
610
This group contains some metaheuristic optimization tools.
413 611
*/
414 612

	
415 613
/**
416 614
@defgroup utils Tools and Utilities
417 615
\brief Tools and utilities for programming in LEMON
418 616

	
419 617
Tools and utilities for programming in LEMON.
420 618
*/
421 619

	
422 620
/**
423 621
@defgroup gutils Basic Graph Utilities
424 622
@ingroup utils
425 623
\brief Simple basic graph utilities.
426 624

	
427
This group describes some simple basic graph utilities.
625
This group contains some simple basic graph utilities.
428 626
*/
429 627

	
430 628
/**
431 629
@defgroup misc Miscellaneous Tools
432 630
@ingroup utils
433 631
\brief Tools for development, debugging and testing.
434 632

	
435
This group describes several useful tools for development,
633
This group contains several useful tools for development,
436 634
debugging and testing.
437 635
*/
438 636

	
439 637
/**
440 638
@defgroup timecount Time Measuring and Counting
441 639
@ingroup misc
442 640
\brief Simple tools for measuring the performance of algorithms.
443 641

	
444
This group describes simple tools for measuring the performance
642
This group contains simple tools for measuring the performance
445 643
of algorithms.
446 644
*/
447 645

	
448 646
/**
449 647
@defgroup exceptions Exceptions
450 648
@ingroup utils
451 649
\brief Exceptions defined in LEMON.
452 650

	
453
This group describes the exceptions defined in LEMON.
651
This group contains the exceptions defined in LEMON.
454 652
*/
455 653

	
456 654
/**
457 655
@defgroup io_group Input-Output
458 656
\brief Graph Input-Output methods
459 657

	
460
This group describes the tools for importing and exporting graphs
658
This group contains the tools for importing and exporting graphs
461 659
and graph related data. Now it supports the \ref lgf-format
462 660
"LEMON Graph Format", the \c DIMACS format and the encapsulated
463 661
postscript (EPS) format.
464 662
*/
465 663

	
466 664
/**
467
@defgroup lemon_io LEMON Input-Output
665
@defgroup lemon_io LEMON Graph Format
468 666
@ingroup io_group
469 667
\brief Reading and writing LEMON Graph Format.
470 668

	
471
This group describes methods for reading and writing
669
This group contains methods for reading and writing
472 670
\ref lgf-format "LEMON Graph Format".
473 671
*/
474 672

	
475 673
/**
476 674
@defgroup eps_io Postscript Exporting
477 675
@ingroup io_group
478 676
\brief General \c EPS drawer and graph exporter
479 677

	
480
This group describes general \c EPS drawing methods and special
678
This group contains general \c EPS drawing methods and special
481 679
graph exporting tools.
482 680
*/
483 681

	
484 682
/**
683
@defgroup dimacs_group DIMACS Format
684
@ingroup io_group
685
\brief Read and write files in DIMACS format
686

	
687
Tools to read a digraph from or write it to a file in DIMACS format data.
688
*/
689

	
690
/**
691
@defgroup nauty_group NAUTY Format
692
@ingroup io_group
693
\brief Read \e Nauty format
694

	
695
Tool to read graphs from \e Nauty format data.
696
*/
697

	
698
/**
485 699
@defgroup concept Concepts
486 700
\brief Skeleton classes and concept checking classes
487 701

	
488
This group describes the data/algorithm skeletons and concept checking
702
This group contains the data/algorithm skeletons and concept checking
489 703
classes implemented in LEMON.
490 704

	
491 705
The purpose of the classes in this group is fourfold.
492 706

	
493 707
- These classes contain the documentations of the %concepts. In order
494 708
  to avoid document multiplications, an implementation of a concept
495 709
  simply refers to the corresponding concept class.
496 710

	
497 711
- These classes declare every functions, <tt>typedef</tt>s etc. an
498 712
  implementation of the %concepts should provide, however completely
499 713
  without implementations and real data structures behind the
500 714
  interface. On the other hand they should provide nothing else. All
501 715
  the algorithms working on a data structure meeting a certain concept
502 716
  should compile with these classes. (Though it will not run properly,
503 717
  of course.) In this way it is easily to check if an algorithm
504 718
  doesn't use any extra feature of a certain implementation.
505 719

	
506 720
- The concept descriptor classes also provide a <em>checker class</em>
507 721
  that makes it possible to check whether a certain implementation of a
508 722
  concept indeed provides all the required features.
509 723

	
510 724
- Finally, They can serve as a skeleton of a new implementation of a concept.
511 725
*/
512 726

	
513 727
/**
514 728
@defgroup graph_concepts Graph Structure Concepts
515 729
@ingroup concept
516 730
\brief Skeleton and concept checking classes for graph structures
517 731

	
518
This group describes the skeletons and concept checking classes of LEMON's
519
graph structures and helper classes used to implement these.
732
This group contains the skeletons and concept checking classes of
733
graph structures.
520 734
*/
521 735

	
522 736
/**
523 737
@defgroup map_concepts Map Concepts
524 738
@ingroup concept
525 739
\brief Skeleton and concept checking classes for maps
526 740

	
527
This group describes the skeletons and concept checking classes of maps.
741
This group contains the skeletons and concept checking classes of maps.
528 742
*/
529 743

	
530 744
/**
531
\anchor demoprograms
532

	
533
@defgroup demos Demo programs
534

	
535
Some demo programs are listed here. Their full source codes can be found in
536
the \c demo subdirectory of the source tree.
537

	
538
It order to compile them, use <tt>--enable-demo</tt> configure option when
539
build the library.
540
*/
541

	
542
/**
543
@defgroup tools Standalone utility applications
745
@defgroup tools Standalone Utility Applications
544 746

	
545 747
Some utility applications are listed here.
546 748

	
547 749
The standard compilation procedure (<tt>./configure;make</tt>) will compile
548 750
them, as well.
549 751
*/
550 752

	
753
/**
754
\anchor demoprograms
755

	
756
@defgroup demos Demo Programs
757

	
758
Some demo programs are listed here. Their full source codes can be found in
759
the \c demo subdirectory of the source tree.
760

	
761
In order to compile them, use the <tt>make demo</tt> or the
762
<tt>make check</tt> commands.
763
*/
764

	
765
}
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
\subsection whatis What is LEMON
25

	
26
LEMON stands for
27
<b>L</b>ibrary of <b>E</b>fficient <b>M</b>odels
28
and <b>O</b>ptimization in <b>N</b>etworks.
29
It is a C++ template
30
library aimed at combinatorial optimization tasks which
31
often involve in working
32
with graphs.
24
<b>LEMON</b> stands for <i><b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
25
and <b>O</b>ptimization in <b>N</b>etworks</i>.
26
It is a C++ template library providing efficient implementation of common
27
data structures and algorithms with focus on combinatorial optimization
28
problems in graphs and networks.
33 29

	
34 30
<b>
35 31
LEMON is an <a class="el" href="http://opensource.org/">open&nbsp;source</a>
36 32
project.
37 33
You are free to use it in your commercial or
38 34
non-commercial applications under very permissive
39 35
\ref license "license terms".
40 36
</b>
41 37

	
42
\subsection howtoread How to read the documentation
38
The project is maintained by the 
39
<a href="http://www.cs.elte.hu/egres/">Egerv&aacute;ry Research Group on
40
Combinatorial Optimization</a> \ref egres
41
at the Operations Research Department of the
42
<a href="http://www.elte.hu/">E&ouml;tv&ouml;s Lor&aacute;nd University,
43
Budapest</a>, Hungary.
44
LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
45
initiative \ref coinor.
43 46

	
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.
47
\section howtoread How to Read the Documentation
47 48

	
48
If you already feel like using our library, see the page that tells you
49
\ref getstart "How to start using LEMON".
49
If you would like to get to know the library, see
50
<a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
50 51

	
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.
52
If you know what you are looking for, then try to find it under the
53
<a class="el" href="modules.html">Modules</a> section.
58 54

	
59 55
If you are a user of the old (0.x) series of LEMON, please check out the
60 56
\ref migration "Migration Guide" for the backward incompatibilities.
61 57
*/
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 1536 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/bellman_ford.h \
61
	lemon/bfs.h \
62
	lemon/bin_heap.h \
63
	lemon/binom_heap.h \
64
	lemon/bucket_heap.h \
65
	lemon/cbc.h \
66
	lemon/circulation.h \
67
	lemon/clp.h \
68
	lemon/color.h \
27 69
	lemon/concept_check.h \
28
        lemon/counter.h \
70
	lemon/connectivity.h \
71
	lemon/counter.h \
29 72
	lemon/core.h \
30
        lemon/dfs.h \
31
        lemon/dijkstra.h \
32
        lemon/dim2.h \
73
	lemon/cplex.h \
74
	lemon/dfs.h \
75
	lemon/dijkstra.h \
76
	lemon/dim2.h \
77
	lemon/dimacs.h \
78
	lemon/edge_set.h \
79
	lemon/elevator.h \
33 80
	lemon/error.h \
34
        lemon/graph_to_eps.h \
81
	lemon/euler.h \
82
	lemon/fib_heap.h \
83
	lemon/fourary_heap.h \
84
	lemon/full_graph.h \
85
	lemon/glpk.h \
86
	lemon/gomory_hu.h \
87
	lemon/graph_to_eps.h \
88
	lemon/grid_graph.h \
89
	lemon/hartmann_orlin.h \
90
	lemon/howard.h \
91
	lemon/hypercube_graph.h \
92
	lemon/karp.h \
93
	lemon/kary_heap.h \
35 94
	lemon/kruskal.h \
95
	lemon/hao_orlin.h \
36 96
	lemon/lgf_reader.h \
37 97
	lemon/lgf_writer.h \
38 98
	lemon/list_graph.h \
99
	lemon/lp.h \
100
	lemon/lp_base.h \
101
	lemon/lp_skeleton.h \
39 102
	lemon/maps.h \
103
	lemon/matching.h \
40 104
	lemon/math.h \
105
	lemon/min_cost_arborescence.h \
106
	lemon/nauty_reader.h \
107
	lemon/network_simplex.h \
108
	lemon/pairing_heap.h \
41 109
	lemon/path.h \
42
        lemon/random.h \
110
	lemon/preflow.h \
111
	lemon/radix_heap.h \
112
	lemon/radix_sort.h \
113
	lemon/random.h \
43 114
	lemon/smart_graph.h \
44
        lemon/time_measure.h \
45
        lemon/tolerance.h \
115
	lemon/soplex.h \
116
	lemon/static_graph.h \
117
	lemon/suurballe.h \
118
	lemon/time_measure.h \
119
	lemon/tolerance.h \
46 120
	lemon/unionfind.h \
47 121
	lemon/bits/windows.h
48 122

	
49 123
bits_HEADERS += \
50 124
	lemon/bits/alteration_notifier.h \
51 125
	lemon/bits/array_map.h \
52
	lemon/bits/base_extender.h \
53
        lemon/bits/bezier.h \
126
	lemon/bits/bezier.h \
54 127
	lemon/bits/default_map.h \
55
        lemon/bits/enable_if.h \
128
	lemon/bits/edge_set_extender.h \
129
	lemon/bits/enable_if.h \
130
	lemon/bits/graph_adaptor_extender.h \
56 131
	lemon/bits/graph_extender.h \
57 132
	lemon/bits/map_extender.h \
58 133
	lemon/bits/path_dump.h \
134
	lemon/bits/solver_bits.h \
59 135
	lemon/bits/traits.h \
136
	lemon/bits/variant.h \
60 137
	lemon/bits/vector_map.h
61 138

	
62 139
concept_HEADERS += \
63 140
	lemon/concepts/digraph.h \
64 141
	lemon/concepts/graph.h \
65 142
	lemon/concepts/graph_components.h \
66 143
	lemon/concepts/heap.h \
67 144
	lemon/concepts/maps.h \
68 145
	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
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
50
    ///It must conform to 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
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
65
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
66
    ///By default it is a NullMap.
66 67
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
67
    ///Instantiates a ProcessedMap.
68
    ///Instantiates a \c ProcessedMap.
68 69

	
69
    ///This function instantiates a ProcessedMap.
70
    ///This function instantiates a \ref ProcessedMap.
70 71
    ///\param g is the digraph, to which
71
    ///we would like to define the ProcessedMap
72
    ///we would like to define the \ref ProcessedMap
72 73
#ifdef DOXYGEN
73 74
    static ProcessedMap *createProcessedMap(const Digraph &g)
74 75
#else
75 76
    static ProcessedMap *createProcessedMap(const Digraph &)
76 77
#endif
77 78
    {
78 79
      return new ProcessedMap();
79 80
    }
80 81

	
81 82
    ///The type of the map that indicates which nodes are reached.
82 83

	
83 84
    ///The type of the map that indicates which nodes are reached.
84
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
85
    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
85 86
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
86
    ///Instantiates a ReachedMap.
87
    ///Instantiates a \c ReachedMap.
87 88

	
88
    ///This function instantiates a ReachedMap.
89
    ///This function instantiates a \ref ReachedMap.
89 90
    ///\param g is the digraph, to which
90
    ///we would like to define the ReachedMap.
91
    ///we would like to define the \ref ReachedMap.
91 92
    static ReachedMap *createReachedMap(const Digraph &g)
92 93
    {
93 94
      return new ReachedMap(g);
94 95
    }
95 96

	
96 97
    ///The type of the map that stores the distances of the nodes.
97 98

	
98 99
    ///The type of the map that stores the distances of the nodes.
99
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
100
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
100 101
    typedef typename Digraph::template NodeMap<int> DistMap;
101
    ///Instantiates a DistMap.
102
    ///Instantiates a \c DistMap.
102 103

	
103
    ///This function instantiates a DistMap.
104
    ///This function instantiates a \ref DistMap.
104 105
    ///\param g is the digraph, to which we would like to define the
105
    ///DistMap.
106
    ///\ref DistMap.
106 107
    static DistMap *createDistMap(const Digraph &g)
107 108
    {
108 109
      return new DistMap(g);
109 110
    }
110 111
  };
111 112

	
112 113
  ///%BFS algorithm class.
113 114

	
114 115
  ///\ingroup search
115 116
  ///This class provides an efficient implementation of the %BFS algorithm.
116 117
  ///
117 118
  ///There is also a \ref bfs() "function-type interface" for the BFS
118 119
  ///algorithm, which is convenient in the simplier cases and it can be
119 120
  ///used easier.
120 121
  ///
121 122
  ///\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.
123
  ///The default type is \ref ListDigraph.
129 124
#ifdef DOXYGEN
130 125
  template <typename GR,
131 126
            typename TR>
132 127
#else
133 128
  template <typename GR=ListDigraph,
134 129
            typename TR=BfsDefaultTraits<GR> >
135 130
#endif
136 131
  class Bfs {
137 132
  public:
138 133

	
139 134
    ///The type of the digraph the algorithm runs on.
140 135
    typedef typename TR::Digraph Digraph;
141 136

	
142 137
    ///\brief The type of the map that stores the predecessor arcs of the
143 138
    ///shortest paths.
144 139
    typedef typename TR::PredMap PredMap;
145 140
    ///The type of the map that stores the distances of the nodes.
146 141
    typedef typename TR::DistMap DistMap;
147 142
    ///The type of the map that indicates which nodes are reached.
148 143
    typedef typename TR::ReachedMap ReachedMap;
149 144
    ///The type of the map that indicates which nodes are processed.
150 145
    typedef typename TR::ProcessedMap ProcessedMap;
151 146
    ///The type of the paths.
152 147
    typedef PredMapPath<Digraph, PredMap> Path;
153 148

	
154
    ///The traits class.
149
    ///The \ref BfsDefaultTraits "traits class" of the algorithm.
155 150
    typedef TR Traits;
156 151

	
157 152
  private:
158 153

	
159 154
    typedef typename Digraph::Node Node;
160 155
    typedef typename Digraph::NodeIt NodeIt;
161 156
    typedef typename Digraph::Arc Arc;
162 157
    typedef typename Digraph::OutArcIt OutArcIt;
163 158

	
164 159
    //Pointer to the underlying digraph.
165 160
    const Digraph *G;
166 161
    //Pointer to the map of predecessor arcs.
167 162
    PredMap *_pred;
168 163
    //Indicates if _pred is locally allocated (true) or not.
169 164
    bool local_pred;
170 165
    //Pointer to the map of distances.
171 166
    DistMap *_dist;
172 167
    //Indicates if _dist is locally allocated (true) or not.
173 168
    bool local_dist;
174 169
    //Pointer to the map of reached status of the nodes.
175 170
    ReachedMap *_reached;
176 171
    //Indicates if _reached is locally allocated (true) or not.
177 172
    bool local_reached;
178 173
    //Pointer to the map of processed status of the nodes.
179 174
    ProcessedMap *_processed;
180 175
    //Indicates if _processed is locally allocated (true) or not.
181 176
    bool local_processed;
182 177

	
183 178
    std::vector<typename Digraph::Node> _queue;
184 179
    int _queue_head,_queue_tail,_queue_next_dist;
185 180
    int _curr_dist;
186 181

	
187 182
    //Creates the maps if necessary.
188 183
    void create_maps()
189 184
    {
190 185
      if(!_pred) {
191 186
        local_pred = true;
192 187
        _pred = Traits::createPredMap(*G);
193 188
      }
194 189
      if(!_dist) {
195 190
        local_dist = true;
196 191
        _dist = Traits::createDistMap(*G);
197 192
      }
198 193
      if(!_reached) {
199 194
        local_reached = true;
200 195
        _reached = Traits::createReachedMap(*G);
201 196
      }
202 197
      if(!_processed) {
203 198
        local_processed = true;
204 199
        _processed = Traits::createProcessedMap(*G);
205 200
      }
206 201
    }
207 202

	
208 203
  protected:
209 204

	
210 205
    Bfs() {}
211 206

	
212 207
  public:
213 208

	
214 209
    typedef Bfs Create;
215 210

	
216
    ///\name Named template parameters
211
    ///\name Named Template Parameters
217 212

	
218 213
    ///@{
219 214

	
220 215
    template <class T>
221 216
    struct SetPredMapTraits : public Traits {
222 217
      typedef T PredMap;
223 218
      static PredMap *createPredMap(const Digraph &)
224 219
      {
225 220
        LEMON_ASSERT(false, "PredMap is not initialized");
226 221
        return 0; // ignore warnings
227 222
      }
228 223
    };
229 224
    ///\brief \ref named-templ-param "Named parameter" for setting
230
    ///PredMap type.
225
    ///\c PredMap type.
231 226
    ///
232 227
    ///\ref named-templ-param "Named parameter" for setting
233
    ///PredMap type.
228
    ///\c PredMap type.
229
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
234 230
    template <class T>
235 231
    struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
236 232
      typedef Bfs< Digraph, SetPredMapTraits<T> > Create;
237 233
    };
238 234

	
239 235
    template <class T>
240 236
    struct SetDistMapTraits : public Traits {
241 237
      typedef T DistMap;
242 238
      static DistMap *createDistMap(const Digraph &)
243 239
      {
244 240
        LEMON_ASSERT(false, "DistMap is not initialized");
245 241
        return 0; // ignore warnings
246 242
      }
247 243
    };
248 244
    ///\brief \ref named-templ-param "Named parameter" for setting
249
    ///DistMap type.
245
    ///\c DistMap type.
250 246
    ///
251 247
    ///\ref named-templ-param "Named parameter" for setting
252
    ///DistMap type.
248
    ///\c DistMap type.
249
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
253 250
    template <class T>
254 251
    struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
255 252
      typedef Bfs< Digraph, SetDistMapTraits<T> > Create;
256 253
    };
257 254

	
258 255
    template <class T>
259 256
    struct SetReachedMapTraits : public Traits {
260 257
      typedef T ReachedMap;
261 258
      static ReachedMap *createReachedMap(const Digraph &)
262 259
      {
263 260
        LEMON_ASSERT(false, "ReachedMap is not initialized");
264 261
        return 0; // ignore warnings
265 262
      }
266 263
    };
267 264
    ///\brief \ref named-templ-param "Named parameter" for setting
268
    ///ReachedMap type.
265
    ///\c ReachedMap type.
269 266
    ///
270 267
    ///\ref named-templ-param "Named parameter" for setting
271
    ///ReachedMap type.
268
    ///\c ReachedMap type.
269
    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
272 270
    template <class T>
273 271
    struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
274 272
      typedef Bfs< Digraph, SetReachedMapTraits<T> > Create;
275 273
    };
276 274

	
277 275
    template <class T>
278 276
    struct SetProcessedMapTraits : public Traits {
279 277
      typedef T ProcessedMap;
280 278
      static ProcessedMap *createProcessedMap(const Digraph &)
281 279
      {
282 280
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
283 281
        return 0; // ignore warnings
284 282
      }
285 283
    };
286 284
    ///\brief \ref named-templ-param "Named parameter" for setting
287
    ///ProcessedMap type.
285
    ///\c ProcessedMap type.
288 286
    ///
289 287
    ///\ref named-templ-param "Named parameter" for setting
290
    ///ProcessedMap type.
288
    ///\c ProcessedMap type.
289
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
291 290
    template <class T>
292 291
    struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
293 292
      typedef Bfs< Digraph, SetProcessedMapTraits<T> > Create;
294 293
    };
295 294

	
296 295
    struct SetStandardProcessedMapTraits : public Traits {
297 296
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
298 297
      static ProcessedMap *createProcessedMap(const Digraph &g)
299 298
      {
300 299
        return new ProcessedMap(g);
301 300
        return 0; // ignore warnings
302 301
      }
303 302
    };
304 303
    ///\brief \ref named-templ-param "Named parameter" for setting
305
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
304
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
306 305
    ///
307 306
    ///\ref named-templ-param "Named parameter" for setting
308
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
307
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
309 308
    ///If you don't set it explicitly, it will be automatically allocated.
310 309
    struct SetStandardProcessedMap :
311 310
      public Bfs< Digraph, SetStandardProcessedMapTraits > {
312 311
      typedef Bfs< Digraph, SetStandardProcessedMapTraits > Create;
313 312
    };
314 313

	
315 314
    ///@}
316 315

	
317 316
  public:
318 317

	
319 318
    ///Constructor.
320 319

	
321 320
    ///Constructor.
322 321
    ///\param g The digraph the algorithm runs on.
323 322
    Bfs(const Digraph &g) :
324 323
      G(&g),
325 324
      _pred(NULL), local_pred(false),
326 325
      _dist(NULL), local_dist(false),
327 326
      _reached(NULL), local_reached(false),
328 327
      _processed(NULL), local_processed(false)
329 328
    { }
330 329

	
331 330
    ///Destructor.
332 331
    ~Bfs()
333 332
    {
334 333
      if(local_pred) delete _pred;
335 334
      if(local_dist) delete _dist;
336 335
      if(local_reached) delete _reached;
337 336
      if(local_processed) delete _processed;
338 337
    }
339 338

	
340 339
    ///Sets the map that stores the predecessor arcs.
341 340

	
342 341
    ///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.
342
    ///If you don't use this function before calling \ref run(Node) "run()"
343
    ///or \ref init(), an instance will be allocated automatically.
344
    ///The destructor deallocates this automatically allocated map,
345
    ///of course.
346 346
    ///\return <tt> (*this) </tt>
347 347
    Bfs &predMap(PredMap &m)
348 348
    {
349 349
      if(local_pred) {
350 350
        delete _pred;
351 351
        local_pred=false;
352 352
      }
353 353
      _pred = &m;
354 354
      return *this;
355 355
    }
356 356

	
357 357
    ///Sets the map that indicates which nodes are reached.
358 358

	
359 359
    ///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.
360
    ///If you don't use this function before calling \ref run(Node) "run()"
361
    ///or \ref init(), an instance will be allocated automatically.
362
    ///The destructor deallocates this automatically allocated map,
363
    ///of course.
363 364
    ///\return <tt> (*this) </tt>
364 365
    Bfs &reachedMap(ReachedMap &m)
365 366
    {
366 367
      if(local_reached) {
367 368
        delete _reached;
368 369
        local_reached=false;
369 370
      }
370 371
      _reached = &m;
371 372
      return *this;
372 373
    }
373 374

	
374 375
    ///Sets the map that indicates which nodes are processed.
375 376

	
376 377
    ///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.
378
    ///If you don't use this function before calling \ref run(Node) "run()"
379
    ///or \ref init(), an instance will be allocated automatically.
380
    ///The destructor deallocates this automatically allocated map,
381
    ///of course.
380 382
    ///\return <tt> (*this) </tt>
381 383
    Bfs &processedMap(ProcessedMap &m)
382 384
    {
383 385
      if(local_processed) {
384 386
        delete _processed;
385 387
        local_processed=false;
386 388
      }
387 389
      _processed = &m;
388 390
      return *this;
389 391
    }
390 392

	
391 393
    ///Sets the map that stores the distances of the nodes.
392 394

	
393 395
    ///Sets the map that stores the distances of the nodes calculated by
394 396
    ///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.
397
    ///If you don't use this function before calling \ref run(Node) "run()"
398
    ///or \ref init(), an instance will be allocated automatically.
399
    ///The destructor deallocates this automatically allocated map,
400
    ///of course.
398 401
    ///\return <tt> (*this) </tt>
399 402
    Bfs &distMap(DistMap &m)
400 403
    {
401 404
      if(local_dist) {
402 405
        delete _dist;
403 406
        local_dist=false;
404 407
      }
405 408
      _dist = &m;
406 409
      return *this;
407 410
    }
408 411

	
409 412
  public:
410 413

	
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.
414
    ///\name Execution Control
415
    ///The simplest way to execute the BFS algorithm is to use one of the
416
    ///member functions called \ref run(Node) "run()".\n
417
    ///If you need better control on the execution, you have to call
418
    ///\ref init() first, then you can add several source nodes with
419
    ///\ref addSource(). Finally the actual path computation can be
420
    ///performed with one of the \ref start() functions.
420 421

	
421 422
    ///@{
422 423

	
424
    ///\brief Initializes the internal data structures.
425
    ///
423 426
    ///Initializes the internal data structures.
424

	
425
    ///Initializes the internal data structures.
426
    ///
427 427
    void init()
428 428
    {
429 429
      create_maps();
430 430
      _queue.resize(countNodes(*G));
431 431
      _queue_head=_queue_tail=0;
432 432
      _curr_dist=1;
433 433
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
434 434
        _pred->set(u,INVALID);
435 435
        _reached->set(u,false);
436 436
        _processed->set(u,false);
437 437
      }
438 438
    }
439 439

	
440 440
    ///Adds a new source node.
441 441

	
442 442
    ///Adds a new source node to the set of nodes to be processed.
443 443
    ///
444 444
    void addSource(Node s)
445 445
    {
446 446
      if(!(*_reached)[s])
447 447
        {
448 448
          _reached->set(s,true);
449 449
          _pred->set(s,INVALID);
450 450
          _dist->set(s,0);
451 451
          _queue[_queue_head++]=s;
452 452
          _queue_next_dist=_queue_head;
453 453
        }
454 454
    }
455 455

	
456 456
    ///Processes the next node.
457 457

	
458 458
    ///Processes the next node.
459 459
    ///
460 460
    ///\return The processed node.
461 461
    ///
462 462
    ///\pre The queue must not be empty.
463 463
    Node processNextNode()
464 464
    {
465 465
      if(_queue_tail==_queue_next_dist) {
466 466
        _curr_dist++;
467 467
        _queue_next_dist=_queue_head;
468 468
      }
469 469
      Node n=_queue[_queue_tail++];
470 470
      _processed->set(n,true);
471 471
      Node m;
472 472
      for(OutArcIt e(*G,n);e!=INVALID;++e)
473 473
        if(!(*_reached)[m=G->target(e)]) {
474 474
          _queue[_queue_head++]=m;
475 475
          _reached->set(m,true);
476 476
          _pred->set(m,e);
477 477
          _dist->set(m,_curr_dist);
478 478
        }
479 479
      return n;
480 480
    }
481 481

	
482 482
    ///Processes the next node.
483 483

	
484 484
    ///Processes the next node and checks if the given target node
485 485
    ///is reached. If the target node is reachable from the processed
486 486
    ///node, then the \c reach parameter will be set to \c true.
487 487
    ///
488 488
    ///\param target The target node.
489 489
    ///\retval reach Indicates if the target node is reached.
490 490
    ///It should be initially \c false.
491 491
    ///
492 492
    ///\return The processed node.
493 493
    ///
494 494
    ///\pre The queue must not be empty.
495 495
    Node processNextNode(Node target, bool& reach)
496 496
    {
497 497
      if(_queue_tail==_queue_next_dist) {
498 498
        _curr_dist++;
499 499
        _queue_next_dist=_queue_head;
500 500
      }
501 501
      Node n=_queue[_queue_tail++];
502 502
      _processed->set(n,true);
503 503
      Node m;
504 504
      for(OutArcIt e(*G,n);e!=INVALID;++e)
505 505
        if(!(*_reached)[m=G->target(e)]) {
506 506
          _queue[_queue_head++]=m;
507 507
          _reached->set(m,true);
508 508
          _pred->set(m,e);
509 509
          _dist->set(m,_curr_dist);
510 510
          reach = reach || (target == m);
511 511
        }
512 512
      return n;
513 513
    }
514 514

	
515 515
    ///Processes the next node.
516 516

	
517 517
    ///Processes the next node and checks if at least one of reached
518 518
    ///nodes has \c true value in the \c nm node map. If one node
519 519
    ///with \c true value is reachable from the processed node, then the
520 520
    ///\c rnode parameter will be set to the first of such nodes.
521 521
    ///
522 522
    ///\param nm A \c bool (or convertible) node map that indicates the
523 523
    ///possible targets.
524 524
    ///\retval rnode The reached target node.
525 525
    ///It should be initially \c INVALID.
526 526
    ///
527 527
    ///\return The processed node.
528 528
    ///
529 529
    ///\pre The queue must not be empty.
530 530
    template<class NM>
531 531
    Node processNextNode(const NM& nm, Node& rnode)
532 532
    {
533 533
      if(_queue_tail==_queue_next_dist) {
534 534
        _curr_dist++;
535 535
        _queue_next_dist=_queue_head;
536 536
      }
537 537
      Node n=_queue[_queue_tail++];
538 538
      _processed->set(n,true);
539 539
      Node m;
540 540
      for(OutArcIt e(*G,n);e!=INVALID;++e)
541 541
        if(!(*_reached)[m=G->target(e)]) {
542 542
          _queue[_queue_head++]=m;
543 543
          _reached->set(m,true);
544 544
          _pred->set(m,e);
545 545
          _dist->set(m,_curr_dist);
546 546
          if (nm[m] && rnode == INVALID) rnode = m;
547 547
        }
548 548
      return n;
549 549
    }
550 550

	
551 551
    ///The next node to be processed.
552 552

	
553 553
    ///Returns the next node to be processed or \c INVALID if the queue
554 554
    ///is empty.
555 555
    Node nextNode() const
556 556
    {
557 557
      return _queue_tail<_queue_head?_queue[_queue_tail]:INVALID;
558 558
    }
559 559

	
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.
560
    ///Returns \c false if there are nodes to be processed.
561

	
562
    ///Returns \c false if there are nodes to be processed
563
    ///in the queue.
565 564
    bool emptyQueue() const { return _queue_tail==_queue_head; }
566 565

	
567 566
    ///Returns the number of the nodes to be processed.
568 567

	
569
    ///Returns the number of the nodes to be processed in the queue.
568
    ///Returns the number of the nodes to be processed
569
    ///in the queue.
570 570
    int queueSize() const { return _queue_head-_queue_tail; }
571 571

	
572 572
    ///Executes the algorithm.
573 573

	
574 574
    ///Executes the algorithm.
575 575
    ///
576 576
    ///This method runs the %BFS algorithm from the root node(s)
577 577
    ///in order to compute the shortest path to each node.
578 578
    ///
579 579
    ///The algorithm computes
580 580
    ///- the shortest path tree (forest),
581 581
    ///- the distance of each node from the root(s).
582 582
    ///
583 583
    ///\pre init() must be called and at least one root node should be
584 584
    ///added with addSource() before using this function.
585 585
    ///
586 586
    ///\note <tt>b.start()</tt> is just a shortcut of the following code.
587 587
    ///\code
588 588
    ///  while ( !b.emptyQueue() ) {
589 589
    ///    b.processNextNode();
590 590
    ///  }
591 591
    ///\endcode
592 592
    void start()
593 593
    {
594 594
      while ( !emptyQueue() ) processNextNode();
595 595
    }
596 596

	
597 597
    ///Executes the algorithm until the given target node is reached.
598 598

	
599 599
    ///Executes the algorithm until the given target node is reached.
600 600
    ///
601 601
    ///This method runs the %BFS algorithm from the root node(s)
602 602
    ///in order to compute the shortest path to \c t.
603 603
    ///
604 604
    ///The algorithm computes
605 605
    ///- the shortest path to \c t,
606 606
    ///- the distance of \c t from the root(s).
607 607
    ///
608 608
    ///\pre init() must be called and at least one root node should be
609 609
    ///added with addSource() before using this function.
610 610
    ///
611 611
    ///\note <tt>b.start(t)</tt> is just a shortcut of the following code.
612 612
    ///\code
613 613
    ///  bool reach = false;
614 614
    ///  while ( !b.emptyQueue() && !reach ) {
615 615
    ///    b.processNextNode(t, reach);
616 616
    ///  }
617 617
    ///\endcode
618 618
    void start(Node t)
619 619
    {
620 620
      bool reach = false;
621 621
      while ( !emptyQueue() && !reach ) processNextNode(t, reach);
622 622
    }
623 623

	
624 624
    ///Executes the algorithm until a condition is met.
625 625

	
626 626
    ///Executes the algorithm until a condition is met.
627 627
    ///
628 628
    ///This method runs the %BFS algorithm from the root node(s) in
629 629
    ///order to compute the shortest path to a node \c v with
630 630
    /// <tt>nm[v]</tt> true, if such a node can be found.
631 631
    ///
632 632
    ///\param nm A \c bool (or convertible) node map. The algorithm
633 633
    ///will stop when it reaches a node \c v with <tt>nm[v]</tt> true.
634 634
    ///
635 635
    ///\return The reached node \c v with <tt>nm[v]</tt> true or
636 636
    ///\c INVALID if no such node was found.
637 637
    ///
638 638
    ///\pre init() must be called and at least one root node should be
639 639
    ///added with addSource() before using this function.
640 640
    ///
641 641
    ///\note <tt>b.start(nm)</tt> is just a shortcut of the following code.
642 642
    ///\code
643 643
    ///  Node rnode = INVALID;
644 644
    ///  while ( !b.emptyQueue() && rnode == INVALID ) {
645 645
    ///    b.processNextNode(nm, rnode);
646 646
    ///  }
647 647
    ///  return rnode;
648 648
    ///\endcode
649 649
    template<class NodeBoolMap>
650 650
    Node start(const NodeBoolMap &nm)
651 651
    {
652 652
      Node rnode = INVALID;
653 653
      while ( !emptyQueue() && rnode == INVALID ) {
654 654
        processNextNode(nm, rnode);
655 655
      }
656 656
      return rnode;
657 657
    }
658 658

	
659 659
    ///Runs the algorithm from the given source node.
660 660

	
661 661
    ///This method runs the %BFS algorithm from node \c s
662 662
    ///in order to compute the shortest path to each node.
663 663
    ///
664 664
    ///The algorithm computes
665 665
    ///- the shortest path tree,
666 666
    ///- the distance of each node from the root.
667 667
    ///
668 668
    ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
669 669
    ///\code
670 670
    ///  b.init();
671 671
    ///  b.addSource(s);
672 672
    ///  b.start();
673 673
    ///\endcode
674 674
    void run(Node s) {
675 675
      init();
676 676
      addSource(s);
677 677
      start();
678 678
    }
679 679

	
680 680
    ///Finds the shortest path between \c s and \c t.
681 681

	
682 682
    ///This method runs the %BFS algorithm from node \c s
683 683
    ///in order to compute the shortest path to node \c t
684 684
    ///(it stops searching when \c t is processed).
685 685
    ///
686 686
    ///\return \c true if \c t is reachable form \c s.
687 687
    ///
688 688
    ///\note Apart from the return value, <tt>b.run(s,t)</tt> is just a
689 689
    ///shortcut of the following code.
690 690
    ///\code
691 691
    ///  b.init();
692 692
    ///  b.addSource(s);
693 693
    ///  b.start(t);
694 694
    ///\endcode
695 695
    bool run(Node s,Node t) {
696 696
      init();
697 697
      addSource(s);
698 698
      start(t);
699 699
      return reached(t);
700 700
    }
701 701

	
702 702
    ///Runs the algorithm to visit all nodes in the digraph.
703 703

	
704 704
    ///This method runs the %BFS algorithm in order to
705 705
    ///compute the shortest path to each node.
706 706
    ///
707 707
    ///The algorithm computes
708 708
    ///- the shortest path tree (forest),
709 709
    ///- the distance of each node from the root(s).
710 710
    ///
711 711
    ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
712 712
    ///\code
713 713
    ///  b.init();
714 714
    ///  for (NodeIt n(gr); n != INVALID; ++n) {
715 715
    ///    if (!b.reached(n)) {
716 716
    ///      b.addSource(n);
717 717
    ///      b.start();
718 718
    ///    }
719 719
    ///  }
720 720
    ///\endcode
721 721
    void run() {
722 722
      init();
723 723
      for (NodeIt n(*G); n != INVALID; ++n) {
724 724
        if (!reached(n)) {
725 725
          addSource(n);
726 726
          start();
727 727
        }
728 728
      }
729 729
    }
730 730

	
731 731
    ///@}
732 732

	
733 733
    ///\name Query Functions
734
    ///The result of the %BFS algorithm can be obtained using these
734
    ///The results of the BFS algorithm can be obtained using these
735 735
    ///functions.\n
736
    ///Either \ref lemon::Bfs::run() "run()" or \ref lemon::Bfs::start()
737
    ///"start()" must be called before using them.
736
    ///Either \ref run(Node) "run()" or \ref start() should be called
737
    ///before using them.
738 738

	
739 739
    ///@{
740 740

	
741
    ///The shortest path to a node.
741
    ///The shortest path to the given node.
742 742

	
743
    ///Returns the shortest path to a node.
743
    ///Returns the shortest path to the given node from the root(s).
744 744
    ///
745
    ///\warning \c t should be reachable from the root(s).
745
    ///\warning \c t should be reached from the root(s).
746 746
    ///
747
    ///\pre Either \ref run() or \ref start() must be called before
748
    ///using this function.
747
    ///\pre Either \ref run(Node) "run()" or \ref init()
748
    ///must be called before using this function.
749 749
    Path path(Node t) const { return Path(*G, *_pred, t); }
750 750

	
751
    ///The distance of a node from the root(s).
751
    ///The distance of the given node from the root(s).
752 752

	
753
    ///Returns the distance of a node from the root(s).
753
    ///Returns the distance of the given node from the root(s).
754 754
    ///
755
    ///\warning If node \c v is not reachable from the root(s), then
755
    ///\warning If node \c v is not reached from the root(s), then
756 756
    ///the return value of this function is undefined.
757 757
    ///
758
    ///\pre Either \ref run() or \ref start() must be called before
759
    ///using this function.
758
    ///\pre Either \ref run(Node) "run()" or \ref init()
759
    ///must be called before using this function.
760 760
    int dist(Node v) const { return (*_dist)[v]; }
761 761

	
762
    ///Returns the 'previous arc' of the shortest path tree for a node.
763

	
762
    ///\brief Returns the 'previous arc' of the shortest path tree for
763
    ///the given node.
764
    ///
764 765
    ///This function returns the 'previous arc' of the shortest path
765 766
    ///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.
767
    ///shortest path from a root to \c v. It is \c INVALID if \c v
768
    ///is not reached from the root(s) or if \c v is a root.
768 769
    ///
769 770
    ///The shortest path tree used here is equal to the shortest path
770
    ///tree used in \ref predNode().
771
    ///tree used in \ref predNode() and \ref predMap().
771 772
    ///
772
    ///\pre Either \ref run() or \ref start() must be called before
773
    ///using this function.
773
    ///\pre Either \ref run(Node) "run()" or \ref init()
774
    ///must be called before using this function.
774 775
    Arc predArc(Node v) const { return (*_pred)[v];}
775 776

	
776
    ///Returns the 'previous node' of the shortest path tree for a node.
777

	
777
    ///\brief Returns the 'previous node' of the shortest path tree for
778
    ///the given node.
779
    ///
778 780
    ///This function returns the 'previous node' of the shortest path
779 781
    ///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.
782
    ///of a shortest path from a root to \c v. It is \c INVALID
783
    ///if \c v is not reached from the root(s) or if \c v is a root.
782 784
    ///
783 785
    ///The shortest path tree used here is equal to the shortest path
784
    ///tree used in \ref predArc().
786
    ///tree used in \ref predArc() and \ref predMap().
785 787
    ///
786
    ///\pre Either \ref run() or \ref start() must be called before
787
    ///using this function.
788
    ///\pre Either \ref run(Node) "run()" or \ref init()
789
    ///must be called before using this function.
788 790
    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
789 791
                                  G->source((*_pred)[v]); }
790 792

	
791 793
    ///\brief Returns a const reference to the node map that stores the
792 794
    /// distances of the nodes.
793 795
    ///
794 796
    ///Returns a const reference to the node map that stores the distances
795 797
    ///of the nodes calculated by the algorithm.
796 798
    ///
797
    ///\pre Either \ref run() or \ref init()
799
    ///\pre Either \ref run(Node) "run()" or \ref init()
798 800
    ///must be called before using this function.
799 801
    const DistMap &distMap() const { return *_dist;}
800 802

	
801 803
    ///\brief Returns a const reference to the node map that stores the
802 804
    ///predecessor arcs.
803 805
    ///
804 806
    ///Returns a const reference to the node map that stores the predecessor
805
    ///arcs, which form the shortest path tree.
807
    ///arcs, which form the shortest path tree (forest).
806 808
    ///
807
    ///\pre Either \ref run() or \ref init()
809
    ///\pre Either \ref run(Node) "run()" or \ref init()
808 810
    ///must be called before using this function.
809 811
    const PredMap &predMap() const { return *_pred;}
810 812

	
811
    ///Checks if a node is reachable from the root(s).
813
    ///Checks if the given node is reached from the root(s).
812 814

	
813
    ///Returns \c true if \c v is reachable from the root(s).
814
    ///\pre Either \ref run() or \ref start()
815
    ///Returns \c true if \c v is reached from the root(s).
816
    ///
817
    ///\pre Either \ref run(Node) "run()" or \ref init()
815 818
    ///must be called before using this function.
816 819
    bool reached(Node v) const { return (*_reached)[v]; }
817 820

	
818 821
    ///@}
819 822
  };
820 823

	
821 824
  ///Default traits class of bfs() function.
822 825

	
823 826
  ///Default traits class of bfs() function.
824 827
  ///\tparam GR Digraph type.
825 828
  template<class GR>
826 829
  struct BfsWizardDefaultTraits
827 830
  {
828 831
    ///The type of the digraph the algorithm runs on.
829 832
    typedef GR Digraph;
830 833

	
831 834
    ///\brief The type of the map that stores the predecessor
832 835
    ///arcs of the shortest paths.
833 836
    ///
834 837
    ///The type of the map that stores the predecessor
835 838
    ///arcs of the shortest paths.
836
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
839
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
837 840
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
838 841
    ///Instantiates a PredMap.
839 842

	
840 843
    ///This function instantiates a PredMap.
841 844
    ///\param g is the digraph, to which we would like to define the
842 845
    ///PredMap.
843 846
    static PredMap *createPredMap(const Digraph &g)
844 847
    {
845 848
      return new PredMap(g);
846 849
    }
847 850

	
848 851
    ///The type of the map that indicates which nodes are processed.
849 852

	
850 853
    ///The type of the map that indicates which nodes are processed.
851
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
854
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
852 855
    ///By default it is a NullMap.
853 856
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
854 857
    ///Instantiates a ProcessedMap.
855 858

	
856 859
    ///This function instantiates a ProcessedMap.
857 860
    ///\param g is the digraph, to which
858 861
    ///we would like to define the ProcessedMap.
859 862
#ifdef DOXYGEN
860 863
    static ProcessedMap *createProcessedMap(const Digraph &g)
861 864
#else
862 865
    static ProcessedMap *createProcessedMap(const Digraph &)
863 866
#endif
864 867
    {
865 868
      return new ProcessedMap();
866 869
    }
867 870

	
868 871
    ///The type of the map that indicates which nodes are reached.
869 872

	
870 873
    ///The type of the map that indicates which nodes are reached.
871
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
874
    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
872 875
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
873 876
    ///Instantiates a ReachedMap.
874 877

	
875 878
    ///This function instantiates a ReachedMap.
876 879
    ///\param g is the digraph, to which
877 880
    ///we would like to define the ReachedMap.
878 881
    static ReachedMap *createReachedMap(const Digraph &g)
879 882
    {
880 883
      return new ReachedMap(g);
881 884
    }
882 885

	
883 886
    ///The type of the map that stores the distances of the nodes.
884 887

	
885 888
    ///The type of the map that stores the distances of the nodes.
886
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
889
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
887 890
    typedef typename Digraph::template NodeMap<int> DistMap;
888 891
    ///Instantiates a DistMap.
889 892

	
890 893
    ///This function instantiates a DistMap.
891 894
    ///\param g is the digraph, to which we would like to define
892 895
    ///the DistMap
893 896
    static DistMap *createDistMap(const Digraph &g)
894 897
    {
895 898
      return new DistMap(g);
896 899
    }
897 900

	
898 901
    ///The type of the shortest paths.
899 902

	
900 903
    ///The type of the shortest paths.
901
    ///It must meet the \ref concepts::Path "Path" concept.
904
    ///It must conform to the \ref concepts::Path "Path" concept.
902 905
    typedef lemon::Path<Digraph> Path;
903 906
  };
904 907

	
905 908
  /// Default traits class used by BfsWizard
906 909

	
907
  /// To make it easier to use Bfs algorithm
908
  /// we have created a wizard class.
909
  /// This \ref BfsWizard class needs default traits,
910
  /// as well as the \ref Bfs class.
911
  /// The \ref BfsWizardBase is a class to be the default traits of the
912
  /// \ref BfsWizard class.
910
  /// Default traits class used by BfsWizard.
911
  /// \tparam GR The type of the digraph.
913 912
  template<class GR>
914 913
  class BfsWizardBase : public BfsWizardDefaultTraits<GR>
915 914
  {
916 915

	
917 916
    typedef BfsWizardDefaultTraits<GR> Base;
918 917
  protected:
919 918
    //The type of the nodes in the digraph.
920 919
    typedef typename Base::Digraph::Node Node;
921 920

	
922 921
    //Pointer to the digraph the algorithm runs on.
923 922
    void *_g;
924 923
    //Pointer to the map of reached nodes.
925 924
    void *_reached;
926 925
    //Pointer to the map of processed nodes.
927 926
    void *_processed;
928 927
    //Pointer to the map of predecessors arcs.
929 928
    void *_pred;
930 929
    //Pointer to the map of distances.
931 930
    void *_dist;
932 931
    //Pointer to the shortest path to the target node.
933 932
    void *_path;
934 933
    //Pointer to the distance of the target node.
935 934
    int *_di;
936 935

	
937 936
    public:
938 937
    /// Constructor.
939 938

	
940
    /// This constructor does not require parameters, therefore it initiates
939
    /// This constructor does not require parameters, it initiates
941 940
    /// all of the attributes to \c 0.
942 941
    BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
943 942
                      _dist(0), _path(0), _di(0) {}
944 943

	
945 944
    /// Constructor.
946 945

	
947 946
    /// This constructor requires one parameter,
948 947
    /// others are initiated to \c 0.
949 948
    /// \param g The digraph the algorithm runs on.
950 949
    BfsWizardBase(const GR &g) :
951 950
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
952 951
      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
953 952

	
954 953
  };
955 954

	
956 955
  /// Auxiliary class for the function-type interface of BFS algorithm.
957 956

	
958 957
  /// This auxiliary class is created to implement the
959 958
  /// \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.
959
  /// It does not have own \ref run(Node) "run()" method, it uses the
960
  /// functions and features of the plain \ref Bfs.
962 961
  ///
963 962
  /// This class should only be used through the \ref bfs() function,
964 963
  /// which makes it easier to use the algorithm.
965 964
  template<class TR>
966 965
  class BfsWizard : public TR
967 966
  {
968 967
    typedef TR Base;
969 968

	
970
    ///The type of the digraph the algorithm runs on.
971 969
    typedef typename TR::Digraph Digraph;
972 970

	
973 971
    typedef typename Digraph::Node Node;
974 972
    typedef typename Digraph::NodeIt NodeIt;
975 973
    typedef typename Digraph::Arc Arc;
976 974
    typedef typename Digraph::OutArcIt OutArcIt;
977 975

	
978
    ///\brief The type of the map that stores the predecessor
979
    ///arcs of the shortest paths.
980 976
    typedef typename TR::PredMap PredMap;
981
    ///\brief The type of the map that stores the distances of the nodes.
982 977
    typedef typename TR::DistMap DistMap;
983
    ///\brief The type of the map that indicates which nodes are reached.
984 978
    typedef typename TR::ReachedMap ReachedMap;
985
    ///\brief The type of the map that indicates which nodes are processed.
986 979
    typedef typename TR::ProcessedMap ProcessedMap;
987
    ///The type of the shortest paths
988 980
    typedef typename TR::Path Path;
989 981

	
990 982
  public:
991 983

	
992 984
    /// Constructor.
993 985
    BfsWizard() : TR() {}
994 986

	
995 987
    /// Constructor that requires parameters.
996 988

	
997 989
    /// Constructor that requires parameters.
998 990
    /// These parameters will be the default values for the traits class.
999 991
    /// \param g The digraph the algorithm runs on.
1000 992
    BfsWizard(const Digraph &g) :
1001 993
      TR(g) {}
1002 994

	
1003 995
    ///Copy constructor
1004 996
    BfsWizard(const TR &b) : TR(b) {}
1005 997

	
1006 998
    ~BfsWizard() {}
1007 999

	
1008 1000
    ///Runs BFS algorithm from the given source node.
1009 1001

	
1010 1002
    ///This method runs BFS algorithm from node \c s
1011 1003
    ///in order to compute the shortest path to each node.
1012 1004
    void run(Node s)
1013 1005
    {
1014 1006
      Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
1015 1007
      if (Base::_pred)
1016 1008
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1017 1009
      if (Base::_dist)
1018 1010
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1019 1011
      if (Base::_reached)
1020 1012
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
1021 1013
      if (Base::_processed)
1022 1014
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1023 1015
      if (s!=INVALID)
1024 1016
        alg.run(s);
1025 1017
      else
1026 1018
        alg.run();
1027 1019
    }
1028 1020

	
1029 1021
    ///Finds the shortest path between \c s and \c t.
1030 1022

	
1031 1023
    ///This method runs BFS algorithm from node \c s
1032 1024
    ///in order to compute the shortest path to node \c t
1033 1025
    ///(it stops searching when \c t is processed).
1034 1026
    ///
1035 1027
    ///\return \c true if \c t is reachable form \c s.
1036 1028
    bool run(Node s, Node t)
1037 1029
    {
1038 1030
      Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
1039 1031
      if (Base::_pred)
1040 1032
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1041 1033
      if (Base::_dist)
1042 1034
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1043 1035
      if (Base::_reached)
1044 1036
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
1045 1037
      if (Base::_processed)
1046 1038
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1047 1039
      alg.run(s,t);
1048 1040
      if (Base::_path)
1049 1041
        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
1050 1042
      if (Base::_di)
1051 1043
        *Base::_di = alg.dist(t);
1052 1044
      return alg.reached(t);
1053 1045
    }
1054 1046

	
1055 1047
    ///Runs BFS algorithm to visit all nodes in the digraph.
1056 1048

	
1057 1049
    ///This method runs BFS algorithm in order to compute
1058 1050
    ///the shortest path to each node.
1059 1051
    void run()
1060 1052
    {
1061 1053
      run(INVALID);
1062 1054
    }
1063 1055

	
1064 1056
    template<class T>
1065 1057
    struct SetPredMapBase : public Base {
1066 1058
      typedef T PredMap;
1067 1059
      static PredMap *createPredMap(const Digraph &) { return 0; };
1068 1060
      SetPredMapBase(const TR &b) : TR(b) {}
1069 1061
    };
1070
    ///\brief \ref named-func-param "Named parameter"
1071
    ///for setting PredMap object.
1062

	
1063
    ///\brief \ref named-templ-param "Named parameter" for setting
1064
    ///the predecessor map.
1072 1065
    ///
1073
    ///\ref named-func-param "Named parameter"
1074
    ///for setting PredMap object.
1066
    ///\ref named-templ-param "Named parameter" function for setting
1067
    ///the map that stores the predecessor arcs of the nodes.
1075 1068
    template<class T>
1076 1069
    BfsWizard<SetPredMapBase<T> > predMap(const T &t)
1077 1070
    {
1078 1071
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1079 1072
      return BfsWizard<SetPredMapBase<T> >(*this);
1080 1073
    }
1081 1074

	
1082 1075
    template<class T>
1083 1076
    struct SetReachedMapBase : public Base {
1084 1077
      typedef T ReachedMap;
1085 1078
      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
1086 1079
      SetReachedMapBase(const TR &b) : TR(b) {}
1087 1080
    };
1088
    ///\brief \ref named-func-param "Named parameter"
1089
    ///for setting ReachedMap object.
1081

	
1082
    ///\brief \ref named-templ-param "Named parameter" for setting
1083
    ///the reached map.
1090 1084
    ///
1091
    /// \ref named-func-param "Named parameter"
1092
    ///for setting ReachedMap object.
1085
    ///\ref named-templ-param "Named parameter" function for setting
1086
    ///the map that indicates which nodes are reached.
1093 1087
    template<class T>
1094 1088
    BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
1095 1089
    {
1096 1090
      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
1097 1091
      return BfsWizard<SetReachedMapBase<T> >(*this);
1098 1092
    }
1099 1093

	
1100 1094
    template<class T>
1101 1095
    struct SetDistMapBase : public Base {
1102 1096
      typedef T DistMap;
1103 1097
      static DistMap *createDistMap(const Digraph &) { return 0; };
1104 1098
      SetDistMapBase(const TR &b) : TR(b) {}
1105 1099
    };
1106
    ///\brief \ref named-func-param "Named parameter"
1107
    ///for setting DistMap object.
1100

	
1101
    ///\brief \ref named-templ-param "Named parameter" for setting
1102
    ///the distance map.
1108 1103
    ///
1109
    /// \ref named-func-param "Named parameter"
1110
    ///for setting DistMap object.
1104
    ///\ref named-templ-param "Named parameter" function for setting
1105
    ///the map that stores the distances of the nodes calculated
1106
    ///by the algorithm.
1111 1107
    template<class T>
1112 1108
    BfsWizard<SetDistMapBase<T> > distMap(const T &t)
1113 1109
    {
1114 1110
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1115 1111
      return BfsWizard<SetDistMapBase<T> >(*this);
1116 1112
    }
1117 1113

	
1118 1114
    template<class T>
1119 1115
    struct SetProcessedMapBase : public Base {
1120 1116
      typedef T ProcessedMap;
1121 1117
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1122 1118
      SetProcessedMapBase(const TR &b) : TR(b) {}
1123 1119
    };
1124
    ///\brief \ref named-func-param "Named parameter"
1125
    ///for setting ProcessedMap object.
1120

	
1121
    ///\brief \ref named-func-param "Named parameter" for setting
1122
    ///the processed map.
1126 1123
    ///
1127
    /// \ref named-func-param "Named parameter"
1128
    ///for setting ProcessedMap object.
1124
    ///\ref named-templ-param "Named parameter" function for setting
1125
    ///the map that indicates which nodes are processed.
1129 1126
    template<class T>
1130 1127
    BfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
1131 1128
    {
1132 1129
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1133 1130
      return BfsWizard<SetProcessedMapBase<T> >(*this);
1134 1131
    }
1135 1132

	
1136 1133
    template<class T>
1137 1134
    struct SetPathBase : public Base {
1138 1135
      typedef T Path;
1139 1136
      SetPathBase(const TR &b) : TR(b) {}
1140 1137
    };
1141 1138
    ///\brief \ref named-func-param "Named parameter"
1142 1139
    ///for getting the shortest path to the target node.
1143 1140
    ///
1144 1141
    ///\ref named-func-param "Named parameter"
1145 1142
    ///for getting the shortest path to the target node.
1146 1143
    template<class T>
1147 1144
    BfsWizard<SetPathBase<T> > path(const T &t)
1148 1145
    {
1149 1146
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1150 1147
      return BfsWizard<SetPathBase<T> >(*this);
1151 1148
    }
1152 1149

	
1153 1150
    ///\brief \ref named-func-param "Named parameter"
1154 1151
    ///for getting the distance of the target node.
1155 1152
    ///
1156 1153
    ///\ref named-func-param "Named parameter"
1157 1154
    ///for getting the distance of the target node.
1158 1155
    BfsWizard dist(const int &d)
1159 1156
    {
1160 1157
      Base::_di=const_cast<int*>(&d);
1161 1158
      return *this;
1162 1159
    }
1163 1160

	
1164 1161
  };
1165 1162

	
1166 1163
  ///Function-type interface for BFS algorithm.
1167 1164

	
1168 1165
  /// \ingroup search
1169 1166
  ///Function-type interface for BFS algorithm.
1170 1167
  ///
1171 1168
  ///This function also has several \ref named-func-param "named parameters",
1172 1169
  ///they are declared as the members of class \ref BfsWizard.
1173 1170
  ///The following examples show how to use these parameters.
1174 1171
  ///\code
1175 1172
  ///  // Compute shortest path from node s to each node
1176 1173
  ///  bfs(g).predMap(preds).distMap(dists).run(s);
1177 1174
  ///
1178 1175
  ///  // Compute shortest path from s to t
1179 1176
  ///  bool reached = bfs(g).path(p).dist(d).run(s,t);
1180 1177
  ///\endcode
1181
  ///\warning Don't forget to put the \ref BfsWizard::run() "run()"
1178
  ///\warning Don't forget to put the \ref BfsWizard::run(Node) "run()"
1182 1179
  ///to the end of the parameter list.
1183 1180
  ///\sa BfsWizard
1184 1181
  ///\sa Bfs
1185 1182
  template<class GR>
1186 1183
  BfsWizard<BfsWizardBase<GR> >
1187 1184
  bfs(const GR &digraph)
1188 1185
  {
1189 1186
    return BfsWizard<BfsWizardBase<GR> >(digraph);
1190 1187
  }
1191 1188

	
1192 1189
#ifdef DOXYGEN
1193 1190
  /// \brief Visitor class for BFS.
1194 1191
  ///
1195 1192
  /// This class defines the interface of the BfsVisit events, and
1196 1193
  /// it could be the base of a real visitor class.
1197
  template <typename _Digraph>
1194
  template <typename GR>
1198 1195
  struct BfsVisitor {
1199
    typedef _Digraph Digraph;
1196
    typedef GR Digraph;
1200 1197
    typedef typename Digraph::Arc Arc;
1201 1198
    typedef typename Digraph::Node Node;
1202 1199
    /// \brief Called for the source node(s) of the BFS.
1203 1200
    ///
1204 1201
    /// This function is called for the source node(s) of the BFS.
1205 1202
    void start(const Node& node) {}
1206 1203
    /// \brief Called when a node is reached first time.
1207 1204
    ///
1208 1205
    /// This function is called when a node is reached first time.
1209 1206
    void reach(const Node& node) {}
1210 1207
    /// \brief Called when a node is processed.
1211 1208
    ///
1212 1209
    /// This function is called when a node is processed.
1213 1210
    void process(const Node& node) {}
1214 1211
    /// \brief Called when an arc reaches a new node.
1215 1212
    ///
1216 1213
    /// This function is called when the BFS finds an arc whose target node
1217 1214
    /// is not reached yet.
1218 1215
    void discover(const Arc& arc) {}
1219 1216
    /// \brief Called when an arc is examined but its target node is
1220 1217
    /// already discovered.
1221 1218
    ///
1222 1219
    /// This function is called when an arc is examined but its target node is
1223 1220
    /// already discovered.
1224 1221
    void examine(const Arc& arc) {}
1225 1222
  };
1226 1223
#else
1227
  template <typename _Digraph>
1224
  template <typename GR>
1228 1225
  struct BfsVisitor {
1229
    typedef _Digraph Digraph;
1226
    typedef GR Digraph;
1230 1227
    typedef typename Digraph::Arc Arc;
1231 1228
    typedef typename Digraph::Node Node;
1232 1229
    void start(const Node&) {}
1233 1230
    void reach(const Node&) {}
1234 1231
    void process(const Node&) {}
1235 1232
    void discover(const Arc&) {}
1236 1233
    void examine(const Arc&) {}
1237 1234

	
1238 1235
    template <typename _Visitor>
1239 1236
    struct Constraints {
1240 1237
      void constraints() {
1241 1238
        Arc arc;
1242 1239
        Node node;
1243 1240
        visitor.start(node);
1244 1241
        visitor.reach(node);
1245 1242
        visitor.process(node);
1246 1243
        visitor.discover(arc);
1247 1244
        visitor.examine(arc);
1248 1245
      }
1249 1246
      _Visitor& visitor;
1250 1247
    };
1251 1248
  };
1252 1249
#endif
1253 1250

	
1254 1251
  /// \brief Default traits class of BfsVisit class.
1255 1252
  ///
1256 1253
  /// Default traits class of BfsVisit class.
1257
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1258
  template<class _Digraph>
1254
  /// \tparam GR The type of the digraph the algorithm runs on.
1255
  template<class GR>
1259 1256
  struct BfsVisitDefaultTraits {
1260 1257

	
1261 1258
    /// \brief The type of the digraph the algorithm runs on.
1262
    typedef _Digraph Digraph;
1259
    typedef GR Digraph;
1263 1260

	
1264 1261
    /// \brief The type of the map that indicates which nodes are reached.
1265 1262
    ///
1266 1263
    /// The type of the map that indicates which nodes are reached.
1267
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1264
    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1268 1265
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
1269 1266

	
1270 1267
    /// \brief Instantiates a ReachedMap.
1271 1268
    ///
1272 1269
    /// This function instantiates a ReachedMap.
1273 1270
    /// \param digraph is the digraph, to which
1274 1271
    /// we would like to define the ReachedMap.
1275 1272
    static ReachedMap *createReachedMap(const Digraph &digraph) {
1276 1273
      return new ReachedMap(digraph);
1277 1274
    }
1278 1275

	
1279 1276
  };
1280 1277

	
1281 1278
  /// \ingroup search
1282 1279
  ///
1283
  /// \brief %BFS algorithm class with visitor interface.
1280
  /// \brief BFS algorithm class with visitor interface.
1284 1281
  ///
1285
  /// This class provides an efficient implementation of the %BFS algorithm
1282
  /// This class provides an efficient implementation of the BFS algorithm
1286 1283
  /// with visitor interface.
1287 1284
  ///
1288
  /// The %BfsVisit class provides an alternative interface to the Bfs
1285
  /// The BfsVisit class provides an alternative interface to the Bfs
1289 1286
  /// class. It works with callback mechanism, the BfsVisit object calls
1290 1287
  /// the member functions of the \c Visitor class on every BFS event.
1291 1288
  ///
1292 1289
  /// This interface of the BFS algorithm should be used in special cases
1293 1290
  /// when extra actions have to be performed in connection with certain
1294 1291
  /// events of the BFS algorithm. Otherwise consider to use Bfs or bfs()
1295 1292
  /// instead.
1296 1293
  ///
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
1294
  /// \tparam GR The type of the digraph the algorithm runs on.
1295
  /// The default type is \ref ListDigraph.
1296
  /// The value of GR is not used directly by \ref BfsVisit,
1297
  /// it is only passed to \ref BfsVisitDefaultTraits.
1298
  /// \tparam VS The Visitor type that is used by the algorithm.
1299
  /// \ref BfsVisitor "BfsVisitor<GR>" is an empty visitor, which
1303 1300
  /// does not observe the BFS events. If you want to observe the BFS
1304 1301
  /// events, you should implement your own visitor class.
1305
  /// \tparam _Traits Traits class to set various data types used by the
1302
  /// \tparam TR Traits class to set various data types used by the
1306 1303
  /// algorithm. The default traits class is
1307
  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<_Digraph>".
1304
  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<GR>".
1308 1305
  /// See \ref BfsVisitDefaultTraits for the documentation of
1309 1306
  /// a BFS visit traits class.
1310 1307
#ifdef DOXYGEN
1311
  template <typename _Digraph, typename _Visitor, typename _Traits>
1308
  template <typename GR, typename VS, typename TR>
1312 1309
#else
1313
  template <typename _Digraph = ListDigraph,
1314
            typename _Visitor = BfsVisitor<_Digraph>,
1315
            typename _Traits = BfsVisitDefaultTraits<_Digraph> >
1310
  template <typename GR = ListDigraph,
1311
            typename VS = BfsVisitor<GR>,
1312
            typename TR = BfsVisitDefaultTraits<GR> >
1316 1313
#endif
1317 1314
  class BfsVisit {
1318 1315
  public:
1319 1316

	
1320 1317
    ///The traits class.
1321
    typedef _Traits Traits;
1318
    typedef TR Traits;
1322 1319

	
1323 1320
    ///The type of the digraph the algorithm runs on.
1324 1321
    typedef typename Traits::Digraph Digraph;
1325 1322

	
1326 1323
    ///The visitor type used by the algorithm.
1327
    typedef _Visitor Visitor;
1324
    typedef VS Visitor;
1328 1325

	
1329 1326
    ///The type of the map that indicates which nodes are reached.
1330 1327
    typedef typename Traits::ReachedMap ReachedMap;
1331 1328

	
1332 1329
  private:
1333 1330

	
1334 1331
    typedef typename Digraph::Node Node;
1335 1332
    typedef typename Digraph::NodeIt NodeIt;
1336 1333
    typedef typename Digraph::Arc Arc;
1337 1334
    typedef typename Digraph::OutArcIt OutArcIt;
1338 1335

	
1339 1336
    //Pointer to the underlying digraph.
1340 1337
    const Digraph *_digraph;
1341 1338
    //Pointer to the visitor object.
1342 1339
    Visitor *_visitor;
1343 1340
    //Pointer to the map of reached status of the nodes.
1344 1341
    ReachedMap *_reached;
1345 1342
    //Indicates if _reached is locally allocated (true) or not.
1346 1343
    bool local_reached;
1347 1344

	
1348 1345
    std::vector<typename Digraph::Node> _list;
1349 1346
    int _list_front, _list_back;
1350 1347

	
1351 1348
    //Creates the maps if necessary.
1352 1349
    void create_maps() {
1353 1350
      if(!_reached) {
1354 1351
        local_reached = true;
1355 1352
        _reached = Traits::createReachedMap(*_digraph);
1356 1353
      }
1357 1354
    }
1358 1355

	
1359 1356
  protected:
1360 1357

	
1361 1358
    BfsVisit() {}
1362 1359

	
1363 1360
  public:
1364 1361

	
1365 1362
    typedef BfsVisit Create;
1366 1363

	
1367
    /// \name Named template parameters
1364
    /// \name Named Template Parameters
1368 1365

	
1369 1366
    ///@{
1370 1367
    template <class T>
1371 1368
    struct SetReachedMapTraits : public Traits {
1372 1369
      typedef T ReachedMap;
1373 1370
      static ReachedMap *createReachedMap(const Digraph &digraph) {
1374 1371
        LEMON_ASSERT(false, "ReachedMap is not initialized");
1375 1372
        return 0; // ignore warnings
1376 1373
      }
1377 1374
    };
1378 1375
    /// \brief \ref named-templ-param "Named parameter" for setting
1379 1376
    /// ReachedMap type.
1380 1377
    ///
1381 1378
    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
1382 1379
    template <class T>
1383 1380
    struct SetReachedMap : public BfsVisit< Digraph, Visitor,
1384 1381
                                            SetReachedMapTraits<T> > {
1385 1382
      typedef BfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
1386 1383
    };
1387 1384
    ///@}
1388 1385

	
1389 1386
  public:
1390 1387

	
1391 1388
    /// \brief Constructor.
1392 1389
    ///
1393 1390
    /// Constructor.
1394 1391
    ///
1395 1392
    /// \param digraph The digraph the algorithm runs on.
1396 1393
    /// \param visitor The visitor object of the algorithm.
1397 1394
    BfsVisit(const Digraph& digraph, Visitor& visitor)
1398 1395
      : _digraph(&digraph), _visitor(&visitor),
1399 1396
        _reached(0), local_reached(false) {}
1400 1397

	
1401 1398
    /// \brief Destructor.
1402 1399
    ~BfsVisit() {
1403 1400
      if(local_reached) delete _reached;
1404 1401
    }
1405 1402

	
1406 1403
    /// \brief Sets the map that indicates which nodes are reached.
1407 1404
    ///
1408 1405
    /// 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.
1406
    /// If you don't use this function before calling \ref run(Node) "run()"
1407
    /// or \ref init(), an instance will be allocated automatically.
1408
    /// The destructor deallocates this automatically allocated map,
1409
    /// of course.
1412 1410
    /// \return <tt> (*this) </tt>
1413 1411
    BfsVisit &reachedMap(ReachedMap &m) {
1414 1412
      if(local_reached) {
1415 1413
        delete _reached;
1416 1414
        local_reached = false;
1417 1415
      }
1418 1416
      _reached = &m;
1419 1417
      return *this;
1420 1418
    }
1421 1419

	
1422 1420
  public:
1423 1421

	
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.
1422
    /// \name Execution Control
1423
    /// The simplest way to execute the BFS algorithm is to use one of the
1424
    /// member functions called \ref run(Node) "run()".\n
1425
    /// If you need better control on the execution, you have to call
1426
    /// \ref init() first, then you can add several source nodes with
1427
    /// \ref addSource(). Finally the actual path computation can be
1428
    /// performed with one of the \ref start() functions.
1434 1429

	
1435 1430
    /// @{
1436 1431

	
1437 1432
    /// \brief Initializes the internal data structures.
1438 1433
    ///
1439 1434
    /// Initializes the internal data structures.
1440 1435
    void init() {
1441 1436
      create_maps();
1442 1437
      _list.resize(countNodes(*_digraph));
1443 1438
      _list_front = _list_back = -1;
1444 1439
      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
1445 1440
        _reached->set(u, false);
1446 1441
      }
1447 1442
    }
1448 1443

	
1449 1444
    /// \brief Adds a new source node.
1450 1445
    ///
1451 1446
    /// Adds a new source node to the set of nodes to be processed.
1452 1447
    void addSource(Node s) {
1453 1448
      if(!(*_reached)[s]) {
1454 1449
          _reached->set(s,true);
1455 1450
          _visitor->start(s);
1456 1451
          _visitor->reach(s);
1457 1452
          _list[++_list_back] = s;
1458 1453
        }
1459 1454
    }
1460 1455

	
1461 1456
    /// \brief Processes the next node.
1462 1457
    ///
1463 1458
    /// Processes the next node.
1464 1459
    ///
1465 1460
    /// \return The processed node.
1466 1461
    ///
1467 1462
    /// \pre The queue must not be empty.
1468 1463
    Node processNextNode() {
1469 1464
      Node n = _list[++_list_front];
1470 1465
      _visitor->process(n);
1471 1466
      Arc e;
1472 1467
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1473 1468
        Node m = _digraph->target(e);
1474 1469
        if (!(*_reached)[m]) {
1475 1470
          _visitor->discover(e);
1476 1471
          _visitor->reach(m);
1477 1472
          _reached->set(m, true);
1478 1473
          _list[++_list_back] = m;
1479 1474
        } else {
1480 1475
          _visitor->examine(e);
1481 1476
        }
1482 1477
      }
1483 1478
      return n;
1484 1479
    }
1485 1480

	
1486 1481
    /// \brief Processes the next node.
1487 1482
    ///
1488 1483
    /// Processes the next node and checks if the given target node
1489 1484
    /// is reached. If the target node is reachable from the processed
1490 1485
    /// node, then the \c reach parameter will be set to \c true.
1491 1486
    ///
1492 1487
    /// \param target The target node.
1493 1488
    /// \retval reach Indicates if the target node is reached.
1494 1489
    /// It should be initially \c false.
1495 1490
    ///
1496 1491
    /// \return The processed node.
1497 1492
    ///
1498 1493
    /// \pre The queue must not be empty.
1499 1494
    Node processNextNode(Node target, bool& reach) {
1500 1495
      Node n = _list[++_list_front];
1501 1496
      _visitor->process(n);
1502 1497
      Arc e;
1503 1498
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1504 1499
        Node m = _digraph->target(e);
1505 1500
        if (!(*_reached)[m]) {
1506 1501
          _visitor->discover(e);
1507 1502
          _visitor->reach(m);
1508 1503
          _reached->set(m, true);
1509 1504
          _list[++_list_back] = m;
1510 1505
          reach = reach || (target == m);
1511 1506
        } else {
1512 1507
          _visitor->examine(e);
1513 1508
        }
1514 1509
      }
1515 1510
      return n;
1516 1511
    }
1517 1512

	
1518 1513
    /// \brief Processes the next node.
1519 1514
    ///
1520 1515
    /// Processes the next node and checks if at least one of reached
1521 1516
    /// nodes has \c true value in the \c nm node map. If one node
1522 1517
    /// with \c true value is reachable from the processed node, then the
1523 1518
    /// \c rnode parameter will be set to the first of such nodes.
1524 1519
    ///
1525 1520
    /// \param nm A \c bool (or convertible) node map that indicates the
1526 1521
    /// possible targets.
1527 1522
    /// \retval rnode The reached target node.
1528 1523
    /// It should be initially \c INVALID.
1529 1524
    ///
1530 1525
    /// \return The processed node.
1531 1526
    ///
1532 1527
    /// \pre The queue must not be empty.
1533 1528
    template <typename NM>
1534 1529
    Node processNextNode(const NM& nm, Node& rnode) {
1535 1530
      Node n = _list[++_list_front];
1536 1531
      _visitor->process(n);
1537 1532
      Arc e;
1538 1533
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1539 1534
        Node m = _digraph->target(e);
1540 1535
        if (!(*_reached)[m]) {
1541 1536
          _visitor->discover(e);
1542 1537
          _visitor->reach(m);
1543 1538
          _reached->set(m, true);
1544 1539
          _list[++_list_back] = m;
1545 1540
          if (nm[m] && rnode == INVALID) rnode = m;
1546 1541
        } else {
1547 1542
          _visitor->examine(e);
1548 1543
        }
1549 1544
      }
1550 1545
      return n;
1551 1546
    }
1552 1547

	
1553 1548
    /// \brief The next node to be processed.
1554 1549
    ///
1555 1550
    /// Returns the next node to be processed or \c INVALID if the queue
1556 1551
    /// is empty.
1557 1552
    Node nextNode() const {
1558 1553
      return _list_front != _list_back ? _list[_list_front + 1] : INVALID;
1559 1554
    }
1560 1555

	
1561 1556
    /// \brief Returns \c false if there are nodes
1562 1557
    /// to be processed.
1563 1558
    ///
1564 1559
    /// Returns \c false if there are nodes
1565 1560
    /// to be processed in the queue.
1566 1561
    bool emptyQueue() const { return _list_front == _list_back; }
1567 1562

	
1568 1563
    /// \brief Returns the number of the nodes to be processed.
1569 1564
    ///
1570 1565
    /// Returns the number of the nodes to be processed in the queue.
1571 1566
    int queueSize() const { return _list_back - _list_front; }
1572 1567

	
1573 1568
    /// \brief Executes the algorithm.
1574 1569
    ///
1575 1570
    /// Executes the algorithm.
1576 1571
    ///
1577 1572
    /// This method runs the %BFS algorithm from the root node(s)
1578 1573
    /// in order to compute the shortest path to each node.
1579 1574
    ///
1580 1575
    /// The algorithm computes
1581 1576
    /// - the shortest path tree (forest),
1582 1577
    /// - the distance of each node from the root(s).
1583 1578
    ///
1584 1579
    /// \pre init() must be called and at least one root node should be added
1585 1580
    /// with addSource() before using this function.
1586 1581
    ///
1587 1582
    /// \note <tt>b.start()</tt> is just a shortcut of the following code.
1588 1583
    /// \code
1589 1584
    ///   while ( !b.emptyQueue() ) {
1590 1585
    ///     b.processNextNode();
1591 1586
    ///   }
1592 1587
    /// \endcode
1593 1588
    void start() {
1594 1589
      while ( !emptyQueue() ) processNextNode();
1595 1590
    }
1596 1591

	
1597 1592
    /// \brief Executes the algorithm until the given target node is reached.
1598 1593
    ///
1599 1594
    /// Executes the algorithm until the given target node is reached.
1600 1595
    ///
1601 1596
    /// This method runs the %BFS algorithm from the root node(s)
1602 1597
    /// in order to compute the shortest path to \c t.
1603 1598
    ///
1604 1599
    /// The algorithm computes
1605 1600
    /// - the shortest path to \c t,
1606 1601
    /// - the distance of \c t from the root(s).
1607 1602
    ///
1608 1603
    /// \pre init() must be called and at least one root node should be
1609 1604
    /// added with addSource() before using this function.
1610 1605
    ///
1611 1606
    /// \note <tt>b.start(t)</tt> is just a shortcut of the following code.
1612 1607
    /// \code
1613 1608
    ///   bool reach = false;
1614 1609
    ///   while ( !b.emptyQueue() && !reach ) {
1615 1610
    ///     b.processNextNode(t, reach);
1616 1611
    ///   }
1617 1612
    /// \endcode
1618 1613
    void start(Node t) {
1619 1614
      bool reach = false;
1620 1615
      while ( !emptyQueue() && !reach ) processNextNode(t, reach);
1621 1616
    }
1622 1617

	
1623 1618
    /// \brief Executes the algorithm until a condition is met.
1624 1619
    ///
1625 1620
    /// Executes the algorithm until a condition is met.
1626 1621
    ///
1627 1622
    /// This method runs the %BFS algorithm from the root node(s) in
1628 1623
    /// order to compute the shortest path to a node \c v with
1629 1624
    /// <tt>nm[v]</tt> true, if such a node can be found.
1630 1625
    ///
1631 1626
    /// \param nm must be a bool (or convertible) node map. The
1632 1627
    /// algorithm will stop when it reaches a node \c v with
1633 1628
    /// <tt>nm[v]</tt> true.
1634 1629
    ///
1635 1630
    /// \return The reached node \c v with <tt>nm[v]</tt> true or
1636 1631
    /// \c INVALID if no such node was found.
1637 1632
    ///
1638 1633
    /// \pre init() must be called and at least one root node should be
1639 1634
    /// added with addSource() before using this function.
1640 1635
    ///
1641 1636
    /// \note <tt>b.start(nm)</tt> is just a shortcut of the following code.
1642 1637
    /// \code
1643 1638
    ///   Node rnode = INVALID;
1644 1639
    ///   while ( !b.emptyQueue() && rnode == INVALID ) {
1645 1640
    ///     b.processNextNode(nm, rnode);
1646 1641
    ///   }
1647 1642
    ///   return rnode;
1648 1643
    /// \endcode
1649 1644
    template <typename NM>
1650 1645
    Node start(const NM &nm) {
1651 1646
      Node rnode = INVALID;
1652 1647
      while ( !emptyQueue() && rnode == INVALID ) {
1653 1648
        processNextNode(nm, rnode);
1654 1649
      }
1655 1650
      return rnode;
1656 1651
    }
1657 1652

	
1658 1653
    /// \brief Runs the algorithm from the given source node.
1659 1654
    ///
1660 1655
    /// This method runs the %BFS algorithm from node \c s
1661 1656
    /// in order to compute the shortest path to each node.
1662 1657
    ///
1663 1658
    /// The algorithm computes
1664 1659
    /// - the shortest path tree,
1665 1660
    /// - the distance of each node from the root.
1666 1661
    ///
1667 1662
    /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
1668 1663
    ///\code
1669 1664
    ///   b.init();
1670 1665
    ///   b.addSource(s);
1671 1666
    ///   b.start();
1672 1667
    ///\endcode
1673 1668
    void run(Node s) {
1674 1669
      init();
1675 1670
      addSource(s);
1676 1671
      start();
1677 1672
    }
1678 1673

	
1679 1674
    /// \brief Finds the shortest path between \c s and \c t.
1680 1675
    ///
1681 1676
    /// This method runs the %BFS algorithm from node \c s
1682 1677
    /// in order to compute the shortest path to node \c t
1683 1678
    /// (it stops searching when \c t is processed).
1684 1679
    ///
1685 1680
    /// \return \c true if \c t is reachable form \c s.
1686 1681
    ///
1687 1682
    /// \note Apart from the return value, <tt>b.run(s,t)</tt> is just a
1688 1683
    /// shortcut of the following code.
1689 1684
    ///\code
1690 1685
    ///   b.init();
1691 1686
    ///   b.addSource(s);
1692 1687
    ///   b.start(t);
1693 1688
    ///\endcode
1694 1689
    bool run(Node s,Node t) {
1695 1690
      init();
1696 1691
      addSource(s);
1697 1692
      start(t);
1698 1693
      return reached(t);
1699 1694
    }
1700 1695

	
1701 1696
    /// \brief Runs the algorithm to visit all nodes in the digraph.
1702 1697
    ///
1703 1698
    /// This method runs the %BFS algorithm in order to
1704 1699
    /// compute the shortest path to each node.
1705 1700
    ///
1706 1701
    /// The algorithm computes
1707 1702
    /// - the shortest path tree (forest),
1708 1703
    /// - the distance of each node from the root(s).
1709 1704
    ///
1710 1705
    /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
1711 1706
    ///\code
1712 1707
    ///  b.init();
1713 1708
    ///  for (NodeIt n(gr); n != INVALID; ++n) {
1714 1709
    ///    if (!b.reached(n)) {
1715 1710
    ///      b.addSource(n);
1716 1711
    ///      b.start();
1717 1712
    ///    }
1718 1713
    ///  }
1719 1714
    ///\endcode
1720 1715
    void run() {
1721 1716
      init();
1722 1717
      for (NodeIt it(*_digraph); it != INVALID; ++it) {
1723 1718
        if (!reached(it)) {
1724 1719
          addSource(it);
1725 1720
          start();
1726 1721
        }
1727 1722
      }
1728 1723
    }
1729 1724

	
1730 1725
    ///@}
1731 1726

	
1732 1727
    /// \name Query Functions
1733
    /// The result of the %BFS algorithm can be obtained using these
1728
    /// The results of the BFS algorithm can be obtained using these
1734 1729
    /// functions.\n
1735
    /// Either \ref lemon::BfsVisit::run() "run()" or
1736
    /// \ref lemon::BfsVisit::start() "start()" must be called before
1737
    /// using them.
1730
    /// Either \ref run(Node) "run()" or \ref start() should be called
1731
    /// before using them.
1732

	
1738 1733
    ///@{
1739 1734

	
1740
    /// \brief Checks if a node is reachable from the root(s).
1735
    /// \brief Checks if the given node is reached from the root(s).
1741 1736
    ///
1742
    /// Returns \c true if \c v is reachable from the root(s).
1743
    /// \pre Either \ref run() or \ref start()
1737
    /// Returns \c true if \c v is reached from the root(s).
1738
    ///
1739
    /// \pre Either \ref run(Node) "run()" or \ref init()
1744 1740
    /// must be called before using this function.
1745
    bool reached(Node v) { return (*_reached)[v]; }
1741
    bool reached(Node v) const { return (*_reached)[v]; }
1746 1742

	
1747 1743
    ///@}
1748 1744

	
1749 1745
  };
1750 1746

	
1751 1747
} //END OF NAMESPACE LEMON
1752 1748

	
1753 1749
#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
///\ingroup auxdat
22
///\ingroup heaps
23 23
///\file
24
///\brief Binary Heap implementation.
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
  ///\ingroup auxdat
32
  /// \ingroup heaps
33 33
  ///
34
  ///\brief A Binary Heap implementation.
34
  /// \brief Binary heap data structure.
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.
37
  /// It fully conforms to the \ref concepts::Heap "heap concept".
41 38
  ///
42
  ///\tparam _Prio Type of the priority of the items.
43
  ///\tparam _ItemIntMap A read and writable Item int map, used internally
44
  ///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
  ///
48
  ///\sa FibHeap
49
  ///\sa Dijkstra
50
  template <typename _Prio, typename _ItemIntMap,
51
            typename _Compare = std::less<_Prio> >
39
  /// \tparam PR Type of the priorities of the items.
40
  /// \tparam IM A read-writable item map with \c int values, used
41
  /// internally to handle the cross references.
42
  /// \tparam CMP A functor class for comparing the priorities.
43
  /// The default is \c std::less<PR>.
44
#ifdef DOXYGEN
45
  template <typename PR, typename IM, typename CMP>
46
#else
47
  template <typename PR, typename IM, typename CMP = std::less<PR> >
48
#endif
52 49
  class BinHeap {
50
  public:
53 51

	
54
  public:
55
    ///\e
56
    typedef _ItemIntMap ItemIntMap;
57
    ///\e
58
    typedef _Prio Prio;
59
    ///\e
52
    /// Type of the item-int map.
53
    typedef IM ItemIntMap;
54
    /// Type of the priorities.
55
    typedef PR Prio;
56
    /// Type of the items stored in the heap.
60 57
    typedef typename ItemIntMap::Key Item;
61
    ///\e
58
    /// Type of the item-priority pairs.
62 59
    typedef std::pair<Item,Prio> Pair;
63
    ///\e
64
    typedef _Compare Compare;
60
    /// Functor type for comparing the priorities.
61
    typedef CMP Compare;
65 62

	
66
    /// \brief Type to represent the items states.
63
    /// \brief Type to represent the states of the items.
67 64
    ///
68
    /// Each Item element have a state associated to it. It may be "in heap",
69
    /// "pre heap" or "post heap". The latter two are indifferent from the
65
    /// Each item has a state associated to it. It can be "in heap",
66
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
70 67
    /// heap's point of view, but may be useful to the user.
71 68
    ///
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...
69
    /// The item-int map must be initialized in such way that it assigns
70
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
74 71
    enum State {
75
      IN_HEAP = 0,
76
      PRE_HEAP = -1,
77
      POST_HEAP = -2
72
      IN_HEAP = 0,    ///< = 0.
73
      PRE_HEAP = -1,  ///< = -1.
74
      POST_HEAP = -2  ///< = -2.
78 75
    };
79 76

	
80 77
  private:
81
    std::vector<Pair> data;
82
    Compare comp;
83
    ItemIntMap &iim;
78
    std::vector<Pair> _data;
79
    Compare _comp;
80
    ItemIntMap &_iim;
84 81

	
85 82
  public:
86
    /// \brief The constructor.
83

	
84
    /// \brief Constructor.
87 85
    ///
88
    /// The constructor.
89
    /// \param _iim should be given to the constructor, since it is used
90
    /// 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) {}
86
    /// Constructor.
87
    /// \param map A map that assigns \c int values to the items.
88
    /// It is used internally to handle the cross references.
89
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
90
    explicit BinHeap(ItemIntMap &map) : _iim(map) {}
93 91

	
94
    /// \brief The constructor.
92
    /// \brief Constructor.
95 93
    ///
96
    /// The constructor.
97
    /// \param _iim should be given to the constructor, since it is used
98
    /// internally to handle the cross references. The value of the map
99
    /// should be PRE_HEAP (-1) for each element.
94
    /// Constructor.
95
    /// \param map A map that assigns \c int values to the items.
96
    /// It is used internally to handle the cross references.
97
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
98
    /// \param comp The function object used for comparing the priorities.
99
    BinHeap(ItemIntMap &map, const Compare &comp)
100
      : _iim(map), _comp(comp) {}
101

	
102

	
103
    /// \brief The number of items stored in the heap.
100 104
    ///
101
    /// \param _comp The comparator function object.
102
    BinHeap(ItemIntMap &_iim, const Compare &_comp)
103
      : iim(_iim), comp(_comp) {}
105
    /// This function returns the number of items stored in the heap.
106
    int size() const { return _data.size(); }
104 107

	
108
    /// \brief Check if the heap is empty.
109
    ///
110
    /// This function returns \c true if the heap is empty.
111
    bool empty() const { return _data.empty(); }
105 112

	
106
    /// The number of items stored in the heap.
113
    /// \brief Make the heap empty.
107 114
    ///
108
    /// \brief Returns the number of items stored in the heap.
109
    int size() const { return data.size(); }
110

	
111
    /// \brief Checks if the heap stores no items.
112
    ///
113
    /// Returns \c true if and only if the heap stores no items.
114
    bool empty() const { return data.empty(); }
115

	
116
    /// \brief Make empty this heap.
117
    ///
118
    /// Make empty this heap. It does not change the cross reference map.
119
    /// If you want to reuse what is not surely empty you should first clear
120
    /// the heap and after that you should set the cross reference map for
121
    /// each item to \c PRE_HEAP.
115
    /// This functon makes the heap empty.
116
    /// It does not change the cross reference map. If you want to reuse
117
    /// a heap that is not surely empty, you should first clear it and
118
    /// then you should set the cross reference map to \c PRE_HEAP
119
    /// for each item.
122 120
    void clear() {
123
      data.clear();
121
      _data.clear();
124 122
    }
125 123

	
126 124
  private:
127 125
    static int parent(int i) { return (i-1)/2; }
128 126

	
129
    static int second_child(int i) { return 2*i+2; }
127
    static int secondChild(int i) { return 2*i+2; }
130 128
    bool less(const Pair &p1, const Pair &p2) const {
131
      return comp(p1.second, p2.second);
129
      return _comp(p1.second, p2.second);
132 130
    }
133 131

	
134
    int bubble_up(int hole, Pair p) {
132
    int bubbleUp(int hole, Pair p) {
135 133
      int par = parent(hole);
136
      while( hole>0 && less(p,data[par]) ) {
137
        move(data[par],hole);
134
      while( hole>0 && less(p,_data[par]) ) {
135
        move(_data[par],hole);
138 136
        hole = par;
139 137
        par = parent(hole);
140 138
      }
141 139
      move(p, hole);
142 140
      return hole;
143 141
    }
144 142

	
145
    int bubble_down(int hole, Pair p, int length) {
146
      int child = second_child(hole);
143
    int bubbleDown(int hole, Pair p, int length) {
144
      int child = secondChild(hole);
147 145
      while(child < length) {
148
        if( less(data[child-1], data[child]) ) {
146
        if( less(_data[child-1], _data[child]) ) {
149 147
          --child;
150 148
        }
151
        if( !less(data[child], p) )
149
        if( !less(_data[child], p) )
152 150
          goto ok;
153
        move(data[child], hole);
151
        move(_data[child], hole);
154 152
        hole = child;
155
        child = second_child(hole);
153
        child = secondChild(hole);
156 154
      }
157 155
      child--;
158
      if( child<length && less(data[child], p) ) {
159
        move(data[child], hole);
156
      if( child<length && less(_data[child], p) ) {
157
        move(_data[child], hole);
160 158
        hole=child;
161 159
      }
162 160
    ok:
163 161
      move(p, hole);
164 162
      return hole;
165 163
    }
166 164

	
167 165
    void move(const Pair &p, int i) {
168
      data[i] = p;
169
      iim.set(p.first, i);
166
      _data[i] = p;
167
      _iim.set(p.first, i);
170 168
    }
171 169

	
172 170
  public:
171

	
173 172
    /// \brief Insert a pair of item and priority into the heap.
174 173
    ///
175
    /// Adds \c p.first to the heap with priority \c p.second.
174
    /// This function inserts \c p.first to the heap with priority
175
    /// \c p.second.
176 176
    /// \param p The pair to insert.
177
    /// \pre \c p.first must not be stored in the heap.
177 178
    void push(const Pair &p) {
178
      int n = data.size();
179
      data.resize(n+1);
180
      bubble_up(n, p);
179
      int n = _data.size();
180
      _data.resize(n+1);
181
      bubbleUp(n, p);
181 182
    }
182 183

	
183
    /// \brief Insert an item into the heap with the given heap.
184
    /// \brief Insert an item into the heap with the given priority.
184 185
    ///
185
    /// Adds \c i to the heap with priority \c p.
186
    /// This function inserts the given item into the heap with the
187
    /// given priority.
186 188
    /// \param i The item to insert.
187 189
    /// \param p The priority of the item.
190
    /// \pre \e i must not be stored in the heap.
188 191
    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
189 192

	
190
    /// \brief Returns the item with minimum priority relative to \c Compare.
193
    /// \brief Return the item having minimum priority.
191 194
    ///
192
    /// This method returns the item with minimum priority relative to \c
193
    /// Compare.
194
    /// \pre The heap must be nonempty.
195
    /// This function returns the item having minimum priority.
196
    /// \pre The heap must be non-empty.
195 197
    Item top() const {
196
      return data[0].first;
198
      return _data[0].first;
197 199
    }
198 200

	
199
    /// \brief Returns the minimum priority relative to \c Compare.
201
    /// \brief The minimum priority.
200 202
    ///
201
    /// It returns the minimum priority relative to \c Compare.
202
    /// \pre The heap must be nonempty.
203
    /// This function returns the minimum priority.
204
    /// \pre The heap must be non-empty.
203 205
    Prio prio() const {
204
      return data[0].second;
206
      return _data[0].second;
205 207
    }
206 208

	
207
    /// \brief Deletes the item with minimum priority relative to \c Compare.
209
    /// \brief Remove the item having minimum priority.
208 210
    ///
209
    /// This method deletes the item with minimum priority relative to \c
210
    /// Compare from the heap.
211
    /// This function removes the item having minimum priority.
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
        bubbleDown(0, _data[n], n);
217 218
      }
218
      data.pop_back();
219
      _data.pop_back();
219 220
    }
220 221

	
221
    /// \brief Deletes \c i from the heap.
222
    /// \brief Remove the given item from the heap.
222 223
    ///
223
    /// This method deletes item \c i from the heap.
224
    /// \param i The item to erase.
225
    /// \pre The item should be in the heap.
224
    /// This function removes the given item from the heap if it is
225
    /// already stored.
226
    /// \param i The item to delete.
227
    /// \pre \e i must be in the heap.
226 228
    void erase(const Item &i) {
227
      int h = iim[i];
228
      int n = data.size()-1;
229
      iim.set(data[h].first, POST_HEAP);
229
      int h = _iim[i];
230
      int n = _data.size()-1;
231
      _iim.set(_data[h].first, POST_HEAP);
230 232
      if( h < n ) {
231
        if ( bubble_up(h, data[n]) == h) {
232
          bubble_down(h, data[n], n);
233
        if ( bubbleUp(h, _data[n]) == h) {
234
          bubbleDown(h, _data[n], n);
233 235
        }
234 236
      }
235
      data.pop_back();
237
      _data.pop_back();
236 238
    }
237 239

	
238

	
239
    /// \brief Returns the priority of \c i.
240
    /// \brief The priority of the given item.
240 241
    ///
241
    /// This function returns the priority of item \c i.
242
    /// \pre \c i must be in the heap.
242
    /// This function returns the priority of the given item.
243 243
    /// \param i The item.
244
    /// \pre \e i must be in the heap.
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
    /// \brief \c i gets to the heap with priority \c p independently
250
    /// if \c i was already there.
250
    /// \brief Set the priority of an item or insert it, if it is
251
    /// not stored in the heap.
251 252
    ///
252
    /// This method calls \ref push(\c i, \c p) if \c i is not stored
253
    /// in the heap and sets the priority of \c i to \c p otherwise.
253
    /// This method sets the priority of the given item if it is
254
    /// already stored in the heap. Otherwise it inserts the given
255
    /// item into the heap with the given priority.
254 256
    /// \param i The item.
255 257
    /// \param p The priority.
256 258
    void set(const Item &i, const Prio &p) {
257
      int idx = iim[i];
259
      int idx = _iim[i];
258 260
      if( idx < 0 ) {
259 261
        push(i,p);
260 262
      }
261
      else if( comp(p, data[idx].second) ) {
262
        bubble_up(idx, Pair(i,p));
263
      else if( _comp(p, _data[idx].second) ) {
264
        bubbleUp(idx, Pair(i,p));
263 265
      }
264 266
      else {
265
        bubble_down(idx, Pair(i,p), data.size());
267
        bubbleDown(idx, Pair(i,p), _data.size());
266 268
      }
267 269
    }
268 270

	
269
    /// \brief Decreases the priority of \c i to \c p.
271
    /// \brief Decrease the priority of an item to the given value.
270 272
    ///
271
    /// This method decreases the priority of item \c i to \c p.
272
    /// \pre \c i must be stored in the heap with priority at least \c
273
    /// p relative to \c Compare.
273
    /// This function decreases the priority of an item to the given value.
274 274
    /// \param i The item.
275 275
    /// \param p The priority.
276
    /// \pre \e i must be stored in the heap with priority at least \e p.
276 277
    void decrease(const Item &i, const Prio &p) {
277
      int idx = iim[i];
278
      bubble_up(idx, Pair(i,p));
278
      int idx = _iim[i];
279
      bubbleUp(idx, Pair(i,p));
279 280
    }
280 281

	
281
    /// \brief Increases the priority of \c i to \c p.
282
    /// \brief Increase the priority of an item to the given value.
282 283
    ///
283
    /// This method sets the priority of item \c i to \c p.
284
    /// \pre \c i must be stored in the heap with priority at most \c
285
    /// p relative to \c Compare.
284
    /// This function increases the priority of an item to the given value.
286 285
    /// \param i The item.
287 286
    /// \param p The priority.
287
    /// \pre \e i must be stored in the heap with priority at most \e p.
288 288
    void increase(const Item &i, const Prio &p) {
289
      int idx = iim[i];
290
      bubble_down(idx, Pair(i,p), data.size());
289
      int idx = _iim[i];
290
      bubbleDown(idx, Pair(i,p), _data.size());
291 291
    }
292 292

	
293
    /// \brief Returns if \c item is in, has already been in, or has
294
    /// never been in the heap.
293
    /// \brief Return the state of an item.
295 294
    ///
296
    /// This method returns PRE_HEAP if \c item has never been in the
297
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
298
    /// otherwise. In the latter case it is possible that \c item will
299
    /// get back to the heap again.
295
    /// This method returns \c PRE_HEAP if the given item has never
296
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
297
    /// and \c POST_HEAP otherwise.
298
    /// In the latter case it is possible that the item will get back
299
    /// to the heap again.
300 300
    /// \param i The item.
301 301
    State state(const Item &i) const {
302
      int s = iim[i];
302
      int s = _iim[i];
303 303
      if( s>=0 )
304 304
        s=0;
305 305
      return State(s);
306 306
    }
307 307

	
308
    /// \brief Sets the state of the \c item in the heap.
308
    /// \brief Set the state of an item in the heap.
309 309
    ///
310
    /// Sets the state of the \c item in the heap. It can be used to
311
    /// manually clear the heap when it is important to achive the
312
    /// better time complexity.
310
    /// This function sets the state of the given item in the heap.
311
    /// It can be used to manually clear the heap when it is important
312
    /// to achive better time complexity.
313 313
    /// \param i The item.
314 314
    /// \param st The state. It should not be \c IN_HEAP.
315 315
    void state(const Item& i, State st) {
316 316
      switch (st) {
317 317
      case POST_HEAP:
318 318
      case PRE_HEAP:
319 319
        if (state(i) == IN_HEAP) {
320 320
          erase(i);
321 321
        }
322
        iim[i] = st;
322
        _iim[i] = st;
323 323
        break;
324 324
      case IN_HEAP:
325 325
        break;
326 326
      }
327 327
    }
328 328

	
329
    /// \brief Replaces an item in the heap.
329
    /// \brief Replace an item in the heap.
330 330
    ///
331
    /// The \c i item is replaced with \c j item. The \c i item should
332
    /// be in the heap, while the \c j should be out of the heap. The
333
    /// \c i item will out of the heap and \c j will be in the heap
334
    /// with the same prioriority as prevoiusly the \c i item.
331
    /// This function replaces item \c i with item \c j.
332
    /// Item \c i must be in the heap, while \c j must be out of the heap.
333
    /// After calling this method, item \c i will be out of the
334
    /// heap and \c j will be in the heap with the same prioriority
335
    /// as item \c i had before.
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
    Node fromId(int id, Node) const {
59
    static Node fromId(int id, Node) {
59 60
      return Parent::nodeFromId(id);
60 61
    }
61 62

	
62
    Arc fromId(int id, Arc) const {
63
    static Arc fromId(int id, Arc) {
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
    Node fromId(int id, Node) const {
358
    static Node fromId(int id, Node) {
359 359
      return Parent::nodeFromId(id);
360 360
    }
361 361

	
362
    Arc fromId(int id, Arc) const {
362
    static Arc fromId(int id, Arc) {
363 363
      return Parent::arcFromId(id);
364 364
    }
365 365

	
366
    Edge fromId(int id, Edge) const {
366
    static Edge fromId(int id, Edge) {
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

	
608
      NodeMap(const Graph& graph)
606
    public:
607
      explicit 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

	
633
      ArcMap(const Graph& graph)
630
    public:
631
      explicit 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

	
658
      EdgeMap(const Graph& graph)
654
    public:
655
      explicit 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() {}
84 88

	
85 89
      MapIt(Invalid i) : Parent(i) { }
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() {}
124 128

	
125 129
      ConstMapIt(Invalid i) : Parent(i) { }
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 {
152
      typedef Item Parent;
153

	
148 154
    public:
149 155

	
150
      typedef Item Parent;
151

	
152 156
      ItemIt() {}
153 157

	
154 158
      ItemIt(Invalid i) : Parent(i) { }
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() {}
228 235

	
229 236
      MapIt(Invalid i) : Parent(i) { }
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() {}
268 275

	
269 276
      ConstMapIt(Invalid i) : Parent(i) { }
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 {
299
      typedef Item Parent;
300

	
292 301
    public:
293 302

	
294
      typedef Item Parent;
295

	
296 303
      ItemIt() {}
297 304

	
298 305
      ItemIt(Invalid i) : Parent(i) { }
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
    /// This class describes the \ref concept "concept" of the
39
    /// immutable directed digraphs.
38
    /// This class describes the common interface of all directed
39
    /// graphs (digraphs).
40 40
    ///
41
    /// Note that actual digraph implementation like @ref ListDigraph or
42
    /// @ref SmartDigraph may have several additional functionality.
41
    /// Like all concept classes, it only provides an interface
42
    /// without any sensible implementation. So any general algorithm for
43
    /// directed graphs should compile with this class, but it will not
44
    /// run properly, of course.
45
    /// An actual digraph implementation like \ref ListDigraph or
46
    /// \ref SmartDigraph may have additional functionality.
43 47
    ///
44
    /// \sa concept
48
    /// \sa Graph
45 49
    class Digraph {
46 50
    private:
47
      ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
51
      /// Diraphs are \e not copy constructible. Use DigraphCopy instead.
52
      Digraph(const Digraph &) {}
53
      /// \brief Assignment of a digraph to another one is \e not allowed.
54
      /// Use DigraphCopy instead.
55
      void operator=(const Digraph &) {}
48 56

	
49
      ///Digraphs are \e not copy constructible. Use DigraphCopy() instead.
50
      ///
51
      Digraph(const Digraph &) {};
52
      ///\brief Assignment of \ref Digraph "Digraph"s to another ones are
53
      ///\e not allowed. Use DigraphCopy() instead.
57
    public:
58
      /// Default constructor.
59
      Digraph() { }
54 60

	
55
      ///Assignment of \ref Digraph "Digraph"s to another ones are
56
      ///\e not allowed.  Use DigraphCopy() instead.
57

	
58
      void operator=(const Digraph &) {}
59
    public:
60
      ///\e
61

	
62
      /// Defalult constructor.
63

	
64
      /// Defalult constructor.
65
      ///
66
      Digraph() { }
67
      /// Class for identifying a node of the digraph
61
      /// The node type of the digraph
68 62

	
69 63
      /// This class identifies a node of the digraph. It also serves
70 64
      /// as a base class of the node iterators,
71
      /// thus they will convert to this type.
65
      /// thus they convert to this type.
72 66
      class Node {
73 67
      public:
74 68
        /// Default constructor
75 69

	
76
        /// @warning The default constructor sets the iterator
77
        /// to an undefined value.
70
        /// Default constructor.
71
        /// \warning It sets the object to an undefined value.
78 72
        Node() { }
79 73
        /// Copy constructor.
80 74

	
81 75
        /// Copy constructor.
82 76
        ///
83 77
        Node(const Node&) { }
84 78

	
85
        /// Invalid constructor \& conversion.
79
        /// %Invalid constructor \& conversion.
86 80

	
87
        /// This constructor initializes the iterator to be invalid.
81
        /// Initializes the object to be invalid.
88 82
        /// \sa Invalid for more details.
89 83
        Node(Invalid) { }
90 84
        /// Equality operator
91 85

	
86
        /// Equality operator.
87
        ///
92 88
        /// Two iterators are equal if and only if they point to the
93
        /// same object or both are invalid.
89
        /// same object or both are \c INVALID.
94 90
        bool operator==(Node) const { return true; }
95 91

	
96 92
        /// Inequality operator
97 93

	
98
        /// \sa operator==(Node n)
99
        ///
94
        /// Inequality operator.
100 95
        bool operator!=(Node) const { return true; }
101 96

	
102 97
        /// Artificial ordering operator.
103 98

	
104
        /// To allow the use of digraph descriptors as key type in std::map or
105
        /// similar associative container we require this.
99
        /// Artificial ordering operator.
106 100
        ///
107
        /// \note This operator only have to define some strict ordering of
108
        /// the items; this order has nothing to do with the iteration
109
        /// ordering of the items.
101
        /// \note This operator only has to define some strict ordering of
102
        /// the nodes; this order has nothing to do with the iteration
103
        /// ordering of the nodes.
110 104
        bool operator<(Node) const { return false; }
111

	
112 105
      };
113 106

	
114
      /// This iterator goes through each node.
107
      /// Iterator class for the nodes.
115 108

	
116
      /// This iterator goes through each node.
109
      /// This iterator goes through each node of the digraph.
117 110
      /// Its usage is quite simple, for example you can count the number
118
      /// of nodes in digraph \c g of type \c Digraph like this:
111
      /// of nodes in a digraph \c g of type \c %Digraph like this:
119 112
      ///\code
120 113
      /// int count=0;
121 114
      /// for (Digraph::NodeIt n(g); n!=INVALID; ++n) ++count;
122 115
      ///\endcode
123 116
      class NodeIt : public Node {
124 117
      public:
125 118
        /// Default constructor
126 119

	
127
        /// @warning The default constructor sets the iterator
128
        /// to an undefined value.
120
        /// Default constructor.
121
        /// \warning It sets the iterator to an undefined value.
129 122
        NodeIt() { }
130 123
        /// Copy constructor.
131 124

	
132 125
        /// Copy constructor.
133 126
        ///
134 127
        NodeIt(const NodeIt& n) : Node(n) { }
135
        /// Invalid constructor \& conversion.
128
        /// %Invalid constructor \& conversion.
136 129

	
137
        /// Initialize the iterator to be invalid.
130
        /// Initializes the iterator to be invalid.
138 131
        /// \sa Invalid for more details.
139 132
        NodeIt(Invalid) { }
140 133
        /// Sets the iterator to the first node.
141 134

	
142
        /// Sets the iterator to the first node of \c g.
135
        /// Sets the iterator to the first node of the given digraph.
143 136
        ///
144
        NodeIt(const Digraph&) { }
145
        /// Node -> NodeIt conversion.
137
        explicit NodeIt(const Digraph&) { }
138
        /// Sets the iterator to the given node.
146 139

	
147
        /// Sets the iterator to the node of \c the digraph pointed by
148
        /// the trivial iterator.
149
        /// This feature necessitates that each time we
150
        /// iterate the arc-set, the iteration order is the same.
140
        /// Sets the iterator to the given node of the given digraph.
141
        ///
151 142
        NodeIt(const Digraph&, const Node&) { }
152 143
        /// Next node.
153 144

	
154 145
        /// Assign the iterator to the next node.
155 146
        ///
156 147
        NodeIt& operator++() { return *this; }
157 148
      };
158 149

	
159 150

	
160
      /// Class for identifying an arc of the digraph
151
      /// The arc type of the digraph
161 152

	
162 153
      /// This class identifies an arc of the digraph. It also serves
163 154
      /// as a base class of the arc iterators,
164 155
      /// thus they will convert to this type.
165 156
      class Arc {
166 157
      public:
167 158
        /// Default constructor
168 159

	
169
        /// @warning The default constructor sets the iterator
170
        /// to an undefined value.
160
        /// Default constructor.
161
        /// \warning It sets the object to an undefined value.
171 162
        Arc() { }
172 163
        /// Copy constructor.
173 164

	
174 165
        /// Copy constructor.
175 166
        ///
176 167
        Arc(const Arc&) { }
177
        /// Initialize the iterator to be invalid.
168
        /// %Invalid constructor \& conversion.
178 169

	
179
        /// Initialize the iterator to be invalid.
180
        ///
170
        /// Initializes the object to be invalid.
171
        /// \sa Invalid for more details.
181 172
        Arc(Invalid) { }
182 173
        /// Equality operator
183 174

	
175
        /// Equality operator.
176
        ///
184 177
        /// Two iterators are equal if and only if they point to the
185
        /// same object or both are invalid.
178
        /// same object or both are \c INVALID.
186 179
        bool operator==(Arc) const { return true; }
187 180
        /// Inequality operator
188 181

	
189
        /// \sa operator==(Arc n)
190
        ///
182
        /// Inequality operator.
191 183
        bool operator!=(Arc) const { return true; }
192 184

	
193 185
        /// Artificial ordering operator.
194 186

	
195
        /// To allow the use of digraph descriptors as key type in std::map or
196
        /// similar associative container we require this.
187
        /// Artificial ordering operator.
197 188
        ///
198
        /// \note This operator only have to define some strict ordering of
199
        /// the items; this order has nothing to do with the iteration
200
        /// ordering of the items.
189
        /// \note This operator only has to define some strict ordering of
190
        /// the arcs; this order has nothing to do with the iteration
191
        /// ordering of the arcs.
201 192
        bool operator<(Arc) const { return false; }
202 193
      };
203 194

	
204
      /// This iterator goes trough the outgoing arcs of a node.
195
      /// Iterator class for the outgoing arcs of a node.
205 196

	
206 197
      /// This iterator goes trough the \e outgoing arcs of a certain node
207 198
      /// of a digraph.
208 199
      /// Its usage is quite simple, for example you can count the number
209 200
      /// of outgoing arcs of a node \c n
210
      /// in digraph \c g of type \c Digraph as follows.
201
      /// in a digraph \c g of type \c %Digraph as follows.
211 202
      ///\code
212 203
      /// int count=0;
213
      /// for (Digraph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
204
      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
214 205
      ///\endcode
215

	
216 206
      class OutArcIt : public Arc {
217 207
      public:
218 208
        /// Default constructor
219 209

	
220
        /// @warning The default constructor sets the iterator
221
        /// to an undefined value.
210
        /// Default constructor.
211
        /// \warning It sets the iterator to an undefined value.
222 212
        OutArcIt() { }
223 213
        /// Copy constructor.
224 214

	
225 215
        /// Copy constructor.
226 216
        ///
227 217
        OutArcIt(const OutArcIt& e) : Arc(e) { }
228
        /// Initialize the iterator to be invalid.
218
        /// %Invalid constructor \& conversion.
229 219

	
230
        /// Initialize the iterator to be invalid.
220
        /// Initializes the iterator to be invalid.
221
        /// \sa Invalid for more details.
222
        OutArcIt(Invalid) { }
223
        /// Sets the iterator to the first outgoing arc.
224

	
225
        /// Sets the iterator to the first outgoing arc of the given node.
231 226
        ///
232
        OutArcIt(Invalid) { }
233
        /// This constructor sets the iterator to the first outgoing arc.
227
        OutArcIt(const Digraph&, const Node&) { }
228
        /// Sets the iterator to the given arc.
234 229

	
235
        /// This constructor sets the iterator to the first outgoing arc of
236
        /// the node.
237
        OutArcIt(const Digraph&, const Node&) { }
238
        /// Arc -> OutArcIt conversion
239

	
240
        /// Sets the iterator to the value of the trivial iterator.
241
        /// This feature necessitates that each time we
242
        /// iterate the arc-set, the iteration order is the same.
230
        /// Sets the iterator to the given arc of the given digraph.
231
        ///
243 232
        OutArcIt(const Digraph&, const Arc&) { }
244
        ///Next outgoing arc
233
        /// Next outgoing arc
245 234

	
246 235
        /// Assign the iterator to the next
247 236
        /// outgoing arc of the corresponding node.
248 237
        OutArcIt& operator++() { return *this; }
249 238
      };
250 239

	
251
      /// This iterator goes trough the incoming arcs of a node.
240
      /// Iterator class for the incoming arcs of a node.
252 241

	
253 242
      /// This iterator goes trough the \e incoming arcs of a certain node
254 243
      /// of a digraph.
255 244
      /// Its usage is quite simple, for example you can count the number
256
      /// of outgoing arcs of a node \c n
257
      /// in digraph \c g of type \c Digraph as follows.
245
      /// of incoming arcs of a node \c n
246
      /// in a digraph \c g of type \c %Digraph as follows.
258 247
      ///\code
259 248
      /// int count=0;
260
      /// for(Digraph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
249
      /// for(Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
261 250
      ///\endcode
262

	
263 251
      class InArcIt : public Arc {
264 252
      public:
265 253
        /// Default constructor
266 254

	
267
        /// @warning The default constructor sets the iterator
268
        /// to an undefined value.
255
        /// Default constructor.
256
        /// \warning It sets the iterator to an undefined value.
269 257
        InArcIt() { }
270 258
        /// Copy constructor.
271 259

	
272 260
        /// Copy constructor.
273 261
        ///
274 262
        InArcIt(const InArcIt& e) : Arc(e) { }
275
        /// Initialize the iterator to be invalid.
263
        /// %Invalid constructor \& conversion.
276 264

	
277
        /// Initialize the iterator to be invalid.
265
        /// Initializes the iterator to be invalid.
266
        /// \sa Invalid for more details.
267
        InArcIt(Invalid) { }
268
        /// Sets the iterator to the first incoming arc.
269

	
270
        /// Sets the iterator to the first incoming arc of the given node.
278 271
        ///
279
        InArcIt(Invalid) { }
280
        /// This constructor sets the iterator to first incoming arc.
272
        InArcIt(const Digraph&, const Node&) { }
273
        /// Sets the iterator to the given arc.
281 274

	
282
        /// This constructor set the iterator to the first incoming arc of
283
        /// the node.
284
        InArcIt(const Digraph&, const Node&) { }
285
        /// Arc -> InArcIt conversion
286

	
287
        /// Sets the iterator to the value of the trivial iterator \c e.
288
        /// This feature necessitates that each time we
289
        /// iterate the arc-set, the iteration order is the same.
275
        /// Sets the iterator to the given arc of the given digraph.
276
        ///
290 277
        InArcIt(const Digraph&, const Arc&) { }
291 278
        /// Next incoming arc
292 279

	
293
        /// Assign the iterator to the next inarc of the corresponding node.
294
        ///
280
        /// Assign the iterator to the next
281
        /// incoming arc of the corresponding node.
295 282
        InArcIt& operator++() { return *this; }
296 283
      };
297
      /// This iterator goes through each arc.
298 284

	
299
      /// This iterator goes through each arc of a digraph.
285
      /// Iterator class for the arcs.
286

	
287
      /// This iterator goes through each arc of the digraph.
300 288
      /// Its usage is quite simple, for example you can count the number
301
      /// of arcs in a digraph \c g of type \c Digraph as follows:
289
      /// of arcs in a digraph \c g of type \c %Digraph as follows:
302 290
      ///\code
303 291
      /// int count=0;
304
      /// for(Digraph::ArcIt e(g); e!=INVALID; ++e) ++count;
292
      /// for(Digraph::ArcIt a(g); a!=INVALID; ++a) ++count;
305 293
      ///\endcode
306 294
      class ArcIt : public Arc {
307 295
      public:
308 296
        /// Default constructor
309 297

	
310
        /// @warning The default constructor sets the iterator
311
        /// to an undefined value.
298
        /// Default constructor.
299
        /// \warning It sets the iterator to an undefined value.
312 300
        ArcIt() { }
313 301
        /// Copy constructor.
314 302

	
315 303
        /// Copy constructor.
316 304
        ///
317 305
        ArcIt(const ArcIt& e) : Arc(e) { }
318
        /// Initialize the iterator to be invalid.
306
        /// %Invalid constructor \& conversion.
319 307

	
320
        /// Initialize the iterator to be invalid.
308
        /// Initializes the iterator to be invalid.
309
        /// \sa Invalid for more details.
310
        ArcIt(Invalid) { }
311
        /// Sets the iterator to the first arc.
312

	
313
        /// Sets the iterator to the first arc of the given digraph.
321 314
        ///
322
        ArcIt(Invalid) { }
323
        /// This constructor sets the iterator to the first arc.
315
        explicit ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
316
        /// Sets the iterator to the given arc.
324 317

	
325
        /// This constructor sets the iterator to the first arc of \c g.
326
        ///@param g the digraph
327
        ArcIt(const Digraph& g) { ignore_unused_variable_warning(g); }
328
        /// Arc -> ArcIt conversion
329

	
330
        /// Sets the iterator to the value of the trivial iterator \c e.
331
        /// This feature necessitates that each time we
332
        /// iterate the arc-set, the iteration order is the same.
318
        /// Sets the iterator to the given arc of the given digraph.
319
        ///
333 320
        ArcIt(const Digraph&, const Arc&) { }
334
        ///Next arc
321
        /// Next arc
335 322

	
336 323
        /// Assign the iterator to the next arc.
324
        ///
337 325
        ArcIt& operator++() { return *this; }
338 326
      };
339
      ///Gives back the target node of an arc.
340 327

	
341
      ///Gives back the target node of an arc.
328
      /// \brief The source node of the arc.
342 329
      ///
343
      Node target(Arc) const { return INVALID; }
344
      ///Gives back the source node of an arc.
345

	
346
      ///Gives back the source node of an arc.
347
      ///
330
      /// Returns the source node of the given arc.
348 331
      Node source(Arc) const { return INVALID; }
349 332

	
350
      /// \brief Returns the ID of the node.
333
      /// \brief The target node of the arc.
334
      ///
335
      /// Returns the target node of the given arc.
336
      Node target(Arc) const { return INVALID; }
337

	
338
      /// \brief The ID of the node.
339
      ///
340
      /// Returns the ID of the given node.
351 341
      int id(Node) const { return -1; }
352 342

	
353
      /// \brief Returns the ID of the arc.
343
      /// \brief The ID of the arc.
344
      ///
345
      /// Returns the ID of the given arc.
354 346
      int id(Arc) const { return -1; }
355 347

	
356
      /// \brief Returns the node with the given ID.
348
      /// \brief The node with the given ID.
357 349
      ///
358
      /// \pre The argument should be a valid node ID in the graph.
350
      /// Returns the node with the given ID.
351
      /// \pre The argument should be a valid node ID in the digraph.
359 352
      Node nodeFromId(int) const { return INVALID; }
360 353

	
361
      /// \brief Returns the arc with the given ID.
354
      /// \brief The arc with the given ID.
362 355
      ///
363
      /// \pre The argument should be a valid arc ID in the graph.
356
      /// Returns the arc with the given ID.
357
      /// \pre The argument should be a valid arc ID in the digraph.
364 358
      Arc arcFromId(int) const { return INVALID; }
365 359

	
366
      /// \brief Returns an upper bound on the node IDs.
360
      /// \brief An upper bound on the node IDs.
361
      ///
362
      /// Returns an upper bound on the node IDs.
367 363
      int maxNodeId() const { return -1; }
368 364

	
369
      /// \brief Returns an upper bound on the arc IDs.
365
      /// \brief An upper bound on the arc IDs.
366
      ///
367
      /// Returns an upper bound on the arc IDs.
370 368
      int maxArcId() const { return -1; }
371 369

	
372 370
      void first(Node&) const {}
373 371
      void next(Node&) const {}
374 372

	
375 373
      void first(Arc&) const {}
376 374
      void next(Arc&) const {}
377 375

	
378 376

	
379 377
      void firstIn(Arc&, const Node&) const {}
380 378
      void nextIn(Arc&) const {}
381 379

	
382 380
      void firstOut(Arc&, const Node&) const {}
383 381
      void nextOut(Arc&) const {}
384 382

	
385 383
      // The second parameter is dummy.
386 384
      Node fromId(int, Node) const { return INVALID; }
387 385
      // The second parameter is dummy.
388 386
      Arc fromId(int, Arc) const { return INVALID; }
389 387

	
390 388
      // Dummy parameter.
391 389
      int maxId(Node) const { return -1; }
392 390
      // Dummy parameter.
393 391
      int maxId(Arc) const { return -1; }
394 392

	
393
      /// \brief The opposite node on the arc.
394
      ///
395
      /// Returns the opposite node on the given arc.
396
      Node oppositeNode(Node, Arc) const { return INVALID; }
397

	
395 398
      /// \brief The base node of the iterator.
396 399
      ///
397
      /// Gives back the base node of the iterator.
398
      /// It is always the target of the pointed arc.
399
      Node baseNode(const InArcIt&) const { return INVALID; }
400
      /// Returns the base node of the given outgoing arc iterator
401
      /// (i.e. the source node of the corresponding arc).
402
      Node baseNode(OutArcIt) const { return INVALID; }
400 403

	
401 404
      /// \brief The running node of the iterator.
402 405
      ///
403
      /// Gives back the running node of the iterator.
404
      /// It is always the source of the pointed arc.
405
      Node runningNode(const InArcIt&) const { return INVALID; }
406
      /// Returns the running node of the given outgoing arc iterator
407
      /// (i.e. the target node of the corresponding arc).
408
      Node runningNode(OutArcIt) const { return INVALID; }
406 409

	
407 410
      /// \brief The base node of the iterator.
408 411
      ///
409
      /// Gives back the base node of the iterator.
410
      /// It is always the source of the pointed arc.
411
      Node baseNode(const OutArcIt&) const { return INVALID; }
412
      /// Returns the base node of the given incomming arc iterator
413
      /// (i.e. the target node of the corresponding arc).
414
      Node baseNode(InArcIt) const { return INVALID; }
412 415

	
413 416
      /// \brief The running node of the iterator.
414 417
      ///
415
      /// Gives back the running node of the iterator.
416
      /// It is always the target of the pointed arc.
417
      Node runningNode(const OutArcIt&) const { return INVALID; }
418
      /// Returns the running node of the given incomming arc iterator
419
      /// (i.e. the source node of the corresponding arc).
420
      Node runningNode(InArcIt) const { return INVALID; }
418 421

	
419
      /// \brief The opposite node on the given arc.
422
      /// \brief Standard graph map type for the nodes.
420 423
      ///
421
      /// Gives back the opposite node on the given arc.
422
      Node oppositeNode(const Node&, const Arc&) const { return INVALID; }
423

	
424
      /// \brief Read write map of the nodes to type \c T.
425
      ///
426
      /// ReadWrite map of the nodes to type \c T.
427
      /// \sa Reference
424
      /// Standard graph map type for the nodes.
425
      /// It conforms to the ReferenceMap concept.
428 426
      template<class T>
429
      class NodeMap : public ReadWriteMap< Node, T > {
427
      class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
430 428
      public:
431 429

	
432
        ///\e
433
        NodeMap(const Digraph&) { }
434
        ///\e
430
        /// Constructor
431
        explicit NodeMap(const Digraph&) { }
432
        /// Constructor with given initial value
435 433
        NodeMap(const Digraph&, T) { }
436 434

	
437 435
      private:
438 436
        ///Copy constructor
439
        NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
437
        NodeMap(const NodeMap& nm) : 
438
          ReferenceMap<Node, T, T&, const T&>(nm) { }
440 439
        ///Assignment operator
441 440
        template <typename CMap>
442 441
        NodeMap& operator=(const CMap&) {
443 442
          checkConcept<ReadMap<Node, T>, CMap>();
444 443
          return *this;
445 444
        }
446 445
      };
447 446

	
448
      /// \brief Read write map of the arcs to type \c T.
447
      /// \brief Standard graph map type for the arcs.
449 448
      ///
450
      /// Reference map of the arcs to type \c T.
451
      /// \sa Reference
449
      /// Standard graph map type for the arcs.
450
      /// It conforms to the ReferenceMap concept.
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
        ///\e
457
        ArcMap(const Digraph&) { }
458
        ///\e
455
        /// Constructor
456
        explicit ArcMap(const Digraph&) { }
457
        /// Constructor with given initial value
459 458
        ArcMap(const Digraph&, T) { }
459

	
460 460
      private:
461 461
        ///Copy constructor
462
        ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { }
462
        ArcMap(const ArcMap& em) :
463
          ReferenceMap<Arc, T, T&, const T&>(em) { }
463 464
        ///Assignment operator
464 465
        template <typename CMap>
465 466
        ArcMap& operator=(const CMap&) {
466 467
          checkConcept<ReadMap<Arc, T>, CMap>();
467 468
          return *this;
468 469
        }
469 470
      };
470 471

	
471 472
      template <typename _Digraph>
472 473
      struct Constraints {
473 474
        void constraints() {
475
          checkConcept<BaseDigraphComponent, _Digraph>();
474 476
          checkConcept<IterableDigraphComponent<>, _Digraph>();
475 477
          checkConcept<IDableDigraphComponent<>, _Digraph>();
476 478
          checkConcept<MappableDigraphComponent<>, _Digraph>();
477 479
        }
478 480
      };
479 481

	
480 482
    };
481 483

	
482 484
  } //namespace concepts
483 485
} //namespace lemon
484 486

	
485 487

	
486 488

	
487
#endif // LEMON_CONCEPT_DIGRAPH_H
489
#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
///\brief The concept of Undirected Graphs.
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>
27
#include <lemon/concepts/maps.h>
28
#include <lemon/concept_check.h>
28 29
#include <lemon/core.h>
29 30

	
30 31
namespace lemon {
31 32
  namespace concepts {
32 33

	
33 34
    /// \ingroup graph_concepts
34 35
    ///
35
    /// \brief Class describing the concept of Undirected Graphs.
36
    /// \brief Class describing the concept of undirected graphs.
36 37
    ///
37
    /// This class describes the common interface of all Undirected
38
    /// Graphs.
38
    /// This class describes the common interface of all undirected
39
    /// graphs.
39 40
    ///
40
    /// As all concept describing classes it provides only interface
41
    /// without any sensible implementation. So any algorithm for
42
    /// undirected graph should compile with this class, but it will not
41
    /// Like all concept classes, it only provides an interface
42
    /// without any sensible implementation. So any general algorithm for
43
    /// undirected graphs should compile with this class, but it will not
43 44
    /// run properly, of course.
45
    /// An actual graph implementation like \ref ListGraph or
46
    /// \ref SmartGraph may have additional functionality.    
44 47
    ///
45
    /// The LEMON undirected graphs also fulfill the concept of
46
    /// directed graphs (\ref lemon::concepts::Digraph "Digraph
47
    /// Concept"). Each edges can be seen as two opposite
48
    /// directed arc and consequently the undirected graph can be
49
    /// seen as the direceted graph of these directed arcs. The
50
    /// Graph has the Edge inner class for the edges and
51
    /// the Arc type for the directed arcs. The Arc type is
52
    /// convertible to Edge or inherited from it so from a directed
53
    /// arc we can get the represented edge.
48
    /// The undirected graphs also fulfill the concept of \ref Digraph
49
    /// "directed graphs", since each edge can also be regarded as two
50
    /// oppositely directed arcs.
51
    /// Undirected graphs provide an Edge type for the undirected edges and
52
    /// an Arc type for the directed arcs. The Arc type is convertible to
53
    /// Edge or inherited from it, i.e. the corresponding edge can be
54
    /// obtained from an arc.
55
    /// EdgeIt and EdgeMap classes can be used for the edges, while ArcIt
56
    /// and ArcMap classes can be used for the arcs (just like in digraphs).
57
    /// Both InArcIt and OutArcIt iterates on the same edges but with
58
    /// opposite direction. IncEdgeIt also iterates on the same edges
59
    /// as OutArcIt and InArcIt, but it is not convertible to Arc,
60
    /// only to Edge.
54 61
    ///
55
    /// In the sense of the LEMON each edge has a default
56
    /// direction (it should be in every computer implementation,
57
    /// because the order of edge's nodes defines an
58
    /// orientation). With the default orientation we can define that
59
    /// the directed arc is forward or backward directed. With the \c
60
    /// direction() and \c direct() function we can get the direction
61
    /// of the directed arc and we can direct an edge.
62
    /// In LEMON, each undirected edge has an inherent orientation.
63
    /// Thus it can defined if an arc is forward or backward oriented in
64
    /// an undirected graph with respect to this default oriantation of
65
    /// the represented edge.
66
    /// With the direction() and direct() functions the direction
67
    /// of an arc can be obtained and set, respectively.
62 68
    ///
63
    /// The EdgeIt is an iterator for the edges. We can use
64
    /// the EdgeMap to map values for the edges. The InArcIt and
65
    /// OutArcIt iterates on the same edges but with opposite
66
    /// direction. The IncEdgeIt iterates also on the same edges
67
    /// as the OutArcIt and InArcIt but it is not convertible to Arc just
68
    /// to Edge.
69
    /// Only nodes and edges can be added to or removed from an undirected
70
    /// graph and the corresponding arcs are added or removed automatically.
71
    ///
72
    /// \sa Digraph
69 73
    class Graph {
74
    private:
75
      /// Graphs are \e not copy constructible. Use DigraphCopy instead.
76
      Graph(const Graph&) {}
77
      /// \brief Assignment of a graph to another one is \e not allowed.
78
      /// Use DigraphCopy instead.
79
      void operator=(const Graph&) {}
80

	
70 81
    public:
71
      /// \brief The undirected graph should be tagged by the
72
      /// UndirectedTag.
82
      /// Default constructor.
83
      Graph() {}
84

	
85
      /// \brief Undirected graphs should be tagged with \c UndirectedTag.
73 86
      ///
74
      /// The undirected graph should be tagged by the UndirectedTag. This
75
      /// tag helps the enable_if technics to make compile time
87
      /// Undirected graphs should be tagged with \c UndirectedTag.
88
      /// 
89
      /// This tag helps the \c enable_if technics to make compile time
76 90
      /// specializations for undirected graphs.
77 91
      typedef True UndirectedTag;
78 92

	
79
      /// \brief The base type of node iterators,
80
      /// or in other words, the trivial node iterator.
81
      ///
82
      /// This is the base type of each node iterator,
83
      /// thus each kind of node iterator converts to this.
84
      /// More precisely each kind of node iterator should be inherited
85
      /// from the trivial node iterator.
93
      /// The node type of the graph
94

	
95
      /// This class identifies a node of the graph. It also serves
96
      /// as a base class of the node iterators,
97
      /// thus they convert to this type.
86 98
      class Node {
87 99
      public:
88 100
        /// Default constructor
89 101

	
90
        /// @warning The default constructor sets the iterator
91
        /// to an undefined value.
102
        /// Default constructor.
103
        /// \warning It sets the object to an undefined value.
92 104
        Node() { }
93 105
        /// Copy constructor.
94 106

	
95 107
        /// Copy constructor.
96 108
        ///
97 109
        Node(const Node&) { }
98 110

	
99
        /// Invalid constructor \& conversion.
111
        /// %Invalid constructor \& conversion.
100 112

	
101
        /// This constructor initializes the iterator to be invalid.
113
        /// Initializes the object to be invalid.
102 114
        /// \sa Invalid for more details.
103 115
        Node(Invalid) { }
104 116
        /// Equality operator
105 117

	
118
        /// Equality operator.
119
        ///
106 120
        /// Two iterators are equal if and only if they point to the
107
        /// same object or both are invalid.
121
        /// same object or both are \c INVALID.
108 122
        bool operator==(Node) const { return true; }
109 123

	
110 124
        /// Inequality operator
111 125

	
112
        /// \sa operator==(Node n)
113
        ///
126
        /// Inequality operator.
114 127
        bool operator!=(Node) const { return true; }
115 128

	
116 129
        /// Artificial ordering operator.
117 130

	
118
        /// To allow the use of graph descriptors as key type in std::map or
119
        /// similar associative container we require this.
131
        /// Artificial ordering operator.
120 132
        ///
121
        /// \note This operator only have to define some strict ordering of
133
        /// \note This operator only has to define some strict ordering of
122 134
        /// the items; this order has nothing to do with the iteration
123 135
        /// ordering of the items.
124 136
        bool operator<(Node) const { return false; }
125 137

	
126 138
      };
127 139

	
128
      /// This iterator goes through each node.
140
      /// Iterator class for the nodes.
129 141

	
130
      /// This iterator goes through each node.
142
      /// This iterator goes through each node of the graph.
131 143
      /// Its usage is quite simple, for example you can count the number
132
      /// of nodes in graph \c g of type \c Graph like this:
144
      /// of nodes in a graph \c g of type \c %Graph like this:
133 145
      ///\code
134 146
      /// int count=0;
135 147
      /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
136 148
      ///\endcode
137 149
      class NodeIt : public Node {
138 150
      public:
139 151
        /// Default constructor
140 152

	
141
        /// @warning The default constructor sets the iterator
142
        /// to an undefined value.
153
        /// Default constructor.
154
        /// \warning It sets the iterator to an undefined value.
143 155
        NodeIt() { }
144 156
        /// Copy constructor.
145 157

	
146 158
        /// Copy constructor.
147 159
        ///
148 160
        NodeIt(const NodeIt& n) : Node(n) { }
149
        /// Invalid constructor \& conversion.
161
        /// %Invalid constructor \& conversion.
150 162

	
151
        /// Initialize the iterator to be invalid.
163
        /// Initializes the iterator to be invalid.
152 164
        /// \sa Invalid for more details.
153 165
        NodeIt(Invalid) { }
154 166
        /// Sets the iterator to the first node.
155 167

	
156
        /// Sets the iterator to the first node of \c g.
168
        /// Sets the iterator to the first node of the given digraph.
157 169
        ///
158
        NodeIt(const Graph&) { }
159
        /// Node -> NodeIt conversion.
170
        explicit NodeIt(const Graph&) { }
171
        /// Sets the iterator to the given node.
160 172

	
161
        /// Sets the iterator to the node of \c the graph pointed by
162
        /// the trivial iterator.
163
        /// This feature necessitates that each time we
164
        /// iterate the arc-set, the iteration order is the same.
173
        /// Sets the iterator to the given node of the given digraph.
174
        ///
165 175
        NodeIt(const Graph&, const Node&) { }
166 176
        /// Next node.
167 177

	
168 178
        /// Assign the iterator to the next node.
169 179
        ///
170 180
        NodeIt& operator++() { return *this; }
171 181
      };
172 182

	
173 183

	
174
      /// The base type of the edge iterators.
184
      /// The edge type of the graph
175 185

	
176
      /// The base type of the edge iterators.
177
      ///
186
      /// This class identifies an edge of the graph. It also serves
187
      /// as a base class of the edge iterators,
188
      /// thus they will convert to this type.
178 189
      class Edge {
179 190
      public:
180 191
        /// Default constructor
181 192

	
182
        /// @warning The default constructor sets the iterator
183
        /// to an undefined value.
193
        /// Default constructor.
194
        /// \warning It sets the object to an undefined value.
184 195
        Edge() { }
185 196
        /// Copy constructor.
186 197

	
187 198
        /// Copy constructor.
188 199
        ///
189 200
        Edge(const Edge&) { }
190
        /// Initialize the iterator to be invalid.
201
        /// %Invalid constructor \& conversion.
191 202

	
192
        /// Initialize the iterator to be invalid.
193
        ///
203
        /// Initializes the object to be invalid.
204
        /// \sa Invalid for more details.
194 205
        Edge(Invalid) { }
195 206
        /// Equality operator
196 207

	
208
        /// Equality operator.
209
        ///
197 210
        /// Two iterators are equal if and only if they point to the
198
        /// same object or both are invalid.
211
        /// same object or both are \c INVALID.
199 212
        bool operator==(Edge) const { return true; }
200 213
        /// Inequality operator
201 214

	
202
        /// \sa operator==(Edge n)
203
        ///
215
        /// Inequality operator.
204 216
        bool operator!=(Edge) const { return true; }
205 217

	
206 218
        /// Artificial ordering operator.
207 219

	
208
        /// To allow the use of graph descriptors as key type in std::map or
209
        /// similar associative container we require this.
220
        /// Artificial ordering operator.
210 221
        ///
211
        /// \note This operator only have to define some strict ordering of
212
        /// the items; this order has nothing to do with the iteration
213
        /// ordering of the items.
222
        /// \note This operator only has to define some strict ordering of
223
        /// the edges; this order has nothing to do with the iteration
224
        /// ordering of the edges.
214 225
        bool operator<(Edge) const { return false; }
215 226
      };
216 227

	
217
      /// This iterator goes through each edge.
228
      /// Iterator class for the edges.
218 229

	
219
      /// This iterator goes through each edge of a graph.
230
      /// This iterator goes through each edge of the graph.
220 231
      /// Its usage is quite simple, for example you can count the number
221
      /// of edges in a graph \c g of type \c Graph as follows:
232
      /// of edges in a graph \c g of type \c %Graph as follows:
222 233
      ///\code
223 234
      /// int count=0;
224 235
      /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
225 236
      ///\endcode
226 237
      class EdgeIt : public Edge {
227 238
      public:
228 239
        /// Default constructor
229 240

	
230
        /// @warning The default constructor sets the iterator
231
        /// to an undefined value.
241
        /// Default constructor.
242
        /// \warning It sets the iterator to an undefined value.
232 243
        EdgeIt() { }
233 244
        /// Copy constructor.
234 245

	
235 246
        /// Copy constructor.
236 247
        ///
237 248
        EdgeIt(const EdgeIt& e) : Edge(e) { }
238
        /// Initialize the iterator to be invalid.
249
        /// %Invalid constructor \& conversion.
239 250

	
240
        /// Initialize the iterator to be invalid.
251
        /// Initializes the iterator to be invalid.
252
        /// \sa Invalid for more details.
253
        EdgeIt(Invalid) { }
254
        /// Sets the iterator to the first edge.
255

	
256
        /// Sets the iterator to the first edge of the given graph.
241 257
        ///
242
        EdgeIt(Invalid) { }
243
        /// This constructor sets the iterator to the first edge.
258
        explicit EdgeIt(const Graph&) { }
259
        /// Sets the iterator to the given edge.
244 260

	
245
        /// This constructor sets the iterator to the first edge.
246
        EdgeIt(const Graph&) { }
247
        /// Edge -> EdgeIt conversion
248

	
249
        /// Sets the iterator to the value of the trivial iterator.
250
        /// This feature necessitates that each time we
251
        /// iterate the edge-set, the iteration order is the
252
        /// same.
261
        /// Sets the iterator to the given edge of the given graph.
262
        ///
253 263
        EdgeIt(const Graph&, const Edge&) { }
254 264
        /// Next edge
255 265

	
256 266
        /// Assign the iterator to the next edge.
267
        ///
257 268
        EdgeIt& operator++() { return *this; }
258 269
      };
259 270

	
260
      /// \brief This iterator goes trough the incident undirected
261
      /// arcs of a node.
262
      ///
263
      /// This iterator goes trough the incident edges
264
      /// of a certain node of a graph. You should assume that the
265
      /// loop arcs will be iterated twice.
266
      ///
271
      /// Iterator class for the incident edges of a node.
272

	
273
      /// This iterator goes trough the incident undirected edges
274
      /// of a certain node of a graph.
267 275
      /// Its usage is quite simple, for example you can compute the
268
      /// degree (i.e. count the number of incident arcs of a node \c n
269
      /// in graph \c g of type \c Graph as follows.
276
      /// degree (i.e. the number of incident edges) of a node \c n
277
      /// in a graph \c g of type \c %Graph as follows.
270 278
      ///
271 279
      ///\code
272 280
      /// int count=0;
273 281
      /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
274 282
      ///\endcode
283
      ///
284
      /// \warning Loop edges will be iterated twice.
275 285
      class IncEdgeIt : public Edge {
276 286
      public:
277 287
        /// Default constructor
278 288

	
279
        /// @warning The default constructor sets the iterator
280
        /// to an undefined value.
289
        /// Default constructor.
290
        /// \warning It sets the iterator to an undefined value.
281 291
        IncEdgeIt() { }
282 292
        /// Copy constructor.
283 293

	
284 294
        /// Copy constructor.
285 295
        ///
286 296
        IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
287
        /// Initialize the iterator to be invalid.
297
        /// %Invalid constructor \& conversion.
288 298

	
289
        /// Initialize the iterator to be invalid.
299
        /// Initializes the iterator to be invalid.
300
        /// \sa Invalid for more details.
301
        IncEdgeIt(Invalid) { }
302
        /// Sets the iterator to the first incident edge.
303

	
304
        /// Sets the iterator to the first incident edge of the given node.
290 305
        ///
291
        IncEdgeIt(Invalid) { }
292
        /// This constructor sets the iterator to first incident arc.
306
        IncEdgeIt(const Graph&, const Node&) { }
307
        /// Sets the iterator to the given edge.
293 308

	
294
        /// This constructor set the iterator to the first incident arc of
295
        /// the node.
296
        IncEdgeIt(const Graph&, const Node&) { }
297
        /// Edge -> IncEdgeIt conversion
309
        /// Sets the iterator to the given edge of the given graph.
310
        ///
311
        IncEdgeIt(const Graph&, const Edge&) { }
312
        /// Next incident edge
298 313

	
299
        /// Sets the iterator to the value of the trivial iterator \c e.
300
        /// This feature necessitates that each time we
301
        /// iterate the arc-set, the iteration order is the same.
302
        IncEdgeIt(const Graph&, const Edge&) { }
303
        /// Next incident arc
304

	
305
        /// Assign the iterator to the next incident arc
314
        /// Assign the iterator to the next incident edge
306 315
        /// of the corresponding node.
307 316
        IncEdgeIt& operator++() { return *this; }
308 317
      };
309 318

	
310
      /// The directed arc type.
319
      /// The arc type of the graph
311 320

	
312
      /// The directed arc type. It can be converted to the
313
      /// edge or it should be inherited from the undirected
314
      /// arc.
315
      class Arc : public Edge {
321
      /// This class identifies a directed arc of the graph. It also serves
322
      /// as a base class of the arc iterators,
323
      /// thus they will convert to this type.
324
      class Arc {
316 325
      public:
317 326
        /// Default constructor
318 327

	
319
        /// @warning The default constructor sets the iterator
320
        /// to an undefined value.
328
        /// Default constructor.
329
        /// \warning It sets the object to an undefined value.
321 330
        Arc() { }
322 331
        /// Copy constructor.
323 332

	
324 333
        /// Copy constructor.
325 334
        ///
326
        Arc(const Arc& e) : Edge(e) { }
327
        /// Initialize the iterator to be invalid.
335
        Arc(const Arc&) { }
336
        /// %Invalid constructor \& conversion.
328 337

	
329
        /// Initialize the iterator to be invalid.
330
        ///
338
        /// Initializes the object to be invalid.
339
        /// \sa Invalid for more details.
331 340
        Arc(Invalid) { }
332 341
        /// Equality operator
333 342

	
343
        /// Equality operator.
344
        ///
334 345
        /// Two iterators are equal if and only if they point to the
335
        /// same object or both are invalid.
346
        /// same object or both are \c INVALID.
336 347
        bool operator==(Arc) const { return true; }
337 348
        /// Inequality operator
338 349

	
339
        /// \sa operator==(Arc n)
340
        ///
350
        /// Inequality operator.
341 351
        bool operator!=(Arc) const { return true; }
342 352

	
343 353
        /// Artificial ordering operator.
344 354

	
345
        /// To allow the use of graph descriptors as key type in std::map or
346
        /// similar associative container we require this.
355
        /// Artificial ordering operator.
347 356
        ///
348
        /// \note This operator only have to define some strict ordering of
349
        /// the items; this order has nothing to do with the iteration
350
        /// ordering of the items.
357
        /// \note This operator only has to define some strict ordering of
358
        /// the arcs; this order has nothing to do with the iteration
359
        /// ordering of the arcs.
351 360
        bool operator<(Arc) const { return false; }
352 361

	
362
        /// Converison to \c Edge
363
        
364
        /// Converison to \c Edge.
365
        ///
366
        operator Edge() const { return Edge(); }
353 367
      };
354
      /// This iterator goes through each directed arc.
355 368

	
356
      /// This iterator goes through each arc of a graph.
369
      /// Iterator class for the arcs.
370

	
371
      /// This iterator goes through each directed arc of the graph.
357 372
      /// Its usage is quite simple, for example you can count the number
358
      /// of arcs in a graph \c g of type \c Graph as follows:
373
      /// of arcs in a graph \c g of type \c %Graph as follows:
359 374
      ///\code
360 375
      /// int count=0;
361
      /// for(Graph::ArcIt e(g); e!=INVALID; ++e) ++count;
376
      /// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count;
362 377
      ///\endcode
363 378
      class ArcIt : public Arc {
364 379
      public:
365 380
        /// Default constructor
366 381

	
367
        /// @warning The default constructor sets the iterator
368
        /// to an undefined value.
382
        /// Default constructor.
383
        /// \warning It sets the iterator to an undefined value.
369 384
        ArcIt() { }
370 385
        /// Copy constructor.
371 386

	
372 387
        /// Copy constructor.
373 388
        ///
374 389
        ArcIt(const ArcIt& e) : Arc(e) { }
375
        /// Initialize the iterator to be invalid.
390
        /// %Invalid constructor \& conversion.
376 391

	
377
        /// Initialize the iterator to be invalid.
392
        /// Initializes the iterator to be invalid.
393
        /// \sa Invalid for more details.
394
        ArcIt(Invalid) { }
395
        /// Sets the iterator to the first arc.
396

	
397
        /// Sets the iterator to the first arc of the given graph.
378 398
        ///
379
        ArcIt(Invalid) { }
380
        /// This constructor sets the iterator to the first arc.
399
        explicit ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
400
        /// Sets the iterator to the given arc.
381 401

	
382
        /// This constructor sets the iterator to the first arc of \c g.
383
        ///@param g the graph
384
        ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
385
        /// Arc -> ArcIt conversion
386

	
387
        /// Sets the iterator to the value of the trivial iterator \c e.
388
        /// This feature necessitates that each time we
389
        /// iterate the arc-set, the iteration order is the same.
402
        /// Sets the iterator to the given arc of the given graph.
403
        ///
390 404
        ArcIt(const Graph&, const Arc&) { }
391
        ///Next arc
405
        /// Next arc
392 406

	
393 407
        /// Assign the iterator to the next arc.
408
        ///
394 409
        ArcIt& operator++() { return *this; }
395 410
      };
396 411

	
397
      /// This iterator goes trough the outgoing directed arcs of a node.
412
      /// Iterator class for the outgoing arcs of a node.
398 413

	
399
      /// This iterator goes trough the \e outgoing arcs of a certain node
400
      /// of a graph.
414
      /// This iterator goes trough the \e outgoing directed arcs of a
415
      /// certain node of a graph.
401 416
      /// Its usage is quite simple, for example you can count the number
402 417
      /// of outgoing arcs of a node \c n
403
      /// in graph \c g of type \c Graph as follows.
418
      /// in a graph \c g of type \c %Graph as follows.
404 419
      ///\code
405 420
      /// int count=0;
406
      /// for (Graph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
421
      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
407 422
      ///\endcode
408

	
409 423
      class OutArcIt : public Arc {
410 424
      public:
411 425
        /// Default constructor
412 426

	
413
        /// @warning The default constructor sets the iterator
414
        /// to an undefined value.
427
        /// Default constructor.
428
        /// \warning It sets the iterator to an undefined value.
415 429
        OutArcIt() { }
416 430
        /// Copy constructor.
417 431

	
418 432
        /// Copy constructor.
419 433
        ///
420 434
        OutArcIt(const OutArcIt& e) : Arc(e) { }
421
        /// Initialize the iterator to be invalid.
435
        /// %Invalid constructor \& conversion.
422 436

	
423
        /// Initialize the iterator to be invalid.
437
        /// Initializes the iterator to be invalid.
438
        /// \sa Invalid for more details.
439
        OutArcIt(Invalid) { }
440
        /// Sets the iterator to the first outgoing arc.
441

	
442
        /// Sets the iterator to the first outgoing arc of the given node.
424 443
        ///
425
        OutArcIt(Invalid) { }
426
        /// This constructor sets the iterator to the first outgoing arc.
427

	
428
        /// This constructor sets the iterator to the first outgoing arc of
429
        /// the node.
430
        ///@param n the node
431
        ///@param g the graph
432 444
        OutArcIt(const Graph& n, const Node& g) {
433 445
          ignore_unused_variable_warning(n);
434 446
          ignore_unused_variable_warning(g);
435 447
        }
436
        /// Arc -> OutArcIt conversion
448
        /// Sets the iterator to the given arc.
437 449

	
438
        /// Sets the iterator to the value of the trivial iterator.
439
        /// This feature necessitates that each time we
440
        /// iterate the arc-set, the iteration order is the same.
450
        /// Sets the iterator to the given arc of the given graph.
451
        ///
441 452
        OutArcIt(const Graph&, const Arc&) { }
442
        ///Next outgoing arc
453
        /// Next outgoing arc
443 454

	
444 455
        /// Assign the iterator to the next
445 456
        /// outgoing arc of the corresponding node.
446 457
        OutArcIt& operator++() { return *this; }
447 458
      };
448 459

	
449
      /// This iterator goes trough the incoming directed arcs of a node.
460
      /// Iterator class for the incoming arcs of a node.
450 461

	
451
      /// This iterator goes trough the \e incoming arcs of a certain node
452
      /// of a graph.
462
      /// This iterator goes trough the \e incoming directed arcs of a
463
      /// certain node of a graph.
453 464
      /// Its usage is quite simple, for example you can count the number
454
      /// of outgoing arcs of a node \c n
455
      /// in graph \c g of type \c Graph as follows.
465
      /// of incoming arcs of a node \c n
466
      /// in a graph \c g of type \c %Graph as follows.
456 467
      ///\code
457 468
      /// int count=0;
458
      /// for(Graph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
469
      /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
459 470
      ///\endcode
460

	
461 471
      class InArcIt : public Arc {
462 472
      public:
463 473
        /// Default constructor
464 474

	
465
        /// @warning The default constructor sets the iterator
466
        /// to an undefined value.
475
        /// Default constructor.
476
        /// \warning It sets the iterator to an undefined value.
467 477
        InArcIt() { }
468 478
        /// Copy constructor.
469 479

	
470 480
        /// Copy constructor.
471 481
        ///
472 482
        InArcIt(const InArcIt& e) : Arc(e) { }
473
        /// Initialize the iterator to be invalid.
483
        /// %Invalid constructor \& conversion.
474 484

	
475
        /// Initialize the iterator to be invalid.
485
        /// Initializes the iterator to be invalid.
486
        /// \sa Invalid for more details.
487
        InArcIt(Invalid) { }
488
        /// Sets the iterator to the first incoming arc.
489

	
490
        /// Sets the iterator to the first incoming arc of the given node.
476 491
        ///
477
        InArcIt(Invalid) { }
478
        /// This constructor sets the iterator to first incoming arc.
479

	
480
        /// This constructor set the iterator to the first incoming arc of
481
        /// the node.
482
        ///@param n the node
483
        ///@param g the graph
484 492
        InArcIt(const Graph& g, const Node& n) {
485 493
          ignore_unused_variable_warning(n);
486 494
          ignore_unused_variable_warning(g);
487 495
        }
488
        /// Arc -> InArcIt conversion
496
        /// Sets the iterator to the given arc.
489 497

	
490
        /// Sets the iterator to the value of the trivial iterator \c e.
491
        /// This feature necessitates that each time we
492
        /// iterate the arc-set, the iteration order is the same.
498
        /// Sets the iterator to the given arc of the given graph.
499
        ///
493 500
        InArcIt(const Graph&, const Arc&) { }
494 501
        /// Next incoming arc
495 502

	
496
        /// Assign the iterator to the next inarc of the corresponding node.
497
        ///
503
        /// Assign the iterator to the next
504
        /// incoming arc of the corresponding node.
498 505
        InArcIt& operator++() { return *this; }
499 506
      };
500 507

	
501
      /// \brief Read write map of the nodes to type \c T.
508
      /// \brief Standard graph map type for the nodes.
502 509
      ///
503
      /// ReadWrite map of the nodes to type \c T.
504
      /// \sa Reference
510
      /// Standard graph map type for the nodes.
511
      /// It conforms to the ReferenceMap concept.
505 512
      template<class T>
506
      class NodeMap : public ReadWriteMap< Node, T >
513
      class NodeMap : public ReferenceMap<Node, T, T&, const T&>
507 514
      {
508 515
      public:
509 516

	
510
        ///\e
511
        NodeMap(const Graph&) { }
512
        ///\e
517
        /// Constructor
518
        explicit NodeMap(const Graph&) { }
519
        /// Constructor with given initial value
513 520
        NodeMap(const Graph&, T) { }
514 521

	
515 522
      private:
516 523
        ///Copy constructor
517
        NodeMap(const NodeMap& nm) : ReadWriteMap< Node, T >(nm) { }
524
        NodeMap(const NodeMap& nm) :
525
          ReferenceMap<Node, T, T&, const T&>(nm) { }
518 526
        ///Assignment operator
519 527
        template <typename CMap>
520 528
        NodeMap& operator=(const CMap&) {
521 529
          checkConcept<ReadMap<Node, T>, CMap>();
522 530
          return *this;
523 531
        }
524 532
      };
525 533

	
526
      /// \brief Read write map of the directed arcs to type \c T.
534
      /// \brief Standard graph map type for the arcs.
527 535
      ///
528
      /// Reference map of the directed arcs to type \c T.
529
      /// \sa Reference
536
      /// Standard graph map type for the arcs.
537
      /// It conforms to the ReferenceMap concept.
530 538
      template<class T>
531
      class ArcMap : public ReadWriteMap<Arc,T>
539
      class ArcMap : public ReferenceMap<Arc, T, T&, const T&>
532 540
      {
533 541
      public:
534 542

	
535
        ///\e
536
        ArcMap(const Graph&) { }
537
        ///\e
543
        /// Constructor
544
        explicit ArcMap(const Graph&) { }
545
        /// Constructor with given initial value
538 546
        ArcMap(const Graph&, T) { }
547

	
539 548
      private:
540 549
        ///Copy constructor
541
        ArcMap(const ArcMap& em) : ReadWriteMap<Arc,T>(em) { }
550
        ArcMap(const ArcMap& em) :
551
          ReferenceMap<Arc, T, T&, const T&>(em) { }
542 552
        ///Assignment operator
543 553
        template <typename CMap>
544 554
        ArcMap& operator=(const CMap&) {
545 555
          checkConcept<ReadMap<Arc, T>, CMap>();
546 556
          return *this;
547 557
        }
548 558
      };
549 559

	
550
      /// Read write map of the edges to type \c T.
551

	
552
      /// Reference map of the arcs to type \c T.
553
      /// \sa Reference
560
      /// \brief Standard graph map type for the edges.
561
      ///
562
      /// Standard graph map type for the edges.
563
      /// It conforms to the ReferenceMap concept.
554 564
      template<class T>
555
      class EdgeMap : public ReadWriteMap<Edge,T>
565
      class EdgeMap : public ReferenceMap<Edge, T, T&, const T&>
556 566
      {
557 567
      public:
558 568

	
559
        ///\e
560
        EdgeMap(const Graph&) { }
561
        ///\e
569
        /// Constructor
570
        explicit EdgeMap(const Graph&) { }
571
        /// Constructor with given initial value
562 572
        EdgeMap(const Graph&, T) { }
573

	
563 574
      private:
564 575
        ///Copy constructor
565
        EdgeMap(const EdgeMap& em) : ReadWriteMap<Edge,T>(em) {}
576
        EdgeMap(const EdgeMap& em) :
577
          ReferenceMap<Edge, T, T&, const T&>(em) {}
566 578
        ///Assignment operator
567 579
        template <typename CMap>
568 580
        EdgeMap& operator=(const CMap&) {
569 581
          checkConcept<ReadMap<Edge, T>, CMap>();
570 582
          return *this;
571 583
        }
572 584
      };
573 585

	
574
      /// \brief Direct the given edge.
586
      /// \brief The first node of the edge.
575 587
      ///
576
      /// Direct the given edge. The returned arc source
577
      /// will be the given node.
578
      Arc direct(const Edge&, const Node&) const {
588
      /// Returns the first node of the given edge.
589
      ///
590
      /// Edges don't have source and target nodes, however methods
591
      /// u() and v() are used to query the two end-nodes of an edge.
592
      /// The orientation of an edge that arises this way is called
593
      /// the inherent direction, it is used to define the default
594
      /// direction for the corresponding arcs.
595
      /// \sa v()
596
      /// \sa direction()
597
      Node u(Edge) const { return INVALID; }
598

	
599
      /// \brief The second node of the edge.
600
      ///
601
      /// Returns the second node of the given edge.
602
      ///
603
      /// Edges don't have source and target nodes, however methods
604
      /// u() and v() are used to query the two end-nodes of an edge.
605
      /// The orientation of an edge that arises this way is called
606
      /// the inherent direction, it is used to define the default
607
      /// direction for the corresponding arcs.
608
      /// \sa u()
609
      /// \sa direction()
610
      Node v(Edge) const { return INVALID; }
611

	
612
      /// \brief The source node of the arc.
613
      ///
614
      /// Returns the source node of the given arc.
615
      Node source(Arc) const { return INVALID; }
616

	
617
      /// \brief The target node of the arc.
618
      ///
619
      /// Returns the target node of the given arc.
620
      Node target(Arc) const { return INVALID; }
621

	
622
      /// \brief The ID of the node.
623
      ///
624
      /// Returns the ID of the given node.
625
      int id(Node) const { return -1; }
626

	
627
      /// \brief The ID of the edge.
628
      ///
629
      /// Returns the ID of the given edge.
630
      int id(Edge) const { return -1; }
631

	
632
      /// \brief The ID of the arc.
633
      ///
634
      /// Returns the ID of the given arc.
635
      int id(Arc) const { return -1; }
636

	
637
      /// \brief The node with the given ID.
638
      ///
639
      /// Returns the node with the given ID.
640
      /// \pre The argument should be a valid node ID in the graph.
641
      Node nodeFromId(int) const { return INVALID; }
642

	
643
      /// \brief The edge with the given ID.
644
      ///
645
      /// Returns the edge with the given ID.
646
      /// \pre The argument should be a valid edge ID in the graph.
647
      Edge edgeFromId(int) const { return INVALID; }
648

	
649
      /// \brief The arc with the given ID.
650
      ///
651
      /// Returns the arc with the given ID.
652
      /// \pre The argument should be a valid arc ID in the graph.
653
      Arc arcFromId(int) const { return INVALID; }
654

	
655
      /// \brief An upper bound on the node IDs.
656
      ///
657
      /// Returns an upper bound on the node IDs.
658
      int maxNodeId() const { return -1; }
659

	
660
      /// \brief An upper bound on the edge IDs.
661
      ///
662
      /// Returns an upper bound on the edge IDs.
663
      int maxEdgeId() const { return -1; }
664

	
665
      /// \brief An upper bound on the arc IDs.
666
      ///
667
      /// Returns an upper bound on the arc IDs.
668
      int maxArcId() const { return -1; }
669

	
670
      /// \brief The direction of the arc.
671
      ///
672
      /// Returns \c true if the direction of the given arc is the same as
673
      /// the inherent orientation of the represented edge.
674
      bool direction(Arc) const { return true; }
675

	
676
      /// \brief Direct the edge.
677
      ///
678
      /// Direct the given edge. The returned arc
679
      /// represents the given edge and its direction comes
680
      /// from the bool parameter. If it is \c true, then the direction
681
      /// of the arc is the same as the inherent orientation of the edge.
682
      Arc direct(Edge, bool) const {
579 683
        return INVALID;
580 684
      }
581 685

	
582
      /// \brief Direct the given edge.
686
      /// \brief Direct the edge.
583 687
      ///
584
      /// Direct the given edge. The returned arc
585
      /// represents the given edge and the direction comes
586
      /// from the bool parameter. The source of the edge and
587
      /// the directed arc is the same when the given bool is true.
588
      Arc direct(const Edge&, bool) const {
688
      /// Direct the given edge. The returned arc represents the given
689
      /// edge and its source node is the given node.
690
      Arc direct(Edge, Node) const {
589 691
        return INVALID;
590 692
      }
591 693

	
592
      /// \brief Returns true if the arc has default orientation.
694
      /// \brief The oppositely directed arc.
593 695
      ///
594
      /// Returns whether the given directed arc is same orientation as
595
      /// the corresponding edge's default orientation.
596
      bool direction(Arc) const { return true; }
597

	
598
      /// \brief Returns the opposite directed arc.
599
      ///
600
      /// Returns the opposite directed arc.
696
      /// Returns the oppositely directed arc representing the same edge.
601 697
      Arc oppositeArc(Arc) const { return INVALID; }
602 698

	
603
      /// \brief Opposite node on an arc
699
      /// \brief The opposite node on the edge.
604 700
      ///
605
      /// \return the opposite of the given Node on the given Edge
701
      /// Returns the opposite node on the given edge.
606 702
      Node oppositeNode(Node, Edge) const { return INVALID; }
607 703

	
608
      /// \brief First node of the edge.
609
      ///
610
      /// \return the first node of the given Edge.
611
      ///
612
      /// 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
616
      /// edge, and is used to define the "default" direction
617
      /// of the directed versions of the arcs.
618
      /// \sa direction
619
      Node u(Edge) const { return INVALID; }
620

	
621
      /// \brief Second node of the edge.
622
      Node v(Edge) const { return INVALID; }
623

	
624
      /// \brief Source node of the directed arc.
625
      Node source(Arc) const { return INVALID; }
626

	
627
      /// \brief Target node of the directed arc.
628
      Node target(Arc) const { return INVALID; }
629

	
630
      /// \brief Returns the id of the node.
631
      int id(Node) const { return -1; }
632

	
633
      /// \brief Returns the id of the edge.
634
      int id(Edge) const { return -1; }
635

	
636
      /// \brief Returns the id of the arc.
637
      int id(Arc) const { return -1; }
638

	
639
      /// \brief Returns the node with the given id.
640
      ///
641
      /// \pre The argument should be a valid node id in the graph.
642
      Node nodeFromId(int) const { return INVALID; }
643

	
644
      /// \brief Returns the edge with the given id.
645
      ///
646
      /// \pre The argument should be a valid edge id in the graph.
647
      Edge edgeFromId(int) const { return INVALID; }
648

	
649
      /// \brief Returns the arc with the given id.
650
      ///
651
      /// \pre The argument should be a valid arc id in the graph.
652
      Arc arcFromId(int) const { return INVALID; }
653

	
654
      /// \brief Returns an upper bound on the node IDs.
655
      int maxNodeId() const { return -1; }
656

	
657
      /// \brief Returns an upper bound on the edge IDs.
658
      int maxEdgeId() const { return -1; }
659

	
660
      /// \brief Returns an upper bound on the arc IDs.
661
      int maxArcId() const { return -1; }
662

	
663 704
      void first(Node&) const {}
664 705
      void next(Node&) const {}
665 706

	
666 707
      void first(Edge&) const {}
667 708
      void next(Edge&) const {}
668 709

	
669 710
      void first(Arc&) const {}
670 711
      void next(Arc&) const {}
671 712

	
672 713
      void firstOut(Arc&, Node) const {}
673 714
      void nextOut(Arc&) const {}
674 715

	
675 716
      void firstIn(Arc&, Node) const {}
676 717
      void nextIn(Arc&) const {}
677 718

	
678 719
      void firstInc(Edge &, bool &, const Node &) const {}
679 720
      void nextInc(Edge &, bool &) const {}
680 721

	
681 722
      // The second parameter is dummy.
682 723
      Node fromId(int, Node) const { return INVALID; }
683 724
      // The second parameter is dummy.
684 725
      Edge fromId(int, Edge) const { return INVALID; }
685 726
      // The second parameter is dummy.
686 727
      Arc fromId(int, Arc) const { return INVALID; }
687 728

	
688 729
      // Dummy parameter.
689 730
      int maxId(Node) const { return -1; }
690 731
      // Dummy parameter.
691 732
      int maxId(Edge) const { return -1; }
692 733
      // Dummy parameter.
693 734
      int maxId(Arc) const { return -1; }
694 735

	
695
      /// \brief Base node of the iterator
736
      /// \brief The base node of the iterator.
696 737
      ///
697
      /// Returns the base node (the source in this case) of the iterator
698
      Node baseNode(OutArcIt e) const {
699
        return source(e);
700
      }
701
      /// \brief Running node of the iterator
738
      /// Returns the base node of the given incident edge iterator.
739
      Node baseNode(IncEdgeIt) const { return INVALID; }
740

	
741
      /// \brief The running node of the iterator.
702 742
      ///
703
      /// Returns the running node (the target in this case) of the
704
      /// iterator
705
      Node runningNode(OutArcIt e) const {
706
        return target(e);
707
      }
743
      /// Returns the running node of the given incident edge iterator.
744
      Node runningNode(IncEdgeIt) const { return INVALID; }
708 745

	
709
      /// \brief Base node of the iterator
746
      /// \brief The base node of the iterator.
710 747
      ///
711
      /// Returns the base node (the target in this case) of the iterator
712
      Node baseNode(InArcIt e) const {
713
        return target(e);
714
      }
715
      /// \brief Running node of the iterator
748
      /// Returns the base node of the given outgoing arc iterator
749
      /// (i.e. the source node of the corresponding arc).
750
      Node baseNode(OutArcIt) const { return INVALID; }
751

	
752
      /// \brief The running node of the iterator.
716 753
      ///
717
      /// Returns the running node (the source in this case) of the
718
      /// iterator
719
      Node runningNode(InArcIt e) const {
720
        return source(e);
721
      }
754
      /// Returns the running node of the given outgoing arc iterator
755
      /// (i.e. the target node of the corresponding arc).
756
      Node runningNode(OutArcIt) const { return INVALID; }
722 757

	
723
      /// \brief Base node of the iterator
758
      /// \brief The base node of the iterator.
724 759
      ///
725
      /// Returns the base node of the iterator
726
      Node baseNode(IncEdgeIt) const {
727
        return INVALID;
728
      }
760
      /// Returns the base node of the given incomming arc iterator
761
      /// (i.e. the target node of the corresponding arc).
762
      Node baseNode(InArcIt) const { return INVALID; }
729 763

	
730
      /// \brief Running node of the iterator
764
      /// \brief The running node of the iterator.
731 765
      ///
732
      /// Returns the running node of the iterator
733
      Node runningNode(IncEdgeIt) const {
734
        return INVALID;
735
      }
766
      /// Returns the running node of the given incomming arc iterator
767
      /// (i.e. the source node of the corresponding arc).
768
      Node runningNode(InArcIt) const { return INVALID; }
736 769

	
737 770
      template <typename _Graph>
738 771
      struct Constraints {
739 772
        void constraints() {
773
          checkConcept<BaseGraphComponent, _Graph>();
740 774
          checkConcept<IterableGraphComponent<>, _Graph>();
741 775
          checkConcept<IDableGraphComponent<>, _Graph>();
742 776
          checkConcept<MappableGraphComponent<>, _Graph>();
743 777
        }
744 778
      };
745 779

	
746 780
    };
747 781

	
748 782
  }
749 783

	
750 784
}
751 785

	
752 786
#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.
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).
84 94
      ///
85
      /// To allow the use of graph descriptors as key type in std::map or
86
      /// similar associative container we require this.
87
      ///
88
      /// \note This operator only have to define some strict ordering of
95
      /// \note This operator only has 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
#ifndef LEMON_CONCEPTS_HEAP_H
20
#define LEMON_CONCEPTS_HEAP_H
21

	
19 22
///\ingroup concept
20 23
///\file
21 24
///\brief The concept of heaps.
22 25

	
23
#ifndef LEMON_CONCEPT_HEAP_H
24
#define LEMON_CONCEPT_HEAP_H
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
    /// This concept class describes the main interface of heaps.
39
    /// The various \ref heaps "heap structures" are efficient
40
    /// implementations of the abstract data type \e priority \e queue.
41
    /// They store items with specified values called \e priorities
42
    /// in such a way that finding and removing the item with minimum
43
    /// priority are efficient. The basic operations are adding and
44
    /// erasing items, changing the priority of an item, etc.
45
    ///
46
    /// Heaps are crucial in several algorithms, such as Dijkstra and Prim.
47
    /// Any class that conforms to this concept can be used easily in such
48
    /// algorithms.
49
    ///
50
    /// \tparam PR Type of the priorities of the items.
51
    /// \tparam IM A read-writable item map with \c int values, used
52
    /// internally to handle the cross references.
53
    /// \tparam CMP A functor class for comparing the priorities.
54
    /// The default is \c std::less<PR>.
55
#ifdef DOXYGEN
56
    template <typename PR, typename IM, typename CMP>
57
#else
58
    template <typename PR, typename IM, typename CMP = std::less<PR> >
59
#endif
39 60
    class Heap {
40 61
    public:
41 62

	
63
      /// Type of the item-int map.
64
      typedef IM ItemIntMap;
65
      /// Type of the priorities.
66
      typedef PR Prio;
42 67
      /// Type of the items stored in the heap.
43 68
      typedef typename ItemIntMap::Key Item;
44 69

	
45
      /// Type of the priorities.
46
      typedef Priority Prio;
47

	
48 70
      /// \brief Type to represent the states of the items.
49 71
      ///
50 72
      /// Each item has a state associated to it. It can be "in heap",
51
      /// "pre heap" or "post heap". The later two are indifferent
52
      /// from the point of view of the heap, but may be useful for
53
      /// the user.
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.
54 75
      ///
55
      /// The \c ItemIntMap must be initialized in such a way, that it
56
      /// assigns \c PRE_HEAP (<tt>-1</tt>) to every item.
76
      /// The item-int map must be initialized in such way that it assigns
77
      /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
57 78
      enum State {
58
        IN_HEAP = 0,
59
        PRE_HEAP = -1,
60
        POST_HEAP = -2
79
        IN_HEAP = 0,    ///< = 0. The "in heap" state constant.
80
        PRE_HEAP = -1,  ///< = -1. The "pre-heap" state constant.
81
        POST_HEAP = -2  ///< = -2. The "post-heap" state constant.
61 82
      };
62 83

	
63
      /// \brief The constructor.
84
      /// \brief Constructor.
64 85
      ///
65
      /// The constructor.
86
      /// Constructor.
66 87
      /// \param map A map that assigns \c int values to keys of type
67 88
      /// \c Item. It is used internally by the heap implementations to
68 89
      /// handle the cross references. The assigned value must be
69
      /// \c PRE_HEAP (<tt>-1</tt>) for every item.
90
      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
70 91
      explicit Heap(ItemIntMap &map) {}
71 92

	
93
      /// \brief Constructor.
94
      ///
95
      /// Constructor.
96
      /// \param map A map that assigns \c int values to keys of type
97
      /// \c Item. It is used internally by the heap implementations to
98
      /// handle the cross references. The assigned value must be
99
      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
100
      /// \param comp The function object used for comparing the priorities.
101
      explicit Heap(ItemIntMap &map, const CMP &comp) {}
102

	
72 103
      /// \brief The number of items stored in the heap.
73 104
      ///
74
      /// Returns the number of items stored in the heap.
105
      /// This function returns the number of items stored in the heap.
75 106
      int size() const { return 0; }
76 107

	
77
      /// \brief Checks if the heap is empty.
108
      /// \brief Check if the heap is empty.
78 109
      ///
79
      /// Returns \c true if the heap is empty.
110
      /// This function returns \c true if the heap is empty.
80 111
      bool empty() const { return false; }
81 112

	
82
      /// \brief Makes the heap empty.
113
      /// \brief Make the heap empty.
83 114
      ///
84
      /// Makes the heap empty.
85
      void clear();
115
      /// This functon makes the heap empty.
116
      /// It does not change the cross reference map. If you want to reuse
117
      /// a heap that is not surely empty, you should first clear it and
118
      /// then you should set the cross reference map to \c PRE_HEAP
119
      /// for each item.
120
      void clear() {}
86 121

	
87
      /// \brief Inserts an item into the heap with the given priority.
122
      /// \brief Insert an item into the heap with the given priority.
88 123
      ///
89
      /// Inserts the given item into the heap with the given priority.
124
      /// This function inserts the given item into the heap with the
125
      /// given priority.
90 126
      /// \param i The item to insert.
91 127
      /// \param p The priority of the item.
128
      /// \pre \e i must not be stored in the heap.
92 129
      void push(const Item &i, const Prio &p) {}
93 130

	
94
      /// \brief Returns the item having minimum priority.
131
      /// \brief Return the item having minimum priority.
95 132
      ///
96
      /// Returns the item having minimum priority.
133
      /// This function returns the item having minimum priority.
97 134
      /// \pre The heap must be non-empty.
98 135
      Item top() const {}
99 136

	
100 137
      /// \brief The minimum priority.
101 138
      ///
102
      /// Returns the minimum priority.
139
      /// This function returns the minimum priority.
103 140
      /// \pre The heap must be non-empty.
104 141
      Prio prio() const {}
105 142

	
106
      /// \brief Removes the item having minimum priority.
143
      /// \brief Remove the item having minimum priority.
107 144
      ///
108
      /// Removes the item having minimum priority.
145
      /// This function removes the item having minimum priority.
109 146
      /// \pre The heap must be non-empty.
110 147
      void pop() {}
111 148

	
112
      /// \brief Removes an item from the heap.
149
      /// \brief Remove the given item from the heap.
113 150
      ///
114
      /// Removes the given item from the heap if it is already stored.
151
      /// This function removes the given item from the heap if it is
152
      /// already stored.
115 153
      /// \param i The item to delete.
154
      /// \pre \e i must be in the heap.
116 155
      void erase(const Item &i) {}
117 156

	
118
      /// \brief The priority of an item.
157
      /// \brief The priority of the given item.
119 158
      ///
120
      /// Returns the priority of the given item.
121
      /// \pre \c i must be in the heap.
159
      /// This function returns the priority of the given item.
122 160
      /// \param i The item.
161
      /// \pre \e i must be in the heap.
123 162
      Prio operator[](const Item &i) const {}
124 163

	
125
      /// \brief Sets the priority of an item or inserts it, if it is
164
      /// \brief Set the priority of an item or insert it, if it is
126 165
      /// not stored in the heap.
127 166
      ///
128 167
      /// This method sets the priority of the given item if it is
129
      /// already stored in the heap.
130
      /// Otherwise it inserts the given item with the given priority.
168
      /// already stored in the heap. Otherwise it inserts the given
169
      /// item into the heap with the given priority.
131 170
      ///
132 171
      /// \param i The item.
133 172
      /// \param p The priority.
134 173
      void set(const Item &i, const Prio &p) {}
135 174

	
136
      /// \brief Decreases the priority of an item to the given value.
175
      /// \brief Decrease the priority of an item to the given value.
137 176
      ///
138
      /// 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.
177
      /// This function decreases the priority of an item to the given value.
140 178
      /// \param i The item.
141 179
      /// \param p The priority.
180
      /// \pre \e i must be stored in the heap with priority at least \e p.
142 181
      void decrease(const Item &i, const Prio &p) {}
143 182

	
144
      /// \brief Increases the priority of an item to the given value.
183
      /// \brief Increase the priority of an item to the given value.
145 184
      ///
146
      /// 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.
185
      /// This function increases the priority of an item to the given value.
148 186
      /// \param i The item.
149 187
      /// \param p The priority.
188
      /// \pre \e i must be stored in the heap with priority at most \e p.
150 189
      void increase(const Item &i, const Prio &p) {}
151 190

	
152
      /// \brief Returns if an item is in, has already been in, or has
153
      /// never been in the heap.
191
      /// \brief Return the state of an item.
154 192
      ///
155 193
      /// This method returns \c PRE_HEAP if the given item has never
156 194
      /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
157 195
      /// and \c POST_HEAP otherwise.
158 196
      /// In the latter case it is possible that the item will get back
159 197
      /// to the heap again.
160 198
      /// \param i The item.
161 199
      State state(const Item &i) const {}
162 200

	
163
      /// \brief Sets the state of an item in the heap.
201
      /// \brief Set the state of an item in the heap.
164 202
      ///
165
      /// Sets the state of the given item in the heap. It can be used
166
      /// to manually clear the heap when it is important to achive the
167
      /// better time complexity.
203
      /// This function sets the state of the given item in the heap.
204
      /// It can be used to manually clear the heap when it is important
205
      /// to achive better time complexity.
168 206
      /// \param i The item.
169 207
      /// \param st The state. It should not be \c IN_HEAP.
170 208
      void state(const Item& i, State st) {}
171 209

	
172 210

	
173 211
      template <typename _Heap>
174 212
      struct Constraints {
175 213
      public:
176 214
        void constraints() {
177 215
          typedef typename _Heap::Item OwnItem;
178 216
          typedef typename _Heap::Prio OwnPrio;
179 217
          typedef typename _Heap::State OwnState;
180 218

	
181 219
          Item item;
182 220
          Prio prio;
183 221
          item=Item();
184 222
          prio=Prio();
185 223
          ignore_unused_variable_warning(item);
186 224
          ignore_unused_variable_warning(prio);
187 225

	
188 226
          OwnItem own_item;
189 227
          OwnPrio own_prio;
190 228
          OwnState own_state;
191 229
          own_item=Item();
192 230
          own_prio=Prio();
193 231
          ignore_unused_variable_warning(own_item);
194 232
          ignore_unused_variable_warning(own_prio);
195 233
          ignore_unused_variable_warning(own_state);
196 234

	
197 235
          _Heap heap1(map);
198 236
          _Heap heap2 = heap1;
199 237
          ignore_unused_variable_warning(heap1);
200 238
          ignore_unused_variable_warning(heap2);
201 239

	
202 240
          int s = heap.size();
203 241
          ignore_unused_variable_warning(s);
204 242
          bool e = heap.empty();
205 243
          ignore_unused_variable_warning(e);
206 244

	
207 245
          prio = heap.prio();
208 246
          item = heap.top();
209 247
          prio = heap[item];
210 248
          own_prio = heap.prio();
211 249
          own_item = heap.top();
212 250
          own_prio = heap[own_item];
213 251

	
214 252
          heap.push(item, prio);
215 253
          heap.push(own_item, own_prio);
216 254
          heap.pop();
217 255

	
218 256
          heap.set(item, prio);
219 257
          heap.decrease(item, prio);
220 258
          heap.increase(item, prio);
221 259
          heap.set(own_item, own_prio);
222 260
          heap.decrease(own_item, own_prio);
223 261
          heap.increase(own_item, own_prio);
224 262

	
225 263
          heap.erase(item);
226 264
          heap.erase(own_item);
227 265
          heap.clear();
228 266

	
229 267
          own_state = heap.state(own_item);
230 268
          heap.state(own_item, own_state);
231 269

	
232 270
          own_state = _Heap::PRE_HEAP;
233 271
          own_state = _Heap::IN_HEAP;
234 272
          own_state = _Heap::POST_HEAP;
235 273
        }
236 274

	
237 275
        _Heap& heap;
238 276
        ItemIntMap& map;
239 277
      };
240 278
    };
241 279

	
242 280
    /// @}
243 281
  } // namespace lemon
244 282
}
245
#endif // LEMON_CONCEPT_PATH_H
283
#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
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
50
    ///It must conform to 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
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
65
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
66
    ///By default it is a NullMap.
66 67
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
67
    ///Instantiates a ProcessedMap.
68
    ///Instantiates a \c ProcessedMap.
68 69

	
69
    ///This function instantiates a ProcessedMap.
70
    ///This function instantiates a \ref ProcessedMap.
70 71
    ///\param g is the digraph, to which
71
    ///we would like to define the ProcessedMap
72
    ///we would like to define the \ref ProcessedMap.
72 73
#ifdef DOXYGEN
73 74
    static ProcessedMap *createProcessedMap(const Digraph &g)
74 75
#else
75 76
    static ProcessedMap *createProcessedMap(const Digraph &)
76 77
#endif
77 78
    {
78 79
      return new ProcessedMap();
79 80
    }
80 81

	
81 82
    ///The type of the map that indicates which nodes are reached.
82 83

	
83 84
    ///The type of the map that indicates which nodes are reached.
84
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
85
    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
85 86
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
86
    ///Instantiates a ReachedMap.
87
    ///Instantiates a \c ReachedMap.
87 88

	
88
    ///This function instantiates a ReachedMap.
89
    ///This function instantiates a \ref ReachedMap.
89 90
    ///\param g is the digraph, to which
90
    ///we would like to define the ReachedMap.
91
    ///we would like to define the \ref ReachedMap.
91 92
    static ReachedMap *createReachedMap(const Digraph &g)
92 93
    {
93 94
      return new ReachedMap(g);
94 95
    }
95 96

	
96 97
    ///The type of the map that stores the distances of the nodes.
97 98

	
98 99
    ///The type of the map that stores the distances of the nodes.
99
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
100
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
100 101
    typedef typename Digraph::template NodeMap<int> DistMap;
101
    ///Instantiates a DistMap.
102
    ///Instantiates a \c DistMap.
102 103

	
103
    ///This function instantiates a DistMap.
104
    ///This function instantiates a \ref DistMap.
104 105
    ///\param g is the digraph, to which we would like to define the
105
    ///DistMap.
106
    ///\ref DistMap.
106 107
    static DistMap *createDistMap(const Digraph &g)
107 108
    {
108 109
      return new DistMap(g);
109 110
    }
110 111
  };
111 112

	
112 113
  ///%DFS algorithm class.
113 114

	
114 115
  ///\ingroup search
115 116
  ///This class provides an efficient implementation of the %DFS algorithm.
116 117
  ///
117 118
  ///There is also a \ref dfs() "function-type interface" for the DFS
118 119
  ///algorithm, which is convenient in the simplier cases and it can be
119 120
  ///used easier.
120 121
  ///
121 122
  ///\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.
123
  ///The default type is \ref ListDigraph.
129 124
#ifdef DOXYGEN
130 125
  template <typename GR,
131 126
            typename TR>
132 127
#else
133 128
  template <typename GR=ListDigraph,
134 129
            typename TR=DfsDefaultTraits<GR> >
135 130
#endif
136 131
  class Dfs {
137 132
  public:
138 133

	
139 134
    ///The type of the digraph the algorithm runs on.
140 135
    typedef typename TR::Digraph Digraph;
141 136

	
142 137
    ///\brief The type of the map that stores the predecessor arcs of the
143 138
    ///DFS paths.
144 139
    typedef typename TR::PredMap PredMap;
145 140
    ///The type of the map that stores the distances of the nodes.
146 141
    typedef typename TR::DistMap DistMap;
147 142
    ///The type of the map that indicates which nodes are reached.
148 143
    typedef typename TR::ReachedMap ReachedMap;
149 144
    ///The type of the map that indicates which nodes are processed.
150 145
    typedef typename TR::ProcessedMap ProcessedMap;
151 146
    ///The type of the paths.
152 147
    typedef PredMapPath<Digraph, PredMap> Path;
153 148

	
154
    ///The traits class.
149
    ///The \ref DfsDefaultTraits "traits class" of the algorithm.
155 150
    typedef TR Traits;
156 151

	
157 152
  private:
158 153

	
159 154
    typedef typename Digraph::Node Node;
160 155
    typedef typename Digraph::NodeIt NodeIt;
161 156
    typedef typename Digraph::Arc Arc;
162 157
    typedef typename Digraph::OutArcIt OutArcIt;
163 158

	
164 159
    //Pointer to the underlying digraph.
165 160
    const Digraph *G;
166 161
    //Pointer to the map of predecessor arcs.
167 162
    PredMap *_pred;
168 163
    //Indicates if _pred is locally allocated (true) or not.
169 164
    bool local_pred;
170 165
    //Pointer to the map of distances.
171 166
    DistMap *_dist;
172 167
    //Indicates if _dist is locally allocated (true) or not.
173 168
    bool local_dist;
174 169
    //Pointer to the map of reached status of the nodes.
175 170
    ReachedMap *_reached;
176 171
    //Indicates if _reached is locally allocated (true) or not.
177 172
    bool local_reached;
178 173
    //Pointer to the map of processed status of the nodes.
179 174
    ProcessedMap *_processed;
180 175
    //Indicates if _processed is locally allocated (true) or not.
181 176
    bool local_processed;
182 177

	
183 178
    std::vector<typename Digraph::OutArcIt> _stack;
184 179
    int _stack_head;
185 180

	
186 181
    //Creates the maps if necessary.
187 182
    void create_maps()
188 183
    {
189 184
      if(!_pred) {
190 185
        local_pred = true;
191 186
        _pred = Traits::createPredMap(*G);
192 187
      }
193 188
      if(!_dist) {
194 189
        local_dist = true;
195 190
        _dist = Traits::createDistMap(*G);
196 191
      }
197 192
      if(!_reached) {
198 193
        local_reached = true;
199 194
        _reached = Traits::createReachedMap(*G);
200 195
      }
201 196
      if(!_processed) {
202 197
        local_processed = true;
203 198
        _processed = Traits::createProcessedMap(*G);
204 199
      }
205 200
    }
206 201

	
207 202
  protected:
208 203

	
209 204
    Dfs() {}
210 205

	
211 206
  public:
212 207

	
213 208
    typedef Dfs Create;
214 209

	
215
    ///\name Named template parameters
210
    ///\name Named Template Parameters
216 211

	
217 212
    ///@{
218 213

	
219 214
    template <class T>
220 215
    struct SetPredMapTraits : public Traits {
221 216
      typedef T PredMap;
222 217
      static PredMap *createPredMap(const Digraph &)
223 218
      {
224 219
        LEMON_ASSERT(false, "PredMap is not initialized");
225 220
        return 0; // ignore warnings
226 221
      }
227 222
    };
228 223
    ///\brief \ref named-templ-param "Named parameter" for setting
229
    ///PredMap type.
224
    ///\c PredMap type.
230 225
    ///
231 226
    ///\ref named-templ-param "Named parameter" for setting
232
    ///PredMap type.
227
    ///\c PredMap type.
228
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
233 229
    template <class T>
234 230
    struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
235 231
      typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
236 232
    };
237 233

	
238 234
    template <class T>
239 235
    struct SetDistMapTraits : public Traits {
240 236
      typedef T DistMap;
241 237
      static DistMap *createDistMap(const Digraph &)
242 238
      {
243 239
        LEMON_ASSERT(false, "DistMap is not initialized");
244 240
        return 0; // ignore warnings
245 241
      }
246 242
    };
247 243
    ///\brief \ref named-templ-param "Named parameter" for setting
248
    ///DistMap type.
244
    ///\c DistMap type.
249 245
    ///
250 246
    ///\ref named-templ-param "Named parameter" for setting
251
    ///DistMap type.
247
    ///\c DistMap type.
248
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
252 249
    template <class T>
253 250
    struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
254 251
      typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
255 252
    };
256 253

	
257 254
    template <class T>
258 255
    struct SetReachedMapTraits : public Traits {
259 256
      typedef T ReachedMap;
260 257
      static ReachedMap *createReachedMap(const Digraph &)
261 258
      {
262 259
        LEMON_ASSERT(false, "ReachedMap is not initialized");
263 260
        return 0; // ignore warnings
264 261
      }
265 262
    };
266 263
    ///\brief \ref named-templ-param "Named parameter" for setting
267
    ///ReachedMap type.
264
    ///\c ReachedMap type.
268 265
    ///
269 266
    ///\ref named-templ-param "Named parameter" for setting
270
    ///ReachedMap type.
267
    ///\c ReachedMap type.
268
    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
271 269
    template <class T>
272 270
    struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
273 271
      typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
274 272
    };
275 273

	
276 274
    template <class T>
277 275
    struct SetProcessedMapTraits : public Traits {
278 276
      typedef T ProcessedMap;
279 277
      static ProcessedMap *createProcessedMap(const Digraph &)
280 278
      {
281 279
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
282 280
        return 0; // ignore warnings
283 281
      }
284 282
    };
285 283
    ///\brief \ref named-templ-param "Named parameter" for setting
286
    ///ProcessedMap type.
284
    ///\c ProcessedMap type.
287 285
    ///
288 286
    ///\ref named-templ-param "Named parameter" for setting
289
    ///ProcessedMap type.
287
    ///\c ProcessedMap type.
288
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
290 289
    template <class T>
291 290
    struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
292 291
      typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
293 292
    };
294 293

	
295 294
    struct SetStandardProcessedMapTraits : public Traits {
296 295
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
297 296
      static ProcessedMap *createProcessedMap(const Digraph &g)
298 297
      {
299 298
        return new ProcessedMap(g);
300 299
      }
301 300
    };
302 301
    ///\brief \ref named-templ-param "Named parameter" for setting
303
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
302
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
304 303
    ///
305 304
    ///\ref named-templ-param "Named parameter" for setting
306
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
305
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
307 306
    ///If you don't set it explicitly, it will be automatically allocated.
308 307
    struct SetStandardProcessedMap :
309 308
      public Dfs< Digraph, SetStandardProcessedMapTraits > {
310 309
      typedef Dfs< Digraph, SetStandardProcessedMapTraits > Create;
311 310
    };
312 311

	
313 312
    ///@}
314 313

	
315 314
  public:
316 315

	
317 316
    ///Constructor.
318 317

	
319 318
    ///Constructor.
320 319
    ///\param g The digraph the algorithm runs on.
321 320
    Dfs(const Digraph &g) :
322 321
      G(&g),
323 322
      _pred(NULL), local_pred(false),
324 323
      _dist(NULL), local_dist(false),
325 324
      _reached(NULL), local_reached(false),
326 325
      _processed(NULL), local_processed(false)
327 326
    { }
328 327

	
329 328
    ///Destructor.
330 329
    ~Dfs()
331 330
    {
332 331
      if(local_pred) delete _pred;
333 332
      if(local_dist) delete _dist;
334 333
      if(local_reached) delete _reached;
335 334
      if(local_processed) delete _processed;
336 335
    }
337 336

	
338 337
    ///Sets the map that stores the predecessor arcs.
339 338

	
340 339
    ///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.
340
    ///If you don't use this function before calling \ref run(Node) "run()"
341
    ///or \ref init(), an instance will be allocated automatically.
342
    ///The destructor deallocates this automatically allocated map,
343
    ///of course.
344 344
    ///\return <tt> (*this) </tt>
345 345
    Dfs &predMap(PredMap &m)
346 346
    {
347 347
      if(local_pred) {
348 348
        delete _pred;
349 349
        local_pred=false;
350 350
      }
351 351
      _pred = &m;
352 352
      return *this;
353 353
    }
354 354

	
355 355
    ///Sets the map that indicates which nodes are reached.
356 356

	
357 357
    ///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.
358
    ///If you don't use this function before calling \ref run(Node) "run()"
359
    ///or \ref init(), an instance will be allocated automatically.
360
    ///The destructor deallocates this automatically allocated map,
361
    ///of course.
361 362
    ///\return <tt> (*this) </tt>
362 363
    Dfs &reachedMap(ReachedMap &m)
363 364
    {
364 365
      if(local_reached) {
365 366
        delete _reached;
366 367
        local_reached=false;
367 368
      }
368 369
      _reached = &m;
369 370
      return *this;
370 371
    }
371 372

	
372 373
    ///Sets the map that indicates which nodes are processed.
373 374

	
374 375
    ///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.
376
    ///If you don't use this function before calling \ref run(Node) "run()"
377
    ///or \ref init(), an instance will be allocated automatically.
378
    ///The destructor deallocates this automatically allocated map,
379
    ///of course.
378 380
    ///\return <tt> (*this) </tt>
379 381
    Dfs &processedMap(ProcessedMap &m)
380 382
    {
381 383
      if(local_processed) {
382 384
        delete _processed;
383 385
        local_processed=false;
384 386
      }
385 387
      _processed = &m;
386 388
      return *this;
387 389
    }
388 390

	
389 391
    ///Sets the map that stores the distances of the nodes.
390 392

	
391 393
    ///Sets the map that stores the distances of the nodes calculated by
392 394
    ///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.
395
    ///If you don't use this function before calling \ref run(Node) "run()"
396
    ///or \ref init(), an instance will be allocated automatically.
397
    ///The destructor deallocates this automatically allocated map,
398
    ///of course.
396 399
    ///\return <tt> (*this) </tt>
397 400
    Dfs &distMap(DistMap &m)
398 401
    {
399 402
      if(local_dist) {
400 403
        delete _dist;
401 404
        local_dist=false;
402 405
      }
403 406
      _dist = &m;
404 407
      return *this;
405 408
    }
406 409

	
407 410
  public:
408 411

	
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.
412
    ///\name Execution Control
413
    ///The simplest way to execute the DFS algorithm is to use one of the
414
    ///member functions called \ref run(Node) "run()".\n
415
    ///If you need better control on the execution, you have to call
416
    ///\ref init() first, then you can add a source node with \ref addSource()
417
    ///and perform the actual computation with \ref start().
418
    ///This procedure can be repeated if there are nodes that have not
419
    ///been reached.
418 420

	
419 421
    ///@{
420 422

	
423
    ///\brief Initializes the internal data structures.
424
    ///
421 425
    ///Initializes the internal data structures.
422

	
423
    ///Initializes the internal data structures.
424
    ///
425 426
    void init()
426 427
    {
427 428
      create_maps();
428 429
      _stack.resize(countNodes(*G));
429 430
      _stack_head=-1;
430 431
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
431 432
        _pred->set(u,INVALID);
432 433
        _reached->set(u,false);
433 434
        _processed->set(u,false);
434 435
      }
435 436
    }
436 437

	
437 438
    ///Adds a new source node.
438 439

	
439 440
    ///Adds a new source node to the set of nodes to be processed.
440 441
    ///
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.
442
    ///\pre The stack must be empty. Otherwise the algorithm gives
443
    ///wrong results. (One of the outgoing arcs of all the source nodes
444
    ///except for the last one will not be visited and distances will
445
    ///also be wrong.)
446 446
    void addSource(Node s)
447 447
    {
448 448
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
449 449
      if(!(*_reached)[s])
450 450
        {
451 451
          _reached->set(s,true);
452 452
          _pred->set(s,INVALID);
453 453
          OutArcIt e(*G,s);
454 454
          if(e!=INVALID) {
455 455
            _stack[++_stack_head]=e;
456 456
            _dist->set(s,_stack_head);
457 457
          }
458 458
          else {
459 459
            _processed->set(s,true);
460 460
            _dist->set(s,0);
461 461
          }
462 462
        }
463 463
    }
464 464

	
465 465
    ///Processes the next arc.
466 466

	
467 467
    ///Processes the next arc.
468 468
    ///
469 469
    ///\return The processed arc.
470 470
    ///
471 471
    ///\pre The stack must not be empty.
472 472
    Arc processNextArc()
473 473
    {
474 474
      Node m;
475 475
      Arc e=_stack[_stack_head];
476 476
      if(!(*_reached)[m=G->target(e)]) {
477 477
        _pred->set(m,e);
478 478
        _reached->set(m,true);
479 479
        ++_stack_head;
480 480
        _stack[_stack_head] = OutArcIt(*G, m);
481 481
        _dist->set(m,_stack_head);
482 482
      }
483 483
      else {
484 484
        m=G->source(e);
485 485
        ++_stack[_stack_head];
486 486
      }
487 487
      while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
488 488
        _processed->set(m,true);
489 489
        --_stack_head;
490 490
        if(_stack_head>=0) {
491 491
          m=G->source(_stack[_stack_head]);
492 492
          ++_stack[_stack_head];
493 493
        }
494 494
      }
495 495
      return e;
496 496
    }
497 497

	
498 498
    ///Next arc to be processed.
499 499

	
500 500
    ///Next arc to be processed.
501 501
    ///
502 502
    ///\return The next arc to be processed or \c INVALID if the stack
503 503
    ///is empty.
504 504
    OutArcIt nextArc() const
505 505
    {
506 506
      return _stack_head>=0?_stack[_stack_head]:INVALID;
507 507
    }
508 508

	
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).
509
    ///Returns \c false if there are nodes to be processed.
510

	
511
    ///Returns \c false if there are nodes to be processed
512
    ///in the queue (stack).
514 513
    bool emptyQueue() const { return _stack_head<0; }
515 514

	
516 515
    ///Returns the number of the nodes to be processed.
517 516

	
518
    ///Returns the number of the nodes to be processed in the queue (stack).
517
    ///Returns the number of the nodes to be processed
518
    ///in the queue (stack).
519 519
    int queueSize() const { return _stack_head+1; }
520 520

	
521 521
    ///Executes the algorithm.
522 522

	
523 523
    ///Executes the algorithm.
524 524
    ///
525 525
    ///This method runs the %DFS algorithm from the root node
526 526
    ///in order to compute the DFS path to each node.
527 527
    ///
528 528
    /// The algorithm computes
529 529
    ///- the %DFS tree,
530 530
    ///- the distance of each node from the root in the %DFS tree.
531 531
    ///
532 532
    ///\pre init() must be called and a root node should be
533 533
    ///added with addSource() before using this function.
534 534
    ///
535 535
    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
536 536
    ///\code
537 537
    ///  while ( !d.emptyQueue() ) {
538 538
    ///    d.processNextArc();
539 539
    ///  }
540 540
    ///\endcode
541 541
    void start()
542 542
    {
543 543
      while ( !emptyQueue() ) processNextArc();
544 544
    }
545 545

	
546 546
    ///Executes the algorithm until the given target node is reached.
547 547

	
548 548
    ///Executes the algorithm until the given target node is reached.
549 549
    ///
550 550
    ///This method runs the %DFS algorithm from the root node
551 551
    ///in order to compute the DFS path to \c t.
552 552
    ///
553 553
    ///The algorithm computes
554 554
    ///- the %DFS path to \c t,
555 555
    ///- the distance of \c t from the root in the %DFS tree.
556 556
    ///
557 557
    ///\pre init() must be called and a root node should be
558 558
    ///added with addSource() before using this function.
559 559
    void start(Node t)
560 560
    {
561 561
      while ( !emptyQueue() && G->target(_stack[_stack_head])!=t )
562 562
        processNextArc();
563 563
    }
564 564

	
565 565
    ///Executes the algorithm until a condition is met.
566 566

	
567 567
    ///Executes the algorithm until a condition is met.
568 568
    ///
569 569
    ///This method runs the %DFS algorithm from the root node
570 570
    ///until an arc \c a with <tt>am[a]</tt> true is found.
571 571
    ///
572 572
    ///\param am A \c bool (or convertible) arc map. The algorithm
573 573
    ///will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
574 574
    ///
575 575
    ///\return The reached arc \c a with <tt>am[a]</tt> true or
576 576
    ///\c INVALID if no such arc was found.
577 577
    ///
578 578
    ///\pre init() must be called and a root node should be
579 579
    ///added with addSource() before using this function.
580 580
    ///
581 581
    ///\warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
582 582
    ///not a node map.
583 583
    template<class ArcBoolMap>
584 584
    Arc start(const ArcBoolMap &am)
585 585
    {
586 586
      while ( !emptyQueue() && !am[_stack[_stack_head]] )
587 587
        processNextArc();
588 588
      return emptyQueue() ? INVALID : _stack[_stack_head];
589 589
    }
590 590

	
591 591
    ///Runs the algorithm from the given source node.
592 592

	
593 593
    ///This method runs the %DFS algorithm from node \c s
594 594
    ///in order to compute the DFS path to each node.
595 595
    ///
596 596
    ///The algorithm computes
597 597
    ///- the %DFS tree,
598 598
    ///- the distance of each node from the root in the %DFS tree.
599 599
    ///
600 600
    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
601 601
    ///\code
602 602
    ///  d.init();
603 603
    ///  d.addSource(s);
604 604
    ///  d.start();
605 605
    ///\endcode
606 606
    void run(Node s) {
607 607
      init();
608 608
      addSource(s);
609 609
      start();
610 610
    }
611 611

	
612 612
    ///Finds the %DFS path between \c s and \c t.
613 613

	
614 614
    ///This method runs the %DFS algorithm from node \c s
615 615
    ///in order to compute the DFS path to node \c t
616 616
    ///(it stops searching when \c t is processed)
617 617
    ///
618 618
    ///\return \c true if \c t is reachable form \c s.
619 619
    ///
620 620
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is
621 621
    ///just a shortcut of the following code.
622 622
    ///\code
623 623
    ///  d.init();
624 624
    ///  d.addSource(s);
625 625
    ///  d.start(t);
626 626
    ///\endcode
627 627
    bool run(Node s,Node t) {
628 628
      init();
629 629
      addSource(s);
630 630
      start(t);
631 631
      return reached(t);
632 632
    }
633 633

	
634 634
    ///Runs the algorithm to visit all nodes in the digraph.
635 635

	
636 636
    ///This method runs the %DFS algorithm in order to compute the
637 637
    ///%DFS path to each node.
638 638
    ///
639 639
    ///The algorithm computes
640
    ///- the %DFS tree,
641
    ///- the distance of each node from the root in the %DFS tree.
640
    ///- the %DFS tree (forest),
641
    ///- the distance of each node from the root(s) in the %DFS tree.
642 642
    ///
643 643
    ///\note <tt>d.run()</tt> is just a shortcut of the following code.
644 644
    ///\code
645 645
    ///  d.init();
646 646
    ///  for (NodeIt n(digraph); n != INVALID; ++n) {
647 647
    ///    if (!d.reached(n)) {
648 648
    ///      d.addSource(n);
649 649
    ///      d.start();
650 650
    ///    }
651 651
    ///  }
652 652
    ///\endcode
653 653
    void run() {
654 654
      init();
655 655
      for (NodeIt it(*G); it != INVALID; ++it) {
656 656
        if (!reached(it)) {
657 657
          addSource(it);
658 658
          start();
659 659
        }
660 660
      }
661 661
    }
662 662

	
663 663
    ///@}
664 664

	
665 665
    ///\name Query Functions
666
    ///The result of the %DFS algorithm can be obtained using these
666
    ///The results of the DFS algorithm can be obtained using these
667 667
    ///functions.\n
668
    ///Either \ref lemon::Dfs::run() "run()" or \ref lemon::Dfs::start()
669
    ///"start()" must be called before using them.
668
    ///Either \ref run(Node) "run()" or \ref start() should be called
669
    ///before using them.
670 670

	
671 671
    ///@{
672 672

	
673
    ///The DFS path to a node.
673
    ///The DFS path to the given node.
674 674

	
675
    ///Returns the DFS path to a node.
675
    ///Returns the DFS path to the given node from the root(s).
676 676
    ///
677
    ///\warning \c t should be reachable from the root.
677
    ///\warning \c t should be reached from the root(s).
678 678
    ///
679
    ///\pre Either \ref run() or \ref start() must be called before
680
    ///using this function.
679
    ///\pre Either \ref run(Node) "run()" or \ref init()
680
    ///must be called before using this function.
681 681
    Path path(Node t) const { return Path(*G, *_pred, t); }
682 682

	
683
    ///The distance of a node from the root.
683
    ///The distance of the given node from the root(s).
684 684

	
685
    ///Returns the distance of a node from the root.
685
    ///Returns the distance of the given node from the root(s).
686 686
    ///
687
    ///\warning If node \c v is not reachable from the root, then
687
    ///\warning If node \c v is not reached from the root(s), then
688 688
    ///the return value of this function is undefined.
689 689
    ///
690
    ///\pre Either \ref run() or \ref start() must be called before
691
    ///using this function.
690
    ///\pre Either \ref run(Node) "run()" or \ref init()
691
    ///must be called before using this function.
692 692
    int dist(Node v) const { return (*_dist)[v]; }
693 693

	
694
    ///Returns the 'previous arc' of the %DFS tree for a node.
694
    ///Returns the 'previous arc' of the %DFS tree for the given node.
695 695

	
696 696
    ///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.
697
    ///node \c v, i.e. it returns the last arc of a %DFS path from a
698
    ///root to \c v. It is \c INVALID if \c v is not reached from the
699
    ///root(s) or if \c v is a root.
700 700
    ///
701 701
    ///The %DFS tree used here is equal to the %DFS tree used in
702
    ///\ref predNode().
702
    ///\ref predNode() and \ref predMap().
703 703
    ///
704
    ///\pre Either \ref run() or \ref start() must be called before using
705
    ///this function.
704
    ///\pre Either \ref run(Node) "run()" or \ref init()
705
    ///must be called before using this function.
706 706
    Arc predArc(Node v) const { return (*_pred)[v];}
707 707

	
708
    ///Returns the 'previous node' of the %DFS tree.
708
    ///Returns the 'previous node' of the %DFS tree for the given node.
709 709

	
710 710
    ///This function returns the 'previous node' of the %DFS
711 711
    ///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.
712
    ///of a %DFS path from a root to \c v. It is \c INVALID
713
    ///if \c v is not reached from the root(s) or if \c v is a root.
714 714
    ///
715 715
    ///The %DFS tree used here is equal to the %DFS tree used in
716
    ///\ref predArc().
716
    ///\ref predArc() and \ref predMap().
717 717
    ///
718
    ///\pre Either \ref run() or \ref start() must be called before
719
    ///using this function.
718
    ///\pre Either \ref run(Node) "run()" or \ref init()
719
    ///must be called before using this function.
720 720
    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
721 721
                                  G->source((*_pred)[v]); }
722 722

	
723 723
    ///\brief Returns a const reference to the node map that stores the
724 724
    ///distances of the nodes.
725 725
    ///
726 726
    ///Returns a const reference to the node map that stores the
727 727
    ///distances of the nodes calculated by the algorithm.
728 728
    ///
729
    ///\pre Either \ref run() or \ref init()
729
    ///\pre Either \ref run(Node) "run()" or \ref init()
730 730
    ///must be called before using this function.
731 731
    const DistMap &distMap() const { return *_dist;}
732 732

	
733 733
    ///\brief Returns a const reference to the node map that stores the
734 734
    ///predecessor arcs.
735 735
    ///
736 736
    ///Returns a const reference to the node map that stores the predecessor
737
    ///arcs, which form the DFS tree.
737
    ///arcs, which form the DFS tree (forest).
738 738
    ///
739
    ///\pre Either \ref run() or \ref init()
739
    ///\pre Either \ref run(Node) "run()" or \ref init()
740 740
    ///must be called before using this function.
741 741
    const PredMap &predMap() const { return *_pred;}
742 742

	
743
    ///Checks if a node is reachable from the root(s).
743
    ///Checks if the given node. node is reached from the root(s).
744 744

	
745
    ///Returns \c true if \c v is reachable from the root(s).
746
    ///\pre Either \ref run() or \ref start()
745
    ///Returns \c true if \c v is reached from the root(s).
746
    ///
747
    ///\pre Either \ref run(Node) "run()" or \ref init()
747 748
    ///must be called before using this function.
748 749
    bool reached(Node v) const { return (*_reached)[v]; }
749 750

	
750 751
    ///@}
751 752
  };
752 753

	
753 754
  ///Default traits class of dfs() function.
754 755

	
755 756
  ///Default traits class of dfs() function.
756 757
  ///\tparam GR Digraph type.
757 758
  template<class GR>
758 759
  struct DfsWizardDefaultTraits
759 760
  {
760 761
    ///The type of the digraph the algorithm runs on.
761 762
    typedef GR Digraph;
762 763

	
763 764
    ///\brief The type of the map that stores the predecessor
764 765
    ///arcs of the %DFS paths.
765 766
    ///
766 767
    ///The type of the map that stores the predecessor
767 768
    ///arcs of the %DFS paths.
768
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
769
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
769 770
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
770 771
    ///Instantiates a PredMap.
771 772

	
772 773
    ///This function instantiates a PredMap.
773 774
    ///\param g is the digraph, to which we would like to define the
774 775
    ///PredMap.
775 776
    static PredMap *createPredMap(const Digraph &g)
776 777
    {
777 778
      return new PredMap(g);
778 779
    }
779 780

	
780 781
    ///The type of the map that indicates which nodes are processed.
781 782

	
782 783
    ///The type of the map that indicates which nodes are processed.
783
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
784
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
784 785
    ///By default it is a NullMap.
785 786
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
786 787
    ///Instantiates a ProcessedMap.
787 788

	
788 789
    ///This function instantiates a ProcessedMap.
789 790
    ///\param g is the digraph, to which
790 791
    ///we would like to define the ProcessedMap.
791 792
#ifdef DOXYGEN
792 793
    static ProcessedMap *createProcessedMap(const Digraph &g)
793 794
#else
794 795
    static ProcessedMap *createProcessedMap(const Digraph &)
795 796
#endif
796 797
    {
797 798
      return new ProcessedMap();
798 799
    }
799 800

	
800 801
    ///The type of the map that indicates which nodes are reached.
801 802

	
802 803
    ///The type of the map that indicates which nodes are reached.
803
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
804
    ///It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
804 805
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
805 806
    ///Instantiates a ReachedMap.
806 807

	
807 808
    ///This function instantiates a ReachedMap.
808 809
    ///\param g is the digraph, to which
809 810
    ///we would like to define the ReachedMap.
810 811
    static ReachedMap *createReachedMap(const Digraph &g)
811 812
    {
812 813
      return new ReachedMap(g);
813 814
    }
814 815

	
815 816
    ///The type of the map that stores the distances of the nodes.
816 817

	
817 818
    ///The type of the map that stores the distances of the nodes.
818
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
819
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
819 820
    typedef typename Digraph::template NodeMap<int> DistMap;
820 821
    ///Instantiates a DistMap.
821 822

	
822 823
    ///This function instantiates a DistMap.
823 824
    ///\param g is the digraph, to which we would like to define
824 825
    ///the DistMap
825 826
    static DistMap *createDistMap(const Digraph &g)
826 827
    {
827 828
      return new DistMap(g);
828 829
    }
829 830

	
830 831
    ///The type of the DFS paths.
831 832

	
832 833
    ///The type of the DFS paths.
833
    ///It must meet the \ref concepts::Path "Path" concept.
834
    ///It must conform to the \ref concepts::Path "Path" concept.
834 835
    typedef lemon::Path<Digraph> Path;
835 836
  };
836 837

	
837 838
  /// Default traits class used by DfsWizard
838 839

	
839
  /// To make it easier to use Dfs algorithm
840
  /// we have created a wizard class.
841
  /// This \ref DfsWizard class needs default traits,
842
  /// as well as the \ref Dfs class.
843
  /// The \ref DfsWizardBase is a class to be the default traits of the
844
  /// \ref DfsWizard class.
840
  /// Default traits class used by DfsWizard.
841
  /// \tparam GR The type of the digraph.
845 842
  template<class GR>
846 843
  class DfsWizardBase : public DfsWizardDefaultTraits<GR>
847 844
  {
848 845

	
849 846
    typedef DfsWizardDefaultTraits<GR> Base;
850 847
  protected:
851 848
    //The type of the nodes in the digraph.
852 849
    typedef typename Base::Digraph::Node Node;
853 850

	
854 851
    //Pointer to the digraph the algorithm runs on.
855 852
    void *_g;
856 853
    //Pointer to the map of reached nodes.
857 854
    void *_reached;
858 855
    //Pointer to the map of processed nodes.
859 856
    void *_processed;
860 857
    //Pointer to the map of predecessors arcs.
861 858
    void *_pred;
862 859
    //Pointer to the map of distances.
863 860
    void *_dist;
864 861
    //Pointer to the DFS path to the target node.
865 862
    void *_path;
866 863
    //Pointer to the distance of the target node.
867 864
    int *_di;
868 865

	
869 866
    public:
870 867
    /// Constructor.
871 868

	
872
    /// This constructor does not require parameters, therefore it initiates
869
    /// This constructor does not require parameters, it initiates
873 870
    /// all of the attributes to \c 0.
874 871
    DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
875 872
                      _dist(0), _path(0), _di(0) {}
876 873

	
877 874
    /// Constructor.
878 875

	
879 876
    /// This constructor requires one parameter,
880 877
    /// others are initiated to \c 0.
881 878
    /// \param g The digraph the algorithm runs on.
882 879
    DfsWizardBase(const GR &g) :
883 880
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
884 881
      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
885 882

	
886 883
  };
887 884

	
888 885
  /// Auxiliary class for the function-type interface of DFS algorithm.
889 886

	
890 887
  /// This auxiliary class is created to implement the
891 888
  /// \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.
889
  /// It does not have own \ref run(Node) "run()" method, it uses the
890
  /// functions and features of the plain \ref Dfs.
894 891
  ///
895 892
  /// This class should only be used through the \ref dfs() function,
896 893
  /// which makes it easier to use the algorithm.
897 894
  template<class TR>
898 895
  class DfsWizard : public TR
899 896
  {
900 897
    typedef TR Base;
901 898

	
902
    ///The type of the digraph the algorithm runs on.
903 899
    typedef typename TR::Digraph Digraph;
904 900

	
905 901
    typedef typename Digraph::Node Node;
906 902
    typedef typename Digraph::NodeIt NodeIt;
907 903
    typedef typename Digraph::Arc Arc;
908 904
    typedef typename Digraph::OutArcIt OutArcIt;
909 905

	
910
    ///\brief The type of the map that stores the predecessor
911
    ///arcs of the DFS paths.
912 906
    typedef typename TR::PredMap PredMap;
913
    ///\brief The type of the map that stores the distances of the nodes.
914 907
    typedef typename TR::DistMap DistMap;
915
    ///\brief The type of the map that indicates which nodes are reached.
916 908
    typedef typename TR::ReachedMap ReachedMap;
917
    ///\brief The type of the map that indicates which nodes are processed.
918 909
    typedef typename TR::ProcessedMap ProcessedMap;
919
    ///The type of the DFS paths
920 910
    typedef typename TR::Path Path;
921 911

	
922 912
  public:
923 913

	
924 914
    /// Constructor.
925 915
    DfsWizard() : TR() {}
926 916

	
927 917
    /// Constructor that requires parameters.
928 918

	
929 919
    /// Constructor that requires parameters.
930 920
    /// These parameters will be the default values for the traits class.
931 921
    /// \param g The digraph the algorithm runs on.
932 922
    DfsWizard(const Digraph &g) :
933 923
      TR(g) {}
934 924

	
935 925
    ///Copy constructor
936 926
    DfsWizard(const TR &b) : TR(b) {}
937 927

	
938 928
    ~DfsWizard() {}
939 929

	
940 930
    ///Runs DFS algorithm from the given source node.
941 931

	
942 932
    ///This method runs DFS algorithm from node \c s
943 933
    ///in order to compute the DFS path to each node.
944 934
    void run(Node s)
945 935
    {
946 936
      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
947 937
      if (Base::_pred)
948 938
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
949 939
      if (Base::_dist)
950 940
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
951 941
      if (Base::_reached)
952 942
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
953 943
      if (Base::_processed)
954 944
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
955 945
      if (s!=INVALID)
956 946
        alg.run(s);
957 947
      else
958 948
        alg.run();
959 949
    }
960 950

	
961 951
    ///Finds the DFS path between \c s and \c t.
962 952

	
963 953
    ///This method runs DFS algorithm from node \c s
964 954
    ///in order to compute the DFS path to node \c t
965 955
    ///(it stops searching when \c t is processed).
966 956
    ///
967 957
    ///\return \c true if \c t is reachable form \c s.
968 958
    bool run(Node s, Node t)
969 959
    {
970 960
      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
971 961
      if (Base::_pred)
972 962
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
973 963
      if (Base::_dist)
974 964
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
975 965
      if (Base::_reached)
976 966
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
977 967
      if (Base::_processed)
978 968
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
979 969
      alg.run(s,t);
980 970
      if (Base::_path)
981 971
        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
982 972
      if (Base::_di)
983 973
        *Base::_di = alg.dist(t);
984 974
      return alg.reached(t);
985 975
      }
986 976

	
987 977
    ///Runs DFS algorithm to visit all nodes in the digraph.
988 978

	
989 979
    ///This method runs DFS algorithm in order to compute
990 980
    ///the DFS path to each node.
991 981
    void run()
992 982
    {
993 983
      run(INVALID);
994 984
    }
995 985

	
996 986
    template<class T>
997 987
    struct SetPredMapBase : public Base {
998 988
      typedef T PredMap;
999 989
      static PredMap *createPredMap(const Digraph &) { return 0; };
1000 990
      SetPredMapBase(const TR &b) : TR(b) {}
1001 991
    };
1002
    ///\brief \ref named-func-param "Named parameter"
1003
    ///for setting PredMap object.
992

	
993
    ///\brief \ref named-templ-param "Named parameter" for setting
994
    ///the predecessor map.
1004 995
    ///
1005
    ///\ref named-func-param "Named parameter"
1006
    ///for setting PredMap object.
996
    ///\ref named-templ-param "Named parameter" function for setting
997
    ///the map that stores the predecessor arcs of the nodes.
1007 998
    template<class T>
1008 999
    DfsWizard<SetPredMapBase<T> > predMap(const T &t)
1009 1000
    {
1010 1001
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1011 1002
      return DfsWizard<SetPredMapBase<T> >(*this);
1012 1003
    }
1013 1004

	
1014 1005
    template<class T>
1015 1006
    struct SetReachedMapBase : public Base {
1016 1007
      typedef T ReachedMap;
1017 1008
      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
1018 1009
      SetReachedMapBase(const TR &b) : TR(b) {}
1019 1010
    };
1020
    ///\brief \ref named-func-param "Named parameter"
1021
    ///for setting ReachedMap object.
1011

	
1012
    ///\brief \ref named-templ-param "Named parameter" for setting
1013
    ///the reached map.
1022 1014
    ///
1023
    /// \ref named-func-param "Named parameter"
1024
    ///for setting ReachedMap object.
1015
    ///\ref named-templ-param "Named parameter" function for setting
1016
    ///the map that indicates which nodes are reached.
1025 1017
    template<class T>
1026 1018
    DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
1027 1019
    {
1028 1020
      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
1029 1021
      return DfsWizard<SetReachedMapBase<T> >(*this);
1030 1022
    }
1031 1023

	
1032 1024
    template<class T>
1033 1025
    struct SetDistMapBase : public Base {
1034 1026
      typedef T DistMap;
1035 1027
      static DistMap *createDistMap(const Digraph &) { return 0; };
1036 1028
      SetDistMapBase(const TR &b) : TR(b) {}
1037 1029
    };
1038
    ///\brief \ref named-func-param "Named parameter"
1039
    ///for setting DistMap object.
1030

	
1031
    ///\brief \ref named-templ-param "Named parameter" for setting
1032
    ///the distance map.
1040 1033
    ///
1041
    /// \ref named-func-param "Named parameter"
1042
    ///for setting DistMap object.
1034
    ///\ref named-templ-param "Named parameter" function for setting
1035
    ///the map that stores the distances of the nodes calculated
1036
    ///by the algorithm.
1043 1037
    template<class T>
1044 1038
    DfsWizard<SetDistMapBase<T> > distMap(const T &t)
1045 1039
    {
1046 1040
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1047 1041
      return DfsWizard<SetDistMapBase<T> >(*this);
1048 1042
    }
1049 1043

	
1050 1044
    template<class T>
1051 1045
    struct SetProcessedMapBase : public Base {
1052 1046
      typedef T ProcessedMap;
1053 1047
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1054 1048
      SetProcessedMapBase(const TR &b) : TR(b) {}
1055 1049
    };
1056
    ///\brief \ref named-func-param "Named parameter"
1057
    ///for setting ProcessedMap object.
1050

	
1051
    ///\brief \ref named-func-param "Named parameter" for setting
1052
    ///the processed map.
1058 1053
    ///
1059
    /// \ref named-func-param "Named parameter"
1060
    ///for setting ProcessedMap object.
1054
    ///\ref named-templ-param "Named parameter" function for setting
1055
    ///the map that indicates which nodes are processed.
1061 1056
    template<class T>
1062 1057
    DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
1063 1058
    {
1064 1059
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1065 1060
      return DfsWizard<SetProcessedMapBase<T> >(*this);
1066 1061
    }
1067 1062

	
1068 1063
    template<class T>
1069 1064
    struct SetPathBase : public Base {
1070 1065
      typedef T Path;
1071 1066
      SetPathBase(const TR &b) : TR(b) {}
1072 1067
    };
1073 1068
    ///\brief \ref named-func-param "Named parameter"
1074 1069
    ///for getting the DFS path to the target node.
1075 1070
    ///
1076 1071
    ///\ref named-func-param "Named parameter"
1077 1072
    ///for getting the DFS path to the target node.
1078 1073
    template<class T>
1079 1074
    DfsWizard<SetPathBase<T> > path(const T &t)
1080 1075
    {
1081 1076
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1082 1077
      return DfsWizard<SetPathBase<T> >(*this);
1083 1078
    }
1084 1079

	
1085 1080
    ///\brief \ref named-func-param "Named parameter"
1086 1081
    ///for getting the distance of the target node.
1087 1082
    ///
1088 1083
    ///\ref named-func-param "Named parameter"
1089 1084
    ///for getting the distance of the target node.
1090 1085
    DfsWizard dist(const int &d)
1091 1086
    {
1092 1087
      Base::_di=const_cast<int*>(&d);
1093 1088
      return *this;
1094 1089
    }
1095 1090

	
1096 1091
  };
1097 1092

	
1098 1093
  ///Function-type interface for DFS algorithm.
1099 1094

	
1100 1095
  ///\ingroup search
1101 1096
  ///Function-type interface for DFS algorithm.
1102 1097
  ///
1103 1098
  ///This function also has several \ref named-func-param "named parameters",
1104 1099
  ///they are declared as the members of class \ref DfsWizard.
1105 1100
  ///The following examples show how to use these parameters.
1106 1101
  ///\code
1107 1102
  ///  // Compute the DFS tree
1108 1103
  ///  dfs(g).predMap(preds).distMap(dists).run(s);
1109 1104
  ///
1110 1105
  ///  // Compute the DFS path from s to t
1111 1106
  ///  bool reached = dfs(g).path(p).dist(d).run(s,t);
1112 1107
  ///\endcode
1113

	
1114
  ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
1108
  ///\warning Don't forget to put the \ref DfsWizard::run(Node) "run()"
1115 1109
  ///to the end of the parameter list.
1116 1110
  ///\sa DfsWizard
1117 1111
  ///\sa Dfs
1118 1112
  template<class GR>
1119 1113
  DfsWizard<DfsWizardBase<GR> >
1120 1114
  dfs(const GR &digraph)
1121 1115
  {
1122 1116
    return DfsWizard<DfsWizardBase<GR> >(digraph);
1123 1117
  }
1124 1118

	
1125 1119
#ifdef DOXYGEN
1126 1120
  /// \brief Visitor class for DFS.
1127 1121
  ///
1128 1122
  /// This class defines the interface of the DfsVisit events, and
1129 1123
  /// it could be the base of a real visitor class.
1130
  template <typename _Digraph>
1124
  template <typename GR>
1131 1125
  struct DfsVisitor {
1132
    typedef _Digraph Digraph;
1126
    typedef GR Digraph;
1133 1127
    typedef typename Digraph::Arc Arc;
1134 1128
    typedef typename Digraph::Node Node;
1135 1129
    /// \brief Called for the source node of the DFS.
1136 1130
    ///
1137 1131
    /// This function is called for the source node of the DFS.
1138 1132
    void start(const Node& node) {}
1139 1133
    /// \brief Called when the source node is leaved.
1140 1134
    ///
1141 1135
    /// This function is called when the source node is leaved.
1142 1136
    void stop(const Node& node) {}
1143 1137
    /// \brief Called when a node is reached first time.
1144 1138
    ///
1145 1139
    /// This function is called when a node is reached first time.
1146 1140
    void reach(const Node& node) {}
1147 1141
    /// \brief Called when an arc reaches a new node.
1148 1142
    ///
1149 1143
    /// This function is called when the DFS finds an arc whose target node
1150 1144
    /// is not reached yet.
1151 1145
    void discover(const Arc& arc) {}
1152 1146
    /// \brief Called when an arc is examined but its target node is
1153 1147
    /// already discovered.
1154 1148
    ///
1155 1149
    /// This function is called when an arc is examined but its target node is
1156 1150
    /// already discovered.
1157 1151
    void examine(const Arc& arc) {}
1158 1152
    /// \brief Called when the DFS steps back from a node.
1159 1153
    ///
1160 1154
    /// This function is called when the DFS steps back from a node.
1161 1155
    void leave(const Node& node) {}
1162 1156
    /// \brief Called when the DFS steps back on an arc.
1163 1157
    ///
1164 1158
    /// This function is called when the DFS steps back on an arc.
1165 1159
    void backtrack(const Arc& arc) {}
1166 1160
  };
1167 1161
#else
1168
  template <typename _Digraph>
1162
  template <typename GR>
1169 1163
  struct DfsVisitor {
1170
    typedef _Digraph Digraph;
1164
    typedef GR Digraph;
1171 1165
    typedef typename Digraph::Arc Arc;
1172 1166
    typedef typename Digraph::Node Node;
1173 1167
    void start(const Node&) {}
1174 1168
    void stop(const Node&) {}
1175 1169
    void reach(const Node&) {}
1176 1170
    void discover(const Arc&) {}
1177 1171
    void examine(const Arc&) {}
1178 1172
    void leave(const Node&) {}
1179 1173
    void backtrack(const Arc&) {}
1180 1174

	
1181 1175
    template <typename _Visitor>
1182 1176
    struct Constraints {
1183 1177
      void constraints() {
1184 1178
        Arc arc;
1185 1179
        Node node;
1186 1180
        visitor.start(node);
1187 1181
        visitor.stop(arc);
1188 1182
        visitor.reach(node);
1189 1183
        visitor.discover(arc);
1190 1184
        visitor.examine(arc);
1191 1185
        visitor.leave(node);
1192 1186
        visitor.backtrack(arc);
1193 1187
      }
1194 1188
      _Visitor& visitor;
1195 1189
    };
1196 1190
  };
1197 1191
#endif
1198 1192

	
1199 1193
  /// \brief Default traits class of DfsVisit class.
1200 1194
  ///
1201 1195
  /// Default traits class of DfsVisit class.
1202 1196
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1203
  template<class _Digraph>
1197
  template<class GR>
1204 1198
  struct DfsVisitDefaultTraits {
1205 1199

	
1206 1200
    /// \brief The type of the digraph the algorithm runs on.
1207
    typedef _Digraph Digraph;
1201
    typedef GR Digraph;
1208 1202

	
1209 1203
    /// \brief The type of the map that indicates which nodes are reached.
1210 1204
    ///
1211 1205
    /// The type of the map that indicates which nodes are reached.
1212
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1206
    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1213 1207
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
1214 1208

	
1215 1209
    /// \brief Instantiates a ReachedMap.
1216 1210
    ///
1217 1211
    /// This function instantiates a ReachedMap.
1218 1212
    /// \param digraph is the digraph, to which
1219 1213
    /// we would like to define the ReachedMap.
1220 1214
    static ReachedMap *createReachedMap(const Digraph &digraph) {
1221 1215
      return new ReachedMap(digraph);
1222 1216
    }
1223 1217

	
1224 1218
  };
1225 1219

	
1226 1220
  /// \ingroup search
1227 1221
  ///
1228
  /// \brief %DFS algorithm class with visitor interface.
1222
  /// \brief DFS algorithm class with visitor interface.
1229 1223
  ///
1230
  /// This class provides an efficient implementation of the %DFS algorithm
1224
  /// This class provides an efficient implementation of the DFS algorithm
1231 1225
  /// with visitor interface.
1232 1226
  ///
1233
  /// The %DfsVisit class provides an alternative interface to the Dfs
1227
  /// The DfsVisit class provides an alternative interface to the Dfs
1234 1228
  /// class. It works with callback mechanism, the DfsVisit object calls
1235 1229
  /// the member functions of the \c Visitor class on every DFS event.
1236 1230
  ///
1237 1231
  /// This interface of the DFS algorithm should be used in special cases
1238 1232
  /// when extra actions have to be performed in connection with certain
1239 1233
  /// events of the DFS algorithm. Otherwise consider to use Dfs or dfs()
1240 1234
  /// instead.
1241 1235
  ///
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
1236
  /// \tparam GR The type of the digraph the algorithm runs on.
1237
  /// The default type is \ref ListDigraph.
1238
  /// The value of GR is not used directly by \ref DfsVisit,
1239
  /// it is only passed to \ref DfsVisitDefaultTraits.
1240
  /// \tparam VS The Visitor type that is used by the algorithm.
1241
  /// \ref DfsVisitor "DfsVisitor<GR>" is an empty visitor, which
1248 1242
  /// does not observe the DFS events. If you want to observe the DFS
1249 1243
  /// events, you should implement your own visitor class.
1250
  /// \tparam _Traits Traits class to set various data types used by the
1244
  /// \tparam TR Traits class to set various data types used by the
1251 1245
  /// algorithm. The default traits class is
1252
  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<_Digraph>".
1246
  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<GR>".
1253 1247
  /// See \ref DfsVisitDefaultTraits for the documentation of
1254 1248
  /// a DFS visit traits class.
1255 1249
#ifdef DOXYGEN
1256
  template <typename _Digraph, typename _Visitor, typename _Traits>
1250
  template <typename GR, typename VS, typename TR>
1257 1251
#else
1258
  template <typename _Digraph = ListDigraph,
1259
            typename _Visitor = DfsVisitor<_Digraph>,
1260
            typename _Traits = DfsVisitDefaultTraits<_Digraph> >
1252
  template <typename GR = ListDigraph,
1253
            typename VS = DfsVisitor<GR>,
1254
            typename TR = DfsVisitDefaultTraits<GR> >
1261 1255
#endif
1262 1256
  class DfsVisit {
1263 1257
  public:
1264 1258

	
1265 1259
    ///The traits class.
1266
    typedef _Traits Traits;
1260
    typedef TR Traits;
1267 1261

	
1268 1262
    ///The type of the digraph the algorithm runs on.
1269 1263
    typedef typename Traits::Digraph Digraph;
1270 1264

	
1271 1265
    ///The visitor type used by the algorithm.
1272
    typedef _Visitor Visitor;
1266
    typedef VS Visitor;
1273 1267

	
1274 1268
    ///The type of the map that indicates which nodes are reached.
1275 1269
    typedef typename Traits::ReachedMap ReachedMap;
1276 1270

	
1277 1271
  private:
1278 1272

	
1279 1273
    typedef typename Digraph::Node Node;
1280 1274
    typedef typename Digraph::NodeIt NodeIt;
1281 1275
    typedef typename Digraph::Arc Arc;
1282 1276
    typedef typename Digraph::OutArcIt OutArcIt;
1283 1277

	
1284 1278
    //Pointer to the underlying digraph.
1285 1279
    const Digraph *_digraph;
1286 1280
    //Pointer to the visitor object.
1287 1281
    Visitor *_visitor;
1288 1282
    //Pointer to the map of reached status of the nodes.
1289 1283
    ReachedMap *_reached;
1290 1284
    //Indicates if _reached is locally allocated (true) or not.
1291 1285
    bool local_reached;
1292 1286

	
1293 1287
    std::vector<typename Digraph::Arc> _stack;
1294 1288
    int _stack_head;
1295 1289

	
1296 1290
    //Creates the maps if necessary.
1297 1291
    void create_maps() {
1298 1292
      if(!_reached) {
1299 1293
        local_reached = true;
1300 1294
        _reached = Traits::createReachedMap(*_digraph);
1301 1295
      }
1302 1296
    }
1303 1297

	
1304 1298
  protected:
1305 1299

	
1306 1300
    DfsVisit() {}
1307 1301

	
1308 1302
  public:
1309 1303

	
1310 1304
    typedef DfsVisit Create;
1311 1305

	
1312
    /// \name Named template parameters
1306
    /// \name Named Template Parameters
1313 1307

	
1314 1308
    ///@{
1315 1309
    template <class T>
1316 1310
    struct SetReachedMapTraits : public Traits {
1317 1311
      typedef T ReachedMap;
1318 1312
      static ReachedMap *createReachedMap(const Digraph &digraph) {
1319 1313
        LEMON_ASSERT(false, "ReachedMap is not initialized");
1320 1314
        return 0; // ignore warnings
1321 1315
      }
1322 1316
    };
1323 1317
    /// \brief \ref named-templ-param "Named parameter" for setting
1324 1318
    /// ReachedMap type.
1325 1319
    ///
1326 1320
    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
1327 1321
    template <class T>
1328 1322
    struct SetReachedMap : public DfsVisit< Digraph, Visitor,
1329 1323
                                            SetReachedMapTraits<T> > {
1330 1324
      typedef DfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
1331 1325
    };
1332 1326
    ///@}
1333 1327

	
1334 1328
  public:
1335 1329

	
1336 1330
    /// \brief Constructor.
1337 1331
    ///
1338 1332
    /// Constructor.
1339 1333
    ///
1340 1334
    /// \param digraph The digraph the algorithm runs on.
1341 1335
    /// \param visitor The visitor object of the algorithm.
1342 1336
    DfsVisit(const Digraph& digraph, Visitor& visitor)
1343 1337
      : _digraph(&digraph), _visitor(&visitor),
1344 1338
        _reached(0), local_reached(false) {}
1345 1339

	
1346 1340
    /// \brief Destructor.
1347 1341
    ~DfsVisit() {
1348 1342
      if(local_reached) delete _reached;
1349 1343
    }
1350 1344

	
1351 1345
    /// \brief Sets the map that indicates which nodes are reached.
1352 1346
    ///
1353 1347
    /// 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.
1348
    /// If you don't use this function before calling \ref run(Node) "run()"
1349
    /// or \ref init(), an instance will be allocated automatically.
1350
    /// The destructor deallocates this automatically allocated map,
1351
    /// of course.
1357 1352
    /// \return <tt> (*this) </tt>
1358 1353
    DfsVisit &reachedMap(ReachedMap &m) {
1359 1354
      if(local_reached) {
1360 1355
        delete _reached;
1361 1356
        local_reached=false;
1362 1357
      }
1363 1358
      _reached = &m;
1364 1359
      return *this;
1365 1360
    }
1366 1361

	
1367 1362
  public:
1368 1363

	
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.
1364
    /// \name Execution Control
1365
    /// The simplest way to execute the DFS algorithm is to use one of the
1366
    /// member functions called \ref run(Node) "run()".\n
1367
    /// If you need better control on the execution, you have to call
1368
    /// \ref init() first, then you can add a source node with \ref addSource()
1369
    /// and perform the actual computation with \ref start().
1370
    /// This procedure can be repeated if there are nodes that have not
1371
    /// been reached.
1379 1372

	
1380 1373
    /// @{
1381 1374

	
1382 1375
    /// \brief Initializes the internal data structures.
1383 1376
    ///
1384 1377
    /// Initializes the internal data structures.
1385 1378
    void init() {
1386 1379
      create_maps();
1387 1380
      _stack.resize(countNodes(*_digraph));
1388 1381
      _stack_head = -1;
1389 1382
      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
1390 1383
        _reached->set(u, false);
1391 1384
      }
1392 1385
    }
1393 1386

	
1394
    ///Adds a new source node.
1395

	
1396
    ///Adds a new source node to the set of nodes to be processed.
1387
    /// \brief Adds a new source node.
1397 1388
    ///
1398
    ///\pre The stack must be empty. (Otherwise the algorithm gives
1399
    ///false results.)
1389
    /// Adds a new source node to the set of nodes to be processed.
1400 1390
    ///
1401
    ///\warning Distances will be wrong (or at least strange) in case of
1402
    ///multiple sources.
1391
    /// \pre The stack must be empty. Otherwise the algorithm gives
1392
    /// wrong results. (One of the outgoing arcs of all the source nodes
1393
    /// except for the last one will not be visited and distances will
1394
    /// also be wrong.)
1403 1395
    void addSource(Node s)
1404 1396
    {
1405 1397
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
1406 1398
      if(!(*_reached)[s]) {
1407 1399
          _reached->set(s,true);
1408 1400
          _visitor->start(s);
1409 1401
          _visitor->reach(s);
1410 1402
          Arc e;
1411 1403
          _digraph->firstOut(e, s);
1412 1404
          if (e != INVALID) {
1413 1405
            _stack[++_stack_head] = e;
1414 1406
          } else {
1415 1407
            _visitor->leave(s);
1408
            _visitor->stop(s);
1416 1409
          }
1417 1410
        }
1418 1411
    }
1419 1412

	
1420 1413
    /// \brief Processes the next arc.
1421 1414
    ///
1422 1415
    /// Processes the next arc.
1423 1416
    ///
1424 1417
    /// \return The processed arc.
1425 1418
    ///
1426 1419
    /// \pre The stack must not be empty.
1427 1420
    Arc processNextArc() {
1428 1421
      Arc e = _stack[_stack_head];
1429 1422
      Node m = _digraph->target(e);
1430 1423
      if(!(*_reached)[m]) {
1431 1424
        _visitor->discover(e);
1432 1425
        _visitor->reach(m);
1433 1426
        _reached->set(m, true);
1434 1427
        _digraph->firstOut(_stack[++_stack_head], m);
1435 1428
      } else {
1436 1429
        _visitor->examine(e);
1437 1430
        m = _digraph->source(e);
1438 1431
        _digraph->nextOut(_stack[_stack_head]);
1439 1432
      }
1440 1433
      while (_stack_head>=0 && _stack[_stack_head] == INVALID) {
1441 1434
        _visitor->leave(m);
1442 1435
        --_stack_head;
1443 1436
        if (_stack_head >= 0) {
1444 1437
          _visitor->backtrack(_stack[_stack_head]);
1445 1438
          m = _digraph->source(_stack[_stack_head]);
1446 1439
          _digraph->nextOut(_stack[_stack_head]);
1447 1440
        } else {
1448 1441
          _visitor->stop(m);
1449 1442
        }
1450 1443
      }
1451 1444
      return e;
1452 1445
    }
1453 1446

	
1454 1447
    /// \brief Next arc to be processed.
1455 1448
    ///
1456 1449
    /// Next arc to be processed.
1457 1450
    ///
1458 1451
    /// \return The next arc to be processed or INVALID if the stack is
1459 1452
    /// empty.
1460 1453
    Arc nextArc() const {
1461 1454
      return _stack_head >= 0 ? _stack[_stack_head] : INVALID;
1462 1455
    }
1463 1456

	
1464 1457
    /// \brief Returns \c false if there are nodes
1465 1458
    /// to be processed.
1466 1459
    ///
1467 1460
    /// Returns \c false if there are nodes
1468 1461
    /// to be processed in the queue (stack).
1469 1462
    bool emptyQueue() const { return _stack_head < 0; }
1470 1463

	
1471 1464
    /// \brief Returns the number of the nodes to be processed.
1472 1465
    ///
1473 1466
    /// Returns the number of the nodes to be processed in the queue (stack).
1474 1467
    int queueSize() const { return _stack_head + 1; }
1475 1468

	
1476 1469
    /// \brief Executes the algorithm.
1477 1470
    ///
1478 1471
    /// Executes the algorithm.
1479 1472
    ///
1480 1473
    /// This method runs the %DFS algorithm from the root node
1481 1474
    /// in order to compute the %DFS path to each node.
1482 1475
    ///
1483 1476
    /// The algorithm computes
1484 1477
    /// - the %DFS tree,
1485 1478
    /// - the distance of each node from the root in the %DFS tree.
1486 1479
    ///
1487 1480
    /// \pre init() must be called and a root node should be
1488 1481
    /// added with addSource() before using this function.
1489 1482
    ///
1490 1483
    /// \note <tt>d.start()</tt> is just a shortcut of the following code.
1491 1484
    /// \code
1492 1485
    ///   while ( !d.emptyQueue() ) {
1493 1486
    ///     d.processNextArc();
1494 1487
    ///   }
1495 1488
    /// \endcode
1496 1489
    void start() {
1497 1490
      while ( !emptyQueue() ) processNextArc();
1498 1491
    }
1499 1492

	
1500 1493
    /// \brief Executes the algorithm until the given target node is reached.
1501 1494
    ///
1502 1495
    /// Executes the algorithm until the given target node is reached.
1503 1496
    ///
1504 1497
    /// This method runs the %DFS algorithm from the root node
1505 1498
    /// in order to compute the DFS path to \c t.
1506 1499
    ///
1507 1500
    /// The algorithm computes
1508 1501
    /// - the %DFS path to \c t,
1509 1502
    /// - the distance of \c t from the root in the %DFS tree.
1510 1503
    ///
1511 1504
    /// \pre init() must be called and a root node should be added
1512 1505
    /// with addSource() before using this function.
1513 1506
    void start(Node t) {
1514 1507
      while ( !emptyQueue() && _digraph->target(_stack[_stack_head]) != t )
1515 1508
        processNextArc();
1516 1509
    }
1517 1510

	
1518 1511
    /// \brief Executes the algorithm until a condition is met.
1519 1512
    ///
1520 1513
    /// Executes the algorithm until a condition is met.
1521 1514
    ///
1522 1515
    /// This method runs the %DFS algorithm from the root node
1523 1516
    /// until an arc \c a with <tt>am[a]</tt> true is found.
1524 1517
    ///
1525 1518
    /// \param am A \c bool (or convertible) arc map. The algorithm
1526 1519
    /// will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
1527 1520
    ///
1528 1521
    /// \return The reached arc \c a with <tt>am[a]</tt> true or
1529 1522
    /// \c INVALID if no such arc was found.
1530 1523
    ///
1531 1524
    /// \pre init() must be called and a root node should be added
1532 1525
    /// with addSource() before using this function.
1533 1526
    ///
1534 1527
    /// \warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
1535 1528
    /// not a node map.
1536 1529
    template <typename AM>
1537 1530
    Arc start(const AM &am) {
1538 1531
      while ( !emptyQueue() && !am[_stack[_stack_head]] )
1539 1532
        processNextArc();
1540 1533
      return emptyQueue() ? INVALID : _stack[_stack_head];
1541 1534
    }
1542 1535

	
1543 1536
    /// \brief Runs the algorithm from the given source node.
1544 1537
    ///
1545 1538
    /// This method runs the %DFS algorithm from node \c s.
1546 1539
    /// in order to compute the DFS path to each node.
1547 1540
    ///
1548 1541
    /// The algorithm computes
1549 1542
    /// - the %DFS tree,
1550 1543
    /// - the distance of each node from the root in the %DFS tree.
1551 1544
    ///
1552 1545
    /// \note <tt>d.run(s)</tt> is just a shortcut of the following code.
1553 1546
    ///\code
1554 1547
    ///   d.init();
1555 1548
    ///   d.addSource(s);
1556 1549
    ///   d.start();
1557 1550
    ///\endcode
1558 1551
    void run(Node s) {
1559 1552
      init();
1560 1553
      addSource(s);
1561 1554
      start();
1562 1555
    }
1563 1556

	
1564 1557
    /// \brief Finds the %DFS path between \c s and \c t.
1565 1558

	
1566 1559
    /// This method runs the %DFS algorithm from node \c s
1567 1560
    /// in order to compute the DFS path to node \c t
1568 1561
    /// (it stops searching when \c t is processed).
1569 1562
    ///
1570 1563
    /// \return \c true if \c t is reachable form \c s.
1571 1564
    ///
1572 1565
    /// \note Apart from the return value, <tt>d.run(s,t)</tt> is
1573 1566
    /// just a shortcut of the following code.
1574 1567
    ///\code
1575 1568
    ///   d.init();
1576 1569
    ///   d.addSource(s);
1577 1570
    ///   d.start(t);
1578 1571
    ///\endcode
1579 1572
    bool run(Node s,Node t) {
1580 1573
      init();
1581 1574
      addSource(s);
1582 1575
      start(t);
1583 1576
      return reached(t);
1584 1577
    }
1585 1578

	
1586 1579
    /// \brief Runs the algorithm to visit all nodes in the digraph.
1587 1580

	
1588 1581
    /// This method runs the %DFS algorithm in order to
1589 1582
    /// compute the %DFS path to each node.
1590 1583
    ///
1591 1584
    /// The algorithm computes
1592
    /// - the %DFS tree,
1593
    /// - the distance of each node from the root in the %DFS tree.
1585
    /// - the %DFS tree (forest),
1586
    /// - the distance of each node from the root(s) in the %DFS tree.
1594 1587
    ///
1595 1588
    /// \note <tt>d.run()</tt> is just a shortcut of the following code.
1596 1589
    ///\code
1597 1590
    ///   d.init();
1598 1591
    ///   for (NodeIt n(digraph); n != INVALID; ++n) {
1599 1592
    ///     if (!d.reached(n)) {
1600 1593
    ///       d.addSource(n);
1601 1594
    ///       d.start();
1602 1595
    ///     }
1603 1596
    ///   }
1604 1597
    ///\endcode
1605 1598
    void run() {
1606 1599
      init();
1607 1600
      for (NodeIt it(*_digraph); it != INVALID; ++it) {
1608 1601
        if (!reached(it)) {
1609 1602
          addSource(it);
1610 1603
          start();
1611 1604
        }
1612 1605
      }
1613 1606
    }
1614 1607

	
1615 1608
    ///@}
1616 1609

	
1617 1610
    /// \name Query Functions
1618
    /// The result of the %DFS algorithm can be obtained using these
1611
    /// The results of the DFS algorithm can be obtained using these
1619 1612
    /// functions.\n
1620
    /// Either \ref lemon::DfsVisit::run() "run()" or
1621
    /// \ref lemon::DfsVisit::start() "start()" must be called before
1622
    /// using them.
1613
    /// Either \ref run(Node) "run()" or \ref start() should be called
1614
    /// before using them.
1615

	
1623 1616
    ///@{
1624 1617

	
1625
    /// \brief Checks if a node is reachable from the root(s).
1618
    /// \brief Checks if the given node is reached from the root(s).
1626 1619
    ///
1627
    /// Returns \c true if \c v is reachable from the root(s).
1628
    /// \pre Either \ref run() or \ref start()
1620
    /// Returns \c true if \c v is reached from the root(s).
1621
    ///
1622
    /// \pre Either \ref run(Node) "run()" or \ref init()
1629 1623
    /// must be called before using this function.
1630
    bool reached(Node v) { return (*_reached)[v]; }
1624
    bool reached(Node v) const { return (*_reached)[v]; }
1631 1625

	
1632 1626
    ///@}
1633 1627

	
1634 1628
  };
1635 1629

	
1636 1630
} //END OF NAMESPACE LEMON
1637 1631

	
1638 1632
#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
    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
72
    typedef LM LengthMap;
73
    ///The type of the length of the arcs.
74
    typedef typename LM::Value Value;
73
    ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
74
    typedef LEN LengthMap;
75
    ///The type of the arc lengths.
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
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
119
    ///It must conform to 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
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
134
    ///It must conform to 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
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
153
    typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
154
    ///Instantiates a DistMap.
154
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
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
  ///
172
  ///The %Dijkstra algorithm solves the single-source shortest path problem
173
  ///when all arc lengths are non-negative. If there are negative lengths,
174
  ///the BellmanFord algorithm should be used instead.
175
  ///
170 176
  ///The arc lengths are passed to the algorithm using a
171 177
  ///\ref concepts::ReadMap "ReadMap",
172 178
  ///so it is easy to change it to any kind of length.
173 179
  ///The type of the length is determined by the
174 180
  ///\ref concepts::ReadMap::Value "Value" of the length map.
175 181
  ///It is also possible to change the underlying priority heap.
176 182
  ///
177 183
  ///There is also a \ref dijkstra() "function-type interface" for the
178 184
  ///%Dijkstra algorithm, which is convenient in the simplier cases and
179 185
  ///it can be used easier.
180 186
  ///
181 187
  ///\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
188
  ///The default type is \ref ListDigraph.
189
  ///\tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
190
  ///the lengths of the arcs.
191
  ///It is read once for each arc, so the map may involve in
187 192
  ///relatively time consuming process to compute the arc lengths if
188 193
  ///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.
194
  ///concepts::Digraph::ArcMap "GR::ArcMap<int>".
196 195
#ifdef DOXYGEN
197
  template <typename GR, typename LM, typename TR>
196
  template <typename GR, typename LEN, typename TR>
198 197
#else
199 198
  template <typename GR=ListDigraph,
200
            typename LM=typename GR::template ArcMap<int>,
201
            typename TR=DijkstraDefaultTraits<GR,LM> >
199
            typename LEN=typename GR::template ArcMap<int>,
200
            typename TR=DijkstraDefaultTraits<GR,LEN> >
202 201
#endif
203 202
  class Dijkstra {
204 203
  public:
205 204

	
206 205
    ///The type of the digraph the algorithm runs on.
207 206
    typedef typename TR::Digraph Digraph;
208 207

	
209
    ///The type of the length of the arcs.
208
    ///The type of the arc lengths.
210 209
    typedef typename TR::LengthMap::Value Value;
211 210
    ///The type of the map that stores the arc lengths.
212 211
    typedef typename TR::LengthMap LengthMap;
213 212
    ///\brief The type of the map that stores the predecessor arcs of the
214 213
    ///shortest paths.
215 214
    typedef typename TR::PredMap PredMap;
216 215
    ///The type of the map that stores the distances of the nodes.
217 216
    typedef typename TR::DistMap DistMap;
218 217
    ///The type of the map that indicates which nodes are processed.
219 218
    typedef typename TR::ProcessedMap ProcessedMap;
220 219
    ///The type of the paths.
221 220
    typedef PredMapPath<Digraph, PredMap> Path;
222 221
    ///The cross reference type used for the current heap.
223 222
    typedef typename TR::HeapCrossRef HeapCrossRef;
224 223
    ///The heap type used by the algorithm.
225 224
    typedef typename TR::Heap Heap;
226
    ///The operation traits class.
225
    ///\brief The \ref DijkstraDefaultOperationTraits "operation traits class"
226
    ///of the algorithm.
227 227
    typedef typename TR::OperationTraits OperationTraits;
228 228

	
229
    ///The traits class.
229
    ///The \ref DijkstraDefaultTraits "traits class" of the algorithm.
230 230
    typedef TR Traits;
231 231

	
232 232
  private:
233 233

	
234 234
    typedef typename Digraph::Node Node;
235 235
    typedef typename Digraph::NodeIt NodeIt;
236 236
    typedef typename Digraph::Arc Arc;
237 237
    typedef typename Digraph::OutArcIt OutArcIt;
238 238

	
239 239
    //Pointer to the underlying digraph.
240 240
    const Digraph *G;
241 241
    //Pointer to the length map.
242
    const LengthMap *length;
242
    const LengthMap *_length;
243 243
    //Pointer to the map of predecessors arcs.
244 244
    PredMap *_pred;
245 245
    //Indicates if _pred is locally allocated (true) or not.
246 246
    bool local_pred;
247 247
    //Pointer to the map of distances.
248 248
    DistMap *_dist;
249 249
    //Indicates if _dist is locally allocated (true) or not.
250 250
    bool local_dist;
251 251
    //Pointer to the map of processed status of the nodes.
252 252
    ProcessedMap *_processed;
253 253
    //Indicates if _processed is locally allocated (true) or not.
254 254
    bool local_processed;
255 255
    //Pointer to the heap cross references.
256 256
    HeapCrossRef *_heap_cross_ref;
257 257
    //Indicates if _heap_cross_ref is locally allocated (true) or not.
258 258
    bool local_heap_cross_ref;
259 259
    //Pointer to the heap.
260 260
    Heap *_heap;
261 261
    //Indicates if _heap is locally allocated (true) or not.
262 262
    bool local_heap;
263 263

	
264 264
    //Creates the maps if necessary.
265 265
    void create_maps()
266 266
    {
267 267
      if(!_pred) {
268 268
        local_pred = true;
269 269
        _pred = Traits::createPredMap(*G);
270 270
      }
271 271
      if(!_dist) {
272 272
        local_dist = true;
273 273
        _dist = Traits::createDistMap(*G);
274 274
      }
275 275
      if(!_processed) {
276 276
        local_processed = true;
277 277
        _processed = Traits::createProcessedMap(*G);
278 278
      }
279 279
      if (!_heap_cross_ref) {
280 280
        local_heap_cross_ref = true;
281 281
        _heap_cross_ref = Traits::createHeapCrossRef(*G);
282 282
      }
283 283
      if (!_heap) {
284 284
        local_heap = true;
285 285
        _heap = Traits::createHeap(*_heap_cross_ref);
286 286
      }
287 287
    }
288 288

	
289 289
  public:
290 290

	
291 291
    typedef Dijkstra Create;
292 292

	
293
    ///\name Named template parameters
293
    ///\name Named Template Parameters
294 294

	
295 295
    ///@{
296 296

	
297 297
    template <class T>
298 298
    struct SetPredMapTraits : public Traits {
299 299
      typedef T PredMap;
300 300
      static PredMap *createPredMap(const Digraph &)
301 301
      {
302 302
        LEMON_ASSERT(false, "PredMap is not initialized");
303 303
        return 0; // ignore warnings
304 304
      }
305 305
    };
306 306
    ///\brief \ref named-templ-param "Named parameter" for setting
307
    ///PredMap type.
307
    ///\c PredMap type.
308 308
    ///
309 309
    ///\ref named-templ-param "Named parameter" for setting
310
    ///PredMap type.
310
    ///\c PredMap type.
311
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
311 312
    template <class T>
312 313
    struct SetPredMap
313 314
      : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
314 315
      typedef Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > Create;
315 316
    };
316 317

	
317 318
    template <class T>
318 319
    struct SetDistMapTraits : public Traits {
319 320
      typedef T DistMap;
320 321
      static DistMap *createDistMap(const Digraph &)
321 322
      {
322 323
        LEMON_ASSERT(false, "DistMap is not initialized");
323 324
        return 0; // ignore warnings
324 325
      }
325 326
    };
326 327
    ///\brief \ref named-templ-param "Named parameter" for setting
327
    ///DistMap type.
328
    ///\c DistMap type.
328 329
    ///
329 330
    ///\ref named-templ-param "Named parameter" for setting
330
    ///DistMap type.
331
    ///\c DistMap type.
332
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
331 333
    template <class T>
332 334
    struct SetDistMap
333 335
      : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
334 336
      typedef Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > Create;
335 337
    };
336 338

	
337 339
    template <class T>
338 340
    struct SetProcessedMapTraits : public Traits {
339 341
      typedef T ProcessedMap;
340 342
      static ProcessedMap *createProcessedMap(const Digraph &)
341 343
      {
342 344
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
343 345
        return 0; // ignore warnings
344 346
      }
345 347
    };
346 348
    ///\brief \ref named-templ-param "Named parameter" for setting
347
    ///ProcessedMap type.
349
    ///\c ProcessedMap type.
348 350
    ///
349 351
    ///\ref named-templ-param "Named parameter" for setting
350
    ///ProcessedMap type.
352
    ///\c ProcessedMap type.
353
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
351 354
    template <class T>
352 355
    struct SetProcessedMap
353 356
      : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
354 357
      typedef Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > Create;
355 358
    };
356 359

	
357 360
    struct SetStandardProcessedMapTraits : public Traits {
358 361
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
359 362
      static ProcessedMap *createProcessedMap(const Digraph &g)
360 363
      {
361 364
        return new ProcessedMap(g);
362 365
      }
363 366
    };
364 367
    ///\brief \ref named-templ-param "Named parameter" for setting
365
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
368
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
366 369
    ///
367 370
    ///\ref named-templ-param "Named parameter" for setting
368
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
371
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
369 372
    ///If you don't set it explicitly, it will be automatically allocated.
370 373
    struct SetStandardProcessedMap
371 374
      : public Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits > {
372 375
      typedef Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits >
373 376
      Create;
374 377
    };
375 378

	
376 379
    template <class H, class CR>
377 380
    struct SetHeapTraits : public Traits {
378 381
      typedef CR HeapCrossRef;
379 382
      typedef H Heap;
380 383
      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
381 384
        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
382 385
        return 0; // ignore warnings
383 386
      }
384 387
      static Heap *createHeap(HeapCrossRef &)
385 388
      {
386 389
        LEMON_ASSERT(false, "Heap is not initialized");
387 390
        return 0; // ignore warnings
388 391
      }
389 392
    };
390 393
    ///\brief \ref named-templ-param "Named parameter" for setting
391
    ///heap and cross reference type
394
    ///heap and cross reference types
392 395
    ///
393 396
    ///\ref named-templ-param "Named parameter" for setting heap and cross
394
    ///reference type.
397
    ///reference types. If this named parameter is used, then external
398
    ///heap and cross reference objects must be passed to the algorithm
399
    ///using the \ref heap() function before calling \ref run(Node) "run()"
400
    ///or \ref init().
401
    ///\sa SetStandardHeap
395 402
    template <class H, class CR = typename Digraph::template NodeMap<int> >
396 403
    struct SetHeap
397 404
      : public Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > {
398 405
      typedef Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > Create;
399 406
    };
400 407

	
401 408
    template <class H, class CR>
402 409
    struct SetStandardHeapTraits : public Traits {
403 410
      typedef CR HeapCrossRef;
404 411
      typedef H Heap;
405 412
      static HeapCrossRef *createHeapCrossRef(const Digraph &G) {
406 413
        return new HeapCrossRef(G);
407 414
      }
408 415
      static Heap *createHeap(HeapCrossRef &R)
409 416
      {
410 417
        return new Heap(R);
411 418
      }
412 419
    };
413 420
    ///\brief \ref named-templ-param "Named parameter" for setting
414
    ///heap and cross reference type with automatic allocation
421
    ///heap and cross reference types with automatic allocation
415 422
    ///
416 423
    ///\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.
424
    ///reference types with automatic allocation.
425
    ///They should have standard constructor interfaces to be able to
426
    ///automatically created by the algorithm (i.e. the digraph should be
427
    ///passed to the constructor of the cross reference and the cross
428
    ///reference should be passed to the constructor of the heap).
429
    ///However external heap and cross reference objects could also be
430
    ///passed to the algorithm using the \ref heap() function before
431
    ///calling \ref run(Node) "run()" or \ref init().
432
    ///\sa SetHeap
420 433
    template <class H, class CR = typename Digraph::template NodeMap<int> >
421 434
    struct SetStandardHeap
422 435
      : public Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> > {
423 436
      typedef Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> >
424 437
      Create;
425 438
    };
426 439

	
427 440
    template <class T>
428 441
    struct SetOperationTraitsTraits : public Traits {
429 442
      typedef T OperationTraits;
430 443
    };
431 444

	
432 445
    /// \brief \ref named-templ-param "Named parameter" for setting
433 446
    ///\c OperationTraits type
434 447
    ///
435 448
    ///\ref named-templ-param "Named parameter" for setting
436
    ///\ref OperationTraits type.
449
    ///\c OperationTraits type.
450
    /// For more information see \ref DijkstraDefaultOperationTraits.
437 451
    template <class T>
438 452
    struct SetOperationTraits
439 453
      : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
440 454
      typedef Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> >
441 455
      Create;
442 456
    };
443 457

	
444 458
    ///@}
445 459

	
446 460
  protected:
447 461

	
448 462
    Dijkstra() {}
449 463

	
450 464
  public:
451 465

	
452 466
    ///Constructor.
453 467

	
454 468
    ///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),
469
    ///\param g The digraph the algorithm runs on.
470
    ///\param length The length map used by the algorithm.
471
    Dijkstra(const Digraph& g, const LengthMap& length) :
472
      G(&g), _length(&length),
459 473
      _pred(NULL), local_pred(false),
460 474
      _dist(NULL), local_dist(false),
461 475
      _processed(NULL), local_processed(false),
462 476
      _heap_cross_ref(NULL), local_heap_cross_ref(false),
463 477
      _heap(NULL), local_heap(false)
464 478
    { }
465 479

	
466 480
    ///Destructor.
467 481
    ~Dijkstra()
468 482
    {
469 483
      if(local_pred) delete _pred;
470 484
      if(local_dist) delete _dist;
471 485
      if(local_processed) delete _processed;
472 486
      if(local_heap_cross_ref) delete _heap_cross_ref;
473 487
      if(local_heap) delete _heap;
474 488
    }
475 489

	
476 490
    ///Sets the length map.
477 491

	
478 492
    ///Sets the length map.
479 493
    ///\return <tt> (*this) </tt>
480 494
    Dijkstra &lengthMap(const LengthMap &m)
481 495
    {
482
      length = &m;
496
      _length = &m;
483 497
      return *this;
484 498
    }
485 499

	
486 500
    ///Sets the map that stores the predecessor arcs.
487 501

	
488 502
    ///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.
503
    ///If you don't use this function before calling \ref run(Node) "run()"
504
    ///or \ref init(), an instance will be allocated automatically.
505
    ///The destructor deallocates this automatically allocated map,
506
    ///of course.
492 507
    ///\return <tt> (*this) </tt>
493 508
    Dijkstra &predMap(PredMap &m)
494 509
    {
495 510
      if(local_pred) {
496 511
        delete _pred;
497 512
        local_pred=false;
498 513
      }
499 514
      _pred = &m;
500 515
      return *this;
501 516
    }
502 517

	
503 518
    ///Sets the map that indicates which nodes are processed.
504 519

	
505 520
    ///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.
521
    ///If you don't use this function before calling \ref run(Node) "run()"
522
    ///or \ref init(), an instance will be allocated automatically.
523
    ///The destructor deallocates this automatically allocated map,
524
    ///of course.
509 525
    ///\return <tt> (*this) </tt>
510 526
    Dijkstra &processedMap(ProcessedMap &m)
511 527
    {
512 528
      if(local_processed) {
513 529
        delete _processed;
514 530
        local_processed=false;
515 531
      }
516 532
      _processed = &m;
517 533
      return *this;
518 534
    }
519 535

	
520 536
    ///Sets the map that stores the distances of the nodes.
521 537

	
522 538
    ///Sets the map that stores the distances of the nodes calculated by the
523 539
    ///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.
540
    ///If you don't use this function before calling \ref run(Node) "run()"
541
    ///or \ref init(), an instance will be allocated automatically.
542
    ///The destructor deallocates this automatically allocated map,
543
    ///of course.
527 544
    ///\return <tt> (*this) </tt>
528 545
    Dijkstra &distMap(DistMap &m)
529 546
    {
530 547
      if(local_dist) {
531 548
        delete _dist;
532 549
        local_dist=false;
533 550
      }
534 551
      _dist = &m;
535 552
      return *this;
536 553
    }
537 554

	
538 555
    ///Sets the heap and the cross reference used by algorithm.
539 556

	
540 557
    ///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.
558
    ///If you don't use this function before calling \ref run(Node) "run()"
559
    ///or \ref init(), heap and cross reference instances will be
560
    ///allocated automatically.
561
    ///The destructor deallocates these automatically allocated objects,
562
    ///of course.
544 563
    ///\return <tt> (*this) </tt>
545 564
    Dijkstra &heap(Heap& hp, HeapCrossRef &cr)
546 565
    {
547 566
      if(local_heap_cross_ref) {
548 567
        delete _heap_cross_ref;
549 568
        local_heap_cross_ref=false;
550 569
      }
551 570
      _heap_cross_ref = &cr;
552 571
      if(local_heap) {
553 572
        delete _heap;
554 573
        local_heap=false;
555 574
      }
556 575
      _heap = &hp;
557 576
      return *this;
558 577
    }
559 578

	
560 579
  private:
561 580

	
562 581
    void finalizeNodeData(Node v,Value dst)
563 582
    {
564 583
      _processed->set(v,true);
565 584
      _dist->set(v, dst);
566 585
    }
567 586

	
568 587
  public:
569 588

	
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.
589
    ///\name Execution Control
590
    ///The simplest way to execute the %Dijkstra algorithm is to use
591
    ///one of the member functions called \ref run(Node) "run()".\n
592
    ///If you need better control on the execution, you have to call
593
    ///\ref init() first, then you can add several source nodes with
594
    ///\ref addSource(). Finally the actual path computation can be
595
    ///performed with one of the \ref start() functions.
579 596

	
580 597
    ///@{
581 598

	
599
    ///\brief Initializes the internal data structures.
600
    ///
582 601
    ///Initializes the internal data structures.
583

	
584
    ///Initializes the internal data structures.
585
    ///
586 602
    void init()
587 603
    {
588 604
      create_maps();
589 605
      _heap->clear();
590 606
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
591 607
        _pred->set(u,INVALID);
592 608
        _processed->set(u,false);
593 609
        _heap_cross_ref->set(u,Heap::PRE_HEAP);
594 610
      }
595 611
    }
596 612

	
597 613
    ///Adds a new source node.
598 614

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

	
615 631
    ///Processes the next node in the priority heap
616 632

	
617 633
    ///Processes the next node in the priority heap.
618 634
    ///
619 635
    ///\return The processed node.
620 636
    ///
621 637
    ///\warning The priority heap must not be empty.
622 638
    Node processNextNode()
623 639
    {
624 640
      Node v=_heap->top();
625 641
      Value oldvalue=_heap->prio();
626 642
      _heap->pop();
627 643
      finalizeNodeData(v,oldvalue);
628 644

	
629 645
      for(OutArcIt e(*G,v); e!=INVALID; ++e) {
630 646
        Node w=G->target(e);
631 647
        switch(_heap->state(w)) {
632 648
        case Heap::PRE_HEAP:
633
          _heap->push(w,OperationTraits::plus(oldvalue, (*length)[e]));
649
          _heap->push(w,OperationTraits::plus(oldvalue, (*_length)[e]));
634 650
          _pred->set(w,e);
635 651
          break;
636 652
        case Heap::IN_HEAP:
637 653
          {
638
            Value newvalue = OperationTraits::plus(oldvalue, (*length)[e]);
654
            Value newvalue = OperationTraits::plus(oldvalue, (*_length)[e]);
639 655
            if ( OperationTraits::less(newvalue, (*_heap)[w]) ) {
640 656
              _heap->decrease(w, newvalue);
641 657
              _pred->set(w,e);
642 658
            }
643 659
          }
644 660
          break;
645 661
        case Heap::POST_HEAP:
646 662
          break;
647 663
        }
648 664
      }
649 665
      return v;
650 666
    }
651 667

	
652 668
    ///The next node to be processed.
653 669

	
654 670
    ///Returns the next node to be processed or \c INVALID if the
655 671
    ///priority heap is empty.
656 672
    Node nextNode() const
657 673
    {
658 674
      return !_heap->empty()?_heap->top():INVALID;
659 675
    }
660 676

	
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.
677
    ///Returns \c false if there are nodes to be processed.
678

	
679
    ///Returns \c false if there are nodes to be processed
680
    ///in the priority heap.
666 681
    bool emptyQueue() const { return _heap->empty(); }
667 682

	
668
    ///Returns the number of the nodes to be processed in the priority heap
683
    ///Returns the number of the nodes to be processed.
669 684

	
670
    ///Returns the number of the nodes to be processed in the priority heap.
671
    ///
685
    ///Returns the number of the nodes to be processed
686
    ///in the priority heap.
672 687
    int queueSize() const { return _heap->size(); }
673 688

	
674 689
    ///Executes the algorithm.
675 690

	
676 691
    ///Executes the algorithm.
677 692
    ///
678 693
    ///This method runs the %Dijkstra algorithm from the root node(s)
679 694
    ///in order to compute the shortest path to each node.
680 695
    ///
681 696
    ///The algorithm computes
682 697
    ///- the shortest path tree (forest),
683 698
    ///- the distance of each node from the root(s).
684 699
    ///
685 700
    ///\pre init() must be called and at least one root node should be
686 701
    ///added with addSource() before using this function.
687 702
    ///
688 703
    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
689 704
    ///\code
690 705
    ///  while ( !d.emptyQueue() ) {
691 706
    ///    d.processNextNode();
692 707
    ///  }
693 708
    ///\endcode
694 709
    void start()
695 710
    {
696 711
      while ( !emptyQueue() ) processNextNode();
697 712
    }
698 713

	
699 714
    ///Executes the algorithm until the given target node is processed.
700 715

	
701 716
    ///Executes the algorithm until the given target node is processed.
702 717
    ///
703 718
    ///This method runs the %Dijkstra algorithm from the root node(s)
704 719
    ///in order to compute the shortest path to \c t.
705 720
    ///
706 721
    ///The algorithm computes
707 722
    ///- the shortest path to \c t,
708 723
    ///- the distance of \c t from the root(s).
709 724
    ///
710 725
    ///\pre init() must be called and at least one root node should be
711 726
    ///added with addSource() before using this function.
712 727
    void start(Node t)
713 728
    {
714 729
      while ( !_heap->empty() && _heap->top()!=t ) processNextNode();
715 730
      if ( !_heap->empty() ) {
716 731
        finalizeNodeData(_heap->top(),_heap->prio());
717 732
        _heap->pop();
718 733
      }
719 734
    }
720 735

	
721 736
    ///Executes the algorithm until a condition is met.
722 737

	
723 738
    ///Executes the algorithm until a condition is met.
724 739
    ///
725 740
    ///This method runs the %Dijkstra algorithm from the root node(s) in
726 741
    ///order to compute the shortest path to a node \c v with
727 742
    /// <tt>nm[v]</tt> true, if such a node can be found.
728 743
    ///
729 744
    ///\param nm A \c bool (or convertible) node map. The algorithm
730 745
    ///will stop when it reaches a node \c v with <tt>nm[v]</tt> true.
731 746
    ///
732 747
    ///\return The reached node \c v with <tt>nm[v]</tt> true or
733 748
    ///\c INVALID if no such node was found.
734 749
    ///
735 750
    ///\pre init() must be called and at least one root node should be
736 751
    ///added with addSource() before using this function.
737 752
    template<class NodeBoolMap>
738 753
    Node start(const NodeBoolMap &nm)
739 754
    {
740 755
      while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
741 756
      if ( _heap->empty() ) return INVALID;
742 757
      finalizeNodeData(_heap->top(),_heap->prio());
743 758
      return _heap->top();
744 759
    }
745 760

	
746 761
    ///Runs the algorithm from the given source node.
747 762

	
748 763
    ///This method runs the %Dijkstra algorithm from node \c s
749 764
    ///in order to compute the shortest path to each node.
750 765
    ///
751 766
    ///The algorithm computes
752 767
    ///- the shortest path tree,
753 768
    ///- the distance of each node from the root.
754 769
    ///
755 770
    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
756 771
    ///\code
757 772
    ///  d.init();
758 773
    ///  d.addSource(s);
759 774
    ///  d.start();
760 775
    ///\endcode
761 776
    void run(Node s) {
762 777
      init();
763 778
      addSource(s);
764 779
      start();
765 780
    }
766 781

	
767 782
    ///Finds the shortest path between \c s and \c t.
768 783

	
769 784
    ///This method runs the %Dijkstra algorithm from node \c s
770 785
    ///in order to compute the shortest path to node \c t
771 786
    ///(it stops searching when \c t is processed).
772 787
    ///
773 788
    ///\return \c true if \c t is reachable form \c s.
774 789
    ///
775 790
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is just a
776 791
    ///shortcut of the following code.
777 792
    ///\code
778 793
    ///  d.init();
779 794
    ///  d.addSource(s);
780 795
    ///  d.start(t);
781 796
    ///\endcode
782 797
    bool run(Node s,Node t) {
783 798
      init();
784 799
      addSource(s);
785 800
      start(t);
786 801
      return (*_heap_cross_ref)[t] == Heap::POST_HEAP;
787 802
    }
788 803

	
789 804
    ///@}
790 805

	
791 806
    ///\name Query Functions
792
    ///The result of the %Dijkstra algorithm can be obtained using these
807
    ///The results of the %Dijkstra algorithm can be obtained using these
793 808
    ///functions.\n
794
    ///Either \ref lemon::Dijkstra::run() "run()" or
795
    ///\ref lemon::Dijkstra::start() "start()" must be called before
796
    ///using them.
809
    ///Either \ref run(Node) "run()" or \ref init() should be called
810
    ///before using them.
797 811

	
798 812
    ///@{
799 813

	
800
    ///The shortest path to a node.
814
    ///The shortest path to the given node.
801 815

	
802
    ///Returns the shortest path to a node.
816
    ///Returns the shortest path to the given node from the root(s).
803 817
    ///
804
    ///\warning \c t should be reachable from the root(s).
818
    ///\warning \c t should be reached from the root(s).
805 819
    ///
806
    ///\pre Either \ref run() or \ref start() must be called before
807
    ///using this function.
820
    ///\pre Either \ref run(Node) "run()" or \ref init()
821
    ///must be called before using this function.
808 822
    Path path(Node t) const { return Path(*G, *_pred, t); }
809 823

	
810
    ///The distance of a node from the root(s).
824
    ///The distance of the given node from the root(s).
811 825

	
812
    ///Returns the distance of a node from the root(s).
826
    ///Returns the distance of the given node from the root(s).
813 827
    ///
814
    ///\warning If node \c v is not reachable from the root(s), then
828
    ///\warning If node \c v is not reached from the root(s), then
815 829
    ///the return value of this function is undefined.
816 830
    ///
817
    ///\pre Either \ref run() or \ref start() must be called before
818
    ///using this function.
831
    ///\pre Either \ref run(Node) "run()" or \ref init()
832
    ///must be called before using this function.
819 833
    Value dist(Node v) const { return (*_dist)[v]; }
820 834

	
821
    ///Returns the 'previous arc' of the shortest path tree for a node.
822

	
835
    ///\brief Returns the 'previous arc' of the shortest path tree for
836
    ///the given node.
837
    ///
823 838
    ///This function returns the 'previous arc' of the shortest path
824 839
    ///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.
840
    ///shortest path from a root to \c v. It is \c INVALID if \c v
841
    ///is not reached from the root(s) or if \c v is a root.
827 842
    ///
828 843
    ///The shortest path tree used here is equal to the shortest path
829
    ///tree used in \ref predNode().
844
    ///tree used in \ref predNode() and \ref predMap().
830 845
    ///
831
    ///\pre Either \ref run() or \ref start() must be called before
832
    ///using this function.
846
    ///\pre Either \ref run(Node) "run()" or \ref init()
847
    ///must be called before using this function.
833 848
    Arc predArc(Node v) const { return (*_pred)[v]; }
834 849

	
835
    ///Returns the 'previous node' of the shortest path tree for a node.
836

	
850
    ///\brief Returns the 'previous node' of the shortest path tree for
851
    ///the given node.
852
    ///
837 853
    ///This function returns the 'previous node' of the shortest path
838 854
    ///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.
855
    ///of a shortest path from a root to \c v. It is \c INVALID
856
    ///if \c v is not reached from the root(s) or if \c v is a root.
841 857
    ///
842 858
    ///The shortest path tree used here is equal to the shortest path
843
    ///tree used in \ref predArc().
859
    ///tree used in \ref predArc() and \ref predMap().
844 860
    ///
845
    ///\pre Either \ref run() or \ref start() must be called before
846
    ///using this function.
861
    ///\pre Either \ref run(Node) "run()" or \ref init()
862
    ///must be called before using this function.
847 863
    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
848 864
                                  G->source((*_pred)[v]); }
849 865

	
850 866
    ///\brief Returns a const reference to the node map that stores the
851 867
    ///distances of the nodes.
852 868
    ///
853 869
    ///Returns a const reference to the node map that stores the distances
854 870
    ///of the nodes calculated by the algorithm.
855 871
    ///
856
    ///\pre Either \ref run() or \ref init()
872
    ///\pre Either \ref run(Node) "run()" or \ref init()
857 873
    ///must be called before using this function.
858 874
    const DistMap &distMap() const { return *_dist;}
859 875

	
860 876
    ///\brief Returns a const reference to the node map that stores the
861 877
    ///predecessor arcs.
862 878
    ///
863 879
    ///Returns a const reference to the node map that stores the predecessor
864
    ///arcs, which form the shortest path tree.
880
    ///arcs, which form the shortest path tree (forest).
865 881
    ///
866
    ///\pre Either \ref run() or \ref init()
882
    ///\pre Either \ref run(Node) "run()" or \ref init()
867 883
    ///must be called before using this function.
868 884
    const PredMap &predMap() const { return *_pred;}
869 885

	
870
    ///Checks if a node is reachable from the root(s).
886
    ///Checks if the given node is reached from the root(s).
871 887

	
872
    ///Returns \c true if \c v is reachable from the root(s).
873
    ///\pre Either \ref run() or \ref start()
888
    ///Returns \c true if \c v is reached from the root(s).
889
    ///
890
    ///\pre Either \ref run(Node) "run()" or \ref init()
874 891
    ///must be called before using this function.
875 892
    bool reached(Node v) const { return (*_heap_cross_ref)[v] !=
876 893
                                        Heap::PRE_HEAP; }
877 894

	
878 895
    ///Checks if a node is processed.
879 896

	
880 897
    ///Returns \c true if \c v is processed, i.e. the shortest
881 898
    ///path to \c v has already found.
882
    ///\pre Either \ref run() or \ref init()
899
    ///
900
    ///\pre Either \ref run(Node) "run()" or \ref init()
883 901
    ///must be called before using this function.
884 902
    bool processed(Node v) const { return (*_heap_cross_ref)[v] ==
885 903
                                          Heap::POST_HEAP; }
886 904

	
887
    ///The current distance of a node from the root(s).
905
    ///The current distance of the given node from the root(s).
888 906

	
889
    ///Returns the current distance of a node from the root(s).
907
    ///Returns the current distance of the given node from the root(s).
890 908
    ///It may be decreased in the following processes.
891
    ///\pre Either \ref run() or \ref init()
909
    ///
910
    ///\pre Either \ref run(Node) "run()" or \ref init()
892 911
    ///must be called before using this function and
893 912
    ///node \c v must be reached but not necessarily processed.
894 913
    Value currentDist(Node v) const {
895 914
      return processed(v) ? (*_dist)[v] : (*_heap)[v];
896 915
    }
897 916

	
898 917
    ///@}
899 918
  };
900 919

	
901 920

	
902 921
  ///Default traits class of dijkstra() function.
903 922

	
904 923
  ///Default traits class of dijkstra() function.
905 924
  ///\tparam GR The type of the digraph.
906
  ///\tparam LM The type of the length map.
907
  template<class GR, class LM>
925
  ///\tparam LEN The type of the length map.
926
  template<class GR, class LEN>
908 927
  struct DijkstraWizardDefaultTraits
909 928
  {
910 929
    ///The type of the digraph the algorithm runs on.
911 930
    typedef GR Digraph;
912 931
    ///The type of the map that stores the arc lengths.
913 932

	
914 933
    ///The type of the map that stores the arc lengths.
915
    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
916
    typedef LM LengthMap;
917
    ///The type of the length of the arcs.
918
    typedef typename LM::Value Value;
934
    ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
935
    typedef LEN LengthMap;
936
    ///The type of the arc lengths.
937
    typedef typename LEN::Value Value;
919 938

	
920 939
    /// Operation traits for Dijkstra algorithm.
921 940

	
922 941
    /// This class defines the operations that are used in the algorithm.
923 942
    /// \see DijkstraDefaultOperationTraits
924 943
    typedef DijkstraDefaultOperationTraits<Value> OperationTraits;
925 944

	
926 945
    /// The cross reference type used by the heap.
927 946

	
928 947
    /// The cross reference type used by the heap.
929 948
    /// Usually it is \c Digraph::NodeMap<int>.
930 949
    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
931 950
    ///Instantiates a \ref HeapCrossRef.
932 951

	
933 952
    ///This function instantiates a \ref HeapCrossRef.
934 953
    /// \param g is the digraph, to which we would like to define the
935 954
    /// HeapCrossRef.
936 955
    static HeapCrossRef *createHeapCrossRef(const Digraph &g)
937 956
    {
938 957
      return new HeapCrossRef(g);
939 958
    }
940 959

	
941 960
    ///The heap type used by the Dijkstra algorithm.
942 961

	
943 962
    ///The heap type used by the Dijkstra algorithm.
944 963
    ///
945 964
    ///\sa BinHeap
946 965
    ///\sa Dijkstra
947 966
    typedef BinHeap<Value, typename Digraph::template NodeMap<int>,
948 967
                    std::less<Value> > Heap;
949 968

	
950 969
    ///Instantiates a \ref Heap.
951 970

	
952 971
    ///This function instantiates a \ref Heap.
953 972
    /// \param r is the HeapCrossRef which is used.
954 973
    static Heap *createHeap(HeapCrossRef& r)
955 974
    {
956 975
      return new Heap(r);
957 976
    }
958 977

	
959 978
    ///\brief The type of the map that stores the predecessor
960 979
    ///arcs of the shortest paths.
961 980
    ///
962 981
    ///The type of the map that stores the predecessor
963 982
    ///arcs of the shortest paths.
964
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
983
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
965 984
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
966 985
    ///Instantiates a PredMap.
967 986

	
968 987
    ///This function instantiates a PredMap.
969 988
    ///\param g is the digraph, to which we would like to define the
970 989
    ///PredMap.
971 990
    static PredMap *createPredMap(const Digraph &g)
972 991
    {
973 992
      return new PredMap(g);
974 993
    }
975 994

	
976 995
    ///The type of the map that indicates which nodes are processed.
977 996

	
978 997
    ///The type of the map that indicates which nodes are processed.
979
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
998
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
980 999
    ///By default it is a NullMap.
981 1000
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
982 1001
    ///Instantiates a ProcessedMap.
983 1002

	
984 1003
    ///This function instantiates a ProcessedMap.
985 1004
    ///\param g is the digraph, to which
986 1005
    ///we would like to define the ProcessedMap.
987 1006
#ifdef DOXYGEN
988 1007
    static ProcessedMap *createProcessedMap(const Digraph &g)
989 1008
#else
990 1009
    static ProcessedMap *createProcessedMap(const Digraph &)
991 1010
#endif
992 1011
    {
993 1012
      return new ProcessedMap();
994 1013
    }
995 1014

	
996 1015
    ///The type of the map that stores the distances of the nodes.
997 1016

	
998 1017
    ///The type of the map that stores the distances of the nodes.
999
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
1000
    typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
1018
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
1019
    typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
1001 1020
    ///Instantiates a DistMap.
1002 1021

	
1003 1022
    ///This function instantiates a DistMap.
1004 1023
    ///\param g is the digraph, to which we would like to define
1005 1024
    ///the DistMap
1006 1025
    static DistMap *createDistMap(const Digraph &g)
1007 1026
    {
1008 1027
      return new DistMap(g);
1009 1028
    }
1010 1029

	
1011 1030
    ///The type of the shortest paths.
1012 1031

	
1013 1032
    ///The type of the shortest paths.
1014
    ///It must meet the \ref concepts::Path "Path" concept.
1033
    ///It must conform to the \ref concepts::Path "Path" concept.
1015 1034
    typedef lemon::Path<Digraph> Path;
1016 1035
  };
1017 1036

	
1018 1037
  /// Default traits class used by DijkstraWizard
1019 1038

	
1020
  /// To make it easier to use Dijkstra algorithm
1021
  /// we have created a wizard class.
1022
  /// This \ref DijkstraWizard class needs default traits,
1023
  /// as well as the \ref Dijkstra class.
1024
  /// The \ref DijkstraWizardBase is a class to be the default traits of the
1025
  /// \ref DijkstraWizard class.
1026
  template<class GR,class LM>
1027
  class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LM>
1039
  /// Default traits class used by DijkstraWizard.
1040
  /// \tparam GR The type of the digraph.
1041
  /// \tparam LEN The type of the length map.
1042
  template<typename GR, typename LEN>
1043
  class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LEN>
1028 1044
  {
1029
    typedef DijkstraWizardDefaultTraits<GR,LM> Base;
1045
    typedef DijkstraWizardDefaultTraits<GR,LEN> Base;
1030 1046
  protected:
1031 1047
    //The type of the nodes in the digraph.
1032 1048
    typedef typename Base::Digraph::Node Node;
1033 1049

	
1034 1050
    //Pointer to the digraph the algorithm runs on.
1035 1051
    void *_g;
1036 1052
    //Pointer to the length map.
1037 1053
    void *_length;
1038 1054
    //Pointer to the map of processed nodes.
1039 1055
    void *_processed;
1040 1056
    //Pointer to the map of predecessors arcs.
1041 1057
    void *_pred;
1042 1058
    //Pointer to the map of distances.
1043 1059
    void *_dist;
1044 1060
    //Pointer to the shortest path to the target node.
1045 1061
    void *_path;
1046 1062
    //Pointer to the distance of the target node.
1047 1063
    void *_di;
1048 1064

	
1049 1065
  public:
1050 1066
    /// Constructor.
1051 1067

	
1052 1068
    /// This constructor does not require parameters, therefore it initiates
1053 1069
    /// all of the attributes to \c 0.
1054 1070
    DijkstraWizardBase() : _g(0), _length(0), _processed(0), _pred(0),
1055 1071
                           _dist(0), _path(0), _di(0) {}
1056 1072

	
1057 1073
    /// Constructor.
1058 1074

	
1059 1075
    /// This constructor requires two parameters,
1060 1076
    /// others are initiated to \c 0.
1061 1077
    /// \param g The digraph the algorithm runs on.
1062 1078
    /// \param l The length map.
1063
    DijkstraWizardBase(const GR &g,const LM &l) :
1079
    DijkstraWizardBase(const GR &g,const LEN &l) :
1064 1080
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
1065
      _length(reinterpret_cast<void*>(const_cast<LM*>(&l))),
1081
      _length(reinterpret_cast<void*>(const_cast<LEN*>(&l))),
1066 1082
      _processed(0), _pred(0), _dist(0), _path(0), _di(0) {}
1067 1083

	
1068 1084
  };
1069 1085

	
1070 1086
  /// Auxiliary class for the function-type interface of Dijkstra algorithm.
1071 1087

	
1072 1088
  /// This auxiliary class is created to implement the
1073 1089
  /// \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.
1090
  /// It does not have own \ref run(Node) "run()" method, it uses the
1091
  /// functions and features of the plain \ref Dijkstra.
1076 1092
  ///
1077 1093
  /// This class should only be used through the \ref dijkstra() function,
1078 1094
  /// which makes it easier to use the algorithm.
1079 1095
  template<class TR>
1080 1096
  class DijkstraWizard : public TR
1081 1097
  {
1082 1098
    typedef TR Base;
1083 1099

	
1084
    ///The type of the digraph the algorithm runs on.
1085 1100
    typedef typename TR::Digraph Digraph;
1086 1101

	
1087 1102
    typedef typename Digraph::Node Node;
1088 1103
    typedef typename Digraph::NodeIt NodeIt;
1089 1104
    typedef typename Digraph::Arc Arc;
1090 1105
    typedef typename Digraph::OutArcIt OutArcIt;
1091 1106

	
1092
    ///The type of the map that stores the arc lengths.
1093 1107
    typedef typename TR::LengthMap LengthMap;
1094
    ///The type of the length of the arcs.
1095 1108
    typedef typename LengthMap::Value Value;
1096
    ///\brief The type of the map that stores the predecessor
1097
    ///arcs of the shortest paths.
1098 1109
    typedef typename TR::PredMap PredMap;
1099
    ///The type of the map that stores the distances of the nodes.
1100 1110
    typedef typename TR::DistMap DistMap;
1101
    ///The type of the map that indicates which nodes are processed.
1102 1111
    typedef typename TR::ProcessedMap ProcessedMap;
1103
    ///The type of the shortest paths
1104 1112
    typedef typename TR::Path Path;
1105
    ///The heap type used by the dijkstra algorithm.
1106 1113
    typedef typename TR::Heap Heap;
1107 1114

	
1108 1115
  public:
1109 1116

	
1110 1117
    /// Constructor.
1111 1118
    DijkstraWizard() : TR() {}
1112 1119

	
1113 1120
    /// Constructor that requires parameters.
1114 1121

	
1115 1122
    /// Constructor that requires parameters.
1116 1123
    /// These parameters will be the default values for the traits class.
1117 1124
    /// \param g The digraph the algorithm runs on.
1118 1125
    /// \param l The length map.
1119 1126
    DijkstraWizard(const Digraph &g, const LengthMap &l) :
1120 1127
      TR(g,l) {}
1121 1128

	
1122 1129
    ///Copy constructor
1123 1130
    DijkstraWizard(const TR &b) : TR(b) {}
1124 1131

	
1125 1132
    ~DijkstraWizard() {}
1126 1133

	
1127 1134
    ///Runs Dijkstra algorithm from the given source node.
1128 1135

	
1129 1136
    ///This method runs %Dijkstra algorithm from the given source node
1130 1137
    ///in order to compute the shortest path to each node.
1131 1138
    void run(Node s)
1132 1139
    {
1133 1140
      Dijkstra<Digraph,LengthMap,TR>
1134 1141
        dijk(*reinterpret_cast<const Digraph*>(Base::_g),
1135 1142
             *reinterpret_cast<const LengthMap*>(Base::_length));
1136 1143
      if (Base::_pred)
1137 1144
        dijk.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1138 1145
      if (Base::_dist)
1139 1146
        dijk.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1140 1147
      if (Base::_processed)
1141 1148
        dijk.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1142 1149
      dijk.run(s);
1143 1150
    }
1144 1151

	
1145 1152
    ///Finds the shortest path between \c s and \c t.
1146 1153

	
1147 1154
    ///This method runs the %Dijkstra algorithm from node \c s
1148 1155
    ///in order to compute the shortest path to node \c t
1149 1156
    ///(it stops searching when \c t is processed).
1150 1157
    ///
1151 1158
    ///\return \c true if \c t is reachable form \c s.
1152 1159
    bool run(Node s, Node t)
1153 1160
    {
1154 1161
      Dijkstra<Digraph,LengthMap,TR>
1155 1162
        dijk(*reinterpret_cast<const Digraph*>(Base::_g),
1156 1163
             *reinterpret_cast<const LengthMap*>(Base::_length));
1157 1164
      if (Base::_pred)
1158 1165
        dijk.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1159 1166
      if (Base::_dist)
1160 1167
        dijk.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1161 1168
      if (Base::_processed)
1162 1169
        dijk.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1163 1170
      dijk.run(s,t);
1164 1171
      if (Base::_path)
1165 1172
        *reinterpret_cast<Path*>(Base::_path) = dijk.path(t);
1166 1173
      if (Base::_di)
1167 1174
        *reinterpret_cast<Value*>(Base::_di) = dijk.dist(t);
1168 1175
      return dijk.reached(t);
1169 1176
    }
1170 1177

	
1171 1178
    template<class T>
1172 1179
    struct SetPredMapBase : public Base {
1173 1180
      typedef T PredMap;
1174 1181
      static PredMap *createPredMap(const Digraph &) { return 0; };
1175 1182
      SetPredMapBase(const TR &b) : TR(b) {}
1176 1183
    };
1177
    ///\brief \ref named-func-param "Named parameter"
1178
    ///for setting PredMap object.
1184

	
1185
    ///\brief \ref named-templ-param "Named parameter" for setting
1186
    ///the predecessor map.
1179 1187
    ///
1180
    ///\ref named-func-param "Named parameter"
1181
    ///for setting PredMap object.
1188
    ///\ref named-templ-param "Named parameter" function for setting
1189
    ///the map that stores the predecessor arcs of the nodes.
1182 1190
    template<class T>
1183 1191
    DijkstraWizard<SetPredMapBase<T> > predMap(const T &t)
1184 1192
    {
1185 1193
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1186 1194
      return DijkstraWizard<SetPredMapBase<T> >(*this);
1187 1195
    }
1188 1196

	
1189 1197
    template<class T>
1190 1198
    struct SetDistMapBase : public Base {
1191 1199
      typedef T DistMap;
1192 1200
      static DistMap *createDistMap(const Digraph &) { return 0; };
1193 1201
      SetDistMapBase(const TR &b) : TR(b) {}
1194 1202
    };
1195
    ///\brief \ref named-func-param "Named parameter"
1196
    ///for setting DistMap object.
1203

	
1204
    ///\brief \ref named-templ-param "Named parameter" for setting
1205
    ///the distance map.
1197 1206
    ///
1198
    ///\ref named-func-param "Named parameter"
1199
    ///for setting DistMap object.
1207
    ///\ref named-templ-param "Named parameter" function for setting
1208
    ///the map that stores the distances of the nodes calculated
1209
    ///by the algorithm.
1200 1210
    template<class T>
1201 1211
    DijkstraWizard<SetDistMapBase<T> > distMap(const T &t)
1202 1212
    {
1203 1213
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1204 1214
      return DijkstraWizard<SetDistMapBase<T> >(*this);
1205 1215
    }
1206 1216

	
1207 1217
    template<class T>
1208 1218
    struct SetProcessedMapBase : public Base {
1209 1219
      typedef T ProcessedMap;
1210 1220
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1211 1221
      SetProcessedMapBase(const TR &b) : TR(b) {}
1212 1222
    };
1213
    ///\brief \ref named-func-param "Named parameter"
1214
    ///for setting ProcessedMap object.
1223

	
1224
    ///\brief \ref named-func-param "Named parameter" for setting
1225
    ///the processed map.
1215 1226
    ///
1216
    /// \ref named-func-param "Named parameter"
1217
    ///for setting ProcessedMap object.
1227
    ///\ref named-templ-param "Named parameter" function for setting
1228
    ///the map that indicates which nodes are processed.
1218 1229
    template<class T>
1219 1230
    DijkstraWizard<SetProcessedMapBase<T> > processedMap(const T &t)
1220 1231
    {
1221 1232
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1222 1233
      return DijkstraWizard<SetProcessedMapBase<T> >(*this);
1223 1234
    }
1224 1235

	
1225 1236
    template<class T>
1226 1237
    struct SetPathBase : public Base {
1227 1238
      typedef T Path;
1228 1239
      SetPathBase(const TR &b) : TR(b) {}
1229 1240
    };
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
///\ingroup misc
24
///\ingroup geomdat
25 25
///\file
26 26
///\brief A simple two dimensional vector and a bounding box implementation
27
///
28
/// The class \ref lemon::dim2::Point "dim2::Point" implements
29
/// a two dimensional vector with the usual operations.
30
///
31
/// The class \ref lemon::dim2::Box "dim2::Box" can be used to determine
32
/// the rectangular bounding box of a set of
33
/// \ref lemon::dim2::Point "dim2::Point"'s.
34 27

	
35 28
namespace lemon {
36 29

	
37 30
  ///Tools for handling two dimensional coordinates
38 31

	
39 32
  ///This namespace is a storage of several
40 33
  ///tools for handling two dimensional coordinates
41 34
  namespace dim2 {
42 35

	
43
  /// \addtogroup misc
36
  /// \addtogroup geomdat
44 37
  /// @{
45 38

	
46 39
  /// Two dimensional vector (plain vector)
47 40

	
48 41
  /// A simple two dimensional vector (plain vector) implementation
49 42
  /// with the usual vector operations.
50 43
  template<typename T>
51 44
    class Point {
52 45

	
53 46
    public:
54 47

	
55 48
      typedef T Value;
56 49

	
57 50
      ///First coordinate
58 51
      T x;
59 52
      ///Second coordinate
60 53
      T y;
61 54

	
62 55
      ///Default constructor
63 56
      Point() {}
64 57

	
65 58
      ///Construct an instance from coordinates
66 59
      Point(T a, T b) : x(a), y(b) { }
67 60

	
68 61
      ///Returns the dimension of the vector (i.e. returns 2).
69 62

	
70 63
      ///The dimension of the vector.
71 64
      ///This function always returns 2.
72 65
      int size() const { return 2; }
73 66

	
74 67
      ///Subscripting operator
75 68

	
76 69
      ///\c p[0] is \c p.x and \c p[1] is \c p.y
77 70
      ///
78 71
      T& operator[](int idx) { return idx == 0 ? x : y; }
79 72

	
80 73
      ///Const subscripting operator
81 74

	
82 75
      ///\c p[0] is \c p.x and \c p[1] is \c p.y
83 76
      ///
84 77
      const T& operator[](int idx) const { return idx == 0 ? x : y; }
85 78

	
86 79
      ///Conversion constructor
87 80
      template<class TT> Point(const Point<TT> &p) : x(p.x), y(p.y) {}
88 81

	
89 82
      ///Give back the square of the norm of the vector
90 83
      T normSquare() const {
91 84
        return x*x+y*y;
92 85
      }
93 86

	
94 87
      ///Increment the left hand side by \c u
95 88
      Point<T>& operator +=(const Point<T>& u) {
96 89
        x += u.x;
97 90
        y += u.y;
98 91
        return *this;
99 92
      }
100 93

	
101 94
      ///Decrement the left hand side by \c u
102 95
      Point<T>& operator -=(const Point<T>& u) {
103 96
        x -= u.x;
104 97
        y -= u.y;
105 98
        return *this;
106 99
      }
107 100

	
108 101
      ///Multiply the left hand side with a scalar
109 102
      Point<T>& operator *=(const T &u) {
110 103
        x *= u;
111 104
        y *= u;
112 105
        return *this;
113 106
      }
114 107

	
115 108
      ///Divide the left hand side by a scalar
116 109
      Point<T>& operator /=(const T &u) {
117 110
        x /= u;
118 111
        y /= u;
119 112
        return *this;
120 113
      }
121 114

	
122 115
      ///Return the scalar product of two vectors
123 116
      T operator *(const Point<T>& u) const {
124 117
        return x*u.x+y*u.y;
125 118
      }
126 119

	
127 120
      ///Return the sum of two vectors
128 121
      Point<T> operator+(const Point<T> &u) const {
129 122
        Point<T> b=*this;
130 123
        return b+=u;
131 124
      }
132 125

	
133 126
      ///Return the negative of the vector
134 127
      Point<T> operator-() const {
135 128
        Point<T> b=*this;
136 129
        b.x=-b.x; b.y=-b.y;
137 130
        return b;
138 131
      }
139 132

	
140 133
      ///Return the difference of two vectors
141 134
      Point<T> operator-(const Point<T> &u) const {
142 135
        Point<T> b=*this;
143 136
        return b-=u;
144 137
      }
145 138

	
146 139
      ///Return a vector multiplied by a scalar
147 140
      Point<T> operator*(const T &u) const {
148 141
        Point<T> b=*this;
149 142
        return b*=u;
150 143
      }
151 144

	
152 145
      ///Return a vector divided by a scalar
153 146
      Point<T> operator/(const T &u) const {
154 147
        Point<T> b=*this;
155 148
        return b/=u;
156 149
      }
157 150

	
158 151
      ///Test equality
159 152
      bool operator==(const Point<T> &u) const {
160 153
        return (x==u.x) && (y==u.y);
161 154
      }
162 155

	
163 156
      ///Test inequality
164 157
      bool operator!=(Point u) const {
165 158
        return  (x!=u.x) || (y!=u.y);
166 159
      }
167 160

	
168 161
    };
169 162

	
170 163
  ///Return a Point
171 164

	
172 165
  ///Return a Point.
173 166
  ///\relates Point
174 167
  template <typename T>
175 168
  inline Point<T> makePoint(const T& x, const T& y) {
176 169
    return Point<T>(x, y);
177 170
  }
178 171

	
179 172
  ///Return a vector multiplied by a scalar
180 173

	
181 174
  ///Return a vector multiplied by a scalar.
182 175
  ///\relates Point
183 176
  template<typename T> Point<T> operator*(const T &u,const Point<T> &x) {
184 177
    return x*u;
185 178
  }
186 179

	
187 180
  ///Read a plain vector from a stream
188 181

	
189 182
  ///Read a plain vector from a stream.
190 183
  ///\relates Point
191 184
  ///
192 185
  template<typename T>
193 186
  inline std::istream& operator>>(std::istream &is, Point<T> &z) {
194 187
    char c;
195 188
    if (is >> c) {
196 189
      if (c != '(') is.putback(c);
197 190
    } else {
198 191
      is.clear();
199 192
    }
200 193
    if (!(is >> z.x)) return is;
201 194
    if (is >> c) {
202 195
      if (c != ',') is.putback(c);
203 196
    } else {
204 197
      is.clear();
205 198
    }
206 199
    if (!(is >> z.y)) return is;
207 200
    if (is >> c) {
208 201
      if (c != ')') is.putback(c);
209 202
    } else {
210 203
      is.clear();
211 204
    }
212 205
    return is;
213 206
  }
214 207

	
215 208
  ///Write a plain vector to a stream
216 209

	
217 210
  ///Write a plain vector to a stream.
218 211
  ///\relates Point
219 212
  ///
220 213
  template<typename T>
221 214
  inline std::ostream& operator<<(std::ostream &os, const Point<T>& z)
222 215
  {
223 216
    os << "(" << z.x << "," << z.y << ")";
224 217
    return os;
225 218
  }
226 219

	
227 220
  ///Rotate by 90 degrees
228 221

	
229 222
  ///Returns the parameter rotated by 90 degrees in positive direction.
230 223
  ///\relates Point
231 224
  ///
232 225
  template<typename T>
233 226
  inline Point<T> rot90(const Point<T> &z)
234 227
  {
235 228
    return Point<T>(-z.y,z.x);
236 229
  }
237 230

	
238 231
  ///Rotate by 180 degrees
239 232

	
240 233
  ///Returns the parameter rotated by 180 degrees.
241 234
  ///\relates Point
242 235
  ///
243 236
  template<typename T>
244 237
  inline Point<T> rot180(const Point<T> &z)
245 238
  {
246 239
    return Point<T>(-z.x,-z.y);
247 240
  }
248 241

	
249 242
  ///Rotate by 270 degrees
250 243

	
251 244
  ///Returns the parameter rotated by 90 degrees in negative direction.
252 245
  ///\relates Point
253 246
  ///
254 247
  template<typename T>
255 248
  inline Point<T> rot270(const Point<T> &z)
256 249
  {
257 250
    return Point<T>(z.y,-z.x);
258 251
  }
259 252

	
260 253

	
261 254

	
262 255
  /// Bounding box of plain vectors (points).
263 256

	
264 257
  /// A class to calculate or store the bounding box of plain vectors
265 258
  /// (\ref Point "points").
266 259
  template<typename T>
267 260
  class Box {
268 261
      Point<T> _bottom_left, _top_right;
269 262
      bool _empty;
270 263
    public:
271 264

	
272 265
      ///Default constructor: creates an empty box
273 266
      Box() { _empty = true; }
274 267

	
275 268
      ///Construct a box from one point
276 269
      Box(Point<T> a) {
277 270
        _bottom_left = _top_right = a;
278 271
        _empty = false;
279 272
      }
280 273

	
281 274
      ///Construct a box from two points
282 275

	
283 276
      ///Construct a box from two points.
284 277
      ///\param a The bottom left corner.
285 278
      ///\param b The top right corner.
286 279
      ///\warning The coordinates of the bottom left corner must be no more
287 280
      ///than those of the top right one.
288 281
      Box(Point<T> a,Point<T> b)
289 282
      {
290 283
        _bottom_left = a;
291 284
        _top_right = b;
292 285
        _empty = false;
293 286
      }
294 287

	
295 288
      ///Construct a box from four numbers
296 289

	
297 290
      ///Construct a box from four numbers.
298 291
      ///\param l The left side of the box.
299 292
      ///\param b The bottom of the box.
300 293
      ///\param r The right side of the box.
301 294
      ///\param t The top of the box.
302 295
      ///\warning The left side must be no more than the right side and
303 296
      ///bottom must be no more than the top.
304 297
      Box(T l,T b,T r,T t)
305 298
      {
306 299
        _bottom_left=Point<T>(l,b);
307 300
        _top_right=Point<T>(r,t);
308 301
        _empty = false;
309 302
      }
310 303

	
311 304
      ///Return \c true if the box is empty.
312 305

	
313 306
      ///Return \c true if the box is empty (i.e. return \c false
314 307
      ///if at least one point was added to the box or the coordinates of
315 308
      ///the box were set).
316 309
      ///
317 310
      ///The coordinates of an empty box are not defined.
318 311
      bool empty() const {
319 312
        return _empty;
320 313
      }
321 314

	
322 315
      ///Make the box empty
323 316
      void clear() {
324 317
        _empty = true;
325 318
      }
326 319

	
327 320
      ///Give back the bottom left corner of the box
328 321

	
329 322
      ///Give back the bottom left corner of the box.
330 323
      ///If the box is empty, then the return value is not defined.
331 324
      Point<T> bottomLeft() const {
332 325
        return _bottom_left;
333 326
      }
334 327

	
335 328
      ///Set the bottom left corner of the box
336 329

	
337 330
      ///Set the bottom left corner of the box.
338 331
      ///\pre The box must not be empty.
339 332
      void bottomLeft(Point<T> p) {
340 333
        _bottom_left = p;
341 334
      }
342 335

	
343 336
      ///Give back the top right corner of the box
344 337

	
345 338
      ///Give back the top right corner of the box.
346 339
      ///If the box is empty, then the return value is not defined.
347 340
      Point<T> topRight() const {
348 341
        return _top_right;
349 342
      }
350 343

	
351 344
      ///Set the top right corner of the box
352 345

	
353 346
      ///Set the top right corner of the box.
354 347
      ///\pre The box must not be empty.
355 348
      void topRight(Point<T> p) {
356 349
        _top_right = p;
357 350
      }
358 351

	
359 352
      ///Give back the bottom right corner of the box
360 353

	
361 354
      ///Give back the bottom right corner of the box.
362 355
      ///If the box is empty, then the return value is not defined.
363 356
      Point<T> bottomRight() const {
364 357
        return Point<T>(_top_right.x,_bottom_left.y);
365 358
      }
366 359

	
367 360
      ///Set the bottom right corner of the box
368 361

	
369 362
      ///Set the bottom right corner of the box.
370 363
      ///\pre The box must not be empty.
371 364
      void bottomRight(Point<T> p) {
372 365
        _top_right.x = p.x;
373 366
        _bottom_left.y = p.y;
374 367
      }
375 368

	
376 369
      ///Give back the top left corner of the box
377 370

	
378 371
      ///Give back the top left corner of the box.
379 372
      ///If the box is empty, then the return value is not defined.
380 373
      Point<T> topLeft() const {
381 374
        return Point<T>(_bottom_left.x,_top_right.y);
382 375
      }
383 376

	
384 377
      ///Set the top left corner of the box
385 378

	
386 379
      ///Set the top left corner of the box.
387 380
      ///\pre The box must not be empty.
388 381
      void topLeft(Point<T> p) {
389 382
        _top_right.y = p.y;
390 383
        _bottom_left.x = p.x;
391 384
      }
392 385

	
393 386
      ///Give back the bottom of the box
394 387

	
395 388
      ///Give back the bottom of the box.
396 389
      ///If the box is empty, then the return value is not defined.
397 390
      T bottom() const {
398 391
        return _bottom_left.y;
399 392
      }
400 393

	
401 394
      ///Set the bottom of the box
402 395

	
403 396
      ///Set the bottom of the box.
404 397
      ///\pre The box must not be empty.
405 398
      void bottom(T t) {
406 399
        _bottom_left.y = t;
407 400
      }
408 401

	
409 402
      ///Give back the top of the box
410 403

	
411 404
      ///Give back the top of the box.
412 405
      ///If the box is empty, then the return value is not defined.
413 406
      T top() const {
414 407
        return _top_right.y;
415 408
      }
416 409

	
417 410
      ///Set the top of the box
418 411

	
419 412
      ///Set the top of the box.
420 413
      ///\pre The box must not be empty.
421 414
      void top(T t) {
422 415
        _top_right.y = t;
423 416
      }
424 417

	
425 418
      ///Give back the left side of the box
426 419

	
427 420
      ///Give back the left side of the box.
428 421
      ///If the box is empty, then the return value is not defined.
429 422
      T left() const {
430 423
        return _bottom_left.x;
431 424
      }
432 425

	
433 426
      ///Set the left side of the box
434 427

	
435 428
      ///Set the left side of the box.
436 429
      ///\pre The box must not be empty.
437 430
      void left(T t) {
438 431
        _bottom_left.x = t;
439 432
      }
440 433

	
441 434
      /// Give back the right side of the box
442 435

	
443 436
      /// Give back the right side of the box.
444 437
      ///If the box is empty, then the return value is not defined.
445 438
      T right() const {
446 439
        return _top_right.x;
447 440
      }
448 441

	
449 442
      ///Set the right side of the box
450 443

	
451 444
      ///Set the right side of the box.
452 445
      ///\pre The box must not be empty.
453 446
      void right(T t) {
454 447
        _top_right.x = t;
455 448
      }
456 449

	
457 450
      ///Give back the height of the box
458 451

	
459 452
      ///Give back the height of the box.
460 453
      ///If the box is empty, then the return value is not defined.
461 454
      T height() const {
462 455
        return _top_right.y-_bottom_left.y;
463 456
      }
464 457

	
465 458
      ///Give back the width of the box
466 459

	
467 460
      ///Give back the width of the box.
468 461
      ///If the box is empty, then the return value is not defined.
469 462
      T width() const {
470 463
        return _top_right.x-_bottom_left.x;
471 464
      }
472 465

	
473 466
      ///Checks whether a point is inside the box
474 467
      bool inside(const Point<T>& u) const {
475 468
        if (_empty)
476 469
          return false;
477 470
        else {
478 471
          return ( (u.x-_bottom_left.x)*(_top_right.x-u.x) >= 0 &&
479 472
                   (u.y-_bottom_left.y)*(_top_right.y-u.y) >= 0 );
480 473
        }
481 474
      }
482 475

	
483 476
      ///Increments the box with a point
484 477

	
485 478
      ///Increments the box with a point.
486 479
      ///
487 480
      Box& add(const Point<T>& u){
488 481
        if (_empty) {
489 482
          _bottom_left = _top_right = u;
490 483
          _empty = false;
491 484
        }
492 485
        else {
493 486
          if (_bottom_left.x > u.x) _bottom_left.x = u.x;
494 487
          if (_bottom_left.y > u.y) _bottom_left.y = u.y;
495 488
          if (_top_right.x < u.x) _top_right.x = u.x;
496 489
          if (_top_right.y < u.y) _top_right.y = u.y;
497 490
        }
498 491
        return *this;
499 492
      }
500 493

	
501 494
      ///Increments the box to contain another box
502 495

	
503 496
      ///Increments the box to contain another box.
504 497
      ///
505 498
      Box& add(const Box &u){
506 499
        if ( !u.empty() ){
507 500
          add(u._bottom_left);
508 501
          add(u._top_right);
509 502
        }
510 503
        return *this;
511 504
      }
512 505

	
513 506
      ///Intersection of two boxes
514 507

	
515 508
      ///Intersection of two boxes.
516 509
      ///
517 510
      Box operator&(const Box& u) const {
518 511
        Box b;
519 512
        if (_empty || u._empty) {
520 513
          b._empty = true;
521 514
        } else {
522 515
          b._bottom_left.x = std::max(_bottom_left.x, u._bottom_left.x);
523 516
          b._bottom_left.y = std::max(_bottom_left.y, u._bottom_left.y);
524 517
          b._top_right.x = std::min(_top_right.x, u._top_right.x);
525 518
          b._top_right.y = std::min(_top_right.y, u._top_right.y);
526 519
          b._empty = b._bottom_left.x > b._top_right.x ||
527 520
                     b._bottom_left.y > b._top_right.y;
528 521
        }
529 522
        return b;
530 523
      }
531 524

	
532 525
  };//class Box
533 526

	
534 527

	
535 528
  ///Read a box from a stream
536 529

	
537 530
  ///Read a box from a stream.
538 531
  ///\relates Box
539 532
  template<typename T>
540 533
  inline std::istream& operator>>(std::istream &is, Box<T>& b) {
541 534
    char c;
542 535
    Point<T> p;
543 536
    if (is >> c) {
544 537
      if (c != '(') is.putback(c);
545 538
    } else {
546 539
      is.clear();
547 540
    }
548 541
    if (!(is >> p)) return is;
549 542
    b.bottomLeft(p);
550 543
    if (is >> c) {
551 544
      if (c != ',') is.putback(c);
552 545
    } else {
553 546
      is.clear();
554 547
    }
555 548
    if (!(is >> p)) return is;
556 549
    b.topRight(p);
557 550
    if (is >> c) {
558 551
      if (c != ')') is.putback(c);
559 552
    } else {
560 553
      is.clear();
561 554
    }
562 555
    return is;
563 556
  }
564 557

	
565 558
  ///Write a box to a stream
566 559

	
567 560
  ///Write a box to a stream.
568 561
  ///\relates Box
569 562
  template<typename T>
570 563
  inline std::ostream& operator<<(std::ostream &os, const Box<T>& b)
571 564
  {
572 565
    os << "(" << b.bottomLeft() << "," << b.topRight() << ")";
573 566
    return os;
574 567
  }
575 568

	
576 569
  ///Map of x-coordinates of a <tt>Point</tt>-map
577 570

	
578 571
  ///Map of x-coordinates of a \ref Point "Point"-map.
579 572
  ///
580 573
  template<class M>
581 574
  class XMap
582 575
  {
583 576
    M& _map;
584 577
  public:
585 578

	
586 579
    typedef typename M::Value::Value Value;
587 580
    typedef typename M::Key Key;
588 581
    ///\e
589 582
    XMap(M& map) : _map(map) {}
590 583
    Value operator[](Key k) const {return _map[k].x;}
591 584
    void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
592 585
  };
593 586

	
594 587
  ///Returns an XMap class
595 588

	
596 589
  ///This function just returns an XMap class.
597 590
  ///\relates XMap
598 591
  template<class M>
599 592
  inline XMap<M> xMap(M &m)
600 593
  {
601 594
    return XMap<M>(m);
602 595
  }
603 596

	
604 597
  template<class M>
605 598
  inline XMap<M> xMap(const M &m)
606 599
  {
607 600
    return XMap<M>(m);
608 601
  }
609 602

	
610 603
  ///Constant (read only) version of XMap
611 604

	
612 605
  ///Constant (read only) version of XMap.
613 606
  ///
614 607
  template<class M>
615 608
  class ConstXMap
616 609
  {
617 610
    const M& _map;
618 611
  public:
619 612

	
620 613
    typedef typename M::Value::Value Value;
621 614
    typedef typename M::Key Key;
622 615
    ///\e
623 616
    ConstXMap(const M &map) : _map(map) {}
624 617
    Value operator[](Key k) const {return _map[k].x;}
625 618
  };
626 619

	
627 620
  ///Returns a ConstXMap class
628 621

	
629 622
  ///This function just returns a ConstXMap class.
630 623
  ///\relates ConstXMap
631 624
  template<class M>
632 625
  inline ConstXMap<M> xMap(const M &m)
633 626
  {
634 627
    return ConstXMap<M>(m);
635 628
  }
636 629

	
637 630
  ///Map of y-coordinates of a <tt>Point</tt>-map
638 631

	
639 632
  ///Map of y-coordinates of a \ref Point "Point"-map.
640 633
  ///
641 634
  template<class M>
642 635
  class YMap
643 636
  {
644 637
    M& _map;
645 638
  public:
646 639

	
647 640
    typedef typename M::Value::Value Value;
648 641
    typedef typename M::Key Key;
649 642
    ///\e
650 643
    YMap(M& map) : _map(map) {}
651 644
    Value operator[](Key k) const {return _map[k].y;}
652 645
    void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
653 646
  };
654 647

	
655 648
  ///Returns a YMap class
656 649

	
657 650
  ///This function just returns a YMap class.
658 651
  ///\relates YMap
659 652
  template<class M>
660 653
  inline YMap<M> yMap(M &m)
661 654
  {
662 655
    return YMap<M>(m);
663 656
  }
664 657

	
665 658
  template<class M>
666 659
  inline YMap<M> yMap(const M &m)
667 660
  {
668 661
    return YMap<M>(m);
669 662
  }
670 663

	
671 664
  ///Constant (read only) version of YMap
672 665

	
673 666
  ///Constant (read only) version of YMap.
674 667
  ///
675 668
  template<class M>
676 669
  class ConstYMap
677 670
  {
678 671
    const M& _map;
679 672
  public:
680 673

	
681 674
    typedef typename M::Value::Value Value;
682 675
    typedef typename M::Key Key;
683 676
    ///\e
684 677
    ConstYMap(const M &map) : _map(map) {}
685 678
    Value operator[](Key k) const {return _map[k].y;}
686 679
  };
687 680

	
688 681
  ///Returns a ConstYMap class
689 682

	
690 683
  ///This function just returns a ConstYMap class.
691 684
  ///\relates ConstYMap
692 685
  template<class M>
693 686
  inline ConstYMap<M> yMap(const M &m)
694 687
  {
695 688
    return ConstYMap<M>(m);
696 689
  }
697 690

	
698 691

	
699 692
  ///\brief Map of the normSquare() of a <tt>Point</tt>-map
700 693
  ///
701 694
  ///Map of the \ref Point::normSquare() "normSquare()"
702 695
  ///of a \ref Point "Point"-map.
703 696
  template<class M>
704 697
  class NormSquareMap
705 698
  {
706 699
    const M& _map;
707 700
  public:
708 701

	
709 702
    typedef typename M::Value::Value Value;
710 703
    typedef typename M::Key Key;
711 704
    ///\e
712 705
    NormSquareMap(const M &map) : _map(map) {}
713 706
    Value operator[](Key k) const {return _map[k].normSquare();}
714 707
  };
715 708

	
716 709
  ///Returns a NormSquareMap class
717 710

	
718 711
  ///This function just returns a NormSquareMap class.
719 712
  ///\relates NormSquareMap
720 713
  template<class M>
721 714
  inline NormSquareMap<M> normSquareMap(const M &m)
722 715
  {
723 716
    return NormSquareMap<M>(m);
724 717
  }
725 718

	
726 719
  /// @}
727 720

	
728 721
  } //namespce dim2
729 722

	
730 723
} //namespace lemon
731 724

	
732 725
#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
///\brief ListDigraph, ListGraph classes.
24
///\brief ListDigraph and 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
  class ListDigraph;
36

	
35 37
  class ListDigraphBase {
36 38

	
37 39
  protected:
38 40
    struct NodeT {
39 41
      int first_in, first_out;
40 42
      int prev, next;
41 43
    };
42 44

	
43 45
    struct ArcT {
44 46
      int target, source;
45 47
      int prev_in, prev_out;
46 48
      int next_in, next_out;
47 49
    };
48 50

	
49 51
    std::vector<NodeT> nodes;
50 52

	
51 53
    int first_node;
52 54

	
53 55
    int first_free_node;
54 56

	
55 57
    std::vector<ArcT> arcs;
56 58

	
57 59
    int first_free_arc;
58 60

	
59 61
  public:
60 62

	
61 63
    typedef ListDigraphBase Digraph;
62 64

	
63 65
    class Node {
64 66
      friend class ListDigraphBase;
67
      friend class ListDigraph;
65 68
    protected:
66 69

	
67 70
      int id;
68 71
      explicit Node(int pid) { id = pid;}
69 72

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

	
78 81
    class Arc {
79 82
      friend class ListDigraphBase;
83
      friend class ListDigraph;
80 84
    protected:
81 85

	
82 86
      int id;
83 87
      explicit Arc(int pid) { id = pid;}
84 88

	
85 89
    public:
86 90
      Arc() {}
87 91
      Arc (Invalid) { id = -1; }
88 92
      bool operator==(const Arc& arc) const {return id == arc.id;}
89 93
      bool operator!=(const Arc& arc) const {return id != arc.id;}
90 94
      bool operator<(const Arc& arc) const {return id < arc.id;}
91 95
    };
92 96

	
93 97

	
94 98

	
95 99
    ListDigraphBase()
96 100
      : nodes(), first_node(-1),
97 101
        first_free_node(-1), arcs(), first_free_arc(-1) {}
98 102

	
99 103

	
100 104
    int maxNodeId() const { return nodes.size()-1; }
101 105
    int maxArcId() const { return arcs.size()-1; }
102 106

	
103 107
    Node source(Arc e) const { return Node(arcs[e.id].source); }
104 108
    Node target(Arc e) const { return Node(arcs[e.id].target); }
105 109

	
106 110

	
107 111
    void first(Node& node) const {
108 112
      node.id = first_node;
109 113
    }
110 114

	
111 115
    void next(Node& node) const {
112 116
      node.id = nodes[node.id].next;
113 117
    }
114 118

	
115 119

	
116 120
    void first(Arc& arc) const {
117 121
      int n;
118 122
      for(n = first_node;
119
          n!=-1 && nodes[n].first_in == -1;
123
          n != -1 && nodes[n].first_out == -1;
120 124
          n = nodes[n].next) {}
121
      arc.id = (n == -1) ? -1 : nodes[n].first_in;
125
      arc.id = (n == -1) ? -1 : nodes[n].first_out;
122 126
    }
123 127

	
124 128
    void next(Arc& arc) const {
125
      if (arcs[arc.id].next_in != -1) {
126
        arc.id = arcs[arc.id].next_in;
129
      if (arcs[arc.id].next_out != -1) {
130
        arc.id = arcs[arc.id].next_out;
127 131
      } else {
128 132
        int n;
129
        for(n = nodes[arcs[arc.id].target].next;
130
            n!=-1 && nodes[n].first_in == -1;
133
        for(n = nodes[arcs[arc.id].source].next;
134
            n != -1 && nodes[n].first_out == -1;
131 135
            n = nodes[n].next) {}
132
        arc.id = (n == -1) ? -1 : nodes[n].first_in;
136
        arc.id = (n == -1) ? -1 : nodes[n].first_out;
133 137
      }
134 138
    }
135 139

	
136 140
    void firstOut(Arc &e, const Node& v) const {
137 141
      e.id = nodes[v.id].first_out;
138 142
    }
139 143
    void nextOut(Arc &e) const {
140 144
      e.id=arcs[e.id].next_out;
141 145
    }
142 146

	
143 147
    void firstIn(Arc &e, const Node& v) const {
144 148
      e.id = nodes[v.id].first_in;
145 149
    }
146 150
    void nextIn(Arc &e) const {
147 151
      e.id=arcs[e.id].next_in;
148 152
    }
149 153

	
150 154

	
151 155
    static int id(Node v) { return v.id; }
152 156
    static int id(Arc e) { return e.id; }
153 157

	
154 158
    static Node nodeFromId(int id) { return Node(id);}
155 159
    static Arc arcFromId(int id) { return Arc(id);}
156 160

	
157 161
    bool valid(Node n) const {
158 162
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
159 163
        nodes[n.id].prev != -2;
160 164
    }
161 165

	
162 166
    bool valid(Arc a) const {
163 167
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
164 168
        arcs[a.id].prev_in != -2;
165 169
    }
166 170

	
167 171
    Node addNode() {
168 172
      int n;
169 173

	
170 174
      if(first_free_node==-1) {
171 175
        n = nodes.size();
172 176
        nodes.push_back(NodeT());
173 177
      } else {
174 178
        n = first_free_node;
175 179
        first_free_node = nodes[n].next;
176 180
      }
177 181

	
178 182
      nodes[n].next = first_node;
179 183
      if(first_node != -1) nodes[first_node].prev = n;
180 184
      first_node = n;
181 185
      nodes[n].prev = -1;
182 186

	
183 187
      nodes[n].first_in = nodes[n].first_out = -1;
184 188

	
185 189
      return Node(n);
186 190
    }
187 191

	
188 192
    Arc addArc(Node u, Node v) {
189 193
      int n;
190 194

	
191 195
      if (first_free_arc == -1) {
192 196
        n = arcs.size();
193 197
        arcs.push_back(ArcT());
194 198
      } else {
195 199
        n = first_free_arc;
196 200
        first_free_arc = arcs[n].next_in;
197 201
      }
198 202

	
199 203
      arcs[n].source = u.id;
200 204
      arcs[n].target = v.id;
201 205

	
202 206
      arcs[n].next_out = nodes[u.id].first_out;
203 207
      if(nodes[u.id].first_out != -1) {
204 208
        arcs[nodes[u.id].first_out].prev_out = n;
205 209
      }
206 210

	
207 211
      arcs[n].next_in = nodes[v.id].first_in;
208 212
      if(nodes[v.id].first_in != -1) {
209 213
        arcs[nodes[v.id].first_in].prev_in = n;
210 214
      }
211 215

	
212 216
      arcs[n].prev_in = arcs[n].prev_out = -1;
213 217

	
214 218
      nodes[u.id].first_out = nodes[v.id].first_in = n;
215 219

	
216 220
      return Arc(n);
217 221
    }
218 222

	
219 223
    void erase(const Node& node) {
220 224
      int n = node.id;
221 225

	
222 226
      if(nodes[n].next != -1) {
223 227
        nodes[nodes[n].next].prev = nodes[n].prev;
224 228
      }
225 229

	
226 230
      if(nodes[n].prev != -1) {
227 231
        nodes[nodes[n].prev].next = nodes[n].next;
228 232
      } else {
229 233
        first_node = nodes[n].next;
230 234
      }
231 235

	
232 236
      nodes[n].next = first_free_node;
233 237
      first_free_node = n;
234 238
      nodes[n].prev = -2;
235 239

	
236 240
    }
237 241

	
238 242
    void erase(const Arc& arc) {
239 243
      int n = arc.id;
240 244

	
241 245
      if(arcs[n].next_in!=-1) {
242 246
        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
243 247
      }
244 248

	
245 249
      if(arcs[n].prev_in!=-1) {
246 250
        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
247 251
      } else {
248 252
        nodes[arcs[n].target].first_in = arcs[n].next_in;
249 253
      }
250 254

	
251 255

	
252 256
      if(arcs[n].next_out!=-1) {
253 257
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
254 258
      }
255 259

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

	
262 266
      arcs[n].next_in = first_free_arc;
263 267
      first_free_arc = n;
264 268
      arcs[n].prev_in = -2;
265 269
    }
266 270

	
267 271
    void clear() {
268 272
      arcs.clear();
269 273
      nodes.clear();
270 274
      first_node = first_free_node = first_free_arc = -1;
271 275
    }
272 276

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

	
305 309
  };
306 310

	
307 311
  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
308 312

	
309 313
  /// \addtogroup graphs
310 314
  /// @{
311 315

	
312 316
  ///A general directed graph structure.
313 317

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

	
328
  class ListDigraph : public ExtendedListDigraphBase {
329 332
  private:
330
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
331

	
332
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
333
    ///
333
    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
334 334
    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
335
    ///\brief Assignment of ListDigraph to another one is \e not allowed.
336
    ///Use copyDigraph() instead.
337

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

	
343
    typedef ExtendedListDigraphBase Parent;
344

	
345 340
    /// Constructor
346 341

	
347 342
    /// Constructor.
348 343
    ///
349 344
    ListDigraph() {}
350 345

	
351 346
    ///Add a new node to the digraph.
352 347

	
353
    ///Add a new node to the digraph.
354
    ///\return the new node.
348
    ///This function adds a new node to the digraph.
349
    ///\return The new node.
355 350
    Node addNode() { return Parent::addNode(); }
356 351

	
357 352
    ///Add a new arc to the digraph.
358 353

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

	
366 361
    ///\brief Erase a node from the digraph.
367 362
    ///
368
    ///Erase a node from the digraph.
369
    ///
370
    void erase(const Node& n) { Parent::erase(n); }
363
    ///This function erases the given node from the digraph.
364
    void erase(Node n) { Parent::erase(n); }
371 365

	
372 366
    ///\brief Erase an arc from the digraph.
373 367
    ///
374
    ///Erase an arc from the digraph.
375
    ///
376
    void erase(const Arc& a) { Parent::erase(a); }
368
    ///This function erases the given arc from the digraph.
369
    void erase(Arc a) { Parent::erase(a); }
377 370

	
378 371
    /// Node validity check
379 372

	
380
    /// This function gives back true if the given node is valid,
381
    /// ie. it is a real node of the graph.
373
    /// This function gives back \c true if the given node is valid,
374
    /// i.e. it is a real node of the digraph.
382 375
    ///
383
    /// \warning A Node pointing to a removed item
384
    /// could become valid again later if new nodes are
385
    /// added to the graph.
376
    /// \warning A removed node could become valid again if new nodes are
377
    /// added to the digraph.
386 378
    bool valid(Node n) const { return Parent::valid(n); }
387 379

	
388 380
    /// Arc validity check
389 381

	
390
    /// This function gives back true if the given arc is valid,
391
    /// ie. it is a real arc of the graph.
382
    /// This function gives back \c true if the given arc is valid,
383
    /// i.e. it is a real arc of the digraph.
392 384
    ///
393
    /// \warning An Arc pointing to a removed item
394
    /// could become valid again later if new nodes are
395
    /// added to the graph.
385
    /// \warning A removed arc could become valid again if new arcs are
386
    /// added to the digraph.
396 387
    bool valid(Arc a) const { return Parent::valid(a); }
397 388

	
398
    /// Change the target of \c a to \c n
389
    /// Change the target node of an arc
399 390

	
400
    /// Change the target of \c a to \c n
391
    /// This function changes the target node of the given arc \c a to \c n.
401 392
    ///
402
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
403
    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
404
    ///invalidated.
393
    ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
394
    ///arc remain valid, however \c InArcIt iterators are invalidated.
405 395
    ///
406 396
    ///\warning This functionality cannot be used together with the Snapshot
407 397
    ///feature.
408 398
    void changeTarget(Arc a, Node n) {
409 399
      Parent::changeTarget(a,n);
410 400
    }
411
    /// Change the source of \c a to \c n
401
    /// Change the source node of an arc
412 402

	
413
    /// Change the source of \c a to \c n
403
    /// This function changes the source node of the given arc \c a to \c n.
414 404
    ///
415
    ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
416
    ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
417
    ///invalidated.
405
    ///\note \c InArcIt iterators referencing the changed arc remain
406
    ///valid, however \c ArcIt and \c OutArcIt iterators are invalidated.
418 407
    ///
419 408
    ///\warning This functionality cannot be used together with the Snapshot
420 409
    ///feature.
421 410
    void changeSource(Arc a, Node n) {
422 411
      Parent::changeSource(a,n);
423 412
    }
424 413

	
425
    /// Invert the direction of an arc.
414
    /// Reverse the direction of an arc.
426 415

	
427
    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
428
    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
429
    ///invalidated.
416
    /// This function reverses the direction of the given arc.
417
    ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
418
    ///the changed arc are invalidated.
430 419
    ///
431 420
    ///\warning This functionality cannot be used together with the Snapshot
432 421
    ///feature.
433
    void reverseArc(Arc e) {
434
      Node t=target(e);
435
      changeTarget(e,source(e));
436
      changeSource(e,t);
422
    void reverseArc(Arc a) {
423
      Node t=target(a);
424
      changeTarget(a,source(a));
425
      changeSource(a,t);
437 426
    }
438 427

	
439
    /// Reserve memory for nodes.
440

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

	
449
    /// Reserve memory for arcs.
450

	
451
    /// Using this function it is possible to avoid the superfluous memory
452
    /// allocation: if you know that the digraph you want to build will
453
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
454
    /// then it is worth reserving space for this amount before starting
455
    /// to build the digraph.
456
    /// \sa reserveNode
457
    void reserveArc(int m) { arcs.reserve(m); };
458

	
459 428
    ///Contract two nodes.
460 429

	
461
    ///This function contracts two nodes.
462
    ///Node \p b will be removed but instead of deleting
463
    ///incident arcs, they will be joined to \p a.
464
    ///The last parameter \p r controls whether to remove loops. \c true
465
    ///means that loops will be removed.
430
    ///This function contracts the given two nodes.
431
    ///Node \c v is removed, but instead of deleting its
432
    ///incident arcs, they are joined to node \c u.
433
    ///If the last parameter \c r is \c true (this is the default value),
434
    ///then the newly created loops are removed.
466 435
    ///
467
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
468
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
469
    ///may be invalidated.
436
    ///\note The moved arcs are joined to node \c u using changeSource()
437
    ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
438
    ///invalidated for the outgoing arcs of node \c v and \c InArcIt
439
    ///iterators are invalidated for the incomming arcs of \c v.
440
    ///Moreover all iterators referencing node \c v or the removed 
441
    ///loops are also invalidated. Other iterators remain valid.
470 442
    ///
471 443
    ///\warning This functionality cannot be used together with the Snapshot
472 444
    ///feature.
473
    void contract(Node a, Node b, bool r = true)
445
    void contract(Node u, Node v, bool r = true)
474 446
    {
475
      for(OutArcIt e(*this,b);e!=INVALID;) {
447
      for(OutArcIt e(*this,v);e!=INVALID;) {
476 448
        OutArcIt f=e;
477 449
        ++f;
478
        if(r && target(e)==a) erase(e);
479
        else changeSource(e,a);
450
        if(r && target(e)==u) erase(e);
451
        else changeSource(e,u);
480 452
        e=f;
481 453
      }
482
      for(InArcIt e(*this,b);e!=INVALID;) {
454
      for(InArcIt e(*this,v);e!=INVALID;) {
483 455
        InArcIt f=e;
484 456
        ++f;
485
        if(r && source(e)==a) erase(e);
486
        else changeTarget(e,a);
457
        if(r && source(e)==u) erase(e);
458
        else changeTarget(e,u);
487 459
        e=f;
488 460
      }
489
      erase(b);
461
      erase(v);
490 462
    }
491 463

	
492 464
    ///Split a node.
493 465

	
494
    ///This function splits a node. First a new node is added to the digraph,
495
    ///then the source of each outgoing arc of \c n is moved to this new node.
496
    ///If \c connect is \c true (this is the default value), then a new arc
497
    ///from \c n to the newly created node is also added.
466
    ///This function splits the given node. First, a new node is added
467
    ///to the digraph, then the source of each outgoing arc of node \c n
468
    ///is moved to this new node.
469
    ///If the second parameter \c connect is \c true (this is the default
470
    ///value), then a new arc from node \c n to the newly created node
471
    ///is also added.
498 472
    ///\return The newly created node.
499 473
    ///
500
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
501
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
502
    ///be invalidated.
474
    ///\note All iterators remain valid.
503 475
    ///
504
    ///\warning This functionality cannot be used in conjunction with the
476
    ///\warning This functionality cannot be used together with the
505 477
    ///Snapshot feature.
506 478
    Node split(Node n, bool connect = true) {
507 479
      Node b = addNode();
508
      for(OutArcIt e(*this,n);e!=INVALID;) {
509
        OutArcIt f=e;
510
        ++f;
511
        changeSource(e,b);
512
        e=f;
480
      nodes[b.id].first_out=nodes[n.id].first_out;
481
      nodes[n.id].first_out=-1;
482
      for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
483
        arcs[i].source=b.id;
513 484
      }
514 485
      if (connect) addArc(n,b);
515 486
      return b;
516 487
    }
517 488

	
518 489
    ///Split an arc.
519 490

	
520
    ///This function splits an arc. First a new node \c b is added to
521
    ///the digraph, then the original arc is re-targeted to \c
522
    ///b. Finally an arc from \c b to the original target is added.
491
    ///This function splits the given arc. First, a new node \c v is
492
    ///added to the digraph, then the target node of the original arc
493
    ///is set to \c v. Finally, an arc from \c v to the original target
494
    ///is added.
495
    ///\return The newly created node.
523 496
    ///
524
    ///\return The newly created node.
497
    ///\note \c InArcIt iterators referencing the original arc are
498
    ///invalidated. Other iterators remain valid.
525 499
    ///
526 500
    ///\warning This functionality cannot be used together with the
527 501
    ///Snapshot feature.
528
    Node split(Arc e) {
529
      Node b = addNode();
530
      addArc(b,target(e));
531
      changeTarget(e,b);
532
      return b;
502
    Node split(Arc a) {
503
      Node v = addNode();
504
      addArc(v,target(a));
505
      changeTarget(a,v);
506
      return v;
533 507
    }
534 508

	
509
    ///Clear the digraph.
510

	
511
    ///This function erases all nodes and arcs from the digraph.
512
    ///
513
    void clear() {
514
      Parent::clear();
515
    }
516

	
517
    /// Reserve memory for nodes.
518

	
519
    /// Using this function, it is possible to avoid superfluous memory
520
    /// allocation: if you know that the digraph you want to build will
521
    /// be large (e.g. it will contain millions of nodes and/or arcs),
522
    /// then it is worth reserving space for this amount before starting
523
    /// to build the digraph.
524
    /// \sa reserveArc()
525
    void reserveNode(int n) { nodes.reserve(n); };
526

	
527
    /// Reserve memory for arcs.
528

	
529
    /// Using this function, it is possible to avoid superfluous memory
530
    /// allocation: if you know that the digraph you want to build will
531
    /// be large (e.g. it will contain millions of nodes and/or arcs),
532
    /// then it is worth reserving space for this amount before starting
533
    /// to build the digraph.
534
    /// \sa reserveNode()
535
    void reserveArc(int m) { arcs.reserve(m); };
536

	
535 537
    /// \brief Class to make a snapshot of the digraph and restore
536 538
    /// it later.
537 539
    ///
538 540
    /// Class to make a snapshot of the digraph and restore it later.
539 541
    ///
540 542
    /// The newly added nodes and arcs can be removed using the
541 543
    /// restore() function.
542 544
    ///
543
    /// \warning Arc and node deletions and other modifications (e.g.
544
    /// contracting, splitting, reversing arcs or nodes) cannot be
545
    /// \note After a state is restored, you cannot restore a later state, 
546
    /// i.e. you cannot add the removed nodes and arcs again using
547
    /// another Snapshot instance.
548
    ///
549
    /// \warning Node and arc deletions and other modifications (e.g.
550
    /// reversing, contracting, splitting arcs or nodes) cannot be
545 551
    /// restored. These events invalidate the snapshot.
552
    /// However the arcs and nodes that were added to the digraph after
553
    /// making the current snapshot can be removed without invalidating it.
546 554
    class Snapshot {
547 555
    protected:
548 556

	
549 557
      typedef Parent::NodeNotifier NodeNotifier;
550 558

	
551 559
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
552 560
      public:
553 561

	
554 562
        NodeObserverProxy(Snapshot& _snapshot)
555 563
          : snapshot(_snapshot) {}
556 564

	
557 565
        using NodeNotifier::ObserverBase::attach;
558 566
        using NodeNotifier::ObserverBase::detach;
559 567
        using NodeNotifier::ObserverBase::attached;
560 568

	
561 569
      protected:
562 570

	
563 571
        virtual void add(const Node& node) {
564 572
          snapshot.addNode(node);
565 573
        }
566 574
        virtual void add(const std::vector<Node>& nodes) {
567 575
          for (int i = nodes.size() - 1; i >= 0; ++i) {
568 576
            snapshot.addNode(nodes[i]);
569 577
          }
570 578
        }
571 579
        virtual void erase(const Node& node) {
572 580
          snapshot.eraseNode(node);
573 581
        }
574 582
        virtual void erase(const std::vector<Node>& nodes) {
575 583
          for (int i = 0; i < int(nodes.size()); ++i) {
576 584
            snapshot.eraseNode(nodes[i]);
577 585
          }
578 586
        }
579 587
        virtual void build() {
580 588
          Node node;
581 589
          std::vector<Node> nodes;
582 590
          for (notifier()->first(node); node != INVALID;
583 591
               notifier()->next(node)) {
584 592
            nodes.push_back(node);
585 593
          }
586 594
          for (int i = nodes.size() - 1; i >= 0; --i) {
587 595
            snapshot.addNode(nodes[i]);
588 596
          }
589 597
        }
590 598
        virtual void clear() {
591 599
          Node node;
592 600
          for (notifier()->first(node); node != INVALID;
593 601
               notifier()->next(node)) {
594 602
            snapshot.eraseNode(node);
595 603
          }
596 604
        }
597 605

	
598 606
        Snapshot& snapshot;
599 607
      };
600 608

	
601 609
      class ArcObserverProxy : public ArcNotifier::ObserverBase {
602 610
      public:
603 611

	
604 612
        ArcObserverProxy(Snapshot& _snapshot)
605 613
          : snapshot(_snapshot) {}
606 614

	
607 615
        using ArcNotifier::ObserverBase::attach;
608 616
        using ArcNotifier::ObserverBase::detach;
609 617
        using ArcNotifier::ObserverBase::attached;
610 618

	
611 619
      protected:
612 620

	
613 621
        virtual void add(const Arc& arc) {
614 622
          snapshot.addArc(arc);
615 623
        }
616 624
        virtual void add(const std::vector<Arc>& arcs) {
617 625
          for (int i = arcs.size() - 1; i >= 0; ++i) {
618 626
            snapshot.addArc(arcs[i]);
619 627
          }
620 628
        }
621 629
        virtual void erase(const Arc& arc) {
622 630
          snapshot.eraseArc(arc);
623 631
        }
624 632
        virtual void erase(const std::vector<Arc>& arcs) {
625 633
          for (int i = 0; i < int(arcs.size()); ++i) {
626 634
            snapshot.eraseArc(arcs[i]);
627 635
          }
628 636
        }
629 637
        virtual void build() {
630 638
          Arc arc;
631 639
          std::vector<Arc> arcs;
632 640
          for (notifier()->first(arc); arc != INVALID;
633 641
               notifier()->next(arc)) {
634 642
            arcs.push_back(arc);
635 643
          }
636 644
          for (int i = arcs.size() - 1; i >= 0; --i) {
637 645
            snapshot.addArc(arcs[i]);
638 646
          }
639 647
        }
640 648
        virtual void clear() {
641 649
          Arc arc;
642 650
          for (notifier()->first(arc); arc != INVALID;
643 651
               notifier()->next(arc)) {
644 652
            snapshot.eraseArc(arc);
645 653
          }
646 654
        }
647 655

	
648 656
        Snapshot& snapshot;
649 657
      };
650 658

	
651 659
      ListDigraph *digraph;
652 660

	
653 661
      NodeObserverProxy node_observer_proxy;
654 662
      ArcObserverProxy arc_observer_proxy;
655 663

	
656 664
      std::list<Node> added_nodes;
657 665
      std::list<Arc> added_arcs;
658 666

	
659 667

	
660 668
      void addNode(const Node& node) {
661 669
        added_nodes.push_front(node);
662 670
      }
663 671
      void eraseNode(const Node& node) {
664 672
        std::list<Node>::iterator it =
665 673
          std::find(added_nodes.begin(), added_nodes.end(), node);
666 674
        if (it == added_nodes.end()) {
667 675
          clear();
668 676
          arc_observer_proxy.detach();
669 677
          throw NodeNotifier::ImmediateDetach();
670 678
        } else {
671 679
          added_nodes.erase(it);
672 680
        }
673 681
      }
674 682

	
675 683
      void addArc(const Arc& arc) {
676 684
        added_arcs.push_front(arc);
677 685
      }
678 686
      void eraseArc(const Arc& arc) {
679 687
        std::list<Arc>::iterator it =
680 688
          std::find(added_arcs.begin(), added_arcs.end(), arc);
681 689
        if (it == added_arcs.end()) {
682 690
          clear();
683 691
          node_observer_proxy.detach();
684 692
          throw ArcNotifier::ImmediateDetach();
685 693
        } else {
686 694
          added_arcs.erase(it);
687 695
        }
688 696
      }
689 697

	
690 698
      void attach(ListDigraph &_digraph) {
691 699
        digraph = &_digraph;
692 700
        node_observer_proxy.attach(digraph->notifier(Node()));
693 701
        arc_observer_proxy.attach(digraph->notifier(Arc()));
694 702
      }
695 703

	
696 704
      void detach() {
697 705
        node_observer_proxy.detach();
698 706
        arc_observer_proxy.detach();
699 707
      }
700 708

	
701 709
      bool attached() const {
702 710
        return node_observer_proxy.attached();
703 711
      }
704 712

	
705 713
      void clear() {
706 714
        added_nodes.clear();
707 715
        added_arcs.clear();
708 716
      }
709 717

	
710 718
    public:
711 719

	
712 720
      /// \brief Default constructor.
713 721
      ///
714 722
      /// Default constructor.
715
      /// To actually make a snapshot you must call save().
723
      /// You have to call save() to actually make a snapshot.
716 724
      Snapshot()
717 725
        : digraph(0), node_observer_proxy(*this),
718 726
          arc_observer_proxy(*this) {}
719 727

	
720 728
      /// \brief Constructor that immediately makes a snapshot.
721 729
      ///
722
      /// This constructor immediately makes a snapshot of the digraph.
723
      /// \param _digraph The digraph we make a snapshot of.
724
      Snapshot(ListDigraph &_digraph)
730
      /// This constructor immediately makes a snapshot of the given digraph.
731
      Snapshot(ListDigraph &gr)
725 732
        : node_observer_proxy(*this),
726 733
          arc_observer_proxy(*this) {
727
        attach(_digraph);
734
        attach(gr);
728 735
      }
729 736

	
730 737
      /// \brief Make a snapshot.
731 738
      ///
732
      /// Make a snapshot of the digraph.
733
      ///
734
      /// This function can be called more than once. In case of a repeated
739
      /// This function makes a snapshot of the given digraph.
740
      /// It can be called more than once. In case of a repeated
735 741
      /// call, the previous snapshot gets lost.
736
      /// \param _digraph The digraph we make the snapshot of.
737
      void save(ListDigraph &_digraph) {
742
      void save(ListDigraph &gr) {
738 743
        if (attached()) {
739 744
          detach();
740 745
          clear();
741 746
        }
742
        attach(_digraph);
747
        attach(gr);
743 748
      }
744 749

	
745 750
      /// \brief Undo the changes until the last snapshot.
746
      //
747
      /// Undo the changes until the last snapshot created by save().
751
      ///
752
      /// This function undos the changes until the last snapshot
753
      /// created by save() or Snapshot(ListDigraph&).
754
      ///
755
      /// \warning This method invalidates the snapshot, i.e. repeated
756
      /// restoring is not supported unless you call save() again.
748 757
      void restore() {
749 758
        detach();
750 759
        for(std::list<Arc>::iterator it = added_arcs.begin();
751 760
            it != added_arcs.end(); ++it) {
752 761
          digraph->erase(*it);
753 762
        }
754 763
        for(std::list<Node>::iterator it = added_nodes.begin();
755 764
            it != added_nodes.end(); ++it) {
756 765
          digraph->erase(*it);
757 766
        }
758 767
        clear();
759 768
      }
760 769

	
761
      /// \brief Gives back true when the snapshot is valid.
770
      /// \brief Returns \c true if the snapshot is valid.
762 771
      ///
763
      /// Gives back true when the snapshot is valid.
772
      /// This function returns \c true if the snapshot is valid.
764 773
      bool valid() const {
765 774
        return attached();
766 775
      }
767 776
    };
768 777

	
769 778
  };
770 779

	
771 780
  ///@}
772 781

	
773 782
  class ListGraphBase {
774 783

	
775 784
  protected:
776 785

	
777 786
    struct NodeT {
778 787
      int first_out;
779 788
      int prev, next;
780 789
    };
781 790

	
782 791
    struct ArcT {
783 792
      int target;
784 793
      int prev_out, next_out;
785 794
    };
786 795

	
787 796
    std::vector<NodeT> nodes;
788 797

	
789 798
    int first_node;
790 799

	
791 800
    int first_free_node;
792 801

	
793 802
    std::vector<ArcT> arcs;
794 803

	
795 804
    int first_free_arc;
796 805

	
797 806
  public:
798 807

	
799
    typedef ListGraphBase Digraph;
800

	
801
    class Node;
802
    class Arc;
803
    class Edge;
808
    typedef ListGraphBase Graph;
804 809

	
805 810
    class Node {
806 811
      friend class ListGraphBase;
807 812
    protected:
808 813

	
809 814
      int id;
810 815
      explicit Node(int pid) { id = pid;}
811 816

	
812 817
    public:
813 818
      Node() {}
814 819
      Node (Invalid) { id = -1; }
815 820
      bool operator==(const Node& node) const {return id == node.id;}
816 821
      bool operator!=(const Node& node) const {return id != node.id;}
817 822
      bool operator<(const Node& node) const {return id < node.id;}
818 823
    };
819 824

	
820 825
    class Edge {
821 826
      friend class ListGraphBase;
822 827
    protected:
823 828

	
824 829
      int id;
825 830
      explicit Edge(int pid) { id = pid;}
826 831

	
827 832
    public:
828 833
      Edge() {}
829 834
      Edge (Invalid) { id = -1; }
830 835
      bool operator==(const Edge& edge) const {return id == edge.id;}
831 836
      bool operator!=(const Edge& edge) const {return id != edge.id;}
832 837
      bool operator<(const Edge& edge) const {return id < edge.id;}
833 838
    };
834 839

	
835 840
    class Arc {
836 841
      friend class ListGraphBase;
837 842
    protected:
838 843

	
839 844
      int id;
840 845
      explicit Arc(int pid) { id = pid;}
841 846

	
842 847
    public:
843
      operator Edge() const { 
844
        return id != -1 ? edgeFromId(id / 2) : INVALID; 
848
      operator Edge() const {
849
        return id != -1 ? edgeFromId(id / 2) : INVALID;
845 850
      }
846 851

	
847 852
      Arc() {}
848 853
      Arc (Invalid) { id = -1; }
849 854
      bool operator==(const Arc& arc) const {return id == arc.id;}
850 855
      bool operator!=(const Arc& arc) const {return id != arc.id;}
851 856
      bool operator<(const Arc& arc) const {return id < arc.id;}
852 857
    };
853 858

	
854

	
855

	
856 859
    ListGraphBase()
857 860
      : nodes(), first_node(-1),
858 861
        first_free_node(-1), arcs(), first_free_arc(-1) {}
859 862

	
860 863

	
861 864
    int maxNodeId() const { return nodes.size()-1; }
862 865
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
863 866
    int maxArcId() const { return arcs.size()-1; }
864 867

	
865 868
    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
866 869
    Node target(Arc e) const { return Node(arcs[e.id].target); }
867 870

	
868 871
    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
869 872
    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
870 873

	
871 874
    static bool direction(Arc e) {
872 875
      return (e.id & 1) == 1;
873 876
    }
874 877

	
875 878
    static Arc direct(Edge e, bool d) {
876 879
      return Arc(e.id * 2 + (d ? 1 : 0));
877 880
    }
878 881

	
879 882
    void first(Node& node) const {
880 883
      node.id = first_node;
881 884
    }
882 885

	
883 886
    void next(Node& node) const {
884 887
      node.id = nodes[node.id].next;
885 888
    }
886 889

	
887 890
    void first(Arc& e) const {
888 891
      int n = first_node;
889 892
      while (n != -1 && nodes[n].first_out == -1) {
890 893
        n = nodes[n].next;
891 894
      }
892 895
      e.id = (n == -1) ? -1 : nodes[n].first_out;
893 896
    }
894 897

	
895 898
    void next(Arc& e) const {
896 899
      if (arcs[e.id].next_out != -1) {
897 900
        e.id = arcs[e.id].next_out;
898 901
      } else {
899 902
        int n = nodes[arcs[e.id ^ 1].target].next;
900 903
        while(n != -1 && nodes[n].first_out == -1) {
901 904
          n = nodes[n].next;
902 905
        }
903 906
        e.id = (n == -1) ? -1 : nodes[n].first_out;
904 907
      }
905 908
    }
906 909

	
907 910
    void first(Edge& e) const {
908 911
      int n = first_node;
909 912
      while (n != -1) {
910 913
        e.id = nodes[n].first_out;
911 914
        while ((e.id & 1) != 1) {
912 915
          e.id = arcs[e.id].next_out;
913 916
        }
914 917
        if (e.id != -1) {
915 918
          e.id /= 2;
916 919
          return;
917 920
        }
918 921
        n = nodes[n].next;
919 922
      }
920 923
      e.id = -1;
921 924
    }
922 925

	
923 926
    void next(Edge& e) const {
924 927
      int n = arcs[e.id * 2].target;
925 928
      e.id = arcs[(e.id * 2) | 1].next_out;
926 929
      while ((e.id & 1) != 1) {
927 930
        e.id = arcs[e.id].next_out;
928 931
      }
929 932
      if (e.id != -1) {
930 933
        e.id /= 2;
931 934
        return;
932 935
      }
933 936
      n = nodes[n].next;
934 937
      while (n != -1) {
935 938
        e.id = nodes[n].first_out;
936 939
        while ((e.id & 1) != 1) {
937 940
          e.id = arcs[e.id].next_out;
938 941
        }
939 942
        if (e.id != -1) {
940 943
          e.id /= 2;
941 944
          return;
942 945
        }
943 946
        n = nodes[n].next;
944 947
      }
945 948
      e.id = -1;
946 949
    }
947 950

	
948 951
    void firstOut(Arc &e, const Node& v) const {
949 952
      e.id = nodes[v.id].first_out;
950 953
    }
951 954
    void nextOut(Arc &e) const {
952 955
      e.id = arcs[e.id].next_out;
953 956
    }
954 957

	
955 958
    void firstIn(Arc &e, const Node& v) const {
956 959
      e.id = ((nodes[v.id].first_out) ^ 1);
957 960
      if (e.id == -2) e.id = -1;
958 961
    }
959 962
    void nextIn(Arc &e) const {
960 963
      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
961 964
      if (e.id == -2) e.id = -1;
962 965
    }
963 966

	
964 967
    void firstInc(Edge &e, bool& d, const Node& v) const {
965 968
      int a = nodes[v.id].first_out;
966 969
      if (a != -1 ) {
967 970
        e.id = a / 2;
968 971
        d = ((a & 1) == 1);
969 972
      } else {
970 973
        e.id = -1;
971 974
        d = true;
972 975
      }
973 976
    }
974 977
    void nextInc(Edge &e, bool& d) const {
975 978
      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
976 979
      if (a != -1 ) {
977 980
        e.id = a / 2;
978 981
        d = ((a & 1) == 1);
979 982
      } else {
980 983
        e.id = -1;
981 984
        d = true;
982 985
      }
983 986
    }
984 987

	
985 988
    static int id(Node v) { return v.id; }
986 989
    static int id(Arc e) { return e.id; }
987 990
    static int id(Edge e) { return e.id; }
988 991

	
989 992
    static Node nodeFromId(int id) { return Node(id);}
990 993
    static Arc arcFromId(int id) { return Arc(id);}
991 994
    static Edge edgeFromId(int id) { return Edge(id);}
992 995

	
993 996
    bool valid(Node n) const {
994 997
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
995 998
        nodes[n.id].prev != -2;
996 999
    }
997 1000

	
998 1001
    bool valid(Arc a) const {
999 1002
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
1000 1003
        arcs[a.id].prev_out != -2;
1001 1004
    }
1002 1005

	
1003 1006
    bool valid(Edge e) const {
1004 1007
      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
1005 1008
        arcs[2 * e.id].prev_out != -2;
1006 1009
    }
1007 1010

	
1008 1011
    Node addNode() {
1009 1012
      int n;
1010 1013

	
1011 1014
      if(first_free_node==-1) {
1012 1015
        n = nodes.size();
1013 1016
        nodes.push_back(NodeT());
1014 1017
      } else {
1015 1018
        n = first_free_node;
1016 1019
        first_free_node = nodes[n].next;
1017 1020
      }
1018 1021

	
1019 1022
      nodes[n].next = first_node;
1020 1023
      if (first_node != -1) nodes[first_node].prev = n;
1021 1024
      first_node = n;
1022 1025
      nodes[n].prev = -1;
1023 1026

	
1024 1027
      nodes[n].first_out = -1;
1025 1028

	
1026 1029
      return Node(n);
1027 1030
    }
1028 1031

	
1029 1032
    Edge addEdge(Node u, Node v) {
1030 1033
      int n;
1031 1034

	
1032 1035
      if (first_free_arc == -1) {
1033 1036
        n = arcs.size();
1034 1037
        arcs.push_back(ArcT());
1035 1038
        arcs.push_back(ArcT());
1036 1039
      } else {
1037 1040
        n = first_free_arc;
1038 1041
        first_free_arc = arcs[n].next_out;
1039 1042
      }
1040 1043

	
1041 1044
      arcs[n].target = u.id;
1042 1045
      arcs[n | 1].target = v.id;
1043 1046

	
1044 1047
      arcs[n].next_out = nodes[v.id].first_out;
1045 1048
      if (nodes[v.id].first_out != -1) {
1046 1049
        arcs[nodes[v.id].first_out].prev_out = n;
1047 1050
      }
1048 1051
      arcs[n].prev_out = -1;
1049 1052
      nodes[v.id].first_out = n;
1050 1053

	
1051 1054
      arcs[n | 1].next_out = nodes[u.id].first_out;
1052 1055
      if (nodes[u.id].first_out != -1) {
1053 1056
        arcs[nodes[u.id].first_out].prev_out = (n | 1);
1054 1057
      }
1055 1058
      arcs[n | 1].prev_out = -1;
1056 1059
      nodes[u.id].first_out = (n | 1);
1057 1060

	
1058 1061
      return Edge(n / 2);
1059 1062
    }
1060 1063

	
1061 1064
    void erase(const Node& node) {
1062 1065
      int n = node.id;
1063 1066

	
1064 1067
      if(nodes[n].next != -1) {
1065 1068
        nodes[nodes[n].next].prev = nodes[n].prev;
1066 1069
      }
1067 1070

	
1068 1071
      if(nodes[n].prev != -1) {
1069 1072
        nodes[nodes[n].prev].next = nodes[n].next;
1070 1073
      } else {
1071 1074
        first_node = nodes[n].next;
1072 1075
      }
1073 1076

	
1074 1077
      nodes[n].next = first_free_node;
1075 1078
      first_free_node = n;
1076 1079
      nodes[n].prev = -2;
1077 1080
    }
1078 1081

	
1079 1082
    void erase(const Edge& edge) {
1080 1083
      int n = edge.id * 2;
1081 1084

	
1082 1085
      if (arcs[n].next_out != -1) {
1083 1086
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1084 1087
      }
1085 1088

	
1086 1089
      if (arcs[n].prev_out != -1) {
1087 1090
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1088 1091
      } else {
1089 1092
        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1090 1093
      }
1091 1094

	
1092 1095
      if (arcs[n | 1].next_out != -1) {
1093 1096
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1094 1097
      }
1095 1098

	
1096 1099
      if (arcs[n | 1].prev_out != -1) {
1097 1100
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1098 1101
      } else {
1099 1102
        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1100 1103
      }
1101 1104

	
1102 1105
      arcs[n].next_out = first_free_arc;
1103 1106
      first_free_arc = n;
1104 1107
      arcs[n].prev_out = -2;
1105 1108
      arcs[n | 1].prev_out = -2;
1106 1109

	
1107 1110
    }
1108 1111

	
1109 1112
    void clear() {
1110 1113
      arcs.clear();
1111 1114
      nodes.clear();
1112 1115
      first_node = first_free_node = first_free_arc = -1;
1113 1116
    }
1114 1117

	
1115 1118
  protected:
1116 1119

	
1117 1120
    void changeV(Edge e, Node n) {
1118 1121
      if(arcs[2 * e.id].next_out != -1) {
1119 1122
        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1120 1123
      }
1121 1124
      if(arcs[2 * e.id].prev_out != -1) {
1122 1125
        arcs[arcs[2 * e.id].prev_out].next_out =
1123 1126
          arcs[2 * e.id].next_out;
1124 1127
      } else {
1125 1128
        nodes[arcs[(2 * e.id) | 1].target].first_out =
1126 1129
          arcs[2 * e.id].next_out;
1127 1130
      }
1128 1131

	
1129 1132
      if (nodes[n.id].first_out != -1) {
1130 1133
        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1131 1134
      }
1132 1135
      arcs[(2 * e.id) | 1].target = n.id;
1133 1136
      arcs[2 * e.id].prev_out = -1;
1134 1137
      arcs[2 * e.id].next_out = nodes[n.id].first_out;
1135 1138
      nodes[n.id].first_out = 2 * e.id;
1136 1139
    }
1137 1140

	
1138 1141
    void changeU(Edge e, Node n) {
1139 1142
      if(arcs[(2 * e.id) | 1].next_out != -1) {
1140 1143
        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1141 1144
          arcs[(2 * e.id) | 1].prev_out;
1142 1145
      }
1143 1146
      if(arcs[(2 * e.id) | 1].prev_out != -1) {
1144 1147
        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1145 1148
          arcs[(2 * e.id) | 1].next_out;
1146 1149
      } else {
1147 1150
        nodes[arcs[2 * e.id].target].first_out =
1148 1151
          arcs[(2 * e.id) | 1].next_out;
1149 1152
      }
1150 1153

	
1151 1154
      if (nodes[n.id].first_out != -1) {
1152 1155
        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1153 1156
      }
1154 1157
      arcs[2 * e.id].target = n.id;
1155 1158
      arcs[(2 * e.id) | 1].prev_out = -1;
1156 1159
      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1157 1160
      nodes[n.id].first_out = ((2 * e.id) | 1);
1158 1161
    }
1159 1162

	
1160 1163
  };
1161 1164

	
1162 1165
  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1163 1166

	
1164 1167

	
1165 1168
  /// \addtogroup graphs
1166 1169
  /// @{
1167 1170

	
1168 1171
  ///A general undirected graph structure.
1169 1172

	
1170
  ///\ref ListGraph is a simple and fast <em>undirected graph</em>
1171
  ///implementation based on static linked lists that are stored in
1173
  ///\ref ListGraph is a versatile and fast undirected graph
1174
  ///implementation based on linked lists that are stored in
1172 1175
  ///\c std::vector structures.
1173 1176
  ///
1174
  ///It conforms to the \ref concepts::Graph "Graph concept" and it
1175
  ///also provides several useful additional functionalities.
1176
  ///Most of the member functions and nested classes are documented
1177
  ///This type fully conforms to the \ref concepts::Graph "Graph concept"
1178
  ///and it also provides several useful additional functionalities.
1179
  ///Most of its member functions and nested classes are documented
1177 1180
  ///only in the concept class.
1178 1181
  ///
1179
  ///An important extra feature of this graph implementation is that
1180
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1181
  ///
1182 1182
  ///\sa concepts::Graph
1183
  ///\sa ListDigraph
1184
  class ListGraph : public ExtendedListGraphBase {
1185
    typedef ExtendedListGraphBase Parent;
1183 1186

	
1184
  class ListGraph : public ExtendedListGraphBase {
1185 1187
  private:
1186
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1187

	
1188
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1189
    ///
1188
    /// Graphs are \e not copy constructible. Use GraphCopy instead.
1190 1189
    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
1191
    ///\brief Assignment of ListGraph to another one is \e not allowed.
1192
    ///Use copyGraph() instead.
1193

	
1194
    ///Assignment of ListGraph to another one is \e not allowed.
1195
    ///Use copyGraph() instead.
1190
    /// \brief Assignment of a graph to another one is \e not allowed.
1191
    /// Use GraphCopy 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
    /// Add a new node to the graph.
1211
    /// \return the new node.
1204
    /// This function adds a new node to the graph.
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
    /// Add a new edge to the graph with source node \c s
1217
    /// and target node \c t.
1218
    /// \return the new edge.
1219
    Edge addEdge(const Node& s, const Node& t) {
1220
      return Parent::addEdge(s, t);
1210
    /// This function adds a new edge to the graph between nodes
1211
    /// \c u and \c v with inherent orientation from node \c u to
1212
    /// node \c v.
1213
    /// \return The new edge.
1214
    Edge addEdge(Node u, Node v) {
1215
      return Parent::addEdge(u, v);
1221 1216
    }
1222 1217

	
1223
    /// \brief Erase a node from the graph.
1218
    ///\brief Erase a node from the graph.
1224 1219
    ///
1225
    /// Erase a node from the graph.
1220
    /// This function erases the given node from the graph.
1221
    void erase(Node n) { Parent::erase(n); }
1222

	
1223
    ///\brief Erase an edge from the graph.
1226 1224
    ///
1227
    void erase(const Node& n) { Parent::erase(n); }
1228

	
1229
    /// \brief Erase an edge from the graph.
1230
    ///
1231
    /// Erase an edge from the graph.
1232
    ///
1233
    void erase(const Edge& e) { Parent::erase(e); }
1225
    /// This function erases the given edge from the graph.
1226
    void erase(Edge e) { Parent::erase(e); }
1234 1227
    /// Node validity check
1235 1228

	
1236
    /// This function gives back true if the given node is valid,
1237
    /// ie. it is a real node of the graph.
1229
    /// This function gives back \c true if the given node is valid,
1230
    /// i.e. it is a real node of the graph.
1238 1231
    ///
1239
    /// \warning A Node pointing to a removed item
1240
    /// could become valid again later if new nodes are
1232
    /// \warning A removed node could become valid again if new nodes are
1241 1233
    /// added to the graph.
1242 1234
    bool valid(Node n) const { return Parent::valid(n); }
1235
    /// Edge validity check
1236

	
1237
    /// This function gives back \c true if the given edge is valid,
1238
    /// i.e. it is a real edge of the graph.
1239
    ///
1240
    /// \warning A removed edge could become valid again if new edges are
1241
    /// added to the graph.
1242
    bool valid(Edge e) const { return Parent::valid(e); }
1243 1243
    /// Arc validity check
1244 1244

	
1245
    /// This function gives back true if the given arc is valid,
1246
    /// ie. it is a real arc of the graph.
1245
    /// This function gives back \c true if the given arc is valid,
1246
    /// i.e. it is a real arc of the graph.
1247 1247
    ///
1248
    /// \warning An Arc pointing to a removed item
1249
    /// could become valid again later if new edges are
1248
    /// \warning A removed arc could become valid again if new edges are
1250 1249
    /// added to the graph.
1251 1250
    bool valid(Arc a) const { return Parent::valid(a); }
1252
    /// Edge validity check
1253 1251

	
1254
    /// This function gives back true if the given edge is valid,
1255
    /// ie. it is a real arc of the graph.
1252
    /// \brief Change the first node of an edge.
1256 1253
    ///
1257
    /// \warning A Edge pointing to a removed item
1258
    /// could become valid again later if new edges are
1259
    /// added to the graph.
1260
    bool valid(Edge e) const { return Parent::valid(e); }
1261
    /// \brief Change the end \c u of \c e to \c n
1254
    /// This function changes the first node of the given edge \c e to \c n.
1262 1255
    ///
1263
    /// This function changes the end \c u of \c e to node \c n.
1264
    ///
1265
    ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
1266
    ///changed edge are invalidated and if the changed node is the
1267
    ///base node of an iterator then this iterator is also
1268
    ///invalidated.
1256
    ///\note \c EdgeIt and \c ArcIt iterators referencing the
1257
    ///changed edge are invalidated and all other iterators whose
1258
    ///base node is the changed node are also invalidated.
1269 1259
    ///
1270 1260
    ///\warning This functionality cannot be used together with the
1271 1261
    ///Snapshot feature.
1272 1262
    void changeU(Edge e, Node n) {
1273 1263
      Parent::changeU(e,n);
1274 1264
    }
1275
    /// \brief Change the end \c v of \c e to \c n
1265
    /// \brief Change the second node of an edge.
1276 1266
    ///
1277
    /// This function changes the end \c v of \c e to \c n.
1267
    /// This function changes the second node of the given edge \c e to \c n.
1278 1268
    ///
1279
    ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
1280
    ///valid, however <tt>ArcIt</tt>s and if the changed node is the
1281
    ///base node of an iterator then this iterator is invalidated.
1269
    ///\note \c EdgeIt iterators referencing the changed edge remain
1270
    ///valid, however \c ArcIt iterators referencing the changed edge and
1271
    ///all other iterators whose base node is the changed node are also
1272
    ///invalidated.
1282 1273
    ///
1283 1274
    ///\warning This functionality cannot be used together with the
1284 1275
    ///Snapshot feature.
1285 1276
    void changeV(Edge e, Node n) {
1286 1277
      Parent::changeV(e,n);
1287 1278
    }
1279

	
1288 1280
    /// \brief Contract two nodes.
1289 1281
    ///
1290
    /// This function contracts two nodes.
1291
    /// Node \p b will be removed but instead of deleting
1292
    /// its neighboring arcs, they will be joined to \p a.
1293
    /// The last parameter \p r controls whether to remove loops. \c true
1294
    /// means that loops will be removed.
1282
    /// This function contracts the given two nodes.
1283
    /// Node \c b is removed, but instead of deleting
1284
    /// its incident edges, they are joined to node \c a.
1285
    /// If the last parameter \c r is \c true (this is the default value),
1286
    /// then the newly created loops are removed.
1295 1287
    ///
1296
    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
1297
    /// valid.
1288
    /// \note The moved edges are joined to node \c a using changeU()
1289
    /// or changeV(), thus all edge and arc iterators whose base node is
1290
    /// \c b are invalidated.
1291
    /// Moreover all iterators referencing node \c b or the removed 
1292
    /// loops are also invalidated. Other iterators remain valid.
1298 1293
    ///
1299 1294
    ///\warning This functionality cannot be used together with the
1300 1295
    ///Snapshot feature.
1301 1296
    void contract(Node a, Node b, bool r = true) {
1302 1297
      for(IncEdgeIt e(*this, b); e!=INVALID;) {
1303 1298
        IncEdgeIt f = e; ++f;
1304 1299
        if (r && runningNode(e) == a) {
1305 1300
          erase(e);
1306 1301
        } else if (u(e) == b) {
1307 1302
          changeU(e, a);
1308 1303
        } else {
1309 1304
          changeV(e, a);
1310 1305
        }
1311 1306
        e = f;
1312 1307
      }
1313 1308
      erase(b);
1314 1309
    }
1315 1310

	
1311
    ///Clear the graph.
1312

	
1313
    ///This function erases all nodes and arcs from the graph.
1314
    ///
1315
    void clear() {
1316
      Parent::clear();
1317
    }
1318

	
1319
    /// Reserve memory for nodes.
1320

	
1321
    /// Using this function, it is possible to avoid superfluous memory
1322
    /// allocation: if you know that the graph you want to build will
1323
    /// be large (e.g. it will contain millions of nodes and/or edges),
1324
    /// then it is worth reserving space for this amount before starting
1325
    /// to build the graph.
1326
    /// \sa reserveEdge()
1327
    void reserveNode(int n) { nodes.reserve(n); };
1328

	
1329
    /// Reserve memory for edges.
1330

	
1331
    /// Using this function, it is possible to avoid superfluous memory
1332
    /// allocation: if you know that the graph you want to build will
1333
    /// be large (e.g. it will contain millions of nodes and/or edges),
1334
    /// then it is worth reserving space for this amount before starting
1335
    /// to build the graph.
1336
    /// \sa reserveNode()
1337
    void reserveEdge(int m) { arcs.reserve(2 * m); };
1316 1338

	
1317 1339
    /// \brief Class to make a snapshot of the graph and restore
1318 1340
    /// it later.
1319 1341
    ///
1320 1342
    /// Class to make a snapshot of the graph and restore it later.
1321 1343
    ///
1322 1344
    /// The newly added nodes and edges can be removed
1323 1345
    /// using the restore() function.
1324 1346
    ///
1325
    /// \warning Edge and node deletions and other modifications
1326
    /// (e.g. changing nodes of edges, contracting nodes) cannot be
1327
    /// restored. These events invalidate the snapshot.
1347
    /// \note After a state is restored, you cannot restore a later state, 
1348
    /// i.e. you cannot add the removed nodes and edges again using
1349
    /// another Snapshot instance.
1350
    ///
1351
    /// \warning Node and edge deletions and other modifications
1352
    /// (e.g. changing the end-nodes of edges or contracting nodes)
1353
    /// cannot be restored. These events invalidate the snapshot.
1354
    /// However the edges and nodes that were added to the graph after
1355
    /// making the current snapshot can be removed without invalidating it.
1328 1356
    class Snapshot {
1329 1357
    protected:
1330 1358

	
1331 1359
      typedef Parent::NodeNotifier NodeNotifier;
1332 1360

	
1333 1361
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
1334 1362
      public:
1335 1363

	
1336 1364
        NodeObserverProxy(Snapshot& _snapshot)
1337 1365
          : snapshot(_snapshot) {}
1338 1366

	
1339 1367
        using NodeNotifier::ObserverBase::attach;
1340 1368
        using NodeNotifier::ObserverBase::detach;
1341 1369
        using NodeNotifier::ObserverBase::attached;
1342 1370

	
1343 1371
      protected:
1344 1372

	
1345 1373
        virtual void add(const Node& node) {
1346 1374
          snapshot.addNode(node);
1347 1375
        }
1348 1376
        virtual void add(const std::vector<Node>& nodes) {
1349 1377
          for (int i = nodes.size() - 1; i >= 0; ++i) {
1350 1378
            snapshot.addNode(nodes[i]);
1351 1379
          }
1352 1380
        }
1353 1381
        virtual void erase(const Node& node) {
1354 1382
          snapshot.eraseNode(node);
1355 1383
        }
1356 1384
        virtual void erase(const std::vector<Node>& nodes) {
1357 1385
          for (int i = 0; i < int(nodes.size()); ++i) {
1358 1386
            snapshot.eraseNode(nodes[i]);
1359 1387
          }
1360 1388
        }
1361 1389
        virtual void build() {
1362 1390
          Node node;
1363 1391
          std::vector<Node> nodes;
1364 1392
          for (notifier()->first(node); node != INVALID;
1365 1393
               notifier()->next(node)) {
1366 1394
            nodes.push_back(node);
1367 1395
          }
1368 1396
          for (int i = nodes.size() - 1; i >= 0; --i) {
1369 1397
            snapshot.addNode(nodes[i]);
1370 1398
          }
1371 1399
        }
1372 1400
        virtual void clear() {
1373 1401
          Node node;
1374 1402
          for (notifier()->first(node); node != INVALID;
1375 1403
               notifier()->next(node)) {
1376 1404
            snapshot.eraseNode(node);
1377 1405
          }
1378 1406
        }
1379 1407

	
1380 1408
        Snapshot& snapshot;
1381 1409
      };
1382 1410

	
1383 1411
      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1384 1412
      public:
1385 1413

	
1386 1414
        EdgeObserverProxy(Snapshot& _snapshot)
1387 1415
          : snapshot(_snapshot) {}
1388 1416

	
1389 1417
        using EdgeNotifier::ObserverBase::attach;
1390 1418
        using EdgeNotifier::ObserverBase::detach;
1391 1419
        using EdgeNotifier::ObserverBase::attached;
1392 1420

	
1393 1421
      protected:
1394 1422

	
1395 1423
        virtual void add(const Edge& edge) {
1396 1424
          snapshot.addEdge(edge);
1397 1425
        }
1398 1426
        virtual void add(const std::vector<Edge>& edges) {
1399 1427
          for (int i = edges.size() - 1; i >= 0; ++i) {
1400 1428
            snapshot.addEdge(edges[i]);
1401 1429
          }
1402 1430
        }
1403 1431
        virtual void erase(const Edge& edge) {
1404 1432
          snapshot.eraseEdge(edge);
1405 1433
        }
1406 1434
        virtual void erase(const std::vector<Edge>& edges) {
1407 1435
          for (int i = 0; i < int(edges.size()); ++i) {
1408 1436
            snapshot.eraseEdge(edges[i]);
1409 1437
          }
1410 1438
        }
1411 1439
        virtual void build() {
1412 1440
          Edge edge;
1413 1441
          std::vector<Edge> edges;
1414 1442
          for (notifier()->first(edge); edge != INVALID;
1415 1443
               notifier()->next(edge)) {
1416 1444
            edges.push_back(edge);
1417 1445
          }
1418 1446
          for (int i = edges.size() - 1; i >= 0; --i) {
1419 1447
            snapshot.addEdge(edges[i]);
1420 1448
          }
1421 1449
        }
1422 1450
        virtual void clear() {
1423 1451
          Edge edge;
1424 1452
          for (notifier()->first(edge); edge != INVALID;
1425 1453
               notifier()->next(edge)) {
1426 1454
            snapshot.eraseEdge(edge);
1427 1455
          }
1428 1456
        }
1429 1457

	
1430 1458
        Snapshot& snapshot;
1431 1459
      };
1432 1460

	
1433 1461
      ListGraph *graph;
1434 1462

	
1435 1463
      NodeObserverProxy node_observer_proxy;
1436 1464
      EdgeObserverProxy edge_observer_proxy;
1437 1465

	
1438 1466
      std::list<Node> added_nodes;
1439 1467
      std::list<Edge> added_edges;
1440 1468

	
1441 1469

	
1442 1470
      void addNode(const Node& node) {
1443 1471
        added_nodes.push_front(node);
1444 1472
      }
1445 1473
      void eraseNode(const Node& node) {
1446 1474
        std::list<Node>::iterator it =
1447 1475
          std::find(added_nodes.begin(), added_nodes.end(), node);
1448 1476
        if (it == added_nodes.end()) {
1449 1477
          clear();
1450 1478
          edge_observer_proxy.detach();
1451 1479
          throw NodeNotifier::ImmediateDetach();
1452 1480
        } else {
1453 1481
          added_nodes.erase(it);
1454 1482
        }
1455 1483
      }
1456 1484

	
1457 1485
      void addEdge(const Edge& edge) {
1458 1486
        added_edges.push_front(edge);
1459 1487
      }
1460 1488
      void eraseEdge(const Edge& edge) {
1461 1489
        std::list<Edge>::iterator it =
1462 1490
          std::find(added_edges.begin(), added_edges.end(), edge);
1463 1491
        if (it == added_edges.end()) {
1464 1492
          clear();
1465 1493
          node_observer_proxy.detach();
1466 1494
          throw EdgeNotifier::ImmediateDetach();
1467 1495
        } else {
1468 1496
          added_edges.erase(it);
1469 1497
        }
1470 1498
      }
1471 1499

	
1472 1500
      void attach(ListGraph &_graph) {
1473 1501
        graph = &_graph;
1474 1502
        node_observer_proxy.attach(graph->notifier(Node()));
1475 1503
        edge_observer_proxy.attach(graph->notifier(Edge()));
1476 1504
      }
1477 1505

	
1478 1506
      void detach() {
1479 1507
        node_observer_proxy.detach();
1480 1508
        edge_observer_proxy.detach();
1481 1509
      }
1482 1510

	
1483 1511
      bool attached() const {
1484 1512
        return node_observer_proxy.attached();
1485 1513
      }
1486 1514

	
1487 1515
      void clear() {
1488 1516
        added_nodes.clear();
1489 1517
        added_edges.clear();
1490 1518
      }
1491 1519

	
1492 1520
    public:
1493 1521

	
1494 1522
      /// \brief Default constructor.
1495 1523
      ///
1496 1524
      /// Default constructor.
1497
      /// To actually make a snapshot you must call save().
1525
      /// You have to call save() to actually make a snapshot.
1498 1526
      Snapshot()
1499 1527
        : graph(0), node_observer_proxy(*this),
1500 1528
          edge_observer_proxy(*this) {}
1501 1529

	
1502 1530
      /// \brief Constructor that immediately makes a snapshot.
1503 1531
      ///
1504
      /// This constructor immediately makes a snapshot of the graph.
1505
      /// \param _graph The graph we make a snapshot of.
1506
      Snapshot(ListGraph &_graph)
1532
      /// This constructor immediately makes a snapshot of the given graph.
1533
      Snapshot(ListGraph &gr)
1507 1534
        : node_observer_proxy(*this),
1508 1535
          edge_observer_proxy(*this) {
1509
        attach(_graph);
1536
        attach(gr);
1510 1537
      }
1511 1538

	
1512 1539
      /// \brief Make a snapshot.
1513 1540
      ///
1514
      /// Make a snapshot of the graph.
1515
      ///
1516
      /// This function can be called more than once. In case of a repeated
1541
      /// This function makes a snapshot of the given graph.
1542
      /// It can be called more than once. In case of a repeated
1517 1543
      /// call, the previous snapshot gets lost.
1518
      /// \param _graph The graph we make the snapshot of.
1519
      void save(ListGraph &_graph) {
1544
      void save(ListGraph &gr) {
1520 1545
        if (attached()) {
1521 1546
          detach();
1522 1547
          clear();
1523 1548
        }
1524
        attach(_graph);
1549
        attach(gr);
1525 1550
      }
1526 1551

	
1527 1552
      /// \brief Undo the changes until the last snapshot.
1528
      //
1529
      /// Undo the changes until the last snapshot created by save().
1553
      ///
1554
      /// This function undos the changes until the last snapshot
1555
      /// created by save() or Snapshot(ListGraph&).
1556
      ///
1557
      /// \warning This method invalidates the snapshot, i.e. repeated
1558
      /// restoring is not supported unless you call save() again.
1530 1559
      void restore() {
1531 1560
        detach();
1532 1561
        for(std::list<Edge>::iterator it = added_edges.begin();
1533 1562
            it != added_edges.end(); ++it) {
1534 1563
          graph->erase(*it);
1535 1564
        }
1536 1565
        for(std::list<Node>::iterator it = added_nodes.begin();
1537 1566
            it != added_nodes.end(); ++it) {
1538 1567
          graph->erase(*it);
1539 1568
        }
1540 1569
        clear();
1541 1570
      }
1542 1571

	
1543
      /// \brief Gives back true when the snapshot is valid.
1572
      /// \brief Returns \c true if the snapshot is valid.
1544 1573
      ///
1545
      /// Gives back true when the snapshot is valid.
1574
      /// This function returns \c true if the snapshot is valid.
1546 1575
      bool valid() const {
1547 1576
        return attached();
1548 1577
      }
1549 1578
    };
1550 1579
  };
1551 1580

	
1552 1581
  /// @}
1553 1582
} //namespace lemon
1554 1583

	
1555 1584

	
1556 1585
#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
#include <map>
25 26

	
26 27
#include <lemon/core.h>
27 28

	
28 29
///\file
29 30
///\ingroup maps
30 31
///\brief Miscellaneous property maps
31 32

	
32
#include <map>
33

	
34 33
namespace lemon {
35 34

	
36 35
  /// \addtogroup maps
37 36
  /// @{
38 37

	
39 38
  /// Base class of maps.
40 39

	
41 40
  /// Base class of maps. It provides the necessary type definitions
42 41
  /// required by the map %concepts.
43 42
  template<typename K, typename V>
44 43
  class MapBase {
45 44
  public:
46 45
    /// \brief The key type of the map.
47 46
    typedef K Key;
48 47
    /// \brief The value type of the map.
49 48
    /// (The type of objects associated with the keys).
50 49
    typedef V Value;
51 50
  };
52 51

	
53 52

	
54 53
  /// Null map. (a.k.a. DoNothingMap)
55 54

	
56 55
  /// This map can be used if you have to provide a map only for
57 56
  /// its type definitions, or if you have to provide a writable map,
58 57
  /// but data written to it is not required (i.e. it will be sent to
59 58
  /// <tt>/dev/null</tt>).
60
  /// It conforms the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
59
  /// It conforms to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
61 60
  ///
62 61
  /// \sa ConstMap
63 62
  template<typename K, typename V>
64 63
  class NullMap : public MapBase<K, V> {
65 64
  public:
66
    typedef MapBase<K, V> Parent;
67
    typedef typename Parent::Key Key;
68
    typedef typename Parent::Value Value;
65
    ///\e
66
    typedef K Key;
67
    ///\e
68
    typedef V Value;
69 69

	
70 70
    /// Gives back a default constructed element.
71 71
    Value operator[](const Key&) const { return Value(); }
72 72
    /// Absorbs the value.
73 73
    void set(const Key&, const Value&) {}
74 74
  };
75 75

	
76 76
  /// Returns a \c NullMap class
77 77

	
78 78
  /// This function just returns a \c NullMap class.
79 79
  /// \relates NullMap
80 80
  template <typename K, typename V>
81 81
  NullMap<K, V> nullMap() {
82 82
    return NullMap<K, V>();
83 83
  }
84 84

	
85 85

	
86 86
  /// Constant map.
87 87

	
88 88
  /// This \ref concepts::ReadMap "readable map" assigns a specified
89 89
  /// value to each key.
90 90
  ///
91 91
  /// In other aspects it is equivalent to \c NullMap.
92
  /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
92
  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
93 93
  /// concept, but it absorbs the data written to it.
94 94
  ///
95 95
  /// The simplest way of using this map is through the constMap()
96 96
  /// function.
97 97
  ///
98 98
  /// \sa NullMap
99 99
  /// \sa IdentityMap
100 100
  template<typename K, typename V>
101 101
  class ConstMap : public MapBase<K, V> {
102 102
  private:
103 103
    V _value;
104 104
  public:
105
    typedef MapBase<K, V> Parent;
106
    typedef typename Parent::Key Key;
107
    typedef typename Parent::Value Value;
105
    ///\e
106
    typedef K Key;
107
    ///\e
108
    typedef V Value;
108 109

	
109 110
    /// Default constructor
110 111

	
111 112
    /// Default constructor.
112 113
    /// The value of the map will be default constructed.
113 114
    ConstMap() {}
114 115

	
115 116
    /// Constructor with specified initial value
116 117

	
117 118
    /// Constructor with specified initial value.
118 119
    /// \param v The initial value of the map.
119 120
    ConstMap(const Value &v) : _value(v) {}
120 121

	
121 122
    /// Gives back the specified value.
122 123
    Value operator[](const Key&) const { return _value; }
123 124

	
124 125
    /// Absorbs the value.
125 126
    void set(const Key&, const Value&) {}
126 127

	
127 128
    /// Sets the value that is assigned to each key.
128 129
    void setAll(const Value &v) {
129 130
      _value = v;
130 131
    }
131 132

	
132 133
    template<typename V1>
133 134
    ConstMap(const ConstMap<K, V1> &, const Value &v) : _value(v) {}
134 135
  };
135 136

	
136 137
  /// Returns a \c ConstMap class
137 138

	
138 139
  /// This function just returns a \c ConstMap class.
139 140
  /// \relates ConstMap
140 141
  template<typename K, typename V>
141 142
  inline ConstMap<K, V> constMap(const V &v) {
142 143
    return ConstMap<K, V>(v);
143 144
  }
144 145

	
145 146
  template<typename K, typename V>
146 147
  inline ConstMap<K, V> constMap() {
147 148
    return ConstMap<K, V>();
148 149
  }
149 150

	
150 151

	
151 152
  template<typename T, T v>
152 153
  struct Const {};
153 154

	
154 155
  /// Constant map with inlined constant value.
155 156

	
156 157
  /// This \ref concepts::ReadMap "readable map" assigns a specified
157 158
  /// value to each key.
158 159
  ///
159 160
  /// In other aspects it is equivalent to \c NullMap.
160
  /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
161
  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
161 162
  /// concept, but it absorbs the data written to it.
162 163
  ///
163 164
  /// The simplest way of using this map is through the constMap()
164 165
  /// function.
165 166
  ///
166 167
  /// \sa NullMap
167 168
  /// \sa IdentityMap
168 169
  template<typename K, typename V, V v>
169 170
  class ConstMap<K, Const<V, v> > : public MapBase<K, V> {
170 171
  public:
171
    typedef MapBase<K, V> Parent;
172
    typedef typename Parent::Key Key;
173
    typedef typename Parent::Value Value;
172
    ///\e
173
    typedef K Key;
174
    ///\e
175
    typedef V Value;
174 176

	
175 177
    /// Constructor.
176 178
    ConstMap() {}
177 179

	
178 180
    /// Gives back the specified value.
179 181
    Value operator[](const Key&) const { return v; }
180 182

	
181 183
    /// Absorbs the value.
182 184
    void set(const Key&, const Value&) {}
183 185
  };
184 186

	
185 187
  /// Returns a \c ConstMap class with inlined constant value
186 188

	
187 189
  /// This function just returns a \c ConstMap class with inlined
188 190
  /// constant value.
189 191
  /// \relates ConstMap
190 192
  template<typename K, typename V, V v>
191 193
  inline ConstMap<K, Const<V, v> > constMap() {
192 194
    return ConstMap<K, Const<V, v> >();
193 195
  }
194 196

	
195 197

	
196 198
  /// Identity map.
197 199

	
198 200
  /// This \ref concepts::ReadMap "read-only map" gives back the given
199 201
  /// key as value without any modification.
200 202
  ///
201 203
  /// \sa ConstMap
202 204
  template <typename T>
203 205
  class IdentityMap : public MapBase<T, T> {
204 206
  public:
205
    typedef MapBase<T, T> Parent;
206
    typedef typename Parent::Key Key;
207
    typedef typename Parent::Value Value;
207
    ///\e
208
    typedef T Key;
209
    ///\e
210
    typedef T Value;
208 211

	
209 212
    /// Gives back the given value without any modification.
210 213
    Value operator[](const Key &k) const {
211 214
      return k;
212 215
    }
213 216
  };
214 217

	
215 218
  /// Returns an \c IdentityMap class
216 219

	
217 220
  /// This function just returns an \c IdentityMap class.
218 221
  /// \relates IdentityMap
219 222
  template<typename T>
220 223
  inline IdentityMap<T> identityMap() {
221 224
    return IdentityMap<T>();
222 225
  }
223 226

	
224 227

	
225 228
  /// \brief Map for storing values for integer keys from the range
226 229
  /// <tt>[0..size-1]</tt>.
227 230
  ///
228 231
  /// This map is essentially a wrapper for \c std::vector. It assigns
229 232
  /// values to integer keys from the range <tt>[0..size-1]</tt>.
230 233
  /// It can be used with some data structures, for example
231 234
  /// \c UnionFind, \c BinHeap, when the used items are small
232
  /// integers. This map conforms the \ref concepts::ReferenceMap
235
  /// integers. This map conforms to the \ref concepts::ReferenceMap
233 236
  /// "ReferenceMap" concept.
234 237
  ///
235 238
  /// The simplest way of using this map is through the rangeMap()
236 239
  /// function.
237 240
  template <typename V>
238 241
  class RangeMap : public MapBase<int, V> {
239 242
    template <typename V1>
240 243
    friend class RangeMap;
241 244
  private:
242 245

	
243 246
    typedef std::vector<V> Vector;
244 247
    Vector _vector;
245 248

	
246 249
  public:
247 250

	
248
    typedef MapBase<int, V> Parent;
249 251
    /// Key type
250
    typedef typename Parent::Key Key;
252
    typedef int Key;
251 253
    /// Value type
252
    typedef typename Parent::Value Value;
254
    typedef V Value;
253 255
    /// Reference type
254 256
    typedef typename Vector::reference Reference;
255 257
    /// Const reference type
256 258
    typedef typename Vector::const_reference ConstReference;
257 259

	
258 260
    typedef True ReferenceMapTag;
259 261

	
260 262
  public:
261 263

	
262 264
    /// Constructor with specified default value.
263 265
    RangeMap(int size = 0, const Value &value = Value())
264 266
      : _vector(size, value) {}
265 267

	
266 268
    /// Constructs the map from an appropriate \c std::vector.
267 269
    template <typename V1>
268 270
    RangeMap(const std::vector<V1>& vector)
269 271
      : _vector(vector.begin(), vector.end()) {}
270 272

	
271 273
    /// Constructs the map from another \c RangeMap.
272 274
    template <typename V1>
273 275
    RangeMap(const RangeMap<V1> &c)
274 276
      : _vector(c._vector.begin(), c._vector.end()) {}
275 277

	
276 278
    /// Returns the size of the map.
277 279
    int size() {
278 280
      return _vector.size();
279 281
    }
280 282

	
281 283
    /// Resizes the map.
282 284

	
283 285
    /// Resizes the underlying \c std::vector container, so changes the
284 286
    /// keyset of the map.
285 287
    /// \param size The new size of the map. The new keyset will be the
286 288
    /// range <tt>[0..size-1]</tt>.
287 289
    /// \param value The default value to assign to the new keys.
288 290
    void resize(int size, const Value &value = Value()) {
289 291
      _vector.resize(size, value);
290 292
    }
291 293

	
292 294
  private:
293 295

	
294 296
    RangeMap& operator=(const RangeMap&);
295 297

	
296 298
  public:
297 299

	
298 300
    ///\e
299 301
    Reference operator[](const Key &k) {
300 302
      return _vector[k];
301 303
    }
302 304

	
303 305
    ///\e
304 306
    ConstReference operator[](const Key &k) const {
305 307
      return _vector[k];
306 308
    }
307 309

	
308 310
    ///\e
309 311
    void set(const Key &k, const Value &v) {
310 312
      _vector[k] = v;
311 313
    }
312 314
  };
313 315

	
314 316
  /// Returns a \c RangeMap class
315 317

	
316 318
  /// This function just returns a \c RangeMap class.
317 319
  /// \relates RangeMap
318 320
  template<typename V>
319 321
  inline RangeMap<V> rangeMap(int size = 0, const V &value = V()) {
320 322
    return RangeMap<V>(size, value);
321 323
  }
322 324

	
323 325
  /// \brief Returns a \c RangeMap class created from an appropriate
324 326
  /// \c std::vector
325 327

	
326 328
  /// This function just returns a \c RangeMap class created from an
327 329
  /// appropriate \c std::vector.
328 330
  /// \relates RangeMap
329 331
  template<typename V>
330 332
  inline RangeMap<V> rangeMap(const std::vector<V> &vector) {
331 333
    return RangeMap<V>(vector);
332 334
  }
333 335

	
334 336

	
335 337
  /// Map type based on \c std::map
336 338

	
337 339
  /// This map is essentially a wrapper for \c std::map with addition
338 340
  /// that you can specify a default value for the keys that are not
339 341
  /// stored actually. This value can be different from the default
340 342
  /// contructed value (i.e. \c %Value()).
341
  /// This type conforms the \ref concepts::ReferenceMap "ReferenceMap"
343
  /// This type conforms to the \ref concepts::ReferenceMap "ReferenceMap"
342 344
  /// concept.
343 345
  ///
344 346
  /// This map is useful if a default value should be assigned to most of
345 347
  /// the keys and different values should be assigned only to a few
346 348
  /// keys (i.e. the map is "sparse").
347 349
  /// The name of this type also refers to this important usage.
348 350
  ///
349 351
  /// Apart form that this map can be used in many other cases since it
350 352
  /// is based on \c std::map, which is a general associative container.
351 353
  /// However keep in mind that it is usually not as efficient as other
352 354
  /// maps.
353 355
  ///
354 356
  /// The simplest way of using this map is through the sparseMap()
355 357
  /// function.
356
  template <typename K, typename V, typename Compare = std::less<K> >
358
  template <typename K, typename V, typename Comp = std::less<K> >
357 359
  class SparseMap : public MapBase<K, V> {
358 360
    template <typename K1, typename V1, typename C1>
359 361
    friend class SparseMap;
360 362
  public:
361 363

	
362
    typedef MapBase<K, V> Parent;
363 364
    /// Key type
364
    typedef typename Parent::Key Key;
365
    typedef K Key;
365 366
    /// Value type
366
    typedef typename Parent::Value Value;
367
    typedef V Value;
367 368
    /// Reference type
368 369
    typedef Value& Reference;
369 370
    /// Const reference type
370 371
    typedef const Value& ConstReference;
371 372

	
372 373
    typedef True ReferenceMapTag;
373 374

	
374 375
  private:
375 376

	
376
    typedef std::map<K, V, Compare> Map;
377
    typedef std::map<K, V, Comp> Map;
377 378
    Map _map;
378 379
    Value _value;
379 380

	
380 381
  public:
381 382

	
382 383
    /// \brief Constructor with specified default value.
383 384
    SparseMap(const Value &value = Value()) : _value(value) {}
384 385
    /// \brief Constructs the map from an appropriate \c std::map, and
385 386
    /// explicitly specifies a default value.
386 387
    template <typename V1, typename Comp1>
387 388
    SparseMap(const std::map<Key, V1, Comp1> &map,
388 389
              const Value &value = Value())
389 390
      : _map(map.begin(), map.end()), _value(value) {}
390 391

	
391 392
    /// \brief Constructs the map from another \c SparseMap.
392 393
    template<typename V1, typename Comp1>
393 394
    SparseMap(const SparseMap<Key, V1, Comp1> &c)
394 395
      : _map(c._map.begin(), c._map.end()), _value(c._value) {}
395 396

	
396 397
  private:
397 398

	
398 399
    SparseMap& operator=(const SparseMap&);
399 400

	
400 401
  public:
401 402

	
402 403
    ///\e
403 404
    Reference operator[](const Key &k) {
404 405
      typename Map::iterator it = _map.lower_bound(k);
405 406
      if (it != _map.end() && !_map.key_comp()(k, it->first))
406 407
        return it->second;
407 408
      else
408 409
        return _map.insert(it, std::make_pair(k, _value))->second;
409 410
    }
410 411

	
411 412
    ///\e
412 413
    ConstReference operator[](const Key &k) const {
413 414
      typename Map::const_iterator it = _map.find(k);
414 415
      if (it != _map.end())
415 416
        return it->second;
416 417
      else
417 418
        return _value;
418 419
    }
419 420

	
420 421
    ///\e
421 422
    void set(const Key &k, const Value &v) {
422 423
      typename Map::iterator it = _map.lower_bound(k);
423 424
      if (it != _map.end() && !_map.key_comp()(k, it->first))
424 425
        it->second = v;
425 426
      else
426 427
        _map.insert(it, std::make_pair(k, v));
427 428
    }
428 429

	
429 430
    ///\e
430 431
    void setAll(const Value &v) {
431 432
      _value = v;
432 433
      _map.clear();
433 434
    }
434 435
  };
435 436

	
436 437
  /// Returns a \c SparseMap class
437 438

	
438 439
  /// This function just returns a \c SparseMap class with specified
439 440
  /// default value.
440 441
  /// \relates SparseMap
441 442
  template<typename K, typename V, typename Compare>
442 443
  inline SparseMap<K, V, Compare> sparseMap(const V& value = V()) {
443 444
    return SparseMap<K, V, Compare>(value);
444 445
  }
445 446

	
446 447
  template<typename K, typename V>
447 448
  inline SparseMap<K, V, std::less<K> > sparseMap(const V& value = V()) {
448 449
    return SparseMap<K, V, std::less<K> >(value);
449 450
  }
450 451

	
451 452
  /// \brief Returns a \c SparseMap class created from an appropriate
452 453
  /// \c std::map
453 454

	
454 455
  /// This function just returns a \c SparseMap class created from an
455 456
  /// appropriate \c std::map.
456 457
  /// \relates SparseMap
457 458
  template<typename K, typename V, typename Compare>
458 459
  inline SparseMap<K, V, Compare>
459 460
    sparseMap(const std::map<K, V, Compare> &map, const V& value = V())
460 461
  {
461 462
    return SparseMap<K, V, Compare>(map, value);
462 463
  }
463 464

	
464 465
  /// @}
465 466

	
466 467
  /// \addtogroup map_adaptors
467 468
  /// @{
468 469

	
469 470
  /// Composition of two maps
470 471

	
471 472
  /// This \ref concepts::ReadMap "read-only map" returns the
472 473
  /// composition of two given maps. That is to say, if \c m1 is of
473 474
  /// type \c M1 and \c m2 is of \c M2, then for
474 475
  /// \code
475 476
  ///   ComposeMap<M1, M2> cm(m1,m2);
476 477
  /// \endcode
477 478
  /// <tt>cm[x]</tt> will be equal to <tt>m1[m2[x]]</tt>.
478 479
  ///
479 480
  /// The \c Key type of the map is inherited from \c M2 and the
480 481
  /// \c Value type is from \c M1.
481 482
  /// \c M2::Value must be convertible to \c M1::Key.
482 483
  ///
483 484
  /// The simplest way of using this map is through the composeMap()
484 485
  /// function.
485 486
  ///
486 487
  /// \sa CombineMap
487 488
  template <typename M1, typename M2>
488 489
  class ComposeMap : public MapBase<typename M2::Key, typename M1::Value> {
489 490
    const M1 &_m1;
490 491
    const M2 &_m2;
491 492
  public:
492
    typedef MapBase<typename M2::Key, typename M1::Value> Parent;
493
    typedef typename Parent::Key Key;
494
    typedef typename Parent::Value Value;
493
    ///\e
494
    typedef typename M2::Key Key;
495
    ///\e
496
    typedef typename M1::Value Value;
495 497

	
496 498
    /// Constructor
497 499
    ComposeMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
498 500

	
499
    /// \e
501
    ///\e
500 502
    typename MapTraits<M1>::ConstReturnValue
501 503
    operator[](const Key &k) const { return _m1[_m2[k]]; }
502 504
  };
503 505

	
504 506
  /// Returns a \c ComposeMap class
505 507

	
506 508
  /// This function just returns a \c ComposeMap class.
507 509
  ///
508 510
  /// If \c m1 and \c m2 are maps and the \c Value type of \c m2 is
509 511
  /// convertible to the \c Key of \c m1, then <tt>composeMap(m1,m2)[x]</tt>
510 512
  /// will be equal to <tt>m1[m2[x]]</tt>.
511 513
  ///
512 514
  /// \relates ComposeMap
513 515
  template <typename M1, typename M2>
514 516
  inline ComposeMap<M1, M2> composeMap(const M1 &m1, const M2 &m2) {
515 517
    return ComposeMap<M1, M2>(m1, m2);
516 518
  }
517 519

	
518 520

	
519 521
  /// Combination of two maps using an STL (binary) functor.
520 522

	
521 523
  /// This \ref concepts::ReadMap "read-only map" takes two maps and a
522 524
  /// binary functor and returns the combination of the two given maps
523 525
  /// using the functor.
524 526
  /// That is to say, if \c m1 is of type \c M1 and \c m2 is of \c M2
525 527
  /// and \c f is of \c F, then for
526 528
  /// \code
527 529
  ///   CombineMap<M1,M2,F,V> cm(m1,m2,f);
528 530
  /// \endcode
529 531
  /// <tt>cm[x]</tt> will be equal to <tt>f(m1[x],m2[x])</tt>.
530 532
  ///
531 533
  /// The \c Key type of the map is inherited from \c M1 (\c M1::Key
532 534
  /// must be convertible to \c M2::Key) and the \c Value type is \c V.
533 535
  /// \c M2::Value and \c M1::Value must be convertible to the
534 536
  /// corresponding input parameter of \c F and the return type of \c F
535 537
  /// must be convertible to \c V.
536 538
  ///
537 539
  /// The simplest way of using this map is through the combineMap()
538 540
  /// function.
539 541
  ///
540 542
  /// \sa ComposeMap
541 543
  template<typename M1, typename M2, typename F,
542 544
           typename V = typename F::result_type>
543 545
  class CombineMap : public MapBase<typename M1::Key, V> {
544 546
    const M1 &_m1;
545 547
    const M2 &_m2;
546 548
    F _f;
547 549
  public:
548
    typedef MapBase<typename M1::Key, V> Parent;
549
    typedef typename Parent::Key Key;
550
    typedef typename Parent::Value Value;
550
    ///\e
551
    typedef typename M1::Key Key;
552
    ///\e
553
    typedef V Value;
551 554

	
552 555
    /// Constructor
553 556
    CombineMap(const M1 &m1, const M2 &m2, const F &f = F())
554 557
      : _m1(m1), _m2(m2), _f(f) {}
555
    /// \e
558
    ///\e
556 559
    Value operator[](const Key &k) const { return _f(_m1[k],_m2[k]); }
557 560
  };
558 561

	
559 562
  /// Returns a \c CombineMap class
560 563

	
561 564
  /// This function just returns a \c CombineMap class.
562 565
  ///
563 566
  /// For example, if \c m1 and \c m2 are both maps with \c double
564 567
  /// values, then
565 568
  /// \code
566 569
  ///   combineMap(m1,m2,std::plus<double>())
567 570
  /// \endcode
568 571
  /// is equivalent to
569 572
  /// \code
570 573
  ///   addMap(m1,m2)
571 574
  /// \endcode
572 575
  ///
573 576
  /// This function is specialized for adaptable binary function
574 577
  /// classes and C++ functions.
575 578
  ///
576 579
  /// \relates CombineMap
577 580
  template<typename M1, typename M2, typename F, typename V>
578 581
  inline CombineMap<M1, M2, F, V>
579 582
  combineMap(const M1 &m1, const M2 &m2, const F &f) {
580 583
    return CombineMap<M1, M2, F, V>(m1,m2,f);
581 584
  }
582 585

	
583 586
  template<typename M1, typename M2, typename F>
584 587
  inline CombineMap<M1, M2, F, typename F::result_type>
585 588
  combineMap(const M1 &m1, const M2 &m2, const F &f) {
586 589
    return combineMap<M1, M2, F, typename F::result_type>(m1,m2,f);
587 590
  }
588 591

	
589 592
  template<typename M1, typename M2, typename K1, typename K2, typename V>
590 593
  inline CombineMap<M1, M2, V (*)(K1, K2), V>
591 594
  combineMap(const M1 &m1, const M2 &m2, V (*f)(K1, K2)) {
592 595
    return combineMap<M1, M2, V (*)(K1, K2), V>(m1,m2,f);
593 596
  }
594 597

	
595 598

	
596 599
  /// Converts an STL style (unary) functor to a map
597 600

	
598 601
  /// This \ref concepts::ReadMap "read-only map" returns the value
599 602
  /// of a given functor. Actually, it just wraps the functor and
600 603
  /// provides the \c Key and \c Value typedefs.
601 604
  ///
602 605
  /// Template parameters \c K and \c V will become its \c Key and
603 606
  /// \c Value. In most cases they have to be given explicitly because
604 607
  /// a functor typically does not provide \c argument_type and
605 608
  /// \c result_type typedefs.
606 609
  /// Parameter \c F is the type of the used functor.
607 610
  ///
608 611
  /// The simplest way of using this map is through the functorToMap()
609 612
  /// function.
610 613
  ///
611 614
  /// \sa MapToFunctor
612 615
  template<typename F,
613 616
           typename K = typename F::argument_type,
614 617
           typename V = typename F::result_type>
615 618
  class FunctorToMap : public MapBase<K, V> {
616 619
    F _f;
617 620
  public:
618
    typedef MapBase<K, V> Parent;
619
    typedef typename Parent::Key Key;
620
    typedef typename Parent::Value Value;
621
    ///\e
622
    typedef K Key;
623
    ///\e
624
    typedef V Value;
621 625

	
622 626
    /// Constructor
623 627
    FunctorToMap(const F &f = F()) : _f(f) {}
624
    /// \e
628
    ///\e
625 629
    Value operator[](const Key &k) const { return _f(k); }
626 630
  };
627 631

	
628 632
  /// Returns a \c FunctorToMap class
629 633

	
630 634
  /// This function just returns a \c FunctorToMap class.
631 635
  ///
632 636
  /// This function is specialized for adaptable binary function
633 637
  /// classes and C++ functions.
634 638
  ///
635 639
  /// \relates FunctorToMap
636 640
  template<typename K, typename V, typename F>
637 641
  inline FunctorToMap<F, K, V> functorToMap(const F &f) {
638 642
    return FunctorToMap<F, K, V>(f);
639 643
  }
640 644

	
641 645
  template <typename F>
642 646
  inline FunctorToMap<F, typename F::argument_type, typename F::result_type>
643 647
    functorToMap(const F &f)
644 648
  {
645 649
    return FunctorToMap<F, typename F::argument_type,
646 650
      typename F::result_type>(f);
647 651
  }
648 652

	
649 653
  template <typename K, typename V>
650 654
  inline FunctorToMap<V (*)(K), K, V> functorToMap(V (*f)(K)) {
651 655
    return FunctorToMap<V (*)(K), K, V>(f);
652 656
  }
653 657

	
654 658

	
655 659
  /// Converts a map to an STL style (unary) functor
656 660

	
657 661
  /// This class converts a map to an STL style (unary) functor.
658 662
  /// That is it provides an <tt>operator()</tt> to read its values.
659 663
  ///
660 664
  /// For the sake of convenience it also works as a usual
661 665
  /// \ref concepts::ReadMap "readable map", i.e. <tt>operator[]</tt>
662 666
  /// and the \c Key and \c Value typedefs also exist.
663 667
  ///
664 668
  /// The simplest way of using this map is through the mapToFunctor()
665 669
  /// function.
666 670
  ///
667 671
  ///\sa FunctorToMap
668 672
  template <typename M>
669 673
  class MapToFunctor : public MapBase<typename M::Key, typename M::Value> {
670 674
    const M &_m;
671 675
  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;
676
    ///\e
677
    typedef typename M::Key Key;
678
    ///\e
679
    typedef typename M::Value Value;
680

	
681
    typedef typename M::Key argument_type;
682
    typedef typename M::Value result_type;
678 683

	
679 684
    /// Constructor
680 685
    MapToFunctor(const M &m) : _m(m) {}
681
    /// \e
686
    ///\e
682 687
    Value operator()(const Key &k) const { return _m[k]; }
683
    /// \e
688
    ///\e
684 689
    Value operator[](const Key &k) const { return _m[k]; }
685 690
  };
686 691

	
687 692
  /// Returns a \c MapToFunctor class
688 693

	
689 694
  /// This function just returns a \c MapToFunctor class.
690 695
  /// \relates MapToFunctor
691 696
  template<typename M>
692 697
  inline MapToFunctor<M> mapToFunctor(const M &m) {
693 698
    return MapToFunctor<M>(m);
694 699
  }
695 700

	
696 701

	
697 702
  /// \brief Map adaptor to convert the \c Value type of a map to
698 703
  /// another type using the default conversion.
699 704

	
700 705
  /// Map adaptor to convert the \c Value type of a \ref concepts::ReadMap
701 706
  /// "readable map" to another type using the default conversion.
702 707
  /// The \c Key type of it is inherited from \c M and the \c Value
703 708
  /// type is \c V.
704
  /// This type conforms the \ref concepts::ReadMap "ReadMap" concept.
709
  /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
705 710
  ///
706 711
  /// The simplest way of using this map is through the convertMap()
707 712
  /// function.
708 713
  template <typename M, typename V>
709 714
  class ConvertMap : public MapBase<typename M::Key, V> {
710 715
    const M &_m;
711 716
  public:
712
    typedef MapBase<typename M::Key, V> Parent;
713
    typedef typename Parent::Key Key;
714
    typedef typename Parent::Value Value;
717
    ///\e
718
    typedef typename M::Key Key;
719
    ///\e
720
    typedef V Value;
715 721

	
716 722
    /// Constructor
717 723

	
718 724
    /// Constructor.
719 725
    /// \param m The underlying map.
720 726
    ConvertMap(const M &m) : _m(m) {}
721 727

	
722
    /// \e
728
    ///\e
723 729
    Value operator[](const Key &k) const { return _m[k]; }
724 730
  };
725 731

	
726 732
  /// Returns a \c ConvertMap class
727 733

	
728 734
  /// This function just returns a \c ConvertMap class.
729 735
  /// \relates ConvertMap
730 736
  template<typename V, typename M>
731 737
  inline ConvertMap<M, V> convertMap(const M &map) {
732 738
    return ConvertMap<M, V>(map);
733 739
  }
734 740

	
735 741

	
736 742
  /// Applies all map setting operations to two maps
737 743

	
738 744
  /// This map has two \ref concepts::WriteMap "writable map" parameters
739 745
  /// and each write request will be passed to both of them.
740 746
  /// If \c M1 is also \ref concepts::ReadMap "readable", then the read
741 747
  /// operations will return the corresponding values of \c M1.
742 748
  ///
743 749
  /// The \c Key and \c Value types are inherited from \c M1.
744 750
  /// The \c Key and \c Value of \c M2 must be convertible from those
745 751
  /// of \c M1.
746 752
  ///
747 753
  /// The simplest way of using this map is through the forkMap()
748 754
  /// function.
749 755
  template<typename  M1, typename M2>
750 756
  class ForkMap : public MapBase<typename M1::Key, typename M1::Value> {
751 757
    M1 &_m1;
752 758
    M2 &_m2;
753 759
  public:
754
    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
755
    typedef typename Parent::Key Key;
756
    typedef typename Parent::Value Value;
760
    ///\e
761
    typedef typename M1::Key Key;
762
    ///\e
763
    typedef typename M1::Value Value;
757 764

	
758 765
    /// Constructor
759 766
    ForkMap(M1 &m1, M2 &m2) : _m1(m1), _m2(m2) {}
760 767
    /// Returns the value associated with the given key in the first map.
761 768
    Value operator[](const Key &k) const { return _m1[k]; }
762 769
    /// Sets the value associated with the given key in both maps.
763 770
    void set(const Key &k, const Value &v) { _m1.set(k,v); _m2.set(k,v); }
764 771
  };
765 772

	
766 773
  /// Returns a \c ForkMap class
767 774

	
768 775
  /// This function just returns a \c ForkMap class.
769 776
  /// \relates ForkMap
770 777
  template <typename M1, typename M2>
771 778
  inline ForkMap<M1,M2> forkMap(M1 &m1, M2 &m2) {
772 779
    return ForkMap<M1,M2>(m1,m2);
773 780
  }
774 781

	
775 782

	
776 783
  /// Sum of two maps
777 784

	
778 785
  /// This \ref concepts::ReadMap "read-only map" returns the sum
779 786
  /// of the values of the two given maps.
780 787
  /// Its \c Key and \c Value types are inherited from \c M1.
781 788
  /// The \c Key and \c Value of \c M2 must be convertible to those of
782 789
  /// \c M1.
783 790
  ///
784 791
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
785 792
  /// \code
786 793
  ///   AddMap<M1,M2> am(m1,m2);
787 794
  /// \endcode
788 795
  /// <tt>am[x]</tt> will be equal to <tt>m1[x]+m2[x]</tt>.
789 796
  ///
790 797
  /// The simplest way of using this map is through the addMap()
791 798
  /// function.
792 799
  ///
793 800
  /// \sa SubMap, MulMap, DivMap
794 801
  /// \sa ShiftMap, ShiftWriteMap
795 802
  template<typename M1, typename M2>
796 803
  class AddMap : public MapBase<typename M1::Key, typename M1::Value> {
797 804
    const M1 &_m1;
798 805
    const M2 &_m2;
799 806
  public:
800
    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
801
    typedef typename Parent::Key Key;
802
    typedef typename Parent::Value Value;
807
    ///\e
808
    typedef typename M1::Key Key;
809
    ///\e
810
    typedef typename M1::Value Value;
803 811

	
804 812
    /// Constructor
805 813
    AddMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
806
    /// \e
814
    ///\e
807 815
    Value operator[](const Key &k) const { return _m1[k]+_m2[k]; }
808 816
  };
809 817

	
810 818
  /// Returns an \c AddMap class
811 819

	
812 820
  /// This function just returns an \c AddMap class.
813 821
  ///
814 822
  /// For example, if \c m1 and \c m2 are both maps with \c double
815 823
  /// values, then <tt>addMap(m1,m2)[x]</tt> will be equal to
816 824
  /// <tt>m1[x]+m2[x]</tt>.
817 825
  ///
818 826
  /// \relates AddMap
819 827
  template<typename M1, typename M2>
820 828
  inline AddMap<M1, M2> addMap(const M1 &m1, const M2 &m2) {
821 829
    return AddMap<M1, M2>(m1,m2);
822 830
  }
823 831

	
824 832

	
825 833
  /// Difference of two maps
826 834

	
827 835
  /// This \ref concepts::ReadMap "read-only map" returns the difference
828 836
  /// of the values of the two given maps.
829 837
  /// Its \c Key and \c Value types are inherited from \c M1.
830 838
  /// The \c Key and \c Value of \c M2 must be convertible to those of
831 839
  /// \c M1.
832 840
  ///
833 841
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
834 842
  /// \code
835 843
  ///   SubMap<M1,M2> sm(m1,m2);
836 844
  /// \endcode
837 845
  /// <tt>sm[x]</tt> will be equal to <tt>m1[x]-m2[x]</tt>.
838 846
  ///
839 847
  /// The simplest way of using this map is through the subMap()
840 848
  /// function.
841 849
  ///
842 850
  /// \sa AddMap, MulMap, DivMap
843 851
  template<typename M1, typename M2>
844 852
  class SubMap : public MapBase<typename M1::Key, typename M1::Value> {
845 853
    const M1 &_m1;
846 854
    const M2 &_m2;
847 855
  public:
848
    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
849
    typedef typename Parent::Key Key;
850
    typedef typename Parent::Value Value;
856
    ///\e
857
    typedef typename M1::Key Key;
858
    ///\e
859
    typedef typename M1::Value Value;
851 860

	
852 861
    /// Constructor
853 862
    SubMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
854
    /// \e
863
    ///\e
855 864
    Value operator[](const Key &k) const { return _m1[k]-_m2[k]; }
856 865
  };
857 866

	
858 867
  /// Returns a \c SubMap class
859 868

	
860 869
  /// This function just returns a \c SubMap class.
861 870
  ///
862 871
  /// For example, if \c m1 and \c m2 are both maps with \c double
863 872
  /// values, then <tt>subMap(m1,m2)[x]</tt> will be equal to
864 873
  /// <tt>m1[x]-m2[x]</tt>.
865 874
  ///
866 875
  /// \relates SubMap
867 876
  template<typename M1, typename M2>
868 877
  inline SubMap<M1, M2> subMap(const M1 &m1, const M2 &m2) {
869 878
    return SubMap<M1, M2>(m1,m2);
870 879
  }
871 880

	
872 881

	
873 882
  /// Product of two maps
874 883

	
875 884
  /// This \ref concepts::ReadMap "read-only map" returns the product
876 885
  /// of the values of the two given maps.
877 886
  /// Its \c Key and \c Value types are inherited from \c M1.
878 887
  /// The \c Key and \c Value of \c M2 must be convertible to those of
879 888
  /// \c M1.
880 889
  ///
881 890
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
882 891
  /// \code
883 892
  ///   MulMap<M1,M2> mm(m1,m2);
884 893
  /// \endcode
885 894
  /// <tt>mm[x]</tt> will be equal to <tt>m1[x]*m2[x]</tt>.
886 895
  ///
887 896
  /// The simplest way of using this map is through the mulMap()
888 897
  /// function.
889 898
  ///
890 899
  /// \sa AddMap, SubMap, DivMap
891 900
  /// \sa ScaleMap, ScaleWriteMap
892 901
  template<typename M1, typename M2>
893 902
  class MulMap : public MapBase<typename M1::Key, typename M1::Value> {
894 903
    const M1 &_m1;
895 904
    const M2 &_m2;
896 905
  public:
897
    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
898
    typedef typename Parent::Key Key;
899
    typedef typename Parent::Value Value;
906
    ///\e
907
    typedef typename M1::Key Key;
908
    ///\e
909
    typedef typename M1::Value Value;
900 910

	
901 911
    /// Constructor
902 912
    MulMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
903
    /// \e
913
    ///\e
904 914
    Value operator[](const Key &k) const { return _m1[k]*_m2[k]; }
905 915
  };
906 916

	
907 917
  /// Returns a \c MulMap class
908 918

	
909 919
  /// This function just returns a \c MulMap class.
910 920
  ///
911 921
  /// For example, if \c m1 and \c m2 are both maps with \c double
912 922
  /// values, then <tt>mulMap(m1,m2)[x]</tt> will be equal to
913 923
  /// <tt>m1[x]*m2[x]</tt>.
914 924
  ///
915 925
  /// \relates MulMap
916 926
  template<typename M1, typename M2>
917 927
  inline MulMap<M1, M2> mulMap(const M1 &m1,const M2 &m2) {
918 928
    return MulMap<M1, M2>(m1,m2);
919 929
  }
920 930

	
921 931

	
922 932
  /// Quotient of two maps
923 933

	
924 934
  /// This \ref concepts::ReadMap "read-only map" returns the quotient
925 935
  /// of the values of the two given maps.
926 936
  /// Its \c Key and \c Value types are inherited from \c M1.
927 937
  /// The \c Key and \c Value of \c M2 must be convertible to those of
928 938
  /// \c M1.
929 939
  ///
930 940
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
931 941
  /// \code
932 942
  ///   DivMap<M1,M2> dm(m1,m2);
933 943
  /// \endcode
934 944
  /// <tt>dm[x]</tt> will be equal to <tt>m1[x]/m2[x]</tt>.
935 945
  ///
936 946
  /// The simplest way of using this map is through the divMap()
937 947
  /// function.
938 948
  ///
939 949
  /// \sa AddMap, SubMap, MulMap
940 950
  template<typename M1, typename M2>
941 951
  class DivMap : public MapBase<typename M1::Key, typename M1::Value> {
942 952
    const M1 &_m1;
943 953
    const M2 &_m2;
944 954
  public:
945
    typedef MapBase<typename M1::Key, typename M1::Value> Parent;
946
    typedef typename Parent::Key Key;
947
    typedef typename Parent::Value Value;
955
    ///\e
956
    typedef typename M1::Key Key;
957
    ///\e
958
    typedef typename M1::Value Value;
948 959

	
949 960
    /// Constructor
950 961
    DivMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
951
    /// \e
962
    ///\e
952 963
    Value operator[](const Key &k) const { return _m1[k]/_m2[k]; }
953 964
  };
954 965

	
955 966
  /// Returns a \c DivMap class
956 967

	
957 968
  /// This function just returns a \c DivMap class.
958 969
  ///
959 970
  /// For example, if \c m1 and \c m2 are both maps with \c double
960 971
  /// values, then <tt>divMap(m1,m2)[x]</tt> will be equal to
961 972
  /// <tt>m1[x]/m2[x]</tt>.
962 973
  ///
963 974
  /// \relates DivMap
964 975
  template<typename M1, typename M2>
965 976
  inline DivMap<M1, M2> divMap(const M1 &m1,const M2 &m2) {
966 977
    return DivMap<M1, M2>(m1,m2);
967 978
  }
968 979

	
969 980

	
970 981
  /// Shifts a map with a constant.
971 982

	
972 983
  /// This \ref concepts::ReadMap "read-only map" returns the sum of
973 984
  /// the given map and a constant value (i.e. it shifts the map with
974 985
  /// the constant). Its \c Key and \c Value are inherited from \c M.
975 986
  ///
976 987
  /// Actually,
977 988
  /// \code
978 989
  ///   ShiftMap<M> sh(m,v);
979 990
  /// \endcode
980 991
  /// is equivalent to
981 992
  /// \code
982 993
  ///   ConstMap<M::Key, M::Value> cm(v);
983 994
  ///   AddMap<M, ConstMap<M::Key, M::Value> > sh(m,cm);
984 995
  /// \endcode
985 996
  ///
986 997
  /// The simplest way of using this map is through the shiftMap()
987 998
  /// function.
988 999
  ///
989 1000
  /// \sa ShiftWriteMap
990 1001
  template<typename M, typename C = typename M::Value>
991 1002
  class ShiftMap : public MapBase<typename M::Key, typename M::Value> {
992 1003
    const M &_m;
993 1004
    C _v;
994 1005
  public:
995
    typedef MapBase<typename M::Key, typename M::Value> Parent;
996
    typedef typename Parent::Key Key;
997
    typedef typename Parent::Value Value;
1006
    ///\e
1007
    typedef typename M::Key Key;
1008
    ///\e
1009
    typedef typename M::Value Value;
998 1010

	
999 1011
    /// Constructor
1000 1012

	
1001 1013
    /// Constructor.
1002 1014
    /// \param m The undelying map.
1003 1015
    /// \param v The constant value.
1004 1016
    ShiftMap(const M &m, const C &v) : _m(m), _v(v) {}
1005
    /// \e
1017
    ///\e
1006 1018
    Value operator[](const Key &k) const { return _m[k]+_v; }
1007 1019
  };
1008 1020

	
1009 1021
  /// Shifts a map with a constant (read-write version).
1010 1022

	
1011 1023
  /// This \ref concepts::ReadWriteMap "read-write map" returns the sum
1012 1024
  /// of the given map and a constant value (i.e. it shifts the map with
1013 1025
  /// the constant). Its \c Key and \c Value are inherited from \c M.
1014 1026
  /// It makes also possible to write the map.
1015 1027
  ///
1016 1028
  /// The simplest way of using this map is through the shiftWriteMap()
1017 1029
  /// function.
1018 1030
  ///
1019 1031
  /// \sa ShiftMap
1020 1032
  template<typename M, typename C = typename M::Value>
1021 1033
  class ShiftWriteMap : public MapBase<typename M::Key, typename M::Value> {
1022 1034
    M &_m;
1023 1035
    C _v;
1024 1036
  public:
1025
    typedef MapBase<typename M::Key, typename M::Value> Parent;
1026
    typedef typename Parent::Key Key;
1027
    typedef typename Parent::Value Value;
1037
    ///\e
1038
    typedef typename M::Key Key;
1039
    ///\e
1040
    typedef typename M::Value Value;
1028 1041

	
1029 1042
    /// Constructor
1030 1043

	
1031 1044
    /// Constructor.
1032 1045
    /// \param m The undelying map.
1033 1046
    /// \param v The constant value.
1034 1047
    ShiftWriteMap(M &m, const C &v) : _m(m), _v(v) {}
1035
    /// \e
1048
    ///\e
1036 1049
    Value operator[](const Key &k) const { return _m[k]+_v; }
1037
    /// \e
1050
    ///\e
1038 1051
    void set(const Key &k, const Value &v) { _m.set(k, v-_v); }
1039 1052
  };
1040 1053

	
1041 1054
  /// Returns a \c ShiftMap class
1042 1055

	
1043 1056
  /// This function just returns a \c ShiftMap class.
1044 1057
  ///
1045 1058
  /// For example, if \c m is a map with \c double values and \c v is
1046 1059
  /// \c double, then <tt>shiftMap(m,v)[x]</tt> will be equal to
1047 1060
  /// <tt>m[x]+v</tt>.
1048 1061
  ///
1049 1062
  /// \relates ShiftMap
1050 1063
  template<typename M, typename C>
1051 1064
  inline ShiftMap<M, C> shiftMap(const M &m, const C &v) {
1052 1065
    return ShiftMap<M, C>(m,v);
1053 1066
  }
1054 1067

	
1055 1068
  /// Returns a \c ShiftWriteMap class
1056 1069

	
1057 1070
  /// This function just returns a \c ShiftWriteMap class.
1058 1071
  ///
1059 1072
  /// For example, if \c m is a map with \c double values and \c v is
1060 1073
  /// \c double, then <tt>shiftWriteMap(m,v)[x]</tt> will be equal to
1061 1074
  /// <tt>m[x]+v</tt>.
1062 1075
  /// Moreover it makes also possible to write the map.
1063 1076
  ///
1064 1077
  /// \relates ShiftWriteMap
1065 1078
  template<typename M, typename C>
1066 1079
  inline ShiftWriteMap<M, C> shiftWriteMap(M &m, const C &v) {
1067 1080
    return ShiftWriteMap<M, C>(m,v);
1068 1081
  }
1069 1082

	
1070 1083

	
1071 1084
  /// Scales a map with a constant.
1072 1085

	
1073 1086
  /// This \ref concepts::ReadMap "read-only map" returns the value of
1074 1087
  /// the given map multiplied from the left side with a constant value.
1075 1088
  /// Its \c Key and \c Value are inherited from \c M.
1076 1089
  ///
1077 1090
  /// Actually,
1078 1091
  /// \code
1079 1092
  ///   ScaleMap<M> sc(m,v);
1080 1093
  /// \endcode
1081 1094
  /// is equivalent to
1082 1095
  /// \code
1083 1096
  ///   ConstMap<M::Key, M::Value> cm(v);
1084 1097
  ///   MulMap<ConstMap<M::Key, M::Value>, M> sc(cm,m);
1085 1098
  /// \endcode
1086 1099
  ///
1087 1100
  /// The simplest way of using this map is through the scaleMap()
1088 1101
  /// function.
1089 1102
  ///
1090 1103
  /// \sa ScaleWriteMap
1091 1104
  template<typename M, typename C = typename M::Value>
1092 1105
  class ScaleMap : public MapBase<typename M::Key, typename M::Value> {
1093 1106
    const M &_m;
1094 1107
    C _v;
1095 1108
  public:
1096
    typedef MapBase<typename M::Key, typename M::Value> Parent;
1097
    typedef typename Parent::Key Key;
1098
    typedef typename Parent::Value Value;
1109
    ///\e
1110
    typedef typename M::Key Key;
1111
    ///\e
1112
    typedef typename M::Value Value;
1099 1113

	
1100 1114
    /// Constructor
1101 1115

	
1102 1116
    /// Constructor.
1103 1117
    /// \param m The undelying map.
1104 1118
    /// \param v The constant value.
1105 1119
    ScaleMap(const M &m, const C &v) : _m(m), _v(v) {}
1106
    /// \e
1120
    ///\e
1107 1121
    Value operator[](const Key &k) const { return _v*_m[k]; }
1108 1122
  };
1109 1123

	
1110 1124
  /// Scales a map with a constant (read-write version).
1111 1125

	
1112 1126
  /// This \ref concepts::ReadWriteMap "read-write map" returns the value of
1113 1127
  /// the given map multiplied from the left side with a constant value.
1114 1128
  /// Its \c Key and \c Value are inherited from \c M.
1115 1129
  /// It can also be used as write map if the \c / operator is defined
1116 1130
  /// between \c Value and \c C and the given multiplier is not zero.
1117 1131
  ///
1118 1132
  /// The simplest way of using this map is through the scaleWriteMap()
1119 1133
  /// function.
1120 1134
  ///
1121 1135
  /// \sa ScaleMap
1122 1136
  template<typename M, typename C = typename M::Value>
1123 1137
  class ScaleWriteMap : public MapBase<typename M::Key, typename M::Value> {
1124 1138
    M &_m;
1125 1139
    C _v;
1126 1140
  public:
1127
    typedef MapBase<typename M::Key, typename M::Value> Parent;
1128
    typedef typename Parent::Key Key;
1129
    typedef typename Parent::Value Value;
1141
    ///\e
1142
    typedef typename M::Key Key;
1143
    ///\e
1144
    typedef typename M::Value Value;
1130 1145

	
1131 1146
    /// Constructor
1132 1147

	
1133 1148
    /// Constructor.
1134 1149
    /// \param m The undelying map.
1135 1150
    /// \param v The constant value.
1136 1151
    ScaleWriteMap(M &m, const C &v) : _m(m), _v(v) {}
1137
    /// \e
1152
    ///\e
1138 1153
    Value operator[](const Key &k) const { return _v*_m[k]; }
1139
    /// \e
1154
    ///\e
1140 1155
    void set(const Key &k, const Value &v) { _m.set(k, v/_v); }
1141 1156
  };
1142 1157

	
1143 1158
  /// Returns a \c ScaleMap class
1144 1159

	
1145 1160
  /// This function just returns a \c ScaleMap class.
1146 1161
  ///
1147 1162
  /// For example, if \c m is a map with \c double values and \c v is
1148 1163
  /// \c double, then <tt>scaleMap(m,v)[x]</tt> will be equal to
1149 1164
  /// <tt>v*m[x]</tt>.
1150 1165
  ///
1151 1166
  /// \relates ScaleMap
1152 1167
  template<typename M, typename C>
1153 1168
  inline ScaleMap<M, C> scaleMap(const M &m, const C &v) {
1154 1169
    return ScaleMap<M, C>(m,v);
1155 1170
  }
1156 1171

	
1157 1172
  /// Returns a \c ScaleWriteMap class
1158 1173

	
1159 1174
  /// This function just returns a \c ScaleWriteMap class.
1160 1175
  ///
1161 1176
  /// For example, if \c m is a map with \c double values and \c v is
1162 1177
  /// \c double, then <tt>scaleWriteMap(m,v)[x]</tt> will be equal to
1163 1178
  /// <tt>v*m[x]</tt>.
1164 1179
  /// Moreover it makes also possible to write the map.
1165 1180
  ///
1166 1181
  /// \relates ScaleWriteMap
1167 1182
  template<typename M, typename C>
1168 1183
  inline ScaleWriteMap<M, C> scaleWriteMap(M &m, const C &v) {
1169 1184
    return ScaleWriteMap<M, C>(m,v);
1170 1185
  }
1171 1186

	
1172 1187

	
1173 1188
  /// Negative of a map
1174 1189

	
1175 1190
  /// This \ref concepts::ReadMap "read-only map" returns the negative
1176 1191
  /// of the values of the given map (using the unary \c - operator).
1177 1192
  /// Its \c Key and \c Value are inherited from \c M.
1178 1193
  ///
1179 1194
  /// If M::Value is \c int, \c double etc., then
1180 1195
  /// \code
1181 1196
  ///   NegMap<M> neg(m);
1182 1197
  /// \endcode
1183 1198
  /// is equivalent to
1184 1199
  /// \code
1185 1200
  ///   ScaleMap<M> neg(m,-1);
1186 1201
  /// \endcode
1187 1202
  ///
1188 1203
  /// The simplest way of using this map is through the negMap()
1189 1204
  /// function.
1190 1205
  ///
1191 1206
  /// \sa NegWriteMap
1192 1207
  template<typename M>
1193 1208
  class NegMap : public MapBase<typename M::Key, typename M::Value> {
1194 1209
    const M& _m;
1195 1210
  public:
1196
    typedef MapBase<typename M::Key, typename M::Value> Parent;
1197
    typedef typename Parent::Key Key;
1198
    typedef typename Parent::Value Value;
1211
    ///\e
1212
    typedef typename M::Key Key;
1213
    ///\e
1214
    typedef typename M::Value Value;
1199 1215

	
1200 1216
    /// Constructor
1201 1217
    NegMap(const M &m) : _m(m) {}
1202
    /// \e
1218
    ///\e
1203 1219
    Value operator[](const Key &k) const { return -_m[k]; }
1204 1220
  };
1205 1221

	
1206 1222
  /// Negative of a map (read-write version)
1207 1223

	
1208 1224
  /// This \ref concepts::ReadWriteMap "read-write map" returns the
1209 1225
  /// negative of the values of the given map (using the unary \c -
1210 1226
  /// operator).
1211 1227
  /// Its \c Key and \c Value are inherited from \c M.
1212 1228
  /// It makes also possible to write the map.
1213 1229
  ///
1214 1230
  /// If M::Value is \c int, \c double etc., then
1215 1231
  /// \code
1216 1232
  ///   NegWriteMap<M> neg(m);
1217 1233
  /// \endcode
1218 1234
  /// is equivalent to
1219 1235
  /// \code
1220 1236
  ///   ScaleWriteMap<M> neg(m,-1);
1221 1237
  /// \endcode
1222 1238
  ///
1223 1239
  /// The simplest way of using this map is through the negWriteMap()
1224 1240
  /// function.
1225 1241
  ///
1226 1242
  /// \sa NegMap
1227 1243
  template<typename M>
1228 1244
  class NegWriteMap : public MapBase<typename M::Key, typename M::Value> {
1229 1245
    M &_m;
1230 1246
  public:
1231
    typedef MapBase<typename M::Key, typename M::Value> Parent;
1232
    typedef typename Parent::Key Key;
1233
    typedef typename Parent::Value Value;
1247
    ///\e
1248
    typedef typename M::Key Key;
1249
    ///\e
1250
    typedef typename M::Value Value;
1234 1251

	
1235 1252
    /// Constructor
1236 1253
    NegWriteMap(M &m) : _m(m) {}
1237
    /// \e
1254
    ///\e
1238 1255
    Value operator[](const Key &k) const { return -_m[k]; }
1239
    /// \e
1256
    ///\e
1240 1257
    void set(const Key &k, const Value &v) { _m.set(k, -v); }
1241 1258
  };
1242 1259

	
1243 1260
  /// Returns a \c NegMap class
1244 1261

	
1245 1262
  /// This function just returns a \c NegMap class.
1246 1263
  ///
1247 1264
  /// For example, if \c m is a map with \c double values, then
1248 1265
  /// <tt>negMap(m)[x]</tt> will be equal to <tt>-m[x]</tt>.
1249 1266
  ///
1250 1267
  /// \relates NegMap
1251 1268
  template <typename M>
1252 1269
  inline NegMap<M> negMap(const M &m) {
1253 1270
    return NegMap<M>(m);
1254 1271
  }
1255 1272

	
1256 1273
  /// Returns a \c NegWriteMap class
1257 1274

	
1258 1275
  /// This function just returns a \c NegWriteMap class.
1259 1276
  ///
1260 1277
  /// For example, if \c m is a map with \c double values, then
1261 1278
  /// <tt>negWriteMap(m)[x]</tt> will be equal to <tt>-m[x]</tt>.
1262 1279
  /// Moreover it makes also possible to write the map.
1263 1280
  ///
1264 1281
  /// \relates NegWriteMap
1265 1282
  template <typename M>
1266 1283
  inline NegWriteMap<M> negWriteMap(M &m) {
1267 1284
    return NegWriteMap<M>(m);
1268 1285
  }
1269 1286

	
1270 1287

	
1271 1288
  /// Absolute value of a map
1272 1289

	
1273 1290
  /// This \ref concepts::ReadMap "read-only map" returns the absolute
1274 1291
  /// value of the values of the given map.
1275 1292
  /// Its \c Key and \c Value are inherited from \c M.
1276 1293
  /// \c Value must be comparable to \c 0 and the unary \c -
1277 1294
  /// operator must be defined for it, of course.
1278 1295
  ///
1279 1296
  /// The simplest way of using this map is through the absMap()
1280 1297
  /// function.
1281 1298
  template<typename M>
1282 1299
  class AbsMap : public MapBase<typename M::Key, typename M::Value> {
1283 1300
    const M &_m;
1284 1301
  public:
1285
    typedef MapBase<typename M::Key, typename M::Value> Parent;
1286
    typedef typename Parent::Key Key;
1287
    typedef typename Parent::Value Value;
1302
    ///\e
1303
    typedef typename M::Key Key;
1304
    ///\e
1305
    typedef typename M::Value Value;
1288 1306

	
1289 1307
    /// Constructor
1290 1308
    AbsMap(const M &m) : _m(m) {}
1291
    /// \e
1309
    ///\e
1292 1310
    Value operator[](const Key &k) const {
1293 1311
      Value tmp = _m[k];
1294 1312
      return tmp >= 0 ? tmp : -tmp;
1295 1313
    }
1296 1314

	
1297 1315
  };
1298 1316

	
1299 1317
  /// Returns an \c AbsMap class
1300 1318

	
1301 1319
  /// This function just returns an \c AbsMap class.
1302 1320
  ///
1303 1321
  /// For example, if \c m is a map with \c double values, then
1304 1322
  /// <tt>absMap(m)[x]</tt> will be equal to <tt>m[x]</tt> if
1305 1323
  /// it is positive or zero and <tt>-m[x]</tt> if <tt>m[x]</tt> is
1306 1324
  /// negative.
1307 1325
  ///
1308 1326
  /// \relates AbsMap
1309 1327
  template<typename M>
1310 1328
  inline AbsMap<M> absMap(const M &m) {
1311 1329
    return AbsMap<M>(m);
1312 1330
  }
1313 1331

	
1314 1332
  /// @}
1315 1333

	
1316 1334
  // Logical maps and map adaptors:
1317 1335

	
1318 1336
  /// \addtogroup maps
1319 1337
  /// @{
1320 1338

	
1321 1339
  /// Constant \c true map.
1322 1340

	
1323 1341
  /// This \ref concepts::ReadMap "read-only map" assigns \c true to
1324 1342
  /// each key.
1325 1343
  ///
1326 1344
  /// Note that
1327 1345
  /// \code
1328 1346
  ///   TrueMap<K> tm;
1329 1347
  /// \endcode
1330 1348
  /// is equivalent to
1331 1349
  /// \code
1332 1350
  ///   ConstMap<K,bool> tm(true);
1333 1351
  /// \endcode
1334 1352
  ///
1335 1353
  /// \sa FalseMap
1336 1354
  /// \sa ConstMap
1337 1355
  template <typename K>
1338 1356
  class TrueMap : public MapBase<K, bool> {
1339 1357
  public:
1340
    typedef MapBase<K, bool> Parent;
1341
    typedef typename Parent::Key Key;
1342
    typedef typename Parent::Value Value;
1358
    ///\e
1359
    typedef K Key;
1360
    ///\e
1361
    typedef bool Value;
1343 1362

	
1344 1363
    /// Gives back \c true.
1345 1364
    Value operator[](const Key&) const { return true; }
1346 1365
  };
1347 1366

	
1348 1367
  /// Returns a \c TrueMap class
1349 1368

	
1350 1369
  /// This function just returns a \c TrueMap class.
1351 1370
  /// \relates TrueMap
1352 1371
  template<typename K>
1353 1372
  inline TrueMap<K> trueMap() {
1354 1373
    return TrueMap<K>();
1355 1374
  }
1356 1375

	
1357 1376

	
1358 1377
  /// Constant \c false map.
1359 1378

	
1360 1379
  /// This \ref concepts::ReadMap "read-only map" assigns \c false to
1361 1380
  /// each key.
1362 1381
  ///
1363 1382
  /// Note that
1364 1383
  /// \code
1365 1384
  ///   FalseMap<K> fm;
1366 1385
  /// \endcode
1367 1386
  /// is equivalent to
1368 1387
  /// \code
1369 1388
  ///   ConstMap<K,bool> fm(false);
1370 1389
  /// \endcode
1371 1390
  ///
1372 1391
  /// \sa TrueMap
1373 1392
  /// \sa ConstMap
1374 1393
  template <typename K>
1375 1394
  class FalseMap : public MapBase<K, bool> {
1376 1395
  public:
1377
    typedef MapBase<K, bool> Parent;
1378
    typedef typename Parent::Key Key;
1379
    typedef typename Parent::Value Value;
1396
    ///\e
1397
    typedef K Key;
1398
    ///\e
1399
    typedef bool Value;
1380 1400

	
1381 1401
    /// Gives back \c false.
1382 1402
    Value operator[](const Key&) const { return false; }
1383 1403
  };
1384 1404

	
1385 1405
  /// Returns a \c FalseMap class
1386 1406

	
1387 1407
  /// This function just returns a \c FalseMap class.
1388 1408
  /// \relates FalseMap
1389 1409
  template<typename K>
1390 1410
  inline FalseMap<K> falseMap() {
1391 1411
    return FalseMap<K>();
1392 1412
  }
1393 1413

	
1394 1414
  /// @}
1395 1415

	
1396 1416
  /// \addtogroup map_adaptors
1397 1417
  /// @{
1398 1418

	
1399 1419
  /// Logical 'and' of two maps
1400 1420

	
1401 1421
  /// This \ref concepts::ReadMap "read-only map" returns the logical
1402 1422
  /// 'and' of the values of the two given maps.
1403 1423
  /// Its \c Key type is inherited from \c M1 and its \c Value type is
1404 1424
  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
1405 1425
  ///
1406 1426
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
1407 1427
  /// \code
1408 1428
  ///   AndMap<M1,M2> am(m1,m2);
1409 1429
  /// \endcode
1410 1430
  /// <tt>am[x]</tt> will be equal to <tt>m1[x]&&m2[x]</tt>.
1411 1431
  ///
1412 1432
  /// The simplest way of using this map is through the andMap()
1413 1433
  /// function.
1414 1434
  ///
1415 1435
  /// \sa OrMap
1416 1436
  /// \sa NotMap, NotWriteMap
1417 1437
  template<typename M1, typename M2>
1418 1438
  class AndMap : public MapBase<typename M1::Key, bool> {
1419 1439
    const M1 &_m1;
1420 1440
    const M2 &_m2;
1421 1441
  public:
1422
    typedef MapBase<typename M1::Key, bool> Parent;
1423
    typedef typename Parent::Key Key;
1424
    typedef typename Parent::Value Value;
1442
    ///\e
1443
    typedef typename M1::Key Key;
1444
    ///\e
1445
    typedef bool Value;
1425 1446

	
1426 1447
    /// Constructor
1427 1448
    AndMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
1428
    /// \e
1449
    ///\e
1429 1450
    Value operator[](const Key &k) const { return _m1[k]&&_m2[k]; }
1430 1451
  };
1431 1452

	
1432 1453
  /// Returns an \c AndMap class
1433 1454

	
1434 1455
  /// This function just returns an \c AndMap class.
1435 1456
  ///
1436 1457
  /// For example, if \c m1 and \c m2 are both maps with \c bool values,
1437 1458
  /// then <tt>andMap(m1,m2)[x]</tt> will be equal to
1438 1459
  /// <tt>m1[x]&&m2[x]</tt>.
1439 1460
  ///
1440 1461
  /// \relates AndMap
1441 1462
  template<typename M1, typename M2>
1442 1463
  inline AndMap<M1, M2> andMap(const M1 &m1, const M2 &m2) {
1443 1464
    return AndMap<M1, M2>(m1,m2);
1444 1465
  }
1445 1466

	
1446 1467

	
1447 1468
  /// Logical 'or' of two maps
1448 1469

	
1449 1470
  /// This \ref concepts::ReadMap "read-only map" returns the logical
1450 1471
  /// 'or' of the values of the two given maps.
1451 1472
  /// Its \c Key type is inherited from \c M1 and its \c Value type is
1452 1473
  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
1453 1474
  ///
1454 1475
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
1455 1476
  /// \code
1456 1477
  ///   OrMap<M1,M2> om(m1,m2);
1457 1478
  /// \endcode
1458 1479
  /// <tt>om[x]</tt> will be equal to <tt>m1[x]||m2[x]</tt>.
1459 1480
  ///
1460 1481
  /// The simplest way of using this map is through the orMap()
1461 1482
  /// function.
1462 1483
  ///
1463 1484
  /// \sa AndMap
1464 1485
  /// \sa NotMap, NotWriteMap
1465 1486
  template<typename M1, typename M2>
1466 1487
  class OrMap : public MapBase<typename M1::Key, bool> {
1467 1488
    const M1 &_m1;
1468 1489
    const M2 &_m2;
1469 1490
  public:
1470
    typedef MapBase<typename M1::Key, bool> Parent;
1471
    typedef typename Parent::Key Key;
1472
    typedef typename Parent::Value Value;
1491
    ///\e
1492
    typedef typename M1::Key Key;
1493
    ///\e
1494
    typedef bool Value;
1473 1495

	
1474 1496
    /// Constructor
1475 1497
    OrMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
1476
    /// \e
1498
    ///\e
1477 1499
    Value operator[](const Key &k) const { return _m1[k]||_m2[k]; }
1478 1500
  };
1479 1501

	
1480 1502
  /// Returns an \c OrMap class
1481 1503

	
1482 1504
  /// This function just returns an \c OrMap class.
1483 1505
  ///
1484 1506
  /// For example, if \c m1 and \c m2 are both maps with \c bool values,
1485 1507
  /// then <tt>orMap(m1,m2)[x]</tt> will be equal to
1486 1508
  /// <tt>m1[x]||m2[x]</tt>.
1487 1509
  ///
1488 1510
  /// \relates OrMap
1489 1511
  template<typename M1, typename M2>
1490 1512
  inline OrMap<M1, M2> orMap(const M1 &m1, const M2 &m2) {
1491 1513
    return OrMap<M1, M2>(m1,m2);
1492 1514
  }
1493 1515

	
1494 1516

	
1495 1517
  /// Logical 'not' of a map
1496 1518

	
1497 1519
  /// This \ref concepts::ReadMap "read-only map" returns the logical
1498 1520
  /// negation of the values of the given map.
1499 1521
  /// Its \c Key is inherited from \c M and its \c Value is \c bool.
1500 1522
  ///
1501 1523
  /// The simplest way of using this map is through the notMap()
1502 1524
  /// function.
1503 1525
  ///
1504 1526
  /// \sa NotWriteMap
1505 1527
  template <typename M>
1506 1528
  class NotMap : public MapBase<typename M::Key, bool> {
1507 1529
    const M &_m;
1508 1530
  public:
1509
    typedef MapBase<typename M::Key, bool> Parent;
1510
    typedef typename Parent::Key Key;
1511
    typedef typename Parent::Value Value;
1531
    ///\e
1532
    typedef typename M::Key Key;
1533
    ///\e
1534
    typedef bool Value;
1512 1535

	
1513 1536
    /// Constructor
1514 1537
    NotMap(const M &m) : _m(m) {}
1515
    /// \e
1538
    ///\e
1516 1539
    Value operator[](const Key &k) const { return !_m[k]; }
1517 1540
  };
1518 1541

	
1519 1542
  /// Logical 'not' of a map (read-write version)
1520 1543

	
1521 1544
  /// This \ref concepts::ReadWriteMap "read-write map" returns the
1522 1545
  /// logical negation of the values of the given map.
1523 1546
  /// Its \c Key is inherited from \c M and its \c Value is \c bool.
1524 1547
  /// It makes also possible to write the map. When a value is set,
1525 1548
  /// the opposite value is set to the original map.
1526 1549
  ///
1527 1550
  /// The simplest way of using this map is through the notWriteMap()
1528 1551
  /// function.
1529 1552
  ///
1530 1553
  /// \sa NotMap
1531 1554
  template <typename M>
1532 1555
  class NotWriteMap : public MapBase<typename M::Key, bool> {
1533 1556
    M &_m;
1534 1557
  public:
1535
    typedef MapBase<typename M::Key, bool> Parent;
1536
    typedef typename Parent::Key Key;
1537
    typedef typename Parent::Value Value;
1558
    ///\e
1559
    typedef typename M::Key Key;
1560
    ///\e
1561
    typedef bool Value;
1538 1562

	
1539 1563
    /// Constructor
1540 1564
    NotWriteMap(M &m) : _m(m) {}
1541
    /// \e
1565
    ///\e
1542 1566
    Value operator[](const Key &k) const { return !_m[k]; }
1543
    /// \e
1567
    ///\e
1544 1568
    void set(const Key &k, bool v) { _m.set(k, !v); }
1545 1569
  };
1546 1570

	
1547 1571
  /// Returns a \c NotMap class
1548 1572

	
1549 1573
  /// This function just returns a \c NotMap class.
1550 1574
  ///
1551 1575
  /// For example, if \c m is a map with \c bool values, then
1552 1576
  /// <tt>notMap(m)[x]</tt> will be equal to <tt>!m[x]</tt>.
1553 1577
  ///
1554 1578
  /// \relates NotMap
1555 1579
  template <typename M>
1556 1580
  inline NotMap<M> notMap(const M &m) {
1557 1581
    return NotMap<M>(m);
1558 1582
  }
1559 1583

	
1560 1584
  /// Returns a \c NotWriteMap class
1561 1585

	
1562 1586
  /// This function just returns a \c NotWriteMap class.
1563 1587
  ///
1564 1588
  /// For example, if \c m is a map with \c bool values, then
1565 1589
  /// <tt>notWriteMap(m)[x]</tt> will be equal to <tt>!m[x]</tt>.
1566 1590
  /// Moreover it makes also possible to write the map.
1567 1591
  ///
1568 1592
  /// \relates NotWriteMap
1569 1593
  template <typename M>
1570 1594
  inline NotWriteMap<M> notWriteMap(M &m) {
1571 1595
    return NotWriteMap<M>(m);
1572 1596
  }
1573 1597

	
1574 1598

	
1575 1599
  /// Combination of two maps using the \c == operator
1576 1600

	
1577 1601
  /// This \ref concepts::ReadMap "read-only map" assigns \c true to
1578 1602
  /// the keys for which the corresponding values of the two maps are
1579 1603
  /// equal.
1580 1604
  /// Its \c Key type is inherited from \c M1 and its \c Value type is
1581 1605
  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
1582 1606
  ///
1583 1607
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
1584 1608
  /// \code
1585 1609
  ///   EqualMap<M1,M2> em(m1,m2);
1586 1610
  /// \endcode
1587 1611
  /// <tt>em[x]</tt> will be equal to <tt>m1[x]==m2[x]</tt>.
1588 1612
  ///
1589 1613
  /// The simplest way of using this map is through the equalMap()
1590 1614
  /// function.
1591 1615
  ///
1592 1616
  /// \sa LessMap
1593 1617
  template<typename M1, typename M2>
1594 1618
  class EqualMap : public MapBase<typename M1::Key, bool> {
1595 1619
    const M1 &_m1;
1596 1620
    const M2 &_m2;
1597 1621
  public:
1598
    typedef MapBase<typename M1::Key, bool> Parent;
1599
    typedef typename Parent::Key Key;
1600
    typedef typename Parent::Value Value;
1622
    ///\e
1623
    typedef typename M1::Key Key;
1624
    ///\e
1625
    typedef bool Value;
1601 1626

	
1602 1627
    /// Constructor
1603 1628
    EqualMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
1604
    /// \e
1629
    ///\e
1605 1630
    Value operator[](const Key &k) const { return _m1[k]==_m2[k]; }
1606 1631
  };
1607 1632

	
1608 1633
  /// Returns an \c EqualMap class
1609 1634

	
1610 1635
  /// This function just returns an \c EqualMap class.
1611 1636
  ///
1612 1637
  /// For example, if \c m1 and \c m2 are maps with keys and values of
1613 1638
  /// the same type, then <tt>equalMap(m1,m2)[x]</tt> will be equal to
1614 1639
  /// <tt>m1[x]==m2[x]</tt>.
1615 1640
  ///
1616 1641
  /// \relates EqualMap
1617 1642
  template<typename M1, typename M2>
1618 1643
  inline EqualMap<M1, M2> equalMap(const M1 &m1, const M2 &m2) {
1619 1644
    return EqualMap<M1, M2>(m1,m2);
1620 1645
  }
1621 1646

	
1622 1647

	
1623 1648
  /// Combination of two maps using the \c < operator
1624 1649

	
1625 1650
  /// This \ref concepts::ReadMap "read-only map" assigns \c true to
1626 1651
  /// the keys for which the corresponding value of the first map is
1627 1652
  /// less then the value of the second map.
1628 1653
  /// Its \c Key type is inherited from \c M1 and its \c Value type is
1629 1654
  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
1630 1655
  ///
1631 1656
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
1632 1657
  /// \code
1633 1658
  ///   LessMap<M1,M2> lm(m1,m2);
1634 1659
  /// \endcode
1635 1660
  /// <tt>lm[x]</tt> will be equal to <tt>m1[x]<m2[x]</tt>.
1636 1661
  ///
1637 1662
  /// The simplest way of using this map is through the lessMap()
1638 1663
  /// function.
1639 1664
  ///
1640 1665
  /// \sa EqualMap
1641 1666
  template<typename M1, typename M2>
1642 1667
  class LessMap : public MapBase<typename M1::Key, bool> {
1643 1668
    const M1 &_m1;
1644 1669
    const M2 &_m2;
1645 1670
  public:
1646
    typedef MapBase<typename M1::Key, bool> Parent;
1647
    typedef typename Parent::Key Key;
1648
    typedef typename Parent::Value Value;
1671
    ///\e
1672
    typedef typename M1::Key Key;
1673
    ///\e
1674
    typedef bool Value;
1649 1675

	
1650 1676
    /// Constructor
1651 1677
    LessMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
1652
    /// \e
1678
    ///\e
1653 1679
    Value operator[](const Key &k) const { return _m1[k]<_m2[k]; }
1654 1680
  };
1655 1681

	
1656 1682
  /// Returns an \c LessMap class
1657 1683

	
1658 1684
  /// This function just returns an \c LessMap class.
1659 1685
  ///
1660 1686
  /// For example, if \c m1 and \c m2 are maps with keys and values of
1661 1687
  /// the same type, then <tt>lessMap(m1,m2)[x]</tt> will be equal to
1662 1688
  /// <tt>m1[x]<m2[x]</tt>.
1663 1689
  ///
1664 1690
  /// \relates LessMap
1665 1691
  template<typename M1, typename M2>
1666 1692
  inline LessMap<M1, M2> lessMap(const M1 &m1, const M2 &m2) {
1667 1693
    return LessMap<M1, M2>(m1,m2);
1668 1694
  }
1669 1695

	
1670 1696
  namespace _maps_bits {
1671 1697

	
1672 1698
    template <typename _Iterator, typename Enable = void>
1673 1699
    struct IteratorTraits {
1674 1700
      typedef typename std::iterator_traits<_Iterator>::value_type Value;
1675 1701
    };
1676 1702

	
1677 1703
    template <typename _Iterator>
1678 1704
    struct IteratorTraits<_Iterator,
1679 1705
      typename exists<typename _Iterator::container_type>::type>
1680 1706
    {
1681 1707
      typedef typename _Iterator::container_type::value_type Value;
1682 1708
    };
1683 1709

	
1684 1710
  }
1685 1711

	
1686 1712
  /// @}
1687 1713

	
1688 1714
  /// \addtogroup maps
1689 1715
  /// @{
1690 1716

	
1691 1717
  /// \brief Writable bool map for logging each \c true assigned element
1692 1718
  ///
1693 1719
  /// A \ref concepts::WriteMap "writable" bool map for logging
1694 1720
  /// each \c true assigned element, i.e it copies subsequently each
1695 1721
  /// keys set to \c true to the given iterator.
1696 1722
  /// The most important usage of it is storing certain nodes or arcs
1697 1723
  /// that were marked \c true by an algorithm.
1698 1724
  ///
1699 1725
  /// There are several algorithms that provide solutions through bool
1700 1726
  /// maps and most of them assign \c true at most once for each key.
1701 1727
  /// In these cases it is a natural request to store each \c true
1702 1728
  /// assigned elements (in order of the assignment), which can be
1703 1729
  /// easily done with LoggerBoolMap.
1704 1730
  ///
1705 1731
  /// The simplest way of using this map is through the loggerBoolMap()
1706 1732
  /// function.
1707 1733
  ///
1708
  /// \tparam It The type of the iterator.
1709
  /// \tparam Ke The key type of the map. The default value set
1734
  /// \tparam IT The type of the iterator.
1735
  /// \tparam KEY The key type of the map. The default value set
1710 1736
  /// according to the iterator type should work in most cases.
1711 1737
  ///
1712 1738
  /// \note The container of the iterator must contain enough space
1713 1739
  /// for the elements or the iterator should be an inserter iterator.
1714 1740
#ifdef DOXYGEN
1715
  template <typename It, typename Ke>
1741
  template <typename IT, typename KEY>
1716 1742
#else
1717
  template <typename It,
1718
            typename Ke=typename _maps_bits::IteratorTraits<It>::Value>
1743
  template <typename IT,
1744
            typename KEY = typename _maps_bits::IteratorTraits<IT>::Value>
1719 1745
#endif
1720
  class LoggerBoolMap {
1746
  class LoggerBoolMap : public MapBase<KEY, bool> {
1721 1747
  public:
1722
    typedef It Iterator;
1723

	
1724
    typedef Ke Key;
1748

	
1749
    ///\e
1750
    typedef KEY Key;
1751
    ///\e
1725 1752
    typedef bool Value;
1753
    ///\e
1754
    typedef IT Iterator;
1726 1755

	
1727 1756
    /// Constructor
1728 1757
    LoggerBoolMap(Iterator it)
1729 1758
      : _begin(it), _end(it) {}
1730 1759

	
1731 1760
    /// Gives back the given iterator set for the first key
1732 1761
    Iterator begin() const {
1733 1762
      return _begin;
1734 1763
    }
1735 1764

	
1736 1765
    /// Gives back the the 'after the last' iterator
1737 1766
    Iterator end() const {
1738 1767
      return _end;
1739 1768
    }
1740 1769

	
1741 1770
    /// The set function of the map
1742 1771
    void set(const Key& key, Value value) {
1743 1772
      if (value) {
1744 1773
        *_end++ = key;
1745 1774
      }
1746 1775
    }
1747 1776

	
1748 1777
  private:
1749 1778
    Iterator _begin;
1750 1779
    Iterator _end;
1751 1780
  };
1752 1781

	
1753 1782
  /// Returns a \c LoggerBoolMap class
1754 1783

	
1755 1784
  /// This function just returns a \c LoggerBoolMap class.
1756 1785
  ///
1757 1786
  /// The most important usage of it is storing certain nodes or arcs
1758 1787
  /// that were marked \c true by an algorithm.
1759 1788
  /// For example it makes easier to store the nodes in the processing
1760 1789
  /// order of Dfs algorithm, as the following examples show.
1761 1790
  /// \code
1762 1791
  ///   std::vector<Node> v;
1763
  ///   dfs(g,s).processedMap(loggerBoolMap(std::back_inserter(v))).run();
1792
  ///   dfs(g).processedMap(loggerBoolMap(std::back_inserter(v))).run(s);
1764 1793
  /// \endcode
1765 1794
  /// \code
1766 1795
  ///   std::vector<Node> v(countNodes(g));
1767
  ///   dfs(g,s).processedMap(loggerBoolMap(v.begin())).run();
1796
  ///   dfs(g).processedMap(loggerBoolMap(v.begin())).run(s);
1768 1797
  /// \endcode
1769 1798
  ///
1770 1799
  /// \note The container of the iterator must contain enough space
1771 1800
  /// for the elements or the iterator should be an inserter iterator.
1772 1801
  ///
1773 1802
  /// \note LoggerBoolMap is just \ref concepts::WriteMap "writable", so
1774 1803
  /// it cannot be used when a readable map is needed, for example as
1775 1804
  /// \c ReachedMap for \c Bfs, \c Dfs and \c Dijkstra algorithms.
1776 1805
  ///
1777 1806
  /// \relates LoggerBoolMap
1778 1807
  template<typename Iterator>
1779 1808
  inline LoggerBoolMap<Iterator> loggerBoolMap(Iterator it) {
1780 1809
    return LoggerBoolMap<Iterator>(it);
1781 1810
  }
1782 1811

	
1783 1812
  /// @}
1784 1813

	
1785 1814
  /// \addtogroup graph_maps
1786 1815
  /// @{
1787 1816

	
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
1796
  /// class \c InverseMap or with the \c operator() member.
1817
  /// \brief Provides an immutable and unique id for each item in a graph.
1797 1818
  ///
1798
  template <typename _Graph, typename _Item>
1799
  class IdMap {
1819
  /// IdMap provides a unique and immutable id for each item of the
1820
  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
1821
  ///  - \b unique: different items get different ids,
1822
  ///  - \b immutable: the id of an item does not change (even if you
1823
  ///    delete other nodes).
1824
  ///
1825
  /// Using this map you get access (i.e. can read) the inner id values of
1826
  /// the items stored in the graph, which is returned by the \c id()
1827
  /// function of the graph. This map can be inverted with its member
1828
  /// class \c InverseMap or with the \c operator()() member.
1829
  ///
1830
  /// \tparam GR The graph type.
1831
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
1832
  /// \c GR::Edge).
1833
  ///
1834
  /// \see RangeIdMap
1835
  template <typename GR, typename K>
1836
  class IdMap : public MapBase<K, int> {
1800 1837
  public:
1801
    typedef _Graph Graph;
1838
    /// The graph type of IdMap.
1839
    typedef GR Graph;
1840
    typedef GR Digraph;
1841
    /// The key type of IdMap (\c Node, \c Arc or \c Edge).
1842
    typedef K Item;
1843
    /// The key type of IdMap (\c Node, \c Arc or \c Edge).
1844
    typedef K Key;
1845
    /// The value type of IdMap.
1802 1846
    typedef int Value;
1803
    typedef _Item Item;
1804
    typedef _Item Key;
1805 1847

	
1806 1848
    /// \brief Constructor.
1807 1849
    ///
1808 1850
    /// Constructor of the map.
1809 1851
    explicit IdMap(const Graph& graph) : _graph(&graph) {}
1810 1852

	
1811 1853
    /// \brief Gives back the \e id of the item.
1812 1854
    ///
1813 1855
    /// Gives back the immutable and unique \e id of the item.
1814 1856
    int operator[](const Item& item) const { return _graph->id(item);}
1815 1857

	
1816
    /// \brief Gives back the item by its id.
1858
    /// \brief Gives back the \e item by its id.
1817 1859
    ///
1818
    /// Gives back the item by its id.
1860
    /// Gives back the \e item by its id.
1819 1861
    Item operator()(int id) { return _graph->fromId(id, Item()); }
1820 1862

	
1821 1863
  private:
1822 1864
    const Graph* _graph;
1823 1865

	
1824 1866
  public:
1825 1867

	
1826
    /// \brief The class represents the inverse of its owner (IdMap).
1868
    /// \brief The inverse map type of IdMap.
1827 1869
    ///
1828
    /// The class represents the inverse of its owner (IdMap).
1870
    /// The inverse map type of IdMap. The subscript operator gives back
1871
    /// an item by its id.
1872
    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
1829 1873
    /// \see inverse()
1830 1874
    class InverseMap {
1831 1875
    public:
1832 1876

	
1833 1877
      /// \brief Constructor.
1834 1878
      ///
1835 1879
      /// Constructor for creating an id-to-item map.
1836 1880
      explicit InverseMap(const Graph& graph) : _graph(&graph) {}
1837 1881

	
1838 1882
      /// \brief Constructor.
1839 1883
      ///
1840 1884
      /// Constructor for creating an id-to-item map.
1841 1885
      explicit InverseMap(const IdMap& map) : _graph(map._graph) {}
1842 1886

	
1843
      /// \brief Gives back the given item from its id.
1887
      /// \brief Gives back an item by its id.
1844 1888
      ///
1845
      /// Gives back the given item from its id.
1846
      ///
1889
      /// Gives back an item by its id.
1847 1890
      Item operator[](int id) const { return _graph->fromId(id, Item());}
1848 1891

	
1849 1892
    private:
1850 1893
      const Graph* _graph;
1851 1894
    };
1852 1895

	
1853 1896
    /// \brief Gives back the inverse of the map.
1854 1897
    ///
1855 1898
    /// Gives back the inverse of the IdMap.
1856 1899
    InverseMap inverse() const { return InverseMap(*_graph);}
1857

	
1858 1900
  };
1859 1901

	
1860

	
1861
  /// \brief General invertable graph-map type.
1862

	
1863
  /// This type provides simple invertable graph-maps.
1864
  /// The InvertableMap wraps an arbitrary ReadWriteMap
1865
  /// and if a key is set to a new value then store it
1866
  /// in the inverse map.
1902
  /// \brief Returns an \c IdMap class.
1867 1903
  ///
1868
  /// The values of the map can be accessed
1869
  /// with stl compatible forward iterator.
1904
  /// This function just returns an \c IdMap class.
1905
  /// \relates IdMap
1906
  template <typename K, typename GR>
1907
  inline IdMap<GR, K> idMap(const GR& graph) {
1908
    return IdMap<GR, K>(graph);
1909
  }
1910

	
1911
  /// \brief General cross reference graph map type.
1912

	
1913
  /// This class provides simple invertable graph maps.
1914
  /// It wraps a standard graph map (\c NodeMap, \c ArcMap or \c EdgeMap)
1915
  /// and if a key is set to a new value, then stores it in the inverse map.
1916
  /// The graph items can be accessed by their values either using
1917
  /// \c InverseMap or \c operator()(), and the values of the map can be
1918
  /// accessed with an STL compatible forward iterator (\c ValueIt).
1919
  /// 
1920
  /// This map is intended to be used when all associated values are
1921
  /// different (the map is actually invertable) or there are only a few
1922
  /// items with the same value.
1923
  /// Otherwise consider to use \c IterableValueMap, which is more 
1924
  /// suitable and more efficient for such cases. It provides iterators
1925
  /// to traverse the items with the same associated value, however
1926
  /// it does not have \c InverseMap.
1870 1927
  ///
1871
  /// \tparam _Graph The graph type.
1872
  /// \tparam _Item The item type of the graph.
1873
  /// \tparam _Value The value type of the map.
1928
  /// This type is not reference map, so it cannot be modified with
1929
  /// the subscript operator.
1930
  ///
1931
  /// \tparam GR The graph type.
1932
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
1933
  /// \c GR::Edge).
1934
  /// \tparam V The value type of the map.
1874 1935
  ///
1875 1936
  /// \see IterableValueMap
1876
  template <typename _Graph, typename _Item, typename _Value>
1877
  class InvertableMap
1878
    : protected ItemSetTraits<_Graph, _Item>::template Map<_Value>::Type {
1937
  template <typename GR, typename K, typename V>
1938
  class CrossRefMap
1939
    : protected ItemSetTraits<GR, K>::template Map<V>::Type {
1879 1940
  private:
1880 1941

	
1881
    typedef typename ItemSetTraits<_Graph, _Item>::
1882
    template Map<_Value>::Type Map;
1883
    typedef _Graph Graph;
1884

	
1885
    typedef std::map<_Value, _Item> Container;
1942
    typedef typename ItemSetTraits<GR, K>::
1943
      template Map<V>::Type Map;
1944

	
1945
    typedef std::multimap<V, K> Container;
1886 1946
    Container _inv_map;
1887 1947

	
1888 1948
  public:
1889 1949

	
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;
1950
    /// The graph type of CrossRefMap.
1951
    typedef GR Graph;
1952
    typedef GR Digraph;
1953
    /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
1954
    typedef K Item;
1955
    /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
1956
    typedef K Key;
1957
    /// The value type of CrossRefMap.
1958
    typedef V Value;
1894 1959

	
1895 1960
    /// \brief Constructor.
1896 1961
    ///
1897
    /// Construct a new InvertableMap for the graph.
1898
    ///
1899
    explicit InvertableMap(const Graph& graph) : Map(graph) {}
1962
    /// Construct a new CrossRefMap for the given graph.
1963
    explicit CrossRefMap(const Graph& graph) : Map(graph) {}
1900 1964

	
1901 1965
    /// \brief Forward iterator for values.
1902 1966
    ///
1903
    /// This iterator is an stl compatible forward
1967
    /// This iterator is an STL compatible forward
1904 1968
    /// iterator on the values of the map. The values can
1905
    /// be accessed in the [beginValue, endValue) range.
1906
    ///
1907
    class ValueIterator
1969
    /// be accessed in the <tt>[beginValue, endValue)</tt> range.
1970
    /// They are considered with multiplicity, so each value is
1971
    /// traversed for each item it is assigned to.
1972
    class ValueIt
1908 1973
      : public std::iterator<std::forward_iterator_tag, Value> {
1909
      friend class InvertableMap;
1974
      friend class CrossRefMap;
1910 1975
    private:
1911
      ValueIterator(typename Container::const_iterator _it)
1976
      ValueIt(typename Container::const_iterator _it)
1912 1977
        : it(_it) {}
1913 1978
    public:
1914 1979

	
1915
      ValueIterator() {}
1916

	
1917
      ValueIterator& operator++() { ++it; return *this; }
1918
      ValueIterator operator++(int) {
1919
        ValueIterator tmp(*this);
1980
      /// Constructor
1981
      ValueIt() {}
1982

	
1983
      /// \e
1984
      ValueIt& operator++() { ++it; return *this; }
1985
      /// \e
1986
      ValueIt operator++(int) {
1987
        ValueIt tmp(*this);
1920 1988
        operator++();
1921 1989
        return tmp;
1922 1990
      }
1923 1991

	
1992
      /// \e
1924 1993
      const Value& operator*() const { return it->first; }
1994
      /// \e
1925 1995
      const Value* operator->() const { return &(it->first); }
1926 1996

	
1927
      bool operator==(ValueIterator jt) const { return it == jt.it; }
1928
      bool operator!=(ValueIterator jt) const { return it != jt.it; }
1997
      /// \e
1998
      bool operator==(ValueIt jt) const { return it == jt.it; }
1999
      /// \e
2000
      bool operator!=(ValueIt jt) const { return it != jt.it; }
1929 2001

	
1930 2002
    private:
1931 2003
      typename Container::const_iterator it;
1932 2004
    };
2005
    
2006
    /// Alias for \c ValueIt
2007
    typedef ValueIt ValueIterator;
1933 2008

	
1934 2009
    /// \brief Returns an iterator to the first value.
1935 2010
    ///
1936
    /// Returns an stl compatible iterator to the
2011
    /// Returns an STL compatible iterator to the
1937 2012
    /// first value of the map. The values of the
1938
    /// map can be accessed in the [beginValue, endValue)
2013
    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
1939 2014
    /// range.
1940
    ValueIterator beginValue() const {
1941
      return ValueIterator(_inv_map.begin());
2015
    ValueIt beginValue() const {
2016
      return ValueIt(_inv_map.begin());
1942 2017
    }
1943 2018

	
1944 2019
    /// \brief Returns an iterator after the last value.
1945 2020
    ///
1946
    /// Returns an stl compatible iterator after the
2021
    /// Returns an STL compatible iterator after the
1947 2022
    /// last value of the map. The values of the
1948
    /// map can be accessed in the [beginValue, endValue)
2023
    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
1949 2024
    /// range.
1950
    ValueIterator endValue() const {
1951
      return ValueIterator(_inv_map.end());
2025
    ValueIt endValue() const {
2026
      return ValueIt(_inv_map.end());
1952 2027
    }
1953 2028

	
1954
    /// \brief The setter function of the map.
2029
    /// \brief Sets the value associated with the given key.
1955 2030
    ///
1956
    /// Sets the mapped value.
2031
    /// Sets the value associated with the given key.
1957 2032
    void set(const Key& key, const Value& val) {
1958 2033
      Value oldval = Map::operator[](key);
1959
      typename Container::iterator it = _inv_map.find(oldval);
1960
      if (it != _inv_map.end() && it->second == key) {
1961
        _inv_map.erase(it);
2034
      typename Container::iterator it;
2035
      for (it = _inv_map.equal_range(oldval).first;
2036
           it != _inv_map.equal_range(oldval).second; ++it) {
2037
        if (it->second == key) {
2038
          _inv_map.erase(it);
2039
          break;
2040
        }
1962 2041
      }
1963
      _inv_map.insert(make_pair(val, key));
2042
      _inv_map.insert(std::make_pair(val, key));
1964 2043
      Map::set(key, val);
1965 2044
    }
1966 2045

	
1967
    /// \brief The getter function of the map.
2046
    /// \brief Returns the value associated with the given key.
1968 2047
    ///
1969
    /// It gives back the value associated with the key.
2048
    /// Returns the value associated with the given key.
1970 2049
    typename MapTraits<Map>::ConstReturnValue
1971 2050
    operator[](const Key& key) const {
1972 2051
      return Map::operator[](key);
1973 2052
    }
1974 2053

	
1975
    /// \brief Gives back the item by its value.
2054
    /// \brief Gives back an item by its value.
1976 2055
    ///
1977
    /// Gives back the item by its value.
1978
    Key operator()(const Value& key) const {
1979
      typename Container::const_iterator it = _inv_map.find(key);
2056
    /// This function gives back an item that is assigned to
2057
    /// the given value or \c INVALID if no such item exists.
2058
    /// If there are more items with the same associated value,
2059
    /// only one of them is returned.
2060
    Key operator()(const Value& val) const {
2061
      typename Container::const_iterator it = _inv_map.find(val);
1980 2062
      return it != _inv_map.end() ? it->second : INVALID;
1981 2063
    }
2064
    
2065
    /// \brief Returns the number of items with the given value.
2066
    ///
2067
    /// This function returns the number of items with the given value
2068
    /// associated with it.
2069
    int count(const Value &val) const {
2070
      return _inv_map.count(val);
2071
    }
1982 2072

	
1983 2073
  protected:
1984 2074

	
1985
    /// \brief Erase the key from the map.
2075
    /// \brief Erase the key from the map and the inverse map.
1986 2076
    ///
1987
    /// Erase the key to the map. It is called by the
2077
    /// Erase the key from the map and the inverse map. It is called by the
1988 2078
    /// \c AlterationNotifier.
1989 2079
    virtual void erase(const Key& key) {
1990 2080
      Value val = Map::operator[](key);
1991
      typename Container::iterator it = _inv_map.find(val);
1992
      if (it != _inv_map.end() && it->second == key) {
1993
        _inv_map.erase(it);
2081
      typename Container::iterator it;
2082
      for (it = _inv_map.equal_range(val).first;
2083
           it != _inv_map.equal_range(val).second; ++it) {
2084
        if (it->second == key) {
2085
          _inv_map.erase(it);
2086
          break;
2087
        }
1994 2088
      }
1995 2089
      Map::erase(key);
1996 2090
    }
1997 2091

	
1998
    /// \brief Erase more keys from the map.
2092
    /// \brief Erase more keys from the map and the inverse map.
1999 2093
    ///
2000
    /// Erase more keys from the map. It is called by the
2094
    /// Erase more keys from the map and the inverse map. It is called by the
2001 2095
    /// \c AlterationNotifier.
2002 2096
    virtual void erase(const std::vector<Key>& keys) {
2003 2097
      for (int i = 0; i < int(keys.size()); ++i) {
2004 2098
        Value val = Map::operator[](keys[i]);
2005
        typename Container::iterator it = _inv_map.find(val);
2006
        if (it != _inv_map.end() && it->second == keys[i]) {
2007
          _inv_map.erase(it);
2099
        typename Container::iterator it;
2100
        for (it = _inv_map.equal_range(val).first;
2101
             it != _inv_map.equal_range(val).second; ++it) {
2102
          if (it->second == keys[i]) {
2103
            _inv_map.erase(it);
2104
            break;
2105
          }
2008 2106
        }
2009 2107
      }
2010 2108
      Map::erase(keys);
2011 2109
    }
2012 2110

	
2013
    /// \brief Clear the keys from the map and inverse map.
2111
    /// \brief Clear the keys from the map and the inverse map.
2014 2112
    ///
2015
    /// Clear the keys from the map and inverse map. It is called by the
2113
    /// Clear the keys from the map and the inverse map. It is called by the
2016 2114
    /// \c AlterationNotifier.
2017 2115
    virtual void clear() {
2018 2116
      _inv_map.clear();
2019 2117
      Map::clear();
2020 2118
    }
2021 2119

	
2022 2120
  public:
2023 2121

	
2024
    /// \brief The inverse map type.
2122
    /// \brief The inverse map type of CrossRefMap.
2025 2123
    ///
2026
    /// The inverse of this map. The subscript operator of the map
2027
    /// gives back always the item what was last assigned to the value.
2124
    /// The inverse map type of CrossRefMap. The subscript operator gives
2125
    /// back an item by its value.
2126
    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
2127
    /// \see inverse()
2028 2128
    class InverseMap {
2029 2129
    public:
2030
      /// \brief Constructor of the InverseMap.
2130
      /// \brief Constructor
2031 2131
      ///
2032 2132
      /// Constructor of the InverseMap.
2033
      explicit InverseMap(const InvertableMap& inverted)
2133
      explicit InverseMap(const CrossRefMap& inverted)
2034 2134
        : _inverted(inverted) {}
2035 2135

	
2036 2136
      /// The value type of the InverseMap.
2037
      typedef typename InvertableMap::Key Value;
2137
      typedef typename CrossRefMap::Key Value;
2038 2138
      /// The key type of the InverseMap.
2039
      typedef typename InvertableMap::Value Key;
2139
      typedef typename CrossRefMap::Value Key;
2040 2140

	
2041 2141
      /// \brief Subscript operator.
2042 2142
      ///
2043
      /// Subscript operator. It gives back always the item
2044
      /// what was last assigned to the value.
2143
      /// Subscript operator. It gives back an item
2144
      /// that is assigned to the given value or \c INVALID
2145
      /// if no such item exists.
2045 2146
      Value operator[](const Key& key) const {
2046 2147
        return _inverted(key);
2047 2148
      }
2048 2149

	
2049 2150
    private:
2050
      const InvertableMap& _inverted;
2151
      const CrossRefMap& _inverted;
2051 2152
    };
2052 2153

	
2053
    /// \brief It gives back the just readable inverse map.
2154
    /// \brief Gives back the inverse of the map.
2054 2155
    ///
2055
    /// It gives back the just readable inverse map.
2156
    /// Gives back the inverse of the CrossRefMap.
2056 2157
    InverseMap inverse() const {
2057 2158
      return InverseMap(*this);
2058 2159
    }
2059 2160

	
2060 2161
  };
2061 2162

	
2062
  /// \brief Provides a mutable, continuous and unique descriptor for each
2063
  /// item in the graph.
2163
  /// \brief Provides continuous and unique id for the
2164
  /// items of a graph.
2064 2165
  ///
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.
2166
  /// RangeIdMap provides a unique and continuous
2167
  /// id for each item of a given type (\c Node, \c Arc or
2168
  /// \c Edge) in a graph. This id is
2169
  ///  - \b unique: different items get different ids,
2170
  ///  - \b continuous: the range of the ids is the set of integers
2171
  ///    between 0 and \c n-1, where \c n is the number of the items of
2172
  ///    this type (\c Node, \c Arc or \c Edge).
2173
  ///  - So, the ids can change when deleting an item of the same type.
2073 2174
  ///
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;
2175
  /// Thus this id is not (necessarily) the same as what can get using
2176
  /// the \c id() function of the graph or \ref IdMap.
2177
  /// This map can be inverted with its member class \c InverseMap,
2178
  /// or with the \c operator()() member.
2179
  ///
2180
  /// \tparam GR The graph type.
2181
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
2182
  /// \c GR::Edge).
2183
  ///
2184
  /// \see IdMap
2185
  template <typename GR, typename K>
2186
  class RangeIdMap
2187
    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
2188

	
2189
    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Map;
2083 2190

	
2084 2191
  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;
2192
    /// The graph type of RangeIdMap.
2193
    typedef GR Graph;
2194
    typedef GR Digraph;
2195
    /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
2196
    typedef K Item;
2197
    /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
2198
    typedef K Key;
2199
    /// The value type of RangeIdMap.
2200
    typedef int Value;
2092 2201

	
2093 2202
    /// \brief Constructor.
2094 2203
    ///
2095
    /// Constructor for descriptor map.
2096
    explicit DescriptorMap(const Graph& _graph) : Map(_graph) {
2204
    /// Constructor.
2205
    explicit RangeIdMap(const Graph& gr) : Map(gr) {
2097 2206
      Item it;
2098 2207
      const typename Map::Notifier* nf = Map::notifier();
2099 2208
      for (nf->first(it); it != INVALID; nf->next(it)) {
2100 2209
        Map::set(it, _inv_map.size());
2101 2210
        _inv_map.push_back(it);
2102 2211
      }
2103 2212
    }
2104 2213

	
2105 2214
  protected:
2106 2215

	
2107
    /// \brief Add a new key to the map.
2216
    /// \brief Adds a new key to the map.
2108 2217
    ///
2109 2218
    /// Add a new key to the map. It is called by the
2110 2219
    /// \c AlterationNotifier.
2111 2220
    virtual void add(const Item& item) {
2112 2221
      Map::add(item);
2113 2222
      Map::set(item, _inv_map.size());
2114 2223
      _inv_map.push_back(item);
2115 2224
    }
2116 2225

	
2117 2226
    /// \brief Add more new keys to the map.
2118 2227
    ///
2119 2228
    /// Add more new keys to the map. It is called by the
2120 2229
    /// \c AlterationNotifier.
2121 2230
    virtual void add(const std::vector<Item>& items) {
2122 2231
      Map::add(items);
2123 2232
      for (int i = 0; i < int(items.size()); ++i) {
2124 2233
        Map::set(items[i], _inv_map.size());
2125 2234
        _inv_map.push_back(items[i]);
2126 2235
      }
2127 2236
    }
2128 2237

	
2129 2238
    /// \brief Erase the key from the map.
2130 2239
    ///
2131 2240
    /// Erase the key from the map. It is called by the
2132 2241
    /// \c AlterationNotifier.
2133 2242
    virtual void erase(const Item& item) {
2134 2243
      Map::set(_inv_map.back(), Map::operator[](item));
2135 2244
      _inv_map[Map::operator[](item)] = _inv_map.back();
2136 2245
      _inv_map.pop_back();
2137 2246
      Map::erase(item);
2138 2247
    }
2139 2248

	
2140 2249
    /// \brief Erase more keys from the map.
2141 2250
    ///
2142 2251
    /// Erase more keys from the map. It is called by the
2143 2252
    /// \c AlterationNotifier.
2144 2253
    virtual void erase(const std::vector<Item>& items) {
2145 2254
      for (int i = 0; i < int(items.size()); ++i) {
2146 2255
        Map::set(_inv_map.back(), Map::operator[](items[i]));
2147 2256
        _inv_map[Map::operator[](items[i])] = _inv_map.back();
2148 2257
        _inv_map.pop_back();
2149 2258
      }
2150 2259
      Map::erase(items);
2151 2260
    }
2152 2261

	
2153 2262
    /// \brief Build the unique map.
2154 2263
    ///
2155 2264
    /// Build the unique map. It is called by the
2156 2265
    /// \c AlterationNotifier.
2157 2266
    virtual void build() {
2158 2267
      Map::build();
2159 2268
      Item it;
2160 2269
      const typename Map::Notifier* nf = Map::notifier();
2161 2270
      for (nf->first(it); it != INVALID; nf->next(it)) {
2162 2271
        Map::set(it, _inv_map.size());
2163 2272
        _inv_map.push_back(it);
2164 2273
      }
2165 2274
    }
2166 2275

	
2167 2276
    /// \brief Clear the keys from the map.
2168 2277
    ///
2169 2278
    /// Clear the keys from the map. It is called by the
2170 2279
    /// \c AlterationNotifier.
2171 2280
    virtual void clear() {
2172 2281
      _inv_map.clear();
2173 2282
      Map::clear();
2174 2283
    }
2175 2284

	
2176 2285
  public:
2177 2286

	
2178 2287
    /// \brief Returns the maximal value plus one.
2179 2288
    ///
2180 2289
    /// Returns the maximal value plus one in the map.
2181 2290
    unsigned int size() const {
2182 2291
      return _inv_map.size();
2183 2292
    }
2184 2293

	
2185 2294
    /// \brief Swaps the position of the two items in the map.
2186 2295
    ///
2187 2296
    /// Swaps the position of the two items in the map.
2188 2297
    void swap(const Item& p, const Item& q) {
2189 2298
      int pi = Map::operator[](p);
2190 2299
      int qi = Map::operator[](q);
2191 2300
      Map::set(p, qi);
2192 2301
      _inv_map[qi] = p;
2193 2302
      Map::set(q, pi);
2194 2303
      _inv_map[pi] = q;
2195 2304
    }
2196 2305

	
2197
    /// \brief Gives back the \e descriptor of the item.
2306
    /// \brief Gives back the \e range \e id of the item
2198 2307
    ///
2199
    /// Gives back the mutable and unique \e descriptor of the map.
2308
    /// Gives back the \e range \e id of the item.
2200 2309
    int operator[](const Item& item) const {
2201 2310
      return Map::operator[](item);
2202 2311
    }
2203 2312

	
2204
    /// \brief Gives back the item by its descriptor.
2313
    /// \brief Gives back the item belonging to a \e range \e id
2205 2314
    ///
2206
    /// Gives back th item by its descriptor.
2315
    /// Gives back the item belonging to the given \e range \e id.
2207 2316
    Item operator()(int id) const {
2208 2317
      return _inv_map[id];
2209 2318
    }
2210 2319

	
2211 2320
  private:
2212 2321

	
2213 2322
    typedef std::vector<Item> Container;
2214 2323
    Container _inv_map;
2215 2324

	
2216 2325
  public:
2217
    /// \brief The inverse map type of DescriptorMap.
2326

	
2327
    /// \brief The inverse map type of RangeIdMap.
2218 2328
    ///
2219
    /// The inverse map type of DescriptorMap.
2329
    /// The inverse map type of RangeIdMap. The subscript operator gives
2330
    /// back an item by its \e range \e id.
2331
    /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
2220 2332
    class InverseMap {
2221 2333
    public:
2222
      /// \brief Constructor of the InverseMap.
2334
      /// \brief Constructor
2223 2335
      ///
2224 2336
      /// Constructor of the InverseMap.
2225
      explicit InverseMap(const DescriptorMap& inverted)
2337
      explicit InverseMap(const RangeIdMap& inverted)
2226 2338
        : _inverted(inverted) {}
2227 2339

	
2228 2340

	
2229 2341
      /// The value type of the InverseMap.
2230
      typedef typename DescriptorMap::Key Value;
2342
      typedef typename RangeIdMap::Key Value;
2231 2343
      /// The key type of the InverseMap.
2232
      typedef typename DescriptorMap::Value Key;
2344
      typedef typename RangeIdMap::Value Key;
2233 2345

	
2234 2346
      /// \brief Subscript operator.
2235 2347
      ///
2236 2348
      /// Subscript operator. It gives back the item
2237
      /// that the descriptor belongs to currently.
2349
      /// that the given \e range \e id currently belongs to.
2238 2350
      Value operator[](const Key& key) const {
2239 2351
        return _inverted(key);
2240 2352
      }
2241 2353

	
2242 2354
      /// \brief Size of the map.
2243 2355
      ///
2244 2356
      /// Returns the size of the map.
2245 2357
      unsigned int size() const {
2246 2358
        return _inverted.size();
2247 2359
      }
2248 2360

	
2249 2361
    private:
2250
      const DescriptorMap& _inverted;
2362
      const RangeIdMap& _inverted;
2251 2363
    };
2252 2364

	
2253 2365
    /// \brief Gives back the inverse of the map.
2254 2366
    ///
2255
    /// Gives back the inverse of the map.
2367
    /// Gives back the inverse of the RangeIdMap.
2256 2368
    const InverseMap inverse() const {
2257 2369
      return InverseMap(*this);
2258 2370
    }
2259 2371
  };
2260 2372

	
2261
  /// \brief Returns the source of the given arc.
2373
  /// \brief Returns a \c RangeIdMap class.
2262 2374
  ///
2263
  /// The SourceMap gives back the source Node of the given arc.
2375
  /// This function just returns an \c RangeIdMap class.
2376
  /// \relates RangeIdMap
2377
  template <typename K, typename GR>
2378
  inline RangeIdMap<GR, K> rangeIdMap(const GR& graph) {
2379
    return RangeIdMap<GR, K>(graph);
2380
  }
2381
  
2382
  /// \brief Dynamic iterable \c bool map.
2383
  ///
2384
  /// This class provides a special graph map type which can store a
2385
  /// \c bool value for graph items (\c Node, \c Arc or \c Edge).
2386
  /// For both \c true and \c false values it is possible to iterate on
2387
  /// the keys mapped to the value.
2388
  ///
2389
  /// This type is a reference map, so it can be modified with the
2390
  /// subscript operator.
2391
  ///
2392
  /// \tparam GR The graph type.
2393
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
2394
  /// \c GR::Edge).
2395
  ///
2396
  /// \see IterableIntMap, IterableValueMap
2397
  /// \see CrossRefMap
2398
  template <typename GR, typename K>
2399
  class IterableBoolMap
2400
    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
2401
  private:
2402
    typedef GR Graph;
2403

	
2404
    typedef typename ItemSetTraits<GR, K>::ItemIt KeyIt;
2405
    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Parent;
2406

	
2407
    std::vector<K> _array;
2408
    int _sep;
2409

	
2410
  public:
2411

	
2412
    /// Indicates that the map is reference map.
2413
    typedef True ReferenceMapTag;
2414

	
2415
    /// The key type
2416
    typedef K Key;
2417
    /// The value type
2418
    typedef bool Value;
2419
    /// The const reference type.
2420
    typedef const Value& ConstReference;
2421

	
2422
  private:
2423

	
2424
    int position(const Key& key) const {
2425
      return Parent::operator[](key);
2426
    }
2427

	
2428
  public:
2429

	
2430
    /// \brief Reference to the value of the map.
2431
    ///
2432
    /// This class is similar to the \c bool type. It can be converted to
2433
    /// \c bool and it provides the same operators.
2434
    class Reference {
2435
      friend class IterableBoolMap;
2436
    private:
2437
      Reference(IterableBoolMap& map, const Key& key)
2438
        : _key(key), _map(map) {}
2439
    public:
2440

	
2441
      Reference& operator=(const Reference& value) {
2442
        _map.set(_key, static_cast<bool>(value));
2443
         return *this;
2444
      }
2445

	
2446
      operator bool() const {
2447
        return static_cast<const IterableBoolMap&>(_map)[_key];
2448
      }
2449

	
2450
      Reference& operator=(bool value) {
2451
        _map.set(_key, value);
2452
        return *this;
2453
      }
2454
      Reference& operator&=(bool value) {
2455
        _map.set(_key, _map[_key] & value);
2456
        return *this;
2457
      }
2458
      Reference& operator|=(bool value) {
2459
        _map.set(_key, _map[_key] | value);
2460
        return *this;
2461
      }
2462
      Reference& operator^=(bool value) {
2463
        _map.set(_key, _map[_key] ^ value);
2464
        return *this;
2465
      }
2466
    private:
2467
      Key _key;
2468
      IterableBoolMap& _map;
2469
    };
2470

	
2471
    /// \brief Constructor of the map with a default value.
2472
    ///
2473
    /// Constructor of the map with a default value.
2474
    explicit IterableBoolMap(const Graph& graph, bool def = false)
2475
      : Parent(graph) {
2476
      typename Parent::Notifier* nf = Parent::notifier();
2477
      Key it;
2478
      for (nf->first(it); it != INVALID; nf->next(it)) {
2479
        Parent::set(it, _array.size());
2480
        _array.push_back(it);
2481
      }
2482
      _sep = (def ? _array.size() : 0);
2483
    }
2484

	
2485
    /// \brief Const subscript operator of the map.
2486
    ///
2487
    /// Const subscript operator of the map.
2488
    bool operator[](const Key& key) const {
2489
      return position(key) < _sep;
2490
    }
2491

	
2492
    /// \brief Subscript operator of the map.
2493
    ///
2494
    /// Subscript operator of the map.
2495
    Reference operator[](const Key& key) {
2496
      return Reference(*this, key);
2497
    }
2498

	
2499
    /// \brief Set operation of the map.
2500
    ///
2501
    /// Set operation of the map.
2502
    void set(const Key& key, bool value) {
2503
      int pos = position(key);
2504
      if (value) {
2505
        if (pos < _sep) return;
2506
        Key tmp = _array[_sep];
2507
        _array[_sep] = key;
2508
        Parent::set(key, _sep);
2509
        _array[pos] = tmp;
2510
        Parent::set(tmp, pos);
2511
        ++_sep;
2512
      } else {
2513
        if (pos >= _sep) return;
2514
        --_sep;
2515
        Key tmp = _array[_sep];
2516
        _array[_sep] = key;
2517
        Parent::set(key, _sep);
2518
        _array[pos] = tmp;
2519
        Parent::set(tmp, pos);
2520
      }
2521
    }
2522

	
2523
    /// \brief Set all items.
2524
    ///
2525
    /// Set all items in the map.
2526
    /// \note Constant time operation.
2527
    void setAll(bool value) {
2528
      _sep = (value ? _array.size() : 0);
2529
    }
2530

	
2531
    /// \brief Returns the number of the keys mapped to \c true.
2532
    ///
2533
    /// Returns the number of the keys mapped to \c true.
2534
    int trueNum() const {
2535
      return _sep;
2536
    }
2537

	
2538
    /// \brief Returns the number of the keys mapped to \c false.
2539
    ///
2540
    /// Returns the number of the keys mapped to \c false.
2541
    int falseNum() const {
2542
      return _array.size() - _sep;
2543
    }
2544

	
2545
    /// \brief Iterator for the keys mapped to \c true.
2546
    ///
2547
    /// Iterator for the keys mapped to \c true. It works
2548
    /// like a graph item iterator, it can be converted to
2549
    /// the key type of the map, incremented with \c ++ operator, and
2550
    /// if the iterator leaves the last valid key, it will be equal to
2551
    /// \c INVALID.
2552
    class TrueIt : public Key {
2553
    public:
2554
      typedef Key Parent;
2555

	
2556
      /// \brief Creates an iterator.
2557
      ///
2558
      /// Creates an iterator. It iterates on the
2559
      /// keys mapped to \c true.
2560
      /// \param map The IterableBoolMap.
2561
      explicit TrueIt(const IterableBoolMap& map)
2562
        : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),
2563
          _map(&map) {}
2564

	
2565
      /// \brief Invalid constructor \& conversion.
2566
      ///
2567
      /// This constructor initializes the iterator to be invalid.
2568
      /// \sa Invalid for more details.
2569
      TrueIt(Invalid) : Parent(INVALID), _map(0) {}
2570

	
2571
      /// \brief Increment operator.
2572
      ///
2573
      /// Increment operator.
2574
      TrueIt& operator++() {
2575
        int pos = _map->position(*this);
2576
        Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);
2577
        return *this;
2578
      }
2579

	
2580
    private:
2581
      const IterableBoolMap* _map;
2582
    };
2583

	
2584
    /// \brief Iterator for the keys mapped to \c false.
2585
    ///
2586
    /// Iterator for the keys mapped to \c false. It works
2587
    /// like a graph item iterator, it can be converted to
2588
    /// the key type of the map, incremented with \c ++ operator, and
2589
    /// if the iterator leaves the last valid key, it will be equal to
2590
    /// \c INVALID.
2591
    class FalseIt : public Key {
2592
    public:
2593
      typedef Key Parent;
2594

	
2595
      /// \brief Creates an iterator.
2596
      ///
2597
      /// Creates an iterator. It iterates on the
2598
      /// keys mapped to \c false.
2599
      /// \param map The IterableBoolMap.
2600
      explicit FalseIt(const IterableBoolMap& map)
2601
        : Parent(map._sep < int(map._array.size()) ?
2602
                 map._array.back() : INVALID), _map(&map) {}
2603

	
2604
      /// \brief Invalid constructor \& conversion.
2605
      ///
2606
      /// This constructor initializes the iterator to be invalid.
2607
      /// \sa Invalid for more details.
2608
      FalseIt(Invalid) : Parent(INVALID), _map(0) {}
2609

	
2610
      /// \brief Increment operator.
2611
      ///
2612
      /// Increment operator.
2613
      FalseIt& operator++() {
2614
        int pos = _map->position(*this);
2615
        Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);
2616
        return *this;
2617
      }
2618

	
2619
    private:
2620
      const IterableBoolMap* _map;
2621
    };
2622

	
2623
    /// \brief Iterator for the keys mapped to a given value.
2624
    ///
2625
    /// Iterator for the keys mapped to a given value. It works
2626
    /// like a graph item iterator, it can be converted to
2627
    /// the key type of the map, incremented with \c ++ operator, and
2628
    /// if the iterator leaves the last valid key, it will be equal to
2629
    /// \c INVALID.
2630
    class ItemIt : public Key {
2631
    public:
2632
      typedef Key Parent;
2633

	
2634
      /// \brief Creates an iterator with a value.
2635
      ///
2636
      /// Creates an iterator with a value. It iterates on the
2637
      /// keys mapped to the given value.
2638
      /// \param map The IterableBoolMap.
2639
      /// \param value The value.
2640
      ItemIt(const IterableBoolMap& map, bool value)
2641
        : Parent(value ? 
2642
                 (map._sep > 0 ?
2643
                  map._array[map._sep - 1] : INVALID) :
2644
                 (map._sep < int(map._array.size()) ?
2645
                  map._array.back() : INVALID)), _map(&map) {}
2646

	
2647
      /// \brief Invalid constructor \& conversion.
2648
      ///
2649
      /// This constructor initializes the iterator to be invalid.
2650
      /// \sa Invalid for more details.
2651
      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
2652

	
2653
      /// \brief Increment operator.
2654
      ///
2655
      /// Increment operator.
2656
      ItemIt& operator++() {
2657
        int pos = _map->position(*this);
2658
        int _sep = pos >= _map->_sep ? _map->_sep : 0;
2659
        Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID);
2660
        return *this;
2661
      }
2662

	
2663
    private:
2664
      const IterableBoolMap* _map;
2665
    };
2666

	
2667
  protected:
2668

	
2669
    virtual void add(const Key& key) {
2670
      Parent::add(key);
2671
      Parent::set(key, _array.size());
2672
      _array.push_back(key);
2673
    }
2674

	
2675
    virtual void add(const std::vector<Key>& keys) {
2676
      Parent::add(keys);
2677
      for (int i = 0; i < int(keys.size()); ++i) {
2678
        Parent::set(keys[i], _array.size());
2679
        _array.push_back(keys[i]);
2680
      }
2681
    }
2682

	
2683
    virtual void erase(const Key& key) {
2684
      int pos = position(key);
2685
      if (pos < _sep) {
2686
        --_sep;
2687
        Parent::set(_array[_sep], pos);
2688
        _array[pos] = _array[_sep];
2689
        Parent::set(_array.back(), _sep);
2690
        _array[_sep] = _array.back();
2691
        _array.pop_back();
2692
      } else {
2693
        Parent::set(_array.back(), pos);
2694
        _array[pos] = _array.back();
2695
        _array.pop_back();
2696
      }
2697
      Parent::erase(key);
2698
    }
2699

	
2700
    virtual void erase(const std::vector<Key>& keys) {
2701
      for (int i = 0; i < int(keys.size()); ++i) {
2702
        int pos = position(keys[i]);
2703
        if (pos < _sep) {
2704
          --_sep;
2705
          Parent::set(_array[_sep], pos);
2706
          _array[pos] = _array[_sep];
2707
          Parent::set(_array.back(), _sep);
2708
          _array[_sep] = _array.back();
2709
          _array.pop_back();
2710
        } else {
2711
          Parent::set(_array.back(), pos);
2712
          _array[pos] = _array.back();
2713
          _array.pop_back();
2714
        }
2715
      }
2716
      Parent::erase(keys);
2717
    }
2718

	
2719
    virtual void build() {
2720
      Parent::build();
2721
      typename Parent::Notifier* nf = Parent::notifier();
2722
      Key it;
2723
      for (nf->first(it); it != INVALID; nf->next(it)) {
2724
        Parent::set(it, _array.size());
2725
        _array.push_back(it);
2726
      }
2727
      _sep = 0;
2728
    }
2729

	
2730
    virtual void clear() {
2731
      _array.clear();
2732
      _sep = 0;
2733
      Parent::clear();
2734
    }
2735

	
2736
  };
2737

	
2738

	
2739
  namespace _maps_bits {
2740
    template <typename Item>
2741
    struct IterableIntMapNode {
2742
      IterableIntMapNode() : value(-1) {}
2743
      IterableIntMapNode(int _value) : value(_value) {}
2744
      Item prev, next;
2745
      int value;
2746
    };
2747
  }
2748

	
2749
  /// \brief Dynamic iterable integer map.
2750
  ///
2751
  /// This class provides a special graph map type which can store an
2752
  /// integer value for graph items (\c Node, \c Arc or \c Edge).
2753
  /// For each non-negative value it is possible to iterate on the keys
2754
  /// mapped to the value.
2755
  ///
2756
  /// This map is intended to be used with small integer values, for which
2757
  /// it is efficient, and supports iteration only for non-negative values.
2758
  /// If you need large values and/or iteration for negative integers,
2759
  /// consider to use \ref IterableValueMap instead.
2760
  ///
2761
  /// This type is a reference map, so it can be modified with the
2762
  /// subscript operator.
2763
  ///
2764
  /// \note The size of the data structure depends on the largest
2765
  /// value in the map.
2766
  ///
2767
  /// \tparam GR The graph type.
2768
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
2769
  /// \c GR::Edge).
2770
  ///
2771
  /// \see IterableBoolMap, IterableValueMap
2772
  /// \see CrossRefMap
2773
  template <typename GR, typename K>
2774
  class IterableIntMap
2775
    : protected ItemSetTraits<GR, K>::
2776
        template Map<_maps_bits::IterableIntMapNode<K> >::Type {
2777
  public:
2778
    typedef typename ItemSetTraits<GR, K>::
2779
      template Map<_maps_bits::IterableIntMapNode<K> >::Type Parent;
2780

	
2781
    /// The key type
2782
    typedef K Key;
2783
    /// The value type
2784
    typedef int Value;
2785
    /// The graph type
2786
    typedef GR Graph;
2787

	
2788
    /// \brief Constructor of the map.
2789
    ///
2790
    /// Constructor of the map. It sets all values to -1.
2791
    explicit IterableIntMap(const Graph& graph)
2792
      : Parent(graph) {}
2793

	
2794
    /// \brief Constructor of the map with a given value.
2795
    ///
2796
    /// Constructor of the map with a given value.
2797
    explicit IterableIntMap(const Graph& graph, int value)
2798
      : Parent(graph, _maps_bits::IterableIntMapNode<K>(value)) {
2799
      if (value >= 0) {
2800
        for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
2801
          lace(it);
2802
        }
2803
      }
2804
    }
2805

	
2806
  private:
2807

	
2808
    void unlace(const Key& key) {
2809
      typename Parent::Value& node = Parent::operator[](key);
2810
      if (node.value < 0) return;
2811
      if (node.prev != INVALID) {
2812
        Parent::operator[](node.prev).next = node.next;
2813
      } else {
2814
        _first[node.value] = node.next;
2815
      }
2816
      if (node.next != INVALID) {
2817
        Parent::operator[](node.next).prev = node.prev;
2818
      }
2819
      while (!_first.empty() && _first.back() == INVALID) {
2820
        _first.pop_back();
2821
      }
2822
    }
2823

	
2824
    void lace(const Key& key) {
2825
      typename Parent::Value& node = Parent::operator[](key);
2826
      if (node.value < 0) return;
2827
      if (node.value >= int(_first.size())) {
2828
        _first.resize(node.value + 1, INVALID);
2829
      }
2830
      node.prev = INVALID;
2831
      node.next = _first[node.value];
2832
      if (node.next != INVALID) {
2833
        Parent::operator[](node.next).prev = key;
2834
      }
2835
      _first[node.value] = key;
2836
    }
2837

	
2838
  public:
2839

	
2840
    /// Indicates that the map is reference map.
2841
    typedef True ReferenceMapTag;
2842

	
2843
    /// \brief Reference to the value of the map.
2844
    ///
2845
    /// This class is similar to the \c int type. It can
2846
    /// be converted to \c int and it has the same operators.
2847
    class Reference {
2848
      friend class IterableIntMap;
2849
    private:
2850
      Reference(IterableIntMap& map, const Key& key)
2851
        : _key(key), _map(map) {}
2852
    public:
2853

	
2854
      Reference& operator=(const Reference& value) {
2855
        _map.set(_key, static_cast<const int&>(value));
2856
         return *this;
2857
      }
2858

	
2859
      operator const int&() const {
2860
        return static_cast<const IterableIntMap&>(_map)[_key];
2861
      }
2862

	
2863
      Reference& operator=(int value) {
2864
        _map.set(_key, value);
2865
        return *this;
2866
      }
2867
      Reference& operator++() {
2868
        _map.set(_key, _map[_key] + 1);
2869
        return *this;
2870
      }
2871
      int operator++(int) {
2872
        int value = _map[_key];
2873
        _map.set(_key, value + 1);
2874
        return value;
2875
      }
2876
      Reference& operator--() {
2877
        _map.set(_key, _map[_key] - 1);
2878
        return *this;
2879
      }
2880
      int operator--(int) {
2881
        int value = _map[_key];
2882
        _map.set(_key, value - 1);
2883
        return value;
2884
      }
2885
      Reference& operator+=(int value) {
2886
        _map.set(_key, _map[_key] + value);
2887
        return *this;
2888
      }
2889
      Reference& operator-=(int value) {
2890
        _map.set(_key, _map[_key] - value);
2891
        return *this;
2892
      }
2893
      Reference& operator*=(int value) {
2894
        _map.set(_key, _map[_key] * value);
2895
        return *this;
2896
      }
2897
      Reference& operator/=(int value) {
2898
        _map.set(_key, _map[_key] / value);
2899
        return *this;
2900
      }
2901
      Reference& operator%=(int value) {
2902
        _map.set(_key, _map[_key] % value);
2903
        return *this;
2904
      }
2905
      Reference& operator&=(int value) {
2906
        _map.set(_key, _map[_key] & value);
2907
        return *this;
2908
      }
2909
      Reference& operator|=(int value) {
2910
        _map.set(_key, _map[_key] | value);
2911
        return *this;
2912
      }
2913
      Reference& operator^=(int value) {
2914
        _map.set(_key, _map[_key] ^ value);
2915
        return *this;
2916
      }
2917
      Reference& operator<<=(int value) {
2918
        _map.set(_key, _map[_key] << value);
2919
        return *this;
2920
      }
2921
      Reference& operator>>=(int value) {
2922
        _map.set(_key, _map[_key] >> value);
2923
        return *this;
2924
      }
2925

	
2926
    private:
2927
      Key _key;
2928
      IterableIntMap& _map;
2929
    };
2930

	
2931
    /// The const reference type.
2932
    typedef const Value& ConstReference;
2933

	
2934
    /// \brief Gives back the maximal value plus one.
2935
    ///
2936
    /// Gives back the maximal value plus one.
2937
    int size() const {
2938
      return _first.size();
2939
    }
2940

	
2941
    /// \brief Set operation of the map.
2942
    ///
2943
    /// Set operation of the map.
2944
    void set(const Key& key, const Value& value) {
2945
      unlace(key);
2946
      Parent::operator[](key).value = value;
2947
      lace(key);
2948
    }
2949

	
2950
    /// \brief Const subscript operator of the map.
2951
    ///
2952
    /// Const subscript operator of the map.
2953
    const Value& operator[](const Key& key) const {
2954
      return Parent::operator[](key).value;
2955
    }
2956

	
2957
    /// \brief Subscript operator of the map.
2958
    ///
2959
    /// Subscript operator of the map.
2960
    Reference operator[](const Key& key) {
2961
      return Reference(*this, key);
2962
    }
2963

	
2964
    /// \brief Iterator for the keys with the same value.
2965
    ///
2966
    /// Iterator for the keys with the same value. It works
2967
    /// like a graph item iterator, it can be converted to
2968
    /// the item type of the map, incremented with \c ++ operator, and
2969
    /// if the iterator leaves the last valid item, it will be equal to
2970
    /// \c INVALID.
2971
    class ItemIt : public Key {
2972
    public:
2973
      typedef Key Parent;
2974

	
2975
      /// \brief Invalid constructor \& conversion.
2976
      ///
2977
      /// This constructor initializes the iterator to be invalid.
2978
      /// \sa Invalid for more details.
2979
      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
2980

	
2981
      /// \brief Creates an iterator with a value.
2982
      ///
2983
      /// Creates an iterator with a value. It iterates on the
2984
      /// keys mapped to the given value.
2985
      /// \param map The IterableIntMap.
2986
      /// \param value The value.
2987
      ItemIt(const IterableIntMap& map, int value) : _map(&map) {
2988
        if (value < 0 || value >= int(_map->_first.size())) {
2989
          Parent::operator=(INVALID);
2990
        } else {
2991
          Parent::operator=(_map->_first[value]);
2992
        }
2993
      }
2994

	
2995
      /// \brief Increment operator.
2996
      ///
2997
      /// Increment operator.
2998
      ItemIt& operator++() {
2999
        Parent::operator=(_map->IterableIntMap::Parent::
3000
                          operator[](static_cast<Parent&>(*this)).next);
3001
        return *this;
3002
      }
3003

	
3004
    private:
3005
      const IterableIntMap* _map;
3006
    };
3007

	
3008
  protected:
3009

	
3010
    virtual void erase(const Key& key) {
3011
      unlace(key);
3012
      Parent::erase(key);
3013
    }
3014

	
3015
    virtual void erase(const std::vector<Key>& keys) {
3016
      for (int i = 0; i < int(keys.size()); ++i) {
3017
        unlace(keys[i]);
3018
      }
3019
      Parent::erase(keys);
3020
    }
3021

	
3022
    virtual void clear() {
3023
      _first.clear();
3024
      Parent::clear();
3025
    }
3026

	
3027
  private:
3028
    std::vector<Key> _first;
3029
  };
3030

	
3031
  namespace _maps_bits {
3032
    template <typename Item, typename Value>
3033
    struct IterableValueMapNode {
3034
      IterableValueMapNode(Value _value = Value()) : value(_value) {}
3035
      Item prev, next;
3036
      Value value;
3037
    };
3038
  }
3039

	
3040
  /// \brief Dynamic iterable map for comparable values.
3041
  ///
3042
  /// This class provides a special graph map type which can store a
3043
  /// comparable value for graph items (\c Node, \c Arc or \c Edge).
3044
  /// For each value it is possible to iterate on the keys mapped to
3045
  /// the value (\c ItemIt), and the values of the map can be accessed
3046
  /// with an STL compatible forward iterator (\c ValueIt).
3047
  /// The map stores a linked list for each value, which contains
3048
  /// the items mapped to the value, and the used values are stored
3049
  /// in balanced binary tree (\c std::map).
3050
  ///
3051
  /// \ref IterableBoolMap and \ref IterableIntMap are similar classes
3052
  /// specialized for \c bool and \c int values, respectively.
3053
  ///
3054
  /// This type is not reference map, so it cannot be modified with
3055
  /// the subscript operator.
3056
  ///
3057
  /// \tparam GR The graph type.
3058
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
3059
  /// \c GR::Edge).
3060
  /// \tparam V The value type of the map. It can be any comparable
3061
  /// value type.
3062
  ///
3063
  /// \see IterableBoolMap, IterableIntMap
3064
  /// \see CrossRefMap
3065
  template <typename GR, typename K, typename V>
3066
  class IterableValueMap
3067
    : protected ItemSetTraits<GR, K>::
3068
        template Map<_maps_bits::IterableValueMapNode<K, V> >::Type {
3069
  public:
3070
    typedef typename ItemSetTraits<GR, K>::
3071
      template Map<_maps_bits::IterableValueMapNode<K, V> >::Type Parent;
3072

	
3073
    /// The key type
3074
    typedef K Key;
3075
    /// The value type
3076
    typedef V Value;
3077
    /// The graph type
3078
    typedef GR Graph;
3079

	
3080
  public:
3081

	
3082
    /// \brief Constructor of the map with a given value.
3083
    ///
3084
    /// Constructor of the map with a given value.
3085
    explicit IterableValueMap(const Graph& graph,
3086
                              const Value& value = Value())
3087
      : Parent(graph, _maps_bits::IterableValueMapNode<K, V>(value)) {
3088
      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
3089
        lace(it);
3090
      }
3091
    }
3092

	
3093
  protected:
3094

	
3095
    void unlace(const Key& key) {
3096
      typename Parent::Value& node = Parent::operator[](key);
3097
      if (node.prev != INVALID) {
3098
        Parent::operator[](node.prev).next = node.next;
3099
      } else {
3100
        if (node.next != INVALID) {
3101
          _first[node.value] = node.next;
3102
        } else {
3103
          _first.erase(node.value);
3104
        }
3105
      }
3106
      if (node.next != INVALID) {
3107
        Parent::operator[](node.next).prev = node.prev;
3108
      }
3109
    }
3110

	
3111
    void lace(const Key& key) {
3112
      typename Parent::Value& node = Parent::operator[](key);
3113
      typename std::map<Value, Key>::iterator it = _first.find(node.value);
3114
      if (it == _first.end()) {
3115
        node.prev = node.next = INVALID;
3116
        _first.insert(std::make_pair(node.value, key));
3117
      } else {
3118
        node.prev = INVALID;
3119
        node.next = it->second;
3120
        if (node.next != INVALID) {
3121
          Parent::operator[](node.next).prev = key;
3122
        }
3123
        it->second = key;
3124
      }
3125
    }
3126

	
3127
  public:
3128

	
3129
    /// \brief Forward iterator for values.
3130
    ///
3131
    /// This iterator is an STL compatible forward
3132
    /// iterator on the values of the map. The values can
3133
    /// be accessed in the <tt>[beginValue, endValue)</tt> range.
3134
    class ValueIt
3135
      : public std::iterator<std::forward_iterator_tag, Value> {
3136
      friend class IterableValueMap;
3137
    private:
3138
      ValueIt(typename std::map<Value, Key>::const_iterator _it)
3139
        : it(_it) {}
3140
    public:
3141

	
3142
      /// Constructor
3143
      ValueIt() {}
3144

	
3145
      /// \e
3146
      ValueIt& operator++() { ++it; return *this; }
3147
      /// \e
3148
      ValueIt operator++(int) {
3149
        ValueIt tmp(*this);
3150
        operator++();
3151
        return tmp;
3152
      }
3153

	
3154
      /// \e
3155
      const Value& operator*() const { return it->first; }
3156
      /// \e
3157
      const Value* operator->() const { return &(it->first); }
3158

	
3159
      /// \e
3160
      bool operator==(ValueIt jt) const { return it == jt.it; }
3161
      /// \e
3162
      bool operator!=(ValueIt jt) const { return it != jt.it; }
3163

	
3164
    private:
3165
      typename std::map<Value, Key>::const_iterator it;
3166
    };
3167

	
3168
    /// \brief Returns an iterator to the first value.
3169
    ///
3170
    /// Returns an STL compatible iterator to the
3171
    /// first value of the map. The values of the
3172
    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
3173
    /// range.
3174
    ValueIt beginValue() const {
3175
      return ValueIt(_first.begin());
3176
    }
3177

	
3178
    /// \brief Returns an iterator after the last value.
3179
    ///
3180
    /// Returns an STL compatible iterator after the
3181
    /// last value of the map. The values of the
3182
    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
3183
    /// range.
3184
    ValueIt endValue() const {
3185
      return ValueIt(_first.end());
3186
    }
3187

	
3188
    /// \brief Set operation of the map.
3189
    ///
3190
    /// Set operation of the map.
3191
    void set(const Key& key, const Value& value) {
3192
      unlace(key);
3193
      Parent::operator[](key).value = value;
3194
      lace(key);
3195
    }
3196

	
3197
    /// \brief Const subscript operator of the map.
3198
    ///
3199
    /// Const subscript operator of the map.
3200
    const Value& operator[](const Key& key) const {
3201
      return Parent::operator[](key).value;
3202
    }
3203

	
3204
    /// \brief Iterator for the keys with the same value.
3205
    ///
3206
    /// Iterator for the keys with the same value. It works
3207
    /// like a graph item iterator, it can be converted to
3208
    /// the item type of the map, incremented with \c ++ operator, and
3209
    /// if the iterator leaves the last valid item, it will be equal to
3210
    /// \c INVALID.
3211
    class ItemIt : public Key {
3212
    public:
3213
      typedef Key Parent;
3214

	
3215
      /// \brief Invalid constructor \& conversion.
3216
      ///
3217
      /// This constructor initializes the iterator to be invalid.
3218
      /// \sa Invalid for more details.
3219
      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
3220

	
3221
      /// \brief Creates an iterator with a value.
3222
      ///
3223
      /// Creates an iterator with a value. It iterates on the
3224
      /// keys which have the given value.
3225
      /// \param map The IterableValueMap
3226
      /// \param value The value
3227
      ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
3228
        typename std::map<Value, Key>::const_iterator it =
3229
          map._first.find(value);
3230
        if (it == map._first.end()) {
3231
          Parent::operator=(INVALID);
3232
        } else {
3233
          Parent::operator=(it->second);
3234
        }
3235
      }
3236

	
3237
      /// \brief Increment operator.
3238
      ///
3239
      /// Increment Operator.
3240
      ItemIt& operator++() {
3241
        Parent::operator=(_map->IterableValueMap::Parent::
3242
                          operator[](static_cast<Parent&>(*this)).next);
3243
        return *this;
3244
      }
3245

	
3246

	
3247
    private:
3248
      const IterableValueMap* _map;
3249
    };
3250

	
3251
  protected:
3252

	
3253
    virtual void add(const Key& key) {
3254
      Parent::add(key);
3255
      unlace(key);
3256
    }
3257

	
3258
    virtual void add(const std::vector<Key>& keys) {
3259
      Parent::add(keys);
3260
      for (int i = 0; i < int(keys.size()); ++i) {
3261
        lace(keys[i]);
3262
      }
3263
    }
3264

	
3265
    virtual void erase(const Key& key) {
3266
      unlace(key);
3267
      Parent::erase(key);
3268
    }
3269

	
3270
    virtual void erase(const std::vector<Key>& keys) {
3271
      for (int i = 0; i < int(keys.size()); ++i) {
3272
        unlace(keys[i]);
3273
      }
3274
      Parent::erase(keys);
3275
    }
3276

	
3277
    virtual void build() {
3278
      Parent::build();
3279
      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
3280
        lace(it);
3281
      }
3282
    }
3283

	
3284
    virtual void clear() {
3285
      _first.clear();
3286
      Parent::clear();
3287
    }
3288

	
3289
  private:
3290
    std::map<Value, Key> _first;
3291
  };
3292

	
3293
  /// \brief Map of the source nodes of arcs in a digraph.
3294
  ///
3295
  /// SourceMap provides access for the source node of each arc in a digraph,
3296
  /// which is returned by the \c source() function of the digraph.
3297
  /// \tparam GR The digraph type.
2264 3298
  /// \see TargetMap
2265
  template <typename Digraph>
3299
  template <typename GR>
2266 3300
  class SourceMap {
2267 3301
  public:
2268 3302

	
2269
    typedef typename Digraph::Node Value;
2270
    typedef typename Digraph::Arc Key;
3303
    /// The key type (the \c Arc type of the digraph).
3304
    typedef typename GR::Arc Key;
3305
    /// The value type (the \c Node type of the digraph).
3306
    typedef typename GR::Node Value;
2271 3307

	
2272 3308
    /// \brief Constructor
2273 3309
    ///
2274
    /// Constructor
3310
    /// Constructor.
2275 3311
    /// \param digraph The digraph that the map belongs to.
2276
    explicit SourceMap(const Digraph& digraph) : _digraph(digraph) {}
2277

	
2278
    /// \brief The subscript operator.
3312
    explicit SourceMap(const GR& digraph) : _graph(digraph) {}
3313

	
3314
    /// \brief Returns the source node of the given arc.
2279 3315
    ///
2280
    /// The subscript operator.
2281
    /// \param arc The arc
2282
    /// \return The source of the arc
3316
    /// Returns the source node of the given arc.
2283 3317
    Value operator[](const Key& arc) const {
2284
      return _digraph.source(arc);
3318
      return _graph.source(arc);
2285 3319
    }
2286 3320

	
2287 3321
  private:
2288
    const Digraph& _digraph;
3322
    const GR& _graph;
2289 3323
  };
2290 3324

	
2291 3325
  /// \brief Returns a \c SourceMap class.
2292 3326
  ///
2293 3327
  /// This function just returns an \c SourceMap class.
2294 3328
  /// \relates SourceMap
2295
  template <typename Digraph>
2296
  inline SourceMap<Digraph> sourceMap(const Digraph& digraph) {
2297
    return SourceMap<Digraph>(digraph);
3329
  template <typename GR>
3330
  inline SourceMap<GR> sourceMap(const GR& graph) {
3331
    return SourceMap<GR>(graph);
2298 3332
  }
2299 3333

	
2300
  /// \brief Returns the target of the given arc.
3334
  /// \brief Map of the target nodes of arcs in a digraph.
2301 3335
  ///
2302
  /// The TargetMap gives back the target Node of the given arc.
3336
  /// TargetMap provides access for the target node of each arc in a digraph,
3337
  /// which is returned by the \c target() function of the digraph.
3338
  /// \tparam GR The digraph type.
2303 3339
  /// \see SourceMap
2304
  template <typename Digraph>
3340
  template <typename GR>
2305 3341
  class TargetMap {
2306 3342
  public:
2307 3343

	
2308
    typedef typename Digraph::Node Value;
2309
    typedef typename Digraph::Arc Key;
3344
    /// The key type (the \c Arc type of the digraph).
3345
    typedef typename GR::Arc Key;
3346
    /// The value type (the \c Node type of the digraph).
3347
    typedef typename GR::Node Value;
2310 3348

	
2311 3349
    /// \brief Constructor
2312 3350
    ///
2313
    /// Constructor
3351
    /// Constructor.
2314 3352
    /// \param digraph The digraph that the map belongs to.
2315
    explicit TargetMap(const Digraph& digraph) : _digraph(digraph) {}
2316

	
2317
    /// \brief The subscript operator.
3353
    explicit TargetMap(const GR& digraph) : _graph(digraph) {}
3354

	
3355
    /// \brief Returns the target node of the given arc.
2318 3356
    ///
2319
    /// The subscript operator.
2320
    /// \param e The arc
2321
    /// \return The target of the arc
3357
    /// Returns the target node of the given arc.
2322 3358
    Value operator[](const Key& e) const {
2323
      return _digraph.target(e);
3359
      return _graph.target(e);
2324 3360
    }
2325 3361

	
2326 3362
  private:
2327
    const Digraph& _digraph;
3363
    const GR& _graph;
2328 3364
  };
2329 3365

	
2330 3366
  /// \brief Returns a \c TargetMap class.
2331 3367
  ///
2332 3368
  /// This function just returns a \c TargetMap class.
2333 3369
  /// \relates TargetMap
2334
  template <typename Digraph>
2335
  inline TargetMap<Digraph> targetMap(const Digraph& digraph) {
2336
    return TargetMap<Digraph>(digraph);
3370
  template <typename GR>
3371
  inline TargetMap<GR> targetMap(const GR& graph) {
3372
    return TargetMap<GR>(graph);
2337 3373
  }
2338 3374

	
2339
  /// \brief Returns the "forward" directed arc view of an edge.
3375
  /// \brief Map of the "forward" directed arc view of edges in a graph.
2340 3376
  ///
2341
  /// Returns the "forward" directed arc view of an edge.
3377
  /// ForwardMap provides access for the "forward" directed arc view of
3378
  /// each edge in a graph, which is returned by the \c direct() function
3379
  /// of the graph with \c true parameter.
3380
  /// \tparam GR The graph type.
2342 3381
  /// \see BackwardMap
2343
  template <typename Graph>
3382
  template <typename GR>
2344 3383
  class ForwardMap {
2345 3384
  public:
2346 3385

	
2347
    typedef typename Graph::Arc Value;
2348
    typedef typename Graph::Edge Key;
3386
    /// The key type (the \c Edge type of the digraph).
3387
    typedef typename GR::Edge Key;
3388
    /// The value type (the \c Arc type of the digraph).
3389
    typedef typename GR::Arc Value;
2349 3390

	
2350 3391
    /// \brief Constructor
2351 3392
    ///
2352
    /// Constructor
3393
    /// Constructor.
2353 3394
    /// \param graph The graph that the map belongs to.
2354
    explicit ForwardMap(const Graph& graph) : _graph(graph) {}
2355

	
2356
    /// \brief The subscript operator.
3395
    explicit ForwardMap(const GR& graph) : _graph(graph) {}
3396

	
3397
    /// \brief Returns the "forward" directed arc view of the given edge.
2357 3398
    ///
2358
    /// The subscript operator.
2359
    /// \param key An edge
2360
    /// \return The "forward" directed arc view of edge
3399
    /// Returns the "forward" directed arc view of the given edge.
2361 3400
    Value operator[](const Key& key) const {
2362 3401
      return _graph.direct(key, true);
2363 3402
    }
2364 3403

	
2365 3404
  private:
2366
    const Graph& _graph;
3405
    const GR& _graph;
2367 3406
  };
2368 3407

	
2369 3408
  /// \brief Returns a \c ForwardMap class.
2370 3409
  ///
2371 3410
  /// This function just returns an \c ForwardMap class.
2372 3411
  /// \relates ForwardMap
2373
  template <typename Graph>
2374
  inline ForwardMap<Graph> forwardMap(const Graph& graph) {
2375
    return ForwardMap<Graph>(graph);
3412
  template <typename GR>
3413
  inline ForwardMap<GR> forwardMap(const GR& graph) {
3414
    return ForwardMap<GR>(graph);
2376 3415
  }
2377 3416

	
2378
  /// \brief Returns the "backward" directed arc view of an edge.
3417
  /// \brief Map of the "backward" directed arc view of edges in a graph.
2379 3418
  ///
2380
  /// Returns the "backward" directed arc view of an edge.
3419
  /// BackwardMap provides access for the "backward" directed arc view of
3420
  /// each edge in a graph, which is returned by the \c direct() function
3421
  /// of the graph with \c false parameter.
3422
  /// \tparam GR The graph type.
2381 3423
  /// \see ForwardMap
2382
  template <typename Graph>
3424
  template <typename GR>
2383 3425
  class BackwardMap {
2384 3426
  public:
2385 3427

	
2386
    typedef typename Graph::Arc Value;
2387
    typedef typename Graph::Edge Key;
3428
    /// The key type (the \c Edge type of the digraph).
3429
    typedef typename GR::Edge Key;
3430
    /// The value type (the \c Arc type of the digraph).
3431
    typedef typename GR::Arc Value;
2388 3432

	
2389 3433
    /// \brief Constructor
2390 3434
    ///
2391
    /// Constructor
3435
    /// Constructor.
2392 3436
    /// \param graph The graph that the map belongs to.
2393
    explicit BackwardMap(const Graph& graph) : _graph(graph) {}
2394

	
2395
    /// \brief The subscript operator.
3437
    explicit BackwardMap(const GR& graph) : _graph(graph) {}
3438

	
3439
    /// \brief Returns the "backward" directed arc view of the given edge.
2396 3440
    ///
2397
    /// The subscript operator.
2398
    /// \param key An edge
2399
    /// \return The "backward" directed arc view of edge
3441
    /// Returns the "backward" directed arc view of the given edge.
2400 3442
    Value operator[](const Key& key) const {
2401 3443
      return _graph.direct(key, false);
2402 3444
    }
2403 3445

	
2404 3446
  private:
2405
    const Graph& _graph;
3447
    const GR& _graph;
2406 3448
  };
2407 3449

	
2408 3450
  /// \brief Returns a \c BackwardMap class
2409 3451

	
2410 3452
  /// This function just returns a \c BackwardMap class.
2411 3453
  /// \relates BackwardMap
2412
  template <typename Graph>
2413
  inline BackwardMap<Graph> backwardMap(const Graph& graph) {
2414
    return BackwardMap<Graph>(graph);
3454
  template <typename GR>
3455
  inline BackwardMap<GR> backwardMap(const GR& graph) {
3456
    return BackwardMap<GR>(graph);
2415 3457
  }
2416 3458

	
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.
3459
  /// \brief Map of the in-degrees of nodes in a digraph.
2459 3460
  ///
2460 3461
  /// 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
3462
  /// the degrees are stored in a standard \c NodeMap, so each query is done
2462 3463
  /// in constant time. On the other hand, the values are updated automatically
2463 3464
  /// whenever the digraph changes.
2464 3465
  ///
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()",
3466
  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
3467
  /// may provide alternative ways to modify the digraph.
3468
  /// The correct behavior of InDegMap is not guarantied if these additional
3469
  /// features are used. For example the functions
3470
  /// \ref ListDigraph::changeSource() "changeSource()",
2469 3471
  /// \ref ListDigraph::changeTarget() "changeTarget()" and
2470 3472
  /// \ref ListDigraph::reverseArc() "reverseArc()"
2471 3473
  /// of \ref ListDigraph will \e not update the degree values correctly.
2472 3474
  ///
2473 3475
  /// \sa OutDegMap
2474

	
2475
  template <typename _Digraph>
3476
  template <typename GR>
2476 3477
  class InDegMap
2477
    : protected ItemSetTraits<_Digraph, typename _Digraph::Arc>
3478
    : protected ItemSetTraits<GR, typename GR::Arc>
2478 3479
      ::ItemNotifier::ObserverBase {
2479 3480

	
2480 3481
  public:
2481 3482

	
2482
    typedef _Digraph Digraph;
3483
    /// The graph type of InDegMap
3484
    typedef GR Graph;
3485
    typedef GR Digraph;
3486
    /// The key type
3487
    typedef typename Digraph::Node Key;
3488
    /// The value type
2483 3489
    typedef int Value;
2484
    typedef typename Digraph::Node Key;
2485 3490

	
2486 3491
    typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
2487 3492
    ::ItemNotifier::ObserverBase Parent;
2488 3493

	
2489 3494
  private:
2490 3495

	
2491 3496
    class AutoNodeMap
2492 3497
      : public ItemSetTraits<Digraph, Key>::template Map<int>::Type {
2493 3498
    public:
2494 3499

	
2495 3500
      typedef typename ItemSetTraits<Digraph, Key>::
2496 3501
      template Map<int>::Type Parent;
2497 3502

	
2498 3503
      AutoNodeMap(const Digraph& digraph) : Parent(digraph, 0) {}
2499 3504

	
2500 3505
      virtual void add(const Key& key) {
2501 3506
        Parent::add(key);
2502 3507
        Parent::set(key, 0);
2503 3508
      }
2504 3509

	
2505 3510
      virtual void add(const std::vector<Key>& keys) {
2506 3511
        Parent::add(keys);
2507 3512
        for (int i = 0; i < int(keys.size()); ++i) {
2508 3513
          Parent::set(keys[i], 0);
2509 3514
        }
2510 3515
      }
2511 3516

	
2512 3517
      virtual void build() {
2513 3518
        Parent::build();
2514 3519
        Key it;
2515 3520
        typename Parent::Notifier* nf = Parent::notifier();
2516 3521
        for (nf->first(it); it != INVALID; nf->next(it)) {
2517 3522
          Parent::set(it, 0);
2518 3523
        }
2519 3524
      }
2520 3525
    };
2521 3526

	
2522 3527
  public:
2523 3528

	
2524 3529
    /// \brief Constructor.
2525 3530
    ///
2526
    /// Constructor for creating in-degree map.
2527
    explicit InDegMap(const Digraph& digraph)
2528
      : _digraph(digraph), _deg(digraph) {
3531
    /// Constructor for creating an in-degree map.
3532
    explicit InDegMap(const Digraph& graph)
3533
      : _digraph(graph), _deg(graph) {
2529 3534
      Parent::attach(_digraph.notifier(typename Digraph::Arc()));
2530 3535

	
2531 3536
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2532 3537
        _deg[it] = countInArcs(_digraph, it);
2533 3538
      }
2534 3539
    }
2535 3540

	
3541
    /// \brief Gives back the in-degree of a Node.
3542
    ///
2536 3543
    /// Gives back the in-degree of a Node.
2537 3544
    int operator[](const Key& key) const {
2538 3545
      return _deg[key];
2539 3546
    }
2540 3547

	
2541 3548
  protected:
2542 3549

	
2543 3550
    typedef typename Digraph::Arc Arc;
2544 3551

	
2545 3552
    virtual void add(const Arc& arc) {
2546 3553
      ++_deg[_digraph.target(arc)];
2547 3554
    }
2548 3555

	
2549 3556
    virtual void add(const std::vector<Arc>& arcs) {
2550 3557
      for (int i = 0; i < int(arcs.size()); ++i) {
2551 3558
        ++_deg[_digraph.target(arcs[i])];
2552 3559
      }
2553 3560
    }
2554 3561

	
2555 3562
    virtual void erase(const Arc& arc) {
2556 3563
      --_deg[_digraph.target(arc)];
2557 3564
    }
2558 3565

	
2559 3566
    virtual void erase(const std::vector<Arc>& arcs) {
2560 3567
      for (int i = 0; i < int(arcs.size()); ++i) {
2561 3568
        --_deg[_digraph.target(arcs[i])];
2562 3569
      }
2563 3570
    }
2564 3571

	
2565 3572
    virtual void build() {
2566 3573
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2567 3574
        _deg[it] = countInArcs(_digraph, it);
2568 3575
      }
2569 3576
    }
2570 3577

	
2571 3578
    virtual void clear() {
2572 3579
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2573 3580
        _deg[it] = 0;
2574 3581
      }
2575 3582
    }
2576 3583
  private:
2577 3584

	
2578 3585
    const Digraph& _digraph;
2579 3586
    AutoNodeMap _deg;
2580 3587
  };
2581 3588

	
2582
  /// \brief Map of the node out-degrees.
3589
  /// \brief Map of the out-degrees of nodes in a digraph.
2583 3590
  ///
2584 3591
  /// 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
3592
  /// the degrees are stored in a standard \c NodeMap, so each query is done
2586 3593
  /// in constant time. On the other hand, the values are updated automatically
2587 3594
  /// whenever the digraph changes.
2588 3595
  ///
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()",
3596
  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
3597
  /// may provide alternative ways to modify the digraph.
3598
  /// The correct behavior of OutDegMap is not guarantied if these additional
3599
  /// features are used. For example the functions
3600
  /// \ref ListDigraph::changeSource() "changeSource()",
2593 3601
  /// \ref ListDigraph::changeTarget() "changeTarget()" and
2594 3602
  /// \ref ListDigraph::reverseArc() "reverseArc()"
2595 3603
  /// of \ref ListDigraph will \e not update the degree values correctly.
2596 3604
  ///
2597 3605
  /// \sa InDegMap
2598

	
2599
  template <typename _Digraph>
3606
  template <typename GR>
2600 3607
  class OutDegMap
2601
    : protected ItemSetTraits<_Digraph, typename _Digraph::Arc>
3608
    : protected ItemSetTraits<GR, typename GR::Arc>
2602 3609
      ::ItemNotifier::ObserverBase {
2603 3610

	
2604 3611
  public:
2605 3612

	
2606
    typedef _Digraph Digraph;
3613
    /// The graph type of OutDegMap
3614
    typedef GR Graph;
3615
    typedef GR Digraph;
3616
    /// The key type
3617
    typedef typename Digraph::Node Key;
3618
    /// The value type
2607 3619
    typedef int Value;
2608
    typedef typename Digraph::Node Key;
2609 3620

	
2610 3621
    typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
2611 3622
    ::ItemNotifier::ObserverBase Parent;
2612 3623

	
2613 3624
  private:
2614 3625

	
2615 3626
    class AutoNodeMap
2616 3627
      : public ItemSetTraits<Digraph, Key>::template Map<int>::Type {
2617 3628
    public:
2618 3629

	
2619 3630
      typedef typename ItemSetTraits<Digraph, Key>::
2620 3631
      template Map<int>::Type Parent;
2621 3632

	
2622 3633
      AutoNodeMap(const Digraph& digraph) : Parent(digraph, 0) {}
2623 3634

	
2624 3635
      virtual void add(const Key& key) {
2625 3636
        Parent::add(key);
2626 3637
        Parent::set(key, 0);
2627 3638
      }
2628 3639
      virtual void add(const std::vector<Key>& keys) {
2629 3640
        Parent::add(keys);
2630 3641
        for (int i = 0; i < int(keys.size()); ++i) {
2631 3642
          Parent::set(keys[i], 0);
2632 3643
        }
2633 3644
      }
2634 3645
      virtual void build() {
2635 3646
        Parent::build();
2636 3647
        Key it;
2637 3648
        typename Parent::Notifier* nf = Parent::notifier();
2638 3649
        for (nf->first(it); it != INVALID; nf->next(it)) {
2639 3650
          Parent::set(it, 0);
2640 3651
        }
2641 3652
      }
2642 3653
    };
2643 3654

	
2644 3655
  public:
2645 3656

	
2646 3657
    /// \brief Constructor.
2647 3658
    ///
2648
    /// Constructor for creating out-degree map.
2649
    explicit OutDegMap(const Digraph& digraph)
2650
      : _digraph(digraph), _deg(digraph) {
3659
    /// Constructor for creating an out-degree map.
3660
    explicit OutDegMap(const Digraph& graph)
3661
      : _digraph(graph), _deg(graph) {
2651 3662
      Parent::attach(_digraph.notifier(typename Digraph::Arc()));
2652 3663

	
2653 3664
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2654 3665
        _deg[it] = countOutArcs(_digraph, it);
2655 3666
      }
2656 3667
    }
2657 3668

	
3669
    /// \brief Gives back the out-degree of a Node.
3670
    ///
2658 3671
    /// Gives back the out-degree of a Node.
2659 3672
    int operator[](const Key& key) const {
2660 3673
      return _deg[key];
2661 3674
    }
2662 3675

	
2663 3676
  protected:
2664 3677

	
2665 3678
    typedef typename Digraph::Arc Arc;
2666 3679

	
2667 3680
    virtual void add(const Arc& arc) {
2668 3681
      ++_deg[_digraph.source(arc)];
2669 3682
    }
2670 3683

	
2671 3684
    virtual void add(const std::vector<Arc>& arcs) {
2672 3685
      for (int i = 0; i < int(arcs.size()); ++i) {
2673 3686
        ++_deg[_digraph.source(arcs[i])];
2674 3687
      }
2675 3688
    }
2676 3689

	
2677 3690
    virtual void erase(const Arc& arc) {
2678 3691
      --_deg[_digraph.source(arc)];
2679 3692
    }
2680 3693

	
2681 3694
    virtual void erase(const std::vector<Arc>& arcs) {
2682 3695
      for (int i = 0; i < int(arcs.size()); ++i) {
2683 3696
        --_deg[_digraph.source(arcs[i])];
2684 3697
      }
2685 3698
    }
2686 3699

	
2687 3700
    virtual void build() {
2688 3701
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2689 3702
        _deg[it] = countOutArcs(_digraph, it);
2690 3703
      }
2691 3704
    }
2692 3705

	
2693 3706
    virtual void clear() {
2694 3707
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2695 3708
        _deg[it] = 0;
2696 3709
      }
2697 3710
    }
2698 3711
  private:
2699 3712

	
2700 3713
    const Digraph& _digraph;
2701 3714
    AutoNodeMap _deg;
2702 3715
  };
2703 3716

	
3717
  /// \brief Potential difference map
3718
  ///
3719
  /// PotentialDifferenceMap returns the difference between the potentials of
3720
  /// the source and target nodes of each arc in a digraph, i.e. it returns
3721
  /// \code
3722
  ///   potential[gr.target(arc)] - potential[gr.source(arc)].
3723
  /// \endcode
3724
  /// \tparam GR The digraph type.
3725
  /// \tparam POT A node map storing the potentials.
3726
  template <typename GR, typename POT>
3727
  class PotentialDifferenceMap {
3728
  public:
3729
    /// Key type
3730
    typedef typename GR::Arc Key;
3731
    /// Value type
3732
    typedef typename POT::Value Value;
3733

	
3734
    /// \brief Constructor
3735
    ///
3736
    /// Contructor of the map.
3737
    explicit PotentialDifferenceMap(const GR& gr,
3738
                                    const POT& potential)
3739
      : _digraph(gr), _potential(potential) {}
3740

	
3741
    /// \brief Returns the potential difference for the given arc.
3742
    ///
3743
    /// Returns the potential difference for the given arc, i.e.
3744
    /// \code
3745
    ///   potential[gr.target(arc)] - potential[gr.source(arc)].
3746
    /// \endcode
3747
    Value operator[](const Key& arc) const {
3748
      return _potential[_digraph.target(arc)] -
3749
        _potential[_digraph.source(arc)];
3750
    }
3751

	
3752
  private:
3753
    const GR& _digraph;
3754
    const POT& _potential;
3755
  };
3756

	
3757
  /// \brief Returns a PotentialDifferenceMap.
3758
  ///
3759
  /// This function just returns a PotentialDifferenceMap.
3760
  /// \relates PotentialDifferenceMap
3761
  template <typename GR, typename POT>
3762
  PotentialDifferenceMap<GR, POT>
3763
  potentialDifferenceMap(const GR& gr, const POT& potential) {
3764
    return PotentialDifferenceMap<GR, POT>(gr, potential);
3765
  }
3766

	
2704 3767
  /// @}
2705 3768
}
2706 3769

	
2707 3770
#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
  ///Base of SmartDigraph
36 35

	
37
  ///Base of SmartDigraph
38
  ///
39 36
  class SmartDigraphBase {
40 37
  protected:
41 38

	
42 39
    struct NodeT
43 40
    {
44 41
      int first_in, first_out;
45 42
      NodeT() {}
46 43
    };
47 44
    struct ArcT
48 45
    {
49 46
      int target, source, next_in, next_out;
50 47
      ArcT() {}
51 48
    };
52 49

	
53 50
    std::vector<NodeT> nodes;
54 51
    std::vector<ArcT> arcs;
55 52

	
56 53
  public:
57 54

	
58
    typedef SmartDigraphBase Graph;
55
    typedef SmartDigraphBase Digraph;
59 56

	
60 57
    class Node;
61 58
    class Arc;
62 59

	
63 60
  public:
64 61

	
65 62
    SmartDigraphBase() : nodes(), arcs() { }
66 63
    SmartDigraphBase(const SmartDigraphBase &_g)
67 64
      : nodes(_g.nodes), arcs(_g.arcs) { }
68 65

	
69 66
    typedef True NodeNumTag;
70
    typedef True EdgeNumTag;
67
    typedef True ArcNumTag;
71 68

	
72 69
    int nodeNum() const { return nodes.size(); }
73 70
    int arcNum() const { return arcs.size(); }
74 71

	
75 72
    int maxNodeId() const { return nodes.size()-1; }
76 73
    int maxArcId() const { return arcs.size()-1; }
77 74

	
78 75
    Node addNode() {
79 76
      int n = nodes.size();
80 77
      nodes.push_back(NodeT());
81 78
      nodes[n].first_in = -1;
82 79
      nodes[n].first_out = -1;
83 80
      return Node(n);
84 81
    }
85 82

	
86 83
    Arc addArc(Node u, Node v) {
87 84
      int n = arcs.size();
88 85
      arcs.push_back(ArcT());
89 86
      arcs[n].source = u._id;
90 87
      arcs[n].target = v._id;
91 88
      arcs[n].next_out = nodes[u._id].first_out;
92 89
      arcs[n].next_in = nodes[v._id].first_in;
93 90
      nodes[u._id].first_out = nodes[v._id].first_in = n;
94 91

	
95 92
      return Arc(n);
96 93
    }
97 94

	
98 95
    void clear() {
99 96
      arcs.clear();
100 97
      nodes.clear();
101 98
    }
102 99

	
103 100
    Node source(Arc a) const { return Node(arcs[a._id].source); }
104 101
    Node target(Arc a) const { return Node(arcs[a._id].target); }
105 102

	
106 103
    static int id(Node v) { return v._id; }
107 104
    static int id(Arc a) { return a._id; }
108 105

	
109 106
    static Node nodeFromId(int id) { return Node(id);}
110 107
    static Arc arcFromId(int id) { return Arc(id);}
111 108

	
112 109
    bool valid(Node n) const {
113 110
      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
114 111
    }
115 112
    bool valid(Arc a) const {
116 113
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
117 114
    }
118 115

	
119 116
    class Node {
120 117
      friend class SmartDigraphBase;
121 118
      friend class SmartDigraph;
122 119

	
123 120
    protected:
124 121
      int _id;
125 122
      explicit Node(int id) : _id(id) {}
126 123
    public:
127 124
      Node() {}
128 125
      Node (Invalid) : _id(-1) {}
129 126
      bool operator==(const Node i) const {return _id == i._id;}
130 127
      bool operator!=(const Node i) const {return _id != i._id;}
131 128
      bool operator<(const Node i) const {return _id < i._id;}
132 129
    };
133 130

	
134 131

	
135 132
    class Arc {
136 133
      friend class SmartDigraphBase;
137 134
      friend class SmartDigraph;
138 135

	
139 136
    protected:
140 137
      int _id;
141 138
      explicit Arc(int id) : _id(id) {}
142 139
    public:
143 140
      Arc() { }
144 141
      Arc (Invalid) : _id(-1) {}
145 142
      bool operator==(const Arc i) const {return _id == i._id;}
146 143
      bool operator!=(const Arc i) const {return _id != i._id;}
147 144
      bool operator<(const Arc i) const {return _id < i._id;}
148 145
    };
149 146

	
150 147
    void first(Node& node) const {
151 148
      node._id = nodes.size() - 1;
152 149
    }
153 150

	
154 151
    static void next(Node& node) {
155 152
      --node._id;
156 153
    }
157 154

	
158 155
    void first(Arc& arc) const {
159 156
      arc._id = arcs.size() - 1;
160 157
    }
161 158

	
162 159
    static void next(Arc& arc) {
163 160
      --arc._id;
164 161
    }
165 162

	
166 163
    void firstOut(Arc& arc, const Node& node) const {
167 164
      arc._id = nodes[node._id].first_out;
168 165
    }
169 166

	
170 167
    void nextOut(Arc& arc) const {
171 168
      arc._id = arcs[arc._id].next_out;
172 169
    }
173 170

	
174 171
    void firstIn(Arc& arc, const Node& node) const {
175 172
      arc._id = nodes[node._id].first_in;
176 173
    }
177 174

	
178 175
    void nextIn(Arc& arc) const {
179 176
      arc._id = arcs[arc._id].next_in;
180 177
    }
181 178

	
182 179
  };
183 180

	
184 181
  typedef DigraphExtender<SmartDigraphBase> ExtendedSmartDigraphBase;
185 182

	
186 183
  ///\ingroup graphs
187 184
  ///
188 185
  ///\brief A smart directed graph class.
189 186
  ///
190
  ///This is a simple and fast digraph implementation.
191
  ///It is also quite memory efficient, but at the price
192
  ///that <b> it does support only limited (only stack-like)
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.
187
  ///\ref SmartDigraph is a simple and fast digraph implementation.
188
  ///It is also quite memory efficient but at the price
189
  ///that it does not support node and arc deletion 
190
  ///(except for the Snapshot feature).
197 191
  ///
198
  ///\sa concepts::Digraph.
192
  ///This type fully conforms to the \ref concepts::Digraph "Digraph concept"
193
  ///and it also provides some additional functionalities.
194
  ///Most of its member functions and nested classes are documented
195
  ///only in the concept class.
196
  ///
197
  ///\sa concepts::Digraph
198
  ///\sa SmartGraph
199 199
  class SmartDigraph : public ExtendedSmartDigraphBase {
200
  public:
201

	
202 200
    typedef ExtendedSmartDigraphBase Parent;
203 201

	
204 202
  private:
205

	
206
    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
207

	
208
    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
209
    ///
203
    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
210 204
    SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
211
    ///\brief Assignment of SmartDigraph to another one is \e not allowed.
212
    ///Use DigraphCopy() instead.
213

	
214
    ///Assignment of SmartDigraph to another one is \e not allowed.
215
    ///Use DigraphCopy() instead.
205
    /// \brief Assignment of a digraph to another one is \e not allowed.
206
    /// Use DigraphCopy instead.
216 207
    void operator=(const SmartDigraph &) {}
217 208

	
218 209
  public:
219 210

	
220 211
    /// Constructor
221 212

	
222 213
    /// Constructor.
223 214
    ///
224 215
    SmartDigraph() {};
225 216

	
226 217
    ///Add a new node to the digraph.
227 218

	
228
    /// \return the new node.
229
    ///
219
    ///This function adds a new node to the digraph.
220
    ///\return The new node.
230 221
    Node addNode() { return Parent::addNode(); }
231 222

	
232 223
    ///Add a new arc to the digraph.
233 224

	
234
    ///Add a new arc to the digraph with source node \c s
225
    ///This function adds a new arc to the digraph with source node \c s
235 226
    ///and target node \c t.
236
    ///\return the new arc.
237
    Arc addArc(const Node& s, const Node& t) {
227
    ///\return The new arc.
228
    Arc addArc(Node s, Node t) {
238 229
      return Parent::addArc(s, t);
239 230
    }
240 231

	
241
    /// \brief Using this it is possible to avoid the superfluous memory
242
    /// allocation.
243

	
244
    /// Using this it is possible to avoid the superfluous memory
245
    /// allocation: if you know that the digraph you want to build will
246
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
247
    /// then it is worth reserving space for this amount before starting
248
    /// to build the digraph.
249
    /// \sa reserveArc
250
    void reserveNode(int n) { nodes.reserve(n); };
251

	
252
    /// \brief Using this it is possible to avoid the superfluous memory
253
    /// allocation.
254

	
255
    /// Using this it is possible to avoid the superfluous memory
256
    /// allocation: if you know that the digraph you want to build will
257
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
258
    /// then it is worth reserving space for this amount before starting
259
    /// to build the digraph.
260
    /// \sa reserveNode
261
    void reserveArc(int m) { arcs.reserve(m); };
262

	
263 232
    /// \brief Node validity check
264 233
    ///
265
    /// This function gives back true if the given node is valid,
266
    /// ie. it is a real node of the graph.
234
    /// This function gives back \c true if the given node is valid,
235
    /// i.e. it is a real node of the digraph.
267 236
    ///
268 237
    /// \warning A removed node (using Snapshot) could become valid again
269
    /// when new nodes are added to the graph.
238
    /// if new nodes are added to the digraph.
270 239
    bool valid(Node n) const { return Parent::valid(n); }
271 240

	
272 241
    /// \brief Arc validity check
273 242
    ///
274
    /// This function gives back true if the given arc is valid,
275
    /// ie. it is a real arc of the graph.
243
    /// This function gives back \c true if the given arc is valid,
244
    /// i.e. it is a real arc of the digraph.
276 245
    ///
277 246
    /// \warning A removed arc (using Snapshot) could become valid again
278
    /// when new arcs are added to the graph.
247
    /// if new arcs are added to the graph.
279 248
    bool valid(Arc a) const { return Parent::valid(a); }
280 249

	
281
    ///Clear the digraph.
282

	
283
    ///Erase all the nodes and arcs from the digraph.
284
    ///
285
    void clear() {
286
      Parent::clear();
287
    }
288

	
289 250
    ///Split a node.
290 251

	
291
    ///This function splits a node. First a new node is added to the digraph,
292
    ///then the source of each outgoing arc of \c n is moved to this new node.
293
    ///If \c connect is \c true (this is the default value), then a new arc
294
    ///from \c n to the newly created node is also added.
252
    ///This function splits the given node. First, a new node is added
253
    ///to the digraph, then the source of each outgoing arc of node \c n
254
    ///is moved to this new node.
255
    ///If the second parameter \c connect is \c true (this is the default
256
    ///value), then a new arc from node \c n to the newly created node
257
    ///is also added.
295 258
    ///\return The newly created node.
296 259
    ///
297
    ///\note The <tt>Arc</tt>s
298
    ///referencing a moved arc remain
299
    ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
300
    ///may be invalidated.
260
    ///\note All iterators remain valid.
261
    ///
301 262
    ///\warning This functionality cannot be used together with the Snapshot
302 263
    ///feature.
303 264
    Node split(Node n, bool connect = true)
304 265
    {
305 266
      Node b = addNode();
306 267
      nodes[b._id].first_out=nodes[n._id].first_out;
307 268
      nodes[n._id].first_out=-1;
308
      for(int i=nodes[b._id].first_out;i!=-1;i++) arcs[i].source=b._id;
269
      for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {
270
        arcs[i].source=b._id;
271
      }
309 272
      if(connect) addArc(n,b);
310 273
      return b;
311 274
    }
312 275

	
276
    ///Clear the digraph.
277

	
278
    ///This function erases all nodes and arcs from the digraph.
279
    ///
280
    void clear() {
281
      Parent::clear();
282
    }
283

	
284
    /// Reserve memory for nodes.
285

	
286
    /// Using this function, it is possible to avoid superfluous memory
287
    /// allocation: if you know that the digraph you want to build will
288
    /// be large (e.g. it will contain millions of nodes and/or arcs),
289
    /// then it is worth reserving space for this amount before starting
290
    /// to build the digraph.
291
    /// \sa reserveArc()
292
    void reserveNode(int n) { nodes.reserve(n); };
293

	
294
    /// Reserve memory for arcs.
295

	
296
    /// Using this function, it is possible to avoid superfluous memory
297
    /// allocation: if you know that the digraph you want to build will
298
    /// be large (e.g. it will contain millions of nodes and/or arcs),
299
    /// then it is worth reserving space for this amount before starting
300
    /// to build the digraph.
301
    /// \sa reserveNode()
302
    void reserveArc(int m) { arcs.reserve(m); };
303

	
313 304
  public:
314 305

	
315 306
    class Snapshot;
316 307

	
317 308
  protected:
318 309

	
319 310
    void restoreSnapshot(const Snapshot &s)
320 311
    {
321 312
      while(s.arc_num<arcs.size()) {
322 313
        Arc arc = arcFromId(arcs.size()-1);
323 314
        Parent::notifier(Arc()).erase(arc);
324 315
        nodes[arcs.back().source].first_out=arcs.back().next_out;
325 316
        nodes[arcs.back().target].first_in=arcs.back().next_in;
326 317
        arcs.pop_back();
327 318
      }
328 319
      while(s.node_num<nodes.size()) {
329 320
        Node node = nodeFromId(nodes.size()-1);
330 321
        Parent::notifier(Node()).erase(node);
331 322
        nodes.pop_back();
332 323
      }
333 324
    }
334 325

	
335 326
  public:
336 327

	
337
    ///Class to make a snapshot of the digraph and to restrore to it later.
328
    ///Class to make a snapshot of the digraph and to restore it later.
338 329

	
339
    ///Class to make a snapshot of the digraph and to restrore to it later.
330
    ///Class to make a snapshot of the digraph and to restore it later.
340 331
    ///
341 332
    ///The newly added nodes and arcs can be removed using the
342
    ///restore() function.
343
    ///\note After you restore a state, you cannot restore
344
    ///a later state, in other word you cannot add again the arcs deleted
345
    ///by restore() using another one Snapshot instance.
333
    ///restore() function. This is the only way for deleting nodes and/or
334
    ///arcs from a SmartDigraph structure.
346 335
    ///
347
    ///\warning If you do not use correctly the snapshot that can cause
348
    ///either broken program, invalid state of the digraph, valid but
349
    ///not the restored digraph or no change. Because the runtime performance
350
    ///the validity of the snapshot is not stored.
336
    ///\note After a state is restored, you cannot restore a later state, 
337
    ///i.e. you cannot add the removed nodes and arcs again using
338
    ///another Snapshot instance.
339
    ///
340
    ///\warning Node splitting cannot be restored.
341
    ///\warning The validity of the snapshot is not stored due to
342
    ///performance reasons. If you do not use the snapshot correctly,
343
    ///it can cause broken program, invalid or not restored state of
344
    ///the digraph or no change.
351 345
    class Snapshot
352 346
    {
353 347
      SmartDigraph *_graph;
354 348
    protected:
355 349
      friend class SmartDigraph;
356 350
      unsigned int node_num;
357 351
      unsigned int arc_num;
358 352
    public:
359 353
      ///Default constructor.
360 354

	
361 355
      ///Default constructor.
362
      ///To actually make a snapshot you must call save().
363
      ///
356
      ///You have to call save() to actually make a snapshot.
364 357
      Snapshot() : _graph(0) {}
365 358
      ///Constructor that immediately makes a snapshot
366 359

	
367
      ///This constructor immediately makes a snapshot of the digraph.
368
      ///\param graph The digraph we make a snapshot of.
369
      Snapshot(SmartDigraph &graph) : _graph(&graph) {
360
      ///This constructor immediately makes a snapshot of the given digraph.
361
      ///
362
      Snapshot(SmartDigraph &gr) : _graph(&gr) {
370 363
        node_num=_graph->nodes.size();
371 364
        arc_num=_graph->arcs.size();
372 365
      }
373 366

	
374 367
      ///Make a snapshot.
375 368

	
376
      ///Make a snapshot of the digraph.
377
      ///
378
      ///This function can be called more than once. In case of a repeated
369
      ///This function makes a snapshot of the given digraph.
370
      ///It can be called more than once. In case of a repeated
379 371
      ///call, the previous snapshot gets lost.
380
      ///\param graph The digraph we make the snapshot of.
381
      void save(SmartDigraph &graph)
382
      {
383
        _graph=&graph;
372
      void save(SmartDigraph &gr) {
373
        _graph=&gr;
384 374
        node_num=_graph->nodes.size();
385 375
        arc_num=_graph->arcs.size();
386 376
      }
387 377

	
388 378
      ///Undo the changes until a snapshot.
389 379

	
390
      ///Undo the changes until a snapshot created by save().
391
      ///
392
      ///\note After you restored a state, you cannot restore
393
      ///a later state, in other word you cannot add again the arcs deleted
394
      ///by restore().
380
      ///This function undos the changes until the last snapshot
381
      ///created by save() or Snapshot(SmartDigraph&).
395 382
      void restore()
396 383
      {
397 384
        _graph->restoreSnapshot(*this);
398 385
      }
399 386
    };
400 387
  };
401 388

	
402 389

	
403 390
  class SmartGraphBase {
404 391

	
405 392
  protected:
406 393

	
407 394
    struct NodeT {
408 395
      int first_out;
409 396
    };
410 397

	
411 398
    struct ArcT {
412 399
      int target;
413 400
      int next_out;
414 401
    };
415 402

	
416 403
    std::vector<NodeT> nodes;
417 404
    std::vector<ArcT> arcs;
418 405

	
419 406
    int first_free_arc;
420 407

	
421 408
  public:
422 409

	
423
    typedef SmartGraphBase Digraph;
410
    typedef SmartGraphBase Graph;
424 411

	
425 412
    class Node;
426 413
    class Arc;
427 414
    class Edge;
428 415

	
429 416
    class Node {
430 417
      friend class SmartGraphBase;
431 418
    protected:
432 419

	
433 420
      int _id;
434 421
      explicit Node(int id) { _id = id;}
435 422

	
436 423
    public:
437 424
      Node() {}
438 425
      Node (Invalid) { _id = -1; }
439 426
      bool operator==(const Node& node) const {return _id == node._id;}
440 427
      bool operator!=(const Node& node) const {return _id != node._id;}
441 428
      bool operator<(const Node& node) const {return _id < node._id;}
442 429
    };
443 430

	
444 431
    class Edge {
445 432
      friend class SmartGraphBase;
446 433
    protected:
447 434

	
448 435
      int _id;
449 436
      explicit Edge(int id) { _id = id;}
450 437

	
451 438
    public:
452 439
      Edge() {}
453 440
      Edge (Invalid) { _id = -1; }
454 441
      bool operator==(const Edge& arc) const {return _id == arc._id;}
455 442
      bool operator!=(const Edge& arc) const {return _id != arc._id;}
456 443
      bool operator<(const Edge& arc) const {return _id < arc._id;}
457 444
    };
458 445

	
459 446
    class Arc {
460 447
      friend class SmartGraphBase;
461 448
    protected:
462 449

	
463 450
      int _id;
464 451
      explicit Arc(int id) { _id = id;}
465 452

	
466 453
    public:
467
      operator Edge() const { 
468
        return _id != -1 ? edgeFromId(_id / 2) : INVALID; 
454
      operator Edge() const {
455
        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
469 456
      }
470 457

	
471 458
      Arc() {}
472 459
      Arc (Invalid) { _id = -1; }
473 460
      bool operator==(const Arc& arc) const {return _id == arc._id;}
474 461
      bool operator!=(const Arc& arc) const {return _id != arc._id;}
475 462
      bool operator<(const Arc& arc) const {return _id < arc._id;}
476 463
    };
477 464

	
478 465

	
479 466

	
480 467
    SmartGraphBase()
481 468
      : nodes(), arcs() {}
482 469

	
470
    typedef True NodeNumTag;
471
    typedef True EdgeNumTag;
472
    typedef True ArcNumTag;
473

	
474
    int nodeNum() const { return nodes.size(); }
475
    int edgeNum() const { return arcs.size() / 2; }
476
    int arcNum() const { return arcs.size(); }
483 477

	
484 478
    int maxNodeId() const { return nodes.size()-1; }
485 479
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
486 480
    int maxArcId() const { return arcs.size()-1; }
487 481

	
488 482
    Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
489 483
    Node target(Arc e) const { return Node(arcs[e._id].target); }
490 484

	
491 485
    Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
492 486
    Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
493 487

	
494 488
    static bool direction(Arc e) {
495 489
      return (e._id & 1) == 1;
496 490
    }
497 491

	
498 492
    static Arc direct(Edge e, bool d) {
499 493
      return Arc(e._id * 2 + (d ? 1 : 0));
500 494
    }
501 495

	
502 496
    void first(Node& node) const {
503 497
      node._id = nodes.size() - 1;
504 498
    }
505 499

	
506
    void next(Node& node) const {
500
    static void next(Node& node) {
507 501
      --node._id;
508 502
    }
509 503

	
510 504
    void first(Arc& arc) const {
511 505
      arc._id = arcs.size() - 1;
512 506
    }
513 507

	
514
    void next(Arc& arc) const {
508
    static void next(Arc& arc) {
515 509
      --arc._id;
516 510
    }
517 511

	
518 512
    void first(Edge& arc) const {
519 513
      arc._id = arcs.size() / 2 - 1;
520 514
    }
521 515

	
522
    void next(Edge& arc) const {
516
    static void next(Edge& arc) {
523 517
      --arc._id;
524 518
    }
525 519

	
526 520
    void firstOut(Arc &arc, const Node& v) const {
527 521
      arc._id = nodes[v._id].first_out;
528 522
    }
529 523
    void nextOut(Arc &arc) const {
530 524
      arc._id = arcs[arc._id].next_out;
531 525
    }
532 526

	
533 527
    void firstIn(Arc &arc, const Node& v) const {
534 528
      arc._id = ((nodes[v._id].first_out) ^ 1);
535 529
      if (arc._id == -2) arc._id = -1;
536 530
    }
537 531
    void nextIn(Arc &arc) const {
538 532
      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
539 533
      if (arc._id == -2) arc._id = -1;
540 534
    }
541 535

	
542 536
    void firstInc(Edge &arc, bool& d, const Node& v) const {
543 537
      int de = nodes[v._id].first_out;
544 538
      if (de != -1) {
545 539
        arc._id = de / 2;
546 540
        d = ((de & 1) == 1);
547 541
      } else {
548 542
        arc._id = -1;
549 543
        d = true;
550 544
      }
551 545
    }
552 546
    void nextInc(Edge &arc, bool& d) const {
553 547
      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
554 548
      if (de != -1) {
555 549
        arc._id = de / 2;
556 550
        d = ((de & 1) == 1);
557 551
      } else {
558 552
        arc._id = -1;
559 553
        d = true;
560 554
      }
561 555
    }
562 556

	
563 557
    static int id(Node v) { return v._id; }
564 558
    static int id(Arc e) { return e._id; }
565 559
    static int id(Edge e) { return e._id; }
566 560

	
567 561
    static Node nodeFromId(int id) { return Node(id);}
568 562
    static Arc arcFromId(int id) { return Arc(id);}
569 563
    static Edge edgeFromId(int id) { return Edge(id);}
570 564

	
571 565
    bool valid(Node n) const {
572 566
      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
573 567
    }
574 568
    bool valid(Arc a) const {
575 569
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
576 570
    }
577 571
    bool valid(Edge e) const {
578 572
      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
579 573
    }
580 574

	
581 575
    Node addNode() {
582 576
      int n = nodes.size();
583 577
      nodes.push_back(NodeT());
584 578
      nodes[n].first_out = -1;
585 579

	
586 580
      return Node(n);
587 581
    }
588 582

	
589 583
    Edge addEdge(Node u, Node v) {
590 584
      int n = arcs.size();
591 585
      arcs.push_back(ArcT());
592 586
      arcs.push_back(ArcT());
593 587

	
594 588
      arcs[n].target = u._id;
595 589
      arcs[n | 1].target = v._id;
596 590

	
597 591
      arcs[n].next_out = nodes[v._id].first_out;
598 592
      nodes[v._id].first_out = n;
599 593

	
600 594
      arcs[n | 1].next_out = nodes[u._id].first_out;
601 595
      nodes[u._id].first_out = (n | 1);
602 596

	
603 597
      return Edge(n / 2);
604 598
    }
605 599

	
606 600
    void clear() {
607 601
      arcs.clear();
608 602
      nodes.clear();
609 603
    }
610 604

	
611 605
  };
612 606

	
613 607
  typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
614 608

	
615 609
  /// \ingroup graphs
616 610
  ///
617 611
  /// \brief A smart undirected graph class.
618 612
  ///
619
  /// This is a simple and fast graph implementation.
620
  /// It is also quite memory efficient, but at the price
621
  /// that <b> it does support only limited (only stack-like)
622
  /// node and arc deletions</b>.
623
  /// Except from this it conforms to
624
  /// the \ref concepts::Graph "Graph concept".
613
  /// \ref SmartGraph is a simple and fast graph implementation.
614
  /// It is also quite memory efficient but at the price
615
  /// that it does not support node and edge deletion 
616
  /// (except for the Snapshot feature).
625 617
  ///
626
  /// It also has an
627
  /// important extra feature that
628
  /// its maps are real \ref concepts::ReferenceMap "reference map"s.
618
  /// This type fully conforms to the \ref concepts::Graph "Graph concept"
619
  /// and it also provides some additional functionalities.
620
  /// Most of its member functions and nested classes are documented
621
  /// only in the concept class.
629 622
  ///
630
  /// \sa concepts::Graph.
631
  ///
623
  /// \sa concepts::Graph
624
  /// \sa SmartDigraph
632 625
  class SmartGraph : public ExtendedSmartGraphBase {
626
    typedef ExtendedSmartGraphBase Parent;
627

	
633 628
  private:
634

	
635
    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
636

	
637
    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
638
    ///
629
    /// Graphs are \e not copy constructible. Use GraphCopy instead.
639 630
    SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
640

	
641
    ///\brief Assignment of SmartGraph to another one is \e not allowed.
642
    ///Use GraphCopy() instead.
643

	
644
    ///Assignment of SmartGraph to another one is \e not allowed.
645
    ///Use GraphCopy() instead.
631
    /// \brief Assignment of a graph to another one is \e not allowed.
632
    /// Use GraphCopy instead.
646 633
    void operator=(const SmartGraph &) {}
647 634

	
648 635
  public:
649 636

	
650
    typedef ExtendedSmartGraphBase Parent;
651

	
652 637
    /// Constructor
653 638

	
654 639
    /// Constructor.
655 640
    ///
656 641
    SmartGraph() {}
657 642

	
658
    ///Add a new node to the graph.
659

	
660
    /// \return the new node.
643
    /// \brief Add a new node to the graph.
661 644
    ///
645
    /// This function adds a new node to the graph.
646
    /// \return The new node.
662 647
    Node addNode() { return Parent::addNode(); }
663 648

	
664
    ///Add a new edge to the graph.
665

	
666
    ///Add a new edge to the graph with node \c s
667
    ///and \c t.
668
    ///\return the new edge.
669
    Edge addEdge(const Node& s, const Node& t) {
670
      return Parent::addEdge(s, t);
649
    /// \brief Add a new edge to the graph.
650
    ///
651
    /// This function adds a new edge to the graph between nodes
652
    /// \c u and \c v with inherent orientation from node \c u to
653
    /// node \c v.
654
    /// \return The new edge.
655
    Edge addEdge(Node u, Node v) {
656
      return Parent::addEdge(u, v);
671 657
    }
672 658

	
673 659
    /// \brief Node validity check
674 660
    ///
675
    /// This function gives back true if the given node is valid,
676
    /// ie. it is a real node of the graph.
661
    /// This function gives back \c true if the given node is valid,
662
    /// i.e. it is a real node of the graph.
677 663
    ///
678 664
    /// \warning A removed node (using Snapshot) could become valid again
679
    /// when new nodes are added to the graph.
665
    /// if new nodes are added to the graph.
680 666
    bool valid(Node n) const { return Parent::valid(n); }
681 667

	
668
    /// \brief Edge validity check
669
    ///
670
    /// This function gives back \c true if the given edge is valid,
671
    /// i.e. it is a real edge of the graph.
672
    ///
673
    /// \warning A removed edge (using Snapshot) could become valid again
674
    /// if new edges are added to the graph.
675
    bool valid(Edge e) const { return Parent::valid(e); }
676

	
682 677
    /// \brief Arc validity check
683 678
    ///
684
    /// This function gives back true if the given arc is valid,
685
    /// ie. it is a real arc of the graph.
679
    /// This function gives back \c true if the given arc is valid,
680
    /// i.e. it is a real arc of the graph.
686 681
    ///
687 682
    /// \warning A removed arc (using Snapshot) could become valid again
688
    /// when new edges are added to the graph.
683
    /// if new edges are added to the graph.
689 684
    bool valid(Arc a) const { return Parent::valid(a); }
690 685

	
691
    /// \brief Edge validity check
692
    ///
693
    /// This function gives back true if the given edge is valid,
694
    /// ie. it is a real edge of the graph.
695
    ///
696
    /// \warning A removed edge (using Snapshot) could become valid again
697
    /// when new edges are added to the graph.
698
    bool valid(Edge e) const { return Parent::valid(e); }
699

	
700 686
    ///Clear the graph.
701 687

	
702
    ///Erase all the nodes and edges from the graph.
688
    ///This function erases all nodes and arcs from the graph.
703 689
    ///
704 690
    void clear() {
705 691
      Parent::clear();
706 692
    }
707 693

	
694
    /// Reserve memory for nodes.
695

	
696
    /// Using this function, it is possible to avoid superfluous memory
697
    /// allocation: if you know that the graph you want to build will
698
    /// be large (e.g. it will contain millions of nodes and/or edges),
699
    /// then it is worth reserving space for this amount before starting
700
    /// to build the graph.
701
    /// \sa reserveEdge()
702
    void reserveNode(int n) { nodes.reserve(n); };
703

	
704
    /// Reserve memory for edges.
705

	
706
    /// Using this function, it is possible to avoid superfluous memory
707
    /// allocation: if you know that the graph you want to build will
708
    /// be large (e.g. it will contain millions of nodes and/or edges),
709
    /// then it is worth reserving space for this amount before starting
710
    /// to build the graph.
711
    /// \sa reserveNode()
712
    void reserveEdge(int m) { arcs.reserve(2 * m); };
713

	
708 714
  public:
709 715

	
710 716
    class Snapshot;
711 717

	
712 718
  protected:
713 719

	
714 720
    void saveSnapshot(Snapshot &s)
715 721
    {
716 722
      s._graph = this;
717 723
      s.node_num = nodes.size();
718 724
      s.arc_num = arcs.size();
719 725
    }
720 726

	
721 727
    void restoreSnapshot(const Snapshot &s)
722 728
    {
723 729
      while(s.arc_num<arcs.size()) {
724 730
        int n=arcs.size()-1;
725 731
        Edge arc=edgeFromId(n/2);
726 732
        Parent::notifier(Edge()).erase(arc);
727 733
        std::vector<Arc> dir;
728 734
        dir.push_back(arcFromId(n));
729 735
        dir.push_back(arcFromId(n-1));
730 736
        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;
737
        nodes[arcs[n-1].target].first_out=arcs[n].next_out;
738
        nodes[arcs[n].target].first_out=arcs[n-1].next_out;
733 739
        arcs.pop_back();
734 740
        arcs.pop_back();
735 741
      }
736 742
      while(s.node_num<nodes.size()) {
737 743
        int n=nodes.size()-1;
738 744
        Node node = nodeFromId(n);
739 745
        Parent::notifier(Node()).erase(node);
740 746
        nodes.pop_back();
741 747
      }
742 748
    }
743 749

	
744 750
  public:
745 751

	
746
    ///Class to make a snapshot of the digraph and to restrore to it later.
752
    ///Class to make a snapshot of the graph and to restore it later.
747 753

	
748
    ///Class to make a snapshot of the digraph and to restrore to it later.
754
    ///Class to make a snapshot of the graph and to restore it later.
749 755
    ///
750
    ///The newly added nodes and arcs can be removed using the
751
    ///restore() function.
756
    ///The newly added nodes and edges can be removed using the
757
    ///restore() function. This is the only way for deleting nodes and/or
758
    ///edges from a SmartGraph structure.
752 759
    ///
753
    ///\note After you restore a state, you cannot restore
754
    ///a later state, in other word you cannot add again the arcs deleted
755
    ///by restore() using another one Snapshot instance.
760
    ///\note After a state is restored, you cannot restore a later state, 
761
    ///i.e. you cannot add the removed nodes and edges again using
762
    ///another Snapshot instance.
756 763
    ///
757
    ///\warning If you do not use correctly the snapshot that can cause
758
    ///either broken program, invalid state of the digraph, valid but
759
    ///not the restored digraph or no change. Because the runtime performance
760
    ///the validity of the snapshot is not stored.
764
    ///\warning The validity of the snapshot is not stored due to
765
    ///performance reasons. If you do not use the snapshot correctly,
766
    ///it can cause broken program, invalid or not restored state of
767
    ///the graph or no change.
761 768
    class Snapshot
762 769
    {
763 770
      SmartGraph *_graph;
764 771
    protected:
765 772
      friend class SmartGraph;
766 773
      unsigned int node_num;
767 774
      unsigned int arc_num;
768 775
    public:
769 776
      ///Default constructor.
770 777

	
771 778
      ///Default constructor.
772
      ///To actually make a snapshot you must call save().
773
      ///
779
      ///You have to call save() to actually make a snapshot.
774 780
      Snapshot() : _graph(0) {}
775 781
      ///Constructor that immediately makes a snapshot
776 782

	
777
      ///This constructor immediately makes a snapshot of the digraph.
778
      ///\param graph The digraph we make a snapshot of.
779
      Snapshot(SmartGraph &graph) {
780
        graph.saveSnapshot(*this);
783
      /// This constructor immediately makes a snapshot of the given graph.
784
      ///
785
      Snapshot(SmartGraph &gr) {
786
        gr.saveSnapshot(*this);
781 787
      }
782 788

	
783 789
      ///Make a snapshot.
784 790

	
785
      ///Make a snapshot of the graph.
786
      ///
787
      ///This function can be called more than once. In case of a repeated
791
      ///This function makes a snapshot of the given graph.
792
      ///It can be called more than once. In case of a repeated
788 793
      ///call, the previous snapshot gets lost.
789
      ///\param graph The digraph we make the snapshot of.
790
      void save(SmartGraph &graph)
794
      void save(SmartGraph &gr)
791 795
      {
792
        graph.saveSnapshot(*this);
796
        gr.saveSnapshot(*this);
793 797
      }
794 798

	
795
      ///Undo the changes until a snapshot.
799
      ///Undo the changes until the last snapshot.
796 800

	
797
      ///Undo the changes until a snapshot created by save().
798
      ///
799
      ///\note After you restored a state, you cannot restore
800
      ///a later state, in other word you cannot add again the arcs deleted
801
      ///by restore().
801
      ///This function undos the changes until the last snapshot
802
      ///created by save() or Snapshot(SmartGraph&).
802 803
      void restore()
803 804
      {
804 805
        _graph->restoreSnapshot(*this);
805 806
      }
806 807
    };
807 808
  };
808 809

	
809 810
} //namespace lemon
810 811

	
811 812

	
812 813
#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
#
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.
2 16

	
3 17
import sys
4
import os
18

	
19
from mercurial import ui, hg
20
from mercurial import util
21

	
22
util.rcpath = lambda : []
5 23

	
6 24
if len(sys.argv)>1 and sys.argv[1] in ["-h","--help"]:
7 25
    print """
8 26
This utility just prints the length of the longest path
9 27
in the revision graph from revison 0 to the current one.
10 28
"""
11 29
    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 30

	
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])
31
u = ui.ui()
32
r = hg.repository(u, ".")
33
N = r.changectx(".").rev()
34
lengths=[0]*(N+1)
35
for i in range(N+1):
36
    p=r.changectx(i).parents()
37
    if p[0]:
38
        p0=lengths[p[0].rev()]
33 39
    else:
34
        par1 = int(s[1].split(":")[0])
35
        par2 = int(s[2].split(":")[0])
36
    if rev == 0:
37
        lengths.append(0)
40
        p0=-1
41
    if len(p)>1 and p[1]:
42
        p1=lengths[p[1].rev()]
38 43
    else:
39
        lengths.append(max(lengths[par1],lengths[par2])+1)
40
print lengths[PAR]
44
        p1=-1
45
    lengths[i]=max(p0,p1)+1
46
print lengths[N]
Ignore white space 6 line context
1 1
#!/bin/bash
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.
2 16

	
3 17
set -e
4 18

	
5 19
if [ $# = 0 ]; then
6 20
    echo "Usage: $0 release-id"
7 21
    exit 1
8 22
else
9 23
    export LEMON_VERSION=$1
10 24
fi
11 25

	
12 26
echo '*****************************************************************'
13 27
echo ' Start making release tarballs for version '${LEMON_VERSION}
14 28
echo '*****************************************************************'
15 29

	
16 30
autoreconf -vif
17
./configure --enable-demo
31
./configure
18 32

	
19 33
make
20 34
make html
21 35
make distcheck
22 36
tar xf lemon-${LEMON_VERSION}.tar.gz
23 37
zip -r lemon-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
24 38
mv lemon-${LEMON_VERSION}/doc/html lemon-doc-${LEMON_VERSION}
25 39
tar czf lemon-doc-${LEMON_VERSION}.tar.gz lemon-doc-${LEMON_VERSION}
26 40
zip -r lemon-doc-${LEMON_VERSION}.zip lemon-doc-${LEMON_VERSION}
27 41
tar czf lemon-nodoc-${LEMON_VERSION}.tar.gz lemon-${LEMON_VERSION}
28 42
zip -r lemon-nodoc-${LEMON_VERSION}.zip lemon-${LEMON_VERSION}
29 43
hg tag -m 'LEMON '${LEMON_VERSION}' released ('$(hg par --template="{node|short}")' tagged as r'${LEMON_VERSION}')' r${LEMON_VERSION}
30 44

	
31 45
rm -rf lemon-${LEMON_VERSION} lemon-doc-${LEMON_VERSION}
32 46

	
33 47
echo '*****************************************************************'
34 48
echo '  Release '${LEMON_VERSION}' has been created' 
35 49
echo '*****************************************************************'
Ignore white space 6 line context
1 1
#!/bin/bash
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.
2 16

	
3
YEAR=`date +2003-%Y`
17
YEAR=`date +%Y`
4 18
HGROOT=`hg root`
5 19

	
6
function update_header() {
20
function hg_year() {
21
    if [ -n "$(hg st $1)" ]; then
22
        echo $YEAR
23
    else
24
        hg log -l 1 --template='{date|isodate}\n' $1 |
25
        cut -d '-' -f 1
26
    fi
27
}
28

	
29
# file enumaration modes
30

	
31
function all_files() {
32
    hg status -a -m -c |
33
    cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
34
    while read file; do echo $HGROOT/$file; done
35
}
36

	
37
function modified_files() {
38
    hg status -a -m |
39
    cut -d ' ' -f 2 | grep -E  '(\.(cc|h|dox)$|Makefile\.am$)' |
40
    while read file; do echo $HGROOT/$file; done
41
}
42

	
43
function changed_files() {
44
    {
45
        if [ -n "$HG_PARENT1" ]
46
        then
47
            hg status --rev $HG_PARENT1:$HG_NODE -a -m
48
        fi
49
        if [ -n "$HG_PARENT2" ]
50
        then
51
            hg status --rev $HG_PARENT2:$HG_NODE -a -m
52
        fi
53
    } | cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' | 
54
    sort | uniq |
55
    while read file; do echo $HGROOT/$file; done
56
}
57

	
58
function given_files() {
59
    for file in $GIVEN_FILES
60
    do
61
	echo $file
62
    done
63
}
64

	
65
# actions
66

	
67
function update_action() {
68
    if ! diff -q $1 $2 >/dev/null
69
    then
70
	echo -n " [$3 updated]"
71
	rm $2
72
	mv $1 $2
73
	CHANGED=YES
74
    fi
75
}
76

	
77
function update_warning() {
78
    echo -n " [$2 warning]"
79
    WARNED=YES
80
}
81

	
82
function update_init() {
83
    echo Update source files...
84
    TOTAL_FILES=0
85
    CHANGED_FILES=0
86
    WARNED_FILES=0
87
}
88

	
89
function update_done() {
90
    echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
91
    echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
92
}
93

	
94
function update_begin() {
95
    ((TOTAL_FILES++))
96
    CHANGED=NO
97
    WARNED=NO
98
}
99

	
100
function update_end() {
101
    if [ $CHANGED == YES ]
102
    then
103
	((++CHANGED_FILES))
104
    fi
105
    if [ $WARNED == YES ]
106
    then
107
	((++WARNED_FILES))
108
    fi
109
}
110

	
111
function check_action() {
112
    if [ "$3" == 'tabs' ]
113
    then
114
        if echo $2 | grep -q -v -E 'Makefile\.am$'
115
        then
116
            PATTERN=$(echo -e '\t')
117
        else
118
            PATTERN='        '
119
        fi
120
    elif [ "$3" == 'trailing spaces' ]
121
    then
122
        PATTERN='\ +$'
123
    else
124
        PATTERN='*'
125
    fi
126

	
127
    if ! diff -q $1 $2 >/dev/null
128
    then
129
        if [ "$PATTERN" == '*' ]
130
        then
131
            diff $1 $2 | grep '^[0-9]' | sed "s|^\(.*\)c.*$|$2:\1: check failed: $3|g" |
132
              sed "s/:\([0-9]*\),\([0-9]*\):\(.*\)$/:\1:\3 (until line \2)/g"
133
        else
134
            grep -n -E "$PATTERN" $2 | sed "s|^\([0-9]*\):.*$|$2:\1: check failed: $3|g"
135
        fi
136
        FAILED=YES
137
    fi
138
}
139

	
140
function check_warning() {
141
    if [ "$2" == 'long lines' ]
142
    then
143
        grep -n -E '.{81,}' $1 | sed "s|^\([0-9]*\):.*$|$1:\1: warning: $2|g"
144
    else
145
        echo "$1: warning: $2"
146
    fi
147
    WARNED=YES
148
}
149

	
150
function check_init() {
151
    echo Check source files...
152
    FAILED_FILES=0
153
    WARNED_FILES=0
154
    TOTAL_FILES=0
155
}
156

	
157
function check_done() {
158
    echo $FAILED_FILES out of $TOTAL_FILES files has been failed.
159
    echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
160

	
161
    if [ $WARNED_FILES -gt 0 -o $FAILED_FILES -gt 0 ]
162
    then
163
	if [ "$WARNING" == 'INTERACTIVE' ]
164
	then
165
	    echo -n "Are the files with errors/warnings acceptable? (yes/no) "
166
	    while read answer
167
	    do
168
		if [ "$answer" == 'yes' ]
169
		then
170
		    return 0
171
		elif [ "$answer" == 'no' ]
172
		then
173
		    return 1
174
		fi
175
		echo -n "Are the files with errors/warnings acceptable? (yes/no) "
176
	    done
177
	elif [ "$WARNING" == 'WERROR' ]
178
	then
179
	    return 1
180
	fi
181
    fi
182
}
183

	
184
function check_begin() {
185
    ((TOTAL_FILES++))
186
    FAILED=NO
187
    WARNED=NO
188
}
189

	
190
function check_end() {
191
    if [ $FAILED == YES ]
192
    then
193
	((++FAILED_FILES))
194
    fi
195
    if [ $WARNED == YES ]
196
    then
197
	((++WARNED_FILES))
198
    fi
199
}
200

	
201

	
202

	
203
# checks
204

	
205
function header_check() {
206
    if echo $1 | grep -q -E 'Makefile\.am$'
207
    then
208
	return
209
    fi
210

	
7 211
    TMP_FILE=`mktemp`
8
    FILE_NAME=$1
9 212

	
10 213
    (echo "/* -*- mode: C++; indent-tabs-mode: nil; -*-
11 214
 *
12 215
 * This file is a part of LEMON, a generic C++ optimization library.
13 216
 *
14
 * Copyright (C) "$YEAR"
217
 * Copyright (C) 2003-"$(hg_year $1)"
15 218
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
16 219
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
17 220
 *
18 221
 * Permission to use, modify and distribute this software is granted
19 222
 * provided that this copyright notice appears in all copies. For
20 223
 * precise terms see the accompanying LICENSE file.
21 224
 *
22 225
 * This software is provided \"AS IS\" with no warranty of any kind,
23 226
 * express or implied, and with no claim as to its suitability for any
24 227
 * purpose.
25 228
 *
26 229
 */
27 230
"
28
	awk 'BEGIN { pm=0; }
231
    awk 'BEGIN { pm=0; }
29 232
     pm==3 { print }
30 233
     /\/\* / && pm==0 { pm=1;}
31 234
     /[^:blank:]/ && (pm==0 || pm==2) { pm=3; print;}
32 235
     /\*\// && pm==1 { pm=2;}
33 236
    ' $1
34
	) >$TMP_FILE
237
    ) >$TMP_FILE
35 238

	
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
239
    "$ACTION"_action "$TMP_FILE" "$1" header
40 240
}
41 241

	
42
function update_tabs() {
242
function tabs_check() {
243
    if echo $1 | grep -q -v -E 'Makefile\.am$'
244
    then
245
        OLD_PATTERN=$(echo -e '\t')
246
        NEW_PATTERN='        '
247
    else
248
        OLD_PATTERN='        '
249
        NEW_PATTERN=$(echo -e '\t')
250
    fi
43 251
    TMP_FILE=`mktemp`
44
    FILE_NAME=$1
252
    cat $1 | sed -e "s/$OLD_PATTERN/$NEW_PATTERN/g" >$TMP_FILE
45 253

	
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
254
    "$ACTION"_action "$TMP_FILE" "$1" 'tabs'
53 255
}
54 256

	
55
function remove_trailing_space() {
257
function spaces_check() {
56 258
    TMP_FILE=`mktemp`
57
    FILE_NAME=$1
259
    cat $1 | sed -e 's/ \+$//g' >$TMP_FILE
58 260

	
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
261
    "$ACTION"_action "$TMP_FILE" "$1" 'trailing spaces'
66 262
}
67 263

	
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 ]];
264
function long_lines_check() {
265
    if cat $1 | grep -q -E '.{81,}'
81 266
    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++))
267
	"$ACTION"_warning $1 'long lines'
104 268
    fi
105 269
}
106 270

	
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)$'`
271
# process the file
272

	
273
function process_file() {
274
    if [ "$ACTION" == 'update' ]
275
    then
276
        echo -n "    $ACTION $1..."
277
    else
278
        echo "	  $ACTION $1..."
279
    fi
280

	
281
    CHECKING="header tabs spaces long_lines"
282

	
283
    "$ACTION"_begin $1
284
    for check in $CHECKING
113 285
    do
114
	update_file $HGROOT/$i
115
	((TOTAL_FILES++))
286
	"$check"_check $1
116 287
    done
117
    echo '  done.'
118
else
119
    for i in $*
288
    "$ACTION"_end $1
289
    if [ "$ACTION" == 'update' ]
290
    then
291
        echo
292
    fi
293
}
294

	
295
function process_all {
296
    "$ACTION"_init
297
    while read file
120 298
    do
121
	update_file $i
122
	((TOTAL_FILES++))
123
    done
299
	process_file $file
300
    done < <($FILES)
301
    "$ACTION"_done
302
}
303

	
304
while [ $# -gt 0 ]
305
do
306
    
307
    if [ "$1" == '--help' ] || [ "$1" == '-h' ]
308
    then
309
	echo -n \
310
"Usage:
311
  $0 [OPTIONS] [files]
312
Options:
313
  --dry-run|-n
314
     Check the files, but do not modify them.
315
  --interactive|-i
316
     If --dry-run is specified and the checker emits warnings,
317
     then the user is asked if the warnings should be considered
318
     errors.
319
  --werror|-w
320
     Make all warnings into errors.
321
  --all|-a
322
     Check all source files in the repository.
323
  --modified|-m
324
     Check only the modified (and new) source files. This option is
325
     useful to check the modification before making a commit.
326
  --changed|-c
327
     Check only the changed source files compared to the parent(s) of
328
     the current hg node.  This option is useful as hg hook script.
329
     To automatically check all your changes before making a commit,
330
     add the following section to the appropriate .hg/hgrc file.
331

	
332
       [hooks]
333
       pretxncommit.checksources = scripts/unify-sources.sh -c -n -i
334

	
335
  --help|-h
336
     Print this help message.
337
  files
338
     The files to check/unify. If no file names are given, the modified
339
     source files will be checked/unified (just like using the
340
     --modified|-m option).
341
"
342
        exit 0
343
    elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ]
344
    then
345
	[ -n "$ACTION" ] && echo "Conflicting action options" >&2 && exit 1
346
	ACTION=check
347
    elif [ "$1" == "--all" ] || [ "$1" == '-a' ]
348
    then
349
	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
350
	FILES=all_files
351
    elif [ "$1" == "--changed" ] || [ "$1" == '-c' ]
352
    then
353
	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
354
	FILES=changed_files
355
    elif [ "$1" == "--modified" ] || [ "$1" == '-m' ]
356
    then
357
	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
358
	FILES=modified_files
359
    elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ]
360
    then
361
	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
362
	WARNING='INTERACTIVE'
363
    elif [ "$1" == "--werror" ] || [ "$1" == "-w" ]
364
    then
365
	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
366
	WARNING='WERROR'
367
    elif [ $(echo x$1 | cut -c 2) == '-' ]
368
    then
369
	echo "Invalid option $1" >&2 && exit 1
370
    else
371
	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
372
	GIVEN_FILES=$@
373
	FILES=given_files
374
	break
375
    fi
376
    
377
    shift
378
done
379

	
380
if [ -z $FILES ]
381
then
382
    FILES=modified_files
124 383
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
384

	
385
if [ -z $ACTION ]
386
then
387
    ACTION=update
134 388
fi
389

	
390
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
12
  bellman_ford_test
9 13
  bfs_test
14
  circulation_test
15
  connectivity_test
10 16
  counter_test
11 17
  dfs_test
12 18
  digraph_test
13 19
  dijkstra_test
14 20
  dim_test
21
  edge_set_test
15 22
  error_test
23
  euler_test
24
  gomory_hu_test
16 25
  graph_copy_test
17 26
  graph_test
18 27
  graph_utils_test
28
  hao_orlin_test
19 29
  heap_test
20 30
  kruskal_test
21 31
  maps_test
32
  matching_test
33
  min_cost_arborescence_test
34
  min_cost_flow_test
35
  min_mean_cycle_test
36
  path_test
37
  preflow_test
38
  radix_sort_test
22 39
  random_test
23
  path_test
40
  suurballe_test
24 41
  time_measure_test
25
  unionfind_test)
42
  unionfind_test
43
)
44

	
45
IF(LEMON_HAVE_LP)
46
  ADD_EXECUTABLE(lp_test lp_test.cc)
47
  SET(LP_TEST_LIBS lemon)
48

	
49
  IF(LEMON_HAVE_GLPK)
50
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
51
  ENDIF()
52
  IF(LEMON_HAVE_CPLEX)
53
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
54
  ENDIF()
55
  IF(LEMON_HAVE_CLP)
56
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
57
  ENDIF()
58

	
59
  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
60
  ADD_TEST(lp_test lp_test)
61

	
62
  IF(WIN32 AND LEMON_HAVE_GLPK)
63
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
64
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
65
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
66
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
67
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
68
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
69
    )
70
  ENDIF()
71

	
72
  IF(WIN32 AND LEMON_HAVE_CPLEX)
73
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
74
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
75
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
76
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
77
    )
78
  ENDIF()
79
ENDIF()
80

	
81
IF(LEMON_HAVE_MIP)
82
  ADD_EXECUTABLE(mip_test mip_test.cc)
83
  SET(MIP_TEST_LIBS lemon)
84

	
85
  IF(LEMON_HAVE_GLPK)
86
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
87
  ENDIF()
88
  IF(LEMON_HAVE_CPLEX)
89
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
90
  ENDIF()
91
  IF(LEMON_HAVE_CBC)
92
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
93
  ENDIF()
94

	
95
  TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
96
  ADD_TEST(mip_test mip_test)
97

	
98
  IF(WIN32 AND LEMON_HAVE_GLPK)
99
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
100
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
101
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
102
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
103
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
104
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
105
    )
106
  ENDIF()
107

	
108
  IF(WIN32 AND LEMON_HAVE_CPLEX)
109
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
110
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
111
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
112
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
113
    )
114
  ENDIF()
115
ENDIF()
26 116

	
27 117
FOREACH(TEST_NAME ${TESTS})
28 118
  ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
29 119
  TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
30 120
  ADD_TEST(${TEST_NAME} ${TEST_NAME})
31
ENDFOREACH(TEST_NAME)
121
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 \
10
	test/bellman_ford_test \
9 11
	test/bfs_test \
10
        test/counter_test \
12
	test/circulation_test \
13
	test/connectivity_test \
14
	test/counter_test \
11 15
	test/dfs_test \
12 16
	test/digraph_test \
13 17
	test/dijkstra_test \
14
        test/dim_test \
18
	test/dim_test \
19
	test/edge_set_test \
15 20
	test/error_test \
21
	test/euler_test \
22
	test/gomory_hu_test \
16 23
	test/graph_copy_test \
17 24
	test/graph_test \
18 25
	test/graph_utils_test \
26
	test/hao_orlin_test \
19 27
	test/heap_test \
20 28
	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 \
29
	test/maps_test \
30
	test/matching_test \
31
	test/min_cost_arborescence_test \
32
	test/min_cost_flow_test \
33
	test/min_mean_cycle_test \
34
	test/path_test \
35
	test/preflow_test \
36
	test/radix_sort_test \
37
	test/random_test \
38
	test/suurballe_test \
39
	test/test_tools_fail \
40
	test/test_tools_pass \
41
	test/time_measure_test \
27 42
	test/unionfind_test
28 43

	
44
test_test_tools_pass_DEPENDENCIES = demo
45

	
46
if HAVE_LP
47
check_PROGRAMS += test/lp_test
48
endif HAVE_LP
49
if HAVE_MIP
50
check_PROGRAMS += test/mip_test
51
endif HAVE_MIP
52

	
29 53
TESTS += $(check_PROGRAMS)
30 54
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
31 55

	
56
test_adaptors_test_SOURCES = test/adaptors_test.cc
57
test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
32 58
test_bfs_test_SOURCES = test/bfs_test.cc
59
test_circulation_test_SOURCES = test/circulation_test.cc
33 60
test_counter_test_SOURCES = test/counter_test.cc
61
test_connectivity_test_SOURCES = test/connectivity_test.cc
34 62
test_dfs_test_SOURCES = test/dfs_test.cc
35 63
test_digraph_test_SOURCES = test/digraph_test.cc
36 64
test_dijkstra_test_SOURCES = test/dijkstra_test.cc
37 65
test_dim_test_SOURCES = test/dim_test.cc
66
test_edge_set_test_SOURCES = test/edge_set_test.cc
38 67
test_error_test_SOURCES = test/error_test.cc
68
test_euler_test_SOURCES = test/euler_test.cc
69
test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
39 70
test_graph_copy_test_SOURCES = test/graph_copy_test.cc
40 71
test_graph_test_SOURCES = test/graph_test.cc
41 72
test_graph_utils_test_SOURCES = test/graph_utils_test.cc
42 73
test_heap_test_SOURCES = test/heap_test.cc
43 74
test_kruskal_test_SOURCES = test/kruskal_test.cc
75
test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
76
test_lp_test_SOURCES = test/lp_test.cc
44 77
test_maps_test_SOURCES = test/maps_test.cc
78
test_mip_test_SOURCES = test/mip_test.cc
79
test_matching_test_SOURCES = test/matching_test.cc
80
test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
81
test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
82
test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
45 83
test_path_test_SOURCES = test/path_test.cc
84
test_preflow_test_SOURCES = test/preflow_test.cc
85
test_radix_sort_test_SOURCES = test/radix_sort_test.cc
86
test_suurballe_test_SOURCES = test/suurballe_test.cc
46 87
test_random_test_SOURCES = test/random_test.cc
47 88
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
48 89
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
49 90
test_time_measure_test_SOURCES = test/time_measure_test.cc
50 91
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/static_graph.h>
23
#include <lemon/full_graph.h>
24 24

	
25 25
#include "test_tools.h"
26 26
#include "graph_test.h"
27 27

	
28 28
using namespace lemon;
29 29
using namespace lemon::concepts;
30 30

	
31 31
template <class Digraph>
32
void checkDigraph() {
32
void checkDigraphBuild() {
33 33
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
34 34
  Digraph G;
35 35

	
36 36
  checkGraphNodeList(G, 0);
37 37
  checkGraphArcList(G, 0);
38 38

	
39
  G.reserveNode(3);
40
  G.reserveArc(4);
41

	
39 42
  Node
40 43
    n1 = G.addNode(),
41 44
    n2 = G.addNode(),
42 45
    n3 = G.addNode();
43 46
  checkGraphNodeList(G, 3);
44 47
  checkGraphArcList(G, 0);
45 48

	
46 49
  Arc a1 = G.addArc(n1, n2);
47 50
  check(G.source(a1) == n1 && G.target(a1) == n2, "Wrong arc");
48 51
  checkGraphNodeList(G, 3);
49 52
  checkGraphArcList(G, 1);
50 53

	
51 54
  checkGraphOutArcList(G, n1, 1);
52 55
  checkGraphOutArcList(G, n2, 0);
53 56
  checkGraphOutArcList(G, n3, 0);
54 57

	
55 58
  checkGraphInArcList(G, n1, 0);
56 59
  checkGraphInArcList(G, n2, 1);
57 60
  checkGraphInArcList(G, n3, 0);
58 61

	
59 62
  checkGraphConArcList(G, 1);
60 63

	
61
  Arc a2 = G.addArc(n2, n1), a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
64
  Arc a2 = G.addArc(n2, n1),
65
      a3 = G.addArc(n2, n3),
66
      a4 = G.addArc(n2, n3);
67

	
68
  checkGraphNodeList(G, 3);
69
  checkGraphArcList(G, 4);
70

	
71
  checkGraphOutArcList(G, n1, 1);
72
  checkGraphOutArcList(G, n2, 3);
73
  checkGraphOutArcList(G, n3, 0);
74

	
75
  checkGraphInArcList(G, n1, 1);
76
  checkGraphInArcList(G, n2, 1);
77
  checkGraphInArcList(G, n3, 2);
78

	
79
  checkGraphConArcList(G, 4);
80

	
81
  checkNodeIds(G);
82
  checkArcIds(G);
83
  checkGraphNodeMap(G);
84
  checkGraphArcMap(G);
85
}
86

	
87
template <class Digraph>
88
void checkDigraphSplit() {
89
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
90

	
91
  Digraph G;
92
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
93
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
94
      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
95

	
96
  Node n4 = G.split(n2);
97

	
98
  check(G.target(OutArcIt(G, n2)) == n4 &&
99
        G.source(InArcIt(G, n4)) == n2,
100
        "Wrong split.");
101

	
102
  checkGraphNodeList(G, 4);
103
  checkGraphArcList(G, 5);
104

	
105
  checkGraphOutArcList(G, n1, 1);
106
  checkGraphOutArcList(G, n2, 1);
107
  checkGraphOutArcList(G, n3, 0);
108
  checkGraphOutArcList(G, n4, 3);
109

	
110
  checkGraphInArcList(G, n1, 1);
111
  checkGraphInArcList(G, n2, 1);
112
  checkGraphInArcList(G, n3, 2);
113
  checkGraphInArcList(G, n4, 1);
114

	
115
  checkGraphConArcList(G, 5);
116
}
117

	
118
template <class Digraph>
119
void checkDigraphAlter() {
120
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
121

	
122
  Digraph G;
123
  Node n1 = G.addNode(), n2 = G.addNode(),
124
       n3 = G.addNode(), n4 = G.addNode();
125
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
126
      a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
127
      a5 = G.addArc(n2, n4);
128

	
129
  checkGraphNodeList(G, 4);
130
  checkGraphArcList(G, 5);
131

	
132
  // Check changeSource() and changeTarget()
133
  G.changeTarget(a4, n1);
134

	
135
  checkGraphNodeList(G, 4);
136
  checkGraphArcList(G, 5);
137

	
138
  checkGraphOutArcList(G, n1, 1);
139
  checkGraphOutArcList(G, n2, 1);
140
  checkGraphOutArcList(G, n3, 0);
141
  checkGraphOutArcList(G, n4, 3);
142

	
143
  checkGraphInArcList(G, n1, 2);
144
  checkGraphInArcList(G, n2, 1);
145
  checkGraphInArcList(G, n3, 1);
146
  checkGraphInArcList(G, n4, 1);
147

	
148
  checkGraphConArcList(G, 5);
149

	
150
  G.changeSource(a4, n3);
151

	
152
  checkGraphNodeList(G, 4);
153
  checkGraphArcList(G, 5);
154

	
155
  checkGraphOutArcList(G, n1, 1);
156
  checkGraphOutArcList(G, n2, 1);
157
  checkGraphOutArcList(G, n3, 1);
158
  checkGraphOutArcList(G, n4, 2);
159

	
160
  checkGraphInArcList(G, n1, 2);
161
  checkGraphInArcList(G, n2, 1);
162
  checkGraphInArcList(G, n3, 1);
163
  checkGraphInArcList(G, n4, 1);
164

	
165
  checkGraphConArcList(G, 5);
166

	
167
  // Check contract()
168
  G.contract(n2, n4, false);
169

	
170
  checkGraphNodeList(G, 3);
171
  checkGraphArcList(G, 5);
172

	
173
  checkGraphOutArcList(G, n1, 1);
174
  checkGraphOutArcList(G, n2, 3);
175
  checkGraphOutArcList(G, n3, 1);
176

	
177
  checkGraphInArcList(G, n1, 2);
178
  checkGraphInArcList(G, n2, 2);
179
  checkGraphInArcList(G, n3, 1);
180

	
181
  checkGraphConArcList(G, 5);
182

	
183
  G.contract(n2, n1);
184

	
185
  checkGraphNodeList(G, 2);
186
  checkGraphArcList(G, 3);
187

	
188
  checkGraphOutArcList(G, n2, 2);
189
  checkGraphOutArcList(G, n3, 1);
190

	
191
  checkGraphInArcList(G, n2, 2);
192
  checkGraphInArcList(G, n3, 1);
193

	
194
  checkGraphConArcList(G, 3);
195
}
196

	
197
template <class Digraph>
198
void checkDigraphErase() {
199
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
200

	
201
  Digraph G;
202
  Node n1 = G.addNode(), n2 = G.addNode(),
203
       n3 = G.addNode(), n4 = G.addNode();
204
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
205
      a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
206
      a5 = G.addArc(n2, n4);
207

	
208
  // Check arc deletion
209
  G.erase(a1);
210

	
211
  checkGraphNodeList(G, 4);
212
  checkGraphArcList(G, 4);
213

	
214
  checkGraphOutArcList(G, n1, 0);
215
  checkGraphOutArcList(G, n2, 1);
216
  checkGraphOutArcList(G, n3, 1);
217
  checkGraphOutArcList(G, n4, 2);
218

	
219
  checkGraphInArcList(G, n1, 2);
220
  checkGraphInArcList(G, n2, 0);
221
  checkGraphInArcList(G, n3, 1);
222
  checkGraphInArcList(G, n4, 1);
223

	
224
  checkGraphConArcList(G, 4);
225

	
226
  // Check node deletion
227
  G.erase(n4);
228

	
229
  checkGraphNodeList(G, 3);
230
  checkGraphArcList(G, 1);
231

	
232
  checkGraphOutArcList(G, n1, 0);
233
  checkGraphOutArcList(G, n2, 0);
234
  checkGraphOutArcList(G, n3, 1);
235
  checkGraphOutArcList(G, n4, 0);
236

	
237
  checkGraphInArcList(G, n1, 1);
238
  checkGraphInArcList(G, n2, 0);
239
  checkGraphInArcList(G, n3, 0);
240
  checkGraphInArcList(G, n4, 0);
241

	
242
  checkGraphConArcList(G, 1);
243
}
244

	
245

	
246
template <class Digraph>
247
void checkDigraphSnapshot() {
248
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
249

	
250
  Digraph G;
251
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
252
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
253
      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
254

	
255
  typename Digraph::Snapshot snapshot(G);
256

	
257
  Node n = G.addNode();
258
  G.addArc(n3, n);
259
  G.addArc(n, n3);
260

	
261
  checkGraphNodeList(G, 4);
262
  checkGraphArcList(G, 6);
263

	
264
  snapshot.restore();
265

	
62 266
  checkGraphNodeList(G, 3);
63 267
  checkGraphArcList(G, 4);
64 268

	
65 269
  checkGraphOutArcList(G, n1, 1);
66 270
  checkGraphOutArcList(G, n2, 3);
67 271
  checkGraphOutArcList(G, n3, 0);
68 272

	
69 273
  checkGraphInArcList(G, n1, 1);
70 274
  checkGraphInArcList(G, n2, 1);
71 275
  checkGraphInArcList(G, n3, 2);
72 276

	
73 277
  checkGraphConArcList(G, 4);
74 278

	
75 279
  checkNodeIds(G);
76 280
  checkArcIds(G);
77 281
  checkGraphNodeMap(G);
78 282
  checkGraphArcMap(G);
79 283

	
284
  G.addNode();
285
  snapshot.save(G);
286

	
287
  G.addArc(G.addNode(), G.addNode());
288

	
289
  snapshot.restore();
290
  snapshot.save(G);
291

	
292
  checkGraphNodeList(G, 4);
293
  checkGraphArcList(G, 4);
294

	
295
  G.addArc(G.addNode(), G.addNode());
296

	
297
  snapshot.restore();
298

	
299
  checkGraphNodeList(G, 4);
300
  checkGraphArcList(G, 4);
80 301
}
81 302

	
82

	
83 303
void checkConcepts() {
84 304
  { // Checking digraph components
85 305
    checkConcept<BaseDigraphComponent, BaseDigraphComponent >();
86 306

	
87 307
    checkConcept<IDableDigraphComponent<>,
88 308
      IDableDigraphComponent<> >();
89 309

	
90 310
    checkConcept<IterableDigraphComponent<>,
91 311
      IterableDigraphComponent<> >();
92 312

	
93 313
    checkConcept<MappableDigraphComponent<>,
94 314
      MappableDigraphComponent<> >();
95 315
  }
96 316
  { // Checking skeleton digraph
97 317
    checkConcept<Digraph, Digraph>();
98 318
  }
99 319
  { // Checking ListDigraph
100 320
    checkConcept<Digraph, ListDigraph>();
101 321
    checkConcept<AlterableDigraphComponent<>, ListDigraph>();
102 322
    checkConcept<ExtendableDigraphComponent<>, ListDigraph>();
103 323
    checkConcept<ClearableDigraphComponent<>, ListDigraph>();
104 324
    checkConcept<ErasableDigraphComponent<>, ListDigraph>();
105 325
  }
106 326
  { // Checking SmartDigraph
107 327
    checkConcept<Digraph, SmartDigraph>();
108 328
    checkConcept<AlterableDigraphComponent<>, SmartDigraph>();
109 329
    checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
110 330
    checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
111 331
  }
112
//  { // Checking FullDigraph
113
//    checkConcept<Digraph, FullDigraph>();
114
//  }
115
//  { // Checking HyperCubeDigraph
116
//    checkConcept<Digraph, HyperCubeDigraph>();
117
//  }
332
  { // Checking StaticDigraph
333
    checkConcept<Digraph, StaticDigraph>();
334
    checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
335
  }
336
  { // Checking FullDigraph
337
    checkConcept<Digraph, FullDigraph>();
338
  }
118 339
}
119 340

	
120 341
template <typename Digraph>
121 342
void checkDigraphValidity() {
122 343
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
123 344
  Digraph g;
124 345

	
125 346
  Node
126 347
    n1 = g.addNode(),
127 348
    n2 = g.addNode(),
128 349
    n3 = g.addNode();
129 350

	
130 351
  Arc
131 352
    e1 = g.addArc(n1, n2),
132 353
    e2 = g.addArc(n2, n3);
133 354

	
134 355
  check(g.valid(n1), "Wrong validity check");
135 356
  check(g.valid(e1), "Wrong validity check");
136 357

	
137 358
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
138 359
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
139 360
}
140 361

	
141 362
template <typename Digraph>
142 363
void checkDigraphValidityErase() {
143 364
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
144 365
  Digraph g;
145 366

	
146 367
  Node
147 368
    n1 = g.addNode(),
148 369
    n2 = g.addNode(),
149 370
    n3 = g.addNode();
150 371

	
151 372
  Arc
152 373
    e1 = g.addArc(n1, n2),
153 374
    e2 = g.addArc(n2, n3);
154 375

	
155 376
  check(g.valid(n1), "Wrong validity check");
156 377
  check(g.valid(e1), "Wrong validity check");
157 378

	
158 379
  g.erase(n1);
159 380

	
160 381
  check(!g.valid(n1), "Wrong validity check");
161 382
  check(g.valid(n2), "Wrong validity check");
162 383
  check(g.valid(n3), "Wrong validity check");
163 384
  check(!g.valid(e1), "Wrong validity check");
164 385
  check(g.valid(e2), "Wrong validity check");
165 386

	
166 387
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
167 388
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
168 389
}
169 390

	
391
void checkStaticDigraph() {
392
  SmartDigraph g;
393
  SmartDigraph::NodeMap<StaticDigraph::Node> nref(g);
394
  SmartDigraph::ArcMap<StaticDigraph::Arc> aref(g);
395
  
396
  StaticDigraph G;
397
  
398
  checkGraphNodeList(G, 0);
399
  checkGraphArcList(G, 0);
400

	
401
  G.build(g, nref, aref);
402

	
403
  checkGraphNodeList(G, 0);
404
  checkGraphArcList(G, 0);
405

	
406
  SmartDigraph::Node
407
    n1 = g.addNode(),
408
    n2 = g.addNode(),
409
    n3 = g.addNode();
410

	
411
  G.build(g, nref, aref);
412

	
413
  checkGraphNodeList(G, 3);
414
  checkGraphArcList(G, 0);
415

	
416
  SmartDigraph::Arc a1 = g.addArc(n1, n2);
417

	
418
  G.build(g, nref, aref);
419

	
420
  check(G.source(aref[a1]) == nref[n1] && G.target(aref[a1]) == nref[n2],
421
        "Wrong arc or wrong references");
422
  checkGraphNodeList(G, 3);
423
  checkGraphArcList(G, 1);
424

	
425
  checkGraphOutArcList(G, nref[n1], 1);
426
  checkGraphOutArcList(G, nref[n2], 0);
427
  checkGraphOutArcList(G, nref[n3], 0);
428

	
429
  checkGraphInArcList(G, nref[n1], 0);
430
  checkGraphInArcList(G, nref[n2], 1);
431
  checkGraphInArcList(G, nref[n3], 0);
432

	
433
  checkGraphConArcList(G, 1);
434

	
435
  SmartDigraph::Arc
436
    a2 = g.addArc(n2, n1),
437
    a3 = g.addArc(n2, n3),
438
    a4 = g.addArc(n2, n3);
439

	
440
  digraphCopy(g, G).nodeRef(nref).run();
441

	
442
  checkGraphNodeList(G, 3);
443
  checkGraphArcList(G, 4);
444

	
445
  checkGraphOutArcList(G, nref[n1], 1);
446
  checkGraphOutArcList(G, nref[n2], 3);
447
  checkGraphOutArcList(G, nref[n3], 0);
448

	
449
  checkGraphInArcList(G, nref[n1], 1);
450
  checkGraphInArcList(G, nref[n2], 1);
451
  checkGraphInArcList(G, nref[n3], 2);
452

	
453
  checkGraphConArcList(G, 4);
454

	
455
  std::vector<std::pair<int,int> > arcs;
456
  arcs.push_back(std::make_pair(0,1));
457
  arcs.push_back(std::make_pair(0,2));
458
  arcs.push_back(std::make_pair(1,3));
459
  arcs.push_back(std::make_pair(1,2));
460
  arcs.push_back(std::make_pair(3,0));
461
  arcs.push_back(std::make_pair(3,3));
462
  arcs.push_back(std::make_pair(4,2));
463
  arcs.push_back(std::make_pair(4,3));
464
  arcs.push_back(std::make_pair(4,1));
465

	
466
  G.build(6, arcs.begin(), arcs.end());
467
  
468
  checkGraphNodeList(G, 6);
469
  checkGraphArcList(G, 9);
470

	
471
  checkGraphOutArcList(G, G.node(0), 2);
472
  checkGraphOutArcList(G, G.node(1), 2);
473
  checkGraphOutArcList(G, G.node(2), 0);
474
  checkGraphOutArcList(G, G.node(3), 2);
475
  checkGraphOutArcList(G, G.node(4), 3);
476
  checkGraphOutArcList(G, G.node(5), 0);
477

	
478
  checkGraphInArcList(G, G.node(0), 1);
479
  checkGraphInArcList(G, G.node(1), 2);
480
  checkGraphInArcList(G, G.node(2), 3);
481
  checkGraphInArcList(G, G.node(3), 3);
482
  checkGraphInArcList(G, G.node(4), 0);
483
  checkGraphInArcList(G, G.node(5), 0);
484

	
485
  checkGraphConArcList(G, 9);
486

	
487
  checkNodeIds(G);
488
  checkArcIds(G);
489
  checkGraphNodeMap(G);
490
  checkGraphArcMap(G);
491
  
492
  int n = G.nodeNum();
493
  int m = G.arcNum();
494
  check(G.index(G.node(n-1)) == n-1, "Wrong index.");
495
  check(G.index(G.arc(m-1)) == m-1, "Wrong index.");
496
}
497

	
498
void checkFullDigraph(int num) {
499
  typedef FullDigraph Digraph;
500
  DIGRAPH_TYPEDEFS(Digraph);
501

	
502
  Digraph G(num);
503
  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
504

	
505
  G.resize(num);
506
  check(G.nodeNum() == num && G.arcNum() == num * num, "Wrong size");
507

	
508
  checkGraphNodeList(G, num);
509
  checkGraphArcList(G, num * num);
510

	
511
  for (NodeIt n(G); n != INVALID; ++n) {
512
    checkGraphOutArcList(G, n, num);
513
    checkGraphInArcList(G, n, num);
514
  }
515

	
516
  checkGraphConArcList(G, num * num);
517

	
518
  checkNodeIds(G);
519
  checkArcIds(G);
520
  checkGraphNodeMap(G);
521
  checkGraphArcMap(G);
522

	
523
  for (int i = 0; i < G.nodeNum(); ++i) {
524
    check(G.index(G(i)) == i, "Wrong index");
525
  }
526

	
527
  for (NodeIt s(G); s != INVALID; ++s) {
528
    for (NodeIt t(G); t != INVALID; ++t) {
529
      Arc a = G.arc(s, t);
530
      check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
531
    }
532
  }
533
}
534

	
170 535
void checkDigraphs() {
171 536
  { // Checking ListDigraph
172
    checkDigraph<ListDigraph>();
537
    checkDigraphBuild<ListDigraph>();
538
    checkDigraphSplit<ListDigraph>();
539
    checkDigraphAlter<ListDigraph>();
540
    checkDigraphErase<ListDigraph>();
541
    checkDigraphSnapshot<ListDigraph>();
173 542
    checkDigraphValidityErase<ListDigraph>();
174 543
  }
175 544
  { // Checking SmartDigraph
176
    checkDigraph<SmartDigraph>();
545
    checkDigraphBuild<SmartDigraph>();
546
    checkDigraphSplit<SmartDigraph>();
547
    checkDigraphSnapshot<SmartDigraph>();
177 548
    checkDigraphValidity<SmartDigraph>();
178 549
  }
550
  { // Checking StaticDigraph
551
    checkStaticDigraph();
552
  }
553
  { // Checking FullDigraph
554
    checkFullDigraph(8);
555
  }
179 556
}
180 557

	
181 558
int main() {
182 559
  checkDigraphs();
183 560
  checkConcepts();
184 561
  return 0;
185 562
}
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);
40

	
41
  G.reserveNode(3);
42
  G.reserveEdge(3);
38 43

	
39 44
  Node
40 45
    n1 = G.addNode(),
41 46
    n2 = G.addNode(),
42 47
    n3 = G.addNode();
43 48
  checkGraphNodeList(G, 3);
44 49
  checkGraphEdgeList(G, 0);
50
  checkGraphArcList(G, 0);
45 51

	
46 52
  Edge e1 = G.addEdge(n1, n2);
47 53
  check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
48 54
        "Wrong edge");
55

	
49 56
  checkGraphNodeList(G, 3);
57
  checkGraphEdgeList(G, 1);
50 58
  checkGraphArcList(G, 2);
51
  checkGraphEdgeList(G, 1);
52 59

	
53
  checkGraphOutArcList(G, n1, 1);
54
  checkGraphOutArcList(G, n2, 1);
55
  checkGraphOutArcList(G, n3, 0);
60
  checkGraphIncEdgeArcLists(G, n1, 1);
61
  checkGraphIncEdgeArcLists(G, n2, 1);
62
  checkGraphIncEdgeArcLists(G, n3, 0);
56 63

	
57
  checkGraphInArcList(G, n1, 1);
58
  checkGraphInArcList(G, n2, 1);
59
  checkGraphInArcList(G, n3, 0);
64
  checkGraphConEdgeList(G, 1);
65
  checkGraphConArcList(G, 2);
60 66

	
61
  checkGraphIncEdgeList(G, n1, 1);
62
  checkGraphIncEdgeList(G, n2, 1);
63
  checkGraphIncEdgeList(G, n3, 0);
67
  Edge e2 = G.addEdge(n2, n1),
68
       e3 = G.addEdge(n2, n3);
64 69

	
65
  checkGraphConArcList(G, 2);
66
  checkGraphConEdgeList(G, 1);
70
  checkGraphNodeList(G, 3);
71
  checkGraphEdgeList(G, 3);
72
  checkGraphArcList(G, 6);
67 73

	
68
  Edge e2 = G.addEdge(n2, n1), e3 = G.addEdge(n2, n3);
69
  checkGraphNodeList(G, 3);
70
  checkGraphArcList(G, 6);
71
  checkGraphEdgeList(G, 3);
74
  checkGraphIncEdgeArcLists(G, n1, 2);
75
  checkGraphIncEdgeArcLists(G, n2, 3);
76
  checkGraphIncEdgeArcLists(G, n3, 1);
72 77

	
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

	
78
  checkGraphConEdgeList(G, 3);
85 79
  checkGraphConArcList(G, 6);
86
  checkGraphConEdgeList(G, 3);
87 80

	
88 81
  checkArcDirections(G);
89 82

	
90 83
  checkNodeIds(G);
91 84
  checkArcIds(G);
92 85
  checkEdgeIds(G);
93 86
  checkGraphNodeMap(G);
94 87
  checkGraphArcMap(G);
95 88
  checkGraphEdgeMap(G);
96 89
}
97 90

	
91
template <class Graph>
92
void checkGraphAlter() {
93
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
94

	
95
  Graph G;
96
  Node n1 = G.addNode(), n2 = G.addNode(),
97
       n3 = G.addNode(), n4 = G.addNode();
98
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
99
       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
100
       e5 = G.addEdge(n4, n3);
101

	
102
  checkGraphNodeList(G, 4);
103
  checkGraphEdgeList(G, 5);
104
  checkGraphArcList(G, 10);
105

	
106
  // Check changeU() and changeV()
107
  if (G.u(e2) == n2) {
108
    G.changeU(e2, n3);
109
  } else {
110
    G.changeV(e2, n3);
111
  }
112

	
113
  checkGraphNodeList(G, 4);
114
  checkGraphEdgeList(G, 5);
115
  checkGraphArcList(G, 10);
116

	
117
  checkGraphIncEdgeArcLists(G, n1, 3);
118
  checkGraphIncEdgeArcLists(G, n2, 2);
119
  checkGraphIncEdgeArcLists(G, n3, 3);
120
  checkGraphIncEdgeArcLists(G, n4, 2);
121

	
122
  checkGraphConEdgeList(G, 5);
123
  checkGraphConArcList(G, 10);
124

	
125
  if (G.u(e2) == n1) {
126
    G.changeU(e2, n2);
127
  } else {
128
    G.changeV(e2, n2);
129
  }
130

	
131
  checkGraphNodeList(G, 4);
132
  checkGraphEdgeList(G, 5);
133
  checkGraphArcList(G, 10);
134

	
135
  checkGraphIncEdgeArcLists(G, n1, 2);
136
  checkGraphIncEdgeArcLists(G, n2, 3);
137
  checkGraphIncEdgeArcLists(G, n3, 3);
138
  checkGraphIncEdgeArcLists(G, n4, 2);
139

	
140
  checkGraphConEdgeList(G, 5);
141
  checkGraphConArcList(G, 10);
142

	
143
  // Check contract()
144
  G.contract(n1, n4, false);
145

	
146
  checkGraphNodeList(G, 3);
147
  checkGraphEdgeList(G, 5);
148
  checkGraphArcList(G, 10);
149

	
150
  checkGraphIncEdgeArcLists(G, n1, 4);
151
  checkGraphIncEdgeArcLists(G, n2, 3);
152
  checkGraphIncEdgeArcLists(G, n3, 3);
153

	
154
  checkGraphConEdgeList(G, 5);
155
  checkGraphConArcList(G, 10);
156

	
157
  G.contract(n2, n3);
158

	
159
  checkGraphNodeList(G, 2);
160
  checkGraphEdgeList(G, 3);
161
  checkGraphArcList(G, 6);
162

	
163
  checkGraphIncEdgeArcLists(G, n1, 4);
164
  checkGraphIncEdgeArcLists(G, n2, 2);
165

	
166
  checkGraphConEdgeList(G, 3);
167
  checkGraphConArcList(G, 6);
168
}
169

	
170
template <class Graph>
171
void checkGraphErase() {
172
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
173

	
174
  Graph G;
175
  Node n1 = G.addNode(), n2 = G.addNode(),
176
       n3 = G.addNode(), n4 = G.addNode();
177
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
178
       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
179
       e5 = G.addEdge(n4, n3);
180

	
181
  // Check edge deletion
182
  G.erase(e2);
183

	
184
  checkGraphNodeList(G, 4);
185
  checkGraphEdgeList(G, 4);
186
  checkGraphArcList(G, 8);
187

	
188
  checkGraphIncEdgeArcLists(G, n1, 2);
189
  checkGraphIncEdgeArcLists(G, n2, 2);
190
  checkGraphIncEdgeArcLists(G, n3, 2);
191
  checkGraphIncEdgeArcLists(G, n4, 2);
192

	
193
  checkGraphConEdgeList(G, 4);
194
  checkGraphConArcList(G, 8);
195

	
196
  // Check node deletion
197
  G.erase(n3);
198

	
199
  checkGraphNodeList(G, 3);
200
  checkGraphEdgeList(G, 2);
201
  checkGraphArcList(G, 4);
202

	
203
  checkGraphIncEdgeArcLists(G, n1, 2);
204
  checkGraphIncEdgeArcLists(G, n2, 1);
205
  checkGraphIncEdgeArcLists(G, n4, 1);
206

	
207
  checkGraphConEdgeList(G, 2);
208
  checkGraphConArcList(G, 4);
209
}
210

	
211

	
212
template <class Graph>
213
void checkGraphSnapshot() {
214
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
215

	
216
  Graph G;
217
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
218
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
219
       e3 = G.addEdge(n2, n3);
220

	
221
  checkGraphNodeList(G, 3);
222
  checkGraphEdgeList(G, 3);
223
  checkGraphArcList(G, 6);
224

	
225
  typename Graph::Snapshot snapshot(G);
226

	
227
  Node n = G.addNode();
228
  G.addEdge(n3, n);
229
  G.addEdge(n, n3);
230
  G.addEdge(n3, n2);
231

	
232
  checkGraphNodeList(G, 4);
233
  checkGraphEdgeList(G, 6);
234
  checkGraphArcList(G, 12);
235

	
236
  snapshot.restore();
237

	
238
  checkGraphNodeList(G, 3);
239
  checkGraphEdgeList(G, 3);
240
  checkGraphArcList(G, 6);
241

	
242
  checkGraphIncEdgeArcLists(G, n1, 2);
243
  checkGraphIncEdgeArcLists(G, n2, 3);
244
  checkGraphIncEdgeArcLists(G, n3, 1);
245

	
246
  checkGraphConEdgeList(G, 3);
247
  checkGraphConArcList(G, 6);
248

	
249
  checkNodeIds(G);
250
  checkEdgeIds(G);
251
  checkArcIds(G);
252
  checkGraphNodeMap(G);
253
  checkGraphEdgeMap(G);
254
  checkGraphArcMap(G);
255

	
256
  G.addNode();
257
  snapshot.save(G);
258

	
259
  G.addEdge(G.addNode(), G.addNode());
260

	
261
  snapshot.restore();
262
  snapshot.save(G);
263

	
264
  checkGraphNodeList(G, 4);
265
  checkGraphEdgeList(G, 3);
266
  checkGraphArcList(G, 6);
267
  
268
  G.addEdge(G.addNode(), G.addNode());
269

	
270
  snapshot.restore();
271

	
272
  checkGraphNodeList(G, 4);
273
  checkGraphEdgeList(G, 3);
274
  checkGraphArcList(G, 6);
275
}
276

	
277
void checkFullGraph(int num) {
278
  typedef FullGraph Graph;
279
  GRAPH_TYPEDEFS(Graph);
280

	
281
  Graph G(num);
282
  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
283
        "Wrong size");
284

	
285
  G.resize(num);
286
  check(G.nodeNum() == num && G.edgeNum() == num * (num - 1) / 2,
287
        "Wrong size");
288

	
289
  checkGraphNodeList(G, num);
290
  checkGraphEdgeList(G, num * (num - 1) / 2);
291

	
292
  for (NodeIt n(G); n != INVALID; ++n) {
293
    checkGraphOutArcList(G, n, num - 1);
294
    checkGraphInArcList(G, n, num - 1);
295
    checkGraphIncEdgeList(G, n, num - 1);
296
  }
297

	
298
  checkGraphConArcList(G, num * (num - 1));
299
  checkGraphConEdgeList(G, num * (num - 1) / 2);
300

	
301
  checkArcDirections(G);
302

	
303
  checkNodeIds(G);
304
  checkArcIds(G);
305
  checkEdgeIds(G);
306
  checkGraphNodeMap(G);
307
  checkGraphArcMap(G);
308
  checkGraphEdgeMap(G);
309

	
310

	
311
  for (int i = 0; i < G.nodeNum(); ++i) {
312
    check(G.index(G(i)) == i, "Wrong index");
313
  }
314

	
315
  for (NodeIt u(G); u != INVALID; ++u) {
316
    for (NodeIt v(G); v != INVALID; ++v) {
317
      Edge e = G.edge(u, v);
318
      Arc a = G.arc(u, v);
319
      if (u == v) {
320
        check(e == INVALID, "Wrong edge lookup");
321
        check(a == INVALID, "Wrong arc lookup");
322
      } else {
323
        check((G.u(e) == u && G.v(e) == v) ||
324
              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
325
        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
326
      }
327
    }
328
  }
329
}
330

	
98 331
void checkConcepts() {
99 332
  { // Checking graph components
100 333
    checkConcept<BaseGraphComponent, BaseGraphComponent >();
101 334

	
102 335
    checkConcept<IDableGraphComponent<>,
103 336
      IDableGraphComponent<> >();
104 337

	
105 338
    checkConcept<IterableGraphComponent<>,
106 339
      IterableGraphComponent<> >();
107 340

	
108 341
    checkConcept<MappableGraphComponent<>,
109 342
      MappableGraphComponent<> >();
110 343
  }
111 344
  { // Checking skeleton graph
112 345
    checkConcept<Graph, Graph>();
113 346
  }
114 347
  { // Checking ListGraph
115 348
    checkConcept<Graph, ListGraph>();
116 349
    checkConcept<AlterableGraphComponent<>, ListGraph>();
117 350
    checkConcept<ExtendableGraphComponent<>, ListGraph>();
118 351
    checkConcept<ClearableGraphComponent<>, ListGraph>();
119 352
    checkConcept<ErasableGraphComponent<>, ListGraph>();
120 353
  }
121 354
  { // Checking SmartGraph
122 355
    checkConcept<Graph, SmartGraph>();
123 356
    checkConcept<AlterableGraphComponent<>, SmartGraph>();
124 357
    checkConcept<ExtendableGraphComponent<>, SmartGraph>();
125 358
    checkConcept<ClearableGraphComponent<>, SmartGraph>();
126 359
  }
127
//  { // Checking FullGraph
128
//    checkConcept<Graph, FullGraph>();
129
//    checkGraphIterators<FullGraph>();
130
//  }
131
//  { // Checking GridGraph
132
//    checkConcept<Graph, GridGraph>();
133
//    checkGraphIterators<GridGraph>();
134
//  }
360
  { // Checking FullGraph
361
    checkConcept<Graph, FullGraph>();
362
  }
363
  { // Checking GridGraph
364
    checkConcept<Graph, GridGraph>();
365
  }
366
  { // Checking HypercubeGraph
367
    checkConcept<Graph, HypercubeGraph>();
368
  }
135 369
}
136 370

	
137 371
template <typename Graph>
138 372
void checkGraphValidity() {
139 373
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
140 374
  Graph g;
141 375

	
142 376
  Node
143 377
    n1 = g.addNode(),
144 378
    n2 = g.addNode(),
145 379
    n3 = g.addNode();
146 380

	
147 381
  Edge
148 382
    e1 = g.addEdge(n1, n2),
149 383
    e2 = g.addEdge(n2, n3);
150 384

	
151 385
  check(g.valid(n1), "Wrong validity check");
152 386
  check(g.valid(e1), "Wrong validity check");
153 387
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
154 388

	
155 389
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
156 390
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
157 391
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
158 392
}
159 393

	
160 394
template <typename Graph>
161 395
void checkGraphValidityErase() {
162 396
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
163 397
  Graph g;
164 398

	
165 399
  Node
166 400
    n1 = g.addNode(),
167 401
    n2 = g.addNode(),
168 402
    n3 = g.addNode();
169 403

	
170 404
  Edge
171 405
    e1 = g.addEdge(n1, n2),
172 406
    e2 = g.addEdge(n2, n3);
173 407

	
174 408
  check(g.valid(n1), "Wrong validity check");
175 409
  check(g.valid(e1), "Wrong validity check");
176 410
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
177 411

	
178 412
  g.erase(n1);
179 413

	
180 414
  check(!g.valid(n1), "Wrong validity check");
181 415
  check(g.valid(n2), "Wrong validity check");
182 416
  check(g.valid(n3), "Wrong validity check");
183 417
  check(!g.valid(e1), "Wrong validity check");
184 418
  check(g.valid(e2), "Wrong validity check");
185 419

	
186 420
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
187 421
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
188 422
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
189 423
}
190 424

	
191
// void checkGridGraph(const GridGraph& g, int w, int h) {
192
//   check(g.width() == w, "Wrong width");
193
//   check(g.height() == h, "Wrong height");
425
void checkGridGraph(int width, int height) {
426
  typedef GridGraph Graph;
427
  GRAPH_TYPEDEFS(Graph);
428
  Graph G(width, height);
194 429

	
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
//   }
430
  check(G.width() == width, "Wrong column number");
431
  check(G.height() == height, "Wrong row number");
201 432

	
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
//   }
433
  G.resize(width, height);
434
  check(G.width() == width, "Wrong column number");
435
  check(G.height() == height, "Wrong row number");
209 436

	
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
//   }
437
  for (int i = 0; i < width; ++i) {
438
    for (int j = 0; j < height; ++j) {
439
      check(G.col(G(i, j)) == i, "Wrong column");
440
      check(G.row(G(i, j)) == j, "Wrong row");
441
      check(G.pos(G(i, j)).x == i, "Wrong column");
442
      check(G.pos(G(i, j)).y == j, "Wrong row");
443
    }
444
  }
217 445

	
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
//   }
446
  for (int j = 0; j < height; ++j) {
447
    for (int i = 0; i < width - 1; ++i) {
448
      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
449
      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
450
    }
451
    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
452
  }
225 453

	
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
// }
454
  for (int j = 0; j < height; ++j) {
455
    for (int i = 1; i < width; ++i) {
456
      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
457
      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
458
    }
459
    check(G.left(G(0, j)) == INVALID, "Wrong left");
460
  }
461

	
462
  for (int i = 0; i < width; ++i) {
463
    for (int j = 0; j < height - 1; ++j) {
464
      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
465
      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
466
    }
467
    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
468
  }
469

	
470
  for (int i = 0; i < width; ++i) {
471
    for (int j = 1; j < height; ++j) {
472
      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
473
      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
474
    }
475
    check(G.down(G(i, 0)) == INVALID, "Wrong down");
476
  }
477

	
478
  checkGraphNodeList(G, width * height);
479
  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
480
  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
481

	
482
  for (NodeIt n(G); n != INVALID; ++n) {
483
    int nb = 4;
484
    if (G.col(n) == 0) --nb;
485
    if (G.col(n) == width - 1) --nb;
486
    if (G.row(n) == 0) --nb;
487
    if (G.row(n) == height - 1) --nb;
488

	
489
    checkGraphOutArcList(G, n, nb);
490
    checkGraphInArcList(G, n, nb);
491
    checkGraphIncEdgeList(G, n, nb);
492
  }
493

	
494
  checkArcDirections(G);
495

	
496
  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
497
  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
498

	
499
  checkNodeIds(G);
500
  checkArcIds(G);
501
  checkEdgeIds(G);
502
  checkGraphNodeMap(G);
503
  checkGraphArcMap(G);
504
  checkGraphEdgeMap(G);
505

	
506
}
507

	
508
void checkHypercubeGraph(int dim) {
509
  GRAPH_TYPEDEFS(HypercubeGraph);
510

	
511
  HypercubeGraph G(dim);
512
  check(G.dimension() == dim, "Wrong dimension");
513

	
514
  G.resize(dim);
515
  check(G.dimension() == dim, "Wrong dimension");
516
  
517
  checkGraphNodeList(G, 1 << dim);
518
  checkGraphEdgeList(G, dim * (1 << (dim-1)));
519
  checkGraphArcList(G, dim * (1 << dim));
520

	
521
  Node n = G.nodeFromId(dim);
522

	
523
  for (NodeIt n(G); n != INVALID; ++n) {
524
    checkGraphIncEdgeList(G, n, dim);
525
    for (IncEdgeIt e(G, n); e != INVALID; ++e) {
526
      check( (G.u(e) == n &&
527
              G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
528
             (G.v(e) == n &&
529
              G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
530
             "Wrong edge or wrong dimension");
531
    }
532

	
533
    checkGraphOutArcList(G, n, dim);
534
    for (OutArcIt a(G, n); a != INVALID; ++a) {
535
      check(G.source(a) == n &&
536
            G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
537
            "Wrong arc or wrong dimension");
538
    }
539

	
540
    checkGraphInArcList(G, n, dim);
541
    for (InArcIt a(G, n); a != INVALID; ++a) {
542
      check(G.target(a) == n &&
543
            G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
544
            "Wrong arc or wrong dimension");
545
    }
546
  }
547

	
548
  checkGraphConArcList(G, (1 << dim) * dim);
549
  checkGraphConEdgeList(G, dim * (1 << (dim-1)));
550

	
551
  checkArcDirections(G);
552

	
553
  checkNodeIds(G);
554
  checkArcIds(G);
555
  checkEdgeIds(G);
556
  checkGraphNodeMap(G);
557
  checkGraphArcMap(G);
558
  checkGraphEdgeMap(G);
559
}
234 560

	
235 561
void checkGraphs() {
236 562
  { // Checking ListGraph
237
    checkGraph<ListGraph>();
563
    checkGraphBuild<ListGraph>();
564
    checkGraphAlter<ListGraph>();
565
    checkGraphErase<ListGraph>();
566
    checkGraphSnapshot<ListGraph>();
238 567
    checkGraphValidityErase<ListGraph>();
239 568
  }
240 569
  { // Checking SmartGraph
241
    checkGraph<SmartGraph>();
570
    checkGraphBuild<SmartGraph>();
571
    checkGraphSnapshot<SmartGraph>();
242 572
    checkGraphValidity<SmartGraph>();
243 573
  }
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
//   }
574
  { // Checking FullGraph
575
    checkFullGraph(7);
576
    checkFullGraph(8);
577
  }
578
  { // Checking GridGraph
579
    checkGridGraph(5, 8);
580
    checkGridGraph(8, 5);
581
    checkGridGraph(5, 5);
582
    checkGridGraph(0, 0);
583
    checkGridGraph(1, 1);
584
  }
585
  { // Checking HypercubeGraph
586
    checkHypercubeGraph(1);
587
    checkHypercubeGraph(2);
588
    checkHypercubeGraph(3);
589
    checkHypercubeGraph(4);
590
  }
255 591
}
256 592

	
257 593
int main() {
258 594
  checkConcepts();
259 595
  checkGraphs();
260 596
  return 0;
261 597
}
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

	
29 28
#include <lemon/lgf_reader.h>
30 29
#include <lemon/dijkstra.h>
31 30
#include <lemon/maps.h>
32 31

	
33 32
#include <lemon/bin_heap.h>
33
#include <lemon/fourary_heap.h>
34
#include <lemon/kary_heap.h>
35
#include <lemon/fib_heap.h>
36
#include <lemon/pairing_heap.h>
37
#include <lemon/radix_heap.h>
38
#include <lemon/binom_heap.h>
39
#include <lemon/bucket_heap.h>
34 40

	
35 41
#include "test_tools.h"
36 42

	
37 43
using namespace lemon;
38 44
using namespace lemon::concepts;
39 45

	
40 46
typedef ListDigraph Digraph;
41 47
DIGRAPH_TYPEDEFS(Digraph);
42 48

	
43 49
char test_lgf[] =
44 50
  "@nodes\n"
45 51
  "label\n"
46 52
  "0\n"
47 53
  "1\n"
48 54
  "2\n"
49 55
  "3\n"
50 56
  "4\n"
51 57
  "5\n"
52 58
  "6\n"
53 59
  "7\n"
54 60
  "8\n"
55 61
  "9\n"
56 62
  "@arcs\n"
57 63
  "                label   capacity\n"
58 64
  "0       5       0       94\n"
59 65
  "3       9       1       11\n"
60 66
  "8       7       2       83\n"
61 67
  "1       2       3       94\n"
62 68
  "5       7       4       35\n"
63 69
  "7       4       5       84\n"
64 70
  "9       5       6       38\n"
65 71
  "0       4       7       96\n"
66 72
  "6       7       8       6\n"
67 73
  "3       1       9       27\n"
68 74
  "5       2       10      77\n"
69 75
  "5       6       11      69\n"
70 76
  "6       5       12      41\n"
71 77
  "4       6       13      70\n"
72 78
  "3       2       14      45\n"
73 79
  "7       9       15      93\n"
74 80
  "5       9       16      50\n"
75 81
  "9       0       17      94\n"
76 82
  "9       6       18      67\n"
77 83
  "0       9       19      86\n"
78 84
  "@attributes\n"
79 85
  "source 3\n";
80 86

	
81 87
int test_seq[] = { 2, 28, 19, 27, 33, 25, 13, 41, 10, 26,  1,  9,  4, 34};
82 88
int test_inc[] = {20, 28, 34, 16,  0, 46, 44,  0, 42, 32, 14,  8,  6, 37};
83 89

	
84 90
int test_len = sizeof(test_seq) / sizeof(test_seq[0]);
85 91

	
86 92
template <typename Heap>
87 93
void heapSortTest() {
88 94
  RangeMap<int> map(test_len, -1);
89

	
90 95
  Heap heap(map);
91 96

	
92 97
  std::vector<int> v(test_len);
93

	
94 98
  for (int i = 0; i < test_len; ++i) {
95 99
    v[i] = test_seq[i];
96 100
    heap.push(i, v[i]);
97 101
  }
98 102
  std::sort(v.begin(), v.end());
99 103
  for (int i = 0; i < test_len; ++i) {
100
    check(v[i] == heap.prio() ,"Wrong order in heap sort.");
104
    check(v[i] == heap.prio(), "Wrong order in heap sort.");
101 105
    heap.pop();
102 106
  }
103 107
}
104 108

	
105 109
template <typename Heap>
106 110
void heapIncreaseTest() {
107 111
  RangeMap<int> map(test_len, -1);
108 112

	
109 113
  Heap heap(map);
110 114

	
111 115
  std::vector<int> v(test_len);
112

	
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
    check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
126
    check(v[i] == heap.prio(), "Wrong order in heap increase test.");
124 127
    heap.pop();
125 128
  }
126 129
}
127 130

	
128

	
129

	
130 131
template <typename Heap>
131 132
void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
132 133
                      Node source) {
133 134

	
134 135
  typename Dijkstra<Digraph, IntArcMap>::template SetStandardHeap<Heap>::
135 136
    Create dijkstra(digraph, length);
136 137

	
137 138
  dijkstra.run(source);
138 139

	
139 140
  for(ArcIt a(digraph); a != INVALID; ++a) {
140 141
    Node s = digraph.source(a);
141 142
    Node t = digraph.target(a);
142 143
    if (dijkstra.reached(s)) {
143 144
      check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
144
             "Error in a shortest path tree!");
145
             "Error in shortest path tree.");
145 146
    }
146 147
  }
147 148

	
148 149
  for(NodeIt n(digraph); n != INVALID; ++n) {
149 150
    if ( dijkstra.reached(n) && dijkstra.predArc(n) != INVALID ) {
150 151
      Arc a = dijkstra.predArc(n);
151 152
      Node s = digraph.source(a);
152 153
      check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
153
             "Error in a shortest path tree!");
154
             "Error in shortest path tree.");
154 155
    }
155 156
  }
156 157

	
157 158
}
158 159

	
159 160
int main() {
160 161

	
161 162
  typedef int Item;
162 163
  typedef int Prio;
163 164
  typedef RangeMap<int> ItemIntMap;
164 165

	
165 166
  Digraph digraph;
166 167
  IntArcMap length(digraph);
167 168
  Node source;
168 169

	
169 170
  std::istringstream input(test_lgf);
170 171
  digraphReader(digraph, input).
171 172
    arcMap("capacity", length).
172 173
    node("source", source).
173 174
    run();
174 175

	
176
  // BinHeap
175 177
  {
176 178
    typedef BinHeap<Prio, ItemIntMap> IntHeap;
177 179
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
178 180
    heapSortTest<IntHeap>();
179 181
    heapIncreaseTest<IntHeap>();
180 182

	
181 183
    typedef BinHeap<Prio, IntNodeMap > NodeHeap;
182 184
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
183 185
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
184 186
  }
185 187

	
188
  // FouraryHeap
189
  {
190
    typedef FouraryHeap<Prio, ItemIntMap> IntHeap;
191
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
192
    heapSortTest<IntHeap>();
193
    heapIncreaseTest<IntHeap>();
194

	
195
    typedef FouraryHeap<Prio, IntNodeMap > NodeHeap;
196
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
197
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
198
  }
199

	
200
  // KaryHeap
201
  {
202
    typedef KaryHeap<Prio, ItemIntMap> IntHeap;
203
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
204
    heapSortTest<IntHeap>();
205
    heapIncreaseTest<IntHeap>();
206

	
207
    typedef KaryHeap<Prio, IntNodeMap > NodeHeap;
208
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
209
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
210
  }
211

	
212
  // FibHeap
213
  {
214
    typedef FibHeap<Prio, ItemIntMap> IntHeap;
215
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
216
    heapSortTest<IntHeap>();
217
    heapIncreaseTest<IntHeap>();
218

	
219
    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
220
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
221
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
222
  }
223

	
224
  // PairingHeap
225
  {
226
    typedef PairingHeap<Prio, ItemIntMap> IntHeap;
227
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
228
    heapSortTest<IntHeap>();
229
    heapIncreaseTest<IntHeap>();
230

	
231
    typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
232
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
233
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
234
  }
235

	
236
  // RadixHeap
237
  {
238
    typedef RadixHeap<ItemIntMap> IntHeap;
239
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
240
    heapSortTest<IntHeap>();
241
    heapIncreaseTest<IntHeap>();
242

	
243
    typedef RadixHeap<IntNodeMap > NodeHeap;
244
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
245
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
246
  }
247

	
248
  // BinomHeap
249
  {
250
    typedef BinomHeap<Prio, ItemIntMap> IntHeap;
251
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
252
    heapSortTest<IntHeap>();
253
    heapIncreaseTest<IntHeap>();
254

	
255
    typedef BinomHeap<Prio, IntNodeMap > NodeHeap;
256
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
257
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
258
  }
259

	
260
  // BucketHeap, SimpleBucketHeap
261
  {
262
    typedef BucketHeap<ItemIntMap> IntHeap;
263
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
264
    heapSortTest<IntHeap>();
265
    heapIncreaseTest<IntHeap>();
266

	
267
    typedef BucketHeap<IntNodeMap > NodeHeap;
268
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
269
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
270

	
271
    typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
272
    heapSortTest<SimpleIntHeap>();
273
  }
274

	
186 275
  return 0;
187 276
}
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
#include <lemon/list_graph.h>
26
#include <lemon/smart_graph.h>
27
#include <lemon/adaptors.h>
28
#include <lemon/dfs.h>
25 29

	
26 30
#include "test_tools.h"
27 31

	
28 32
using namespace lemon;
29 33
using namespace lemon::concepts;
30 34

	
31 35
struct A {};
32 36
inline bool operator<(A, A) { return true; }
33 37
struct B {};
34 38

	
35 39
class C {
36 40
  int x;
37 41
public:
38 42
  C(int _x) : x(_x) {}
39 43
};
40 44

	
41 45
class F {
42 46
public:
43 47
  typedef A argument_type;
44 48
  typedef B result_type;
45 49

	
46 50
  B operator()(const A&) const { return B(); }
47 51
private:
48 52
  F& operator=(const F&);
49 53
};
50 54

	
51 55
int func(A) { return 3; }
52 56

	
53 57
int binc(int a, B) { return a+1; }
54 58

	
55 59
typedef ReadMap<A, double> DoubleMap;
56 60
typedef ReadWriteMap<A, double> DoubleWriteMap;
57 61
typedef ReferenceMap<A, double, double&, const double&> DoubleRefMap;
58 62

	
59 63
typedef ReadMap<A, bool> BoolMap;
60 64
typedef ReadWriteMap<A, bool> BoolWriteMap;
61 65
typedef ReferenceMap<A, bool, bool&, const bool&> BoolRefMap;
62 66

	
67
template<typename Map1, typename Map2, typename ItemIt>
68
void compareMap(const Map1& map1, const Map2& map2, ItemIt it) {
69
  for (; it != INVALID; ++it)
70
    check(map1[it] == map2[it], "The maps are not equal");
71
}
72

	
63 73
int main()
64 74
{
65 75
  // Map concepts
66 76
  checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
67 77
  checkConcept<ReadMap<A,C>, ReadMap<A,C> >();
68 78
  checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
69 79
  checkConcept<WriteMap<A,C>, WriteMap<A,C> >();
70 80
  checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
71 81
  checkConcept<ReadWriteMap<A,C>, ReadWriteMap<A,C> >();
72 82
  checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();
73 83
  checkConcept<ReferenceMap<A,C,C&,const C&>, ReferenceMap<A,C,C&,const C&> >();
74 84

	
75 85
  // NullMap
76 86
  {
77 87
    checkConcept<ReadWriteMap<A,B>, NullMap<A,B> >();
78 88
    NullMap<A,B> map1;
79 89
    NullMap<A,B> map2 = map1;
80 90
    map1 = nullMap<A,B>();
81 91
  }
82 92

	
83 93
  // ConstMap
84 94
  {
85 95
    checkConcept<ReadWriteMap<A,B>, ConstMap<A,B> >();
86 96
    checkConcept<ReadWriteMap<A,C>, ConstMap<A,C> >();
87 97
    ConstMap<A,B> map1;
88 98
    ConstMap<A,B> map2 = B();
89 99
    ConstMap<A,B> map3 = map1;
90 100
    map1 = constMap<A>(B());
91 101
    map1 = constMap<A,B>();
92 102
    map1.setAll(B());
93 103
    ConstMap<A,C> map4(C(1));
94 104
    ConstMap<A,C> map5 = map4;
95 105
    map4 = constMap<A>(C(2));
96 106
    map4.setAll(C(3));
97 107

	
98 108
    checkConcept<ReadWriteMap<A,int>, ConstMap<A,int> >();
99 109
    check(constMap<A>(10)[A()] == 10, "Something is wrong with ConstMap");
100 110

	
101 111
    checkConcept<ReadWriteMap<A,int>, ConstMap<A,Const<int,10> > >();
102 112
    ConstMap<A,Const<int,10> > map6;
103 113
    ConstMap<A,Const<int,10> > map7 = map6;
104 114
    map6 = constMap<A,int,10>();
105 115
    map7 = constMap<A,Const<int,10> >();
106 116
    check(map6[A()] == 10 && map7[A()] == 10,
107 117
          "Something is wrong with ConstMap");
108 118
  }
109 119

	
110 120
  // IdentityMap
111 121
  {
112 122
    checkConcept<ReadMap<A,A>, IdentityMap<A> >();
113 123
    IdentityMap<A> map1;
114 124
    IdentityMap<A> map2 = map1;
115 125
    map1 = identityMap<A>();
116 126

	
117 127
    checkConcept<ReadMap<double,double>, IdentityMap<double> >();
118 128
    check(identityMap<double>()[1.0] == 1.0 &&
119 129
          identityMap<double>()[3.14] == 3.14,
120 130
          "Something is wrong with IdentityMap");
121 131
  }
122 132

	
123 133
  // RangeMap
124 134
  {
125 135
    checkConcept<ReferenceMap<int,B,B&,const B&>, RangeMap<B> >();
126 136
    RangeMap<B> map1;
127 137
    RangeMap<B> map2(10);
128 138
    RangeMap<B> map3(10,B());
129 139
    RangeMap<B> map4 = map1;
130 140
    RangeMap<B> map5 = rangeMap<B>();
131 141
    RangeMap<B> map6 = rangeMap<B>(10);
132 142
    RangeMap<B> map7 = rangeMap(10,B());
133 143

	
134 144
    checkConcept< ReferenceMap<int, double, double&, const double&>,
135 145
                  RangeMap<double> >();
136 146
    std::vector<double> v(10, 0);
137 147
    v[5] = 100;
138 148
    RangeMap<double> map8(v);
139 149
    RangeMap<double> map9 = rangeMap(v);
140 150
    check(map9.size() == 10 && map9[2] == 0 && map9[5] == 100,
141 151
          "Something is wrong with RangeMap");
142 152
  }
143 153

	
144 154
  // SparseMap
145 155
  {
146 156
    checkConcept<ReferenceMap<A,B,B&,const B&>, SparseMap<A,B> >();
147 157
    SparseMap<A,B> map1;
148 158
    SparseMap<A,B> map2 = B();
149 159
    SparseMap<A,B> map3 = sparseMap<A,B>();
150 160
    SparseMap<A,B> map4 = sparseMap<A>(B());
151 161

	
152 162
    checkConcept< ReferenceMap<double, int, int&, const int&>,
153 163
                  SparseMap<double, int> >();
154 164
    std::map<double, int> m;
155 165
    SparseMap<double, int> map5(m);
156 166
    SparseMap<double, int> map6(m,10);
157 167
    SparseMap<double, int> map7 = sparseMap(m);
158 168
    SparseMap<double, int> map8 = sparseMap(m,10);
159 169

	
160 170
    check(map5[1.0] == 0 && map5[3.14] == 0 &&
161 171
          map6[1.0] == 10 && map6[3.14] == 10,
162 172
          "Something is wrong with SparseMap");
163 173
    map5[1.0] = map6[3.14] = 100;
164 174
    check(map5[1.0] == 100 && map5[3.14] == 0 &&
165 175
          map6[1.0] == 10 && map6[3.14] == 100,
166 176
          "Something is wrong with SparseMap");
167 177
  }
168 178

	
169 179
  // ComposeMap
170 180
  {
171 181
    typedef ComposeMap<DoubleMap, ReadMap<B,A> > CompMap;
172 182
    checkConcept<ReadMap<B,double>, CompMap>();
173
    CompMap map1(DoubleMap(),ReadMap<B,A>());
183
    CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
174 184
    CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
175 185

	
176 186
    SparseMap<double, bool> m1(false); m1[3.14] = true;
177 187
    RangeMap<double> m2(2); m2[0] = 3.0; m2[1] = 3.14;
178 188
    check(!composeMap(m1,m2)[0] && composeMap(m1,m2)[1],
179 189
          "Something is wrong with ComposeMap")
180 190
  }
181 191

	
182 192
  // CombineMap
183 193
  {
184 194
    typedef CombineMap<DoubleMap, DoubleMap, std::plus<double> > CombMap;
185 195
    checkConcept<ReadMap<A,double>, CombMap>();
186
    CombMap map1(DoubleMap(), DoubleMap());
196
    CombMap map1 = CombMap(DoubleMap(), DoubleMap());
187 197
    CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
188 198

	
189 199
    check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
190 200
          "Something is wrong with CombineMap");
191 201
  }
192 202

	
193 203
  // FunctorToMap, MapToFunctor
194 204
  {
195 205
    checkConcept<ReadMap<A,B>, FunctorToMap<F,A,B> >();
196 206
    checkConcept<ReadMap<A,B>, FunctorToMap<F> >();
197 207
    FunctorToMap<F> map1;
198
    FunctorToMap<F> map2(F());
208
    FunctorToMap<F> map2 = FunctorToMap<F>(F());
199 209
    B b = functorToMap(F())[A()];
200 210

	
201 211
    checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
202
    MapToFunctor<ReadMap<A,B> > map(ReadMap<A,B>());
212
    MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
203 213

	
204 214
    check(functorToMap(&func)[A()] == 3,
205 215
          "Something is wrong with FunctorToMap");
206 216
    check(mapToFunctor(constMap<A,int>(2))(A()) == 2,
207 217
          "Something is wrong with MapToFunctor");
208 218
    check(mapToFunctor(functorToMap(&func))(A()) == 3 &&
209 219
          mapToFunctor(functorToMap(&func))[A()] == 3,
210 220
          "Something is wrong with FunctorToMap or MapToFunctor");
211 221
    check(functorToMap(mapToFunctor(constMap<A,int>(2)))[A()] == 2,
212 222
          "Something is wrong with FunctorToMap or MapToFunctor");
213 223
  }
214 224

	
215 225
  // ConvertMap
216 226
  {
217 227
    checkConcept<ReadMap<double,double>,
218 228
      ConvertMap<ReadMap<double, int>, double> >();
219 229
    ConvertMap<RangeMap<bool>, int> map1(rangeMap(1, true));
220 230
    ConvertMap<RangeMap<bool>, int> map2 = convertMap<int>(rangeMap(2, false));
221 231
  }
222 232

	
223 233
  // ForkMap
224 234
  {
225 235
    checkConcept<DoubleWriteMap, ForkMap<DoubleWriteMap, DoubleWriteMap> >();
226 236

	
227 237
    typedef RangeMap<double> RM;
228 238
    typedef SparseMap<int, double> SM;
229 239
    RM m1(10, -1);
230 240
    SM m2(-1);
231 241
    checkConcept<ReadWriteMap<int, double>, ForkMap<RM, SM> >();
232 242
    checkConcept<ReadWriteMap<int, double>, ForkMap<SM, RM> >();
233 243
    ForkMap<RM, SM> map1(m1,m2);
234 244
    ForkMap<SM, RM> map2 = forkMap(m2,m1);
235 245
    map2.set(5, 10);
236 246
    check(m1[1] == -1 && m1[5] == 10 && m2[1] == -1 &&
237 247
          m2[5] == 10 && map2[1] == -1 && map2[5] == 10,
238 248
          "Something is wrong with ForkMap");
239 249
  }
240 250

	
241 251
  // Arithmetic maps:
242 252
  // - AddMap, SubMap, MulMap, DivMap
243 253
  // - ShiftMap, ShiftWriteMap, ScaleMap, ScaleWriteMap
244 254
  // - NegMap, NegWriteMap, AbsMap
245 255
  {
246 256
    checkConcept<DoubleMap, AddMap<DoubleMap,DoubleMap> >();
247 257
    checkConcept<DoubleMap, SubMap<DoubleMap,DoubleMap> >();
248 258
    checkConcept<DoubleMap, MulMap<DoubleMap,DoubleMap> >();
249 259
    checkConcept<DoubleMap, DivMap<DoubleMap,DoubleMap> >();
250 260

	
251 261
    ConstMap<int, double> c1(1.0), c2(3.14);
252 262
    IdentityMap<int> im;
253 263
    ConvertMap<IdentityMap<int>, double> id(im);
254 264
    check(addMap(c1,id)[0] == 1.0  && addMap(c1,id)[10] == 11.0,
255 265
          "Something is wrong with AddMap");
256 266
    check(subMap(id,c1)[0] == -1.0 && subMap(id,c1)[10] == 9.0,
257 267
          "Something is wrong with SubMap");
258 268
    check(mulMap(id,c2)[0] == 0    && mulMap(id,c2)[2]  == 6.28,
259 269
          "Something is wrong with MulMap");
260 270
    check(divMap(c2,id)[1] == 3.14 && divMap(c2,id)[2]  == 1.57,
261 271
          "Something is wrong with DivMap");
262 272

	
263 273
    checkConcept<DoubleMap, ShiftMap<DoubleMap> >();
264 274
    checkConcept<DoubleWriteMap, ShiftWriteMap<DoubleWriteMap> >();
265 275
    checkConcept<DoubleMap, ScaleMap<DoubleMap> >();
266 276
    checkConcept<DoubleWriteMap, ScaleWriteMap<DoubleWriteMap> >();
267 277
    checkConcept<DoubleMap, NegMap<DoubleMap> >();
268 278
    checkConcept<DoubleWriteMap, NegWriteMap<DoubleWriteMap> >();
269 279
    checkConcept<DoubleMap, AbsMap<DoubleMap> >();
270 280

	
271 281
    check(shiftMap(id, 2.0)[1] == 3.0 && shiftMap(id, 2.0)[10] == 12.0,
272 282
          "Something is wrong with ShiftMap");
273 283
    check(shiftWriteMap(id, 2.0)[1] == 3.0 &&
274 284
          shiftWriteMap(id, 2.0)[10] == 12.0,
275 285
          "Something is wrong with ShiftWriteMap");
276 286
    check(scaleMap(id, 2.0)[1] == 2.0 && scaleMap(id, 2.0)[10] == 20.0,
277 287
          "Something is wrong with ScaleMap");
278 288
    check(scaleWriteMap(id, 2.0)[1] == 2.0 &&
279 289
          scaleWriteMap(id, 2.0)[10] == 20.0,
280 290
          "Something is wrong with ScaleWriteMap");
281 291
    check(negMap(id)[1] == -1.0 && negMap(id)[-10] == 10.0,
282 292
          "Something is wrong with NegMap");
283 293
    check(negWriteMap(id)[1] == -1.0 && negWriteMap(id)[-10] == 10.0,
284 294
          "Something is wrong with NegWriteMap");
285 295
    check(absMap(id)[1] == 1.0 && absMap(id)[-10] == 10.0,
286 296
          "Something is wrong with AbsMap");
287 297
  }
288 298

	
289 299
  // Logical maps:
290 300
  // - TrueMap, FalseMap
291 301
  // - AndMap, OrMap
292 302
  // - NotMap, NotWriteMap
293 303
  // - EqualMap, LessMap
294 304
  {
295 305
    checkConcept<BoolMap, TrueMap<A> >();
296 306
    checkConcept<BoolMap, FalseMap<A> >();
297 307
    checkConcept<BoolMap, AndMap<BoolMap,BoolMap> >();
298 308
    checkConcept<BoolMap, OrMap<BoolMap,BoolMap> >();
299 309
    checkConcept<BoolMap, NotMap<BoolMap> >();
300 310
    checkConcept<BoolWriteMap, NotWriteMap<BoolWriteMap> >();
301 311
    checkConcept<BoolMap, EqualMap<DoubleMap,DoubleMap> >();
302 312
    checkConcept<BoolMap, LessMap<DoubleMap,DoubleMap> >();
303 313

	
304 314
    TrueMap<int> tm;
305 315
    FalseMap<int> fm;
306 316
    RangeMap<bool> rm(2);
307 317
    rm[0] = true; rm[1] = false;
308 318
    check(andMap(tm,rm)[0] && !andMap(tm,rm)[1] &&
309 319
          !andMap(fm,rm)[0] && !andMap(fm,rm)[1],
310 320
          "Something is wrong with AndMap");
311 321
    check(orMap(tm,rm)[0] && orMap(tm,rm)[1] &&
312 322
          orMap(fm,rm)[0] && !orMap(fm,rm)[1],
313 323
          "Something is wrong with OrMap");
314 324
    check(!notMap(rm)[0] && notMap(rm)[1],
315 325
          "Something is wrong with NotMap");
316 326
    check(!notWriteMap(rm)[0] && notWriteMap(rm)[1],
317 327
          "Something is wrong with NotWriteMap");
318 328

	
319 329
    ConstMap<int, double> cm(2.0);
320 330
    IdentityMap<int> im;
321 331
    ConvertMap<IdentityMap<int>, double> id(im);
322 332
    check(lessMap(id,cm)[1] && !lessMap(id,cm)[2] && !lessMap(id,cm)[3],
323 333
          "Something is wrong with LessMap");
324 334
    check(!equalMap(id,cm)[1] && equalMap(id,cm)[2] && !equalMap(id,cm)[3],
325 335
          "Something is wrong with EqualMap");
326 336
  }
327 337

	
328 338
  // LoggerBoolMap
329 339
  {
330 340
    typedef std::vector<int> vec;
341
    checkConcept<WriteMap<int, bool>, LoggerBoolMap<vec::iterator> >();
342
    checkConcept<WriteMap<int, bool>,
343
                 LoggerBoolMap<std::back_insert_iterator<vec> > >();
344

	
331 345
    vec v1;
332 346
    vec v2(10);
333 347
    LoggerBoolMap<std::back_insert_iterator<vec> >
334 348
      map1(std::back_inserter(v1));
335 349
    LoggerBoolMap<vec::iterator> map2(v2.begin());
336 350
    map1.set(10, false);
337 351
    map1.set(20, true);   map2.set(20, true);
338 352
    map1.set(30, false);  map2.set(40, false);
339 353
    map1.set(50, true);   map2.set(50, true);
340 354
    map1.set(60, true);   map2.set(60, true);
341 355
    check(v1.size() == 3 && v2.size() == 10 &&
342 356
          v1[0]==20 && v1[1]==50 && v1[2]==60 &&
343 357
          v2[0]==20 && v2[1]==50 && v2[2]==60,
344 358
          "Something is wrong with LoggerBoolMap");
345 359

	
346 360
    int i = 0;
347 361
    for ( LoggerBoolMap<vec::iterator>::Iterator it = map2.begin();
348 362
          it != map2.end(); ++it )
349 363
      check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
364
    
365
    typedef ListDigraph Graph;
366
    DIGRAPH_TYPEDEFS(Graph);
367
    Graph gr;
368

	
369
    Node n0 = gr.addNode();
370
    Node n1 = gr.addNode();
371
    Node n2 = gr.addNode();
372
    Node n3 = gr.addNode();
373
    
374
    gr.addArc(n3, n0);
375
    gr.addArc(n3, n2);
376
    gr.addArc(n0, n2);
377
    gr.addArc(n2, n1);
378
    gr.addArc(n0, n1);
379
    
380
    {
381
      std::vector<Node> v;
382
      dfs(gr).processedMap(loggerBoolMap(std::back_inserter(v))).run();
383

	
384
      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
385
            "Something is wrong with LoggerBoolMap");
386
    }
387
    {
388
      std::vector<Node> v(countNodes(gr));
389
      dfs(gr).processedMap(loggerBoolMap(v.begin())).run();
390
      
391
      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
392
            "Something is wrong with LoggerBoolMap");
393
    }
394
  }
395
  
396
  // IdMap, RangeIdMap
397
  {
398
    typedef ListDigraph Graph;
399
    DIGRAPH_TYPEDEFS(Graph);
400

	
401
    checkConcept<ReadMap<Node, int>, IdMap<Graph, Node> >();
402
    checkConcept<ReadMap<Arc, int>, IdMap<Graph, Arc> >();
403
    checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
404
    checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
405
    
406
    Graph gr;
407
    IdMap<Graph, Node> nmap(gr);
408
    IdMap<Graph, Arc> amap(gr);
409
    RangeIdMap<Graph, Node> nrmap(gr);
410
    RangeIdMap<Graph, Arc> armap(gr);
411
    
412
    Node n0 = gr.addNode();
413
    Node n1 = gr.addNode();
414
    Node n2 = gr.addNode();
415
    
416
    Arc a0 = gr.addArc(n0, n1);
417
    Arc a1 = gr.addArc(n0, n2);
418
    Arc a2 = gr.addArc(n2, n1);
419
    Arc a3 = gr.addArc(n2, n0);
420
    
421
    check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
422
    check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
423
    check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap");
424

	
425
    check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap");
426
    check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap");
427
    check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap");
428
    check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap");
429

	
430
    check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
431
    check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
432
    
433
    check(nrmap.size() == 3 && armap.size() == 4,
434
          "Wrong RangeIdMap::size()");
435

	
436
    check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap");
437
    check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
438
    check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
439
    
440
    check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
441
    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
442
    check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap");
443
    check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap");
444

	
445
    check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
446
    check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
447
    
448
    gr.erase(n1);
449
    
450
    if (nrmap[n0] == 1) nrmap.swap(n0, n2);
451
    nrmap.swap(n2, n0);
452
    if (armap[a1] == 1) armap.swap(a1, a3);
453
    armap.swap(a3, a1);
454
    
455
    check(nrmap.size() == 2 && armap.size() == 2,
456
          "Wrong RangeIdMap::size()");
457

	
458
    check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
459
    check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
460
    
461
    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
462
    check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
463

	
464
    check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap");
465
    check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
466
  }
467
  
468
  // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap
469
  {
470
    typedef ListGraph Graph;
471
    GRAPH_TYPEDEFS(Graph);
472
    
473
    checkConcept<ReadMap<Arc, Node>, SourceMap<Graph> >();
474
    checkConcept<ReadMap<Arc, Node>, TargetMap<Graph> >();
475
    checkConcept<ReadMap<Edge, Arc>, ForwardMap<Graph> >();
476
    checkConcept<ReadMap<Edge, Arc>, BackwardMap<Graph> >();
477
    checkConcept<ReadMap<Node, int>, InDegMap<Graph> >();
478
    checkConcept<ReadMap<Node, int>, OutDegMap<Graph> >();
479

	
480
    Graph gr;
481
    Node n0 = gr.addNode();
482
    Node n1 = gr.addNode();
483
    Node n2 = gr.addNode();
484
    
485
    gr.addEdge(n0,n1);
486
    gr.addEdge(n1,n2);
487
    gr.addEdge(n0,n2);
488
    gr.addEdge(n2,n1);
489
    gr.addEdge(n1,n2);
490
    gr.addEdge(n0,n1);
491
    
492
    for (EdgeIt e(gr); e != INVALID; ++e) {
493
      check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap");
494
      check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap");
495
    }
496
    
497
    compareMap(sourceMap(orienter(gr, constMap<Edge, bool>(true))),
498
               targetMap(orienter(gr, constMap<Edge, bool>(false))),
499
               EdgeIt(gr));
500

	
501
    typedef Orienter<Graph, const ConstMap<Edge, bool> > Digraph;
502
    Digraph dgr(gr, constMap<Edge, bool>(true));
503
    OutDegMap<Digraph> odm(dgr);
504
    InDegMap<Digraph> idm(dgr);
505
    
506
    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap");
507
    check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
508
   
509
    gr.addEdge(n2, n0);
510

	
511
    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 2, "Wrong OutDegMap");
512
    check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
513
  }
514
  
515
  // CrossRefMap
516
  {
517
    typedef ListDigraph Graph;
518
    DIGRAPH_TYPEDEFS(Graph);
519

	
520
    checkConcept<ReadWriteMap<Node, int>,
521
                 CrossRefMap<Graph, Node, int> >();
522
    checkConcept<ReadWriteMap<Node, bool>,
523
                 CrossRefMap<Graph, Node, bool> >();
524
    checkConcept<ReadWriteMap<Node, double>,
525
                 CrossRefMap<Graph, Node, double> >();
526
    
527
    Graph gr;
528
    typedef CrossRefMap<Graph, Node, char> CRMap;
529
    CRMap map(gr);
530
    
531
    Node n0 = gr.addNode();
532
    Node n1 = gr.addNode();
533
    Node n2 = gr.addNode();
534
    
535
    map.set(n0, 'A');
536
    map.set(n1, 'B');
537
    map.set(n2, 'C');
538
    
539
    check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
540
          "Wrong CrossRefMap");
541
    check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1,
542
          "Wrong CrossRefMap");
543
    check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2,
544
          "Wrong CrossRefMap");
545
    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
546
          "Wrong CrossRefMap::count()");
547
    
548
    CRMap::ValueIt it = map.beginValue();
549
    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
550
          it == map.endValue(), "Wrong value iterator");
551
    
552
    map.set(n2, 'A');
553

	
554
    check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A',
555
          "Wrong CrossRefMap");
556
    check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap");
557
    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
558
    check(map('C') == INVALID && map.inverse()['C'] == INVALID,
559
          "Wrong CrossRefMap");
560
    check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0,
561
          "Wrong CrossRefMap::count()");
562

	
563
    it = map.beginValue();
564
    check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' &&
565
          it == map.endValue(), "Wrong value iterator");
566

	
567
    map.set(n0, 'C');
568

	
569
    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
570
          "Wrong CrossRefMap");
571
    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
572
    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
573
    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
574
    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
575
          "Wrong CrossRefMap::count()");
576

	
577
    it = map.beginValue();
578
    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
579
          it == map.endValue(), "Wrong value iterator");
350 580
  }
351 581

	
582
  // CrossRefMap
583
  {
584
    typedef SmartDigraph Graph;
585
    DIGRAPH_TYPEDEFS(Graph);
586

	
587
    checkConcept<ReadWriteMap<Node, int>,
588
                 CrossRefMap<Graph, Node, int> >();
589
    
590
    Graph gr;
591
    typedef CrossRefMap<Graph, Node, char> CRMap;
592
    typedef CRMap::ValueIterator ValueIt;
593
    CRMap map(gr);
594
    
595
    Node n0 = gr.addNode();
596
    Node n1 = gr.addNode();
597
    Node n2 = gr.addNode();
598
    
599
    map.set(n0, 'A');
600
    map.set(n1, 'B');
601
    map.set(n2, 'C');
602
    map.set(n2, 'A');
603
    map.set(n0, 'C');
604

	
605
    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
606
          "Wrong CrossRefMap");
607
    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
608
    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
609
    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
610

	
611
    ValueIt it = map.beginValue();
612
    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
613
          it == map.endValue(), "Wrong value iterator");
614
  }
615
  
616
  // Iterable bool map
617
  {
618
    typedef SmartGraph Graph;
619
    typedef SmartGraph::Node Item;
620

	
621
    typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
622
    checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
623

	
624
    const int num = 10;
625
    Graph g;
626
    std::vector<Item> items;
627
    for (int i = 0; i < num; ++i) {
628
      items.push_back(g.addNode());
629
    }
630

	
631
    Ibm map1(g, true);
632
    int n = 0;
633
    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
634
      check(map1[static_cast<Item>(it)], "Wrong TrueIt");
635
      ++n;
636
    }
637
    check(n == num, "Wrong number");
638

	
639
    n = 0;
640
    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
641
        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
642
        ++n;
643
    }
644
    check(n == num, "Wrong number");
645
    check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
646
    check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
647

	
648
    map1[items[5]] = true;
649

	
650
    n = 0;
651
    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
652
        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
653
        ++n;
654
    }
655
    check(n == num, "Wrong number");
656

	
657
    map1[items[num / 2]] = false;
658
    check(map1[items[num / 2]] == false, "Wrong map value");
659

	
660
    n = 0;
661
    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
662
        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
663
        ++n;
664
    }
665
    check(n == num - 1, "Wrong number");
666

	
667
    n = 0;
668
    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
669
        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
670
        ++n;
671
    }
672
    check(n == 1, "Wrong number");
673

	
674
    map1[items[0]] = false;
675
    check(map1[items[0]] == false, "Wrong map value");
676

	
677
    map1[items[num - 1]] = false;
678
    check(map1[items[num - 1]] == false, "Wrong map value");
679

	
680
    n = 0;
681
    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
682
        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
683
        ++n;
684
    }
685
    check(n == num - 3, "Wrong number");
686
    check(map1.trueNum() == num - 3, "Wrong number");
687

	
688
    n = 0;
689
    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
690
        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
691
        ++n;
692
    }
693
    check(n == 3, "Wrong number");
694
    check(map1.falseNum() == 3, "Wrong number");
695
  }
696

	
697
  // Iterable int map
698
  {
699
    typedef SmartGraph Graph;
700
    typedef SmartGraph::Node Item;
701
    typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
702

	
703
    checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
704

	
705
    const int num = 10;
706
    Graph g;
707
    std::vector<Item> items;
708
    for (int i = 0; i < num; ++i) {
709
      items.push_back(g.addNode());
710
    }
711

	
712
    Iim map1(g);
713
    check(map1.size() == 0, "Wrong size");
714

	
715
    for (int i = 0; i < num; ++i) {
716
      map1[items[i]] = i;
717
    }
718
    check(map1.size() == num, "Wrong size");
719

	
720
    for (int i = 0; i < num; ++i) {
721
      Iim::ItemIt it(map1, i);
722
      check(static_cast<Item>(it) == items[i], "Wrong value");
723
      ++it;
724
      check(static_cast<Item>(it) == INVALID, "Wrong value");
725
    }
726

	
727
    for (int i = 0; i < num; ++i) {
728
      map1[items[i]] = i % 2;
729
    }
730
    check(map1.size() == 2, "Wrong size");
731

	
732
    int n = 0;
733
    for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
734
      check(map1[static_cast<Item>(it)] == 0, "Wrong value");
735
      ++n;
736
    }
737
    check(n == (num + 1) / 2, "Wrong number");
738

	
739
    for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
740
      check(map1[static_cast<Item>(it)] == 1, "Wrong value");
741
      ++n;
742
    }
743
    check(n == num, "Wrong number");
744

	
745
  }
746

	
747
  // Iterable value map
748
  {
749
    typedef SmartGraph Graph;
750
    typedef SmartGraph::Node Item;
751
    typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
752

	
753
    checkConcept<ReadWriteMap<Item, double>, Ivm>();
754

	
755
    const int num = 10;
756
    Graph g;
757
    std::vector<Item> items;
758
    for (int i = 0; i < num; ++i) {
759
      items.push_back(g.addNode());
760
    }
761

	
762
    Ivm map1(g, 0.0);
763
    check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
764
    check(*map1.beginValue() == 0.0, "Wrong value");
765

	
766
    for (int i = 0; i < num; ++i) {
767
      map1.set(items[i], static_cast<double>(i));
768
    }
769
    check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
770

	
771
    for (int i = 0; i < num; ++i) {
772
      Ivm::ItemIt it(map1, static_cast<double>(i));
773
      check(static_cast<Item>(it) == items[i], "Wrong value");
774
      ++it;
775
      check(static_cast<Item>(it) == INVALID, "Wrong value");
776
    }
777

	
778
    for (Ivm::ValueIt vit = map1.beginValue();
779
         vit != map1.endValue(); ++vit) {
780
      check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
781
            "Wrong ValueIt");
782
    }
783

	
784
    for (int i = 0; i < num; ++i) {
785
      map1.set(items[i], static_cast<double>(i % 2));
786
    }
787
    check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
788

	
789
    int n = 0;
790
    for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
791
      check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
792
      ++n;
793
    }
794
    check(n == (num + 1) / 2, "Wrong number");
795

	
796
    for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
797
      check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
798
      ++n;
799
    }
800
    check(n == num, "Wrong number");
801

	
802
  }
352 803
  return 0;
353 804
}
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
#define check(rc, msg) \
41
  if(!(rc)) { \
42
    std::cerr << __FILE__ ":" << __LINE__ << ": error: " << msg << std::endl; \
43
    abort(); \
44
  } else { } \
40
#define check(rc, msg)                                                  \
41
  {                                                                     \
42
    if(!(rc)) {                                                         \
43
      std::cerr << __FILE__ ":" << __LINE__ << ": error: "              \
44
                << msg << std::endl;                                    \
45
      abort();                                                          \
46
    } else { }                                                          \
47
  }                                                                     \
48
    
45 49

	
46 50
#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/\<digraph_adaptor\.h\>/adaptors.h/g"\
72
        -e "s/\<digraph_utils\.h\>/core.h/g"\
73
        -e "s/\<digraph_reader\.h\>/lgf_reader.h/g"\
74
        -e "s/\<digraph_writer\.h\>/lgf_writer.h/g"\
75
        -e "s/\<topology\.h\>/connectivity.h/g"\
76
        -e "s/DigraphToEps/GraphToEps/g"\
77
        -e "s/digraphToEps/graphToEps/g"\
78
        -e "s/\<DefPredMap\>/SetPredMap/g"\
79
        -e "s/\<DefDistMap\>/SetDistMap/g"\
80
        -e "s/\<DefReachedMap\>/SetReachedMap/g"\
81
        -e "s/\<DefProcessedMap\>/SetProcessedMap/g"\
82
        -e "s/\<DefHeap\>/SetHeap/g"\
83
        -e "s/\<DefStandardHeap\>/SetStandradHeap/g"\
84
        -e "s/\<DefOperationTraits\>/SetOperationTraits/g"\
85
        -e "s/\<DefProcessedMapToBeDefaultMap\>/SetStandardProcessedMap/g"\
86
        -e "s/\<copyGraph\>/graphCopy/g"\
87
        -e "s/\<copyDigraph\>/digraphCopy/g"\
88
        -e "s/\<HyperCubeDigraph\>/HypercubeGraph/g"\
89
        -e "s/\<IntegerMap\>/RangeMap/g"\
90
        -e "s/\<integerMap\>/rangeMap/g"\
91
        -e "s/\<\([sS]\)tdMap\>/\1parseMap/g"\
92
        -e "s/\<\([Ff]\)unctorMap\>/\1unctorToMap/g"\
93
        -e "s/\<\([Mm]\)apFunctor\>/\1apToFunctor/g"\
94
        -e "s/\<\([Ff]\)orkWriteMap\>/\1orkMap/g"\
95
        -e "s/\<StoreBoolMap\>/LoggerBoolMap/g"\
96
        -e "s/\<storeBoolMap\>/loggerBoolMap/g"\
97
        -e "s/\<InvertableMap\>/CrossRefMap/g"\
98
        -e "s/\<invertableMap\>/crossRefMap/g"\
99
        -e "s/\<DescriptorMap\>/RangeIdMap/g"\
100
        -e "s/\<descriptorMap\>/rangeIdMap/g"\
101
        -e "s/\<BoundingBox\>/Box/g"\
102
        -e "s/\<readNauty\>/readNautyGraph/g"\
103
        -e "s/\<RevDigraphAdaptor\>/ReverseDigraph/g"\
104
        -e "s/\<revDigraphAdaptor\>/reverseDigraph/g"\
105
        -e "s/\<SubDigraphAdaptor\>/SubDigraph/g"\
106
        -e "s/\<subDigraphAdaptor\>/subDigraph/g"\
107
        -e "s/\<SubGraphAdaptor\>/SubGraph/g"\
108
        -e "s/\<subGraphAdaptor\>/subGraph/g"\
109
        -e "s/\<NodeSubDigraphAdaptor\>/FilterNodes/g"\
110
        -e "s/\<nodeSubDigraphAdaptor\>/filterNodes/g"\
111
        -e "s/\<ArcSubDigraphAdaptor\>/FilterArcs/g"\
112
        -e "s/\<arcSubDigraphAdaptor\>/filterArcs/g"\
113
        -e "s/\<UndirDigraphAdaptor\>/Undirector/g"\
114
        -e "s/\<undirDigraphAdaptor\>/undirector/g"\
115
        -e "s/\<ResDigraphAdaptor\>/ResidualDigraph/g"\
116
        -e "s/\<resDigraphAdaptor\>/residualDigraph/g"\
117
        -e "s/\<SplitDigraphAdaptor\>/SplitNodes/g"\
118
        -e "s/\<splitDigraphAdaptor\>/splitNodes/g"\
119
        -e "s/\<SubGraphAdaptor\>/SubGraph/g"\
120
        -e "s/\<subGraphAdaptor\>/subGraph/g"\
121
        -e "s/\<NodeSubGraphAdaptor\>/FilterNodes/g"\
122
        -e "s/\<nodeSubGraphAdaptor\>/filterNodes/g"\
123
        -e "s/\<ArcSubGraphAdaptor\>/FilterEdges/g"\
124
        -e "s/\<arcSubGraphAdaptor\>/filterEdges/g"\
125
        -e "s/\<DirGraphAdaptor\>/Orienter/g"\
126
        -e "s/\<dirGraphAdaptor\>/orienter/g"\
127
        -e "s/\<LpCplex\>/CplexLp/g"\
128
        -e "s/\<MipCplex\>/CplexMip/g"\
129
        -e "s/\<LpGlpk\>/GlpkLp/g"\
130
        -e "s/\<MipGlpk\>/GlpkMip/g"\
131
        -e "s/\<LpSoplex\>/SoplexLp/g"\
132
    <$i > $TMP
133
    mv $TMP $i
134
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)