gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 105 25
merge default
20 files changed with 23512 insertions and 3550 deletions:
22
8
1319
68
↑ Collapse diff ↑
Ignore white space 6 line context
1
%!PS-Adobe-2.0 EPSF-2.0
2
%%Creator: LEMON, graphToEps()
3
%%CreationDate: Sun Mar 14 09:08:34 2010
4
%%BoundingBox: -353 -264 559 292
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
/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
30
  newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
31
  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
32
  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
33
  5 index 5 index 5 index c fill
34
  setrgbcolor 1.1 div c fill
35
  } bind def
36
/nmale {
37
  0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
38
  newpath 5 index 5 index moveto
39
  5 index 4 index 1 mul 1.5 mul add
40
  5 index 5 index 3 sqrt 1.5 mul mul add
41
  1 index 1 index lineto
42
  1 index 1 index 7 index sub moveto
43
  1 index 1 index lineto
44
  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
45
  stroke
46
  5 index 5 index 5 index c fill
47
  setrgbcolor 1.1 div c fill
48
  } bind def
49
/arrl 1 def
50
/arrw 0.3 def
51
/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
52
/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
53
       /w exch def /len exch def
54
       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
55
       len w sub arrl sub dx dy lrl
56
       arrw dy dx neg lrl
57
       dx arrl w add mul dy w 2 div arrw add mul sub
58
       dy arrl w add mul dx w 2 div arrw add mul add rlineto
59
       dx arrl w add mul neg dy w 2 div arrw add mul sub
60
       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
61
       arrw dy dx neg lrl
62
       len w sub arrl sub neg dx dy lrl
63
       closepath fill } bind def
64
/cshow { 2 index 2 index moveto dup stringwidth pop
65
         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
66

	
67
gsave
68
%Arcs:
69
gsave
70
140.321 266.249 -327.729 150.06 0 0 0 4.99223 l
71
82.1207 -238.726 -245.288 -110.743 0 0 0 4.99223 l
72
336.635 -229.036 533.603 13.109 0 0 0 4.99223 l
73
53.8598 -45.8071 -245.288 -110.743 0 0 0 4.99223 l
74
-75.5617 118.579 -327.729 150.06 0 0 0 4.99223 l
75
-327.729 150.06 -245.288 -110.743 1 0 0 11.9813 l
76
533.603 13.109 218.184 -84.2955 0 0 0 4.99223 l
77
39.87 175.035 141.163 67.2575 0 0 0 4.99223 l
78
53.8598 -45.8071 -75.5617 118.579 0 0 0 4.99223 l
79
-102.406 -141.267 82.1207 -238.726 0 0 0 4.99223 l
80
399.144 166.894 533.603 13.109 1 0 0 11.9813 l
81
39.87 175.035 140.321 266.249 1 0 0 11.9813 l
82
399.144 166.894 140.321 266.249 0 0 0 4.99223 l
83
399.144 166.894 141.163 67.2575 0 0 0 4.99223 l
84
53.8598 -45.8071 204.765 -173.77 0 0 0 4.99223 l
85
82.1207 -238.726 204.765 -173.77 0 0 0 4.99223 l
86
258.227 61.658 399.144 166.894 0 0 0 4.99223 l
87
53.8598 -45.8071 -102.406 -141.267 1 0 0 11.9813 l
88
175.073 -37.4477 141.163 67.2575 0 0 0 4.99223 l
89
258.227 61.658 380 0 0 0 0 4.99223 l
90
34.6739 40.8267 -75.5617 118.579 1 0 0 11.9813 l
91
380 0 533.603 13.109 0 0 0 4.99223 l
92
175.073 -37.4477 380 0 0 0 0 4.99223 l
93
218.184 -84.2955 204.765 -173.77 0 0 0 4.99223 l
94
53.8598 -45.8071 34.6739 40.8267 0 0 0 4.99223 l
95
167.905 -213.988 82.1207 -238.726 1 0 0 11.9813 l
96
336.635 -229.036 204.765 -173.77 1 0 0 11.9813 l
97
336.635 -229.036 167.905 -213.988 0 0 0 4.99223 l
98
329.08 -26.3098 218.184 -84.2955 0 0 0 4.99223 l
99
39.87 175.035 -75.5617 118.579 0 0 0 4.99223 l
100
53.8598 -45.8071 175.073 -37.4477 0 0 0 4.99223 l
101
34.6739 40.8267 141.163 67.2575 0 0 0 4.99223 l
102
258.227 61.658 141.163 67.2575 1 0 0 11.9813 l
103
175.073 -37.4477 218.184 -84.2955 1 0 0 11.9813 l
104
380 0 329.08 -26.3098 1 0 0 11.9813 l
105
grestore
106
%Nodes:
107
gsave
108
-245.288 -110.743 14.9767 1 1 1 nc
109
204.765 -173.77 14.9767 1 1 1 nc
110
-327.729 150.06 14.9767 1 1 1 nc
111
-75.5617 118.579 14.9767 1 1 1 nc
112
218.184 -84.2955 14.9767 1 1 1 nc
113
140.321 266.249 14.9767 1 1 1 nc
114
141.163 67.2575 14.9767 1 1 1 nc
115
82.1207 -238.726 14.9767 1 1 1 nc
116
329.08 -26.3098 14.9767 1 1 1 nc
117
-102.406 -141.267 14.9767 1 1 1 nc
118
533.603 13.109 14.9767 1 1 1 nc
119
167.905 -213.988 14.9767 1 1 1 nc
120
336.635 -229.036 14.9767 1 1 1 nc
121
380 0 14.9767 1 1 1 nc
122
399.144 166.894 14.9767 1 1 1 nc
123
34.6739 40.8267 14.9767 1 1 1 nc
124
39.87 175.035 14.9767 1 1 1 nc
125
175.073 -37.4477 14.9767 1 1 1 nc
126
53.8598 -45.8071 14.9767 1 1 1 nc
127
258.227 61.658 14.9767 1 1 1 nc
128
grestore
129
grestore
130
showpage
Ignore white space 6 line context
1
%!PS-Adobe-2.0 EPSF-2.0
2
%%Creator: LEMON, graphToEps()
3
%%CreationDate: Fri Oct 19 18:32:32 2007
4
%%BoundingBox: 0 0 596 842
5
%%DocumentPaperSizes: a4
6
%%EndComments
7
/lb { setlinewidth setrgbcolor newpath moveto
8
      4 2 roll 1 index 1 index curveto stroke } bind def
9
/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def
10
/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def
11
/sq { newpath 2 index 1 index add 2 index 2 index add moveto
12
      2 index 1 index sub 2 index 2 index add lineto
13
      2 index 1 index sub 2 index 2 index sub lineto
14
      2 index 1 index add 2 index 2 index sub lineto
15
      closepath pop pop pop} bind def
16
/di { newpath 2 index 1 index add 2 index moveto
17
      2 index             2 index 2 index add lineto
18
      2 index 1 index sub 2 index             lineto
19
      2 index             2 index 2 index sub lineto
20
      closepath pop pop pop} bind def
21
/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill
22
     setrgbcolor 1.1 div c fill
23
   } bind def
24
/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill
25
     setrgbcolor 1.1 div sq fill
26
   } bind def
27
/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill
28
     setrgbcolor 1.1 div di fill
29
   } bind def
30
/nfemale { 0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
31
  newpath 5 index 5 index moveto 5 index 5 index 5 index 3.01 mul sub
32
  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub moveto
33
  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto stroke
34
  5 index 5 index 5 index c fill
35
  setrgbcolor 1.1 div c fill
36
  } bind def
37
/nmale {
38
  0 0 0 setrgbcolor 3 index 0.0909091 1.5 mul mul setlinewidth
39
  newpath 5 index 5 index moveto
40
  5 index 4 index 1 mul 1.5 mul add
41
  5 index 5 index 3 sqrt 1.5 mul mul add
42
  1 index 1 index lineto
43
  1 index 1 index 7 index sub moveto
44
  1 index 1 index lineto
45
  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub lineto
46
  stroke
47
  5 index 5 index 5 index c fill
48
  setrgbcolor 1.1 div c fill
49
  } bind def
50
/arrl 1 def
51
/arrw 0.3 def
52
/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def
53
/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def
54
       /w exch def /len exch def
55
       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto
56
       len w sub arrl sub dx dy lrl
57
       arrw dy dx neg lrl
58
       dx arrl w add mul dy w 2 div arrw add mul sub
59
       dy arrl w add mul dx w 2 div arrw add mul add rlineto
60
       dx arrl w add mul neg dy w 2 div arrw add mul sub
61
       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto
62
       arrw dy dx neg lrl
63
       len w sub arrl sub neg dx dy lrl
64
       closepath fill } bind def
65
/cshow { 2 index 2 index moveto dup stringwidth pop
66
         neg 2 div fosi .35 mul neg rmoveto show pop pop} def
67

	
68
gsave
69
15 138.307 translate
70
12.7843 dup scale
71
90 rotate
72
0.608112 -43.6081 translate
73
%Edges:
74
gsave
75
9 31 9.5 30.5 10 30 0 0 0 0.091217 lb
76
9 31 5.5 34.5 2 38 0 0 0 0.091217 lb
77
9 31 25.5 16 42 1 0 0 0 0.091217 lb
78
3 40 23 20.5 43 1 0 0 0 0.091217 lb
79
3 40 22.5 20.5 42 1 0 0 0 0.091217 lb
80
3 40 2.5 40.5 2 41 0 0 0 0.091217 lb
81
13 25 10.5 24.5 8 24 0 0 0 0.091217 lb
82
13 25 12 27 11 29 0 0 0 0.091217 lb
83
3 4 2.5 3 2 2 0 0 0 0.091217 lb
84
3 4 4.5 3 6 2 0 0 0 0.091217 lb
85
6 25 7 24.5 8 24 0 0 0 0.091217 lb
86
6 25 6 24.5 6 24 0 0 0 0.091217 lb
87
34 2 33.5 2 33 2 0 0 0 0.091217 lb
88
34 2 35 2 36 2 0 0 0 0.091217 lb
89
6 8 16 9 26 10 0 0 0 0.091217 lb
90
6 8 6 10.5 6 13 0 0 0 0.091217 lb
91
6 8 6 7.5 6 7 0 0 0 0.091217 lb
92
26 10 27.5 8.5 29 7 0 0 0 0.091217 lb
93
26 10 27.5 9 29 8 0 0 0 0.091217 lb
94
10 30 10.5 29.5 11 29 0 0 0 0.091217 lb
95
8 24 7 23.5 6 23 0 0 0 0.091217 lb
96
8 24 8 24.5 8 25 0 0 0 0.091217 lb
97
33 2 32.5 2 32 2 0 0 0 0.091217 lb
98
29 7 17.5 7 6 7 0 0 0 0.091217 lb
99
2 2 1.5 22 1 42 0 0 0 0.091217 lb
100
2 2 3.5 2 5 2 0 0 0 0.091217 lb
101
21 15 13.5 14.5 6 14 0 0 0 0.091217 lb
102
21 15 21 15.5 21 16 0 0 0 0.091217 lb
103
1 42 0.5 42.5 0 43 0 0 0 0.091217 lb
104
1 42 1.5 41.5 2 41 0 0 0 0.091217 lb
105
6 15 6 15.5 6 16 0 0 0 0.091217 lb
106
6 15 6 14.5 6 14 0 0 0 0.091217 lb
107
43 1 22 0.5 1 0 0 0 0 0.091217 lb
108
31 2 18.5 2 6 2 0 0 0 0.091217 lb
109
31 2 31.5 2 32 2 0 0 0 0.091217 lb
110
6 24 6 23.5 6 23 0 0 0 0.091217 lb
111
6 16 6 16.5 6 17 0 0 0 0.091217 lb
112
6 23 6 20 6 17 0 0 0 0.091217 lb
113
6 2 5.5 2 5 2 0 0 0 0.091217 lb
114
6 2 6 4.5 6 7 0 0 0 0.091217 lb
115
0 43 0.5 21.5 1 0 0 0 0 0.091217 lb
116
1 1 19.5 1.5 38 2 0 0 0 0.091217 lb
117
1 1 1 0.5 1 0 0 0 0 0.091217 lb
118
2 38 5.5 31.5 9 25 0 0 0 0.091217 lb
119
25 13 15.5 13 6 13 0 0 0 0.091217 lb
120
25 13 15.5 13.5 6 14 0 0 0 0.091217 lb
121
8 25 8.5 25 9 25 0 0 0 0.091217 lb
122
11 29 24.5 15.5 38 2 0 0 0 0.091217 lb
123
6 17 11.5 18 17 19 0 0 0 0.091217 lb
124
16 23 26.5 12.5 37 2 0 0 0 0.091217 lb
125
16 23 18.5 19.5 21 16 0 0 0 0.091217 lb
126
36 2 36.5 2 37 2 0 0 0 0.091217 lb
127
36 2 32.5 5 29 8 0 0 0 0.091217 lb
128
6 13 6 13.5 6 14 0 0 0 0.091217 lb
129
37 2 37.5 2 38 2 0 0 0 0.091217 lb
130
21 16 19 17.5 17 19 0 0 0 0.091217 lb
131
grestore
132
%Nodes:
133
gsave
134
29 8 0.304556 1 1 1 nc
135
2 41 0.304556 1 1 1 nc
136
6 7 0.304556 1 1 1 nc
137
5 2 0.304556 1 1 1 nc
138
17 19 0.304556 1 1 1 nc
139
21 16 0.304556 1 1 1 nc
140
1 0 0.304556 1 1 1 nc
141
9 25 0.304556 1 1 1 nc
142
6 14 0.304556 1 1 1 nc
143
42 1 0.304556 1 1 1 nc
144
38 2 0.304556 1 1 1 nc
145
37 2 0.304556 1 1 1 nc
146
6 13 0.304556 1 1 1 nc
147
36 2 0.304556 1 1 1 nc
148
16 23 0.304556 1 1 1 nc
149
6 17 0.304556 1 1 1 nc
150
11 29 0.304556 1 1 1 nc
151
8 25 0.304556 1 1 1 nc
152
32 2 0.304556 1 1 1 nc
153
25 13 0.304556 1 1 1 nc
154
2 38 0.304556 1 1 1 nc
155
1 1 0.304556 1 1 1 nc
156
0 43 0.304556 1 1 1 nc
157
6 2 0.304556 1 1 1 nc
158
6 23 0.304556 1 1 1 nc
159
6 16 0.304556 1 1 1 nc
160
6 24 0.304556 1 1 1 nc
161
31 2 0.304556 1 1 1 nc
162
43 1 0.304556 1 1 1 nc
163
6 15 0.304556 1 1 1 nc
164
1 42 0.304556 1 1 1 nc
165
21 15 0.304556 1 1 1 nc
166
2 2 0.304556 1 1 1 nc
167
29 7 0.304556 1 1 1 nc
168
33 2 0.304556 1 1 1 nc
169
8 24 0.304556 1 1 1 nc
170
10 30 0.304556 1 1 1 nc
171
26 10 0.304556 1 1 1 nc
172
6 8 0.304556 1 1 1 nc
173
34 2 0.304556 1 1 1 nc
174
6 25 0.304556 1 1 1 nc
175
3 4 0.304556 1 1 1 nc
176
13 25 0.304556 1 1 1 nc
177
3 40 0.304556 1 1 1 nc
178
9 31 0.304556 1 1 1 nc
179
grestore
180
grestore
181
showpage
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-2010
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/tolerance.h>
32
#include <lemon/path.h>
33

	
34
#include <limits>
35

	
36
namespace lemon {
37

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

	
72
  template <typename V>
73
  struct BellmanFordDefaultOperationTraits<V, false> {
74
    typedef V Value;
75
    static Value zero() {
76
      return static_cast<Value>(0);
77
    }
78
    static Value infinity() {
79
      return std::numeric_limits<Value>::max();
80
    }
81
    static Value plus(const Value& left, const Value& right) {
82
      if (left == infinity() || right == infinity()) return infinity();
83
      return left + right;
84
    }
85
    static bool less(const Value& left, const Value& right) {
86
      return left < right;
87
    }
88
  };
89

	
90
  /// \brief Operation traits for the BellmanFord algorithm class
91
  /// using tolerance.
92
  ///
93
  /// This operation traits class defines all computational operations
94
  /// and constants that are used in the Bellman-Ford algorithm.
95
  /// The only difference between this implementation and
96
  /// \ref BellmanFordDefaultOperationTraits is that this class uses
97
  /// the \ref Tolerance "tolerance technique" in its \ref less()
98
  /// function.
99
  ///
100
  /// \tparam V The value type.
101
  /// \tparam eps The epsilon value for the \ref less() function.
102
  /// By default, it is the epsilon value used by \ref Tolerance
103
  /// "Tolerance<V>".
104
  ///
105
  /// \see BellmanFordDefaultOperationTraits
106
#ifdef DOXYGEN
107
  template <typename V, V eps>
108
#else
109
  template <
110
    typename V,
111
    V eps = Tolerance<V>::def_epsilon>
112
#endif
113
  struct BellmanFordToleranceOperationTraits {
114
    /// \brief Value type for the algorithm.
115
    typedef V Value;
116
    /// \brief Gives back the zero value of the type.
117
    static Value zero() {
118
      return static_cast<Value>(0);
119
    }
120
    /// \brief Gives back the positive infinity value of the type.
121
    static Value infinity() {
122
      return std::numeric_limits<Value>::infinity();
123
    }
124
    /// \brief Gives back the sum of the given two elements.
125
    static Value plus(const Value& left, const Value& right) {
126
      return left + right;
127
    }
128
    /// \brief Gives back \c true only if the first value is less than
129
    /// the second.
130
    static bool less(const Value& left, const Value& right) {
131
      return left + eps < right;
132
    }
133
  };
134

	
135
  /// \brief Default traits class of BellmanFord class.
136
  ///
137
  /// Default traits class of BellmanFord class.
138
  /// \param GR The type of the digraph.
139
  /// \param LEN The type of the length map.
140
  template<typename GR, typename LEN>
141
  struct BellmanFordDefaultTraits {
142
    /// The type of the digraph the algorithm runs on.
143
    typedef GR Digraph;
144

	
145
    /// \brief The type of the map that stores the arc lengths.
146
    ///
147
    /// The type of the map that stores the arc lengths.
148
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
149
    typedef LEN LengthMap;
150

	
151
    /// The type of the arc lengths.
152
    typedef typename LEN::Value Value;
153

	
154
    /// \brief Operation traits for Bellman-Ford algorithm.
155
    ///
156
    /// It defines the used operations and the infinity value for the
157
    /// given \c Value type.
158
    /// \see BellmanFordDefaultOperationTraits,
159
    /// BellmanFordToleranceOperationTraits
160
    typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
161

	
162
    /// \brief The type of the map that stores the last arcs of the
163
    /// shortest paths.
164
    ///
165
    /// The type of the map that stores the last
166
    /// arcs of the shortest paths.
167
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
168
    typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
169

	
170
    /// \brief Instantiates a \c PredMap.
171
    ///
172
    /// This function instantiates a \ref PredMap.
173
    /// \param g is the digraph to which we would like to define the
174
    /// \ref PredMap.
175
    static PredMap *createPredMap(const GR& g) {
176
      return new PredMap(g);
177
    }
178

	
179
    /// \brief The type of the map that stores the distances of the nodes.
180
    ///
181
    /// The type of the map that stores the distances of the nodes.
182
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
183
    typedef typename GR::template NodeMap<typename LEN::Value> DistMap;
184

	
185
    /// \brief Instantiates a \c DistMap.
186
    ///
187
    /// This function instantiates a \ref DistMap.
188
    /// \param g is the digraph to which we would like to define the
189
    /// \ref DistMap.
190
    static DistMap *createDistMap(const GR& g) {
191
      return new DistMap(g);
192
    }
193

	
194
  };
195

	
196
  /// \brief %BellmanFord algorithm class.
197
  ///
198
  /// \ingroup shortest_path
199
  /// This class provides an efficient implementation of the Bellman-Ford
200
  /// algorithm. The maximum time complexity of the algorithm is
201
  /// <tt>O(ne)</tt>.
202
  ///
203
  /// The Bellman-Ford algorithm solves the single-source shortest path
204
  /// problem when the arcs can have negative lengths, but the digraph
205
  /// should not contain directed cycles with negative total length.
206
  /// If all arc costs are non-negative, consider to use the Dijkstra
207
  /// algorithm instead, since it is more efficient.
208
  ///
209
  /// The arc lengths are passed to the algorithm using a
210
  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
211
  /// kind of length. The type of the length values is determined by the
212
  /// \ref concepts::ReadMap::Value "Value" type of the length map.
213
  ///
214
  /// There is also a \ref bellmanFord() "function-type interface" for the
215
  /// Bellman-Ford algorithm, which is convenient in the simplier cases and
216
  /// it can be used easier.
217
  ///
218
  /// \tparam GR The type of the digraph the algorithm runs on.
219
  /// The default type is \ref ListDigraph.
220
  /// \tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
221
  /// the lengths of the arcs. The default map type is
222
  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
223
  /// \tparam TR The traits class that defines various types used by the
224
  /// algorithm. By default, it is \ref BellmanFordDefaultTraits
225
  /// "BellmanFordDefaultTraits<GR, LEN>".
226
  /// In most cases, this parameter should not be set directly,
227
  /// consider to use the named template parameters instead.
228
#ifdef DOXYGEN
229
  template <typename GR, typename LEN, typename TR>
230
#else
231
  template <typename GR=ListDigraph,
232
            typename LEN=typename GR::template ArcMap<int>,
233
            typename TR=BellmanFordDefaultTraits<GR,LEN> >
234
#endif
235
  class BellmanFord {
236
  public:
237

	
238
    ///The type of the underlying digraph.
239
    typedef typename TR::Digraph Digraph;
240

	
241
    /// \brief The type of the arc lengths.
242
    typedef typename TR::LengthMap::Value Value;
243
    /// \brief The type of the map that stores the arc lengths.
244
    typedef typename TR::LengthMap LengthMap;
245
    /// \brief The type of the map that stores the last
246
    /// arcs of the shortest paths.
247
    typedef typename TR::PredMap PredMap;
248
    /// \brief The type of the map that stores the distances of the nodes.
249
    typedef typename TR::DistMap DistMap;
250
    /// The type of the paths.
251
    typedef PredMapPath<Digraph, PredMap> Path;
252
    ///\brief The \ref BellmanFordDefaultOperationTraits
253
    /// "operation traits class" of the algorithm.
254
    typedef typename TR::OperationTraits OperationTraits;
255

	
256
    ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm.
257
    typedef TR Traits;
258

	
259
  private:
260

	
261
    typedef typename Digraph::Node Node;
262
    typedef typename Digraph::NodeIt NodeIt;
263
    typedef typename Digraph::Arc Arc;
264
    typedef typename Digraph::OutArcIt OutArcIt;
265

	
266
    // Pointer to the underlying digraph.
267
    const Digraph *_gr;
268
    // Pointer to the length map
269
    const LengthMap *_length;
270
    // Pointer to the map of predecessors arcs.
271
    PredMap *_pred;
272
    // Indicates if _pred is locally allocated (true) or not.
273
    bool _local_pred;
274
    // Pointer to the map of distances.
275
    DistMap *_dist;
276
    // Indicates if _dist is locally allocated (true) or not.
277
    bool _local_dist;
278

	
279
    typedef typename Digraph::template NodeMap<bool> MaskMap;
280
    MaskMap *_mask;
281

	
282
    std::vector<Node> _process;
283

	
284
    // Creates the maps if necessary.
285
    void create_maps() {
286
      if(!_pred) {
287
        _local_pred = true;
288
        _pred = Traits::createPredMap(*_gr);
289
      }
290
      if(!_dist) {
291
        _local_dist = true;
292
        _dist = Traits::createDistMap(*_gr);
293
      }
294
      if(!_mask) {
295
        _mask = new MaskMap(*_gr);
296
      }
297
    }
298

	
299
  public :
300

	
301
    typedef BellmanFord Create;
302

	
303
    /// \name Named Template Parameters
304

	
305
    ///@{
306

	
307
    template <class T>
308
    struct SetPredMapTraits : public Traits {
309
      typedef T PredMap;
310
      static PredMap *createPredMap(const Digraph&) {
311
        LEMON_ASSERT(false, "PredMap is not initialized");
312
        return 0; // ignore warnings
313
      }
314
    };
315

	
316
    /// \brief \ref named-templ-param "Named parameter" for setting
317
    /// \c PredMap type.
318
    ///
319
    /// \ref named-templ-param "Named parameter" for setting
320
    /// \c PredMap type.
321
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
322
    template <class T>
323
    struct SetPredMap
324
      : public BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > {
325
      typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > Create;
326
    };
327

	
328
    template <class T>
329
    struct SetDistMapTraits : public Traits {
330
      typedef T DistMap;
331
      static DistMap *createDistMap(const Digraph&) {
332
        LEMON_ASSERT(false, "DistMap is not initialized");
333
        return 0; // ignore warnings
334
      }
335
    };
336

	
337
    /// \brief \ref named-templ-param "Named parameter" for setting
338
    /// \c DistMap type.
339
    ///
340
    /// \ref named-templ-param "Named parameter" for setting
341
    /// \c DistMap type.
342
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
343
    template <class T>
344
    struct SetDistMap
345
      : public BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > {
346
      typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > Create;
347
    };
348

	
349
    template <class T>
350
    struct SetOperationTraitsTraits : public Traits {
351
      typedef T OperationTraits;
352
    };
353

	
354
    /// \brief \ref named-templ-param "Named parameter" for setting
355
    /// \c OperationTraits type.
356
    ///
357
    /// \ref named-templ-param "Named parameter" for setting
358
    /// \c OperationTraits type.
359
    /// For more information, see \ref BellmanFordDefaultOperationTraits.
360
    template <class T>
361
    struct SetOperationTraits
362
      : public BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> > {
363
      typedef BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> >
364
      Create;
365
    };
366

	
367
    ///@}
368

	
369
  protected:
370

	
371
    BellmanFord() {}
372

	
373
  public:
374

	
375
    /// \brief Constructor.
376
    ///
377
    /// Constructor.
378
    /// \param g The digraph the algorithm runs on.
379
    /// \param length The length map used by the algorithm.
380
    BellmanFord(const Digraph& g, const LengthMap& length) :
381
      _gr(&g), _length(&length),
382
      _pred(0), _local_pred(false),
383
      _dist(0), _local_dist(false), _mask(0) {}
384

	
385
    ///Destructor.
386
    ~BellmanFord() {
387
      if(_local_pred) delete _pred;
388
      if(_local_dist) delete _dist;
389
      if(_mask) delete _mask;
390
    }
391

	
392
    /// \brief Sets the length map.
393
    ///
394
    /// Sets the length map.
395
    /// \return <tt>(*this)</tt>
396
    BellmanFord &lengthMap(const LengthMap &map) {
397
      _length = &map;
398
      return *this;
399
    }
400

	
401
    /// \brief Sets the map that stores the predecessor arcs.
402
    ///
403
    /// Sets the map that stores the predecessor arcs.
404
    /// If you don't use this function before calling \ref run()
405
    /// or \ref init(), an instance will be allocated automatically.
406
    /// The destructor deallocates this automatically allocated map,
407
    /// of course.
408
    /// \return <tt>(*this)</tt>
409
    BellmanFord &predMap(PredMap &map) {
410
      if(_local_pred) {
411
        delete _pred;
412
        _local_pred=false;
413
      }
414
      _pred = &map;
415
      return *this;
416
    }
417

	
418
    /// \brief Sets the map that stores the distances of the nodes.
419
    ///
420
    /// Sets the map that stores the distances of the nodes calculated
421
    /// by the algorithm.
422
    /// If you don't use this function before calling \ref run()
423
    /// or \ref init(), an instance will be allocated automatically.
424
    /// The destructor deallocates this automatically allocated map,
425
    /// of course.
426
    /// \return <tt>(*this)</tt>
427
    BellmanFord &distMap(DistMap &map) {
428
      if(_local_dist) {
429
        delete _dist;
430
        _local_dist=false;
431
      }
432
      _dist = &map;
433
      return *this;
434
    }
435

	
436
    /// \name Execution Control
437
    /// The simplest way to execute the Bellman-Ford algorithm is to use
438
    /// one of the member functions called \ref run().\n
439
    /// If you need better control on the execution, you have to call
440
    /// \ref init() first, then you can add several source nodes
441
    /// with \ref addSource(). Finally the actual path computation can be
442
    /// performed with \ref start(), \ref checkedStart() or
443
    /// \ref limitedStart().
444

	
445
    ///@{
446

	
447
    /// \brief Initializes the internal data structures.
448
    ///
449
    /// Initializes the internal data structures. The optional parameter
450
    /// is the initial distance of each node.
451
    void init(const Value value = OperationTraits::infinity()) {
452
      create_maps();
453
      for (NodeIt it(*_gr); it != INVALID; ++it) {
454
        _pred->set(it, INVALID);
455
        _dist->set(it, value);
456
      }
457
      _process.clear();
458
      if (OperationTraits::less(value, OperationTraits::infinity())) {
459
        for (NodeIt it(*_gr); it != INVALID; ++it) {
460
          _process.push_back(it);
461
          _mask->set(it, true);
462
        }
463
      } else {
464
        for (NodeIt it(*_gr); it != INVALID; ++it) {
465
          _mask->set(it, false);
466
        }
467
      }
468
    }
469

	
470
    /// \brief Adds a new source node.
471
    ///
472
    /// This function adds a new source node. The optional second parameter
473
    /// is the initial distance of the node.
474
    void addSource(Node source, Value dst = OperationTraits::zero()) {
475
      _dist->set(source, dst);
476
      if (!(*_mask)[source]) {
477
        _process.push_back(source);
478
        _mask->set(source, true);
479
      }
480
    }
481

	
482
    /// \brief Executes one round from the Bellman-Ford algorithm.
483
    ///
484
    /// If the algoritm calculated the distances in the previous round
485
    /// exactly for the paths of at most \c k arcs, then this function
486
    /// will calculate the distances exactly for the paths of at most
487
    /// <tt>k+1</tt> arcs. Performing \c k iterations using this function
488
    /// calculates the shortest path distances exactly for the paths
489
    /// consisting of at most \c k arcs.
490
    ///
491
    /// \warning The paths with limited arc number cannot be retrieved
492
    /// easily with \ref path() or \ref predArc() functions. If you also
493
    /// need the shortest paths and not only the distances, you should
494
    /// store the \ref predMap() "predecessor map" after each iteration
495
    /// and build the path manually.
496
    ///
497
    /// \return \c true when the algorithm have not found more shorter
498
    /// paths.
499
    ///
500
    /// \see ActiveIt
501
    bool processNextRound() {
502
      for (int i = 0; i < int(_process.size()); ++i) {
503
        _mask->set(_process[i], false);
504
      }
505
      std::vector<Node> nextProcess;
506
      std::vector<Value> values(_process.size());
507
      for (int i = 0; i < int(_process.size()); ++i) {
508
        values[i] = (*_dist)[_process[i]];
509
      }
510
      for (int i = 0; i < int(_process.size()); ++i) {
511
        for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
512
          Node target = _gr->target(it);
513
          Value relaxed = OperationTraits::plus(values[i], (*_length)[it]);
514
          if (OperationTraits::less(relaxed, (*_dist)[target])) {
515
            _pred->set(target, it);
516
            _dist->set(target, relaxed);
517
            if (!(*_mask)[target]) {
518
              _mask->set(target, true);
519
              nextProcess.push_back(target);
520
            }
521
          }
522
        }
523
      }
524
      _process.swap(nextProcess);
525
      return _process.empty();
526
    }
527

	
528
    /// \brief Executes one weak round from the Bellman-Ford algorithm.
529
    ///
530
    /// If the algorithm calculated the distances in the previous round
531
    /// at least for the paths of at most \c k arcs, then this function
532
    /// will calculate the distances at least for the paths of at most
533
    /// <tt>k+1</tt> arcs.
534
    /// This function does not make it possible to calculate the shortest
535
    /// path distances exactly for paths consisting of at most \c k arcs,
536
    /// this is why it is called weak round.
537
    ///
538
    /// \return \c true when the algorithm have not found more shorter
539
    /// paths.
540
    ///
541
    /// \see ActiveIt
542
    bool processNextWeakRound() {
543
      for (int i = 0; i < int(_process.size()); ++i) {
544
        _mask->set(_process[i], false);
545
      }
546
      std::vector<Node> nextProcess;
547
      for (int i = 0; i < int(_process.size()); ++i) {
548
        for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
549
          Node target = _gr->target(it);
550
          Value relaxed =
551
            OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]);
552
          if (OperationTraits::less(relaxed, (*_dist)[target])) {
553
            _pred->set(target, it);
554
            _dist->set(target, relaxed);
555
            if (!(*_mask)[target]) {
556
              _mask->set(target, true);
557
              nextProcess.push_back(target);
558
            }
559
          }
560
        }
561
      }
562
      _process.swap(nextProcess);
563
      return _process.empty();
564
    }
565

	
566
    /// \brief Executes the algorithm.
567
    ///
568
    /// Executes the algorithm.
569
    ///
570
    /// This method runs the Bellman-Ford algorithm from the root node(s)
571
    /// in order to compute the shortest path to each node.
572
    ///
573
    /// The algorithm computes
574
    /// - the shortest path tree (forest),
575
    /// - the distance of each node from the root(s).
576
    ///
577
    /// \pre init() must be called and at least one root node should be
578
    /// added with addSource() before using this function.
579
    void start() {
580
      int num = countNodes(*_gr) - 1;
581
      for (int i = 0; i < num; ++i) {
582
        if (processNextWeakRound()) break;
583
      }
584
    }
585

	
586
    /// \brief Executes the algorithm and checks the negative cycles.
587
    ///
588
    /// Executes the algorithm and checks the negative cycles.
589
    ///
590
    /// This method runs the Bellman-Ford algorithm from the root node(s)
591
    /// in order to compute the shortest path to each node and also checks
592
    /// if the digraph contains cycles with negative total length.
593
    ///
594
    /// The algorithm computes
595
    /// - the shortest path tree (forest),
596
    /// - the distance of each node from the root(s).
597
    ///
598
    /// \return \c false if there is a negative cycle in the digraph.
599
    ///
600
    /// \pre init() must be called and at least one root node should be
601
    /// added with addSource() before using this function.
602
    bool checkedStart() {
603
      int num = countNodes(*_gr);
604
      for (int i = 0; i < num; ++i) {
605
        if (processNextWeakRound()) return true;
606
      }
607
      return _process.empty();
608
    }
609

	
610
    /// \brief Executes the algorithm with arc number limit.
611
    ///
612
    /// Executes the algorithm with arc number limit.
613
    ///
614
    /// This method runs the Bellman-Ford algorithm from the root node(s)
615
    /// in order to compute the shortest path distance for each node
616
    /// using only the paths consisting of at most \c num arcs.
617
    ///
618
    /// The algorithm computes
619
    /// - the limited distance of each node from the root(s),
620
    /// - the predecessor arc for each node.
621
    ///
622
    /// \warning The paths with limited arc number cannot be retrieved
623
    /// easily with \ref path() or \ref predArc() functions. If you also
624
    /// need the shortest paths and not only the distances, you should
625
    /// store the \ref predMap() "predecessor map" after each iteration
626
    /// and build the path manually.
627
    ///
628
    /// \pre init() must be called and at least one root node should be
629
    /// added with addSource() before using this function.
630
    void limitedStart(int num) {
631
      for (int i = 0; i < num; ++i) {
632
        if (processNextRound()) break;
633
      }
634
    }
635

	
636
    /// \brief Runs the algorithm from the given root node.
637
    ///
638
    /// This method runs the Bellman-Ford algorithm from the given root
639
    /// node \c s in order to compute the shortest path to each node.
640
    ///
641
    /// The algorithm computes
642
    /// - the shortest path tree (forest),
643
    /// - the distance of each node from the root(s).
644
    ///
645
    /// \note bf.run(s) is just a shortcut of the following code.
646
    /// \code
647
    ///   bf.init();
648
    ///   bf.addSource(s);
649
    ///   bf.start();
650
    /// \endcode
651
    void run(Node s) {
652
      init();
653
      addSource(s);
654
      start();
655
    }
656

	
657
    /// \brief Runs the algorithm from the given root node with arc
658
    /// number limit.
659
    ///
660
    /// This method runs the Bellman-Ford algorithm from the given root
661
    /// node \c s in order to compute the shortest path distance for each
662
    /// node using only the paths consisting of at most \c num arcs.
663
    ///
664
    /// The algorithm computes
665
    /// - the limited distance of each node from the root(s),
666
    /// - the predecessor arc for each node.
667
    ///
668
    /// \warning The paths with limited arc number cannot be retrieved
669
    /// easily with \ref path() or \ref predArc() functions. If you also
670
    /// need the shortest paths and not only the distances, you should
671
    /// store the \ref predMap() "predecessor map" after each iteration
672
    /// and build the path manually.
673
    ///
674
    /// \note bf.run(s, num) is just a shortcut of the following code.
675
    /// \code
676
    ///   bf.init();
677
    ///   bf.addSource(s);
678
    ///   bf.limitedStart(num);
679
    /// \endcode
680
    void run(Node s, int num) {
681
      init();
682
      addSource(s);
683
      limitedStart(num);
684
    }
685

	
686
    ///@}
687

	
688
    /// \brief LEMON iterator for getting the active nodes.
689
    ///
690
    /// This class provides a common style LEMON iterator that traverses
691
    /// the active nodes of the Bellman-Ford algorithm after the last
692
    /// phase. These nodes should be checked in the next phase to
693
    /// find augmenting arcs outgoing from them.
694
    class ActiveIt {
695
    public:
696

	
697
      /// \brief Constructor.
698
      ///
699
      /// Constructor for getting the active nodes of the given BellmanFord
700
      /// instance.
701
      ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm)
702
      {
703
        _index = _algorithm->_process.size() - 1;
704
      }
705

	
706
      /// \brief Invalid constructor.
707
      ///
708
      /// Invalid constructor.
709
      ActiveIt(Invalid) : _algorithm(0), _index(-1) {}
710

	
711
      /// \brief Conversion to \c Node.
712
      ///
713
      /// Conversion to \c Node.
714
      operator Node() const {
715
        return _index >= 0 ? _algorithm->_process[_index] : INVALID;
716
      }
717

	
718
      /// \brief Increment operator.
719
      ///
720
      /// Increment operator.
721
      ActiveIt& operator++() {
722
        --_index;
723
        return *this;
724
      }
725

	
726
      bool operator==(const ActiveIt& it) const {
727
        return static_cast<Node>(*this) == static_cast<Node>(it);
728
      }
729
      bool operator!=(const ActiveIt& it) const {
730
        return static_cast<Node>(*this) != static_cast<Node>(it);
731
      }
732
      bool operator<(const ActiveIt& it) const {
733
        return static_cast<Node>(*this) < static_cast<Node>(it);
734
      }
735

	
736
    private:
737
      const BellmanFord* _algorithm;
738
      int _index;
739
    };
740

	
741
    /// \name Query Functions
742
    /// The result of the Bellman-Ford algorithm can be obtained using these
743
    /// functions.\n
744
    /// Either \ref run() or \ref init() should be called before using them.
745

	
746
    ///@{
747

	
748
    /// \brief The shortest path to the given node.
749
    ///
750
    /// Gives back the shortest path to the given node from the root(s).
751
    ///
752
    /// \warning \c t should be reached from the root(s).
753
    ///
754
    /// \pre Either \ref run() or \ref init() must be called before
755
    /// using this function.
756
    Path path(Node t) const
757
    {
758
      return Path(*_gr, *_pred, t);
759
    }
760

	
761
    /// \brief The distance of the given node from the root(s).
762
    ///
763
    /// Returns the distance of the given node from the root(s).
764
    ///
765
    /// \warning If node \c v is not reached from the root(s), then
766
    /// the return value of this function is undefined.
767
    ///
768
    /// \pre Either \ref run() or \ref init() must be called before
769
    /// using this function.
770
    Value dist(Node v) const { return (*_dist)[v]; }
771

	
772
    /// \brief Returns the 'previous arc' of the shortest path tree for
773
    /// the given node.
774
    ///
775
    /// This function returns the 'previous arc' of the shortest path
776
    /// tree for node \c v, i.e. it returns the last arc of a
777
    /// shortest path from a root to \c v. It is \c INVALID if \c v
778
    /// is not reached from the root(s) or if \c v is a root.
779
    ///
780
    /// The shortest path tree used here is equal to the shortest path
781
    /// tree used in \ref predNode() and \ref predMap().
782
    ///
783
    /// \pre Either \ref run() or \ref init() must be called before
784
    /// using this function.
785
    Arc predArc(Node v) const { return (*_pred)[v]; }
786

	
787
    /// \brief Returns the 'previous node' of the shortest path tree for
788
    /// the given node.
789
    ///
790
    /// This function returns the 'previous node' of the shortest path
791
    /// tree for node \c v, i.e. it returns the last but one node of
792
    /// a shortest path from a root to \c v. It is \c INVALID if \c v
793
    /// is not reached from the root(s) or if \c v is a root.
794
    ///
795
    /// The shortest path tree used here is equal to the shortest path
796
    /// tree used in \ref predArc() and \ref predMap().
797
    ///
798
    /// \pre Either \ref run() or \ref init() must be called before
799
    /// using this function.
800
    Node predNode(Node v) const {
801
      return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]);
802
    }
803

	
804
    /// \brief Returns a const reference to the node map that stores the
805
    /// distances of the nodes.
806
    ///
807
    /// Returns a const reference to the node map that stores the distances
808
    /// of the nodes calculated by the algorithm.
809
    ///
810
    /// \pre Either \ref run() or \ref init() must be called before
811
    /// using this function.
812
    const DistMap &distMap() const { return *_dist;}
813

	
814
    /// \brief Returns a const reference to the node map that stores the
815
    /// predecessor arcs.
816
    ///
817
    /// Returns a const reference to the node map that stores the predecessor
818
    /// arcs, which form the shortest path tree (forest).
819
    ///
820
    /// \pre Either \ref run() or \ref init() must be called before
821
    /// using this function.
822
    const PredMap &predMap() const { return *_pred; }
823

	
824
    /// \brief Checks if a node is reached from the root(s).
825
    ///
826
    /// Returns \c true if \c v is reached from the root(s).
827
    ///
828
    /// \pre Either \ref run() or \ref init() must be called before
829
    /// using this function.
830
    bool reached(Node v) const {
831
      return (*_dist)[v] != OperationTraits::infinity();
832
    }
833

	
834
    /// \brief Gives back a negative cycle.
835
    ///
836
    /// This function gives back a directed cycle with negative total
837
    /// length if the algorithm has already found one.
838
    /// Otherwise it gives back an empty path.
839
    lemon::Path<Digraph> negativeCycle() const {
840
      typename Digraph::template NodeMap<int> state(*_gr, -1);
841
      lemon::Path<Digraph> cycle;
842
      for (int i = 0; i < int(_process.size()); ++i) {
843
        if (state[_process[i]] != -1) continue;
844
        for (Node v = _process[i]; (*_pred)[v] != INVALID;
845
             v = _gr->source((*_pred)[v])) {
846
          if (state[v] == i) {
847
            cycle.addFront((*_pred)[v]);
848
            for (Node u = _gr->source((*_pred)[v]); u != v;
849
                 u = _gr->source((*_pred)[u])) {
850
              cycle.addFront((*_pred)[u]);
851
            }
852
            return cycle;
853
          }
854
          else if (state[v] >= 0) {
855
            break;
856
          }
857
          state[v] = i;
858
        }
859
      }
860
      return cycle;
861
    }
862

	
863
    ///@}
864
  };
865

	
866
  /// \brief Default traits class of bellmanFord() function.
867
  ///
868
  /// Default traits class of bellmanFord() function.
869
  /// \tparam GR The type of the digraph.
870
  /// \tparam LEN The type of the length map.
871
  template <typename GR, typename LEN>
872
  struct BellmanFordWizardDefaultTraits {
873
    /// The type of the digraph the algorithm runs on.
874
    typedef GR Digraph;
875

	
876
    /// \brief The type of the map that stores the arc lengths.
877
    ///
878
    /// The type of the map that stores the arc lengths.
879
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
880
    typedef LEN LengthMap;
881

	
882
    /// The type of the arc lengths.
883
    typedef typename LEN::Value Value;
884

	
885
    /// \brief Operation traits for Bellman-Ford algorithm.
886
    ///
887
    /// It defines the used operations and the infinity value for the
888
    /// given \c Value type.
889
    /// \see BellmanFordDefaultOperationTraits,
890
    /// BellmanFordToleranceOperationTraits
891
    typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
892

	
893
    /// \brief The type of the map that stores the last
894
    /// arcs of the shortest paths.
895
    ///
896
    /// The type of the map that stores the last arcs of the shortest paths.
897
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
898
    typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
899

	
900
    /// \brief Instantiates a \c PredMap.
901
    ///
902
    /// This function instantiates a \ref PredMap.
903
    /// \param g is the digraph to which we would like to define the
904
    /// \ref PredMap.
905
    static PredMap *createPredMap(const GR &g) {
906
      return new PredMap(g);
907
    }
908

	
909
    /// \brief The type of the map that stores the distances of the nodes.
910
    ///
911
    /// The type of the map that stores the distances of the nodes.
912
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
913
    typedef typename GR::template NodeMap<Value> DistMap;
914

	
915
    /// \brief Instantiates a \c DistMap.
916
    ///
917
    /// This function instantiates a \ref DistMap.
918
    /// \param g is the digraph to which we would like to define the
919
    /// \ref DistMap.
920
    static DistMap *createDistMap(const GR &g) {
921
      return new DistMap(g);
922
    }
923

	
924
    ///The type of the shortest paths.
925

	
926
    ///The type of the shortest paths.
927
    ///It must meet the \ref concepts::Path "Path" concept.
928
    typedef lemon::Path<Digraph> Path;
929
  };
930

	
931
  /// \brief Default traits class used by BellmanFordWizard.
932
  ///
933
  /// Default traits class used by BellmanFordWizard.
934
  /// \tparam GR The type of the digraph.
935
  /// \tparam LEN The type of the length map.
936
  template <typename GR, typename LEN>
937
  class BellmanFordWizardBase
938
    : public BellmanFordWizardDefaultTraits<GR, LEN> {
939

	
940
    typedef BellmanFordWizardDefaultTraits<GR, LEN> Base;
941
  protected:
942
    // Type of the nodes in the digraph.
943
    typedef typename Base::Digraph::Node Node;
944

	
945
    // Pointer to the underlying digraph.
946
    void *_graph;
947
    // Pointer to the length map
948
    void *_length;
949
    // Pointer to the map of predecessors arcs.
950
    void *_pred;
951
    // Pointer to the map of distances.
952
    void *_dist;
953
    //Pointer to the shortest path to the target node.
954
    void *_path;
955
    //Pointer to the distance of the target node.
956
    void *_di;
957

	
958
    public:
959
    /// Constructor.
960

	
961
    /// This constructor does not require parameters, it initiates
962
    /// all of the attributes to default values \c 0.
963
    BellmanFordWizardBase() :
964
      _graph(0), _length(0), _pred(0), _dist(0), _path(0), _di(0) {}
965

	
966
    /// Constructor.
967

	
968
    /// This constructor requires two parameters,
969
    /// others are initiated to \c 0.
970
    /// \param gr The digraph the algorithm runs on.
971
    /// \param len The length map.
972
    BellmanFordWizardBase(const GR& gr,
973
                          const LEN& len) :
974
      _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))),
975
      _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))),
976
      _pred(0), _dist(0), _path(0), _di(0) {}
977

	
978
  };
979

	
980
  /// \brief Auxiliary class for the function-type interface of the
981
  /// \ref BellmanFord "Bellman-Ford" algorithm.
982
  ///
983
  /// This auxiliary class is created to implement the
984
  /// \ref bellmanFord() "function-type interface" of the
985
  /// \ref BellmanFord "Bellman-Ford" algorithm.
986
  /// It does not have own \ref run() method, it uses the
987
  /// functions and features of the plain \ref BellmanFord.
988
  ///
989
  /// This class should only be used through the \ref bellmanFord()
990
  /// function, which makes it easier to use the algorithm.
991
  ///
992
  /// \tparam TR The traits class that defines various types used by the
993
  /// algorithm.
994
  template<class TR>
995
  class BellmanFordWizard : public TR {
996
    typedef TR Base;
997

	
998
    typedef typename TR::Digraph Digraph;
999

	
1000
    typedef typename Digraph::Node Node;
1001
    typedef typename Digraph::NodeIt NodeIt;
1002
    typedef typename Digraph::Arc Arc;
1003
    typedef typename Digraph::OutArcIt ArcIt;
1004

	
1005
    typedef typename TR::LengthMap LengthMap;
1006
    typedef typename LengthMap::Value Value;
1007
    typedef typename TR::PredMap PredMap;
1008
    typedef typename TR::DistMap DistMap;
1009
    typedef typename TR::Path Path;
1010

	
1011
  public:
1012
    /// Constructor.
1013
    BellmanFordWizard() : TR() {}
1014

	
1015
    /// \brief Constructor that requires parameters.
1016
    ///
1017
    /// Constructor that requires parameters.
1018
    /// These parameters will be the default values for the traits class.
1019
    /// \param gr The digraph the algorithm runs on.
1020
    /// \param len The length map.
1021
    BellmanFordWizard(const Digraph& gr, const LengthMap& len)
1022
      : TR(gr, len) {}
1023

	
1024
    /// \brief Copy constructor
1025
    BellmanFordWizard(const TR &b) : TR(b) {}
1026

	
1027
    ~BellmanFordWizard() {}
1028

	
1029
    /// \brief Runs the Bellman-Ford algorithm from the given source node.
1030
    ///
1031
    /// This method runs the Bellman-Ford algorithm from the given source
1032
    /// node in order to compute the shortest path to each node.
1033
    void run(Node s) {
1034
      BellmanFord<Digraph,LengthMap,TR>
1035
        bf(*reinterpret_cast<const Digraph*>(Base::_graph),
1036
           *reinterpret_cast<const LengthMap*>(Base::_length));
1037
      if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1038
      if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1039
      bf.run(s);
1040
    }
1041

	
1042
    /// \brief Runs the Bellman-Ford algorithm to find the shortest path
1043
    /// between \c s and \c t.
1044
    ///
1045
    /// This method runs the Bellman-Ford algorithm from node \c s
1046
    /// in order to compute the shortest path to node \c t.
1047
    /// Actually, it computes the shortest path to each node, but using
1048
    /// this function you can retrieve the distance and the shortest path
1049
    /// for a single target node easier.
1050
    ///
1051
    /// \return \c true if \c t is reachable form \c s.
1052
    bool run(Node s, Node t) {
1053
      BellmanFord<Digraph,LengthMap,TR>
1054
        bf(*reinterpret_cast<const Digraph*>(Base::_graph),
1055
           *reinterpret_cast<const LengthMap*>(Base::_length));
1056
      if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1057
      if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1058
      bf.run(s);
1059
      if (Base::_path) *reinterpret_cast<Path*>(Base::_path) = bf.path(t);
1060
      if (Base::_di) *reinterpret_cast<Value*>(Base::_di) = bf.dist(t);
1061
      return bf.reached(t);
1062
    }
1063

	
1064
    template<class T>
1065
    struct SetPredMapBase : public Base {
1066
      typedef T PredMap;
1067
      static PredMap *createPredMap(const Digraph &) { return 0; };
1068
      SetPredMapBase(const TR &b) : TR(b) {}
1069
    };
1070

	
1071
    /// \brief \ref named-templ-param "Named parameter" for setting
1072
    /// the predecessor map.
1073
    ///
1074
    /// \ref named-templ-param "Named parameter" for setting
1075
    /// the map that stores the predecessor arcs of the nodes.
1076
    template<class T>
1077
    BellmanFordWizard<SetPredMapBase<T> > predMap(const T &t) {
1078
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1079
      return BellmanFordWizard<SetPredMapBase<T> >(*this);
1080
    }
1081

	
1082
    template<class T>
1083
    struct SetDistMapBase : public Base {
1084
      typedef T DistMap;
1085
      static DistMap *createDistMap(const Digraph &) { return 0; };
1086
      SetDistMapBase(const TR &b) : TR(b) {}
1087
    };
1088

	
1089
    /// \brief \ref named-templ-param "Named parameter" for setting
1090
    /// the distance map.
1091
    ///
1092
    /// \ref named-templ-param "Named parameter" for setting
1093
    /// the map that stores the distances of the nodes calculated
1094
    /// by the algorithm.
1095
    template<class T>
1096
    BellmanFordWizard<SetDistMapBase<T> > distMap(const T &t) {
1097
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1098
      return BellmanFordWizard<SetDistMapBase<T> >(*this);
1099
    }
1100

	
1101
    template<class T>
1102
    struct SetPathBase : public Base {
1103
      typedef T Path;
1104
      SetPathBase(const TR &b) : TR(b) {}
1105
    };
1106

	
1107
    /// \brief \ref named-func-param "Named parameter" for getting
1108
    /// the shortest path to the target node.
1109
    ///
1110
    /// \ref named-func-param "Named parameter" for getting
1111
    /// the shortest path to the target node.
1112
    template<class T>
1113
    BellmanFordWizard<SetPathBase<T> > path(const T &t)
1114
    {
1115
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1116
      return BellmanFordWizard<SetPathBase<T> >(*this);
1117
    }
1118

	
1119
    /// \brief \ref named-func-param "Named parameter" for getting
1120
    /// the distance of the target node.
1121
    ///
1122
    /// \ref named-func-param "Named parameter" for getting
1123
    /// the distance of the target node.
1124
    BellmanFordWizard dist(const Value &d)
1125
    {
1126
      Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
1127
      return *this;
1128
    }
1129

	
1130
  };
1131

	
1132
  /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford"
1133
  /// algorithm.
1134
  ///
1135
  /// \ingroup shortest_path
1136
  /// Function type interface for the \ref BellmanFord "Bellman-Ford"
1137
  /// algorithm.
1138
  ///
1139
  /// This function also has several \ref named-templ-func-param
1140
  /// "named parameters", they are declared as the members of class
1141
  /// \ref BellmanFordWizard.
1142
  /// The following examples show how to use these parameters.
1143
  /// \code
1144
  ///   // Compute shortest path from node s to each node
1145
  ///   bellmanFord(g,length).predMap(preds).distMap(dists).run(s);
1146
  ///
1147
  ///   // Compute shortest path from s to t
1148
  ///   bool reached = bellmanFord(g,length).path(p).dist(d).run(s,t);
1149
  /// \endcode
1150
  /// \warning Don't forget to put the \ref BellmanFordWizard::run() "run()"
1151
  /// to the end of the parameter list.
1152
  /// \sa BellmanFordWizard
1153
  /// \sa BellmanFord
1154
  template<typename GR, typename LEN>
1155
  BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >
1156
  bellmanFord(const GR& digraph,
1157
              const LEN& length)
1158
  {
1159
    return BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >(digraph, length);
1160
  }
1161

	
1162
} //END OF NAMESPACE LEMON
1163

	
1164
#endif
1165

	
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-2010
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_BINOMIAL_HEAP_H
20
#define LEMON_BINOMIAL_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 BinomialHeap {
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 BinomialHeap(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
    BinomialHeap(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 BinomialHeap;
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_BINOMIAL_HEAP_H
445

	
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-2010
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_CAPACITY_SCALING_H
20
#define LEMON_CAPACITY_SCALING_H
21

	
22
/// \ingroup min_cost_flow_algs
23
///
24
/// \file
25
/// \brief Capacity Scaling algorithm for finding a minimum cost flow.
26

	
27
#include <vector>
28
#include <limits>
29
#include <lemon/core.h>
30
#include <lemon/bin_heap.h>
31

	
32
namespace lemon {
33

	
34
  /// \brief Default traits class of CapacityScaling algorithm.
35
  ///
36
  /// Default traits class of CapacityScaling algorithm.
37
  /// \tparam GR Digraph type.
38
  /// \tparam V The number type used for flow amounts, capacity bounds
39
  /// and supply values. By default it is \c int.
40
  /// \tparam C The number type used for costs and potentials.
41
  /// By default it is the same as \c V.
42
  template <typename GR, typename V = int, typename C = V>
43
  struct CapacityScalingDefaultTraits
44
  {
45
    /// The type of the digraph
46
    typedef GR Digraph;
47
    /// The type of the flow amounts, capacity bounds and supply values
48
    typedef V Value;
49
    /// The type of the arc costs
50
    typedef C Cost;
51

	
52
    /// \brief The type of the heap used for internal Dijkstra computations.
53
    ///
54
    /// The type of the heap used for internal Dijkstra computations.
55
    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept,
56
    /// its priority type must be \c Cost and its cross reference type
57
    /// must be \ref RangeMap "RangeMap<int>".
58
    typedef BinHeap<Cost, RangeMap<int> > Heap;
59
  };
60

	
61
  /// \addtogroup min_cost_flow_algs
62
  /// @{
63

	
64
  /// \brief Implementation of the Capacity Scaling algorithm for
65
  /// finding a \ref min_cost_flow "minimum cost flow".
66
  ///
67
  /// \ref CapacityScaling implements the capacity scaling version
68
  /// of the successive shortest path algorithm for finding a
69
  /// \ref min_cost_flow "minimum cost flow" \ref amo93networkflows,
70
  /// \ref edmondskarp72theoretical. It is an efficient dual
71
  /// solution method.
72
  ///
73
  /// Most of the parameters of the problem (except for the digraph)
74
  /// can be given using separate functions, and the algorithm can be
75
  /// executed using the \ref run() function. If some parameters are not
76
  /// specified, then default values will be used.
77
  ///
78
  /// \tparam GR The digraph type the algorithm runs on.
79
  /// \tparam V The number type used for flow amounts, capacity bounds
80
  /// and supply values in the algorithm. By default, it is \c int.
81
  /// \tparam C The number type used for costs and potentials in the
82
  /// algorithm. By default, it is the same as \c V.
83
  /// \tparam TR The traits class that defines various types used by the
84
  /// algorithm. By default, it is \ref CapacityScalingDefaultTraits
85
  /// "CapacityScalingDefaultTraits<GR, V, C>".
86
  /// In most cases, this parameter should not be set directly,
87
  /// consider to use the named template parameters instead.
88
  ///
89
  /// \warning Both number types must be signed and all input data must
90
  /// be integer.
91
  /// \warning This algorithm does not support negative costs for such
92
  /// arcs that have infinite upper bound.
93
#ifdef DOXYGEN
94
  template <typename GR, typename V, typename C, typename TR>
95
#else
96
  template < typename GR, typename V = int, typename C = V,
97
             typename TR = CapacityScalingDefaultTraits<GR, V, C> >
98
#endif
99
  class CapacityScaling
100
  {
101
  public:
102

	
103
    /// The type of the digraph
104
    typedef typename TR::Digraph Digraph;
105
    /// The type of the flow amounts, capacity bounds and supply values
106
    typedef typename TR::Value Value;
107
    /// The type of the arc costs
108
    typedef typename TR::Cost Cost;
109

	
110
    /// The type of the heap used for internal Dijkstra computations
111
    typedef typename TR::Heap Heap;
112

	
113
    /// The \ref CapacityScalingDefaultTraits "traits class" of the algorithm
114
    typedef TR Traits;
115

	
116
  public:
117

	
118
    /// \brief Problem type constants for the \c run() function.
119
    ///
120
    /// Enum type containing the problem type constants that can be
121
    /// returned by the \ref run() function of the algorithm.
122
    enum ProblemType {
123
      /// The problem has no feasible solution (flow).
124
      INFEASIBLE,
125
      /// The problem has optimal solution (i.e. it is feasible and
126
      /// bounded), and the algorithm has found optimal flow and node
127
      /// potentials (primal and dual solutions).
128
      OPTIMAL,
129
      /// The digraph contains an arc of negative cost and infinite
130
      /// upper bound. It means that the objective function is unbounded
131
      /// on that arc, however, note that it could actually be bounded
132
      /// over the feasible flows, but this algroithm cannot handle
133
      /// these cases.
134
      UNBOUNDED
135
    };
136

	
137
  private:
138

	
139
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
140

	
141
    typedef std::vector<int> IntVector;
142
    typedef std::vector<Value> ValueVector;
143
    typedef std::vector<Cost> CostVector;
144
    typedef std::vector<char> BoolVector;
145
    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
146

	
147
  private:
148

	
149
    // Data related to the underlying digraph
150
    const GR &_graph;
151
    int _node_num;
152
    int _arc_num;
153
    int _res_arc_num;
154
    int _root;
155

	
156
    // Parameters of the problem
157
    bool _have_lower;
158
    Value _sum_supply;
159

	
160
    // Data structures for storing the digraph
161
    IntNodeMap _node_id;
162
    IntArcMap _arc_idf;
163
    IntArcMap _arc_idb;
164
    IntVector _first_out;
165
    BoolVector _forward;
166
    IntVector _source;
167
    IntVector _target;
168
    IntVector _reverse;
169

	
170
    // Node and arc data
171
    ValueVector _lower;
172
    ValueVector _upper;
173
    CostVector _cost;
174
    ValueVector _supply;
175

	
176
    ValueVector _res_cap;
177
    CostVector _pi;
178
    ValueVector _excess;
179
    IntVector _excess_nodes;
180
    IntVector _deficit_nodes;
181

	
182
    Value _delta;
183
    int _factor;
184
    IntVector _pred;
185

	
186
  public:
187

	
188
    /// \brief Constant for infinite upper bounds (capacities).
189
    ///
190
    /// Constant for infinite upper bounds (capacities).
191
    /// It is \c std::numeric_limits<Value>::infinity() if available,
192
    /// \c std::numeric_limits<Value>::max() otherwise.
193
    const Value INF;
194

	
195
  private:
196

	
197
    // Special implementation of the Dijkstra algorithm for finding
198
    // shortest paths in the residual network of the digraph with
199
    // respect to the reduced arc costs and modifying the node
200
    // potentials according to the found distance labels.
201
    class ResidualDijkstra
202
    {
203
    private:
204

	
205
      int _node_num;
206
      bool _geq;
207
      const IntVector &_first_out;
208
      const IntVector &_target;
209
      const CostVector &_cost;
210
      const ValueVector &_res_cap;
211
      const ValueVector &_excess;
212
      CostVector &_pi;
213
      IntVector &_pred;
214

	
215
      IntVector _proc_nodes;
216
      CostVector _dist;
217

	
218
    public:
219

	
220
      ResidualDijkstra(CapacityScaling& cs) :
221
        _node_num(cs._node_num), _geq(cs._sum_supply < 0),
222
        _first_out(cs._first_out), _target(cs._target), _cost(cs._cost),
223
        _res_cap(cs._res_cap), _excess(cs._excess), _pi(cs._pi),
224
        _pred(cs._pred), _dist(cs._node_num)
225
      {}
226

	
227
      int run(int s, Value delta = 1) {
228
        RangeMap<int> heap_cross_ref(_node_num, Heap::PRE_HEAP);
229
        Heap heap(heap_cross_ref);
230
        heap.push(s, 0);
231
        _pred[s] = -1;
232
        _proc_nodes.clear();
233

	
234
        // Process nodes
235
        while (!heap.empty() && _excess[heap.top()] > -delta) {
236
          int u = heap.top(), v;
237
          Cost d = heap.prio() + _pi[u], dn;
238
          _dist[u] = heap.prio();
239
          _proc_nodes.push_back(u);
240
          heap.pop();
241

	
242
          // Traverse outgoing residual arcs
243
          int last_out = _geq ? _first_out[u+1] : _first_out[u+1] - 1;
244
          for (int a = _first_out[u]; a != last_out; ++a) {
245
            if (_res_cap[a] < delta) continue;
246
            v = _target[a];
247
            switch (heap.state(v)) {
248
              case Heap::PRE_HEAP:
249
                heap.push(v, d + _cost[a] - _pi[v]);
250
                _pred[v] = a;
251
                break;
252
              case Heap::IN_HEAP:
253
                dn = d + _cost[a] - _pi[v];
254
                if (dn < heap[v]) {
255
                  heap.decrease(v, dn);
256
                  _pred[v] = a;
257
                }
258
                break;
259
              case Heap::POST_HEAP:
260
                break;
261
            }
262
          }
263
        }
264
        if (heap.empty()) return -1;
265

	
266
        // Update potentials of processed nodes
267
        int t = heap.top();
268
        Cost dt = heap.prio();
269
        for (int i = 0; i < int(_proc_nodes.size()); ++i) {
270
          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - dt;
271
        }
272

	
273
        return t;
274
      }
275

	
276
    }; //class ResidualDijkstra
277

	
278
  public:
279

	
280
    /// \name Named Template Parameters
281
    /// @{
282

	
283
    template <typename T>
284
    struct SetHeapTraits : public Traits {
285
      typedef T Heap;
286
    };
287

	
288
    /// \brief \ref named-templ-param "Named parameter" for setting
289
    /// \c Heap type.
290
    ///
291
    /// \ref named-templ-param "Named parameter" for setting \c Heap
292
    /// type, which is used for internal Dijkstra computations.
293
    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept,
294
    /// its priority type must be \c Cost and its cross reference type
295
    /// must be \ref RangeMap "RangeMap<int>".
296
    template <typename T>
297
    struct SetHeap
298
      : public CapacityScaling<GR, V, C, SetHeapTraits<T> > {
299
      typedef  CapacityScaling<GR, V, C, SetHeapTraits<T> > Create;
300
    };
301

	
302
    /// @}
303

	
304
  protected:
305

	
306
    CapacityScaling() {}
307

	
308
  public:
309

	
310
    /// \brief Constructor.
311
    ///
312
    /// The constructor of the class.
313
    ///
314
    /// \param graph The digraph the algorithm runs on.
315
    CapacityScaling(const GR& graph) :
316
      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
317
      INF(std::numeric_limits<Value>::has_infinity ?
318
          std::numeric_limits<Value>::infinity() :
319
          std::numeric_limits<Value>::max())
320
    {
321
      // Check the number types
322
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
323
        "The flow type of CapacityScaling must be signed");
324
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
325
        "The cost type of CapacityScaling must be signed");
326

	
327
      // Reset data structures
328
      reset();
329
    }
330

	
331
    /// \name Parameters
332
    /// The parameters of the algorithm can be specified using these
333
    /// functions.
334

	
335
    /// @{
336

	
337
    /// \brief Set the lower bounds on the arcs.
338
    ///
339
    /// This function sets the lower bounds on the arcs.
340
    /// If it is not used before calling \ref run(), the lower bounds
341
    /// will be set to zero on all arcs.
342
    ///
343
    /// \param map An arc map storing the lower bounds.
344
    /// Its \c Value type must be convertible to the \c Value type
345
    /// of the algorithm.
346
    ///
347
    /// \return <tt>(*this)</tt>
348
    template <typename LowerMap>
349
    CapacityScaling& lowerMap(const LowerMap& map) {
350
      _have_lower = true;
351
      for (ArcIt a(_graph); a != INVALID; ++a) {
352
        _lower[_arc_idf[a]] = map[a];
353
        _lower[_arc_idb[a]] = map[a];
354
      }
355
      return *this;
356
    }
357

	
358
    /// \brief Set the upper bounds (capacities) on the arcs.
359
    ///
360
    /// This function sets the upper bounds (capacities) on the arcs.
361
    /// If it is not used before calling \ref run(), the upper bounds
362
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
363
    /// unbounded from above).
364
    ///
365
    /// \param map An arc map storing the upper bounds.
366
    /// Its \c Value type must be convertible to the \c Value type
367
    /// of the algorithm.
368
    ///
369
    /// \return <tt>(*this)</tt>
370
    template<typename UpperMap>
371
    CapacityScaling& upperMap(const UpperMap& map) {
372
      for (ArcIt a(_graph); a != INVALID; ++a) {
373
        _upper[_arc_idf[a]] = map[a];
374
      }
375
      return *this;
376
    }
377

	
378
    /// \brief Set the costs of the arcs.
379
    ///
380
    /// This function sets the costs of the arcs.
381
    /// If it is not used before calling \ref run(), the costs
382
    /// will be set to \c 1 on all arcs.
383
    ///
384
    /// \param map An arc map storing the costs.
385
    /// Its \c Value type must be convertible to the \c Cost type
386
    /// of the algorithm.
387
    ///
388
    /// \return <tt>(*this)</tt>
389
    template<typename CostMap>
390
    CapacityScaling& costMap(const CostMap& map) {
391
      for (ArcIt a(_graph); a != INVALID; ++a) {
392
        _cost[_arc_idf[a]] =  map[a];
393
        _cost[_arc_idb[a]] = -map[a];
394
      }
395
      return *this;
396
    }
397

	
398
    /// \brief Set the supply values of the nodes.
399
    ///
400
    /// This function sets the supply values of the nodes.
401
    /// If neither this function nor \ref stSupply() is used before
402
    /// calling \ref run(), the supply of each node will be set to zero.
403
    ///
404
    /// \param map A node map storing the supply values.
405
    /// Its \c Value type must be convertible to the \c Value type
406
    /// of the algorithm.
407
    ///
408
    /// \return <tt>(*this)</tt>
409
    template<typename SupplyMap>
410
    CapacityScaling& supplyMap(const SupplyMap& map) {
411
      for (NodeIt n(_graph); n != INVALID; ++n) {
412
        _supply[_node_id[n]] = map[n];
413
      }
414
      return *this;
415
    }
416

	
417
    /// \brief Set single source and target nodes and a supply value.
418
    ///
419
    /// This function sets a single source node and a single target node
420
    /// and the required flow value.
421
    /// If neither this function nor \ref supplyMap() is used before
422
    /// calling \ref run(), the supply of each node will be set to zero.
423
    ///
424
    /// Using this function has the same effect as using \ref supplyMap()
425
    /// with such a map in which \c k is assigned to \c s, \c -k is
426
    /// assigned to \c t and all other nodes have zero supply value.
427
    ///
428
    /// \param s The source node.
429
    /// \param t The target node.
430
    /// \param k The required amount of flow from node \c s to node \c t
431
    /// (i.e. the supply of \c s and the demand of \c t).
432
    ///
433
    /// \return <tt>(*this)</tt>
434
    CapacityScaling& stSupply(const Node& s, const Node& t, Value k) {
435
      for (int i = 0; i != _node_num; ++i) {
436
        _supply[i] = 0;
437
      }
438
      _supply[_node_id[s]] =  k;
439
      _supply[_node_id[t]] = -k;
440
      return *this;
441
    }
442

	
443
    /// @}
444

	
445
    /// \name Execution control
446
    /// The algorithm can be executed using \ref run().
447

	
448
    /// @{
449

	
450
    /// \brief Run the algorithm.
451
    ///
452
    /// This function runs the algorithm.
453
    /// The paramters can be specified using functions \ref lowerMap(),
454
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
455
    /// For example,
456
    /// \code
457
    ///   CapacityScaling<ListDigraph> cs(graph);
458
    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
459
    ///     .supplyMap(sup).run();
460
    /// \endcode
461
    ///
462
    /// This function can be called more than once. All the given parameters
463
    /// are kept for the next call, unless \ref resetParams() or \ref reset()
464
    /// is used, thus only the modified parameters have to be set again.
465
    /// If the underlying digraph was also modified after the construction
466
    /// of the class (or the last \ref reset() call), then the \ref reset()
467
    /// function must be called.
468
    ///
469
    /// \param factor The capacity scaling factor. It must be larger than
470
    /// one to use scaling. If it is less or equal to one, then scaling
471
    /// will be disabled.
472
    ///
473
    /// \return \c INFEASIBLE if no feasible flow exists,
474
    /// \n \c OPTIMAL if the problem has optimal solution
475
    /// (i.e. it is feasible and bounded), and the algorithm has found
476
    /// optimal flow and node potentials (primal and dual solutions),
477
    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
478
    /// and infinite upper bound. It means that the objective function
479
    /// is unbounded on that arc, however, note that it could actually be
480
    /// bounded over the feasible flows, but this algroithm cannot handle
481
    /// these cases.
482
    ///
483
    /// \see ProblemType
484
    /// \see resetParams(), reset()
485
    ProblemType run(int factor = 4) {
486
      _factor = factor;
487
      ProblemType pt = init();
488
      if (pt != OPTIMAL) return pt;
489
      return start();
490
    }
491

	
492
    /// \brief Reset all the parameters that have been given before.
493
    ///
494
    /// This function resets all the paramaters that have been given
495
    /// before using functions \ref lowerMap(), \ref upperMap(),
496
    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
497
    ///
498
    /// It is useful for multiple \ref run() calls. Basically, all the given
499
    /// parameters are kept for the next \ref run() call, unless
500
    /// \ref resetParams() or \ref reset() is used.
501
    /// If the underlying digraph was also modified after the construction
502
    /// of the class or the last \ref reset() call, then the \ref reset()
503
    /// function must be used, otherwise \ref resetParams() is sufficient.
504
    ///
505
    /// For example,
506
    /// \code
507
    ///   CapacityScaling<ListDigraph> cs(graph);
508
    ///
509
    ///   // First run
510
    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
511
    ///     .supplyMap(sup).run();
512
    ///
513
    ///   // Run again with modified cost map (resetParams() is not called,
514
    ///   // so only the cost map have to be set again)
515
    ///   cost[e] += 100;
516
    ///   cs.costMap(cost).run();
517
    ///
518
    ///   // Run again from scratch using resetParams()
519
    ///   // (the lower bounds will be set to zero on all arcs)
520
    ///   cs.resetParams();
521
    ///   cs.upperMap(capacity).costMap(cost)
522
    ///     .supplyMap(sup).run();
523
    /// \endcode
524
    ///
525
    /// \return <tt>(*this)</tt>
526
    ///
527
    /// \see reset(), run()
528
    CapacityScaling& resetParams() {
529
      for (int i = 0; i != _node_num; ++i) {
530
        _supply[i] = 0;
531
      }
532
      for (int j = 0; j != _res_arc_num; ++j) {
533
        _lower[j] = 0;
534
        _upper[j] = INF;
535
        _cost[j] = _forward[j] ? 1 : -1;
536
      }
537
      _have_lower = false;
538
      return *this;
539
    }
540

	
541
    /// \brief Reset the internal data structures and all the parameters
542
    /// that have been given before.
543
    ///
544
    /// This function resets the internal data structures and all the
545
    /// paramaters that have been given before using functions \ref lowerMap(),
546
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
547
    ///
548
    /// It is useful for multiple \ref run() calls. Basically, all the given
549
    /// parameters are kept for the next \ref run() call, unless
550
    /// \ref resetParams() or \ref reset() is used.
551
    /// If the underlying digraph was also modified after the construction
552
    /// of the class or the last \ref reset() call, then the \ref reset()
553
    /// function must be used, otherwise \ref resetParams() is sufficient.
554
    ///
555
    /// See \ref resetParams() for examples.
556
    ///
557
    /// \return <tt>(*this)</tt>
558
    ///
559
    /// \see resetParams(), run()
560
    CapacityScaling& reset() {
561
      // Resize vectors
562
      _node_num = countNodes(_graph);
563
      _arc_num = countArcs(_graph);
564
      _res_arc_num = 2 * (_arc_num + _node_num);
565
      _root = _node_num;
566
      ++_node_num;
567

	
568
      _first_out.resize(_node_num + 1);
569
      _forward.resize(_res_arc_num);
570
      _source.resize(_res_arc_num);
571
      _target.resize(_res_arc_num);
572
      _reverse.resize(_res_arc_num);
573

	
574
      _lower.resize(_res_arc_num);
575
      _upper.resize(_res_arc_num);
576
      _cost.resize(_res_arc_num);
577
      _supply.resize(_node_num);
578

	
579
      _res_cap.resize(_res_arc_num);
580
      _pi.resize(_node_num);
581
      _excess.resize(_node_num);
582
      _pred.resize(_node_num);
583

	
584
      // Copy the graph
585
      int i = 0, j = 0, k = 2 * _arc_num + _node_num - 1;
586
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
587
        _node_id[n] = i;
588
      }
589
      i = 0;
590
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
591
        _first_out[i] = j;
592
        for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
593
          _arc_idf[a] = j;
594
          _forward[j] = true;
595
          _source[j] = i;
596
          _target[j] = _node_id[_graph.runningNode(a)];
597
        }
598
        for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
599
          _arc_idb[a] = j;
600
          _forward[j] = false;
601
          _source[j] = i;
602
          _target[j] = _node_id[_graph.runningNode(a)];
603
        }
604
        _forward[j] = false;
605
        _source[j] = i;
606
        _target[j] = _root;
607
        _reverse[j] = k;
608
        _forward[k] = true;
609
        _source[k] = _root;
610
        _target[k] = i;
611
        _reverse[k] = j;
612
        ++j; ++k;
613
      }
614
      _first_out[i] = j;
615
      _first_out[_node_num] = k;
616
      for (ArcIt a(_graph); a != INVALID; ++a) {
617
        int fi = _arc_idf[a];
618
        int bi = _arc_idb[a];
619
        _reverse[fi] = bi;
620
        _reverse[bi] = fi;
621
      }
622

	
623
      // Reset parameters
624
      resetParams();
625
      return *this;
626
    }
627

	
628
    /// @}
629

	
630
    /// \name Query Functions
631
    /// The results of the algorithm can be obtained using these
632
    /// functions.\n
633
    /// The \ref run() function must be called before using them.
634

	
635
    /// @{
636

	
637
    /// \brief Return the total cost of the found flow.
638
    ///
639
    /// This function returns the total cost of the found flow.
640
    /// Its complexity is O(e).
641
    ///
642
    /// \note The return type of the function can be specified as a
643
    /// template parameter. For example,
644
    /// \code
645
    ///   cs.totalCost<double>();
646
    /// \endcode
647
    /// It is useful if the total cost cannot be stored in the \c Cost
648
    /// type of the algorithm, which is the default return type of the
649
    /// function.
650
    ///
651
    /// \pre \ref run() must be called before using this function.
652
    template <typename Number>
653
    Number totalCost() const {
654
      Number c = 0;
655
      for (ArcIt a(_graph); a != INVALID; ++a) {
656
        int i = _arc_idb[a];
657
        c += static_cast<Number>(_res_cap[i]) *
658
             (-static_cast<Number>(_cost[i]));
659
      }
660
      return c;
661
    }
662

	
663
#ifndef DOXYGEN
664
    Cost totalCost() const {
665
      return totalCost<Cost>();
666
    }
667
#endif
668

	
669
    /// \brief Return the flow on the given arc.
670
    ///
671
    /// This function returns the flow on the given arc.
672
    ///
673
    /// \pre \ref run() must be called before using this function.
674
    Value flow(const Arc& a) const {
675
      return _res_cap[_arc_idb[a]];
676
    }
677

	
678
    /// \brief Return the flow map (the primal solution).
679
    ///
680
    /// This function copies the flow value on each arc into the given
681
    /// map. The \c Value type of the algorithm must be convertible to
682
    /// the \c Value type of the map.
683
    ///
684
    /// \pre \ref run() must be called before using this function.
685
    template <typename FlowMap>
686
    void flowMap(FlowMap &map) const {
687
      for (ArcIt a(_graph); a != INVALID; ++a) {
688
        map.set(a, _res_cap[_arc_idb[a]]);
689
      }
690
    }
691

	
692
    /// \brief Return the potential (dual value) of the given node.
693
    ///
694
    /// This function returns the potential (dual value) of the
695
    /// given node.
696
    ///
697
    /// \pre \ref run() must be called before using this function.
698
    Cost potential(const Node& n) const {
699
      return _pi[_node_id[n]];
700
    }
701

	
702
    /// \brief Return the potential map (the dual solution).
703
    ///
704
    /// This function copies the potential (dual value) of each node
705
    /// into the given map.
706
    /// The \c Cost type of the algorithm must be convertible to the
707
    /// \c Value type of the map.
708
    ///
709
    /// \pre \ref run() must be called before using this function.
710
    template <typename PotentialMap>
711
    void potentialMap(PotentialMap &map) const {
712
      for (NodeIt n(_graph); n != INVALID; ++n) {
713
        map.set(n, _pi[_node_id[n]]);
714
      }
715
    }
716

	
717
    /// @}
718

	
719
  private:
720

	
721
    // Initialize the algorithm
722
    ProblemType init() {
723
      if (_node_num <= 1) return INFEASIBLE;
724

	
725
      // Check the sum of supply values
726
      _sum_supply = 0;
727
      for (int i = 0; i != _root; ++i) {
728
        _sum_supply += _supply[i];
729
      }
730
      if (_sum_supply > 0) return INFEASIBLE;
731

	
732
      // Initialize vectors
733
      for (int i = 0; i != _root; ++i) {
734
        _pi[i] = 0;
735
        _excess[i] = _supply[i];
736
      }
737

	
738
      // Remove non-zero lower bounds
739
      const Value MAX = std::numeric_limits<Value>::max();
740
      int last_out;
741
      if (_have_lower) {
742
        for (int i = 0; i != _root; ++i) {
743
          last_out = _first_out[i+1];
744
          for (int j = _first_out[i]; j != last_out; ++j) {
745
            if (_forward[j]) {
746
              Value c = _lower[j];
747
              if (c >= 0) {
748
                _res_cap[j] = _upper[j] < MAX ? _upper[j] - c : INF;
749
              } else {
750
                _res_cap[j] = _upper[j] < MAX + c ? _upper[j] - c : INF;
751
              }
752
              _excess[i] -= c;
753
              _excess[_target[j]] += c;
754
            } else {
755
              _res_cap[j] = 0;
756
            }
757
          }
758
        }
759
      } else {
760
        for (int j = 0; j != _res_arc_num; ++j) {
761
          _res_cap[j] = _forward[j] ? _upper[j] : 0;
762
        }
763
      }
764

	
765
      // Handle negative costs
766
      for (int i = 0; i != _root; ++i) {
767
        last_out = _first_out[i+1] - 1;
768
        for (int j = _first_out[i]; j != last_out; ++j) {
769
          Value rc = _res_cap[j];
770
          if (_cost[j] < 0 && rc > 0) {
771
            if (rc >= MAX) return UNBOUNDED;
772
            _excess[i] -= rc;
773
            _excess[_target[j]] += rc;
774
            _res_cap[j] = 0;
775
            _res_cap[_reverse[j]] += rc;
776
          }
777
        }
778
      }
779

	
780
      // Handle GEQ supply type
781
      if (_sum_supply < 0) {
782
        _pi[_root] = 0;
783
        _excess[_root] = -_sum_supply;
784
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
785
          int ra = _reverse[a];
786
          _res_cap[a] = -_sum_supply + 1;
787
          _res_cap[ra] = 0;
788
          _cost[a] = 0;
789
          _cost[ra] = 0;
790
        }
791
      } else {
792
        _pi[_root] = 0;
793
        _excess[_root] = 0;
794
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
795
          int ra = _reverse[a];
796
          _res_cap[a] = 1;
797
          _res_cap[ra] = 0;
798
          _cost[a] = 0;
799
          _cost[ra] = 0;
800
        }
801
      }
802

	
803
      // Initialize delta value
804
      if (_factor > 1) {
805
        // With scaling
806
        Value max_sup = 0, max_dem = 0, max_cap = 0;
807
        for (int i = 0; i != _root; ++i) {
808
          Value ex = _excess[i];
809
          if ( ex > max_sup) max_sup =  ex;
810
          if (-ex > max_dem) max_dem = -ex;
811
          int last_out = _first_out[i+1] - 1;
812
          for (int j = _first_out[i]; j != last_out; ++j) {
813
            if (_res_cap[j] > max_cap) max_cap = _res_cap[j];
814
          }
815
        }
816
        max_sup = std::min(std::min(max_sup, max_dem), max_cap);
817
        for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2) ;
818
      } else {
819
        // Without scaling
820
        _delta = 1;
821
      }
822

	
823
      return OPTIMAL;
824
    }
825

	
826
    ProblemType start() {
827
      // Execute the algorithm
828
      ProblemType pt;
829
      if (_delta > 1)
830
        pt = startWithScaling();
831
      else
832
        pt = startWithoutScaling();
833

	
834
      // Handle non-zero lower bounds
835
      if (_have_lower) {
836
        int limit = _first_out[_root];
837
        for (int j = 0; j != limit; ++j) {
838
          if (!_forward[j]) _res_cap[j] += _lower[j];
839
        }
840
      }
841

	
842
      // Shift potentials if necessary
843
      Cost pr = _pi[_root];
844
      if (_sum_supply < 0 || pr > 0) {
845
        for (int i = 0; i != _node_num; ++i) {
846
          _pi[i] -= pr;
847
        }
848
      }
849

	
850
      return pt;
851
    }
852

	
853
    // Execute the capacity scaling algorithm
854
    ProblemType startWithScaling() {
855
      // Perform capacity scaling phases
856
      int s, t;
857
      ResidualDijkstra _dijkstra(*this);
858
      while (true) {
859
        // Saturate all arcs not satisfying the optimality condition
860
        int last_out;
861
        for (int u = 0; u != _node_num; ++u) {
862
          last_out = _sum_supply < 0 ?
863
            _first_out[u+1] : _first_out[u+1] - 1;
864
          for (int a = _first_out[u]; a != last_out; ++a) {
865
            int v = _target[a];
866
            Cost c = _cost[a] + _pi[u] - _pi[v];
867
            Value rc = _res_cap[a];
868
            if (c < 0 && rc >= _delta) {
869
              _excess[u] -= rc;
870
              _excess[v] += rc;
871
              _res_cap[a] = 0;
872
              _res_cap[_reverse[a]] += rc;
873
            }
874
          }
875
        }
876

	
877
        // Find excess nodes and deficit nodes
878
        _excess_nodes.clear();
879
        _deficit_nodes.clear();
880
        for (int u = 0; u != _node_num; ++u) {
881
          Value ex = _excess[u];
882
          if (ex >=  _delta) _excess_nodes.push_back(u);
883
          if (ex <= -_delta) _deficit_nodes.push_back(u);
884
        }
885
        int next_node = 0, next_def_node = 0;
886

	
887
        // Find augmenting shortest paths
888
        while (next_node < int(_excess_nodes.size())) {
889
          // Check deficit nodes
890
          if (_delta > 1) {
891
            bool delta_deficit = false;
892
            for ( ; next_def_node < int(_deficit_nodes.size());
893
                    ++next_def_node ) {
894
              if (_excess[_deficit_nodes[next_def_node]] <= -_delta) {
895
                delta_deficit = true;
896
                break;
897
              }
898
            }
899
            if (!delta_deficit) break;
900
          }
901

	
902
          // Run Dijkstra in the residual network
903
          s = _excess_nodes[next_node];
904
          if ((t = _dijkstra.run(s, _delta)) == -1) {
905
            if (_delta > 1) {
906
              ++next_node;
907
              continue;
908
            }
909
            return INFEASIBLE;
910
          }
911

	
912
          // Augment along a shortest path from s to t
913
          Value d = std::min(_excess[s], -_excess[t]);
914
          int u = t;
915
          int a;
916
          if (d > _delta) {
917
            while ((a = _pred[u]) != -1) {
918
              if (_res_cap[a] < d) d = _res_cap[a];
919
              u = _source[a];
920
            }
921
          }
922
          u = t;
923
          while ((a = _pred[u]) != -1) {
924
            _res_cap[a] -= d;
925
            _res_cap[_reverse[a]] += d;
926
            u = _source[a];
927
          }
928
          _excess[s] -= d;
929
          _excess[t] += d;
930

	
931
          if (_excess[s] < _delta) ++next_node;
932
        }
933

	
934
        if (_delta == 1) break;
935
        _delta = _delta <= _factor ? 1 : _delta / _factor;
936
      }
937

	
938
      return OPTIMAL;
939
    }
940

	
941
    // Execute the successive shortest path algorithm
942
    ProblemType startWithoutScaling() {
943
      // Find excess nodes
944
      _excess_nodes.clear();
945
      for (int i = 0; i != _node_num; ++i) {
946
        if (_excess[i] > 0) _excess_nodes.push_back(i);
947
      }
948
      if (_excess_nodes.size() == 0) return OPTIMAL;
949
      int next_node = 0;
950

	
951
      // Find shortest paths
952
      int s, t;
953
      ResidualDijkstra _dijkstra(*this);
954
      while ( _excess[_excess_nodes[next_node]] > 0 ||
955
              ++next_node < int(_excess_nodes.size()) )
956
      {
957
        // Run Dijkstra in the residual network
958
        s = _excess_nodes[next_node];
959
        if ((t = _dijkstra.run(s)) == -1) return INFEASIBLE;
960

	
961
        // Augment along a shortest path from s to t
962
        Value d = std::min(_excess[s], -_excess[t]);
963
        int u = t;
964
        int a;
965
        if (d > 1) {
966
          while ((a = _pred[u]) != -1) {
967
            if (_res_cap[a] < d) d = _res_cap[a];
968
            u = _source[a];
969
          }
970
        }
971
        u = t;
972
        while ((a = _pred[u]) != -1) {
973
          _res_cap[a] -= d;
974
          _res_cap[_reverse[a]] += d;
975
          u = _source[a];
976
        }
977
        _excess[s] -= d;
978
        _excess[t] += d;
979
      }
980

	
981
      return OPTIMAL;
982
    }
983

	
984
  }; //class CapacityScaling
985

	
986
  ///@}
987

	
988
} //namespace lemon
989

	
990
#endif //LEMON_CAPACITY_SCALING_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-2010
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_COST_SCALING_H
20
#define LEMON_COST_SCALING_H
21

	
22
/// \ingroup min_cost_flow_algs
23
/// \file
24
/// \brief Cost scaling algorithm for finding a minimum cost flow.
25

	
26
#include <vector>
27
#include <deque>
28
#include <limits>
29

	
30
#include <lemon/core.h>
31
#include <lemon/maps.h>
32
#include <lemon/math.h>
33
#include <lemon/static_graph.h>
34
#include <lemon/circulation.h>
35
#include <lemon/bellman_ford.h>
36

	
37
namespace lemon {
38

	
39
  /// \brief Default traits class of CostScaling algorithm.
40
  ///
41
  /// Default traits class of CostScaling algorithm.
42
  /// \tparam GR Digraph type.
43
  /// \tparam V The number type used for flow amounts, capacity bounds
44
  /// and supply values. By default it is \c int.
45
  /// \tparam C The number type used for costs and potentials.
46
  /// By default it is the same as \c V.
47
#ifdef DOXYGEN
48
  template <typename GR, typename V = int, typename C = V>
49
#else
50
  template < typename GR, typename V = int, typename C = V,
51
             bool integer = std::numeric_limits<C>::is_integer >
52
#endif
53
  struct CostScalingDefaultTraits
54
  {
55
    /// The type of the digraph
56
    typedef GR Digraph;
57
    /// The type of the flow amounts, capacity bounds and supply values
58
    typedef V Value;
59
    /// The type of the arc costs
60
    typedef C Cost;
61

	
62
    /// \brief The large cost type used for internal computations
63
    ///
64
    /// The large cost type used for internal computations.
65
    /// It is \c long \c long if the \c Cost type is integer,
66
    /// otherwise it is \c double.
67
    /// \c Cost must be convertible to \c LargeCost.
68
    typedef double LargeCost;
69
  };
70

	
71
  // Default traits class for integer cost types
72
  template <typename GR, typename V, typename C>
73
  struct CostScalingDefaultTraits<GR, V, C, true>
74
  {
75
    typedef GR Digraph;
76
    typedef V Value;
77
    typedef C Cost;
78
#ifdef LEMON_HAVE_LONG_LONG
79
    typedef long long LargeCost;
80
#else
81
    typedef long LargeCost;
82
#endif
83
  };
84

	
85

	
86
  /// \addtogroup min_cost_flow_algs
87
  /// @{
88

	
89
  /// \brief Implementation of the Cost Scaling algorithm for
90
  /// finding a \ref min_cost_flow "minimum cost flow".
91
  ///
92
  /// \ref CostScaling implements a cost scaling algorithm that performs
93
  /// push/augment and relabel operations for finding a \ref min_cost_flow
94
  /// "minimum cost flow" \ref amo93networkflows, \ref goldberg90approximation,
95
  /// \ref goldberg97efficient, \ref bunnagel98efficient.
96
  /// It is a highly efficient primal-dual solution method, which
97
  /// can be viewed as the generalization of the \ref Preflow
98
  /// "preflow push-relabel" algorithm for the maximum flow problem.
99
  ///
100
  /// Most of the parameters of the problem (except for the digraph)
101
  /// can be given using separate functions, and the algorithm can be
102
  /// executed using the \ref run() function. If some parameters are not
103
  /// specified, then default values will be used.
104
  ///
105
  /// \tparam GR The digraph type the algorithm runs on.
106
  /// \tparam V The number type used for flow amounts, capacity bounds
107
  /// and supply values in the algorithm. By default, it is \c int.
108
  /// \tparam C The number type used for costs and potentials in the
109
  /// algorithm. By default, it is the same as \c V.
110
  /// \tparam TR The traits class that defines various types used by the
111
  /// algorithm. By default, it is \ref CostScalingDefaultTraits
112
  /// "CostScalingDefaultTraits<GR, V, C>".
113
  /// In most cases, this parameter should not be set directly,
114
  /// consider to use the named template parameters instead.
115
  ///
116
  /// \warning Both number types must be signed and all input data must
117
  /// be integer.
118
  /// \warning This algorithm does not support negative costs for such
119
  /// arcs that have infinite upper bound.
120
  ///
121
  /// \note %CostScaling provides three different internal methods,
122
  /// from which the most efficient one is used by default.
123
  /// For more information, see \ref Method.
124
#ifdef DOXYGEN
125
  template <typename GR, typename V, typename C, typename TR>
126
#else
127
  template < typename GR, typename V = int, typename C = V,
128
             typename TR = CostScalingDefaultTraits<GR, V, C> >
129
#endif
130
  class CostScaling
131
  {
132
  public:
133

	
134
    /// The type of the digraph
135
    typedef typename TR::Digraph Digraph;
136
    /// The type of the flow amounts, capacity bounds and supply values
137
    typedef typename TR::Value Value;
138
    /// The type of the arc costs
139
    typedef typename TR::Cost Cost;
140

	
141
    /// \brief The large cost type
142
    ///
143
    /// The large cost type used for internal computations.
144
    /// By default, it is \c long \c long if the \c Cost type is integer,
145
    /// otherwise it is \c double.
146
    typedef typename TR::LargeCost LargeCost;
147

	
148
    /// The \ref CostScalingDefaultTraits "traits class" of the algorithm
149
    typedef TR Traits;
150

	
151
  public:
152

	
153
    /// \brief Problem type constants for the \c run() function.
154
    ///
155
    /// Enum type containing the problem type constants that can be
156
    /// returned by the \ref run() function of the algorithm.
157
    enum ProblemType {
158
      /// The problem has no feasible solution (flow).
159
      INFEASIBLE,
160
      /// The problem has optimal solution (i.e. it is feasible and
161
      /// bounded), and the algorithm has found optimal flow and node
162
      /// potentials (primal and dual solutions).
163
      OPTIMAL,
164
      /// The digraph contains an arc of negative cost and infinite
165
      /// upper bound. It means that the objective function is unbounded
166
      /// on that arc, however, note that it could actually be bounded
167
      /// over the feasible flows, but this algroithm cannot handle
168
      /// these cases.
169
      UNBOUNDED
170
    };
171

	
172
    /// \brief Constants for selecting the internal method.
173
    ///
174
    /// Enum type containing constants for selecting the internal method
175
    /// for the \ref run() function.
176
    ///
177
    /// \ref CostScaling provides three internal methods that differ mainly
178
    /// in their base operations, which are used in conjunction with the
179
    /// relabel operation.
180
    /// By default, the so called \ref PARTIAL_AUGMENT
181
    /// "Partial Augment-Relabel" method is used, which proved to be
182
    /// the most efficient and the most robust on various test inputs.
183
    /// However, the other methods can be selected using the \ref run()
184
    /// function with the proper parameter.
185
    enum Method {
186
      /// Local push operations are used, i.e. flow is moved only on one
187
      /// admissible arc at once.
188
      PUSH,
189
      /// Augment operations are used, i.e. flow is moved on admissible
190
      /// paths from a node with excess to a node with deficit.
191
      AUGMENT,
192
      /// Partial augment operations are used, i.e. flow is moved on
193
      /// admissible paths started from a node with excess, but the
194
      /// lengths of these paths are limited. This method can be viewed
195
      /// as a combined version of the previous two operations.
196
      PARTIAL_AUGMENT
197
    };
198

	
199
  private:
200

	
201
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
202

	
203
    typedef std::vector<int> IntVector;
204
    typedef std::vector<Value> ValueVector;
205
    typedef std::vector<Cost> CostVector;
206
    typedef std::vector<LargeCost> LargeCostVector;
207
    typedef std::vector<char> BoolVector;
208
    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
209

	
210
  private:
211

	
212
    template <typename KT, typename VT>
213
    class StaticVectorMap {
214
    public:
215
      typedef KT Key;
216
      typedef VT Value;
217

	
218
      StaticVectorMap(std::vector<Value>& v) : _v(v) {}
219

	
220
      const Value& operator[](const Key& key) const {
221
        return _v[StaticDigraph::id(key)];
222
      }
223

	
224
      Value& operator[](const Key& key) {
225
        return _v[StaticDigraph::id(key)];
226
      }
227

	
228
      void set(const Key& key, const Value& val) {
229
        _v[StaticDigraph::id(key)] = val;
230
      }
231

	
232
    private:
233
      std::vector<Value>& _v;
234
    };
235

	
236
    typedef StaticVectorMap<StaticDigraph::Node, LargeCost> LargeCostNodeMap;
237
    typedef StaticVectorMap<StaticDigraph::Arc, LargeCost> LargeCostArcMap;
238

	
239
  private:
240

	
241
    // Data related to the underlying digraph
242
    const GR &_graph;
243
    int _node_num;
244
    int _arc_num;
245
    int _res_node_num;
246
    int _res_arc_num;
247
    int _root;
248

	
249
    // Parameters of the problem
250
    bool _have_lower;
251
    Value _sum_supply;
252
    int _sup_node_num;
253

	
254
    // Data structures for storing the digraph
255
    IntNodeMap _node_id;
256
    IntArcMap _arc_idf;
257
    IntArcMap _arc_idb;
258
    IntVector _first_out;
259
    BoolVector _forward;
260
    IntVector _source;
261
    IntVector _target;
262
    IntVector _reverse;
263

	
264
    // Node and arc data
265
    ValueVector _lower;
266
    ValueVector _upper;
267
    CostVector _scost;
268
    ValueVector _supply;
269

	
270
    ValueVector _res_cap;
271
    LargeCostVector _cost;
272
    LargeCostVector _pi;
273
    ValueVector _excess;
274
    IntVector _next_out;
275
    std::deque<int> _active_nodes;
276

	
277
    // Data for scaling
278
    LargeCost _epsilon;
279
    int _alpha;
280

	
281
    IntVector _buckets;
282
    IntVector _bucket_next;
283
    IntVector _bucket_prev;
284
    IntVector _rank;
285
    int _max_rank;
286

	
287
    // Data for a StaticDigraph structure
288
    typedef std::pair<int, int> IntPair;
289
    StaticDigraph _sgr;
290
    std::vector<IntPair> _arc_vec;
291
    std::vector<LargeCost> _cost_vec;
292
    LargeCostArcMap _cost_map;
293
    LargeCostNodeMap _pi_map;
294

	
295
  public:
296

	
297
    /// \brief Constant for infinite upper bounds (capacities).
298
    ///
299
    /// Constant for infinite upper bounds (capacities).
300
    /// It is \c std::numeric_limits<Value>::infinity() if available,
301
    /// \c std::numeric_limits<Value>::max() otherwise.
302
    const Value INF;
303

	
304
  public:
305

	
306
    /// \name Named Template Parameters
307
    /// @{
308

	
309
    template <typename T>
310
    struct SetLargeCostTraits : public Traits {
311
      typedef T LargeCost;
312
    };
313

	
314
    /// \brief \ref named-templ-param "Named parameter" for setting
315
    /// \c LargeCost type.
316
    ///
317
    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
318
    /// type, which is used for internal computations in the algorithm.
319
    /// \c Cost must be convertible to \c LargeCost.
320
    template <typename T>
321
    struct SetLargeCost
322
      : public CostScaling<GR, V, C, SetLargeCostTraits<T> > {
323
      typedef  CostScaling<GR, V, C, SetLargeCostTraits<T> > Create;
324
    };
325

	
326
    /// @}
327

	
328
  protected:
329

	
330
    CostScaling() {}
331

	
332
  public:
333

	
334
    /// \brief Constructor.
335
    ///
336
    /// The constructor of the class.
337
    ///
338
    /// \param graph The digraph the algorithm runs on.
339
    CostScaling(const GR& graph) :
340
      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
341
      _cost_map(_cost_vec), _pi_map(_pi),
342
      INF(std::numeric_limits<Value>::has_infinity ?
343
          std::numeric_limits<Value>::infinity() :
344
          std::numeric_limits<Value>::max())
345
    {
346
      // Check the number types
347
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
348
        "The flow type of CostScaling must be signed");
349
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
350
        "The cost type of CostScaling must be signed");
351

	
352
      // Reset data structures
353
      reset();
354
    }
355

	
356
    /// \name Parameters
357
    /// The parameters of the algorithm can be specified using these
358
    /// functions.
359

	
360
    /// @{
361

	
362
    /// \brief Set the lower bounds on the arcs.
363
    ///
364
    /// This function sets the lower bounds on the arcs.
365
    /// If it is not used before calling \ref run(), the lower bounds
366
    /// will be set to zero on all arcs.
367
    ///
368
    /// \param map An arc map storing the lower bounds.
369
    /// Its \c Value type must be convertible to the \c Value type
370
    /// of the algorithm.
371
    ///
372
    /// \return <tt>(*this)</tt>
373
    template <typename LowerMap>
374
    CostScaling& lowerMap(const LowerMap& map) {
375
      _have_lower = true;
376
      for (ArcIt a(_graph); a != INVALID; ++a) {
377
        _lower[_arc_idf[a]] = map[a];
378
        _lower[_arc_idb[a]] = map[a];
379
      }
380
      return *this;
381
    }
382

	
383
    /// \brief Set the upper bounds (capacities) on the arcs.
384
    ///
385
    /// This function sets the upper bounds (capacities) on the arcs.
386
    /// If it is not used before calling \ref run(), the upper bounds
387
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
388
    /// unbounded from above).
389
    ///
390
    /// \param map An arc map storing the upper bounds.
391
    /// Its \c Value type must be convertible to the \c Value type
392
    /// of the algorithm.
393
    ///
394
    /// \return <tt>(*this)</tt>
395
    template<typename UpperMap>
396
    CostScaling& upperMap(const UpperMap& map) {
397
      for (ArcIt a(_graph); a != INVALID; ++a) {
398
        _upper[_arc_idf[a]] = map[a];
399
      }
400
      return *this;
401
    }
402

	
403
    /// \brief Set the costs of the arcs.
404
    ///
405
    /// This function sets the costs of the arcs.
406
    /// If it is not used before calling \ref run(), the costs
407
    /// will be set to \c 1 on all arcs.
408
    ///
409
    /// \param map An arc map storing the costs.
410
    /// Its \c Value type must be convertible to the \c Cost type
411
    /// of the algorithm.
412
    ///
413
    /// \return <tt>(*this)</tt>
414
    template<typename CostMap>
415
    CostScaling& costMap(const CostMap& map) {
416
      for (ArcIt a(_graph); a != INVALID; ++a) {
417
        _scost[_arc_idf[a]] =  map[a];
418
        _scost[_arc_idb[a]] = -map[a];
419
      }
420
      return *this;
421
    }
422

	
423
    /// \brief Set the supply values of the nodes.
424
    ///
425
    /// This function sets the supply values of the nodes.
426
    /// If neither this function nor \ref stSupply() is used before
427
    /// calling \ref run(), the supply of each node will be set to zero.
428
    ///
429
    /// \param map A node map storing the supply values.
430
    /// Its \c Value type must be convertible to the \c Value type
431
    /// of the algorithm.
432
    ///
433
    /// \return <tt>(*this)</tt>
434
    template<typename SupplyMap>
435
    CostScaling& supplyMap(const SupplyMap& map) {
436
      for (NodeIt n(_graph); n != INVALID; ++n) {
437
        _supply[_node_id[n]] = map[n];
438
      }
439
      return *this;
440
    }
441

	
442
    /// \brief Set single source and target nodes and a supply value.
443
    ///
444
    /// This function sets a single source node and a single target node
445
    /// and the required flow value.
446
    /// If neither this function nor \ref supplyMap() is used before
447
    /// calling \ref run(), the supply of each node will be set to zero.
448
    ///
449
    /// Using this function has the same effect as using \ref supplyMap()
450
    /// with such a map in which \c k is assigned to \c s, \c -k is
451
    /// assigned to \c t and all other nodes have zero supply value.
452
    ///
453
    /// \param s The source node.
454
    /// \param t The target node.
455
    /// \param k The required amount of flow from node \c s to node \c t
456
    /// (i.e. the supply of \c s and the demand of \c t).
457
    ///
458
    /// \return <tt>(*this)</tt>
459
    CostScaling& stSupply(const Node& s, const Node& t, Value k) {
460
      for (int i = 0; i != _res_node_num; ++i) {
461
        _supply[i] = 0;
462
      }
463
      _supply[_node_id[s]] =  k;
464
      _supply[_node_id[t]] = -k;
465
      return *this;
466
    }
467

	
468
    /// @}
469

	
470
    /// \name Execution control
471
    /// The algorithm can be executed using \ref run().
472

	
473
    /// @{
474

	
475
    /// \brief Run the algorithm.
476
    ///
477
    /// This function runs the algorithm.
478
    /// The paramters can be specified using functions \ref lowerMap(),
479
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
480
    /// For example,
481
    /// \code
482
    ///   CostScaling<ListDigraph> cs(graph);
483
    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
484
    ///     .supplyMap(sup).run();
485
    /// \endcode
486
    ///
487
    /// This function can be called more than once. All the given parameters
488
    /// are kept for the next call, unless \ref resetParams() or \ref reset()
489
    /// is used, thus only the modified parameters have to be set again.
490
    /// If the underlying digraph was also modified after the construction
491
    /// of the class (or the last \ref reset() call), then the \ref reset()
492
    /// function must be called.
493
    ///
494
    /// \param method The internal method that will be used in the
495
    /// algorithm. For more information, see \ref Method.
496
    /// \param factor The cost scaling factor. It must be larger than one.
497
    ///
498
    /// \return \c INFEASIBLE if no feasible flow exists,
499
    /// \n \c OPTIMAL if the problem has optimal solution
500
    /// (i.e. it is feasible and bounded), and the algorithm has found
501
    /// optimal flow and node potentials (primal and dual solutions),
502
    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
503
    /// and infinite upper bound. It means that the objective function
504
    /// is unbounded on that arc, however, note that it could actually be
505
    /// bounded over the feasible flows, but this algroithm cannot handle
506
    /// these cases.
507
    ///
508
    /// \see ProblemType, Method
509
    /// \see resetParams(), reset()
510
    ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) {
511
      _alpha = factor;
512
      ProblemType pt = init();
513
      if (pt != OPTIMAL) return pt;
514
      start(method);
515
      return OPTIMAL;
516
    }
517

	
518
    /// \brief Reset all the parameters that have been given before.
519
    ///
520
    /// This function resets all the paramaters that have been given
521
    /// before using functions \ref lowerMap(), \ref upperMap(),
522
    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
523
    ///
524
    /// It is useful for multiple \ref run() calls. Basically, all the given
525
    /// parameters are kept for the next \ref run() call, unless
526
    /// \ref resetParams() or \ref reset() is used.
527
    /// If the underlying digraph was also modified after the construction
528
    /// of the class or the last \ref reset() call, then the \ref reset()
529
    /// function must be used, otherwise \ref resetParams() is sufficient.
530
    ///
531
    /// For example,
532
    /// \code
533
    ///   CostScaling<ListDigraph> cs(graph);
534
    ///
535
    ///   // First run
536
    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
537
    ///     .supplyMap(sup).run();
538
    ///
539
    ///   // Run again with modified cost map (resetParams() is not called,
540
    ///   // so only the cost map have to be set again)
541
    ///   cost[e] += 100;
542
    ///   cs.costMap(cost).run();
543
    ///
544
    ///   // Run again from scratch using resetParams()
545
    ///   // (the lower bounds will be set to zero on all arcs)
546
    ///   cs.resetParams();
547
    ///   cs.upperMap(capacity).costMap(cost)
548
    ///     .supplyMap(sup).run();
549
    /// \endcode
550
    ///
551
    /// \return <tt>(*this)</tt>
552
    ///
553
    /// \see reset(), run()
554
    CostScaling& resetParams() {
555
      for (int i = 0; i != _res_node_num; ++i) {
556
        _supply[i] = 0;
557
      }
558
      int limit = _first_out[_root];
559
      for (int j = 0; j != limit; ++j) {
560
        _lower[j] = 0;
561
        _upper[j] = INF;
562
        _scost[j] = _forward[j] ? 1 : -1;
563
      }
564
      for (int j = limit; j != _res_arc_num; ++j) {
565
        _lower[j] = 0;
566
        _upper[j] = INF;
567
        _scost[j] = 0;
568
        _scost[_reverse[j]] = 0;
569
      }
570
      _have_lower = false;
571
      return *this;
572
    }
573

	
574
    /// \brief Reset all the parameters that have been given before.
575
    ///
576
    /// This function resets all the paramaters that have been given
577
    /// before using functions \ref lowerMap(), \ref upperMap(),
578
    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
579
    ///
580
    /// It is useful for multiple run() calls. If this function is not
581
    /// used, all the parameters given before are kept for the next
582
    /// \ref run() call.
583
    /// However, the underlying digraph must not be modified after this
584
    /// class have been constructed, since it copies and extends the graph.
585
    /// \return <tt>(*this)</tt>
586
    CostScaling& reset() {
587
      // Resize vectors
588
      _node_num = countNodes(_graph);
589
      _arc_num = countArcs(_graph);
590
      _res_node_num = _node_num + 1;
591
      _res_arc_num = 2 * (_arc_num + _node_num);
592
      _root = _node_num;
593

	
594
      _first_out.resize(_res_node_num + 1);
595
      _forward.resize(_res_arc_num);
596
      _source.resize(_res_arc_num);
597
      _target.resize(_res_arc_num);
598
      _reverse.resize(_res_arc_num);
599

	
600
      _lower.resize(_res_arc_num);
601
      _upper.resize(_res_arc_num);
602
      _scost.resize(_res_arc_num);
603
      _supply.resize(_res_node_num);
604

	
605
      _res_cap.resize(_res_arc_num);
606
      _cost.resize(_res_arc_num);
607
      _pi.resize(_res_node_num);
608
      _excess.resize(_res_node_num);
609
      _next_out.resize(_res_node_num);
610

	
611
      _arc_vec.reserve(_res_arc_num);
612
      _cost_vec.reserve(_res_arc_num);
613

	
614
      // Copy the graph
615
      int i = 0, j = 0, k = 2 * _arc_num + _node_num;
616
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
617
        _node_id[n] = i;
618
      }
619
      i = 0;
620
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
621
        _first_out[i] = j;
622
        for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
623
          _arc_idf[a] = j;
624
          _forward[j] = true;
625
          _source[j] = i;
626
          _target[j] = _node_id[_graph.runningNode(a)];
627
        }
628
        for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
629
          _arc_idb[a] = j;
630
          _forward[j] = false;
631
          _source[j] = i;
632
          _target[j] = _node_id[_graph.runningNode(a)];
633
        }
634
        _forward[j] = false;
635
        _source[j] = i;
636
        _target[j] = _root;
637
        _reverse[j] = k;
638
        _forward[k] = true;
639
        _source[k] = _root;
640
        _target[k] = i;
641
        _reverse[k] = j;
642
        ++j; ++k;
643
      }
644
      _first_out[i] = j;
645
      _first_out[_res_node_num] = k;
646
      for (ArcIt a(_graph); a != INVALID; ++a) {
647
        int fi = _arc_idf[a];
648
        int bi = _arc_idb[a];
649
        _reverse[fi] = bi;
650
        _reverse[bi] = fi;
651
      }
652

	
653
      // Reset parameters
654
      resetParams();
655
      return *this;
656
    }
657

	
658
    /// @}
659

	
660
    /// \name Query Functions
661
    /// The results of the algorithm can be obtained using these
662
    /// functions.\n
663
    /// The \ref run() function must be called before using them.
664

	
665
    /// @{
666

	
667
    /// \brief Return the total cost of the found flow.
668
    ///
669
    /// This function returns the total cost of the found flow.
670
    /// Its complexity is O(e).
671
    ///
672
    /// \note The return type of the function can be specified as a
673
    /// template parameter. For example,
674
    /// \code
675
    ///   cs.totalCost<double>();
676
    /// \endcode
677
    /// It is useful if the total cost cannot be stored in the \c Cost
678
    /// type of the algorithm, which is the default return type of the
679
    /// function.
680
    ///
681
    /// \pre \ref run() must be called before using this function.
682
    template <typename Number>
683
    Number totalCost() const {
684
      Number c = 0;
685
      for (ArcIt a(_graph); a != INVALID; ++a) {
686
        int i = _arc_idb[a];
687
        c += static_cast<Number>(_res_cap[i]) *
688
             (-static_cast<Number>(_scost[i]));
689
      }
690
      return c;
691
    }
692

	
693
#ifndef DOXYGEN
694
    Cost totalCost() const {
695
      return totalCost<Cost>();
696
    }
697
#endif
698

	
699
    /// \brief Return the flow on the given arc.
700
    ///
701
    /// This function returns the flow on the given arc.
702
    ///
703
    /// \pre \ref run() must be called before using this function.
704
    Value flow(const Arc& a) const {
705
      return _res_cap[_arc_idb[a]];
706
    }
707

	
708
    /// \brief Return the flow map (the primal solution).
709
    ///
710
    /// This function copies the flow value on each arc into the given
711
    /// map. The \c Value type of the algorithm must be convertible to
712
    /// the \c Value type of the map.
713
    ///
714
    /// \pre \ref run() must be called before using this function.
715
    template <typename FlowMap>
716
    void flowMap(FlowMap &map) const {
717
      for (ArcIt a(_graph); a != INVALID; ++a) {
718
        map.set(a, _res_cap[_arc_idb[a]]);
719
      }
720
    }
721

	
722
    /// \brief Return the potential (dual value) of the given node.
723
    ///
724
    /// This function returns the potential (dual value) of the
725
    /// given node.
726
    ///
727
    /// \pre \ref run() must be called before using this function.
728
    Cost potential(const Node& n) const {
729
      return static_cast<Cost>(_pi[_node_id[n]]);
730
    }
731

	
732
    /// \brief Return the potential map (the dual solution).
733
    ///
734
    /// This function copies the potential (dual value) of each node
735
    /// into the given map.
736
    /// The \c Cost type of the algorithm must be convertible to the
737
    /// \c Value type of the map.
738
    ///
739
    /// \pre \ref run() must be called before using this function.
740
    template <typename PotentialMap>
741
    void potentialMap(PotentialMap &map) const {
742
      for (NodeIt n(_graph); n != INVALID; ++n) {
743
        map.set(n, static_cast<Cost>(_pi[_node_id[n]]));
744
      }
745
    }
746

	
747
    /// @}
748

	
749
  private:
750

	
751
    // Initialize the algorithm
752
    ProblemType init() {
753
      if (_res_node_num <= 1) return INFEASIBLE;
754

	
755
      // Check the sum of supply values
756
      _sum_supply = 0;
757
      for (int i = 0; i != _root; ++i) {
758
        _sum_supply += _supply[i];
759
      }
760
      if (_sum_supply > 0) return INFEASIBLE;
761

	
762

	
763
      // Initialize vectors
764
      for (int i = 0; i != _res_node_num; ++i) {
765
        _pi[i] = 0;
766
        _excess[i] = _supply[i];
767
      }
768

	
769
      // Remove infinite upper bounds and check negative arcs
770
      const Value MAX = std::numeric_limits<Value>::max();
771
      int last_out;
772
      if (_have_lower) {
773
        for (int i = 0; i != _root; ++i) {
774
          last_out = _first_out[i+1];
775
          for (int j = _first_out[i]; j != last_out; ++j) {
776
            if (_forward[j]) {
777
              Value c = _scost[j] < 0 ? _upper[j] : _lower[j];
778
              if (c >= MAX) return UNBOUNDED;
779
              _excess[i] -= c;
780
              _excess[_target[j]] += c;
781
            }
782
          }
783
        }
784
      } else {
785
        for (int i = 0; i != _root; ++i) {
786
          last_out = _first_out[i+1];
787
          for (int j = _first_out[i]; j != last_out; ++j) {
788
            if (_forward[j] && _scost[j] < 0) {
789
              Value c = _upper[j];
790
              if (c >= MAX) return UNBOUNDED;
791
              _excess[i] -= c;
792
              _excess[_target[j]] += c;
793
            }
794
          }
795
        }
796
      }
797
      Value ex, max_cap = 0;
798
      for (int i = 0; i != _res_node_num; ++i) {
799
        ex = _excess[i];
800
        _excess[i] = 0;
801
        if (ex < 0) max_cap -= ex;
802
      }
803
      for (int j = 0; j != _res_arc_num; ++j) {
804
        if (_upper[j] >= MAX) _upper[j] = max_cap;
805
      }
806

	
807
      // Initialize the large cost vector and the epsilon parameter
808
      _epsilon = 0;
809
      LargeCost lc;
810
      for (int i = 0; i != _root; ++i) {
811
        last_out = _first_out[i+1];
812
        for (int j = _first_out[i]; j != last_out; ++j) {
813
          lc = static_cast<LargeCost>(_scost[j]) * _res_node_num * _alpha;
814
          _cost[j] = lc;
815
          if (lc > _epsilon) _epsilon = lc;
816
        }
817
      }
818
      _epsilon /= _alpha;
819

	
820
      // Initialize maps for Circulation and remove non-zero lower bounds
821
      ConstMap<Arc, Value> low(0);
822
      typedef typename Digraph::template ArcMap<Value> ValueArcMap;
823
      typedef typename Digraph::template NodeMap<Value> ValueNodeMap;
824
      ValueArcMap cap(_graph), flow(_graph);
825
      ValueNodeMap sup(_graph);
826
      for (NodeIt n(_graph); n != INVALID; ++n) {
827
        sup[n] = _supply[_node_id[n]];
828
      }
829
      if (_have_lower) {
830
        for (ArcIt a(_graph); a != INVALID; ++a) {
831
          int j = _arc_idf[a];
832
          Value c = _lower[j];
833
          cap[a] = _upper[j] - c;
834
          sup[_graph.source(a)] -= c;
835
          sup[_graph.target(a)] += c;
836
        }
837
      } else {
838
        for (ArcIt a(_graph); a != INVALID; ++a) {
839
          cap[a] = _upper[_arc_idf[a]];
840
        }
841
      }
842

	
843
      _sup_node_num = 0;
844
      for (NodeIt n(_graph); n != INVALID; ++n) {
845
        if (sup[n] > 0) ++_sup_node_num;
846
      }
847

	
848
      // Find a feasible flow using Circulation
849
      Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap>
850
        circ(_graph, low, cap, sup);
851
      if (!circ.flowMap(flow).run()) return INFEASIBLE;
852

	
853
      // Set residual capacities and handle GEQ supply type
854
      if (_sum_supply < 0) {
855
        for (ArcIt a(_graph); a != INVALID; ++a) {
856
          Value fa = flow[a];
857
          _res_cap[_arc_idf[a]] = cap[a] - fa;
858
          _res_cap[_arc_idb[a]] = fa;
859
          sup[_graph.source(a)] -= fa;
860
          sup[_graph.target(a)] += fa;
861
        }
862
        for (NodeIt n(_graph); n != INVALID; ++n) {
863
          _excess[_node_id[n]] = sup[n];
864
        }
865
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
866
          int u = _target[a];
867
          int ra = _reverse[a];
868
          _res_cap[a] = -_sum_supply + 1;
869
          _res_cap[ra] = -_excess[u];
870
          _cost[a] = 0;
871
          _cost[ra] = 0;
872
          _excess[u] = 0;
873
        }
874
      } else {
875
        for (ArcIt a(_graph); a != INVALID; ++a) {
876
          Value fa = flow[a];
877
          _res_cap[_arc_idf[a]] = cap[a] - fa;
878
          _res_cap[_arc_idb[a]] = fa;
879
        }
880
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
881
          int ra = _reverse[a];
882
          _res_cap[a] = 0;
883
          _res_cap[ra] = 0;
884
          _cost[a] = 0;
885
          _cost[ra] = 0;
886
        }
887
      }
888

	
889
      return OPTIMAL;
890
    }
891

	
892
    // Execute the algorithm and transform the results
893
    void start(Method method) {
894
      // Maximum path length for partial augment
895
      const int MAX_PATH_LENGTH = 4;
896

	
897
      // Initialize data structures for buckets
898
      _max_rank = _alpha * _res_node_num;
899
      _buckets.resize(_max_rank);
900
      _bucket_next.resize(_res_node_num + 1);
901
      _bucket_prev.resize(_res_node_num + 1);
902
      _rank.resize(_res_node_num + 1);
903

	
904
      // Execute the algorithm
905
      switch (method) {
906
        case PUSH:
907
          startPush();
908
          break;
909
        case AUGMENT:
910
          startAugment(_res_node_num - 1);
911
          break;
912
        case PARTIAL_AUGMENT:
913
          startAugment(MAX_PATH_LENGTH);
914
          break;
915
      }
916

	
917
      // Compute node potentials for the original costs
918
      _arc_vec.clear();
919
      _cost_vec.clear();
920
      for (int j = 0; j != _res_arc_num; ++j) {
921
        if (_res_cap[j] > 0) {
922
          _arc_vec.push_back(IntPair(_source[j], _target[j]));
923
          _cost_vec.push_back(_scost[j]);
924
        }
925
      }
926
      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
927

	
928
      typename BellmanFord<StaticDigraph, LargeCostArcMap>
929
        ::template SetDistMap<LargeCostNodeMap>::Create bf(_sgr, _cost_map);
930
      bf.distMap(_pi_map);
931
      bf.init(0);
932
      bf.start();
933

	
934
      // Handle non-zero lower bounds
935
      if (_have_lower) {
936
        int limit = _first_out[_root];
937
        for (int j = 0; j != limit; ++j) {
938
          if (!_forward[j]) _res_cap[j] += _lower[j];
939
        }
940
      }
941
    }
942

	
943
    // Initialize a cost scaling phase
944
    void initPhase() {
945
      // Saturate arcs not satisfying the optimality condition
946
      for (int u = 0; u != _res_node_num; ++u) {
947
        int last_out = _first_out[u+1];
948
        LargeCost pi_u = _pi[u];
949
        for (int a = _first_out[u]; a != last_out; ++a) {
950
          int v = _target[a];
951
          if (_res_cap[a] > 0 && _cost[a] + pi_u - _pi[v] < 0) {
952
            Value delta = _res_cap[a];
953
            _excess[u] -= delta;
954
            _excess[v] += delta;
955
            _res_cap[a] = 0;
956
            _res_cap[_reverse[a]] += delta;
957
          }
958
        }
959
      }
960

	
961
      // Find active nodes (i.e. nodes with positive excess)
962
      for (int u = 0; u != _res_node_num; ++u) {
963
        if (_excess[u] > 0) _active_nodes.push_back(u);
964
      }
965

	
966
      // Initialize the next arcs
967
      for (int u = 0; u != _res_node_num; ++u) {
968
        _next_out[u] = _first_out[u];
969
      }
970
    }
971

	
972
    // Early termination heuristic
973
    bool earlyTermination() {
974
      const double EARLY_TERM_FACTOR = 3.0;
975

	
976
      // Build a static residual graph
977
      _arc_vec.clear();
978
      _cost_vec.clear();
979
      for (int j = 0; j != _res_arc_num; ++j) {
980
        if (_res_cap[j] > 0) {
981
          _arc_vec.push_back(IntPair(_source[j], _target[j]));
982
          _cost_vec.push_back(_cost[j] + 1);
983
        }
984
      }
985
      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
986

	
987
      // Run Bellman-Ford algorithm to check if the current flow is optimal
988
      BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
989
      bf.init(0);
990
      bool done = false;
991
      int K = int(EARLY_TERM_FACTOR * std::sqrt(double(_res_node_num)));
992
      for (int i = 0; i < K && !done; ++i) {
993
        done = bf.processNextWeakRound();
994
      }
995
      return done;
996
    }
997

	
998
    // Global potential update heuristic
999
    void globalUpdate() {
1000
      int bucket_end = _root + 1;
1001

	
1002
      // Initialize buckets
1003
      for (int r = 0; r != _max_rank; ++r) {
1004
        _buckets[r] = bucket_end;
1005
      }
1006
      Value total_excess = 0;
1007
      for (int i = 0; i != _res_node_num; ++i) {
1008
        if (_excess[i] < 0) {
1009
          _rank[i] = 0;
1010
          _bucket_next[i] = _buckets[0];
1011
          _bucket_prev[_buckets[0]] = i;
1012
          _buckets[0] = i;
1013
        } else {
1014
          total_excess += _excess[i];
1015
          _rank[i] = _max_rank;
1016
        }
1017
      }
1018
      if (total_excess == 0) return;
1019

	
1020
      // Search the buckets
1021
      int r = 0;
1022
      for ( ; r != _max_rank; ++r) {
1023
        while (_buckets[r] != bucket_end) {
1024
          // Remove the first node from the current bucket
1025
          int u = _buckets[r];
1026
          _buckets[r] = _bucket_next[u];
1027

	
1028
          // Search the incomming arcs of u
1029
          LargeCost pi_u = _pi[u];
1030
          int last_out = _first_out[u+1];
1031
          for (int a = _first_out[u]; a != last_out; ++a) {
1032
            int ra = _reverse[a];
1033
            if (_res_cap[ra] > 0) {
1034
              int v = _source[ra];
1035
              int old_rank_v = _rank[v];
1036
              if (r < old_rank_v) {
1037
                // Compute the new rank of v
1038
                LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon;
1039
                int new_rank_v = old_rank_v;
1040
                if (nrc < LargeCost(_max_rank))
1041
                  new_rank_v = r + 1 + int(nrc);
1042

	
1043
                // Change the rank of v
1044
                if (new_rank_v < old_rank_v) {
1045
                  _rank[v] = new_rank_v;
1046
                  _next_out[v] = _first_out[v];
1047

	
1048
                  // Remove v from its old bucket
1049
                  if (old_rank_v < _max_rank) {
1050
                    if (_buckets[old_rank_v] == v) {
1051
                      _buckets[old_rank_v] = _bucket_next[v];
1052
                    } else {
1053
                      _bucket_next[_bucket_prev[v]] = _bucket_next[v];
1054
                      _bucket_prev[_bucket_next[v]] = _bucket_prev[v];
1055
                    }
1056
                  }
1057

	
1058
                  // Insert v to its new bucket
1059
                  _bucket_next[v] = _buckets[new_rank_v];
1060
                  _bucket_prev[_buckets[new_rank_v]] = v;
1061
                  _buckets[new_rank_v] = v;
1062
                }
1063
              }
1064
            }
1065
          }
1066

	
1067
          // Finish search if there are no more active nodes
1068
          if (_excess[u] > 0) {
1069
            total_excess -= _excess[u];
1070
            if (total_excess <= 0) break;
1071
          }
1072
        }
1073
        if (total_excess <= 0) break;
1074
      }
1075

	
1076
      // Relabel nodes
1077
      for (int u = 0; u != _res_node_num; ++u) {
1078
        int k = std::min(_rank[u], r);
1079
        if (k > 0) {
1080
          _pi[u] -= _epsilon * k;
1081
          _next_out[u] = _first_out[u];
1082
        }
1083
      }
1084
    }
1085

	
1086
    /// Execute the algorithm performing augment and relabel operations
1087
    void startAugment(int max_length) {
1088
      // Paramters for heuristics
1089
      const int EARLY_TERM_EPSILON_LIMIT = 1000;
1090
      const double GLOBAL_UPDATE_FACTOR = 3.0;
1091

	
1092
      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
1093
        (_res_node_num + _sup_node_num * _sup_node_num));
1094
      int next_update_limit = global_update_freq;
1095

	
1096
      int relabel_cnt = 0;
1097

	
1098
      // Perform cost scaling phases
1099
      std::vector<int> path;
1100
      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
1101
                                        1 : _epsilon / _alpha )
1102
      {
1103
        // Early termination heuristic
1104
        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
1105
          if (earlyTermination()) break;
1106
        }
1107

	
1108
        // Initialize current phase
1109
        initPhase();
1110

	
1111
        // Perform partial augment and relabel operations
1112
        while (true) {
1113
          // Select an active node (FIFO selection)
1114
          while (_active_nodes.size() > 0 &&
1115
                 _excess[_active_nodes.front()] <= 0) {
1116
            _active_nodes.pop_front();
1117
          }
1118
          if (_active_nodes.size() == 0) break;
1119
          int start = _active_nodes.front();
1120

	
1121
          // Find an augmenting path from the start node
1122
          path.clear();
1123
          int tip = start;
1124
          while (_excess[tip] >= 0 && int(path.size()) < max_length) {
1125
            int u;
1126
            LargeCost min_red_cost, rc, pi_tip = _pi[tip];
1127
            int last_out = _first_out[tip+1];
1128
            for (int a = _next_out[tip]; a != last_out; ++a) {
1129
              u = _target[a];
1130
              if (_res_cap[a] > 0 && _cost[a] + pi_tip - _pi[u] < 0) {
1131
                path.push_back(a);
1132
                _next_out[tip] = a;
1133
                tip = u;
1134
                goto next_step;
1135
              }
1136
            }
1137

	
1138
            // Relabel tip node
1139
            min_red_cost = std::numeric_limits<LargeCost>::max();
1140
            if (tip != start) {
1141
              int ra = _reverse[path.back()];
1142
              min_red_cost = _cost[ra] + pi_tip - _pi[_target[ra]];
1143
            }
1144
            for (int a = _first_out[tip]; a != last_out; ++a) {
1145
              rc = _cost[a] + pi_tip - _pi[_target[a]];
1146
              if (_res_cap[a] > 0 && rc < min_red_cost) {
1147
                min_red_cost = rc;
1148
              }
1149
            }
1150
            _pi[tip] -= min_red_cost + _epsilon;
1151
            _next_out[tip] = _first_out[tip];
1152
            ++relabel_cnt;
1153

	
1154
            // Step back
1155
            if (tip != start) {
1156
              tip = _source[path.back()];
1157
              path.pop_back();
1158
            }
1159

	
1160
          next_step: ;
1161
          }
1162

	
1163
          // Augment along the found path (as much flow as possible)
1164
          Value delta;
1165
          int pa, u, v = start;
1166
          for (int i = 0; i != int(path.size()); ++i) {
1167
            pa = path[i];
1168
            u = v;
1169
            v = _target[pa];
1170
            delta = std::min(_res_cap[pa], _excess[u]);
1171
            _res_cap[pa] -= delta;
1172
            _res_cap[_reverse[pa]] += delta;
1173
            _excess[u] -= delta;
1174
            _excess[v] += delta;
1175
            if (_excess[v] > 0 && _excess[v] <= delta)
1176
              _active_nodes.push_back(v);
1177
          }
1178

	
1179
          // Global update heuristic
1180
          if (relabel_cnt >= next_update_limit) {
1181
            globalUpdate();
1182
            next_update_limit += global_update_freq;
1183
          }
1184
        }
1185
      }
1186
    }
1187

	
1188
    /// Execute the algorithm performing push and relabel operations
1189
    void startPush() {
1190
      // Paramters for heuristics
1191
      const int EARLY_TERM_EPSILON_LIMIT = 1000;
1192
      const double GLOBAL_UPDATE_FACTOR = 2.0;
1193

	
1194
      const int global_update_freq = int(GLOBAL_UPDATE_FACTOR *
1195
        (_res_node_num + _sup_node_num * _sup_node_num));
1196
      int next_update_limit = global_update_freq;
1197

	
1198
      int relabel_cnt = 0;
1199

	
1200
      // Perform cost scaling phases
1201
      BoolVector hyper(_res_node_num, false);
1202
      LargeCostVector hyper_cost(_res_node_num);
1203
      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
1204
                                        1 : _epsilon / _alpha )
1205
      {
1206
        // Early termination heuristic
1207
        if (_epsilon <= EARLY_TERM_EPSILON_LIMIT) {
1208
          if (earlyTermination()) break;
1209
        }
1210

	
1211
        // Initialize current phase
1212
        initPhase();
1213

	
1214
        // Perform push and relabel operations
1215
        while (_active_nodes.size() > 0) {
1216
          LargeCost min_red_cost, rc, pi_n;
1217
          Value delta;
1218
          int n, t, a, last_out = _res_arc_num;
1219

	
1220
        next_node:
1221
          // Select an active node (FIFO selection)
1222
          n = _active_nodes.front();
1223
          last_out = _first_out[n+1];
1224
          pi_n = _pi[n];
1225

	
1226
          // Perform push operations if there are admissible arcs
1227
          if (_excess[n] > 0) {
1228
            for (a = _next_out[n]; a != last_out; ++a) {
1229
              if (_res_cap[a] > 0 &&
1230
                  _cost[a] + pi_n - _pi[_target[a]] < 0) {
1231
                delta = std::min(_res_cap[a], _excess[n]);
1232
                t = _target[a];
1233

	
1234
                // Push-look-ahead heuristic
1235
                Value ahead = -_excess[t];
1236
                int last_out_t = _first_out[t+1];
1237
                LargeCost pi_t = _pi[t];
1238
                for (int ta = _next_out[t]; ta != last_out_t; ++ta) {
1239
                  if (_res_cap[ta] > 0 &&
1240
                      _cost[ta] + pi_t - _pi[_target[ta]] < 0)
1241
                    ahead += _res_cap[ta];
1242
                  if (ahead >= delta) break;
1243
                }
1244
                if (ahead < 0) ahead = 0;
1245

	
1246
                // Push flow along the arc
1247
                if (ahead < delta && !hyper[t]) {
1248
                  _res_cap[a] -= ahead;
1249
                  _res_cap[_reverse[a]] += ahead;
1250
                  _excess[n] -= ahead;
1251
                  _excess[t] += ahead;
1252
                  _active_nodes.push_front(t);
1253
                  hyper[t] = true;
1254
                  hyper_cost[t] = _cost[a] + pi_n - pi_t;
1255
                  _next_out[n] = a;
1256
                  goto next_node;
1257
                } else {
1258
                  _res_cap[a] -= delta;
1259
                  _res_cap[_reverse[a]] += delta;
1260
                  _excess[n] -= delta;
1261
                  _excess[t] += delta;
1262
                  if (_excess[t] > 0 && _excess[t] <= delta)
1263
                    _active_nodes.push_back(t);
1264
                }
1265

	
1266
                if (_excess[n] == 0) {
1267
                  _next_out[n] = a;
1268
                  goto remove_nodes;
1269
                }
1270
              }
1271
            }
1272
            _next_out[n] = a;
1273
          }
1274

	
1275
          // Relabel the node if it is still active (or hyper)
1276
          if (_excess[n] > 0 || hyper[n]) {
1277
             min_red_cost = hyper[n] ? -hyper_cost[n] :
1278
               std::numeric_limits<LargeCost>::max();
1279
            for (int a = _first_out[n]; a != last_out; ++a) {
1280
              rc = _cost[a] + pi_n - _pi[_target[a]];
1281
              if (_res_cap[a] > 0 && rc < min_red_cost) {
1282
                min_red_cost = rc;
1283
              }
1284
            }
1285
            _pi[n] -= min_red_cost + _epsilon;
1286
            _next_out[n] = _first_out[n];
1287
            hyper[n] = false;
1288
            ++relabel_cnt;
1289
          }
1290

	
1291
          // Remove nodes that are not active nor hyper
1292
        remove_nodes:
1293
          while ( _active_nodes.size() > 0 &&
1294
                  _excess[_active_nodes.front()] <= 0 &&
1295
                  !hyper[_active_nodes.front()] ) {
1296
            _active_nodes.pop_front();
1297
          }
1298

	
1299
          // Global update heuristic
1300
          if (relabel_cnt >= next_update_limit) {
1301
            globalUpdate();
1302
            for (int u = 0; u != _res_node_num; ++u)
1303
              hyper[u] = false;
1304
            next_update_limit += global_update_freq;
1305
          }
1306
        }
1307
      }
1308
    }
1309

	
1310
  }; //class CostScaling
1311

	
1312
  ///@}
1313

	
1314
} //namespace lemon
1315

	
1316
#endif //LEMON_COST_SCALING_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-2010
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_CYCLE_CANCELING_H
20
#define LEMON_CYCLE_CANCELING_H
21

	
22
/// \ingroup min_cost_flow_algs
23
/// \file
24
/// \brief Cycle-canceling algorithms for finding a minimum cost flow.
25

	
26
#include <vector>
27
#include <limits>
28

	
29
#include <lemon/core.h>
30
#include <lemon/maps.h>
31
#include <lemon/path.h>
32
#include <lemon/math.h>
33
#include <lemon/static_graph.h>
34
#include <lemon/adaptors.h>
35
#include <lemon/circulation.h>
36
#include <lemon/bellman_ford.h>
37
#include <lemon/howard_mmc.h>
38

	
39
namespace lemon {
40

	
41
  /// \addtogroup min_cost_flow_algs
42
  /// @{
43

	
44
  /// \brief Implementation of cycle-canceling algorithms for
45
  /// finding a \ref min_cost_flow "minimum cost flow".
46
  ///
47
  /// \ref CycleCanceling implements three different cycle-canceling
48
  /// algorithms for finding a \ref min_cost_flow "minimum cost flow"
49
  /// \ref amo93networkflows, \ref klein67primal,
50
  /// \ref goldberg89cyclecanceling.
51
  /// The most efficent one (both theoretically and practically)
52
  /// is the \ref CANCEL_AND_TIGHTEN "Cancel and Tighten" algorithm,
53
  /// thus it is the default method.
54
  /// It is strongly polynomial, but in practice, it is typically much
55
  /// slower than the scaling algorithms and NetworkSimplex.
56
  ///
57
  /// Most of the parameters of the problem (except for the digraph)
58
  /// can be given using separate functions, and the algorithm can be
59
  /// executed using the \ref run() function. If some parameters are not
60
  /// specified, then default values will be used.
61
  ///
62
  /// \tparam GR The digraph type the algorithm runs on.
63
  /// \tparam V The number type used for flow amounts, capacity bounds
64
  /// and supply values in the algorithm. By default, it is \c int.
65
  /// \tparam C The number type used for costs and potentials in the
66
  /// algorithm. By default, it is the same as \c V.
67
  ///
68
  /// \warning Both number types must be signed and all input data must
69
  /// be integer.
70
  /// \warning This algorithm does not support negative costs for such
71
  /// arcs that have infinite upper bound.
72
  ///
73
  /// \note For more information about the three available methods,
74
  /// see \ref Method.
75
#ifdef DOXYGEN
76
  template <typename GR, typename V, typename C>
77
#else
78
  template <typename GR, typename V = int, typename C = V>
79
#endif
80
  class CycleCanceling
81
  {
82
  public:
83

	
84
    /// The type of the digraph
85
    typedef GR Digraph;
86
    /// The type of the flow amounts, capacity bounds and supply values
87
    typedef V Value;
88
    /// The type of the arc costs
89
    typedef C Cost;
90

	
91
  public:
92

	
93
    /// \brief Problem type constants for the \c run() function.
94
    ///
95
    /// Enum type containing the problem type constants that can be
96
    /// returned by the \ref run() function of the algorithm.
97
    enum ProblemType {
98
      /// The problem has no feasible solution (flow).
99
      INFEASIBLE,
100
      /// The problem has optimal solution (i.e. it is feasible and
101
      /// bounded), and the algorithm has found optimal flow and node
102
      /// potentials (primal and dual solutions).
103
      OPTIMAL,
104
      /// The digraph contains an arc of negative cost and infinite
105
      /// upper bound. It means that the objective function is unbounded
106
      /// on that arc, however, note that it could actually be bounded
107
      /// over the feasible flows, but this algroithm cannot handle
108
      /// these cases.
109
      UNBOUNDED
110
    };
111

	
112
    /// \brief Constants for selecting the used method.
113
    ///
114
    /// Enum type containing constants for selecting the used method
115
    /// for the \ref run() function.
116
    ///
117
    /// \ref CycleCanceling provides three different cycle-canceling
118
    /// methods. By default, \ref CANCEL_AND_TIGHTEN "Cancel and Tighten"
119
    /// is used, which proved to be the most efficient and the most robust
120
    /// on various test inputs.
121
    /// However, the other methods can be selected using the \ref run()
122
    /// function with the proper parameter.
123
    enum Method {
124
      /// A simple cycle-canceling method, which uses the
125
      /// \ref BellmanFord "Bellman-Ford" algorithm with limited iteration
126
      /// number for detecting negative cycles in the residual network.
127
      SIMPLE_CYCLE_CANCELING,
128
      /// The "Minimum Mean Cycle-Canceling" algorithm, which is a
129
      /// well-known strongly polynomial method
130
      /// \ref goldberg89cyclecanceling. It improves along a
131
      /// \ref min_mean_cycle "minimum mean cycle" in each iteration.
132
      /// Its running time complexity is O(n<sup>2</sup>m<sup>3</sup>log(n)).
133
      MINIMUM_MEAN_CYCLE_CANCELING,
134
      /// The "Cancel And Tighten" algorithm, which can be viewed as an
135
      /// improved version of the previous method
136
      /// \ref goldberg89cyclecanceling.
137
      /// It is faster both in theory and in practice, its running time
138
      /// complexity is O(n<sup>2</sup>m<sup>2</sup>log(n)).
139
      CANCEL_AND_TIGHTEN
140
    };
141

	
142
  private:
143

	
144
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
145

	
146
    typedef std::vector<int> IntVector;
147
    typedef std::vector<double> DoubleVector;
148
    typedef std::vector<Value> ValueVector;
149
    typedef std::vector<Cost> CostVector;
150
    typedef std::vector<char> BoolVector;
151
    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
152

	
153
  private:
154

	
155
    template <typename KT, typename VT>
156
    class StaticVectorMap {
157
    public:
158
      typedef KT Key;
159
      typedef VT Value;
160

	
161
      StaticVectorMap(std::vector<Value>& v) : _v(v) {}
162

	
163
      const Value& operator[](const Key& key) const {
164
        return _v[StaticDigraph::id(key)];
165
      }
166

	
167
      Value& operator[](const Key& key) {
168
        return _v[StaticDigraph::id(key)];
169
      }
170

	
171
      void set(const Key& key, const Value& val) {
172
        _v[StaticDigraph::id(key)] = val;
173
      }
174

	
175
    private:
176
      std::vector<Value>& _v;
177
    };
178

	
179
    typedef StaticVectorMap<StaticDigraph::Node, Cost> CostNodeMap;
180
    typedef StaticVectorMap<StaticDigraph::Arc, Cost> CostArcMap;
181

	
182
  private:
183

	
184

	
185
    // Data related to the underlying digraph
186
    const GR &_graph;
187
    int _node_num;
188
    int _arc_num;
189
    int _res_node_num;
190
    int _res_arc_num;
191
    int _root;
192

	
193
    // Parameters of the problem
194
    bool _have_lower;
195
    Value _sum_supply;
196

	
197
    // Data structures for storing the digraph
198
    IntNodeMap _node_id;
199
    IntArcMap _arc_idf;
200
    IntArcMap _arc_idb;
201
    IntVector _first_out;
202
    BoolVector _forward;
203
    IntVector _source;
204
    IntVector _target;
205
    IntVector _reverse;
206

	
207
    // Node and arc data
208
    ValueVector _lower;
209
    ValueVector _upper;
210
    CostVector _cost;
211
    ValueVector _supply;
212

	
213
    ValueVector _res_cap;
214
    CostVector _pi;
215

	
216
    // Data for a StaticDigraph structure
217
    typedef std::pair<int, int> IntPair;
218
    StaticDigraph _sgr;
219
    std::vector<IntPair> _arc_vec;
220
    std::vector<Cost> _cost_vec;
221
    IntVector _id_vec;
222
    CostArcMap _cost_map;
223
    CostNodeMap _pi_map;
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
  public:
235

	
236
    /// \brief Constructor.
237
    ///
238
    /// The constructor of the class.
239
    ///
240
    /// \param graph The digraph the algorithm runs on.
241
    CycleCanceling(const GR& graph) :
242
      _graph(graph), _node_id(graph), _arc_idf(graph), _arc_idb(graph),
243
      _cost_map(_cost_vec), _pi_map(_pi),
244
      INF(std::numeric_limits<Value>::has_infinity ?
245
          std::numeric_limits<Value>::infinity() :
246
          std::numeric_limits<Value>::max())
247
    {
248
      // Check the number types
249
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
250
        "The flow type of CycleCanceling must be signed");
251
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
252
        "The cost type of CycleCanceling must be signed");
253

	
254
      // Reset data structures
255
      reset();
256
    }
257

	
258
    /// \name Parameters
259
    /// The parameters of the algorithm can be specified using these
260
    /// functions.
261

	
262
    /// @{
263

	
264
    /// \brief Set the lower bounds on the arcs.
265
    ///
266
    /// This function sets the lower bounds on the arcs.
267
    /// If it is not used before calling \ref run(), the lower bounds
268
    /// will be set to zero on all arcs.
269
    ///
270
    /// \param map An arc map storing the lower bounds.
271
    /// Its \c Value type must be convertible to the \c Value type
272
    /// of the algorithm.
273
    ///
274
    /// \return <tt>(*this)</tt>
275
    template <typename LowerMap>
276
    CycleCanceling& lowerMap(const LowerMap& map) {
277
      _have_lower = true;
278
      for (ArcIt a(_graph); a != INVALID; ++a) {
279
        _lower[_arc_idf[a]] = map[a];
280
        _lower[_arc_idb[a]] = map[a];
281
      }
282
      return *this;
283
    }
284

	
285
    /// \brief Set the upper bounds (capacities) on the arcs.
286
    ///
287
    /// This function sets the upper bounds (capacities) on the arcs.
288
    /// If it is not used before calling \ref run(), the upper bounds
289
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
290
    /// unbounded from above).
291
    ///
292
    /// \param map An arc map storing the upper bounds.
293
    /// Its \c Value type must be convertible to the \c Value type
294
    /// of the algorithm.
295
    ///
296
    /// \return <tt>(*this)</tt>
297
    template<typename UpperMap>
298
    CycleCanceling& upperMap(const UpperMap& map) {
299
      for (ArcIt a(_graph); a != INVALID; ++a) {
300
        _upper[_arc_idf[a]] = map[a];
301
      }
302
      return *this;
303
    }
304

	
305
    /// \brief Set the costs of the arcs.
306
    ///
307
    /// This function sets the costs of the arcs.
308
    /// If it is not used before calling \ref run(), the costs
309
    /// will be set to \c 1 on all arcs.
310
    ///
311
    /// \param map An arc map storing the costs.
312
    /// Its \c Value type must be convertible to the \c Cost type
313
    /// of the algorithm.
314
    ///
315
    /// \return <tt>(*this)</tt>
316
    template<typename CostMap>
317
    CycleCanceling& costMap(const CostMap& map) {
318
      for (ArcIt a(_graph); a != INVALID; ++a) {
319
        _cost[_arc_idf[a]] =  map[a];
320
        _cost[_arc_idb[a]] = -map[a];
321
      }
322
      return *this;
323
    }
324

	
325
    /// \brief Set the supply values of the nodes.
326
    ///
327
    /// This function sets the supply values of the nodes.
328
    /// If neither this function nor \ref stSupply() is used before
329
    /// calling \ref run(), the supply of each node will be set to zero.
330
    ///
331
    /// \param map A node map storing the supply values.
332
    /// Its \c Value type must be convertible to the \c Value type
333
    /// of the algorithm.
334
    ///
335
    /// \return <tt>(*this)</tt>
336
    template<typename SupplyMap>
337
    CycleCanceling& supplyMap(const SupplyMap& map) {
338
      for (NodeIt n(_graph); n != INVALID; ++n) {
339
        _supply[_node_id[n]] = map[n];
340
      }
341
      return *this;
342
    }
343

	
344
    /// \brief Set single source and target nodes and a supply value.
345
    ///
346
    /// This function sets a single source node and a single target node
347
    /// and the required flow value.
348
    /// If neither this function nor \ref supplyMap() is used before
349
    /// calling \ref run(), the supply of each node will be set to zero.
350
    ///
351
    /// Using this function has the same effect as using \ref supplyMap()
352
    /// with such a map in which \c k is assigned to \c s, \c -k is
353
    /// assigned to \c t and all other nodes have zero supply value.
354
    ///
355
    /// \param s The source node.
356
    /// \param t The target node.
357
    /// \param k The required amount of flow from node \c s to node \c t
358
    /// (i.e. the supply of \c s and the demand of \c t).
359
    ///
360
    /// \return <tt>(*this)</tt>
361
    CycleCanceling& stSupply(const Node& s, const Node& t, Value k) {
362
      for (int i = 0; i != _res_node_num; ++i) {
363
        _supply[i] = 0;
364
      }
365
      _supply[_node_id[s]] =  k;
366
      _supply[_node_id[t]] = -k;
367
      return *this;
368
    }
369

	
370
    /// @}
371

	
372
    /// \name Execution control
373
    /// The algorithm can be executed using \ref run().
374

	
375
    /// @{
376

	
377
    /// \brief Run the algorithm.
378
    ///
379
    /// This function runs the algorithm.
380
    /// The paramters can be specified using functions \ref lowerMap(),
381
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
382
    /// For example,
383
    /// \code
384
    ///   CycleCanceling<ListDigraph> cc(graph);
385
    ///   cc.lowerMap(lower).upperMap(upper).costMap(cost)
386
    ///     .supplyMap(sup).run();
387
    /// \endcode
388
    ///
389
    /// This function can be called more than once. All the given parameters
390
    /// are kept for the next call, unless \ref resetParams() or \ref reset()
391
    /// is used, thus only the modified parameters have to be set again.
392
    /// If the underlying digraph was also modified after the construction
393
    /// of the class (or the last \ref reset() call), then the \ref reset()
394
    /// function must be called.
395
    ///
396
    /// \param method The cycle-canceling method that will be used.
397
    /// For more information, see \ref Method.
398
    ///
399
    /// \return \c INFEASIBLE if no feasible flow exists,
400
    /// \n \c OPTIMAL if the problem has optimal solution
401
    /// (i.e. it is feasible and bounded), and the algorithm has found
402
    /// optimal flow and node potentials (primal and dual solutions),
403
    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
404
    /// and infinite upper bound. It means that the objective function
405
    /// is unbounded on that arc, however, note that it could actually be
406
    /// bounded over the feasible flows, but this algroithm cannot handle
407
    /// these cases.
408
    ///
409
    /// \see ProblemType, Method
410
    /// \see resetParams(), reset()
411
    ProblemType run(Method method = CANCEL_AND_TIGHTEN) {
412
      ProblemType pt = init();
413
      if (pt != OPTIMAL) return pt;
414
      start(method);
415
      return OPTIMAL;
416
    }
417

	
418
    /// \brief Reset all the parameters that have been given before.
419
    ///
420
    /// This function resets all the paramaters that have been given
421
    /// before using functions \ref lowerMap(), \ref upperMap(),
422
    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
423
    ///
424
    /// It is useful for multiple \ref run() calls. Basically, all the given
425
    /// parameters are kept for the next \ref run() call, unless
426
    /// \ref resetParams() or \ref reset() is used.
427
    /// If the underlying digraph was also modified after the construction
428
    /// of the class or the last \ref reset() call, then the \ref reset()
429
    /// function must be used, otherwise \ref resetParams() is sufficient.
430
    ///
431
    /// For example,
432
    /// \code
433
    ///   CycleCanceling<ListDigraph> cs(graph);
434
    ///
435
    ///   // First run
436
    ///   cc.lowerMap(lower).upperMap(upper).costMap(cost)
437
    ///     .supplyMap(sup).run();
438
    ///
439
    ///   // Run again with modified cost map (resetParams() is not called,
440
    ///   // so only the cost map have to be set again)
441
    ///   cost[e] += 100;
442
    ///   cc.costMap(cost).run();
443
    ///
444
    ///   // Run again from scratch using resetParams()
445
    ///   // (the lower bounds will be set to zero on all arcs)
446
    ///   cc.resetParams();
447
    ///   cc.upperMap(capacity).costMap(cost)
448
    ///     .supplyMap(sup).run();
449
    /// \endcode
450
    ///
451
    /// \return <tt>(*this)</tt>
452
    ///
453
    /// \see reset(), run()
454
    CycleCanceling& resetParams() {
455
      for (int i = 0; i != _res_node_num; ++i) {
456
        _supply[i] = 0;
457
      }
458
      int limit = _first_out[_root];
459
      for (int j = 0; j != limit; ++j) {
460
        _lower[j] = 0;
461
        _upper[j] = INF;
462
        _cost[j] = _forward[j] ? 1 : -1;
463
      }
464
      for (int j = limit; j != _res_arc_num; ++j) {
465
        _lower[j] = 0;
466
        _upper[j] = INF;
467
        _cost[j] = 0;
468
        _cost[_reverse[j]] = 0;
469
      }
470
      _have_lower = false;
471
      return *this;
472
    }
473

	
474
    /// \brief Reset the internal data structures and all the parameters
475
    /// that have been given before.
476
    ///
477
    /// This function resets the internal data structures and all the
478
    /// paramaters that have been given before using functions \ref lowerMap(),
479
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
480
    ///
481
    /// It is useful for multiple \ref run() calls. Basically, all the given
482
    /// parameters are kept for the next \ref run() call, unless
483
    /// \ref resetParams() or \ref reset() is used.
484
    /// If the underlying digraph was also modified after the construction
485
    /// of the class or the last \ref reset() call, then the \ref reset()
486
    /// function must be used, otherwise \ref resetParams() is sufficient.
487
    ///
488
    /// See \ref resetParams() for examples.
489
    ///
490
    /// \return <tt>(*this)</tt>
491
    ///
492
    /// \see resetParams(), run()
493
    CycleCanceling& reset() {
494
      // Resize vectors
495
      _node_num = countNodes(_graph);
496
      _arc_num = countArcs(_graph);
497
      _res_node_num = _node_num + 1;
498
      _res_arc_num = 2 * (_arc_num + _node_num);
499
      _root = _node_num;
500

	
501
      _first_out.resize(_res_node_num + 1);
502
      _forward.resize(_res_arc_num);
503
      _source.resize(_res_arc_num);
504
      _target.resize(_res_arc_num);
505
      _reverse.resize(_res_arc_num);
506

	
507
      _lower.resize(_res_arc_num);
508
      _upper.resize(_res_arc_num);
509
      _cost.resize(_res_arc_num);
510
      _supply.resize(_res_node_num);
511

	
512
      _res_cap.resize(_res_arc_num);
513
      _pi.resize(_res_node_num);
514

	
515
      _arc_vec.reserve(_res_arc_num);
516
      _cost_vec.reserve(_res_arc_num);
517
      _id_vec.reserve(_res_arc_num);
518

	
519
      // Copy the graph
520
      int i = 0, j = 0, k = 2 * _arc_num + _node_num;
521
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
522
        _node_id[n] = i;
523
      }
524
      i = 0;
525
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
526
        _first_out[i] = j;
527
        for (OutArcIt a(_graph, n); a != INVALID; ++a, ++j) {
528
          _arc_idf[a] = j;
529
          _forward[j] = true;
530
          _source[j] = i;
531
          _target[j] = _node_id[_graph.runningNode(a)];
532
        }
533
        for (InArcIt a(_graph, n); a != INVALID; ++a, ++j) {
534
          _arc_idb[a] = j;
535
          _forward[j] = false;
536
          _source[j] = i;
537
          _target[j] = _node_id[_graph.runningNode(a)];
538
        }
539
        _forward[j] = false;
540
        _source[j] = i;
541
        _target[j] = _root;
542
        _reverse[j] = k;
543
        _forward[k] = true;
544
        _source[k] = _root;
545
        _target[k] = i;
546
        _reverse[k] = j;
547
        ++j; ++k;
548
      }
549
      _first_out[i] = j;
550
      _first_out[_res_node_num] = k;
551
      for (ArcIt a(_graph); a != INVALID; ++a) {
552
        int fi = _arc_idf[a];
553
        int bi = _arc_idb[a];
554
        _reverse[fi] = bi;
555
        _reverse[bi] = fi;
556
      }
557

	
558
      // Reset parameters
559
      resetParams();
560
      return *this;
561
    }
562

	
563
    /// @}
564

	
565
    /// \name Query Functions
566
    /// The results of the algorithm can be obtained using these
567
    /// functions.\n
568
    /// The \ref run() function must be called before using them.
569

	
570
    /// @{
571

	
572
    /// \brief Return the total cost of the found flow.
573
    ///
574
    /// This function returns the total cost of the found flow.
575
    /// Its complexity is O(e).
576
    ///
577
    /// \note The return type of the function can be specified as a
578
    /// template parameter. For example,
579
    /// \code
580
    ///   cc.totalCost<double>();
581
    /// \endcode
582
    /// It is useful if the total cost cannot be stored in the \c Cost
583
    /// type of the algorithm, which is the default return type of the
584
    /// function.
585
    ///
586
    /// \pre \ref run() must be called before using this function.
587
    template <typename Number>
588
    Number totalCost() const {
589
      Number c = 0;
590
      for (ArcIt a(_graph); a != INVALID; ++a) {
591
        int i = _arc_idb[a];
592
        c += static_cast<Number>(_res_cap[i]) *
593
             (-static_cast<Number>(_cost[i]));
594
      }
595
      return c;
596
    }
597

	
598
#ifndef DOXYGEN
599
    Cost totalCost() const {
600
      return totalCost<Cost>();
601
    }
602
#endif
603

	
604
    /// \brief Return the flow on the given arc.
605
    ///
606
    /// This function returns the flow on the given arc.
607
    ///
608
    /// \pre \ref run() must be called before using this function.
609
    Value flow(const Arc& a) const {
610
      return _res_cap[_arc_idb[a]];
611
    }
612

	
613
    /// \brief Return the flow map (the primal solution).
614
    ///
615
    /// This function copies the flow value on each arc into the given
616
    /// map. The \c Value type of the algorithm must be convertible to
617
    /// the \c Value type of the map.
618
    ///
619
    /// \pre \ref run() must be called before using this function.
620
    template <typename FlowMap>
621
    void flowMap(FlowMap &map) const {
622
      for (ArcIt a(_graph); a != INVALID; ++a) {
623
        map.set(a, _res_cap[_arc_idb[a]]);
624
      }
625
    }
626

	
627
    /// \brief Return the potential (dual value) of the given node.
628
    ///
629
    /// This function returns the potential (dual value) of the
630
    /// given node.
631
    ///
632
    /// \pre \ref run() must be called before using this function.
633
    Cost potential(const Node& n) const {
634
      return static_cast<Cost>(_pi[_node_id[n]]);
635
    }
636

	
637
    /// \brief Return the potential map (the dual solution).
638
    ///
639
    /// This function copies the potential (dual value) of each node
640
    /// into the given map.
641
    /// The \c Cost type of the algorithm must be convertible to the
642
    /// \c Value type of the map.
643
    ///
644
    /// \pre \ref run() must be called before using this function.
645
    template <typename PotentialMap>
646
    void potentialMap(PotentialMap &map) const {
647
      for (NodeIt n(_graph); n != INVALID; ++n) {
648
        map.set(n, static_cast<Cost>(_pi[_node_id[n]]));
649
      }
650
    }
651

	
652
    /// @}
653

	
654
  private:
655

	
656
    // Initialize the algorithm
657
    ProblemType init() {
658
      if (_res_node_num <= 1) return INFEASIBLE;
659

	
660
      // Check the sum of supply values
661
      _sum_supply = 0;
662
      for (int i = 0; i != _root; ++i) {
663
        _sum_supply += _supply[i];
664
      }
665
      if (_sum_supply > 0) return INFEASIBLE;
666

	
667

	
668
      // Initialize vectors
669
      for (int i = 0; i != _res_node_num; ++i) {
670
        _pi[i] = 0;
671
      }
672
      ValueVector excess(_supply);
673

	
674
      // Remove infinite upper bounds and check negative arcs
675
      const Value MAX = std::numeric_limits<Value>::max();
676
      int last_out;
677
      if (_have_lower) {
678
        for (int i = 0; i != _root; ++i) {
679
          last_out = _first_out[i+1];
680
          for (int j = _first_out[i]; j != last_out; ++j) {
681
            if (_forward[j]) {
682
              Value c = _cost[j] < 0 ? _upper[j] : _lower[j];
683
              if (c >= MAX) return UNBOUNDED;
684
              excess[i] -= c;
685
              excess[_target[j]] += c;
686
            }
687
          }
688
        }
689
      } else {
690
        for (int i = 0; i != _root; ++i) {
691
          last_out = _first_out[i+1];
692
          for (int j = _first_out[i]; j != last_out; ++j) {
693
            if (_forward[j] && _cost[j] < 0) {
694
              Value c = _upper[j];
695
              if (c >= MAX) return UNBOUNDED;
696
              excess[i] -= c;
697
              excess[_target[j]] += c;
698
            }
699
          }
700
        }
701
      }
702
      Value ex, max_cap = 0;
703
      for (int i = 0; i != _res_node_num; ++i) {
704
        ex = excess[i];
705
        if (ex < 0) max_cap -= ex;
706
      }
707
      for (int j = 0; j != _res_arc_num; ++j) {
708
        if (_upper[j] >= MAX) _upper[j] = max_cap;
709
      }
710

	
711
      // Initialize maps for Circulation and remove non-zero lower bounds
712
      ConstMap<Arc, Value> low(0);
713
      typedef typename Digraph::template ArcMap<Value> ValueArcMap;
714
      typedef typename Digraph::template NodeMap<Value> ValueNodeMap;
715
      ValueArcMap cap(_graph), flow(_graph);
716
      ValueNodeMap sup(_graph);
717
      for (NodeIt n(_graph); n != INVALID; ++n) {
718
        sup[n] = _supply[_node_id[n]];
719
      }
720
      if (_have_lower) {
721
        for (ArcIt a(_graph); a != INVALID; ++a) {
722
          int j = _arc_idf[a];
723
          Value c = _lower[j];
724
          cap[a] = _upper[j] - c;
725
          sup[_graph.source(a)] -= c;
726
          sup[_graph.target(a)] += c;
727
        }
728
      } else {
729
        for (ArcIt a(_graph); a != INVALID; ++a) {
730
          cap[a] = _upper[_arc_idf[a]];
731
        }
732
      }
733

	
734
      // Find a feasible flow using Circulation
735
      Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap>
736
        circ(_graph, low, cap, sup);
737
      if (!circ.flowMap(flow).run()) return INFEASIBLE;
738

	
739
      // Set residual capacities and handle GEQ supply type
740
      if (_sum_supply < 0) {
741
        for (ArcIt a(_graph); a != INVALID; ++a) {
742
          Value fa = flow[a];
743
          _res_cap[_arc_idf[a]] = cap[a] - fa;
744
          _res_cap[_arc_idb[a]] = fa;
745
          sup[_graph.source(a)] -= fa;
746
          sup[_graph.target(a)] += fa;
747
        }
748
        for (NodeIt n(_graph); n != INVALID; ++n) {
749
          excess[_node_id[n]] = sup[n];
750
        }
751
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
752
          int u = _target[a];
753
          int ra = _reverse[a];
754
          _res_cap[a] = -_sum_supply + 1;
755
          _res_cap[ra] = -excess[u];
756
          _cost[a] = 0;
757
          _cost[ra] = 0;
758
        }
759
      } else {
760
        for (ArcIt a(_graph); a != INVALID; ++a) {
761
          Value fa = flow[a];
762
          _res_cap[_arc_idf[a]] = cap[a] - fa;
763
          _res_cap[_arc_idb[a]] = fa;
764
        }
765
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
766
          int ra = _reverse[a];
767
          _res_cap[a] = 1;
768
          _res_cap[ra] = 0;
769
          _cost[a] = 0;
770
          _cost[ra] = 0;
771
        }
772
      }
773

	
774
      return OPTIMAL;
775
    }
776

	
777
    // Build a StaticDigraph structure containing the current
778
    // residual network
779
    void buildResidualNetwork() {
780
      _arc_vec.clear();
781
      _cost_vec.clear();
782
      _id_vec.clear();
783
      for (int j = 0; j != _res_arc_num; ++j) {
784
        if (_res_cap[j] > 0) {
785
          _arc_vec.push_back(IntPair(_source[j], _target[j]));
786
          _cost_vec.push_back(_cost[j]);
787
          _id_vec.push_back(j);
788
        }
789
      }
790
      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
791
    }
792

	
793
    // Execute the algorithm and transform the results
794
    void start(Method method) {
795
      // Execute the algorithm
796
      switch (method) {
797
        case SIMPLE_CYCLE_CANCELING:
798
          startSimpleCycleCanceling();
799
          break;
800
        case MINIMUM_MEAN_CYCLE_CANCELING:
801
          startMinMeanCycleCanceling();
802
          break;
803
        case CANCEL_AND_TIGHTEN:
804
          startCancelAndTighten();
805
          break;
806
      }
807

	
808
      // Compute node potentials
809
      if (method != SIMPLE_CYCLE_CANCELING) {
810
        buildResidualNetwork();
811
        typename BellmanFord<StaticDigraph, CostArcMap>
812
          ::template SetDistMap<CostNodeMap>::Create bf(_sgr, _cost_map);
813
        bf.distMap(_pi_map);
814
        bf.init(0);
815
        bf.start();
816
      }
817

	
818
      // Handle non-zero lower bounds
819
      if (_have_lower) {
820
        int limit = _first_out[_root];
821
        for (int j = 0; j != limit; ++j) {
822
          if (!_forward[j]) _res_cap[j] += _lower[j];
823
        }
824
      }
825
    }
826

	
827
    // Execute the "Simple Cycle Canceling" method
828
    void startSimpleCycleCanceling() {
829
      // Constants for computing the iteration limits
830
      const int BF_FIRST_LIMIT  = 2;
831
      const double BF_LIMIT_FACTOR = 1.5;
832

	
833
      typedef StaticVectorMap<StaticDigraph::Arc, Value> FilterMap;
834
      typedef FilterArcs<StaticDigraph, FilterMap> ResDigraph;
835
      typedef StaticVectorMap<StaticDigraph::Node, StaticDigraph::Arc> PredMap;
836
      typedef typename BellmanFord<ResDigraph, CostArcMap>
837
        ::template SetDistMap<CostNodeMap>
838
        ::template SetPredMap<PredMap>::Create BF;
839

	
840
      // Build the residual network
841
      _arc_vec.clear();
842
      _cost_vec.clear();
843
      for (int j = 0; j != _res_arc_num; ++j) {
844
        _arc_vec.push_back(IntPair(_source[j], _target[j]));
845
        _cost_vec.push_back(_cost[j]);
846
      }
847
      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
848

	
849
      FilterMap filter_map(_res_cap);
850
      ResDigraph rgr(_sgr, filter_map);
851
      std::vector<int> cycle;
852
      std::vector<StaticDigraph::Arc> pred(_res_arc_num);
853
      PredMap pred_map(pred);
854
      BF bf(rgr, _cost_map);
855
      bf.distMap(_pi_map).predMap(pred_map);
856

	
857
      int length_bound = BF_FIRST_LIMIT;
858
      bool optimal = false;
859
      while (!optimal) {
860
        bf.init(0);
861
        int iter_num = 0;
862
        bool cycle_found = false;
863
        while (!cycle_found) {
864
          // Perform some iterations of the Bellman-Ford algorithm
865
          int curr_iter_num = iter_num + length_bound <= _node_num ?
866
            length_bound : _node_num - iter_num;
867
          iter_num += curr_iter_num;
868
          int real_iter_num = curr_iter_num;
869
          for (int i = 0; i < curr_iter_num; ++i) {
870
            if (bf.processNextWeakRound()) {
871
              real_iter_num = i;
872
              break;
873
            }
874
          }
875
          if (real_iter_num < curr_iter_num) {
876
            // Optimal flow is found
877
            optimal = true;
878
            break;
879
          } else {
880
            // Search for node disjoint negative cycles
881
            std::vector<int> state(_res_node_num, 0);
882
            int id = 0;
883
            for (int u = 0; u != _res_node_num; ++u) {
884
              if (state[u] != 0) continue;
885
              ++id;
886
              int v = u;
887
              for (; v != -1 && state[v] == 0; v = pred[v] == INVALID ?
888
                   -1 : rgr.id(rgr.source(pred[v]))) {
889
                state[v] = id;
890
              }
891
              if (v != -1 && state[v] == id) {
892
                // A negative cycle is found
893
                cycle_found = true;
894
                cycle.clear();
895
                StaticDigraph::Arc a = pred[v];
896
                Value d, delta = _res_cap[rgr.id(a)];
897
                cycle.push_back(rgr.id(a));
898
                while (rgr.id(rgr.source(a)) != v) {
899
                  a = pred_map[rgr.source(a)];
900
                  d = _res_cap[rgr.id(a)];
901
                  if (d < delta) delta = d;
902
                  cycle.push_back(rgr.id(a));
903
                }
904

	
905
                // Augment along the cycle
906
                for (int i = 0; i < int(cycle.size()); ++i) {
907
                  int j = cycle[i];
908
                  _res_cap[j] -= delta;
909
                  _res_cap[_reverse[j]] += delta;
910
                }
911
              }
912
            }
913
          }
914

	
915
          // Increase iteration limit if no cycle is found
916
          if (!cycle_found) {
917
            length_bound = static_cast<int>(length_bound * BF_LIMIT_FACTOR);
918
          }
919
        }
920
      }
921
    }
922

	
923
    // Execute the "Minimum Mean Cycle Canceling" method
924
    void startMinMeanCycleCanceling() {
925
      typedef SimplePath<StaticDigraph> SPath;
926
      typedef typename SPath::ArcIt SPathArcIt;
927
      typedef typename HowardMmc<StaticDigraph, CostArcMap>
928
        ::template SetPath<SPath>::Create MMC;
929

	
930
      SPath cycle;
931
      MMC mmc(_sgr, _cost_map);
932
      mmc.cycle(cycle);
933
      buildResidualNetwork();
934
      while (mmc.findCycleMean() && mmc.cycleCost() < 0) {
935
        // Find the cycle
936
        mmc.findCycle();
937

	
938
        // Compute delta value
939
        Value delta = INF;
940
        for (SPathArcIt a(cycle); a != INVALID; ++a) {
941
          Value d = _res_cap[_id_vec[_sgr.id(a)]];
942
          if (d < delta) delta = d;
943
        }
944

	
945
        // Augment along the cycle
946
        for (SPathArcIt a(cycle); a != INVALID; ++a) {
947
          int j = _id_vec[_sgr.id(a)];
948
          _res_cap[j] -= delta;
949
          _res_cap[_reverse[j]] += delta;
950
        }
951

	
952
        // Rebuild the residual network
953
        buildResidualNetwork();
954
      }
955
    }
956

	
957
    // Execute the "Cancel And Tighten" method
958
    void startCancelAndTighten() {
959
      // Constants for the min mean cycle computations
960
      const double LIMIT_FACTOR = 1.0;
961
      const int MIN_LIMIT = 5;
962

	
963
      // Contruct auxiliary data vectors
964
      DoubleVector pi(_res_node_num, 0.0);
965
      IntVector level(_res_node_num);
966
      BoolVector reached(_res_node_num);
967
      BoolVector processed(_res_node_num);
968
      IntVector pred_node(_res_node_num);
969
      IntVector pred_arc(_res_node_num);
970
      std::vector<int> stack(_res_node_num);
971
      std::vector<int> proc_vector(_res_node_num);
972

	
973
      // Initialize epsilon
974
      double epsilon = 0;
975
      for (int a = 0; a != _res_arc_num; ++a) {
976
        if (_res_cap[a] > 0 && -_cost[a] > epsilon)
977
          epsilon = -_cost[a];
978
      }
979

	
980
      // Start phases
981
      Tolerance<double> tol;
982
      tol.epsilon(1e-6);
983
      int limit = int(LIMIT_FACTOR * std::sqrt(double(_res_node_num)));
984
      if (limit < MIN_LIMIT) limit = MIN_LIMIT;
985
      int iter = limit;
986
      while (epsilon * _res_node_num >= 1) {
987
        // Find and cancel cycles in the admissible network using DFS
988
        for (int u = 0; u != _res_node_num; ++u) {
989
          reached[u] = false;
990
          processed[u] = false;
991
        }
992
        int stack_head = -1;
993
        int proc_head = -1;
994
        for (int start = 0; start != _res_node_num; ++start) {
995
          if (reached[start]) continue;
996

	
997
          // New start node
998
          reached[start] = true;
999
          pred_arc[start] = -1;
1000
          pred_node[start] = -1;
1001

	
1002
          // Find the first admissible outgoing arc
1003
          double p = pi[start];
1004
          int a = _first_out[start];
1005
          int last_out = _first_out[start+1];
1006
          for (; a != last_out && (_res_cap[a] == 0 ||
1007
               !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
1008
          if (a == last_out) {
1009
            processed[start] = true;
1010
            proc_vector[++proc_head] = start;
1011
            continue;
1012
          }
1013
          stack[++stack_head] = a;
1014

	
1015
          while (stack_head >= 0) {
1016
            int sa = stack[stack_head];
1017
            int u = _source[sa];
1018
            int v = _target[sa];
1019

	
1020
            if (!reached[v]) {
1021
              // A new node is reached
1022
              reached[v] = true;
1023
              pred_node[v] = u;
1024
              pred_arc[v] = sa;
1025
              p = pi[v];
1026
              a = _first_out[v];
1027
              last_out = _first_out[v+1];
1028
              for (; a != last_out && (_res_cap[a] == 0 ||
1029
                   !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
1030
              stack[++stack_head] = a == last_out ? -1 : a;
1031
            } else {
1032
              if (!processed[v]) {
1033
                // A cycle is found
1034
                int n, w = u;
1035
                Value d, delta = _res_cap[sa];
1036
                for (n = u; n != v; n = pred_node[n]) {
1037
                  d = _res_cap[pred_arc[n]];
1038
                  if (d <= delta) {
1039
                    delta = d;
1040
                    w = pred_node[n];
1041
                  }
1042
                }
1043

	
1044
                // Augment along the cycle
1045
                _res_cap[sa] -= delta;
1046
                _res_cap[_reverse[sa]] += delta;
1047
                for (n = u; n != v; n = pred_node[n]) {
1048
                  int pa = pred_arc[n];
1049
                  _res_cap[pa] -= delta;
1050
                  _res_cap[_reverse[pa]] += delta;
1051
                }
1052
                for (n = u; stack_head > 0 && n != w; n = pred_node[n]) {
1053
                  --stack_head;
1054
                  reached[n] = false;
1055
                }
1056
                u = w;
1057
              }
1058
              v = u;
1059

	
1060
              // Find the next admissible outgoing arc
1061
              p = pi[v];
1062
              a = stack[stack_head] + 1;
1063
              last_out = _first_out[v+1];
1064
              for (; a != last_out && (_res_cap[a] == 0 ||
1065
                   !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
1066
              stack[stack_head] = a == last_out ? -1 : a;
1067
            }
1068

	
1069
            while (stack_head >= 0 && stack[stack_head] == -1) {
1070
              processed[v] = true;
1071
              proc_vector[++proc_head] = v;
1072
              if (--stack_head >= 0) {
1073
                // Find the next admissible outgoing arc
1074
                v = _source[stack[stack_head]];
1075
                p = pi[v];
1076
                a = stack[stack_head] + 1;
1077
                last_out = _first_out[v+1];
1078
                for (; a != last_out && (_res_cap[a] == 0 ||
1079
                     !tol.negative(_cost[a] + p - pi[_target[a]])); ++a) ;
1080
                stack[stack_head] = a == last_out ? -1 : a;
1081
              }
1082
            }
1083
          }
1084
        }
1085

	
1086
        // Tighten potentials and epsilon
1087
        if (--iter > 0) {
1088
          for (int u = 0; u != _res_node_num; ++u) {
1089
            level[u] = 0;
1090
          }
1091
          for (int i = proc_head; i > 0; --i) {
1092
            int u = proc_vector[i];
1093
            double p = pi[u];
1094
            int l = level[u] + 1;
1095
            int last_out = _first_out[u+1];
1096
            for (int a = _first_out[u]; a != last_out; ++a) {
1097
              int v = _target[a];
1098
              if (_res_cap[a] > 0 && tol.negative(_cost[a] + p - pi[v]) &&
1099
                  l > level[v]) level[v] = l;
1100
            }
1101
          }
1102

	
1103
          // Modify potentials
1104
          double q = std::numeric_limits<double>::max();
1105
          for (int u = 0; u != _res_node_num; ++u) {
1106
            int lu = level[u];
1107
            double p, pu = pi[u];
1108
            int last_out = _first_out[u+1];
1109
            for (int a = _first_out[u]; a != last_out; ++a) {
1110
              if (_res_cap[a] == 0) continue;
1111
              int v = _target[a];
1112
              int ld = lu - level[v];
1113
              if (ld > 0) {
1114
                p = (_cost[a] + pu - pi[v] + epsilon) / (ld + 1);
1115
                if (p < q) q = p;
1116
              }
1117
            }
1118
          }
1119
          for (int u = 0; u != _res_node_num; ++u) {
1120
            pi[u] -= q * level[u];
1121
          }
1122

	
1123
          // Modify epsilon
1124
          epsilon = 0;
1125
          for (int u = 0; u != _res_node_num; ++u) {
1126
            double curr, pu = pi[u];
1127
            int last_out = _first_out[u+1];
1128
            for (int a = _first_out[u]; a != last_out; ++a) {
1129
              if (_res_cap[a] == 0) continue;
1130
              curr = _cost[a] + pu - pi[_target[a]];
1131
              if (-curr > epsilon) epsilon = -curr;
1132
            }
1133
          }
1134
        } else {
1135
          typedef HowardMmc<StaticDigraph, CostArcMap> MMC;
1136
          typedef typename BellmanFord<StaticDigraph, CostArcMap>
1137
            ::template SetDistMap<CostNodeMap>::Create BF;
1138

	
1139
          // Set epsilon to the minimum cycle mean
1140
          buildResidualNetwork();
1141
          MMC mmc(_sgr, _cost_map);
1142
          mmc.findCycleMean();
1143
          epsilon = -mmc.cycleMean();
1144
          Cost cycle_cost = mmc.cycleCost();
1145
          int cycle_size = mmc.cycleSize();
1146

	
1147
          // Compute feasible potentials for the current epsilon
1148
          for (int i = 0; i != int(_cost_vec.size()); ++i) {
1149
            _cost_vec[i] = cycle_size * _cost_vec[i] - cycle_cost;
1150
          }
1151
          BF bf(_sgr, _cost_map);
1152
          bf.distMap(_pi_map);
1153
          bf.init(0);
1154
          bf.start();
1155
          for (int u = 0; u != _res_node_num; ++u) {
1156
            pi[u] = static_cast<double>(_pi[u]) / cycle_size;
1157
          }
1158

	
1159
          iter = limit;
1160
        }
1161
      }
1162
    }
1163

	
1164
  }; //class CycleCanceling
1165

	
1166
  ///@}
1167

	
1168
} //namespace lemon
1169

	
1170
#endif //LEMON_CYCLE_CANCELING_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_DHEAP_H
20
#define LEMON_DHEAP_H
21

	
22
///\ingroup heaps
23
///\file
24
///\brief D-ary heap implementation.
25

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

	
30
namespace lemon {
31

	
32
  /// \ingroup heaps
33
  ///
34
  ///\brief D-ary heap data structure.
35
  ///
36
  /// This class implements the \e D-ary \e heap data structure.
37
  /// It fully conforms to the \ref concepts::Heap "heap concept".
38
  ///
39
  /// The \ref DHeap "D-ary heap" is a generalization of the
40
  /// \ref BinHeap "binary heap" structure, its nodes have at most
41
  /// \c D children, instead of two.
42
  /// \ref BinHeap and \ref QuadHeap are specialized implementations
43
  /// of this structure for <tt>D=2</tt> and <tt>D=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 D The degree of the heap, each node have at most \e D
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 D, typename CMP>
59
#else
60
  template <typename PR, typename IM, int D = 16,
61
            typename CMP = std::less<PR> >
62
#endif
63
  class DHeap {
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 DHeap(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
    DHeap(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)/D; }
135
    int firstChild(int i) { return D*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+D<=length ) {
155
          int min=child;
156
          for (int i=1; i<D; ++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 DHeap
349

	
350
} // namespace lemon
351

	
352
#endif // LEMON_DHEAP_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-2010
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_FRACTIONAL_MATCHING_H
20
#define LEMON_FRACTIONAL_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
#include <lemon/assert.h>
32
#include <lemon/elevator.h>
33

	
34
///\ingroup matching
35
///\file
36
///\brief Fractional matching algorithms in general graphs.
37

	
38
namespace lemon {
39

	
40
  /// \brief Default traits class of MaxFractionalMatching class.
41
  ///
42
  /// Default traits class of MaxFractionalMatching class.
43
  /// \tparam GR Graph type.
44
  template <typename GR>
45
  struct MaxFractionalMatchingDefaultTraits {
46

	
47
    /// \brief The type of the graph the algorithm runs on.
48
    typedef GR Graph;
49

	
50
    /// \brief The type of the map that stores the matching.
51
    ///
52
    /// The type of the map that stores the matching arcs.
53
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
54
    typedef typename Graph::template NodeMap<typename GR::Arc> MatchingMap;
55

	
56
    /// \brief Instantiates a MatchingMap.
57
    ///
58
    /// This function instantiates a \ref MatchingMap.
59
    /// \param graph The graph for which we would like to define
60
    /// the matching map.
61
    static MatchingMap* createMatchingMap(const Graph& graph) {
62
      return new MatchingMap(graph);
63
    }
64

	
65
    /// \brief The elevator type used by MaxFractionalMatching algorithm.
66
    ///
67
    /// The elevator type used by MaxFractionalMatching algorithm.
68
    ///
69
    /// \sa Elevator
70
    /// \sa LinkedElevator
71
    typedef LinkedElevator<Graph, typename Graph::Node> Elevator;
72

	
73
    /// \brief Instantiates an Elevator.
74
    ///
75
    /// This function instantiates an \ref Elevator.
76
    /// \param graph The graph for which we would like to define
77
    /// the elevator.
78
    /// \param max_level The maximum level of the elevator.
79
    static Elevator* createElevator(const Graph& graph, int max_level) {
80
      return new Elevator(graph, max_level);
81
    }
82
  };
83

	
84
  /// \ingroup matching
85
  ///
86
  /// \brief Max cardinality fractional matching
87
  ///
88
  /// This class provides an implementation of fractional matching
89
  /// algorithm based on push-relabel principle.
90
  ///
91
  /// The maximum cardinality fractional matching is a relaxation of the
92
  /// maximum cardinality matching problem where the odd set constraints
93
  /// are omitted.
94
  /// It can be formulated with the following linear program.
95
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
96
  /// \f[x_e \ge 0\quad \forall e\in E\f]
97
  /// \f[\max \sum_{e\in E}x_e\f]
98
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
99
  /// \f$X\f$. The result can be represented as the union of a
100
  /// matching with one value edges and a set of odd length cycles
101
  /// with half value edges.
102
  ///
103
  /// The algorithm calculates an optimal fractional matching and a
104
  /// barrier. The number of adjacents of any node set minus the size
105
  /// of node set is a lower bound on the uncovered nodes in the
106
  /// graph. For maximum matching a barrier is computed which
107
  /// maximizes this difference.
108
  ///
109
  /// The algorithm can be executed with the run() function.  After it
110
  /// the matching (the primal solution) and the barrier (the dual
111
  /// solution) can be obtained using the query functions.
112
  ///
113
  /// The primal solution is multiplied by
114
  /// \ref MaxFractionalMatching::primalScale "2".
115
  ///
116
  /// \tparam GR The undirected graph type the algorithm runs on.
117
#ifdef DOXYGEN
118
  template <typename GR, typename TR>
119
#else
120
  template <typename GR,
121
            typename TR = MaxFractionalMatchingDefaultTraits<GR> >
122
#endif
123
  class MaxFractionalMatching {
124
  public:
125

	
126
    /// \brief The \ref MaxFractionalMatchingDefaultTraits "traits
127
    /// class" of the algorithm.
128
    typedef TR Traits;
129
    /// The type of the graph the algorithm runs on.
130
    typedef typename TR::Graph Graph;
131
    /// The type of the matching map.
132
    typedef typename TR::MatchingMap MatchingMap;
133
    /// The type of the elevator.
134
    typedef typename TR::Elevator Elevator;
135

	
136
    /// \brief Scaling factor for primal solution
137
    ///
138
    /// Scaling factor for primal solution.
139
    static const int primalScale = 2;
140

	
141
  private:
142

	
143
    const Graph &_graph;
144
    int _node_num;
145
    bool _allow_loops;
146
    int _empty_level;
147

	
148
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
149

	
150
    bool _local_matching;
151
    MatchingMap *_matching;
152

	
153
    bool _local_level;
154
    Elevator *_level;
155

	
156
    typedef typename Graph::template NodeMap<int> InDegMap;
157
    InDegMap *_indeg;
158

	
159
    void createStructures() {
160
      _node_num = countNodes(_graph);
161

	
162
      if (!_matching) {
163
        _local_matching = true;
164
        _matching = Traits::createMatchingMap(_graph);
165
      }
166
      if (!_level) {
167
        _local_level = true;
168
        _level = Traits::createElevator(_graph, _node_num);
169
      }
170
      if (!_indeg) {
171
        _indeg = new InDegMap(_graph);
172
      }
173
    }
174

	
175
    void destroyStructures() {
176
      if (_local_matching) {
177
        delete _matching;
178
      }
179
      if (_local_level) {
180
        delete _level;
181
      }
182
      if (_indeg) {
183
        delete _indeg;
184
      }
185
    }
186

	
187
    void postprocessing() {
188
      for (NodeIt n(_graph); n != INVALID; ++n) {
189
        if ((*_indeg)[n] != 0) continue;
190
        _indeg->set(n, -1);
191
        Node u = n;
192
        while ((*_matching)[u] != INVALID) {
193
          Node v = _graph.target((*_matching)[u]);
194
          _indeg->set(v, -1);
195
          Arc a = _graph.oppositeArc((*_matching)[u]);
196
          u = _graph.target((*_matching)[v]);
197
          _indeg->set(u, -1);
198
          _matching->set(v, a);
199
        }
200
      }
201

	
202
      for (NodeIt n(_graph); n != INVALID; ++n) {
203
        if ((*_indeg)[n] != 1) continue;
204
        _indeg->set(n, -1);
205

	
206
        int num = 1;
207
        Node u = _graph.target((*_matching)[n]);
208
        while (u != n) {
209
          _indeg->set(u, -1);
210
          u = _graph.target((*_matching)[u]);
211
          ++num;
212
        }
213
        if (num % 2 == 0 && num > 2) {
214
          Arc prev = _graph.oppositeArc((*_matching)[n]);
215
          Node v = _graph.target((*_matching)[n]);
216
          u = _graph.target((*_matching)[v]);
217
          _matching->set(v, prev);
218
          while (u != n) {
219
            prev = _graph.oppositeArc((*_matching)[u]);
220
            v = _graph.target((*_matching)[u]);
221
            u = _graph.target((*_matching)[v]);
222
            _matching->set(v, prev);
223
          }
224
        }
225
      }
226
    }
227

	
228
  public:
229

	
230
    typedef MaxFractionalMatching Create;
231

	
232
    ///\name Named Template Parameters
233

	
234
    ///@{
235

	
236
    template <typename T>
237
    struct SetMatchingMapTraits : public Traits {
238
      typedef T MatchingMap;
239
      static MatchingMap *createMatchingMap(const Graph&) {
240
        LEMON_ASSERT(false, "MatchingMap is not initialized");
241
        return 0; // ignore warnings
242
      }
243
    };
244

	
245
    /// \brief \ref named-templ-param "Named parameter" for setting
246
    /// MatchingMap type
247
    ///
248
    /// \ref named-templ-param "Named parameter" for setting MatchingMap
249
    /// type.
250
    template <typename T>
251
    struct SetMatchingMap
252
      : public MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > {
253
      typedef MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > Create;
254
    };
255

	
256
    template <typename T>
257
    struct SetElevatorTraits : public Traits {
258
      typedef T Elevator;
259
      static Elevator *createElevator(const Graph&, int) {
260
        LEMON_ASSERT(false, "Elevator is not initialized");
261
        return 0; // ignore warnings
262
      }
263
    };
264

	
265
    /// \brief \ref named-templ-param "Named parameter" for setting
266
    /// Elevator type
267
    ///
268
    /// \ref named-templ-param "Named parameter" for setting Elevator
269
    /// type. If this named parameter is used, then an external
270
    /// elevator object must be passed to the algorithm using the
271
    /// \ref elevator(Elevator&) "elevator()" function before calling
272
    /// \ref run() or \ref init().
273
    /// \sa SetStandardElevator
274
    template <typename T>
275
    struct SetElevator
276
      : public MaxFractionalMatching<Graph, SetElevatorTraits<T> > {
277
      typedef MaxFractionalMatching<Graph, SetElevatorTraits<T> > Create;
278
    };
279

	
280
    template <typename T>
281
    struct SetStandardElevatorTraits : public Traits {
282
      typedef T Elevator;
283
      static Elevator *createElevator(const Graph& graph, int max_level) {
284
        return new Elevator(graph, max_level);
285
      }
286
    };
287

	
288
    /// \brief \ref named-templ-param "Named parameter" for setting
289
    /// Elevator type with automatic allocation
290
    ///
291
    /// \ref named-templ-param "Named parameter" for setting Elevator
292
    /// type with automatic allocation.
293
    /// The Elevator should have standard constructor interface to be
294
    /// able to automatically created by the algorithm (i.e. the
295
    /// graph and the maximum level should be passed to it).
296
    /// However an external elevator object could also be passed to the
297
    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
298
    /// before calling \ref run() or \ref init().
299
    /// \sa SetElevator
300
    template <typename T>
301
    struct SetStandardElevator
302
      : public MaxFractionalMatching<Graph, SetStandardElevatorTraits<T> > {
303
      typedef MaxFractionalMatching<Graph,
304
                                    SetStandardElevatorTraits<T> > Create;
305
    };
306

	
307
    /// @}
308

	
309
  protected:
310

	
311
    MaxFractionalMatching() {}
312

	
313
  public:
314

	
315
    /// \brief Constructor
316
    ///
317
    /// Constructor.
318
    ///
319
    MaxFractionalMatching(const Graph &graph, bool allow_loops = true)
320
      : _graph(graph), _allow_loops(allow_loops),
321
        _local_matching(false), _matching(0),
322
        _local_level(false), _level(0),  _indeg(0)
323
    {}
324

	
325
    ~MaxFractionalMatching() {
326
      destroyStructures();
327
    }
328

	
329
    /// \brief Sets the matching map.
330
    ///
331
    /// Sets the matching map.
332
    /// If you don't use this function before calling \ref run() or
333
    /// \ref init(), an instance will be allocated automatically.
334
    /// The destructor deallocates this automatically allocated map,
335
    /// of course.
336
    /// \return <tt>(*this)</tt>
337
    MaxFractionalMatching& matchingMap(MatchingMap& map) {
338
      if (_local_matching) {
339
        delete _matching;
340
        _local_matching = false;
341
      }
342
      _matching = &map;
343
      return *this;
344
    }
345

	
346
    /// \brief Sets the elevator used by algorithm.
347
    ///
348
    /// Sets the elevator used by algorithm.
349
    /// If you don't use this function before calling \ref run() or
350
    /// \ref init(), an instance will be allocated automatically.
351
    /// The destructor deallocates this automatically allocated elevator,
352
    /// of course.
353
    /// \return <tt>(*this)</tt>
354
    MaxFractionalMatching& elevator(Elevator& elevator) {
355
      if (_local_level) {
356
        delete _level;
357
        _local_level = false;
358
      }
359
      _level = &elevator;
360
      return *this;
361
    }
362

	
363
    /// \brief Returns a const reference to the elevator.
364
    ///
365
    /// Returns a const reference to the elevator.
366
    ///
367
    /// \pre Either \ref run() or \ref init() must be called before
368
    /// using this function.
369
    const Elevator& elevator() const {
370
      return *_level;
371
    }
372

	
373
    /// \name Execution control
374
    /// The simplest way to execute the algorithm is to use one of the
375
    /// member functions called \c run(). \n
376
    /// If you need more control on the execution, first
377
    /// you must call \ref init() and then one variant of the start()
378
    /// member.
379

	
380
    /// @{
381

	
382
    /// \brief Initializes the internal data structures.
383
    ///
384
    /// Initializes the internal data structures and sets the initial
385
    /// matching.
386
    void init() {
387
      createStructures();
388

	
389
      _level->initStart();
390
      for (NodeIt n(_graph); n != INVALID; ++n) {
391
        _indeg->set(n, 0);
392
        _matching->set(n, INVALID);
393
        _level->initAddItem(n);
394
      }
395
      _level->initFinish();
396

	
397
      _empty_level = _node_num;
398
      for (NodeIt n(_graph); n != INVALID; ++n) {
399
        for (OutArcIt a(_graph, n); a != INVALID; ++a) {
400
          if (_graph.target(a) == n && !_allow_loops) continue;
401
          _matching->set(n, a);
402
          Node v = _graph.target((*_matching)[n]);
403
          _indeg->set(v, (*_indeg)[v] + 1);
404
          break;
405
        }
406
      }
407

	
408
      for (NodeIt n(_graph); n != INVALID; ++n) {
409
        if ((*_indeg)[n] == 0) {
410
          _level->activate(n);
411
        }
412
      }
413
    }
414

	
415
    /// \brief Starts the algorithm and computes a fractional matching
416
    ///
417
    /// The algorithm computes a maximum fractional matching.
418
    ///
419
    /// \param postprocess The algorithm computes first a matching
420
    /// which is a union of a matching with one value edges, cycles
421
    /// with half value edges and even length paths with half value
422
    /// edges. If the parameter is true, then after the push-relabel
423
    /// algorithm it postprocesses the matching to contain only
424
    /// matching edges and half value odd cycles.
425
    void start(bool postprocess = true) {
426
      Node n;
427
      while ((n = _level->highestActive()) != INVALID) {
428
        int level = _level->highestActiveLevel();
429
        int new_level = _level->maxLevel();
430
        for (InArcIt a(_graph, n); a != INVALID; ++a) {
431
          Node u = _graph.source(a);
432
          if (n == u && !_allow_loops) continue;
433
          Node v = _graph.target((*_matching)[u]);
434
          if ((*_level)[v] < level) {
435
            _indeg->set(v, (*_indeg)[v] - 1);
436
            if ((*_indeg)[v] == 0) {
437
              _level->activate(v);
438
            }
439
            _matching->set(u, a);
440
            _indeg->set(n, (*_indeg)[n] + 1);
441
            _level->deactivate(n);
442
            goto no_more_push;
443
          } else if (new_level > (*_level)[v]) {
444
            new_level = (*_level)[v];
445
          }
446
        }
447

	
448
        if (new_level + 1 < _level->maxLevel()) {
449
          _level->liftHighestActive(new_level + 1);
450
        } else {
451
          _level->liftHighestActiveToTop();
452
        }
453
        if (_level->emptyLevel(level)) {
454
          _level->liftToTop(level);
455
        }
456
      no_more_push:
457
        ;
458
      }
459
      for (NodeIt n(_graph); n != INVALID; ++n) {
460
        if ((*_matching)[n] == INVALID) continue;
461
        Node u = _graph.target((*_matching)[n]);
462
        if ((*_indeg)[u] > 1) {
463
          _indeg->set(u, (*_indeg)[u] - 1);
464
          _matching->set(n, INVALID);
465
        }
466
      }
467
      if (postprocess) {
468
        postprocessing();
469
      }
470
    }
471

	
472
    /// \brief Starts the algorithm and computes a perfect fractional
473
    /// matching
474
    ///
475
    /// The algorithm computes a perfect fractional matching. If it
476
    /// does not exists, then the algorithm returns false and the
477
    /// matching is undefined and the barrier.
478
    ///
479
    /// \param postprocess The algorithm computes first a matching
480
    /// which is a union of a matching with one value edges, cycles
481
    /// with half value edges and even length paths with half value
482
    /// edges. If the parameter is true, then after the push-relabel
483
    /// algorithm it postprocesses the matching to contain only
484
    /// matching edges and half value odd cycles.
485
    bool startPerfect(bool postprocess = true) {
486
      Node n;
487
      while ((n = _level->highestActive()) != INVALID) {
488
        int level = _level->highestActiveLevel();
489
        int new_level = _level->maxLevel();
490
        for (InArcIt a(_graph, n); a != INVALID; ++a) {
491
          Node u = _graph.source(a);
492
          if (n == u && !_allow_loops) continue;
493
          Node v = _graph.target((*_matching)[u]);
494
          if ((*_level)[v] < level) {
495
            _indeg->set(v, (*_indeg)[v] - 1);
496
            if ((*_indeg)[v] == 0) {
497
              _level->activate(v);
498
            }
499
            _matching->set(u, a);
500
            _indeg->set(n, (*_indeg)[n] + 1);
501
            _level->deactivate(n);
502
            goto no_more_push;
503
          } else if (new_level > (*_level)[v]) {
504
            new_level = (*_level)[v];
505
          }
506
        }
507

	
508
        if (new_level + 1 < _level->maxLevel()) {
509
          _level->liftHighestActive(new_level + 1);
510
        } else {
511
          _level->liftHighestActiveToTop();
512
          _empty_level = _level->maxLevel() - 1;
513
          return false;
514
        }
515
        if (_level->emptyLevel(level)) {
516
          _level->liftToTop(level);
517
          _empty_level = level;
518
          return false;
519
        }
520
      no_more_push:
521
        ;
522
      }
523
      if (postprocess) {
524
        postprocessing();
525
      }
526
      return true;
527
    }
528

	
529
    /// \brief Runs the algorithm
530
    ///
531
    /// Just a shortcut for the next code:
532
    ///\code
533
    /// init();
534
    /// start();
535
    ///\endcode
536
    void run(bool postprocess = true) {
537
      init();
538
      start(postprocess);
539
    }
540

	
541
    /// \brief Runs the algorithm to find a perfect fractional matching
542
    ///
543
    /// Just a shortcut for the next code:
544
    ///\code
545
    /// init();
546
    /// startPerfect();
547
    ///\endcode
548
    bool runPerfect(bool postprocess = true) {
549
      init();
550
      return startPerfect(postprocess);
551
    }
552

	
553
    ///@}
554

	
555
    /// \name Query Functions
556
    /// The result of the %Matching algorithm can be obtained using these
557
    /// functions.\n
558
    /// Before the use of these functions,
559
    /// either run() or start() must be called.
560
    ///@{
561

	
562

	
563
    /// \brief Return the number of covered nodes in the matching.
564
    ///
565
    /// This function returns the number of covered nodes in the matching.
566
    ///
567
    /// \pre Either run() or start() must be called before using this function.
568
    int matchingSize() const {
569
      int num = 0;
570
      for (NodeIt n(_graph); n != INVALID; ++n) {
571
        if ((*_matching)[n] != INVALID) {
572
          ++num;
573
        }
574
      }
575
      return num;
576
    }
577

	
578
    /// \brief Returns a const reference to the matching map.
579
    ///
580
    /// Returns a const reference to the node map storing the found
581
    /// fractional matching. This method can be called after
582
    /// running the algorithm.
583
    ///
584
    /// \pre Either \ref run() or \ref init() must be called before
585
    /// using this function.
586
    const MatchingMap& matchingMap() const {
587
      return *_matching;
588
    }
589

	
590
    /// \brief Return \c true if the given edge is in the matching.
591
    ///
592
    /// This function returns \c true if the given edge is in the
593
    /// found matching. The result is scaled by \ref primalScale
594
    /// "primal scale".
595
    ///
596
    /// \pre Either run() or start() must be called before using this function.
597
    int matching(const Edge& edge) const {
598
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) +
599
        (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
600
    }
601

	
602
    /// \brief Return the fractional matching arc (or edge) incident
603
    /// to the given node.
604
    ///
605
    /// This function returns one of the fractional matching arc (or
606
    /// edge) incident to the given node in the found matching or \c
607
    /// INVALID if the node is not covered by the matching or if the
608
    /// node is on an odd length cycle then it is the successor edge
609
    /// on the cycle.
610
    ///
611
    /// \pre Either run() or start() must be called before using this function.
612
    Arc matching(const Node& node) const {
613
      return (*_matching)[node];
614
    }
615

	
616
    /// \brief Returns true if the node is in the barrier
617
    ///
618
    /// The barrier is a subset of the nodes. If the nodes in the
619
    /// barrier have less adjacent nodes than the size of the barrier,
620
    /// then at least as much nodes cannot be covered as the
621
    /// difference of the two subsets.
622
    bool barrier(const Node& node) const {
623
      return (*_level)[node] >= _empty_level;
624
    }
625

	
626
    /// @}
627

	
628
  };
629

	
630
  /// \ingroup matching
631
  ///
632
  /// \brief Weighted fractional matching in general graphs
633
  ///
634
  /// This class provides an efficient implementation of fractional
635
  /// matching algorithm. The implementation uses priority queues and
636
  /// provides \f$O(nm\log n)\f$ time complexity.
637
  ///
638
  /// The maximum weighted fractional matching is a relaxation of the
639
  /// maximum weighted matching problem where the odd set constraints
640
  /// are omitted.
641
  /// It can be formulated with the following linear program.
642
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
643
  /// \f[x_e \ge 0\quad \forall e\in E\f]
644
  /// \f[\max \sum_{e\in E}x_ew_e\f]
645
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
646
  /// \f$X\f$. The result must be the union of a matching with one
647
  /// value edges and a set of odd length cycles with half value edges.
648
  ///
649
  /// The algorithm calculates an optimal fractional matching and a
650
  /// proof of the optimality. The solution of the dual problem can be
651
  /// used to check the result of the algorithm. The dual linear
652
  /// problem is the following.
653
  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
654
  /// \f[y_u \ge 0 \quad \forall u \in V\f]
655
  /// \f[\min \sum_{u \in V}y_u \f]
656
  ///
657
  /// The algorithm can be executed with the run() function.
658
  /// After it the matching (the primal solution) and the dual solution
659
  /// can be obtained using the query functions.
660
  ///
661
  /// The primal solution is multiplied by
662
  /// \ref MaxWeightedFractionalMatching::primalScale "2".
663
  /// If the value type is integer, then the dual
664
  /// solution is scaled by
665
  /// \ref MaxWeightedFractionalMatching::dualScale "4".
666
  ///
667
  /// \tparam GR The undirected graph type the algorithm runs on.
668
  /// \tparam WM The type edge weight map. The default type is
669
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
670
#ifdef DOXYGEN
671
  template <typename GR, typename WM>
672
#else
673
  template <typename GR,
674
            typename WM = typename GR::template EdgeMap<int> >
675
#endif
676
  class MaxWeightedFractionalMatching {
677
  public:
678

	
679
    /// The graph type of the algorithm
680
    typedef GR Graph;
681
    /// The type of the edge weight map
682
    typedef WM WeightMap;
683
    /// The value type of the edge weights
684
    typedef typename WeightMap::Value Value;
685

	
686
    /// The type of the matching map
687
    typedef typename Graph::template NodeMap<typename Graph::Arc>
688
    MatchingMap;
689

	
690
    /// \brief Scaling factor for primal solution
691
    ///
692
    /// Scaling factor for primal solution.
693
    static const int primalScale = 2;
694

	
695
    /// \brief Scaling factor for dual solution
696
    ///
697
    /// Scaling factor for dual solution. It is equal to 4 or 1
698
    /// according to the value type.
699
    static const int dualScale =
700
      std::numeric_limits<Value>::is_integer ? 4 : 1;
701

	
702
  private:
703

	
704
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
705

	
706
    typedef typename Graph::template NodeMap<Value> NodePotential;
707

	
708
    const Graph& _graph;
709
    const WeightMap& _weight;
710

	
711
    MatchingMap* _matching;
712
    NodePotential* _node_potential;
713

	
714
    int _node_num;
715
    bool _allow_loops;
716

	
717
    enum Status {
718
      EVEN = -1, MATCHED = 0, ODD = 1
719
    };
720

	
721
    typedef typename Graph::template NodeMap<Status> StatusMap;
722
    StatusMap* _status;
723

	
724
    typedef typename Graph::template NodeMap<Arc> PredMap;
725
    PredMap* _pred;
726

	
727
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
728

	
729
    IntNodeMap *_tree_set_index;
730
    TreeSet *_tree_set;
731

	
732
    IntNodeMap *_delta1_index;
733
    BinHeap<Value, IntNodeMap> *_delta1;
734

	
735
    IntNodeMap *_delta2_index;
736
    BinHeap<Value, IntNodeMap> *_delta2;
737

	
738
    IntEdgeMap *_delta3_index;
739
    BinHeap<Value, IntEdgeMap> *_delta3;
740

	
741
    Value _delta_sum;
742

	
743
    void createStructures() {
744
      _node_num = countNodes(_graph);
745

	
746
      if (!_matching) {
747
        _matching = new MatchingMap(_graph);
748
      }
749
      if (!_node_potential) {
750
        _node_potential = new NodePotential(_graph);
751
      }
752
      if (!_status) {
753
        _status = new StatusMap(_graph);
754
      }
755
      if (!_pred) {
756
        _pred = new PredMap(_graph);
757
      }
758
      if (!_tree_set) {
759
        _tree_set_index = new IntNodeMap(_graph);
760
        _tree_set = new TreeSet(*_tree_set_index);
761
      }
762
      if (!_delta1) {
763
        _delta1_index = new IntNodeMap(_graph);
764
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
765
      }
766
      if (!_delta2) {
767
        _delta2_index = new IntNodeMap(_graph);
768
        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
769
      }
770
      if (!_delta3) {
771
        _delta3_index = new IntEdgeMap(_graph);
772
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
773
      }
774
    }
775

	
776
    void destroyStructures() {
777
      if (_matching) {
778
        delete _matching;
779
      }
780
      if (_node_potential) {
781
        delete _node_potential;
782
      }
783
      if (_status) {
784
        delete _status;
785
      }
786
      if (_pred) {
787
        delete _pred;
788
      }
789
      if (_tree_set) {
790
        delete _tree_set_index;
791
        delete _tree_set;
792
      }
793
      if (_delta1) {
794
        delete _delta1_index;
795
        delete _delta1;
796
      }
797
      if (_delta2) {
798
        delete _delta2_index;
799
        delete _delta2;
800
      }
801
      if (_delta3) {
802
        delete _delta3_index;
803
        delete _delta3;
804
      }
805
    }
806

	
807
    void matchedToEven(Node node, int tree) {
808
      _tree_set->insert(node, tree);
809
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
810
      _delta1->push(node, (*_node_potential)[node]);
811

	
812
      if (_delta2->state(node) == _delta2->IN_HEAP) {
813
        _delta2->erase(node);
814
      }
815

	
816
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
817
        Node v = _graph.source(a);
818
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
819
          dualScale * _weight[a];
820
        if (node == v) {
821
          if (_allow_loops && _graph.direction(a)) {
822
            _delta3->push(a, rw / 2);
823
          }
824
        } else if ((*_status)[v] == EVEN) {
825
          _delta3->push(a, rw / 2);
826
        } else if ((*_status)[v] == MATCHED) {
827
          if (_delta2->state(v) != _delta2->IN_HEAP) {
828
            _pred->set(v, a);
829
            _delta2->push(v, rw);
830
          } else if ((*_delta2)[v] > rw) {
831
            _pred->set(v, a);
832
            _delta2->decrease(v, rw);
833
          }
834
        }
835
      }
836
    }
837

	
838
    void matchedToOdd(Node node, int tree) {
839
      _tree_set->insert(node, tree);
840
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
841

	
842
      if (_delta2->state(node) == _delta2->IN_HEAP) {
843
        _delta2->erase(node);
844
      }
845
    }
846

	
847
    void evenToMatched(Node node, int tree) {
848
      _delta1->erase(node);
849
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
850
      Arc min = INVALID;
851
      Value minrw = std::numeric_limits<Value>::max();
852
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
853
        Node v = _graph.source(a);
854
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
855
          dualScale * _weight[a];
856

	
857
        if (node == v) {
858
          if (_allow_loops && _graph.direction(a)) {
859
            _delta3->erase(a);
860
          }
861
        } else if ((*_status)[v] == EVEN) {
862
          _delta3->erase(a);
863
          if (minrw > rw) {
864
            min = _graph.oppositeArc(a);
865
            minrw = rw;
866
          }
867
        } else if ((*_status)[v]  == MATCHED) {
868
          if ((*_pred)[v] == a) {
869
            Arc mina = INVALID;
870
            Value minrwa = std::numeric_limits<Value>::max();
871
            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
872
              Node va = _graph.target(aa);
873
              if ((*_status)[va] != EVEN ||
874
                  _tree_set->find(va) == tree) continue;
875
              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
876
                dualScale * _weight[aa];
877
              if (minrwa > rwa) {
878
                minrwa = rwa;
879
                mina = aa;
880
              }
881
            }
882
            if (mina != INVALID) {
883
              _pred->set(v, mina);
884
              _delta2->increase(v, minrwa);
885
            } else {
886
              _pred->set(v, INVALID);
887
              _delta2->erase(v);
888
            }
889
          }
890
        }
891
      }
892
      if (min != INVALID) {
893
        _pred->set(node, min);
894
        _delta2->push(node, minrw);
895
      } else {
896
        _pred->set(node, INVALID);
897
      }
898
    }
899

	
900
    void oddToMatched(Node node) {
901
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
902
      Arc min = INVALID;
903
      Value minrw = std::numeric_limits<Value>::max();
904
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
905
        Node v = _graph.source(a);
906
        if ((*_status)[v] != EVEN) continue;
907
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
908
          dualScale * _weight[a];
909

	
910
        if (minrw > rw) {
911
          min = _graph.oppositeArc(a);
912
          minrw = rw;
913
        }
914
      }
915
      if (min != INVALID) {
916
        _pred->set(node, min);
917
        _delta2->push(node, minrw);
918
      } else {
919
        _pred->set(node, INVALID);
920
      }
921
    }
922

	
923
    void alternatePath(Node even, int tree) {
924
      Node odd;
925

	
926
      _status->set(even, MATCHED);
927
      evenToMatched(even, tree);
928

	
929
      Arc prev = (*_matching)[even];
930
      while (prev != INVALID) {
931
        odd = _graph.target(prev);
932
        even = _graph.target((*_pred)[odd]);
933
        _matching->set(odd, (*_pred)[odd]);
934
        _status->set(odd, MATCHED);
935
        oddToMatched(odd);
936

	
937
        prev = (*_matching)[even];
938
        _status->set(even, MATCHED);
939
        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
940
        evenToMatched(even, tree);
941
      }
942
    }
943

	
944
    void destroyTree(int tree) {
945
      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
946
        if ((*_status)[n] == EVEN) {
947
          _status->set(n, MATCHED);
948
          evenToMatched(n, tree);
949
        } else if ((*_status)[n] == ODD) {
950
          _status->set(n, MATCHED);
951
          oddToMatched(n);
952
        }
953
      }
954
      _tree_set->eraseClass(tree);
955
    }
956

	
957

	
958
    void unmatchNode(const Node& node) {
959
      int tree = _tree_set->find(node);
960

	
961
      alternatePath(node, tree);
962
      destroyTree(tree);
963

	
964
      _matching->set(node, INVALID);
965
    }
966

	
967

	
968
    void augmentOnEdge(const Edge& edge) {
969
      Node left = _graph.u(edge);
970
      int left_tree = _tree_set->find(left);
971

	
972
      alternatePath(left, left_tree);
973
      destroyTree(left_tree);
974
      _matching->set(left, _graph.direct(edge, true));
975

	
976
      Node right = _graph.v(edge);
977
      int right_tree = _tree_set->find(right);
978

	
979
      alternatePath(right, right_tree);
980
      destroyTree(right_tree);
981
      _matching->set(right, _graph.direct(edge, false));
982
    }
983

	
984
    void augmentOnArc(const Arc& arc) {
985
      Node left = _graph.source(arc);
986
      _status->set(left, MATCHED);
987
      _matching->set(left, arc);
988
      _pred->set(left, arc);
989

	
990
      Node right = _graph.target(arc);
991
      int right_tree = _tree_set->find(right);
992

	
993
      alternatePath(right, right_tree);
994
      destroyTree(right_tree);
995
      _matching->set(right, _graph.oppositeArc(arc));
996
    }
997

	
998
    void extendOnArc(const Arc& arc) {
999
      Node base = _graph.target(arc);
1000
      int tree = _tree_set->find(base);
1001

	
1002
      Node odd = _graph.source(arc);
1003
      _tree_set->insert(odd, tree);
1004
      _status->set(odd, ODD);
1005
      matchedToOdd(odd, tree);
1006
      _pred->set(odd, arc);
1007

	
1008
      Node even = _graph.target((*_matching)[odd]);
1009
      _tree_set->insert(even, tree);
1010
      _status->set(even, EVEN);
1011
      matchedToEven(even, tree);
1012
    }
1013

	
1014
    void cycleOnEdge(const Edge& edge, int tree) {
1015
      Node nca = INVALID;
1016
      std::vector<Node> left_path, right_path;
1017

	
1018
      {
1019
        std::set<Node> left_set, right_set;
1020
        Node left = _graph.u(edge);
1021
        left_path.push_back(left);
1022
        left_set.insert(left);
1023

	
1024
        Node right = _graph.v(edge);
1025
        right_path.push_back(right);
1026
        right_set.insert(right);
1027

	
1028
        while (true) {
1029

	
1030
          if (left_set.find(right) != left_set.end()) {
1031
            nca = right;
1032
            break;
1033
          }
1034

	
1035
          if ((*_matching)[left] == INVALID) break;
1036

	
1037
          left = _graph.target((*_matching)[left]);
1038
          left_path.push_back(left);
1039
          left = _graph.target((*_pred)[left]);
1040
          left_path.push_back(left);
1041

	
1042
          left_set.insert(left);
1043

	
1044
          if (right_set.find(left) != right_set.end()) {
1045
            nca = left;
1046
            break;
1047
          }
1048

	
1049
          if ((*_matching)[right] == INVALID) break;
1050

	
1051
          right = _graph.target((*_matching)[right]);
1052
          right_path.push_back(right);
1053
          right = _graph.target((*_pred)[right]);
1054
          right_path.push_back(right);
1055

	
1056
          right_set.insert(right);
1057

	
1058
        }
1059

	
1060
        if (nca == INVALID) {
1061
          if ((*_matching)[left] == INVALID) {
1062
            nca = right;
1063
            while (left_set.find(nca) == left_set.end()) {
1064
              nca = _graph.target((*_matching)[nca]);
1065
              right_path.push_back(nca);
1066
              nca = _graph.target((*_pred)[nca]);
1067
              right_path.push_back(nca);
1068
            }
1069
          } else {
1070
            nca = left;
1071
            while (right_set.find(nca) == right_set.end()) {
1072
              nca = _graph.target((*_matching)[nca]);
1073
              left_path.push_back(nca);
1074
              nca = _graph.target((*_pred)[nca]);
1075
              left_path.push_back(nca);
1076
            }
1077
          }
1078
        }
1079
      }
1080

	
1081
      alternatePath(nca, tree);
1082
      Arc prev;
1083

	
1084
      prev = _graph.direct(edge, true);
1085
      for (int i = 0; left_path[i] != nca; i += 2) {
1086
        _matching->set(left_path[i], prev);
1087
        _status->set(left_path[i], MATCHED);
1088
        evenToMatched(left_path[i], tree);
1089

	
1090
        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
1091
        _status->set(left_path[i + 1], MATCHED);
1092
        oddToMatched(left_path[i + 1]);
1093
      }
1094
      _matching->set(nca, prev);
1095

	
1096
      for (int i = 0; right_path[i] != nca; i += 2) {
1097
        _status->set(right_path[i], MATCHED);
1098
        evenToMatched(right_path[i], tree);
1099

	
1100
        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
1101
        _status->set(right_path[i + 1], MATCHED);
1102
        oddToMatched(right_path[i + 1]);
1103
      }
1104

	
1105
      destroyTree(tree);
1106
    }
1107

	
1108
    void extractCycle(const Arc &arc) {
1109
      Node left = _graph.source(arc);
1110
      Node odd = _graph.target((*_matching)[left]);
1111
      Arc prev;
1112
      while (odd != left) {
1113
        Node even = _graph.target((*_matching)[odd]);
1114
        prev = (*_matching)[odd];
1115
        odd = _graph.target((*_matching)[even]);
1116
        _matching->set(even, _graph.oppositeArc(prev));
1117
      }
1118
      _matching->set(left, arc);
1119

	
1120
      Node right = _graph.target(arc);
1121
      int right_tree = _tree_set->find(right);
1122
      alternatePath(right, right_tree);
1123
      destroyTree(right_tree);
1124
      _matching->set(right, _graph.oppositeArc(arc));
1125
    }
1126

	
1127
  public:
1128

	
1129
    /// \brief Constructor
1130
    ///
1131
    /// Constructor.
1132
    MaxWeightedFractionalMatching(const Graph& graph, const WeightMap& weight,
1133
                                  bool allow_loops = true)
1134
      : _graph(graph), _weight(weight), _matching(0),
1135
      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
1136
      _status(0),  _pred(0),
1137
      _tree_set_index(0), _tree_set(0),
1138

	
1139
      _delta1_index(0), _delta1(0),
1140
      _delta2_index(0), _delta2(0),
1141
      _delta3_index(0), _delta3(0),
1142

	
1143
      _delta_sum() {}
1144

	
1145
    ~MaxWeightedFractionalMatching() {
1146
      destroyStructures();
1147
    }
1148

	
1149
    /// \name Execution Control
1150
    /// The simplest way to execute the algorithm is to use the
1151
    /// \ref run() member function.
1152

	
1153
    ///@{
1154

	
1155
    /// \brief Initialize the algorithm
1156
    ///
1157
    /// This function initializes the algorithm.
1158
    void init() {
1159
      createStructures();
1160

	
1161
      for (NodeIt n(_graph); n != INVALID; ++n) {
1162
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1163
        (*_delta2_index)[n] = _delta2->PRE_HEAP;
1164
      }
1165
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1166
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1167
      }
1168

	
1169
      _delta1->clear();
1170
      _delta2->clear();
1171
      _delta3->clear();
1172
      _tree_set->clear();
1173

	
1174
      for (NodeIt n(_graph); n != INVALID; ++n) {
1175
        Value max = 0;
1176
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1177
          if (_graph.target(e) == n && !_allow_loops) continue;
1178
          if ((dualScale * _weight[e]) / 2 > max) {
1179
            max = (dualScale * _weight[e]) / 2;
1180
          }
1181
        }
1182
        _node_potential->set(n, max);
1183
        _delta1->push(n, max);
1184

	
1185
        _tree_set->insert(n);
1186

	
1187
        _matching->set(n, INVALID);
1188
        _status->set(n, EVEN);
1189
      }
1190

	
1191
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1192
        Node left = _graph.u(e);
1193
        Node right = _graph.v(e);
1194
        if (left == right && !_allow_loops) continue;
1195
        _delta3->push(e, ((*_node_potential)[left] +
1196
                          (*_node_potential)[right] -
1197
                          dualScale * _weight[e]) / 2);
1198
      }
1199
    }
1200

	
1201
    /// \brief Start the algorithm
1202
    ///
1203
    /// This function starts the algorithm.
1204
    ///
1205
    /// \pre \ref init() must be called before using this function.
1206
    void start() {
1207
      enum OpType {
1208
        D1, D2, D3
1209
      };
1210

	
1211
      int unmatched = _node_num;
1212
      while (unmatched > 0) {
1213
        Value d1 = !_delta1->empty() ?
1214
          _delta1->prio() : std::numeric_limits<Value>::max();
1215

	
1216
        Value d2 = !_delta2->empty() ?
1217
          _delta2->prio() : std::numeric_limits<Value>::max();
1218

	
1219
        Value d3 = !_delta3->empty() ?
1220
          _delta3->prio() : std::numeric_limits<Value>::max();
1221

	
1222
        _delta_sum = d3; OpType ot = D3;
1223
        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
1224
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1225

	
1226
        switch (ot) {
1227
        case D1:
1228
          {
1229
            Node n = _delta1->top();
1230
            unmatchNode(n);
1231
            --unmatched;
1232
          }
1233
          break;
1234
        case D2:
1235
          {
1236
            Node n = _delta2->top();
1237
            Arc a = (*_pred)[n];
1238
            if ((*_matching)[n] == INVALID) {
1239
              augmentOnArc(a);
1240
              --unmatched;
1241
            } else {
1242
              Node v = _graph.target((*_matching)[n]);
1243
              if ((*_matching)[n] !=
1244
                  _graph.oppositeArc((*_matching)[v])) {
1245
                extractCycle(a);
1246
                --unmatched;
1247
              } else {
1248
                extendOnArc(a);
1249
              }
1250
            }
1251
          } break;
1252
        case D3:
1253
          {
1254
            Edge e = _delta3->top();
1255

	
1256
            Node left = _graph.u(e);
1257
            Node right = _graph.v(e);
1258

	
1259
            int left_tree = _tree_set->find(left);
1260
            int right_tree = _tree_set->find(right);
1261

	
1262
            if (left_tree == right_tree) {
1263
              cycleOnEdge(e, left_tree);
1264
              --unmatched;
1265
            } else {
1266
              augmentOnEdge(e);
1267
              unmatched -= 2;
1268
            }
1269
          } break;
1270
        }
1271
      }
1272
    }
1273

	
1274
    /// \brief Run the algorithm.
1275
    ///
1276
    /// This method runs the \c %MaxWeightedFractionalMatching algorithm.
1277
    ///
1278
    /// \note mwfm.run() is just a shortcut of the following code.
1279
    /// \code
1280
    ///   mwfm.init();
1281
    ///   mwfm.start();
1282
    /// \endcode
1283
    void run() {
1284
      init();
1285
      start();
1286
    }
1287

	
1288
    /// @}
1289

	
1290
    /// \name Primal Solution
1291
    /// Functions to get the primal solution, i.e. the maximum weighted
1292
    /// matching.\n
1293
    /// Either \ref run() or \ref start() function should be called before
1294
    /// using them.
1295

	
1296
    /// @{
1297

	
1298
    /// \brief Return the weight of the matching.
1299
    ///
1300
    /// This function returns the weight of the found matching. This
1301
    /// value is scaled by \ref primalScale "primal scale".
1302
    ///
1303
    /// \pre Either run() or start() must be called before using this function.
1304
    Value matchingWeight() const {
1305
      Value sum = 0;
1306
      for (NodeIt n(_graph); n != INVALID; ++n) {
1307
        if ((*_matching)[n] != INVALID) {
1308
          sum += _weight[(*_matching)[n]];
1309
        }
1310
      }
1311
      return sum * primalScale / 2;
1312
    }
1313

	
1314
    /// \brief Return the number of covered nodes in the matching.
1315
    ///
1316
    /// This function returns the number of covered nodes in the matching.
1317
    ///
1318
    /// \pre Either run() or start() must be called before using this function.
1319
    int matchingSize() const {
1320
      int num = 0;
1321
      for (NodeIt n(_graph); n != INVALID; ++n) {
1322
        if ((*_matching)[n] != INVALID) {
1323
          ++num;
1324
        }
1325
      }
1326
      return num;
1327
    }
1328

	
1329
    /// \brief Return \c true if the given edge is in the matching.
1330
    ///
1331
    /// This function returns \c true if the given edge is in the
1332
    /// found matching. The result is scaled by \ref primalScale
1333
    /// "primal scale".
1334
    ///
1335
    /// \pre Either run() or start() must be called before using this function.
1336
    int matching(const Edge& edge) const {
1337
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
1338
        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
1339
    }
1340

	
1341
    /// \brief Return the fractional matching arc (or edge) incident
1342
    /// to the given node.
1343
    ///
1344
    /// This function returns one of the fractional matching arc (or
1345
    /// edge) incident to the given node in the found matching or \c
1346
    /// INVALID if the node is not covered by the matching or if the
1347
    /// node is on an odd length cycle then it is the successor edge
1348
    /// on the cycle.
1349
    ///
1350
    /// \pre Either run() or start() must be called before using this function.
1351
    Arc matching(const Node& node) const {
1352
      return (*_matching)[node];
1353
    }
1354

	
1355
    /// \brief Return a const reference to the matching map.
1356
    ///
1357
    /// This function returns a const reference to a node map that stores
1358
    /// the matching arc (or edge) incident to each node.
1359
    const MatchingMap& matchingMap() const {
1360
      return *_matching;
1361
    }
1362

	
1363
    /// @}
1364

	
1365
    /// \name Dual Solution
1366
    /// Functions to get the dual solution.\n
1367
    /// Either \ref run() or \ref start() function should be called before
1368
    /// using them.
1369

	
1370
    /// @{
1371

	
1372
    /// \brief Return the value of the dual solution.
1373
    ///
1374
    /// This function returns the value of the dual solution.
1375
    /// It should be equal to the primal value scaled by \ref dualScale
1376
    /// "dual scale".
1377
    ///
1378
    /// \pre Either run() or start() must be called before using this function.
1379
    Value dualValue() const {
1380
      Value sum = 0;
1381
      for (NodeIt n(_graph); n != INVALID; ++n) {
1382
        sum += nodeValue(n);
1383
      }
1384
      return sum;
1385
    }
1386

	
1387
    /// \brief Return the dual value (potential) of the given node.
1388
    ///
1389
    /// This function returns the dual value (potential) of the given node.
1390
    ///
1391
    /// \pre Either run() or start() must be called before using this function.
1392
    Value nodeValue(const Node& n) const {
1393
      return (*_node_potential)[n];
1394
    }
1395

	
1396
    /// @}
1397

	
1398
  };
1399

	
1400
  /// \ingroup matching
1401
  ///
1402
  /// \brief Weighted fractional perfect matching in general graphs
1403
  ///
1404
  /// This class provides an efficient implementation of fractional
1405
  /// matching algorithm. The implementation uses priority queues and
1406
  /// provides \f$O(nm\log n)\f$ time complexity.
1407
  ///
1408
  /// The maximum weighted fractional perfect matching is a relaxation
1409
  /// of the maximum weighted perfect matching problem where the odd
1410
  /// set constraints are omitted.
1411
  /// It can be formulated with the following linear program.
1412
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
1413
  /// \f[x_e \ge 0\quad \forall e\in E\f]
1414
  /// \f[\max \sum_{e\in E}x_ew_e\f]
1415
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
1416
  /// \f$X\f$. The result must be the union of a matching with one
1417
  /// value edges and a set of odd length cycles with half value edges.
1418
  ///
1419
  /// The algorithm calculates an optimal fractional matching and a
1420
  /// proof of the optimality. The solution of the dual problem can be
1421
  /// used to check the result of the algorithm. The dual linear
1422
  /// problem is the following.
1423
  /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
1424
  /// \f[\min \sum_{u \in V}y_u \f]
1425
  ///
1426
  /// The algorithm can be executed with the run() function.
1427
  /// After it the matching (the primal solution) and the dual solution
1428
  /// can be obtained using the query functions.
1429
  ///
1430
  /// The primal solution is multiplied by
1431
  /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2".
1432
  /// If the value type is integer, then the dual
1433
  /// solution is scaled by
1434
  /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4".
1435
  ///
1436
  /// \tparam GR The undirected graph type the algorithm runs on.
1437
  /// \tparam WM The type edge weight map. The default type is
1438
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
1439
#ifdef DOXYGEN
1440
  template <typename GR, typename WM>
1441
#else
1442
  template <typename GR,
1443
            typename WM = typename GR::template EdgeMap<int> >
1444
#endif
1445
  class MaxWeightedPerfectFractionalMatching {
1446
  public:
1447

	
1448
    /// The graph type of the algorithm
1449
    typedef GR Graph;
1450
    /// The type of the edge weight map
1451
    typedef WM WeightMap;
1452
    /// The value type of the edge weights
1453
    typedef typename WeightMap::Value Value;
1454

	
1455
    /// The type of the matching map
1456
    typedef typename Graph::template NodeMap<typename Graph::Arc>
1457
    MatchingMap;
1458

	
1459
    /// \brief Scaling factor for primal solution
1460
    ///
1461
    /// Scaling factor for primal solution.
1462
    static const int primalScale = 2;
1463

	
1464
    /// \brief Scaling factor for dual solution
1465
    ///
1466
    /// Scaling factor for dual solution. It is equal to 4 or 1
1467
    /// according to the value type.
1468
    static const int dualScale =
1469
      std::numeric_limits<Value>::is_integer ? 4 : 1;
1470

	
1471
  private:
1472

	
1473
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1474

	
1475
    typedef typename Graph::template NodeMap<Value> NodePotential;
1476

	
1477
    const Graph& _graph;
1478
    const WeightMap& _weight;
1479

	
1480
    MatchingMap* _matching;
1481
    NodePotential* _node_potential;
1482

	
1483
    int _node_num;
1484
    bool _allow_loops;
1485

	
1486
    enum Status {
1487
      EVEN = -1, MATCHED = 0, ODD = 1
1488
    };
1489

	
1490
    typedef typename Graph::template NodeMap<Status> StatusMap;
1491
    StatusMap* _status;
1492

	
1493
    typedef typename Graph::template NodeMap<Arc> PredMap;
1494
    PredMap* _pred;
1495

	
1496
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
1497

	
1498
    IntNodeMap *_tree_set_index;
1499
    TreeSet *_tree_set;
1500

	
1501
    IntNodeMap *_delta2_index;
1502
    BinHeap<Value, IntNodeMap> *_delta2;
1503

	
1504
    IntEdgeMap *_delta3_index;
1505
    BinHeap<Value, IntEdgeMap> *_delta3;
1506

	
1507
    Value _delta_sum;
1508

	
1509
    void createStructures() {
1510
      _node_num = countNodes(_graph);
1511

	
1512
      if (!_matching) {
1513
        _matching = new MatchingMap(_graph);
1514
      }
1515
      if (!_node_potential) {
1516
        _node_potential = new NodePotential(_graph);
1517
      }
1518
      if (!_status) {
1519
        _status = new StatusMap(_graph);
1520
      }
1521
      if (!_pred) {
1522
        _pred = new PredMap(_graph);
1523
      }
1524
      if (!_tree_set) {
1525
        _tree_set_index = new IntNodeMap(_graph);
1526
        _tree_set = new TreeSet(*_tree_set_index);
1527
      }
1528
      if (!_delta2) {
1529
        _delta2_index = new IntNodeMap(_graph);
1530
        _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
1531
      }
1532
      if (!_delta3) {
1533
        _delta3_index = new IntEdgeMap(_graph);
1534
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
1535
      }
1536
    }
1537

	
1538
    void destroyStructures() {
1539
      if (_matching) {
1540
        delete _matching;
1541
      }
1542
      if (_node_potential) {
1543
        delete _node_potential;
1544
      }
1545
      if (_status) {
1546
        delete _status;
1547
      }
1548
      if (_pred) {
1549
        delete _pred;
1550
      }
1551
      if (_tree_set) {
1552
        delete _tree_set_index;
1553
        delete _tree_set;
1554
      }
1555
      if (_delta2) {
1556
        delete _delta2_index;
1557
        delete _delta2;
1558
      }
1559
      if (_delta3) {
1560
        delete _delta3_index;
1561
        delete _delta3;
1562
      }
1563
    }
1564

	
1565
    void matchedToEven(Node node, int tree) {
1566
      _tree_set->insert(node, tree);
1567
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
1568

	
1569
      if (_delta2->state(node) == _delta2->IN_HEAP) {
1570
        _delta2->erase(node);
1571
      }
1572

	
1573
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
1574
        Node v = _graph.source(a);
1575
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
1576
          dualScale * _weight[a];
1577
        if (node == v) {
1578
          if (_allow_loops && _graph.direction(a)) {
1579
            _delta3->push(a, rw / 2);
1580
          }
1581
        } else if ((*_status)[v] == EVEN) {
1582
          _delta3->push(a, rw / 2);
1583
        } else if ((*_status)[v] == MATCHED) {
1584
          if (_delta2->state(v) != _delta2->IN_HEAP) {
1585
            _pred->set(v, a);
1586
            _delta2->push(v, rw);
1587
          } else if ((*_delta2)[v] > rw) {
1588
            _pred->set(v, a);
1589
            _delta2->decrease(v, rw);
1590
          }
1591
        }
1592
      }
1593
    }
1594

	
1595
    void matchedToOdd(Node node, int tree) {
1596
      _tree_set->insert(node, tree);
1597
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
1598

	
1599
      if (_delta2->state(node) == _delta2->IN_HEAP) {
1600
        _delta2->erase(node);
1601
      }
1602
    }
1603

	
1604
    void evenToMatched(Node node, int tree) {
1605
      _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
1606
      Arc min = INVALID;
1607
      Value minrw = std::numeric_limits<Value>::max();
1608
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
1609
        Node v = _graph.source(a);
1610
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
1611
          dualScale * _weight[a];
1612

	
1613
        if (node == v) {
1614
          if (_allow_loops && _graph.direction(a)) {
1615
            _delta3->erase(a);
1616
          }
1617
        } else if ((*_status)[v] == EVEN) {
1618
          _delta3->erase(a);
1619
          if (minrw > rw) {
1620
            min = _graph.oppositeArc(a);
1621
            minrw = rw;
1622
          }
1623
        } else if ((*_status)[v]  == MATCHED) {
1624
          if ((*_pred)[v] == a) {
1625
            Arc mina = INVALID;
1626
            Value minrwa = std::numeric_limits<Value>::max();
1627
            for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
1628
              Node va = _graph.target(aa);
1629
              if ((*_status)[va] != EVEN ||
1630
                  _tree_set->find(va) == tree) continue;
1631
              Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
1632
                dualScale * _weight[aa];
1633
              if (minrwa > rwa) {
1634
                minrwa = rwa;
1635
                mina = aa;
1636
              }
1637
            }
1638
            if (mina != INVALID) {
1639
              _pred->set(v, mina);
1640
              _delta2->increase(v, minrwa);
1641
            } else {
1642
              _pred->set(v, INVALID);
1643
              _delta2->erase(v);
1644
            }
1645
          }
1646
        }
1647
      }
1648
      if (min != INVALID) {
1649
        _pred->set(node, min);
1650
        _delta2->push(node, minrw);
1651
      } else {
1652
        _pred->set(node, INVALID);
1653
      }
1654
    }
1655

	
1656
    void oddToMatched(Node node) {
1657
      _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
1658
      Arc min = INVALID;
1659
      Value minrw = std::numeric_limits<Value>::max();
1660
      for (InArcIt a(_graph, node); a != INVALID; ++a) {
1661
        Node v = _graph.source(a);
1662
        if ((*_status)[v] != EVEN) continue;
1663
        Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
1664
          dualScale * _weight[a];
1665

	
1666
        if (minrw > rw) {
1667
          min = _graph.oppositeArc(a);
1668
          minrw = rw;
1669
        }
1670
      }
1671
      if (min != INVALID) {
1672
        _pred->set(node, min);
1673
        _delta2->push(node, minrw);
1674
      } else {
1675
        _pred->set(node, INVALID);
1676
      }
1677
    }
1678

	
1679
    void alternatePath(Node even, int tree) {
1680
      Node odd;
1681

	
1682
      _status->set(even, MATCHED);
1683
      evenToMatched(even, tree);
1684

	
1685
      Arc prev = (*_matching)[even];
1686
      while (prev != INVALID) {
1687
        odd = _graph.target(prev);
1688
        even = _graph.target((*_pred)[odd]);
1689
        _matching->set(odd, (*_pred)[odd]);
1690
        _status->set(odd, MATCHED);
1691
        oddToMatched(odd);
1692

	
1693
        prev = (*_matching)[even];
1694
        _status->set(even, MATCHED);
1695
        _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
1696
        evenToMatched(even, tree);
1697
      }
1698
    }
1699

	
1700
    void destroyTree(int tree) {
1701
      for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
1702
        if ((*_status)[n] == EVEN) {
1703
          _status->set(n, MATCHED);
1704
          evenToMatched(n, tree);
1705
        } else if ((*_status)[n] == ODD) {
1706
          _status->set(n, MATCHED);
1707
          oddToMatched(n);
1708
        }
1709
      }
1710
      _tree_set->eraseClass(tree);
1711
    }
1712

	
1713
    void augmentOnEdge(const Edge& edge) {
1714
      Node left = _graph.u(edge);
1715
      int left_tree = _tree_set->find(left);
1716

	
1717
      alternatePath(left, left_tree);
1718
      destroyTree(left_tree);
1719
      _matching->set(left, _graph.direct(edge, true));
1720

	
1721
      Node right = _graph.v(edge);
1722
      int right_tree = _tree_set->find(right);
1723

	
1724
      alternatePath(right, right_tree);
1725
      destroyTree(right_tree);
1726
      _matching->set(right, _graph.direct(edge, false));
1727
    }
1728

	
1729
    void augmentOnArc(const Arc& arc) {
1730
      Node left = _graph.source(arc);
1731
      _status->set(left, MATCHED);
1732
      _matching->set(left, arc);
1733
      _pred->set(left, arc);
1734

	
1735
      Node right = _graph.target(arc);
1736
      int right_tree = _tree_set->find(right);
1737

	
1738
      alternatePath(right, right_tree);
1739
      destroyTree(right_tree);
1740
      _matching->set(right, _graph.oppositeArc(arc));
1741
    }
1742

	
1743
    void extendOnArc(const Arc& arc) {
1744
      Node base = _graph.target(arc);
1745
      int tree = _tree_set->find(base);
1746

	
1747
      Node odd = _graph.source(arc);
1748
      _tree_set->insert(odd, tree);
1749
      _status->set(odd, ODD);
1750
      matchedToOdd(odd, tree);
1751
      _pred->set(odd, arc);
1752

	
1753
      Node even = _graph.target((*_matching)[odd]);
1754
      _tree_set->insert(even, tree);
1755
      _status->set(even, EVEN);
1756
      matchedToEven(even, tree);
1757
    }
1758

	
1759
    void cycleOnEdge(const Edge& edge, int tree) {
1760
      Node nca = INVALID;
1761
      std::vector<Node> left_path, right_path;
1762

	
1763
      {
1764
        std::set<Node> left_set, right_set;
1765
        Node left = _graph.u(edge);
1766
        left_path.push_back(left);
1767
        left_set.insert(left);
1768

	
1769
        Node right = _graph.v(edge);
1770
        right_path.push_back(right);
1771
        right_set.insert(right);
1772

	
1773
        while (true) {
1774

	
1775
          if (left_set.find(right) != left_set.end()) {
1776
            nca = right;
1777
            break;
1778
          }
1779

	
1780
          if ((*_matching)[left] == INVALID) break;
1781

	
1782
          left = _graph.target((*_matching)[left]);
1783
          left_path.push_back(left);
1784
          left = _graph.target((*_pred)[left]);
1785
          left_path.push_back(left);
1786

	
1787
          left_set.insert(left);
1788

	
1789
          if (right_set.find(left) != right_set.end()) {
1790
            nca = left;
1791
            break;
1792
          }
1793

	
1794
          if ((*_matching)[right] == INVALID) break;
1795

	
1796
          right = _graph.target((*_matching)[right]);
1797
          right_path.push_back(right);
1798
          right = _graph.target((*_pred)[right]);
1799
          right_path.push_back(right);
1800

	
1801
          right_set.insert(right);
1802

	
1803
        }
1804

	
1805
        if (nca == INVALID) {
1806
          if ((*_matching)[left] == INVALID) {
1807
            nca = right;
1808
            while (left_set.find(nca) == left_set.end()) {
1809
              nca = _graph.target((*_matching)[nca]);
1810
              right_path.push_back(nca);
1811
              nca = _graph.target((*_pred)[nca]);
1812
              right_path.push_back(nca);
1813
            }
1814
          } else {
1815
            nca = left;
1816
            while (right_set.find(nca) == right_set.end()) {
1817
              nca = _graph.target((*_matching)[nca]);
1818
              left_path.push_back(nca);
1819
              nca = _graph.target((*_pred)[nca]);
1820
              left_path.push_back(nca);
1821
            }
1822
          }
1823
        }
1824
      }
1825

	
1826
      alternatePath(nca, tree);
1827
      Arc prev;
1828

	
1829
      prev = _graph.direct(edge, true);
1830
      for (int i = 0; left_path[i] != nca; i += 2) {
1831
        _matching->set(left_path[i], prev);
1832
        _status->set(left_path[i], MATCHED);
1833
        evenToMatched(left_path[i], tree);
1834

	
1835
        prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
1836
        _status->set(left_path[i + 1], MATCHED);
1837
        oddToMatched(left_path[i + 1]);
1838
      }
1839
      _matching->set(nca, prev);
1840

	
1841
      for (int i = 0; right_path[i] != nca; i += 2) {
1842
        _status->set(right_path[i], MATCHED);
1843
        evenToMatched(right_path[i], tree);
1844

	
1845
        _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
1846
        _status->set(right_path[i + 1], MATCHED);
1847
        oddToMatched(right_path[i + 1]);
1848
      }
1849

	
1850
      destroyTree(tree);
1851
    }
1852

	
1853
    void extractCycle(const Arc &arc) {
1854
      Node left = _graph.source(arc);
1855
      Node odd = _graph.target((*_matching)[left]);
1856
      Arc prev;
1857
      while (odd != left) {
1858
        Node even = _graph.target((*_matching)[odd]);
1859
        prev = (*_matching)[odd];
1860
        odd = _graph.target((*_matching)[even]);
1861
        _matching->set(even, _graph.oppositeArc(prev));
1862
      }
1863
      _matching->set(left, arc);
1864

	
1865
      Node right = _graph.target(arc);
1866
      int right_tree = _tree_set->find(right);
1867
      alternatePath(right, right_tree);
1868
      destroyTree(right_tree);
1869
      _matching->set(right, _graph.oppositeArc(arc));
1870
    }
1871

	
1872
  public:
1873

	
1874
    /// \brief Constructor
1875
    ///
1876
    /// Constructor.
1877
    MaxWeightedPerfectFractionalMatching(const Graph& graph,
1878
                                         const WeightMap& weight,
1879
                                         bool allow_loops = true)
1880
      : _graph(graph), _weight(weight), _matching(0),
1881
      _node_potential(0), _node_num(0), _allow_loops(allow_loops),
1882
      _status(0),  _pred(0),
1883
      _tree_set_index(0), _tree_set(0),
1884

	
1885
      _delta2_index(0), _delta2(0),
1886
      _delta3_index(0), _delta3(0),
1887

	
1888
      _delta_sum() {}
1889

	
1890
    ~MaxWeightedPerfectFractionalMatching() {
1891
      destroyStructures();
1892
    }
1893

	
1894
    /// \name Execution Control
1895
    /// The simplest way to execute the algorithm is to use the
1896
    /// \ref run() member function.
1897

	
1898
    ///@{
1899

	
1900
    /// \brief Initialize the algorithm
1901
    ///
1902
    /// This function initializes the algorithm.
1903
    void init() {
1904
      createStructures();
1905

	
1906
      for (NodeIt n(_graph); n != INVALID; ++n) {
1907
        (*_delta2_index)[n] = _delta2->PRE_HEAP;
1908
      }
1909
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1910
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1911
      }
1912

	
1913
      _delta2->clear();
1914
      _delta3->clear();
1915
      _tree_set->clear();
1916

	
1917
      for (NodeIt n(_graph); n != INVALID; ++n) {
1918
        Value max = - std::numeric_limits<Value>::max();
1919
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1920
          if (_graph.target(e) == n && !_allow_loops) continue;
1921
          if ((dualScale * _weight[e]) / 2 > max) {
1922
            max = (dualScale * _weight[e]) / 2;
1923
          }
1924
        }
1925
        _node_potential->set(n, max);
1926

	
1927
        _tree_set->insert(n);
1928

	
1929
        _matching->set(n, INVALID);
1930
        _status->set(n, EVEN);
1931
      }
1932

	
1933
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1934
        Node left = _graph.u(e);
1935
        Node right = _graph.v(e);
1936
        if (left == right && !_allow_loops) continue;
1937
        _delta3->push(e, ((*_node_potential)[left] +
1938
                          (*_node_potential)[right] -
1939
                          dualScale * _weight[e]) / 2);
1940
      }
1941
    }
1942

	
1943
    /// \brief Start the algorithm
1944
    ///
1945
    /// This function starts the algorithm.
1946
    ///
1947
    /// \pre \ref init() must be called before using this function.
1948
    bool start() {
1949
      enum OpType {
1950
        D2, D3
1951
      };
1952

	
1953
      int unmatched = _node_num;
1954
      while (unmatched > 0) {
1955
        Value d2 = !_delta2->empty() ?
1956
          _delta2->prio() : std::numeric_limits<Value>::max();
1957

	
1958
        Value d3 = !_delta3->empty() ?
1959
          _delta3->prio() : std::numeric_limits<Value>::max();
1960

	
1961
        _delta_sum = d3; OpType ot = D3;
1962
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1963

	
1964
        if (_delta_sum == std::numeric_limits<Value>::max()) {
1965
          return false;
1966
        }
1967

	
1968
        switch (ot) {
1969
        case D2:
1970
          {
1971
            Node n = _delta2->top();
1972
            Arc a = (*_pred)[n];
1973
            if ((*_matching)[n] == INVALID) {
1974
              augmentOnArc(a);
1975
              --unmatched;
1976
            } else {
1977
              Node v = _graph.target((*_matching)[n]);
1978
              if ((*_matching)[n] !=
1979
                  _graph.oppositeArc((*_matching)[v])) {
1980
                extractCycle(a);
1981
                --unmatched;
1982
              } else {
1983
                extendOnArc(a);
1984
              }
1985
            }
1986
          } break;
1987
        case D3:
1988
          {
1989
            Edge e = _delta3->top();
1990

	
1991
            Node left = _graph.u(e);
1992
            Node right = _graph.v(e);
1993

	
1994
            int left_tree = _tree_set->find(left);
1995
            int right_tree = _tree_set->find(right);
1996

	
1997
            if (left_tree == right_tree) {
1998
              cycleOnEdge(e, left_tree);
1999
              --unmatched;
2000
            } else {
2001
              augmentOnEdge(e);
2002
              unmatched -= 2;
2003
            }
2004
          } break;
2005
        }
2006
      }
2007
      return true;
2008
    }
2009

	
2010
    /// \brief Run the algorithm.
2011
    ///
2012
    /// This method runs the \c %MaxWeightedPerfectFractionalMatching
2013
    /// algorithm.
2014
    ///
2015
    /// \note mwfm.run() is just a shortcut of the following code.
2016
    /// \code
2017
    ///   mwpfm.init();
2018
    ///   mwpfm.start();
2019
    /// \endcode
2020
    bool run() {
2021
      init();
2022
      return start();
2023
    }
2024

	
2025
    /// @}
2026

	
2027
    /// \name Primal Solution
2028
    /// Functions to get the primal solution, i.e. the maximum weighted
2029
    /// matching.\n
2030
    /// Either \ref run() or \ref start() function should be called before
2031
    /// using them.
2032

	
2033
    /// @{
2034

	
2035
    /// \brief Return the weight of the matching.
2036
    ///
2037
    /// This function returns the weight of the found matching. This
2038
    /// value is scaled by \ref primalScale "primal scale".
2039
    ///
2040
    /// \pre Either run() or start() must be called before using this function.
2041
    Value matchingWeight() const {
2042
      Value sum = 0;
2043
      for (NodeIt n(_graph); n != INVALID; ++n) {
2044
        if ((*_matching)[n] != INVALID) {
2045
          sum += _weight[(*_matching)[n]];
2046
        }
2047
      }
2048
      return sum * primalScale / 2;
2049
    }
2050

	
2051
    /// \brief Return the number of covered nodes in the matching.
2052
    ///
2053
    /// This function returns the number of covered nodes in the matching.
2054
    ///
2055
    /// \pre Either run() or start() must be called before using this function.
2056
    int matchingSize() const {
2057
      int num = 0;
2058
      for (NodeIt n(_graph); n != INVALID; ++n) {
2059
        if ((*_matching)[n] != INVALID) {
2060
          ++num;
2061
        }
2062
      }
2063
      return num;
2064
    }
2065

	
2066
    /// \brief Return \c true if the given edge is in the matching.
2067
    ///
2068
    /// This function returns \c true if the given edge is in the
2069
    /// found matching. The result is scaled by \ref primalScale
2070
    /// "primal scale".
2071
    ///
2072
    /// \pre Either run() or start() must be called before using this function.
2073
    int matching(const Edge& edge) const {
2074
      return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
2075
        + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
2076
    }
2077

	
2078
    /// \brief Return the fractional matching arc (or edge) incident
2079
    /// to the given node.
2080
    ///
2081
    /// This function returns one of the fractional matching arc (or
2082
    /// edge) incident to the given node in the found matching or \c
2083
    /// INVALID if the node is not covered by the matching or if the
2084
    /// node is on an odd length cycle then it is the successor edge
2085
    /// on the cycle.
2086
    ///
2087
    /// \pre Either run() or start() must be called before using this function.
2088
    Arc matching(const Node& node) const {
2089
      return (*_matching)[node];
2090
    }
2091

	
2092
    /// \brief Return a const reference to the matching map.
2093
    ///
2094
    /// This function returns a const reference to a node map that stores
2095
    /// the matching arc (or edge) incident to each node.
2096
    const MatchingMap& matchingMap() const {
2097
      return *_matching;
2098
    }
2099

	
2100
    /// @}
2101

	
2102
    /// \name Dual Solution
2103
    /// Functions to get the dual solution.\n
2104
    /// Either \ref run() or \ref start() function should be called before
2105
    /// using them.
2106

	
2107
    /// @{
2108

	
2109
    /// \brief Return the value of the dual solution.
2110
    ///
2111
    /// This function returns the value of the dual solution.
2112
    /// It should be equal to the primal value scaled by \ref dualScale
2113
    /// "dual scale".
2114
    ///
2115
    /// \pre Either run() or start() must be called before using this function.
2116
    Value dualValue() const {
2117
      Value sum = 0;
2118
      for (NodeIt n(_graph); n != INVALID; ++n) {
2119
        sum += nodeValue(n);
2120
      }
2121
      return sum;
2122
    }
2123

	
2124
    /// \brief Return the dual value (potential) of the given node.
2125
    ///
2126
    /// This function returns the dual value (potential) of the given node.
2127
    ///
2128
    /// \pre Either run() or start() must be called before using this function.
2129
    Value nodeValue(const Node& n) const {
2130
      return (*_node_potential)[n];
2131
    }
2132

	
2133
    /// @}
2134

	
2135
  };
2136

	
2137
} //END OF NAMESPACE LEMON
2138

	
2139
#endif //LEMON_FRACTIONAL_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-2010
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_MMC_H
20
#define LEMON_HARTMANN_ORLIN_MMC_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 HartmannOrlinMmc class.
37
  ///
38
  /// Default traits class of HartmannOrlinMmc class.
39
  /// \tparam GR The type of the digraph.
40
  /// \tparam CM The type of the cost map.
41
  /// It must conform to the \ref concepts::Rea_data "Rea_data" concept.
42
#ifdef DOXYGEN
43
  template <typename GR, typename CM>
44
#else
45
  template <typename GR, typename CM,
46
    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
47
#endif
48
  struct HartmannOrlinMmcDefaultTraits
49
  {
50
    /// The type of the digraph
51
    typedef GR Digraph;
52
    /// The type of the cost map
53
    typedef CM CostMap;
54
    /// The type of the arc costs
55
    typedef typename CostMap::Value Cost;
56

	
57
    /// \brief The large cost type used for internal computations
58
    ///
59
    /// The large cost type used for internal computations.
60
    /// It is \c long \c long if the \c Cost type is integer,
61
    /// otherwise it is \c double.
62
    /// \c Cost must be convertible to \c LargeCost.
63
    typedef double LargeCost;
64

	
65
    /// The tolerance type used for internal computations
66
    typedef lemon::Tolerance<LargeCost> 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 cost types
77
  template <typename GR, typename CM>
78
  struct HartmannOrlinMmcDefaultTraits<GR, CM, true>
79
  {
80
    typedef GR Digraph;
81
    typedef CM CostMap;
82
    typedef typename CostMap::Value Cost;
83
#ifdef LEMON_HAVE_LONG_LONG
84
    typedef long long LargeCost;
85
#else
86
    typedef long LargeCost;
87
#endif
88
    typedef lemon::Tolerance<LargeCost> 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 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 CM The type of the cost map. The default
108
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
109
  /// \tparam TR The traits class that defines various types used by the
110
  /// algorithm. By default, it is \ref HartmannOrlinMmcDefaultTraits
111
  /// "HartmannOrlinMmcDefaultTraits<GR, CM>".
112
  /// In most cases, this parameter should not be set directly,
113
  /// consider to use the named template parameters instead.
114
#ifdef DOXYGEN
115
  template <typename GR, typename CM, typename TR>
116
#else
117
  template < typename GR,
118
             typename CM = typename GR::template ArcMap<int>,
119
             typename TR = HartmannOrlinMmcDefaultTraits<GR, CM> >
120
#endif
121
  class HartmannOrlinMmc
122
  {
123
  public:
124

	
125
    /// The type of the digraph
126
    typedef typename TR::Digraph Digraph;
127
    /// The type of the cost map
128
    typedef typename TR::CostMap CostMap;
129
    /// The type of the arc costs
130
    typedef typename TR::Cost Cost;
131

	
132
    /// \brief The large cost type
133
    ///
134
    /// The large cost type used for internal computations.
135
    /// By default, it is \c long \c long if the \c Cost type is integer,
136
    /// otherwise it is \c double.
137
    typedef typename TR::LargeCost LargeCost;
138

	
139
    /// The tolerance type
140
    typedef typename TR::Tolerance Tolerance;
141

	
142
    /// \brief The path type of the found cycles
143
    ///
144
    /// The path type of the found cycles.
145
    /// Using the \ref HartmannOrlinMmcDefaultTraits "default traits class",
146
    /// it is \ref lemon::Path "Path<Digraph>".
147
    typedef typename TR::Path Path;
148

	
149
    /// The \ref HartmannOrlinMmcDefaultTraits "traits class" of the algorithm
150
    typedef TR Traits;
151

	
152
  private:
153

	
154
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
155

	
156
    // Data sturcture for path data
157
    struct PathData
158
    {
159
      LargeCost dist;
160
      Arc pred;
161
      PathData(LargeCost d, Arc p = INVALID) :
162
        dist(d), pred(p) {}
163
    };
164

	
165
    typedef typename Digraph::template NodeMap<std::vector<PathData> >
166
      PathDataNodeMap;
167

	
168
  private:
169

	
170
    // The digraph the algorithm runs on
171
    const Digraph &_gr;
172
    // The cost of the arcs
173
    const CostMap &_cost;
174

	
175
    // Data for storing the strongly connected components
176
    int _comp_num;
177
    typename Digraph::template NodeMap<int> _comp;
178
    std::vector<std::vector<Node> > _comp_nodes;
179
    std::vector<Node>* _nodes;
180
    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
181

	
182
    // Data for the found cycles
183
    bool _curr_found, _best_found;
184
    LargeCost _curr_cost, _best_cost;
185
    int _curr_size, _best_size;
186
    Node _curr_node, _best_node;
187
    int _curr_level, _best_level;
188

	
189
    Path *_cycle_path;
190
    bool _local_path;
191

	
192
    // Node map for storing path data
193
    PathDataNodeMap _data;
194
    // The processed nodes in the last round
195
    std::vector<Node> _process;
196

	
197
    Tolerance _tolerance;
198

	
199
    // Infinite constant
200
    const LargeCost INF;
201

	
202
  public:
203

	
204
    /// \name Named Template Parameters
205
    /// @{
206

	
207
    template <typename T>
208
    struct SetLargeCostTraits : public Traits {
209
      typedef T LargeCost;
210
      typedef lemon::Tolerance<T> Tolerance;
211
    };
212

	
213
    /// \brief \ref named-templ-param "Named parameter" for setting
214
    /// \c LargeCost type.
215
    ///
216
    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
217
    /// type. It is used for internal computations in the algorithm.
218
    template <typename T>
219
    struct SetLargeCost
220
      : public HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > {
221
      typedef HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > Create;
222
    };
223

	
224
    template <typename T>
225
    struct SetPathTraits : public Traits {
226
      typedef T Path;
227
    };
228

	
229
    /// \brief \ref named-templ-param "Named parameter" for setting
230
    /// \c %Path type.
231
    ///
232
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
233
    /// type of the found cycles.
234
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
235
    /// and it must have an \c addFront() function.
236
    template <typename T>
237
    struct SetPath
238
      : public HartmannOrlinMmc<GR, CM, SetPathTraits<T> > {
239
      typedef HartmannOrlinMmc<GR, CM, SetPathTraits<T> > Create;
240
    };
241

	
242
    /// @}
243

	
244
  protected:
245

	
246
    HartmannOrlinMmc() {}
247

	
248
  public:
249

	
250
    /// \brief Constructor.
251
    ///
252
    /// The constructor of the class.
253
    ///
254
    /// \param digraph The digraph the algorithm runs on.
255
    /// \param cost The costs of the arcs.
256
    HartmannOrlinMmc( const Digraph &digraph,
257
                      const CostMap &cost ) :
258
      _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
259
      _best_found(false), _best_cost(0), _best_size(1),
260
      _cycle_path(NULL), _local_path(false), _data(digraph),
261
      INF(std::numeric_limits<LargeCost>::has_infinity ?
262
          std::numeric_limits<LargeCost>::infinity() :
263
          std::numeric_limits<LargeCost>::max())
264
    {}
265

	
266
    /// Destructor.
267
    ~HartmannOrlinMmc() {
268
      if (_local_path) delete _cycle_path;
269
    }
270

	
271
    /// \brief Set the path structure for storing the found cycle.
272
    ///
273
    /// This function sets an external path structure for storing the
274
    /// found cycle.
275
    ///
276
    /// If you don't call this function before calling \ref run() or
277
    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
278
    /// structure. The destuctor deallocates this automatically
279
    /// allocated object, of course.
280
    ///
281
    /// \note The algorithm calls only the \ref lemon::Path::addFront()
282
    /// "addFront()" function of the given path structure.
283
    ///
284
    /// \return <tt>(*this)</tt>
285
    HartmannOrlinMmc& cycle(Path &path) {
286
      if (_local_path) {
287
        delete _cycle_path;
288
        _local_path = false;
289
      }
290
      _cycle_path = &path;
291
      return *this;
292
    }
293

	
294
    /// \brief Set the tolerance used by the algorithm.
295
    ///
296
    /// This function sets the tolerance object used by the algorithm.
297
    ///
298
    /// \return <tt>(*this)</tt>
299
    HartmannOrlinMmc& tolerance(const Tolerance& tolerance) {
300
      _tolerance = tolerance;
301
      return *this;
302
    }
303

	
304
    /// \brief Return a const reference to the tolerance.
305
    ///
306
    /// This function returns a const reference to the tolerance object
307
    /// used by the algorithm.
308
    const Tolerance& tolerance() const {
309
      return _tolerance;
310
    }
311

	
312
    /// \name Execution control
313
    /// The simplest way to execute the algorithm is to call the \ref run()
314
    /// function.\n
315
    /// If you only need the minimum mean cost, you may call
316
    /// \ref findCycleMean().
317

	
318
    /// @{
319

	
320
    /// \brief Run the algorithm.
321
    ///
322
    /// This function runs the algorithm.
323
    /// It can be called more than once (e.g. if the underlying digraph
324
    /// and/or the arc costs have been modified).
325
    ///
326
    /// \return \c true if a directed cycle exists in the digraph.
327
    ///
328
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
329
    /// \code
330
    ///   return mmc.findCycleMean() && mmc.findCycle();
331
    /// \endcode
332
    bool run() {
333
      return findCycleMean() && findCycle();
334
    }
335

	
336
    /// \brief Find the minimum cycle mean.
337
    ///
338
    /// This function finds the minimum mean cost of the directed
339
    /// cycles in the digraph.
340
    ///
341
    /// \return \c true if a directed cycle exists in the digraph.
342
    bool findCycleMean() {
343
      // Initialization and find strongly connected components
344
      init();
345
      findComponents();
346

	
347
      // Find the minimum cycle mean in the components
348
      for (int comp = 0; comp < _comp_num; ++comp) {
349
        if (!initComponent(comp)) continue;
350
        processRounds();
351

	
352
        // Update the best cycle (global minimum mean cycle)
353
        if ( _curr_found && (!_best_found ||
354
             _curr_cost * _best_size < _best_cost * _curr_size) ) {
355
          _best_found = true;
356
          _best_cost = _curr_cost;
357
          _best_size = _curr_size;
358
          _best_node = _curr_node;
359
          _best_level = _curr_level;
360
        }
361
      }
362
      return _best_found;
363
    }
364

	
365
    /// \brief Find a minimum mean directed cycle.
366
    ///
367
    /// This function finds a directed cycle of minimum mean cost
368
    /// in the digraph using the data computed by findCycleMean().
369
    ///
370
    /// \return \c true if a directed cycle exists in the digraph.
371
    ///
372
    /// \pre \ref findCycleMean() must be called before using this function.
373
    bool findCycle() {
374
      if (!_best_found) return false;
375
      IntNodeMap reached(_gr, -1);
376
      int r = _best_level + 1;
377
      Node u = _best_node;
378
      while (reached[u] < 0) {
379
        reached[u] = --r;
380
        u = _gr.source(_data[u][r].pred);
381
      }
382
      r = reached[u];
383
      Arc e = _data[u][r].pred;
384
      _cycle_path->addFront(e);
385
      _best_cost = _cost[e];
386
      _best_size = 1;
387
      Node v;
388
      while ((v = _gr.source(e)) != u) {
389
        e = _data[v][--r].pred;
390
        _cycle_path->addFront(e);
391
        _best_cost += _cost[e];
392
        ++_best_size;
393
      }
394
      return true;
395
    }
396

	
397
    /// @}
398

	
399
    /// \name Query Functions
400
    /// The results of the algorithm can be obtained using these
401
    /// functions.\n
402
    /// The algorithm should be executed before using them.
403

	
404
    /// @{
405

	
406
    /// \brief Return the total cost of the found cycle.
407
    ///
408
    /// This function returns the total cost of the found cycle.
409
    ///
410
    /// \pre \ref run() or \ref findCycleMean() must be called before
411
    /// using this function.
412
    Cost cycleCost() const {
413
      return static_cast<Cost>(_best_cost);
414
    }
415

	
416
    /// \brief Return the number of arcs on the found cycle.
417
    ///
418
    /// This function returns the number of arcs on the found cycle.
419
    ///
420
    /// \pre \ref run() or \ref findCycleMean() must be called before
421
    /// using this function.
422
    int cycleSize() const {
423
      return _best_size;
424
    }
425

	
426
    /// \brief Return the mean cost of the found cycle.
427
    ///
428
    /// This function returns the mean cost of the found cycle.
429
    ///
430
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
431
    /// following code.
432
    /// \code
433
    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
434
    /// \endcode
435
    ///
436
    /// \pre \ref run() or \ref findCycleMean() must be called before
437
    /// using this function.
438
    double cycleMean() const {
439
      return static_cast<double>(_best_cost) / _best_size;
440
    }
441

	
442
    /// \brief Return the found cycle.
443
    ///
444
    /// This function returns a const reference to the path structure
445
    /// storing the found cycle.
446
    ///
447
    /// \pre \ref run() or \ref findCycle() must be called before using
448
    /// this function.
449
    const Path& cycle() const {
450
      return *_cycle_path;
451
    }
452

	
453
    ///@}
454

	
455
  private:
456

	
457
    // Initialization
458
    void init() {
459
      if (!_cycle_path) {
460
        _local_path = true;
461
        _cycle_path = new Path;
462
      }
463
      _cycle_path->clear();
464
      _best_found = false;
465
      _best_cost = 0;
466
      _best_size = 1;
467
      _cycle_path->clear();
468
      for (NodeIt u(_gr); u != INVALID; ++u)
469
        _data[u].clear();
470
    }
471

	
472
    // Find strongly connected components and initialize _comp_nodes
473
    // and _out_arcs
474
    void findComponents() {
475
      _comp_num = stronglyConnectedComponents(_gr, _comp);
476
      _comp_nodes.resize(_comp_num);
477
      if (_comp_num == 1) {
478
        _comp_nodes[0].clear();
479
        for (NodeIt n(_gr); n != INVALID; ++n) {
480
          _comp_nodes[0].push_back(n);
481
          _out_arcs[n].clear();
482
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
483
            _out_arcs[n].push_back(a);
484
          }
485
        }
486
      } else {
487
        for (int i = 0; i < _comp_num; ++i)
488
          _comp_nodes[i].clear();
489
        for (NodeIt n(_gr); n != INVALID; ++n) {
490
          int k = _comp[n];
491
          _comp_nodes[k].push_back(n);
492
          _out_arcs[n].clear();
493
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
494
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
495
          }
496
        }
497
      }
498
    }
499

	
500
    // Initialize path data for the current component
501
    bool initComponent(int comp) {
502
      _nodes = &(_comp_nodes[comp]);
503
      int n = _nodes->size();
504
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
505
        return false;
506
      }
507
      for (int i = 0; i < n; ++i) {
508
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
509
      }
510
      return true;
511
    }
512

	
513
    // Process all rounds of computing path data for the current component.
514
    // _data[v][k] is the cost of a shortest directed walk from the root
515
    // node to node v containing exactly k arcs.
516
    void processRounds() {
517
      Node start = (*_nodes)[0];
518
      _data[start][0] = PathData(0);
519
      _process.clear();
520
      _process.push_back(start);
521

	
522
      int k, n = _nodes->size();
523
      int next_check = 4;
524
      bool terminate = false;
525
      for (k = 1; k <= n && int(_process.size()) < n && !terminate; ++k) {
526
        processNextBuildRound(k);
527
        if (k == next_check || k == n) {
528
          terminate = checkTermination(k);
529
          next_check = next_check * 3 / 2;
530
        }
531
      }
532
      for ( ; k <= n && !terminate; ++k) {
533
        processNextFullRound(k);
534
        if (k == next_check || k == n) {
535
          terminate = checkTermination(k);
536
          next_check = next_check * 3 / 2;
537
        }
538
      }
539
    }
540

	
541
    // Process one round and rebuild _process
542
    void processNextBuildRound(int k) {
543
      std::vector<Node> next;
544
      Node u, v;
545
      Arc e;
546
      LargeCost d;
547
      for (int i = 0; i < int(_process.size()); ++i) {
548
        u = _process[i];
549
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
550
          e = _out_arcs[u][j];
551
          v = _gr.target(e);
552
          d = _data[u][k-1].dist + _cost[e];
553
          if (_tolerance.less(d, _data[v][k].dist)) {
554
            if (_data[v][k].dist == INF) next.push_back(v);
555
            _data[v][k] = PathData(d, e);
556
          }
557
        }
558
      }
559
      _process.swap(next);
560
    }
561

	
562
    // Process one round using _nodes instead of _process
563
    void processNextFullRound(int k) {
564
      Node u, v;
565
      Arc e;
566
      LargeCost d;
567
      for (int i = 0; i < int(_nodes->size()); ++i) {
568
        u = (*_nodes)[i];
569
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
570
          e = _out_arcs[u][j];
571
          v = _gr.target(e);
572
          d = _data[u][k-1].dist + _cost[e];
573
          if (_tolerance.less(d, _data[v][k].dist)) {
574
            _data[v][k] = PathData(d, e);
575
          }
576
        }
577
      }
578
    }
579

	
580
    // Check early termination
581
    bool checkTermination(int k) {
582
      typedef std::pair<int, int> Pair;
583
      typename GR::template NodeMap<Pair> level(_gr, Pair(-1, 0));
584
      typename GR::template NodeMap<LargeCost> pi(_gr);
585
      int n = _nodes->size();
586
      LargeCost cost;
587
      int size;
588
      Node u;
589

	
590
      // Search for cycles that are already found
591
      _curr_found = false;
592
      for (int i = 0; i < n; ++i) {
593
        u = (*_nodes)[i];
594
        if (_data[u][k].dist == INF) continue;
595
        for (int j = k; j >= 0; --j) {
596
          if (level[u].first == i && level[u].second > 0) {
597
            // A cycle is found
598
            cost = _data[u][level[u].second].dist - _data[u][j].dist;
599
            size = level[u].second - j;
600
            if (!_curr_found || cost * _curr_size < _curr_cost * size) {
601
              _curr_cost = cost;
602
              _curr_size = size;
603
              _curr_node = u;
604
              _curr_level = level[u].second;
605
              _curr_found = true;
606
            }
607
          }
608
          level[u] = Pair(i, j);
609
          if (j != 0) {
610
            u = _gr.source(_data[u][j].pred);
611
          }
612
        }
613
      }
614

	
615
      // If at least one cycle is found, check the optimality condition
616
      LargeCost d;
617
      if (_curr_found && k < n) {
618
        // Find node potentials
619
        for (int i = 0; i < n; ++i) {
620
          u = (*_nodes)[i];
621
          pi[u] = INF;
622
          for (int j = 0; j <= k; ++j) {
623
            if (_data[u][j].dist < INF) {
624
              d = _data[u][j].dist * _curr_size - j * _curr_cost;
625
              if (_tolerance.less(d, pi[u])) pi[u] = d;
626
            }
627
          }
628
        }
629

	
630
        // Check the optimality condition for all arcs
631
        bool done = true;
632
        for (ArcIt a(_gr); a != INVALID; ++a) {
633
          if (_tolerance.less(_cost[a] * _curr_size - _curr_cost,
634
                              pi[_gr.target(a)] - pi[_gr.source(a)]) ) {
635
            done = false;
636
            break;
637
          }
638
        }
639
        return done;
640
      }
641
      return (k == n);
642
    }
643

	
644
  }; //class HartmannOrlinMmc
645

	
646
  ///@}
647

	
648
} //namespace lemon
649

	
650
#endif //LEMON_HARTMANN_ORLIN_MMC_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-2010
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_MMC_H
20
#define LEMON_HOWARD_MMC_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 HowardMmc class.
37
  ///
38
  /// Default traits class of HowardMmc class.
39
  /// \tparam GR The type of the digraph.
40
  /// \tparam CM The type of the cost map.
41
  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
42
#ifdef DOXYGEN
43
  template <typename GR, typename CM>
44
#else
45
  template <typename GR, typename CM,
46
    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
47
#endif
48
  struct HowardMmcDefaultTraits
49
  {
50
    /// The type of the digraph
51
    typedef GR Digraph;
52
    /// The type of the cost map
53
    typedef CM CostMap;
54
    /// The type of the arc costs
55
    typedef typename CostMap::Value Cost;
56

	
57
    /// \brief The large cost type used for internal computations
58
    ///
59
    /// The large cost type used for internal computations.
60
    /// It is \c long \c long if the \c Cost type is integer,
61
    /// otherwise it is \c double.
62
    /// \c Cost must be convertible to \c LargeCost.
63
    typedef double LargeCost;
64

	
65
    /// The tolerance type used for internal computations
66
    typedef lemon::Tolerance<LargeCost> 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 cost types
77
  template <typename GR, typename CM>
78
  struct HowardMmcDefaultTraits<GR, CM, true>
79
  {
80
    typedef GR Digraph;
81
    typedef CM CostMap;
82
    typedef typename CostMap::Value Cost;
83
#ifdef LEMON_HAVE_LONG_LONG
84
    typedef long long LargeCost;
85
#else
86
    typedef long LargeCost;
87
#endif
88
    typedef lemon::Tolerance<LargeCost> 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 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 CM The type of the cost map. The default
108
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
109
  /// \tparam TR The traits class that defines various types used by the
110
  /// algorithm. By default, it is \ref HowardMmcDefaultTraits
111
  /// "HowardMmcDefaultTraits<GR, CM>".
112
  /// In most cases, this parameter should not be set directly,
113
  /// consider to use the named template parameters instead.
114
#ifdef DOXYGEN
115
  template <typename GR, typename CM, typename TR>
116
#else
117
  template < typename GR,
118
             typename CM = typename GR::template ArcMap<int>,
119
             typename TR = HowardMmcDefaultTraits<GR, CM> >
120
#endif
121
  class HowardMmc
122
  {
123
  public:
124

	
125
    /// The type of the digraph
126
    typedef typename TR::Digraph Digraph;
127
    /// The type of the cost map
128
    typedef typename TR::CostMap CostMap;
129
    /// The type of the arc costs
130
    typedef typename TR::Cost Cost;
131

	
132
    /// \brief The large cost type
133
    ///
134
    /// The large cost type used for internal computations.
135
    /// By default, it is \c long \c long if the \c Cost type is integer,
136
    /// otherwise it is \c double.
137
    typedef typename TR::LargeCost LargeCost;
138

	
139
    /// The tolerance type
140
    typedef typename TR::Tolerance Tolerance;
141

	
142
    /// \brief The path type of the found cycles
143
    ///
144
    /// The path type of the found cycles.
145
    /// Using the \ref HowardMmcDefaultTraits "default traits class",
146
    /// it is \ref lemon::Path "Path<Digraph>".
147
    typedef typename TR::Path Path;
148

	
149
    /// The \ref HowardMmcDefaultTraits "traits class" of the algorithm
150
    typedef TR Traits;
151

	
152
  private:
153

	
154
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
155

	
156
    // The digraph the algorithm runs on
157
    const Digraph &_gr;
158
    // The cost of the arcs
159
    const CostMap &_cost;
160

	
161
    // Data for the found cycles
162
    bool _curr_found, _best_found;
163
    LargeCost _curr_cost, _best_cost;
164
    int _curr_size, _best_size;
165
    Node _curr_node, _best_node;
166

	
167
    Path *_cycle_path;
168
    bool _local_path;
169

	
170
    // Internal data used by the algorithm
171
    typename Digraph::template NodeMap<Arc> _policy;
172
    typename Digraph::template NodeMap<bool> _reached;
173
    typename Digraph::template NodeMap<int> _level;
174
    typename Digraph::template NodeMap<LargeCost> _dist;
175

	
176
    // Data for storing the strongly connected components
177
    int _comp_num;
178
    typename Digraph::template NodeMap<int> _comp;
179
    std::vector<std::vector<Node> > _comp_nodes;
180
    std::vector<Node>* _nodes;
181
    typename Digraph::template NodeMap<std::vector<Arc> > _in_arcs;
182

	
183
    // Queue used for BFS search
184
    std::vector<Node> _queue;
185
    int _qfront, _qback;
186

	
187
    Tolerance _tolerance;
188

	
189
    // Infinite constant
190
    const LargeCost INF;
191

	
192
  public:
193

	
194
    /// \name Named Template Parameters
195
    /// @{
196

	
197
    template <typename T>
198
    struct SetLargeCostTraits : public Traits {
199
      typedef T LargeCost;
200
      typedef lemon::Tolerance<T> Tolerance;
201
    };
202

	
203
    /// \brief \ref named-templ-param "Named parameter" for setting
204
    /// \c LargeCost type.
205
    ///
206
    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
207
    /// type. It is used for internal computations in the algorithm.
208
    template <typename T>
209
    struct SetLargeCost
210
      : public HowardMmc<GR, CM, SetLargeCostTraits<T> > {
211
      typedef HowardMmc<GR, CM, SetLargeCostTraits<T> > Create;
212
    };
213

	
214
    template <typename T>
215
    struct SetPathTraits : public Traits {
216
      typedef T Path;
217
    };
218

	
219
    /// \brief \ref named-templ-param "Named parameter" for setting
220
    /// \c %Path type.
221
    ///
222
    /// \ref named-templ-param "Named parameter" for setting the \c %Path
223
    /// type of the found cycles.
224
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
225
    /// and it must have an \c addBack() function.
226
    template <typename T>
227
    struct SetPath
228
      : public HowardMmc<GR, CM, SetPathTraits<T> > {
229
      typedef HowardMmc<GR, CM, SetPathTraits<T> > Create;
230
    };
231

	
232
    /// @}
233

	
234
  protected:
235

	
236
    HowardMmc() {}
237

	
238
  public:
239

	
240
    /// \brief Constructor.
241
    ///
242
    /// The constructor of the class.
243
    ///
244
    /// \param digraph The digraph the algorithm runs on.
245
    /// \param cost The costs of the arcs.
246
    HowardMmc( const Digraph &digraph,
247
               const CostMap &cost ) :
248
      _gr(digraph), _cost(cost), _best_found(false),
249
      _best_cost(0), _best_size(1), _cycle_path(NULL), _local_path(false),
250
      _policy(digraph), _reached(digraph), _level(digraph), _dist(digraph),
251
      _comp(digraph), _in_arcs(digraph),
252
      INF(std::numeric_limits<LargeCost>::has_infinity ?
253
          std::numeric_limits<LargeCost>::infinity() :
254
          std::numeric_limits<LargeCost>::max())
255
    {}
256

	
257
    /// Destructor.
258
    ~HowardMmc() {
259
      if (_local_path) delete _cycle_path;
260
    }
261

	
262
    /// \brief Set the path structure for storing the found cycle.
263
    ///
264
    /// This function sets an external path structure for storing the
265
    /// found cycle.
266
    ///
267
    /// If you don't call this function before calling \ref run() or
268
    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
269
    /// structure. The destuctor deallocates this automatically
270
    /// allocated object, of course.
271
    ///
272
    /// \note The algorithm calls only the \ref lemon::Path::addBack()
273
    /// "addBack()" function of the given path structure.
274
    ///
275
    /// \return <tt>(*this)</tt>
276
    HowardMmc& cycle(Path &path) {
277
      if (_local_path) {
278
        delete _cycle_path;
279
        _local_path = false;
280
      }
281
      _cycle_path = &path;
282
      return *this;
283
    }
284

	
285
    /// \brief Set the tolerance used by the algorithm.
286
    ///
287
    /// This function sets the tolerance object used by the algorithm.
288
    ///
289
    /// \return <tt>(*this)</tt>
290
    HowardMmc& tolerance(const Tolerance& tolerance) {
291
      _tolerance = tolerance;
292
      return *this;
293
    }
294

	
295
    /// \brief Return a const reference to the tolerance.
296
    ///
297
    /// This function returns a const reference to the tolerance object
298
    /// used by the algorithm.
299
    const Tolerance& tolerance() const {
300
      return _tolerance;
301
    }
302

	
303
    /// \name Execution control
304
    /// The simplest way to execute the algorithm is to call the \ref run()
305
    /// function.\n
306
    /// If you only need the minimum mean cost, you may call
307
    /// \ref findCycleMean().
308

	
309
    /// @{
310

	
311
    /// \brief Run the algorithm.
312
    ///
313
    /// This function runs the algorithm.
314
    /// It can be called more than once (e.g. if the underlying digraph
315
    /// and/or the arc costs have been modified).
316
    ///
317
    /// \return \c true if a directed cycle exists in the digraph.
318
    ///
319
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
320
    /// \code
321
    ///   return mmc.findCycleMean() && mmc.findCycle();
322
    /// \endcode
323
    bool run() {
324
      return findCycleMean() && findCycle();
325
    }
326

	
327
    /// \brief Find the minimum cycle mean.
328
    ///
329
    /// This function finds the minimum mean cost of the directed
330
    /// cycles in the digraph.
331
    ///
332
    /// \return \c true if a directed cycle exists in the digraph.
333
    bool findCycleMean() {
334
      // Initialize and find strongly connected components
335
      init();
336
      findComponents();
337

	
338
      // Find the minimum cycle mean in the components
339
      for (int comp = 0; comp < _comp_num; ++comp) {
340
        // Find the minimum mean cycle in the current component
341
        if (!buildPolicyGraph(comp)) continue;
342
        while (true) {
343
          findPolicyCycle();
344
          if (!computeNodeDistances()) break;
345
        }
346
        // Update the best cycle (global minimum mean cycle)
347
        if ( _curr_found && (!_best_found ||
348
             _curr_cost * _best_size < _best_cost * _curr_size) ) {
349
          _best_found = true;
350
          _best_cost = _curr_cost;
351
          _best_size = _curr_size;
352
          _best_node = _curr_node;
353
        }
354
      }
355
      return _best_found;
356
    }
357

	
358
    /// \brief Find a minimum mean directed cycle.
359
    ///
360
    /// This function finds a directed cycle of minimum mean cost
361
    /// in the digraph using the data computed by findCycleMean().
362
    ///
363
    /// \return \c true if a directed cycle exists in the digraph.
364
    ///
365
    /// \pre \ref findCycleMean() must be called before using this function.
366
    bool findCycle() {
367
      if (!_best_found) return false;
368
      _cycle_path->addBack(_policy[_best_node]);
369
      for ( Node v = _best_node;
370
            (v = _gr.target(_policy[v])) != _best_node; ) {
371
        _cycle_path->addBack(_policy[v]);
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 cost of the found cycle.
386
    ///
387
    /// This function returns the total cost of the found cycle.
388
    ///
389
    /// \pre \ref run() or \ref findCycleMean() must be called before
390
    /// using this function.
391
    Cost cycleCost() const {
392
      return static_cast<Cost>(_best_cost);
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 findCycleMean() must be called before
400
    /// using this function.
401
    int cycleSize() const {
402
      return _best_size;
403
    }
404

	
405
    /// \brief Return the mean cost of the found cycle.
406
    ///
407
    /// This function returns the mean cost 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.cycleCost()) / alg.cycleSize();
413
    /// \endcode
414
    ///
415
    /// \pre \ref run() or \ref findCycleMean() must be called before
416
    /// using this function.
417
    double cycleMean() const {
418
      return static_cast<double>(_best_cost) / _best_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
    // Initialize
437
    void init() {
438
      if (!_cycle_path) {
439
        _local_path = true;
440
        _cycle_path = new Path;
441
      }
442
      _queue.resize(countNodes(_gr));
443
      _best_found = false;
444
      _best_cost = 0;
445
      _best_size = 1;
446
      _cycle_path->clear();
447
    }
448

	
449
    // Find strongly connected components and initialize _comp_nodes
450
    // and _in_arcs
451
    void findComponents() {
452
      _comp_num = stronglyConnectedComponents(_gr, _comp);
453
      _comp_nodes.resize(_comp_num);
454
      if (_comp_num == 1) {
455
        _comp_nodes[0].clear();
456
        for (NodeIt n(_gr); n != INVALID; ++n) {
457
          _comp_nodes[0].push_back(n);
458
          _in_arcs[n].clear();
459
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
460
            _in_arcs[n].push_back(a);
461
          }
462
        }
463
      } else {
464
        for (int i = 0; i < _comp_num; ++i)
465
          _comp_nodes[i].clear();
466
        for (NodeIt n(_gr); n != INVALID; ++n) {
467
          int k = _comp[n];
468
          _comp_nodes[k].push_back(n);
469
          _in_arcs[n].clear();
470
          for (InArcIt a(_gr, n); a != INVALID; ++a) {
471
            if (_comp[_gr.source(a)] == k) _in_arcs[n].push_back(a);
472
          }
473
        }
474
      }
475
    }
476

	
477
    // Build the policy graph in the given strongly connected component
478
    // (the out-degree of every node is 1)
479
    bool buildPolicyGraph(int comp) {
480
      _nodes = &(_comp_nodes[comp]);
481
      if (_nodes->size() < 1 ||
482
          (_nodes->size() == 1 && _in_arcs[(*_nodes)[0]].size() == 0)) {
483
        return false;
484
      }
485
      for (int i = 0; i < int(_nodes->size()); ++i) {
486
        _dist[(*_nodes)[i]] = INF;
487
      }
488
      Node u, v;
489
      Arc e;
490
      for (int i = 0; i < int(_nodes->size()); ++i) {
491
        v = (*_nodes)[i];
492
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
493
          e = _in_arcs[v][j];
494
          u = _gr.source(e);
495
          if (_cost[e] < _dist[u]) {
496
            _dist[u] = _cost[e];
497
            _policy[u] = e;
498
          }
499
        }
500
      }
501
      return true;
502
    }
503

	
504
    // Find the minimum mean cycle in the policy graph
505
    void findPolicyCycle() {
506
      for (int i = 0; i < int(_nodes->size()); ++i) {
507
        _level[(*_nodes)[i]] = -1;
508
      }
509
      LargeCost ccost;
510
      int csize;
511
      Node u, v;
512
      _curr_found = false;
513
      for (int i = 0; i < int(_nodes->size()); ++i) {
514
        u = (*_nodes)[i];
515
        if (_level[u] >= 0) continue;
516
        for (; _level[u] < 0; u = _gr.target(_policy[u])) {
517
          _level[u] = i;
518
        }
519
        if (_level[u] == i) {
520
          // A cycle is found
521
          ccost = _cost[_policy[u]];
522
          csize = 1;
523
          for (v = u; (v = _gr.target(_policy[v])) != u; ) {
524
            ccost += _cost[_policy[v]];
525
            ++csize;
526
          }
527
          if ( !_curr_found ||
528
               (ccost * _curr_size < _curr_cost * csize) ) {
529
            _curr_found = true;
530
            _curr_cost = ccost;
531
            _curr_size = csize;
532
            _curr_node = u;
533
          }
534
        }
535
      }
536
    }
537

	
538
    // Contract the policy graph and compute node distances
539
    bool computeNodeDistances() {
540
      // Find the component of the main cycle and compute node distances
541
      // using reverse BFS
542
      for (int i = 0; i < int(_nodes->size()); ++i) {
543
        _reached[(*_nodes)[i]] = false;
544
      }
545
      _qfront = _qback = 0;
546
      _queue[0] = _curr_node;
547
      _reached[_curr_node] = true;
548
      _dist[_curr_node] = 0;
549
      Node u, v;
550
      Arc e;
551
      while (_qfront <= _qback) {
552
        v = _queue[_qfront++];
553
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
554
          e = _in_arcs[v][j];
555
          u = _gr.source(e);
556
          if (_policy[u] == e && !_reached[u]) {
557
            _reached[u] = true;
558
            _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
559
            _queue[++_qback] = u;
560
          }
561
        }
562
      }
563

	
564
      // Connect all other nodes to this component and compute node
565
      // distances using reverse BFS
566
      _qfront = 0;
567
      while (_qback < int(_nodes->size())-1) {
568
        v = _queue[_qfront++];
569
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
570
          e = _in_arcs[v][j];
571
          u = _gr.source(e);
572
          if (!_reached[u]) {
573
            _reached[u] = true;
574
            _policy[u] = e;
575
            _dist[u] = _dist[v] + _cost[e] * _curr_size - _curr_cost;
576
            _queue[++_qback] = u;
577
          }
578
        }
579
      }
580

	
581
      // Improve node distances
582
      bool improved = false;
583
      for (int i = 0; i < int(_nodes->size()); ++i) {
584
        v = (*_nodes)[i];
585
        for (int j = 0; j < int(_in_arcs[v].size()); ++j) {
586
          e = _in_arcs[v][j];
587
          u = _gr.source(e);
588
          LargeCost delta = _dist[v] + _cost[e] * _curr_size - _curr_cost;
589
          if (_tolerance.less(delta, _dist[u])) {
590
            _dist[u] = delta;
591
            _policy[u] = e;
592
            improved = true;
593
          }
594
        }
595
      }
596
      return improved;
597
    }
598

	
599
  }; //class HowardMmc
600

	
601
  ///@}
602

	
603
} //namespace lemon
604

	
605
#endif //LEMON_HOWARD_MMC_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-2010
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_MMC_H
20
#define LEMON_KARP_MMC_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 KarpMmc class.
37
  ///
38
  /// Default traits class of KarpMmc class.
39
  /// \tparam GR The type of the digraph.
40
  /// \tparam CM The type of the cost map.
41
  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
42
#ifdef DOXYGEN
43
  template <typename GR, typename CM>
44
#else
45
  template <typename GR, typename CM,
46
    bool integer = std::numeric_limits<typename CM::Value>::is_integer>
47
#endif
48
  struct KarpMmcDefaultTraits
49
  {
50
    /// The type of the digraph
51
    typedef GR Digraph;
52
    /// The type of the cost map
53
    typedef CM CostMap;
54
    /// The type of the arc costs
55
    typedef typename CostMap::Value Cost;
56

	
57
    /// \brief The large cost type used for internal computations
58
    ///
59
    /// The large cost type used for internal computations.
60
    /// It is \c long \c long if the \c Cost type is integer,
61
    /// otherwise it is \c double.
62
    /// \c Cost must be convertible to \c LargeCost.
63
    typedef double LargeCost;
64

	
65
    /// The tolerance type used for internal computations
66
    typedef lemon::Tolerance<LargeCost> 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 cost types
77
  template <typename GR, typename CM>
78
  struct KarpMmcDefaultTraits<GR, CM, true>
79
  {
80
    typedef GR Digraph;
81
    typedef CM CostMap;
82
    typedef typename CostMap::Value Cost;
83
#ifdef LEMON_HAVE_LONG_LONG
84
    typedef long long LargeCost;
85
#else
86
    typedef long LargeCost;
87
#endif
88
    typedef lemon::Tolerance<LargeCost> 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 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 CM The type of the cost map. The default
106
  /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
107
  /// \tparam TR The traits class that defines various types used by the
108
  /// algorithm. By default, it is \ref KarpMmcDefaultTraits
109
  /// "KarpMmcDefaultTraits<GR, CM>".
110
  /// In most cases, this parameter should not be set directly,
111
  /// consider to use the named template parameters instead.
112
#ifdef DOXYGEN
113
  template <typename GR, typename CM, typename TR>
114
#else
115
  template < typename GR,
116
             typename CM = typename GR::template ArcMap<int>,
117
             typename TR = KarpMmcDefaultTraits<GR, CM> >
118
#endif
119
  class KarpMmc
120
  {
121
  public:
122

	
123
    /// The type of the digraph
124
    typedef typename TR::Digraph Digraph;
125
    /// The type of the cost map
126
    typedef typename TR::CostMap CostMap;
127
    /// The type of the arc costs
128
    typedef typename TR::Cost Cost;
129

	
130
    /// \brief The large cost type
131
    ///
132
    /// The large cost type used for internal computations.
133
    /// By default, it is \c long \c long if the \c Cost type is integer,
134
    /// otherwise it is \c double.
135
    typedef typename TR::LargeCost LargeCost;
136

	
137
    /// The tolerance type
138
    typedef typename TR::Tolerance Tolerance;
139

	
140
    /// \brief The path type of the found cycles
141
    ///
142
    /// The path type of the found cycles.
143
    /// Using the \ref KarpMmcDefaultTraits "default traits class",
144
    /// it is \ref lemon::Path "Path<Digraph>".
145
    typedef typename TR::Path Path;
146

	
147
    /// The \ref KarpMmcDefaultTraits "traits class" of the algorithm
148
    typedef TR Traits;
149

	
150
  private:
151

	
152
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
153

	
154
    // Data sturcture for path data
155
    struct PathData
156
    {
157
      LargeCost dist;
158
      Arc pred;
159
      PathData(LargeCost d, Arc p = INVALID) :
160
        dist(d), pred(p) {}
161
    };
162

	
163
    typedef typename Digraph::template NodeMap<std::vector<PathData> >
164
      PathDataNodeMap;
165

	
166
  private:
167

	
168
    // The digraph the algorithm runs on
169
    const Digraph &_gr;
170
    // The cost of the arcs
171
    const CostMap &_cost;
172

	
173
    // Data for storing the strongly connected components
174
    int _comp_num;
175
    typename Digraph::template NodeMap<int> _comp;
176
    std::vector<std::vector<Node> > _comp_nodes;
177
    std::vector<Node>* _nodes;
178
    typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
179

	
180
    // Data for the found cycle
181
    LargeCost _cycle_cost;
182
    int _cycle_size;
183
    Node _cycle_node;
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 LargeCost INF;
197

	
198
  public:
199

	
200
    /// \name Named Template Parameters
201
    /// @{
202

	
203
    template <typename T>
204
    struct SetLargeCostTraits : public Traits {
205
      typedef T LargeCost;
206
      typedef lemon::Tolerance<T> Tolerance;
207
    };
208

	
209
    /// \brief \ref named-templ-param "Named parameter" for setting
210
    /// \c LargeCost type.
211
    ///
212
    /// \ref named-templ-param "Named parameter" for setting \c LargeCost
213
    /// type. It is used for internal computations in the algorithm.
214
    template <typename T>
215
    struct SetLargeCost
216
      : public KarpMmc<GR, CM, SetLargeCostTraits<T> > {
217
      typedef KarpMmc<GR, CM, SetLargeCostTraits<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 KarpMmc<GR, CM, SetPathTraits<T> > {
235
      typedef KarpMmc<GR, CM, SetPathTraits<T> > Create;
236
    };
237

	
238
    /// @}
239

	
240
  protected:
241

	
242
    KarpMmc() {}
243

	
244
  public:
245

	
246
    /// \brief Constructor.
247
    ///
248
    /// The constructor of the class.
249
    ///
250
    /// \param digraph The digraph the algorithm runs on.
251
    /// \param cost The costs of the arcs.
252
    KarpMmc( const Digraph &digraph,
253
             const CostMap &cost ) :
254
      _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph),
255
      _cycle_cost(0), _cycle_size(1), _cycle_node(INVALID),
256
      _cycle_path(NULL), _local_path(false), _data(digraph),
257
      INF(std::numeric_limits<LargeCost>::has_infinity ?
258
          std::numeric_limits<LargeCost>::infinity() :
259
          std::numeric_limits<LargeCost>::max())
260
    {}
261

	
262
    /// Destructor.
263
    ~KarpMmc() {
264
      if (_local_path) delete _cycle_path;
265
    }
266

	
267
    /// \brief Set the path structure for storing the found cycle.
268
    ///
269
    /// This function sets an external path structure for storing the
270
    /// found cycle.
271
    ///
272
    /// If you don't call this function before calling \ref run() or
273
    /// \ref findCycleMean(), it will allocate a local \ref Path "path"
274
    /// structure. The destuctor deallocates this automatically
275
    /// allocated object, of course.
276
    ///
277
    /// \note The algorithm calls only the \ref lemon::Path::addFront()
278
    /// "addFront()" function of the given path structure.
279
    ///
280
    /// \return <tt>(*this)</tt>
281
    KarpMmc& cycle(Path &path) {
282
      if (_local_path) {
283
        delete _cycle_path;
284
        _local_path = false;
285
      }
286
      _cycle_path = &path;
287
      return *this;
288
    }
289

	
290
    /// \brief Set the tolerance used by the algorithm.
291
    ///
292
    /// This function sets the tolerance object used by the algorithm.
293
    ///
294
    /// \return <tt>(*this)</tt>
295
    KarpMmc& tolerance(const Tolerance& tolerance) {
296
      _tolerance = tolerance;
297
      return *this;
298
    }
299

	
300
    /// \brief Return a const reference to the tolerance.
301
    ///
302
    /// This function returns a const reference to the tolerance object
303
    /// used by the algorithm.
304
    const Tolerance& tolerance() const {
305
      return _tolerance;
306
    }
307

	
308
    /// \name Execution control
309
    /// The simplest way to execute the algorithm is to call the \ref run()
310
    /// function.\n
311
    /// If you only need the minimum mean cost, you may call
312
    /// \ref findCycleMean().
313

	
314
    /// @{
315

	
316
    /// \brief Run the algorithm.
317
    ///
318
    /// This function runs the algorithm.
319
    /// It can be called more than once (e.g. if the underlying digraph
320
    /// and/or the arc costs have been modified).
321
    ///
322
    /// \return \c true if a directed cycle exists in the digraph.
323
    ///
324
    /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
325
    /// \code
326
    ///   return mmc.findCycleMean() && mmc.findCycle();
327
    /// \endcode
328
    bool run() {
329
      return findCycleMean() && findCycle();
330
    }
331

	
332
    /// \brief Find the minimum cycle mean.
333
    ///
334
    /// This function finds the minimum mean cost of the directed
335
    /// cycles in the digraph.
336
    ///
337
    /// \return \c true if a directed cycle exists in the digraph.
338
    bool findCycleMean() {
339
      // Initialization and find strongly connected components
340
      init();
341
      findComponents();
342

	
343
      // Find the minimum cycle mean in the components
344
      for (int comp = 0; comp < _comp_num; ++comp) {
345
        if (!initComponent(comp)) continue;
346
        processRounds();
347
        updateMinMean();
348
      }
349
      return (_cycle_node != INVALID);
350
    }
351

	
352
    /// \brief Find a minimum mean directed cycle.
353
    ///
354
    /// This function finds a directed cycle of minimum mean cost
355
    /// in the digraph using the data computed by findCycleMean().
356
    ///
357
    /// \return \c true if a directed cycle exists in the digraph.
358
    ///
359
    /// \pre \ref findCycleMean() must be called before using this function.
360
    bool findCycle() {
361
      if (_cycle_node == INVALID) return false;
362
      IntNodeMap reached(_gr, -1);
363
      int r = _data[_cycle_node].size();
364
      Node u = _cycle_node;
365
      while (reached[u] < 0) {
366
        reached[u] = --r;
367
        u = _gr.source(_data[u][r].pred);
368
      }
369
      r = reached[u];
370
      Arc e = _data[u][r].pred;
371
      _cycle_path->addFront(e);
372
      _cycle_cost = _cost[e];
373
      _cycle_size = 1;
374
      Node v;
375
      while ((v = _gr.source(e)) != u) {
376
        e = _data[v][--r].pred;
377
        _cycle_path->addFront(e);
378
        _cycle_cost += _cost[e];
379
        ++_cycle_size;
380
      }
381
      return true;
382
    }
383

	
384
    /// @}
385

	
386
    /// \name Query Functions
387
    /// The results of the algorithm can be obtained using these
388
    /// functions.\n
389
    /// The algorithm should be executed before using them.
390

	
391
    /// @{
392

	
393
    /// \brief Return the total cost of the found cycle.
394
    ///
395
    /// This function returns the total cost of the found cycle.
396
    ///
397
    /// \pre \ref run() or \ref findCycleMean() must be called before
398
    /// using this function.
399
    Cost cycleCost() const {
400
      return static_cast<Cost>(_cycle_cost);
401
    }
402

	
403
    /// \brief Return the number of arcs on the found cycle.
404
    ///
405
    /// This function returns the number of arcs on the found cycle.
406
    ///
407
    /// \pre \ref run() or \ref findCycleMean() must be called before
408
    /// using this function.
409
    int cycleSize() const {
410
      return _cycle_size;
411
    }
412

	
413
    /// \brief Return the mean cost of the found cycle.
414
    ///
415
    /// This function returns the mean cost of the found cycle.
416
    ///
417
    /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
418
    /// following code.
419
    /// \code
420
    ///   return static_cast<double>(alg.cycleCost()) / alg.cycleSize();
421
    /// \endcode
422
    ///
423
    /// \pre \ref run() or \ref findCycleMean() must be called before
424
    /// using this function.
425
    double cycleMean() const {
426
      return static_cast<double>(_cycle_cost) / _cycle_size;
427
    }
428

	
429
    /// \brief Return the found cycle.
430
    ///
431
    /// This function returns a const reference to the path structure
432
    /// storing the found cycle.
433
    ///
434
    /// \pre \ref run() or \ref findCycle() must be called before using
435
    /// this function.
436
    const Path& cycle() const {
437
      return *_cycle_path;
438
    }
439

	
440
    ///@}
441

	
442
  private:
443

	
444
    // Initialization
445
    void init() {
446
      if (!_cycle_path) {
447
        _local_path = true;
448
        _cycle_path = new Path;
449
      }
450
      _cycle_path->clear();
451
      _cycle_cost = 0;
452
      _cycle_size = 1;
453
      _cycle_node = INVALID;
454
      for (NodeIt u(_gr); u != INVALID; ++u)
455
        _data[u].clear();
456
    }
457

	
458
    // Find strongly connected components and initialize _comp_nodes
459
    // and _out_arcs
460
    void findComponents() {
461
      _comp_num = stronglyConnectedComponents(_gr, _comp);
462
      _comp_nodes.resize(_comp_num);
463
      if (_comp_num == 1) {
464
        _comp_nodes[0].clear();
465
        for (NodeIt n(_gr); n != INVALID; ++n) {
466
          _comp_nodes[0].push_back(n);
467
          _out_arcs[n].clear();
468
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
469
            _out_arcs[n].push_back(a);
470
          }
471
        }
472
      } else {
473
        for (int i = 0; i < _comp_num; ++i)
474
          _comp_nodes[i].clear();
475
        for (NodeIt n(_gr); n != INVALID; ++n) {
476
          int k = _comp[n];
477
          _comp_nodes[k].push_back(n);
478
          _out_arcs[n].clear();
479
          for (OutArcIt a(_gr, n); a != INVALID; ++a) {
480
            if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
481
          }
482
        }
483
      }
484
    }
485

	
486
    // Initialize path data for the current component
487
    bool initComponent(int comp) {
488
      _nodes = &(_comp_nodes[comp]);
489
      int n = _nodes->size();
490
      if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
491
        return false;
492
      }
493
      for (int i = 0; i < n; ++i) {
494
        _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
495
      }
496
      return true;
497
    }
498

	
499
    // Process all rounds of computing path data for the current component.
500
    // _data[v][k] is the cost of a shortest directed walk from the root
501
    // node to node v containing exactly k arcs.
502
    void processRounds() {
503
      Node start = (*_nodes)[0];
504
      _data[start][0] = PathData(0);
505
      _process.clear();
506
      _process.push_back(start);
507

	
508
      int k, n = _nodes->size();
509
      for (k = 1; k <= n && int(_process.size()) < n; ++k) {
510
        processNextBuildRound(k);
511
      }
512
      for ( ; k <= n; ++k) {
513
        processNextFullRound(k);
514
      }
515
    }
516

	
517
    // Process one round and rebuild _process
518
    void processNextBuildRound(int k) {
519
      std::vector<Node> next;
520
      Node u, v;
521
      Arc e;
522
      LargeCost d;
523
      for (int i = 0; i < int(_process.size()); ++i) {
524
        u = _process[i];
525
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
526
          e = _out_arcs[u][j];
527
          v = _gr.target(e);
528
          d = _data[u][k-1].dist + _cost[e];
529
          if (_tolerance.less(d, _data[v][k].dist)) {
530
            if (_data[v][k].dist == INF) next.push_back(v);
531
            _data[v][k] = PathData(d, e);
532
          }
533
        }
534
      }
535
      _process.swap(next);
536
    }
537

	
538
    // Process one round using _nodes instead of _process
539
    void processNextFullRound(int k) {
540
      Node u, v;
541
      Arc e;
542
      LargeCost d;
543
      for (int i = 0; i < int(_nodes->size()); ++i) {
544
        u = (*_nodes)[i];
545
        for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
546
          e = _out_arcs[u][j];
547
          v = _gr.target(e);
548
          d = _data[u][k-1].dist + _cost[e];
549
          if (_tolerance.less(d, _data[v][k].dist)) {
550
            _data[v][k] = PathData(d, e);
551
          }
552
        }
553
      }
554
    }
555

	
556
    // Update the minimum cycle mean
557
    void updateMinMean() {
558
      int n = _nodes->size();
559
      for (int i = 0; i < n; ++i) {
560
        Node u = (*_nodes)[i];
561
        if (_data[u][n].dist == INF) continue;
562
        LargeCost cost, max_cost = 0;
563
        int size, max_size = 1;
564
        bool found_curr = false;
565
        for (int k = 0; k < n; ++k) {
566
          if (_data[u][k].dist == INF) continue;
567
          cost = _data[u][n].dist - _data[u][k].dist;
568
          size = n - k;
569
          if (!found_curr || cost * max_size > max_cost * size) {
570
            found_curr = true;
571
            max_cost = cost;
572
            max_size = size;
573
          }
574
        }
575
        if ( found_curr && (_cycle_node == INVALID ||
576
             max_cost * _cycle_size < _cycle_cost * max_size) ) {
577
          _cycle_cost = max_cost;
578
          _cycle_size = max_size;
579
          _cycle_node = u;
580
        }
581
      }
582
    }
583

	
584
  }; //class KarpMmc
585

	
586
  ///@}
587

	
588
} //namespace lemon
589

	
590
#endif //LEMON_KARP_MMC_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-2010
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_PLANARITY_H
20
#define LEMON_PLANARITY_H
21

	
22
/// \ingroup planar
23
/// \file
24
/// \brief Planarity checking, embedding, drawing and coloring
25

	
26
#include <vector>
27
#include <list>
28

	
29
#include <lemon/dfs.h>
30
#include <lemon/bfs.h>
31
#include <lemon/radix_sort.h>
32
#include <lemon/maps.h>
33
#include <lemon/path.h>
34
#include <lemon/bucket_heap.h>
35
#include <lemon/adaptors.h>
36
#include <lemon/edge_set.h>
37
#include <lemon/color.h>
38
#include <lemon/dim2.h>
39

	
40
namespace lemon {
41

	
42
  namespace _planarity_bits {
43

	
44
    template <typename Graph>
45
    struct PlanarityVisitor : DfsVisitor<Graph> {
46

	
47
      TEMPLATE_GRAPH_TYPEDEFS(Graph);
48

	
49
      typedef typename Graph::template NodeMap<Arc> PredMap;
50

	
51
      typedef typename Graph::template EdgeMap<bool> TreeMap;
52

	
53
      typedef typename Graph::template NodeMap<int> OrderMap;
54
      typedef std::vector<Node> OrderList;
55

	
56
      typedef typename Graph::template NodeMap<int> LowMap;
57
      typedef typename Graph::template NodeMap<int> AncestorMap;
58

	
59
      PlanarityVisitor(const Graph& graph,
60
                       PredMap& pred_map, TreeMap& tree_map,
61
                       OrderMap& order_map, OrderList& order_list,
62
                       AncestorMap& ancestor_map, LowMap& low_map)
63
        : _graph(graph), _pred_map(pred_map), _tree_map(tree_map),
64
          _order_map(order_map), _order_list(order_list),
65
          _ancestor_map(ancestor_map), _low_map(low_map) {}
66

	
67
      void reach(const Node& node) {
68
        _order_map[node] = _order_list.size();
69
        _low_map[node] = _order_list.size();
70
        _ancestor_map[node] = _order_list.size();
71
        _order_list.push_back(node);
72
      }
73

	
74
      void discover(const Arc& arc) {
75
        Node source = _graph.source(arc);
76
        Node target = _graph.target(arc);
77

	
78
        _tree_map[arc] = true;
79
        _pred_map[target] = arc;
80
      }
81

	
82
      void examine(const Arc& arc) {
83
        Node source = _graph.source(arc);
84
        Node target = _graph.target(arc);
85

	
86
        if (_order_map[target] < _order_map[source] && !_tree_map[arc]) {
87
          if (_low_map[source] > _order_map[target]) {
88
            _low_map[source] = _order_map[target];
89
          }
90
          if (_ancestor_map[source] > _order_map[target]) {
91
            _ancestor_map[source] = _order_map[target];
92
          }
93
        }
94
      }
95

	
96
      void backtrack(const Arc& arc) {
97
        Node source = _graph.source(arc);
98
        Node target = _graph.target(arc);
99

	
100
        if (_low_map[source] > _low_map[target]) {
101
          _low_map[source] = _low_map[target];
102
        }
103
      }
104

	
105
      const Graph& _graph;
106
      PredMap& _pred_map;
107
      TreeMap& _tree_map;
108
      OrderMap& _order_map;
109
      OrderList& _order_list;
110
      AncestorMap& _ancestor_map;
111
      LowMap& _low_map;
112
    };
113

	
114
    template <typename Graph, bool embedding = true>
115
    struct NodeDataNode {
116
      int prev, next;
117
      int visited;
118
      typename Graph::Arc first;
119
      bool inverted;
120
    };
121

	
122
    template <typename Graph>
123
    struct NodeDataNode<Graph, false> {
124
      int prev, next;
125
      int visited;
126
    };
127

	
128
    template <typename Graph>
129
    struct ChildListNode {
130
      typedef typename Graph::Node Node;
131
      Node first;
132
      Node prev, next;
133
    };
134

	
135
    template <typename Graph>
136
    struct ArcListNode {
137
      typename Graph::Arc prev, next;
138
    };
139

	
140
    template <typename Graph>
141
    class PlanarityChecking {
142
    private:
143

	
144
      TEMPLATE_GRAPH_TYPEDEFS(Graph);
145

	
146
      const Graph& _graph;
147

	
148
    private:
149

	
150
      typedef typename Graph::template NodeMap<Arc> PredMap;
151

	
152
      typedef typename Graph::template EdgeMap<bool> TreeMap;
153

	
154
      typedef typename Graph::template NodeMap<int> OrderMap;
155
      typedef std::vector<Node> OrderList;
156

	
157
      typedef typename Graph::template NodeMap<int> LowMap;
158
      typedef typename Graph::template NodeMap<int> AncestorMap;
159

	
160
      typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
161
      typedef std::vector<NodeDataNode> NodeData;
162

	
163
      typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
164
      typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
165

	
166
      typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
167

	
168
      typedef typename Graph::template NodeMap<bool> EmbedArc;
169

	
170
    public:
171

	
172
      PlanarityChecking(const Graph& graph) : _graph(graph) {}
173

	
174
      bool run() {
175
        typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
176

	
177
        PredMap pred_map(_graph, INVALID);
178
        TreeMap tree_map(_graph, false);
179

	
180
        OrderMap order_map(_graph, -1);
181
        OrderList order_list;
182

	
183
        AncestorMap ancestor_map(_graph, -1);
184
        LowMap low_map(_graph, -1);
185

	
186
        Visitor visitor(_graph, pred_map, tree_map,
187
                        order_map, order_list, ancestor_map, low_map);
188
        DfsVisit<Graph, Visitor> visit(_graph, visitor);
189
        visit.run();
190

	
191
        ChildLists child_lists(_graph);
192
        createChildLists(tree_map, order_map, low_map, child_lists);
193

	
194
        NodeData node_data(2 * order_list.size());
195

	
196
        EmbedArc embed_arc(_graph, false);
197

	
198
        MergeRoots merge_roots(_graph);
199

	
200
        for (int i = order_list.size() - 1; i >= 0; --i) {
201

	
202
          Node node = order_list[i];
203

	
204
          Node source = node;
205
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
206
            Node target = _graph.target(e);
207

	
208
            if (order_map[source] < order_map[target] && tree_map[e]) {
209
              initFace(target, node_data, order_map, order_list);
210
            }
211
          }
212

	
213
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
214
            Node target = _graph.target(e);
215

	
216
            if (order_map[source] < order_map[target] && !tree_map[e]) {
217
              embed_arc[target] = true;
218
              walkUp(target, source, i, pred_map, low_map,
219
                     order_map, order_list, node_data, merge_roots);
220
            }
221
          }
222

	
223
          for (typename MergeRoots::Value::iterator it =
224
                 merge_roots[node].begin();
225
               it != merge_roots[node].end(); ++it) {
226
            int rn = *it;
227
            walkDown(rn, i, node_data, order_list, child_lists,
228
                     ancestor_map, low_map, embed_arc, merge_roots);
229
          }
230
          merge_roots[node].clear();
231

	
232
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
233
            Node target = _graph.target(e);
234

	
235
            if (order_map[source] < order_map[target] && !tree_map[e]) {
236
              if (embed_arc[target]) {
237
                return false;
238
              }
239
            }
240
          }
241
        }
242

	
243
        return true;
244
      }
245

	
246
    private:
247

	
248
      void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
249
                            const LowMap& low_map, ChildLists& child_lists) {
250

	
251
        for (NodeIt n(_graph); n != INVALID; ++n) {
252
          Node source = n;
253

	
254
          std::vector<Node> targets;
255
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
256
            Node target = _graph.target(e);
257

	
258
            if (order_map[source] < order_map[target] && tree_map[e]) {
259
              targets.push_back(target);
260
            }
261
          }
262

	
263
          if (targets.size() == 0) {
264
            child_lists[source].first = INVALID;
265
          } else if (targets.size() == 1) {
266
            child_lists[source].first = targets[0];
267
            child_lists[targets[0]].prev = INVALID;
268
            child_lists[targets[0]].next = INVALID;
269
          } else {
270
            radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
271
            for (int i = 1; i < int(targets.size()); ++i) {
272
              child_lists[targets[i]].prev = targets[i - 1];
273
              child_lists[targets[i - 1]].next = targets[i];
274
            }
275
            child_lists[targets.back()].next = INVALID;
276
            child_lists[targets.front()].prev = INVALID;
277
            child_lists[source].first = targets.front();
278
          }
279
        }
280
      }
281

	
282
      void walkUp(const Node& node, Node root, int rorder,
283
                  const PredMap& pred_map, const LowMap& low_map,
284
                  const OrderMap& order_map, const OrderList& order_list,
285
                  NodeData& node_data, MergeRoots& merge_roots) {
286

	
287
        int na, nb;
288
        bool da, db;
289

	
290
        na = nb = order_map[node];
291
        da = true; db = false;
292

	
293
        while (true) {
294

	
295
          if (node_data[na].visited == rorder) break;
296
          if (node_data[nb].visited == rorder) break;
297

	
298
          node_data[na].visited = rorder;
299
          node_data[nb].visited = rorder;
300

	
301
          int rn = -1;
302

	
303
          if (na >= int(order_list.size())) {
304
            rn = na;
305
          } else if (nb >= int(order_list.size())) {
306
            rn = nb;
307
          }
308

	
309
          if (rn == -1) {
310
            int nn;
311

	
312
            nn = da ? node_data[na].prev : node_data[na].next;
313
            da = node_data[nn].prev != na;
314
            na = nn;
315

	
316
            nn = db ? node_data[nb].prev : node_data[nb].next;
317
            db = node_data[nn].prev != nb;
318
            nb = nn;
319

	
320
          } else {
321

	
322
            Node rep = order_list[rn - order_list.size()];
323
            Node parent = _graph.source(pred_map[rep]);
324

	
325
            if (low_map[rep] < rorder) {
326
              merge_roots[parent].push_back(rn);
327
            } else {
328
              merge_roots[parent].push_front(rn);
329
            }
330

	
331
            if (parent != root) {
332
              na = nb = order_map[parent];
333
              da = true; db = false;
334
            } else {
335
              break;
336
            }
337
          }
338
        }
339
      }
340

	
341
      void walkDown(int rn, int rorder, NodeData& node_data,
342
                    OrderList& order_list, ChildLists& child_lists,
343
                    AncestorMap& ancestor_map, LowMap& low_map,
344
                    EmbedArc& embed_arc, MergeRoots& merge_roots) {
345

	
346
        std::vector<std::pair<int, bool> > merge_stack;
347

	
348
        for (int di = 0; di < 2; ++di) {
349
          bool rd = di == 0;
350
          int pn = rn;
351
          int n = rd ? node_data[rn].next : node_data[rn].prev;
352

	
353
          while (n != rn) {
354

	
355
            Node node = order_list[n];
356

	
357
            if (embed_arc[node]) {
358

	
359
              // Merging components on the critical path
360
              while (!merge_stack.empty()) {
361

	
362
                // Component root
363
                int cn = merge_stack.back().first;
364
                bool cd = merge_stack.back().second;
365
                merge_stack.pop_back();
366

	
367
                // Parent of component
368
                int dn = merge_stack.back().first;
369
                bool dd = merge_stack.back().second;
370
                merge_stack.pop_back();
371

	
372
                Node parent = order_list[dn];
373

	
374
                // Erasing from merge_roots
375
                merge_roots[parent].pop_front();
376

	
377
                Node child = order_list[cn - order_list.size()];
378

	
379
                // Erasing from child_lists
380
                if (child_lists[child].prev != INVALID) {
381
                  child_lists[child_lists[child].prev].next =
382
                    child_lists[child].next;
383
                } else {
384
                  child_lists[parent].first = child_lists[child].next;
385
                }
386

	
387
                if (child_lists[child].next != INVALID) {
388
                  child_lists[child_lists[child].next].prev =
389
                    child_lists[child].prev;
390
                }
391

	
392
                // Merging external faces
393
                {
394
                  int en = cn;
395
                  cn = cd ? node_data[cn].prev : node_data[cn].next;
396
                  cd = node_data[cn].next == en;
397

	
398
                }
399

	
400
                if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
401
                if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
402

	
403
              }
404

	
405
              bool d = pn == node_data[n].prev;
406

	
407
              if (node_data[n].prev == node_data[n].next &&
408
                  node_data[n].inverted) {
409
                d = !d;
410
              }
411

	
412
              // Embedding arc into external face
413
              if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
414
              if (d) node_data[n].prev = rn; else node_data[n].next = rn;
415
              pn = rn;
416

	
417
              embed_arc[order_list[n]] = false;
418
            }
419

	
420
            if (!merge_roots[node].empty()) {
421

	
422
              bool d = pn == node_data[n].prev;
423

	
424
              merge_stack.push_back(std::make_pair(n, d));
425

	
426
              int rn = merge_roots[node].front();
427

	
428
              int xn = node_data[rn].next;
429
              Node xnode = order_list[xn];
430

	
431
              int yn = node_data[rn].prev;
432
              Node ynode = order_list[yn];
433

	
434
              bool rd;
435
              if (!external(xnode, rorder, child_lists,
436
                            ancestor_map, low_map)) {
437
                rd = true;
438
              } else if (!external(ynode, rorder, child_lists,
439
                                   ancestor_map, low_map)) {
440
                rd = false;
441
              } else if (pertinent(xnode, embed_arc, merge_roots)) {
442
                rd = true;
443
              } else {
444
                rd = false;
445
              }
446

	
447
              merge_stack.push_back(std::make_pair(rn, rd));
448

	
449
              pn = rn;
450
              n = rd ? xn : yn;
451

	
452
            } else if (!external(node, rorder, child_lists,
453
                                 ancestor_map, low_map)) {
454
              int nn = (node_data[n].next != pn ?
455
                        node_data[n].next : node_data[n].prev);
456

	
457
              bool nd = n == node_data[nn].prev;
458

	
459
              if (nd) node_data[nn].prev = pn;
460
              else node_data[nn].next = pn;
461

	
462
              if (n == node_data[pn].prev) node_data[pn].prev = nn;
463
              else node_data[pn].next = nn;
464

	
465
              node_data[nn].inverted =
466
                (node_data[nn].prev == node_data[nn].next && nd != rd);
467

	
468
              n = nn;
469
            }
470
            else break;
471

	
472
          }
473

	
474
          if (!merge_stack.empty() || n == rn) {
475
            break;
476
          }
477
        }
478
      }
479

	
480
      void initFace(const Node& node, NodeData& node_data,
481
                    const OrderMap& order_map, const OrderList& order_list) {
482
        int n = order_map[node];
483
        int rn = n + order_list.size();
484

	
485
        node_data[n].next = node_data[n].prev = rn;
486
        node_data[rn].next = node_data[rn].prev = n;
487

	
488
        node_data[n].visited = order_list.size();
489
        node_data[rn].visited = order_list.size();
490

	
491
      }
492

	
493
      bool external(const Node& node, int rorder,
494
                    ChildLists& child_lists, AncestorMap& ancestor_map,
495
                    LowMap& low_map) {
496
        Node child = child_lists[node].first;
497

	
498
        if (child != INVALID) {
499
          if (low_map[child] < rorder) return true;
500
        }
501

	
502
        if (ancestor_map[node] < rorder) return true;
503

	
504
        return false;
505
      }
506

	
507
      bool pertinent(const Node& node, const EmbedArc& embed_arc,
508
                     const MergeRoots& merge_roots) {
509
        return !merge_roots[node].empty() || embed_arc[node];
510
      }
511

	
512
    };
513

	
514
  }
515

	
516
  /// \ingroup planar
517
  ///
518
  /// \brief Planarity checking of an undirected simple graph
519
  ///
520
  /// This function implements the Boyer-Myrvold algorithm for
521
  /// planarity checking of an undirected simple graph. It is a simplified
522
  /// version of the PlanarEmbedding algorithm class because neither
523
  /// the embedding nor the Kuratowski subdivisons are computed.
524
  template <typename GR>
525
  bool checkPlanarity(const GR& graph) {
526
    _planarity_bits::PlanarityChecking<GR> pc(graph);
527
    return pc.run();
528
  }
529

	
530
  /// \ingroup planar
531
  ///
532
  /// \brief Planar embedding of an undirected simple graph
533
  ///
534
  /// This class implements the Boyer-Myrvold algorithm for planar
535
  /// embedding of an undirected simple graph. The planar embedding is an
536
  /// ordering of the outgoing edges of the nodes, which is a possible
537
  /// configuration to draw the graph in the plane. If there is not
538
  /// such ordering then the graph contains a K<sub>5</sub> (full graph
539
  /// with 5 nodes) or a K<sub>3,3</sub> (complete bipartite graph on
540
  /// 3 Red and 3 Blue nodes) subdivision.
541
  ///
542
  /// The current implementation calculates either an embedding or a
543
  /// Kuratowski subdivision. The running time of the algorithm is O(n).
544
  ///
545
  /// \see PlanarDrawing, checkPlanarity()
546
  template <typename Graph>
547
  class PlanarEmbedding {
548
  private:
549

	
550
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
551

	
552
    const Graph& _graph;
553
    typename Graph::template ArcMap<Arc> _embedding;
554

	
555
    typename Graph::template EdgeMap<bool> _kuratowski;
556

	
557
  private:
558

	
559
    typedef typename Graph::template NodeMap<Arc> PredMap;
560

	
561
    typedef typename Graph::template EdgeMap<bool> TreeMap;
562

	
563
    typedef typename Graph::template NodeMap<int> OrderMap;
564
    typedef std::vector<Node> OrderList;
565

	
566
    typedef typename Graph::template NodeMap<int> LowMap;
567
    typedef typename Graph::template NodeMap<int> AncestorMap;
568

	
569
    typedef _planarity_bits::NodeDataNode<Graph> NodeDataNode;
570
    typedef std::vector<NodeDataNode> NodeData;
571

	
572
    typedef _planarity_bits::ChildListNode<Graph> ChildListNode;
573
    typedef typename Graph::template NodeMap<ChildListNode> ChildLists;
574

	
575
    typedef typename Graph::template NodeMap<std::list<int> > MergeRoots;
576

	
577
    typedef typename Graph::template NodeMap<Arc> EmbedArc;
578

	
579
    typedef _planarity_bits::ArcListNode<Graph> ArcListNode;
580
    typedef typename Graph::template ArcMap<ArcListNode> ArcLists;
581

	
582
    typedef typename Graph::template NodeMap<bool> FlipMap;
583

	
584
    typedef typename Graph::template NodeMap<int> TypeMap;
585

	
586
    enum IsolatorNodeType {
587
      HIGHX = 6, LOWX = 7,
588
      HIGHY = 8, LOWY = 9,
589
      ROOT = 10, PERTINENT = 11,
590
      INTERNAL = 12
591
    };
592

	
593
  public:
594

	
595
    /// \brief The map type for storing the embedding
596
    ///
597
    /// The map type for storing the embedding.
598
    /// \see embeddingMap()
599
    typedef typename Graph::template ArcMap<Arc> EmbeddingMap;
600

	
601
    /// \brief Constructor
602
    ///
603
    /// Constructor.
604
    /// \pre The graph must be simple, i.e. it should not
605
    /// contain parallel or loop arcs.
606
    PlanarEmbedding(const Graph& graph)
607
      : _graph(graph), _embedding(_graph), _kuratowski(graph, false) {}
608

	
609
    /// \brief Run the algorithm.
610
    ///
611
    /// This function runs the algorithm.
612
    /// \param kuratowski If this parameter is set to \c false, then the
613
    /// algorithm does not compute a Kuratowski subdivision.
614
    /// \return \c true if the graph is planar.
615
    bool run(bool kuratowski = true) {
616
      typedef _planarity_bits::PlanarityVisitor<Graph> Visitor;
617

	
618
      PredMap pred_map(_graph, INVALID);
619
      TreeMap tree_map(_graph, false);
620

	
621
      OrderMap order_map(_graph, -1);
622
      OrderList order_list;
623

	
624
      AncestorMap ancestor_map(_graph, -1);
625
      LowMap low_map(_graph, -1);
626

	
627
      Visitor visitor(_graph, pred_map, tree_map,
628
                      order_map, order_list, ancestor_map, low_map);
629
      DfsVisit<Graph, Visitor> visit(_graph, visitor);
630
      visit.run();
631

	
632
      ChildLists child_lists(_graph);
633
      createChildLists(tree_map, order_map, low_map, child_lists);
634

	
635
      NodeData node_data(2 * order_list.size());
636

	
637
      EmbedArc embed_arc(_graph, INVALID);
638

	
639
      MergeRoots merge_roots(_graph);
640

	
641
      ArcLists arc_lists(_graph);
642

	
643
      FlipMap flip_map(_graph, false);
644

	
645
      for (int i = order_list.size() - 1; i >= 0; --i) {
646

	
647
        Node node = order_list[i];
648

	
649
        node_data[i].first = INVALID;
650

	
651
        Node source = node;
652
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
653
          Node target = _graph.target(e);
654

	
655
          if (order_map[source] < order_map[target] && tree_map[e]) {
656
            initFace(target, arc_lists, node_data,
657
                     pred_map, order_map, order_list);
658
          }
659
        }
660

	
661
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
662
          Node target = _graph.target(e);
663

	
664
          if (order_map[source] < order_map[target] && !tree_map[e]) {
665
            embed_arc[target] = e;
666
            walkUp(target, source, i, pred_map, low_map,
667
                   order_map, order_list, node_data, merge_roots);
668
          }
669
        }
670

	
671
        for (typename MergeRoots::Value::iterator it =
672
               merge_roots[node].begin(); it != merge_roots[node].end(); ++it) {
673
          int rn = *it;
674
          walkDown(rn, i, node_data, arc_lists, flip_map, order_list,
675
                   child_lists, ancestor_map, low_map, embed_arc, merge_roots);
676
        }
677
        merge_roots[node].clear();
678

	
679
        for (OutArcIt e(_graph, node); e != INVALID; ++e) {
680
          Node target = _graph.target(e);
681

	
682
          if (order_map[source] < order_map[target] && !tree_map[e]) {
683
            if (embed_arc[target] != INVALID) {
684
              if (kuratowski) {
685
                isolateKuratowski(e, node_data, arc_lists, flip_map,
686
                                  order_map, order_list, pred_map, child_lists,
687
                                  ancestor_map, low_map,
688
                                  embed_arc, merge_roots);
689
              }
690
              return false;
691
            }
692
          }
693
        }
694
      }
695

	
696
      for (int i = 0; i < int(order_list.size()); ++i) {
697

	
698
        mergeRemainingFaces(order_list[i], node_data, order_list, order_map,
699
                            child_lists, arc_lists);
700
        storeEmbedding(order_list[i], node_data, order_map, pred_map,
701
                       arc_lists, flip_map);
702
      }
703

	
704
      return true;
705
    }
706

	
707
    /// \brief Give back the successor of an arc
708
    ///
709
    /// This function gives back the successor of an arc. It makes
710
    /// possible to query the cyclic order of the outgoing arcs from
711
    /// a node.
712
    Arc next(const Arc& arc) const {
713
      return _embedding[arc];
714
    }
715

	
716
    /// \brief Give back the calculated embedding map
717
    ///
718
    /// This function gives back the calculated embedding map, which
719
    /// contains the successor of each arc in the cyclic order of the
720
    /// outgoing arcs of its source node.
721
    const EmbeddingMap& embeddingMap() const {
722
      return _embedding;
723
    }
724

	
725
    /// \brief Give back \c true if the given edge is in the Kuratowski
726
    /// subdivision
727
    ///
728
    /// This function gives back \c true if the given edge is in the found
729
    /// Kuratowski subdivision.
730
    /// \pre The \c run() function must be called with \c true parameter
731
    /// before using this function.
732
    bool kuratowski(const Edge& edge) const {
733
      return _kuratowski[edge];
734
    }
735

	
736
  private:
737

	
738
    void createChildLists(const TreeMap& tree_map, const OrderMap& order_map,
739
                          const LowMap& low_map, ChildLists& child_lists) {
740

	
741
      for (NodeIt n(_graph); n != INVALID; ++n) {
742
        Node source = n;
743

	
744
        std::vector<Node> targets;
745
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
746
          Node target = _graph.target(e);
747

	
748
          if (order_map[source] < order_map[target] && tree_map[e]) {
749
            targets.push_back(target);
750
          }
751
        }
752

	
753
        if (targets.size() == 0) {
754
          child_lists[source].first = INVALID;
755
        } else if (targets.size() == 1) {
756
          child_lists[source].first = targets[0];
757
          child_lists[targets[0]].prev = INVALID;
758
          child_lists[targets[0]].next = INVALID;
759
        } else {
760
          radixSort(targets.begin(), targets.end(), mapToFunctor(low_map));
761
          for (int i = 1; i < int(targets.size()); ++i) {
762
            child_lists[targets[i]].prev = targets[i - 1];
763
            child_lists[targets[i - 1]].next = targets[i];
764
          }
765
          child_lists[targets.back()].next = INVALID;
766
          child_lists[targets.front()].prev = INVALID;
767
          child_lists[source].first = targets.front();
768
        }
769
      }
770
    }
771

	
772
    void walkUp(const Node& node, Node root, int rorder,
773
                const PredMap& pred_map, const LowMap& low_map,
774
                const OrderMap& order_map, const OrderList& order_list,
775
                NodeData& node_data, MergeRoots& merge_roots) {
776

	
777
      int na, nb;
778
      bool da, db;
779

	
780
      na = nb = order_map[node];
781
      da = true; db = false;
782

	
783
      while (true) {
784

	
785
        if (node_data[na].visited == rorder) break;
786
        if (node_data[nb].visited == rorder) break;
787

	
788
        node_data[na].visited = rorder;
789
        node_data[nb].visited = rorder;
790

	
791
        int rn = -1;
792

	
793
        if (na >= int(order_list.size())) {
794
          rn = na;
795
        } else if (nb >= int(order_list.size())) {
796
          rn = nb;
797
        }
798

	
799
        if (rn == -1) {
800
          int nn;
801

	
802
          nn = da ? node_data[na].prev : node_data[na].next;
803
          da = node_data[nn].prev != na;
804
          na = nn;
805

	
806
          nn = db ? node_data[nb].prev : node_data[nb].next;
807
          db = node_data[nn].prev != nb;
808
          nb = nn;
809

	
810
        } else {
811

	
812
          Node rep = order_list[rn - order_list.size()];
813
          Node parent = _graph.source(pred_map[rep]);
814

	
815
          if (low_map[rep] < rorder) {
816
            merge_roots[parent].push_back(rn);
817
          } else {
818
            merge_roots[parent].push_front(rn);
819
          }
820

	
821
          if (parent != root) {
822
            na = nb = order_map[parent];
823
            da = true; db = false;
824
          } else {
825
            break;
826
          }
827
        }
828
      }
829
    }
830

	
831
    void walkDown(int rn, int rorder, NodeData& node_data,
832
                  ArcLists& arc_lists, FlipMap& flip_map,
833
                  OrderList& order_list, ChildLists& child_lists,
834
                  AncestorMap& ancestor_map, LowMap& low_map,
835
                  EmbedArc& embed_arc, MergeRoots& merge_roots) {
836

	
837
      std::vector<std::pair<int, bool> > merge_stack;
838

	
839
      for (int di = 0; di < 2; ++di) {
840
        bool rd = di == 0;
841
        int pn = rn;
842
        int n = rd ? node_data[rn].next : node_data[rn].prev;
843

	
844
        while (n != rn) {
845

	
846
          Node node = order_list[n];
847

	
848
          if (embed_arc[node] != INVALID) {
849

	
850
            // Merging components on the critical path
851
            while (!merge_stack.empty()) {
852

	
853
              // Component root
854
              int cn = merge_stack.back().first;
855
              bool cd = merge_stack.back().second;
856
              merge_stack.pop_back();
857

	
858
              // Parent of component
859
              int dn = merge_stack.back().first;
860
              bool dd = merge_stack.back().second;
861
              merge_stack.pop_back();
862

	
863
              Node parent = order_list[dn];
864

	
865
              // Erasing from merge_roots
866
              merge_roots[parent].pop_front();
867

	
868
              Node child = order_list[cn - order_list.size()];
869

	
870
              // Erasing from child_lists
871
              if (child_lists[child].prev != INVALID) {
872
                child_lists[child_lists[child].prev].next =
873
                  child_lists[child].next;
874
              } else {
875
                child_lists[parent].first = child_lists[child].next;
876
              }
877

	
878
              if (child_lists[child].next != INVALID) {
879
                child_lists[child_lists[child].next].prev =
880
                  child_lists[child].prev;
881
              }
882

	
883
              // Merging arcs + flipping
884
              Arc de = node_data[dn].first;
885
              Arc ce = node_data[cn].first;
886

	
887
              flip_map[order_list[cn - order_list.size()]] = cd != dd;
888
              if (cd != dd) {
889
                std::swap(arc_lists[ce].prev, arc_lists[ce].next);
890
                ce = arc_lists[ce].prev;
891
                std::swap(arc_lists[ce].prev, arc_lists[ce].next);
892
              }
893

	
894
              {
895
                Arc dne = arc_lists[de].next;
896
                Arc cne = arc_lists[ce].next;
897

	
898
                arc_lists[de].next = cne;
899
                arc_lists[ce].next = dne;
900

	
901
                arc_lists[dne].prev = ce;
902
                arc_lists[cne].prev = de;
903
              }
904

	
905
              if (dd) {
906
                node_data[dn].first = ce;
907
              }
908

	
909
              // Merging external faces
910
              {
911
                int en = cn;
912
                cn = cd ? node_data[cn].prev : node_data[cn].next;
913
                cd = node_data[cn].next == en;
914

	
915
                 if (node_data[cn].prev == node_data[cn].next &&
916
                    node_data[cn].inverted) {
917
                   cd = !cd;
918
                 }
919
              }
920

	
921
              if (cd) node_data[cn].next = dn; else node_data[cn].prev = dn;
922
              if (dd) node_data[dn].prev = cn; else node_data[dn].next = cn;
923

	
924
            }
925

	
926
            bool d = pn == node_data[n].prev;
927

	
928
            if (node_data[n].prev == node_data[n].next &&
929
                node_data[n].inverted) {
930
              d = !d;
931
            }
932

	
933
            // Add new arc
934
            {
935
              Arc arc = embed_arc[node];
936
              Arc re = node_data[rn].first;
937

	
938
              arc_lists[arc_lists[re].next].prev = arc;
939
              arc_lists[arc].next = arc_lists[re].next;
940
              arc_lists[arc].prev = re;
941
              arc_lists[re].next = arc;
942

	
943
              if (!rd) {
944
                node_data[rn].first = arc;
945
              }
946

	
947
              Arc rev = _graph.oppositeArc(arc);
948
              Arc e = node_data[n].first;
949

	
950
              arc_lists[arc_lists[e].next].prev = rev;
951
              arc_lists[rev].next = arc_lists[e].next;
952
              arc_lists[rev].prev = e;
953
              arc_lists[e].next = rev;
954

	
955
              if (d) {
956
                node_data[n].first = rev;
957
              }
958

	
959
            }
960

	
961
            // Embedding arc into external face
962
            if (rd) node_data[rn].next = n; else node_data[rn].prev = n;
963
            if (d) node_data[n].prev = rn; else node_data[n].next = rn;
964
            pn = rn;
965

	
966
            embed_arc[order_list[n]] = INVALID;
967
          }
968

	
969
          if (!merge_roots[node].empty()) {
970

	
971
            bool d = pn == node_data[n].prev;
972
            if (node_data[n].prev == node_data[n].next &&
973
                node_data[n].inverted) {
974
              d = !d;
975
            }
976

	
977
            merge_stack.push_back(std::make_pair(n, d));
978

	
979
            int rn = merge_roots[node].front();
980

	
981
            int xn = node_data[rn].next;
982
            Node xnode = order_list[xn];
983

	
984
            int yn = node_data[rn].prev;
985
            Node ynode = order_list[yn];
986

	
987
            bool rd;
988
            if (!external(xnode, rorder, child_lists, ancestor_map, low_map)) {
989
              rd = true;
990
            } else if (!external(ynode, rorder, child_lists,
991
                                 ancestor_map, low_map)) {
992
              rd = false;
993
            } else if (pertinent(xnode, embed_arc, merge_roots)) {
994
              rd = true;
995
            } else {
996
              rd = false;
997
            }
998

	
999
            merge_stack.push_back(std::make_pair(rn, rd));
1000

	
1001
            pn = rn;
1002
            n = rd ? xn : yn;
1003

	
1004
          } else if (!external(node, rorder, child_lists,
1005
                               ancestor_map, low_map)) {
1006
            int nn = (node_data[n].next != pn ?
1007
                      node_data[n].next : node_data[n].prev);
1008

	
1009
            bool nd = n == node_data[nn].prev;
1010

	
1011
            if (nd) node_data[nn].prev = pn;
1012
            else node_data[nn].next = pn;
1013

	
1014
            if (n == node_data[pn].prev) node_data[pn].prev = nn;
1015
            else node_data[pn].next = nn;
1016

	
1017
            node_data[nn].inverted =
1018
              (node_data[nn].prev == node_data[nn].next && nd != rd);
1019

	
1020
            n = nn;
1021
          }
1022
          else break;
1023

	
1024
        }
1025

	
1026
        if (!merge_stack.empty() || n == rn) {
1027
          break;
1028
        }
1029
      }
1030
    }
1031

	
1032
    void initFace(const Node& node, ArcLists& arc_lists,
1033
                  NodeData& node_data, const PredMap& pred_map,
1034
                  const OrderMap& order_map, const OrderList& order_list) {
1035
      int n = order_map[node];
1036
      int rn = n + order_list.size();
1037

	
1038
      node_data[n].next = node_data[n].prev = rn;
1039
      node_data[rn].next = node_data[rn].prev = n;
1040

	
1041
      node_data[n].visited = order_list.size();
1042
      node_data[rn].visited = order_list.size();
1043

	
1044
      node_data[n].inverted = false;
1045
      node_data[rn].inverted = false;
1046

	
1047
      Arc arc = pred_map[node];
1048
      Arc rev = _graph.oppositeArc(arc);
1049

	
1050
      node_data[rn].first = arc;
1051
      node_data[n].first = rev;
1052

	
1053
      arc_lists[arc].prev = arc;
1054
      arc_lists[arc].next = arc;
1055

	
1056
      arc_lists[rev].prev = rev;
1057
      arc_lists[rev].next = rev;
1058

	
1059
    }
1060

	
1061
    void mergeRemainingFaces(const Node& node, NodeData& node_data,
1062
                             OrderList& order_list, OrderMap& order_map,
1063
                             ChildLists& child_lists, ArcLists& arc_lists) {
1064
      while (child_lists[node].first != INVALID) {
1065
        int dd = order_map[node];
1066
        Node child = child_lists[node].first;
1067
        int cd = order_map[child] + order_list.size();
1068
        child_lists[node].first = child_lists[child].next;
1069

	
1070
        Arc de = node_data[dd].first;
1071
        Arc ce = node_data[cd].first;
1072

	
1073
        if (de != INVALID) {
1074
          Arc dne = arc_lists[de].next;
1075
          Arc cne = arc_lists[ce].next;
1076

	
1077
          arc_lists[de].next = cne;
1078
          arc_lists[ce].next = dne;
1079

	
1080
          arc_lists[dne].prev = ce;
1081
          arc_lists[cne].prev = de;
1082
        }
1083

	
1084
        node_data[dd].first = ce;
1085

	
1086
      }
1087
    }
1088

	
1089
    void storeEmbedding(const Node& node, NodeData& node_data,
1090
                        OrderMap& order_map, PredMap& pred_map,
1091
                        ArcLists& arc_lists, FlipMap& flip_map) {
1092

	
1093
      if (node_data[order_map[node]].first == INVALID) return;
1094

	
1095
      if (pred_map[node] != INVALID) {
1096
        Node source = _graph.source(pred_map[node]);
1097
        flip_map[node] = flip_map[node] != flip_map[source];
1098
      }
1099

	
1100
      Arc first = node_data[order_map[node]].first;
1101
      Arc prev = first;
1102

	
1103
      Arc arc = flip_map[node] ?
1104
        arc_lists[prev].prev : arc_lists[prev].next;
1105

	
1106
      _embedding[prev] = arc;
1107

	
1108
      while (arc != first) {
1109
        Arc next = arc_lists[arc].prev == prev ?
1110
          arc_lists[arc].next : arc_lists[arc].prev;
1111
        prev = arc; arc = next;
1112
        _embedding[prev] = arc;
1113
      }
1114
    }
1115

	
1116

	
1117
    bool external(const Node& node, int rorder,
1118
                  ChildLists& child_lists, AncestorMap& ancestor_map,
1119
                  LowMap& low_map) {
1120
      Node child = child_lists[node].first;
1121

	
1122
      if (child != INVALID) {
1123
        if (low_map[child] < rorder) return true;
1124
      }
1125

	
1126
      if (ancestor_map[node] < rorder) return true;
1127

	
1128
      return false;
1129
    }
1130

	
1131
    bool pertinent(const Node& node, const EmbedArc& embed_arc,
1132
                   const MergeRoots& merge_roots) {
1133
      return !merge_roots[node].empty() || embed_arc[node] != INVALID;
1134
    }
1135

	
1136
    int lowPoint(const Node& node, OrderMap& order_map, ChildLists& child_lists,
1137
                 AncestorMap& ancestor_map, LowMap& low_map) {
1138
      int low_point;
1139

	
1140
      Node child = child_lists[node].first;
1141

	
1142
      if (child != INVALID) {
1143
        low_point = low_map[child];
1144
      } else {
1145
        low_point = order_map[node];
1146
      }
1147

	
1148
      if (low_point > ancestor_map[node]) {
1149
        low_point = ancestor_map[node];
1150
      }
1151

	
1152
      return low_point;
1153
    }
1154

	
1155
    int findComponentRoot(Node root, Node node, ChildLists& child_lists,
1156
                          OrderMap& order_map, OrderList& order_list) {
1157

	
1158
      int order = order_map[root];
1159
      int norder = order_map[node];
1160

	
1161
      Node child = child_lists[root].first;
1162
      while (child != INVALID) {
1163
        int corder = order_map[child];
1164
        if (corder > order && corder < norder) {
1165
          order = corder;
1166
        }
1167
        child = child_lists[child].next;
1168
      }
1169
      return order + order_list.size();
1170
    }
1171

	
1172
    Node findPertinent(Node node, OrderMap& order_map, NodeData& node_data,
1173
                       EmbedArc& embed_arc, MergeRoots& merge_roots) {
1174
      Node wnode =_graph.target(node_data[order_map[node]].first);
1175
      while (!pertinent(wnode, embed_arc, merge_roots)) {
1176
        wnode = _graph.target(node_data[order_map[wnode]].first);
1177
      }
1178
      return wnode;
1179
    }
1180

	
1181

	
1182
    Node findExternal(Node node, int rorder, OrderMap& order_map,
1183
                      ChildLists& child_lists, AncestorMap& ancestor_map,
1184
                      LowMap& low_map, NodeData& node_data) {
1185
      Node wnode =_graph.target(node_data[order_map[node]].first);
1186
      while (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
1187
        wnode = _graph.target(node_data[order_map[wnode]].first);
1188
      }
1189
      return wnode;
1190
    }
1191

	
1192
    void markCommonPath(Node node, int rorder, Node& wnode, Node& znode,
1193
                        OrderList& order_list, OrderMap& order_map,
1194
                        NodeData& node_data, ArcLists& arc_lists,
1195
                        EmbedArc& embed_arc, MergeRoots& merge_roots,
1196
                        ChildLists& child_lists, AncestorMap& ancestor_map,
1197
                        LowMap& low_map) {
1198

	
1199
      Node cnode = node;
1200
      Node pred = INVALID;
1201

	
1202
      while (true) {
1203

	
1204
        bool pert = pertinent(cnode, embed_arc, merge_roots);
1205
        bool ext = external(cnode, rorder, child_lists, ancestor_map, low_map);
1206

	
1207
        if (pert && ext) {
1208
          if (!merge_roots[cnode].empty()) {
1209
            int cn = merge_roots[cnode].back();
1210

	
1211
            if (low_map[order_list[cn - order_list.size()]] < rorder) {
1212
              Arc arc = node_data[cn].first;
1213
              _kuratowski.set(arc, true);
1214

	
1215
              pred = cnode;
1216
              cnode = _graph.target(arc);
1217

	
1218
              continue;
1219
            }
1220
          }
1221
          wnode = znode = cnode;
1222
          return;
1223

	
1224
        } else if (pert) {
1225
          wnode = cnode;
1226

	
1227
          while (!external(cnode, rorder, child_lists, ancestor_map, low_map)) {
1228
            Arc arc = node_data[order_map[cnode]].first;
1229

	
1230
            if (_graph.target(arc) == pred) {
1231
              arc = arc_lists[arc].next;
1232
            }
1233
            _kuratowski.set(arc, true);
1234

	
1235
            Node next = _graph.target(arc);
1236
            pred = cnode; cnode = next;
1237
          }
1238

	
1239
          znode = cnode;
1240
          return;
1241

	
1242
        } else if (ext) {
1243
          znode = cnode;
1244

	
1245
          while (!pertinent(cnode, embed_arc, merge_roots)) {
1246
            Arc arc = node_data[order_map[cnode]].first;
1247

	
1248
            if (_graph.target(arc) == pred) {
1249
              arc = arc_lists[arc].next;
1250
            }
1251
            _kuratowski.set(arc, true);
1252

	
1253
            Node next = _graph.target(arc);
1254
            pred = cnode; cnode = next;
1255
          }
1256

	
1257
          wnode = cnode;
1258
          return;
1259

	
1260
        } else {
1261
          Arc arc = node_data[order_map[cnode]].first;
1262

	
1263
          if (_graph.target(arc) == pred) {
1264
            arc = arc_lists[arc].next;
1265
          }
1266
          _kuratowski.set(arc, true);
1267

	
1268
          Node next = _graph.target(arc);
1269
          pred = cnode; cnode = next;
1270
        }
1271

	
1272
      }
1273

	
1274
    }
1275

	
1276
    void orientComponent(Node root, int rn, OrderMap& order_map,
1277
                         PredMap& pred_map, NodeData& node_data,
1278
                         ArcLists& arc_lists, FlipMap& flip_map,
1279
                         TypeMap& type_map) {
1280
      node_data[order_map[root]].first = node_data[rn].first;
1281
      type_map[root] = 1;
1282

	
1283
      std::vector<Node> st, qu;
1284

	
1285
      st.push_back(root);
1286
      while (!st.empty()) {
1287
        Node node = st.back();
1288
        st.pop_back();
1289
        qu.push_back(node);
1290

	
1291
        Arc arc = node_data[order_map[node]].first;
1292

	
1293
        if (type_map[_graph.target(arc)] == 0) {
1294
          st.push_back(_graph.target(arc));
1295
          type_map[_graph.target(arc)] = 1;
1296
        }
1297

	
1298
        Arc last = arc, pred = arc;
1299
        arc = arc_lists[arc].next;
1300
        while (arc != last) {
1301

	
1302
          if (type_map[_graph.target(arc)] == 0) {
1303
            st.push_back(_graph.target(arc));
1304
            type_map[_graph.target(arc)] = 1;
1305
          }
1306

	
1307
          Arc next = arc_lists[arc].next != pred ?
1308
            arc_lists[arc].next : arc_lists[arc].prev;
1309
          pred = arc; arc = next;
1310
        }
1311

	
1312
      }
1313

	
1314
      type_map[root] = 2;
1315
      flip_map[root] = false;
1316

	
1317
      for (int i = 1; i < int(qu.size()); ++i) {
1318

	
1319
        Node node = qu[i];
1320

	
1321
        while (type_map[node] != 2) {
1322
          st.push_back(node);
1323
          type_map[node] = 2;
1324
          node = _graph.source(pred_map[node]);
1325
        }
1326

	
1327
        bool flip = flip_map[node];
1328

	
1329
        while (!st.empty()) {
1330
          node = st.back();
1331
          st.pop_back();
1332

	
1333
          flip_map[node] = flip != flip_map[node];
1334
          flip = flip_map[node];
1335

	
1336
          if (flip) {
1337
            Arc arc = node_data[order_map[node]].first;
1338
            std::swap(arc_lists[arc].prev, arc_lists[arc].next);
1339
            arc = arc_lists[arc].prev;
1340
            std::swap(arc_lists[arc].prev, arc_lists[arc].next);
1341
            node_data[order_map[node]].first = arc;
1342
          }
1343
        }
1344
      }
1345

	
1346
      for (int i = 0; i < int(qu.size()); ++i) {
1347

	
1348
        Arc arc = node_data[order_map[qu[i]]].first;
1349
        Arc last = arc, pred = arc;
1350

	
1351
        arc = arc_lists[arc].next;
1352
        while (arc != last) {
1353

	
1354
          if (arc_lists[arc].next == pred) {
1355
            std::swap(arc_lists[arc].next, arc_lists[arc].prev);
1356
          }
1357
          pred = arc; arc = arc_lists[arc].next;
1358
        }
1359

	
1360
      }
1361
    }
1362

	
1363
    void setFaceFlags(Node root, Node wnode, Node ynode, Node xnode,
1364
                      OrderMap& order_map, NodeData& node_data,
1365
                      TypeMap& type_map) {
1366
      Node node = _graph.target(node_data[order_map[root]].first);
1367

	
1368
      while (node != ynode) {
1369
        type_map[node] = HIGHY;
1370
        node = _graph.target(node_data[order_map[node]].first);
1371
      }
1372

	
1373
      while (node != wnode) {
1374
        type_map[node] = LOWY;
1375
        node = _graph.target(node_data[order_map[node]].first);
1376
      }
1377

	
1378
      node = _graph.target(node_data[order_map[wnode]].first);
1379

	
1380
      while (node != xnode) {
1381
        type_map[node] = LOWX;
1382
        node = _graph.target(node_data[order_map[node]].first);
1383
      }
1384
      type_map[node] = LOWX;
1385

	
1386
      node = _graph.target(node_data[order_map[xnode]].first);
1387
      while (node != root) {
1388
        type_map[node] = HIGHX;
1389
        node = _graph.target(node_data[order_map[node]].first);
1390
      }
1391

	
1392
      type_map[wnode] = PERTINENT;
1393
      type_map[root] = ROOT;
1394
    }
1395

	
1396
    void findInternalPath(std::vector<Arc>& ipath,
1397
                          Node wnode, Node root, TypeMap& type_map,
1398
                          OrderMap& order_map, NodeData& node_data,
1399
                          ArcLists& arc_lists) {
1400
      std::vector<Arc> st;
1401

	
1402
      Node node = wnode;
1403

	
1404
      while (node != root) {
1405
        Arc arc = arc_lists[node_data[order_map[node]].first].next;
1406
        st.push_back(arc);
1407
        node = _graph.target(arc);
1408
      }
1409

	
1410
      while (true) {
1411
        Arc arc = st.back();
1412
        if (type_map[_graph.target(arc)] == LOWX ||
1413
            type_map[_graph.target(arc)] == HIGHX) {
1414
          break;
1415
        }
1416
        if (type_map[_graph.target(arc)] == 2) {
1417
          type_map[_graph.target(arc)] = 3;
1418

	
1419
          arc = arc_lists[_graph.oppositeArc(arc)].next;
1420
          st.push_back(arc);
1421
        } else {
1422
          st.pop_back();
1423
          arc = arc_lists[arc].next;
1424

	
1425
          while (_graph.oppositeArc(arc) == st.back()) {
1426
            arc = st.back();
1427
            st.pop_back();
1428
            arc = arc_lists[arc].next;
1429
          }
1430
          st.push_back(arc);
1431
        }
1432
      }
1433

	
1434
      for (int i = 0; i < int(st.size()); ++i) {
1435
        if (type_map[_graph.target(st[i])] != LOWY &&
1436
            type_map[_graph.target(st[i])] != HIGHY) {
1437
          for (; i < int(st.size()); ++i) {
1438
            ipath.push_back(st[i]);
1439
          }
1440
        }
1441
      }
1442
    }
1443

	
1444
    void setInternalFlags(std::vector<Arc>& ipath, TypeMap& type_map) {
1445
      for (int i = 1; i < int(ipath.size()); ++i) {
1446
        type_map[_graph.source(ipath[i])] = INTERNAL;
1447
      }
1448
    }
1449

	
1450
    void findPilePath(std::vector<Arc>& ppath,
1451
                      Node root, TypeMap& type_map, OrderMap& order_map,
1452
                      NodeData& node_data, ArcLists& arc_lists) {
1453
      std::vector<Arc> st;
1454

	
1455
      st.push_back(_graph.oppositeArc(node_data[order_map[root]].first));
1456
      st.push_back(node_data[order_map[root]].first);
1457

	
1458
      while (st.size() > 1) {
1459
        Arc arc = st.back();
1460
        if (type_map[_graph.target(arc)] == INTERNAL) {
1461
          break;
1462
        }
1463
        if (type_map[_graph.target(arc)] == 3) {
1464
          type_map[_graph.target(arc)] = 4;
1465

	
1466
          arc = arc_lists[_graph.oppositeArc(arc)].next;
1467
          st.push_back(arc);
1468
        } else {
1469
          st.pop_back();
1470
          arc = arc_lists[arc].next;
1471

	
1472
          while (!st.empty() && _graph.oppositeArc(arc) == st.back()) {
1473
            arc = st.back();
1474
            st.pop_back();
1475
            arc = arc_lists[arc].next;
1476
          }
1477
          st.push_back(arc);
1478
        }
1479
      }
1480

	
1481
      for (int i = 1; i < int(st.size()); ++i) {
1482
        ppath.push_back(st[i]);
1483
      }
1484
    }
1485

	
1486

	
1487
    int markExternalPath(Node node, OrderMap& order_map,
1488
                         ChildLists& child_lists, PredMap& pred_map,
1489
                         AncestorMap& ancestor_map, LowMap& low_map) {
1490
      int lp = lowPoint(node, order_map, child_lists,
1491
                        ancestor_map, low_map);
1492

	
1493
      if (ancestor_map[node] != lp) {
1494
        node = child_lists[node].first;
1495
        _kuratowski[pred_map[node]] = true;
1496

	
1497
        while (ancestor_map[node] != lp) {
1498
          for (OutArcIt e(_graph, node); e != INVALID; ++e) {
1499
            Node tnode = _graph.target(e);
1500
            if (order_map[tnode] > order_map[node] && low_map[tnode] == lp) {
1501
              node = tnode;
1502
              _kuratowski[e] = true;
1503
              break;
1504
            }
1505
          }
1506
        }
1507
      }
1508

	
1509
      for (OutArcIt e(_graph, node); e != INVALID; ++e) {
1510
        if (order_map[_graph.target(e)] == lp) {
1511
          _kuratowski[e] = true;
1512
          break;
1513
        }
1514
      }
1515

	
1516
      return lp;
1517
    }
1518

	
1519
    void markPertinentPath(Node node, OrderMap& order_map,
1520
                           NodeData& node_data, ArcLists& arc_lists,
1521
                           EmbedArc& embed_arc, MergeRoots& merge_roots) {
1522
      while (embed_arc[node] == INVALID) {
1523
        int n = merge_roots[node].front();
1524
        Arc arc = node_data[n].first;
1525

	
1526
        _kuratowski.set(arc, true);
1527

	
1528
        Node pred = node;
1529
        node = _graph.target(arc);
1530
        while (!pertinent(node, embed_arc, merge_roots)) {
1531
          arc = node_data[order_map[node]].first;
1532
          if (_graph.target(arc) == pred) {
1533
            arc = arc_lists[arc].next;
1534
          }
1535
          _kuratowski.set(arc, true);
1536
          pred = node;
1537
          node = _graph.target(arc);
1538
        }
1539
      }
1540
      _kuratowski.set(embed_arc[node], true);
1541
    }
1542

	
1543
    void markPredPath(Node node, Node snode, PredMap& pred_map) {
1544
      while (node != snode) {
1545
        _kuratowski.set(pred_map[node], true);
1546
        node = _graph.source(pred_map[node]);
1547
      }
1548
    }
1549

	
1550
    void markFacePath(Node ynode, Node xnode,
1551
                      OrderMap& order_map, NodeData& node_data) {
1552
      Arc arc = node_data[order_map[ynode]].first;
1553
      Node node = _graph.target(arc);
1554
      _kuratowski.set(arc, true);
1555

	
1556
      while (node != xnode) {
1557
        arc = node_data[order_map[node]].first;
1558
        _kuratowski.set(arc, true);
1559
        node = _graph.target(arc);
1560
      }
1561
    }
1562

	
1563
    void markInternalPath(std::vector<Arc>& path) {
1564
      for (int i = 0; i < int(path.size()); ++i) {
1565
        _kuratowski.set(path[i], true);
1566
      }
1567
    }
1568

	
1569
    void markPilePath(std::vector<Arc>& path) {
1570
      for (int i = 0; i < int(path.size()); ++i) {
1571
        _kuratowski.set(path[i], true);
1572
      }
1573
    }
1574

	
1575
    void isolateKuratowski(Arc arc, NodeData& node_data,
1576
                           ArcLists& arc_lists, FlipMap& flip_map,
1577
                           OrderMap& order_map, OrderList& order_list,
1578
                           PredMap& pred_map, ChildLists& child_lists,
1579
                           AncestorMap& ancestor_map, LowMap& low_map,
1580
                           EmbedArc& embed_arc, MergeRoots& merge_roots) {
1581

	
1582
      Node root = _graph.source(arc);
1583
      Node enode = _graph.target(arc);
1584

	
1585
      int rorder = order_map[root];
1586

	
1587
      TypeMap type_map(_graph, 0);
1588

	
1589
      int rn = findComponentRoot(root, enode, child_lists,
1590
                                 order_map, order_list);
1591

	
1592
      Node xnode = order_list[node_data[rn].next];
1593
      Node ynode = order_list[node_data[rn].prev];
1594

	
1595
      // Minor-A
1596
      {
1597
        while (!merge_roots[xnode].empty() || !merge_roots[ynode].empty()) {
1598

	
1599
          if (!merge_roots[xnode].empty()) {
1600
            root = xnode;
1601
            rn = merge_roots[xnode].front();
1602
          } else {
1603
            root = ynode;
1604
            rn = merge_roots[ynode].front();
1605
          }
1606

	
1607
          xnode = order_list[node_data[rn].next];
1608
          ynode = order_list[node_data[rn].prev];
1609
        }
1610

	
1611
        if (root != _graph.source(arc)) {
1612
          orientComponent(root, rn, order_map, pred_map,
1613
                          node_data, arc_lists, flip_map, type_map);
1614
          markFacePath(root, root, order_map, node_data);
1615
          int xlp = markExternalPath(xnode, order_map, child_lists,
1616
                                     pred_map, ancestor_map, low_map);
1617
          int ylp = markExternalPath(ynode, order_map, child_lists,
1618
                                     pred_map, ancestor_map, low_map);
1619
          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1620
          Node lwnode = findPertinent(ynode, order_map, node_data,
1621
                                      embed_arc, merge_roots);
1622

	
1623
          markPertinentPath(lwnode, order_map, node_data, arc_lists,
1624
                            embed_arc, merge_roots);
1625

	
1626
          return;
1627
        }
1628
      }
1629

	
1630
      orientComponent(root, rn, order_map, pred_map,
1631
                      node_data, arc_lists, flip_map, type_map);
1632

	
1633
      Node wnode = findPertinent(ynode, order_map, node_data,
1634
                                 embed_arc, merge_roots);
1635
      setFaceFlags(root, wnode, ynode, xnode, order_map, node_data, type_map);
1636

	
1637

	
1638
      //Minor-B
1639
      if (!merge_roots[wnode].empty()) {
1640
        int cn = merge_roots[wnode].back();
1641
        Node rep = order_list[cn - order_list.size()];
1642
        if (low_map[rep] < rorder) {
1643
          markFacePath(root, root, order_map, node_data);
1644
          int xlp = markExternalPath(xnode, order_map, child_lists,
1645
                                     pred_map, ancestor_map, low_map);
1646
          int ylp = markExternalPath(ynode, order_map, child_lists,
1647
                                     pred_map, ancestor_map, low_map);
1648

	
1649
          Node lwnode, lznode;
1650
          markCommonPath(wnode, rorder, lwnode, lznode, order_list,
1651
                         order_map, node_data, arc_lists, embed_arc,
1652
                         merge_roots, child_lists, ancestor_map, low_map);
1653

	
1654
          markPertinentPath(lwnode, order_map, node_data, arc_lists,
1655
                            embed_arc, merge_roots);
1656
          int zlp = markExternalPath(lznode, order_map, child_lists,
1657
                                     pred_map, ancestor_map, low_map);
1658

	
1659
          int minlp = xlp < ylp ? xlp : ylp;
1660
          if (zlp < minlp) minlp = zlp;
1661

	
1662
          int maxlp = xlp > ylp ? xlp : ylp;
1663
          if (zlp > maxlp) maxlp = zlp;
1664

	
1665
          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1666

	
1667
          return;
1668
        }
1669
      }
1670

	
1671
      Node pxnode, pynode;
1672
      std::vector<Arc> ipath;
1673
      findInternalPath(ipath, wnode, root, type_map, order_map,
1674
                       node_data, arc_lists);
1675
      setInternalFlags(ipath, type_map);
1676
      pynode = _graph.source(ipath.front());
1677
      pxnode = _graph.target(ipath.back());
1678

	
1679
      wnode = findPertinent(pynode, order_map, node_data,
1680
                            embed_arc, merge_roots);
1681

	
1682
      // Minor-C
1683
      {
1684
        if (type_map[_graph.source(ipath.front())] == HIGHY) {
1685
          if (type_map[_graph.target(ipath.back())] == HIGHX) {
1686
            markFacePath(xnode, pxnode, order_map, node_data);
1687
          }
1688
          markFacePath(root, xnode, order_map, node_data);
1689
          markPertinentPath(wnode, order_map, node_data, arc_lists,
1690
                            embed_arc, merge_roots);
1691
          markInternalPath(ipath);
1692
          int xlp = markExternalPath(xnode, order_map, child_lists,
1693
                                     pred_map, ancestor_map, low_map);
1694
          int ylp = markExternalPath(ynode, order_map, child_lists,
1695
                                     pred_map, ancestor_map, low_map);
1696
          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1697
          return;
1698
        }
1699

	
1700
        if (type_map[_graph.target(ipath.back())] == HIGHX) {
1701
          markFacePath(ynode, root, order_map, node_data);
1702
          markPertinentPath(wnode, order_map, node_data, arc_lists,
1703
                            embed_arc, merge_roots);
1704
          markInternalPath(ipath);
1705
          int xlp = markExternalPath(xnode, order_map, child_lists,
1706
                                     pred_map, ancestor_map, low_map);
1707
          int ylp = markExternalPath(ynode, order_map, child_lists,
1708
                                     pred_map, ancestor_map, low_map);
1709
          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1710
          return;
1711
        }
1712
      }
1713

	
1714
      std::vector<Arc> ppath;
1715
      findPilePath(ppath, root, type_map, order_map, node_data, arc_lists);
1716

	
1717
      // Minor-D
1718
      if (!ppath.empty()) {
1719
        markFacePath(ynode, xnode, order_map, node_data);
1720
        markPertinentPath(wnode, order_map, node_data, arc_lists,
1721
                          embed_arc, merge_roots);
1722
        markPilePath(ppath);
1723
        markInternalPath(ipath);
1724
        int xlp = markExternalPath(xnode, order_map, child_lists,
1725
                                   pred_map, ancestor_map, low_map);
1726
        int ylp = markExternalPath(ynode, order_map, child_lists,
1727
                                   pred_map, ancestor_map, low_map);
1728
        markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1729
        return;
1730
      }
1731

	
1732
      // Minor-E*
1733
      {
1734

	
1735
        if (!external(wnode, rorder, child_lists, ancestor_map, low_map)) {
1736
          Node znode = findExternal(pynode, rorder, order_map,
1737
                                    child_lists, ancestor_map,
1738
                                    low_map, node_data);
1739

	
1740
          if (type_map[znode] == LOWY) {
1741
            markFacePath(root, xnode, order_map, node_data);
1742
            markPertinentPath(wnode, order_map, node_data, arc_lists,
1743
                              embed_arc, merge_roots);
1744
            markInternalPath(ipath);
1745
            int xlp = markExternalPath(xnode, order_map, child_lists,
1746
                                       pred_map, ancestor_map, low_map);
1747
            int zlp = markExternalPath(znode, order_map, child_lists,
1748
                                       pred_map, ancestor_map, low_map);
1749
            markPredPath(root, order_list[xlp < zlp ? xlp : zlp], pred_map);
1750
          } else {
1751
            markFacePath(ynode, root, order_map, node_data);
1752
            markPertinentPath(wnode, order_map, node_data, arc_lists,
1753
                              embed_arc, merge_roots);
1754
            markInternalPath(ipath);
1755
            int ylp = markExternalPath(ynode, order_map, child_lists,
1756
                                       pred_map, ancestor_map, low_map);
1757
            int zlp = markExternalPath(znode, order_map, child_lists,
1758
                                       pred_map, ancestor_map, low_map);
1759
            markPredPath(root, order_list[ylp < zlp ? ylp : zlp], pred_map);
1760
          }
1761
          return;
1762
        }
1763

	
1764
        int xlp = markExternalPath(xnode, order_map, child_lists,
1765
                                   pred_map, ancestor_map, low_map);
1766
        int ylp = markExternalPath(ynode, order_map, child_lists,
1767
                                   pred_map, ancestor_map, low_map);
1768
        int wlp = markExternalPath(wnode, order_map, child_lists,
1769
                                   pred_map, ancestor_map, low_map);
1770

	
1771
        if (wlp > xlp && wlp > ylp) {
1772
          markFacePath(root, root, order_map, node_data);
1773
          markPredPath(root, order_list[xlp < ylp ? xlp : ylp], pred_map);
1774
          return;
1775
        }
1776

	
1777
        markInternalPath(ipath);
1778
        markPertinentPath(wnode, order_map, node_data, arc_lists,
1779
                          embed_arc, merge_roots);
1780

	
1781
        if (xlp > ylp && xlp > wlp) {
1782
          markFacePath(root, pynode, order_map, node_data);
1783
          markFacePath(wnode, xnode, order_map, node_data);
1784
          markPredPath(root, order_list[ylp < wlp ? ylp : wlp], pred_map);
1785
          return;
1786
        }
1787

	
1788
        if (ylp > xlp && ylp > wlp) {
1789
          markFacePath(pxnode, root, order_map, node_data);
1790
          markFacePath(ynode, wnode, order_map, node_data);
1791
          markPredPath(root, order_list[xlp < wlp ? xlp : wlp], pred_map);
1792
          return;
1793
        }
1794

	
1795
        if (pynode != ynode) {
1796
          markFacePath(pxnode, wnode, order_map, node_data);
1797

	
1798
          int minlp = xlp < ylp ? xlp : ylp;
1799
          if (wlp < minlp) minlp = wlp;
1800

	
1801
          int maxlp = xlp > ylp ? xlp : ylp;
1802
          if (wlp > maxlp) maxlp = wlp;
1803

	
1804
          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1805
          return;
1806
        }
1807

	
1808
        if (pxnode != xnode) {
1809
          markFacePath(wnode, pynode, order_map, node_data);
1810

	
1811
          int minlp = xlp < ylp ? xlp : ylp;
1812
          if (wlp < minlp) minlp = wlp;
1813

	
1814
          int maxlp = xlp > ylp ? xlp : ylp;
1815
          if (wlp > maxlp) maxlp = wlp;
1816

	
1817
          markPredPath(order_list[maxlp], order_list[minlp], pred_map);
1818
          return;
1819
        }
1820

	
1821
        markFacePath(root, root, order_map, node_data);
1822
        int minlp = xlp < ylp ? xlp : ylp;
1823
        if (wlp < minlp) minlp = wlp;
1824
        markPredPath(root, order_list[minlp], pred_map);
1825
        return;
1826
      }
1827

	
1828
    }
1829

	
1830
  };
1831

	
1832
  namespace _planarity_bits {
1833

	
1834
    template <typename Graph, typename EmbeddingMap>
1835
    void makeConnected(Graph& graph, EmbeddingMap& embedding) {
1836
      DfsVisitor<Graph> null_visitor;
1837
      DfsVisit<Graph, DfsVisitor<Graph> > dfs(graph, null_visitor);
1838
      dfs.init();
1839

	
1840
      typename Graph::Node u = INVALID;
1841
      for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1842
        if (!dfs.reached(n)) {
1843
          dfs.addSource(n);
1844
          dfs.start();
1845
          if (u == INVALID) {
1846
            u = n;
1847
          } else {
1848
            typename Graph::Node v = n;
1849

	
1850
            typename Graph::Arc ue = typename Graph::OutArcIt(graph, u);
1851
            typename Graph::Arc ve = typename Graph::OutArcIt(graph, v);
1852

	
1853
            typename Graph::Arc e = graph.direct(graph.addEdge(u, v), true);
1854

	
1855
            if (ue != INVALID) {
1856
              embedding[e] = embedding[ue];
1857
              embedding[ue] = e;
1858
            } else {
1859
              embedding[e] = e;
1860
            }
1861

	
1862
            if (ve != INVALID) {
1863
              embedding[graph.oppositeArc(e)] = embedding[ve];
1864
              embedding[ve] = graph.oppositeArc(e);
1865
            } else {
1866
              embedding[graph.oppositeArc(e)] = graph.oppositeArc(e);
1867
            }
1868
          }
1869
        }
1870
      }
1871
    }
1872

	
1873
    template <typename Graph, typename EmbeddingMap>
1874
    void makeBiNodeConnected(Graph& graph, EmbeddingMap& embedding) {
1875
      typename Graph::template ArcMap<bool> processed(graph);
1876

	
1877
      std::vector<typename Graph::Arc> arcs;
1878
      for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
1879
        arcs.push_back(e);
1880
      }
1881

	
1882
      IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
1883

	
1884
      for (int i = 0; i < int(arcs.size()); ++i) {
1885
        typename Graph::Arc pp = arcs[i];
1886
        if (processed[pp]) continue;
1887

	
1888
        typename Graph::Arc e = embedding[graph.oppositeArc(pp)];
1889
        processed[e] = true;
1890
        visited.set(graph.source(e), true);
1891

	
1892
        typename Graph::Arc p = e, l = e;
1893
        e = embedding[graph.oppositeArc(e)];
1894

	
1895
        while (e != l) {
1896
          processed[e] = true;
1897

	
1898
          if (visited[graph.source(e)]) {
1899

	
1900
            typename Graph::Arc n =
1901
              graph.direct(graph.addEdge(graph.source(p),
1902
                                           graph.target(e)), true);
1903
            embedding[n] = p;
1904
            embedding[graph.oppositeArc(pp)] = n;
1905

	
1906
            embedding[graph.oppositeArc(n)] =
1907
              embedding[graph.oppositeArc(e)];
1908
            embedding[graph.oppositeArc(e)] =
1909
              graph.oppositeArc(n);
1910

	
1911
            p = n;
1912
            e = embedding[graph.oppositeArc(n)];
1913
          } else {
1914
            visited.set(graph.source(e), true);
1915
            pp = p;
1916
            p = e;
1917
            e = embedding[graph.oppositeArc(e)];
1918
          }
1919
        }
1920
        visited.setAll(false);
1921
      }
1922
    }
1923

	
1924

	
1925
    template <typename Graph, typename EmbeddingMap>
1926
    void makeMaxPlanar(Graph& graph, EmbeddingMap& embedding) {
1927

	
1928
      typename Graph::template NodeMap<int> degree(graph);
1929

	
1930
      for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1931
        degree[n] = countIncEdges(graph, n);
1932
      }
1933

	
1934
      typename Graph::template ArcMap<bool> processed(graph);
1935
      IterableBoolMap<Graph, typename Graph::Node> visited(graph, false);
1936

	
1937
      std::vector<typename Graph::Arc> arcs;
1938
      for (typename Graph::ArcIt e(graph); e != INVALID; ++e) {
1939
        arcs.push_back(e);
1940
      }
1941

	
1942
      for (int i = 0; i < int(arcs.size()); ++i) {
1943
        typename Graph::Arc e = arcs[i];
1944

	
1945
        if (processed[e]) continue;
1946
        processed[e] = true;
1947

	
1948
        typename Graph::Arc mine = e;
1949
        int mind = degree[graph.source(e)];
1950

	
1951
        int face_size = 1;
1952

	
1953
        typename Graph::Arc l = e;
1954
        e = embedding[graph.oppositeArc(e)];
1955
        while (l != e) {
1956
          processed[e] = true;
1957

	
1958
          ++face_size;
1959

	
1960
          if (degree[graph.source(e)] < mind) {
1961
            mine = e;
1962
            mind = degree[graph.source(e)];
1963
          }
1964

	
1965
          e = embedding[graph.oppositeArc(e)];
1966
        }
1967

	
1968
        if (face_size < 4) {
1969
          continue;
1970
        }
1971

	
1972
        typename Graph::Node s = graph.source(mine);
1973
        for (typename Graph::OutArcIt e(graph, s); e != INVALID; ++e) {
1974
          visited.set(graph.target(e), true);
1975
        }
1976

	
1977
        typename Graph::Arc oppe = INVALID;
1978

	
1979
        e = embedding[graph.oppositeArc(mine)];
1980
        e = embedding[graph.oppositeArc(e)];
1981
        while (graph.target(e) != s) {
1982
          if (visited[graph.source(e)]) {
1983
            oppe = e;
1984
            break;
1985
          }
1986
          e = embedding[graph.oppositeArc(e)];
1987
        }
1988
        visited.setAll(false);
1989

	
1990
        if (oppe == INVALID) {
1991

	
1992
          e = embedding[graph.oppositeArc(mine)];
1993
          typename Graph::Arc pn = mine, p = e;
1994

	
1995
          e = embedding[graph.oppositeArc(e)];
1996
          while (graph.target(e) != s) {
1997
            typename Graph::Arc n =
1998
              graph.direct(graph.addEdge(s, graph.source(e)), true);
1999

	
2000
            embedding[n] = pn;
2001
            embedding[graph.oppositeArc(n)] = e;
2002
            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
2003

	
2004
            pn = n;
2005

	
2006
            p = e;
2007
            e = embedding[graph.oppositeArc(e)];
2008
          }
2009

	
2010
          embedding[graph.oppositeArc(e)] = pn;
2011

	
2012
        } else {
2013

	
2014
          mine = embedding[graph.oppositeArc(mine)];
2015
          s = graph.source(mine);
2016
          oppe = embedding[graph.oppositeArc(oppe)];
2017
          typename Graph::Node t = graph.source(oppe);
2018

	
2019
          typename Graph::Arc ce = graph.direct(graph.addEdge(s, t), true);
2020
          embedding[ce] = mine;
2021
          embedding[graph.oppositeArc(ce)] = oppe;
2022

	
2023
          typename Graph::Arc pn = ce, p = oppe;
2024
          e = embedding[graph.oppositeArc(oppe)];
2025
          while (graph.target(e) != s) {
2026
            typename Graph::Arc n =
2027
              graph.direct(graph.addEdge(s, graph.source(e)), true);
2028

	
2029
            embedding[n] = pn;
2030
            embedding[graph.oppositeArc(n)] = e;
2031
            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
2032

	
2033
            pn = n;
2034

	
2035
            p = e;
2036
            e = embedding[graph.oppositeArc(e)];
2037

	
2038
          }
2039
          embedding[graph.oppositeArc(e)] = pn;
2040

	
2041
          pn = graph.oppositeArc(ce), p = mine;
2042
          e = embedding[graph.oppositeArc(mine)];
2043
          while (graph.target(e) != t) {
2044
            typename Graph::Arc n =
2045
              graph.direct(graph.addEdge(t, graph.source(e)), true);
2046

	
2047
            embedding[n] = pn;
2048
            embedding[graph.oppositeArc(n)] = e;
2049
            embedding[graph.oppositeArc(p)] = graph.oppositeArc(n);
2050

	
2051
            pn = n;
2052

	
2053
            p = e;
2054
            e = embedding[graph.oppositeArc(e)];
2055

	
2056
          }
2057
          embedding[graph.oppositeArc(e)] = pn;
2058
        }
2059
      }
2060
    }
2061

	
2062
  }
2063

	
2064
  /// \ingroup planar
2065
  ///
2066
  /// \brief Schnyder's planar drawing algorithm
2067
  ///
2068
  /// The planar drawing algorithm calculates positions for the nodes
2069
  /// in the plane. These coordinates satisfy that if the edges are
2070
  /// represented with straight lines, then they will not intersect
2071
  /// each other.
2072
  ///
2073
  /// Scnyder's algorithm embeds the graph on an \c (n-2)x(n-2) size grid,
2074
  /// i.e. each node will be located in the \c [0..n-2]x[0..n-2] square.
2075
  /// The time complexity of the algorithm is O(n).
2076
  ///
2077
  /// \see PlanarEmbedding
2078
  template <typename Graph>
2079
  class PlanarDrawing {
2080
  public:
2081

	
2082
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2083

	
2084
    /// \brief The point type for storing coordinates
2085
    typedef dim2::Point<int> Point;
2086
    /// \brief The map type for storing the coordinates of the nodes
2087
    typedef typename Graph::template NodeMap<Point> PointMap;
2088

	
2089

	
2090
    /// \brief Constructor
2091
    ///
2092
    /// Constructor
2093
    /// \pre The graph must be simple, i.e. it should not
2094
    /// contain parallel or loop arcs.
2095
    PlanarDrawing(const Graph& graph)
2096
      : _graph(graph), _point_map(graph) {}
2097

	
2098
  private:
2099

	
2100
    template <typename AuxGraph, typename AuxEmbeddingMap>
2101
    void drawing(const AuxGraph& graph,
2102
                 const AuxEmbeddingMap& next,
2103
                 PointMap& point_map) {
2104
      TEMPLATE_GRAPH_TYPEDEFS(AuxGraph);
2105

	
2106
      typename AuxGraph::template ArcMap<Arc> prev(graph);
2107

	
2108
      for (NodeIt n(graph); n != INVALID; ++n) {
2109
        Arc e = OutArcIt(graph, n);
2110

	
2111
        Arc p = e, l = e;
2112

	
2113
        e = next[e];
2114
        while (e != l) {
2115
          prev[e] = p;
2116
          p = e;
2117
          e = next[e];
2118
        }
2119
        prev[e] = p;
2120
      }
2121

	
2122
      Node anode, bnode, cnode;
2123

	
2124
      {
2125
        Arc e = ArcIt(graph);
2126
        anode = graph.source(e);
2127
        bnode = graph.target(e);
2128
        cnode = graph.target(next[graph.oppositeArc(e)]);
2129
      }
2130

	
2131
      IterableBoolMap<AuxGraph, Node> proper(graph, false);
2132
      typename AuxGraph::template NodeMap<int> conn(graph, -1);
2133

	
2134
      conn[anode] = conn[bnode] = -2;
2135
      {
2136
        for (OutArcIt e(graph, anode); e != INVALID; ++e) {
2137
          Node m = graph.target(e);
2138
          if (conn[m] == -1) {
2139
            conn[m] = 1;
2140
          }
2141
        }
2142
        conn[cnode] = 2;
2143

	
2144
        for (OutArcIt e(graph, bnode); e != INVALID; ++e) {
2145
          Node m = graph.target(e);
2146
          if (conn[m] == -1) {
2147
            conn[m] = 1;
2148
          } else if (conn[m] != -2) {
2149
            conn[m] += 1;
2150
            Arc pe = graph.oppositeArc(e);
2151
            if (conn[graph.target(next[pe])] == -2) {
2152
              conn[m] -= 1;
2153
            }
2154
            if (conn[graph.target(prev[pe])] == -2) {
2155
              conn[m] -= 1;
2156
            }
2157

	
2158
            proper.set(m, conn[m] == 1);
2159
          }
2160
        }
2161
      }
2162

	
2163

	
2164
      typename AuxGraph::template ArcMap<int> angle(graph, -1);
2165

	
2166
      while (proper.trueNum() != 0) {
2167
        Node n = typename IterableBoolMap<AuxGraph, Node>::TrueIt(proper);
2168
        proper.set(n, false);
2169
        conn[n] = -2;
2170

	
2171
        for (OutArcIt e(graph, n); e != INVALID; ++e) {
2172
          Node m = graph.target(e);
2173
          if (conn[m] == -1) {
2174
            conn[m] = 1;
2175
          } else if (conn[m] != -2) {
2176
            conn[m] += 1;
2177
            Arc pe = graph.oppositeArc(e);
2178
            if (conn[graph.target(next[pe])] == -2) {
2179
              conn[m] -= 1;
2180
            }
2181
            if (conn[graph.target(prev[pe])] == -2) {
2182
              conn[m] -= 1;
2183
            }
2184

	
2185
            proper.set(m, conn[m] == 1);
2186
          }
2187
        }
2188

	
2189
        {
2190
          Arc e = OutArcIt(graph, n);
2191
          Arc p = e, l = e;
2192

	
2193
          e = next[e];
2194
          while (e != l) {
2195

	
2196
            if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
2197
              Arc f = e;
2198
              angle[f] = 0;
2199
              f = next[graph.oppositeArc(f)];
2200
              angle[f] = 1;
2201
              f = next[graph.oppositeArc(f)];
2202
              angle[f] = 2;
2203
            }
2204

	
2205
            p = e;
2206
            e = next[e];
2207
          }
2208

	
2209
          if (conn[graph.target(e)] == -2 && conn[graph.target(p)] == -2) {
2210
            Arc f = e;
2211
            angle[f] = 0;
2212
            f = next[graph.oppositeArc(f)];
2213
            angle[f] = 1;
2214
            f = next[graph.oppositeArc(f)];
2215
            angle[f] = 2;
2216
          }
2217
        }
2218
      }
2219

	
2220
      typename AuxGraph::template NodeMap<Node> apred(graph, INVALID);
2221
      typename AuxGraph::template NodeMap<Node> bpred(graph, INVALID);
2222
      typename AuxGraph::template NodeMap<Node> cpred(graph, INVALID);
2223

	
2224
      typename AuxGraph::template NodeMap<int> apredid(graph, -1);
2225
      typename AuxGraph::template NodeMap<int> bpredid(graph, -1);
2226
      typename AuxGraph::template NodeMap<int> cpredid(graph, -1);
2227

	
2228
      for (ArcIt e(graph); e != INVALID; ++e) {
2229
        if (angle[e] == angle[next[e]]) {
2230
          switch (angle[e]) {
2231
          case 2:
2232
            apred[graph.target(e)] = graph.source(e);
2233
            apredid[graph.target(e)] = graph.id(graph.source(e));
2234
            break;
2235
          case 1:
2236
            bpred[graph.target(e)] = graph.source(e);
2237
            bpredid[graph.target(e)] = graph.id(graph.source(e));
2238
            break;
2239
          case 0:
2240
            cpred[graph.target(e)] = graph.source(e);
2241
            cpredid[graph.target(e)] = graph.id(graph.source(e));
2242
            break;
2243
          }
2244
        }
2245
      }
2246

	
2247
      cpred[anode] = INVALID;
2248
      cpred[bnode] = INVALID;
2249

	
2250
      std::vector<Node> aorder, border, corder;
2251

	
2252
      {
2253
        typename AuxGraph::template NodeMap<bool> processed(graph, false);
2254
        std::vector<Node> st;
2255
        for (NodeIt n(graph); n != INVALID; ++n) {
2256
          if (!processed[n] && n != bnode && n != cnode) {
2257
            st.push_back(n);
2258
            processed[n] = true;
2259
            Node m = apred[n];
2260
            while (m != INVALID && !processed[m]) {
2261
              st.push_back(m);
2262
              processed[m] = true;
2263
              m = apred[m];
2264
            }
2265
            while (!st.empty()) {
2266
              aorder.push_back(st.back());
2267
              st.pop_back();
2268
            }
2269
          }
2270
        }
2271
      }
2272

	
2273
      {
2274
        typename AuxGraph::template NodeMap<bool> processed(graph, false);
2275
        std::vector<Node> st;
2276
        for (NodeIt n(graph); n != INVALID; ++n) {
2277
          if (!processed[n] && n != cnode && n != anode) {
2278
            st.push_back(n);
2279
            processed[n] = true;
2280
            Node m = bpred[n];
2281
            while (m != INVALID && !processed[m]) {
2282
              st.push_back(m);
2283
              processed[m] = true;
2284
              m = bpred[m];
2285
            }
2286
            while (!st.empty()) {
2287
              border.push_back(st.back());
2288
              st.pop_back();
2289
            }
2290
          }
2291
        }
2292
      }
2293

	
2294
      {
2295
        typename AuxGraph::template NodeMap<bool> processed(graph, false);
2296
        std::vector<Node> st;
2297
        for (NodeIt n(graph); n != INVALID; ++n) {
2298
          if (!processed[n] && n != anode && n != bnode) {
2299
            st.push_back(n);
2300
            processed[n] = true;
2301
            Node m = cpred[n];
2302
            while (m != INVALID && !processed[m]) {
2303
              st.push_back(m);
2304
              processed[m] = true;
2305
              m = cpred[m];
2306
            }
2307
            while (!st.empty()) {
2308
              corder.push_back(st.back());
2309
              st.pop_back();
2310
            }
2311
          }
2312
        }
2313
      }
2314

	
2315
      typename AuxGraph::template NodeMap<int> atree(graph, 0);
2316
      for (int i = aorder.size() - 1; i >= 0; --i) {
2317
        Node n = aorder[i];
2318
        atree[n] = 1;
2319
        for (OutArcIt e(graph, n); e != INVALID; ++e) {
2320
          if (apred[graph.target(e)] == n) {
2321
            atree[n] += atree[graph.target(e)];
2322
          }
2323
        }
2324
      }
2325

	
2326
      typename AuxGraph::template NodeMap<int> btree(graph, 0);
2327
      for (int i = border.size() - 1; i >= 0; --i) {
2328
        Node n = border[i];
2329
        btree[n] = 1;
2330
        for (OutArcIt e(graph, n); e != INVALID; ++e) {
2331
          if (bpred[graph.target(e)] == n) {
2332
            btree[n] += btree[graph.target(e)];
2333
          }
2334
        }
2335
      }
2336

	
2337
      typename AuxGraph::template NodeMap<int> apath(graph, 0);
2338
      apath[bnode] = apath[cnode] = 1;
2339
      typename AuxGraph::template NodeMap<int> apath_btree(graph, 0);
2340
      apath_btree[bnode] = btree[bnode];
2341
      for (int i = 1; i < int(aorder.size()); ++i) {
2342
        Node n = aorder[i];
2343
        apath[n] = apath[apred[n]] + 1;
2344
        apath_btree[n] = btree[n] + apath_btree[apred[n]];
2345
      }
2346

	
2347
      typename AuxGraph::template NodeMap<int> bpath_atree(graph, 0);
2348
      bpath_atree[anode] = atree[anode];
2349
      for (int i = 1; i < int(border.size()); ++i) {
2350
        Node n = border[i];
2351
        bpath_atree[n] = atree[n] + bpath_atree[bpred[n]];
2352
      }
2353

	
2354
      typename AuxGraph::template NodeMap<int> cpath(graph, 0);
2355
      cpath[anode] = cpath[bnode] = 1;
2356
      typename AuxGraph::template NodeMap<int> cpath_atree(graph, 0);
2357
      cpath_atree[anode] = atree[anode];
2358
      typename AuxGraph::template NodeMap<int> cpath_btree(graph, 0);
2359
      cpath_btree[bnode] = btree[bnode];
2360
      for (int i = 1; i < int(corder.size()); ++i) {
2361
        Node n = corder[i];
2362
        cpath[n] = cpath[cpred[n]] + 1;
2363
        cpath_atree[n] = atree[n] + cpath_atree[cpred[n]];
2364
        cpath_btree[n] = btree[n] + cpath_btree[cpred[n]];
2365
      }
2366

	
2367
      typename AuxGraph::template NodeMap<int> third(graph);
2368
      for (NodeIt n(graph); n != INVALID; ++n) {
2369
        point_map[n].x =
2370
          bpath_atree[n] + cpath_atree[n] - atree[n] - cpath[n] + 1;
2371
        point_map[n].y =
2372
          cpath_btree[n] + apath_btree[n] - btree[n] - apath[n] + 1;
2373
      }
2374

	
2375
    }
2376

	
2377
  public:
2378

	
2379
    /// \brief Calculate the node positions
2380
    ///
2381
    /// This function calculates the node positions on the plane.
2382
    /// \return \c true if the graph is planar.
2383
    bool run() {
2384
      PlanarEmbedding<Graph> pe(_graph);
2385
      if (!pe.run()) return false;
2386

	
2387
      run(pe);
2388
      return true;
2389
    }
2390

	
2391
    /// \brief Calculate the node positions according to a
2392
    /// combinatorical embedding
2393
    ///
2394
    /// This function calculates the node positions on the plane.
2395
    /// The given \c embedding map should contain a valid combinatorical
2396
    /// embedding, i.e. a valid cyclic order of the arcs.
2397
    /// It can be computed using PlanarEmbedding.
2398
    template <typename EmbeddingMap>
2399
    void run(const EmbeddingMap& embedding) {
2400
      typedef SmartEdgeSet<Graph> AuxGraph;
2401

	
2402
      if (3 * countNodes(_graph) - 6 == countEdges(_graph)) {
2403
        drawing(_graph, embedding, _point_map);
2404
        return;
2405
      }
2406

	
2407
      AuxGraph aux_graph(_graph);
2408
      typename AuxGraph::template ArcMap<typename AuxGraph::Arc>
2409
        aux_embedding(aux_graph);
2410

	
2411
      {
2412

	
2413
        typename Graph::template EdgeMap<typename AuxGraph::Edge>
2414
          ref(_graph);
2415

	
2416
        for (EdgeIt e(_graph); e != INVALID; ++e) {
2417
          ref[e] = aux_graph.addEdge(_graph.u(e), _graph.v(e));
2418
        }
2419

	
2420
        for (EdgeIt e(_graph); e != INVALID; ++e) {
2421
          Arc ee = embedding[_graph.direct(e, true)];
2422
          aux_embedding[aux_graph.direct(ref[e], true)] =
2423
            aux_graph.direct(ref[ee], _graph.direction(ee));
2424
          ee = embedding[_graph.direct(e, false)];
2425
          aux_embedding[aux_graph.direct(ref[e], false)] =
2426
            aux_graph.direct(ref[ee], _graph.direction(ee));
2427
        }
2428
      }
2429
      _planarity_bits::makeConnected(aux_graph, aux_embedding);
2430
      _planarity_bits::makeBiNodeConnected(aux_graph, aux_embedding);
2431
      _planarity_bits::makeMaxPlanar(aux_graph, aux_embedding);
2432
      drawing(aux_graph, aux_embedding, _point_map);
2433
    }
2434

	
2435
    /// \brief The coordinate of the given node
2436
    ///
2437
    /// This function returns the coordinate of the given node.
2438
    Point operator[](const Node& node) const {
2439
      return _point_map[node];
2440
    }
2441

	
2442
    /// \brief Return the grid embedding in a node map
2443
    ///
2444
    /// This function returns the grid embedding in a node map of
2445
    /// \c dim2::Point<int> coordinates.
2446
    const PointMap& coords() const {
2447
      return _point_map;
2448
    }
2449

	
2450
  private:
2451

	
2452
    const Graph& _graph;
2453
    PointMap _point_map;
2454

	
2455
  };
2456

	
2457
  namespace _planarity_bits {
2458

	
2459
    template <typename ColorMap>
2460
    class KempeFilter {
2461
    public:
2462
      typedef typename ColorMap::Key Key;
2463
      typedef bool Value;
2464

	
2465
      KempeFilter(const ColorMap& color_map,
2466
                  const typename ColorMap::Value& first,
2467
                  const typename ColorMap::Value& second)
2468
        : _color_map(color_map), _first(first), _second(second) {}
2469

	
2470
      Value operator[](const Key& key) const {
2471
        return _color_map[key] == _first || _color_map[key] == _second;
2472
      }
2473

	
2474
    private:
2475
      const ColorMap& _color_map;
2476
      typename ColorMap::Value _first, _second;
2477
    };
2478
  }
2479

	
2480
  /// \ingroup planar
2481
  ///
2482
  /// \brief Coloring planar graphs
2483
  ///
2484
  /// The graph coloring problem is the coloring of the graph nodes
2485
  /// so that there are no adjacent nodes with the same color. The
2486
  /// planar graphs can always be colored with four colors, which is
2487
  /// proved by Appel and Haken. Their proofs provide a quadratic
2488
  /// time algorithm for four coloring, but it could not be used to
2489
  /// implement an efficient algorithm. The five and six coloring can be
2490
  /// made in linear time, but in this class, the five coloring has
2491
  /// quadratic worst case time complexity. The two coloring (if
2492
  /// possible) is solvable with a graph search algorithm and it is
2493
  /// implemented in \ref bipartitePartitions() function in LEMON. To
2494
  /// decide whether a planar graph is three colorable is NP-complete.
2495
  ///
2496
  /// This class contains member functions for calculate colorings
2497
  /// with five and six colors. The six coloring algorithm is a simple
2498
  /// greedy coloring on the backward minimum outgoing order of nodes.
2499
  /// This order can be computed by selecting the node with least
2500
  /// outgoing arcs to unprocessed nodes in each phase. This order
2501
  /// guarantees that when a node is chosen for coloring it has at
2502
  /// most five already colored adjacents. The five coloring algorithm
2503
  /// use the same method, but if the greedy approach fails to color
2504
  /// with five colors, i.e. the node has five already different
2505
  /// colored neighbours, it swaps the colors in one of the connected
2506
  /// two colored sets with the Kempe recoloring method.
2507
  template <typename Graph>
2508
  class PlanarColoring {
2509
  public:
2510

	
2511
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2512

	
2513
    /// \brief The map type for storing color indices
2514
    typedef typename Graph::template NodeMap<int> IndexMap;
2515
    /// \brief The map type for storing colors
2516
    ///
2517
    /// The map type for storing colors.
2518
    /// \see Palette, Color
2519
    typedef ComposeMap<Palette, IndexMap> ColorMap;
2520

	
2521
    /// \brief Constructor
2522
    ///
2523
    /// Constructor.
2524
    /// \pre The graph must be simple, i.e. it should not
2525
    /// contain parallel or loop arcs.
2526
    PlanarColoring(const Graph& graph)
2527
      : _graph(graph), _color_map(graph), _palette(0) {
2528
      _palette.add(Color(1,0,0));
2529
      _palette.add(Color(0,1,0));
2530
      _palette.add(Color(0,0,1));
2531
      _palette.add(Color(1,1,0));
2532
      _palette.add(Color(1,0,1));
2533
      _palette.add(Color(0,1,1));
2534
    }
2535

	
2536
    /// \brief Return the node map of color indices
2537
    ///
2538
    /// This function returns the node map of color indices. The values are
2539
    /// in the range \c [0..4] or \c [0..5] according to the coloring method.
2540
    IndexMap colorIndexMap() const {
2541
      return _color_map;
2542
    }
2543

	
2544
    /// \brief Return the node map of colors
2545
    ///
2546
    /// This function returns the node map of colors. The values are among
2547
    /// five or six distinct \ref lemon::Color "colors".
2548
    ColorMap colorMap() const {
2549
      return composeMap(_palette, _color_map);
2550
    }
2551

	
2552
    /// \brief Return the color index of the node
2553
    ///
2554
    /// This function returns the color index of the given node. The value is
2555
    /// in the range \c [0..4] or \c [0..5] according to the coloring method.
2556
    int colorIndex(const Node& node) const {
2557
      return _color_map[node];
2558
    }
2559

	
2560
    /// \brief Return the color of the node
2561
    ///
2562
    /// This function returns the color of the given node. The value is among
2563
    /// five or six distinct \ref lemon::Color "colors".
2564
    Color color(const Node& node) const {
2565
      return _palette[_color_map[node]];
2566
    }
2567

	
2568

	
2569
    /// \brief Calculate a coloring with at most six colors
2570
    ///
2571
    /// This function calculates a coloring with at most six colors. The time
2572
    /// complexity of this variant is linear in the size of the graph.
2573
    /// \return \c true if the algorithm could color the graph with six colors.
2574
    /// If the algorithm fails, then the graph is not planar.
2575
    /// \note This function can return \c true if the graph is not
2576
    /// planar, but it can be colored with at most six colors.
2577
    bool runSixColoring() {
2578

	
2579
      typename Graph::template NodeMap<int> heap_index(_graph, -1);
2580
      BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
2581

	
2582
      for (NodeIt n(_graph); n != INVALID; ++n) {
2583
        _color_map[n] = -2;
2584
        heap.push(n, countOutArcs(_graph, n));
2585
      }
2586

	
2587
      std::vector<Node> order;
2588

	
2589
      while (!heap.empty()) {
2590
        Node n = heap.top();
2591
        heap.pop();
2592
        _color_map[n] = -1;
2593
        order.push_back(n);
2594
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2595
          Node t = _graph.runningNode(e);
2596
          if (_color_map[t] == -2) {
2597
            heap.decrease(t, heap[t] - 1);
2598
          }
2599
        }
2600
      }
2601

	
2602
      for (int i = order.size() - 1; i >= 0; --i) {
2603
        std::vector<bool> forbidden(6, false);
2604
        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
2605
          Node t = _graph.runningNode(e);
2606
          if (_color_map[t] != -1) {
2607
            forbidden[_color_map[t]] = true;
2608
          }
2609
        }
2610
               for (int k = 0; k < 6; ++k) {
2611
          if (!forbidden[k]) {
2612
            _color_map[order[i]] = k;
2613
            break;
2614
          }
2615
        }
2616
        if (_color_map[order[i]] == -1) {
2617
          return false;
2618
        }
2619
      }
2620
      return true;
2621
    }
2622

	
2623
  private:
2624

	
2625
    bool recolor(const Node& u, const Node& v) {
2626
      int ucolor = _color_map[u];
2627
      int vcolor = _color_map[v];
2628
      typedef _planarity_bits::KempeFilter<IndexMap> KempeFilter;
2629
      KempeFilter filter(_color_map, ucolor, vcolor);
2630

	
2631
      typedef FilterNodes<const Graph, const KempeFilter> KempeGraph;
2632
      KempeGraph kempe_graph(_graph, filter);
2633

	
2634
      std::vector<Node> comp;
2635
      Bfs<KempeGraph> bfs(kempe_graph);
2636
      bfs.init();
2637
      bfs.addSource(u);
2638
      while (!bfs.emptyQueue()) {
2639
        Node n = bfs.nextNode();
2640
        if (n == v) return false;
2641
        comp.push_back(n);
2642
        bfs.processNextNode();
2643
      }
2644

	
2645
      int scolor = ucolor + vcolor;
2646
      for (int i = 0; i < static_cast<int>(comp.size()); ++i) {
2647
        _color_map[comp[i]] = scolor - _color_map[comp[i]];
2648
      }
2649

	
2650
      return true;
2651
    }
2652

	
2653
    template <typename EmbeddingMap>
2654
    void kempeRecoloring(const Node& node, const EmbeddingMap& embedding) {
2655
      std::vector<Node> nodes;
2656
      nodes.reserve(4);
2657

	
2658
      for (Arc e = OutArcIt(_graph, node); e != INVALID; e = embedding[e]) {
2659
        Node t = _graph.target(e);
2660
        if (_color_map[t] != -1) {
2661
          nodes.push_back(t);
2662
          if (nodes.size() == 4) break;
2663
        }
2664
      }
2665

	
2666
      int color = _color_map[nodes[0]];
2667
      if (recolor(nodes[0], nodes[2])) {
2668
        _color_map[node] = color;
2669
      } else {
2670
        color = _color_map[nodes[1]];
2671
        recolor(nodes[1], nodes[3]);
2672
        _color_map[node] = color;
2673
      }
2674
    }
2675

	
2676
  public:
2677

	
2678
    /// \brief Calculate a coloring with at most five colors
2679
    ///
2680
    /// This function calculates a coloring with at most five
2681
    /// colors. The worst case time complexity of this variant is
2682
    /// quadratic in the size of the graph.
2683
    /// \param embedding This map should contain a valid combinatorical
2684
    /// embedding, i.e. a valid cyclic order of the arcs.
2685
    /// It can be computed using PlanarEmbedding.
2686
    template <typename EmbeddingMap>
2687
    void runFiveColoring(const EmbeddingMap& embedding) {
2688

	
2689
      typename Graph::template NodeMap<int> heap_index(_graph, -1);
2690
      BucketHeap<typename Graph::template NodeMap<int> > heap(heap_index);
2691

	
2692
      for (NodeIt n(_graph); n != INVALID; ++n) {
2693
        _color_map[n] = -2;
2694
        heap.push(n, countOutArcs(_graph, n));
2695
      }
2696

	
2697
      std::vector<Node> order;
2698

	
2699
      while (!heap.empty()) {
2700
        Node n = heap.top();
2701
        heap.pop();
2702
        _color_map[n] = -1;
2703
        order.push_back(n);
2704
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2705
          Node t = _graph.runningNode(e);
2706
          if (_color_map[t] == -2) {
2707
            heap.decrease(t, heap[t] - 1);
2708
          }
2709
        }
2710
      }
2711

	
2712
      for (int i = order.size() - 1; i >= 0; --i) {
2713
        std::vector<bool> forbidden(5, false);
2714
        for (OutArcIt e(_graph, order[i]); e != INVALID; ++e) {
2715
          Node t = _graph.runningNode(e);
2716
          if (_color_map[t] != -1) {
2717
            forbidden[_color_map[t]] = true;
2718
          }
2719
        }
2720
        for (int k = 0; k < 5; ++k) {
2721
          if (!forbidden[k]) {
2722
            _color_map[order[i]] = k;
2723
            break;
2724
          }
2725
        }
2726
        if (_color_map[order[i]] == -1) {
2727
          kempeRecoloring(order[i], embedding);
2728
        }
2729
      }
2730
    }
2731

	
2732
    /// \brief Calculate a coloring with at most five colors
2733
    ///
2734
    /// This function calculates a coloring with at most five
2735
    /// colors. The worst case time complexity of this variant is
2736
    /// quadratic in the size of the graph.
2737
    /// \return \c true if the graph is planar.
2738
    bool runFiveColoring() {
2739
      PlanarEmbedding<Graph> pe(_graph);
2740
      if (!pe.run()) return false;
2741

	
2742
      runFiveColoring(pe.embeddingMap());
2743
      return true;
2744
    }
2745

	
2746
  private:
2747

	
2748
    const Graph& _graph;
2749
    IndexMap _color_map;
2750
    Palette _palette;
2751
  };
2752

	
2753
}
2754

	
2755
#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_QUAD_HEAP_H
20
#define LEMON_QUAD_HEAP_H
21

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

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

	
30
namespace lemon {
31

	
32
  /// \ingroup heaps
33
  ///
34
  ///\brief Fourary (quaternary) heap data structure.
35
  ///
36
  /// This class implements the \e Fourary (\e quaternary) \e heap
37
  /// data structure.
38
  /// It fully conforms to the \ref concepts::Heap "heap concept".
39
  ///
40
  /// The fourary heap is a specialization of the \ref DHeap "D-ary heap"
41
  /// for <tt>D=4</tt>. It is similar to the \ref BinHeap "binary heap",
42
  /// but its nodes have at most four children, instead of two.
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
  ///
50
  ///\sa BinHeap
51
  ///\sa DHeap
52
#ifdef DOXYGEN
53
  template <typename PR, typename IM, typename CMP>
54
#else
55
  template <typename PR, typename IM, typename CMP = std::less<PR> >
56
#endif
57
  class QuadHeap {
58
  public:
59
    /// Type of the item-int map.
60
    typedef IM ItemIntMap;
61
    /// Type of the priorities.
62
    typedef PR Prio;
63
    /// Type of the items stored in the heap.
64
    typedef typename ItemIntMap::Key Item;
65
    /// Type of the item-priority pairs.
66
    typedef std::pair<Item,Prio> Pair;
67
    /// Functor type for comparing the priorities.
68
    typedef CMP Compare;
69

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

	
84
  private:
85
    std::vector<Pair> _data;
86
    Compare _comp;
87
    ItemIntMap &_iim;
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 QuadHeap(ItemIntMap &map) : _iim(map) {}
97

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
339
  }; // class QuadHeap
340

	
341
} // namespace lemon
342

	
343
#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-2010
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
  /// This class provides constant time counting for nodes and arcs.
296
  ///
297
  /// \sa concepts::Digraph
298
  class StaticDigraph : public ExtendedStaticDigraphBase {
299
  public:
300

	
301
    typedef ExtendedStaticDigraphBase Parent;
302

	
303
  public:
304

	
305
    /// \brief Constructor
306
    ///
307
    /// Default constructor.
308
    StaticDigraph() : Parent() {}
309

	
310
    /// \brief The node with the given index.
311
    ///
312
    /// This function returns the node with the given index.
313
    /// \sa index()
314
    static Node node(int ix) { return Parent::nodeFromId(ix); }
315

	
316
    /// \brief The arc with the given index.
317
    ///
318
    /// This function returns the arc with the given index.
319
    /// \sa index()
320
    static Arc arc(int ix) { return Parent::arcFromId(ix); }
321

	
322
    /// \brief The index of the given node.
323
    ///
324
    /// This function returns the index of the the given node.
325
    /// \sa node()
326
    static int index(Node node) { return Parent::id(node); }
327

	
328
    /// \brief The index of the given arc.
329
    ///
330
    /// This function returns the index of the the given arc.
331
    /// \sa arc()
332
    static int index(Arc arc) { return Parent::id(arc); }
333

	
334
    /// \brief Number of nodes.
335
    ///
336
    /// This function returns the number of nodes.
337
    int nodeNum() const { return node_num; }
338

	
339
    /// \brief Number of arcs.
340
    ///
341
    /// This function returns the number of arcs.
342
    int arcNum() const { return arc_num; }
343

	
344
    /// \brief Build the digraph copying another digraph.
345
    ///
346
    /// This function builds the digraph copying another digraph of any
347
    /// kind. It can be called more than once, but in such case, the whole
348
    /// structure and all maps will be cleared and rebuilt.
349
    ///
350
    /// This method also makes possible to copy a digraph to a StaticDigraph
351
    /// structure using \ref DigraphCopy.
352
    ///
353
    /// \param digraph An existing digraph to be copied.
354
    /// \param nodeRef The node references will be copied into this map.
355
    /// Its key type must be \c Digraph::Node and its value type must be
356
    /// \c StaticDigraph::Node.
357
    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
358
    /// concept.
359
    /// \param arcRef The arc references will be copied into this map.
360
    /// Its key type must be \c Digraph::Arc and its value type must be
361
    /// \c StaticDigraph::Arc.
362
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
363
    ///
364
    /// \note If you do not need the arc references, then you could use
365
    /// \ref NullMap for the last parameter. However the node references
366
    /// are required by the function itself, thus they must be readable
367
    /// from the map.
368
    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
369
    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
370
      if (built) Parent::clear();
371
      Parent::build(digraph, nodeRef, arcRef);
372
    }
373

	
374
    /// \brief Build the digraph from an arc list.
375
    ///
376
    /// This function builds the digraph from the given arc list.
377
    /// It can be called more than once, but in such case, the whole
378
    /// structure and all maps will be cleared and rebuilt.
379
    ///
380
    /// The list of the arcs must be given in the range <tt>[begin, end)</tt>
381
    /// specified by STL compatible itartors whose \c value_type must be
382
    /// <tt>std::pair<int,int></tt>.
383
    /// Each arc must be specified by a pair of integer indices
384
    /// from the range <tt>[0..n-1]</tt>. <i>The pairs must be in a
385
    /// non-decreasing order with respect to their first values.</i>
386
    /// If the k-th pair in the list is <tt>(i,j)</tt>, then
387
    /// <tt>arc(k-1)</tt> will connect <tt>node(i)</tt> to <tt>node(j)</tt>.
388
    ///
389
    /// \param n The number of nodes.
390
    /// \param begin An iterator pointing to the beginning of the arc list.
391
    /// \param end An iterator pointing to the end of the arc list.
392
    ///
393
    /// For example, a simple digraph can be constructed like this.
394
    /// \code
395
    ///   std::vector<std::pair<int,int> > arcs;
396
    ///   arcs.push_back(std::make_pair(0,1));
397
    ///   arcs.push_back(std::make_pair(0,2));
398
    ///   arcs.push_back(std::make_pair(1,3));
399
    ///   arcs.push_back(std::make_pair(1,2));
400
    ///   arcs.push_back(std::make_pair(3,0));
401
    ///   StaticDigraph gr;
402
    ///   gr.build(4, arcs.begin(), arcs.end());
403
    /// \endcode
404
    template <typename ArcListIterator>
405
    void build(int n, ArcListIterator begin, ArcListIterator end) {
406
      if (built) Parent::clear();
407
      StaticDigraphBase::build(n, begin, end);
408
      notifier(Node()).build();
409
      notifier(Arc()).build();
410
    }
411

	
412
    /// \brief Clear the digraph.
413
    ///
414
    /// This function erases all nodes and arcs from the digraph.
415
    void clear() {
416
      Parent::clear();
417
    }
418

	
419
  protected:
420

	
421
    using Parent::fastFirstOut;
422
    using Parent::fastNextOut;
423
    using Parent::fastLastOut;
424

	
425
  public:
426

	
427
    class OutArcIt : public Arc {
428
    public:
429

	
430
      OutArcIt() { }
431

	
432
      OutArcIt(Invalid i) : Arc(i) { }
433

	
434
      OutArcIt(const StaticDigraph& digraph, const Node& node) {
435
        digraph.fastFirstOut(*this, node);
436
        digraph.fastLastOut(last, node);
437
        if (last == *this) *this = INVALID;
438
      }
439

	
440
      OutArcIt(const StaticDigraph& digraph, const Arc& arc) : Arc(arc) {
441
        if (arc != INVALID) {
442
          digraph.fastLastOut(last, digraph.source(arc));
443
        }
444
      }
445

	
446
      OutArcIt& operator++() {
447
        StaticDigraph::fastNextOut(*this);
448
        if (last == *this) *this = INVALID;
449
        return *this;
450
      }
451

	
452
    private:
453
      Arc last;
454
    };
455

	
456
    Node baseNode(const OutArcIt &arc) const {
457
      return Parent::source(static_cast<const Arc&>(arc));
458
    }
459

	
460
    Node runningNode(const OutArcIt &arc) const {
461
      return Parent::target(static_cast<const Arc&>(arc));
462
    }
463

	
464
    Node baseNode(const InArcIt &arc) const {
465
      return Parent::target(static_cast<const Arc&>(arc));
466
    }
467

	
468
    Node runningNode(const InArcIt &arc) const {
469
      return Parent::source(static_cast<const Arc&>(arc));
470
    }
471

	
472
  };
473

	
474
}
475

	
476
#endif
Ignore white space 6 line context
1
EXTRA_DIST += \
2
	scripts/bib2dox.py \
3
	scripts/bootstrap.sh \
4
	scripts/chg-len.py \
5
	scripts/mk-release.sh \
6
	scripts/unify-sources.sh \
7
	scripts/valgrind-wrapper.sh
Ignore white space 6 line context
1
#! /usr/bin/env python
2
"""
3
  BibTeX to Doxygen converter
4
  Usage: python bib2dox.py bibfile.bib > bibfile.dox
5

	
6
  This file is a part of LEMON, a generic C++ optimization library.
7

	
8
  **********************************************************************
9

	
10
  This code is the modification of the BibTeX to XML converter
11
  by Vidar Bronken Gundersen et al.
12
  See the original copyright notices below. 
13

	
14
  **********************************************************************
15

	
16
  Decoder for bibliographic data, BibTeX
17
  Usage: python bibtex2xml.py bibfile.bib > bibfile.xml
18

	
19
  v.8
20
  (c)2002-06-23 Vidar Bronken Gundersen
21
  http://bibtexml.sf.net/
22
  Reuse approved as long as this notification is kept.
23
  Licence: GPL.
24

	
25
  Contributions/thanks to:
26
  Egon Willighagen, http://sf.net/projects/jreferences/
27
  Richard Mahoney (for providing a test case)
28

	
29
  Editted by Sara Sprenkle to be more robust and handle more bibtex features.
30
  (c) 2003-01-15
31

	
32
  1.  Changed bibtex: tags to bibxml: tags.
33
  2.  Use xmlns:bibxml="http://bibtexml.sf.net/"
34
  3.  Allow spaces between @type and first {
35
  4.  "author" fields with multiple authors split by " and "
36
      are put in separate xml "bibxml:author" tags.
37
  5.  Option for Titles: words are capitalized
38
      only if first letter in title or capitalized inside braces
39
  6.  Removes braces from within field values
40
  7.  Ignores comments in bibtex file (including @comment{ or % )
41
  8.  Replaces some special latex tags, e.g., replaces ~ with '&#160;'
42
  9.  Handles bibtex @string abbreviations
43
        --> includes bibtex's default abbreviations for months
44
        --> does concatenation of abbr # " more " and " more " # abbr
45
  10. Handles @type( ... ) or @type{ ... }
46
  11. The keywords field is split on , or ; and put into separate xml
47
      "bibxml:keywords" tags
48
  12. Ignores @preamble
49

	
50
  Known Limitations
51
  1.  Does not transform Latex encoding like math mode and special
52
      latex symbols.
53
  2.  Does not parse author fields into first and last names.
54
      E.g., It does not do anything special to an author whose name is
55
      in the form LAST_NAME, FIRST_NAME
56
      In "author" tag, will show up as
57
      <bibxml:author>LAST_NAME, FIRST_NAME</bibxml:author>
58
  3.  Does not handle "crossref" fields other than to print
59
      <bibxml:crossref>...</bibxml:crossref>
60
  4.  Does not inform user of the input's format errors.  You just won't
61
      be able to transform the file later with XSL
62

	
63
  You will have to manually edit the XML output if you need to handle
64
  these (and unknown) limitations.
65

	
66
"""
67

	
68
import string, re
69

	
70
# set of valid name characters
71
valid_name_chars = '[\w\-:]'
72

	
73
#
74
# define global regular expression variables
75
#
76
author_rex = re.compile('\s+and\s+')
77
rembraces_rex = re.compile('[{}]')
78
capitalize_rex = re.compile('({[^}]*})')
79

	
80
# used by bibtexkeywords(data)
81
keywords_rex = re.compile('[,;]')
82

	
83
# used by concat_line(line)
84
concatsplit_rex = re.compile('\s*#\s*')
85

	
86
# split on {, }, or " in verify_out_of_braces
87
delimiter_rex = re.compile('([{}"])',re.I)
88

	
89
field_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
90
data_rex = re.compile('\s*(\w*)\s*=\s*([^,]*),?')
91

	
92
url_rex = re.compile('\\\url\{([^}]*)\}')
93

	
94
#
95
# styles for html formatting
96
#
97
divstyle = 'margin-top: -4ex; margin-left: 8em;'
98

	
99
#
100
# return the string parameter without braces
101
#
102
def transformurls(str):
103
    return url_rex.sub(r'<a href="\1">\1</a>', str)
104

	
105
#
106
# return the string parameter without braces
107
#
108
def removebraces(str):
109
    return rembraces_rex.sub('', str)
110

	
111
#
112
# latex-specific replacements
113
# (do this after braces were removed)
114
#
115
def latexreplacements(line):
116
    line = string.replace(line, '~', '&nbsp;')
117
    line = string.replace(line, '\\\'a', '&aacute;')
118
    line = string.replace(line, '\\"a', '&auml;')
119
    line = string.replace(line, '\\\'e', '&eacute;')
120
    line = string.replace(line, '\\"e', '&euml;')
121
    line = string.replace(line, '\\\'i', '&iacute;')
122
    line = string.replace(line, '\\"i', '&iuml;')
123
    line = string.replace(line, '\\\'o', '&oacute;')
124
    line = string.replace(line, '\\"o', '&ouml;')
125
    line = string.replace(line, '\\\'u', '&uacute;')
126
    line = string.replace(line, '\\"u', '&uuml;')
127
    line = string.replace(line, '\\H o', '&otilde;')
128
    line = string.replace(line, '\\H u', '&uuml;')   # &utilde; does not exist
129
    line = string.replace(line, '\\\'A', '&Aacute;')
130
    line = string.replace(line, '\\"A', '&Auml;')
131
    line = string.replace(line, '\\\'E', '&Eacute;')
132
    line = string.replace(line, '\\"E', '&Euml;')
133
    line = string.replace(line, '\\\'I', '&Iacute;')
134
    line = string.replace(line, '\\"I', '&Iuml;')
135
    line = string.replace(line, '\\\'O', '&Oacute;')
136
    line = string.replace(line, '\\"O', '&Ouml;')
137
    line = string.replace(line, '\\\'U', '&Uacute;')
138
    line = string.replace(line, '\\"U', '&Uuml;')
139
    line = string.replace(line, '\\H O', '&Otilde;')
140
    line = string.replace(line, '\\H U', '&Uuml;')   # &Utilde; does not exist
141

	
142
    return line
143

	
144
#
145
# copy characters form a string decoding html expressions (&xyz;)
146
#
147
def copychars(str, ifrom, count):
148
    result = ''
149
    i = ifrom
150
    c = 0
151
    html_spec = False
152
    while (i < len(str)) and (c < count):
153
        if str[i] == '&':
154
            html_spec = True;
155
            if i+1 < len(str):
156
                result += str[i+1]
157
            c += 1
158
            i += 2
159
        else:
160
            if not html_spec:
161
                if ((str[i] >= 'A') and (str[i] <= 'Z')) or \
162
                   ((str[i] >= 'a') and (str[i] <= 'z')):
163
                    result += str[i]
164
                    c += 1
165
            elif str[i] == ';':
166
                html_spec = False;
167
            i += 1
168
    
169
    return result
170

	
171

	
172
# 
173
# Handle a list of authors (separated by 'and').
174
# It gives back an array of the follwing values:
175
#  - num: the number of authors,
176
#  - list: the list of the author names,
177
#  - text: the bibtex text (separated by commas and/or 'and')
178
#  - abbrev: abbreviation that can be used for indicate the
179
#    bibliography entries
180
#
181
def bibtexauthor(data):
182
    result = {}
183
    bibtex = ''
184
    result['list'] = author_rex.split(data)
185
    result['num'] = len(result['list'])
186
    for i, author in enumerate(result['list']):
187
        # general transformations
188
        author = latexreplacements(removebraces(author.strip()))
189
        # transform "Xyz, A. B." to "A. B. Xyz"
190
        pos = author.find(',')
191
        if pos != -1:
192
            author = author[pos+1:].strip() + ' ' + author[:pos].strip()
193
        result['list'][i] = author
194
        bibtex += author + '#'
195
    bibtex = bibtex[:-1]
196
    if result['num'] > 1:
197
        ix = bibtex.rfind('#')
198
        if result['num'] == 2:
199
            bibtex = bibtex[:ix] + ' and ' + bibtex[ix+1:]
200
        else:
201
            bibtex = bibtex[:ix] + ', and ' + bibtex[ix+1:]
202
    bibtex = bibtex.replace('#', ', ')
203
    result['text'] = bibtex
204
    
205
    result['abbrev'] = ''
206
    for author in result['list']:
207
        pos = author.rfind(' ') + 1
208
        count = 1
209
        if result['num'] == 1:
210
            count = 3
211
        result['abbrev'] += copychars(author, pos, count)
212

	
213
    return result
214

	
215

	
216
#
217
# data = title string
218
# @return the capitalized title (first letter is capitalized), rest are capitalized
219
# only if capitalized inside braces
220
#
221
def capitalizetitle(data):
222
    title_list = capitalize_rex.split(data)
223
    title = ''
224
    count = 0
225
    for phrase in title_list:
226
         check = string.lstrip(phrase)
227

	
228
         # keep phrase's capitalization the same
229
         if check.find('{') == 0:
230
              title += removebraces(phrase)
231
         else:
232
         # first word --> capitalize first letter (after spaces)
233
              if count == 0:
234
                  title += check.capitalize()
235
              else:
236
                  title += phrase.lower()
237
         count = count + 1
238

	
239
    return title
240

	
241

	
242
#
243
# @return the bibtex for the title
244
# @param data --> title string
245
# braces are removed from title
246
#
247
def bibtextitle(data, entrytype):
248
    if entrytype in ('book', 'inbook'):
249
        title = removebraces(data.strip())
250
    else:
251
        title = removebraces(capitalizetitle(data.strip()))
252
    bibtex = title
253
    return bibtex
254

	
255

	
256
#
257
# function to compare entry lists
258
#
259
def entry_cmp(x, y):
260
    return cmp(x[0], y[0])
261

	
262

	
263
#
264
# print the XML for the transformed "filecont_source"
265
#
266
def bibtexdecoder(filecont_source):
267
    filecont = []
268
    file = []
269
    
270
    # want @<alphanumeric chars><spaces>{<spaces><any chars>,
271
    pubtype_rex = re.compile('@(\w*)\s*{\s*(.*),')
272
    endtype_rex = re.compile('}\s*$')
273
    endtag_rex = re.compile('^\s*}\s*$')
274

	
275
    bracefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
276
    bracedata_rex = re.compile('\s*(\w*)\s*=\s*{(.*)},?')
277

	
278
    quotefield_rex = re.compile('\s*(\w*)\s*=\s*(.*)')
279
    quotedata_rex = re.compile('\s*(\w*)\s*=\s*"(.*)",?')
280

	
281
    for line in filecont_source:
282
        line = line[:-1]
283

	
284
        # encode character entities
285
        line = string.replace(line, '&', '&amp;')
286
        line = string.replace(line, '<', '&lt;')
287
        line = string.replace(line, '>', '&gt;')
288

	
289
        # start entry: publication type (store for later use)
290
        if pubtype_rex.match(line):
291
        # want @<alphanumeric chars><spaces>{<spaces><any chars>,
292
            entrycont = {}
293
            entry = []
294
            entrytype = pubtype_rex.sub('\g<1>',line)
295
            entrytype = string.lower(entrytype)
296
            entryid   = pubtype_rex.sub('\g<2>', line)
297

	
298
        # end entry if just a }
299
        elif endtype_rex.match(line):
300
            # generate doxygen code for the entry
301

	
302
            # enty type related formattings
303
            if entrytype in ('book', 'inbook'):
304
                entrycont['title'] = '<em>' + entrycont['title'] + '</em>'
305
                if not entrycont.has_key('author'):
306
                    entrycont['author'] = entrycont['editor']
307
                    entrycont['author']['text'] += ', editors'
308
            elif entrytype == 'article':
309
                entrycont['journal'] = '<em>' + entrycont['journal'] + '</em>'
310
            elif entrytype in ('inproceedings', 'incollection', 'conference'):
311
                entrycont['booktitle'] = '<em>' + entrycont['booktitle'] + '</em>'
312
            elif entrytype == 'techreport':
313
                if not entrycont.has_key('type'):
314
                    entrycont['type'] = 'Technical report'
315
            elif entrytype == 'mastersthesis':
316
                entrycont['type'] = 'Master\'s thesis'
317
            elif entrytype == 'phdthesis':
318
                entrycont['type'] = 'PhD thesis'
319

	
320
            for eline in entrycont:
321
                if eline != '':
322
                    eline = latexreplacements(eline)
323

	
324
            if entrycont.has_key('pages') and (entrycont['pages'] != ''):
325
                entrycont['pages'] = string.replace(entrycont['pages'], '--', '-')
326

	
327
            if entrycont.has_key('author') and (entrycont['author'] != ''):
328
                entry.append(entrycont['author']['text'] + '.')
329
            if entrycont.has_key('title') and (entrycont['title'] != ''):
330
                entry.append(entrycont['title'] + '.')
331
            if entrycont.has_key('journal') and (entrycont['journal'] != ''):
332
                entry.append(entrycont['journal'] + ',')
333
            if entrycont.has_key('booktitle') and (entrycont['booktitle'] != ''):
334
                entry.append('In ' + entrycont['booktitle'] + ',')
335
            if entrycont.has_key('type') and (entrycont['type'] != ''):
336
                eline = entrycont['type']
337
                if entrycont.has_key('number') and (entrycont['number'] != ''):
338
                    eline += ' ' + entrycont['number']
339
                eline += ','
340
                entry.append(eline)
341
            if entrycont.has_key('institution') and (entrycont['institution'] != ''):
342
                entry.append(entrycont['institution'] + ',')
343
            if entrycont.has_key('publisher') and (entrycont['publisher'] != ''):
344
                entry.append(entrycont['publisher'] + ',')
345
            if entrycont.has_key('school') and (entrycont['school'] != ''):
346
                entry.append(entrycont['school'] + ',')
347
            if entrycont.has_key('address') and (entrycont['address'] != ''):
348
                entry.append(entrycont['address'] + ',')
349
            if entrycont.has_key('edition') and (entrycont['edition'] != ''):
350
                entry.append(entrycont['edition'] + ' edition,')
351
            if entrycont.has_key('howpublished') and (entrycont['howpublished'] != ''):
352
                entry.append(entrycont['howpublished'] + ',')
353
            if entrycont.has_key('volume') and (entrycont['volume'] != ''):
354
                eline = entrycont['volume'];
355
                if entrycont.has_key('number') and (entrycont['number'] != ''):
356
                    eline += '(' + entrycont['number'] + ')'
357
                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
358
                    eline += ':' + entrycont['pages']
359
                eline += ','
360
                entry.append(eline)
361
            else:
362
                if entrycont.has_key('pages') and (entrycont['pages'] != ''):
363
                    entry.append('pages ' + entrycont['pages'] + ',')
364
            if entrycont.has_key('year') and (entrycont['year'] != ''):
365
                if entrycont.has_key('month') and (entrycont['month'] != ''):
366
                    entry.append(entrycont['month'] + ' ' + entrycont['year'] + '.')
367
                else:
368
                    entry.append(entrycont['year'] + '.')
369
            if entrycont.has_key('note') and (entrycont['note'] != ''):
370
                entry.append(entrycont['note'] + '.')
371
            if entrycont.has_key('url') and (entrycont['url'] != ''):
372
                entry.append(entrycont['url'] + '.')
373

	
374
            # generate keys for sorting and for the output
375
            sortkey = ''
376
            bibkey = ''
377
            if entrycont.has_key('author'):
378
                for author in entrycont['author']['list']:
379
                    sortkey += copychars(author, author.rfind(' ')+1, len(author))
380
                bibkey = entrycont['author']['abbrev']
381
            else:
382
                bibkey = 'x'
383
            if entrycont.has_key('year'):
384
                sortkey += entrycont['year']
385
                bibkey += entrycont['year'][-2:]
386
            if entrycont.has_key('title'):
387
                sortkey += entrycont['title']
388
            if entrycont.has_key('key'):
389
                sortkey = entrycont['key'] + sortkey
390
                bibkey = entrycont['key']
391
            entry.insert(0, sortkey)
392
            entry.insert(1, bibkey)
393
            entry.insert(2, entryid)
394
           
395
            # add the entry to the file contents
396
            filecont.append(entry)
397

	
398
        else:
399
            # field, publication info
400
            field = ''
401
            data = ''
402
            
403
            # field = {data} entries
404
            if bracedata_rex.match(line):
405
                field = bracefield_rex.sub('\g<1>', line)
406
                field = string.lower(field)
407
                data =  bracedata_rex.sub('\g<2>', line)
408

	
409
            # field = "data" entries
410
            elif quotedata_rex.match(line):
411
                field = quotefield_rex.sub('\g<1>', line)
412
                field = string.lower(field)
413
                data =  quotedata_rex.sub('\g<2>', line)
414

	
415
            # field = data entries
416
            elif data_rex.match(line):
417
                field = field_rex.sub('\g<1>', line)
418
                field = string.lower(field)
419
                data =  data_rex.sub('\g<2>', line)
420

	
421
            if field == 'url':
422
                data = '\\url{' + data.strip() + '}'
423
            
424
            if field in ('author', 'editor'):
425
                entrycont[field] = bibtexauthor(data)
426
                line = ''
427
            elif field == 'title':
428
                line = bibtextitle(data, entrytype)
429
            elif field != '':
430
                line = removebraces(transformurls(data.strip()))
431

	
432
            if line != '':
433
                line = latexreplacements(line)
434
                entrycont[field] = line
435

	
436

	
437
    # sort entries
438
    filecont.sort(entry_cmp)
439
    
440
    # count the bibtex keys
441
    keytable = {}
442
    counttable = {}
443
    for entry in filecont:
444
        bibkey = entry[1]
445
        if not keytable.has_key(bibkey):
446
            keytable[bibkey] = 1
447
        else:
448
            keytable[bibkey] += 1
449

	
450
    for bibkey in keytable.keys():
451
        counttable[bibkey] = 0
452
    
453
    # generate output
454
    for entry in filecont:
455
        # generate output key form the bibtex key
456
        bibkey = entry[1]
457
        entryid = entry[2]
458
        if keytable[bibkey] == 1:
459
            outkey = bibkey
460
        else:
461
            outkey = bibkey + chr(97 + counttable[bibkey])
462
        counttable[bibkey] += 1
463
        
464
        # append the entry code to the output
465
        file.append('\\section ' + entryid + ' [' + outkey + ']')
466
        file.append('<div style="' + divstyle + '">')
467
        for line in entry[3:]:
468
            file.append(line)
469
        file.append('</div>')
470
        file.append('')
471

	
472
    return file
473

	
474

	
475
#
476
# return 1 iff abbr is in line but not inside braces or quotes
477
# assumes that abbr appears only once on the line (out of braces and quotes)
478
#
479
def verify_out_of_braces(line, abbr):
480

	
481
    phrase_split = delimiter_rex.split(line)
482

	
483
    abbr_rex = re.compile( '\\b' + abbr + '\\b', re.I)
484

	
485
    open_brace = 0
486
    open_quote = 0
487

	
488
    for phrase in phrase_split:
489
        if phrase == "{":
490
            open_brace = open_brace + 1
491
        elif phrase == "}":
492
            open_brace = open_brace - 1
493
        elif phrase == '"':
494
            if open_quote == 1:
495
                open_quote = 0
496
            else:
497
                open_quote = 1
498
        elif abbr_rex.search(phrase):
499
            if open_brace == 0 and open_quote == 0:
500
                return 1
501

	
502
    return 0
503

	
504

	
505
#
506
# a line in the form phrase1 # phrase2 # ... # phrasen
507
# is returned as phrase1 phrase2 ... phrasen
508
# with the correct punctuation
509
# Bug: Doesn't always work with multiple abbreviations plugged in
510
#
511
def concat_line(line):
512
    # only look at part after equals
513
    field = field_rex.sub('\g<1>',line)
514
    rest = field_rex.sub('\g<2>',line)
515

	
516
    concat_line = field + ' ='
517

	
518
    pound_split = concatsplit_rex.split(rest)
519

	
520
    phrase_count = 0
521
    length = len(pound_split)
522

	
523
    for phrase in pound_split:
524
        phrase = phrase.strip()
525
        if phrase_count != 0:
526
            if phrase.startswith('"') or phrase.startswith('{'):
527
                phrase = phrase[1:]
528
        elif phrase.startswith('"'):
529
            phrase = phrase.replace('"','{',1)
530

	
531
        if phrase_count != length-1:
532
            if phrase.endswith('"') or phrase.endswith('}'):
533
                phrase = phrase[:-1]
534
        else:
535
            if phrase.endswith('"'):
536
                phrase = phrase[:-1]
537
                phrase = phrase + "}"
538
            elif phrase.endswith('",'):
539
                phrase = phrase[:-2]
540
                phrase = phrase + "},"
541

	
542
        # if phrase did have \#, add the \# back
543
        if phrase.endswith('\\'):
544
            phrase = phrase + "#"
545
        concat_line = concat_line + ' ' + phrase
546

	
547
        phrase_count = phrase_count + 1
548

	
549
    return concat_line
550

	
551

	
552
#
553
# substitute abbreviations into filecont
554
# @param filecont_source - string of data from file
555
#
556
def bibtex_replace_abbreviations(filecont_source):
557
    filecont = filecont_source.splitlines()
558

	
559
    #  These are defined in bibtex, so we'll define them too
560
    abbr_list = ['jan','feb','mar','apr','may','jun',
561
                 'jul','aug','sep','oct','nov','dec']
562
    value_list = ['January','February','March','April',
563
                  'May','June','July','August','September',
564
                  'October','November','December']
565

	
566
    abbr_rex = []
567
    total_abbr_count = 0
568

	
569
    front = '\\b'
570
    back = '(,?)\\b'
571

	
572
    for x in abbr_list:
573
        abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
574
        total_abbr_count = total_abbr_count + 1
575

	
576

	
577
    abbrdef_rex = re.compile('\s*@string\s*{\s*('+ valid_name_chars +'*)\s*=(.*)',
578
                             re.I)
579

	
580
    comment_rex = re.compile('@comment\s*{',re.I)
581
    preamble_rex = re.compile('@preamble\s*{',re.I)
582

	
583
    waiting_for_end_string = 0
584
    i = 0
585
    filecont2 = ''
586

	
587
    for line in filecont:
588
        if line == ' ' or line == '':
589
            continue
590

	
591
        if waiting_for_end_string:
592
            if re.search('}',line):
593
                waiting_for_end_string = 0
594
                continue
595

	
596
        if abbrdef_rex.search(line):
597
            abbr = abbrdef_rex.sub('\g<1>', line)
598

	
599
            if abbr_list.count(abbr) == 0:
600
                val = abbrdef_rex.sub('\g<2>', line)
601
                abbr_list.append(abbr)
602
                value_list.append(string.strip(val))
603
                abbr_rex.append( re.compile( front + abbr_list[total_abbr_count] + back, re.I ) )
604
                total_abbr_count = total_abbr_count + 1
605
            waiting_for_end_string = 1
606
            continue
607

	
608
        if comment_rex.search(line):
609
            waiting_for_end_string = 1
610
            continue
611

	
612
        if preamble_rex.search(line):
613
            waiting_for_end_string = 1
614
            continue
615

	
616

	
617
        # replace subsequent abbreviations with the value
618
        abbr_count = 0
619

	
620
        for x in abbr_list:
621

	
622
            if abbr_rex[abbr_count].search(line):
623
                if verify_out_of_braces(line,abbr_list[abbr_count]) == 1:
624
                    line = abbr_rex[abbr_count].sub( value_list[abbr_count] + '\g<1>', line)
625
                # Check for # concatenations
626
                if concatsplit_rex.search(line):
627
                    line = concat_line(line)
628
            abbr_count = abbr_count + 1
629

	
630

	
631
        filecont2 = filecont2 + line + '\n'
632
        i = i+1
633

	
634

	
635
    # Do one final pass over file
636

	
637
    # make sure that didn't end up with {" or }" after the substitution
638
    filecont2 = filecont2.replace('{"','{{')
639
    filecont2 = filecont2.replace('"}','}}')
640

	
641
    afterquotevalue_rex = re.compile('"\s*,\s*')
642
    afterbrace_rex = re.compile('"\s*}')
643
    afterbracevalue_rex = re.compile('(=\s*{[^=]*)},\s*')
644

	
645
    # add new lines to data that changed because of abbreviation substitutions
646
    filecont2 = afterquotevalue_rex.sub('",\n', filecont2)
647
    filecont2 = afterbrace_rex.sub('"\n}', filecont2)
648
    filecont2 = afterbracevalue_rex.sub('\g<1>},\n', filecont2)
649

	
650
    return filecont2
651

	
652
#
653
# convert @type( ... ) to @type{ ... }
654
#
655
def no_outer_parens(filecont):
656

	
657
    # do checking for open parens
658
    # will convert to braces
659
    paren_split = re.split('([(){}])',filecont)
660

	
661
    open_paren_count = 0
662
    open_type = 0
663
    look_next = 0
664

	
665
    # rebuild filecont
666
    filecont = ''
667

	
668
    at_rex = re.compile('@\w*')
669

	
670
    for phrase in paren_split:
671
        if look_next == 1:
672
            if phrase == '(':
673
                phrase = '{'
674
                open_paren_count = open_paren_count + 1
675
            else:
676
                open_type = 0
677
            look_next = 0
678

	
679
        if phrase == '(':
680
            open_paren_count = open_paren_count + 1
681

	
682
        elif phrase == ')':
683
            open_paren_count = open_paren_count - 1
684
            if open_type == 1 and open_paren_count == 0:
685
                phrase = '}'
686
                open_type = 0
687

	
688
        elif at_rex.search( phrase ):
689
            open_type = 1
690
            look_next = 1
691

	
692
        filecont = filecont + phrase
693

	
694
    return filecont
695

	
696

	
697
#
698
# make all whitespace into just one space
699
# format the bibtex file into a usable form.
700
#
701
def bibtexwasher(filecont_source):
702

	
703
    space_rex = re.compile('\s+')
704
    comment_rex = re.compile('\s*%')
705

	
706
    filecont = []
707

	
708
    # remove trailing and excessive whitespace
709
    # ignore comments
710
    for line in filecont_source:
711
        line = string.strip(line)
712
        line = space_rex.sub(' ', line)
713
        # ignore comments
714
        if not comment_rex.match(line) and line != '':
715
            filecont.append(' '+ line)
716

	
717
    filecont = string.join(filecont, '')
718

	
719
    # the file is in one long string
720

	
721
    filecont = no_outer_parens(filecont)
722

	
723
    #
724
    # split lines according to preferred syntax scheme
725
    #
726
    filecont = re.sub('(=\s*{[^=]*)},', '\g<1>},\n', filecont)
727

	
728
    # add new lines after commas that are after values
729
    filecont = re.sub('"\s*,', '",\n', filecont)
730
    filecont = re.sub('=\s*([\w\d]+)\s*,', '= \g<1>,\n', filecont)
731
    filecont = re.sub('(@\w*)\s*({(\s*)[^,\s]*)\s*,',
732
                          '\n\n\g<1>\g<2>,\n', filecont)
733

	
734
    # add new lines after }
735
    filecont = re.sub('"\s*}','"\n}\n', filecont)
736
    filecont = re.sub('}\s*,','},\n', filecont)
737

	
738

	
739
    filecont = re.sub('@(\w*)', '\n@\g<1>', filecont)
740

	
741
    # character encoding, reserved latex characters
742
    filecont = re.sub('{\\\&}', '&', filecont)
743
    filecont = re.sub('\\\&', '&', filecont)
744

	
745
    # do checking for open braces to get format correct
746
    open_brace_count = 0
747
    brace_split = re.split('([{}])',filecont)
748

	
749
    # rebuild filecont
750
    filecont = ''
751

	
752
    for phrase in brace_split:
753
        if phrase == '{':
754
            open_brace_count = open_brace_count + 1
755
        elif phrase == '}':
756
            open_brace_count = open_brace_count - 1
757
            if open_brace_count == 0:
758
                filecont = filecont + '\n'
759

	
760
        filecont = filecont + phrase
761

	
762
    filecont2 = bibtex_replace_abbreviations(filecont)
763

	
764
    # gather
765
    filecont = filecont2.splitlines()
766
    i=0
767
    j=0         # count the number of blank lines
768
    for line in filecont:
769
        # ignore blank lines
770
        if line == '' or line == ' ':
771
            j = j+1
772
            continue
773
        filecont[i] = line + '\n'
774
        i = i+1
775

	
776
    # get rid of the extra stuff at the end of the array
777
    # (The extra stuff are duplicates that are in the array because
778
    # blank lines were removed.)
779
    length = len( filecont)
780
    filecont[length-j:length] = []
781

	
782
    return filecont
783

	
784

	
785
def filehandler(filepath):
786
    try:
787
        fd = open(filepath, 'r')
788
        filecont_source = fd.readlines()
789
        fd.close()
790
    except:
791
        print 'Could not open file:', filepath
792
    washeddata = bibtexwasher(filecont_source)
793
    outdata = bibtexdecoder(washeddata)
794
    print '/**'
795
    print '\page references References'
796
    print
797
    for line in outdata:
798
        print line
799
    print '*/'
800

	
801

	
802
# main program
803

	
804
def main():
805
    import sys
806
    if sys.argv[1:]:
807
        filepath = sys.argv[1]
808
    else:
809
        print "No input file"
810
        sys.exit()
811
    filehandler(filepath)
812

	
813
if __name__ == "__main__": main()
814

	
815

	
816
# 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 GLPK_PREFIX /usr/local/ \
48
    "# GLPK installation root prefix"
49

	
50
augment_config COIN_OR_PREFIX /usr/local/coin-or \
51
    "# COIN-OR installation root prefix (used for CLP/CBC)"
52

	
53
augment_config SOPLEX_PREFIX /usr/local/soplex \
54
    "# Soplex build prefix"
55

	
56

	
57
function ask() {
58
echo -n "$1 [$2]? "
59
read _an
60
if [ "x$_an" == "x" ]; then
61
    ret="$2"
62
else
63
    ret=$_an
64
fi
65
}
66

	
67
function yesorno() {
68
    ret='rossz'
69
    while [ "$ret" != "y" -a "$ret" != "n" -a "$ret" != "yes" -a "$ret" != "no" ]; do
70
        ask "$1" "$2"
71
    done
72
    if [ "$ret" != "y" -a "$ret" != "yes" ]; then
73
        return 1
74
    else
75
        return 0
76
    fi
77
}
78

	
79
if yesorno "External build" "n"
80
then
81
    CONFIGURE_PATH=".."
82
else
83
    CONFIGURE_PATH="."
84
    if yesorno "Autoreconf" "y"
85
    then
86
        AUTORE=yes
87
    else
88
        AUTORE=no
89
    fi
90
fi
91

	
92
if yesorno "Optimize" "n" 
93
then
94
    opt_flags=' -O2'
95
else
96
    opt_flags=''
97
fi
98

	
99
if yesorno "Stop on warning" "y" 
100
then
101
    werror_flags=' -Werror'
102
else
103
    werror_flags=''
104
fi
105

	
106
cxx_flags="CXXFLAGS=-ggdb$opt_flags$werror_flags"
107

	
108
if yesorno "Check with valgrind" "n" 
109
then
110
    valgrind_flags=' --enable-valgrind'
111
else
112
    valgrind_flags=''
113
fi
114

	
115
if [ -f ${GLPK_PREFIX}/include/glpk.h ]; then
116
    if yesorno "Use GLPK" "y"
117
    then
118
        glpk_flag="--with-glpk=$GLPK_PREFIX"
119
    else
120
        glpk_flag="--without-glpk"
121
    fi
122
else
123
    glpk_flag="--without-glpk"        
124
fi
125

	
126
if [ -f ${COIN_OR_PREFIX}/include/coin/config_coinutils.h ]; then
127
    if yesorno "Use COIN-OR (CBC/CLP)" "n"
128
    then
129
        coin_flag="--with-coin=$COIN_OR_PREFIX"
130
    else
131
        coin_flag="--without-coin"
132
    fi
133
else
134
    coin_flag="--without-coin"        
135
fi
136

	
137
if [ -f ${SOPLEX_PREFIX}/src/soplex.h ]; then
138
    if yesorno "Use Soplex" "n"
139
    then
140
        soplex_flag="--with-soplex=$SOPLEX_PREFIX"
141
    else
142
        soplex_flag="--without-soplex"
143
    fi
144
else
145
    soplex_flag="--without-soplex"
146
fi
147

	
148
if [ "x$AUTORE" == "xyes" ]; then
149
    autoreconf -vif;
150
fi
151
${CONFIGURE_PATH}/configure --prefix=$LEMON_INSTALL_PREFIX \
152
$valgrind_flags \
153
"$cxx_flags" \
154
$glpk_flag \
155
$coin_flag \
156
$soplex_flag \
157
$*
Ignore white space 6 line context
1
#!/bin/sh
2

	
3
# Run in valgrind, with leak checking enabled
4

	
5
valgrind -q --leak-check=full "$@" 2> .valgrind-log
6

	
7
# Save the test result
8

	
9
result="$?"
10

	
11
# Valgrind should generate no error messages
12

	
13
log_contents="`cat .valgrind-log`"
14

	
15
if [ "$log_contents" != "" ]; then
16
        cat .valgrind-log >&2
17
        result=1
18
fi
19

	
20
rm -f .valgrind-log
21

	
22
exit $result
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-2010
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=3;
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
      ::SetOperationTraits<BellmanFordToleranceOperationTraits<Value, 0> >
108
      ::Create bf_test(gr,length);
109

	
110
    LengthMap length_map;
111
    concepts::ReadWriteMap<Node,Arc> pred_map;
112
    concepts::ReadWriteMap<Node,Value> dist_map;
113

	
114
    bf_test
115
      .lengthMap(length_map)
116
      .predMap(pred_map)
117
      .distMap(dist_map);
118

	
119
    bf_test.run(s);
120
    bf_test.run(s,k);
121

	
122
    bf_test.init();
123
    bf_test.addSource(s);
124
    bf_test.addSource(s, 1);
125
    b = bf_test.processNextRound();
126
    b = bf_test.processNextWeakRound();
127

	
128
    bf_test.start();
129
    bf_test.checkedStart();
130
    bf_test.limitedStart(k);
131

	
132
    l  = bf_test.dist(t);
133
    e  = bf_test.predArc(t);
134
    s  = bf_test.predNode(t);
135
    b  = bf_test.reached(t);
136
    pp = bf_test.path(t);
137
    pp = bf_test.negativeCycle();
138
  }
139
}
140

	
141
void checkBellmanFordFunctionCompile()
142
{
143
  typedef int Value;
144
  typedef concepts::Digraph Digraph;
145
  typedef Digraph::Arc Arc;
146
  typedef Digraph::Node Node;
147
  typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
148

	
149
  Digraph g;
150
  bool b;
151
  bellmanFord(g,LengthMap()).run(Node());
152
  b = bellmanFord(g,LengthMap()).run(Node(),Node());
153
  bellmanFord(g,LengthMap())
154
    .predMap(concepts::ReadWriteMap<Node,Arc>())
155
    .distMap(concepts::ReadWriteMap<Node,Value>())
156
    .run(Node());
157
  b=bellmanFord(g,LengthMap())
158
    .predMap(concepts::ReadWriteMap<Node,Arc>())
159
    .distMap(concepts::ReadWriteMap<Node,Value>())
160
    .path(concepts::Path<Digraph>())
161
    .dist(Value())
162
    .run(Node(),Node());
163
}
164

	
165

	
166
template <typename Digraph, typename Value>
167
void checkBellmanFord() {
168
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
169
  typedef typename Digraph::template ArcMap<Value> LengthMap;
170

	
171
  Digraph gr;
172
  Node s, t;
173
  LengthMap length(gr);
174

	
175
  std::istringstream input(test_lgf);
176
  digraphReader(gr, input).
177
    arcMap("length", length).
178
    node("source", s).
179
    node("target", t).
180
    run();
181

	
182
  BellmanFord<Digraph, LengthMap>
183
    bf(gr, length);
184
  bf.run(s);
185
  Path<Digraph> p = bf.path(t);
186

	
187
  check(bf.reached(t) && bf.dist(t) == -1, "Bellman-Ford found a wrong path.");
188
  check(p.length() == 3, "path() found a wrong path.");
189
  check(checkPath(gr, p), "path() found a wrong path.");
190
  check(pathSource(gr, p) == s, "path() found a wrong path.");
191
  check(pathTarget(gr, p) == t, "path() found a wrong path.");
192

	
193
  ListPath<Digraph> path;
194
  Value dist;
195
  bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
196

	
197
  check(reached && dist == -1, "Bellman-Ford found a wrong path.");
198
  check(path.length() == 3, "path() found a wrong path.");
199
  check(checkPath(gr, path), "path() found a wrong path.");
200
  check(pathSource(gr, path) == s, "path() found a wrong path.");
201
  check(pathTarget(gr, path) == t, "path() found a wrong path.");
202

	
203
  for(ArcIt e(gr); e!=INVALID; ++e) {
204
    Node u=gr.source(e);
205
    Node v=gr.target(e);
206
    check(!bf.reached(u) || (bf.dist(v) - bf.dist(u) <= length[e]),
207
          "Wrong output. dist(target)-dist(source)-arc_length=" <<
208
          bf.dist(v) - bf.dist(u) - length[e]);
209
  }
210

	
211
  for(NodeIt v(gr); v!=INVALID; ++v) {
212
    if (bf.reached(v)) {
213
      check(v==s || bf.predArc(v)!=INVALID, "Wrong tree.");
214
      if (bf.predArc(v)!=INVALID ) {
215
        Arc e=bf.predArc(v);
216
        Node u=gr.source(e);
217
        check(u==bf.predNode(v),"Wrong tree.");
218
        check(bf.dist(v) - bf.dist(u) == length[e],
219
              "Wrong distance! Difference: " <<
220
              bf.dist(v) - bf.dist(u) - length[e]);
221
      }
222
    }
223
  }
224
}
225

	
226
void checkBellmanFordNegativeCycle() {
227
  DIGRAPH_TYPEDEFS(SmartDigraph);
228

	
229
  SmartDigraph gr;
230
  IntArcMap length(gr);
231

	
232
  Node n1 = gr.addNode();
233
  Node n2 = gr.addNode();
234
  Node n3 = gr.addNode();
235
  Node n4 = gr.addNode();
236

	
237
  Arc a1 = gr.addArc(n1, n2);
238
  Arc a2 = gr.addArc(n2, n2);
239

	
240
  length[a1] = 2;
241
  length[a2] = -1;
242

	
243
  {
244
    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
245
    bf.run(n1);
246
    StaticPath<SmartDigraph> p = bf.negativeCycle();
247
    check(p.length() == 1 && p.front() == p.back() && p.front() == a2,
248
          "Wrong negative cycle.");
249
  }
250

	
251
  length[a2] = 0;
252

	
253
  {
254
    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
255
    bf.run(n1);
256
    check(bf.negativeCycle().empty(),
257
          "Negative cycle should not be found.");
258
  }
259

	
260
  length[gr.addArc(n1, n3)] = 5;
261
  length[gr.addArc(n4, n3)] = 1;
262
  length[gr.addArc(n2, n4)] = 2;
263
  length[gr.addArc(n3, n2)] = -4;
264

	
265
  {
266
    BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
267
    bf.init();
268
    bf.addSource(n1);
269
    for (int i = 0; i < 4; ++i) {
270
      check(bf.negativeCycle().empty(),
271
            "Negative cycle should not be found.");
272
      bf.processNextRound();
273
    }
274
    StaticPath<SmartDigraph> p = bf.negativeCycle();
275
    check(p.length() == 3, "Wrong negative cycle.");
276
    check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1,
277
          "Wrong negative cycle.");
278
  }
279
}
280

	
281
int main() {
282
  checkBellmanFord<ListDigraph, int>();
283
  checkBellmanFord<SmartDigraph, double>();
284
  checkBellmanFordNegativeCycle();
285
  return 0;
286
}
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-2010
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/fractional_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 = 4;
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
  "@nodes\n"
115
  "label\n"
116
  "0\n"
117
  "@edges\n"
118
  "     label  weight\n"
119
  "0 0  0      100\n"
120
};
121

	
122
void checkMaxFractionalMatchingCompile()
123
{
124
  typedef concepts::Graph Graph;
125
  typedef Graph::Node Node;
126
  typedef Graph::Edge Edge;
127

	
128
  Graph g;
129
  Node n;
130
  Edge e;
131

	
132
  MaxFractionalMatching<Graph> mat_test(g);
133
  const MaxFractionalMatching<Graph>&
134
    const_mat_test = mat_test;
135

	
136
  mat_test.init();
137
  mat_test.start();
138
  mat_test.start(true);
139
  mat_test.startPerfect();
140
  mat_test.startPerfect(true);
141
  mat_test.run();
142
  mat_test.run(true);
143
  mat_test.runPerfect();
144
  mat_test.runPerfect(true);
145

	
146
  const_mat_test.matchingSize();
147
  const_mat_test.matching(e);
148
  const_mat_test.matching(n);
149
  const MaxFractionalMatching<Graph>::MatchingMap& mmap =
150
    const_mat_test.matchingMap();
151
  e = mmap[n];
152

	
153
  const_mat_test.barrier(n);
154
}
155

	
156
void checkMaxWeightedFractionalMatchingCompile()
157
{
158
  typedef concepts::Graph Graph;
159
  typedef Graph::Node Node;
160
  typedef Graph::Edge Edge;
161
  typedef Graph::EdgeMap<int> WeightMap;
162

	
163
  Graph g;
164
  Node n;
165
  Edge e;
166
  WeightMap w(g);
167

	
168
  MaxWeightedFractionalMatching<Graph> mat_test(g, w);
169
  const MaxWeightedFractionalMatching<Graph>&
170
    const_mat_test = mat_test;
171

	
172
  mat_test.init();
173
  mat_test.start();
174
  mat_test.run();
175

	
176
  const_mat_test.matchingWeight();
177
  const_mat_test.matchingSize();
178
  const_mat_test.matching(e);
179
  const_mat_test.matching(n);
180
  const MaxWeightedFractionalMatching<Graph>::MatchingMap& mmap =
181
    const_mat_test.matchingMap();
182
  e = mmap[n];
183

	
184
  const_mat_test.dualValue();
185
  const_mat_test.nodeValue(n);
186
}
187

	
188
void checkMaxWeightedPerfectFractionalMatchingCompile()
189
{
190
  typedef concepts::Graph Graph;
191
  typedef Graph::Node Node;
192
  typedef Graph::Edge Edge;
193
  typedef Graph::EdgeMap<int> WeightMap;
194

	
195
  Graph g;
196
  Node n;
197
  Edge e;
198
  WeightMap w(g);
199

	
200
  MaxWeightedPerfectFractionalMatching<Graph> mat_test(g, w);
201
  const MaxWeightedPerfectFractionalMatching<Graph>&
202
    const_mat_test = mat_test;
203

	
204
  mat_test.init();
205
  mat_test.start();
206
  mat_test.run();
207

	
208
  const_mat_test.matchingWeight();
209
  const_mat_test.matching(e);
210
  const_mat_test.matching(n);
211
  const MaxWeightedPerfectFractionalMatching<Graph>::MatchingMap& mmap =
212
    const_mat_test.matchingMap();
213
  e = mmap[n];
214

	
215
  const_mat_test.dualValue();
216
  const_mat_test.nodeValue(n);
217
}
218

	
219
void checkFractionalMatching(const SmartGraph& graph,
220
                             const MaxFractionalMatching<SmartGraph>& mfm,
221
                             bool allow_loops = true) {
222
  int pv = 0;
223
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
224
    int indeg = 0;
225
    for (InArcIt a(graph, n); a != INVALID; ++a) {
226
      if (mfm.matching(graph.source(a)) == a) {
227
        ++indeg;
228
      }
229
    }
230
    if (mfm.matching(n) != INVALID) {
231
      check(indeg == 1, "Invalid matching");
232
      ++pv;
233
    } else {
234
      check(indeg == 0, "Invalid matching");
235
    }
236
  }
237
  check(pv == mfm.matchingSize(), "Wrong matching size");
238

	
239
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
240
    check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
241
          (e == mfm.matching(graph.v(e)) ? 1 : 0) ==
242
          mfm.matching(e), "Invalid matching");
243
  }
244

	
245
  SmartGraph::NodeMap<bool> processed(graph, false);
246
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
247
    if (processed[n]) continue;
248
    processed[n] = true;
249
    if (mfm.matching(n) == INVALID) continue;
250
    int num = 1;
251
    Node v = graph.target(mfm.matching(n));
252
    while (v != n) {
253
      processed[v] = true;
254
      ++num;
255
      v = graph.target(mfm.matching(v));
256
    }
257
    check(num == 2 || num % 2 == 1, "Wrong cycle size");
258
    check(allow_loops || num != 1, "Wrong cycle size");
259
  }
260

	
261
  int anum = 0, bnum = 0;
262
  SmartGraph::NodeMap<bool> neighbours(graph, false);
263
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
264
    if (!mfm.barrier(n)) continue;
265
    ++anum;
266
    for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
267
      Node u = graph.source(a);
268
      if (!allow_loops && u == n) continue;
269
      if (!neighbours[u]) {
270
        neighbours[u] = true;
271
        ++bnum;
272
      }
273
    }
274
  }
275
  check(anum - bnum + mfm.matchingSize() == countNodes(graph),
276
        "Wrong barrier");
277
}
278

	
279
void checkPerfectFractionalMatching(const SmartGraph& graph,
280
                             const MaxFractionalMatching<SmartGraph>& mfm,
281
                             bool perfect, bool allow_loops = true) {
282
  if (perfect) {
283
    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
284
      int indeg = 0;
285
      for (InArcIt a(graph, n); a != INVALID; ++a) {
286
        if (mfm.matching(graph.source(a)) == a) {
287
          ++indeg;
288
        }
289
      }
290
      check(mfm.matching(n) != INVALID, "Invalid matching");
291
      check(indeg == 1, "Invalid matching");
292
    }
293
    for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
294
      check((e == mfm.matching(graph.u(e)) ? 1 : 0) +
295
            (e == mfm.matching(graph.v(e)) ? 1 : 0) ==
296
            mfm.matching(e), "Invalid matching");
297
    }
298
  } else {
299
    int anum = 0, bnum = 0;
300
    SmartGraph::NodeMap<bool> neighbours(graph, false);
301
    for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
302
      if (!mfm.barrier(n)) continue;
303
      ++anum;
304
      for (SmartGraph::InArcIt a(graph, n); a != INVALID; ++a) {
305
        Node u = graph.source(a);
306
        if (!allow_loops && u == n) continue;
307
        if (!neighbours[u]) {
308
          neighbours[u] = true;
309
          ++bnum;
310
        }
311
      }
312
    }
313
    check(anum - bnum > 0, "Wrong barrier");
314
  }
315
}
316

	
317
void checkWeightedFractionalMatching(const SmartGraph& graph,
318
                   const SmartGraph::EdgeMap<int>& weight,
319
                   const MaxWeightedFractionalMatching<SmartGraph>& mwfm,
320
                   bool allow_loops = true) {
321
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
322
    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
323
    int rw = mwfm.nodeValue(graph.u(e)) + mwfm.nodeValue(graph.v(e))
324
      - weight[e] * mwfm.dualScale;
325

	
326
    check(rw >= 0, "Negative reduced weight");
327
    check(rw == 0 || !mwfm.matching(e),
328
          "Non-zero reduced weight on matching edge");
329
  }
330

	
331
  int pv = 0;
332
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
333
    int indeg = 0;
334
    for (InArcIt a(graph, n); a != INVALID; ++a) {
335
      if (mwfm.matching(graph.source(a)) == a) {
336
        ++indeg;
337
      }
338
    }
339
    check(indeg <= 1, "Invalid matching");
340
    if (mwfm.matching(n) != INVALID) {
341
      check(mwfm.nodeValue(n) >= 0, "Invalid node value");
342
      check(indeg == 1, "Invalid matching");
343
      pv += weight[mwfm.matching(n)];
344
      SmartGraph::Node o = graph.target(mwfm.matching(n));
345
    } else {
346
      check(mwfm.nodeValue(n) == 0, "Invalid matching");
347
      check(indeg == 0, "Invalid matching");
348
    }
349
  }
350

	
351
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
352
    check((e == mwfm.matching(graph.u(e)) ? 1 : 0) +
353
          (e == mwfm.matching(graph.v(e)) ? 1 : 0) ==
354
          mwfm.matching(e), "Invalid matching");
355
  }
356

	
357
  int dv = 0;
358
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
359
    dv += mwfm.nodeValue(n);
360
  }
361

	
362
  check(pv * mwfm.dualScale == dv * 2, "Wrong duality");
363

	
364
  SmartGraph::NodeMap<bool> processed(graph, false);
365
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
366
    if (processed[n]) continue;
367
    processed[n] = true;
368
    if (mwfm.matching(n) == INVALID) continue;
369
    int num = 1;
370
    Node v = graph.target(mwfm.matching(n));
371
    while (v != n) {
372
      processed[v] = true;
373
      ++num;
374
      v = graph.target(mwfm.matching(v));
375
    }
376
    check(num == 2 || num % 2 == 1, "Wrong cycle size");
377
    check(allow_loops || num != 1, "Wrong cycle size");
378
  }
379

	
380
  return;
381
}
382

	
383
void checkWeightedPerfectFractionalMatching(const SmartGraph& graph,
384
                const SmartGraph::EdgeMap<int>& weight,
385
                const MaxWeightedPerfectFractionalMatching<SmartGraph>& mwpfm,
386
                bool allow_loops = true) {
387
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
388
    if (graph.u(e) == graph.v(e) && !allow_loops) continue;
389
    int rw = mwpfm.nodeValue(graph.u(e)) + mwpfm.nodeValue(graph.v(e))
390
      - weight[e] * mwpfm.dualScale;
391

	
392
    check(rw >= 0, "Negative reduced weight");
393
    check(rw == 0 || !mwpfm.matching(e),
394
          "Non-zero reduced weight on matching edge");
395
  }
396

	
397
  int pv = 0;
398
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
399
    int indeg = 0;
400
    for (InArcIt a(graph, n); a != INVALID; ++a) {
401
      if (mwpfm.matching(graph.source(a)) == a) {
402
        ++indeg;
403
      }
404
    }
405
    check(mwpfm.matching(n) != INVALID, "Invalid perfect matching");
406
    check(indeg == 1, "Invalid perfect matching");
407
    pv += weight[mwpfm.matching(n)];
408
    SmartGraph::Node o = graph.target(mwpfm.matching(n));
409
  }
410

	
411
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
412
    check((e == mwpfm.matching(graph.u(e)) ? 1 : 0) +
413
          (e == mwpfm.matching(graph.v(e)) ? 1 : 0) ==
414
          mwpfm.matching(e), "Invalid matching");
415
  }
416

	
417
  int dv = 0;
418
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
419
    dv += mwpfm.nodeValue(n);
420
  }
421

	
422
  check(pv * mwpfm.dualScale == dv * 2, "Wrong duality");
423

	
424
  SmartGraph::NodeMap<bool> processed(graph, false);
425
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
426
    if (processed[n]) continue;
427
    processed[n] = true;
428
    if (mwpfm.matching(n) == INVALID) continue;
429
    int num = 1;
430
    Node v = graph.target(mwpfm.matching(n));
431
    while (v != n) {
432
      processed[v] = true;
433
      ++num;
434
      v = graph.target(mwpfm.matching(v));
435
    }
436
    check(num == 2 || num % 2 == 1, "Wrong cycle size");
437
    check(allow_loops || num != 1, "Wrong cycle size");
438
  }
439

	
440
  return;
441
}
442

	
443

	
444
int main() {
445

	
446
  for (int i = 0; i < lgfn; ++i) {
447
    SmartGraph graph;
448
    SmartGraph::EdgeMap<int> weight(graph);
449

	
450
    istringstream lgfs(lgf[i]);
451
    graphReader(graph, lgfs).
452
      edgeMap("weight", weight).run();
453

	
454
    bool perfect_with_loops;
455
    {
456
      MaxFractionalMatching<SmartGraph> mfm(graph, true);
457
      mfm.run();
458
      checkFractionalMatching(graph, mfm, true);
459
      perfect_with_loops = mfm.matchingSize() == countNodes(graph);
460
    }
461

	
462
    bool perfect_without_loops;
463
    {
464
      MaxFractionalMatching<SmartGraph> mfm(graph, false);
465
      mfm.run();
466
      checkFractionalMatching(graph, mfm, false);
467
      perfect_without_loops = mfm.matchingSize() == countNodes(graph);
468
    }
469

	
470
    {
471
      MaxFractionalMatching<SmartGraph> mfm(graph, true);
472
      bool result = mfm.runPerfect();
473
      checkPerfectFractionalMatching(graph, mfm, result, true);
474
      check(result == perfect_with_loops, "Wrong perfect matching");
475
    }
476

	
477
    {
478
      MaxFractionalMatching<SmartGraph> mfm(graph, false);
479
      bool result = mfm.runPerfect();
480
      checkPerfectFractionalMatching(graph, mfm, result, false);
481
      check(result == perfect_without_loops, "Wrong perfect matching");
482
    }
483

	
484
    {
485
      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, true);
486
      mwfm.run();
487
      checkWeightedFractionalMatching(graph, weight, mwfm, true);
488
    }
489

	
490
    {
491
      MaxWeightedFractionalMatching<SmartGraph> mwfm(graph, weight, false);
492
      mwfm.run();
493
      checkWeightedFractionalMatching(graph, weight, mwfm, false);
494
    }
495

	
496
    {
497
      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
498
                                                             true);
499
      bool perfect = mwpfm.run();
500
      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
501
            "Perfect matching found");
502
      check(perfect == perfect_with_loops, "Wrong perfect matching");
503

	
504
      if (perfect) {
505
        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, true);
506
      }
507
    }
508

	
509
    {
510
      MaxWeightedPerfectFractionalMatching<SmartGraph> mwpfm(graph, weight,
511
                                                             false);
512
      bool perfect = mwpfm.run();
513
      check(perfect == (mwpfm.matchingSize() == countNodes(graph)),
514
            "Perfect matching found");
515
      check(perfect == perfect_without_loops, "Wrong perfect matching");
516

	
517
      if (perfect) {
518
        checkWeightedPerfectFractionalMatching(graph, weight, mwpfm, false);
519
      }
520
    }
521

	
522
  }
523

	
524
  return 0;
525
}
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-2010
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_mmc.h>
29
#include <lemon/hartmann_orlin_mmc.h>
30
#include <lemon/howard_mmc.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 Cost>
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 SetLargeCost<Cost>
77
        ::Create MmcAlg;
78
      MmcAlg mmc(me.g, me.cost);
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.findCycleMean();
86
      b = mmc.findCycle();
87

	
88
      v = const_mmc.cycleCost();
89
      i = const_mmc.cycleSize();
90
      d = const_mmc.cycleMean();
91
      p = const_mmc.cycle();
92
    }
93

	
94
    typedef concepts::ReadMap<typename GR::Arc, Cost> CM;
95

	
96
    GR g;
97
    CM cost;
98
    ListPath<GR> p;
99
    Cost 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 cost, int size) {
112
  MMC alg(gr, lm);
113
  alg.findCycleMean();
114
  check(alg.cycleMean() == static_cast<double>(cost) / size,
115
        "Wrong cycle mean");
116
  alg.findCycle();
117
  check(alg.cycleCost() == cost && alg.cycleSize() == 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
    // KarpMmc
152
    checkConcept< MmcClassConcept<GR, int>,
153
                  KarpMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
154
    checkConcept< MmcClassConcept<GR, float>,
155
                  KarpMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
156

	
157
    // HartmannOrlinMmc
158
    checkConcept< MmcClassConcept<GR, int>,
159
                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
160
    checkConcept< MmcClassConcept<GR, float>,
161
                  HartmannOrlinMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
162

	
163
    // HowardMmc
164
    checkConcept< MmcClassConcept<GR, int>,
165
                  HowardMmc<GR, concepts::ReadMap<GR::Arc, int> > >();
166
    checkConcept< MmcClassConcept<GR, float>,
167
                  HowardMmc<GR, concepts::ReadMap<GR::Arc, float> > >();
168

	
169
    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, int> >
170
           ::LargeCost, long_int>::result == 1), "Wrong LargeCost type");
171
    check((IsSameType<HowardMmc<GR, concepts::ReadMap<GR::Arc, float> >
172
           ::LargeCost, double>::result == 1), "Wrong LargeCost 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<KarpMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
198
    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
199
    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
200
    checkMmcAlg<KarpMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
201

	
202
    // HartmannOrlin
203
    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
204
    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
205
    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
206
    checkMmcAlg<HartmannOrlinMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1);
207

	
208
    // Howard
209
    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l1, c1,  6, 3);
210
    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l2, c2,  5, 2);
211
    checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3,  0, 1);
212
    checkMmcAlg<HowardMmc<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 <iostream>
20

	
21
#include <lemon/planarity.h>
22

	
23
#include <lemon/smart_graph.h>
24
#include <lemon/lgf_reader.h>
25
#include <lemon/connectivity.h>
26
#include <lemon/dim2.h>
27

	
28
#include "test_tools.h"
29

	
30
using namespace lemon;
31
using namespace lemon::dim2;
32

	
33
const int lgfn = 4;
34
const std::string lgf[lgfn] = {
35
  "@nodes\n"
36
  "label\n"
37
  "0\n"
38
  "1\n"
39
  "2\n"
40
  "3\n"
41
  "4\n"
42
  "@edges\n"
43
  "     label\n"
44
  "0 1  0\n"
45
  "0 2  0\n"
46
  "0 3  0\n"
47
  "0 4  0\n"
48
  "1 2  0\n"
49
  "1 3  0\n"
50
  "1 4  0\n"
51
  "2 3  0\n"
52
  "2 4  0\n"
53
  "3 4  0\n",
54

	
55
  "@nodes\n"
56
  "label\n"
57
  "0\n"
58
  "1\n"
59
  "2\n"
60
  "3\n"
61
  "4\n"
62
  "@edges\n"
63
  "     label\n"
64
  "0 1  0\n"
65
  "0 2  0\n"
66
  "0 3  0\n"
67
  "0 4  0\n"
68
  "1 2  0\n"
69
  "1 3  0\n"
70
  "2 3  0\n"
71
  "2 4  0\n"
72
  "3 4  0\n",
73

	
74
  "@nodes\n"
75
  "label\n"
76
  "0\n"
77
  "1\n"
78
  "2\n"
79
  "3\n"
80
  "4\n"
81
  "5\n"
82
  "@edges\n"
83
  "     label\n"
84
  "0 3  0\n"
85
  "0 4  0\n"
86
  "0 5  0\n"
87
  "1 3  0\n"
88
  "1 4  0\n"
89
  "1 5  0\n"
90
  "2 3  0\n"
91
  "2 4  0\n"
92
  "2 5  0\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
  "@edges\n"
103
  "     label\n"
104
  "0 3  0\n"
105
  "0 4  0\n"
106
  "0 5  0\n"
107
  "1 3  0\n"
108
  "1 4  0\n"
109
  "1 5  0\n"
110
  "2 3  0\n"
111
  "2 5  0\n"
112
};
113

	
114

	
115

	
116
typedef SmartGraph Graph;
117
GRAPH_TYPEDEFS(Graph);
118

	
119
typedef PlanarEmbedding<SmartGraph> PE;
120
typedef PlanarDrawing<SmartGraph> PD;
121
typedef PlanarColoring<SmartGraph> PC;
122

	
123
void checkEmbedding(const Graph& graph, PE& pe) {
124
  int face_num = 0;
125

	
126
  Graph::ArcMap<int> face(graph, -1);
127

	
128
  for (ArcIt a(graph); a != INVALID; ++a) {
129
    if (face[a] == -1) {
130
      Arc b = a;
131
      while (face[b] == -1) {
132
        face[b] = face_num;
133
        b = pe.next(graph.oppositeArc(b));
134
      }
135
      check(face[b] == face_num, "Wrong face");
136
      ++face_num;
137
    }
138
  }
139
  check(face_num + countNodes(graph) - countConnectedComponents(graph) ==
140
        countEdges(graph) + 1, "Euler test does not passed");
141
}
142

	
143
void checkKuratowski(const Graph& graph, PE& pe) {
144
  std::map<int, int> degs;
145
  for (NodeIt n(graph); n != INVALID; ++n) {
146
    int deg = 0;
147
    for (IncEdgeIt e(graph, n); e != INVALID; ++e) {
148
      if (pe.kuratowski(e)) {
149
        ++deg;
150
      }
151
    }
152
    ++degs[deg];
153
  }
154
  for (std::map<int, int>::iterator it = degs.begin(); it != degs.end(); ++it) {
155
    check(it->first == 0 || it->first == 2 ||
156
          (it->first == 3 && it->second == 6) ||
157
          (it->first == 4 && it->second == 5),
158
          "Wrong degree in Kuratowski graph");
159
  }
160

	
161
  // Not full test
162
  check((degs[3] == 0) != (degs[4] == 0), "Wrong Kuratowski graph");
163
}
164

	
165
bool intersect(Point<int> e1, Point<int> e2, Point<int> f1, Point<int> f2) {
166
  int l, r;
167
  if (std::min(e1.x, e2.x) > std::max(f1.x, f2.x)) return false;
168
  if (std::max(e1.x, e2.x) < std::min(f1.x, f2.x)) return false;
169
  if (std::min(e1.y, e2.y) > std::max(f1.y, f2.y)) return false;
170
  if (std::max(e1.y, e2.y) < std::min(f1.y, f2.y)) return false;
171

	
172
  l = (e2.x - e1.x) * (f1.y - e1.y) - (e2.y - e1.y) * (f1.x - e1.x);
173
  r = (e2.x - e1.x) * (f2.y - e1.y) - (e2.y - e1.y) * (f2.x - e1.x);
174
  if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
175
  l = (f2.x - f1.x) * (e1.y - f1.y) - (f2.y - f1.y) * (e1.x - f1.x);
176
  r = (f2.x - f1.x) * (e2.y - f1.y) - (f2.y - f1.y) * (e2.x - f1.x);
177
  if (!((l >= 0 && r <= 0) || (l <= 0 && r >= 0))) return false;
178
  return true;
179
}
180

	
181
bool collinear(Point<int> p, Point<int> q, Point<int> r) {
182
  int v;
183
  v = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x);
184
  if (v != 0) return false;
185
  v = (q.x - p.x) * (r.x - p.x) + (q.y - p.y) * (r.y - p.y);
186
  if (v < 0) return false;
187
  return true;
188
}
189

	
190
void checkDrawing(const Graph& graph, PD& pd) {
191
  for (Graph::NodeIt n(graph); n != INVALID; ++n) {
192
    Graph::NodeIt m(n);
193
    for (++m; m != INVALID; ++m) {
194
      check(pd[m] != pd[n], "Two nodes with identical coordinates");
195
    }
196
  }
197

	
198
  for (Graph::EdgeIt e(graph); e != INVALID; ++e) {
199
    for (Graph::EdgeIt f(e); f != e; ++f) {
200
      Point<int> e1 = pd[graph.u(e)];
201
      Point<int> e2 = pd[graph.v(e)];
202
      Point<int> f1 = pd[graph.u(f)];
203
      Point<int> f2 = pd[graph.v(f)];
204

	
205
      if (graph.u(e) == graph.u(f)) {
206
        check(!collinear(e1, e2, f2), "Wrong drawing");
207
      } else if (graph.u(e) == graph.v(f)) {
208
        check(!collinear(e1, e2, f1), "Wrong drawing");
209
      } else if (graph.v(e) == graph.u(f)) {
210
        check(!collinear(e2, e1, f2), "Wrong drawing");
211
      } else if (graph.v(e) == graph.v(f)) {
212
        check(!collinear(e2, e1, f1), "Wrong drawing");
213
      } else {
214
        check(!intersect(e1, e2, f1, f2), "Wrong drawing");
215
      }
216
    }
217
  }
218
}
219

	
220
void checkColoring(const Graph& graph, PC& pc, int num) {
221
  for (NodeIt n(graph); n != INVALID; ++n) {
222
    check(pc.colorIndex(n) >= 0 && pc.colorIndex(n) < num,
223
          "Wrong coloring");
224
  }
225
  for (EdgeIt e(graph); e != INVALID; ++e) {
226
    check(pc.colorIndex(graph.u(e)) != pc.colorIndex(graph.v(e)),
227
          "Wrong coloring");
228
  }
229
}
230

	
231
int main() {
232

	
233
  for (int i = 0; i < lgfn; ++i) {
234
    std::istringstream lgfs(lgf[i]);
235

	
236
    SmartGraph graph;
237
    graphReader(graph, lgfs).run();
238

	
239
    check(simpleGraph(graph), "Test graphs must be simple");
240

	
241
    PE pe(graph);
242
    bool planar = pe.run();
243
    check(checkPlanarity(graph) == planar, "Planarity checking failed");
244

	
245
    if (planar) {
246
      checkEmbedding(graph, pe);
247

	
248
      PlanarDrawing<Graph> pd(graph);
249
      pd.run(pe.embeddingMap());
250
      checkDrawing(graph, pd);
251

	
252
      PlanarColoring<Graph> pc(graph);
253
      pc.runFiveColoring(pe.embeddingMap());
254
      checkColoring(graph, pc, 5);
255

	
256
    } else {
257
      checkKuratowski(graph, pe);
258
    }
259
  }
260

	
261
  return 0;
262
}
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
doc/references.dox
25 26
cmake/version.cmake
26 27
.dirstamp
27 28
.libs/*
28 29
.deps/*
29 30
demo/*.eps
30 31
m4/libtool.m4
31 32
m4/ltoptions.m4
32 33
m4/ltsugar.m4
33 34
m4/ltversion.m4
34 35
m4/lt~obsolete.m4
35 36

	
36 37
syntax: regexp
37 38
(.*/)?\#[^/]*\#$
38 39
(.*/)?\.\#[^/]*$
39 40
^doc/html/.*
40 41
^doc/.*\.tag
41 42
^autom4te.cache/.*
42 43
^build-aux/.*
43 44
^.*objs.*/.*
44 45
^test/[a-z_]*$
45 46
^tools/[a-z-_]*$
46 47
^demo/.*_demo$
47 48
^.*build.*/.*
48 49
^doc/gen-images/.*
49 50
CMakeFiles
50 51
DartTestfile.txt
51 52
cmake_install.cmake
52 53
CMakeCache.txt
Ignore white space 268435456 line context
1 1
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
2 2

	
3 3
SET(PROJECT_NAME "LEMON")
4 4
PROJECT(${PROJECT_NAME})
5 5

	
6 6
INCLUDE(FindPythonInterp)
7 7
INCLUDE(FindWget)
8 8

	
9 9
IF(EXISTS ${PROJECT_SOURCE_DIR}/cmake/version.cmake)
10 10
  INCLUDE(${PROJECT_SOURCE_DIR}/cmake/version.cmake)
11 11
ELSEIF(DEFINED ENV{LEMON_VERSION})
12 12
  SET(LEMON_VERSION $ENV{LEMON_VERSION} CACHE STRING "LEMON version string.")
13 13
ELSE()
14 14
  EXECUTE_PROCESS(
15 15
    COMMAND ${PYTHON_EXECUTABLE} ./scripts/chg-len.py
16 16
    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
17 17
    OUTPUT_VARIABLE HG_REVISION_PATH
18 18
    ERROR_QUIET
19 19
    OUTPUT_STRIP_TRAILING_WHITESPACE
20 20
  )
21 21
  EXECUTE_PROCESS(
22 22
    COMMAND hg id -i
23 23
    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
24 24
    OUTPUT_VARIABLE HG_REVISION
25 25
    ERROR_QUIET
26 26
    OUTPUT_STRIP_TRAILING_WHITESPACE
27 27
  )
28 28
  IF(HG_REVISION STREQUAL "")
29 29
    SET(HG_REVISION_ID "hg-tip")
30 30
  ELSE()
31 31
    IF(HG_REVISION_PATH STREQUAL "")
32 32
      SET(HG_REVISION_ID ${HG_REVISION})
33 33
    ELSE()
34 34
      SET(HG_REVISION_ID ${HG_REVISION_PATH}.${HG_REVISION})
35 35
    ENDIF()
36 36
  ENDIF()
37 37
  SET(LEMON_VERSION ${HG_REVISION_ID} CACHE STRING "LEMON version string.")
38 38
ENDIF()
39 39

	
40 40
SET(PROJECT_VERSION ${LEMON_VERSION})
41 41

	
42 42
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
43 43

	
44 44
FIND_PACKAGE(Doxygen)
45 45
FIND_PACKAGE(Ghostscript)
46 46
FIND_PACKAGE(GLPK 4.33)
47 47
FIND_PACKAGE(CPLEX)
48 48
FIND_PACKAGE(COIN)
49 49

	
50 50
IF(DEFINED ENV{LEMON_CXX_WARNING})
51 51
  SET(CXX_WARNING $ENV{LEMON_CXX_WARNING})
52 52
ELSE()
53 53
  IF(CMAKE_COMPILER_IS_GNUCXX)
54 54
    SET(CXX_WARNING "-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 -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas")
55 55
    SET(CMAKE_CXX_FLAGS_DEBUG CACHE STRING "-ggdb")
56 56
    SET(CMAKE_C_FLAGS_DEBUG CACHE STRING "-ggdb")
57 57
  ELSEIF(MSVC)
58 58
    # This part is unnecessary 'casue the same is set by the lemon/core.h.
59 59
    # Still keep it as an example.
60 60
    SET(CXX_WARNING "/wd4250 /wd4355 /wd4503 /wd4800 /wd4996")
61 61
    # Suppressed warnings:
62 62
    # C4250: 'class1' : inherits 'class2::member' via dominance
63 63
    # C4355: 'this' : used in base member initializer list
64 64
    # C4503: 'function' : decorated name length exceeded, name was truncated
65 65
    # C4800: 'type' : forcing value to bool 'true' or 'false'
66 66
    #        (performance warning)
67 67
    # C4996: 'function': was declared deprecated
68 68
  ELSE()
69 69
    SET(CXX_WARNING "-Wall -W")
70 70
  ENDIF()
71 71
ENDIF()
72 72
SET(LEMON_CXX_WARNING_FLAGS ${CXX_WARNING} CACHE STRING "LEMON warning flags.")
73 73

	
74 74
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LEMON_CXX_WARNING_FLAGS}")
75 75

	
76 76
SET( CMAKE_CXX_FLAGS_MAINTAINER "-Werror -ggdb" CACHE STRING
77 77
    "Flags used by the C++ compiler during maintainer builds."
78 78
    FORCE )
79 79
SET( CMAKE_C_FLAGS_MAINTAINER "-Werror" CACHE STRING
80 80
    "Flags used by the C compiler during maintainer builds."
81 81
    FORCE )
82 82
SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
83 83
    "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
84 84
    "Flags used for linking binaries during maintainer builds."
85 85
    FORCE )
86 86
SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
87 87
    "-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
88 88
    "Flags used by the shared libraries linker during maintainer builds."
89 89
    FORCE )
90 90
MARK_AS_ADVANCED(
91 91
    CMAKE_CXX_FLAGS_MAINTAINER
92 92
    CMAKE_C_FLAGS_MAINTAINER
93 93
    CMAKE_EXE_LINKER_FLAGS_MAINTAINER
94 94
    CMAKE_SHARED_LINKER_FLAGS_MAINTAINER )
95 95

	
96 96
IF(CMAKE_CONFIGURATION_TYPES)
97 97
  LIST(APPEND CMAKE_CONFIGURATION_TYPES Maintainer)
98 98
  LIST(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
99 99
  SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
100 100
      "Add the configurations that we need"
101 101
      FORCE)
102 102
 endif()
103 103

	
104 104
IF(NOT CMAKE_BUILD_TYPE)
105 105
  SET(CMAKE_BUILD_TYPE "Release")
106 106
ENDIF()
107 107

	
108 108
SET( CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
109 109
    "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel Maintainer."
110 110
    FORCE )
111 111

	
112 112

	
113 113
INCLUDE(CheckTypeSize)
114 114
CHECK_TYPE_SIZE("long long" LONG_LONG)
115 115
SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
116 116

	
117
INCLUDE(FindPythonInterp)
118

	
117 119
ENABLE_TESTING()
118 120

	
119 121
IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
120 122
  ADD_CUSTOM_TARGET(check ALL COMMAND ${CMAKE_CTEST_COMMAND})
121 123
ELSE()
122 124
  ADD_CUSTOM_TARGET(check COMMAND ${CMAKE_CTEST_COMMAND})
123 125
ENDIF()
124 126

	
125 127
ADD_SUBDIRECTORY(lemon)
126 128
IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
127 129
  ADD_SUBDIRECTORY(demo)
128 130
  ADD_SUBDIRECTORY(tools)
129 131
  ADD_SUBDIRECTORY(doc)
130 132
  ADD_SUBDIRECTORY(test)
131 133
ENDIF()
132 134

	
133 135
CONFIGURE_FILE(
134 136
  ${PROJECT_SOURCE_DIR}/cmake/LEMONConfig.cmake.in
135 137
  ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
136 138
  @ONLY
137 139
)
138 140
IF(UNIX)
139 141
  INSTALL(
140 142
    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
141 143
    DESTINATION share/lemon/cmake
142 144
  )
143 145
ELSEIF(WIN32)
144 146
  INSTALL(
145 147
    FILES ${PROJECT_BINARY_DIR}/cmake/LEMONConfig.cmake
146 148
    DESTINATION cmake
147 149
  )
148 150
ENDIF()
149 151

	
150 152
IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
151 153
  SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
152 154
  SET(CPACK_PACKAGE_VENDOR "EGRES")
153 155
  SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
154 156
    "LEMON - Library for Efficient Modeling and Optimization in Networks")
155 157
  SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
156 158

	
157 159
  SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
158 160

	
159 161
  SET(CPACK_PACKAGE_INSTALL_DIRECTORY
160 162
    "${PROJECT_NAME} ${PROJECT_VERSION}")
161 163
  SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
162 164
    "${PROJECT_NAME} ${PROJECT_VERSION}")
163 165

	
164 166
  SET(CPACK_COMPONENTS_ALL headers library html_documentation bin)
165 167

	
166 168
  SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
167 169
  SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
168 170
  SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities")
169 171
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
170 172

	
171 173
  SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
172 174
    "C++ header files")
173 175
  SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
174 176
    "DLL and import library")
175 177
  SET(CPACK_COMPONENT_BIN_DESCRIPTION
176 178
    "Command line utilities")
177 179
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
178 180
    "Doxygen generated documentation")
179 181

	
180 182
  SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
181 183

	
182 184
  SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
183 185
  SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
184 186
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
185 187

	
186 188
  SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
187 189
    "Components needed to develop software using LEMON")
188 190
  SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
189 191
    "Documentation of LEMON")
190 192

	
191 193
  SET(CPACK_ALL_INSTALL_TYPES Full Developer)
192 194

	
193 195
  SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
194 196
  SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
195 197
  SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
196 198

	
197 199
  SET(CPACK_GENERATOR "NSIS")
198 200
  SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis/lemon.ico")
199 201
  SET(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/cmake/nsis/uninstall.ico")
200 202
  #SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
201 203
  SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
202 204
  SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
203 205
  SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
204 206
  SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lemon.cs.elte.hu")
205 207
  SET(CPACK_NSIS_CONTACT "lemon-user@lemon.cs.elte.hu")
206 208
  SET(CPACK_NSIS_CREATE_ICONS_EXTRA "
207 209
    CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\share\\\\doc\\\\index.html\\\"
208 210
    ")
209 211
  SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
210 212
    !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
211 213
    Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Documentation.lnk\\\"
212 214
    ")
213 215

	
214 216
  INCLUDE(CPack)
215 217
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 30
      file. It also compiles the programs in the tools subdirectory by
31 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 78
--enable-tools
79 79

	
80 80
   Build the programs in the tools subdirectory (default).
81 81

	
82 82
--disable-tools
83 83

	
84 84
   Do not build the programs in the tools subdirectory.
85 85

	
86 86
--with-glpk[=PREFIX]
87 87

	
88 88
   Enable GLPK support (default). You should specify the prefix too if
89 89
   you installed GLPK to some non-standard location (e.g. your home
90 90
   directory). If it is not found, GLPK support will be disabled.
91 91

	
92 92
--with-glpk-includedir=DIR
93 93

	
94 94
   The directory where the GLPK header files are located. This is only
95 95
   useful when the GLPK headers and libraries are not under the same
96 96
   prefix (which is unlikely).
97 97

	
98 98
--with-glpk-libdir=DIR
99 99

	
100 100
   The directory where the GLPK libraries are located. This is only
101 101
   useful when the GLPK headers and libraries are not under the same
102 102
   prefix (which is unlikely).
103 103

	
104 104
--without-glpk
105 105

	
106 106
   Disable GLPK support.
107 107

	
108 108
--with-cplex[=PREFIX]
109 109

	
110 110
   Enable CPLEX support (default). You should specify the prefix too
111 111
   if you installed CPLEX to some non-standard location
112 112
   (e.g. /opt/ilog/cplex75). If it is not found, CPLEX support will be
113 113
   disabled.
114 114

	
115 115
--with-cplex-includedir=DIR
116 116

	
117 117
   The directory where the CPLEX header files are located. This is
118 118
   only useful when the CPLEX headers and libraries are not under the
119 119
   same prefix (e.g.  /usr/local/cplex/cplex75/include).
120 120

	
121 121
--with-cplex-libdir=DIR
122 122

	
123 123
   The directory where the CPLEX libraries are located. This is only
124 124
   useful when the CPLEX headers and libraries are not under the same
125 125
   prefix (e.g.
126 126
   /usr/local/cplex/cplex75/lib/i86_linux2_glibc2.2_gcc3.0/static_pic_mt).
127 127

	
128 128
--without-cplex
129 129

	
130 130
   Disable CPLEX support.
131 131

	
132 132
--with-soplex[=PREFIX]
133 133

	
134 134
   Enable SoPlex support (default). You should specify the prefix too if
135 135
   you installed SoPlex to some non-standard location (e.g. your home
136 136
   directory). If it is not found, SoPlex support will be disabled.
137 137

	
138 138
--with-soplex-includedir=DIR
139 139

	
140 140
   The directory where the SoPlex header files are located. This is only
141 141
   useful when the SoPlex headers and libraries are not under the same
142 142
   prefix (which is unlikely).
143 143

	
144 144
--with-soplex-libdir=DIR
145 145

	
146 146
   The directory where the SoPlex libraries are located. This is only
147 147
   useful when the SoPlex headers and libraries are not under the same
148 148
   prefix (which is unlikely).
149 149

	
150 150
--without-soplex
151 151

	
152 152
   Disable SoPlex support.
153 153

	
154 154
--with-coin[=PREFIX]
155 155

	
156 156
   Enable support for COIN-OR solvers (CLP and CBC). You should
157 157
   specify the prefix too. (by default, COIN-OR tools install
158 158
   themselves to the source code directory). This command enables the
159 159
   solvers that are actually found.
160 160

	
161 161
--with-coin-includedir=DIR
162 162

	
163 163
   The directory where the COIN-OR header files are located. This is
164 164
   only useful when the COIN-OR headers and libraries are not under
165 165
   the same prefix (which is unlikely).
166 166

	
167 167
--with-coin-libdir=DIR
168 168

	
169 169
   The directory where the COIN-OR libraries are located. This is only
170 170
   useful when the COIN-OR headers and libraries are not under the
171 171
   same prefix (which is unlikely).
172 172

	
173 173
--without-coin
174 174

	
175 175
   Disable COIN-OR support.
176

	
177

	
178
Makefile Variables
179
==================
180

	
181
Some Makefile variables are reserved by the GNU Coding Standards for
182
the use of the "user" - the person building the package. For instance,
183
CXX and CXXFLAGS are such variables, and have the same meaning as
184
explained in the previous section. These variables can be set on the
185
command line when invoking `make' like this:
186
`make [VARIABLE=VALUE]...'
187

	
188
WARNINGCXXFLAGS is a non-standard Makefile variable introduced by us
189
to hold several compiler flags related to warnings. Its default value
190
can be overridden when invoking `make'. For example to disable all
191
warning flags use `make WARNINGCXXFLAGS='.
192

	
193
In order to turn off a single flag from the default set of warning
194
flags, you can use the CXXFLAGS variable, since this is passed after
195
WARNINGCXXFLAGS. For example to turn off `-Wold-style-cast' (which is
196
used by default when g++ is detected) you can use
197
`make CXXFLAGS="-g -O2 -Wno-old-style-cast"'.
Ignore white space 6 line context
1 1
ACLOCAL_AMFLAGS = -I m4
2 2

	
3 3
AM_CXXFLAGS = $(WARNINGCXXFLAGS)
4 4

	
5 5
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_builddir)
6 6
LDADD = $(top_builddir)/lemon/libemon.la
7 7

	
8 8
EXTRA_DIST = \
9 9
	AUTHORS \
10 10
	LICENSE \
11 11
	m4/lx_check_cplex.m4 \
12 12
	m4/lx_check_glpk.m4 \
13 13
	m4/lx_check_soplex.m4 \
14 14
	m4/lx_check_coin.m4 \
15 15
	CMakeLists.txt \
16 16
	cmake/FindGhostscript.cmake \
17 17
	cmake/FindCPLEX.cmake \
18 18
	cmake/FindGLPK.cmake \
19 19
	cmake/FindCOIN.cmake \
20 20
	cmake/LEMONConfig.cmake.in \
21 21
	cmake/version.cmake.in \
22 22
	cmake/version.cmake \
23 23
	cmake/nsis/lemon.ico \
24 24
	cmake/nsis/uninstall.ico
25 25

	
26 26
pkgconfigdir = $(libdir)/pkgconfig
27 27
lemondir = $(pkgincludedir)
28 28
bitsdir = $(lemondir)/bits
29 29
conceptdir = $(lemondir)/concepts
30 30
pkgconfig_DATA =
31 31
lib_LTLIBRARIES =
32 32
lemon_HEADERS =
33 33
bits_HEADERS =
34 34
concept_HEADERS =
35 35
noinst_HEADERS =
36 36
noinst_PROGRAMS =
37 37
bin_PROGRAMS =
38 38
check_PROGRAMS =
39 39
dist_bin_SCRIPTS =
40 40
TESTS =
41 41
XFAIL_TESTS =
42 42

	
43 43
include lemon/Makefile.am
44 44
include test/Makefile.am
45 45
include doc/Makefile.am
46 46
include tools/Makefile.am
47
include scripts/Makefile.am
47 48

	
48 49
DIST_SUBDIRS = demo
49 50

	
50 51
demo:
51 52
	$(MAKE) $(AM_MAKEFLAGS) -C demo
52 53

	
53 54
MRPROPERFILES = \
54 55
	aclocal.m4 \
55 56
	config.h.in \
56 57
	config.h.in~ \
57 58
	configure \
58 59
	Makefile.in \
59 60
	build-aux/config.guess \
60 61
	build-aux/config.sub \
61 62
	build-aux/depcomp \
62 63
	build-aux/install-sh \
63 64
	build-aux/ltmain.sh \
64 65
	build-aux/missing \
65 66
	doc/doxygen.log
66 67

	
67 68
mrproper:
68 69
	$(MAKE) $(AM_MAKEFLAGS) maintainer-clean
69 70
	-rm -f $(MRPROPERFILES)
70 71

	
71 72
dist-bz2: dist
72 73
	zcat $(PACKAGE)-$(VERSION).tar.gz | \
73 74
	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
74 75

	
75 76
distcheck-bz2: distcheck
76 77
	zcat $(PACKAGE)-$(VERSION).tar.gz | \
77 78
	bzip2 --best -c > $(PACKAGE)-$(VERSION).tar.bz2
78 79

	
79 80
.PHONY: demo mrproper dist-bz2 distcheck-bz2
Ignore white space 6 line context
1 1
=====================================================================
2 2
LEMON - a Library for Efficient Modeling and Optimization in Networks
3 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
NEWS
21

	
22
   News and version history.
23

	
20 24
INSTALL
21 25

	
22 26
   General building and installation instructions.
23 27

	
24 28
lemon/
25 29

	
26 30
   Source code of LEMON library.
27 31

	
28 32
doc/
29 33

	
30 34
   Documentation of LEMON. The starting page is doc/html/index.html.
31 35

	
32 36
demo/
33 37

	
34 38
   Some example programs to make you easier to get familiar with LEMON.
35 39

	
40
scripts/
41

	
42
   Scripts that make it easier to develop LEMON.
43

	
36 44
test/
37 45

	
38 46
   Programs to check the integrity and correctness of LEMON.
39 47

	
40 48
tools/
41 49

	
42 50
   Various utilities related to LEMON.
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 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 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 10
                           [],
11 11
                           [ifelse(lemon_hg_revision(),
12 12
                           [],
13 13
                           [hg-tip],
14 14
                           [lemon_hg_path().lemon_hg_revision()])],
15 15
                           [lemon_version_number()])])
16 16

	
17 17
AC_PREREQ([2.59])
18 18
AC_INIT([LEMON], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
19 19
AC_CONFIG_AUX_DIR([build-aux])
20 20
AC_CONFIG_MACRO_DIR([m4])
21 21
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects nostdinc])
22 22
AC_CONFIG_SRCDIR([lemon/list_graph.h])
23 23
AC_CONFIG_HEADERS([config.h lemon/config.h])
24 24

	
25 25
AC_DEFINE([LEMON_VERSION], [lemon_version()], [The version string])
26 26

	
27 27
dnl Do compilation tests using the C++ compiler.
28 28
AC_LANG([C++])
29 29

	
30 30
dnl Check the existence of long long type.
31 31
AC_CHECK_TYPE(long long, [long_long_found=yes], [long_long_found=no])
32 32
if test x"$long_long_found" = x"yes"; then
33 33
  AC_DEFINE([LEMON_HAVE_LONG_LONG], [1], [Define to 1 if you have long long.])
34 34
fi
35 35

	
36 36
dnl Checks for programs.
37 37
AC_PROG_CXX
38 38
AC_PROG_CXXCPP
39 39
AC_PROG_INSTALL
40 40
AC_DISABLE_SHARED
41 41
AC_PROG_LIBTOOL
42 42

	
43 43
AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
44
AC_CHECK_PROG([python_found],[python],[yes],[no])
44 45
AC_CHECK_PROG([gs_found],[gs],[yes],[no])
45 46

	
46 47
dnl Detect Intel compiler.
47 48
AC_MSG_CHECKING([whether we are using the Intel C++ compiler])
48 49
AC_COMPILE_IFELSE([#ifndef __INTEL_COMPILER
49 50
choke me
50 51
#endif], [ICC=[yes]], [ICC=[no]])
51 52
if test x"$ICC" = x"yes"; then
52 53
  AC_MSG_RESULT([yes])
53 54
else
54 55
  AC_MSG_RESULT([no])
55 56
fi
56 57

	
57 58
dnl Set custom compiler flags when using g++.
58 59
if test "$GXX" = yes -a "$ICC" = no; then
59 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"
60 61
fi
61 62
AC_SUBST([WARNINGCXXFLAGS])
62 63

	
63 64
dnl Checks for libraries.
64 65
LX_CHECK_GLPK
65 66
LX_CHECK_CPLEX
66 67
LX_CHECK_SOPLEX
67 68
LX_CHECK_COIN
68 69

	
69 70
AM_CONDITIONAL([HAVE_LP], [test x"$lx_lp_found" = x"yes"])
70 71
AM_CONDITIONAL([HAVE_MIP], [test x"$lx_mip_found" = x"yes"])
71 72

	
72 73
dnl Disable/enable building the binary tools.
73 74
AC_ARG_ENABLE([tools],
74 75
AS_HELP_STRING([--enable-tools], [build additional tools @<:@default@:>@])
75 76
AS_HELP_STRING([--disable-tools], [do not build additional tools]),
76 77
              [], [enable_tools=yes])
77 78
AC_MSG_CHECKING([whether to build the additional tools])
78 79
if test x"$enable_tools" != x"no"; then
79 80
  AC_MSG_RESULT([yes])
80 81
else
81 82
  AC_MSG_RESULT([no])
82 83
fi
83 84
AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
84 85

	
86
dnl Support for running test cases using valgrind.
87
use_valgrind=no
88
AC_ARG_ENABLE([valgrind],
89
AS_HELP_STRING([--enable-valgrind], [use valgrind when running tests]),
90
              [use_valgrind=yes])
91

	
92
if [[ "$use_valgrind" = "yes" ]]; then
93
  AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
94

	
95
  if [[ "$HAVE_VALGRIND" = "no" ]]; then
96
    AC_MSG_ERROR([Valgrind not found in PATH.])
97
  fi
98
fi
99
AM_CONDITIONAL(USE_VALGRIND, [test "$use_valgrind" = "yes"])
100

	
85 101
dnl Checks for header files.
86 102
AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
87 103

	
88 104
dnl Checks for typedefs, structures, and compiler characteristics.
89 105
AC_C_CONST
90 106
AC_C_INLINE
91 107
AC_TYPE_SIZE_T
92 108
AC_HEADER_TIME
93 109
AC_STRUCT_TM
94 110

	
95 111
dnl Checks for library functions.
96 112
AC_HEADER_STDC
97 113
AC_CHECK_FUNCS(gettimeofday times ctime_r)
98 114

	
99 115
dnl Add dependencies on files generated by configure.
100 116
AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
101 117
  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/doc/mainpage.dox.in $(top_srcdir)/lemon/lemon.pc.in $(top_srcdir)/cmake/version.cmake.in'])
102 118

	
103 119
AC_CONFIG_FILES([
104 120
Makefile
105 121
demo/Makefile
106 122
cmake/version.cmake
107 123
doc/Doxyfile
108 124
doc/mainpage.dox
109 125
lemon/lemon.pc
110 126
])
111 127

	
112 128
AC_OUTPUT
113 129

	
114 130
echo
115 131
echo '****************************** SUMMARY ******************************'
116 132
echo
117 133
echo Package version............... : $PACKAGE-$VERSION
118 134
echo
119 135
echo C++ compiler.................. : $CXX
120 136
echo C++ compiles flags............ : $WARNINGCXXFLAGS $CXXFLAGS
121 137
echo
122 138
echo Compiler supports long long... : $long_long_found
123 139
echo
124 140
echo GLPK support.................. : $lx_glpk_found
125 141
echo CPLEX support................. : $lx_cplex_found
126 142
echo SOPLEX support................ : $lx_soplex_found
127 143
echo CLP support................... : $lx_clp_found
128 144
echo CBC support................... : $lx_cbc_found
129 145
echo
130 146
echo Build additional tools........ : $enable_tools
147
echo Use valgrind for tests........ : $use_valgrind
131 148
echo
132 149
echo The packace will be installed in
133 150
echo -n '  '
134 151
echo $prefix.
135 152
echo
136 153
echo '*********************************************************************'
137 154

	
138 155
echo
139 156
echo Configure complete, now type \'make\' and then \'make install\'.
140 157
echo
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-2009
5
 * Copyright (C) 2003-2010
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
  // Throw an exception when problems occurs. The default behavior is to
69
  // exit(1) on these cases, but this makes Valgrind falsely warn
70
  // about memory leaks.
71
  ap.throwOnProblems();
72

	
68 73
  // Perform the parsing process
69 74
  // (in case of any error it terminates the program)
70
  ap.parse();
75
  // The try {} construct is necessary only if the ap.trowOnProblems()
76
  // setting is in use.
77
  try {
78
    ap.parse();
79
  } catch (ArgParserException &) { return 1; }
71 80

	
72 81
  // Check each option if it has been given and print its value
73 82
  std::cout << "Parameters of '" << ap.commandName() << "':\n";
74 83

	
75 84
  std::cout << "  Value of -n: " << i << std::endl;
76 85
  if(ap.given("val")) std::cout << "  Value of -val: " << d << std::endl;
77 86
  if(ap.given("val2")) {
78 87
    d = ap["val2"];
79 88
    std::cout << "  Value of -val2: " << d << std::endl;
80 89
  }
81 90
  if(ap.given("name")) std::cout << "  Value of -name: " << s << std::endl;
82 91
  if(ap.given("f")) std::cout << "  -f is given\n";
83 92
  if(ap.given("nohelp")) std::cout << "  Value of -nohelp: " << nh << std::endl;
84 93
  if(ap.given("gra")) std::cout << "  -gra is given\n";
85 94
  if(ap.given("grb")) std::cout << "  -grb is given\n";
86 95
  if(ap.given("grc")) std::cout << "  -grc is given\n";
87 96

	
88 97
  switch(ap.files().size()) {
89 98
  case 0:
90 99
    std::cout << "  No file argument was given.\n";
91 100
    break;
92 101
  case 1:
93 102
    std::cout << "  1 file argument was given. It is:\n";
94 103
    break;
95 104
  default:
96 105
    std::cout << "  "
97 106
              << ap.files().size() << " file arguments were given. They are:\n";
98 107
  }
99 108
  for(unsigned int i=0;i<ap.files().size();++i)
100 109
    std::cout << "    '" << ap.files()[i] << "'\n";
101 110

	
102 111
  return 0;
103 112
}
Ignore white space 6 line context
1 1
SET(PACKAGE_NAME ${PROJECT_NAME})
2 2
SET(PACKAGE_VERSION ${PROJECT_VERSION})
3 3
SET(abs_top_srcdir ${PROJECT_SOURCE_DIR})
4 4
SET(abs_top_builddir ${PROJECT_BINARY_DIR})
5 5

	
6 6
SET(LEMON_DOC_SOURCE_BROWSER "NO" CACHE STRING "Include source into the doc (YES/NO).")
7 7

	
8 8
CONFIGURE_FILE(
9 9
  ${PROJECT_SOURCE_DIR}/doc/Doxyfile.in
10 10
  ${PROJECT_BINARY_DIR}/doc/Doxyfile
11 11
  @ONLY
12 12
)
13 13

	
14 14
CONFIGURE_FILE(
15 15
  ${PROJECT_SOURCE_DIR}/doc/mainpage.dox.in
16 16
  ${PROJECT_BINARY_DIR}/doc/mainpage.dox
17 17
  @ONLY
18 18
)
19 19

	
20
IF(DOXYGEN_EXECUTABLE AND GHOSTSCRIPT_EXECUTABLE)
20
IF(DOXYGEN_EXECUTABLE AND PYTHONINTERP_FOUND AND GHOSTSCRIPT_EXECUTABLE)
21 21
  FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/)
22 22
  SET(GHOSTSCRIPT_OPTIONS -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=pngalpha)
23 23
  ADD_CUSTOM_TARGET(html
24 24
    COMMAND ${CMAKE_COMMAND} -E remove_directory gen-images
25 25
    COMMAND ${CMAKE_COMMAND} -E make_directory gen-images
26 26
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_matching.eps
27 27
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/bipartite_partitions.png ${CMAKE_CURRENT_SOURCE_DIR}/images/bipartite_partitions.eps
28 28
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/connected_components.eps
29 29
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/edge_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/edge_biconnected_components.eps
30 30
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/grid_graph.png ${CMAKE_CURRENT_SOURCE_DIR}/images/grid_graph.eps
31
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/matching.png ${CMAKE_CURRENT_SOURCE_DIR}/images/matching.eps
31 32
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/node_biconnected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/node_biconnected_components.eps
32 33
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_0.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_0.eps
33 34
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_1.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_1.eps
34 35
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_2.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_2.eps
35 36
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_3.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_3.eps
36 37
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/nodeshape_4.png ${CMAKE_CURRENT_SOURCE_DIR}/images/nodeshape_4.eps
38
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/planar.png ${CMAKE_CURRENT_SOURCE_DIR}/images/planar.eps
37 39
    COMMAND ${GHOSTSCRIPT_EXECUTABLE} ${GHOSTSCRIPT_OPTIONS} -r18 -sOutputFile=gen-images/strongly_connected_components.png ${CMAKE_CURRENT_SOURCE_DIR}/images/strongly_connected_components.eps
38 40
    COMMAND ${CMAKE_COMMAND} -E remove_directory html
41
    COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/bib2dox.py ${CMAKE_CURRENT_SOURCE_DIR}/references.bib >references.dox
39 42
    COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
40 43
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
41 44
  )
42 45

	
43 46
  SET_TARGET_PROPERTIES(html PROPERTIES PROJECT_LABEL BUILD_DOC)
44 47

	
45 48
  IF(UNIX)
46 49
    INSTALL(
47 50
      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
48 51
      DESTINATION share/doc/lemon/html
49 52
      COMPONENT html_documentation
50 53
    )
51 54
  ELSEIF(WIN32)
52 55
    INSTALL(
53 56
      DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/
54 57
      DESTINATION doc
55 58
      COMPONENT html_documentation
56 59
    )
57 60
  ENDIF()
58 61

	
59 62
ENDIF()
60 63

	
61 64
IF(WGET_FOUND)
62 65
ADD_CUSTOM_TARGET(update-external-tags
63 66
  COMMAND ${CMAKE_COMMAND} -E make_directory dl
64 67
  # COMMAND ${CMAKE_COMMAND} -E copy libstdc++.tag dl
65 68
  COMMAND ${WGET_EXECUTABLE} wget -P dl -N libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag
66 69
  COMMAND ${CMAKE_COMMAND} -E rename dl/libstdc++.tag libstdc++.tag
67 70
  COMMAND ${CMAKE_COMMAND} -E remove dl/libstdc++.tag
68 71
  COMMAND ${CMAKE_COMMAND} -E remove_directory dl
69 72
  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
70 73
  )
71 74
ENDIF()
Ignore white space 6 line context
1 1
# Doxyfile 1.7.3
2 2

	
3 3
#---------------------------------------------------------------------------
4 4
# Project related configuration options
5 5
#---------------------------------------------------------------------------
6 6
DOXYFILE_ENCODING      = UTF-8
7 7
PROJECT_NAME           = 
8 8
PROJECT_NUMBER         = 
9 9
PROJECT_BRIEF          =
10 10
PROJECT_LOGO           =
11 11
OUTPUT_DIRECTORY       = 
12 12
CREATE_SUBDIRS         = NO
13 13
OUTPUT_LANGUAGE        = English
14 14
BRIEF_MEMBER_DESC      = YES
15 15
REPEAT_BRIEF           = NO
16 16
ABBREVIATE_BRIEF       = 
17 17
ALWAYS_DETAILED_SEC    = NO
18 18
INLINE_INHERITED_MEMB  = NO
19 19
FULL_PATH_NAMES        = YES
20 20
STRIP_FROM_PATH        = "@abs_top_srcdir@"
21 21
STRIP_FROM_INC_PATH    = "@abs_top_srcdir@"
22 22
SHORT_NAMES            = YES
23 23
JAVADOC_AUTOBRIEF      = NO
24 24
QT_AUTOBRIEF           = NO
25 25
MULTILINE_CPP_IS_BRIEF = NO
26 26
INHERIT_DOCS           = NO
27 27
SEPARATE_MEMBER_PAGES  = NO
28 28
TAB_SIZE               = 8
29 29
ALIASES                = 
30 30
OPTIMIZE_OUTPUT_FOR_C  = NO
31 31
OPTIMIZE_OUTPUT_JAVA   = NO
32 32
OPTIMIZE_FOR_FORTRAN   = NO
33 33
OPTIMIZE_OUTPUT_VHDL   = NO
34 34
EXTENSION_MAPPING      =
35 35
BUILTIN_STL_SUPPORT    = YES
36 36
CPP_CLI_SUPPORT        = NO
37 37
SIP_SUPPORT            = NO
38 38
IDL_PROPERTY_SUPPORT   = YES
39 39
DISTRIBUTE_GROUP_DOC   = NO
40 40
SUBGROUPING            = YES
41 41
TYPEDEF_HIDES_STRUCT   = NO
42 42
SYMBOL_CACHE_SIZE      = 0
43 43
#---------------------------------------------------------------------------
44 44
# Build related configuration options
45 45
#---------------------------------------------------------------------------
46 46
EXTRACT_ALL            = NO
47 47
EXTRACT_PRIVATE        = YES
48 48
EXTRACT_STATIC         = YES
49 49
EXTRACT_LOCAL_CLASSES  = NO
50 50
EXTRACT_LOCAL_METHODS  = NO
51 51
EXTRACT_ANON_NSPACES   = NO
52 52
HIDE_UNDOC_MEMBERS     = YES
53 53
HIDE_UNDOC_CLASSES     = YES
54 54
HIDE_FRIEND_COMPOUNDS  = NO
55 55
HIDE_IN_BODY_DOCS      = NO
56 56
INTERNAL_DOCS          = NO
57 57
CASE_SENSE_NAMES       = YES
58 58
HIDE_SCOPE_NAMES       = YES
59 59
SHOW_INCLUDE_FILES     = YES
60 60
FORCE_LOCAL_INCLUDES   = NO
61 61
INLINE_INFO            = YES
62 62
SORT_MEMBER_DOCS       = NO
63 63
SORT_BRIEF_DOCS        = NO
64 64
SORT_MEMBERS_CTORS_1ST = NO
65 65
SORT_GROUP_NAMES       = NO
66 66
SORT_BY_SCOPE_NAME     = NO
67 67
STRICT_PROTO_MATCHING  = NO
68 68
GENERATE_TODOLIST      = YES
69 69
GENERATE_TESTLIST      = YES
70 70
GENERATE_BUGLIST       = YES
71 71
GENERATE_DEPRECATEDLIST= YES
72 72
ENABLED_SECTIONS       = 
73 73
MAX_INITIALIZER_LINES  = 5
74 74
SHOW_USED_FILES        = NO
75 75
SHOW_DIRECTORIES       = YES
76 76
SHOW_FILES             = YES
77 77
SHOW_NAMESPACES        = YES
78 78
FILE_VERSION_FILTER    = 
79 79
LAYOUT_FILE            = "@abs_top_srcdir@/doc/DoxygenLayout.xml"
80 80
#---------------------------------------------------------------------------
81 81
# configuration options related to warning and progress messages
82 82
#---------------------------------------------------------------------------
83 83
QUIET                  = NO
84 84
WARNINGS               = YES
85 85
WARN_IF_UNDOCUMENTED   = YES
86 86
WARN_IF_DOC_ERROR      = YES
87 87
WARN_NO_PARAMDOC       = NO
88 88
WARN_FORMAT            = "$file:$line: $text"
89 89
WARN_LOGFILE           = doxygen.log
90 90
#---------------------------------------------------------------------------
91 91
# configuration options related to the input files
92 92
#---------------------------------------------------------------------------
93 93
INPUT                  = "@abs_top_srcdir@/doc" \
94 94
                         "@abs_top_srcdir@/lemon" \
95 95
                         "@abs_top_srcdir@/lemon/bits" \
96 96
                         "@abs_top_srcdir@/lemon/concepts" \
97 97
                         "@abs_top_srcdir@/demo" \
98 98
                         "@abs_top_srcdir@/tools" \
99 99
                         "@abs_top_srcdir@/test/test_tools.h" \
100
                         "@abs_top_builddir@/doc/mainpage.dox"
100
                         "@abs_top_builddir@/doc/mainpage.dox" \
101
                         "@abs_top_builddir@/doc/references.dox"
101 102
INPUT_ENCODING         = UTF-8
102 103
FILE_PATTERNS          = *.h \
103 104
                         *.cc \
104 105
                         *.dox
105 106
RECURSIVE              = NO
106 107
EXCLUDE                = 
107 108
EXCLUDE_SYMLINKS       = NO
108 109
EXCLUDE_PATTERNS       = 
109 110
EXCLUDE_SYMBOLS        = 
110 111
EXAMPLE_PATH           = "@abs_top_srcdir@/demo" \
111 112
                         "@abs_top_srcdir@/LICENSE" \
112 113
                         "@abs_top_srcdir@/doc"
113 114
EXAMPLE_PATTERNS       = 
114 115
EXAMPLE_RECURSIVE      = NO
115 116
IMAGE_PATH             = "@abs_top_srcdir@/doc/images" \
116 117
                         "@abs_top_builddir@/doc/gen-images"
117 118
INPUT_FILTER           = 
118 119
FILTER_PATTERNS        = 
119 120
FILTER_SOURCE_FILES    = NO
120 121
FILTER_SOURCE_PATTERNS =
121 122
#---------------------------------------------------------------------------
122 123
# configuration options related to source browsing
123 124
#---------------------------------------------------------------------------
124 125
SOURCE_BROWSER         = @LEMON_DOC_SOURCE_BROWSER@
125 126
INLINE_SOURCES         = NO
126 127
STRIP_CODE_COMMENTS    = YES
127 128
REFERENCED_BY_RELATION = NO
128 129
REFERENCES_RELATION    = NO
129 130
REFERENCES_LINK_SOURCE = YES
130 131
USE_HTAGS              = NO
131 132
VERBATIM_HEADERS       = NO
132 133
#---------------------------------------------------------------------------
133 134
# configuration options related to the alphabetical class index
134 135
#---------------------------------------------------------------------------
135 136
ALPHABETICAL_INDEX     = YES
136 137
COLS_IN_ALPHA_INDEX    = 2
137 138
IGNORE_PREFIX          = 
138 139
#---------------------------------------------------------------------------
139 140
# configuration options related to the HTML output
140 141
#---------------------------------------------------------------------------
141 142
GENERATE_HTML          = YES
142 143
HTML_OUTPUT            = html
143 144
HTML_FILE_EXTENSION    = .html
144 145
HTML_HEADER            = 
145 146
HTML_FOOTER            = 
146 147
HTML_STYLESHEET        = 
147 148
HTML_COLORSTYLE_HUE    = 220
148 149
HTML_COLORSTYLE_SAT    = 100
149 150
HTML_COLORSTYLE_GAMMA  = 80
150 151
HTML_TIMESTAMP         = YES
151 152
HTML_ALIGN_MEMBERS     = YES
152 153
HTML_DYNAMIC_SECTIONS  = YES
153 154
GENERATE_DOCSET        = NO
154 155
DOCSET_FEEDNAME        = "Doxygen generated docs"
155 156
DOCSET_BUNDLE_ID       = org.doxygen.Project
156 157
DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
157 158
DOCSET_PUBLISHER_NAME  = Publisher
158 159
GENERATE_HTMLHELP      = NO
159 160
CHM_FILE               = 
160 161
HHC_LOCATION           = 
161 162
GENERATE_CHI           = NO
162 163
CHM_INDEX_ENCODING     = 
163 164
BINARY_TOC             = NO
164 165
TOC_EXPAND             = NO
165 166
GENERATE_QHP           = NO
166 167
QCH_FILE               = 
167 168
QHP_NAMESPACE          = org.doxygen.Project
168 169
QHP_VIRTUAL_FOLDER     = doc
169 170
QHP_CUST_FILTER_NAME   =
170 171
QHP_CUST_FILTER_ATTRS  =
171 172
QHP_SECT_FILTER_ATTRS  =
172 173
QHG_LOCATION           = 
173 174
GENERATE_ECLIPSEHELP   = NO
174 175
ECLIPSE_DOC_ID         = org.doxygen.Project
175 176
DISABLE_INDEX          = NO
176 177
ENUM_VALUES_PER_LINE   = 4
177 178
GENERATE_TREEVIEW      = NO
178 179
USE_INLINE_TREES       = NO
179 180
TREEVIEW_WIDTH         = 250
180 181
EXT_LINKS_IN_WINDOW    = NO
181 182
FORMULA_FONTSIZE       = 10
182 183
FORMULA_TRANSPARENT    = YES
183 184
USE_MATHJAX            = NO
184 185
MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
185 186
SEARCHENGINE           = YES
186 187
SERVER_BASED_SEARCH    = NO
187 188
#---------------------------------------------------------------------------
188 189
# configuration options related to the LaTeX output
189 190
#---------------------------------------------------------------------------
190 191
GENERATE_LATEX         = NO
191 192
LATEX_OUTPUT           = latex
192 193
LATEX_CMD_NAME         = latex
193 194
MAKEINDEX_CMD_NAME     = makeindex
194 195
COMPACT_LATEX          = YES
195 196
PAPER_TYPE             = a4wide
196 197
EXTRA_PACKAGES         = amsmath \
197 198
                         amssymb
198 199
LATEX_HEADER           = 
199 200
PDF_HYPERLINKS         = YES
200 201
USE_PDFLATEX           = YES
201 202
LATEX_BATCHMODE        = NO
202 203
LATEX_HIDE_INDICES     = NO
203 204
LATEX_SOURCE_CODE      = NO
204 205
#---------------------------------------------------------------------------
205 206
# configuration options related to the RTF output
206 207
#---------------------------------------------------------------------------
207 208
GENERATE_RTF           = NO
208 209
RTF_OUTPUT             = rtf
209 210
COMPACT_RTF            = NO
210 211
RTF_HYPERLINKS         = NO
211 212
RTF_STYLESHEET_FILE    = 
212 213
RTF_EXTENSIONS_FILE    = 
213 214
#---------------------------------------------------------------------------
214 215
# configuration options related to the man page output
215 216
#---------------------------------------------------------------------------
216 217
GENERATE_MAN           = NO
217 218
MAN_OUTPUT             = man
218 219
MAN_EXTENSION          = .3
219 220
MAN_LINKS              = NO
220 221
#---------------------------------------------------------------------------
221 222
# configuration options related to the XML output
222 223
#---------------------------------------------------------------------------
223 224
GENERATE_XML           = NO
224 225
XML_OUTPUT             = xml
225 226
XML_SCHEMA             = 
226 227
XML_DTD                = 
227 228
XML_PROGRAMLISTING     = YES
228 229
#---------------------------------------------------------------------------
229 230
# configuration options for the AutoGen Definitions output
230 231
#---------------------------------------------------------------------------
231 232
GENERATE_AUTOGEN_DEF   = NO
232 233
#---------------------------------------------------------------------------
233 234
# configuration options related to the Perl module output
234 235
#---------------------------------------------------------------------------
235 236
GENERATE_PERLMOD       = NO
236 237
PERLMOD_LATEX          = NO
237 238
PERLMOD_PRETTY         = YES
238 239
PERLMOD_MAKEVAR_PREFIX = 
239 240
#---------------------------------------------------------------------------
240 241
# Configuration options related to the preprocessor   
241 242
#---------------------------------------------------------------------------
242 243
ENABLE_PREPROCESSING   = YES
243 244
MACRO_EXPANSION        = NO
244 245
EXPAND_ONLY_PREDEF     = NO
245 246
SEARCH_INCLUDES        = YES
246 247
INCLUDE_PATH           = 
247 248
INCLUDE_FILE_PATTERNS  = 
248 249
PREDEFINED             = DOXYGEN
249 250
EXPAND_AS_DEFINED      = 
250 251
SKIP_FUNCTION_MACROS   = YES
251 252
#---------------------------------------------------------------------------
252 253
# Configuration::additions related to external references
253 254
#---------------------------------------------------------------------------
254 255
TAGFILES               = "@abs_top_builddir@/doc/libstdc++.tag = http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/  "
255 256
GENERATE_TAGFILE       = html/lemon.tag
256 257
ALLEXTERNALS           = NO
257 258
EXTERNAL_GROUPS        = NO
258 259
PERL_PATH              = /usr/bin/perl
259 260
#---------------------------------------------------------------------------
260 261
# Configuration options related to the dot tool   
261 262
#---------------------------------------------------------------------------
262 263
CLASS_DIAGRAMS         = YES
263 264
MSCGEN_PATH            = 
264 265
HIDE_UNDOC_RELATIONS   = YES
265 266
HAVE_DOT               = YES
266 267
DOT_NUM_THREADS        = 0
267 268
DOT_FONTNAME           = FreeSans
268 269
DOT_FONTSIZE           = 10
269 270
DOT_FONTPATH           = 
270 271
CLASS_GRAPH            = YES
271 272
COLLABORATION_GRAPH    = NO
272 273
GROUP_GRAPHS           = NO
273 274
UML_LOOK               = NO
274 275
TEMPLATE_RELATIONS     = NO
275 276
INCLUDE_GRAPH          = NO
276 277
INCLUDED_BY_GRAPH      = NO
277 278
CALL_GRAPH             = NO
278 279
CALLER_GRAPH           = NO
279 280
GRAPHICAL_HIERARCHY    = NO
280 281
DIRECTORY_GRAPH        = NO
281 282
DOT_IMAGE_FORMAT       = png
282 283
DOT_PATH               = 
283 284
DOTFILE_DIRS           = 
284 285
MSCFILE_DIRS           =
285 286
DOT_GRAPH_MAX_NODES    = 50
286 287
MAX_DOT_GRAPH_DEPTH    = 0
287 288
DOT_TRANSPARENT        = NO
288 289
DOT_MULTI_TARGETS      = NO
289 290
GENERATE_LEGEND        = YES
290 291
DOT_CLEANUP            = YES
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 11
	doc/min_cost_flow.dox \
12 12
	doc/named-param.dox \
13 13
	doc/namespaces.dox \
14 14
	doc/html \
15 15
	doc/CMakeLists.txt
16 16

	
17 17
DOC_EPS_IMAGES18 = \
18 18
	grid_graph.eps \
19 19
	nodeshape_0.eps \
20 20
	nodeshape_1.eps \
21 21
	nodeshape_2.eps \
22 22
	nodeshape_3.eps \
23 23
	nodeshape_4.eps
24 24

	
25 25
DOC_EPS_IMAGES27 = \
26 26
	bipartite_matching.eps \
27 27
	bipartite_partitions.eps \
28 28
	connected_components.eps \
29 29
	edge_biconnected_components.eps \
30
	matching.eps \
30 31
	node_biconnected_components.eps \
32
	planar.eps \
31 33
	strongly_connected_components.eps
32 34

	
33 35
DOC_EPS_IMAGES = \
34 36
	$(DOC_EPS_IMAGES18) \
35 37
	$(DOC_EPS_IMAGES27)
36 38

	
37 39
DOC_PNG_IMAGES = \
38 40
	$(DOC_EPS_IMAGES:%.eps=doc/gen-images/%.png)
39 41

	
40 42
EXTRA_DIST += $(DOC_EPS_IMAGES:%=doc/images/%)
41 43

	
42 44
doc/html:
43 45
	$(MAKE) $(AM_MAKEFLAGS) html
44 46

	
45 47
GS_COMMAND=gs -dNOPAUSE -dBATCH -q -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4
46 48

	
47 49
$(DOC_EPS_IMAGES18:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
48 50
	-mkdir doc/gen-images
49 51
	if test ${gs_found} = yes; then \
50 52
	  $(GS_COMMAND) -sDEVICE=pngalpha -r18 -sOutputFile=$@ $<; \
51 53
	else \
52 54
	  echo; \
53 55
	  echo "Ghostscript not found."; \
54 56
	  echo; \
55 57
	  exit 1; \
56 58
	fi
57 59

	
58 60
$(DOC_EPS_IMAGES27:%.eps=doc/gen-images/%.png): doc/gen-images/%.png: doc/images/%.eps
59 61
	-mkdir doc/gen-images
60 62
	if test ${gs_found} = yes; then \
61 63
	  $(GS_COMMAND) -sDEVICE=pngalpha -r27 -sOutputFile=$@ $<; \
62 64
	else \
63 65
	  echo; \
64 66
	  echo "Ghostscript not found."; \
65 67
	  echo; \
66 68
	  exit 1; \
67 69
	fi
68 70

	
69
html-local: $(DOC_PNG_IMAGES)
71
references.dox: doc/references.bib
72
	if test ${python_found} = yes; then \
73
	  cd doc; \
74
	  python @abs_top_srcdir@/scripts/bib2dox.py @abs_top_builddir@/$< >$@; \
75
	  cd ..; \
76
	else \
77
	  echo; \
78
	  echo "Python not found."; \
79
	  echo; \
80
	  exit 1; \
81
	fi
82

	
83
html-local: $(DOC_PNG_IMAGES) references.dox
70 84
	if test ${doxygen_found} = yes; then \
71 85
	  cd doc; \
72 86
	  doxygen Doxyfile; \
73 87
	  cd ..; \
74 88
	else \
75 89
	  echo; \
76 90
	  echo "Doxygen not found."; \
77 91
	  echo; \
78 92
	  exit 1; \
79 93
	fi
80 94

	
81 95
clean-local:
82 96
	-rm -rf doc/html
83 97
	-rm -f doc/doxygen.log
84 98
	-rm -f $(DOC_PNG_IMAGES)
85 99
	-rm -rf doc/gen-images
86 100

	
87 101
update-external-tags:
88 102
	wget -O doc/libstdc++.tag.tmp http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag && \
89 103
	mv doc/libstdc++.tag.tmp doc/libstdc++.tag || \
90 104
	rm doc/libstdc++.tag.tmp
91 105

	
92 106
install-html-local: doc/html
93 107
	@$(NORMAL_INSTALL)
94 108
	$(mkinstalldirs) $(DESTDIR)$(htmldir)/html
95 109
	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
96 110
	  f="`echo $$p | sed -e 's|^.*/||'`"; \
97 111
	  echo " $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f"; \
98 112
	  $(INSTALL_DATA) $$p $(DESTDIR)$(htmldir)/html/$$f; \
99 113
	done
100 114

	
101 115
uninstall-local:
102 116
	@$(NORMAL_UNINSTALL)
103 117
	for p in doc/html/*.{html,css,png,map,gif,tag} ; do \
104 118
	  f="`echo $$p | sed -e 's|^.*/||'`"; \
105 119
	  echo " rm -f $(DESTDIR)$(htmldir)/html/$$f"; \
106 120
	  rm -f $(DESTDIR)$(htmldir)/html/$$f; \
107 121
	done
108 122

	
109 123
.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-2009
5
 * Copyright (C) 2003-2010
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
@defgroup datas Data Structures
23 23
This group contains the several data structures implemented in LEMON.
24 24
*/
25 25

	
26 26
/**
27 27
@defgroup graphs Graph Structures
28 28
@ingroup datas
29 29
\brief Graph structures implemented in LEMON.
30 30

	
31 31
The implementation of combinatorial algorithms heavily relies on
32 32
efficient graph implementations. LEMON offers data structures which are
33 33
planned to be easily used in an experimental phase of implementation studies,
34 34
and thereafter the program code can be made efficient by small modifications.
35 35

	
36 36
The most efficient implementation of diverse applications require the
37 37
usage of different physical graph implementations. These differences
38 38
appear in the size of graph we require to handle, memory or time usage
39 39
limitations or in the set of operations through which the graph can be
40 40
accessed.  LEMON provides several physical graph structures to meet
41 41
the diverging requirements of the possible users.  In order to save on
42 42
running time or on memory usage, some structures may fail to provide
43 43
some graph features like arc/edge or node deletion.
44 44

	
45 45
Alteration of standard containers need a very limited number of
46 46
operations, these together satisfy the everyday requirements.
47 47
In the case of graph structures, different operations are needed which do
48 48
not alter the physical graph, but gives another view. If some nodes or
49 49
arcs have to be hidden or the reverse oriented graph have to be used, then
50 50
this is the case. It also may happen that in a flow implementation
51 51
the residual graph can be accessed by another algorithm, or a node-set
52 52
is to be shrunk for another algorithm.
53 53
LEMON also provides a variety of graphs for these requirements called
54 54
\ref graph_adaptors "graph adaptors". Adaptors cannot be used alone but only
55 55
in conjunction with other graph representations.
56 56

	
57 57
You are free to use the graph structure that fit your requirements
58 58
the best, most graph algorithms and auxiliary data structures can be used
59 59
with any graph structure.
60 60

	
61 61
<b>See also:</b> \ref graph_concepts "Graph Structure Concepts".
62 62
*/
63 63

	
64 64
/**
65 65
@defgroup graph_adaptors Adaptor Classes for Graphs
66 66
@ingroup graphs
67 67
\brief Adaptor classes for digraphs and graphs
68 68

	
69 69
This group contains several useful adaptor classes for digraphs and graphs.
70 70

	
71 71
The main parts of LEMON are the different graph structures, generic
72 72
graph algorithms, graph concepts, which couple them, and graph
73 73
adaptors. While the previous notions are more or less clear, the
74 74
latter one needs further explanation. Graph adaptors are graph classes
75 75
which serve for considering graph structures in different ways.
76 76

	
77 77
A short example makes this much clearer.  Suppose that we have an
78 78
instance \c g of a directed graph type, say ListDigraph and an algorithm
79 79
\code
80 80
template <typename Digraph>
81 81
int algorithm(const Digraph&);
82 82
\endcode
83 83
is needed to run on the reverse oriented graph.  It may be expensive
84 84
(in time or in memory usage) to copy \c g with the reversed
85 85
arcs.  In this case, an adaptor class is used, which (according
86 86
to LEMON \ref concepts::Digraph "digraph concepts") works as a digraph.
87 87
The adaptor uses the original digraph structure and digraph operations when
88 88
methods of the reversed oriented graph are called.  This means that the adaptor
89 89
have minor memory usage, and do not perform sophisticated algorithmic
90 90
actions.  The purpose of it is to give a tool for the cases when a
91 91
graph have to be used in a specific alteration.  If this alteration is
92 92
obtained by a usual construction like filtering the node or the arc set or
93 93
considering a new orientation, then an adaptor is worthwhile to use.
94 94
To come back to the reverse oriented graph, in this situation
95 95
\code
96 96
template<typename Digraph> class ReverseDigraph;
97 97
\endcode
98 98
template class can be used. The code looks as follows
99 99
\code
100 100
ListDigraph g;
101 101
ReverseDigraph<ListDigraph> rg(g);
102 102
int result = algorithm(rg);
103 103
\endcode
104 104
During running the algorithm, the original digraph \c g is untouched.
105 105
This techniques give rise to an elegant code, and based on stable
106 106
graph adaptors, complex algorithms can be implemented easily.
107 107

	
108 108
In flow, circulation and matching problems, the residual
109 109
graph is of particular importance. Combining an adaptor implementing
110 110
this with shortest path algorithms or minimum mean cycle algorithms,
111 111
a range of weighted and cardinality optimization algorithms can be
112 112
obtained. For other examples, the interested user is referred to the
113 113
detailed documentation of particular adaptors.
114 114

	
115 115
The behavior of graph adaptors can be very different. Some of them keep
116 116
capabilities of the original graph while in other cases this would be
117 117
meaningless. This means that the concepts that they meet depend
118 118
on the graph adaptor, and the wrapped graph.
119 119
For example, if an arc of a reversed digraph is deleted, this is carried
120 120
out by deleting the corresponding arc of the original digraph, thus the
121 121
adaptor modifies the original digraph.
122 122
However in case of a residual digraph, this operation has no sense.
123 123

	
124 124
Let us stand one more example here to simplify your work.
125 125
ReverseDigraph has constructor
126 126
\code
127 127
ReverseDigraph(Digraph& digraph);
128 128
\endcode
129 129
This means that in a situation, when a <tt>const %ListDigraph&</tt>
130 130
reference to a graph is given, then it have to be instantiated with
131 131
<tt>Digraph=const %ListDigraph</tt>.
132 132
\code
133 133
int algorithm1(const ListDigraph& g) {
134 134
  ReverseDigraph<const ListDigraph> rg(g);
135 135
  return algorithm2(rg);
136 136
}
137 137
\endcode
138 138
*/
139 139

	
140 140
/**
141 141
@defgroup maps Maps
142 142
@ingroup datas
143 143
\brief Map structures implemented in LEMON.
144 144

	
145 145
This group contains the map structures implemented in LEMON.
146 146

	
147 147
LEMON provides several special purpose maps and map adaptors that e.g. combine
148 148
new maps from existing ones.
149 149

	
150 150
<b>See also:</b> \ref map_concepts "Map Concepts".
151 151
*/
152 152

	
153 153
/**
154 154
@defgroup graph_maps Graph Maps
155 155
@ingroup maps
156 156
\brief Special graph-related maps.
157 157

	
158 158
This group contains maps that are specifically designed to assign
159 159
values to the nodes and arcs/edges of graphs.
160 160

	
161 161
If you are looking for the standard graph maps (\c NodeMap, \c ArcMap,
162 162
\c EdgeMap), see the \ref graph_concepts "Graph Structure Concepts".
163 163
*/
164 164

	
165 165
/**
166 166
\defgroup map_adaptors Map Adaptors
167 167
\ingroup maps
168 168
\brief Tools to create new maps from existing ones
169 169

	
170 170
This group contains map adaptors that are used to create "implicit"
171 171
maps from other maps.
172 172

	
173 173
Most of them are \ref concepts::ReadMap "read-only maps".
174 174
They can make arithmetic and logical operations between one or two maps
175 175
(negation, shifting, addition, multiplication, logical 'and', 'or',
176 176
'not' etc.) or e.g. convert a map to another one of different Value type.
177 177

	
178 178
The typical usage of this classes is passing implicit maps to
179 179
algorithms.  If a function type algorithm is called then the function
180 180
type map adaptors can be used comfortable. For example let's see the
181 181
usage of map adaptors with the \c graphToEps() function.
182 182
\code
183 183
  Color nodeColor(int deg) {
184 184
    if (deg >= 2) {
185 185
      return Color(0.5, 0.0, 0.5);
186 186
    } else if (deg == 1) {
187 187
      return Color(1.0, 0.5, 1.0);
188 188
    } else {
189 189
      return Color(0.0, 0.0, 0.0);
190 190
    }
191 191
  }
192 192

	
193 193
  Digraph::NodeMap<int> degree_map(graph);
194 194

	
195 195
  graphToEps(graph, "graph.eps")
196 196
    .coords(coords).scaleToA4().undirected()
197 197
    .nodeColors(composeMap(functorToMap(nodeColor), degree_map))
198 198
    .run();
199 199
\endcode
200 200
The \c functorToMap() function makes an \c int to \c Color map from the
201 201
\c nodeColor() function. The \c composeMap() compose the \c degree_map
202 202
and the previously created map. The composed map is a proper function to
203 203
get the color of each node.
204 204

	
205 205
The usage with class type algorithms is little bit harder. In this
206 206
case the function type map adaptors can not be used, because the
207 207
function map adaptors give back temporary objects.
208 208
\code
209 209
  Digraph graph;
210 210

	
211 211
  typedef Digraph::ArcMap<double> DoubleArcMap;
212 212
  DoubleArcMap length(graph);
213 213
  DoubleArcMap speed(graph);
214 214

	
215 215
  typedef DivMap<DoubleArcMap, DoubleArcMap> TimeMap;
216 216
  TimeMap time(length, speed);
217 217

	
218 218
  Dijkstra<Digraph, TimeMap> dijkstra(graph, time);
219 219
  dijkstra.run(source, target);
220 220
\endcode
221 221
We have a length map and a maximum speed map on the arcs of a digraph.
222 222
The minimum time to pass the arc can be calculated as the division of
223 223
the two maps which can be done implicitly with the \c DivMap template
224 224
class. We use the implicit minimum time map as the length map of the
225 225
\c Dijkstra algorithm.
226 226
*/
227 227

	
228 228
/**
229
@defgroup matrices Matrices
230
@ingroup datas
231
\brief Two dimensional data storages implemented in LEMON.
232

	
233
This group contains two dimensional data storages implemented in LEMON.
234
*/
235

	
236
/**
237 229
@defgroup paths Path Structures
238 230
@ingroup datas
239 231
\brief %Path structures implemented in LEMON.
240 232

	
241 233
This group contains the path structures implemented in LEMON.
242 234

	
243 235
LEMON provides flexible data structures to work with paths.
244 236
All of them have similar interfaces and they can be copied easily with
245 237
assignment operators and copy constructors. This makes it easy and
246 238
efficient to have e.g. the Dijkstra algorithm to store its result in
247 239
any kind of path structure.
248 240

	
249
\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.
250 271
*/
251 272

	
252 273
/**
253 274
@defgroup auxdat Auxiliary Data Structures
254 275
@ingroup datas
255 276
\brief Auxiliary data structures implemented in LEMON.
256 277

	
257 278
This group contains some data structures implemented in LEMON in
258 279
order to make it easier to implement combinatorial algorithms.
259 280
*/
260 281

	
261 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
/**
262 305
@defgroup algs Algorithms
263 306
\brief This group contains the several algorithms
264 307
implemented in LEMON.
265 308

	
266 309
This group contains the several algorithms
267 310
implemented in LEMON.
268 311
*/
269 312

	
270 313
/**
271 314
@defgroup search Graph Search
272 315
@ingroup algs
273 316
\brief Common graph search algorithms.
274 317

	
275 318
This group contains the common graph search algorithms, namely
276
\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
319
\e breadth-first \e search (BFS) and \e depth-first \e search (DFS)
320
\ref clrs01algorithms.
277 321
*/
278 322

	
279 323
/**
280 324
@defgroup shortest_path Shortest Path Algorithms
281 325
@ingroup algs
282 326
\brief Algorithms for finding shortest paths.
283 327

	
284
This group contains the algorithms for finding shortest paths in digraphs.
328
This group contains the algorithms for finding shortest paths in digraphs
329
\ref clrs01algorithms.
285 330

	
286 331
 - \ref Dijkstra algorithm for finding shortest paths from a source node
287 332
   when all arc lengths are non-negative.
288 333
 - \ref BellmanFord "Bellman-Ford" algorithm for finding shortest paths
289 334
   from a source node when arc lenghts can be either positive or negative,
290 335
   but the digraph should not contain directed cycles with negative total
291 336
   length.
292 337
 - \ref FloydWarshall "Floyd-Warshall" and \ref Johnson "Johnson" algorithms
293 338
   for solving the \e all-pairs \e shortest \e paths \e problem when arc
294 339
   lenghts can be either positive or negative, but the digraph should
295 340
   not contain directed cycles with negative total length.
296 341
 - \ref Suurballe A successive shortest path algorithm for finding
297 342
   arc-disjoint paths between two nodes having minimum total length.
298 343
*/
299 344

	
300 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.
352
*/
353

	
354
/**
301 355
@defgroup max_flow Maximum Flow Algorithms
302 356
@ingroup algs
303 357
\brief Algorithms for finding maximum flows.
304 358

	
305 359
This group contains the algorithms for finding maximum flows and
306
feasible circulations.
360
feasible circulations \ref clrs01algorithms, \ref amo93networkflows.
307 361

	
308 362
The \e maximum \e flow \e problem is to find a flow of maximum value between
309 363
a single source and a single target. Formally, there is a \f$G=(V,A)\f$
310 364
digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and
311 365
\f$s, t \in V\f$ source and target nodes.
312 366
A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the
313 367
following optimization problem.
314 368

	
315 369
\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
316 370
\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
317 371
    \quad \forall u\in V\setminus\{s,t\} \f]
318 372
\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
319 373

	
320 374
LEMON contains several algorithms for solving maximum flow problems:
321
- \ref EdmondsKarp Edmonds-Karp algorithm.
322
- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm.
323
- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees.
324
- \ref GoldbergTarjan Preflow push-relabel algorithm with dynamic trees.
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.
325 383

	
326
In most cases the \ref Preflow "Preflow" algorithm provides the
384
In most cases the \ref Preflow algorithm provides the
327 385
fastest method for computing a maximum flow. All implementations
328 386
also provide functions to query the minimum cut, which is the dual
329 387
problem of maximum flow.
330 388

	
331
\ref Circulation is a preflow push-relabel algorithm implemented directly 
389
\ref Circulation is a preflow push-relabel algorithm implemented directly
332 390
for finding feasible circulations, which is a somewhat different problem,
333 391
but it is strongly related to maximum flow.
334 392
For more information, see \ref Circulation.
335 393
*/
336 394

	
337 395
/**
338 396
@defgroup min_cost_flow_algs Minimum Cost Flow Algorithms
339 397
@ingroup algs
340 398

	
341 399
\brief Algorithms for finding minimum cost flows and circulations.
342 400

	
343 401
This group contains the algorithms for finding minimum cost flows and
344
circulations. For more information about this problem and its dual
345
solution see \ref min_cost_flow "Minimum Cost Flow Problem".
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".
346 405

	
347 406
LEMON contains several algorithms for this problem.
348 407
 - \ref NetworkSimplex Primal Network Simplex algorithm with various
349
   pivot strategies.
350
 - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
351
   cost scaling.
352
 - \ref CapacityScaling Successive Shortest %Path algorithm with optional
353
   capacity scaling.
354
 - \ref CancelAndTighten The Cancel and Tighten algorithm.
355
 - \ref CycleCanceling Cycle-Canceling algorithms.
408
   pivot strategies \ref dantzig63linearprog, \ref kellyoneill91netsimplex.
409
 - \ref CostScaling Cost Scaling algorithm based on push/augment and
410
   relabel operations \ref goldberg90approximation, \ref goldberg97efficient,
411
   \ref bunnagel98efficient.
412
 - \ref CapacityScaling Capacity Scaling algorithm based on the successive
413
   shortest path method \ref edmondskarp72theoretical.
414
 - \ref CycleCanceling Cycle-Canceling algorithms, two of which are
415
   strongly polynomial \ref klein67primal, \ref goldberg89cyclecanceling.
356 416

	
357 417
In general NetworkSimplex is the most efficient implementation,
358 418
but in special cases other algorithms could be faster.
359 419
For example, if the total supply and/or capacities are rather small,
360 420
CapacityScaling is usually the fastest algorithm (without effective scaling).
361 421
*/
362 422

	
363 423
/**
364 424
@defgroup min_cut Minimum Cut Algorithms
365 425
@ingroup algs
366 426

	
367 427
\brief Algorithms for finding minimum cut in graphs.
368 428

	
369 429
This group contains the algorithms for finding minimum cut in graphs.
370 430

	
371 431
The \e minimum \e cut \e problem is to find a non-empty and non-complete
372 432
\f$X\f$ subset of the nodes with minimum overall capacity on
373 433
outgoing arcs. Formally, there is a \f$G=(V,A)\f$ digraph, a
374 434
\f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
375 435
cut is the \f$X\f$ solution of the next optimization problem:
376 436

	
377 437
\f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
378
    \sum_{uv\in A, u\in X, v\not\in X}cap(uv) \f]
438
    \sum_{uv\in A: u\in X, v\not\in X}cap(uv) \f]
379 439

	
380 440
LEMON contains several algorithms related to minimum cut problems:
381 441

	
382 442
- \ref HaoOrlin "Hao-Orlin algorithm" for calculating minimum cut
383 443
  in directed graphs.
384 444
- \ref NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
385 445
  calculating minimum cut in undirected graphs.
386 446
- \ref GomoryHu "Gomory-Hu tree computation" for calculating
387 447
  all-pairs minimum cut in undirected graphs.
388 448

	
389 449
If you want to find minimum cut just between two distinict nodes,
390 450
see the \ref max_flow "maximum flow problem".
391 451
*/
392 452

	
393 453
/**
394
@defgroup graph_properties Connectivity and Other Graph Properties
454
@defgroup min_mean_cycle Minimum Mean Cycle Algorithms
395 455
@ingroup algs
396
\brief Algorithms for discovering the graph properties
456
\brief Algorithms for finding minimum mean cycles.
397 457

	
398
This group contains the algorithms for discovering the graph properties
399
like connectivity, bipartiteness, euler property, simplicity etc.
458
This group contains the algorithms for finding minimum mean cycles
459
\ref clrs01algorithms, \ref amo93networkflows.
400 460

	
401
\image html edge_biconnected_components.png
402
\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
403
*/
461
The \e minimum \e mean \e cycle \e problem is to find a directed cycle
462
of minimum mean length (cost) in a digraph.
463
The mean length of a cycle is the average length of its arcs, i.e. the
464
ratio between the total length of the cycle and the number of arcs on it.
404 465

	
405
/**
406
@defgroup planar Planarity Embedding and Drawing
407
@ingroup algs
408
\brief Algorithms for planarity checking, embedding and drawing
466
This problem has an important connection to \e conservative \e length
467
\e functions, too. A length function on the arcs of a digraph is called
468
conservative if and only if there is no directed cycle of negative total
469
length. For an arbitrary length function, the negative of the minimum
470
cycle mean is the smallest \f$\epsilon\f$ value so that increasing the
471
arc lengths uniformly by \f$\epsilon\f$ results in a conservative length
472
function.
409 473

	
410
This group contains the algorithms for planarity checking,
411
embedding and drawing.
474
LEMON contains three algorithms for solving the minimum mean cycle problem:
475
- \ref Karp "Karp"'s original algorithm \ref amo93networkflows,
476
  \ref dasdan98minmeancycle.
477
- \ref HartmannOrlin "Hartmann-Orlin"'s algorithm, which is an improved
478
  version of Karp's algorithm \ref dasdan98minmeancycle.
479
- \ref Howard "Howard"'s policy iteration algorithm
480
  \ref dasdan98minmeancycle.
412 481

	
413
\image html planar.png
414
\image latex planar.eps "Plane graph" width=\textwidth
482
In practice, the Howard algorithm proved to be by far the most efficient
483
one, though the best known theoretical bound on its running time is
484
exponential.
485
Both Karp and HartmannOrlin algorithms run in time O(ne) and use space
486
O(n<sup>2</sup>+e), but the latter one is typically faster due to the
487
applied early termination scheme.
415 488
*/
416 489

	
417 490
/**
418 491
@defgroup matching Matching Algorithms
419 492
@ingroup algs
420 493
\brief Algorithms for finding matchings in graphs and bipartite graphs.
421 494

	
422 495
This group contains the algorithms for calculating
423 496
matchings in graphs and bipartite graphs. The general matching problem is
424 497
finding a subset of the edges for which each node has at most one incident
425 498
edge.
426 499

	
427 500
There are several different algorithms for calculate matchings in
428 501
graphs.  The matching problems in bipartite graphs are generally
429 502
easier than in general graphs. The goal of the matching optimization
430 503
can be finding maximum cardinality, maximum weight or minimum cost
431 504
matching. The search can be constrained to find perfect or
432 505
maximum cardinality matching.
433 506

	
434 507
The matching algorithms implemented in LEMON:
435 508
- \ref MaxBipartiteMatching Hopcroft-Karp augmenting path algorithm
436 509
  for calculating maximum cardinality matching in bipartite graphs.
437 510
- \ref PrBipartiteMatching Push-relabel algorithm
438 511
  for calculating maximum cardinality matching in bipartite graphs.
439 512
- \ref MaxWeightedBipartiteMatching
440 513
  Successive shortest path algorithm for calculating maximum weighted
441 514
  matching and maximum weighted bipartite matching in bipartite graphs.
442 515
- \ref MinCostMaxBipartiteMatching
443 516
  Successive shortest path algorithm for calculating minimum cost maximum
444 517
  matching in bipartite graphs.
445 518
- \ref MaxMatching Edmond's blossom shrinking algorithm for calculating
446 519
  maximum cardinality matching in general graphs.
447 520
- \ref MaxWeightedMatching Edmond's blossom shrinking algorithm for calculating
448 521
  maximum weighted matching in general graphs.
449 522
- \ref MaxWeightedPerfectMatching
450 523
  Edmond's blossom shrinking algorithm for calculating maximum weighted
451 524
  perfect matching in general graphs.
525
- \ref MaxFractionalMatching Push-relabel algorithm for calculating
526
  maximum cardinality fractional matching in general graphs.
527
- \ref MaxWeightedFractionalMatching Augmenting path algorithm for calculating
528
  maximum weighted fractional matching in general graphs.
529
- \ref MaxWeightedPerfectFractionalMatching
530
  Augmenting path algorithm for calculating maximum weighted
531
  perfect fractional matching in general graphs.
452 532

	
453
\image html bipartite_matching.png
454
\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
533
\image html matching.png
534
\image latex matching.eps "Min Cost Perfect Matching" width=\textwidth
455 535
*/
456 536

	
457 537
/**
458
@defgroup spantree Minimum Spanning Tree Algorithms
538
@defgroup graph_properties Connectivity and Other Graph Properties
459 539
@ingroup algs
460
\brief Algorithms for finding minimum cost spanning trees and arborescences.
540
\brief Algorithms for discovering the graph properties
461 541

	
462
This group contains the algorithms for finding minimum cost spanning
463
trees and arborescences.
542
This group contains the algorithms for discovering the graph properties
543
like connectivity, bipartiteness, euler property, simplicity etc.
544

	
545
\image html connected_components.png
546
\image latex connected_components.eps "Connected components" width=\textwidth
547
*/
548

	
549
/**
550
@defgroup planar Planarity Embedding and Drawing
551
@ingroup algs
552
\brief Algorithms for planarity checking, embedding and drawing
553

	
554
This group contains the algorithms for planarity checking,
555
embedding and drawing.
556

	
557
\image html planar.png
558
\image latex planar.eps "Plane graph" width=\textwidth
559
*/
560

	
561
/**
562
@defgroup approx Approximation Algorithms
563
@ingroup algs
564
\brief Approximation algorithms.
565

	
566
This group contains the approximation and heuristic algorithms
567
implemented in LEMON.
464 568
*/
465 569

	
466 570
/**
467 571
@defgroup auxalg Auxiliary Algorithms
468 572
@ingroup algs
469 573
\brief Auxiliary algorithms implemented in LEMON.
470 574

	
471 575
This group contains some algorithms implemented in LEMON
472 576
in order to make it easier to implement complex algorithms.
473 577
*/
474 578

	
475 579
/**
476
@defgroup approx Approximation Algorithms
477
@ingroup algs
478
\brief Approximation algorithms.
479

	
480
This group contains the approximation and heuristic algorithms
481
implemented in LEMON.
482
*/
483

	
484
/**
485 580
@defgroup gen_opt_group General Optimization Tools
486 581
\brief This group contains some general optimization frameworks
487 582
implemented in LEMON.
488 583

	
489 584
This group contains some general optimization frameworks
490 585
implemented in LEMON.
491 586
*/
492 587

	
493 588
/**
494
@defgroup lp_group Lp and Mip Solvers
589
@defgroup lp_group LP and MIP Solvers
495 590
@ingroup gen_opt_group
496
\brief Lp and Mip solver interfaces for LEMON.
591
\brief LP and MIP solver interfaces for LEMON.
497 592

	
498
This group contains Lp and Mip solver interfaces for LEMON. The
499
various LP solvers could be used in the same manner with this
500
interface.
593
This group contains LP and MIP solver interfaces for LEMON.
594
Various LP solvers could be used in the same manner with this
595
high-level interface.
596

	
597
The currently supported solvers are \ref glpk, \ref clp, \ref cbc,
598
\ref cplex, \ref soplex.
501 599
*/
502 600

	
503 601
/**
504 602
@defgroup lp_utils Tools for Lp and Mip Solvers
505 603
@ingroup lp_group
506 604
\brief Helper tools to the Lp and Mip solvers.
507 605

	
508 606
This group adds some helper tools to general optimization framework
509 607
implemented in LEMON.
510 608
*/
511 609

	
512 610
/**
513 611
@defgroup metah Metaheuristics
514 612
@ingroup gen_opt_group
515 613
\brief Metaheuristics for LEMON library.
516 614

	
517 615
This group contains some metaheuristic optimization tools.
518 616
*/
519 617

	
520 618
/**
521 619
@defgroup utils Tools and Utilities
522 620
\brief Tools and utilities for programming in LEMON
523 621

	
524 622
Tools and utilities for programming in LEMON.
525 623
*/
526 624

	
527 625
/**
528 626
@defgroup gutils Basic Graph Utilities
529 627
@ingroup utils
530 628
\brief Simple basic graph utilities.
531 629

	
532 630
This group contains some simple basic graph utilities.
533 631
*/
534 632

	
535 633
/**
536 634
@defgroup misc Miscellaneous Tools
537 635
@ingroup utils
538 636
\brief Tools for development, debugging and testing.
539 637

	
540 638
This group contains several useful tools for development,
541 639
debugging and testing.
542 640
*/
543 641

	
544 642
/**
545 643
@defgroup timecount Time Measuring and Counting
546 644
@ingroup misc
547 645
\brief Simple tools for measuring the performance of algorithms.
548 646

	
549 647
This group contains simple tools for measuring the performance
550 648
of algorithms.
551 649
*/
552 650

	
553 651
/**
554 652
@defgroup exceptions Exceptions
555 653
@ingroup utils
556 654
\brief Exceptions defined in LEMON.
557 655

	
558 656
This group contains the exceptions defined in LEMON.
559 657
*/
560 658

	
561 659
/**
562 660
@defgroup io_group Input-Output
563 661
\brief Graph Input-Output methods
564 662

	
565 663
This group contains the tools for importing and exporting graphs
566 664
and graph related data. Now it supports the \ref lgf-format
567 665
"LEMON Graph Format", the \c DIMACS format and the encapsulated
568 666
postscript (EPS) format.
569 667
*/
570 668

	
571 669
/**
572 670
@defgroup lemon_io LEMON Graph Format
573 671
@ingroup io_group
574 672
\brief Reading and writing LEMON Graph Format.
575 673

	
576 674
This group contains methods for reading and writing
577 675
\ref lgf-format "LEMON Graph Format".
578 676
*/
579 677

	
580 678
/**
581 679
@defgroup eps_io Postscript Exporting
582 680
@ingroup io_group
583 681
\brief General \c EPS drawer and graph exporter
584 682

	
585 683
This group contains general \c EPS drawing methods and special
586 684
graph exporting tools.
587 685
*/
588 686

	
589 687
/**
590
@defgroup dimacs_group DIMACS format
688
@defgroup dimacs_group DIMACS Format
591 689
@ingroup io_group
592 690
\brief Read and write files in DIMACS format
593 691

	
594 692
Tools to read a digraph from or write it to a file in DIMACS format data.
595 693
*/
596 694

	
597 695
/**
598 696
@defgroup nauty_group NAUTY Format
599 697
@ingroup io_group
600 698
\brief Read \e Nauty format
601 699

	
602 700
Tool to read graphs from \e Nauty format data.
603 701
*/
604 702

	
605 703
/**
606 704
@defgroup concept Concepts
607 705
\brief Skeleton classes and concept checking classes
608 706

	
609 707
This group contains the data/algorithm skeletons and concept checking
610 708
classes implemented in LEMON.
611 709

	
612 710
The purpose of the classes in this group is fourfold.
613 711

	
614 712
- These classes contain the documentations of the %concepts. In order
615 713
  to avoid document multiplications, an implementation of a concept
616 714
  simply refers to the corresponding concept class.
617 715

	
618 716
- These classes declare every functions, <tt>typedef</tt>s etc. an
619 717
  implementation of the %concepts should provide, however completely
620 718
  without implementations and real data structures behind the
621 719
  interface. On the other hand they should provide nothing else. All
622 720
  the algorithms working on a data structure meeting a certain concept
623 721
  should compile with these classes. (Though it will not run properly,
624 722
  of course.) In this way it is easily to check if an algorithm
625 723
  doesn't use any extra feature of a certain implementation.
626 724

	
627 725
- The concept descriptor classes also provide a <em>checker class</em>
628 726
  that makes it possible to check whether a certain implementation of a
629 727
  concept indeed provides all the required features.
630 728

	
631 729
- Finally, They can serve as a skeleton of a new implementation of a concept.
632 730
*/
633 731

	
634 732
/**
635 733
@defgroup graph_concepts Graph Structure Concepts
636 734
@ingroup concept
637 735
\brief Skeleton and concept checking classes for graph structures
638 736

	
639
This group contains the skeletons and concept checking classes of LEMON's
640
graph structures and helper classes used to implement these.
737
This group contains the skeletons and concept checking classes of
738
graph structures.
641 739
*/
642 740

	
643 741
/**
644 742
@defgroup map_concepts Map Concepts
645 743
@ingroup concept
646 744
\brief Skeleton and concept checking classes for maps
647 745

	
648 746
This group contains the skeletons and concept checking classes of maps.
649 747
*/
650 748

	
651 749
/**
750
@defgroup tools Standalone Utility Applications
751

	
752
Some utility applications are listed here.
753

	
754
The standard compilation procedure (<tt>./configure;make</tt>) will compile
755
them, as well.
756
*/
757

	
758
/**
652 759
\anchor demoprograms
653 760

	
654 761
@defgroup demos Demo Programs
655 762

	
656 763
Some demo programs are listed here. Their full source codes can be found in
657 764
the \c demo subdirectory of the source tree.
658 765

	
659 766
In order to compile them, use the <tt>make demo</tt> or the
660 767
<tt>make check</tt> commands.
661 768
*/
662 769

	
663
/**
664
@defgroup tools Standalone Utility Applications
665

	
666
Some utility applications are listed here.
667

	
668
The standard compilation procedure (<tt>./configure;make</tt>) will compile
669
them, as well.
670
*/
671

	
672 770
}
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-2009
5
 * Copyright (C) 2003-2010
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 @PACKAGE_NAME@ @PACKAGE_VERSION@ Documentation
21 21

	
22 22
\section intro Introduction
23 23

	
24
\subsection whatis What is LEMON
25

	
26
LEMON stands for <b>L</b>ibrary for <b>E</b>fficient <b>M</b>odeling
27
and <b>O</b>ptimization in <b>N</b>etworks.
28
It is a C++ template
29
library aimed at combinatorial optimization tasks which
30
often involve in working
31
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 implementations of common
27
data structures and algorithms with focus on combinatorial optimization
28
tasks connected mainly with graphs and networks.
32 29

	
33 30
<b>
34 31
LEMON is an <a class="el" href="http://opensource.org/">open&nbsp;source</a>
35 32
project.
36 33
You are free to use it in your commercial or
37 34
non-commercial applications under very permissive
38 35
\ref license "license terms".
39 36
</b>
40 37

	
41
\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/en/">E&ouml;tv&ouml;s Lor&aacute;nd University</a>,
43
Budapest, Hungary.
44
LEMON is also a member of the <a href="http://www.coin-or.org/">COIN-OR</a>
45
initiative \ref coinor.
46

	
47
\section howtoread How to Read the Documentation
42 48

	
43 49
If you would like to get to know the library, see
44 50
<a class="el" href="http://lemon.cs.elte.hu/pub/tutorial/">LEMON Tutorial</a>.
45 51

	
52
If you are interested in starting to use the library, see the <a class="el"
53
href="http://lemon.cs.elte.hu/trac/lemon/wiki/InstallGuide/">Installation
54
Guide</a>.
55

	
46 56
If you know what you are looking for, then try to find it under the
47 57
<a class="el" href="modules.html">Modules</a> section.
48 58

	
49 59
If you are a user of the old (0.x) series of LEMON, please check out the
50 60
\ref migration "Migration Guide" for the backward incompatibilities.
51 61
*/
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-2009
5
 * Copyright (C) 2003-2010
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 min_cost_flow Minimum Cost Flow Problem
23 23

	
24 24
\section mcf_def Definition (GEQ form)
25 25

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

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

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

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

	
59 59

	
60 60
\section mcf_algs Algorithms
61 61

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

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

	
67 67

	
68 68
\section mcf_dual Dual Solution
69 69

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

	
76 76
 - For all \f$uv\in A\f$ arcs:
77 77
   - if \f$cost^\pi(uv)>0\f$, then \f$f(uv)=lower(uv)\f$;
78 78
   - if \f$lower(uv)<f(uv)<upper(uv)\f$, then \f$cost^\pi(uv)=0\f$;
79 79
   - if \f$cost^\pi(uv)<0\f$, then \f$f(uv)=upper(uv)\f$.
80 80
 - For all \f$u\in V\f$ nodes:
81
   - \f$\pi(u)<=0\f$;
81
   - \f$\pi(u)\leq 0\f$;
82 82
   - if \f$\sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \neq sup(u)\f$,
83 83
     then \f$\pi(u)=0\f$.
84
 
84

	
85 85
Here \f$cost^\pi(uv)\f$ denotes the \e reduced \e cost of the arc
86 86
\f$uv\in A\f$ with respect to the potential function \f$\pi\f$, i.e.
87 87
\f[ cost^\pi(uv) = cost(uv) + \pi(u) - \pi(v).\f]
88 88

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

	
92 92

	
93 93
\section mcf_eq Equality Form
94 94

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

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

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

	
110 110

	
111 111
\section mcf_leq Opposite Inequalites (LEQ Form)
112 112

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

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

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

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

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

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

	
152 152
*/
153 153
}
Ignore white space 6 line context
1 1
EXTRA_DIST += \
2 2
	lemon/lemon.pc.in \
3 3
	lemon/lemon.pc.cmake \
4 4
	lemon/CMakeLists.txt \
5 5
	lemon/config.h.cmake
6 6

	
7 7
pkgconfig_DATA += lemon/lemon.pc
8 8

	
9 9
lib_LTLIBRARIES += lemon/libemon.la
10 10

	
11 11
lemon_libemon_la_SOURCES = \
12 12
	lemon/arg_parser.cc \
13 13
	lemon/base.cc \
14 14
	lemon/color.cc \
15 15
	lemon/lp_base.cc \
16 16
	lemon/lp_skeleton.cc \
17 17
	lemon/random.cc \
18 18
	lemon/bits/windows.cc
19 19

	
20 20
nodist_lemon_HEADERS = lemon/config.h	
21 21

	
22 22
lemon_libemon_la_CXXFLAGS = \
23 23
	$(AM_CXXFLAGS) \
24 24
	$(GLPK_CFLAGS) \
25 25
	$(CPLEX_CFLAGS) \
26 26
	$(SOPLEX_CXXFLAGS) \
27 27
	$(CLP_CXXFLAGS) \
28 28
	$(CBC_CXXFLAGS)
29 29

	
30 30
lemon_libemon_la_LDFLAGS = \
31 31
	$(GLPK_LIBS) \
32 32
	$(CPLEX_LIBS) \
33 33
	$(SOPLEX_LIBS) \
34 34
	$(CLP_LIBS) \
35 35
	$(CBC_LIBS)
36 36

	
37 37
if HAVE_GLPK
38 38
lemon_libemon_la_SOURCES += lemon/glpk.cc
39 39
endif
40 40

	
41 41
if HAVE_CPLEX
42 42
lemon_libemon_la_SOURCES += lemon/cplex.cc
43 43
endif
44 44

	
45 45
if HAVE_SOPLEX
46 46
lemon_libemon_la_SOURCES += lemon/soplex.cc
47 47
endif
48 48

	
49 49
if HAVE_CLP
50 50
lemon_libemon_la_SOURCES += lemon/clp.cc
51 51
endif
52 52

	
53 53
if HAVE_CBC
54 54
lemon_libemon_la_SOURCES += lemon/cbc.cc
55 55
endif
56 56

	
57 57
lemon_HEADERS += \
58 58
	lemon/adaptors.h \
59 59
	lemon/arg_parser.h \
60 60
	lemon/assert.h \
61
	lemon/bellman_ford.h \
61 62
	lemon/bfs.h \
62 63
	lemon/bin_heap.h \
64
	lemon/binomial_heap.h \
63 65
	lemon/bucket_heap.h \
66
	lemon/capacity_scaling.h \
64 67
	lemon/cbc.h \
65 68
	lemon/circulation.h \
66 69
	lemon/clp.h \
67 70
	lemon/color.h \
68 71
	lemon/concept_check.h \
69 72
	lemon/connectivity.h \
73
	lemon/core.h \
74
	lemon/cost_scaling.h \
70 75
	lemon/counter.h \
71
	lemon/core.h \
72 76
	lemon/cplex.h \
77
	lemon/cycle_canceling.h \
73 78
	lemon/dfs.h \
79
	lemon/dheap.h \
74 80
	lemon/dijkstra.h \
75 81
	lemon/dim2.h \
76 82
	lemon/dimacs.h \
77 83
	lemon/edge_set.h \
78 84
	lemon/elevator.h \
79 85
	lemon/error.h \
80 86
	lemon/euler.h \
81 87
	lemon/fib_heap.h \
88
	lemon/fractional_matching.h \
82 89
	lemon/full_graph.h \
83 90
	lemon/glpk.h \
84 91
	lemon/gomory_hu.h \
85 92
	lemon/graph_to_eps.h \
86 93
	lemon/grid_graph.h \
94
	lemon/hartmann_orlin_mmc.h \
95
	lemon/howard_mmc.h \
87 96
	lemon/hypercube_graph.h \
97
	lemon/karp_mmc.h \
88 98
	lemon/kruskal.h \
89 99
	lemon/hao_orlin.h \
90 100
	lemon/lgf_reader.h \
91 101
	lemon/lgf_writer.h \
92 102
	lemon/list_graph.h \
93 103
	lemon/lp.h \
94 104
	lemon/lp_base.h \
95 105
	lemon/lp_skeleton.h \
96 106
	lemon/maps.h \
97 107
	lemon/matching.h \
98 108
	lemon/math.h \
99 109
	lemon/min_cost_arborescence.h \
100 110
	lemon/nauty_reader.h \
101 111
	lemon/network_simplex.h \
112
	lemon/pairing_heap.h \
102 113
	lemon/path.h \
114
	lemon/planarity.h \
103 115
	lemon/preflow.h \
116
	lemon/quad_heap.h \
104 117
	lemon/radix_heap.h \
105 118
	lemon/radix_sort.h \
106 119
	lemon/random.h \
107 120
	lemon/smart_graph.h \
108 121
	lemon/soplex.h \
122
	lemon/static_graph.h \
109 123
	lemon/suurballe.h \
110 124
	lemon/time_measure.h \
111 125
	lemon/tolerance.h \
112 126
	lemon/unionfind.h \
113 127
	lemon/bits/windows.h
114 128

	
115 129
bits_HEADERS += \
116 130
	lemon/bits/alteration_notifier.h \
117 131
	lemon/bits/array_map.h \
118 132
	lemon/bits/bezier.h \
119 133
	lemon/bits/default_map.h \
120 134
	lemon/bits/edge_set_extender.h \
121 135
	lemon/bits/enable_if.h \
122 136
	lemon/bits/graph_adaptor_extender.h \
123 137
	lemon/bits/graph_extender.h \
124 138
	lemon/bits/map_extender.h \
125 139
	lemon/bits/path_dump.h \
126 140
	lemon/bits/solver_bits.h \
127 141
	lemon/bits/traits.h \
128 142
	lemon/bits/variant.h \
129 143
	lemon/bits/vector_map.h
130 144

	
131 145
concept_HEADERS += \
132 146
	lemon/concepts/digraph.h \
133 147
	lemon/concepts/graph.h \
134 148
	lemon/concepts/graph_components.h \
135 149
	lemon/concepts/heap.h \
136 150
	lemon/concepts/maps.h \
137 151
	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-2009
5
 * Copyright (C) 2003-2010
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_ADAPTORS_H
20 20
#define LEMON_ADAPTORS_H
21 21

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

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

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

	
36 36
#include <algorithm>
37 37

	
38 38
namespace lemon {
39 39

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
131 131
    };
132 132

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

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

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

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

	
154 154
    };
155 155

	
156 156
  };
157 157

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

	
163 163
  protected:
164 164
    GR* _graph;
165 165

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
273 273
    };
274 274

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

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

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

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

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

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

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

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

	
319 319
  };
320 320

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

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

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

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

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

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

	
349 349
  };
350 350

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

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

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

	
402 405

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

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

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

	
424 427
  public:
425 428

	
426 429
    typedef typename Parent::Node Node;
427 430
    typedef typename Parent::Arc Arc;
428 431

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

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

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

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

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

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

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

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

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

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

	
489 492
    typedef False NodeNumTag;
490 493
    typedef False ArcNumTag;
491 494

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

	
505 508
  public:
506 509

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

	
514 517
    public:
515 518
      typedef V Value;
516 519

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

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

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

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

	
541 544
    public:
542 545
      typedef V Value;
543 546

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

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

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

	
561 564
  };
562 565

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

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

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

	
585 588
  public:
586 589

	
587 590
    typedef typename Parent::Node Node;
588 591
    typedef typename Parent::Arc Arc;
589 592

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

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

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

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

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

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

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

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

	
634 637
    typedef False NodeNumTag;
635 638
    typedef False ArcNumTag;
636 639

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

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

	
657 660
    public:
658 661
      typedef V Value;
659 662

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

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

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

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

	
684 687
    public:
685 688
      typedef V Value;
686 689

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

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

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

	
704 707
  };
705 708

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

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

	
760 765
    typedef typename Parent::Node Node;
761 766
    typedef typename Parent::Arc Arc;
762 767

	
763 768
  protected:
764 769
    SubDigraph() { }
765 770
  public:
766 771

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

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

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

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

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

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

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

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

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

	
827 832
  };
828 833

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

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

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

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

	
866 871

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

	
875 880
    typedef SubGraphBase Adaptor;
876 881
  protected:
877 882

	
878 883
    NF* _node_filter;
879 884
    EF* _edge_filter;
880 885

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

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

	
890 895
  public:
891 896

	
892 897
    typedef typename Parent::Node Node;
893 898
    typedef typename Parent::Arc Arc;
894 899
    typedef typename Parent::Edge Edge;
895 900

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
988 993
    typedef False NodeNumTag;
989 994
    typedef False ArcNumTag;
990 995
    typedef False EdgeNumTag;
991 996

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

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

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

	
1025 1030
    public:
1026 1031
      typedef V Value;
1027 1032

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

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

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

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

	
1052 1057
    public:
1053 1058
      typedef V Value;
1054 1059

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

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

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

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

	
1079 1084
    public:
1080 1085
      typedef V Value;
1081 1086

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

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

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

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

	
1100 1105
  };
1101 1106

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

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

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

	
1124 1129
  public:
1125 1130

	
1126 1131
    typedef typename Parent::Node Node;
1127 1132
    typedef typename Parent::Arc Arc;
1128 1133
    typedef typename Parent::Edge Edge;
1129 1134

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

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

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

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

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

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

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

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

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

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

	
1192 1197
    typedef False NodeNumTag;
1193 1198
    typedef False ArcNumTag;
1194 1199
    typedef False EdgeNumTag;
1195 1200

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

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

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

	
1223 1228
    public:
1224 1229
      typedef V Value;
1225 1230

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

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

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

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

	
1250 1255
    public:
1251 1256
      typedef V Value;
1252 1257

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

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

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

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

	
1277 1282
    public:
1278 1283
      typedef V Value;
1279 1284

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

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

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

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

	
1298 1303
  };
1299 1304

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

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

	
1355 1362
    typedef typename Parent::Node Node;
1356 1363
    typedef typename Parent::Edge Edge;
1357 1364

	
1358 1365
  protected:
1359 1366
    SubGraph() { }
1360 1367
  public:
1361 1368

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

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

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

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

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

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

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

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

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

	
1422 1429
  };
1423 1430

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

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

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

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

	
1457 1464

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

	
1501 1510
  public:
1502 1511

	
1503 1512
    typedef GR Digraph;
1504 1513
    typedef NF NodeFilterMap;
1505 1514

	
1506 1515
    typedef typename Parent::Node Node;
1507 1516

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

	
1511 1520
    FilterNodes() : const_true_map() {}
1512 1521

	
1513 1522
  public:
1514 1523

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

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

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

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

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

	
1551 1560
  };
1552 1561

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

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

	
1564 1573
  public:
1565 1574

	
1566 1575
    typedef GR Graph;
1567 1576
    typedef NF NodeFilterMap;
1568 1577

	
1569 1578
    typedef typename Parent::Node Node;
1570 1579

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

	
1574 1583
    FilterNodes() : const_true_map() {}
1575 1584

	
1576 1585
  public:
1577 1586

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

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

	
1588 1597
  };
1589 1598

	
1590 1599

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

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

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

	
1648 1659
  public:
1649 1660

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

	
1655 1666
    typedef typename Parent::Arc Arc;
1656 1667

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

	
1660 1671
    FilterArcs() : const_true_map() {}
1661 1672

	
1662 1673
  public:
1663 1674

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

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

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

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

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

	
1699 1710
  };
1700 1711

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

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

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

	
1758 1771
  public:
1759 1772

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

	
1765 1778
    typedef typename Parent::Edge Edge;
1766 1779

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

	
1770 1783
    FilterEdges() : const_true_map(true) {
1771 1784
      Parent::setNodeFilterMap(const_true_map);
1772 1785
    }
1773 1786

	
1774 1787
  public:
1775 1788

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

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

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

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

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

	
1811 1824
  };
1812 1825

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

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

	
1830 1843

	
1831 1844
  template <typename DGR>
1832 1845
  class UndirectorBase {
1833 1846
  public:
1834 1847
    typedef DGR Digraph;
1835 1848
    typedef UndirectorBase Adaptor;
1836 1849

	
1837 1850
    typedef True UndirectedTag;
1838 1851

	
1839 1852
    typedef typename Digraph::Arc Edge;
1840 1853
    typedef typename Digraph::Node Node;
1841 1854

	
1842 1855
    class Arc {
1843 1856
      friend class UndirectorBase;
1844 1857
    protected:
1845 1858
      Edge _edge;
1846 1859
      bool _forward;
1847 1860

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

	
1851 1864
    public:
1852 1865
      Arc() {}
1853 1866

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

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

	
1858 1871
      bool operator==(const Arc &other) const {
1859 1872
        return _forward == other._forward && _edge == other._edge;
1860 1873
      }
1861 1874
      bool operator!=(const Arc &other) const {
1862 1875
        return _forward != other._forward || _edge != other._edge;
1863 1876
      }
1864 1877
      bool operator<(const Arc &other) const {
1865 1878
        return _forward < other._forward ||
1866 1879
          (_forward == other._forward && _edge < other._edge);
1867 1880
      }
1868 1881
    };
1869 1882

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

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

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

	
1883 1896
    void next(Arc& a) const {
1884 1897
      if (a._forward) {
1885 1898
        a._forward = false;
1886 1899
      } else {
1887 1900
        _digraph->next(a._edge);
1888 1901
        a._forward = true;
1889 1902
      }
1890 1903
    }
1891 1904

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

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

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

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

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

	
1954 1967
    void nextInc(Edge &e, bool &d) const {
1955 1968
      if (d) {
1956 1969
        Node s = _digraph->source(e);
1957 1970
        _digraph->nextOut(e);
1958 1971
        if (e != INVALID) return;
1959 1972
        d = false;
1960 1973
        _digraph->firstIn(e, s);
1961 1974
      } else {
1962 1975
        _digraph->nextIn(e);
1963 1976
      }
1964 1977
    }
1965 1978

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
2042 2055
    typedef FindArcTag FindEdgeTag;
2043 2056
    Edge findEdge(Node s, Node t, Edge p = INVALID) const {
2044 2057
      if (s != t) {
2045 2058
        if (p == INVALID) {
2046 2059
          Edge arc = _digraph->findArc(s, t);
2047 2060
          if (arc != INVALID) return arc;
2048 2061
          arc = _digraph->findArc(t, s);
2049 2062
          if (arc != INVALID) return arc;
2050 2063
        } else if (_digraph->source(p) == s) {
2051 2064
          Edge arc = _digraph->findArc(s, t, p);
2052 2065
          if (arc != INVALID) return arc;
2053 2066
          arc = _digraph->findArc(t, s);
2054 2067
          if (arc != INVALID) return arc;
2055 2068
        } else {
2056 2069
          Edge arc = _digraph->findArc(t, s, p);
2057 2070
          if (arc != INVALID) return arc;
2058 2071
        }
2059 2072
      } else {
2060 2073
        return _digraph->findArc(s, t, p);
2061 2074
      }
2062 2075
      return INVALID;
2063 2076
    }
2064 2077

	
2065 2078
  private:
2066 2079

	
2067 2080
    template <typename V>
2068 2081
    class ArcMapBase {
2069 2082
    private:
2070 2083

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

	
2073 2086
    public:
2074 2087

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

	
2077 2090
      typedef V Value;
2078 2091
      typedef Arc Key;
2079 2092
      typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReturnValue;
2080 2093
      typedef typename MapTraits<MapImpl>::ReturnValue ReturnValue;
2081 2094
      typedef typename MapTraits<MapImpl>::ConstReturnValue ConstReference;
2082 2095
      typedef typename MapTraits<MapImpl>::ReturnValue Reference;
2083 2096

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

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

	
2091 2104
      void set(const Arc& a, const V& value) {
2092 2105
        if (direction(a)) {
2093 2106
          _forward.set(a, value);
2094 2107
        } else {
2095 2108
          _backward.set(a, value);
2096 2109
        }
2097 2110
      }
2098 2111

	
2099 2112
      ConstReturnValue operator[](const Arc& a) const {
2100 2113
        if (direction(a)) {
2101 2114
          return _forward[a];
2102 2115
        } else {
2103 2116
          return _backward[a];
2104 2117
        }
2105 2118
      }
2106 2119

	
2107 2120
      ReturnValue operator[](const Arc& a) {
2108 2121
        if (direction(a)) {
2109 2122
          return _forward[a];
2110 2123
        } else {
2111 2124
          return _backward[a];
2112 2125
        }
2113 2126
      }
2114 2127

	
2115 2128
    protected:
2116 2129

	
2117 2130
      MapImpl _forward, _backward;
2118 2131

	
2119 2132
    };
2120 2133

	
2121 2134
  public:
2122 2135

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

	
2127 2140
    public:
2128 2141
      typedef V Value;
2129 2142

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

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

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

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

	
2147 2160
    };
2148 2161

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

	
2154 2167
    public:
2155 2168
      typedef V Value;
2156 2169

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

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

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

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

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

	
2179 2192
    public:
2180 2193
      typedef V Value;
2181 2194

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

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

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

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

	
2199 2212
    };
2200 2213

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

	
2204 2217
    typedef typename ItemSetTraits<DGR, Edge>::ItemNotifier EdgeNotifier;
2205 2218
    EdgeNotifier& notifier(Edge) const { return _digraph->notifier(Edge()); }
2206
    
2219

	
2207 2220
    typedef EdgeNotifier ArcNotifier;
2208 2221
    ArcNotifier& notifier(Arc) const { return _digraph->notifier(Edge()); }
2209 2222

	
2210 2223
  protected:
2211 2224

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

	
2214 2227
    DGR* _digraph;
2215 2228

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

	
2220 2233
  };
2221 2234

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

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

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

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

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

	
2285 2301
      typedef typename MapTraits<FW>::ReturnValue ReturnValue;
2286 2302
      typedef typename MapTraits<FW>::ConstReturnValue ConstReturnValue;
2287 2303
      typedef typename MapTraits<FW>::ReturnValue Reference;
2288 2304
      typedef typename MapTraits<FW>::ConstReturnValue ConstReference;
2289 2305

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

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

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

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

	
2321 2337
    protected:
2322 2338

	
2323 2339
      FW* _forward;
2324 2340
      BK* _backward;
2325 2341

	
2326 2342
    };
2327 2343

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

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

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

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

	
2355 2371
  };
2356 2372

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

	
2367 2383

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

	
2372 2388
    typedef GR Graph;
2373 2389
    typedef DM DirectionMap;
2374 2390

	
2375 2391
    typedef typename GR::Node Node;
2376 2392
    typedef typename GR::Edge Arc;
2377 2393

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

	
2382 2398
    void first(Node& i) const { _graph->first(i); }
2383 2399
    void first(Arc& i) const { _graph->first(i); }
2384 2400
    void firstIn(Arc& i, const Node& n) const {
2385 2401
      bool d = true;
2386 2402
      _graph->firstInc(i, d, n);
2387 2403
      while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
2388 2404
    }
2389 2405
    void firstOut(Arc& i, const Node& n ) const {
2390 2406
      bool d = true;
2391 2407
      _graph->firstInc(i, d, n);
2392 2408
      while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
2393 2409
    }
2394 2410

	
2395 2411
    void next(Node& i) const { _graph->next(i); }
2396 2412
    void next(Arc& i) const { _graph->next(i); }
2397 2413
    void nextIn(Arc& i) const {
2398 2414
      bool d = !(*_direction)[i];
2399 2415
      _graph->nextInc(i, d);
2400 2416
      while (i != INVALID && d == (*_direction)[i]) _graph->nextInc(i, d);
2401 2417
    }
2402 2418
    void nextOut(Arc& i) const {
2403 2419
      bool d = (*_direction)[i];
2404 2420
      _graph->nextInc(i, d);
2405 2421
      while (i != INVALID && d != (*_direction)[i]) _graph->nextInc(i, d);
2406 2422
    }
2407 2423

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

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

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

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

	
2431 2447
    Node addNode() {
2432 2448
      return Node(_graph->addNode());
2433 2449
    }
2434 2450

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

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

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

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

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

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

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

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

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

	
2465 2481
    public:
2466 2482

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

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

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

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

	
2484 2500
    };
2485 2501

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

	
2490 2506
    public:
2491 2507

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

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

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

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

	
2510 2526

	
2511 2527

	
2512 2528
  protected:
2513 2529
    Graph* _graph;
2514 2530
    DM* _direction;
2515 2531

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

	
2521 2537
  };
2522 2538

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

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

	
2568 2587
    typedef typename Parent::Arc Arc;
2569 2588

	
2570 2589
  protected:
2571 2590
    Orienter() { }
2572 2591

	
2573 2592
  public:
2574 2593

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

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

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

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

	
2609 2628
  namespace _adaptor_bits {
2610 2629

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

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

	
2618 2637
    private:
2619 2638

	
2620 2639
      const CM* _capacity;
2621 2640
      const FM* _flow;
2622 2641
      TL _tolerance;
2623 2642

	
2624 2643
    public:
2625 2644

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

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

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

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

	
2642 2661
    private:
2643 2662

	
2644 2663
      const CM* _capacity;
2645 2664
      const FM* _flow;
2646 2665
      TL _tolerance;
2647 2666

	
2648 2667
    public:
2649 2668

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

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

	
2659 2678
  }
2660 2679

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

	
2721 2742
    /// The type of the underlying digraph.
2722 2743
    typedef DGR Digraph;
2723 2744
    /// The type of the capacity map.
2724 2745
    typedef CM CapacityMap;
2725 2746
    /// The type of the flow map.
2726 2747
    typedef FM FlowMap;
2727 2748
    /// The tolerance type.
2728 2749
    typedef TL Tolerance;
2729 2750

	
2730 2751
    typedef typename CapacityMap::Value Value;
2731 2752
    typedef ResidualDigraph Adaptor;
2732 2753

	
2733 2754
  protected:
2734 2755

	
2735 2756
    typedef Undirector<const Digraph> Undirected;
2736 2757

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

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

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

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

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

	
2750 2771
    const CapacityMap* _capacity;
2751 2772
    FlowMap* _flow;
2752 2773

	
2753 2774
    Undirected _graph;
2754 2775
    NodeFilter _node_filter;
2755 2776
    ForwardFilter _forward_filter;
2756 2777
    BackwardFilter _backward_filter;
2757 2778
    ArcFilter _arc_filter;
2758 2779

	
2759 2780
  public:
2760 2781

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

	
2776 2797
    typedef typename Parent::Arc Arc;
2777 2798

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

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

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

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

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

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

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

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

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

	
2857 2878
    };
2858 2879

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

	
2866 2887
  };
2867 2888

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

	
2879 2900

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

	
2884 2905
  public:
2885 2906

	
2886 2907
    typedef DGR Digraph;
2887 2908
    typedef SplitNodesBase Adaptor;
2888 2909

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

	
2892 2913
    class Node;
2893 2914
    class Arc;
2894 2915

	
2895 2916
  private:
2896 2917

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

	
2900 2921
  public:
2901 2922

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

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

	
2911 2932
    public:
2912 2933

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

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

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

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

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

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

	
2939 2960
      ArcImpl _item;
2940 2961

	
2941 2962
    public:
2942 2963
      Arc() {}
2943 2964
      Arc(Invalid) : _item(DigraphArc(INVALID)) {}
2944 2965

	
2945 2966
      bool operator==(const Arc& arc) const {
2946 2967
        if (_item.firstState()) {
2947 2968
          if (arc._item.firstState()) {
2948 2969
            return _item.first() == arc._item.first();
2949 2970
          }
2950 2971
        } else {
2951 2972
          if (arc._item.secondState()) {
2952 2973
            return _item.second() == arc._item.second();
2953 2974
          }
2954 2975
        }
2955 2976
        return false;
2956 2977
      }
2957 2978

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

	
2962 2983
      bool operator<(const Arc& arc) const {
2963 2984
        if (_item.firstState()) {
2964 2985
          if (arc._item.firstState()) {
2965 2986
            return _item.first() < arc._item.first();
2966 2987
          }
2967 2988
          return false;
2968 2989
        } else {
2969 2990
          if (arc._item.secondState()) {
2970 2991
            return _item.second() < arc._item.second();
2971 2992
          }
2972 2993
          return true;
2973 2994
        }
2974 2995
      }
2975 2996

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

	
2979 3000
    };
2980 3001

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

	
2986 3007
    void next(Node& n) const {
2987 3008
      if (n._in) {
2988 3009
        n._in = false;
2989 3010
      } else {
2990 3011
        n._in = true;
2991 3012
        _digraph->next(n);
2992 3013
      }
2993 3014
    }
2994 3015

	
2995 3016
    void first(Arc& e) const {
2996 3017
      e._item.setSecond();
2997 3018
      _digraph->first(e._item.second());
2998 3019
      if (e._item.second() == INVALID) {
2999 3020
        e._item.setFirst();
3000 3021
        _digraph->first(e._item.first());
3001 3022
      }
3002 3023
    }
3003 3024

	
3004 3025
    void next(Arc& e) const {
3005 3026
      if (e._item.secondState()) {
3006 3027
        _digraph->next(e._item.second());
3007 3028
        if (e._item.second() == INVALID) {
3008 3029
          e._item.setFirst();
3009 3030
          _digraph->first(e._item.first());
3010 3031
        }
3011 3032
      } else {
3012 3033
        _digraph->next(e._item.first());
3013 3034
      }
3014 3035
    }
3015 3036

	
3016 3037
    void firstOut(Arc& e, const Node& n) const {
3017 3038
      if (n._in) {
3018 3039
        e._item.setSecond(n);
3019 3040
      } else {
3020 3041
        e._item.setFirst();
3021 3042
        _digraph->firstOut(e._item.first(), n);
3022 3043
      }
3023 3044
    }
3024 3045

	
3025 3046
    void nextOut(Arc& e) const {
3026 3047
      if (!e._item.firstState()) {
3027 3048
        e._item.setFirst(INVALID);
3028 3049
      } else {
3029 3050
        _digraph->nextOut(e._item.first());
3030 3051
      }
3031 3052
    }
3032 3053

	
3033 3054
    void firstIn(Arc& e, const Node& n) const {
3034 3055
      if (!n._in) {
3035 3056
        e._item.setSecond(n);
3036 3057
      } else {
3037 3058
        e._item.setFirst();
3038 3059
        _digraph->firstIn(e._item.first(), n);
3039 3060
      }
3040 3061
    }
3041 3062

	
3042 3063
    void nextIn(Arc& e) const {
3043 3064
      if (!e._item.firstState()) {
3044 3065
        e._item.setFirst(INVALID);
3045 3066
      } else {
3046 3067
        _digraph->nextIn(e._item.first());
3047 3068
      }
3048 3069
    }
3049 3070

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

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

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

	
3076 3097
    int id(const Arc& e) const {
3077 3098
      if (e._item.firstState()) {
3078 3099
        return _digraph->id(e._item.first()) << 1;
3079 3100
      } else {
3080 3101
        return (_digraph->id(e._item.second()) << 1) | 1;
3081 3102
      }
3082 3103
    }
3083 3104
    Arc arcFromId(int ix) const {
3084 3105
      if ((ix & 1) == 0) {
3085 3106
        return Arc(_digraph->arcFromId(ix >> 1));
3086 3107
      } else {
3087 3108
        return Arc(_digraph->nodeFromId(ix >> 1));
3088 3109
      }
3089 3110
    }
3090 3111
    int maxArcId() const {
3091 3112
      return std::max(_digraph->maxNodeId() << 1,
3092 3113
                      (_digraph->maxArcId() << 1) | 1);
3093 3114
    }
3094 3115

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

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

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

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

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

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

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

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

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

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

	
3137 3158
    typedef True FindArcTag;
3138 3159
    Arc findArc(const Node& u, const Node& v,
3139 3160
                const Arc& prev = INVALID) const {
3140 3161
      if (inNode(u) && outNode(v)) {
3141 3162
        if (static_cast<const DigraphNode&>(u) ==
3142 3163
            static_cast<const DigraphNode&>(v) && prev == INVALID) {
3143 3164
          return Arc(u);
3144 3165
        }
3145 3166
      }
3146 3167
      else if (outNode(u) && inNode(v)) {
3147 3168
        return Arc(::lemon::findArc(*_digraph, u, v, prev));
3148 3169
      }
3149 3170
      return INVALID;
3150 3171
    }
3151 3172

	
3152 3173
  private:
3153 3174

	
3154 3175
    template <typename V>
3155 3176
    class NodeMapBase
3156 3177
      : public MapTraits<typename Parent::template NodeMap<V> > {
3157 3178
      typedef typename Parent::template NodeMap<V> NodeImpl;
3158 3179
    public:
3159 3180
      typedef Node Key;
3160 3181
      typedef V Value;
3161 3182
      typedef typename MapTraits<NodeImpl>::ReferenceMapTag ReferenceMapTag;
3162 3183
      typedef typename MapTraits<NodeImpl>::ReturnValue ReturnValue;
3163 3184
      typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReturnValue;
3164 3185
      typedef typename MapTraits<NodeImpl>::ReturnValue Reference;
3165 3186
      typedef typename MapTraits<NodeImpl>::ConstReturnValue ConstReference;
3166 3187

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

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

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

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

	
3188 3209
    private:
3189 3210
      NodeImpl _in_map, _out_map;
3190 3211
    };
3191 3212

	
3192 3213
    template <typename V>
3193 3214
    class ArcMapBase
3194 3215
      : public MapTraits<typename Parent::template ArcMap<V> > {
3195 3216
      typedef typename Parent::template ArcMap<V> ArcImpl;
3196 3217
      typedef typename Parent::template NodeMap<V> NodeImpl;
3197 3218
    public:
3198 3219
      typedef Arc Key;
3199 3220
      typedef V Value;
3200 3221
      typedef typename MapTraits<ArcImpl>::ReferenceMapTag ReferenceMapTag;
3201 3222
      typedef typename MapTraits<ArcImpl>::ReturnValue ReturnValue;
3202 3223
      typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReturnValue;
3203 3224
      typedef typename MapTraits<ArcImpl>::ReturnValue Reference;
3204 3225
      typedef typename MapTraits<ArcImpl>::ConstReturnValue ConstReference;
3205 3226

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

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

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

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

	
3236 3257
    private:
3237 3258
      ArcImpl _arc_map;
3238 3259
      NodeImpl _node_map;
3239 3260
    };
3240 3261

	
3241 3262
  public:
3242 3263

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

	
3248 3269
    public:
3249 3270
      typedef V Value;
3250 3271

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

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

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

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

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

	
3274 3295
    public:
3275 3296
      typedef V Value;
3276 3297

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

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

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

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

	
3295 3316
  protected:
3296 3317

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

	
3299 3320
    DGR* _digraph;
3300 3321

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

	
3305 3326
  };
3306 3327

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

	
3343 3367
  public:
3344 3368
    typedef DGR Digraph;
3345 3369

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

	
3349 3373
    typedef typename Parent::Node Node;
3350 3374
    typedef typename Parent::Arc Arc;
3351 3375

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

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

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

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

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

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

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

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

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

	
3421 3445
    /// \brief Node map combined from two original node maps
3422 3446
    ///
3423 3447
    /// This map adaptor class adapts two node maps of the original digraph
3424 3448
    /// to get a node map of the split digraph.
3425 3449
    /// 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. 
3450
    /// \tparam IN The type of the node map for the in-nodes.
3427 3451
    /// \tparam OUT The type of the node map for the out-nodes.
3428 3452
    template <typename IN, typename OUT>
3429 3453
    class CombinedNodeMap {
3430 3454
    public:
3431 3455

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

	
3437 3461
      typedef typename MapTraits<IN>::ReferenceMapTag ReferenceMapTag;
3438 3462
      typedef typename MapTraits<IN>::ReturnValue ReturnValue;
3439 3463
      typedef typename MapTraits<IN>::ConstReturnValue ConstReturnValue;
3440 3464
      typedef typename MapTraits<IN>::ReturnValue Reference;
3441 3465
      typedef typename MapTraits<IN>::ConstReturnValue ConstReference;
3442 3466

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

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

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

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

	
3474 3498
    private:
3475 3499

	
3476 3500
      IN& _in_map;
3477 3501
      OUT& _out_map;
3478 3502

	
3479 3503
    };
3480 3504

	
3481 3505

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

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

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

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

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

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

	
3526 3550
      typedef typename MapTraits<AM>::ReferenceMapTag ReferenceMapTag;
3527 3551
      typedef typename MapTraits<AM>::ReturnValue ReturnValue;
3528 3552
      typedef typename MapTraits<AM>::ConstReturnValue ConstReturnValue;
3529 3553
      typedef typename MapTraits<AM>::ReturnValue Reference;
3530 3554
      typedef typename MapTraits<AM>::ConstReturnValue ConstReference;
3531 3555

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

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

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

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

	
3563 3587
    private:
3564 3588

	
3565 3589
      AM& _arc_map;
3566 3590
      NM& _node_map;
3567 3591

	
3568 3592
    };
3569 3593

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

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

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

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

	
3597 3621
  };
3598 3622

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

	
3610 3634
#undef LEMON_SCOPE_FIX
3611 3635

	
3612 3636
} //namespace lemon
3613 3637

	
3614 3638
#endif //LEMON_ADAPTORS_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-2009
5
 * Copyright (C) 2003-2010
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
  void ArgParser::_terminate(ArgParserException::Reason reason) const
24
  {
25
    if(_exit_on_problems)
26
      exit(1);
27
    else throw(ArgParserException(reason));
28
  }
29

	
30

	
23 31
  void ArgParser::_showHelp(void *p)
24 32
  {
25 33
    (static_cast<ArgParser*>(p))->showHelp();
26
    exit(1);
34
    (static_cast<ArgParser*>(p))->_terminate(ArgParserException::HELP);
27 35
  }
28 36

	
29 37
  ArgParser::ArgParser(int argc, const char * const *argv)
30
    :_argc(argc), _argv(argv), _command_name(argv[0]) {
38
    :_argc(argc), _argv(argv), _command_name(argv[0]),
39
    _exit_on_problems(true) {
31 40
    funcOption("-help","Print a short help message",_showHelp,this);
32 41
    synonym("help","-help");
33 42
    synonym("h","-help");
34 43
  }
35 44

	
36 45
  ArgParser::~ArgParser()
37 46
  {
38 47
    for(Opts::iterator i=_opts.begin();i!=_opts.end();++i)
39 48
      if(i->second.self_delete)
40 49
        switch(i->second.type) {
41 50
        case BOOL:
42 51
          delete i->second.bool_p;
43 52
          break;
44 53
        case STRING:
45 54
          delete i->second.string_p;
46 55
          break;
47 56
        case DOUBLE:
48 57
          delete i->second.double_p;
49 58
          break;
50 59
        case INTEGER:
51 60
          delete i->second.int_p;
52 61
          break;
53 62
        case UNKNOWN:
54 63
          break;
55 64
        case FUNC:
56 65
          break;
57 66
        }
58 67
  }
59 68

	
60 69

	
61 70
  ArgParser &ArgParser::intOption(const std::string &name,
62 71
                               const std::string &help,
63 72
                               int value, bool obl)
64 73
  {
65 74
    ParData p;
66 75
    p.int_p=new int(value);
67 76
    p.self_delete=true;
68 77
    p.help=help;
69 78
    p.type=INTEGER;
70 79
    p.mandatory=obl;
71 80
    _opts[name]=p;
72 81
    return *this;
73 82
  }
74 83

	
75 84
  ArgParser &ArgParser::doubleOption(const std::string &name,
76 85
                               const std::string &help,
77 86
                               double value, bool obl)
78 87
  {
79 88
    ParData p;
80 89
    p.double_p=new double(value);
81 90
    p.self_delete=true;
82 91
    p.help=help;
83 92
    p.type=DOUBLE;
84 93
    p.mandatory=obl;
85 94
    _opts[name]=p;
86 95
    return *this;
87 96
  }
88 97

	
89 98
  ArgParser &ArgParser::boolOption(const std::string &name,
90 99
                               const std::string &help,
91 100
                               bool value, bool obl)
92 101
  {
93 102
    ParData p;
94 103
    p.bool_p=new bool(value);
95 104
    p.self_delete=true;
96 105
    p.help=help;
97 106
    p.type=BOOL;
98 107
    p.mandatory=obl;
99 108
    _opts[name]=p;
100 109
    return *this;
101 110
  }
102 111

	
103 112
  ArgParser &ArgParser::stringOption(const std::string &name,
104 113
                               const std::string &help,
105 114
                               std::string value, bool obl)
106 115
  {
107 116
    ParData p;
108 117
    p.string_p=new std::string(value);
109 118
    p.self_delete=true;
110 119
    p.help=help;
111 120
    p.type=STRING;
112 121
    p.mandatory=obl;
113 122
    _opts[name]=p;
114 123
    return *this;
115 124
  }
116 125

	
117 126
  ArgParser &ArgParser::refOption(const std::string &name,
118 127
                               const std::string &help,
119 128
                               int &ref, bool obl)
120 129
  {
121 130
    ParData p;
122 131
    p.int_p=&ref;
123 132
    p.self_delete=false;
124 133
    p.help=help;
125 134
    p.type=INTEGER;
126 135
    p.mandatory=obl;
127 136
    _opts[name]=p;
128 137
    return *this;
129 138
  }
130 139

	
131 140
  ArgParser &ArgParser::refOption(const std::string &name,
132 141
                                  const std::string &help,
133 142
                                  double &ref, bool obl)
134 143
  {
135 144
    ParData p;
136 145
    p.double_p=&ref;
137 146
    p.self_delete=false;
138 147
    p.help=help;
139 148
    p.type=DOUBLE;
140 149
    p.mandatory=obl;
141 150
    _opts[name]=p;
142 151
    return *this;
143 152
  }
144 153

	
145 154
  ArgParser &ArgParser::refOption(const std::string &name,
146 155
                                  const std::string &help,
147 156
                                  bool &ref, bool obl)
148 157
  {
149 158
    ParData p;
150 159
    p.bool_p=&ref;
151 160
    p.self_delete=false;
152 161
    p.help=help;
153 162
    p.type=BOOL;
154 163
    p.mandatory=obl;
155 164
    _opts[name]=p;
156 165

	
157 166
    ref = false;
158 167

	
159 168
    return *this;
160 169
  }
161 170

	
162 171
  ArgParser &ArgParser::refOption(const std::string &name,
163 172
                               const std::string &help,
164 173
                               std::string &ref, bool obl)
165 174
  {
166 175
    ParData p;
167 176
    p.string_p=&ref;
168 177
    p.self_delete=false;
169 178
    p.help=help;
170 179
    p.type=STRING;
171 180
    p.mandatory=obl;
172 181
    _opts[name]=p;
173 182
    return *this;
174 183
  }
175 184

	
176 185
  ArgParser &ArgParser::funcOption(const std::string &name,
177 186
                               const std::string &help,
178 187
                               void (*func)(void *),void *data)
179 188
  {
180 189
    ParData p;
181 190
    p.func_p.p=func;
182 191
    p.func_p.data=data;
183 192
    p.self_delete=false;
184 193
    p.help=help;
185 194
    p.type=FUNC;
186 195
    p.mandatory=false;
187 196
    _opts[name]=p;
188 197
    return *this;
189 198
  }
190 199

	
191 200
  ArgParser &ArgParser::optionGroup(const std::string &group,
192 201
                                    const std::string &opt)
193 202
  {
194 203
    Opts::iterator i = _opts.find(opt);
195 204
    LEMON_ASSERT(i!=_opts.end(), "Unknown option: '"+opt+"'");
196 205
    LEMON_ASSERT(!(i->second.ingroup),
197 206
                 "Option already in option group: '"+opt+"'");
198 207
    GroupData &g=_groups[group];
199 208
    g.opts.push_back(opt);
200 209
    i->second.ingroup=true;
201 210
    return *this;
202 211
  }
203 212

	
204 213
  ArgParser &ArgParser::onlyOneGroup(const std::string &group)
205 214
  {
206 215
    GroupData &g=_groups[group];
207 216
    g.only_one=true;
208 217
    return *this;
209 218
  }
210 219

	
211 220
  ArgParser &ArgParser::synonym(const std::string &syn,
212 221
                                const std::string &opt)
213 222
  {
214 223
    Opts::iterator o = _opts.find(opt);
215 224
    Opts::iterator s = _opts.find(syn);
216 225
    LEMON_ASSERT(o!=_opts.end(), "Unknown option: '"+opt+"'");
217 226
    LEMON_ASSERT(s==_opts.end(), "Option already used: '"+syn+"'");
218 227
    ParData p;
219 228
    p.help=opt;
220 229
    p.mandatory=false;
221 230
    p.syn=true;
222 231
    _opts[syn]=p;
223 232
    o->second.has_syn=true;
224 233
    return *this;
225 234
  }
226 235

	
227 236
  ArgParser &ArgParser::mandatoryGroup(const std::string &group)
228 237
  {
229 238
    GroupData &g=_groups[group];
230 239
    g.mandatory=true;
231 240
    return *this;
232 241
  }
233 242

	
234 243
  ArgParser &ArgParser::other(const std::string &name,
235 244
                              const std::string &help)
236 245
  {
237 246
    _others_help.push_back(OtherArg(name,help));
238 247
    return *this;
239 248
  }
240 249

	
241 250
  void ArgParser::show(std::ostream &os,Opts::const_iterator i) const
242 251
  {
243 252
    os << "-" << i->first;
244 253
    if(i->second.has_syn)
245 254
      for(Opts::const_iterator j=_opts.begin();j!=_opts.end();++j)
246 255
        if(j->second.syn&&j->second.help==i->first)
247 256
          os << "|-" << j->first;
248 257
    switch(i->second.type) {
249 258
    case STRING:
250 259
      os << " str";
251 260
      break;
252 261
    case INTEGER:
253 262
      os << " int";
254 263
      break;
255 264
    case DOUBLE:
256 265
      os << " num";
257 266
      break;
258 267
    default:
259 268
      break;
260 269
    }
261 270
  }
262 271

	
263 272
  void ArgParser::show(std::ostream &os,Groups::const_iterator i) const
264 273
  {
265 274
    GroupData::Opts::const_iterator o=i->second.opts.begin();
266 275
    while(o!=i->second.opts.end()) {
267 276
      show(os,_opts.find(*o));
268 277
      ++o;
269 278
      if(o!=i->second.opts.end()) os<<'|';
270 279
    }
271 280
  }
272 281

	
273 282
  void ArgParser::showHelp(Opts::const_iterator i) const
274 283
  {
275 284
    if(i->second.help.size()==0||i->second.syn) return;
276 285
    std::cerr << "  ";
277 286
    show(std::cerr,i);
278 287
    std::cerr << std::endl;
279 288
    std::cerr << "     " << i->second.help << std::endl;
280 289
  }
281 290
  void ArgParser::showHelp(std::vector<ArgParser::OtherArg>::const_iterator i)
282 291
    const
283 292
  {
284 293
    if(i->help.size()==0) return;
285 294
    std::cerr << "  " << i->name << std::endl
286 295
              << "     " << i->help << std::endl;
287 296
  }
288 297

	
289 298
  void ArgParser::shortHelp() const
290 299
  {
291 300
    const unsigned int LINE_LEN=77;
292 301
    const std::string indent("    ");
293 302
    std::cerr << "Usage:\n  " << _command_name;
294 303
    int pos=_command_name.size()+2;
295 304
    for(Groups::const_iterator g=_groups.begin();g!=_groups.end();++g) {
296 305
      std::ostringstream cstr;
297 306
      cstr << ' ';
298 307
      if(!g->second.mandatory) cstr << '[';
299 308
      show(cstr,g);
300 309
      if(!g->second.mandatory) cstr << ']';
301 310
      if(pos+cstr.str().size()>LINE_LEN) {
302 311
        std::cerr << std::endl << indent;
303 312
        pos=indent.size();
304 313
      }
305 314
      std::cerr << cstr.str();
306 315
      pos+=cstr.str().size();
307 316
    }
308 317
    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i)
309 318
      if(!i->second.ingroup&&!i->second.syn) {
310 319
        std::ostringstream cstr;
311 320
        cstr << ' ';
312 321
        if(!i->second.mandatory) cstr << '[';
313 322
        show(cstr,i);
314 323
        if(!i->second.mandatory) cstr << ']';
315 324
        if(pos+cstr.str().size()>LINE_LEN) {
316 325
          std::cerr << std::endl << indent;
317 326
          pos=indent.size();
318 327
        }
319 328
        std::cerr << cstr.str();
320 329
        pos+=cstr.str().size();
321 330
      }
322 331
    for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
323 332
        i!=_others_help.end();++i)
324 333
      {
325 334
        std::ostringstream cstr;
326 335
        cstr << ' ' << i->name;
327 336

	
328 337
        if(pos+cstr.str().size()>LINE_LEN) {
329 338
          std::cerr << std::endl << indent;
330 339
          pos=indent.size();
331 340
        }
332 341
        std::cerr << cstr.str();
333 342
        pos+=cstr.str().size();
334 343
      }
335 344
    std::cerr << std::endl;
336 345
  }
337 346

	
338 347
  void ArgParser::showHelp() const
339 348
  {
340 349
    shortHelp();
341 350
    std::cerr << "Where:\n";
342 351
    for(std::vector<OtherArg>::const_iterator i=_others_help.begin();
343 352
        i!=_others_help.end();++i) showHelp(i);
344 353
    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i) showHelp(i);
345
    exit(1);
354
    _terminate(ArgParserException::HELP);
346 355
  }
347 356

	
348 357

	
349 358
  void ArgParser::unknownOpt(std::string arg) const
350 359
  {
351 360
    std::cerr << "\nUnknown option: " << arg << "\n";
352 361
    std::cerr << "\nType '" << _command_name <<
353 362
      " --help' to obtain a short summary on the usage.\n\n";
354
    exit(1);
363
    _terminate(ArgParserException::UNKNOWN_OPT);
355 364
  }
356 365

	
357 366
  void ArgParser::requiresValue(std::string arg, OptType t) const
358 367
  {
359 368
    std::cerr << "Argument '" << arg << "' requires a";
360 369
    switch(t) {
361 370
    case STRING:
362 371
      std::cerr << " string";
363 372
      break;
364 373
    case INTEGER:
365 374
      std::cerr << "n integer";
366 375
      break;
367 376
    case DOUBLE:
368 377
      std::cerr << " floating point";
369 378
      break;
370 379
    default:
371 380
      break;
372 381
    }
373 382
    std::cerr << " value\n\n";
374 383
    showHelp();
375 384
  }
376 385

	
377 386

	
378 387
  void ArgParser::checkMandatories() const
379 388
  {
380 389
    bool ok=true;
381 390
    for(Opts::const_iterator i=_opts.begin();i!=_opts.end();++i)
382 391
      if(i->second.mandatory&&!i->second.set)
383 392
        {
384 393
          if(ok)
385 394
            std::cerr << _command_name
386 395
                      << ": The following mandatory arguments are missing.\n";
387 396
          ok=false;
388 397
          showHelp(i);
389 398
        }
390 399
    for(Groups::const_iterator i=_groups.begin();i!=_groups.end();++i)
391 400
      if(i->second.mandatory||i->second.only_one)
392 401
        {
393 402
          int set=0;
394 403
          for(GroupData::Opts::const_iterator o=i->second.opts.begin();
395 404
              o!=i->second.opts.end();++o)
396 405
            if(_opts.find(*o)->second.set) ++set;
397 406
          if(i->second.mandatory&&!set) {
398 407
            std::cerr << _command_name <<
399 408
              ": At least one of the following arguments is mandatory.\n";
400 409
            ok=false;
401 410
            for(GroupData::Opts::const_iterator o=i->second.opts.begin();
402 411
                o!=i->second.opts.end();++o)
403 412
              showHelp(_opts.find(*o));
404 413
          }
405 414
          if(i->second.only_one&&set>1) {
406 415
            std::cerr << _command_name <<
407 416
              ": At most one of the following arguments can be given.\n";
408 417
            ok=false;
409 418
            for(GroupData::Opts::const_iterator o=i->second.opts.begin();
410 419
                o!=i->second.opts.end();++o)
411 420
              showHelp(_opts.find(*o));
412 421
          }
413 422
        }
414 423
    if(!ok) {
415 424
      std::cerr << "\nType '" << _command_name <<
416 425
        " --help' to obtain a short summary on the usage.\n\n";
417
      exit(1);
426
      _terminate(ArgParserException::INVALID_OPT);
418 427
    }
419 428
  }
420 429

	
421 430
  ArgParser &ArgParser::parse()
422 431
  {
423 432
    for(int ar=1; ar<_argc; ++ar) {
424 433
      std::string arg(_argv[ar]);
425 434
      if (arg[0] != '-' || arg.size() == 1) {
426 435
        _file_args.push_back(arg);
427 436
      }
428 437
      else {
429 438
        Opts::iterator i = _opts.find(arg.substr(1));
430 439
        if(i==_opts.end()) unknownOpt(arg);
431 440
        else {
432 441
          if(i->second.syn) i=_opts.find(i->second.help);
433 442
          ParData &p(i->second);
434 443
          if (p.type==BOOL) *p.bool_p=true;
435 444
          else if (p.type==FUNC) p.func_p.p(p.func_p.data);
436 445
          else if(++ar==_argc) requiresValue(arg, p.type);
437 446
          else {
438 447
            std::string val(_argv[ar]);
439 448
            std::istringstream vals(val);
440 449
            switch(p.type) {
441 450
            case STRING:
442 451
              *p.string_p=val;
443 452
              break;
444 453
            case INTEGER:
445 454
              vals >> *p.int_p;
446 455
              break;
447 456
            case DOUBLE:
448 457
              vals >> *p.double_p;
449 458
              break;
450 459
            default:
451 460
              break;
452 461
            }
453 462
            if(p.type!=STRING&&(!vals||!vals.eof()))
454 463
              requiresValue(arg, p.type);
455 464
          }
456 465
          p.set = true;
457 466
        }
458 467
      }
459 468
    }
460 469
    checkMandatories();
461 470

	
462 471
    return *this;
463 472
  }
464 473

	
465 474
}
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-2009
5
 * Copyright (C) 2003-2010
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
  ///Exception used by ArgParser
38
  class ArgParserException : public Exception {
39
  public:
40
    enum Reason {
41
      HELP,         /// <tt>--help</tt> option was given
42
      UNKNOWN_OPT,  /// Unknown option was given
43
      INVALID_OPT   /// Invalid combination of options
44
    };
45

	
46
  private:
47
    Reason _reason;
48

	
49
  public:
50
    ///Constructor
51
    ArgParserException(Reason r) throw() : _reason(r) {}
52
    ///Virtual destructor
53
    virtual ~ArgParserException() throw() {}
54
    ///A short description of the exception
55
    virtual const char* what() const throw() {
56
      switch(_reason)
57
        {
58
        case HELP:
59
          return "lemon::ArgParseException: ask for help";
60
          break;
61
        case UNKNOWN_OPT:
62
          return "lemon::ArgParseException: unknown option";
63
          break;
64
        case INVALID_OPT:
65
          return "lemon::ArgParseException: invalid combination of options";
66
          break;
67
        }
68
      return "";
69
    }
70
    ///Return the reason for the failure
71
    Reason reason() const {return _reason; }
72
  };
73

	
74

	
37 75
  ///Command line arguments parser
38 76

	
39 77
  ///\ingroup misc
40 78
  ///Command line arguments parser.
41 79
  ///
42 80
  ///For a complete example see the \ref arg_parser_demo.cc demo file.
43 81
  class ArgParser {
44 82

	
45 83
    static void _showHelp(void *p);
46 84
  protected:
47 85

	
48 86
    int _argc;
49 87
    const char * const *_argv;
50 88

	
51 89
    enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
52 90

	
53 91
    class ParData {
54 92
    public:
55 93
      union {
56 94
        bool *bool_p;
57 95
        int *int_p;
58 96
        double *double_p;
59 97
        std::string *string_p;
60 98
        struct {
61 99
          void (*p)(void *);
62 100
          void *data;
63 101
        } func_p;
64 102

	
65 103
      };
66 104
      std::string help;
67 105
      bool mandatory;
68 106
      OptType type;
69 107
      bool set;
70 108
      bool ingroup;
71 109
      bool has_syn;
72 110
      bool syn;
73 111
      bool self_delete;
74 112
      ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
75 113
                  has_syn(false), syn(false), self_delete(false) {}
76 114
    };
77 115

	
78 116
    typedef std::map<std::string,ParData> Opts;
79 117
    Opts _opts;
80 118

	
81 119
    class GroupData
82 120
    {
83 121
    public:
84 122
      typedef std::list<std::string> Opts;
85 123
      Opts opts;
86 124
      bool only_one;
87 125
      bool mandatory;
88 126
      GroupData() :only_one(false), mandatory(false) {}
89 127
    };
90 128

	
91 129
    typedef std::map<std::string,GroupData> Groups;
92 130
    Groups _groups;
93 131

	
94 132
    struct OtherArg
95 133
    {
96 134
      std::string name;
97 135
      std::string help;
98 136
      OtherArg(std::string n, std::string h) :name(n), help(h) {}
99 137

	
100 138
    };
101 139

	
102 140
    std::vector<OtherArg> _others_help;
103 141
    std::vector<std::string> _file_args;
104 142
    std::string _command_name;
105 143

	
106 144

	
107 145
  private:
108 146
    //Bind a function to an option.
109 147

	
110 148
    //\param name The name of the option. The leading '-' must be omitted.
111 149
    //\param help A help string.
112 150
    //\retval func The function to be called when the option is given. It
113 151
    //  must be of type "void f(void *)"
114 152
    //\param data Data to be passed to \c func
115 153
    ArgParser &funcOption(const std::string &name,
116 154
                    const std::string &help,
117 155
                    void (*func)(void *),void *data);
118 156

	
157
    bool _exit_on_problems;
158

	
159
    void _terminate(ArgParserException::Reason reason) const;
160

	
119 161
  public:
120 162

	
121 163
    ///Constructor
122 164
    ArgParser(int argc, const char * const *argv);
123 165

	
124 166
    ~ArgParser();
125 167

	
126 168
    ///\name Options
127 169
    ///
128 170

	
129 171
    ///@{
130 172

	
131 173
    ///Add a new integer type option
132 174

	
133 175
    ///Add a new integer type option.
134 176
    ///\param name The name of the option. The leading '-' must be omitted.
135 177
    ///\param help A help string.
136 178
    ///\param value A default value for the option.
137 179
    ///\param obl Indicate if the option is mandatory.
138 180
    ArgParser &intOption(const std::string &name,
139 181
                    const std::string &help,
140 182
                    int value=0, bool obl=false);
141 183

	
142 184
    ///Add a new floating point type option
143 185

	
144 186
    ///Add a new floating point type option.
145 187
    ///\param name The name of the option. The leading '-' must be omitted.
146 188
    ///\param help A help string.
147 189
    ///\param value A default value for the option.
148 190
    ///\param obl Indicate if the option is mandatory.
149 191
    ArgParser &doubleOption(const std::string &name,
150 192
                      const std::string &help,
151 193
                      double value=0, bool obl=false);
152 194

	
153 195
    ///Add a new bool type option
154 196

	
155 197
    ///Add a new bool type option.
156 198
    ///\param name The name of the option. The leading '-' must be omitted.
157 199
    ///\param help A help string.
158 200
    ///\param value A default value for the option.
159 201
    ///\param obl Indicate if the option is mandatory.
160 202
    ///\note A mandatory bool obtion is of very little use.
161 203
    ArgParser &boolOption(const std::string &name,
162 204
                      const std::string &help,
163 205
                      bool value=false, bool obl=false);
164 206

	
165 207
    ///Add a new string type option
166 208

	
167 209
    ///Add a new string type option.
168 210
    ///\param name The name of the option. The leading '-' must be omitted.
169 211
    ///\param help A help string.
170 212
    ///\param value A default value for the option.
171 213
    ///\param obl Indicate if the option is mandatory.
172 214
    ArgParser &stringOption(const std::string &name,
173 215
                      const std::string &help,
174 216
                      std::string value="", bool obl=false);
175 217

	
176 218
    ///Give help string for non-parsed arguments.
177 219

	
178 220
    ///With this function you can give help string for non-parsed arguments.
179 221
    ///The parameter \c name will be printed in the short usage line, while
180 222
    ///\c help gives a more detailed description.
181 223
    ArgParser &other(const std::string &name,
182 224
                     const std::string &help="");
183 225

	
184 226
    ///@}
185 227

	
186 228
    ///\name Options with External Storage
187 229
    ///Using this functions, the value of the option will be directly written
188 230
    ///into a variable once the option appears in the command line.
189 231

	
190 232
    ///@{
191 233

	
192 234
    ///Add a new integer type option with a storage reference
193 235

	
194 236
    ///Add a new integer type option with a storage reference.
195 237
    ///\param name The name of the option. The leading '-' must be omitted.
196 238
    ///\param help A help string.
197 239
    ///\param obl Indicate if the option is mandatory.
198 240
    ///\retval ref The value of the argument will be written to this variable.
199 241
    ArgParser &refOption(const std::string &name,
200 242
                    const std::string &help,
201 243
                    int &ref, bool obl=false);
202 244

	
203 245
    ///Add a new floating type option with a storage reference
204 246

	
205 247
    ///Add a new floating type option with a storage reference.
206 248
    ///\param name The name of the option. The leading '-' must be omitted.
207 249
    ///\param help A help string.
208 250
    ///\param obl Indicate if the option is mandatory.
209 251
    ///\retval ref The value of the argument will be written to this variable.
210 252
    ArgParser &refOption(const std::string &name,
211 253
                      const std::string &help,
212 254
                      double &ref, bool obl=false);
213 255

	
214 256
    ///Add a new bool type option with a storage reference
215 257

	
216 258
    ///Add a new bool type option with a storage reference.
217 259
    ///\param name The name of the option. The leading '-' must be omitted.
218 260
    ///\param help A help string.
219 261
    ///\param obl Indicate if the option is mandatory.
220 262
    ///\retval ref The value of the argument will be written to this variable.
221 263
    ///\note A mandatory bool obtion is of very little use.
222 264
    ArgParser &refOption(const std::string &name,
223 265
                      const std::string &help,
224 266
                      bool &ref, bool obl=false);
225 267

	
226 268
    ///Add a new string type option with a storage reference
227 269

	
228 270
    ///Add a new string type option with a storage reference.
229 271
    ///\param name The name of the option. The leading '-' must be omitted.
230 272
    ///\param help A help string.
231 273
    ///\param obl Indicate if the option is mandatory.
232 274
    ///\retval ref The value of the argument will be written to this variable.
233 275
    ArgParser &refOption(const std::string &name,
234 276
                      const std::string &help,
235 277
                      std::string &ref, bool obl=false);
236 278

	
237 279
    ///@}
238 280

	
239 281
    ///\name Option Groups and Synonyms
240 282
    ///
241 283

	
242 284
    ///@{
243 285

	
244 286
    ///Bundle some options into a group
245 287

	
246 288
    /// You can group some option by calling this function repeatedly for each
247 289
    /// option to be grouped with the same groupname.
248 290
    ///\param group The group name.
249 291
    ///\param opt The option name.
250 292
    ArgParser &optionGroup(const std::string &group,
251 293
                           const std::string &opt);
252 294

	
253 295
    ///Make the members of a group exclusive
254 296

	
255 297
    ///If you call this function for a group, than at most one of them can be
256 298
    ///given at the same time.
257 299
    ArgParser &onlyOneGroup(const std::string &group);
258 300

	
259 301
    ///Make a group mandatory
260 302

	
261 303
    ///Using this function, at least one of the members of \c group
262 304
    ///must be given.
263 305
    ArgParser &mandatoryGroup(const std::string &group);
264 306

	
265 307
    ///Create synonym to an option
266 308

	
267 309
    ///With this function you can create a synonym \c syn of the
268 310
    ///option \c opt.
269 311
    ArgParser &synonym(const std::string &syn,
270 312
                           const std::string &opt);
271 313

	
272 314
    ///@}
273 315

	
274 316
  private:
275 317
    void show(std::ostream &os,Opts::const_iterator i) const;
276 318
    void show(std::ostream &os,Groups::const_iterator i) const;
277 319
    void showHelp(Opts::const_iterator i) const;
278 320
    void showHelp(std::vector<OtherArg>::const_iterator i) const;
279 321

	
280 322
    void unknownOpt(std::string arg) const;
281 323

	
282 324
    void requiresValue(std::string arg, OptType t) const;
283 325
    void checkMandatories() const;
284 326

	
285 327
    void shortHelp() const;
286 328
    void showHelp() const;
287 329
  public:
288 330

	
289 331
    ///Start the parsing process
290 332
    ArgParser &parse();
291 333

	
292 334
    /// Synonym for parse()
293 335
    ArgParser &run()
294 336
    {
295 337
      return parse();
296 338
    }
297 339

	
298 340
    ///Give back the command name (the 0th argument)
299 341
    const std::string &commandName() const { return _command_name; }
300 342

	
301 343
    ///Check if an opion has been given to the command.
302 344
    bool given(std::string op) const
303 345
    {
304 346
      Opts::const_iterator i = _opts.find(op);
305 347
      return i!=_opts.end()?i->second.set:false;
306 348
    }
307 349

	
308 350

	
309 351
    ///Magic type for operator[]
310 352

	
311 353
    ///This is the type of the return value of ArgParser::operator[]().
312 354
    ///It automatically converts to \c int, \c double, \c bool or
313 355
    ///\c std::string if the type of the option matches, which is checked
314 356
    ///with an \ref LEMON_ASSERT "assertion" (i.e. it performs runtime
315 357
    ///type checking).
316 358
    class RefType
317 359
    {
318 360
      const ArgParser &_parser;
319 361
      std::string _name;
320 362
    public:
321 363
      ///\e
322 364
      RefType(const ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
323 365
      ///\e
324 366
      operator bool()
325 367
      {
326 368
        Opts::const_iterator i = _parser._opts.find(_name);
327 369
        LEMON_ASSERT(i!=_parser._opts.end(),
328 370
                     std::string()+"Unkown option: '"+_name+"'");
329 371
        LEMON_ASSERT(i->second.type==ArgParser::BOOL,
330 372
                     std::string()+"'"+_name+"' is a bool option");
331 373
        return *(i->second.bool_p);
332 374
      }
333 375
      ///\e
334 376
      operator std::string()
335 377
      {
336 378
        Opts::const_iterator i = _parser._opts.find(_name);
337 379
        LEMON_ASSERT(i!=_parser._opts.end(),
338 380
                     std::string()+"Unkown option: '"+_name+"'");
339 381
        LEMON_ASSERT(i->second.type==ArgParser::STRING,
340 382
                     std::string()+"'"+_name+"' is a string option");
341 383
        return *(i->second.string_p);
342 384
      }
343 385
      ///\e
344 386
      operator double()
345 387
      {
346 388
        Opts::const_iterator i = _parser._opts.find(_name);
347 389
        LEMON_ASSERT(i!=_parser._opts.end(),
348 390
                     std::string()+"Unkown option: '"+_name+"'");
349 391
        LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
350 392
                     i->second.type==ArgParser::INTEGER,
351 393
                     std::string()+"'"+_name+"' is a floating point option");
352 394
        return i->second.type==ArgParser::DOUBLE ?
353 395
          *(i->second.double_p) : *(i->second.int_p);
354 396
      }
355 397
      ///\e
356 398
      operator int()
357 399
      {
358 400
        Opts::const_iterator i = _parser._opts.find(_name);
359 401
        LEMON_ASSERT(i!=_parser._opts.end(),
360 402
                     std::string()+"Unkown option: '"+_name+"'");
361 403
        LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
362 404
                     std::string()+"'"+_name+"' is an integer option");
363 405
        return *(i->second.int_p);
364 406
      }
365 407

	
366 408
    };
367 409

	
368 410
    ///Give back the value of an option
369 411

	
370 412
    ///Give back the value of an option.
371 413
    ///\sa RefType
372 414
    RefType operator[](const std::string &n) const
373 415
    {
374 416
      return RefType(*this, n);
375 417
    }
376 418

	
377 419
    ///Give back the non-option type arguments.
378 420

	
379 421
    ///Give back a reference to a vector consisting of the program arguments
380 422
    ///not starting with a '-' character.
381 423
    const std::vector<std::string> &files() const { return _file_args; }
382 424

	
425
    ///Throw instead of exit in case of problems
426
    void throwOnProblems()
427
    {
428
      _exit_on_problems=false;
429
    }
383 430
  };
384 431
}
385 432

	
386 433
#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-2009
5
 * Copyright (C) 2003-2010
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 52
    ///Instantiates a \c PredMap.
53 53

	
54 54
    ///This function instantiates a \ref PredMap.
55 55
    ///\param g is the digraph, to which we would like to define the
56 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 68
    ///Instantiates a \c ProcessedMap.
68 69

	
69 70
    ///This function instantiates a \ref ProcessedMap.
70 71
    ///\param g is the digraph, to which
71 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
86
    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
85 87
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
86 88
    ///Instantiates a \c ReachedMap.
87 89

	
88 90
    ///This function instantiates a \ref ReachedMap.
89 91
    ///\param g is the digraph, to which
90 92
    ///we would like to define the \ref ReachedMap.
91 93
    static ReachedMap *createReachedMap(const Digraph &g)
92 94
    {
93 95
      return new ReachedMap(g);
94 96
    }
95 97

	
96 98
    ///The type of the map that stores the distances of the nodes.
97 99

	
98 100
    ///The type of the map that stores the distances of the nodes.
99
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
101
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
100 102
    typedef typename Digraph::template NodeMap<int> DistMap;
101 103
    ///Instantiates a \c DistMap.
102 104

	
103 105
    ///This function instantiates a \ref DistMap.
104 106
    ///\param g is the digraph, to which we would like to define the
105 107
    ///\ref DistMap.
106 108
    static DistMap *createDistMap(const Digraph &g)
107 109
    {
108 110
      return new DistMap(g);
109 111
    }
110 112
  };
111 113

	
112 114
  ///%BFS algorithm class.
113 115

	
114 116
  ///\ingroup search
115 117
  ///This class provides an efficient implementation of the %BFS algorithm.
116 118
  ///
117 119
  ///There is also a \ref bfs() "function-type interface" for the BFS
118 120
  ///algorithm, which is convenient in the simplier cases and it can be
119 121
  ///used easier.
120 122
  ///
121 123
  ///\tparam GR The type of the digraph the algorithm runs on.
122 124
  ///The default type is \ref ListDigraph.
125
  ///\tparam TR The traits class that defines various types used by the
126
  ///algorithm. By default, it is \ref BfsDefaultTraits
127
  ///"BfsDefaultTraits<GR>".
128
  ///In most cases, this parameter should not be set directly,
129
  ///consider to use the named template parameters instead.
123 130
#ifdef DOXYGEN
124 131
  template <typename GR,
125 132
            typename TR>
126 133
#else
127 134
  template <typename GR=ListDigraph,
128 135
            typename TR=BfsDefaultTraits<GR> >
129 136
#endif
130 137
  class Bfs {
131 138
  public:
132 139

	
133 140
    ///The type of the digraph the algorithm runs on.
134 141
    typedef typename TR::Digraph Digraph;
135 142

	
136 143
    ///\brief The type of the map that stores the predecessor arcs of the
137 144
    ///shortest paths.
138 145
    typedef typename TR::PredMap PredMap;
139 146
    ///The type of the map that stores the distances of the nodes.
140 147
    typedef typename TR::DistMap DistMap;
141 148
    ///The type of the map that indicates which nodes are reached.
142 149
    typedef typename TR::ReachedMap ReachedMap;
143 150
    ///The type of the map that indicates which nodes are processed.
144 151
    typedef typename TR::ProcessedMap ProcessedMap;
145 152
    ///The type of the paths.
146 153
    typedef PredMapPath<Digraph, PredMap> Path;
147 154

	
148 155
    ///The \ref BfsDefaultTraits "traits class" of the algorithm.
149 156
    typedef TR Traits;
150 157

	
151 158
  private:
152 159

	
153 160
    typedef typename Digraph::Node Node;
154 161
    typedef typename Digraph::NodeIt NodeIt;
155 162
    typedef typename Digraph::Arc Arc;
156 163
    typedef typename Digraph::OutArcIt OutArcIt;
157 164

	
158 165
    //Pointer to the underlying digraph.
159 166
    const Digraph *G;
160 167
    //Pointer to the map of predecessor arcs.
161 168
    PredMap *_pred;
162 169
    //Indicates if _pred is locally allocated (true) or not.
163 170
    bool local_pred;
164 171
    //Pointer to the map of distances.
165 172
    DistMap *_dist;
166 173
    //Indicates if _dist is locally allocated (true) or not.
167 174
    bool local_dist;
168 175
    //Pointer to the map of reached status of the nodes.
169 176
    ReachedMap *_reached;
170 177
    //Indicates if _reached is locally allocated (true) or not.
171 178
    bool local_reached;
172 179
    //Pointer to the map of processed status of the nodes.
173 180
    ProcessedMap *_processed;
174 181
    //Indicates if _processed is locally allocated (true) or not.
175 182
    bool local_processed;
176 183

	
177 184
    std::vector<typename Digraph::Node> _queue;
178 185
    int _queue_head,_queue_tail,_queue_next_dist;
179 186
    int _curr_dist;
180 187

	
181 188
    //Creates the maps if necessary.
182 189
    void create_maps()
183 190
    {
184 191
      if(!_pred) {
185 192
        local_pred = true;
186 193
        _pred = Traits::createPredMap(*G);
187 194
      }
188 195
      if(!_dist) {
189 196
        local_dist = true;
190 197
        _dist = Traits::createDistMap(*G);
191 198
      }
192 199
      if(!_reached) {
193 200
        local_reached = true;
194 201
        _reached = Traits::createReachedMap(*G);
195 202
      }
196 203
      if(!_processed) {
197 204
        local_processed = true;
198 205
        _processed = Traits::createProcessedMap(*G);
199 206
      }
200 207
    }
201 208

	
202 209
  protected:
203 210

	
204 211
    Bfs() {}
205 212

	
206 213
  public:
207 214

	
208 215
    typedef Bfs Create;
209 216

	
210 217
    ///\name Named Template Parameters
211 218

	
212 219
    ///@{
213 220

	
214 221
    template <class T>
215 222
    struct SetPredMapTraits : public Traits {
216 223
      typedef T PredMap;
217 224
      static PredMap *createPredMap(const Digraph &)
218 225
      {
219 226
        LEMON_ASSERT(false, "PredMap is not initialized");
220 227
        return 0; // ignore warnings
221 228
      }
222 229
    };
223 230
    ///\brief \ref named-templ-param "Named parameter" for setting
224 231
    ///\c PredMap type.
225 232
    ///
226 233
    ///\ref named-templ-param "Named parameter" for setting
227 234
    ///\c PredMap type.
228
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
235
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
229 236
    template <class T>
230 237
    struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
231 238
      typedef Bfs< Digraph, SetPredMapTraits<T> > Create;
232 239
    };
233 240

	
234 241
    template <class T>
235 242
    struct SetDistMapTraits : public Traits {
236 243
      typedef T DistMap;
237 244
      static DistMap *createDistMap(const Digraph &)
238 245
      {
239 246
        LEMON_ASSERT(false, "DistMap is not initialized");
240 247
        return 0; // ignore warnings
241 248
      }
242 249
    };
243 250
    ///\brief \ref named-templ-param "Named parameter" for setting
244 251
    ///\c DistMap type.
245 252
    ///
246 253
    ///\ref named-templ-param "Named parameter" for setting
247 254
    ///\c DistMap type.
248
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
255
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
249 256
    template <class T>
250 257
    struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
251 258
      typedef Bfs< Digraph, SetDistMapTraits<T> > Create;
252 259
    };
253 260

	
254 261
    template <class T>
255 262
    struct SetReachedMapTraits : public Traits {
256 263
      typedef T ReachedMap;
257 264
      static ReachedMap *createReachedMap(const Digraph &)
258 265
      {
259 266
        LEMON_ASSERT(false, "ReachedMap is not initialized");
260 267
        return 0; // ignore warnings
261 268
      }
262 269
    };
263 270
    ///\brief \ref named-templ-param "Named parameter" for setting
264 271
    ///\c ReachedMap type.
265 272
    ///
266 273
    ///\ref named-templ-param "Named parameter" for setting
267 274
    ///\c ReachedMap type.
268
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
275
    ///It must conform to
276
    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
269 277
    template <class T>
270 278
    struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
271 279
      typedef Bfs< Digraph, SetReachedMapTraits<T> > Create;
272 280
    };
273 281

	
274 282
    template <class T>
275 283
    struct SetProcessedMapTraits : public Traits {
276 284
      typedef T ProcessedMap;
277 285
      static ProcessedMap *createProcessedMap(const Digraph &)
278 286
      {
279 287
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
280 288
        return 0; // ignore warnings
281 289
      }
282 290
    };
283 291
    ///\brief \ref named-templ-param "Named parameter" for setting
284 292
    ///\c ProcessedMap type.
285 293
    ///
286 294
    ///\ref named-templ-param "Named parameter" for setting
287 295
    ///\c ProcessedMap type.
288
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
296
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
289 297
    template <class T>
290 298
    struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
291 299
      typedef Bfs< Digraph, SetProcessedMapTraits<T> > Create;
292 300
    };
293 301

	
294 302
    struct SetStandardProcessedMapTraits : public Traits {
295 303
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
296 304
      static ProcessedMap *createProcessedMap(const Digraph &g)
297 305
      {
298 306
        return new ProcessedMap(g);
299 307
        return 0; // ignore warnings
300 308
      }
301 309
    };
302 310
    ///\brief \ref named-templ-param "Named parameter" for setting
303 311
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
304 312
    ///
305 313
    ///\ref named-templ-param "Named parameter" for setting
306 314
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
307 315
    ///If you don't set it explicitly, it will be automatically allocated.
308 316
    struct SetStandardProcessedMap :
309 317
      public Bfs< Digraph, SetStandardProcessedMapTraits > {
310 318
      typedef Bfs< Digraph, SetStandardProcessedMapTraits > Create;
311 319
    };
312 320

	
313 321
    ///@}
314 322

	
315 323
  public:
316 324

	
317 325
    ///Constructor.
318 326

	
319 327
    ///Constructor.
320 328
    ///\param g The digraph the algorithm runs on.
321 329
    Bfs(const Digraph &g) :
322 330
      G(&g),
323 331
      _pred(NULL), local_pred(false),
324 332
      _dist(NULL), local_dist(false),
325 333
      _reached(NULL), local_reached(false),
326 334
      _processed(NULL), local_processed(false)
327 335
    { }
328 336

	
329 337
    ///Destructor.
330 338
    ~Bfs()
331 339
    {
332 340
      if(local_pred) delete _pred;
333 341
      if(local_dist) delete _dist;
334 342
      if(local_reached) delete _reached;
335 343
      if(local_processed) delete _processed;
336 344
    }
337 345

	
338 346
    ///Sets the map that stores the predecessor arcs.
339 347

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

	
356 364
    ///Sets the map that indicates which nodes are reached.
357 365

	
358 366
    ///Sets the map that indicates which nodes are reached.
359 367
    ///If you don't use this function before calling \ref run(Node) "run()"
360 368
    ///or \ref init(), an instance will be allocated automatically.
361 369
    ///The destructor deallocates this automatically allocated map,
362 370
    ///of course.
363 371
    ///\return <tt> (*this) </tt>
364 372
    Bfs &reachedMap(ReachedMap &m)
365 373
    {
366 374
      if(local_reached) {
367 375
        delete _reached;
368 376
        local_reached=false;
369 377
      }
370 378
      _reached = &m;
371 379
      return *this;
372 380
    }
373 381

	
374 382
    ///Sets the map that indicates which nodes are processed.
375 383

	
376 384
    ///Sets the map that indicates which nodes are processed.
377 385
    ///If you don't use this function before calling \ref run(Node) "run()"
378 386
    ///or \ref init(), an instance will be allocated automatically.
379 387
    ///The destructor deallocates this automatically allocated map,
380 388
    ///of course.
381 389
    ///\return <tt> (*this) </tt>
382 390
    Bfs &processedMap(ProcessedMap &m)
383 391
    {
384 392
      if(local_processed) {
385 393
        delete _processed;
386 394
        local_processed=false;
387 395
      }
388 396
      _processed = &m;
389 397
      return *this;
390 398
    }
391 399

	
392 400
    ///Sets the map that stores the distances of the nodes.
393 401

	
394 402
    ///Sets the map that stores the distances of the nodes calculated by
395 403
    ///the algorithm.
396 404
    ///If you don't use this function before calling \ref run(Node) "run()"
397 405
    ///or \ref init(), an instance will be allocated automatically.
398 406
    ///The destructor deallocates this automatically allocated map,
399 407
    ///of course.
400 408
    ///\return <tt> (*this) </tt>
401 409
    Bfs &distMap(DistMap &m)
402 410
    {
403 411
      if(local_dist) {
404 412
        delete _dist;
405 413
        local_dist=false;
406 414
      }
407 415
      _dist = &m;
408 416
      return *this;
409 417
    }
410 418

	
411 419
  public:
412 420

	
413 421
    ///\name Execution Control
414 422
    ///The simplest way to execute the BFS algorithm is to use one of the
415 423
    ///member functions called \ref run(Node) "run()".\n
416
    ///If you need more control on the execution, first you have to call
417
    ///\ref init(), then you can add several source nodes with
424
    ///If you need better control on the execution, you have to call
425
    ///\ref init() first, then you can add several source nodes with
418 426
    ///\ref addSource(). Finally the actual path computation can be
419 427
    ///performed with one of the \ref start() functions.
420 428

	
421 429
    ///@{
422 430

	
423 431
    ///\brief Initializes the internal data structures.
424 432
    ///
425 433
    ///Initializes the internal data structures.
426 434
    void init()
427 435
    {
428 436
      create_maps();
429 437
      _queue.resize(countNodes(*G));
430 438
      _queue_head=_queue_tail=0;
431 439
      _curr_dist=1;
432 440
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
433 441
        _pred->set(u,INVALID);
434 442
        _reached->set(u,false);
435 443
        _processed->set(u,false);
436 444
      }
437 445
    }
438 446

	
439 447
    ///Adds a new source node.
440 448

	
441 449
    ///Adds a new source node to the set of nodes to be processed.
442 450
    ///
443 451
    void addSource(Node s)
444 452
    {
445 453
      if(!(*_reached)[s])
446 454
        {
447 455
          _reached->set(s,true);
448 456
          _pred->set(s,INVALID);
449 457
          _dist->set(s,0);
450 458
          _queue[_queue_head++]=s;
451 459
          _queue_next_dist=_queue_head;
452 460
        }
453 461
    }
454 462

	
455 463
    ///Processes the next node.
456 464

	
457 465
    ///Processes the next node.
458 466
    ///
459 467
    ///\return The processed node.
460 468
    ///
461 469
    ///\pre The queue must not be empty.
462 470
    Node processNextNode()
463 471
    {
464 472
      if(_queue_tail==_queue_next_dist) {
465 473
        _curr_dist++;
466 474
        _queue_next_dist=_queue_head;
467 475
      }
468 476
      Node n=_queue[_queue_tail++];
469 477
      _processed->set(n,true);
470 478
      Node m;
471 479
      for(OutArcIt e(*G,n);e!=INVALID;++e)
472 480
        if(!(*_reached)[m=G->target(e)]) {
473 481
          _queue[_queue_head++]=m;
474 482
          _reached->set(m,true);
475 483
          _pred->set(m,e);
476 484
          _dist->set(m,_curr_dist);
477 485
        }
478 486
      return n;
479 487
    }
480 488

	
481 489
    ///Processes the next node.
482 490

	
483 491
    ///Processes the next node and checks if the given target node
484 492
    ///is reached. If the target node is reachable from the processed
485 493
    ///node, then the \c reach parameter will be set to \c true.
486 494
    ///
487 495
    ///\param target The target node.
488 496
    ///\retval reach Indicates if the target node is reached.
489 497
    ///It should be initially \c false.
490 498
    ///
491 499
    ///\return The processed node.
492 500
    ///
493 501
    ///\pre The queue must not be empty.
494 502
    Node processNextNode(Node target, bool& reach)
495 503
    {
496 504
      if(_queue_tail==_queue_next_dist) {
497 505
        _curr_dist++;
498 506
        _queue_next_dist=_queue_head;
499 507
      }
500 508
      Node n=_queue[_queue_tail++];
501 509
      _processed->set(n,true);
502 510
      Node m;
503 511
      for(OutArcIt e(*G,n);e!=INVALID;++e)
504 512
        if(!(*_reached)[m=G->target(e)]) {
505 513
          _queue[_queue_head++]=m;
506 514
          _reached->set(m,true);
507 515
          _pred->set(m,e);
508 516
          _dist->set(m,_curr_dist);
509 517
          reach = reach || (target == m);
510 518
        }
511 519
      return n;
512 520
    }
513 521

	
514 522
    ///Processes the next node.
515 523

	
516 524
    ///Processes the next node and checks if at least one of reached
517 525
    ///nodes has \c true value in the \c nm node map. If one node
518 526
    ///with \c true value is reachable from the processed node, then the
519 527
    ///\c rnode parameter will be set to the first of such nodes.
520 528
    ///
521 529
    ///\param nm A \c bool (or convertible) node map that indicates the
522 530
    ///possible targets.
523 531
    ///\retval rnode The reached target node.
524 532
    ///It should be initially \c INVALID.
525 533
    ///
526 534
    ///\return The processed node.
527 535
    ///
528 536
    ///\pre The queue must not be empty.
529 537
    template<class NM>
530 538
    Node processNextNode(const NM& nm, Node& rnode)
531 539
    {
532 540
      if(_queue_tail==_queue_next_dist) {
533 541
        _curr_dist++;
534 542
        _queue_next_dist=_queue_head;
535 543
      }
536 544
      Node n=_queue[_queue_tail++];
537 545
      _processed->set(n,true);
538 546
      Node m;
539 547
      for(OutArcIt e(*G,n);e!=INVALID;++e)
540 548
        if(!(*_reached)[m=G->target(e)]) {
541 549
          _queue[_queue_head++]=m;
542 550
          _reached->set(m,true);
543 551
          _pred->set(m,e);
544 552
          _dist->set(m,_curr_dist);
545 553
          if (nm[m] && rnode == INVALID) rnode = m;
546 554
        }
547 555
      return n;
548 556
    }
549 557

	
550 558
    ///The next node to be processed.
551 559

	
552 560
    ///Returns the next node to be processed or \c INVALID if the queue
553 561
    ///is empty.
554 562
    Node nextNode() const
555 563
    {
556 564
      return _queue_tail<_queue_head?_queue[_queue_tail]:INVALID;
557 565
    }
558 566

	
559 567
    ///Returns \c false if there are nodes to be processed.
560 568

	
561 569
    ///Returns \c false if there are nodes to be processed
562 570
    ///in the queue.
563 571
    bool emptyQueue() const { return _queue_tail==_queue_head; }
564 572

	
565 573
    ///Returns the number of the nodes to be processed.
566 574

	
567 575
    ///Returns the number of the nodes to be processed
568 576
    ///in the queue.
569 577
    int queueSize() const { return _queue_head-_queue_tail; }
570 578

	
571 579
    ///Executes the algorithm.
572 580

	
573 581
    ///Executes the algorithm.
574 582
    ///
575 583
    ///This method runs the %BFS algorithm from the root node(s)
576 584
    ///in order to compute the shortest path to each node.
577 585
    ///
578 586
    ///The algorithm computes
579 587
    ///- the shortest path tree (forest),
580 588
    ///- the distance of each node from the root(s).
581 589
    ///
582 590
    ///\pre init() must be called and at least one root node should be
583 591
    ///added with addSource() before using this function.
584 592
    ///
585 593
    ///\note <tt>b.start()</tt> is just a shortcut of the following code.
586 594
    ///\code
587 595
    ///  while ( !b.emptyQueue() ) {
588 596
    ///    b.processNextNode();
589 597
    ///  }
590 598
    ///\endcode
591 599
    void start()
592 600
    {
593 601
      while ( !emptyQueue() ) processNextNode();
594 602
    }
595 603

	
596 604
    ///Executes the algorithm until the given target node is reached.
597 605

	
598 606
    ///Executes the algorithm until the given target node is reached.
599 607
    ///
600 608
    ///This method runs the %BFS algorithm from the root node(s)
601 609
    ///in order to compute the shortest path to \c t.
602 610
    ///
603 611
    ///The algorithm computes
604 612
    ///- the shortest path to \c t,
605 613
    ///- the distance of \c t from the root(s).
606 614
    ///
607 615
    ///\pre init() must be called and at least one root node should be
608 616
    ///added with addSource() before using this function.
609 617
    ///
610 618
    ///\note <tt>b.start(t)</tt> is just a shortcut of the following code.
611 619
    ///\code
612 620
    ///  bool reach = false;
613 621
    ///  while ( !b.emptyQueue() && !reach ) {
614 622
    ///    b.processNextNode(t, reach);
615 623
    ///  }
616 624
    ///\endcode
617 625
    void start(Node t)
618 626
    {
619 627
      bool reach = false;
620 628
      while ( !emptyQueue() && !reach ) processNextNode(t, reach);
621 629
    }
622 630

	
623 631
    ///Executes the algorithm until a condition is met.
624 632

	
625 633
    ///Executes the algorithm until a condition is met.
626 634
    ///
627 635
    ///This method runs the %BFS algorithm from the root node(s) in
628 636
    ///order to compute the shortest path to a node \c v with
629 637
    /// <tt>nm[v]</tt> true, if such a node can be found.
630 638
    ///
631 639
    ///\param nm A \c bool (or convertible) node map. The algorithm
632 640
    ///will stop when it reaches a node \c v with <tt>nm[v]</tt> true.
633 641
    ///
634 642
    ///\return The reached node \c v with <tt>nm[v]</tt> true or
635 643
    ///\c INVALID if no such node was found.
636 644
    ///
637 645
    ///\pre init() must be called and at least one root node should be
638 646
    ///added with addSource() before using this function.
639 647
    ///
640 648
    ///\note <tt>b.start(nm)</tt> is just a shortcut of the following code.
641 649
    ///\code
642 650
    ///  Node rnode = INVALID;
643 651
    ///  while ( !b.emptyQueue() && rnode == INVALID ) {
644 652
    ///    b.processNextNode(nm, rnode);
645 653
    ///  }
646 654
    ///  return rnode;
647 655
    ///\endcode
648 656
    template<class NodeBoolMap>
649 657
    Node start(const NodeBoolMap &nm)
650 658
    {
651 659
      Node rnode = INVALID;
652 660
      while ( !emptyQueue() && rnode == INVALID ) {
653 661
        processNextNode(nm, rnode);
654 662
      }
655 663
      return rnode;
656 664
    }
657 665

	
658 666
    ///Runs the algorithm from the given source node.
659 667

	
660 668
    ///This method runs the %BFS algorithm from node \c s
661 669
    ///in order to compute the shortest path to each node.
662 670
    ///
663 671
    ///The algorithm computes
664 672
    ///- the shortest path tree,
665 673
    ///- the distance of each node from the root.
666 674
    ///
667 675
    ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
668 676
    ///\code
669 677
    ///  b.init();
670 678
    ///  b.addSource(s);
671 679
    ///  b.start();
672 680
    ///\endcode
673 681
    void run(Node s) {
674 682
      init();
675 683
      addSource(s);
676 684
      start();
677 685
    }
678 686

	
679 687
    ///Finds the shortest path between \c s and \c t.
680 688

	
681 689
    ///This method runs the %BFS algorithm from node \c s
682 690
    ///in order to compute the shortest path to node \c t
683 691
    ///(it stops searching when \c t is processed).
684 692
    ///
685 693
    ///\return \c true if \c t is reachable form \c s.
686 694
    ///
687 695
    ///\note Apart from the return value, <tt>b.run(s,t)</tt> is just a
688 696
    ///shortcut of the following code.
689 697
    ///\code
690 698
    ///  b.init();
691 699
    ///  b.addSource(s);
692 700
    ///  b.start(t);
693 701
    ///\endcode
694 702
    bool run(Node s,Node t) {
695 703
      init();
696 704
      addSource(s);
697 705
      start(t);
698 706
      return reached(t);
699 707
    }
700 708

	
701 709
    ///Runs the algorithm to visit all nodes in the digraph.
702 710

	
703
    ///This method runs the %BFS algorithm in order to
704
    ///compute the shortest path to each node.
705
    ///
706
    ///The algorithm computes
707
    ///- the shortest path tree (forest),
708
    ///- the distance of each node from the root(s).
711
    ///This method runs the %BFS algorithm in order to visit all nodes
712
    ///in the digraph.
709 713
    ///
710 714
    ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
711 715
    ///\code
712 716
    ///  b.init();
713 717
    ///  for (NodeIt n(gr); n != INVALID; ++n) {
714 718
    ///    if (!b.reached(n)) {
715 719
    ///      b.addSource(n);
716 720
    ///      b.start();
717 721
    ///    }
718 722
    ///  }
719 723
    ///\endcode
720 724
    void run() {
721 725
      init();
722 726
      for (NodeIt n(*G); n != INVALID; ++n) {
723 727
        if (!reached(n)) {
724 728
          addSource(n);
725 729
          start();
726 730
        }
727 731
      }
728 732
    }
729 733

	
730 734
    ///@}
731 735

	
732 736
    ///\name Query Functions
733 737
    ///The results of the BFS algorithm can be obtained using these
734 738
    ///functions.\n
735 739
    ///Either \ref run(Node) "run()" or \ref start() should be called
736 740
    ///before using them.
737 741

	
738 742
    ///@{
739 743

	
740
    ///The shortest path to a node.
744
    ///The shortest path to the given node.
741 745

	
742
    ///Returns the shortest path to a node.
746
    ///Returns the shortest path to the given node from the root(s).
743 747
    ///
744 748
    ///\warning \c t should be reached from the root(s).
745 749
    ///
746 750
    ///\pre Either \ref run(Node) "run()" or \ref init()
747 751
    ///must be called before using this function.
748 752
    Path path(Node t) const { return Path(*G, *_pred, t); }
749 753

	
750
    ///The distance of a node from the root(s).
754
    ///The distance of the given node from the root(s).
751 755

	
752
    ///Returns the distance of a node from the root(s).
756
    ///Returns the distance of the given node from the root(s).
753 757
    ///
754 758
    ///\warning If node \c v is not reached from the root(s), then
755 759
    ///the return value of this function is undefined.
756 760
    ///
757 761
    ///\pre Either \ref run(Node) "run()" or \ref init()
758 762
    ///must be called before using this function.
759 763
    int dist(Node v) const { return (*_dist)[v]; }
760 764

	
761
    ///Returns the 'previous arc' of the shortest path tree for a node.
762

	
765
    ///\brief Returns the 'previous arc' of the shortest path tree for
766
    ///the given node.
767
    ///
763 768
    ///This function returns the 'previous arc' of the shortest path
764 769
    ///tree for the node \c v, i.e. it returns the last arc of a
765 770
    ///shortest path from a root to \c v. It is \c INVALID if \c v
766 771
    ///is not reached from the root(s) or if \c v is a root.
767 772
    ///
768 773
    ///The shortest path tree used here is equal to the shortest path
769
    ///tree used in \ref predNode().
774
    ///tree used in \ref predNode() and \ref predMap().
770 775
    ///
771 776
    ///\pre Either \ref run(Node) "run()" or \ref init()
772 777
    ///must be called before using this function.
773 778
    Arc predArc(Node v) const { return (*_pred)[v];}
774 779

	
775
    ///Returns the 'previous node' of the shortest path tree for a node.
776

	
780
    ///\brief Returns the 'previous node' of the shortest path tree for
781
    ///the given node.
782
    ///
777 783
    ///This function returns the 'previous node' of the shortest path
778 784
    ///tree for the node \c v, i.e. it returns the last but one node
779
    ///from a shortest path from a root to \c v. It is \c INVALID
785
    ///of a shortest path from a root to \c v. It is \c INVALID
780 786
    ///if \c v is not reached from the root(s) or if \c v is a root.
781 787
    ///
782 788
    ///The shortest path tree used here is equal to the shortest path
783
    ///tree used in \ref predArc().
789
    ///tree used in \ref predArc() and \ref predMap().
784 790
    ///
785 791
    ///\pre Either \ref run(Node) "run()" or \ref init()
786 792
    ///must be called before using this function.
787 793
    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
788 794
                                  G->source((*_pred)[v]); }
789 795

	
790 796
    ///\brief Returns a const reference to the node map that stores the
791 797
    /// distances of the nodes.
792 798
    ///
793 799
    ///Returns a const reference to the node map that stores the distances
794 800
    ///of the nodes calculated by the algorithm.
795 801
    ///
796 802
    ///\pre Either \ref run(Node) "run()" or \ref init()
797 803
    ///must be called before using this function.
798 804
    const DistMap &distMap() const { return *_dist;}
799 805

	
800 806
    ///\brief Returns a const reference to the node map that stores the
801 807
    ///predecessor arcs.
802 808
    ///
803 809
    ///Returns a const reference to the node map that stores the predecessor
804
    ///arcs, which form the shortest path tree.
810
    ///arcs, which form the shortest path tree (forest).
805 811
    ///
806 812
    ///\pre Either \ref run(Node) "run()" or \ref init()
807 813
    ///must be called before using this function.
808 814
    const PredMap &predMap() const { return *_pred;}
809 815

	
810
    ///Checks if a node is reached from the root(s).
816
    ///Checks if the given node is reached from the root(s).
811 817

	
812 818
    ///Returns \c true if \c v is reached from the root(s).
813 819
    ///
814 820
    ///\pre Either \ref run(Node) "run()" or \ref init()
815 821
    ///must be called before using this function.
816 822
    bool reached(Node v) const { return (*_reached)[v]; }
817 823

	
818 824
    ///@}
819 825
  };
820 826

	
821 827
  ///Default traits class of bfs() function.
822 828

	
823 829
  ///Default traits class of bfs() function.
824 830
  ///\tparam GR Digraph type.
825 831
  template<class GR>
826 832
  struct BfsWizardDefaultTraits
827 833
  {
828 834
    ///The type of the digraph the algorithm runs on.
829 835
    typedef GR Digraph;
830 836

	
831 837
    ///\brief The type of the map that stores the predecessor
832 838
    ///arcs of the shortest paths.
833 839
    ///
834 840
    ///The type of the map that stores the predecessor
835 841
    ///arcs of the shortest paths.
836
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
842
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
837 843
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
838 844
    ///Instantiates a PredMap.
839 845

	
840 846
    ///This function instantiates a PredMap.
841 847
    ///\param g is the digraph, to which we would like to define the
842 848
    ///PredMap.
843 849
    static PredMap *createPredMap(const Digraph &g)
844 850
    {
845 851
      return new PredMap(g);
846 852
    }
847 853

	
848 854
    ///The type of the map that indicates which nodes are processed.
849 855

	
850 856
    ///The type of the map that indicates which nodes are processed.
851
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
852
    ///By default it is a NullMap.
857
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
858
    ///By default, it is a NullMap.
853 859
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
854 860
    ///Instantiates a ProcessedMap.
855 861

	
856 862
    ///This function instantiates a ProcessedMap.
857 863
    ///\param g is the digraph, to which
858 864
    ///we would like to define the ProcessedMap.
859 865
#ifdef DOXYGEN
860 866
    static ProcessedMap *createProcessedMap(const Digraph &g)
861 867
#else
862 868
    static ProcessedMap *createProcessedMap(const Digraph &)
863 869
#endif
864 870
    {
865 871
      return new ProcessedMap();
866 872
    }
867 873

	
868 874
    ///The type of the map that indicates which nodes are reached.
869 875

	
870 876
    ///The type of the map that indicates which nodes are reached.
871
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
877
    ///It must conform to
878
    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
872 879
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
873 880
    ///Instantiates a ReachedMap.
874 881

	
875 882
    ///This function instantiates a ReachedMap.
876 883
    ///\param g is the digraph, to which
877 884
    ///we would like to define the ReachedMap.
878 885
    static ReachedMap *createReachedMap(const Digraph &g)
879 886
    {
880 887
      return new ReachedMap(g);
881 888
    }
882 889

	
883 890
    ///The type of the map that stores the distances of the nodes.
884 891

	
885 892
    ///The type of the map that stores the distances of the nodes.
886
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
893
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
887 894
    typedef typename Digraph::template NodeMap<int> DistMap;
888 895
    ///Instantiates a DistMap.
889 896

	
890 897
    ///This function instantiates a DistMap.
891 898
    ///\param g is the digraph, to which we would like to define
892 899
    ///the DistMap
893 900
    static DistMap *createDistMap(const Digraph &g)
894 901
    {
895 902
      return new DistMap(g);
896 903
    }
897 904

	
898 905
    ///The type of the shortest paths.
899 906

	
900 907
    ///The type of the shortest paths.
901
    ///It must meet the \ref concepts::Path "Path" concept.
908
    ///It must conform to the \ref concepts::Path "Path" concept.
902 909
    typedef lemon::Path<Digraph> Path;
903 910
  };
904 911

	
905 912
  /// Default traits class used by BfsWizard
906 913

	
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.
914
  /// Default traits class used by BfsWizard.
915
  /// \tparam GR The type of the digraph.
913 916
  template<class GR>
914 917
  class BfsWizardBase : public BfsWizardDefaultTraits<GR>
915 918
  {
916 919

	
917 920
    typedef BfsWizardDefaultTraits<GR> Base;
918 921
  protected:
919 922
    //The type of the nodes in the digraph.
920 923
    typedef typename Base::Digraph::Node Node;
921 924

	
922 925
    //Pointer to the digraph the algorithm runs on.
923 926
    void *_g;
924 927
    //Pointer to the map of reached nodes.
925 928
    void *_reached;
926 929
    //Pointer to the map of processed nodes.
927 930
    void *_processed;
928 931
    //Pointer to the map of predecessors arcs.
929 932
    void *_pred;
930 933
    //Pointer to the map of distances.
931 934
    void *_dist;
932 935
    //Pointer to the shortest path to the target node.
933 936
    void *_path;
934 937
    //Pointer to the distance of the target node.
935 938
    int *_di;
936 939

	
937 940
    public:
938 941
    /// Constructor.
939 942

	
940
    /// This constructor does not require parameters, therefore it initiates
943
    /// This constructor does not require parameters, it initiates
941 944
    /// all of the attributes to \c 0.
942 945
    BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
943 946
                      _dist(0), _path(0), _di(0) {}
944 947

	
945 948
    /// Constructor.
946 949

	
947 950
    /// This constructor requires one parameter,
948 951
    /// others are initiated to \c 0.
949 952
    /// \param g The digraph the algorithm runs on.
950 953
    BfsWizardBase(const GR &g) :
951 954
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
952 955
      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
953 956

	
954 957
  };
955 958

	
956 959
  /// Auxiliary class for the function-type interface of BFS algorithm.
957 960

	
958 961
  /// This auxiliary class is created to implement the
959 962
  /// \ref bfs() "function-type interface" of \ref Bfs algorithm.
960 963
  /// It does not have own \ref run(Node) "run()" method, it uses the
961 964
  /// functions and features of the plain \ref Bfs.
962 965
  ///
963 966
  /// This class should only be used through the \ref bfs() function,
964 967
  /// which makes it easier to use the algorithm.
968
  ///
969
  /// \tparam TR The traits class that defines various types used by the
970
  /// algorithm.
965 971
  template<class TR>
966 972
  class BfsWizard : public TR
967 973
  {
968 974
    typedef TR Base;
969 975

	
970
    ///The type of the digraph the algorithm runs on.
971 976
    typedef typename TR::Digraph Digraph;
972 977

	
973 978
    typedef typename Digraph::Node Node;
974 979
    typedef typename Digraph::NodeIt NodeIt;
975 980
    typedef typename Digraph::Arc Arc;
976 981
    typedef typename Digraph::OutArcIt OutArcIt;
977 982

	
978
    ///\brief The type of the map that stores the predecessor
979
    ///arcs of the shortest paths.
980 983
    typedef typename TR::PredMap PredMap;
981
    ///\brief The type of the map that stores the distances of the nodes.
982 984
    typedef typename TR::DistMap DistMap;
983
    ///\brief The type of the map that indicates which nodes are reached.
984 985
    typedef typename TR::ReachedMap ReachedMap;
985
    ///\brief The type of the map that indicates which nodes are processed.
986 986
    typedef typename TR::ProcessedMap ProcessedMap;
987
    ///The type of the shortest paths
988 987
    typedef typename TR::Path Path;
989 988

	
990 989
  public:
991 990

	
992 991
    /// Constructor.
993 992
    BfsWizard() : TR() {}
994 993

	
995 994
    /// Constructor that requires parameters.
996 995

	
997 996
    /// Constructor that requires parameters.
998 997
    /// These parameters will be the default values for the traits class.
999 998
    /// \param g The digraph the algorithm runs on.
1000 999
    BfsWizard(const Digraph &g) :
1001 1000
      TR(g) {}
1002 1001

	
1003 1002
    ///Copy constructor
1004 1003
    BfsWizard(const TR &b) : TR(b) {}
1005 1004

	
1006 1005
    ~BfsWizard() {}
1007 1006

	
1008 1007
    ///Runs BFS algorithm from the given source node.
1009 1008

	
1010 1009
    ///This method runs BFS algorithm from node \c s
1011 1010
    ///in order to compute the shortest path to each node.
1012 1011
    void run(Node s)
1013 1012
    {
1014 1013
      Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
1015 1014
      if (Base::_pred)
1016 1015
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1017 1016
      if (Base::_dist)
1018 1017
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1019 1018
      if (Base::_reached)
1020 1019
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
1021 1020
      if (Base::_processed)
1022 1021
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1023 1022
      if (s!=INVALID)
1024 1023
        alg.run(s);
1025 1024
      else
1026 1025
        alg.run();
1027 1026
    }
1028 1027

	
1029 1028
    ///Finds the shortest path between \c s and \c t.
1030 1029

	
1031 1030
    ///This method runs BFS algorithm from node \c s
1032 1031
    ///in order to compute the shortest path to node \c t
1033 1032
    ///(it stops searching when \c t is processed).
1034 1033
    ///
1035 1034
    ///\return \c true if \c t is reachable form \c s.
1036 1035
    bool run(Node s, Node t)
1037 1036
    {
1038 1037
      Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
1039 1038
      if (Base::_pred)
1040 1039
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1041 1040
      if (Base::_dist)
1042 1041
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1043 1042
      if (Base::_reached)
1044 1043
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
1045 1044
      if (Base::_processed)
1046 1045
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1047 1046
      alg.run(s,t);
1048 1047
      if (Base::_path)
1049 1048
        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
1050 1049
      if (Base::_di)
1051 1050
        *Base::_di = alg.dist(t);
1052 1051
      return alg.reached(t);
1053 1052
    }
1054 1053

	
1055 1054
    ///Runs BFS algorithm to visit all nodes in the digraph.
1056 1055

	
1057
    ///This method runs BFS algorithm in order to compute
1058
    ///the shortest path to each node.
1056
    ///This method runs BFS algorithm in order to visit all nodes
1057
    ///in the digraph.
1059 1058
    void run()
1060 1059
    {
1061 1060
      run(INVALID);
1062 1061
    }
1063 1062

	
1064 1063
    template<class T>
1065 1064
    struct SetPredMapBase : public Base {
1066 1065
      typedef T PredMap;
1067 1066
      static PredMap *createPredMap(const Digraph &) { return 0; };
1068 1067
      SetPredMapBase(const TR &b) : TR(b) {}
1069 1068
    };
1070
    ///\brief \ref named-func-param "Named parameter"
1071
    ///for setting PredMap object.
1069

	
1070
    ///\brief \ref named-templ-param "Named parameter" for setting
1071
    ///the predecessor map.
1072 1072
    ///
1073
    ///\ref named-func-param "Named parameter"
1074
    ///for setting PredMap object.
1073
    ///\ref named-templ-param "Named parameter" function for setting
1074
    ///the map that stores the predecessor arcs of the nodes.
1075 1075
    template<class T>
1076 1076
    BfsWizard<SetPredMapBase<T> > predMap(const T &t)
1077 1077
    {
1078 1078
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1079 1079
      return BfsWizard<SetPredMapBase<T> >(*this);
1080 1080
    }
1081 1081

	
1082 1082
    template<class T>
1083 1083
    struct SetReachedMapBase : public Base {
1084 1084
      typedef T ReachedMap;
1085 1085
      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
1086 1086
      SetReachedMapBase(const TR &b) : TR(b) {}
1087 1087
    };
1088
    ///\brief \ref named-func-param "Named parameter"
1089
    ///for setting ReachedMap object.
1088

	
1089
    ///\brief \ref named-templ-param "Named parameter" for setting
1090
    ///the reached map.
1090 1091
    ///
1091
    /// \ref named-func-param "Named parameter"
1092
    ///for setting ReachedMap object.
1092
    ///\ref named-templ-param "Named parameter" function for setting
1093
    ///the map that indicates which nodes are reached.
1093 1094
    template<class T>
1094 1095
    BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
1095 1096
    {
1096 1097
      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
1097 1098
      return BfsWizard<SetReachedMapBase<T> >(*this);
1098 1099
    }
1099 1100

	
1100 1101
    template<class T>
1101 1102
    struct SetDistMapBase : public Base {
1102 1103
      typedef T DistMap;
1103 1104
      static DistMap *createDistMap(const Digraph &) { return 0; };
1104 1105
      SetDistMapBase(const TR &b) : TR(b) {}
1105 1106
    };
1106
    ///\brief \ref named-func-param "Named parameter"
1107
    ///for setting DistMap object.
1107

	
1108
    ///\brief \ref named-templ-param "Named parameter" for setting
1109
    ///the distance map.
1108 1110
    ///
1109
    /// \ref named-func-param "Named parameter"
1110
    ///for setting DistMap object.
1111
    ///\ref named-templ-param "Named parameter" function for setting
1112
    ///the map that stores the distances of the nodes calculated
1113
    ///by the algorithm.
1111 1114
    template<class T>
1112 1115
    BfsWizard<SetDistMapBase<T> > distMap(const T &t)
1113 1116
    {
1114 1117
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1115 1118
      return BfsWizard<SetDistMapBase<T> >(*this);
1116 1119
    }
1117 1120

	
1118 1121
    template<class T>
1119 1122
    struct SetProcessedMapBase : public Base {
1120 1123
      typedef T ProcessedMap;
1121 1124
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1122 1125
      SetProcessedMapBase(const TR &b) : TR(b) {}
1123 1126
    };
1124
    ///\brief \ref named-func-param "Named parameter"
1125
    ///for setting ProcessedMap object.
1127

	
1128
    ///\brief \ref named-func-param "Named parameter" for setting
1129
    ///the processed map.
1126 1130
    ///
1127
    /// \ref named-func-param "Named parameter"
1128
    ///for setting ProcessedMap object.
1131
    ///\ref named-templ-param "Named parameter" function for setting
1132
    ///the map that indicates which nodes are processed.
1129 1133
    template<class T>
1130 1134
    BfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
1131 1135
    {
1132 1136
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1133 1137
      return BfsWizard<SetProcessedMapBase<T> >(*this);
1134 1138
    }
1135 1139

	
1136 1140
    template<class T>
1137 1141
    struct SetPathBase : public Base {
1138 1142
      typedef T Path;
1139 1143
      SetPathBase(const TR &b) : TR(b) {}
1140 1144
    };
1141 1145
    ///\brief \ref named-func-param "Named parameter"
1142 1146
    ///for getting the shortest path to the target node.
1143 1147
    ///
1144 1148
    ///\ref named-func-param "Named parameter"
1145 1149
    ///for getting the shortest path to the target node.
1146 1150
    template<class T>
1147 1151
    BfsWizard<SetPathBase<T> > path(const T &t)
1148 1152
    {
1149 1153
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1150 1154
      return BfsWizard<SetPathBase<T> >(*this);
1151 1155
    }
1152 1156

	
1153 1157
    ///\brief \ref named-func-param "Named parameter"
1154 1158
    ///for getting the distance of the target node.
1155 1159
    ///
1156 1160
    ///\ref named-func-param "Named parameter"
1157 1161
    ///for getting the distance of the target node.
1158 1162
    BfsWizard dist(const int &d)
1159 1163
    {
1160 1164
      Base::_di=const_cast<int*>(&d);
1161 1165
      return *this;
1162 1166
    }
1163 1167

	
1164 1168
  };
1165 1169

	
1166 1170
  ///Function-type interface for BFS algorithm.
1167 1171

	
1168 1172
  /// \ingroup search
1169 1173
  ///Function-type interface for BFS algorithm.
1170 1174
  ///
1171 1175
  ///This function also has several \ref named-func-param "named parameters",
1172 1176
  ///they are declared as the members of class \ref BfsWizard.
1173 1177
  ///The following examples show how to use these parameters.
1174 1178
  ///\code
1175 1179
  ///  // Compute shortest path from node s to each node
1176 1180
  ///  bfs(g).predMap(preds).distMap(dists).run(s);
1177 1181
  ///
1178 1182
  ///  // Compute shortest path from s to t
1179 1183
  ///  bool reached = bfs(g).path(p).dist(d).run(s,t);
1180 1184
  ///\endcode
1181 1185
  ///\warning Don't forget to put the \ref BfsWizard::run(Node) "run()"
1182 1186
  ///to the end of the parameter list.
1183 1187
  ///\sa BfsWizard
1184 1188
  ///\sa Bfs
1185 1189
  template<class GR>
1186 1190
  BfsWizard<BfsWizardBase<GR> >
1187 1191
  bfs(const GR &digraph)
1188 1192
  {
1189 1193
    return BfsWizard<BfsWizardBase<GR> >(digraph);
1190 1194
  }
1191 1195

	
1192 1196
#ifdef DOXYGEN
1193 1197
  /// \brief Visitor class for BFS.
1194 1198
  ///
1195 1199
  /// This class defines the interface of the BfsVisit events, and
1196 1200
  /// it could be the base of a real visitor class.
1197 1201
  template <typename GR>
1198 1202
  struct BfsVisitor {
1199 1203
    typedef GR Digraph;
1200 1204
    typedef typename Digraph::Arc Arc;
1201 1205
    typedef typename Digraph::Node Node;
1202 1206
    /// \brief Called for the source node(s) of the BFS.
1203 1207
    ///
1204 1208
    /// This function is called for the source node(s) of the BFS.
1205 1209
    void start(const Node& node) {}
1206 1210
    /// \brief Called when a node is reached first time.
1207 1211
    ///
1208 1212
    /// This function is called when a node is reached first time.
1209 1213
    void reach(const Node& node) {}
1210 1214
    /// \brief Called when a node is processed.
1211 1215
    ///
1212 1216
    /// This function is called when a node is processed.
1213 1217
    void process(const Node& node) {}
1214 1218
    /// \brief Called when an arc reaches a new node.
1215 1219
    ///
1216 1220
    /// This function is called when the BFS finds an arc whose target node
1217 1221
    /// is not reached yet.
1218 1222
    void discover(const Arc& arc) {}
1219 1223
    /// \brief Called when an arc is examined but its target node is
1220 1224
    /// already discovered.
1221 1225
    ///
1222 1226
    /// This function is called when an arc is examined but its target node is
1223 1227
    /// already discovered.
1224 1228
    void examine(const Arc& arc) {}
1225 1229
  };
1226 1230
#else
1227 1231
  template <typename GR>
1228 1232
  struct BfsVisitor {
1229 1233
    typedef GR Digraph;
1230 1234
    typedef typename Digraph::Arc Arc;
1231 1235
    typedef typename Digraph::Node Node;
1232 1236
    void start(const Node&) {}
1233 1237
    void reach(const Node&) {}
1234 1238
    void process(const Node&) {}
1235 1239
    void discover(const Arc&) {}
1236 1240
    void examine(const Arc&) {}
1237 1241

	
1238 1242
    template <typename _Visitor>
1239 1243
    struct Constraints {
1240 1244
      void constraints() {
1241 1245
        Arc arc;
1242 1246
        Node node;
1243 1247
        visitor.start(node);
1244 1248
        visitor.reach(node);
1245 1249
        visitor.process(node);
1246 1250
        visitor.discover(arc);
1247 1251
        visitor.examine(arc);
1248 1252
      }
1249 1253
      _Visitor& visitor;
1250 1254
    };
1251 1255
  };
1252 1256
#endif
1253 1257

	
1254 1258
  /// \brief Default traits class of BfsVisit class.
1255 1259
  ///
1256 1260
  /// Default traits class of BfsVisit class.
1257 1261
  /// \tparam GR The type of the digraph the algorithm runs on.
1258 1262
  template<class GR>
1259 1263
  struct BfsVisitDefaultTraits {
1260 1264

	
1261 1265
    /// \brief The type of the digraph the algorithm runs on.
1262 1266
    typedef GR Digraph;
1263 1267

	
1264 1268
    /// \brief The type of the map that indicates which nodes are reached.
1265 1269
    ///
1266 1270
    /// The type of the map that indicates which nodes are reached.
1267
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1271
    /// It must conform to
1272
    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1268 1273
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
1269 1274

	
1270 1275
    /// \brief Instantiates a ReachedMap.
1271 1276
    ///
1272 1277
    /// This function instantiates a ReachedMap.
1273 1278
    /// \param digraph is the digraph, to which
1274 1279
    /// we would like to define the ReachedMap.
1275 1280
    static ReachedMap *createReachedMap(const Digraph &digraph) {
1276 1281
      return new ReachedMap(digraph);
1277 1282
    }
1278 1283

	
1279 1284
  };
1280 1285

	
1281 1286
  /// \ingroup search
1282 1287
  ///
1283 1288
  /// \brief BFS algorithm class with visitor interface.
1284 1289
  ///
1285 1290
  /// This class provides an efficient implementation of the BFS algorithm
1286 1291
  /// with visitor interface.
1287 1292
  ///
1288 1293
  /// The BfsVisit class provides an alternative interface to the Bfs
1289 1294
  /// class. It works with callback mechanism, the BfsVisit object calls
1290 1295
  /// the member functions of the \c Visitor class on every BFS event.
1291 1296
  ///
1292 1297
  /// This interface of the BFS algorithm should be used in special cases
1293 1298
  /// when extra actions have to be performed in connection with certain
1294 1299
  /// events of the BFS algorithm. Otherwise consider to use Bfs or bfs()
1295 1300
  /// instead.
1296 1301
  ///
1297 1302
  /// \tparam GR The type of the digraph the algorithm runs on.
1298 1303
  /// The default type is \ref ListDigraph.
1299 1304
  /// The value of GR is not used directly by \ref BfsVisit,
1300 1305
  /// it is only passed to \ref BfsVisitDefaultTraits.
1301 1306
  /// \tparam VS The Visitor type that is used by the algorithm.
1302 1307
  /// \ref BfsVisitor "BfsVisitor<GR>" is an empty visitor, which
1303 1308
  /// does not observe the BFS events. If you want to observe the BFS
1304 1309
  /// events, you should implement your own visitor class.
1305
  /// \tparam TR Traits class to set various data types used by the
1306
  /// algorithm. The default traits class is
1307
  /// \ref BfsVisitDefaultTraits "BfsVisitDefaultTraits<GR>".
1308
  /// See \ref BfsVisitDefaultTraits for the documentation of
1309
  /// a BFS visit traits class.
1310
  /// \tparam TR The traits class that defines various types used by the
1311
  /// algorithm. By default, it is \ref BfsVisitDefaultTraits
1312
  /// "BfsVisitDefaultTraits<GR>".
1313
  /// In most cases, this parameter should not be set directly,
1314
  /// consider to use the named template parameters instead.
1310 1315
#ifdef DOXYGEN
1311 1316
  template <typename GR, typename VS, typename TR>
1312 1317
#else
1313 1318
  template <typename GR = ListDigraph,
1314 1319
            typename VS = BfsVisitor<GR>,
1315 1320
            typename TR = BfsVisitDefaultTraits<GR> >
1316 1321
#endif
1317 1322
  class BfsVisit {
1318 1323
  public:
1319 1324

	
1320 1325
    ///The traits class.
1321 1326
    typedef TR Traits;
1322 1327

	
1323 1328
    ///The type of the digraph the algorithm runs on.
1324 1329
    typedef typename Traits::Digraph Digraph;
1325 1330

	
1326 1331
    ///The visitor type used by the algorithm.
1327 1332
    typedef VS Visitor;
1328 1333

	
1329 1334
    ///The type of the map that indicates which nodes are reached.
1330 1335
    typedef typename Traits::ReachedMap ReachedMap;
1331 1336

	
1332 1337
  private:
1333 1338

	
1334 1339
    typedef typename Digraph::Node Node;
1335 1340
    typedef typename Digraph::NodeIt NodeIt;
1336 1341
    typedef typename Digraph::Arc Arc;
1337 1342
    typedef typename Digraph::OutArcIt OutArcIt;
1338 1343

	
1339 1344
    //Pointer to the underlying digraph.
1340 1345
    const Digraph *_digraph;
1341 1346
    //Pointer to the visitor object.
1342 1347
    Visitor *_visitor;
1343 1348
    //Pointer to the map of reached status of the nodes.
1344 1349
    ReachedMap *_reached;
1345 1350
    //Indicates if _reached is locally allocated (true) or not.
1346 1351
    bool local_reached;
1347 1352

	
1348 1353
    std::vector<typename Digraph::Node> _list;
1349 1354
    int _list_front, _list_back;
1350 1355

	
1351 1356
    //Creates the maps if necessary.
1352 1357
    void create_maps() {
1353 1358
      if(!_reached) {
1354 1359
        local_reached = true;
1355 1360
        _reached = Traits::createReachedMap(*_digraph);
1356 1361
      }
1357 1362
    }
1358 1363

	
1359 1364
  protected:
1360 1365

	
1361 1366
    BfsVisit() {}
1362 1367

	
1363 1368
  public:
1364 1369

	
1365 1370
    typedef BfsVisit Create;
1366 1371

	
1367 1372
    /// \name Named Template Parameters
1368 1373

	
1369 1374
    ///@{
1370 1375
    template <class T>
1371 1376
    struct SetReachedMapTraits : public Traits {
1372 1377
      typedef T ReachedMap;
1373 1378
      static ReachedMap *createReachedMap(const Digraph &digraph) {
1374 1379
        LEMON_ASSERT(false, "ReachedMap is not initialized");
1375 1380
        return 0; // ignore warnings
1376 1381
      }
1377 1382
    };
1378 1383
    /// \brief \ref named-templ-param "Named parameter" for setting
1379 1384
    /// ReachedMap type.
1380 1385
    ///
1381 1386
    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
1382 1387
    template <class T>
1383 1388
    struct SetReachedMap : public BfsVisit< Digraph, Visitor,
1384 1389
                                            SetReachedMapTraits<T> > {
1385 1390
      typedef BfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
1386 1391
    };
1387 1392
    ///@}
1388 1393

	
1389 1394
  public:
1390 1395

	
1391 1396
    /// \brief Constructor.
1392 1397
    ///
1393 1398
    /// Constructor.
1394 1399
    ///
1395 1400
    /// \param digraph The digraph the algorithm runs on.
1396 1401
    /// \param visitor The visitor object of the algorithm.
1397 1402
    BfsVisit(const Digraph& digraph, Visitor& visitor)
1398 1403
      : _digraph(&digraph), _visitor(&visitor),
1399 1404
        _reached(0), local_reached(false) {}
1400 1405

	
1401 1406
    /// \brief Destructor.
1402 1407
    ~BfsVisit() {
1403 1408
      if(local_reached) delete _reached;
1404 1409
    }
1405 1410

	
1406 1411
    /// \brief Sets the map that indicates which nodes are reached.
1407 1412
    ///
1408 1413
    /// Sets the map that indicates which nodes are reached.
1409 1414
    /// If you don't use this function before calling \ref run(Node) "run()"
1410 1415
    /// or \ref init(), an instance will be allocated automatically.
1411 1416
    /// The destructor deallocates this automatically allocated map,
1412 1417
    /// of course.
1413 1418
    /// \return <tt> (*this) </tt>
1414 1419
    BfsVisit &reachedMap(ReachedMap &m) {
1415 1420
      if(local_reached) {
1416 1421
        delete _reached;
1417 1422
        local_reached = false;
1418 1423
      }
1419 1424
      _reached = &m;
1420 1425
      return *this;
1421 1426
    }
1422 1427

	
1423 1428
  public:
1424 1429

	
1425 1430
    /// \name Execution Control
1426 1431
    /// The simplest way to execute the BFS algorithm is to use one of the
1427 1432
    /// member functions called \ref run(Node) "run()".\n
1428
    /// If you need more control on the execution, first you have to call
1429
    /// \ref init(), then you can add several source nodes with
1433
    /// If you need better control on the execution, you have to call
1434
    /// \ref init() first, then you can add several source nodes with
1430 1435
    /// \ref addSource(). Finally the actual path computation can be
1431 1436
    /// performed with one of the \ref start() functions.
1432 1437

	
1433 1438
    /// @{
1434 1439

	
1435 1440
    /// \brief Initializes the internal data structures.
1436 1441
    ///
1437 1442
    /// Initializes the internal data structures.
1438 1443
    void init() {
1439 1444
      create_maps();
1440 1445
      _list.resize(countNodes(*_digraph));
1441 1446
      _list_front = _list_back = -1;
1442 1447
      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
1443 1448
        _reached->set(u, false);
1444 1449
      }
1445 1450
    }
1446 1451

	
1447 1452
    /// \brief Adds a new source node.
1448 1453
    ///
1449 1454
    /// Adds a new source node to the set of nodes to be processed.
1450 1455
    void addSource(Node s) {
1451 1456
      if(!(*_reached)[s]) {
1452 1457
          _reached->set(s,true);
1453 1458
          _visitor->start(s);
1454 1459
          _visitor->reach(s);
1455 1460
          _list[++_list_back] = s;
1456 1461
        }
1457 1462
    }
1458 1463

	
1459 1464
    /// \brief Processes the next node.
1460 1465
    ///
1461 1466
    /// Processes the next node.
1462 1467
    ///
1463 1468
    /// \return The processed node.
1464 1469
    ///
1465 1470
    /// \pre The queue must not be empty.
1466 1471
    Node processNextNode() {
1467 1472
      Node n = _list[++_list_front];
1468 1473
      _visitor->process(n);
1469 1474
      Arc e;
1470 1475
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1471 1476
        Node m = _digraph->target(e);
1472 1477
        if (!(*_reached)[m]) {
1473 1478
          _visitor->discover(e);
1474 1479
          _visitor->reach(m);
1475 1480
          _reached->set(m, true);
1476 1481
          _list[++_list_back] = m;
1477 1482
        } else {
1478 1483
          _visitor->examine(e);
1479 1484
        }
1480 1485
      }
1481 1486
      return n;
1482 1487
    }
1483 1488

	
1484 1489
    /// \brief Processes the next node.
1485 1490
    ///
1486 1491
    /// Processes the next node and checks if the given target node
1487 1492
    /// is reached. If the target node is reachable from the processed
1488 1493
    /// node, then the \c reach parameter will be set to \c true.
1489 1494
    ///
1490 1495
    /// \param target The target node.
1491 1496
    /// \retval reach Indicates if the target node is reached.
1492 1497
    /// It should be initially \c false.
1493 1498
    ///
1494 1499
    /// \return The processed node.
1495 1500
    ///
1496 1501
    /// \pre The queue must not be empty.
1497 1502
    Node processNextNode(Node target, bool& reach) {
1498 1503
      Node n = _list[++_list_front];
1499 1504
      _visitor->process(n);
1500 1505
      Arc e;
1501 1506
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1502 1507
        Node m = _digraph->target(e);
1503 1508
        if (!(*_reached)[m]) {
1504 1509
          _visitor->discover(e);
1505 1510
          _visitor->reach(m);
1506 1511
          _reached->set(m, true);
1507 1512
          _list[++_list_back] = m;
1508 1513
          reach = reach || (target == m);
1509 1514
        } else {
1510 1515
          _visitor->examine(e);
1511 1516
        }
1512 1517
      }
1513 1518
      return n;
1514 1519
    }
1515 1520

	
1516 1521
    /// \brief Processes the next node.
1517 1522
    ///
1518 1523
    /// Processes the next node and checks if at least one of reached
1519 1524
    /// nodes has \c true value in the \c nm node map. If one node
1520 1525
    /// with \c true value is reachable from the processed node, then the
1521 1526
    /// \c rnode parameter will be set to the first of such nodes.
1522 1527
    ///
1523 1528
    /// \param nm A \c bool (or convertible) node map that indicates the
1524 1529
    /// possible targets.
1525 1530
    /// \retval rnode The reached target node.
1526 1531
    /// It should be initially \c INVALID.
1527 1532
    ///
1528 1533
    /// \return The processed node.
1529 1534
    ///
1530 1535
    /// \pre The queue must not be empty.
1531 1536
    template <typename NM>
1532 1537
    Node processNextNode(const NM& nm, Node& rnode) {
1533 1538
      Node n = _list[++_list_front];
1534 1539
      _visitor->process(n);
1535 1540
      Arc e;
1536 1541
      for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
1537 1542
        Node m = _digraph->target(e);
1538 1543
        if (!(*_reached)[m]) {
1539 1544
          _visitor->discover(e);
1540 1545
          _visitor->reach(m);
1541 1546
          _reached->set(m, true);
1542 1547
          _list[++_list_back] = m;
1543 1548
          if (nm[m] && rnode == INVALID) rnode = m;
1544 1549
        } else {
1545 1550
          _visitor->examine(e);
1546 1551
        }
1547 1552
      }
1548 1553
      return n;
1549 1554
    }
1550 1555

	
1551 1556
    /// \brief The next node to be processed.
1552 1557
    ///
1553 1558
    /// Returns the next node to be processed or \c INVALID if the queue
1554 1559
    /// is empty.
1555 1560
    Node nextNode() const {
1556 1561
      return _list_front != _list_back ? _list[_list_front + 1] : INVALID;
1557 1562
    }
1558 1563

	
1559 1564
    /// \brief Returns \c false if there are nodes
1560 1565
    /// to be processed.
1561 1566
    ///
1562 1567
    /// Returns \c false if there are nodes
1563 1568
    /// to be processed in the queue.
1564 1569
    bool emptyQueue() const { return _list_front == _list_back; }
1565 1570

	
1566 1571
    /// \brief Returns the number of the nodes to be processed.
1567 1572
    ///
1568 1573
    /// Returns the number of the nodes to be processed in the queue.
1569 1574
    int queueSize() const { return _list_back - _list_front; }
1570 1575

	
1571 1576
    /// \brief Executes the algorithm.
1572 1577
    ///
1573 1578
    /// Executes the algorithm.
1574 1579
    ///
1575 1580
    /// This method runs the %BFS algorithm from the root node(s)
1576 1581
    /// in order to compute the shortest path to each node.
1577 1582
    ///
1578 1583
    /// The algorithm computes
1579 1584
    /// - the shortest path tree (forest),
1580 1585
    /// - the distance of each node from the root(s).
1581 1586
    ///
1582 1587
    /// \pre init() must be called and at least one root node should be added
1583 1588
    /// with addSource() before using this function.
1584 1589
    ///
1585 1590
    /// \note <tt>b.start()</tt> is just a shortcut of the following code.
1586 1591
    /// \code
1587 1592
    ///   while ( !b.emptyQueue() ) {
1588 1593
    ///     b.processNextNode();
1589 1594
    ///   }
1590 1595
    /// \endcode
1591 1596
    void start() {
1592 1597
      while ( !emptyQueue() ) processNextNode();
1593 1598
    }
1594 1599

	
1595 1600
    /// \brief Executes the algorithm until the given target node is reached.
1596 1601
    ///
1597 1602
    /// Executes the algorithm until the given target node is reached.
1598 1603
    ///
1599 1604
    /// This method runs the %BFS algorithm from the root node(s)
1600 1605
    /// in order to compute the shortest path to \c t.
1601 1606
    ///
1602 1607
    /// The algorithm computes
1603 1608
    /// - the shortest path to \c t,
1604 1609
    /// - the distance of \c t from the root(s).
1605 1610
    ///
1606 1611
    /// \pre init() must be called and at least one root node should be
1607 1612
    /// added with addSource() before using this function.
1608 1613
    ///
1609 1614
    /// \note <tt>b.start(t)</tt> is just a shortcut of the following code.
1610 1615
    /// \code
1611 1616
    ///   bool reach = false;
1612 1617
    ///   while ( !b.emptyQueue() && !reach ) {
1613 1618
    ///     b.processNextNode(t, reach);
1614 1619
    ///   }
1615 1620
    /// \endcode
1616 1621
    void start(Node t) {
1617 1622
      bool reach = false;
1618 1623
      while ( !emptyQueue() && !reach ) processNextNode(t, reach);
1619 1624
    }
1620 1625

	
1621 1626
    /// \brief Executes the algorithm until a condition is met.
1622 1627
    ///
1623 1628
    /// Executes the algorithm until a condition is met.
1624 1629
    ///
1625 1630
    /// This method runs the %BFS algorithm from the root node(s) in
1626 1631
    /// order to compute the shortest path to a node \c v with
1627 1632
    /// <tt>nm[v]</tt> true, if such a node can be found.
1628 1633
    ///
1629 1634
    /// \param nm must be a bool (or convertible) node map. The
1630 1635
    /// algorithm will stop when it reaches a node \c v with
1631 1636
    /// <tt>nm[v]</tt> true.
1632 1637
    ///
1633 1638
    /// \return The reached node \c v with <tt>nm[v]</tt> true or
1634 1639
    /// \c INVALID if no such node was found.
1635 1640
    ///
1636 1641
    /// \pre init() must be called and at least one root node should be
1637 1642
    /// added with addSource() before using this function.
1638 1643
    ///
1639 1644
    /// \note <tt>b.start(nm)</tt> is just a shortcut of the following code.
1640 1645
    /// \code
1641 1646
    ///   Node rnode = INVALID;
1642 1647
    ///   while ( !b.emptyQueue() && rnode == INVALID ) {
1643 1648
    ///     b.processNextNode(nm, rnode);
1644 1649
    ///   }
1645 1650
    ///   return rnode;
1646 1651
    /// \endcode
1647 1652
    template <typename NM>
1648 1653
    Node start(const NM &nm) {
1649 1654
      Node rnode = INVALID;
1650 1655
      while ( !emptyQueue() && rnode == INVALID ) {
1651 1656
        processNextNode(nm, rnode);
1652 1657
      }
1653 1658
      return rnode;
1654 1659
    }
1655 1660

	
1656 1661
    /// \brief Runs the algorithm from the given source node.
1657 1662
    ///
1658 1663
    /// This method runs the %BFS algorithm from node \c s
1659 1664
    /// in order to compute the shortest path to each node.
1660 1665
    ///
1661 1666
    /// The algorithm computes
1662 1667
    /// - the shortest path tree,
1663 1668
    /// - the distance of each node from the root.
1664 1669
    ///
1665 1670
    /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
1666 1671
    ///\code
1667 1672
    ///   b.init();
1668 1673
    ///   b.addSource(s);
1669 1674
    ///   b.start();
1670 1675
    ///\endcode
1671 1676
    void run(Node s) {
1672 1677
      init();
1673 1678
      addSource(s);
1674 1679
      start();
1675 1680
    }
1676 1681

	
1677 1682
    /// \brief Finds the shortest path between \c s and \c t.
1678 1683
    ///
1679 1684
    /// This method runs the %BFS algorithm from node \c s
1680 1685
    /// in order to compute the shortest path to node \c t
1681 1686
    /// (it stops searching when \c t is processed).
1682 1687
    ///
1683 1688
    /// \return \c true if \c t is reachable form \c s.
1684 1689
    ///
1685 1690
    /// \note Apart from the return value, <tt>b.run(s,t)</tt> is just a
1686 1691
    /// shortcut of the following code.
1687 1692
    ///\code
1688 1693
    ///   b.init();
1689 1694
    ///   b.addSource(s);
1690 1695
    ///   b.start(t);
1691 1696
    ///\endcode
1692 1697
    bool run(Node s,Node t) {
1693 1698
      init();
1694 1699
      addSource(s);
1695 1700
      start(t);
1696 1701
      return reached(t);
1697 1702
    }
1698 1703

	
1699 1704
    /// \brief Runs the algorithm to visit all nodes in the digraph.
1700 1705
    ///
1701
    /// This method runs the %BFS algorithm in order to
1702
    /// compute the shortest path to each node.
1703
    ///
1704
    /// The algorithm computes
1705
    /// - the shortest path tree (forest),
1706
    /// - the distance of each node from the root(s).
1706
    /// This method runs the %BFS algorithm in order to visit all nodes
1707
    /// in the digraph.
1707 1708
    ///
1708 1709
    /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
1709 1710
    ///\code
1710 1711
    ///  b.init();
1711 1712
    ///  for (NodeIt n(gr); n != INVALID; ++n) {
1712 1713
    ///    if (!b.reached(n)) {
1713 1714
    ///      b.addSource(n);
1714 1715
    ///      b.start();
1715 1716
    ///    }
1716 1717
    ///  }
1717 1718
    ///\endcode
1718 1719
    void run() {
1719 1720
      init();
1720 1721
      for (NodeIt it(*_digraph); it != INVALID; ++it) {
1721 1722
        if (!reached(it)) {
1722 1723
          addSource(it);
1723 1724
          start();
1724 1725
        }
1725 1726
      }
1726 1727
    }
1727 1728

	
1728 1729
    ///@}
1729 1730

	
1730 1731
    /// \name Query Functions
1731 1732
    /// The results of the BFS algorithm can be obtained using these
1732 1733
    /// functions.\n
1733 1734
    /// Either \ref run(Node) "run()" or \ref start() should be called
1734 1735
    /// before using them.
1735 1736

	
1736 1737
    ///@{
1737 1738

	
1738
    /// \brief Checks if a node is reached from the root(s).
1739
    /// \brief Checks if the given node is reached from the root(s).
1739 1740
    ///
1740 1741
    /// Returns \c true if \c v is reached from the root(s).
1741 1742
    ///
1742 1743
    /// \pre Either \ref run(Node) "run()" or \ref init()
1743 1744
    /// must be called before using this function.
1744 1745
    bool reached(Node v) const { return (*_reached)[v]; }
1745 1746

	
1746 1747
    ///@}
1747 1748

	
1748 1749
  };
1749 1750

	
1750 1751
} //END OF NAMESPACE LEMON
1751 1752

	
1752 1753
#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 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.
36
  /// This class implements the \e binary \e heap data structure.
37
  /// It fully conforms to the \ref concepts::Heap "heap concept".
37 38
  ///
38
  ///A \e heap is a data structure for storing items with specified values
39
  ///called \e priorities in such a way that finding the item with minimum
40
  ///priority is efficient. \c CMP specifies the ordering of the priorities.
41
  ///In a heap one can change the priority of an item, add or erase an
42
  ///item, etc.
43
  ///
44
  ///\tparam PR Type of the priority of the items.
45
  ///\tparam IM A read and writable item map with int values, used internally
46
  ///to handle the cross references.
47
  ///\tparam CMP A functor class for the ordering of the priorities.
48
  ///The default is \c std::less<PR>.
49
  ///
50
  ///\sa FibHeap
51
  ///\sa Dijkstra
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
52 47
  template <typename PR, typename IM, typename CMP = std::less<PR> >
48
#endif
53 49
  class BinHeap {
50
  public:
54 51

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

	
67
    /// \brief Type to represent the items states.
63
    /// \brief Type to represent the states of the items.
68 64
    ///
69
    /// Each Item element have a state associated to it. It may be "in heap",
70
    /// "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
71 67
    /// heap's point of view, but may be useful to the user.
72 68
    ///
73 69
    /// The item-int map must be initialized in such way that it assigns
74 70
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
75 71
    enum State {
76 72
      IN_HEAP = 0,    ///< = 0.
77 73
      PRE_HEAP = -1,  ///< = -1.
78 74
      POST_HEAP = -2  ///< = -2.
79 75
    };
80 76

	
81 77
  private:
82 78
    std::vector<Pair> _data;
83 79
    Compare _comp;
84 80
    ItemIntMap &_iim;
85 81

	
86 82
  public:
87
    /// \brief The constructor.
83

	
84
    /// \brief Constructor.
88 85
    ///
89
    /// The constructor.
90
    /// \param map should be given to the constructor, since it is used
91
    /// internally to handle the cross references. The value of the map
92
    /// must be \c PRE_HEAP (<tt>-1</tt>) for every item.
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.
93 90
    explicit BinHeap(ItemIntMap &map) : _iim(map) {}
94 91

	
95
    /// \brief The constructor.
92
    /// \brief Constructor.
96 93
    ///
97
    /// The constructor.
98
    /// \param map should be given to the constructor, since it is used
99
    /// internally to handle the cross references. The value of the map
100
    /// should be PRE_HEAP (-1) for each element.
101
    ///
102
    /// \param comp The comparator function object.
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.
103 99
    BinHeap(ItemIntMap &map, const Compare &comp)
104 100
      : _iim(map), _comp(comp) {}
105 101

	
106 102

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

	
112
    /// \brief Checks if the heap stores no items.
108
    /// \brief Check if the heap is empty.
113 109
    ///
114
    /// Returns \c true if and only if the heap stores no items.
110
    /// This function returns \c true if the heap is empty.
115 111
    bool empty() const { return _data.empty(); }
116 112

	
117
    /// \brief Make empty this heap.
113
    /// \brief Make the heap empty.
118 114
    ///
119
    /// Make empty this heap. It does not change the cross reference map.
120
    /// If you want to reuse what is not surely empty you should first clear
121
    /// the heap and after that you should set the cross reference map for
122
    /// 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.
123 120
    void clear() {
124 121
      _data.clear();
125 122
    }
126 123

	
127 124
  private:
128 125
    static int parent(int i) { return (i-1)/2; }
129 126

	
130
    static int second_child(int i) { return 2*i+2; }
127
    static int secondChild(int i) { return 2*i+2; }
131 128
    bool less(const Pair &p1, const Pair &p2) const {
132 129
      return _comp(p1.second, p2.second);
133 130
    }
134 131

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

	
146
    int bubble_down(int hole, Pair p, int length) {
147
      int child = second_child(hole);
143
    int bubbleDown(int hole, Pair p, int length) {
144
      int child = secondChild(hole);
148 145
      while(child < length) {
149 146
        if( less(_data[child-1], _data[child]) ) {
150 147
          --child;
151 148
        }
152 149
        if( !less(_data[child], p) )
153 150
          goto ok;
154 151
        move(_data[child], hole);
155 152
        hole = child;
156
        child = second_child(hole);
153
        child = secondChild(hole);
157 154
      }
158 155
      child--;
159 156
      if( child<length && less(_data[child], p) ) {
160 157
        move(_data[child], hole);
161 158
        hole=child;
162 159
      }
163 160
    ok:
164 161
      move(p, hole);
165 162
      return hole;
166 163
    }
167 164

	
168 165
    void move(const Pair &p, int i) {
169 166
      _data[i] = p;
170 167
      _iim.set(p.first, i);
171 168
    }
172 169

	
173 170
  public:
171

	
174 172
    /// \brief Insert a pair of item and priority into the heap.
175 173
    ///
176
    /// 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.
177 176
    /// \param p The pair to insert.
177
    /// \pre \c p.first must not be stored in the heap.
178 178
    void push(const Pair &p) {
179 179
      int n = _data.size();
180 180
      _data.resize(n+1);
181
      bubble_up(n, p);
181
      bubbleUp(n, p);
182 182
    }
183 183

	
184
    /// \brief Insert an item into the heap with the given heap.
184
    /// \brief Insert an item into the heap with the given priority.
185 185
    ///
186
    /// 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.
187 188
    /// \param i The item to insert.
188 189
    /// \param p The priority of the item.
190
    /// \pre \e i must not be stored in the heap.
189 191
    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
190 192

	
191
    /// \brief Returns the item with minimum priority relative to \c Compare.
193
    /// \brief Return the item having minimum priority.
192 194
    ///
193
    /// This method returns the item with minimum priority relative to \c
194
    /// Compare.
195
    /// \pre The heap must be nonempty.
195
    /// This function returns the item having minimum priority.
196
    /// \pre The heap must be non-empty.
196 197
    Item top() const {
197 198
      return _data[0].first;
198 199
    }
199 200

	
200
    /// \brief Returns the minimum priority relative to \c Compare.
201
    /// \brief The minimum priority.
201 202
    ///
202
    /// It returns the minimum priority relative to \c Compare.
203
    /// \pre The heap must be nonempty.
203
    /// This function returns the minimum priority.
204
    /// \pre The heap must be non-empty.
204 205
    Prio prio() const {
205 206
      return _data[0].second;
206 207
    }
207 208

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

	
222
    /// \brief Deletes \c i from the heap.
222
    /// \brief Remove the given item from the heap.
223 223
    ///
224
    /// This method deletes item \c i from the heap.
225
    /// \param i The item to erase.
226
    /// \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.
227 228
    void erase(const Item &i) {
228 229
      int h = _iim[i];
229 230
      int n = _data.size()-1;
230 231
      _iim.set(_data[h].first, POST_HEAP);
231 232
      if( h < n ) {
232
        if ( bubble_up(h, _data[n]) == h) {
233
          bubble_down(h, _data[n], n);
233
        if ( bubbleUp(h, _data[n]) == h) {
234
          bubbleDown(h, _data[n], n);
234 235
        }
235 236
      }
236 237
      _data.pop_back();
237 238
    }
238 239

	
239

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

	
250
    /// \brief \c i gets to the heap with priority \c p independently
251
    /// 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.
252 252
    ///
253
    /// This method calls \ref push(\c i, \c p) if \c i is not stored
254
    /// 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.
255 256
    /// \param i The item.
256 257
    /// \param p The priority.
257 258
    void set(const Item &i, const Prio &p) {
258 259
      int idx = _iim[i];
259 260
      if( idx < 0 ) {
260 261
        push(i,p);
261 262
      }
262 263
      else if( _comp(p, _data[idx].second) ) {
263
        bubble_up(idx, Pair(i,p));
264
        bubbleUp(idx, Pair(i,p));
264 265
      }
265 266
      else {
266
        bubble_down(idx, Pair(i,p), _data.size());
267
        bubbleDown(idx, Pair(i,p), _data.size());
267 268
      }
268 269
    }
269 270

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

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

	
294
    /// \brief Returns if \c item is in, has already been in, or has
295
    /// never been in the heap.
293
    /// \brief Return the state of an item.
296 294
    ///
297
    /// This method returns PRE_HEAP if \c item has never been in the
298
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
299
    /// otherwise. In the latter case it is possible that \c item will
300
    /// 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.
301 300
    /// \param i The item.
302 301
    State state(const Item &i) const {
303 302
      int s = _iim[i];
304 303
      if( s>=0 )
305 304
        s=0;
306 305
      return State(s);
307 306
    }
308 307

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

	
330
    /// \brief Replaces an item in the heap.
329
    /// \brief Replace an item in the heap.
331 330
    ///
332
    /// The \c i item is replaced with \c j item. The \c i item should
333
    /// be in the heap, while the \c j should be out of the heap. The
334
    /// \c i item will out of the heap and \c j will be in the heap
335
    /// 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.
336 336
    void replace(const Item& i, const Item& j) {
337 337
      int idx = _iim[i];
338 338
      _iim.set(i, _iim[j]);
339 339
      _iim.set(j, idx);
340 340
      _data[idx].first = j;
341 341
    }
342 342

	
343 343
  }; // class BinHeap
344 344

	
345 345
} // namespace lemon
346 346

	
347 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-2009
5
 * Copyright (C) 2003-2010
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 39
  // The ArrayMap template class is graph map structure that automatically
40 40
  // updates the map when a key is added to or erased from the graph.
41 41
  // This map uses the allocators to implement the container functionality.
42 42
  //
43 43
  // The template parameters are the Graph, the current Item type and
44 44
  // the Value type of the map.
45 45
  template <typename _Graph, typename _Item, typename _Value>
46 46
  class ArrayMap
47 47
    : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
48 48
  public:
49 49
    // The graph type.
50 50
    typedef _Graph GraphType;
51 51
    // The item type.
52 52
    typedef _Item Item;
53 53
    // The reference map tag.
54 54
    typedef True ReferenceMapTag;
55 55

	
56 56
    // The key type of the map.
57 57
    typedef _Item Key;
58 58
    // The value type of the map.
59 59
    typedef _Value Value;
60 60

	
61 61
    // The const reference type of the map.
62 62
    typedef const _Value& ConstReference;
63 63
    // The reference type of the map.
64 64
    typedef _Value& Reference;
65 65

	
66 66
    // The map type.
67 67
    typedef ArrayMap Map;
68 68

	
69 69
    // The notifier type.
70 70
    typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
71 71

	
72 72
  private:
73
  
73

	
74 74
    // The MapBase of the Map which imlements the core regisitry function.
75 75
    typedef typename Notifier::ObserverBase Parent;
76 76

	
77 77
    typedef std::allocator<Value> Allocator;
78 78

	
79 79
  public:
80 80

	
81 81
    // \brief Graph initialized map constructor.
82 82
    //
83 83
    // Graph initialized map constructor.
84 84
    explicit ArrayMap(const GraphType& graph) {
85 85
      Parent::attach(graph.notifier(Item()));
86 86
      allocate_memory();
87 87
      Notifier* nf = Parent::notifier();
88 88
      Item it;
89 89
      for (nf->first(it); it != INVALID; nf->next(it)) {
90 90
        int id = nf->id(it);;
91 91
        allocator.construct(&(values[id]), Value());
92 92
      }
93 93
    }
94 94

	
95 95
    // \brief Constructor to use default value to initialize the map.
96 96
    //
97 97
    // It constructs a map and initialize all of the the map.
98 98
    ArrayMap(const GraphType& graph, const Value& value) {
99 99
      Parent::attach(graph.notifier(Item()));
100 100
      allocate_memory();
101 101
      Notifier* nf = Parent::notifier();
102 102
      Item it;
103 103
      for (nf->first(it); it != INVALID; nf->next(it)) {
104 104
        int id = nf->id(it);;
105 105
        allocator.construct(&(values[id]), value);
106 106
      }
107 107
    }
108 108

	
109 109
  private:
110 110
    // \brief Constructor to copy a map of the same map type.
111 111
    //
112 112
    // Constructor to copy a map of the same map type.
113 113
    ArrayMap(const ArrayMap& copy) : Parent() {
114 114
      if (copy.attached()) {
115 115
        attach(*copy.notifier());
116 116
      }
117 117
      capacity = copy.capacity;
118 118
      if (capacity == 0) return;
119 119
      values = allocator.allocate(capacity);
120 120
      Notifier* nf = Parent::notifier();
121 121
      Item it;
122 122
      for (nf->first(it); it != INVALID; nf->next(it)) {
123 123
        int id = nf->id(it);;
124 124
        allocator.construct(&(values[id]), copy.values[id]);
125 125
      }
126 126
    }
127 127

	
128 128
    // \brief Assign operator.
129 129
    //
130 130
    // This operator assigns for each item in the map the
131 131
    // value mapped to the same item in the copied map.
132 132
    // The parameter map should be indiced with the same
133 133
    // itemset because this assign operator does not change
134 134
    // the container of the map.
135 135
    ArrayMap& operator=(const ArrayMap& cmap) {
136 136
      return operator=<ArrayMap>(cmap);
137 137
    }
138 138

	
139 139

	
140 140
    // \brief Template assign operator.
141 141
    //
142 142
    // The given parameter should conform to the ReadMap
143 143
    // concecpt and could be indiced by the current item set of
144 144
    // the NodeMap. In this case the value for each item
145 145
    // is assigned by the value of the given ReadMap.
146 146
    template <typename CMap>
147 147
    ArrayMap& operator=(const CMap& cmap) {
148 148
      checkConcept<concepts::ReadMap<Key, _Value>, CMap>();
149 149
      const typename Parent::Notifier* nf = Parent::notifier();
150 150
      Item it;
151 151
      for (nf->first(it); it != INVALID; nf->next(it)) {
152 152
        set(it, cmap[it]);
153 153
      }
154 154
      return *this;
155 155
    }
156 156

	
157 157
  public:
158 158
    // \brief The destructor of the map.
159 159
    //
160 160
    // The destructor of the map.
161 161
    virtual ~ArrayMap() {
162 162
      if (attached()) {
163 163
        clear();
164 164
        detach();
165 165
      }
166 166
    }
167 167

	
168 168
  protected:
169 169

	
170 170
    using Parent::attach;
171 171
    using Parent::detach;
172 172
    using Parent::attached;
173 173

	
174 174
  public:
175 175

	
176 176
    // \brief The subscript operator.
177 177
    //
178 178
    // The subscript operator. The map can be subscripted by the
179 179
    // actual keys of the graph.
180 180
    Value& operator[](const Key& key) {
181 181
      int id = Parent::notifier()->id(key);
182 182
      return values[id];
183 183
    }
184 184

	
185 185
    // \brief The const subscript operator.
186 186
    //
187 187
    // The const subscript operator. The map can be subscripted by the
188 188
    // actual keys of the graph.
189 189
    const Value& operator[](const Key& key) const {
190 190
      int id = Parent::notifier()->id(key);
191 191
      return values[id];
192 192
    }
193 193

	
194 194
    // \brief Setter function of the map.
195 195
    //
196 196
    // Setter function of the map. Equivalent with map[key] = val.
197 197
    // This is a compatibility feature with the not dereferable maps.
198 198
    void set(const Key& key, const Value& val) {
199 199
      (*this)[key] = val;
200 200
    }
201 201

	
202 202
  protected:
203 203

	
204 204
    // \brief Adds a new key to the map.
205 205
    //
206 206
    // It adds a new key to the map. It is called by the observer notifier
207 207
    // and it overrides the add() member function of the observer base.
208 208
    virtual void add(const Key& key) {
209 209
      Notifier* nf = Parent::notifier();
210 210
      int id = nf->id(key);
211 211
      if (id >= capacity) {
212 212
        int new_capacity = (capacity == 0 ? 1 : capacity);
213 213
        while (new_capacity <= id) {
214 214
          new_capacity <<= 1;
215 215
        }
216 216
        Value* new_values = allocator.allocate(new_capacity);
217 217
        Item it;
218 218
        for (nf->first(it); it != INVALID; nf->next(it)) {
219 219
          int jd = nf->id(it);;
220 220
          if (id != jd) {
221 221
            allocator.construct(&(new_values[jd]), values[jd]);
222 222
            allocator.destroy(&(values[jd]));
223 223
          }
224 224
        }
225 225
        if (capacity != 0) allocator.deallocate(values, capacity);
226 226
        values = new_values;
227 227
        capacity = new_capacity;
228 228
      }
229 229
      allocator.construct(&(values[id]), Value());
230 230
    }
231 231

	
232 232
    // \brief Adds more new keys to the map.
233 233
    //
234 234
    // It adds more new keys to the map. It is called by the observer notifier
235 235
    // and it overrides the add() member function of the observer base.
236 236
    virtual void add(const std::vector<Key>& keys) {
237 237
      Notifier* nf = Parent::notifier();
238 238
      int max_id = -1;
239 239
      for (int i = 0; i < int(keys.size()); ++i) {
240 240
        int id = nf->id(keys[i]);
241 241
        if (id > max_id) {
242 242
          max_id = id;
243 243
        }
244 244
      }
245 245
      if (max_id >= capacity) {
246 246
        int new_capacity = (capacity == 0 ? 1 : capacity);
247 247
        while (new_capacity <= max_id) {
248 248
          new_capacity <<= 1;
249 249
        }
250 250
        Value* new_values = allocator.allocate(new_capacity);
251 251
        Item it;
252 252
        for (nf->first(it); it != INVALID; nf->next(it)) {
253 253
          int id = nf->id(it);
254 254
          bool found = false;
255 255
          for (int i = 0; i < int(keys.size()); ++i) {
256 256
            int jd = nf->id(keys[i]);
257 257
            if (id == jd) {
258 258
              found = true;
259 259
              break;
260 260
            }
261 261
          }
262 262
          if (found) continue;
263 263
          allocator.construct(&(new_values[id]), values[id]);
264 264
          allocator.destroy(&(values[id]));
265 265
        }
266 266
        if (capacity != 0) allocator.deallocate(values, capacity);
267 267
        values = new_values;
268 268
        capacity = new_capacity;
269 269
      }
270 270
      for (int i = 0; i < int(keys.size()); ++i) {
271 271
        int id = nf->id(keys[i]);
272 272
        allocator.construct(&(values[id]), Value());
273 273
      }
274 274
    }
275 275

	
276 276
    // \brief Erase a key from the map.
277 277
    //
278 278
    // Erase a key from the map. It is called by the observer notifier
279 279
    // and it overrides the erase() member function of the observer base.
280 280
    virtual void erase(const Key& key) {
281 281
      int id = Parent::notifier()->id(key);
282 282
      allocator.destroy(&(values[id]));
283 283
    }
284 284

	
285 285
    // \brief Erase more keys from the map.
286 286
    //
287 287
    // Erase more keys from the map. It is called by the observer notifier
288 288
    // and it overrides the erase() member function of the observer base.
289 289
    virtual void erase(const std::vector<Key>& keys) {
290 290
      for (int i = 0; i < int(keys.size()); ++i) {
291 291
        int id = Parent::notifier()->id(keys[i]);
292 292
        allocator.destroy(&(values[id]));
293 293
      }
294 294
    }
295 295

	
296 296
    // \brief Builds the map.
297 297
    //
298 298
    // It builds the map. It is called by the observer notifier
299 299
    // and it overrides the build() member function of the observer base.
300 300
    virtual void build() {
301 301
      Notifier* nf = Parent::notifier();
302 302
      allocate_memory();
303 303
      Item it;
304 304
      for (nf->first(it); it != INVALID; nf->next(it)) {
305 305
        int id = nf->id(it);;
306 306
        allocator.construct(&(values[id]), Value());
307 307
      }
308 308
    }
309 309

	
310 310
    // \brief Clear the map.
311 311
    //
312 312
    // It erase all items from the map. It is called by the observer notifier
313 313
    // and it overrides the clear() member function of the observer base.
314 314
    virtual void clear() {
315 315
      Notifier* nf = Parent::notifier();
316 316
      if (capacity != 0) {
317 317
        Item it;
318 318
        for (nf->first(it); it != INVALID; nf->next(it)) {
319 319
          int id = nf->id(it);
320 320
          allocator.destroy(&(values[id]));
321 321
        }
322 322
        allocator.deallocate(values, capacity);
323 323
        capacity = 0;
324 324
      }
325 325
    }
326 326

	
327 327
  private:
328 328

	
329 329
    void allocate_memory() {
330 330
      int max_id = Parent::notifier()->maxId();
331 331
      if (max_id == -1) {
332 332
        capacity = 0;
333 333
        values = 0;
334 334
        return;
335 335
      }
336 336
      capacity = 1;
337 337
      while (capacity <= max_id) {
338 338
        capacity <<= 1;
339 339
      }
340 340
      values = allocator.allocate(capacity);
341 341
    }
342 342

	
343 343
    int capacity;
344 344
    Value* values;
345 345
    Allocator allocator;
346 346

	
347 347
  };
348 348

	
349 349
}
350 350

	
351 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-2009
5
 * Copyright (C) 2003-2010
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 156
    typedef typename DefaultMapSelector<_Graph, _Item, _Value>::Map Parent;
157 157

	
158 158
  public:
159 159
    typedef DefaultMap<_Graph, _Item, _Value> Map;
160
    
160

	
161 161
    typedef typename Parent::GraphType GraphType;
162 162
    typedef typename Parent::Value Value;
163 163

	
164 164
    explicit DefaultMap(const GraphType& graph) : Parent(graph) {}
165 165
    DefaultMap(const GraphType& graph, const Value& value)
166 166
      : Parent(graph, value) {}
167 167

	
168 168
    DefaultMap& operator=(const DefaultMap& cmap) {
169 169
      return operator=<DefaultMap>(cmap);
170 170
    }
171 171

	
172 172
    template <typename CMap>
173 173
    DefaultMap& operator=(const CMap& cmap) {
174 174
      Parent::operator=(cmap);
175 175
      return *this;
176 176
    }
177 177

	
178 178
  };
179 179

	
180 180
}
181 181

	
182 182
#endif
Ignore white space 6 line context
1
/* -*- C++ -*-
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2010
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_EDGE_SET_EXTENDER_H
20 20
#define LEMON_BITS_EDGE_SET_EXTENDER_H
21 21

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

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

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

	
39 39
  public:
40 40

	
41 41
    typedef ArcSetExtender Digraph;
42 42

	
43 43
    // Base extensions
44 44

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

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

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

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

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

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

	
73 73

	
74 74
    // Alteration notifier extensions
75 75

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

	
79 79
  protected:
80 80

	
81 81
    mutable ArcNotifier arc_notifier;
82 82

	
83 83
  public:
84 84

	
85 85
    using Parent::notifier;
86 86

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

	
92 92
    // Iterable extensions
93 93

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

	
98 98
      NodeIt() {}
99 99

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

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

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

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

	
114 114
    };
115 115

	
116 116

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

	
121 121
      ArcIt() { }
122 122

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

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

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

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

	
137 137
    };
138 138

	
139 139

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

	
144 144
      OutArcIt() { }
145 145

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

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

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

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

	
161 161
    };
162 162

	
163 163

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

	
168 168
      InArcIt() { }
169 169

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

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

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

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

	
185 185
    };
186 186

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

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

	
215 215
    using Parent::first;
216 216

	
217 217
    // Mappable extension
218
    
218

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

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

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

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

	
240 240
    };
241 241

	
242 242

	
243 243
    // Alteration extension
244 244

	
245 245
    Arc addArc(const Node& from, const Node& to) {
246 246
      Arc arc = Parent::addArc(from, to);
247 247
      notifier(Arc()).add(arc);
248 248
      return arc;
249 249
    }
250
    
250

	
251 251
    void clear() {
252 252
      notifier(Arc()).clear();
253 253
      Parent::clear();
254 254
    }
255 255

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

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

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

	
269 269
  };
270 270

	
271 271

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

	
279 279
  public:
280 280

	
281 281
    typedef EdgeSetExtender Graph;
282 282

	
283 283
    typedef True UndirectedTag;
284 284

	
285 285
    typedef typename Parent::Node Node;
286 286
    typedef typename Parent::Arc Arc;
287 287
    typedef typename Parent::Edge Edge;
288 288

	
289 289
    int maxId(Node) const {
290 290
      return Parent::maxNodeId();
291 291
    }
292 292

	
293 293
    int maxId(Arc) const {
294 294
      return Parent::maxArcId();
295 295
    }
296 296

	
297 297
    int maxId(Edge) const {
298 298
      return Parent::maxEdgeId();
299 299
    }
300 300

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

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

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

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

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

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

	
331 331
    typedef AlterationNotifier<EdgeSetExtender, Arc> ArcNotifier;
332 332
    typedef AlterationNotifier<EdgeSetExtender, Edge> EdgeNotifier;
333 333

	
334 334

	
335 335
  protected:
336 336

	
337 337
    mutable ArcNotifier arc_notifier;
338 338
    mutable EdgeNotifier edge_notifier;
339 339

	
340 340
  public:
341 341

	
342 342
    using Parent::notifier;
343
    
343

	
344 344
    ArcNotifier& notifier(Arc) const {
345 345
      return arc_notifier;
346 346
    }
347 347

	
348 348
    EdgeNotifier& notifier(Edge) const {
349 349
      return edge_notifier;
350 350
    }
351 351

	
352 352

	
353
    class NodeIt : public Node { 
353
    class NodeIt : public Node {
354 354
      const Graph* graph;
355 355
    public:
356 356

	
357 357
      NodeIt() {}
358 358

	
359 359
      NodeIt(Invalid i) : Node(i) { }
360 360

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

	
365
      NodeIt(const Graph& _graph, const Node& node) 
366
	: Node(node), graph(&_graph) {}
365
      NodeIt(const Graph& _graph, const Node& node)
366
        : Node(node), graph(&_graph) {}
367 367

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

	
373 373
    };
374 374

	
375 375

	
376
    class ArcIt : public Arc { 
376
    class ArcIt : public Arc {
377 377
      const Graph* graph;
378 378
    public:
379 379

	
380 380
      ArcIt() { }
381 381

	
382 382
      ArcIt(Invalid i) : Arc(i) { }
383 383

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

	
388
      ArcIt(const Graph& _graph, const Arc& e) : 
389
	Arc(e), graph(&_graph) { }
388
      ArcIt(const Graph& _graph, const Arc& e) :
389
        Arc(e), graph(&_graph) { }
390 390

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

	
396 396
    };
397 397

	
398 398

	
399
    class OutArcIt : public Arc { 
399
    class OutArcIt : public Arc {
400 400
      const Graph* graph;
401 401
    public:
402 402

	
403 403
      OutArcIt() { }
404 404

	
405 405
      OutArcIt(Invalid i) : Arc(i) { }
406 406

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

	
412
      OutArcIt(const Graph& _graph, const Arc& arc) 
413
	: Arc(arc), graph(&_graph) {}
412
      OutArcIt(const Graph& _graph, const Arc& arc)
413
        : Arc(arc), graph(&_graph) {}
414 414

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

	
420 420
    };
421 421

	
422 422

	
423
    class InArcIt : public Arc { 
423
    class InArcIt : public Arc {
424 424
      const Graph* graph;
425 425
    public:
426 426

	
427 427
      InArcIt() { }
428 428

	
429 429
      InArcIt(Invalid i) : Arc(i) { }
430 430

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

	
436
      InArcIt(const Graph& _graph, const Arc& arc) : 
437
	Arc(arc), graph(&_graph) {}
436
      InArcIt(const Graph& _graph, const Arc& arc) :
437
        Arc(arc), graph(&_graph) {}
438 438

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

	
444 444
    };
445 445

	
446 446

	
447
    class EdgeIt : public Parent::Edge { 
447
    class EdgeIt : public Parent::Edge {
448 448
      const Graph* graph;
449 449
    public:
450 450

	
451 451
      EdgeIt() { }
452 452

	
453 453
      EdgeIt(Invalid i) : Edge(i) { }
454 454

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

	
459
      EdgeIt(const Graph& _graph, const Edge& e) : 
460
	Edge(e), graph(&_graph) { }
459
      EdgeIt(const Graph& _graph, const Edge& e) :
460
        Edge(e), graph(&_graph) { }
461 461

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

	
467 467
    };
468 468

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

	
475 475
      IncEdgeIt() { }
476 476

	
477 477
      IncEdgeIt(Invalid i) : Edge(i), direction(false) { }
478 478

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

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

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

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

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

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

	
535 535

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

	
541 541
    public:
542
      explicit ArcMap(const Graph& _g) 
543
	: Parent(_g) {}
544
      ArcMap(const Graph& _g, const _Value& _v) 
545
	: Parent(_g, _v) {}
542
      explicit ArcMap(const Graph& _g)
543
        : Parent(_g) {}
544
      ArcMap(const Graph& _g, const _Value& _v)
545
        : Parent(_g, _v) {}
546 546

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

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

	
557 557
    };
558 558

	
559 559

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

	
565 565
    public:
566
      explicit EdgeMap(const Graph& _g) 
567
	: Parent(_g) {}
566
      explicit EdgeMap(const Graph& _g)
567
        : Parent(_g) {}
568 568

	
569
      EdgeMap(const Graph& _g, const _Value& _v) 
570
	: Parent(_g, _v) {}
569
      EdgeMap(const Graph& _g, const _Value& _v)
570
        : Parent(_g, _v) {}
571 571

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

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

	
582 582
    };
583 583

	
584 584

	
585 585
    // Alteration extension
586 586

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

	
597 597
    void clear() {
598 598
      notifier(Arc()).clear();
599 599
      notifier(Edge()).clear();
600 600
      Parent::clear();
601 601
    }
602 602

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

	
612 612

	
613 613
    EdgeSetExtender() {
614 614
      arc_notifier.setContainer(*this);
615 615
      edge_notifier.setContainer(*this);
616 616
    }
617 617

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

	
623 623
  };
624 624

	
625 625
}
626 626

	
627 627
#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 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 32
//\brief Extenders for the graph types
33 33
namespace lemon {
34 34

	
35 35
  // \ingroup graphbits
36 36
  //
37 37
  // \brief Extender for the digraph implementations
38 38
  template <typename Base>
39 39
  class DigraphExtender : public Base {
40 40
    typedef Base Parent;
41 41

	
42 42
  public:
43 43

	
44 44
    typedef DigraphExtender Digraph;
45 45

	
46 46
    // Base extensions
47 47

	
48 48
    typedef typename Parent::Node Node;
49 49
    typedef typename Parent::Arc Arc;
50 50

	
51 51
    int maxId(Node) const {
52 52
      return Parent::maxNodeId();
53 53
    }
54 54

	
55 55
    int maxId(Arc) const {
56 56
      return Parent::maxArcId();
57 57
    }
58 58

	
59
    Node fromId(int id, Node) const {
59
    static Node fromId(int id, Node) {
60 60
      return Parent::nodeFromId(id);
61 61
    }
62 62

	
63
    Arc fromId(int id, Arc) const {
63
    static Arc fromId(int id, Arc) {
64 64
      return Parent::arcFromId(id);
65 65
    }
66 66

	
67 67
    Node oppositeNode(const Node &node, const Arc &arc) const {
68 68
      if (node == Parent::source(arc))
69 69
        return Parent::target(arc);
70 70
      else if(node == Parent::target(arc))
71 71
        return Parent::source(arc);
72 72
      else
73 73
        return INVALID;
74 74
    }
75 75

	
76 76
    // Alterable extension
77 77

	
78 78
    typedef AlterationNotifier<DigraphExtender, Node> NodeNotifier;
79 79
    typedef AlterationNotifier<DigraphExtender, Arc> ArcNotifier;
80 80

	
81 81

	
82 82
  protected:
83 83

	
84 84
    mutable NodeNotifier node_notifier;
85 85
    mutable ArcNotifier arc_notifier;
86 86

	
87 87
  public:
88 88

	
89 89
    NodeNotifier& notifier(Node) const {
90 90
      return node_notifier;
91 91
    }
92 92

	
93 93
    ArcNotifier& notifier(Arc) const {
94 94
      return arc_notifier;
95 95
    }
96 96

	
97 97
    class NodeIt : public Node {
98 98
      const Digraph* _digraph;
99 99
    public:
100 100

	
101 101
      NodeIt() {}
102 102

	
103 103
      NodeIt(Invalid i) : Node(i) { }
104 104

	
105 105
      explicit NodeIt(const Digraph& digraph) : _digraph(&digraph) {
106 106
        _digraph->first(static_cast<Node&>(*this));
107 107
      }
108 108

	
109 109
      NodeIt(const Digraph& digraph, const Node& node)
110 110
        : Node(node), _digraph(&digraph) {}
111 111

	
112 112
      NodeIt& operator++() {
113 113
        _digraph->next(*this);
114 114
        return *this;
115 115
      }
116 116

	
117 117
    };
118 118

	
119 119

	
120 120
    class ArcIt : public Arc {
121 121
      const Digraph* _digraph;
122 122
    public:
123 123

	
124 124
      ArcIt() { }
125 125

	
126 126
      ArcIt(Invalid i) : Arc(i) { }
127 127

	
128 128
      explicit ArcIt(const Digraph& digraph) : _digraph(&digraph) {
129 129
        _digraph->first(static_cast<Arc&>(*this));
130 130
      }
131 131

	
132 132
      ArcIt(const Digraph& digraph, const Arc& arc) :
133 133
        Arc(arc), _digraph(&digraph) { }
134 134

	
135 135
      ArcIt& operator++() {
136 136
        _digraph->next(*this);
137 137
        return *this;
138 138
      }
139 139

	
140 140
    };
141 141

	
142 142

	
143 143
    class OutArcIt : public Arc {
144 144
      const Digraph* _digraph;
145 145
    public:
146 146

	
147 147
      OutArcIt() { }
148 148

	
149 149
      OutArcIt(Invalid i) : Arc(i) { }
150 150

	
151 151
      OutArcIt(const Digraph& digraph, const Node& node)
152 152
        : _digraph(&digraph) {
153 153
        _digraph->firstOut(*this, node);
154 154
      }
155 155

	
156 156
      OutArcIt(const Digraph& digraph, const Arc& arc)
157 157
        : Arc(arc), _digraph(&digraph) {}
158 158

	
159 159
      OutArcIt& operator++() {
160 160
        _digraph->nextOut(*this);
161 161
        return *this;
162 162
      }
163 163

	
164 164
    };
165 165

	
166 166

	
167 167
    class InArcIt : public Arc {
168 168
      const Digraph* _digraph;
169 169
    public:
170 170

	
171 171
      InArcIt() { }
172 172

	
173 173
      InArcIt(Invalid i) : Arc(i) { }
174 174

	
175 175
      InArcIt(const Digraph& digraph, const Node& node)
176 176
        : _digraph(&digraph) {
177 177
        _digraph->firstIn(*this, node);
178 178
      }
179 179

	
180 180
      InArcIt(const Digraph& digraph, const Arc& arc) :
181 181
        Arc(arc), _digraph(&digraph) {}
182 182

	
183 183
      InArcIt& operator++() {
184 184
        _digraph->nextIn(*this);
185 185
        return *this;
186 186
      }
187 187

	
188 188
    };
189 189

	
190 190
    // \brief Base node of the iterator
191 191
    //
192 192
    // Returns the base node (i.e. the source in this case) of the iterator
193 193
    Node baseNode(const OutArcIt &arc) const {
194 194
      return Parent::source(arc);
195 195
    }
196 196
    // \brief Running node of the iterator
197 197
    //
198 198
    // Returns the running node (i.e. the target in this case) of the
199 199
    // iterator
200 200
    Node runningNode(const OutArcIt &arc) const {
201 201
      return Parent::target(arc);
202 202
    }
203 203

	
204 204
    // \brief Base node of the iterator
205 205
    //
206 206
    // Returns the base node (i.e. the target in this case) of the iterator
207 207
    Node baseNode(const InArcIt &arc) const {
208 208
      return Parent::target(arc);
209 209
    }
210 210
    // \brief Running node of the iterator
211 211
    //
212 212
    // Returns the running node (i.e. the source in this case) of the
213 213
    // iterator
214 214
    Node runningNode(const InArcIt &arc) const {
215 215
      return Parent::source(arc);
216 216
    }
217 217

	
218 218

	
219 219
    template <typename _Value>
220 220
    class NodeMap
221 221
      : public MapExtender<DefaultMap<Digraph, Node, _Value> > {
222 222
      typedef MapExtender<DefaultMap<Digraph, Node, _Value> > Parent;
223 223

	
224 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 246
      typedef MapExtender<DefaultMap<Digraph, Arc, _Value> > Parent;
247 247

	
248 248
    public:
249 249
      explicit ArcMap(const Digraph& digraph)
250 250
        : Parent(digraph) {}
251 251
      ArcMap(const Digraph& digraph, const _Value& value)
252 252
        : Parent(digraph, value) {}
253 253

	
254 254
    private:
255 255
      ArcMap& operator=(const ArcMap& cmap) {
256 256
        return operator=<ArcMap>(cmap);
257 257
      }
258 258

	
259 259
      template <typename CMap>
260 260
      ArcMap& operator=(const CMap& cmap) {
261 261
        Parent::operator=(cmap);
262 262
        return *this;
263 263
      }
264 264
    };
265 265

	
266 266

	
267 267
    Node addNode() {
268 268
      Node node = Parent::addNode();
269 269
      notifier(Node()).add(node);
270 270
      return node;
271 271
    }
272 272

	
273 273
    Arc addArc(const Node& from, const Node& to) {
274 274
      Arc arc = Parent::addArc(from, to);
275 275
      notifier(Arc()).add(arc);
276 276
      return arc;
277 277
    }
278 278

	
279 279
    void clear() {
280 280
      notifier(Arc()).clear();
281 281
      notifier(Node()).clear();
282 282
      Parent::clear();
283 283
    }
284 284

	
285 285
    template <typename Digraph, typename NodeRefMap, typename ArcRefMap>
286 286
    void build(const Digraph& digraph, NodeRefMap& nodeRef, ArcRefMap& arcRef) {
287 287
      Parent::build(digraph, nodeRef, arcRef);
288 288
      notifier(Node()).build();
289 289
      notifier(Arc()).build();
290 290
    }
291 291

	
292 292
    void erase(const Node& node) {
293 293
      Arc arc;
294 294
      Parent::firstOut(arc, node);
295 295
      while (arc != INVALID ) {
296 296
        erase(arc);
297 297
        Parent::firstOut(arc, node);
298 298
      }
299 299

	
300 300
      Parent::firstIn(arc, node);
301 301
      while (arc != INVALID ) {
302 302
        erase(arc);
303 303
        Parent::firstIn(arc, node);
304 304
      }
305 305

	
306 306
      notifier(Node()).erase(node);
307 307
      Parent::erase(node);
308 308
    }
309 309

	
310 310
    void erase(const Arc& arc) {
311 311
      notifier(Arc()).erase(arc);
312 312
      Parent::erase(arc);
313 313
    }
314 314

	
315 315
    DigraphExtender() {
316 316
      node_notifier.setContainer(*this);
317 317
      arc_notifier.setContainer(*this);
318 318
    }
319 319

	
320 320

	
321 321
    ~DigraphExtender() {
322 322
      arc_notifier.clear();
323 323
      node_notifier.clear();
324 324
    }
325 325
  };
326 326

	
327 327
  // \ingroup _graphbits
328 328
  //
329 329
  // \brief Extender for the Graphs
330 330
  template <typename Base>
331 331
  class GraphExtender : public Base {
332 332
    typedef Base Parent;
333 333

	
334 334
  public:
335 335

	
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 604
      typedef MapExtender<DefaultMap<Graph, Node, _Value> > Parent;
605 605

	
606 606
    public:
607 607
      explicit NodeMap(const Graph& graph)
608 608
        : Parent(graph) {}
609 609
      NodeMap(const Graph& graph, const _Value& value)
610 610
        : Parent(graph, value) {}
611 611

	
612 612
    private:
613 613
      NodeMap& operator=(const NodeMap& cmap) {
614 614
        return operator=<NodeMap>(cmap);
615 615
      }
616 616

	
617 617
      template <typename CMap>
618 618
      NodeMap& operator=(const CMap& cmap) {
619 619
        Parent::operator=(cmap);
620 620
        return *this;
621 621
      }
622 622

	
623 623
    };
624 624

	
625 625
    template <typename _Value>
626 626
    class ArcMap
627 627
      : public MapExtender<DefaultMap<Graph, Arc, _Value> > {
628 628
      typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
629 629

	
630 630
    public:
631 631
      explicit ArcMap(const Graph& graph)
632 632
        : Parent(graph) {}
633 633
      ArcMap(const Graph& graph, const _Value& value)
634 634
        : Parent(graph, value) {}
635 635

	
636 636
    private:
637 637
      ArcMap& operator=(const ArcMap& cmap) {
638 638
        return operator=<ArcMap>(cmap);
639 639
      }
640 640

	
641 641
      template <typename CMap>
642 642
      ArcMap& operator=(const CMap& cmap) {
643 643
        Parent::operator=(cmap);
644 644
        return *this;
645 645
      }
646 646
    };
647 647

	
648 648

	
649 649
    template <typename _Value>
650 650
    class EdgeMap
651 651
      : public MapExtender<DefaultMap<Graph, Edge, _Value> > {
652 652
      typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
653 653

	
654 654
    public:
655 655
      explicit EdgeMap(const Graph& graph)
656 656
        : Parent(graph) {}
657 657

	
658 658
      EdgeMap(const Graph& graph, const _Value& value)
659 659
        : Parent(graph, value) {}
660 660

	
661 661
    private:
662 662
      EdgeMap& operator=(const EdgeMap& cmap) {
663 663
        return operator=<EdgeMap>(cmap);
664 664
      }
665 665

	
666 666
      template <typename CMap>
667 667
      EdgeMap& operator=(const CMap& cmap) {
668 668
        Parent::operator=(cmap);
669 669
        return *this;
670 670
      }
671 671

	
672 672
    };
673 673

	
674 674
    // Alteration extension
675 675

	
676 676
    Node addNode() {
677 677
      Node node = Parent::addNode();
678 678
      notifier(Node()).add(node);
679 679
      return node;
680 680
    }
681 681

	
682 682
    Edge addEdge(const Node& from, const Node& to) {
683 683
      Edge edge = Parent::addEdge(from, to);
684 684
      notifier(Edge()).add(edge);
685 685
      std::vector<Arc> ev;
686 686
      ev.push_back(Parent::direct(edge, true));
687 687
      ev.push_back(Parent::direct(edge, false));
688 688
      notifier(Arc()).add(ev);
689 689
      return edge;
690 690
    }
691 691

	
692 692
    void clear() {
693 693
      notifier(Arc()).clear();
694 694
      notifier(Edge()).clear();
695 695
      notifier(Node()).clear();
696 696
      Parent::clear();
697 697
    }
698 698

	
699 699
    template <typename Graph, typename NodeRefMap, typename EdgeRefMap>
700 700
    void build(const Graph& graph, NodeRefMap& nodeRef,
701 701
               EdgeRefMap& edgeRef) {
702 702
      Parent::build(graph, nodeRef, edgeRef);
703 703
      notifier(Node()).build();
704 704
      notifier(Edge()).build();
705 705
      notifier(Arc()).build();
706 706
    }
707 707

	
708 708
    void erase(const Node& node) {
709 709
      Arc arc;
710 710
      Parent::firstOut(arc, node);
711 711
      while (arc != INVALID ) {
712 712
        erase(arc);
713 713
        Parent::firstOut(arc, node);
714 714
      }
715 715

	
716 716
      Parent::firstIn(arc, node);
717 717
      while (arc != INVALID ) {
718 718
        erase(arc);
719 719
        Parent::firstIn(arc, node);
720 720
      }
721 721

	
722 722
      notifier(Node()).erase(node);
723 723
      Parent::erase(node);
724 724
    }
725 725

	
726 726
    void erase(const Edge& edge) {
727 727
      std::vector<Arc> av;
728 728
      av.push_back(Parent::direct(edge, true));
729 729
      av.push_back(Parent::direct(edge, false));
730 730
      notifier(Arc()).erase(av);
731 731
      notifier(Edge()).erase(edge);
732 732
      Parent::erase(edge);
733 733
    }
734 734

	
735 735
    GraphExtender() {
736 736
      node_notifier.setContainer(*this);
737 737
      arc_notifier.setContainer(*this);
738 738
      edge_notifier.setContainer(*this);
739 739
    }
740 740

	
741 741
    ~GraphExtender() {
742 742
      edge_notifier.clear();
743 743
      arc_notifier.clear();
744 744
      node_notifier.clear();
745 745
    }
746 746

	
747 747
  };
748 748

	
749 749
}
750 750

	
751 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-2010
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_SOLVER_BITS_H
20 20
#define LEMON_BITS_SOLVER_BITS_H
21 21

	
22 22
#include <vector>
23 23

	
24 24
namespace lemon {
25 25

	
26 26
  namespace _solver_bits {
27 27

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

	
37 37
      std::vector<int> cross;
38 38

	
39 39
    public:
40 40

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

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

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

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

	
79 79
        return n;
80 80
      }
81 81

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

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

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

	
116 116
        return n;
117 117
      }
118 118

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

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

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

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

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

	
149 149
      void shiftIndices(int idx) {
150 150
        for (int i = idx + 1; i < static_cast<int>(cross.size()); ++i) {
151 151
          cross[i - 1] = cross[i];
152 152
          if (cross[i] != -1) {
153 153
            --items[cross[i]].index;
154 154
          }
155 155
        }
156 156
        cross.back() = -1;
157 157
        cross.pop_back();
158 158
        while (!cross.empty() && cross.back() == -1) {
159 159
          cross.pop_back();
160 160
        }
161 161
      }
162 162

	
163 163
      void relocateIndex(int idx, int jdx) {
164 164
        cross[idx] = cross[jdx];
165 165
        items[cross[jdx]].index = idx;
166 166
        cross[jdx] = -1;
167 167

	
168 168
        while (!cross.empty() && cross.back() == -1) {
169 169
          cross.pop_back();
170 170
        }
171 171
      }
172 172

	
173 173
      int operator[](int idx) const {
174 174
        return cross[idx];
175 175
      }
176 176

	
177 177
      int operator()(int fdx) const {
178 178
        return items[fdx].index;
179 179
      }
180 180

	
181 181
      void firstItem(int& fdx) const {
182 182
        fdx = first_item;
183 183
      }
184 184

	
185 185
      void nextItem(int& fdx) const {
186 186
        fdx = items[fdx].next;
187 187
      }
188 188

	
189 189
    };
190 190
  }
191 191
}
192 192

	
193 193
#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-2009
5
 * Copyright (C) 2003-2010
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/bits/windows.h>
23 23

	
24 24
#ifdef WIN32
25 25
#ifndef WIN32_LEAN_AND_MEAN
26 26
#define WIN32_LEAN_AND_MEAN
27 27
#endif
28 28
#ifndef NOMINMAX
29 29
#define NOMINMAX
30 30
#endif
31 31
#ifdef UNICODE
32 32
#undef UNICODE
33 33
#endif
34 34
#include <windows.h>
35 35
#ifdef LOCALE_INVARIANT
36 36
#define MY_LOCALE LOCALE_INVARIANT
37 37
#else
38 38
#define MY_LOCALE LOCALE_NEUTRAL
39 39
#endif
40 40
#else
41 41
#include <unistd.h>
42 42
#include <ctime>
43 43
#ifndef WIN32
44 44
#include <sys/times.h>
45 45
#endif
46 46
#include <sys/time.h>
47 47
#endif
48 48

	
49 49
#include <cmath>
50 50
#include <sstream>
51 51

	
52 52
namespace lemon {
53 53
  namespace bits {
54 54
    void getWinProcTimes(double &rtime,
55 55
                         double &utime, double &stime,
56 56
                         double &cutime, double &cstime)
57 57
    {
58 58
#ifdef WIN32
59 59
      static const double ch = 4294967296.0e-7;
60 60
      static const double cl = 1.0e-7;
61 61

	
62 62
      FILETIME system;
63 63
      GetSystemTimeAsFileTime(&system);
64 64
      rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
65 65

	
66 66
      FILETIME create, exit, kernel, user;
67 67
      if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
68 68
        utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
69 69
        stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
70 70
        cutime = 0;
71 71
        cstime = 0;
72 72
      } else {
73 73
        rtime = 0;
74 74
        utime = 0;
75 75
        stime = 0;
76 76
        cutime = 0;
77 77
        cstime = 0;
78 78
      }
79 79
#else
80 80
      timeval tv;
81 81
      gettimeofday(&tv, 0);
82 82
      rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
83 83

	
84 84
      tms ts;
85 85
      double tck=sysconf(_SC_CLK_TCK);
86 86
      times(&ts);
87 87
      utime=ts.tms_utime/tck;
88 88
      stime=ts.tms_stime/tck;
89 89
      cutime=ts.tms_cutime/tck;
90 90
      cstime=ts.tms_cstime/tck;
91 91
#endif
92 92
    }
93 93

	
94 94
    std::string getWinFormattedDate()
95 95
    {
96 96
      std::ostringstream os;
97 97
#ifdef WIN32
98 98
      SYSTEMTIME time;
99 99
      GetSystemTime(&time);
100 100
      char buf1[11], buf2[9], buf3[5];
101
	  if (GetDateFormat(MY_LOCALE, 0, &time,
101
          if (GetDateFormat(MY_LOCALE, 0, &time,
102 102
                        ("ddd MMM dd"), buf1, 11) &&
103 103
          GetTimeFormat(MY_LOCALE, 0, &time,
104 104
                        ("HH':'mm':'ss"), buf2, 9) &&
105 105
          GetDateFormat(MY_LOCALE, 0, &time,
106 106
                        ("yyyy"), buf3, 5)) {
107 107
        os << buf1 << ' ' << buf2 << ' ' << buf3;
108 108
      }
109 109
      else os << "unknown";
110 110
#else
111 111
      timeval tv;
112 112
      gettimeofday(&tv, 0);
113 113

	
114 114
      char cbuf[26];
115 115
      ctime_r(&tv.tv_sec,cbuf);
116 116
      os << cbuf;
117 117
#endif
118 118
      return os.str();
119 119
    }
120 120

	
121 121
    int getWinRndSeed()
122 122
    {
123 123
#ifdef WIN32
124 124
      FILETIME time;
125 125
      GetSystemTimeAsFileTime(&time);
126 126
      return GetCurrentProcessId() + time.dwHighDateTime + time.dwLowDateTime;
127 127
#else
128 128
      timeval tv;
129 129
      gettimeofday(&tv, 0);
130 130
      return getpid() + tv.tv_sec + tv.tv_usec;
131 131
#endif
132 132
    }
133 133
  }
134 134
}
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-2009
5
 * Copyright (C) 2003-2010
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_BUCKET_HEAP_H
20 20
#define LEMON_BUCKET_HEAP_H
21 21

	
22
///\ingroup auxdat
22
///\ingroup heaps
23 23
///\file
24
///\brief Bucket Heap implementation.
24
///\brief Bucket heap implementation.
25 25

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

	
30 30
namespace lemon {
31 31

	
32 32
  namespace _bucket_heap_bits {
33 33

	
34 34
    template <bool MIN>
35 35
    struct DirectionTraits {
36 36
      static bool less(int left, int right) {
37 37
        return left < right;
38 38
      }
39 39
      static void increase(int& value) {
40 40
        ++value;
41 41
      }
42 42
    };
43 43

	
44 44
    template <>
45 45
    struct DirectionTraits<false> {
46 46
      static bool less(int left, int right) {
47 47
        return left > right;
48 48
      }
49 49
      static void increase(int& value) {
50 50
        --value;
51 51
      }
52 52
    };
53 53

	
54 54
  }
55 55

	
56
  /// \ingroup auxdat
56
  /// \ingroup heaps
57 57
  ///
58
  /// \brief A Bucket Heap implementation.
58
  /// \brief Bucket heap data structure.
59 59
  ///
60
  /// This class implements the \e bucket \e heap data structure. A \e heap
61
  /// is a data structure for storing items with specified values called \e
62
  /// priorities in such a way that finding the item with minimum priority is
63
  /// efficient. The bucket heap is very simple implementation, it can store
64
  /// only integer priorities and it stores for each priority in the
65
  /// \f$ [0..C) \f$ range a list of items. So it should be used only when
66
  /// the priorities are small. It is not intended to use as dijkstra heap.
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.
67 63
  ///
68
  /// \param IM A read and write Item int map, used internally
69
  /// to handle the cross references.
70
  /// \param MIN If the given parameter is false then instead of the
71
  /// minimum value the maximum can be retrivied with the top() and
72
  /// prio() member functions.
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
73 78
  template <typename IM, bool MIN = true>
74 79
  class BucketHeap {
75 80

	
76 81
  public:
77
    /// \e
78
    typedef typename IM::Key Item;
79
    /// \e
82

	
83
    /// Type of the item-int map.
84
    typedef IM ItemIntMap;
85
    /// Type of the priorities.
80 86
    typedef int Prio;
81
    /// \e
82
    typedef std::pair<Item, Prio> Pair;
83
    /// \e
84
    typedef IM ItemIntMap;
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;
85 91

	
86 92
  private:
87 93

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

	
90 96
  public:
91 97

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

	
106 112
  public:
107
    /// \brief The constructor.
113

	
114
    /// \brief Constructor.
108 115
    ///
109
    /// The constructor.
110
    /// \param map should be given to the constructor, since it is used
111
    /// internally to handle the cross references. The value of the map
112
    /// should be PRE_HEAP (-1) for each element.
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.
113 120
    explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
114 121

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

	
120
    /// \brief Checks if the heap stores no items.
127
    /// \brief Check if the heap is empty.
121 128
    ///
122
    /// Returns \c true if and only if the heap stores no items.
129
    /// This function returns \c true if the heap is empty.
123 130
    bool empty() const { return _data.empty(); }
124 131

	
125
    /// \brief Make empty this heap.
132
    /// \brief Make the heap empty.
126 133
    ///
127
    /// Make empty this heap. It does not change the cross reference
128
    /// map.  If you want to reuse a heap what is not surely empty you
129
    /// should first clear the heap and after that you should set the
130
    /// cross reference map for each item to \c PRE_HEAP.
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.
131 139
    void clear() {
132 140
      _data.clear(); _first.clear(); _minimum = 0;
133 141
    }
134 142

	
135 143
  private:
136 144

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

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

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

	
176 184
  public:
185

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

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

	
200
    /// \brief Returns the item with minimum priority.
213
    /// \brief Return the item having minimum priority.
201 214
    ///
202
    /// This method returns the item with minimum priority.
203
    /// \pre The heap must be nonempty.
215
    /// This function returns the item having minimum priority.
216
    /// \pre The heap must be non-empty.
204 217
    Item top() const {
205 218
      while (_first[_minimum] == -1) {
206 219
        Direction::increase(_minimum);
207 220
      }
208 221
      return _data[_first[_minimum]].item;
209 222
    }
210 223

	
211
    /// \brief Returns the minimum priority.
224
    /// \brief The minimum priority.
212 225
    ///
213
    /// It returns the minimum priority.
214
    /// \pre The heap must be nonempty.
226
    /// This function returns the minimum priority.
227
    /// \pre The heap must be non-empty.
215 228
    Prio prio() const {
216 229
      while (_first[_minimum] == -1) {
217 230
        Direction::increase(_minimum);
218 231
      }
219 232
      return _minimum;
220 233
    }
221 234

	
222
    /// \brief Deletes the item with minimum priority.
235
    /// \brief Remove the item having minimum priority.
223 236
    ///
224
    /// This method deletes the item with minimum priority from the heap.
237
    /// This function removes the item having minimum priority.
225 238
    /// \pre The heap must be non-empty.
226 239
    void pop() {
227 240
      while (_first[_minimum] == -1) {
228 241
        Direction::increase(_minimum);
229 242
      }
230 243
      int idx = _first[_minimum];
231 244
      _iim[_data[idx].item] = -2;
232 245
      unlace(idx);
233
      relocate_last(idx);
246
      relocateLast(idx);
234 247
    }
235 248

	
236
    /// \brief Deletes \c i from the heap.
249
    /// \brief Remove the given item from the heap.
237 250
    ///
238
    /// This method deletes item \c i from the heap, if \c i was
239
    /// already stored in the heap.
240
    /// \param i The item to erase.
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.
241 255
    void erase(const Item &i) {
242 256
      int idx = _iim[i];
243 257
      _iim[_data[idx].item] = -2;
244 258
      unlace(idx);
245
      relocate_last(idx);
259
      relocateLast(idx);
246 260
    }
247 261

	
248

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

	
259
    /// \brief \c i gets to the heap with priority \c p independently
260
    /// if \c i was already there.
272
    /// \brief Set the priority of an item or insert it, if it is
273
    /// not stored in the heap.
261 274
    ///
262
    /// This method calls \ref push(\c i, \c p) if \c i is not stored
263
    /// in the heap and sets the priority of \c i to \c p otherwise.
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.
264 278
    /// \param i The item.
265 279
    /// \param p The priority.
266 280
    void set(const Item &i, const Prio &p) {
267 281
      int idx = _iim[i];
268 282
      if (idx < 0) {
269 283
        push(i, p);
270 284
      } else if (Direction::less(p, _data[idx].value)) {
271 285
        decrease(i, p);
272 286
      } else {
273 287
        increase(i, p);
274 288
      }
275 289
    }
276 290

	
277
    /// \brief Decreases the priority of \c i to \c p.
291
    /// \brief Decrease the priority of an item to the given value.
278 292
    ///
279
    /// This method decreases the priority of item \c i to \c p.
280
    /// \pre \c i must be stored in the heap with priority at least \c
281
    /// p relative to \c Compare.
293
    /// This function decreases the priority of an item to the given value.
282 294
    /// \param i The item.
283 295
    /// \param p The priority.
296
    /// \pre \e i must be stored in the heap with priority at least \e p.
284 297
    void decrease(const Item &i, const Prio &p) {
285 298
      int idx = _iim[i];
286 299
      unlace(idx);
287 300
      _data[idx].value = p;
288 301
      if (Direction::less(p, _minimum)) {
289 302
        _minimum = p;
290 303
      }
291 304
      lace(idx);
292 305
    }
293 306

	
294
    /// \brief Increases the priority of \c i to \c p.
307
    /// \brief Increase the priority of an item to the given value.
295 308
    ///
296
    /// This method sets the priority of item \c i to \c p.
297
    /// \pre \c i must be stored in the heap with priority at most \c
298
    /// p relative to \c Compare.
309
    /// This function increases the priority of an item to the given value.
299 310
    /// \param i The item.
300 311
    /// \param p The priority.
312
    /// \pre \e i must be stored in the heap with priority at most \e p.
301 313
    void increase(const Item &i, const Prio &p) {
302 314
      int idx = _iim[i];
303 315
      unlace(idx);
304 316
      _data[idx].value = p;
305 317
      lace(idx);
306 318
    }
307 319

	
308
    /// \brief Returns if \c item is in, has already been in, or has
309
    /// never been in the heap.
320
    /// \brief Return the state of an item.
310 321
    ///
311
    /// This method returns PRE_HEAP if \c item has never been in the
312
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
313
    /// otherwise. In the latter case it is possible that \c item will
314
    /// get back to the heap again.
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.
315 327
    /// \param i The item.
316 328
    State state(const Item &i) const {
317 329
      int idx = _iim[i];
318 330
      if (idx >= 0) idx = 0;
319 331
      return State(idx);
320 332
    }
321 333

	
322
    /// \brief Sets the state of the \c item in the heap.
334
    /// \brief Set the state of an item in the heap.
323 335
    ///
324
    /// Sets the state of the \c item in the heap. It can be used to
325
    /// manually clear the heap when it is important to achive the
326
    /// better time complexity.
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.
327 339
    /// \param i The item.
328 340
    /// \param st The state. It should not be \c IN_HEAP.
329 341
    void state(const Item& i, State st) {
330 342
      switch (st) {
331 343
      case POST_HEAP:
332 344
      case PRE_HEAP:
333 345
        if (state(i) == IN_HEAP) {
334 346
          erase(i);
335 347
        }
336 348
        _iim[i] = st;
337 349
        break;
338 350
      case IN_HEAP:
339 351
        break;
340 352
      }
341 353
    }
342 354

	
343 355
  private:
344 356

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

	
349 361
      Item item;
350 362
      int value;
351 363

	
352 364
      int prev, next;
353 365
    };
354 366

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

	
360 372
  }; // class BucketHeap
361 373

	
362
  /// \ingroup auxdat
374
  /// \ingroup heaps
363 375
  ///
364
  /// \brief A Simplified Bucket Heap implementation.
376
  /// \brief Simplified bucket heap data structure.
365 377
  ///
366 378
  /// This class implements a simplified \e bucket \e heap data
367
  /// structure.  It does not provide some functionality but it faster
368
  /// and simplier data structure than the BucketHeap. The main
369
  /// difference is that the BucketHeap stores for every key a double
370
  /// linked list while this class stores just simple lists. In the
371
  /// other way it does not support erasing each elements just the
372
  /// minimal and it does not supports key increasing, decreasing.
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.
373 385
  ///
374
  /// \param IM A read and write Item int map, used internally
375
  /// to handle the cross references.
376
  /// \param MIN If the given parameter is false then instead of the
377
  /// minimum value the maximum can be retrivied with the top() and
378
  /// prio() member functions.
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.
379 397
  ///
380 398
  /// \sa BucketHeap
381 399
  template <typename IM, bool MIN = true >
382 400
  class SimpleBucketHeap {
383 401

	
384 402
  public:
385
    typedef typename IM::Key Item;
403

	
404
    /// Type of the item-int map.
405
    typedef IM ItemIntMap;
406
    /// Type of the priorities.
386 407
    typedef int Prio;
387
    typedef std::pair<Item, Prio> Pair;
388
    typedef IM ItemIntMap;
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;
389 412

	
390 413
  private:
391 414

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

	
394 417
  public:
395 418

	
396
    /// \brief Type to represent the items states.
419
    /// \brief Type to represent the states of the items.
397 420
    ///
398
    /// Each Item element have a state associated to it. It may be "in heap",
399
    /// "pre heap" or "post heap". The latter two are indifferent from the
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
400 423
    /// heap's point of view, but may be useful to the user.
401 424
    ///
402 425
    /// The item-int map must be initialized in such way that it assigns
403 426
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
404 427
    enum State {
405 428
      IN_HEAP = 0,    ///< = 0.
406 429
      PRE_HEAP = -1,  ///< = -1.
407 430
      POST_HEAP = -2  ///< = -2.
408 431
    };
409 432

	
410 433
  public:
411 434

	
412
    /// \brief The constructor.
435
    /// \brief Constructor.
413 436
    ///
414
    /// The constructor.
415
    /// \param map should be given to the constructor, since it is used
416
    /// internally to handle the cross references. The value of the map
417
    /// should be PRE_HEAP (-1) for each element.
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.
418 441
    explicit SimpleBucketHeap(ItemIntMap &map)
419 442
      : _iim(map), _free(-1), _num(0), _minimum(0) {}
420 443

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

	
426
    /// \brief Checks if the heap stores no items.
449
    /// \brief Check if the heap is empty.
427 450
    ///
428
    /// Returns \c true if and only if the heap stores no items.
451
    /// This function returns \c true if the heap is empty.
429 452
    bool empty() const { return _num == 0; }
430 453

	
431
    /// \brief Make empty this heap.
454
    /// \brief Make the heap empty.
432 455
    ///
433
    /// Make empty this heap. It does not change the cross reference
434
    /// map.  If you want to reuse a heap what is not surely empty you
435
    /// should first clear the heap and after that you should set the
436
    /// cross reference map for each item to \c PRE_HEAP.
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.
437 461
    void clear() {
438 462
      _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
439 463
    }
440 464

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

	
449 475
    /// \brief Insert an item into the heap with the given priority.
450 476
    ///
451
    /// Adds \c i to the heap with priority \c p.
477
    /// This function inserts the given item into the heap with the
478
    /// given priority.
452 479
    /// \param i The item to insert.
453 480
    /// \param p The priority of the item.
481
    /// \pre \e i must not be stored in the heap.
454 482
    void push(const Item &i, const Prio &p) {
455 483
      int idx;
456 484
      if (_free == -1) {
457 485
        idx = _data.size();
458 486
        _data.push_back(BucketItem(i));
459 487
      } else {
460 488
        idx = _free;
461 489
        _free = _data[idx].next;
462 490
        _data[idx].item = i;
463 491
      }
464 492
      _iim[i] = idx;
465 493
      if (p >= int(_first.size())) _first.resize(p + 1, -1);
466 494
      _data[idx].next = _first[p];
467 495
      _first[p] = idx;
468 496
      if (Direction::less(p, _minimum)) {
469 497
        _minimum = p;
470 498
      }
471 499
      ++_num;
472 500
    }
473 501

	
474
    /// \brief Returns the item with minimum priority.
502
    /// \brief Return the item having minimum priority.
475 503
    ///
476
    /// This method returns the item with minimum priority.
477
    /// \pre The heap must be nonempty.
504
    /// This function returns the item having minimum priority.
505
    /// \pre The heap must be non-empty.
478 506
    Item top() const {
479 507
      while (_first[_minimum] == -1) {
480 508
        Direction::increase(_minimum);
481 509
      }
482 510
      return _data[_first[_minimum]].item;
483 511
    }
484 512

	
485
    /// \brief Returns the minimum priority.
513
    /// \brief The minimum priority.
486 514
    ///
487
    /// It returns the minimum priority.
488
    /// \pre The heap must be nonempty.
515
    /// This function returns the minimum priority.
516
    /// \pre The heap must be non-empty.
489 517
    Prio prio() const {
490 518
      while (_first[_minimum] == -1) {
491 519
        Direction::increase(_minimum);
492 520
      }
493 521
      return _minimum;
494 522
    }
495 523

	
496
    /// \brief Deletes the item with minimum priority.
524
    /// \brief Remove the item having minimum priority.
497 525
    ///
498
    /// This method deletes the item with minimum priority from the heap.
526
    /// This function removes the item having minimum priority.
499 527
    /// \pre The heap must be non-empty.
500 528
    void pop() {
501 529
      while (_first[_minimum] == -1) {
502 530
        Direction::increase(_minimum);
503 531
      }
504 532
      int idx = _first[_minimum];
505 533
      _iim[_data[idx].item] = -2;
506 534
      _first[_minimum] = _data[idx].next;
507 535
      _data[idx].next = _free;
508 536
      _free = idx;
509 537
      --_num;
510 538
    }
511 539

	
512
    /// \brief Returns the priority of \c i.
540
    /// \brief The priority of the given item.
513 541
    ///
514
    /// This function returns the priority of item \c i.
515
    /// \warning This operator is not a constant time function
516
    /// because it scans the whole data structure to find the proper
517
    /// value.
518
    /// \pre \c i must be in the heap.
542
    /// This function returns the priority of the given item.
519 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.
520 547
    Prio operator[](const Item &i) const {
521
      for (int k = 0; k < _first.size(); ++k) {
548
      for (int k = 0; k < int(_first.size()); ++k) {
522 549
        int idx = _first[k];
523 550
        while (idx != -1) {
524 551
          if (_data[idx].item == i) {
525 552
            return k;
526 553
          }
527 554
          idx = _data[idx].next;
528 555
        }
529 556
      }
530 557
      return -1;
531 558
    }
532 559

	
533
    /// \brief Returns if \c item is in, has already been in, or has
534
    /// never been in the heap.
560
    /// \brief Return the state of an item.
535 561
    ///
536
    /// This method returns PRE_HEAP if \c item has never been in the
537
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
538
    /// otherwise. In the latter case it is possible that \c item will
539
    /// get back to the heap again.
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.
540 567
    /// \param i The item.
541 568
    State state(const Item &i) const {
542 569
      int idx = _iim[i];
543 570
      if (idx >= 0) idx = 0;
544 571
      return State(idx);
545 572
    }
546 573

	
547 574
  private:
548 575

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

	
553 580
      Item item;
554 581
      int next;
555 582
    };
556 583

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

	
563 590
  }; // class SimpleBucketHeap
564 591

	
565 592
}
566 593

	
567 594
#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 19
///\file
20 20
///\brief Implementation of the CBC MIP solver interface.
21 21

	
22 22
#include "cbc.h"
23 23

	
24 24
#include <coin/CoinModel.hpp>
25 25
#include <coin/CbcModel.hpp>
26 26
#include <coin/OsiSolverInterface.hpp>
27 27

	
28 28
#ifdef COIN_HAS_CLP
29 29
#include "coin/OsiClpSolverInterface.hpp"
30 30
#endif
31 31
#ifdef COIN_HAS_OSL
32 32
#include "coin/OsiOslSolverInterface.hpp"
33 33
#endif
34 34

	
35 35
#include "coin/CbcCutGenerator.hpp"
36 36
#include "coin/CbcHeuristicLocal.hpp"
37 37
#include "coin/CbcHeuristicGreedy.hpp"
38 38
#include "coin/CbcHeuristicFPump.hpp"
39 39
#include "coin/CbcHeuristicRINS.hpp"
40 40

	
41 41
#include "coin/CglGomory.hpp"
42 42
#include "coin/CglProbing.hpp"
43 43
#include "coin/CglKnapsackCover.hpp"
44 44
#include "coin/CglOddHole.hpp"
45 45
#include "coin/CglClique.hpp"
46 46
#include "coin/CglFlowCover.hpp"
47 47
#include "coin/CglMixedIntegerRounding.hpp"
48 48

	
49 49
#include "coin/CbcHeuristic.hpp"
50 50

	
51 51
namespace lemon {
52 52

	
53 53
  CbcMip::CbcMip() {
54 54
    _prob = new CoinModel();
55 55
    _prob->setProblemName("LEMON");
56 56
    _osi_solver = 0;
57 57
    _cbc_model = 0;
58 58
    messageLevel(MESSAGE_NOTHING);
59 59
  }
60 60

	
61 61
  CbcMip::CbcMip(const CbcMip& other) {
62 62
    _prob = new CoinModel(*other._prob);
63 63
    _prob->setProblemName("LEMON");
64 64
    _osi_solver = 0;
65 65
    _cbc_model = 0;
66 66
    messageLevel(MESSAGE_NOTHING);
67 67
  }
68 68

	
69 69
  CbcMip::~CbcMip() {
70 70
    delete _prob;
71 71
    if (_osi_solver) delete _osi_solver;
72 72
    if (_cbc_model) delete _cbc_model;
73 73
  }
74 74

	
75 75
  const char* CbcMip::_solverName() const { return "CbcMip"; }
76 76

	
77 77
  int CbcMip::_addCol() {
78 78
    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0, 0, false);
79 79
    return _prob->numberColumns() - 1;
80 80
  }
81 81

	
82 82
  CbcMip* CbcMip::newSolver() const {
83 83
    CbcMip* newlp = new CbcMip;
84 84
    return newlp;
85 85
  }
86 86

	
87 87
  CbcMip* CbcMip::cloneSolver() const {
88 88
    CbcMip* copylp = new CbcMip(*this);
89 89
    return copylp;
90 90
  }
91 91

	
92 92
  int CbcMip::_addRow() {
93 93
    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
94 94
    return _prob->numberRows() - 1;
95 95
  }
96 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
  }
97 109

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
186 198

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

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

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

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

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

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

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

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

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

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

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

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

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

	
258 270
    if (_osi_solver) {
259 271
      delete _osi_solver;
260 272
    }
261 273
#ifdef COIN_HAS_CLP
262 274
    _osi_solver = new OsiClpSolverInterface();
263 275
#elif COIN_HAS_OSL
264 276
    _osi_solver = new OsiOslSolverInterface();
265 277
#else
266 278
#error Cannot instantiate Osi solver
267 279
#endif
268 280

	
269 281
    _osi_solver->loadFromCoinModel(*_prob);
270 282

	
271 283
    if (_cbc_model) {
272 284
      delete _cbc_model;
273 285
    }
274 286
    _cbc_model= new CbcModel(*_osi_solver);
275 287

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

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

	
282 294
    if (!_cbc_model->isInitialSolveAbandoned() &&
283 295
        _cbc_model->isInitialSolveProvenOptimal() &&
284 296
        !_cbc_model->isInitialSolveProvenPrimalInfeasible() &&
285 297
        !_cbc_model->isInitialSolveProvenDualInfeasible()) {
286 298

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

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

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

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

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

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

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

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

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

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

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

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

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

	
348 360
      if (_cbc_model->getNumCols() < 500) {
349 361
        _cbc_model->setMaximumCutPassesAtRoot(-100);
350 362
      } else if (_cbc_model->getNumCols() < 5000) {
351 363
        _cbc_model->setMaximumCutPassesAtRoot(100);
352 364
      } else {
353 365
        _cbc_model->setMaximumCutPassesAtRoot(20);
354 366
      }
355 367

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

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

	
364 376
    if (_cbc_model->isAbandoned()) {
365 377
      return UNSOLVED;
366 378
    } else {
367 379
      return SOLVED;
368 380
    }
369 381
  }
370 382

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

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

	
379 391
  CbcMip::ProblemType CbcMip::_getType() const {
380 392
    if (_cbc_model->isProvenOptimal()) {
381 393
      return OPTIMAL;
382 394
    } else if (_cbc_model->isContinuousUnbounded()) {
383 395
      return UNBOUNDED;
384 396
    }
385 397
    return FEASIBLE;
386 398
  }
387 399

	
388 400
  void CbcMip::_setSense(Sense sense) {
389 401
    switch (sense) {
390 402
    case MIN:
391 403
      _prob->setOptimizationDirection(1.0);
392 404
      break;
393 405
    case MAX:
394 406
      _prob->setOptimizationDirection(- 1.0);
395 407
      break;
396 408
    }
397 409
  }
398 410

	
399 411
  CbcMip::Sense CbcMip::_getSense() const {
400 412
    if (_prob->optimizationDirection() > 0.0) {
401 413
      return MIN;
402 414
    } else if (_prob->optimizationDirection() < 0.0) {
403 415
      return MAX;
404 416
    } else {
405 417
      LEMON_ASSERT(false, "Wrong sense");
406 418
      return CbcMip::Sense();
407 419
    }
408 420
  }
409 421

	
410 422
  void CbcMip::_setColType(int i, CbcMip::ColTypes col_type) {
411 423
    switch (col_type){
412 424
    case INTEGER:
413 425
      _prob->setInteger(i);
414 426
      break;
415 427
    case REAL:
416 428
      _prob->setContinuous(i);
417 429
      break;
418 430
    default:;
419 431
      LEMON_ASSERT(false, "Wrong sense");
420 432
    }
421 433
  }
422 434

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

	
427 439
  void CbcMip::_clear() {
428 440
    delete _prob;
429 441
    if (_osi_solver) {
430 442
      delete _osi_solver;
431 443
      _osi_solver = 0;
432 444
    }
433 445
    if (_cbc_model) {
434 446
      delete _cbc_model;
435 447
      _cbc_model = 0;
436 448
    }
437 449

	
438 450
    _prob = new CoinModel();
439 451
    rows.clear();
440 452
    cols.clear();
441 453
  }
442 454

	
443 455
  void CbcMip::_messageLevel(MessageLevel level) {
444 456
    switch (level) {
445 457
    case MESSAGE_NOTHING:
446 458
      _message_level = 0;
447 459
      break;
448 460
    case MESSAGE_ERROR:
449 461
      _message_level = 1;
450 462
      break;
451 463
    case MESSAGE_WARNING:
452 464
      _message_level = 1;
453 465
      break;
454 466
    case MESSAGE_NORMAL:
455 467
      _message_level = 2;
456 468
      break;
457 469
    case MESSAGE_VERBOSE:
458 470
      _message_level = 3;
459 471
      break;
460 472
    }
461 473
  }
462 474

	
463 475
} //END OF 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-2009
5
 * Copyright (C) 2003-2010
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
// -*- C++ -*-
20 20
#ifndef LEMON_CBC_H
21 21
#define LEMON_CBC_H
22 22

	
23 23
///\file
24 24
///\brief Header of the LEMON-CBC mip solver interface.
25 25
///\ingroup lp_group
26 26

	
27 27
#include <lemon/lp_base.h>
28 28

	
29 29
class CoinModel;
30 30
class OsiSolverInterface;
31 31
class CbcModel;
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  /// \brief Interface for the CBC MIP solver
36 36
  ///
37 37
  /// This class implements an interface for the CBC MIP solver.
38 38
  ///\ingroup lp_group
39 39
  class CbcMip : public MipSolver {
40 40
  protected:
41 41

	
42 42
    CoinModel *_prob;
43 43
    OsiSolverInterface *_osi_solver;
44 44
    CbcModel *_cbc_model;
45 45

	
46 46
  public:
47 47

	
48 48
    /// \e
49 49
    CbcMip();
50 50
    /// \e
51 51
    CbcMip(const CbcMip&);
52 52
    /// \e
53 53
    ~CbcMip();
54 54
    /// \e
55 55
    virtual CbcMip* newSolver() const;
56 56
    /// \e
57 57
    virtual CbcMip* cloneSolver() const;
58 58

	
59 59
  protected:
60 60

	
61 61
    virtual const char* _solverName() const;
62 62

	
63 63
    virtual int _addCol();
64 64
    virtual int _addRow();
65
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
65 66

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
116 117
    virtual void _clear();
117 118

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

	
121 122
    int _message_level;
122 123

	
123
    
124

	
124 125

	
125 126
  };
126 127

	
127 128
}
128 129

	
129 130
#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-2009
5
 * Copyright (C) 2003-2010
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_CIRCULATION_H
20 20
#define LEMON_CIRCULATION_H
21 21

	
22 22
#include <lemon/tolerance.h>
23 23
#include <lemon/elevator.h>
24 24
#include <limits>
25 25

	
26 26
///\ingroup max_flow
27 27
///\file
28 28
///\brief Push-relabel algorithm for finding a feasible circulation.
29 29
///
30 30
namespace lemon {
31 31

	
32 32
  /// \brief Default traits class of Circulation class.
33 33
  ///
34 34
  /// Default traits class of Circulation class.
35 35
  ///
36 36
  /// \tparam GR Type of the digraph the algorithm runs on.
37 37
  /// \tparam LM The type of the lower bound map.
38 38
  /// \tparam UM The type of the upper bound (capacity) map.
39 39
  /// \tparam SM The type of the supply map.
40 40
  template <typename GR, typename LM,
41 41
            typename UM, typename SM>
42 42
  struct CirculationDefaultTraits {
43 43

	
44 44
    /// \brief The type of the digraph the algorithm runs on.
45 45
    typedef GR Digraph;
46 46

	
47 47
    /// \brief The type of the lower bound map.
48 48
    ///
49 49
    /// The type of the map that stores the lower bounds on the arcs.
50 50
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
51 51
    typedef LM LowerMap;
52 52

	
53 53
    /// \brief The type of the upper bound (capacity) map.
54 54
    ///
55 55
    /// The type of the map that stores the upper bounds (capacities)
56 56
    /// on the arcs.
57 57
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
58 58
    typedef UM UpperMap;
59 59

	
60 60
    /// \brief The type of supply map.
61 61
    ///
62
    /// The type of the map that stores the signed supply values of the 
63
    /// nodes. 
62
    /// The type of the map that stores the signed supply values of the
63
    /// nodes.
64 64
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
65 65
    typedef SM SupplyMap;
66 66

	
67 67
    /// \brief The type of the flow and supply values.
68 68
    typedef typename SupplyMap::Value Value;
69 69

	
70 70
    /// \brief The type of the map that stores the flow values.
71 71
    ///
72 72
    /// The type of the map that stores the flow values.
73 73
    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
74 74
    /// concept.
75
#ifdef DOXYGEN
76
    typedef GR::ArcMap<Value> FlowMap;
77
#else
75 78
    typedef typename Digraph::template ArcMap<Value> FlowMap;
79
#endif
76 80

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

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

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

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

	
109 116
  };
110 117

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

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

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

	
134 141
     \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
135 142
     \geq sup(u) \quad \forall u\in V, \f]
136 143
     \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
137
     
144

	
138 145
     The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
139 146
     zero or negative in order to have a feasible solution (since the sum
140 147
     of the expressions on the left-hand side of the inequalities is zero).
141 148
     It means that the total demand must be greater or equal to the total
142 149
     supply and all the supplies have to be carried out from the supply nodes,
143 150
     but there could be demands that are not satisfied.
144 151
     If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
145 152
     constraints have to be satisfied with equality, i.e. all demands
146 153
     have to be satisfied and all supplies have to be used.
147
     
154

	
148 155
     If you need the opposite inequalities in the supply/demand constraints
149 156
     (i.e. the total demand is less than the total supply and all the demands
150 157
     have to be satisfied while there could be supplies that are not used),
151 158
     then you could easily transform the problem to the above form by reversing
152 159
     the direction of the arcs and taking the negative of the supply values
153 160
     (e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
154 161

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

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

	
162 169
     \tparam GR The type of the digraph the algorithm runs on.
163 170
     \tparam LM The type of the lower bound map. The default
164 171
     map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
165 172
     \tparam UM The type of the upper bound (capacity) map.
166 173
     The default map type is \c LM.
167 174
     \tparam SM The type of the supply map. The default map type is
168 175
     \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
176
     \tparam TR The traits class that defines various types used by the
177
     algorithm. By default, it is \ref CirculationDefaultTraits
178
     "CirculationDefaultTraits<GR, LM, UM, SM>".
179
     In most cases, this parameter should not be set directly,
180
     consider to use the named template parameters instead.
169 181
  */
170 182
#ifdef DOXYGEN
171 183
template< typename GR,
172 184
          typename LM,
173 185
          typename UM,
174 186
          typename SM,
175 187
          typename TR >
176 188
#else
177 189
template< typename GR,
178 190
          typename LM = typename GR::template ArcMap<int>,
179 191
          typename UM = LM,
180 192
          typename SM = typename GR::template NodeMap<typename UM::Value>,
181 193
          typename TR = CirculationDefaultTraits<GR, LM, UM, SM> >
182 194
#endif
183 195
  class Circulation {
184 196
  public:
185 197

	
186 198
    ///The \ref CirculationDefaultTraits "traits class" of the algorithm.
187 199
    typedef TR Traits;
188 200
    ///The type of the digraph the algorithm runs on.
189 201
    typedef typename Traits::Digraph Digraph;
190 202
    ///The type of the flow and supply values.
191 203
    typedef typename Traits::Value Value;
192 204

	
193 205
    ///The type of the lower bound map.
194 206
    typedef typename Traits::LowerMap LowerMap;
195 207
    ///The type of the upper bound (capacity) map.
196 208
    typedef typename Traits::UpperMap UpperMap;
197 209
    ///The type of the supply map.
198 210
    typedef typename Traits::SupplyMap SupplyMap;
199 211
    ///The type of the flow map.
200 212
    typedef typename Traits::FlowMap FlowMap;
201 213

	
202 214
    ///The type of the elevator.
203 215
    typedef typename Traits::Elevator Elevator;
204 216
    ///The type of the tolerance.
205 217
    typedef typename Traits::Tolerance Tolerance;
206 218

	
207 219
  private:
208 220

	
209 221
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
210 222

	
211 223
    const Digraph &_g;
212 224
    int _node_num;
213 225

	
214 226
    const LowerMap *_lo;
215 227
    const UpperMap *_up;
216 228
    const SupplyMap *_supply;
217 229

	
218 230
    FlowMap *_flow;
219 231
    bool _local_flow;
220 232

	
221 233
    Elevator* _level;
222 234
    bool _local_level;
223 235

	
224 236
    typedef typename Digraph::template NodeMap<Value> ExcessMap;
225 237
    ExcessMap* _excess;
226 238

	
227 239
    Tolerance _tol;
228 240
    int _el;
229 241

	
230 242
  public:
231 243

	
232 244
    typedef Circulation Create;
233 245

	
234 246
    ///\name Named Template Parameters
235 247

	
236 248
    ///@{
237 249

	
238 250
    template <typename T>
239 251
    struct SetFlowMapTraits : public Traits {
240 252
      typedef T FlowMap;
241 253
      static FlowMap *createFlowMap(const Digraph&) {
242 254
        LEMON_ASSERT(false, "FlowMap is not initialized");
243 255
        return 0; // ignore warnings
244 256
      }
245 257
    };
246 258

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

	
260 272
    template <typename T>
261 273
    struct SetElevatorTraits : public Traits {
262 274
      typedef T Elevator;
263 275
      static Elevator *createElevator(const Digraph&, int) {
264 276
        LEMON_ASSERT(false, "Elevator is not initialized");
265 277
        return 0; // ignore warnings
266 278
      }
267 279
    };
268 280

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

	
286 298
    template <typename T>
287 299
    struct SetStandardElevatorTraits : public Traits {
288 300
      typedef T Elevator;
289 301
      static Elevator *createElevator(const Digraph& digraph, int max_level) {
290 302
        return new Elevator(digraph, max_level);
291 303
      }
292 304
    };
293 305

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

	
314 326
    /// @}
315 327

	
316 328
  protected:
317 329

	
318 330
    Circulation() {}
319 331

	
320 332
  public:
321 333

	
322 334
    /// Constructor.
323 335

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

	
337 349
    /// Destructor.
338 350
    ~Circulation() {
339 351
      destroyStructures();
340 352
    }
341 353

	
342 354

	
343 355
  private:
344 356

	
345 357
    bool checkBoundMaps() {
346 358
      for (ArcIt e(_g);e!=INVALID;++e) {
347 359
        if (_tol.less((*_up)[e], (*_lo)[e])) return false;
348 360
      }
349 361
      return true;
350 362
    }
351 363

	
352 364
    void createStructures() {
353 365
      _node_num = _el = countNodes(_g);
354 366

	
355 367
      if (!_flow) {
356 368
        _flow = Traits::createFlowMap(_g);
357 369
        _local_flow = true;
358 370
      }
359 371
      if (!_level) {
360 372
        _level = Traits::createElevator(_g, _node_num);
361 373
        _local_level = true;
362 374
      }
363 375
      if (!_excess) {
364 376
        _excess = new ExcessMap(_g);
365 377
      }
366 378
    }
367 379

	
368 380
    void destroyStructures() {
369 381
      if (_local_flow) {
370 382
        delete _flow;
371 383
      }
372 384
      if (_local_level) {
373 385
        delete _level;
374 386
      }
375 387
      if (_excess) {
376 388
        delete _excess;
377 389
      }
378 390
    }
379 391

	
380 392
  public:
381 393

	
382 394
    /// Sets the lower bound map.
383 395

	
384 396
    /// Sets the lower bound map.
385 397
    /// \return <tt>(*this)</tt>
386 398
    Circulation& lowerMap(const LowerMap& map) {
387 399
      _lo = &map;
388 400
      return *this;
389 401
    }
390 402

	
391 403
    /// Sets the upper bound (capacity) map.
392 404

	
393 405
    /// Sets the upper bound (capacity) map.
394 406
    /// \return <tt>(*this)</tt>
395 407
    Circulation& upperMap(const UpperMap& map) {
396 408
      _up = &map;
397 409
      return *this;
398 410
    }
399 411

	
400 412
    /// Sets the supply map.
401 413

	
402 414
    /// Sets the supply map.
403 415
    /// \return <tt>(*this)</tt>
404 416
    Circulation& supplyMap(const SupplyMap& map) {
405 417
      _supply = &map;
406 418
      return *this;
407 419
    }
408 420

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

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

	
443 455
    /// \brief Returns a const reference to the elevator.
444 456
    ///
445 457
    /// Returns a const reference to the elevator.
446 458
    ///
447 459
    /// \pre Either \ref run() or \ref init() must be called before
448 460
    /// using this function.
449 461
    const Elevator& elevator() const {
450 462
      return *_level;
451 463
    }
452 464

	
453
    /// \brief Sets the tolerance used by algorithm.
465
    /// \brief Sets the tolerance used by the algorithm.
454 466
    ///
455
    /// Sets the tolerance used by algorithm.
467
    /// Sets the tolerance object used by the algorithm.
468
    /// \return <tt>(*this)</tt>
456 469
    Circulation& tolerance(const Tolerance& tolerance) {
457 470
      _tol = tolerance;
458 471
      return *this;
459 472
    }
460 473

	
461 474
    /// \brief Returns a const reference to the tolerance.
462 475
    ///
463
    /// Returns a const reference to the tolerance.
476
    /// Returns a const reference to the tolerance object used by
477
    /// the algorithm.
464 478
    const Tolerance& tolerance() const {
465 479
      return _tol;
466 480
    }
467 481

	
468 482
    /// \name Execution Control
469 483
    /// The simplest way to execute the algorithm is to call \ref run().\n
470
    /// If you need more control on the initial solution or the execution,
471
    /// first you have to call one of the \ref init() functions, then
484
    /// If you need better control on the initial solution or the execution,
485
    /// you have to call one of the \ref init() functions first, then
472 486
    /// the \ref start() function.
473 487

	
474 488
    ///@{
475 489

	
476 490
    /// Initializes the internal data structures.
477 491

	
478 492
    /// Initializes the internal data structures and sets all flow values
479 493
    /// to the lower bound.
480 494
    void init()
481 495
    {
482 496
      LEMON_DEBUG(checkBoundMaps(),
483 497
        "Upper bounds must be greater or equal to the lower bounds");
484 498

	
485 499
      createStructures();
486 500

	
487 501
      for(NodeIt n(_g);n!=INVALID;++n) {
488 502
        (*_excess)[n] = (*_supply)[n];
489 503
      }
490 504

	
491 505
      for (ArcIt e(_g);e!=INVALID;++e) {
492 506
        _flow->set(e, (*_lo)[e]);
493 507
        (*_excess)[_g.target(e)] += (*_flow)[e];
494 508
        (*_excess)[_g.source(e)] -= (*_flow)[e];
495 509
      }
496 510

	
497 511
      // global relabeling tested, but in general case it provides
498 512
      // worse performance for random digraphs
499 513
      _level->initStart();
500 514
      for(NodeIt n(_g);n!=INVALID;++n)
501 515
        _level->initAddItem(n);
502 516
      _level->initFinish();
503 517
      for(NodeIt n(_g);n!=INVALID;++n)
504 518
        if(_tol.positive((*_excess)[n]))
505 519
          _level->activate(n);
506 520
    }
507 521

	
508 522
    /// Initializes the internal data structures using a greedy approach.
509 523

	
510 524
    /// Initializes the internal data structures using a greedy approach
511 525
    /// to construct the initial solution.
512 526
    void greedyInit()
513 527
    {
514 528
      LEMON_DEBUG(checkBoundMaps(),
515 529
        "Upper bounds must be greater or equal to the lower bounds");
516 530

	
517 531
      createStructures();
518 532

	
519 533
      for(NodeIt n(_g);n!=INVALID;++n) {
520 534
        (*_excess)[n] = (*_supply)[n];
521 535
      }
522 536

	
523 537
      for (ArcIt e(_g);e!=INVALID;++e) {
524 538
        if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) {
525 539
          _flow->set(e, (*_up)[e]);
526 540
          (*_excess)[_g.target(e)] += (*_up)[e];
527 541
          (*_excess)[_g.source(e)] -= (*_up)[e];
528 542
        } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) {
529 543
          _flow->set(e, (*_lo)[e]);
530 544
          (*_excess)[_g.target(e)] += (*_lo)[e];
531 545
          (*_excess)[_g.source(e)] -= (*_lo)[e];
532 546
        } else {
533 547
          Value fc = -(*_excess)[_g.target(e)];
534 548
          _flow->set(e, fc);
535 549
          (*_excess)[_g.target(e)] = 0;
536 550
          (*_excess)[_g.source(e)] -= fc;
537 551
        }
538 552
      }
539 553

	
540 554
      _level->initStart();
541 555
      for(NodeIt n(_g);n!=INVALID;++n)
542 556
        _level->initAddItem(n);
543 557
      _level->initFinish();
544 558
      for(NodeIt n(_g);n!=INVALID;++n)
545 559
        if(_tol.positive((*_excess)[n]))
546 560
          _level->activate(n);
547 561
    }
548 562

	
549 563
    ///Executes the algorithm
550 564

	
551 565
    ///This function executes the algorithm.
552 566
    ///
553 567
    ///\return \c true if a feasible circulation is found.
554 568
    ///
555 569
    ///\sa barrier()
556 570
    ///\sa barrierMap()
557 571
    bool start()
558 572
    {
559 573

	
560 574
      Node act;
561 575
      Node bact=INVALID;
562 576
      Node last_activated=INVALID;
563 577
      while((act=_level->highestActive())!=INVALID) {
564 578
        int actlevel=(*_level)[act];
565 579
        int mlevel=_node_num;
566 580
        Value exc=(*_excess)[act];
567 581

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

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

	
637 651
    /// Runs the algorithm.
638 652

	
639 653
    /// This function runs the algorithm.
640 654
    ///
641 655
    /// \return \c true if a feasible circulation is found.
642 656
    ///
643 657
    /// \note Apart from the return value, c.run() is just a shortcut of
644 658
    /// the following code.
645 659
    /// \code
646 660
    ///   c.greedyInit();
647 661
    ///   c.start();
648 662
    /// \endcode
649 663
    bool run() {
650 664
      greedyInit();
651 665
      return start();
652 666
    }
653 667

	
654 668
    /// @}
655 669

	
656 670
    /// \name Query Functions
657 671
    /// The results of the circulation algorithm can be obtained using
658 672
    /// these functions.\n
659 673
    /// Either \ref run() or \ref start() should be called before
660 674
    /// using them.
661 675

	
662 676
    ///@{
663 677

	
664 678
    /// \brief Returns the flow value on the given arc.
665 679
    ///
666 680
    /// Returns the flow value on the given arc.
667 681
    ///
668 682
    /// \pre Either \ref run() or \ref init() must be called before
669 683
    /// using this function.
670 684
    Value flow(const Arc& arc) const {
671 685
      return (*_flow)[arc];
672 686
    }
673 687

	
674 688
    /// \brief Returns a const reference to the flow map.
675 689
    ///
676 690
    /// Returns a const reference to the arc map storing the found flow.
677 691
    ///
678 692
    /// \pre Either \ref run() or \ref init() must be called before
679 693
    /// using this function.
680 694
    const FlowMap& flowMap() const {
681 695
      return *_flow;
682 696
    }
683 697

	
684 698
    /**
685 699
       \brief Returns \c true if the given node is in a barrier.
686 700

	
687 701
       Barrier is a set \e B of nodes for which
688 702

	
689 703
       \f[ \sum_{uv\in A: u\in B} upper(uv) -
690 704
           \sum_{uv\in A: v\in B} lower(uv) < \sum_{v\in B} sup(v) \f]
691 705

	
692 706
       holds. The existence of a set with this property prooves that a
693 707
       feasible circualtion cannot exist.
694 708

	
695 709
       This function returns \c true if the given node is in the found
696 710
       barrier. If a feasible circulation is found, the function
697 711
       gives back \c false for every node.
698 712

	
699 713
       \pre Either \ref run() or \ref init() must be called before
700 714
       using this function.
701 715

	
702 716
       \sa barrierMap()
703 717
       \sa checkBarrier()
704 718
    */
705 719
    bool barrier(const Node& node) const
706 720
    {
707 721
      return (*_level)[node] >= _el;
708 722
    }
709 723

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

	
734 748
    /// @}
735 749

	
736 750
    /// \name Checker Functions
737 751
    /// The feasibility of the results can be checked using
738 752
    /// these functions.\n
739 753
    /// Either \ref run() or \ref start() should be called before
740 754
    /// using them.
741 755

	
742 756
    ///@{
743 757

	
744 758
    ///Check if the found flow is a feasible circulation
745 759

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

	
761 775
    ///Check whether or not the last execution provides a barrier
762 776

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

	
788 802
    /// @}
789 803

	
790 804
  };
791 805

	
792 806
}
793 807

	
794 808
#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-2010
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/clp.h>
20 20
#include <coin/ClpSimplex.hpp>
21 21

	
22 22
namespace lemon {
23 23

	
24 24
  ClpLp::ClpLp() {
25 25
    _prob = new ClpSimplex();
26 26
    _init_temporals();
27 27
    messageLevel(MESSAGE_NOTHING);
28 28
  }
29 29

	
30 30
  ClpLp::ClpLp(const ClpLp& other) {
31 31
    _prob = new ClpSimplex(*other._prob);
32 32
    rows = other.rows;
33 33
    cols = other.cols;
34 34
    _init_temporals();
35 35
    messageLevel(MESSAGE_NOTHING);
36 36
  }
37 37

	
38 38
  ClpLp::~ClpLp() {
39 39
    delete _prob;
40 40
    _clear_temporals();
41 41
  }
42 42

	
43 43
  void ClpLp::_init_temporals() {
44 44
    _primal_ray = 0;
45 45
    _dual_ray = 0;
46 46
  }
47 47

	
48 48
  void ClpLp::_clear_temporals() {
49 49
    if (_primal_ray) {
50 50
      delete[] _primal_ray;
51 51
      _primal_ray = 0;
52 52
    }
53 53
    if (_dual_ray) {
54 54
      delete[] _dual_ray;
55 55
      _dual_ray = 0;
56 56
    }
57 57
  }
58 58

	
59 59
  ClpLp* ClpLp::newSolver() const {
60 60
    ClpLp* newlp = new ClpLp;
61 61
    return newlp;
62 62
  }
63 63

	
64 64
  ClpLp* ClpLp::cloneSolver() const {
65 65
    ClpLp* copylp = new ClpLp(*this);
66 66
    return copylp;
67 67
  }
68 68

	
69 69
  const char* ClpLp::_solverName() const { return "ClpLp"; }
70 70

	
71 71
  int ClpLp::_addCol() {
72 72
    _prob->addColumn(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX, 0.0);
73 73
    return _prob->numberColumns() - 1;
74 74
  }
75 75

	
76 76
  int ClpLp::_addRow() {
77 77
    _prob->addRow(0, 0, 0, -COIN_DBL_MAX, COIN_DBL_MAX);
78 78
    return _prob->numberRows() - 1;
79 79
  }
80 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

	
81 94

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

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

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

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

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

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

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

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

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

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

	
130 143

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	
379 392

	
380 393
  ClpLp::ProblemType ClpLp::_getPrimalType() const {
381 394
    if (_prob->isProvenOptimal()) {
382 395
      return OPTIMAL;
383 396
    } else if (_prob->isProvenPrimalInfeasible()) {
384 397
      return INFEASIBLE;
385 398
    } else if (_prob->isProvenDualInfeasible()) {
386 399
      return UNBOUNDED;
387 400
    } else {
388 401
      return UNDEFINED;
389 402
    }
390 403
  }
391 404

	
392 405
  ClpLp::ProblemType ClpLp::_getDualType() const {
393 406
    if (_prob->isProvenOptimal()) {
394 407
      return OPTIMAL;
395 408
    } else if (_prob->isProvenDualInfeasible()) {
396 409
      return INFEASIBLE;
397 410
    } else if (_prob->isProvenPrimalInfeasible()) {
398 411
      return INFEASIBLE;
399 412
    } else {
400 413
      return UNDEFINED;
401 414
    }
402 415
  }
403 416

	
404 417
  void ClpLp::_setSense(ClpLp::Sense sense) {
405 418
    switch (sense) {
406 419
    case MIN:
407 420
      _prob->setOptimizationDirection(1);
408 421
      break;
409 422
    case MAX:
410 423
      _prob->setOptimizationDirection(-1);
411 424
      break;
412 425
    }
413 426
  }
414 427

	
415 428
  ClpLp::Sense ClpLp::_getSense() const {
416 429
    double dir = _prob->optimizationDirection();
417 430
    if (dir > 0.0) {
418 431
      return MIN;
419 432
    } else {
420 433
      return MAX;
421 434
    }
422 435
  }
423 436

	
424 437
  void ClpLp::_clear() {
425 438
    delete _prob;
426 439
    _prob = new ClpSimplex();
427 440
    rows.clear();
428 441
    cols.clear();
429 442
    _col_names_ref.clear();
430 443
    _clear_temporals();
431 444
  }
432 445

	
433 446
  void ClpLp::_messageLevel(MessageLevel level) {
434 447
    switch (level) {
435 448
    case MESSAGE_NOTHING:
436 449
      _prob->setLogLevel(0);
437 450
      break;
438 451
    case MESSAGE_ERROR:
439 452
      _prob->setLogLevel(1);
440 453
      break;
441 454
    case MESSAGE_WARNING:
442 455
      _prob->setLogLevel(2);
443 456
      break;
444 457
    case MESSAGE_NORMAL:
445 458
      _prob->setLogLevel(3);
446 459
      break;
447 460
    case MESSAGE_VERBOSE:
448 461
      _prob->setLogLevel(4);
449 462
      break;
450 463
    }
451 464
  }
452 465

	
453 466
} //END OF 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-2010
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_CLP_H
20 20
#define LEMON_CLP_H
21 21

	
22 22
///\file
23 23
///\brief Header of the LEMON-CLP lp solver interface.
24 24

	
25 25
#include <vector>
26 26
#include <string>
27 27

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

	
30 30
class ClpSimplex;
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  /// \ingroup lp_group
35 35
  ///
36 36
  /// \brief Interface for the CLP solver
37 37
  ///
38 38
  /// This class implements an interface for the Clp LP solver.  The
39 39
  /// Clp library is an object oriented lp solver library developed at
40 40
  /// the IBM. The CLP is part of the COIN-OR package and it can be
41 41
  /// used with Common Public License.
42 42
  class ClpLp : public LpSolver {
43 43
  protected:
44 44

	
45 45
    ClpSimplex* _prob;
46 46

	
47 47
    std::map<std::string, int> _col_names_ref;
48 48
    std::map<std::string, int> _row_names_ref;
49 49

	
50 50
  public:
51 51

	
52 52
    /// \e
53 53
    ClpLp();
54 54
    /// \e
55 55
    ClpLp(const ClpLp&);
56 56
    /// \e
57 57
    ~ClpLp();
58 58

	
59 59
    /// \e
60 60
    virtual ClpLp* newSolver() const;
61 61
    /// \e
62 62
    virtual ClpLp* cloneSolver() const;
63 63

	
64 64
  protected:
65 65

	
66 66
    mutable double* _primal_ray;
67 67
    mutable double* _dual_ray;
68 68

	
69 69
    void _init_temporals();
70 70
    void _clear_temporals();
71 71

	
72 72
  protected:
73 73

	
74 74
    virtual const char* _solverName() const;
75 75

	
76 76
    virtual int _addCol();
77 77
    virtual int _addRow();
78
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
78 79

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

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

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

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

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

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

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

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

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

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

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

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

	
121 122
    virtual SolveExitStatus _solve();
122 123

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

	
126 127
    virtual Value _getPrimalValue() const;
127 128

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

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

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

	
137 138
    virtual void _clear();
138 139

	
139 140
    virtual void _messageLevel(MessageLevel);
140
    
141

	
141 142
  public:
142 143

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

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

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

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

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

	
158 159
  };
159 160

	
160 161
} //END OF NAMESPACE LEMON
161 162

	
162 163
#endif //LEMON_CLP_H
163 164

	
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-2009
5
 * Copyright (C) 2003-2010
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_CONCEPTS_DIGRAPH_H
20 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.
117
      /// 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:
109
      /// This iterator goes through each node of the digraph.
110
      /// Its usage is quite simple, for example, you can count the number
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
      /// Its usage is quite simple, for example you can count the number
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
      /// 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.
244
      /// Its usage is quite simple, for example, you can count the number
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.
300
      /// 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:
285
      /// Iterator class for the arcs.
286

	
287
      /// This iterator goes through each arc of the digraph.
288
      /// Its usage is quite simple, for example, you can count the number
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 Reference map of the nodes to type \c T.
425
      ///
426
      /// Reference map of the nodes to type \c T.
424
      /// Standard graph map type for the nodes.
425
      /// It conforms to the ReferenceMap concept.
427 426
      template<class T>
428 427
      class NodeMap : public ReferenceMap<Node, T, T&, const T&> {
429 428
      public:
430 429

	
431
        ///\e
432
        NodeMap(const Digraph&) { }
433
        ///\e
430
        /// Constructor
431
        explicit NodeMap(const Digraph&) { }
432
        /// Constructor with given initial value
434 433
        NodeMap(const Digraph&, T) { }
435 434

	
436 435
      private:
437 436
        ///Copy constructor
438
        NodeMap(const NodeMap& nm) : 
437
        NodeMap(const NodeMap& nm) :
439 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 Reference 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.
449
      /// Standard graph map type for the arcs.
450
      /// It conforms to the ReferenceMap concept.
451 451
      template<class T>
452 452
      class ArcMap : public ReferenceMap<Arc, T, T&, const T&> {
453 453
      public:
454 454

	
455
        ///\e
456
        ArcMap(const Digraph&) { }
457
        ///\e
455
        /// Constructor
456
        explicit ArcMap(const Digraph&) { }
457
        /// Constructor with given initial value
458 458
        ArcMap(const Digraph&, T) { }
459

	
459 460
      private:
460 461
        ///Copy constructor
461 462
        ArcMap(const ArcMap& em) :
462 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() {
474 475
          checkConcept<BaseDigraphComponent, _Digraph>();
475 476
          checkConcept<IterableDigraphComponent<>, _Digraph>();
476 477
          checkConcept<IDableDigraphComponent<>, _Digraph>();
477 478
          checkConcept<MappableDigraphComponent<>, _Digraph>();
478 479
        }
479 480
      };
480 481

	
481 482
    };
482 483

	
483 484
  } //namespace concepts
484 485
} //namespace lemon
485 486

	
486 487

	
487 488

	
488 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-2009
5
 * Copyright (C) 2003-2010
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 23
#ifndef LEMON_CONCEPTS_GRAPH_H
24 24
#define LEMON_CONCEPTS_GRAPH_H
25 25

	
26 26
#include <lemon/concepts/graph_components.h>
27
#include <lemon/concepts/maps.h>
28
#include <lemon/concept_check.h>
27 29
#include <lemon/core.h>
28 30

	
29 31
namespace lemon {
30 32
  namespace concepts {
31 33

	
32 34
    /// \ingroup graph_concepts
33 35
    ///
34
    /// \brief Class describing the concept of Undirected Graphs.
36
    /// \brief Class describing the concept of undirected graphs.
35 37
    ///
36
    /// This class describes the common interface of all Undirected
37
    /// Graphs.
38
    /// This class describes the common interface of all undirected
39
    /// graphs.
38 40
    ///
39
    /// As all concept describing classes it provides only interface
40
    /// without any sensible implementation. So any algorithm for
41
    /// 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
42 44
    /// run properly, of course.
45
    /// An actual graph implementation like \ref ListGraph or
46
    /// \ref SmartGraph may have additional functionality.
43 47
    ///
44
    /// The LEMON undirected graphs also fulfill the concept of
45
    /// directed graphs (\ref lemon::concepts::Digraph "Digraph
46
    /// Concept"). Each edges can be seen as two opposite
47
    /// directed arc and consequently the undirected graph can be
48
    /// seen as the direceted graph of these directed arcs. The
49
    /// Graph has the Edge inner class for the edges and
50
    /// the Arc type for the directed arcs. The Arc type is
51
    /// convertible to Edge or inherited from it so from a directed
52
    /// 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.
53 61
    ///
54
    /// In the sense of the LEMON each edge has a default
55
    /// direction (it should be in every computer implementation,
56
    /// because the order of edge's nodes defines an
57
    /// orientation). With the default orientation we can define that
58
    /// the directed arc is forward or backward directed. With the \c
59
    /// direction() and \c direct() function we can get the direction
60
    /// 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.
61 68
    ///
62
    /// The EdgeIt is an iterator for the edges. We can use
63
    /// the EdgeMap to map values for the edges. The InArcIt and
64
    /// OutArcIt iterates on the same edges but with opposite
65
    /// direction. The IncEdgeIt iterates also on the same edges
66
    /// as the OutArcIt and InArcIt but it is not convertible to Arc just
67
    /// 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
68 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

	
69 81
    public:
70
      /// \brief The undirected graph should be tagged by the
71
      /// UndirectedTag.
82
      /// Default constructor.
83
      Graph() {}
84

	
85
      /// \brief Undirected graphs should be tagged with \c UndirectedTag.
72 86
      ///
73
      /// The undirected graph should be tagged by the UndirectedTag. This
74
      /// 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
75 90
      /// specializations for undirected graphs.
76 91
      typedef True UndirectedTag;
77 92

	
78
      /// \brief The base type of node iterators,
79
      /// or in other words, the trivial node iterator.
80
      ///
81
      /// This is the base type of each node iterator,
82
      /// thus each kind of node iterator converts to this.
83
      /// More precisely each kind of node iterator should be inherited
84
      /// 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.
85 98
      class Node {
86 99
      public:
87 100
        /// Default constructor
88 101

	
89
        /// @warning The default constructor sets the iterator
90
        /// to an undefined value.
102
        /// Default constructor.
103
        /// \warning It sets the object to an undefined value.
91 104
        Node() { }
92 105
        /// Copy constructor.
93 106

	
94 107
        /// Copy constructor.
95 108
        ///
96 109
        Node(const Node&) { }
97 110

	
98
        /// Invalid constructor \& conversion.
111
        /// %Invalid constructor \& conversion.
99 112

	
100
        /// This constructor initializes the iterator to be invalid.
113
        /// Initializes the object to be invalid.
101 114
        /// \sa Invalid for more details.
102 115
        Node(Invalid) { }
103 116
        /// Equality operator
104 117

	
118
        /// Equality operator.
119
        ///
105 120
        /// Two iterators are equal if and only if they point to the
106
        /// same object or both are invalid.
121
        /// same object or both are \c INVALID.
107 122
        bool operator==(Node) const { return true; }
108 123

	
109 124
        /// Inequality operator
110 125

	
111
        /// \sa operator==(Node n)
112
        ///
126
        /// Inequality operator.
113 127
        bool operator!=(Node) const { return true; }
114 128

	
115 129
        /// Artificial ordering operator.
116 130

	
117
        /// To allow the use of graph descriptors as key type in std::map or
118
        /// similar associative container we require this.
131
        /// Artificial ordering operator.
119 132
        ///
120
        /// \note This operator only have to define some strict ordering of
133
        /// \note This operator only has to define some strict ordering of
121 134
        /// the items; this order has nothing to do with the iteration
122 135
        /// ordering of the items.
123 136
        bool operator<(Node) const { return false; }
124 137

	
125 138
      };
126 139

	
127
      /// This iterator goes through each node.
140
      /// Iterator class for the nodes.
128 141

	
129
      /// This iterator goes through each node.
130
      /// Its usage is quite simple, for example you can count the number
131
      /// of nodes in graph \c g of type \c Graph like this:
142
      /// This iterator goes through each node of the graph.
143
      /// Its usage is quite simple, for example, you can count the number
144
      /// of nodes in a graph \c g of type \c %Graph like this:
132 145
      ///\code
133 146
      /// int count=0;
134 147
      /// for (Graph::NodeIt n(g); n!=INVALID; ++n) ++count;
135 148
      ///\endcode
136 149
      class NodeIt : public Node {
137 150
      public:
138 151
        /// Default constructor
139 152

	
140
        /// @warning The default constructor sets the iterator
141
        /// to an undefined value.
153
        /// Default constructor.
154
        /// \warning It sets the iterator to an undefined value.
142 155
        NodeIt() { }
143 156
        /// Copy constructor.
144 157

	
145 158
        /// Copy constructor.
146 159
        ///
147 160
        NodeIt(const NodeIt& n) : Node(n) { }
148
        /// Invalid constructor \& conversion.
161
        /// %Invalid constructor \& conversion.
149 162

	
150
        /// Initialize the iterator to be invalid.
163
        /// Initializes the iterator to be invalid.
151 164
        /// \sa Invalid for more details.
152 165
        NodeIt(Invalid) { }
153 166
        /// Sets the iterator to the first node.
154 167

	
155
        /// Sets the iterator to the first node of \c g.
168
        /// Sets the iterator to the first node of the given digraph.
156 169
        ///
157
        NodeIt(const Graph&) { }
158
        /// Node -> NodeIt conversion.
170
        explicit NodeIt(const Graph&) { }
171
        /// Sets the iterator to the given node.
159 172

	
160
        /// Sets the iterator to the node of \c the graph pointed by
161
        /// the trivial iterator.
162
        /// This feature necessitates that each time we
163
        /// iterate the arc-set, the iteration order is the same.
173
        /// Sets the iterator to the given node of the given digraph.
174
        ///
164 175
        NodeIt(const Graph&, const Node&) { }
165 176
        /// Next node.
166 177

	
167 178
        /// Assign the iterator to the next node.
168 179
        ///
169 180
        NodeIt& operator++() { return *this; }
170 181
      };
171 182

	
172 183

	
173
      /// The base type of the edge iterators.
184
      /// The edge type of the graph
174 185

	
175
      /// The base type of the edge iterators.
176
      ///
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.
177 189
      class Edge {
178 190
      public:
179 191
        /// Default constructor
180 192

	
181
        /// @warning The default constructor sets the iterator
182
        /// to an undefined value.
193
        /// Default constructor.
194
        /// \warning It sets the object to an undefined value.
183 195
        Edge() { }
184 196
        /// Copy constructor.
185 197

	
186 198
        /// Copy constructor.
187 199
        ///
188 200
        Edge(const Edge&) { }
189
        /// Initialize the iterator to be invalid.
201
        /// %Invalid constructor \& conversion.
190 202

	
191
        /// Initialize the iterator to be invalid.
192
        ///
203
        /// Initializes the object to be invalid.
204
        /// \sa Invalid for more details.
193 205
        Edge(Invalid) { }
194 206
        /// Equality operator
195 207

	
208
        /// Equality operator.
209
        ///
196 210
        /// Two iterators are equal if and only if they point to the
197
        /// same object or both are invalid.
211
        /// same object or both are \c INVALID.
198 212
        bool operator==(Edge) const { return true; }
199 213
        /// Inequality operator
200 214

	
201
        /// \sa operator==(Edge n)
202
        ///
215
        /// Inequality operator.
203 216
        bool operator!=(Edge) const { return true; }
204 217

	
205 218
        /// Artificial ordering operator.
206 219

	
207
        /// To allow the use of graph descriptors as key type in std::map or
208
        /// similar associative container we require this.
220
        /// Artificial ordering operator.
209 221
        ///
210
        /// \note This operator only have to define some strict ordering of
211
        /// the items; this order has nothing to do with the iteration
212
        /// 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.
213 225
        bool operator<(Edge) const { return false; }
214 226
      };
215 227

	
216
      /// This iterator goes through each edge.
228
      /// Iterator class for the edges.
217 229

	
218
      /// This iterator goes through each edge of a graph.
219
      /// Its usage is quite simple, for example you can count the number
220
      /// of edges in a graph \c g of type \c Graph as follows:
230
      /// This iterator goes through each edge of the graph.
231
      /// Its usage is quite simple, for example, you can count the number
232
      /// of edges in a graph \c g of type \c %Graph as follows:
221 233
      ///\code
222 234
      /// int count=0;
223 235
      /// for(Graph::EdgeIt e(g); e!=INVALID; ++e) ++count;
224 236
      ///\endcode
225 237
      class EdgeIt : public Edge {
226 238
      public:
227 239
        /// Default constructor
228 240

	
229
        /// @warning The default constructor sets the iterator
230
        /// to an undefined value.
241
        /// Default constructor.
242
        /// \warning It sets the iterator to an undefined value.
231 243
        EdgeIt() { }
232 244
        /// Copy constructor.
233 245

	
234 246
        /// Copy constructor.
235 247
        ///
236 248
        EdgeIt(const EdgeIt& e) : Edge(e) { }
237
        /// Initialize the iterator to be invalid.
249
        /// %Invalid constructor \& conversion.
238 250

	
239
        /// 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.
240 257
        ///
241
        EdgeIt(Invalid) { }
242
        /// This constructor sets the iterator to the first edge.
258
        explicit EdgeIt(const Graph&) { }
259
        /// Sets the iterator to the given edge.
243 260

	
244
        /// This constructor sets the iterator to the first edge.
245
        EdgeIt(const Graph&) { }
246
        /// Edge -> EdgeIt conversion
247

	
248
        /// Sets the iterator to the value of the trivial iterator.
249
        /// This feature necessitates that each time we
250
        /// iterate the edge-set, the iteration order is the
251
        /// same.
261
        /// Sets the iterator to the given edge of the given graph.
262
        ///
252 263
        EdgeIt(const Graph&, const Edge&) { }
253 264
        /// Next edge
254 265

	
255 266
        /// Assign the iterator to the next edge.
267
        ///
256 268
        EdgeIt& operator++() { return *this; }
257 269
      };
258 270

	
259
      /// \brief This iterator goes trough the incident undirected
260
      /// arcs of a node.
261
      ///
262
      /// This iterator goes trough the incident edges
263
      /// of a certain node of a graph. You should assume that the
264
      /// loop arcs will be iterated twice.
265
      ///
266
      /// Its usage is quite simple, for example you can compute the
267
      /// degree (i.e. count the number of incident arcs of a node \c n
268
      /// in graph \c g of type \c Graph as follows.
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.
275
      /// Its usage is quite simple, for example, you can compute the
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.
269 278
      ///
270 279
      ///\code
271 280
      /// int count=0;
272 281
      /// for(Graph::IncEdgeIt e(g, n); e!=INVALID; ++e) ++count;
273 282
      ///\endcode
283
      ///
284
      /// \warning Loop edges will be iterated twice.
274 285
      class IncEdgeIt : public Edge {
275 286
      public:
276 287
        /// Default constructor
277 288

	
278
        /// @warning The default constructor sets the iterator
279
        /// to an undefined value.
289
        /// Default constructor.
290
        /// \warning It sets the iterator to an undefined value.
280 291
        IncEdgeIt() { }
281 292
        /// Copy constructor.
282 293

	
283 294
        /// Copy constructor.
284 295
        ///
285 296
        IncEdgeIt(const IncEdgeIt& e) : Edge(e) { }
286
        /// Initialize the iterator to be invalid.
297
        /// %Invalid constructor \& conversion.
287 298

	
288
        /// 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.
289 305
        ///
290
        IncEdgeIt(Invalid) { }
291
        /// This constructor sets the iterator to first incident arc.
306
        IncEdgeIt(const Graph&, const Node&) { }
307
        /// Sets the iterator to the given edge.
292 308

	
293
        /// This constructor set the iterator to the first incident arc of
294
        /// the node.
295
        IncEdgeIt(const Graph&, const Node&) { }
296
        /// 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
297 313

	
298
        /// Sets the iterator to the value of the trivial iterator \c e.
299
        /// This feature necessitates that each time we
300
        /// iterate the arc-set, the iteration order is the same.
301
        IncEdgeIt(const Graph&, const Edge&) { }
302
        /// Next incident arc
303

	
304
        /// Assign the iterator to the next incident arc
314
        /// Assign the iterator to the next incident edge
305 315
        /// of the corresponding node.
306 316
        IncEdgeIt& operator++() { return *this; }
307 317
      };
308 318

	
309
      /// The directed arc type.
319
      /// The arc type of the graph
310 320

	
311
      /// The directed arc type. It can be converted to the
312
      /// edge or it should be inherited from the undirected
313
      /// 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.
314 324
      class Arc {
315 325
      public:
316 326
        /// Default constructor
317 327

	
318
        /// @warning The default constructor sets the iterator
319
        /// to an undefined value.
328
        /// Default constructor.
329
        /// \warning It sets the object to an undefined value.
320 330
        Arc() { }
321 331
        /// Copy constructor.
322 332

	
323 333
        /// Copy constructor.
324 334
        ///
325 335
        Arc(const Arc&) { }
326
        /// Initialize the iterator to be invalid.
336
        /// %Invalid constructor \& conversion.
327 337

	
328
        /// Initialize the iterator to be invalid.
329
        ///
338
        /// Initializes the object to be invalid.
339
        /// \sa Invalid for more details.
330 340
        Arc(Invalid) { }
331 341
        /// Equality operator
332 342

	
343
        /// Equality operator.
344
        ///
333 345
        /// Two iterators are equal if and only if they point to the
334
        /// same object or both are invalid.
346
        /// same object or both are \c INVALID.
335 347
        bool operator==(Arc) const { return true; }
336 348
        /// Inequality operator
337 349

	
338
        /// \sa operator==(Arc n)
339
        ///
350
        /// Inequality operator.
340 351
        bool operator!=(Arc) const { return true; }
341 352

	
342 353
        /// Artificial ordering operator.
343 354

	
344
        /// To allow the use of graph descriptors as key type in std::map or
345
        /// similar associative container we require this.
355
        /// Artificial ordering operator.
346 356
        ///
347
        /// \note This operator only have to define some strict ordering of
348
        /// the items; this order has nothing to do with the iteration
349
        /// 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.
350 360
        bool operator<(Arc) const { return false; }
351 361

	
352
        /// Converison to Edge
362
        /// Converison to \c Edge
363

	
364
        /// Converison to \c Edge.
365
        ///
353 366
        operator Edge() const { return Edge(); }
354 367
      };
355
      /// This iterator goes through each directed arc.
356 368

	
357
      /// This iterator goes through each arc of a graph.
358
      /// Its usage is quite simple, for example you can count the number
359
      /// of arcs in a graph \c g of type \c Graph as follows:
369
      /// Iterator class for the arcs.
370

	
371
      /// This iterator goes through each directed arc of the graph.
372
      /// Its usage is quite simple, for example, you can count the number
373
      /// of arcs in a graph \c g of type \c %Graph as follows:
360 374
      ///\code
361 375
      /// int count=0;
362
      /// for(Graph::ArcIt e(g); e!=INVALID; ++e) ++count;
376
      /// for(Graph::ArcIt a(g); a!=INVALID; ++a) ++count;
363 377
      ///\endcode
364 378
      class ArcIt : public Arc {
365 379
      public:
366 380
        /// Default constructor
367 381

	
368
        /// @warning The default constructor sets the iterator
369
        /// to an undefined value.
382
        /// Default constructor.
383
        /// \warning It sets the iterator to an undefined value.
370 384
        ArcIt() { }
371 385
        /// Copy constructor.
372 386

	
373 387
        /// Copy constructor.
374 388
        ///
375 389
        ArcIt(const ArcIt& e) : Arc(e) { }
376
        /// Initialize the iterator to be invalid.
390
        /// %Invalid constructor \& conversion.
377 391

	
378
        /// 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.
379 398
        ///
380
        ArcIt(Invalid) { }
381
        /// 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.
382 401

	
383
        /// This constructor sets the iterator to the first arc of \c g.
384
        ///@param g the graph
385
        ArcIt(const Graph &g) { ignore_unused_variable_warning(g); }
386
        /// Arc -> ArcIt conversion
387

	
388
        /// Sets the iterator to the value of the trivial iterator \c e.
389
        /// This feature necessitates that each time we
390
        /// iterate the arc-set, the iteration order is the same.
402
        /// Sets the iterator to the given arc of the given graph.
403
        ///
391 404
        ArcIt(const Graph&, const Arc&) { }
392
        ///Next arc
405
        /// Next arc
393 406

	
394 407
        /// Assign the iterator to the next arc.
408
        ///
395 409
        ArcIt& operator++() { return *this; }
396 410
      };
397 411

	
398
      /// This iterator goes trough the outgoing directed arcs of a node.
412
      /// Iterator class for the outgoing arcs of a node.
399 413

	
400
      /// This iterator goes trough the \e outgoing arcs of a certain node
401
      /// of a graph.
402
      /// Its usage is quite simple, for example you can count the number
414
      /// This iterator goes trough the \e outgoing directed arcs of a
415
      /// certain node of a graph.
416
      /// Its usage is quite simple, for example, you can count the number
403 417
      /// of outgoing arcs of a node \c n
404
      /// in graph \c g of type \c Graph as follows.
418
      /// in a graph \c g of type \c %Graph as follows.
405 419
      ///\code
406 420
      /// int count=0;
407
      /// for (Graph::OutArcIt e(g, n); e!=INVALID; ++e) ++count;
421
      /// for (Digraph::OutArcIt a(g, n); a!=INVALID; ++a) ++count;
408 422
      ///\endcode
409

	
410 423
      class OutArcIt : public Arc {
411 424
      public:
412 425
        /// Default constructor
413 426

	
414
        /// @warning The default constructor sets the iterator
415
        /// to an undefined value.
427
        /// Default constructor.
428
        /// \warning It sets the iterator to an undefined value.
416 429
        OutArcIt() { }
417 430
        /// Copy constructor.
418 431

	
419 432
        /// Copy constructor.
420 433
        ///
421 434
        OutArcIt(const OutArcIt& e) : Arc(e) { }
422
        /// Initialize the iterator to be invalid.
435
        /// %Invalid constructor \& conversion.
423 436

	
424
        /// 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.
425 443
        ///
426
        OutArcIt(Invalid) { }
427
        /// This constructor sets the iterator to the first outgoing arc.
428

	
429
        /// This constructor sets the iterator to the first outgoing arc of
430
        /// the node.
431
        ///@param n the node
432
        ///@param g the graph
433 444
        OutArcIt(const Graph& n, const Node& g) {
434 445
          ignore_unused_variable_warning(n);
435 446
          ignore_unused_variable_warning(g);
436 447
        }
437
        /// Arc -> OutArcIt conversion
448
        /// Sets the iterator to the given arc.
438 449

	
439
        /// Sets the iterator to the value of the trivial iterator.
440
        /// This feature necessitates that each time we
441
        /// iterate the arc-set, the iteration order is the same.
450
        /// Sets the iterator to the given arc of the given graph.
451
        ///
442 452
        OutArcIt(const Graph&, const Arc&) { }
443
        ///Next outgoing arc
453
        /// Next outgoing arc
444 454

	
445 455
        /// Assign the iterator to the next
446 456
        /// outgoing arc of the corresponding node.
447 457
        OutArcIt& operator++() { return *this; }
448 458
      };
449 459

	
450
      /// This iterator goes trough the incoming directed arcs of a node.
460
      /// Iterator class for the incoming arcs of a node.
451 461

	
452
      /// This iterator goes trough the \e incoming arcs of a certain node
453
      /// of a graph.
454
      /// Its usage is quite simple, for example you can count the number
455
      /// of outgoing arcs of a node \c n
456
      /// in graph \c g of type \c Graph as follows.
462
      /// This iterator goes trough the \e incoming directed arcs of a
463
      /// certain node of a graph.
464
      /// Its usage is quite simple, for example, you can count the number
465
      /// of incoming arcs of a node \c n
466
      /// in a graph \c g of type \c %Graph as follows.
457 467
      ///\code
458 468
      /// int count=0;
459
      /// for(Graph::InArcIt e(g, n); e!=INVALID; ++e) ++count;
469
      /// for (Digraph::InArcIt a(g, n); a!=INVALID; ++a) ++count;
460 470
      ///\endcode
461

	
462 471
      class InArcIt : public Arc {
463 472
      public:
464 473
        /// Default constructor
465 474

	
466
        /// @warning The default constructor sets the iterator
467
        /// to an undefined value.
475
        /// Default constructor.
476
        /// \warning It sets the iterator to an undefined value.
468 477
        InArcIt() { }
469 478
        /// Copy constructor.
470 479

	
471 480
        /// Copy constructor.
472 481
        ///
473 482
        InArcIt(const InArcIt& e) : Arc(e) { }
474
        /// Initialize the iterator to be invalid.
483
        /// %Invalid constructor \& conversion.
475 484

	
476
        /// 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.
477 491
        ///
478
        InArcIt(Invalid) { }
479
        /// This constructor sets the iterator to first incoming arc.
480

	
481
        /// This constructor set the iterator to the first incoming arc of
482
        /// the node.
483
        ///@param n the node
484
        ///@param g the graph
485 492
        InArcIt(const Graph& g, const Node& n) {
486 493
          ignore_unused_variable_warning(n);
487 494
          ignore_unused_variable_warning(g);
488 495
        }
489
        /// Arc -> InArcIt conversion
496
        /// Sets the iterator to the given arc.
490 497

	
491
        /// Sets the iterator to the value of the trivial iterator \c e.
492
        /// This feature necessitates that each time we
493
        /// iterate the arc-set, the iteration order is the same.
498
        /// Sets the iterator to the given arc of the given graph.
499
        ///
494 500
        InArcIt(const Graph&, const Arc&) { }
495 501
        /// Next incoming arc
496 502

	
497
        /// Assign the iterator to the next inarc of the corresponding node.
498
        ///
503
        /// Assign the iterator to the next
504
        /// incoming arc of the corresponding node.
499 505
        InArcIt& operator++() { return *this; }
500 506
      };
501 507

	
502
      /// \brief Reference map of the nodes to type \c T.
508
      /// \brief Standard graph map type for the nodes.
503 509
      ///
504
      /// Reference map of the nodes to type \c T.
510
      /// Standard graph map type for the nodes.
511
      /// It conforms to the ReferenceMap concept.
505 512
      template<class T>
506 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 524
        NodeMap(const NodeMap& nm) :
518 525
          ReferenceMap<Node, T, T&, const T&>(nm) { }
519 526
        ///Assignment operator
520 527
        template <typename CMap>
521 528
        NodeMap& operator=(const CMap&) {
522 529
          checkConcept<ReadMap<Node, T>, CMap>();
523 530
          return *this;
524 531
        }
525 532
      };
526 533

	
527
      /// \brief Reference map of the arcs to type \c T.
534
      /// \brief Standard graph map type for the arcs.
528 535
      ///
529
      /// Reference map of the arcs to type \c T.
536
      /// Standard graph map type for the arcs.
537
      /// It conforms to the ReferenceMap concept.
530 538
      template<class T>
531 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 550
        ArcMap(const ArcMap& em) :
542 551
          ReferenceMap<Arc, T, T&, const T&>(em) { }
543 552
        ///Assignment operator
544 553
        template <typename CMap>
545 554
        ArcMap& operator=(const CMap&) {
546 555
          checkConcept<ReadMap<Arc, T>, CMap>();
547 556
          return *this;
548 557
        }
549 558
      };
550 559

	
551
      /// Reference map of the edges to type \c T.
552

	
553
      /// Reference map of the edges to type \c T.
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 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 576
        EdgeMap(const EdgeMap& em) :
566 577
          ReferenceMap<Edge, T, T&, const T&>(em) {}
567 578
        ///Assignment operator
568 579
        template <typename CMap>
569 580
        EdgeMap& operator=(const CMap&) {
570 581
          checkConcept<ReadMap<Edge, T>, CMap>();
571 582
          return *this;
572 583
        }
573 584
      };
574 585

	
575
      /// \brief Direct the given edge.
586
      /// \brief The first node of the edge.
576 587
      ///
577
      /// Direct the given edge. The returned arc source
578
      /// will be the given node.
579
      Arc direct(const Edge&, const Node&) const {
580
        return INVALID;
581
      }
582

	
583
      /// \brief Direct the given edge.
588
      /// Returns the first node of the given edge.
584 589
      ///
585
      /// Direct the given edge. The returned arc
586
      /// represents the given edge and the direction comes
587
      /// from the bool parameter. The source of the edge and
588
      /// the directed arc is the same when the given bool is true.
589
      Arc direct(const Edge&, bool) const {
590
        return INVALID;
591
      }
592

	
593
      /// \brief Returns true if the arc has default orientation.
594
      ///
595
      /// Returns whether the given directed arc is same orientation as
596
      /// the corresponding edge's default orientation.
597
      bool direction(Arc) const { return true; }
598

	
599
      /// \brief Returns the opposite directed arc.
600
      ///
601
      /// Returns the opposite directed arc.
602
      Arc oppositeArc(Arc) const { return INVALID; }
603

	
604
      /// \brief Opposite node on an arc
605
      ///
606
      /// \return The opposite of the given node on the given edge.
607
      Node oppositeNode(Node, Edge) const { return INVALID; }
608

	
609
      /// \brief First node of the edge.
610
      ///
611
      /// \return The first node of the given edge.
612
      ///
613
      /// Naturally edges don't have direction and thus
614
      /// don't have source and target node. However we use \c u() and \c v()
615
      /// methods to query the two nodes of the arc. The direction of the
616
      /// arc which arises this way is called the inherent direction of the
617
      /// edge, and is used to define the "default" direction
618
      /// of the directed versions of the arcs.
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.
619 595
      /// \sa v()
620 596
      /// \sa direction()
621 597
      Node u(Edge) const { return INVALID; }
622 598

	
623
      /// \brief Second node of the edge.
599
      /// \brief The second node of the edge.
624 600
      ///
625
      /// \return The second node of the given edge.
601
      /// Returns the second node of the given edge.
626 602
      ///
627
      /// Naturally edges don't have direction and thus
628
      /// don't have source and target node. However we use \c u() and \c v()
629
      /// methods to query the two nodes of the arc. The direction of the
630
      /// arc which arises this way is called the inherent direction of the
631
      /// edge, and is used to define the "default" direction
632
      /// of the directed versions of the arcs.
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.
633 608
      /// \sa u()
634 609
      /// \sa direction()
635 610
      Node v(Edge) const { return INVALID; }
636 611

	
637
      /// \brief Source node of the directed arc.
612
      /// \brief The source node of the arc.
613
      ///
614
      /// Returns the source node of the given arc.
638 615
      Node source(Arc) const { return INVALID; }
639 616

	
640
      /// \brief Target node of the directed arc.
617
      /// \brief The target node of the arc.
618
      ///
619
      /// Returns the target node of the given arc.
641 620
      Node target(Arc) const { return INVALID; }
642 621

	
643
      /// \brief Returns the id of the node.
622
      /// \brief The ID of the node.
623
      ///
624
      /// Returns the ID of the given node.
644 625
      int id(Node) const { return -1; }
645 626

	
646
      /// \brief Returns the id of the edge.
627
      /// \brief The ID of the edge.
628
      ///
629
      /// Returns the ID of the given edge.
647 630
      int id(Edge) const { return -1; }
648 631

	
649
      /// \brief Returns the id of the arc.
632
      /// \brief The ID of the arc.
633
      ///
634
      /// Returns the ID of the given arc.
650 635
      int id(Arc) const { return -1; }
651 636

	
652
      /// \brief Returns the node with the given id.
637
      /// \brief The node with the given ID.
653 638
      ///
654
      /// \pre The argument should be a valid node id in the graph.
639
      /// Returns the node with the given ID.
640
      /// \pre The argument should be a valid node ID in the graph.
655 641
      Node nodeFromId(int) const { return INVALID; }
656 642

	
657
      /// \brief Returns the edge with the given id.
643
      /// \brief The edge with the given ID.
658 644
      ///
659
      /// \pre The argument should be a valid edge id in the graph.
645
      /// Returns the edge with the given ID.
646
      /// \pre The argument should be a valid edge ID in the graph.
660 647
      Edge edgeFromId(int) const { return INVALID; }
661 648

	
662
      /// \brief Returns the arc with the given id.
649
      /// \brief The arc with the given ID.
663 650
      ///
664
      /// \pre The argument should be a valid arc id in the graph.
651
      /// Returns the arc with the given ID.
652
      /// \pre The argument should be a valid arc ID in the graph.
665 653
      Arc arcFromId(int) const { return INVALID; }
666 654

	
667
      /// \brief Returns an upper bound on the node IDs.
655
      /// \brief An upper bound on the node IDs.
656
      ///
657
      /// Returns an upper bound on the node IDs.
668 658
      int maxNodeId() const { return -1; }
669 659

	
670
      /// \brief Returns an upper bound on the edge IDs.
660
      /// \brief An upper bound on the edge IDs.
661
      ///
662
      /// Returns an upper bound on the edge IDs.
671 663
      int maxEdgeId() const { return -1; }
672 664

	
673
      /// \brief Returns an upper bound on the arc IDs.
665
      /// \brief An upper bound on the arc IDs.
666
      ///
667
      /// Returns an upper bound on the arc IDs.
674 668
      int maxArcId() const { return -1; }
675 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 {
683
        return INVALID;
684
      }
685

	
686
      /// \brief Direct the edge.
687
      ///
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 {
691
        return INVALID;
692
      }
693

	
694
      /// \brief The oppositely directed arc.
695
      ///
696
      /// Returns the oppositely directed arc representing the same edge.
697
      Arc oppositeArc(Arc) const { return INVALID; }
698

	
699
      /// \brief The opposite node on the edge.
700
      ///
701
      /// Returns the opposite node on the given edge.
702
      Node oppositeNode(Node, Edge) const { return INVALID; }
703

	
676 704
      void first(Node&) const {}
677 705
      void next(Node&) const {}
678 706

	
679 707
      void first(Edge&) const {}
680 708
      void next(Edge&) const {}
681 709

	
682 710
      void first(Arc&) const {}
683 711
      void next(Arc&) const {}
684 712

	
685 713
      void firstOut(Arc&, Node) const {}
686 714
      void nextOut(Arc&) const {}
687 715

	
688 716
      void firstIn(Arc&, Node) const {}
689 717
      void nextIn(Arc&) const {}
690 718

	
691 719
      void firstInc(Edge &, bool &, const Node &) const {}
692 720
      void nextInc(Edge &, bool &) const {}
693 721

	
694 722
      // The second parameter is dummy.
695 723
      Node fromId(int, Node) const { return INVALID; }
696 724
      // The second parameter is dummy.
697 725
      Edge fromId(int, Edge) const { return INVALID; }
698 726
      // The second parameter is dummy.
699 727
      Arc fromId(int, Arc) const { return INVALID; }
700 728

	
701 729
      // Dummy parameter.
702 730
      int maxId(Node) const { return -1; }
703 731
      // Dummy parameter.
704 732
      int maxId(Edge) const { return -1; }
705 733
      // Dummy parameter.
706 734
      int maxId(Arc) const { return -1; }
707 735

	
708
      /// \brief Base node of the iterator
736
      /// \brief The base node of the iterator.
709 737
      ///
710
      /// Returns the base node (the source in this case) of the iterator
711
      Node baseNode(OutArcIt e) const {
712
        return source(e);
713
      }
714
      /// \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.
715 742
      ///
716
      /// Returns the running node (the target in this case) of the
717
      /// iterator
718
      Node runningNode(OutArcIt e) const {
719
        return target(e);
720
      }
743
      /// Returns the running node of the given incident edge iterator.
744
      Node runningNode(IncEdgeIt) const { return INVALID; }
721 745

	
722
      /// \brief Base node of the iterator
746
      /// \brief The base node of the iterator.
723 747
      ///
724
      /// Returns the base node (the target in this case) of the iterator
725
      Node baseNode(InArcIt e) const {
726
        return target(e);
727
      }
728
      /// \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.
729 753
      ///
730
      /// Returns the running node (the source in this case) of the
731
      /// iterator
732
      Node runningNode(InArcIt e) const {
733
        return source(e);
734
      }
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; }
735 757

	
736
      /// \brief Base node of the iterator
758
      /// \brief The base node of the iterator.
737 759
      ///
738
      /// Returns the base node of the iterator
739
      Node baseNode(IncEdgeIt) const {
740
        return INVALID;
741
      }
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; }
742 763

	
743
      /// \brief Running node of the iterator
764
      /// \brief The running node of the iterator.
744 765
      ///
745
      /// Returns the running node of the iterator
746
      Node runningNode(IncEdgeIt) const {
747
        return INVALID;
748
      }
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; }
749 769

	
750 770
      template <typename _Graph>
751 771
      struct Constraints {
752 772
        void constraints() {
753 773
          checkConcept<BaseGraphComponent, _Graph>();
754 774
          checkConcept<IterableGraphComponent<>, _Graph>();
755 775
          checkConcept<IDableGraphComponent<>, _Graph>();
756 776
          checkConcept<MappableGraphComponent<>, _Graph>();
757 777
        }
758 778
      };
759 779

	
760 780
    };
761 781

	
762 782
  }
763 783

	
764 784
}
765 785

	
766 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-2009
5
 * Copyright (C) 2003-2010
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 graph components.
21
///\brief The concepts of graph components.
22 22

	
23 23
#ifndef LEMON_CONCEPTS_GRAPH_COMPONENTS_H
24 24
#define LEMON_CONCEPTS_GRAPH_COMPONENTS_H
25 25

	
26 26
#include <lemon/core.h>
27 27
#include <lemon/concepts/maps.h>
28 28

	
29 29
#include <lemon/bits/alteration_notifier.h>
30 30

	
31 31
namespace lemon {
32 32
  namespace concepts {
33 33

	
34 34
    /// \brief Concept class for \c Node, \c Arc and \c Edge types.
35 35
    ///
36 36
    /// This class describes the concept of \c Node, \c Arc and \c Edge
37 37
    /// subtypes of digraph and graph types.
38 38
    ///
39 39
    /// \note This class is a template class so that we can use it to
40 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 
41
    /// and \c Arc (or \c Edge) types should \e not derive from the same
42 42
    /// base class. For \c Node you should instantiate it with character
43 43
    /// \c 'n', for \c Arc with \c 'a' and for \c Edge with \c 'e'.
44 44
#ifndef DOXYGEN
45 45
    template <char sel = '0'>
46 46
#endif
47 47
    class GraphItem {
48 48
    public:
49 49
      /// \brief Default constructor.
50 50
      ///
51 51
      /// Default constructor.
52 52
      /// \warning The default constructor is not required to set
53 53
      /// the item to some well-defined value. So you should consider it
54 54
      /// as uninitialized.
55 55
      GraphItem() {}
56 56

	
57 57
      /// \brief Copy constructor.
58 58
      ///
59 59
      /// Copy constructor.
60 60
      GraphItem(const GraphItem &) {}
61 61

	
62 62
      /// \brief Constructor for conversion from \c INVALID.
63 63
      ///
64 64
      /// Constructor for conversion from \c INVALID.
65 65
      /// It initializes the item to be invalid.
66 66
      /// \sa Invalid for more details.
67 67
      GraphItem(Invalid) {}
68 68

	
69 69
      /// \brief Assignment operator.
70 70
      ///
71 71
      /// Assignment operator for the item.
72 72
      GraphItem& operator=(const GraphItem&) { return *this; }
73 73

	
74 74
      /// \brief Assignment operator for INVALID.
75 75
      ///
76 76
      /// This operator makes the item invalid.
77 77
      GraphItem& operator=(Invalid) { return *this; }
78 78

	
79 79
      /// \brief Equality operator.
80 80
      ///
81 81
      /// Equality operator.
82 82
      bool operator==(const GraphItem&) const { return false; }
83 83

	
84 84
      /// \brief Inequality operator.
85 85
      ///
86 86
      /// Inequality operator.
87 87
      bool operator!=(const GraphItem&) const { return false; }
88 88

	
89 89
      /// \brief Ordering operator.
90 90
      ///
91 91
      /// This operator defines an ordering of the items.
92
      /// It makes possible to use graph item types as key types in 
92
      /// It makes possible to use graph item types as key types in
93 93
      /// associative containers (e.g. \c std::map).
94 94
      ///
95
      /// \note This operator only have to define some strict ordering of
95
      /// \note This operator only has to define some strict ordering of
96 96
      /// the items; this order has nothing to do with the iteration
97 97
      /// ordering of the items.
98 98
      bool operator<(const GraphItem&) const { return false; }
99 99

	
100 100
      template<typename _GraphItem>
101 101
      struct Constraints {
102 102
        void constraints() {
103 103
          _GraphItem i1;
104 104
          i1=INVALID;
105 105
          _GraphItem i2 = i1;
106 106
          _GraphItem i3 = INVALID;
107 107

	
108 108
          i1 = i2 = i3;
109 109

	
110 110
          bool b;
111 111
          b = (ia == ib) && (ia != ib);
112 112
          b = (ia == INVALID) && (ib != INVALID);
113 113
          b = (ia < ib);
114 114
        }
115 115

	
116 116
        const _GraphItem &ia;
117 117
        const _GraphItem &ib;
118 118
      };
119 119
    };
120 120

	
121 121
    /// \brief Base skeleton class for directed graphs.
122 122
    ///
123 123
    /// This class describes the base interface of directed graph types.
124 124
    /// All digraph %concepts have to conform to this class.
125
    /// It just provides types for nodes and arcs and functions 
125
    /// It just provides types for nodes and arcs and functions
126 126
    /// to get the source and the target nodes of arcs.
127 127
    class BaseDigraphComponent {
128 128
    public:
129 129

	
130 130
      typedef BaseDigraphComponent Digraph;
131 131

	
132 132
      /// \brief Node class of the digraph.
133 133
      ///
134 134
      /// This class represents the nodes of the digraph.
135 135
      typedef GraphItem<'n'> Node;
136 136

	
137 137
      /// \brief Arc class of the digraph.
138 138
      ///
139 139
      /// This class represents the arcs of the digraph.
140 140
      typedef GraphItem<'a'> Arc;
141 141

	
142 142
      /// \brief Return the source node of an arc.
143 143
      ///
144 144
      /// This function returns the source node of an arc.
145 145
      Node source(const Arc&) const { return INVALID; }
146 146

	
147 147
      /// \brief Return the target node of an arc.
148 148
      ///
149 149
      /// This function returns the target node of an arc.
150 150
      Node target(const Arc&) const { return INVALID; }
151 151

	
152 152
      /// \brief Return the opposite node on the given arc.
153 153
      ///
154 154
      /// This function returns the opposite node on the given arc.
155 155
      Node oppositeNode(const Node&, const Arc&) const {
156 156
        return INVALID;
157 157
      }
158 158

	
159 159
      template <typename _Digraph>
160 160
      struct Constraints {
161 161
        typedef typename _Digraph::Node Node;
162 162
        typedef typename _Digraph::Arc Arc;
163 163

	
164 164
        void constraints() {
165 165
          checkConcept<GraphItem<'n'>, Node>();
166 166
          checkConcept<GraphItem<'a'>, Arc>();
167 167
          {
168 168
            Node n;
169 169
            Arc e(INVALID);
170 170
            n = digraph.source(e);
171 171
            n = digraph.target(e);
172 172
            n = digraph.oppositeNode(n, e);
173 173
          }
174 174
        }
175 175

	
176 176
        const _Digraph& digraph;
177 177
      };
178 178
    };
179 179

	
180 180
    /// \brief Base skeleton class for undirected graphs.
181 181
    ///
182 182
    /// This class describes the base interface of undirected graph types.
183 183
    /// All graph %concepts have to conform to this class.
184 184
    /// It extends the interface of \ref BaseDigraphComponent with an
185 185
    /// \c Edge type and functions to get the end nodes of edges,
186 186
    /// to convert from arcs to edges and to get both direction of edges.
187 187
    class BaseGraphComponent : public BaseDigraphComponent {
188 188
    public:
189 189

	
190 190
      typedef BaseGraphComponent Graph;
191 191

	
192 192
      typedef BaseDigraphComponent::Node Node;
193 193
      typedef BaseDigraphComponent::Arc Arc;
194 194

	
195 195
      /// \brief Undirected edge class of the graph.
196 196
      ///
197 197
      /// This class represents the undirected edges of the graph.
198 198
      /// Undirected graphs can be used as directed graphs, each edge is
199 199
      /// represented by two opposite directed arcs.
200 200
      class Edge : public GraphItem<'e'> {
201 201
        typedef GraphItem<'e'> Parent;
202 202

	
203 203
      public:
204 204
        /// \brief Default constructor.
205 205
        ///
206 206
        /// Default constructor.
207 207
        /// \warning The default constructor is not required to set
208 208
        /// the item to some well-defined value. So you should consider it
209 209
        /// as uninitialized.
210 210
        Edge() {}
211 211

	
212 212
        /// \brief Copy constructor.
213 213
        ///
214 214
        /// Copy constructor.
215 215
        Edge(const Edge &) : Parent() {}
216 216

	
217 217
        /// \brief Constructor for conversion from \c INVALID.
218 218
        ///
219 219
        /// Constructor for conversion from \c INVALID.
220 220
        /// It initializes the item to be invalid.
221 221
        /// \sa Invalid for more details.
222 222
        Edge(Invalid) {}
223 223

	
224 224
        /// \brief Constructor for conversion from an arc.
225 225
        ///
226 226
        /// Constructor for conversion from an arc.
227 227
        /// Besides the core graph item functionality each arc should
228 228
        /// be convertible to the represented edge.
229 229
        Edge(const Arc&) {}
230 230
     };
231 231

	
232 232
      /// \brief Return one end node of an edge.
233 233
      ///
234 234
      /// This function returns one end node of an edge.
235 235
      Node u(const Edge&) const { return INVALID; }
236 236

	
237 237
      /// \brief Return the other end node of an edge.
238 238
      ///
239 239
      /// This function returns the other end node of an edge.
240 240
      Node v(const Edge&) const { return INVALID; }
241 241

	
242 242
      /// \brief Return a directed arc related to an edge.
243 243
      ///
244 244
      /// This function returns a directed arc from its direction and the
245 245
      /// represented edge.
246 246
      Arc direct(const Edge&, bool) const { return INVALID; }
247 247

	
248 248
      /// \brief Return a directed arc related to an edge.
249 249
      ///
250 250
      /// This function returns a directed arc from its source node and the
251 251
      /// represented edge.
252 252
      Arc direct(const Edge&, const Node&) const { return INVALID; }
253 253

	
254 254
      /// \brief Return the direction of the arc.
255 255
      ///
256 256
      /// Returns the direction of the arc. Each arc represents an
257 257
      /// edge with a direction. It gives back the
258 258
      /// direction.
259 259
      bool direction(const Arc&) const { return true; }
260 260

	
261 261
      /// \brief Return the opposite arc.
262 262
      ///
263 263
      /// This function returns the opposite arc, i.e. the arc representing
264 264
      /// the same edge and has opposite direction.
265 265
      Arc oppositeArc(const Arc&) const { return INVALID; }
266 266

	
267 267
      template <typename _Graph>
268 268
      struct Constraints {
269 269
        typedef typename _Graph::Node Node;
270 270
        typedef typename _Graph::Arc Arc;
271 271
        typedef typename _Graph::Edge Edge;
272 272

	
273 273
        void constraints() {
274 274
          checkConcept<BaseDigraphComponent, _Graph>();
275 275
          checkConcept<GraphItem<'e'>, Edge>();
276 276
          {
277 277
            Node n;
278 278
            Edge ue(INVALID);
279 279
            Arc e;
280 280
            n = graph.u(ue);
281 281
            n = graph.v(ue);
282 282
            e = graph.direct(ue, true);
283 283
            e = graph.direct(ue, false);
284 284
            e = graph.direct(ue, n);
285 285
            e = graph.oppositeArc(e);
286 286
            ue = e;
287 287
            bool d = graph.direction(e);
288 288
            ignore_unused_variable_warning(d);
289 289
          }
290 290
        }
291 291

	
292 292
        const _Graph& graph;
293 293
      };
294 294

	
295 295
    };
296 296

	
297 297
    /// \brief Skeleton class for \e idable directed graphs.
298 298
    ///
299 299
    /// This class describes the interface of \e idable directed graphs.
300 300
    /// It extends \ref BaseDigraphComponent with the core ID functions.
301 301
    /// The ids of the items must be unique and immutable.
302 302
    /// This concept is part of the Digraph concept.
303 303
    template <typename BAS = BaseDigraphComponent>
304 304
    class IDableDigraphComponent : public BAS {
305 305
    public:
306 306

	
307 307
      typedef BAS Base;
308 308
      typedef typename Base::Node Node;
309 309
      typedef typename Base::Arc Arc;
310 310

	
311 311
      /// \brief Return a unique integer id for the given node.
312 312
      ///
313 313
      /// This function returns a unique integer id for the given node.
314 314
      int id(const Node&) const { return -1; }
315 315

	
316 316
      /// \brief Return the node by its unique id.
317 317
      ///
318 318
      /// This function returns the node by its unique id.
319 319
      /// If the digraph does not contain a node with the given id,
320 320
      /// then the result of the function is undefined.
321 321
      Node nodeFromId(int) const { return INVALID; }
322 322

	
323 323
      /// \brief Return a unique integer id for the given arc.
324 324
      ///
325 325
      /// This function returns a unique integer id for the given arc.
326 326
      int id(const Arc&) const { return -1; }
327 327

	
328 328
      /// \brief Return the arc by its unique id.
329 329
      ///
330 330
      /// This function returns the arc by its unique id.
331 331
      /// If the digraph does not contain an arc with the given id,
332 332
      /// then the result of the function is undefined.
333 333
      Arc arcFromId(int) const { return INVALID; }
334 334

	
335 335
      /// \brief Return an integer greater or equal to the maximum
336 336
      /// node id.
337 337
      ///
338 338
      /// This function returns an integer greater or equal to the
339 339
      /// maximum node id.
340 340
      int maxNodeId() const { return -1; }
341 341

	
342 342
      /// \brief Return an integer greater or equal to the maximum
343 343
      /// arc id.
344 344
      ///
345 345
      /// This function returns an integer greater or equal to the
346 346
      /// maximum arc id.
347 347
      int maxArcId() const { return -1; }
348 348

	
349 349
      template <typename _Digraph>
350 350
      struct Constraints {
351 351

	
352 352
        void constraints() {
353 353
          checkConcept<Base, _Digraph >();
354 354
          typename _Digraph::Node node;
355 355
          node=INVALID;
356 356
          int nid = digraph.id(node);
357 357
          nid = digraph.id(node);
358 358
          node = digraph.nodeFromId(nid);
359 359
          typename _Digraph::Arc arc;
360 360
          arc=INVALID;
361 361
          int eid = digraph.id(arc);
362 362
          eid = digraph.id(arc);
363 363
          arc = digraph.arcFromId(eid);
364 364

	
365 365
          nid = digraph.maxNodeId();
366 366
          ignore_unused_variable_warning(nid);
367 367
          eid = digraph.maxArcId();
368 368
          ignore_unused_variable_warning(eid);
369 369
        }
370 370

	
371 371
        const _Digraph& digraph;
372 372
      };
373 373
    };
374 374

	
375 375
    /// \brief Skeleton class for \e idable undirected graphs.
376 376
    ///
377 377
    /// This class describes the interface of \e idable undirected
378 378
    /// graphs. It extends \ref IDableDigraphComponent with the core ID
379 379
    /// functions of undirected graphs.
380 380
    /// The ids of the items must be unique and immutable.
381 381
    /// This concept is part of the Graph concept.
382 382
    template <typename BAS = BaseGraphComponent>
383 383
    class IDableGraphComponent : public IDableDigraphComponent<BAS> {
384 384
    public:
385 385

	
386 386
      typedef BAS Base;
387 387
      typedef typename Base::Edge Edge;
388 388

	
389 389
      using IDableDigraphComponent<Base>::id;
390 390

	
391 391
      /// \brief Return a unique integer id for the given edge.
392 392
      ///
393 393
      /// This function returns a unique integer id for the given edge.
394 394
      int id(const Edge&) const { return -1; }
395 395

	
396 396
      /// \brief Return the edge by its unique id.
397 397
      ///
398 398
      /// This function returns the edge by its unique id.
399 399
      /// If the graph does not contain an edge with the given id,
400 400
      /// then the result of the function is undefined.
401 401
      Edge edgeFromId(int) const { return INVALID; }
402 402

	
403 403
      /// \brief Return an integer greater or equal to the maximum
404 404
      /// edge id.
405 405
      ///
406 406
      /// This function returns an integer greater or equal to the
407 407
      /// maximum edge id.
408 408
      int maxEdgeId() const { return -1; }
409 409

	
410 410
      template <typename _Graph>
411 411
      struct Constraints {
412 412

	
413 413
        void constraints() {
414 414
          checkConcept<IDableDigraphComponent<Base>, _Graph >();
415 415
          typename _Graph::Edge edge;
416 416
          int ueid = graph.id(edge);
417 417
          ueid = graph.id(edge);
418 418
          edge = graph.edgeFromId(ueid);
419 419
          ueid = graph.maxEdgeId();
420 420
          ignore_unused_variable_warning(ueid);
421 421
        }
422 422

	
423 423
        const _Graph& graph;
424 424
      };
425 425
    };
426 426

	
427 427
    /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
428 428
    ///
429
    /// This class describes the concept of \c NodeIt, \c ArcIt and 
429
    /// This class describes the concept of \c NodeIt, \c ArcIt and
430 430
    /// \c EdgeIt subtypes of digraph and graph types.
431 431
    template <typename GR, typename Item>
432 432
    class GraphItemIt : public Item {
433 433
    public:
434 434
      /// \brief Default constructor.
435 435
      ///
436 436
      /// Default constructor.
437 437
      /// \warning The default constructor is not required to set
438 438
      /// the iterator to some well-defined value. So you should consider it
439 439
      /// as uninitialized.
440 440
      GraphItemIt() {}
441 441

	
442 442
      /// \brief Copy constructor.
443 443
      ///
444 444
      /// Copy constructor.
445 445
      GraphItemIt(const GraphItemIt& it) : Item(it) {}
446 446

	
447 447
      /// \brief Constructor that sets the iterator to the first item.
448 448
      ///
449 449
      /// Constructor that sets the iterator to the first item.
450 450
      explicit GraphItemIt(const GR&) {}
451 451

	
452 452
      /// \brief Constructor for conversion from \c INVALID.
453 453
      ///
454 454
      /// Constructor for conversion from \c INVALID.
455 455
      /// It initializes the iterator to be invalid.
456 456
      /// \sa Invalid for more details.
457 457
      GraphItemIt(Invalid) {}
458 458

	
459 459
      /// \brief Assignment operator.
460 460
      ///
461 461
      /// Assignment operator for the iterator.
462 462
      GraphItemIt& operator=(const GraphItemIt&) { return *this; }
463 463

	
464 464
      /// \brief Increment the iterator.
465 465
      ///
466 466
      /// This operator increments the iterator, i.e. assigns it to the
467 467
      /// next item.
468 468
      GraphItemIt& operator++() { return *this; }
469
 
469

	
470 470
      /// \brief Equality operator
471 471
      ///
472 472
      /// Equality operator.
473 473
      /// Two iterators are equal if and only if they point to the
474 474
      /// same object or both are invalid.
475 475
      bool operator==(const GraphItemIt&) const { return true;}
476 476

	
477 477
      /// \brief Inequality operator
478 478
      ///
479 479
      /// Inequality operator.
480 480
      /// Two iterators are equal if and only if they point to the
481 481
      /// same object or both are invalid.
482 482
      bool operator!=(const GraphItemIt&) const { return true;}
483 483

	
484 484
      template<typename _GraphItemIt>
485 485
      struct Constraints {
486 486
        void constraints() {
487 487
          checkConcept<GraphItem<>, _GraphItemIt>();
488 488
          _GraphItemIt it1(g);
489 489
          _GraphItemIt it2;
490 490
          _GraphItemIt it3 = it1;
491 491
          _GraphItemIt it4 = INVALID;
492 492

	
493 493
          it2 = ++it1;
494 494
          ++it2 = it1;
495 495
          ++(++it1);
496 496

	
497 497
          Item bi = it1;
498 498
          bi = it2;
499 499
        }
500 500
        const GR& g;
501 501
      };
502 502
    };
503 503

	
504
    /// \brief Concept class for \c InArcIt, \c OutArcIt and 
504
    /// \brief Concept class for \c InArcIt, \c OutArcIt and
505 505
    /// \c IncEdgeIt types.
506 506
    ///
507
    /// This class describes the concept of \c InArcIt, \c OutArcIt 
507
    /// This class describes the concept of \c InArcIt, \c OutArcIt
508 508
    /// and \c IncEdgeIt subtypes of digraph and graph types.
509 509
    ///
510 510
    /// \note Since these iterator classes do not inherit from the same
511 511
    /// base class, there is an additional template parameter (selector)
512
    /// \c sel. For \c InArcIt you should instantiate it with character 
512
    /// \c sel. For \c InArcIt you should instantiate it with character
513 513
    /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'.
514 514
    template <typename GR,
515 515
              typename Item = typename GR::Arc,
516 516
              typename Base = typename GR::Node,
517 517
              char sel = '0'>
518 518
    class GraphIncIt : public Item {
519 519
    public:
520 520
      /// \brief Default constructor.
521 521
      ///
522 522
      /// Default constructor.
523 523
      /// \warning The default constructor is not required to set
524 524
      /// the iterator to some well-defined value. So you should consider it
525 525
      /// as uninitialized.
526 526
      GraphIncIt() {}
527 527

	
528 528
      /// \brief Copy constructor.
529 529
      ///
530 530
      /// Copy constructor.
531 531
      GraphIncIt(const GraphIncIt& it) : Item(it) {}
532 532

	
533
      /// \brief Constructor that sets the iterator to the first 
533
      /// \brief Constructor that sets the iterator to the first
534 534
      /// incoming or outgoing arc.
535 535
      ///
536
      /// Constructor that sets the iterator to the first arc 
536
      /// Constructor that sets the iterator to the first arc
537 537
      /// incoming to or outgoing from the given node.
538 538
      explicit GraphIncIt(const GR&, const Base&) {}
539 539

	
540 540
      /// \brief Constructor for conversion from \c INVALID.
541 541
      ///
542 542
      /// Constructor for conversion from \c INVALID.
543 543
      /// It initializes the iterator to be invalid.
544 544
      /// \sa Invalid for more details.
545 545
      GraphIncIt(Invalid) {}
546 546

	
547 547
      /// \brief Assignment operator.
548 548
      ///
549 549
      /// Assignment operator for the iterator.
550 550
      GraphIncIt& operator=(const GraphIncIt&) { return *this; }
551 551

	
552 552
      /// \brief Increment the iterator.
553 553
      ///
554 554
      /// This operator increments the iterator, i.e. assigns it to the
555 555
      /// next arc incoming to or outgoing from the given node.
556 556
      GraphIncIt& operator++() { return *this; }
557 557

	
558 558
      /// \brief Equality operator
559 559
      ///
560 560
      /// Equality operator.
561 561
      /// Two iterators are equal if and only if they point to the
562 562
      /// same object or both are invalid.
563 563
      bool operator==(const GraphIncIt&) const { return true;}
564 564

	
565 565
      /// \brief Inequality operator
566 566
      ///
567 567
      /// Inequality operator.
568 568
      /// Two iterators are equal if and only if they point to the
569 569
      /// same object or both are invalid.
570 570
      bool operator!=(const GraphIncIt&) const { return true;}
571 571

	
572 572
      template <typename _GraphIncIt>
573 573
      struct Constraints {
574 574
        void constraints() {
575 575
          checkConcept<GraphItem<sel>, _GraphIncIt>();
576 576
          _GraphIncIt it1(graph, node);
577 577
          _GraphIncIt it2;
578 578
          _GraphIncIt it3 = it1;
579 579
          _GraphIncIt it4 = INVALID;
580 580

	
581 581
          it2 = ++it1;
582 582
          ++it2 = it1;
583 583
          ++(++it1);
584 584
          Item e = it1;
585 585
          e = it2;
586 586
        }
587 587
        const Base& node;
588 588
        const GR& graph;
589 589
      };
590 590
    };
591 591

	
592 592
    /// \brief Skeleton class for iterable directed graphs.
593 593
    ///
594 594
    /// This class describes the interface of iterable directed
595 595
    /// graphs. It extends \ref BaseDigraphComponent with the core
596 596
    /// iterable interface.
597 597
    /// This concept is part of the Digraph concept.
598 598
    template <typename BAS = BaseDigraphComponent>
599 599
    class IterableDigraphComponent : public BAS {
600 600

	
601 601
    public:
602 602

	
603 603
      typedef BAS Base;
604 604
      typedef typename Base::Node Node;
605 605
      typedef typename Base::Arc Arc;
606 606

	
607 607
      typedef IterableDigraphComponent Digraph;
608 608

	
609 609
      /// \name Base Iteration
610 610
      ///
611 611
      /// This interface provides functions for iteration on digraph items.
612 612
      ///
613 613
      /// @{
614 614

	
615 615
      /// \brief Return the first node.
616 616
      ///
617 617
      /// This function gives back the first node in the iteration order.
618 618
      void first(Node&) const {}
619 619

	
620 620
      /// \brief Return the next node.
621 621
      ///
622 622
      /// This function gives back the next node in the iteration order.
623 623
      void next(Node&) const {}
624 624

	
625 625
      /// \brief Return the first arc.
626 626
      ///
627 627
      /// This function gives back the first arc in the iteration order.
628 628
      void first(Arc&) const {}
629 629

	
630 630
      /// \brief Return the next arc.
631 631
      ///
632 632
      /// This function gives back the next arc in the iteration order.
633 633
      void next(Arc&) const {}
634 634

	
635 635
      /// \brief Return the first arc incomming to the given node.
636 636
      ///
637 637
      /// This function gives back the first arc incomming to the
638 638
      /// given node.
639 639
      void firstIn(Arc&, const Node&) const {}
640 640

	
641 641
      /// \brief Return the next arc incomming to the given node.
642 642
      ///
643 643
      /// This function gives back the next arc incomming to the
644 644
      /// given node.
645 645
      void nextIn(Arc&) const {}
646 646

	
647 647
      /// \brief Return the first arc outgoing form the given node.
648 648
      ///
649 649
      /// This function gives back the first arc outgoing form the
650 650
      /// given node.
651 651
      void firstOut(Arc&, const Node&) const {}
652 652

	
653 653
      /// \brief Return the next arc outgoing form the given node.
654 654
      ///
655 655
      /// This function gives back the next arc outgoing form the
656 656
      /// given node.
657 657
      void nextOut(Arc&) const {}
658 658

	
659 659
      /// @}
660 660

	
661 661
      /// \name Class Based Iteration
662 662
      ///
663 663
      /// This interface provides iterator classes for digraph items.
664 664
      ///
665 665
      /// @{
666 666

	
667 667
      /// \brief This iterator goes through each node.
668 668
      ///
669 669
      /// This iterator goes through each node.
670 670
      ///
671 671
      typedef GraphItemIt<Digraph, Node> NodeIt;
672 672

	
673 673
      /// \brief This iterator goes through each arc.
674 674
      ///
675 675
      /// This iterator goes through each arc.
676 676
      ///
677 677
      typedef GraphItemIt<Digraph, Arc> ArcIt;
678 678

	
679 679
      /// \brief This iterator goes trough the incoming arcs of a node.
680 680
      ///
681 681
      /// This iterator goes trough the \e incoming arcs of a certain node
682 682
      /// of a digraph.
683 683
      typedef GraphIncIt<Digraph, Arc, Node, 'i'> InArcIt;
684 684

	
685 685
      /// \brief This iterator goes trough the outgoing arcs of a node.
686 686
      ///
687 687
      /// This iterator goes trough the \e outgoing arcs of a certain node
688 688
      /// of a digraph.
689 689
      typedef GraphIncIt<Digraph, Arc, Node, 'o'> OutArcIt;
690 690

	
691 691
      /// \brief The base node of the iterator.
692 692
      ///
693 693
      /// This function gives back the base node of the iterator.
694 694
      /// It is always the target node of the pointed arc.
695 695
      Node baseNode(const InArcIt&) const { return INVALID; }
696 696

	
697 697
      /// \brief The running node of the iterator.
698 698
      ///
699 699
      /// This function gives back the running node of the iterator.
700 700
      /// It is always the source node of the pointed arc.
701 701
      Node runningNode(const InArcIt&) const { return INVALID; }
702 702

	
703 703
      /// \brief The base node of the iterator.
704 704
      ///
705 705
      /// This function gives back the base node of the iterator.
706 706
      /// It is always the source node of the pointed arc.
707 707
      Node baseNode(const OutArcIt&) const { return INVALID; }
708 708

	
709 709
      /// \brief The running node of the iterator.
710 710
      ///
711 711
      /// This function gives back the running node of the iterator.
712 712
      /// It is always the target node of the pointed arc.
713 713
      Node runningNode(const OutArcIt&) const { return INVALID; }
714 714

	
715 715
      /// @}
716 716

	
717 717
      template <typename _Digraph>
718 718
      struct Constraints {
719 719
        void constraints() {
720 720
          checkConcept<Base, _Digraph>();
721 721

	
722 722
          {
723 723
            typename _Digraph::Node node(INVALID);
724 724
            typename _Digraph::Arc arc(INVALID);
725 725
            {
726 726
              digraph.first(node);
727 727
              digraph.next(node);
728 728
            }
729 729
            {
730 730
              digraph.first(arc);
731 731
              digraph.next(arc);
732 732
            }
733 733
            {
734 734
              digraph.firstIn(arc, node);
735 735
              digraph.nextIn(arc);
736 736
            }
737 737
            {
738 738
              digraph.firstOut(arc, node);
739 739
              digraph.nextOut(arc);
740 740
            }
741 741
          }
742 742

	
743 743
          {
744 744
            checkConcept<GraphItemIt<_Digraph, typename _Digraph::Arc>,
745 745
              typename _Digraph::ArcIt >();
746 746
            checkConcept<GraphItemIt<_Digraph, typename _Digraph::Node>,
747 747
              typename _Digraph::NodeIt >();
748 748
            checkConcept<GraphIncIt<_Digraph, typename _Digraph::Arc,
749 749
              typename _Digraph::Node, 'i'>, typename _Digraph::InArcIt>();
750 750
            checkConcept<GraphIncIt<_Digraph, typename _Digraph::Arc,
751 751
              typename _Digraph::Node, 'o'>, typename _Digraph::OutArcIt>();
752 752

	
753 753
            typename _Digraph::Node n;
754 754
            const typename _Digraph::InArcIt iait(INVALID);
755 755
            const typename _Digraph::OutArcIt oait(INVALID);
756 756
            n = digraph.baseNode(iait);
757 757
            n = digraph.runningNode(iait);
758 758
            n = digraph.baseNode(oait);
759 759
            n = digraph.runningNode(oait);
760 760
            ignore_unused_variable_warning(n);
761 761
          }
762 762
        }
763 763

	
764 764
        const _Digraph& digraph;
765 765
      };
766 766
    };
767 767

	
768 768
    /// \brief Skeleton class for iterable undirected graphs.
769 769
    ///
770 770
    /// This class describes the interface of iterable undirected
771 771
    /// graphs. It extends \ref IterableDigraphComponent with the core
772 772
    /// iterable interface of undirected graphs.
773 773
    /// This concept is part of the Graph concept.
774 774
    template <typename BAS = BaseGraphComponent>
775 775
    class IterableGraphComponent : public IterableDigraphComponent<BAS> {
776 776
    public:
777 777

	
778 778
      typedef BAS Base;
779 779
      typedef typename Base::Node Node;
780 780
      typedef typename Base::Arc Arc;
781 781
      typedef typename Base::Edge Edge;
782 782

	
783 783

	
784 784
      typedef IterableGraphComponent Graph;
785 785

	
786 786
      /// \name Base Iteration
787 787
      ///
788 788
      /// This interface provides functions for iteration on edges.
789 789
      ///
790 790
      /// @{
791 791

	
792 792
      using IterableDigraphComponent<Base>::first;
793 793
      using IterableDigraphComponent<Base>::next;
794 794

	
795 795
      /// \brief Return the first edge.
796 796
      ///
797 797
      /// This function gives back the first edge in the iteration order.
798 798
      void first(Edge&) const {}
799 799

	
800 800
      /// \brief Return the next edge.
801 801
      ///
802 802
      /// This function gives back the next edge in the iteration order.
803 803
      void next(Edge&) const {}
804 804

	
805 805
      /// \brief Return the first edge incident to the given node.
806 806
      ///
807
      /// This function gives back the first edge incident to the given 
807
      /// This function gives back the first edge incident to the given
808 808
      /// node. The bool parameter gives back the direction for which the
809
      /// source node of the directed arc representing the edge is the 
809
      /// source node of the directed arc representing the edge is the
810 810
      /// given node.
811 811
      void firstInc(Edge&, bool&, const Node&) const {}
812 812

	
813 813
      /// \brief Gives back the next of the edges from the
814 814
      /// given node.
815 815
      ///
816
      /// This function gives back the next edge incident to the given 
816
      /// This function gives back the next edge incident to the given
817 817
      /// node. The bool parameter should be used as \c firstInc() use it.
818 818
      void nextInc(Edge&, bool&) const {}
819 819

	
820 820
      using IterableDigraphComponent<Base>::baseNode;
821 821
      using IterableDigraphComponent<Base>::runningNode;
822 822

	
823 823
      /// @}
824 824

	
825 825
      /// \name Class Based Iteration
826 826
      ///
827 827
      /// This interface provides iterator classes for edges.
828 828
      ///
829 829
      /// @{
830 830

	
831 831
      /// \brief This iterator goes through each edge.
832 832
      ///
833 833
      /// This iterator goes through each edge.
834 834
      typedef GraphItemIt<Graph, Edge> EdgeIt;
835 835

	
836 836
      /// \brief This iterator goes trough the incident edges of a
837 837
      /// node.
838 838
      ///
839 839
      /// This iterator goes trough the incident edges of a certain
840 840
      /// node of a graph.
841 841
      typedef GraphIncIt<Graph, Edge, Node, 'e'> IncEdgeIt;
842 842

	
843 843
      /// \brief The base node of the iterator.
844 844
      ///
845 845
      /// This function gives back the base node of the iterator.
846 846
      Node baseNode(const IncEdgeIt&) const { return INVALID; }
847 847

	
848 848
      /// \brief The running node of the iterator.
849 849
      ///
850 850
      /// This function gives back the running node of the iterator.
851 851
      Node runningNode(const IncEdgeIt&) const { return INVALID; }
852 852

	
853 853
      /// @}
854 854

	
855 855
      template <typename _Graph>
856 856
      struct Constraints {
857 857
        void constraints() {
858 858
          checkConcept<IterableDigraphComponent<Base>, _Graph>();
859 859

	
860 860
          {
861 861
            typename _Graph::Node node(INVALID);
862 862
            typename _Graph::Edge edge(INVALID);
863 863
            bool dir;
864 864
            {
865 865
              graph.first(edge);
866 866
              graph.next(edge);
867 867
            }
868 868
            {
869 869
              graph.firstInc(edge, dir, node);
870 870
              graph.nextInc(edge, dir);
871 871
            }
872 872

	
873 873
          }
874 874

	
875 875
          {
876 876
            checkConcept<GraphItemIt<_Graph, typename _Graph::Edge>,
877 877
              typename _Graph::EdgeIt >();
878 878
            checkConcept<GraphIncIt<_Graph, typename _Graph::Edge,
879 879
              typename _Graph::Node, 'e'>, typename _Graph::IncEdgeIt>();
880 880

	
881 881
            typename _Graph::Node n;
882 882
            const typename _Graph::IncEdgeIt ieit(INVALID);
883 883
            n = graph.baseNode(ieit);
884 884
            n = graph.runningNode(ieit);
885 885
          }
886 886
        }
887 887

	
888 888
        const _Graph& graph;
889 889
      };
890 890
    };
891 891

	
892 892
    /// \brief Skeleton class for alterable directed graphs.
893 893
    ///
894 894
    /// This class describes the interface of alterable directed
895 895
    /// graphs. It extends \ref BaseDigraphComponent with the alteration
896 896
    /// notifier interface. It implements
897 897
    /// an observer-notifier pattern for each digraph item. More
898 898
    /// obsevers can be registered into the notifier and whenever an
899 899
    /// alteration occured in the digraph all the observers will be
900 900
    /// notified about it.
901 901
    template <typename BAS = BaseDigraphComponent>
902 902
    class AlterableDigraphComponent : public BAS {
903 903
    public:
904 904

	
905 905
      typedef BAS Base;
906 906
      typedef typename Base::Node Node;
907 907
      typedef typename Base::Arc Arc;
908 908

	
909 909

	
910 910
      /// Node alteration notifier class.
911 911
      typedef AlterationNotifier<AlterableDigraphComponent, Node>
912 912
      NodeNotifier;
913 913
      /// Arc alteration notifier class.
914 914
      typedef AlterationNotifier<AlterableDigraphComponent, Arc>
915 915
      ArcNotifier;
916 916

	
917 917
      /// \brief Return the node alteration notifier.
918 918
      ///
919 919
      /// This function gives back the node alteration notifier.
920 920
      NodeNotifier& notifier(Node) const {
921 921
         return NodeNotifier();
922 922
      }
923 923

	
924 924
      /// \brief Return the arc alteration notifier.
925 925
      ///
926 926
      /// This function gives back the arc alteration notifier.
927 927
      ArcNotifier& notifier(Arc) const {
928 928
        return ArcNotifier();
929 929
      }
930 930

	
931 931
      template <typename _Digraph>
932 932
      struct Constraints {
933 933
        void constraints() {
934 934
          checkConcept<Base, _Digraph>();
935 935
          typename _Digraph::NodeNotifier& nn
936 936
            = digraph.notifier(typename _Digraph::Node());
937 937

	
938 938
          typename _Digraph::ArcNotifier& en
939 939
            = digraph.notifier(typename _Digraph::Arc());
940 940

	
941 941
          ignore_unused_variable_warning(nn);
942 942
          ignore_unused_variable_warning(en);
943 943
        }
944 944

	
945 945
        const _Digraph& digraph;
946 946
      };
947 947
    };
948 948

	
949 949
    /// \brief Skeleton class for alterable undirected graphs.
950 950
    ///
951 951
    /// This class describes the interface of alterable undirected
952 952
    /// graphs. It extends \ref AlterableDigraphComponent with the alteration
953 953
    /// notifier interface of undirected graphs. It implements
954 954
    /// an observer-notifier pattern for the edges. More
955 955
    /// obsevers can be registered into the notifier and whenever an
956 956
    /// alteration occured in the graph all the observers will be
957 957
    /// notified about it.
958 958
    template <typename BAS = BaseGraphComponent>
959 959
    class AlterableGraphComponent : public AlterableDigraphComponent<BAS> {
960 960
    public:
961 961

	
962 962
      typedef BAS Base;
963 963
      typedef typename Base::Edge Edge;
964 964

	
965 965

	
966 966
      /// Edge alteration notifier class.
967 967
      typedef AlterationNotifier<AlterableGraphComponent, Edge>
968 968
      EdgeNotifier;
969 969

	
970 970
      /// \brief Return the edge alteration notifier.
971 971
      ///
972 972
      /// This function gives back the edge alteration notifier.
973 973
      EdgeNotifier& notifier(Edge) const {
974 974
        return EdgeNotifier();
975 975
      }
976 976

	
977 977
      template <typename _Graph>
978 978
      struct Constraints {
979 979
        void constraints() {
980 980
          checkConcept<AlterableDigraphComponent<Base>, _Graph>();
981 981
          typename _Graph::EdgeNotifier& uen
982 982
            = graph.notifier(typename _Graph::Edge());
983 983
          ignore_unused_variable_warning(uen);
984 984
        }
985 985

	
986 986
        const _Graph& graph;
987 987
      };
988 988
    };
989 989

	
990 990
    /// \brief Concept class for standard graph maps.
991 991
    ///
992 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 
993
    /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and
994 994
    /// graph types, which can be used for associating data to graph items.
995 995
    /// The standard graph maps must conform to the ReferenceMap concept.
996 996
    template <typename GR, typename K, typename V>
997 997
    class GraphMap : public ReferenceMap<K, V, V&, const V&> {
998 998
      typedef ReferenceMap<K, V, V&, const V&> Parent;
999 999

	
1000 1000
    public:
1001 1001

	
1002 1002
      /// The key type of the map.
1003 1003
      typedef K Key;
1004 1004
      /// The value type of the map.
1005 1005
      typedef V Value;
1006 1006
      /// The reference type of the map.
1007 1007
      typedef Value& Reference;
1008 1008
      /// The const reference type of the map.
1009 1009
      typedef const Value& ConstReference;
1010 1010

	
1011 1011
      // The reference map tag.
1012 1012
      typedef True ReferenceMapTag;
1013 1013

	
1014 1014
      /// \brief Construct a new map.
1015 1015
      ///
1016 1016
      /// Construct a new map for the graph.
1017 1017
      explicit GraphMap(const GR&) {}
1018 1018
      /// \brief Construct a new map with default value.
1019 1019
      ///
1020 1020
      /// Construct a new map for the graph and initalize the values.
1021 1021
      GraphMap(const GR&, const Value&) {}
1022 1022

	
1023 1023
    private:
1024 1024
      /// \brief Copy constructor.
1025 1025
      ///
1026 1026
      /// Copy Constructor.
1027 1027
      GraphMap(const GraphMap&) : Parent() {}
1028 1028

	
1029 1029
      /// \brief Assignment operator.
1030 1030
      ///
1031 1031
      /// Assignment operator. It does not mofify the underlying graph,
1032 1032
      /// it just iterates on the current item set and set the  map
1033 1033
      /// with the value returned by the assigned map.
1034 1034
      template <typename CMap>
1035 1035
      GraphMap& operator=(const CMap&) {
1036 1036
        checkConcept<ReadMap<Key, Value>, CMap>();
1037 1037
        return *this;
1038 1038
      }
1039 1039

	
1040 1040
    public:
1041 1041
      template<typename _Map>
1042 1042
      struct Constraints {
1043 1043
        void constraints() {
1044 1044
          checkConcept
1045 1045
            <ReferenceMap<Key, Value, Value&, const Value&>, _Map>();
1046 1046
          _Map m1(g);
1047 1047
          _Map m2(g,t);
1048
          
1048

	
1049 1049
          // Copy constructor
1050 1050
          // _Map m3(m);
1051 1051

	
1052 1052
          // Assignment operator
1053 1053
          // ReadMap<Key, Value> cmap;
1054 1054
          // m3 = cmap;
1055 1055

	
1056 1056
          ignore_unused_variable_warning(m1);
1057 1057
          ignore_unused_variable_warning(m2);
1058 1058
          // ignore_unused_variable_warning(m3);
1059 1059
        }
1060 1060

	
1061 1061
        const _Map &m;
1062 1062
        const GR &g;
1063 1063
        const typename GraphMap::Value &t;
1064 1064
      };
1065 1065

	
1066 1066
    };
1067 1067

	
1068 1068
    /// \brief Skeleton class for mappable directed graphs.
1069 1069
    ///
1070 1070
    /// This class describes the interface of mappable directed graphs.
1071
    /// It extends \ref BaseDigraphComponent with the standard digraph 
1071
    /// It extends \ref BaseDigraphComponent with the standard digraph
1072 1072
    /// map classes, namely \c NodeMap and \c ArcMap.
1073 1073
    /// This concept is part of the Digraph concept.
1074 1074
    template <typename BAS = BaseDigraphComponent>
1075 1075
    class MappableDigraphComponent : public BAS  {
1076 1076
    public:
1077 1077

	
1078 1078
      typedef BAS Base;
1079 1079
      typedef typename Base::Node Node;
1080 1080
      typedef typename Base::Arc Arc;
1081 1081

	
1082 1082
      typedef MappableDigraphComponent Digraph;
1083 1083

	
1084 1084
      /// \brief Standard graph map for the nodes.
1085 1085
      ///
1086 1086
      /// Standard graph map for the nodes.
1087 1087
      /// It conforms to the ReferenceMap concept.
1088 1088
      template <typename V>
1089 1089
      class NodeMap : public GraphMap<MappableDigraphComponent, Node, V> {
1090 1090
        typedef GraphMap<MappableDigraphComponent, Node, V> Parent;
1091 1091

	
1092 1092
      public:
1093 1093
        /// \brief Construct a new map.
1094 1094
        ///
1095 1095
        /// Construct a new map for the digraph.
1096 1096
        explicit NodeMap(const MappableDigraphComponent& digraph)
1097 1097
          : Parent(digraph) {}
1098 1098

	
1099 1099
        /// \brief Construct a new map with default value.
1100 1100
        ///
1101 1101
        /// Construct a new map for the digraph and initalize the values.
1102 1102
        NodeMap(const MappableDigraphComponent& digraph, const V& value)
1103 1103
          : Parent(digraph, value) {}
1104 1104

	
1105 1105
      private:
1106 1106
        /// \brief Copy constructor.
1107 1107
        ///
1108 1108
        /// Copy Constructor.
1109 1109
        NodeMap(const NodeMap& nm) : Parent(nm) {}
1110 1110

	
1111 1111
        /// \brief Assignment operator.
1112 1112
        ///
1113 1113
        /// Assignment operator.
1114 1114
        template <typename CMap>
1115 1115
        NodeMap& operator=(const CMap&) {
1116 1116
          checkConcept<ReadMap<Node, V>, CMap>();
1117 1117
          return *this;
1118 1118
        }
1119 1119

	
1120 1120
      };
1121 1121

	
1122 1122
      /// \brief Standard graph map for the arcs.
1123 1123
      ///
1124 1124
      /// Standard graph map for the arcs.
1125 1125
      /// It conforms to the ReferenceMap concept.
1126 1126
      template <typename V>
1127 1127
      class ArcMap : public GraphMap<MappableDigraphComponent, Arc, V> {
1128 1128
        typedef GraphMap<MappableDigraphComponent, Arc, V> Parent;
1129 1129

	
1130 1130
      public:
1131 1131
        /// \brief Construct a new map.
1132 1132
        ///
1133 1133
        /// Construct a new map for the digraph.
1134 1134
        explicit ArcMap(const MappableDigraphComponent& digraph)
1135 1135
          : Parent(digraph) {}
1136 1136

	
1137 1137
        /// \brief Construct a new map with default value.
1138 1138
        ///
1139 1139
        /// Construct a new map for the digraph and initalize the values.
1140 1140
        ArcMap(const MappableDigraphComponent& digraph, const V& value)
1141 1141
          : Parent(digraph, value) {}
1142 1142

	
1143 1143
      private:
1144 1144
        /// \brief Copy constructor.
1145 1145
        ///
1146 1146
        /// Copy Constructor.
1147 1147
        ArcMap(const ArcMap& nm) : Parent(nm) {}
1148 1148

	
1149 1149
        /// \brief Assignment operator.
1150 1150
        ///
1151 1151
        /// Assignment operator.
1152 1152
        template <typename CMap>
1153 1153
        ArcMap& operator=(const CMap&) {
1154 1154
          checkConcept<ReadMap<Arc, V>, CMap>();
1155 1155
          return *this;
1156 1156
        }
1157 1157

	
1158 1158
      };
1159 1159

	
1160 1160

	
1161 1161
      template <typename _Digraph>
1162 1162
      struct Constraints {
1163 1163

	
1164 1164
        struct Dummy {
1165 1165
          int value;
1166 1166
          Dummy() : value(0) {}
1167 1167
          Dummy(int _v) : value(_v) {}
1168 1168
        };
1169 1169

	
1170 1170
        void constraints() {
1171 1171
          checkConcept<Base, _Digraph>();
1172 1172
          { // int map test
1173 1173
            typedef typename _Digraph::template NodeMap<int> IntNodeMap;
1174 1174
            checkConcept<GraphMap<_Digraph, typename _Digraph::Node, int>,
1175 1175
              IntNodeMap >();
1176 1176
          } { // bool map test
1177 1177
            typedef typename _Digraph::template NodeMap<bool> BoolNodeMap;
1178 1178
            checkConcept<GraphMap<_Digraph, typename _Digraph::Node, bool>,
1179 1179
              BoolNodeMap >();
1180 1180
          } { // Dummy map test
1181 1181
            typedef typename _Digraph::template NodeMap<Dummy> DummyNodeMap;
1182 1182
            checkConcept<GraphMap<_Digraph, typename _Digraph::Node, Dummy>,
1183 1183
              DummyNodeMap >();
1184 1184
          }
1185 1185

	
1186 1186
          { // int map test
1187 1187
            typedef typename _Digraph::template ArcMap<int> IntArcMap;
1188 1188
            checkConcept<GraphMap<_Digraph, typename _Digraph::Arc, int>,
1189 1189
              IntArcMap >();
1190 1190
          } { // bool map test
1191 1191
            typedef typename _Digraph::template ArcMap<bool> BoolArcMap;
1192 1192
            checkConcept<GraphMap<_Digraph, typename _Digraph::Arc, bool>,
1193 1193
              BoolArcMap >();
1194 1194
          } { // Dummy map test
1195 1195
            typedef typename _Digraph::template ArcMap<Dummy> DummyArcMap;
1196 1196
            checkConcept<GraphMap<_Digraph, typename _Digraph::Arc, Dummy>,
1197 1197
              DummyArcMap >();
1198 1198
          }
1199 1199
        }
1200 1200

	
1201 1201
        const _Digraph& digraph;
1202 1202
      };
1203 1203
    };
1204 1204

	
1205 1205
    /// \brief Skeleton class for mappable undirected graphs.
1206 1206
    ///
1207 1207
    /// This class describes the interface of mappable undirected graphs.
1208
    /// It extends \ref MappableDigraphComponent with the standard graph 
1208
    /// It extends \ref MappableDigraphComponent with the standard graph
1209 1209
    /// map class for edges (\c EdgeMap).
1210 1210
    /// This concept is part of the Graph concept.
1211 1211
    template <typename BAS = BaseGraphComponent>
1212 1212
    class MappableGraphComponent : public MappableDigraphComponent<BAS>  {
1213 1213
    public:
1214 1214

	
1215 1215
      typedef BAS Base;
1216 1216
      typedef typename Base::Edge Edge;
1217 1217

	
1218 1218
      typedef MappableGraphComponent Graph;
1219 1219

	
1220 1220
      /// \brief Standard graph map for the edges.
1221 1221
      ///
1222 1222
      /// Standard graph map for the edges.
1223 1223
      /// It conforms to the ReferenceMap concept.
1224 1224
      template <typename V>
1225 1225
      class EdgeMap : public GraphMap<MappableGraphComponent, Edge, V> {
1226 1226
        typedef GraphMap<MappableGraphComponent, Edge, V> Parent;
1227 1227

	
1228 1228
      public:
1229 1229
        /// \brief Construct a new map.
1230 1230
        ///
1231 1231
        /// Construct a new map for the graph.
1232 1232
        explicit EdgeMap(const MappableGraphComponent& graph)
1233 1233
          : Parent(graph) {}
1234 1234

	
1235 1235
        /// \brief Construct a new map with default value.
1236 1236
        ///
1237 1237
        /// Construct a new map for the graph and initalize the values.
1238 1238
        EdgeMap(const MappableGraphComponent& graph, const V& value)
1239 1239
          : Parent(graph, value) {}
1240 1240

	
1241 1241
      private:
1242 1242
        /// \brief Copy constructor.
1243 1243
        ///
1244 1244
        /// Copy Constructor.
1245 1245
        EdgeMap(const EdgeMap& nm) : Parent(nm) {}
1246 1246

	
1247 1247
        /// \brief Assignment operator.
1248 1248
        ///
1249 1249
        /// Assignment operator.
1250 1250
        template <typename CMap>
1251 1251
        EdgeMap& operator=(const CMap&) {
1252 1252
          checkConcept<ReadMap<Edge, V>, CMap>();
1253 1253
          return *this;
1254 1254
        }
1255 1255

	
1256 1256
      };
1257 1257

	
1258 1258

	
1259 1259
      template <typename _Graph>
1260 1260
      struct Constraints {
1261 1261

	
1262 1262
        struct Dummy {
1263 1263
          int value;
1264 1264
          Dummy() : value(0) {}
1265 1265
          Dummy(int _v) : value(_v) {}
1266 1266
        };
1267 1267

	
1268 1268
        void constraints() {
1269 1269
          checkConcept<MappableDigraphComponent<Base>, _Graph>();
1270 1270

	
1271 1271
          { // int map test
1272 1272
            typedef typename _Graph::template EdgeMap<int> IntEdgeMap;
1273 1273
            checkConcept<GraphMap<_Graph, typename _Graph::Edge, int>,
1274 1274
              IntEdgeMap >();
1275 1275
          } { // bool map test
1276 1276
            typedef typename _Graph::template EdgeMap<bool> BoolEdgeMap;
1277 1277
            checkConcept<GraphMap<_Graph, typename _Graph::Edge, bool>,
1278 1278
              BoolEdgeMap >();
1279 1279
          } { // Dummy map test
1280 1280
            typedef typename _Graph::template EdgeMap<Dummy> DummyEdgeMap;
1281 1281
            checkConcept<GraphMap<_Graph, typename _Graph::Edge, Dummy>,
1282 1282
              DummyEdgeMap >();
1283 1283
          }
1284 1284
        }
1285 1285

	
1286 1286
        const _Graph& graph;
1287 1287
      };
1288 1288
    };
1289 1289

	
1290 1290
    /// \brief Skeleton class for extendable directed graphs.
1291 1291
    ///
1292 1292
    /// This class describes the interface of extendable directed graphs.
1293
    /// It extends \ref BaseDigraphComponent with functions for adding 
1293
    /// It extends \ref BaseDigraphComponent with functions for adding
1294 1294
    /// nodes and arcs to the digraph.
1295 1295
    /// This concept requires \ref AlterableDigraphComponent.
1296 1296
    template <typename BAS = BaseDigraphComponent>
1297 1297
    class ExtendableDigraphComponent : public BAS {
1298 1298
    public:
1299 1299
      typedef BAS Base;
1300 1300

	
1301 1301
      typedef typename Base::Node Node;
1302 1302
      typedef typename Base::Arc Arc;
1303 1303

	
1304 1304
      /// \brief Add a new node to the digraph.
1305 1305
      ///
1306 1306
      /// This function adds a new node to the digraph.
1307 1307
      Node addNode() {
1308 1308
        return INVALID;
1309 1309
      }
1310 1310

	
1311 1311
      /// \brief Add a new arc connecting the given two nodes.
1312 1312
      ///
1313 1313
      /// This function adds a new arc connecting the given two nodes
1314 1314
      /// of the digraph.
1315 1315
      Arc addArc(const Node&, const Node&) {
1316 1316
        return INVALID;
1317 1317
      }
1318 1318

	
1319 1319
      template <typename _Digraph>
1320 1320
      struct Constraints {
1321 1321
        void constraints() {
1322 1322
          checkConcept<Base, _Digraph>();
1323 1323
          typename _Digraph::Node node_a, node_b;
1324 1324
          node_a = digraph.addNode();
1325 1325
          node_b = digraph.addNode();
1326 1326
          typename _Digraph::Arc arc;
1327 1327
          arc = digraph.addArc(node_a, node_b);
1328 1328
        }
1329 1329

	
1330 1330
        _Digraph& digraph;
1331 1331
      };
1332 1332
    };
1333 1333

	
1334 1334
    /// \brief Skeleton class for extendable undirected graphs.
1335 1335
    ///
1336 1336
    /// This class describes the interface of extendable undirected graphs.
1337
    /// It extends \ref BaseGraphComponent with functions for adding 
1337
    /// It extends \ref BaseGraphComponent with functions for adding
1338 1338
    /// nodes and edges to the graph.
1339 1339
    /// This concept requires \ref AlterableGraphComponent.
1340 1340
    template <typename BAS = BaseGraphComponent>
1341 1341
    class ExtendableGraphComponent : public BAS {
1342 1342
    public:
1343 1343

	
1344 1344
      typedef BAS Base;
1345 1345
      typedef typename Base::Node Node;
1346 1346
      typedef typename Base::Edge Edge;
1347 1347

	
1348 1348
      /// \brief Add a new node to the digraph.
1349 1349
      ///
1350 1350
      /// This function adds a new node to the digraph.
1351 1351
      Node addNode() {
1352 1352
        return INVALID;
1353 1353
      }
1354 1354

	
1355 1355
      /// \brief Add a new edge connecting the given two nodes.
1356 1356
      ///
1357 1357
      /// This function adds a new edge connecting the given two nodes
1358 1358
      /// of the graph.
1359 1359
      Edge addEdge(const Node&, const Node&) {
1360 1360
        return INVALID;
1361 1361
      }
1362 1362

	
1363 1363
      template <typename _Graph>
1364 1364
      struct Constraints {
1365 1365
        void constraints() {
1366 1366
          checkConcept<Base, _Graph>();
1367 1367
          typename _Graph::Node node_a, node_b;
1368 1368
          node_a = graph.addNode();
1369 1369
          node_b = graph.addNode();
1370 1370
          typename _Graph::Edge edge;
1371 1371
          edge = graph.addEdge(node_a, node_b);
1372 1372
        }
1373 1373

	
1374 1374
        _Graph& graph;
1375 1375
      };
1376 1376
    };
1377 1377

	
1378 1378
    /// \brief Skeleton class for erasable directed graphs.
1379 1379
    ///
1380 1380
    /// This class describes the interface of erasable directed graphs.
1381
    /// It extends \ref BaseDigraphComponent with functions for removing 
1381
    /// It extends \ref BaseDigraphComponent with functions for removing
1382 1382
    /// nodes and arcs from the digraph.
1383 1383
    /// This concept requires \ref AlterableDigraphComponent.
1384 1384
    template <typename BAS = BaseDigraphComponent>
1385 1385
    class ErasableDigraphComponent : public BAS {
1386 1386
    public:
1387 1387

	
1388 1388
      typedef BAS Base;
1389 1389
      typedef typename Base::Node Node;
1390 1390
      typedef typename Base::Arc Arc;
1391 1391

	
1392 1392
      /// \brief Erase a node from the digraph.
1393 1393
      ///
1394
      /// This function erases the given node from the digraph and all arcs 
1394
      /// This function erases the given node from the digraph and all arcs
1395 1395
      /// connected to the node.
1396 1396
      void erase(const Node&) {}
1397 1397

	
1398 1398
      /// \brief Erase an arc from the digraph.
1399 1399
      ///
1400 1400
      /// This function erases the given arc from the digraph.
1401 1401
      void erase(const Arc&) {}
1402 1402

	
1403 1403
      template <typename _Digraph>
1404 1404
      struct Constraints {
1405 1405
        void constraints() {
1406 1406
          checkConcept<Base, _Digraph>();
1407 1407
          const typename _Digraph::Node node(INVALID);
1408 1408
          digraph.erase(node);
1409 1409
          const typename _Digraph::Arc arc(INVALID);
1410 1410
          digraph.erase(arc);
1411 1411
        }
1412 1412

	
1413 1413
        _Digraph& digraph;
1414 1414
      };
1415 1415
    };
1416 1416

	
1417 1417
    /// \brief Skeleton class for erasable undirected graphs.
1418 1418
    ///
1419 1419
    /// This class describes the interface of erasable undirected graphs.
1420
    /// It extends \ref BaseGraphComponent with functions for removing 
1420
    /// It extends \ref BaseGraphComponent with functions for removing
1421 1421
    /// nodes and edges from the graph.
1422 1422
    /// This concept requires \ref AlterableGraphComponent.
1423 1423
    template <typename BAS = BaseGraphComponent>
1424 1424
    class ErasableGraphComponent : public BAS {
1425 1425
    public:
1426 1426

	
1427 1427
      typedef BAS Base;
1428 1428
      typedef typename Base::Node Node;
1429 1429
      typedef typename Base::Edge Edge;
1430 1430

	
1431 1431
      /// \brief Erase a node from the graph.
1432 1432
      ///
1433 1433
      /// This function erases the given node from the graph and all edges
1434 1434
      /// connected to the node.
1435 1435
      void erase(const Node&) {}
1436 1436

	
1437 1437
      /// \brief Erase an edge from the digraph.
1438 1438
      ///
1439 1439
      /// This function erases the given edge from the digraph.
1440 1440
      void erase(const Edge&) {}
1441 1441

	
1442 1442
      template <typename _Graph>
1443 1443
      struct Constraints {
1444 1444
        void constraints() {
1445 1445
          checkConcept<Base, _Graph>();
1446 1446
          const typename _Graph::Node node(INVALID);
1447 1447
          graph.erase(node);
1448 1448
          const typename _Graph::Edge edge(INVALID);
1449 1449
          graph.erase(edge);
1450 1450
        }
1451 1451

	
1452 1452
        _Graph& graph;
1453 1453
      };
1454 1454
    };
1455 1455

	
1456 1456
    /// \brief Skeleton class for clearable directed graphs.
1457 1457
    ///
1458 1458
    /// This class describes the interface of clearable directed graphs.
1459 1459
    /// It extends \ref BaseDigraphComponent with a function for clearing
1460 1460
    /// the digraph.
1461 1461
    /// This concept requires \ref AlterableDigraphComponent.
1462 1462
    template <typename BAS = BaseDigraphComponent>
1463 1463
    class ClearableDigraphComponent : public BAS {
1464 1464
    public:
1465 1465

	
1466 1466
      typedef BAS Base;
1467 1467

	
1468 1468
      /// \brief Erase all nodes and arcs from the digraph.
1469 1469
      ///
1470 1470
      /// This function erases all nodes and arcs from the digraph.
1471 1471
      void clear() {}
1472 1472

	
1473 1473
      template <typename _Digraph>
1474 1474
      struct Constraints {
1475 1475
        void constraints() {
1476 1476
          checkConcept<Base, _Digraph>();
1477 1477
          digraph.clear();
1478 1478
        }
1479 1479

	
1480 1480
        _Digraph& digraph;
1481 1481
      };
1482 1482
    };
1483 1483

	
1484 1484
    /// \brief Skeleton class for clearable undirected graphs.
1485 1485
    ///
1486 1486
    /// This class describes the interface of clearable undirected graphs.
1487 1487
    /// It extends \ref BaseGraphComponent with a function for clearing
1488 1488
    /// the graph.
1489 1489
    /// This concept requires \ref AlterableGraphComponent.
1490 1490
    template <typename BAS = BaseGraphComponent>
1491 1491
    class ClearableGraphComponent : public ClearableDigraphComponent<BAS> {
1492 1492
    public:
1493 1493

	
1494 1494
      typedef BAS Base;
1495 1495

	
1496 1496
      /// \brief Erase all nodes and edges from the graph.
1497 1497
      ///
1498 1498
      /// This function erases all nodes and edges from the graph.
1499 1499
      void clear() {}
1500 1500

	
1501 1501
      template <typename _Graph>
1502 1502
      struct Constraints {
1503 1503
        void constraints() {
1504 1504
          checkConcept<Base, _Graph>();
1505 1505
          graph.clear();
1506 1506
        }
1507 1507

	
1508 1508
        _Graph& graph;
1509 1509
      };
1510 1510
    };
1511 1511

	
1512 1512
  }
1513 1513

	
1514 1514
}
1515 1515

	
1516 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-2009
5
 * Copyright (C) 2003-2010
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_CONCEPTS_HEAP_H
24
#define LEMON_CONCEPTS_HEAP_H
25

	
26 26
#include <lemon/core.h>
27 27
#include <lemon/concept_check.h>
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  namespace concepts {
32 32

	
33 33
    /// \addtogroup concept
34 34
    /// @{
35 35

	
36 36
    /// \brief The heap concept.
37 37
    ///
38
    /// Concept class describing the main interface of heaps. A \e heap
39
    /// is a data structure for storing items with specified values called
40
    /// \e priorities in such a way that finding the item with minimum
41
    /// priority is efficient. In a heap one can change the priority of an
42
    /// item, add or erase an item, etc.
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.
43 45
    ///
44
    /// \tparam PR Type of the priority of the items.
45
    /// \tparam IM A read and writable item map with int values, used
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
46 52
    /// internally to handle the cross references.
47
    /// \tparam Comp A functor class for the ordering of the priorities.
53
    /// \tparam CMP A functor class for comparing the priorities.
48 54
    /// The default is \c std::less<PR>.
49 55
#ifdef DOXYGEN
50
    template <typename PR, typename IM, typename Comp = std::less<PR> >
56
    template <typename PR, typename IM, typename CMP>
51 57
#else
52
    template <typename PR, typename IM>
58
    template <typename PR, typename IM, typename CMP = std::less<PR> >
53 59
#endif
54 60
    class Heap {
55 61
    public:
56 62

	
57 63
      /// Type of the item-int map.
58 64
      typedef IM ItemIntMap;
59 65
      /// Type of the priorities.
60 66
      typedef PR Prio;
61 67
      /// Type of the items stored in the heap.
62 68
      typedef typename ItemIntMap::Key Item;
63 69

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

	
79
      /// \brief The constructor.
84
      /// \brief Constructor.
80 85
      ///
81
      /// The constructor.
86
      /// Constructor.
82 87
      /// \param map A map that assigns \c int values to keys of type
83 88
      /// \c Item. It is used internally by the heap implementations to
84 89
      /// handle the cross references. The assigned value must be
85
      /// \c PRE_HEAP (<tt>-1</tt>) for every item.
90
      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
91
#ifdef DOXYGEN
86 92
      explicit Heap(ItemIntMap &map) {}
93
#else
94
      explicit Heap(ItemIntMap&) {}
95
#endif
96

	
97
      /// \brief Constructor.
98
      ///
99
      /// Constructor.
100
      /// \param map A map that assigns \c int values to keys of type
101
      /// \c Item. It is used internally by the heap implementations to
102
      /// handle the cross references. The assigned value must be
103
      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
104
      /// \param comp The function object used for comparing the priorities.
105
#ifdef DOXYGEN
106
      explicit Heap(ItemIntMap &map, const CMP &comp) {}
107
#else
108
      explicit Heap(ItemIntMap&, const CMP&) {}
109
#endif
87 110

	
88 111
      /// \brief The number of items stored in the heap.
89 112
      ///
90
      /// Returns the number of items stored in the heap.
113
      /// This function returns the number of items stored in the heap.
91 114
      int size() const { return 0; }
92 115

	
93
      /// \brief Checks if the heap is empty.
116
      /// \brief Check if the heap is empty.
94 117
      ///
95
      /// Returns \c true if the heap is empty.
118
      /// This function returns \c true if the heap is empty.
96 119
      bool empty() const { return false; }
97 120

	
98
      /// \brief Makes the heap empty.
121
      /// \brief Make the heap empty.
99 122
      ///
100
      /// Makes the heap empty.
101
      void clear();
123
      /// This functon makes the heap empty.
124
      /// It does not change the cross reference map. If you want to reuse
125
      /// a heap that is not surely empty, you should first clear it and
126
      /// then you should set the cross reference map to \c PRE_HEAP
127
      /// for each item.
128
      void clear() {}
102 129

	
103
      /// \brief Inserts an item into the heap with the given priority.
130
      /// \brief Insert an item into the heap with the given priority.
104 131
      ///
105
      /// Inserts the given item into the heap with the given priority.
132
      /// This function inserts the given item into the heap with the
133
      /// given priority.
106 134
      /// \param i The item to insert.
107 135
      /// \param p The priority of the item.
136
      /// \pre \e i must not be stored in the heap.
137
#ifdef DOXYGEN
108 138
      void push(const Item &i, const Prio &p) {}
139
#else
140
      void push(const Item&, const Prio&) {}
141
#endif
109 142

	
110
      /// \brief Returns the item having minimum priority.
143
      /// \brief Return the item having minimum priority.
111 144
      ///
112
      /// Returns the item having minimum priority.
145
      /// This function returns the item having minimum priority.
113 146
      /// \pre The heap must be non-empty.
114
      Item top() const {}
147
      Item top() const { return Item(); }
115 148

	
116 149
      /// \brief The minimum priority.
117 150
      ///
118
      /// Returns the minimum priority.
151
      /// This function returns the minimum priority.
119 152
      /// \pre The heap must be non-empty.
120
      Prio prio() const {}
153
      Prio prio() const { return Prio(); }
121 154

	
122
      /// \brief Removes the item having minimum priority.
155
      /// \brief Remove the item having minimum priority.
123 156
      ///
124
      /// Removes the item having minimum priority.
157
      /// This function removes the item having minimum priority.
125 158
      /// \pre The heap must be non-empty.
126 159
      void pop() {}
127 160

	
128
      /// \brief Removes an item from the heap.
161
      /// \brief Remove the given item from the heap.
129 162
      ///
130
      /// Removes the given item from the heap if it is already stored.
163
      /// This function removes the given item from the heap if it is
164
      /// already stored.
131 165
      /// \param i The item to delete.
166
      /// \pre \e i must be in the heap.
167
#ifdef DOXYGEN
132 168
      void erase(const Item &i) {}
169
#else
170
      void erase(const Item&) {}
171
#endif
133 172

	
134
      /// \brief The priority of an item.
173
      /// \brief The priority of the given item.
135 174
      ///
136
      /// Returns the priority of the given item.
175
      /// This function returns the priority of the given item.
137 176
      /// \param i The item.
138
      /// \pre \c i must be in the heap.
177
      /// \pre \e i must be in the heap.
178
#ifdef DOXYGEN
139 179
      Prio operator[](const Item &i) const {}
180
#else
181
      Prio operator[](const Item&) const { return Prio(); }
182
#endif
140 183

	
141
      /// \brief Sets the priority of an item or inserts it, if it is
184
      /// \brief Set the priority of an item or insert it, if it is
142 185
      /// not stored in the heap.
143 186
      ///
144 187
      /// This method sets the priority of the given item if it is
145
      /// already stored in the heap.
146
      /// Otherwise it inserts the given item with the given priority.
188
      /// already stored in the heap. Otherwise it inserts the given
189
      /// item into the heap with the given priority.
147 190
      ///
148 191
      /// \param i The item.
149 192
      /// \param p The priority.
193
#ifdef DOXYGEN
150 194
      void set(const Item &i, const Prio &p) {}
195
#else
196
      void set(const Item&, const Prio&) {}
197
#endif
151 198

	
152
      /// \brief Decreases the priority of an item to the given value.
199
      /// \brief Decrease the priority of an item to the given value.
153 200
      ///
154
      /// Decreases the priority of an item to the given value.
201
      /// This function decreases the priority of an item to the given value.
155 202
      /// \param i The item.
156 203
      /// \param p The priority.
157
      /// \pre \c i must be stored in the heap with priority at least \c p.
204
      /// \pre \e i must be stored in the heap with priority at least \e p.
205
#ifdef DOXYGEN
158 206
      void decrease(const Item &i, const Prio &p) {}
207
#else
208
      void decrease(const Item&, const Prio&) {}
209
#endif
159 210

	
160
      /// \brief Increases the priority of an item to the given value.
211
      /// \brief Increase the priority of an item to the given value.
161 212
      ///
162
      /// Increases the priority of an item to the given value.
213
      /// This function increases the priority of an item to the given value.
163 214
      /// \param i The item.
164 215
      /// \param p The priority.
165
      /// \pre \c i must be stored in the heap with priority at most \c p.
216
      /// \pre \e i must be stored in the heap with priority at most \e p.
217
#ifdef DOXYGEN
166 218
      void increase(const Item &i, const Prio &p) {}
219
#else
220
      void increase(const Item&, const Prio&) {}
221
#endif
167 222

	
168
      /// \brief Returns if an item is in, has already been in, or has
169
      /// never been in the heap.
223
      /// \brief Return the state of an item.
170 224
      ///
171 225
      /// This method returns \c PRE_HEAP if the given item has never
172 226
      /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
173 227
      /// and \c POST_HEAP otherwise.
174 228
      /// In the latter case it is possible that the item will get back
175 229
      /// to the heap again.
176 230
      /// \param i The item.
231
#ifdef DOXYGEN
177 232
      State state(const Item &i) const {}
233
#else
234
      State state(const Item&) const { return PRE_HEAP; }
235
#endif
178 236

	
179
      /// \brief Sets the state of an item in the heap.
237
      /// \brief Set the state of an item in the heap.
180 238
      ///
181
      /// Sets the state of the given item in the heap. It can be used
182
      /// to manually clear the heap when it is important to achive the
183
      /// better time complexity.
239
      /// This function sets the state of the given item in the heap.
240
      /// It can be used to manually clear the heap when it is important
241
      /// to achive better time complexity.
184 242
      /// \param i The item.
185 243
      /// \param st The state. It should not be \c IN_HEAP.
244
#ifdef DOXYGEN
186 245
      void state(const Item& i, State st) {}
246
#else
247
      void state(const Item&, State) {}
248
#endif
187 249

	
188 250

	
189 251
      template <typename _Heap>
190 252
      struct Constraints {
191 253
      public:
192 254
        void constraints() {
193 255
          typedef typename _Heap::Item OwnItem;
194 256
          typedef typename _Heap::Prio OwnPrio;
195 257
          typedef typename _Heap::State OwnState;
196 258

	
197 259
          Item item;
198 260
          Prio prio;
199 261
          item=Item();
200 262
          prio=Prio();
201 263
          ignore_unused_variable_warning(item);
202 264
          ignore_unused_variable_warning(prio);
203 265

	
204 266
          OwnItem own_item;
205 267
          OwnPrio own_prio;
206 268
          OwnState own_state;
207 269
          own_item=Item();
208 270
          own_prio=Prio();
209 271
          ignore_unused_variable_warning(own_item);
210 272
          ignore_unused_variable_warning(own_prio);
211 273
          ignore_unused_variable_warning(own_state);
212 274

	
213 275
          _Heap heap1(map);
214 276
          _Heap heap2 = heap1;
215 277
          ignore_unused_variable_warning(heap1);
216 278
          ignore_unused_variable_warning(heap2);
217 279

	
218 280
          int s = heap.size();
219 281
          ignore_unused_variable_warning(s);
220 282
          bool e = heap.empty();
221 283
          ignore_unused_variable_warning(e);
222 284

	
223 285
          prio = heap.prio();
224 286
          item = heap.top();
225 287
          prio = heap[item];
226 288
          own_prio = heap.prio();
227 289
          own_item = heap.top();
228 290
          own_prio = heap[own_item];
229 291

	
230 292
          heap.push(item, prio);
231 293
          heap.push(own_item, own_prio);
232 294
          heap.pop();
233 295

	
234 296
          heap.set(item, prio);
235 297
          heap.decrease(item, prio);
236 298
          heap.increase(item, prio);
237 299
          heap.set(own_item, own_prio);
238 300
          heap.decrease(own_item, own_prio);
239 301
          heap.increase(own_item, own_prio);
240 302

	
241 303
          heap.erase(item);
242 304
          heap.erase(own_item);
243 305
          heap.clear();
244 306

	
245 307
          own_state = heap.state(own_item);
246 308
          heap.state(own_item, own_state);
247 309

	
248 310
          own_state = _Heap::PRE_HEAP;
249 311
          own_state = _Heap::IN_HEAP;
250 312
          own_state = _Heap::POST_HEAP;
251 313
        }
252 314

	
253 315
        _Heap& heap;
254 316
        ItemIntMap& map;
255 317
      };
256 318
    };
257 319

	
258 320
    /// @}
259 321
  } // namespace lemon
260 322
}
261 323
#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 19
///\ingroup concept
20 20
///\file
21
///\brief Classes for representing paths in digraphs.
21
///\brief The concept of paths
22 22
///
23 23

	
24 24
#ifndef LEMON_CONCEPTS_PATH_H
25 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
    /// In a sense, a path can be treated as a list of arcs.
42
    /// LEMON path types just store this list. As a consequence, they cannot
43
    /// enumerate the nodes on the path directly and a zero length path
44
    /// cannot store its source node.
45
    ///
46
    /// The arcs of a path should be stored in the order of their directions,
47
    /// i.e. the target node of each arc should be the same as the source
48
    /// node of the next arc. This consistency could be checked using
49
    /// \ref checkPath().
50
    /// The source and target nodes of a (consistent) path can be obtained
51
    /// using \ref pathSource() and \ref pathTarget().
52
    ///
53
    /// A path can be constructed from another path of any type using the
54
    /// copy constructor or the assignment operator.
55
    ///
41 56
    /// \tparam GR The digraph type in which the path is.
42
    ///
43
    /// In a sense, the path can be treated as a list of arcs. The
44
    /// lemon path type stores just this list. As a consequence it
45
    /// cannot enumerate the nodes in the path and the zero length
46
    /// paths cannot store the source.
47
    ///
48 57
    template <typename GR>
49 58
    class Path {
50 59
    public:
51 60

	
52 61
      /// Type of the underlying digraph.
53 62
      typedef GR Digraph;
54 63
      /// Arc type of the underlying digraph.
55 64
      typedef typename Digraph::Arc Arc;
56 65

	
57 66
      class ArcIt;
58 67

	
59 68
      /// \brief Default constructor
60 69
      Path() {}
61 70

	
62
      /// \brief Template constructor
71
      /// \brief Template copy constructor
63 72
      template <typename CPath>
64 73
      Path(const CPath& cpath) {}
65 74

	
66
      /// \brief Template assigment
75
      /// \brief Template assigment operator
67 76
      template <typename CPath>
68 77
      Path& operator=(const CPath& cpath) {
69 78
        ignore_unused_variable_warning(cpath);
70 79
        return *this;
71 80
      }
72 81

	
73
      /// Length of the path ie. the number of arcs in the path.
82
      /// Length of the path, i.e. the number of arcs on the path.
74 83
      int length() const { return 0;}
75 84

	
76 85
      /// Returns whether the path is empty.
77 86
      bool empty() const { return true;}
78 87

	
79 88
      /// Resets the path to an empty path.
80 89
      void clear() {}
81 90

	
82
      /// \brief LEMON style iterator for path arcs
91
      /// \brief LEMON style iterator for enumerating the arcs of a path.
83 92
      ///
84
      /// This class is used to iterate on the arcs of the paths.
93
      /// LEMON style iterator class for enumerating the arcs of a path.
85 94
      class ArcIt {
86 95
      public:
87 96
        /// Default constructor
88 97
        ArcIt() {}
89 98
        /// Invalid constructor
90 99
        ArcIt(Invalid) {}
91
        /// Constructor for first arc
100
        /// Sets the iterator to the first arc of the given path
92 101
        ArcIt(const Path &) {}
93 102

	
94
        /// Conversion to Arc
103
        /// Conversion to \c Arc
95 104
        operator Arc() const { return INVALID; }
96 105

	
97 106
        /// Next arc
98 107
        ArcIt& operator++() {return *this;}
99 108

	
100 109
        /// Comparison operator
101 110
        bool operator==(const ArcIt&) const {return true;}
102 111
        /// Comparison operator
103 112
        bool operator!=(const ArcIt&) const {return true;}
104 113
        /// Comparison operator
105 114
        bool operator<(const ArcIt&) const {return false;}
106 115

	
107 116
      };
108 117

	
109 118
      template <typename _Path>
110 119
      struct Constraints {
111 120
        void constraints() {
112 121
          Path<Digraph> pc;
113 122
          _Path p, pp(pc);
114 123
          int l = p.length();
115 124
          int e = p.empty();
116 125
          p.clear();
117 126

	
118 127
          p = pc;
119 128

	
120 129
          typename _Path::ArcIt id, ii(INVALID), i(p);
121 130

	
122 131
          ++i;
123 132
          typename Digraph::Arc ed = i;
124 133

	
125 134
          e = (i == ii);
126 135
          e = (i != ii);
127 136
          e = (i < ii);
128 137

	
129 138
          ignore_unused_variable_warning(l);
130 139
          ignore_unused_variable_warning(pp);
131 140
          ignore_unused_variable_warning(e);
132 141
          ignore_unused_variable_warning(id);
133 142
          ignore_unused_variable_warning(ii);
134 143
          ignore_unused_variable_warning(ed);
135 144
        }
136 145
      };
137 146

	
138 147
    };
139 148

	
140 149
    namespace _path_bits {
141 150

	
142 151
      template <typename _Digraph, typename _Path, typename RevPathTag = void>
143 152
      struct PathDumperConstraints {
144 153
        void constraints() {
145 154
          int l = p.length();
146 155
          int e = p.empty();
147 156

	
148 157
          typename _Path::ArcIt id, i(p);
149 158

	
150 159
          ++i;
151 160
          typename _Digraph::Arc ed = i;
152 161

	
153 162
          e = (i == INVALID);
154 163
          e = (i != INVALID);
155 164

	
156 165
          ignore_unused_variable_warning(l);
157 166
          ignore_unused_variable_warning(e);
158 167
          ignore_unused_variable_warning(id);
159 168
          ignore_unused_variable_warning(ed);
160 169
        }
161 170
        _Path& p;
162 171
      };
163 172

	
164 173
      template <typename _Digraph, typename _Path>
165 174
      struct PathDumperConstraints<
166 175
        _Digraph, _Path,
167 176
        typename enable_if<typename _Path::RevPathTag, void>::type
168 177
      > {
169 178
        void constraints() {
170 179
          int l = p.length();
171 180
          int e = p.empty();
172 181

	
173 182
          typename _Path::RevArcIt id, i(p);
174 183

	
175 184
          ++i;
176 185
          typename _Digraph::Arc ed = i;
177 186

	
178 187
          e = (i == INVALID);
179 188
          e = (i != INVALID);
180 189

	
181 190
          ignore_unused_variable_warning(l);
182 191
          ignore_unused_variable_warning(e);
183 192
          ignore_unused_variable_warning(id);
184 193
          ignore_unused_variable_warning(ed);
185 194
        }
186 195
        _Path& p;
187 196
      };
188 197

	
189 198
    }
190 199

	
191 200

	
192 201
    /// \brief A skeleton structure for path dumpers.
193 202
    ///
194 203
    /// A skeleton structure for path dumpers. The path dumpers are
195
    /// the generalization of the paths. The path dumpers can
196
    /// enumerate the arcs of the path wheter in forward or in
197
    /// backward order.  In most time these classes are not used
198
    /// directly rather it used to assign a dumped class to a real
199
    /// path type.
204
    /// the generalization of the paths, they can enumerate the arcs
205
    /// of the path either in forward or in backward order.
206
    /// These classes are typically not used directly, they are rather
207
    /// used to be assigned to a real path type.
200 208
    ///
201 209
    /// The main purpose of this concept is that the shortest path
202
    /// algorithms can enumerate easily the arcs in reverse order.
203
    /// If we would like to give back a real path from these
204
    /// algorithms then we should create a temporarly path object. In
205
    /// LEMON such algorithms gives back a path dumper what can
206
    /// assigned to a real path and the dumpers can be implemented as
210
    /// algorithms can enumerate the arcs easily in reverse order.
211
    /// In LEMON, such algorithms give back a (reverse) path dumper that
212
    /// can be assigned to a real path. The dumpers can be implemented as
207 213
    /// an adaptor class to the predecessor map.
208 214
    ///
209 215
    /// \tparam GR The digraph type in which the path is.
210
    ///
211
    /// The paths can be constructed from any path type by a
212
    /// template constructor or a template assignment operator.
213 216
    template <typename GR>
214 217
    class PathDumper {
215 218
    public:
216 219

	
217 220
      /// Type of the underlying digraph.
218 221
      typedef GR Digraph;
219 222
      /// Arc type of the underlying digraph.
220 223
      typedef typename Digraph::Arc Arc;
221 224

	
222
      /// Length of the path ie. the number of arcs in the path.
225
      /// Length of the path, i.e. the number of arcs on the path.
223 226
      int length() const { return 0;}
224 227

	
225 228
      /// Returns whether the path is empty.
226 229
      bool empty() const { return true;}
227 230

	
228 231
      /// \brief Forward or reverse dumping
229 232
      ///
230
      /// If the RevPathTag is defined and true then reverse dumping
231
      /// is provided in the path dumper. In this case instead of the
232
      /// ArcIt the RevArcIt iterator should be implemented in the
233
      /// dumper.
233
      /// If this tag is defined to be \c True, then reverse dumping
234
      /// is provided in the path dumper. In this case, \c RevArcIt
235
      /// iterator should be implemented instead of \c ArcIt iterator.
234 236
      typedef False RevPathTag;
235 237

	
236
      /// \brief LEMON style iterator for path arcs
238
      /// \brief LEMON style iterator for enumerating the arcs of a path.
237 239
      ///
238
      /// This class is used to iterate on the arcs of the paths.
240
      /// LEMON style iterator class for enumerating the arcs of a path.
239 241
      class ArcIt {
240 242
      public:
241 243
        /// Default constructor
242 244
        ArcIt() {}
243 245
        /// Invalid constructor
244 246
        ArcIt(Invalid) {}
245
        /// Constructor for first arc
247
        /// Sets the iterator to the first arc of the given path
246 248
        ArcIt(const PathDumper&) {}
247 249

	
248
        /// Conversion to Arc
250
        /// Conversion to \c Arc
249 251
        operator Arc() const { return INVALID; }
250 252

	
251 253
        /// Next arc
252 254
        ArcIt& operator++() {return *this;}
253 255

	
254 256
        /// Comparison operator
255 257
        bool operator==(const ArcIt&) const {return true;}
256 258
        /// Comparison operator
257 259
        bool operator!=(const ArcIt&) const {return true;}
258 260
        /// Comparison operator
259 261
        bool operator<(const ArcIt&) const {return false;}
260 262

	
261 263
      };
262 264

	
263
      /// \brief LEMON style iterator for path arcs
265
      /// \brief LEMON style iterator for enumerating the arcs of a path
266
      /// in reverse direction.
264 267
      ///
265
      /// This class is used to iterate on the arcs of the paths in
266
      /// reverse direction.
268
      /// LEMON style iterator class for enumerating the arcs of a path
269
      /// in reverse direction.
267 270
      class RevArcIt {
268 271
      public:
269 272
        /// Default constructor
270 273
        RevArcIt() {}
271 274
        /// Invalid constructor
272 275
        RevArcIt(Invalid) {}
273
        /// Constructor for first arc
276
        /// Sets the iterator to the last arc of the given path
274 277
        RevArcIt(const PathDumper &) {}
275 278

	
276
        /// Conversion to Arc
279
        /// Conversion to \c Arc
277 280
        operator Arc() const { return INVALID; }
278 281

	
279 282
        /// Next arc
280 283
        RevArcIt& operator++() {return *this;}
281 284

	
282 285
        /// Comparison operator
283 286
        bool operator==(const RevArcIt&) const {return true;}
284 287
        /// Comparison operator
285 288
        bool operator!=(const RevArcIt&) const {return true;}
286 289
        /// Comparison operator
287 290
        bool operator<(const RevArcIt&) const {return false;}
288 291

	
289 292
      };
290 293

	
291 294
      template <typename _Path>
292 295
      struct Constraints {
293 296
        void constraints() {
294 297
          function_requires<_path_bits::
295 298
            PathDumperConstraints<Digraph, _Path> >();
296 299
        }
297 300
      };
298 301

	
299 302
    };
300 303

	
301 304

	
302 305
    ///@}
303 306
  }
304 307

	
305 308
} // namespace lemon
306 309

	
307 310
#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-2009
5
 * Copyright (C) 2003-2010
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_CONNECTIVITY_H
20 20
#define LEMON_CONNECTIVITY_H
21 21

	
22 22
#include <lemon/dfs.h>
23 23
#include <lemon/bfs.h>
24 24
#include <lemon/core.h>
25 25
#include <lemon/maps.h>
26 26
#include <lemon/adaptors.h>
27 27

	
28 28
#include <lemon/concepts/digraph.h>
29 29
#include <lemon/concepts/graph.h>
30 30
#include <lemon/concept_check.h>
31 31

	
32 32
#include <stack>
33 33
#include <functional>
34 34

	
35 35
/// \ingroup graph_properties
36 36
/// \file
37 37
/// \brief Connectivity algorithms
38 38
///
39 39
/// Connectivity algorithms
40 40

	
41 41
namespace lemon {
42 42

	
43 43
  /// \ingroup graph_properties
44 44
  ///
45 45
  /// \brief Check whether an undirected graph is connected.
46 46
  ///
47 47
  /// This function checks whether the given undirected graph is connected,
48 48
  /// i.e. there is a path between any two nodes in the graph.
49 49
  ///
50 50
  /// \return \c true if the graph is connected.
51 51
  /// \note By definition, the empty graph is connected.
52 52
  ///
53 53
  /// \see countConnectedComponents(), connectedComponents()
54 54
  /// \see stronglyConnected()
55 55
  template <typename Graph>
56 56
  bool connected(const Graph& graph) {
57 57
    checkConcept<concepts::Graph, Graph>();
58 58
    typedef typename Graph::NodeIt NodeIt;
59 59
    if (NodeIt(graph) == INVALID) return true;
60 60
    Dfs<Graph> dfs(graph);
61 61
    dfs.run(NodeIt(graph));
62 62
    for (NodeIt it(graph); it != INVALID; ++it) {
63 63
      if (!dfs.reached(it)) {
64 64
        return false;
65 65
      }
66 66
    }
67 67
    return true;
68 68
  }
69 69

	
70 70
  /// \ingroup graph_properties
71 71
  ///
72 72
  /// \brief Count the number of connected components of an undirected graph
73 73
  ///
74 74
  /// This function counts the number of connected components of the given
75 75
  /// undirected graph.
76 76
  ///
77 77
  /// The connected components are the classes of an equivalence relation
78 78
  /// on the nodes of an undirected graph. Two nodes are in the same class
79 79
  /// if they are connected with a path.
80 80
  ///
81 81
  /// \return The number of connected components.
82 82
  /// \note By definition, the empty graph consists
83 83
  /// of zero connected components.
84 84
  ///
85 85
  /// \see connected(), connectedComponents()
86 86
  template <typename Graph>
87 87
  int countConnectedComponents(const Graph &graph) {
88 88
    checkConcept<concepts::Graph, Graph>();
89 89
    typedef typename Graph::Node Node;
90 90
    typedef typename Graph::Arc Arc;
91 91

	
92 92
    typedef NullMap<Node, Arc> PredMap;
93 93
    typedef NullMap<Node, int> DistMap;
94 94

	
95 95
    int compNum = 0;
96 96
    typename Bfs<Graph>::
97 97
      template SetPredMap<PredMap>::
98 98
      template SetDistMap<DistMap>::
99 99
      Create bfs(graph);
100 100

	
101 101
    PredMap predMap;
102 102
    bfs.predMap(predMap);
103 103

	
104 104
    DistMap distMap;
105 105
    bfs.distMap(distMap);
106 106

	
107 107
    bfs.init();
108 108
    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
109 109
      if (!bfs.reached(n)) {
110 110
        bfs.addSource(n);
111 111
        bfs.start();
112 112
        ++compNum;
113 113
      }
114 114
    }
115 115
    return compNum;
116 116
  }
117 117

	
118 118
  /// \ingroup graph_properties
119 119
  ///
120 120
  /// \brief Find the connected components of an undirected graph
121 121
  ///
122 122
  /// This function finds the connected components of the given undirected
123 123
  /// graph.
124 124
  ///
125 125
  /// The connected components are the classes of an equivalence relation
126 126
  /// on the nodes of an undirected graph. Two nodes are in the same class
127 127
  /// if they are connected with a path.
128 128
  ///
129 129
  /// \image html connected_components.png
130 130
  /// \image latex connected_components.eps "Connected components" width=\textwidth
131 131
  ///
132 132
  /// \param graph The undirected graph.
133 133
  /// \retval compMap A writable node map. The values will be set from 0 to
134 134
  /// the number of the connected components minus one. Each value of the map
135 135
  /// will be set exactly once, and the values of a certain component will be
136 136
  /// set continuously.
137 137
  /// \return The number of connected components.
138 138
  /// \note By definition, the empty graph consists
139 139
  /// of zero connected components.
140 140
  ///
141 141
  /// \see connected(), countConnectedComponents()
142 142
  template <class Graph, class NodeMap>
143 143
  int connectedComponents(const Graph &graph, NodeMap &compMap) {
144 144
    checkConcept<concepts::Graph, Graph>();
145 145
    typedef typename Graph::Node Node;
146 146
    typedef typename Graph::Arc Arc;
147 147
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
148 148

	
149 149
    typedef NullMap<Node, Arc> PredMap;
150 150
    typedef NullMap<Node, int> DistMap;
151 151

	
152 152
    int compNum = 0;
153 153
    typename Bfs<Graph>::
154 154
      template SetPredMap<PredMap>::
155 155
      template SetDistMap<DistMap>::
156 156
      Create bfs(graph);
157 157

	
158 158
    PredMap predMap;
159 159
    bfs.predMap(predMap);
160 160

	
161 161
    DistMap distMap;
162 162
    bfs.distMap(distMap);
163 163

	
164 164
    bfs.init();
165 165
    for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
166 166
      if(!bfs.reached(n)) {
167 167
        bfs.addSource(n);
168 168
        while (!bfs.emptyQueue()) {
169 169
          compMap.set(bfs.nextNode(), compNum);
170 170
          bfs.processNextNode();
171 171
        }
172 172
        ++compNum;
173 173
      }
174 174
    }
175 175
    return compNum;
176 176
  }
177 177

	
178 178
  namespace _connectivity_bits {
179 179

	
180 180
    template <typename Digraph, typename Iterator >
181 181
    struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
182 182
    public:
183 183
      typedef typename Digraph::Node Node;
184 184
      LeaveOrderVisitor(Iterator it) : _it(it) {}
185 185

	
186 186
      void leave(const Node& node) {
187 187
        *(_it++) = node;
188 188
      }
189 189

	
190 190
    private:
191 191
      Iterator _it;
192 192
    };
193 193

	
194 194
    template <typename Digraph, typename Map>
195 195
    struct FillMapVisitor : public DfsVisitor<Digraph> {
196 196
    public:
197 197
      typedef typename Digraph::Node Node;
198 198
      typedef typename Map::Value Value;
199 199

	
200 200
      FillMapVisitor(Map& map, Value& value)
201 201
        : _map(map), _value(value) {}
202 202

	
203 203
      void reach(const Node& node) {
204 204
        _map.set(node, _value);
205 205
      }
206 206
    private:
207 207
      Map& _map;
208 208
      Value& _value;
209 209
    };
210 210

	
211 211
    template <typename Digraph, typename ArcMap>
212 212
    struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
213 213
    public:
214 214
      typedef typename Digraph::Node Node;
215 215
      typedef typename Digraph::Arc Arc;
216 216

	
217 217
      StronglyConnectedCutArcsVisitor(const Digraph& digraph,
218 218
                                      ArcMap& cutMap,
219 219
                                      int& cutNum)
220 220
        : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
221 221
          _compMap(digraph, -1), _num(-1) {
222 222
      }
223 223

	
224 224
      void start(const Node&) {
225 225
        ++_num;
226 226
      }
227 227

	
228 228
      void reach(const Node& node) {
229 229
        _compMap.set(node, _num);
230 230
      }
231 231

	
232 232
      void examine(const Arc& arc) {
233 233
         if (_compMap[_digraph.source(arc)] !=
234 234
             _compMap[_digraph.target(arc)]) {
235 235
           _cutMap.set(arc, true);
236 236
           ++_cutNum;
237 237
         }
238 238
      }
239 239
    private:
240 240
      const Digraph& _digraph;
241 241
      ArcMap& _cutMap;
242 242
      int& _cutNum;
243 243

	
244 244
      typename Digraph::template NodeMap<int> _compMap;
245 245
      int _num;
246 246
    };
247 247

	
248 248
  }
249 249

	
250 250

	
251 251
  /// \ingroup graph_properties
252 252
  ///
253 253
  /// \brief Check whether a directed graph is strongly connected.
254 254
  ///
255 255
  /// This function checks whether the given directed graph is strongly
256 256
  /// connected, i.e. any two nodes of the digraph are
257 257
  /// connected with directed paths in both direction.
258 258
  ///
259 259
  /// \return \c true if the digraph is strongly connected.
260 260
  /// \note By definition, the empty digraph is strongly connected.
261
  /// 
261
  ///
262 262
  /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
263 263
  /// \see connected()
264 264
  template <typename Digraph>
265 265
  bool stronglyConnected(const Digraph& digraph) {
266 266
    checkConcept<concepts::Digraph, Digraph>();
267 267

	
268 268
    typedef typename Digraph::Node Node;
269 269
    typedef typename Digraph::NodeIt NodeIt;
270 270

	
271 271
    typename Digraph::Node source = NodeIt(digraph);
272 272
    if (source == INVALID) return true;
273 273

	
274 274
    using namespace _connectivity_bits;
275 275

	
276 276
    typedef DfsVisitor<Digraph> Visitor;
277 277
    Visitor visitor;
278 278

	
279 279
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
280 280
    dfs.init();
281 281
    dfs.addSource(source);
282 282
    dfs.start();
283 283

	
284 284
    for (NodeIt it(digraph); it != INVALID; ++it) {
285 285
      if (!dfs.reached(it)) {
286 286
        return false;
287 287
      }
288 288
    }
289 289

	
290 290
    typedef ReverseDigraph<const Digraph> RDigraph;
291 291
    typedef typename RDigraph::NodeIt RNodeIt;
292 292
    RDigraph rdigraph(digraph);
293 293

	
294 294
    typedef DfsVisitor<RDigraph> RVisitor;
295 295
    RVisitor rvisitor;
296 296

	
297 297
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
298 298
    rdfs.init();
299 299
    rdfs.addSource(source);
300 300
    rdfs.start();
301 301

	
302 302
    for (RNodeIt it(rdigraph); it != INVALID; ++it) {
303 303
      if (!rdfs.reached(it)) {
304 304
        return false;
305 305
      }
306 306
    }
307 307

	
308 308
    return true;
309 309
  }
310 310

	
311 311
  /// \ingroup graph_properties
312 312
  ///
313
  /// \brief Count the number of strongly connected components of a 
313
  /// \brief Count the number of strongly connected components of a
314 314
  /// directed graph
315 315
  ///
316 316
  /// This function counts the number of strongly connected components of
317 317
  /// the given directed graph.
318 318
  ///
319 319
  /// The strongly connected components are the classes of an
320 320
  /// equivalence relation on the nodes of a digraph. Two nodes are in
321 321
  /// the same class if they are connected with directed paths in both
322 322
  /// direction.
323 323
  ///
324 324
  /// \return The number of strongly connected components.
325 325
  /// \note By definition, the empty digraph has zero
326 326
  /// strongly connected components.
327 327
  ///
328 328
  /// \see stronglyConnected(), stronglyConnectedComponents()
329 329
  template <typename Digraph>
330 330
  int countStronglyConnectedComponents(const Digraph& digraph) {
331 331
    checkConcept<concepts::Digraph, Digraph>();
332 332

	
333 333
    using namespace _connectivity_bits;
334 334

	
335 335
    typedef typename Digraph::Node Node;
336 336
    typedef typename Digraph::Arc Arc;
337 337
    typedef typename Digraph::NodeIt NodeIt;
338 338
    typedef typename Digraph::ArcIt ArcIt;
339 339

	
340 340
    typedef std::vector<Node> Container;
341 341
    typedef typename Container::iterator Iterator;
342 342

	
343 343
    Container nodes(countNodes(digraph));
344 344
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
345 345
    Visitor visitor(nodes.begin());
346 346

	
347 347
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
348 348
    dfs.init();
349 349
    for (NodeIt it(digraph); it != INVALID; ++it) {
350 350
      if (!dfs.reached(it)) {
351 351
        dfs.addSource(it);
352 352
        dfs.start();
353 353
      }
354 354
    }
355 355

	
356 356
    typedef typename Container::reverse_iterator RIterator;
357 357
    typedef ReverseDigraph<const Digraph> RDigraph;
358 358

	
359 359
    RDigraph rdigraph(digraph);
360 360

	
361 361
    typedef DfsVisitor<Digraph> RVisitor;
362 362
    RVisitor rvisitor;
363 363

	
364 364
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
365 365

	
366 366
    int compNum = 0;
367 367

	
368 368
    rdfs.init();
369 369
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
370 370
      if (!rdfs.reached(*it)) {
371 371
        rdfs.addSource(*it);
372 372
        rdfs.start();
373 373
        ++compNum;
374 374
      }
375 375
    }
376 376
    return compNum;
377 377
  }
378 378

	
379 379
  /// \ingroup graph_properties
380 380
  ///
381 381
  /// \brief Find the strongly connected components of a directed graph
382 382
  ///
383 383
  /// This function finds the strongly connected components of the given
384 384
  /// directed graph. In addition, the numbering of the components will
385 385
  /// satisfy that there is no arc going from a higher numbered component
386 386
  /// to a lower one (i.e. it provides a topological order of the components).
387 387
  ///
388 388
  /// The strongly connected components are the classes of an
389 389
  /// equivalence relation on the nodes of a digraph. Two nodes are in
390 390
  /// the same class if they are connected with directed paths in both
391 391
  /// direction.
392 392
  ///
393 393
  /// \image html strongly_connected_components.png
394 394
  /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
395 395
  ///
396 396
  /// \param digraph The digraph.
397 397
  /// \retval compMap A writable node map. The values will be set from 0 to
398 398
  /// the number of the strongly connected components minus one. Each value
399 399
  /// of the map will be set exactly once, and the values of a certain
400 400
  /// component will be set continuously.
401 401
  /// \return The number of strongly connected components.
402 402
  /// \note By definition, the empty digraph has zero
403 403
  /// strongly connected components.
404 404
  ///
405 405
  /// \see stronglyConnected(), countStronglyConnectedComponents()
406 406
  template <typename Digraph, typename NodeMap>
407 407
  int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
408 408
    checkConcept<concepts::Digraph, Digraph>();
409 409
    typedef typename Digraph::Node Node;
410 410
    typedef typename Digraph::NodeIt NodeIt;
411 411
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
412 412

	
413 413
    using namespace _connectivity_bits;
414 414

	
415 415
    typedef std::vector<Node> Container;
416 416
    typedef typename Container::iterator Iterator;
417 417

	
418 418
    Container nodes(countNodes(digraph));
419 419
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
420 420
    Visitor visitor(nodes.begin());
421 421

	
422 422
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
423 423
    dfs.init();
424 424
    for (NodeIt it(digraph); it != INVALID; ++it) {
425 425
      if (!dfs.reached(it)) {
426 426
        dfs.addSource(it);
427 427
        dfs.start();
428 428
      }
429 429
    }
430 430

	
431 431
    typedef typename Container::reverse_iterator RIterator;
432 432
    typedef ReverseDigraph<const Digraph> RDigraph;
433 433

	
434 434
    RDigraph rdigraph(digraph);
435 435

	
436 436
    int compNum = 0;
437 437

	
438 438
    typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
439 439
    RVisitor rvisitor(compMap, compNum);
440 440

	
441 441
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
442 442

	
443 443
    rdfs.init();
444 444
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
445 445
      if (!rdfs.reached(*it)) {
446 446
        rdfs.addSource(*it);
447 447
        rdfs.start();
448 448
        ++compNum;
449 449
      }
450 450
    }
451 451
    return compNum;
452 452
  }
453 453

	
454 454
  /// \ingroup graph_properties
455 455
  ///
456 456
  /// \brief Find the cut arcs of the strongly connected components.
457 457
  ///
458 458
  /// This function finds the cut arcs of the strongly connected components
459 459
  /// of the given digraph.
460 460
  ///
461 461
  /// The strongly connected components are the classes of an
462 462
  /// equivalence relation on the nodes of a digraph. Two nodes are in
463 463
  /// the same class if they are connected with directed paths in both
464 464
  /// direction.
465 465
  /// The strongly connected components are separated by the cut arcs.
466 466
  ///
467 467
  /// \param digraph The digraph.
468 468
  /// \retval cutMap A writable arc map. The values will be set to \c true
469 469
  /// for the cut arcs (exactly once for each cut arc), and will not be
470 470
  /// changed for other arcs.
471 471
  /// \return The number of cut arcs.
472 472
  ///
473 473
  /// \see stronglyConnected(), stronglyConnectedComponents()
474 474
  template <typename Digraph, typename ArcMap>
475 475
  int stronglyConnectedCutArcs(const Digraph& digraph, ArcMap& cutMap) {
476 476
    checkConcept<concepts::Digraph, Digraph>();
477 477
    typedef typename Digraph::Node Node;
478 478
    typedef typename Digraph::Arc Arc;
479 479
    typedef typename Digraph::NodeIt NodeIt;
480 480
    checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
481 481

	
482 482
    using namespace _connectivity_bits;
483 483

	
484 484
    typedef std::vector<Node> Container;
485 485
    typedef typename Container::iterator Iterator;
486 486

	
487 487
    Container nodes(countNodes(digraph));
488 488
    typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
489 489
    Visitor visitor(nodes.begin());
490 490

	
491 491
    DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
492 492
    dfs.init();
493 493
    for (NodeIt it(digraph); it != INVALID; ++it) {
494 494
      if (!dfs.reached(it)) {
495 495
        dfs.addSource(it);
496 496
        dfs.start();
497 497
      }
498 498
    }
499 499

	
500 500
    typedef typename Container::reverse_iterator RIterator;
501 501
    typedef ReverseDigraph<const Digraph> RDigraph;
502 502

	
503 503
    RDigraph rdigraph(digraph);
504 504

	
505 505
    int cutNum = 0;
506 506

	
507 507
    typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
508 508
    RVisitor rvisitor(rdigraph, cutMap, cutNum);
509 509

	
510 510
    DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
511 511

	
512 512
    rdfs.init();
513 513
    for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
514 514
      if (!rdfs.reached(*it)) {
515 515
        rdfs.addSource(*it);
516 516
        rdfs.start();
517 517
      }
518 518
    }
519 519
    return cutNum;
520 520
  }
521 521

	
522 522
  namespace _connectivity_bits {
523 523

	
524 524
    template <typename Digraph>
525 525
    class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
526 526
    public:
527 527
      typedef typename Digraph::Node Node;
528 528
      typedef typename Digraph::Arc Arc;
529 529
      typedef typename Digraph::Edge Edge;
530 530

	
531 531
      CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
532 532
        : _graph(graph), _compNum(compNum),
533 533
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
534 534

	
535 535
      void start(const Node& node) {
536 536
        _predMap.set(node, INVALID);
537 537
      }
538 538

	
539 539
      void reach(const Node& node) {
540 540
        _numMap.set(node, _num);
541 541
        _retMap.set(node, _num);
542 542
        ++_num;
543 543
      }
544 544

	
545 545
      void discover(const Arc& edge) {
546 546
        _predMap.set(_graph.target(edge), _graph.source(edge));
547 547
      }
548 548

	
549 549
      void examine(const Arc& edge) {
550 550
        if (_graph.source(edge) == _graph.target(edge) &&
551 551
            _graph.direction(edge)) {
552 552
          ++_compNum;
553 553
          return;
554 554
        }
555 555
        if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
556 556
          return;
557 557
        }
558 558
        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
559 559
          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
560 560
        }
561 561
      }
562 562

	
563 563
      void backtrack(const Arc& edge) {
564 564
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
565 565
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
566 566
        }
567 567
        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
568 568
          ++_compNum;
569 569
        }
570 570
      }
571 571

	
572 572
    private:
573 573
      const Digraph& _graph;
574 574
      int& _compNum;
575 575

	
576 576
      typename Digraph::template NodeMap<int> _numMap;
577 577
      typename Digraph::template NodeMap<int> _retMap;
578 578
      typename Digraph::template NodeMap<Node> _predMap;
579 579
      int _num;
580 580
    };
581 581

	
582 582
    template <typename Digraph, typename ArcMap>
583 583
    class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
584 584
    public:
585 585
      typedef typename Digraph::Node Node;
586 586
      typedef typename Digraph::Arc Arc;
587 587
      typedef typename Digraph::Edge Edge;
588 588

	
589 589
      BiNodeConnectedComponentsVisitor(const Digraph& graph,
590 590
                                       ArcMap& compMap, int &compNum)
591 591
        : _graph(graph), _compMap(compMap), _compNum(compNum),
592 592
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
593 593

	
594 594
      void start(const Node& node) {
595 595
        _predMap.set(node, INVALID);
596 596
      }
597 597

	
598 598
      void reach(const Node& node) {
599 599
        _numMap.set(node, _num);
600 600
        _retMap.set(node, _num);
601 601
        ++_num;
602 602
      }
603 603

	
604 604
      void discover(const Arc& edge) {
605 605
        Node target = _graph.target(edge);
606 606
        _predMap.set(target, edge);
607 607
        _edgeStack.push(edge);
608 608
      }
609 609

	
610 610
      void examine(const Arc& edge) {
611 611
        Node source = _graph.source(edge);
612 612
        Node target = _graph.target(edge);
613 613
        if (source == target && _graph.direction(edge)) {
614 614
          _compMap.set(edge, _compNum);
615 615
          ++_compNum;
616 616
          return;
617 617
        }
618 618
        if (_numMap[target] < _numMap[source]) {
619 619
          if (_predMap[source] != _graph.oppositeArc(edge)) {
620 620
            _edgeStack.push(edge);
621 621
          }
622 622
        }
623 623
        if (_predMap[source] != INVALID &&
624 624
            target == _graph.source(_predMap[source])) {
625 625
          return;
626 626
        }
627 627
        if (_retMap[source] > _numMap[target]) {
628 628
          _retMap.set(source, _numMap[target]);
629 629
        }
630 630
      }
631 631

	
632 632
      void backtrack(const Arc& edge) {
633 633
        Node source = _graph.source(edge);
634 634
        Node target = _graph.target(edge);
635 635
        if (_retMap[source] > _retMap[target]) {
636 636
          _retMap.set(source, _retMap[target]);
637 637
        }
638 638
        if (_numMap[source] <= _retMap[target]) {
639 639
          while (_edgeStack.top() != edge) {
640 640
            _compMap.set(_edgeStack.top(), _compNum);
641 641
            _edgeStack.pop();
642 642
          }
643 643
          _compMap.set(edge, _compNum);
644 644
          _edgeStack.pop();
645 645
          ++_compNum;
646 646
        }
647 647
      }
648 648

	
649 649
    private:
650 650
      const Digraph& _graph;
651 651
      ArcMap& _compMap;
652 652
      int& _compNum;
653 653

	
654 654
      typename Digraph::template NodeMap<int> _numMap;
655 655
      typename Digraph::template NodeMap<int> _retMap;
656 656
      typename Digraph::template NodeMap<Arc> _predMap;
657 657
      std::stack<Edge> _edgeStack;
658 658
      int _num;
659 659
    };
660 660

	
661 661

	
662 662
    template <typename Digraph, typename NodeMap>
663 663
    class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
664 664
    public:
665 665
      typedef typename Digraph::Node Node;
666 666
      typedef typename Digraph::Arc Arc;
667 667
      typedef typename Digraph::Edge Edge;
668 668

	
669 669
      BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
670 670
                                     int& cutNum)
671 671
        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
672 672
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
673 673

	
674 674
      void start(const Node& node) {
675 675
        _predMap.set(node, INVALID);
676 676
        rootCut = false;
677 677
      }
678 678

	
679 679
      void reach(const Node& node) {
680 680
        _numMap.set(node, _num);
681 681
        _retMap.set(node, _num);
682 682
        ++_num;
683 683
      }
684 684

	
685 685
      void discover(const Arc& edge) {
686 686
        _predMap.set(_graph.target(edge), _graph.source(edge));
687 687
      }
688 688

	
689 689
      void examine(const Arc& edge) {
690 690
        if (_graph.source(edge) == _graph.target(edge) &&
691 691
            _graph.direction(edge)) {
692 692
          if (!_cutMap[_graph.source(edge)]) {
693 693
            _cutMap.set(_graph.source(edge), true);
694 694
            ++_cutNum;
695 695
          }
696 696
          return;
697 697
        }
698 698
        if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
699 699
        if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
700 700
          _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
701 701
        }
702 702
      }
703 703

	
704 704
      void backtrack(const Arc& edge) {
705 705
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
706 706
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
707 707
        }
708 708
        if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
709 709
          if (_predMap[_graph.source(edge)] != INVALID) {
710 710
            if (!_cutMap[_graph.source(edge)]) {
711 711
              _cutMap.set(_graph.source(edge), true);
712 712
              ++_cutNum;
713 713
            }
714 714
          } else if (rootCut) {
715 715
            if (!_cutMap[_graph.source(edge)]) {
716 716
              _cutMap.set(_graph.source(edge), true);
717 717
              ++_cutNum;
718 718
            }
719 719
          } else {
720 720
            rootCut = true;
721 721
          }
722 722
        }
723 723
      }
724 724

	
725 725
    private:
726 726
      const Digraph& _graph;
727 727
      NodeMap& _cutMap;
728 728
      int& _cutNum;
729 729

	
730 730
      typename Digraph::template NodeMap<int> _numMap;
731 731
      typename Digraph::template NodeMap<int> _retMap;
732 732
      typename Digraph::template NodeMap<Node> _predMap;
733 733
      std::stack<Edge> _edgeStack;
734 734
      int _num;
735 735
      bool rootCut;
736 736
    };
737 737

	
738 738
  }
739 739

	
740 740
  template <typename Graph>
741 741
  int countBiNodeConnectedComponents(const Graph& graph);
742 742

	
743 743
  /// \ingroup graph_properties
744 744
  ///
745 745
  /// \brief Check whether an undirected graph is bi-node-connected.
746 746
  ///
747
  /// This function checks whether the given undirected graph is 
747
  /// This function checks whether the given undirected graph is
748 748
  /// bi-node-connected, i.e. any two edges are on same circle.
749 749
  ///
750 750
  /// \return \c true if the graph bi-node-connected.
751 751
  /// \note By definition, the empty graph is bi-node-connected.
752 752
  ///
753 753
  /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents()
754 754
  template <typename Graph>
755 755
  bool biNodeConnected(const Graph& graph) {
756 756
    return countBiNodeConnectedComponents(graph) <= 1;
757 757
  }
758 758

	
759 759
  /// \ingroup graph_properties
760 760
  ///
761
  /// \brief Count the number of bi-node-connected components of an 
761
  /// \brief Count the number of bi-node-connected components of an
762 762
  /// undirected graph.
763 763
  ///
764 764
  /// This function counts the number of bi-node-connected components of
765 765
  /// the given undirected graph.
766 766
  ///
767 767
  /// The bi-node-connected components are the classes of an equivalence
768 768
  /// relation on the edges of a undirected graph. Two edges are in the
769 769
  /// same class if they are on same circle.
770 770
  ///
771 771
  /// \return The number of bi-node-connected components.
772 772
  ///
773 773
  /// \see biNodeConnected(), biNodeConnectedComponents()
774 774
  template <typename Graph>
775 775
  int countBiNodeConnectedComponents(const Graph& graph) {
776 776
    checkConcept<concepts::Graph, Graph>();
777 777
    typedef typename Graph::NodeIt NodeIt;
778 778

	
779 779
    using namespace _connectivity_bits;
780 780

	
781 781
    typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
782 782

	
783 783
    int compNum = 0;
784 784
    Visitor visitor(graph, compNum);
785 785

	
786 786
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
787 787
    dfs.init();
788 788

	
789 789
    for (NodeIt it(graph); it != INVALID; ++it) {
790 790
      if (!dfs.reached(it)) {
791 791
        dfs.addSource(it);
792 792
        dfs.start();
793 793
      }
794 794
    }
795 795
    return compNum;
796 796
  }
797 797

	
798 798
  /// \ingroup graph_properties
799 799
  ///
800 800
  /// \brief Find the bi-node-connected components of an undirected graph.
801 801
  ///
802 802
  /// This function finds the bi-node-connected components of the given
803 803
  /// undirected graph.
804 804
  ///
805 805
  /// The bi-node-connected components are the classes of an equivalence
806 806
  /// relation on the edges of a undirected graph. Two edges are in the
807 807
  /// same class if they are on same circle.
808 808
  ///
809 809
  /// \image html node_biconnected_components.png
810 810
  /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
811 811
  ///
812 812
  /// \param graph The undirected graph.
813 813
  /// \retval compMap A writable edge map. The values will be set from 0
814 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 
815
  /// value of the map will be set exactly once, and the values of a
816 816
  /// certain component will be set continuously.
817 817
  /// \return The number of bi-node-connected components.
818 818
  ///
819 819
  /// \see biNodeConnected(), countBiNodeConnectedComponents()
820 820
  template <typename Graph, typename EdgeMap>
821 821
  int biNodeConnectedComponents(const Graph& graph,
822 822
                                EdgeMap& compMap) {
823 823
    checkConcept<concepts::Graph, Graph>();
824 824
    typedef typename Graph::NodeIt NodeIt;
825 825
    typedef typename Graph::Edge Edge;
826 826
    checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
827 827

	
828 828
    using namespace _connectivity_bits;
829 829

	
830 830
    typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
831 831

	
832 832
    int compNum = 0;
833 833
    Visitor visitor(graph, compMap, compNum);
834 834

	
835 835
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
836 836
    dfs.init();
837 837

	
838 838
    for (NodeIt it(graph); it != INVALID; ++it) {
839 839
      if (!dfs.reached(it)) {
840 840
        dfs.addSource(it);
841 841
        dfs.start();
842 842
      }
843 843
    }
844 844
    return compNum;
845 845
  }
846 846

	
847 847
  /// \ingroup graph_properties
848 848
  ///
849 849
  /// \brief Find the bi-node-connected cut nodes in an undirected graph.
850 850
  ///
851 851
  /// This function finds the bi-node-connected cut nodes in the given
852 852
  /// undirected graph.
853 853
  ///
854 854
  /// The bi-node-connected components are the classes of an equivalence
855 855
  /// relation on the edges of a undirected graph. Two edges are in the
856 856
  /// same class if they are on same circle.
857 857
  /// The bi-node-connected components are separted by the cut nodes of
858 858
  /// the components.
859 859
  ///
860 860
  /// \param graph The undirected graph.
861
  /// \retval cutMap A writable node map. The values will be set to 
861
  /// \retval cutMap A writable node map. The values will be set to
862 862
  /// \c true for the nodes that separate two or more components
863 863
  /// (exactly once for each cut node), and will not be changed for
864 864
  /// other nodes.
865 865
  /// \return The number of the cut nodes.
866 866
  ///
867 867
  /// \see biNodeConnected(), biNodeConnectedComponents()
868 868
  template <typename Graph, typename NodeMap>
869 869
  int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
870 870
    checkConcept<concepts::Graph, Graph>();
871 871
    typedef typename Graph::Node Node;
872 872
    typedef typename Graph::NodeIt NodeIt;
873 873
    checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
874 874

	
875 875
    using namespace _connectivity_bits;
876 876

	
877 877
    typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
878 878

	
879 879
    int cutNum = 0;
880 880
    Visitor visitor(graph, cutMap, cutNum);
881 881

	
882 882
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
883 883
    dfs.init();
884 884

	
885 885
    for (NodeIt it(graph); it != INVALID; ++it) {
886 886
      if (!dfs.reached(it)) {
887 887
        dfs.addSource(it);
888 888
        dfs.start();
889 889
      }
890 890
    }
891 891
    return cutNum;
892 892
  }
893 893

	
894 894
  namespace _connectivity_bits {
895 895

	
896 896
    template <typename Digraph>
897 897
    class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
898 898
    public:
899 899
      typedef typename Digraph::Node Node;
900 900
      typedef typename Digraph::Arc Arc;
901 901
      typedef typename Digraph::Edge Edge;
902 902

	
903 903
      CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
904 904
        : _graph(graph), _compNum(compNum),
905 905
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
906 906

	
907 907
      void start(const Node& node) {
908 908
        _predMap.set(node, INVALID);
909 909
      }
910 910

	
911 911
      void reach(const Node& node) {
912 912
        _numMap.set(node, _num);
913 913
        _retMap.set(node, _num);
914 914
        ++_num;
915 915
      }
916 916

	
917 917
      void leave(const Node& node) {
918 918
        if (_numMap[node] <= _retMap[node]) {
919 919
          ++_compNum;
920 920
        }
921 921
      }
922 922

	
923 923
      void discover(const Arc& edge) {
924 924
        _predMap.set(_graph.target(edge), edge);
925 925
      }
926 926

	
927 927
      void examine(const Arc& edge) {
928 928
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
929 929
          return;
930 930
        }
931 931
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
932 932
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
933 933
        }
934 934
      }
935 935

	
936 936
      void backtrack(const Arc& edge) {
937 937
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
938 938
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
939 939
        }
940 940
      }
941 941

	
942 942
    private:
943 943
      const Digraph& _graph;
944 944
      int& _compNum;
945 945

	
946 946
      typename Digraph::template NodeMap<int> _numMap;
947 947
      typename Digraph::template NodeMap<int> _retMap;
948 948
      typename Digraph::template NodeMap<Arc> _predMap;
949 949
      int _num;
950 950
    };
951 951

	
952 952
    template <typename Digraph, typename NodeMap>
953 953
    class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
954 954
    public:
955 955
      typedef typename Digraph::Node Node;
956 956
      typedef typename Digraph::Arc Arc;
957 957
      typedef typename Digraph::Edge Edge;
958 958

	
959 959
      BiEdgeConnectedComponentsVisitor(const Digraph& graph,
960 960
                                       NodeMap& compMap, int &compNum)
961 961
        : _graph(graph), _compMap(compMap), _compNum(compNum),
962 962
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
963 963

	
964 964
      void start(const Node& node) {
965 965
        _predMap.set(node, INVALID);
966 966
      }
967 967

	
968 968
      void reach(const Node& node) {
969 969
        _numMap.set(node, _num);
970 970
        _retMap.set(node, _num);
971 971
        _nodeStack.push(node);
972 972
        ++_num;
973 973
      }
974 974

	
975 975
      void leave(const Node& node) {
976 976
        if (_numMap[node] <= _retMap[node]) {
977 977
          while (_nodeStack.top() != node) {
978 978
            _compMap.set(_nodeStack.top(), _compNum);
979 979
            _nodeStack.pop();
980 980
          }
981 981
          _compMap.set(node, _compNum);
982 982
          _nodeStack.pop();
983 983
          ++_compNum;
984 984
        }
985 985
      }
986 986

	
987 987
      void discover(const Arc& edge) {
988 988
        _predMap.set(_graph.target(edge), edge);
989 989
      }
990 990

	
991 991
      void examine(const Arc& edge) {
992 992
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
993 993
          return;
994 994
        }
995 995
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
996 996
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
997 997
        }
998 998
      }
999 999

	
1000 1000
      void backtrack(const Arc& edge) {
1001 1001
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1002 1002
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1003 1003
        }
1004 1004
      }
1005 1005

	
1006 1006
    private:
1007 1007
      const Digraph& _graph;
1008 1008
      NodeMap& _compMap;
1009 1009
      int& _compNum;
1010 1010

	
1011 1011
      typename Digraph::template NodeMap<int> _numMap;
1012 1012
      typename Digraph::template NodeMap<int> _retMap;
1013 1013
      typename Digraph::template NodeMap<Arc> _predMap;
1014 1014
      std::stack<Node> _nodeStack;
1015 1015
      int _num;
1016 1016
    };
1017 1017

	
1018 1018

	
1019 1019
    template <typename Digraph, typename ArcMap>
1020 1020
    class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
1021 1021
    public:
1022 1022
      typedef typename Digraph::Node Node;
1023 1023
      typedef typename Digraph::Arc Arc;
1024 1024
      typedef typename Digraph::Edge Edge;
1025 1025

	
1026 1026
      BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
1027 1027
                                     ArcMap& cutMap, int &cutNum)
1028 1028
        : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
1029 1029
          _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
1030 1030

	
1031 1031
      void start(const Node& node) {
1032 1032
        _predMap[node] = INVALID;
1033 1033
      }
1034 1034

	
1035 1035
      void reach(const Node& node) {
1036 1036
        _numMap.set(node, _num);
1037 1037
        _retMap.set(node, _num);
1038 1038
        ++_num;
1039 1039
      }
1040 1040

	
1041 1041
      void leave(const Node& node) {
1042 1042
        if (_numMap[node] <= _retMap[node]) {
1043 1043
          if (_predMap[node] != INVALID) {
1044 1044
            _cutMap.set(_predMap[node], true);
1045 1045
            ++_cutNum;
1046 1046
          }
1047 1047
        }
1048 1048
      }
1049 1049

	
1050 1050
      void discover(const Arc& edge) {
1051 1051
        _predMap.set(_graph.target(edge), edge);
1052 1052
      }
1053 1053

	
1054 1054
      void examine(const Arc& edge) {
1055 1055
        if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
1056 1056
          return;
1057 1057
        }
1058 1058
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1059 1059
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1060 1060
        }
1061 1061
      }
1062 1062

	
1063 1063
      void backtrack(const Arc& edge) {
1064 1064
        if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
1065 1065
          _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
1066 1066
        }
1067 1067
      }
1068 1068

	
1069 1069
    private:
1070 1070
      const Digraph& _graph;
1071 1071
      ArcMap& _cutMap;
1072 1072
      int& _cutNum;
1073 1073

	
1074 1074
      typename Digraph::template NodeMap<int> _numMap;
1075 1075
      typename Digraph::template NodeMap<int> _retMap;
1076 1076
      typename Digraph::template NodeMap<Arc> _predMap;
1077 1077
      int _num;
1078 1078
    };
1079 1079
  }
1080 1080

	
1081 1081
  template <typename Graph>
1082 1082
  int countBiEdgeConnectedComponents(const Graph& graph);
1083 1083

	
1084 1084
  /// \ingroup graph_properties
1085 1085
  ///
1086 1086
  /// \brief Check whether an undirected graph is bi-edge-connected.
1087 1087
  ///
1088
  /// This function checks whether the given undirected graph is 
1088
  /// This function checks whether the given undirected graph is
1089 1089
  /// bi-edge-connected, i.e. any two nodes are connected with at least
1090 1090
  /// two edge-disjoint paths.
1091 1091
  ///
1092 1092
  /// \return \c true if the graph is bi-edge-connected.
1093 1093
  /// \note By definition, the empty graph is bi-edge-connected.
1094 1094
  ///
1095 1095
  /// \see countBiEdgeConnectedComponents(), biEdgeConnectedComponents()
1096 1096
  template <typename Graph>
1097 1097
  bool biEdgeConnected(const Graph& graph) {
1098 1098
    return countBiEdgeConnectedComponents(graph) <= 1;
1099 1099
  }
1100 1100

	
1101 1101
  /// \ingroup graph_properties
1102 1102
  ///
1103 1103
  /// \brief Count the number of bi-edge-connected components of an
1104 1104
  /// undirected graph.
1105 1105
  ///
1106 1106
  /// This function counts the number of bi-edge-connected components of
1107 1107
  /// the given undirected graph.
1108 1108
  ///
1109 1109
  /// The bi-edge-connected components are the classes of an equivalence
1110 1110
  /// relation on the nodes of an undirected graph. Two nodes are in the
1111 1111
  /// same class if they are connected with at least two edge-disjoint
1112 1112
  /// paths.
1113 1113
  ///
1114 1114
  /// \return The number of bi-edge-connected components.
1115 1115
  ///
1116 1116
  /// \see biEdgeConnected(), biEdgeConnectedComponents()
1117 1117
  template <typename Graph>
1118 1118
  int countBiEdgeConnectedComponents(const Graph& graph) {
1119 1119
    checkConcept<concepts::Graph, Graph>();
1120 1120
    typedef typename Graph::NodeIt NodeIt;
1121 1121

	
1122 1122
    using namespace _connectivity_bits;
1123 1123

	
1124 1124
    typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
1125 1125

	
1126 1126
    int compNum = 0;
1127 1127
    Visitor visitor(graph, compNum);
1128 1128

	
1129 1129
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1130 1130
    dfs.init();
1131 1131

	
1132 1132
    for (NodeIt it(graph); it != INVALID; ++it) {
1133 1133
      if (!dfs.reached(it)) {
1134 1134
        dfs.addSource(it);
1135 1135
        dfs.start();
1136 1136
      }
1137 1137
    }
1138 1138
    return compNum;
1139 1139
  }
1140 1140

	
1141 1141
  /// \ingroup graph_properties
1142 1142
  ///
1143 1143
  /// \brief Find the bi-edge-connected components of an undirected graph.
1144 1144
  ///
1145 1145
  /// This function finds the bi-edge-connected components of the given
1146 1146
  /// undirected graph.
1147 1147
  ///
1148 1148
  /// The bi-edge-connected components are the classes of an equivalence
1149 1149
  /// relation on the nodes of an undirected graph. Two nodes are in the
1150 1150
  /// same class if they are connected with at least two edge-disjoint
1151 1151
  /// paths.
1152 1152
  ///
1153 1153
  /// \image html edge_biconnected_components.png
1154 1154
  /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
1155 1155
  ///
1156 1156
  /// \param graph The undirected graph.
1157 1157
  /// \retval compMap A writable node map. The values will be set from 0 to
1158 1158
  /// the number of the bi-edge-connected components minus one. Each value
1159 1159
  /// of the map will be set exactly once, and the values of a certain
1160 1160
  /// component will be set continuously.
1161 1161
  /// \return The number of bi-edge-connected components.
1162 1162
  ///
1163 1163
  /// \see biEdgeConnected(), countBiEdgeConnectedComponents()
1164 1164
  template <typename Graph, typename NodeMap>
1165 1165
  int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
1166 1166
    checkConcept<concepts::Graph, Graph>();
1167 1167
    typedef typename Graph::NodeIt NodeIt;
1168 1168
    typedef typename Graph::Node Node;
1169 1169
    checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
1170 1170

	
1171 1171
    using namespace _connectivity_bits;
1172 1172

	
1173 1173
    typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
1174 1174

	
1175 1175
    int compNum = 0;
1176 1176
    Visitor visitor(graph, compMap, compNum);
1177 1177

	
1178 1178
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1179 1179
    dfs.init();
1180 1180

	
1181 1181
    for (NodeIt it(graph); it != INVALID; ++it) {
1182 1182
      if (!dfs.reached(it)) {
1183 1183
        dfs.addSource(it);
1184 1184
        dfs.start();
1185 1185
      }
1186 1186
    }
1187 1187
    return compNum;
1188 1188
  }
1189 1189

	
1190 1190
  /// \ingroup graph_properties
1191 1191
  ///
1192 1192
  /// \brief Find the bi-edge-connected cut edges in an undirected graph.
1193 1193
  ///
1194 1194
  /// This function finds the bi-edge-connected cut edges in the given
1195
  /// undirected graph. 
1195
  /// undirected graph.
1196 1196
  ///
1197 1197
  /// The bi-edge-connected components are the classes of an equivalence
1198 1198
  /// relation on the nodes of an undirected graph. Two nodes are in the
1199 1199
  /// same class if they are connected with at least two edge-disjoint
1200 1200
  /// paths.
1201 1201
  /// The bi-edge-connected components are separted by the cut edges of
1202 1202
  /// the components.
1203 1203
  ///
1204 1204
  /// \param graph The undirected graph.
1205 1205
  /// \retval cutMap A writable edge map. The values will be set to \c true
1206 1206
  /// for the cut edges (exactly once for each cut edge), and will not be
1207 1207
  /// changed for other edges.
1208 1208
  /// \return The number of cut edges.
1209 1209
  ///
1210 1210
  /// \see biEdgeConnected(), biEdgeConnectedComponents()
1211 1211
  template <typename Graph, typename EdgeMap>
1212 1212
  int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
1213 1213
    checkConcept<concepts::Graph, Graph>();
1214 1214
    typedef typename Graph::NodeIt NodeIt;
1215 1215
    typedef typename Graph::Edge Edge;
1216 1216
    checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
1217 1217

	
1218 1218
    using namespace _connectivity_bits;
1219 1219

	
1220 1220
    typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
1221 1221

	
1222 1222
    int cutNum = 0;
1223 1223
    Visitor visitor(graph, cutMap, cutNum);
1224 1224

	
1225 1225
    DfsVisit<Graph, Visitor> dfs(graph, visitor);
1226 1226
    dfs.init();
1227 1227

	
1228 1228
    for (NodeIt it(graph); it != INVALID; ++it) {
1229 1229
      if (!dfs.reached(it)) {
1230 1230
        dfs.addSource(it);
1231 1231
        dfs.start();
1232 1232
      }
1233 1233
    }
1234 1234
    return cutNum;
1235 1235
  }
1236 1236

	
1237 1237

	
1238 1238
  namespace _connectivity_bits {
1239 1239

	
1240 1240
    template <typename Digraph, typename IntNodeMap>
1241 1241
    class TopologicalSortVisitor : public DfsVisitor<Digraph> {
1242 1242
    public:
1243 1243
      typedef typename Digraph::Node Node;
1244 1244
      typedef typename Digraph::Arc edge;
1245 1245

	
1246 1246
      TopologicalSortVisitor(IntNodeMap& order, int num)
1247 1247
        : _order(order), _num(num) {}
1248 1248

	
1249 1249
      void leave(const Node& node) {
1250 1250
        _order.set(node, --_num);
1251 1251
      }
1252 1252

	
1253 1253
    private:
1254 1254
      IntNodeMap& _order;
1255 1255
      int _num;
1256 1256
    };
1257 1257

	
1258 1258
  }
1259 1259

	
1260 1260
  /// \ingroup graph_properties
1261 1261
  ///
1262 1262
  /// \brief Check whether a digraph is DAG.
1263 1263
  ///
1264 1264
  /// This function checks whether the given digraph is DAG, i.e.
1265 1265
  /// \e Directed \e Acyclic \e Graph.
1266 1266
  /// \return \c true if there is no directed cycle in the digraph.
1267 1267
  /// \see acyclic()
1268 1268
  template <typename Digraph>
1269 1269
  bool dag(const Digraph& digraph) {
1270 1270

	
1271 1271
    checkConcept<concepts::Digraph, Digraph>();
1272 1272

	
1273 1273
    typedef typename Digraph::Node Node;
1274 1274
    typedef typename Digraph::NodeIt NodeIt;
1275 1275
    typedef typename Digraph::Arc Arc;
1276 1276

	
1277 1277
    typedef typename Digraph::template NodeMap<bool> ProcessedMap;
1278 1278

	
1279 1279
    typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
1280 1280
      Create dfs(digraph);
1281 1281

	
1282 1282
    ProcessedMap processed(digraph);
1283 1283
    dfs.processedMap(processed);
1284 1284

	
1285 1285
    dfs.init();
1286 1286
    for (NodeIt it(digraph); it != INVALID; ++it) {
1287 1287
      if (!dfs.reached(it)) {
1288 1288
        dfs.addSource(it);
1289 1289
        while (!dfs.emptyQueue()) {
1290 1290
          Arc arc = dfs.nextArc();
1291 1291
          Node target = digraph.target(arc);
1292 1292
          if (dfs.reached(target) && !processed[target]) {
1293 1293
            return false;
1294 1294
          }
1295 1295
          dfs.processNextArc();
1296 1296
        }
1297 1297
      }
1298 1298
    }
1299 1299
    return true;
1300 1300
  }
1301 1301

	
1302 1302
  /// \ingroup graph_properties
1303 1303
  ///
1304 1304
  /// \brief Sort the nodes of a DAG into topolgical order.
1305 1305
  ///
1306 1306
  /// This function sorts the nodes of the given acyclic digraph (DAG)
1307 1307
  /// into topolgical order.
1308 1308
  ///
1309 1309
  /// \param digraph The digraph, which must be DAG.
1310 1310
  /// \retval order A writable node map. The values will be set from 0 to
1311 1311
  /// the number of the nodes in the digraph minus one. Each value of the
1312 1312
  /// map will be set exactly once, and the values will be set descending
1313 1313
  /// order.
1314 1314
  ///
1315 1315
  /// \see dag(), checkedTopologicalSort()
1316 1316
  template <typename Digraph, typename NodeMap>
1317 1317
  void topologicalSort(const Digraph& digraph, NodeMap& order) {
1318 1318
    using namespace _connectivity_bits;
1319 1319

	
1320 1320
    checkConcept<concepts::Digraph, Digraph>();
1321 1321
    checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
1322 1322

	
1323 1323
    typedef typename Digraph::Node Node;
1324 1324
    typedef typename Digraph::NodeIt NodeIt;
1325 1325
    typedef typename Digraph::Arc Arc;
1326 1326

	
1327 1327
    TopologicalSortVisitor<Digraph, NodeMap>
1328 1328
      visitor(order, countNodes(digraph));
1329 1329

	
1330 1330
    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1331 1331
      dfs(digraph, visitor);
1332 1332

	
1333 1333
    dfs.init();
1334 1334
    for (NodeIt it(digraph); it != INVALID; ++it) {
1335 1335
      if (!dfs.reached(it)) {
1336 1336
        dfs.addSource(it);
1337 1337
        dfs.start();
1338 1338
      }
1339 1339
    }
1340 1340
  }
1341 1341

	
1342 1342
  /// \ingroup graph_properties
1343 1343
  ///
1344 1344
  /// \brief Sort the nodes of a DAG into topolgical order.
1345 1345
  ///
1346 1346
  /// This function sorts the nodes of the given acyclic digraph (DAG)
1347 1347
  /// into topolgical order and also checks whether the given digraph
1348 1348
  /// is DAG.
1349 1349
  ///
1350 1350
  /// \param digraph The digraph.
1351 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. 
1352
  /// set from 0 to the number of the nodes in the digraph minus one.
1353 1353
  /// Each value of the map will be set exactly once, and the values will
1354 1354
  /// be set descending order.
1355 1355
  /// \return \c false if the digraph is not DAG.
1356 1356
  ///
1357 1357
  /// \see dag(), topologicalSort()
1358 1358
  template <typename Digraph, typename NodeMap>
1359 1359
  bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
1360 1360
    using namespace _connectivity_bits;
1361 1361

	
1362 1362
    checkConcept<concepts::Digraph, Digraph>();
1363 1363
    checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
1364 1364
      NodeMap>();
1365 1365

	
1366 1366
    typedef typename Digraph::Node Node;
1367 1367
    typedef typename Digraph::NodeIt NodeIt;
1368 1368
    typedef typename Digraph::Arc Arc;
1369 1369

	
1370 1370
    for (NodeIt it(digraph); it != INVALID; ++it) {
1371 1371
      order.set(it, -1);
1372 1372
    }
1373 1373

	
1374 1374
    TopologicalSortVisitor<Digraph, NodeMap>
1375 1375
      visitor(order, countNodes(digraph));
1376 1376

	
1377 1377
    DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
1378 1378
      dfs(digraph, visitor);
1379 1379

	
1380 1380
    dfs.init();
1381 1381
    for (NodeIt it(digraph); it != INVALID; ++it) {
1382 1382
      if (!dfs.reached(it)) {
1383 1383
        dfs.addSource(it);
1384 1384
        while (!dfs.emptyQueue()) {
1385 1385
           Arc arc = dfs.nextArc();
1386 1386
           Node target = digraph.target(arc);
1387 1387
           if (dfs.reached(target) && order[target] == -1) {
1388 1388
             return false;
1389 1389
           }
1390 1390
           dfs.processNextArc();
1391 1391
         }
1392 1392
      }
1393 1393
    }
1394 1394
    return true;
1395 1395
  }
1396 1396

	
1397 1397
  /// \ingroup graph_properties
1398 1398
  ///
1399 1399
  /// \brief Check whether an undirected graph is acyclic.
1400 1400
  ///
1401 1401
  /// This function checks whether the given undirected graph is acyclic.
1402 1402
  /// \return \c true if there is no cycle in the graph.
1403 1403
  /// \see dag()
1404 1404
  template <typename Graph>
1405 1405
  bool acyclic(const Graph& graph) {
1406 1406
    checkConcept<concepts::Graph, Graph>();
1407 1407
    typedef typename Graph::Node Node;
1408 1408
    typedef typename Graph::NodeIt NodeIt;
1409 1409
    typedef typename Graph::Arc Arc;
1410 1410
    Dfs<Graph> dfs(graph);
1411 1411
    dfs.init();
1412 1412
    for (NodeIt it(graph); it != INVALID; ++it) {
1413 1413
      if (!dfs.reached(it)) {
1414 1414
        dfs.addSource(it);
1415 1415
        while (!dfs.emptyQueue()) {
1416 1416
          Arc arc = dfs.nextArc();
1417 1417
          Node source = graph.source(arc);
1418 1418
          Node target = graph.target(arc);
1419 1419
          if (dfs.reached(target) &&
1420 1420
              dfs.predArc(source) != graph.oppositeArc(arc)) {
1421 1421
            return false;
1422 1422
          }
1423 1423
          dfs.processNextArc();
1424 1424
        }
1425 1425
      }
1426 1426
    }
1427 1427
    return true;
1428 1428
  }
1429 1429

	
1430 1430
  /// \ingroup graph_properties
1431 1431
  ///
1432 1432
  /// \brief Check whether an undirected graph is tree.
1433 1433
  ///
1434 1434
  /// This function checks whether the given undirected graph is tree.
1435 1435
  /// \return \c true if the graph is acyclic and connected.
1436 1436
  /// \see acyclic(), connected()
1437 1437
  template <typename Graph>
1438 1438
  bool tree(const Graph& graph) {
1439 1439
    checkConcept<concepts::Graph, Graph>();
1440 1440
    typedef typename Graph::Node Node;
1441 1441
    typedef typename Graph::NodeIt NodeIt;
1442 1442
    typedef typename Graph::Arc Arc;
1443 1443
    if (NodeIt(graph) == INVALID) return true;
1444 1444
    Dfs<Graph> dfs(graph);
1445 1445
    dfs.init();
1446 1446
    dfs.addSource(NodeIt(graph));
1447 1447
    while (!dfs.emptyQueue()) {
1448 1448
      Arc arc = dfs.nextArc();
1449 1449
      Node source = graph.source(arc);
1450 1450
      Node target = graph.target(arc);
1451 1451
      if (dfs.reached(target) &&
1452 1452
          dfs.predArc(source) != graph.oppositeArc(arc)) {
1453 1453
        return false;
1454 1454
      }
1455 1455
      dfs.processNextArc();
1456 1456
    }
1457 1457
    for (NodeIt it(graph); it != INVALID; ++it) {
1458 1458
      if (!dfs.reached(it)) {
1459 1459
        return false;
1460 1460
      }
1461 1461
    }
1462 1462
    return true;
1463 1463
  }
1464 1464

	
1465 1465
  namespace _connectivity_bits {
1466 1466

	
1467 1467
    template <typename Digraph>
1468 1468
    class BipartiteVisitor : public BfsVisitor<Digraph> {
1469 1469
    public:
1470 1470
      typedef typename Digraph::Arc Arc;
1471 1471
      typedef typename Digraph::Node Node;
1472 1472

	
1473 1473
      BipartiteVisitor(const Digraph& graph, bool& bipartite)
1474 1474
        : _graph(graph), _part(graph), _bipartite(bipartite) {}
1475 1475

	
1476 1476
      void start(const Node& node) {
1477 1477
        _part[node] = true;
1478 1478
      }
1479 1479
      void discover(const Arc& edge) {
1480 1480
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1481 1481
      }
1482 1482
      void examine(const Arc& edge) {
1483 1483
        _bipartite = _bipartite &&
1484 1484
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
1485 1485
      }
1486 1486

	
1487 1487
    private:
1488 1488

	
1489 1489
      const Digraph& _graph;
1490 1490
      typename Digraph::template NodeMap<bool> _part;
1491 1491
      bool& _bipartite;
1492 1492
    };
1493 1493

	
1494 1494
    template <typename Digraph, typename PartMap>
1495 1495
    class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
1496 1496
    public:
1497 1497
      typedef typename Digraph::Arc Arc;
1498 1498
      typedef typename Digraph::Node Node;
1499 1499

	
1500 1500
      BipartitePartitionsVisitor(const Digraph& graph,
1501 1501
                                 PartMap& part, bool& bipartite)
1502 1502
        : _graph(graph), _part(part), _bipartite(bipartite) {}
1503 1503

	
1504 1504
      void start(const Node& node) {
1505 1505
        _part.set(node, true);
1506 1506
      }
1507 1507
      void discover(const Arc& edge) {
1508 1508
        _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
1509 1509
      }
1510 1510
      void examine(const Arc& edge) {
1511 1511
        _bipartite = _bipartite &&
1512 1512
          _part[_graph.target(edge)] != _part[_graph.source(edge)];
1513 1513
      }
1514 1514

	
1515 1515
    private:
1516 1516

	
1517 1517
      const Digraph& _graph;
1518 1518
      PartMap& _part;
1519 1519
      bool& _bipartite;
1520 1520
    };
1521 1521
  }
1522 1522

	
1523 1523
  /// \ingroup graph_properties
1524 1524
  ///
1525 1525
  /// \brief Check whether an undirected graph is bipartite.
1526 1526
  ///
1527 1527
  /// The function checks whether the given undirected graph is bipartite.
1528 1528
  /// \return \c true if the graph is bipartite.
1529 1529
  ///
1530 1530
  /// \see bipartitePartitions()
1531 1531
  template<typename Graph>
1532 1532
  bool bipartite(const Graph &graph){
1533 1533
    using namespace _connectivity_bits;
1534 1534

	
1535 1535
    checkConcept<concepts::Graph, Graph>();
1536 1536

	
1537 1537
    typedef typename Graph::NodeIt NodeIt;
1538 1538
    typedef typename Graph::ArcIt ArcIt;
1539 1539

	
1540 1540
    bool bipartite = true;
1541 1541

	
1542 1542
    BipartiteVisitor<Graph>
1543 1543
      visitor(graph, bipartite);
1544 1544
    BfsVisit<Graph, BipartiteVisitor<Graph> >
1545 1545
      bfs(graph, visitor);
1546 1546
    bfs.init();
1547 1547
    for(NodeIt it(graph); it != INVALID; ++it) {
1548 1548
      if(!bfs.reached(it)){
1549 1549
        bfs.addSource(it);
1550 1550
        while (!bfs.emptyQueue()) {
1551 1551
          bfs.processNextNode();
1552 1552
          if (!bipartite) return false;
1553 1553
        }
1554 1554
      }
1555 1555
    }
1556 1556
    return true;
1557 1557
  }
1558 1558

	
1559 1559
  /// \ingroup graph_properties
1560 1560
  ///
1561 1561
  /// \brief Find the bipartite partitions of an undirected graph.
1562 1562
  ///
1563 1563
  /// This function checks whether the given undirected graph is bipartite
1564 1564
  /// and gives back the bipartite partitions.
1565 1565
  ///
1566 1566
  /// \image html bipartite_partitions.png
1567 1567
  /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
1568 1568
  ///
1569 1569
  /// \param graph The undirected graph.
1570 1570
  /// \retval partMap A writable node map of \c bool (or convertible) value
1571 1571
  /// type. The values will be set to \c true for one component and
1572 1572
  /// \c false for the other one.
1573 1573
  /// \return \c true if the graph is bipartite, \c false otherwise.
1574 1574
  ///
1575 1575
  /// \see bipartite()
1576 1576
  template<typename Graph, typename NodeMap>
1577 1577
  bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
1578 1578
    using namespace _connectivity_bits;
1579 1579

	
1580 1580
    checkConcept<concepts::Graph, Graph>();
1581 1581
    checkConcept<concepts::WriteMap<typename Graph::Node, bool>, NodeMap>();
1582 1582

	
1583 1583
    typedef typename Graph::Node Node;
1584 1584
    typedef typename Graph::NodeIt NodeIt;
1585 1585
    typedef typename Graph::ArcIt ArcIt;
1586 1586

	
1587 1587
    bool bipartite = true;
1588 1588

	
1589 1589
    BipartitePartitionsVisitor<Graph, NodeMap>
1590 1590
      visitor(graph, partMap, bipartite);
1591 1591
    BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
1592 1592
      bfs(graph, visitor);
1593 1593
    bfs.init();
1594 1594
    for(NodeIt it(graph); it != INVALID; ++it) {
1595 1595
      if(!bfs.reached(it)){
1596 1596
        bfs.addSource(it);
1597 1597
        while (!bfs.emptyQueue()) {
1598 1598
          bfs.processNextNode();
1599 1599
          if (!bipartite) return false;
1600 1600
        }
1601 1601
      }
1602 1602
    }
1603 1603
    return true;
1604 1604
  }
1605 1605

	
1606 1606
  /// \ingroup graph_properties
1607 1607
  ///
1608 1608
  /// \brief Check whether the given graph contains no loop arcs/edges.
1609 1609
  ///
1610 1610
  /// This function returns \c true if there are no loop arcs/edges in
1611 1611
  /// the given graph. It works for both directed and undirected graphs.
1612 1612
  template <typename Graph>
1613 1613
  bool loopFree(const Graph& graph) {
1614 1614
    for (typename Graph::ArcIt it(graph); it != INVALID; ++it) {
1615 1615
      if (graph.source(it) == graph.target(it)) return false;
1616 1616
    }
1617 1617
    return true;
1618 1618
  }
1619 1619

	
1620 1620
  /// \ingroup graph_properties
1621 1621
  ///
1622 1622
  /// \brief Check whether the given graph contains no parallel arcs/edges.
1623 1623
  ///
1624 1624
  /// This function returns \c true if there are no parallel arcs/edges in
1625 1625
  /// the given graph. It works for both directed and undirected graphs.
1626 1626
  template <typename Graph>
1627 1627
  bool parallelFree(const Graph& graph) {
1628 1628
    typename Graph::template NodeMap<int> reached(graph, 0);
1629 1629
    int cnt = 1;
1630 1630
    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1631 1631
      for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
1632 1632
        if (reached[graph.target(a)] == cnt) return false;
1633 1633
        reached[graph.target(a)] = cnt;
1634 1634
      }
1635 1635
      ++cnt;
1636 1636
    }
1637 1637
    return true;
1638 1638
  }
1639 1639

	
1640 1640
  /// \ingroup graph_properties
1641 1641
  ///
1642 1642
  /// \brief Check whether the given graph is simple.
1643 1643
  ///
1644 1644
  /// This function returns \c true if the given graph is simple, i.e.
1645 1645
  /// it contains no loop arcs/edges and no parallel arcs/edges.
1646 1646
  /// The function works for both directed and undirected graphs.
1647 1647
  /// \see loopFree(), parallelFree()
1648 1648
  template <typename Graph>
1649 1649
  bool simpleGraph(const Graph& graph) {
1650 1650
    typename Graph::template NodeMap<int> reached(graph, 0);
1651 1651
    int cnt = 1;
1652 1652
    for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
1653 1653
      reached[n] = cnt;
1654 1654
      for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
1655 1655
        if (reached[graph.target(a)] == cnt) return false;
1656 1656
        reached[graph.target(a)] = cnt;
1657 1657
      }
1658 1658
      ++cnt;
1659 1659
    }
1660 1660
    return true;
1661 1661
  }
1662 1662

	
1663 1663
} //namespace lemon
1664 1664

	
1665 1665
#endif //LEMON_CONNECTIVITY_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-2009
5
 * Copyright (C) 2003-2010
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 30
// Disable the following warnings when compiling with MSVC:
31 31
// C4250: 'class1' : inherits 'class2::member' via dominance
32 32
// C4355: 'this' : used in base member initializer list
33 33
// C4503: 'function' : decorated name length exceeded, name was truncated
34 34
// C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
35 35
// C4996: 'function': was declared deprecated
36 36
#ifdef _MSC_VER
37 37
#pragma warning( disable : 4250 4355 4503 4800 4996 )
38 38
#endif
39 39

	
40 40
///\file
41 41
///\brief LEMON core utilities.
42 42
///
43 43
///This header file contains core utilities for LEMON.
44 44
///It is automatically included by all graph types, therefore it usually
45 45
///do not have to be included directly.
46 46

	
47 47
namespace lemon {
48 48

	
49 49
  /// \brief Dummy type to make it easier to create invalid iterators.
50 50
  ///
51 51
  /// Dummy type to make it easier to create invalid iterators.
52 52
  /// See \ref INVALID for the usage.
53 53
  struct Invalid {
54 54
  public:
55 55
    bool operator==(Invalid) { return true;  }
56 56
    bool operator!=(Invalid) { return false; }
57 57
    bool operator< (Invalid) { return false; }
58 58
  };
59 59

	
60 60
  /// \brief Invalid iterators.
61 61
  ///
62 62
  /// \ref Invalid is a global type that converts to each iterator
63 63
  /// in such a way that the value of the target iterator will be invalid.
64 64
#ifdef LEMON_ONLY_TEMPLATES
65 65
  const Invalid INVALID = Invalid();
66 66
#else
67 67
  extern const Invalid INVALID;
68 68
#endif
69 69

	
70 70
  /// \addtogroup gutils
71 71
  /// @{
72 72

	
73 73
  ///Create convenience typedefs for the digraph types and iterators
74 74

	
75 75
  ///This \c \#define creates convenient type definitions for the following
76 76
  ///types of \c Digraph: \c Node,  \c NodeIt, \c Arc, \c ArcIt, \c InArcIt,
77 77
  ///\c OutArcIt, \c BoolNodeMap, \c IntNodeMap, \c DoubleNodeMap,
78 78
  ///\c BoolArcMap, \c IntArcMap, \c DoubleArcMap.
79 79
  ///
80 80
  ///\note If the graph type is a dependent type, ie. the graph type depend
81 81
  ///on a template parameter, then use \c TEMPLATE_DIGRAPH_TYPEDEFS()
82 82
  ///macro.
83 83
#define DIGRAPH_TYPEDEFS(Digraph)                                       \
84 84
  typedef Digraph::Node Node;                                           \
85 85
  typedef Digraph::NodeIt NodeIt;                                       \
86 86
  typedef Digraph::Arc Arc;                                             \
87 87
  typedef Digraph::ArcIt ArcIt;                                         \
88 88
  typedef Digraph::InArcIt InArcIt;                                     \
89 89
  typedef Digraph::OutArcIt OutArcIt;                                   \
90 90
  typedef Digraph::NodeMap<bool> BoolNodeMap;                           \
91 91
  typedef Digraph::NodeMap<int> IntNodeMap;                             \
92 92
  typedef Digraph::NodeMap<double> DoubleNodeMap;                       \
93 93
  typedef Digraph::ArcMap<bool> BoolArcMap;                             \
94 94
  typedef Digraph::ArcMap<int> IntArcMap;                               \
95 95
  typedef Digraph::ArcMap<double> DoubleArcMap
96 96

	
97 97
  ///Create convenience typedefs for the digraph types and iterators
98 98

	
99 99
  ///\see DIGRAPH_TYPEDEFS
100 100
  ///
101 101
  ///\note Use this macro, if the graph type is a dependent type,
102 102
  ///ie. the graph type depend on a template parameter.
103 103
#define TEMPLATE_DIGRAPH_TYPEDEFS(Digraph)                              \
104 104
  typedef typename Digraph::Node Node;                                  \
105 105
  typedef typename Digraph::NodeIt NodeIt;                              \
106 106
  typedef typename Digraph::Arc Arc;                                    \
107 107
  typedef typename Digraph::ArcIt ArcIt;                                \
108 108
  typedef typename Digraph::InArcIt InArcIt;                            \
109 109
  typedef typename Digraph::OutArcIt OutArcIt;                          \
110 110
  typedef typename Digraph::template NodeMap<bool> BoolNodeMap;         \
111 111
  typedef typename Digraph::template NodeMap<int> IntNodeMap;           \
112 112
  typedef typename Digraph::template NodeMap<double> DoubleNodeMap;     \
113 113
  typedef typename Digraph::template ArcMap<bool> BoolArcMap;           \
114 114
  typedef typename Digraph::template ArcMap<int> IntArcMap;             \
115 115
  typedef typename Digraph::template ArcMap<double> DoubleArcMap
116 116

	
117 117
  ///Create convenience typedefs for the graph types and iterators
118 118

	
119 119
  ///This \c \#define creates the same convenient type definitions as defined
120 120
  ///by \ref DIGRAPH_TYPEDEFS(Graph) and six more, namely it creates
121 121
  ///\c Edge, \c EdgeIt, \c IncEdgeIt, \c BoolEdgeMap, \c IntEdgeMap,
122 122
  ///\c DoubleEdgeMap.
123 123
  ///
124 124
  ///\note If the graph type is a dependent type, ie. the graph type depend
125 125
  ///on a template parameter, then use \c TEMPLATE_GRAPH_TYPEDEFS()
126 126
  ///macro.
127 127
#define GRAPH_TYPEDEFS(Graph)                                           \
128 128
  DIGRAPH_TYPEDEFS(Graph);                                              \
129 129
  typedef Graph::Edge Edge;                                             \
130 130
  typedef Graph::EdgeIt EdgeIt;                                         \
131 131
  typedef Graph::IncEdgeIt IncEdgeIt;                                   \
132 132
  typedef Graph::EdgeMap<bool> BoolEdgeMap;                             \
133 133
  typedef Graph::EdgeMap<int> IntEdgeMap;                               \
134 134
  typedef Graph::EdgeMap<double> DoubleEdgeMap
135 135

	
136 136
  ///Create convenience typedefs for the graph types and iterators
137 137

	
138 138
  ///\see GRAPH_TYPEDEFS
139 139
  ///
140 140
  ///\note Use this macro, if the graph type is a dependent type,
141 141
  ///ie. the graph type depend on a template parameter.
142 142
#define TEMPLATE_GRAPH_TYPEDEFS(Graph)                                  \
143 143
  TEMPLATE_DIGRAPH_TYPEDEFS(Graph);                                     \
144 144
  typedef typename Graph::Edge Edge;                                    \
145 145
  typedef typename Graph::EdgeIt EdgeIt;                                \
146 146
  typedef typename Graph::IncEdgeIt IncEdgeIt;                          \
147 147
  typedef typename Graph::template EdgeMap<bool> BoolEdgeMap;           \
148 148
  typedef typename Graph::template EdgeMap<int> IntEdgeMap;             \
149 149
  typedef typename Graph::template EdgeMap<double> DoubleEdgeMap
150 150

	
151 151
  /// \brief Function to count the items in a graph.
152 152
  ///
153 153
  /// This function counts the items (nodes, arcs etc.) in a graph.
154 154
  /// The complexity of the function is linear because
155 155
  /// it iterates on all of the items.
156 156
  template <typename Graph, typename Item>
157 157
  inline int countItems(const Graph& g) {
158 158
    typedef typename ItemSetTraits<Graph, Item>::ItemIt ItemIt;
159 159
    int num = 0;
160 160
    for (ItemIt it(g); it != INVALID; ++it) {
161 161
      ++num;
162 162
    }
163 163
    return num;
164 164
  }
165 165

	
166 166
  // Node counting:
167 167

	
168 168
  namespace _core_bits {
169 169

	
170 170
    template <typename Graph, typename Enable = void>
171 171
    struct CountNodesSelector {
172 172
      static int count(const Graph &g) {
173 173
        return countItems<Graph, typename Graph::Node>(g);
174 174
      }
175 175
    };
176 176

	
177 177
    template <typename Graph>
178 178
    struct CountNodesSelector<
179 179
      Graph, typename
180 180
      enable_if<typename Graph::NodeNumTag, void>::type>
181 181
    {
182 182
      static int count(const Graph &g) {
183 183
        return g.nodeNum();
184 184
      }
185 185
    };
186 186
  }
187 187

	
188 188
  /// \brief Function to count the nodes in the graph.
189 189
  ///
190 190
  /// This function counts the nodes in the graph.
191 191
  /// The complexity of the function is <em>O</em>(<em>n</em>), but for some
192 192
  /// graph structures it is specialized to run in <em>O</em>(1).
193 193
  ///
194 194
  /// \note If the graph contains a \c nodeNum() member function and a
195 195
  /// \c NodeNumTag tag then this function calls directly the member
196 196
  /// function to query the cardinality of the node set.
197 197
  template <typename Graph>
198 198
  inline int countNodes(const Graph& g) {
199 199
    return _core_bits::CountNodesSelector<Graph>::count(g);
200 200
  }
201 201

	
202 202
  // Arc counting:
203 203

	
204 204
  namespace _core_bits {
205 205

	
206 206
    template <typename Graph, typename Enable = void>
207 207
    struct CountArcsSelector {
208 208
      static int count(const Graph &g) {
209 209
        return countItems<Graph, typename Graph::Arc>(g);
210 210
      }
211 211
    };
212 212

	
213 213
    template <typename Graph>
214 214
    struct CountArcsSelector<
215 215
      Graph,
216 216
      typename enable_if<typename Graph::ArcNumTag, void>::type>
217 217
    {
218 218
      static int count(const Graph &g) {
219 219
        return g.arcNum();
220 220
      }
221 221
    };
222 222
  }
223 223

	
224 224
  /// \brief Function to count the arcs in the graph.
225 225
  ///
226 226
  /// This function counts the arcs in the graph.
227 227
  /// The complexity of the function is <em>O</em>(<em>m</em>), but for some
228 228
  /// graph structures it is specialized to run in <em>O</em>(1).
229 229
  ///
230 230
  /// \note If the graph contains a \c arcNum() member function and a
231 231
  /// \c ArcNumTag tag then this function calls directly the member
232 232
  /// function to query the cardinality of the arc set.
233 233
  template <typename Graph>
234 234
  inline int countArcs(const Graph& g) {
235 235
    return _core_bits::CountArcsSelector<Graph>::count(g);
236 236
  }
237 237

	
238 238
  // Edge counting:
239 239

	
240 240
  namespace _core_bits {
241 241

	
242 242
    template <typename Graph, typename Enable = void>
243 243
    struct CountEdgesSelector {
244 244
      static int count(const Graph &g) {
245 245
        return countItems<Graph, typename Graph::Edge>(g);
246 246
      }
247 247
    };
248 248

	
249 249
    template <typename Graph>
250 250
    struct CountEdgesSelector<
251 251
      Graph,
252 252
      typename enable_if<typename Graph::EdgeNumTag, void>::type>
253 253
    {
254 254
      static int count(const Graph &g) {
255 255
        return g.edgeNum();
256 256
      }
257 257
    };
258 258
  }
259 259

	
260 260
  /// \brief Function to count the edges in the graph.
261 261
  ///
262 262
  /// This function counts the edges in the graph.
263 263
  /// The complexity of the function is <em>O</em>(<em>m</em>), but for some
264 264
  /// graph structures it is specialized to run in <em>O</em>(1).
265 265
  ///
266 266
  /// \note If the graph contains a \c edgeNum() member function and a
267 267
  /// \c EdgeNumTag tag then this function calls directly the member
268 268
  /// function to query the cardinality of the edge set.
269 269
  template <typename Graph>
270 270
  inline int countEdges(const Graph& g) {
271 271
    return _core_bits::CountEdgesSelector<Graph>::count(g);
272 272

	
273 273
  }
274 274

	
275 275

	
276 276
  template <typename Graph, typename DegIt>
277 277
  inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) {
278 278
    int num = 0;
279 279
    for (DegIt it(_g, _n); it != INVALID; ++it) {
280 280
      ++num;
281 281
    }
282 282
    return num;
283 283
  }
284 284

	
285 285
  /// \brief Function to count the number of the out-arcs from node \c n.
286 286
  ///
287 287
  /// This function counts the number of the out-arcs from node \c n
288 288
  /// in the graph \c g.
289 289
  template <typename Graph>
290 290
  inline int countOutArcs(const Graph& g,  const typename Graph::Node& n) {
291 291
    return countNodeDegree<Graph, typename Graph::OutArcIt>(g, n);
292 292
  }
293 293

	
294 294
  /// \brief Function to count the number of the in-arcs to node \c n.
295 295
  ///
296 296
  /// This function counts the number of the in-arcs to node \c n
297 297
  /// in the graph \c g.
298 298
  template <typename Graph>
299 299
  inline int countInArcs(const Graph& g,  const typename Graph::Node& n) {
300 300
    return countNodeDegree<Graph, typename Graph::InArcIt>(g, n);
301 301
  }
302 302

	
303 303
  /// \brief Function to count the number of the inc-edges to node \c n.
304 304
  ///
305 305
  /// This function counts the number of the inc-edges to node \c n
306 306
  /// in the undirected graph \c g.
307 307
  template <typename Graph>
308 308
  inline int countIncEdges(const Graph& g,  const typename Graph::Node& n) {
309 309
    return countNodeDegree<Graph, typename Graph::IncEdgeIt>(g, n);
310 310
  }
311 311

	
312 312
  namespace _core_bits {
313 313

	
314 314
    template <typename Digraph, typename Item, typename RefMap>
315 315
    class MapCopyBase {
316 316
    public:
317 317
      virtual void copy(const Digraph& from, const RefMap& refMap) = 0;
318 318

	
319 319
      virtual ~MapCopyBase() {}
320 320
    };
321 321

	
322 322
    template <typename Digraph, typename Item, typename RefMap,
323 323
              typename FromMap, typename ToMap>
324 324
    class MapCopy : public MapCopyBase<Digraph, Item, RefMap> {
325 325
    public:
326 326

	
327 327
      MapCopy(const FromMap& map, ToMap& tmap)
328 328
        : _map(map), _tmap(tmap) {}
329 329

	
330 330
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
331 331
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
332 332
        for (ItemIt it(digraph); it != INVALID; ++it) {
333 333
          _tmap.set(refMap[it], _map[it]);
334 334
        }
335 335
      }
336 336

	
337 337
    private:
338 338
      const FromMap& _map;
339 339
      ToMap& _tmap;
340 340
    };
341 341

	
342 342
    template <typename Digraph, typename Item, typename RefMap, typename It>
343 343
    class ItemCopy : public MapCopyBase<Digraph, Item, RefMap> {
344 344
    public:
345 345

	
346 346
      ItemCopy(const Item& item, It& it) : _item(item), _it(it) {}
347 347

	
348 348
      virtual void copy(const Digraph&, const RefMap& refMap) {
349 349
        _it = refMap[_item];
350 350
      }
351 351

	
352 352
    private:
353 353
      Item _item;
354 354
      It& _it;
355 355
    };
356 356

	
357 357
    template <typename Digraph, typename Item, typename RefMap, typename Ref>
358 358
    class RefCopy : public MapCopyBase<Digraph, Item, RefMap> {
359 359
    public:
360 360

	
361 361
      RefCopy(Ref& map) : _map(map) {}
362 362

	
363 363
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
364 364
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
365 365
        for (ItemIt it(digraph); it != INVALID; ++it) {
366 366
          _map.set(it, refMap[it]);
367 367
        }
368 368
      }
369 369

	
370 370
    private:
371 371
      Ref& _map;
372 372
    };
373 373

	
374 374
    template <typename Digraph, typename Item, typename RefMap,
375 375
              typename CrossRef>
376 376
    class CrossRefCopy : public MapCopyBase<Digraph, Item, RefMap> {
377 377
    public:
378 378

	
379 379
      CrossRefCopy(CrossRef& cmap) : _cmap(cmap) {}
380 380

	
381 381
      virtual void copy(const Digraph& digraph, const RefMap& refMap) {
382 382
        typedef typename ItemSetTraits<Digraph, Item>::ItemIt ItemIt;
383 383
        for (ItemIt it(digraph); it != INVALID; ++it) {
384 384
          _cmap.set(refMap[it], it);
385 385
        }
386 386
      }
387 387

	
388 388
    private:
389 389
      CrossRef& _cmap;
390 390
    };
391 391

	
392 392
    template <typename Digraph, typename Enable = void>
393 393
    struct DigraphCopySelector {
394 394
      template <typename From, typename NodeRefMap, typename ArcRefMap>
395 395
      static void copy(const From& from, Digraph &to,
396 396
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
397 397
        to.clear();
398 398
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
399 399
          nodeRefMap[it] = to.addNode();
400 400
        }
401 401
        for (typename From::ArcIt it(from); it != INVALID; ++it) {
402 402
          arcRefMap[it] = to.addArc(nodeRefMap[from.source(it)],
403 403
                                    nodeRefMap[from.target(it)]);
404 404
        }
405 405
      }
406 406
    };
407 407

	
408 408
    template <typename Digraph>
409 409
    struct DigraphCopySelector<
410 410
      Digraph,
411 411
      typename enable_if<typename Digraph::BuildTag, void>::type>
412 412
    {
413 413
      template <typename From, typename NodeRefMap, typename ArcRefMap>
414 414
      static void copy(const From& from, Digraph &to,
415 415
                       NodeRefMap& nodeRefMap, ArcRefMap& arcRefMap) {
416 416
        to.build(from, nodeRefMap, arcRefMap);
417 417
      }
418 418
    };
419 419

	
420 420
    template <typename Graph, typename Enable = void>
421 421
    struct GraphCopySelector {
422 422
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
423 423
      static void copy(const From& from, Graph &to,
424 424
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
425 425
        to.clear();
426 426
        for (typename From::NodeIt it(from); it != INVALID; ++it) {
427 427
          nodeRefMap[it] = to.addNode();
428 428
        }
429 429
        for (typename From::EdgeIt it(from); it != INVALID; ++it) {
430 430
          edgeRefMap[it] = to.addEdge(nodeRefMap[from.u(it)],
431 431
                                      nodeRefMap[from.v(it)]);
432 432
        }
433 433
      }
434 434
    };
435 435

	
436 436
    template <typename Graph>
437 437
    struct GraphCopySelector<
438 438
      Graph,
439 439
      typename enable_if<typename Graph::BuildTag, void>::type>
440 440
    {
441 441
      template <typename From, typename NodeRefMap, typename EdgeRefMap>
442 442
      static void copy(const From& from, Graph &to,
443 443
                       NodeRefMap& nodeRefMap, EdgeRefMap& edgeRefMap) {
444 444
        to.build(from, nodeRefMap, edgeRefMap);
445 445
      }
446 446
    };
447 447

	
448 448
  }
449 449

	
450 450
  /// \brief Class to copy a digraph.
451 451
  ///
452 452
  /// Class to copy a digraph to another digraph (duplicate a digraph). The
453 453
  /// simplest way of using it is through the \c digraphCopy() function.
454 454
  ///
455 455
  /// This class not only make a copy of a digraph, but it can create
456 456
  /// references and cross references between the nodes and arcs of
457 457
  /// the two digraphs, and it can copy maps to use with the newly created
458 458
  /// digraph.
459 459
  ///
460 460
  /// To make a copy from a digraph, first an instance of DigraphCopy
461 461
  /// should be created, then the data belongs to the digraph should
462 462
  /// assigned to copy. In the end, the \c run() member should be
463 463
  /// called.
464 464
  ///
465 465
  /// The next code copies a digraph with several data:
466 466
  ///\code
467 467
  ///  DigraphCopy<OrigGraph, NewGraph> cg(orig_graph, new_graph);
468 468
  ///  // Create references for the nodes
469 469
  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
470 470
  ///  cg.nodeRef(nr);
471 471
  ///  // Create cross references (inverse) for the arcs
472 472
  ///  NewGraph::ArcMap<OrigGraph::Arc> acr(new_graph);
473 473
  ///  cg.arcCrossRef(acr);
474 474
  ///  // Copy an arc map
475 475
  ///  OrigGraph::ArcMap<double> oamap(orig_graph);
476 476
  ///  NewGraph::ArcMap<double> namap(new_graph);
477 477
  ///  cg.arcMap(oamap, namap);
478 478
  ///  // Copy a node
479 479
  ///  OrigGraph::Node on;
480 480
  ///  NewGraph::Node nn;
481 481
  ///  cg.node(on, nn);
482 482
  ///  // Execute copying
483 483
  ///  cg.run();
484 484
  ///\endcode
485 485
  template <typename From, typename To>
486 486
  class DigraphCopy {
487 487
  private:
488 488

	
489 489
    typedef typename From::Node Node;
490 490
    typedef typename From::NodeIt NodeIt;
491 491
    typedef typename From::Arc Arc;
492 492
    typedef typename From::ArcIt ArcIt;
493 493

	
494 494
    typedef typename To::Node TNode;
495 495
    typedef typename To::Arc TArc;
496 496

	
497 497
    typedef typename From::template NodeMap<TNode> NodeRefMap;
498 498
    typedef typename From::template ArcMap<TArc> ArcRefMap;
499 499

	
500 500
  public:
501 501

	
502 502
    /// \brief Constructor of DigraphCopy.
503 503
    ///
504 504
    /// Constructor of DigraphCopy for copying the content of the
505 505
    /// \c from digraph into the \c to digraph.
506 506
    DigraphCopy(const From& from, To& to)
507 507
      : _from(from), _to(to) {}
508 508

	
509 509
    /// \brief Destructor of DigraphCopy
510 510
    ///
511 511
    /// Destructor of DigraphCopy.
512 512
    ~DigraphCopy() {
513 513
      for (int i = 0; i < int(_node_maps.size()); ++i) {
514 514
        delete _node_maps[i];
515 515
      }
516 516
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
517 517
        delete _arc_maps[i];
518 518
      }
519 519

	
520 520
    }
521 521

	
522 522
    /// \brief Copy the node references into the given map.
523 523
    ///
524 524
    /// This function copies the node references into the given map.
525 525
    /// The parameter should be a map, whose key type is the Node type of
526 526
    /// the source digraph, while the value type is the Node type of the
527 527
    /// destination digraph.
528 528
    template <typename NodeRef>
529 529
    DigraphCopy& nodeRef(NodeRef& map) {
530 530
      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
531 531
                           NodeRefMap, NodeRef>(map));
532 532
      return *this;
533 533
    }
534 534

	
535 535
    /// \brief Copy the node cross references into the given map.
536 536
    ///
537 537
    /// This function copies the node cross references (reverse references)
538 538
    /// into the given map. The parameter should be a map, whose key type
539 539
    /// is the Node type of the destination digraph, while the value type is
540 540
    /// the Node type of the source digraph.
541 541
    template <typename NodeCrossRef>
542 542
    DigraphCopy& nodeCrossRef(NodeCrossRef& map) {
543 543
      _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node,
544 544
                           NodeRefMap, NodeCrossRef>(map));
545 545
      return *this;
546 546
    }
547 547

	
548 548
    /// \brief Make a copy of the given node map.
549 549
    ///
550 550
    /// This function makes a copy of the given node map for the newly
551 551
    /// created digraph.
552 552
    /// The key type of the new map \c tmap should be the Node type of the
553 553
    /// destination digraph, and the key type of the original map \c map
554 554
    /// should be the Node type of the source digraph.
555 555
    template <typename FromMap, typename ToMap>
556 556
    DigraphCopy& nodeMap(const FromMap& map, ToMap& tmap) {
557 557
      _node_maps.push_back(new _core_bits::MapCopy<From, Node,
558 558
                           NodeRefMap, FromMap, ToMap>(map, tmap));
559 559
      return *this;
560 560
    }
561 561

	
562 562
    /// \brief Make a copy of the given node.
563 563
    ///
564 564
    /// This function makes a copy of the given node.
565 565
    DigraphCopy& node(const Node& node, TNode& tnode) {
566 566
      _node_maps.push_back(new _core_bits::ItemCopy<From, Node,
567 567
                           NodeRefMap, TNode>(node, tnode));
568 568
      return *this;
569 569
    }
570 570

	
571 571
    /// \brief Copy the arc references into the given map.
572 572
    ///
573 573
    /// This function copies the arc references into the given map.
574 574
    /// The parameter should be a map, whose key type is the Arc type of
575 575
    /// the source digraph, while the value type is the Arc type of the
576 576
    /// destination digraph.
577 577
    template <typename ArcRef>
578 578
    DigraphCopy& arcRef(ArcRef& map) {
579 579
      _arc_maps.push_back(new _core_bits::RefCopy<From, Arc,
580 580
                          ArcRefMap, ArcRef>(map));
581 581
      return *this;
582 582
    }
583 583

	
584 584
    /// \brief Copy the arc cross references into the given map.
585 585
    ///
586 586
    /// This function copies the arc cross references (reverse references)
587 587
    /// into the given map. The parameter should be a map, whose key type
588 588
    /// is the Arc type of the destination digraph, while the value type is
589 589
    /// the Arc type of the source digraph.
590 590
    template <typename ArcCrossRef>
591 591
    DigraphCopy& arcCrossRef(ArcCrossRef& map) {
592 592
      _arc_maps.push_back(new _core_bits::CrossRefCopy<From, Arc,
593 593
                          ArcRefMap, ArcCrossRef>(map));
594 594
      return *this;
595 595
    }
596 596

	
597 597
    /// \brief Make a copy of the given arc map.
598 598
    ///
599 599
    /// This function makes a copy of the given arc map for the newly
600 600
    /// created digraph.
601 601
    /// The key type of the new map \c tmap should be the Arc type of the
602 602
    /// destination digraph, and the key type of the original map \c map
603 603
    /// should be the Arc type of the source digraph.
604 604
    template <typename FromMap, typename ToMap>
605 605
    DigraphCopy& arcMap(const FromMap& map, ToMap& tmap) {
606 606
      _arc_maps.push_back(new _core_bits::MapCopy<From, Arc,
607 607
                          ArcRefMap, FromMap, ToMap>(map, tmap));
608 608
      return *this;
609 609
    }
610 610

	
611 611
    /// \brief Make a copy of the given arc.
612 612
    ///
613 613
    /// This function makes a copy of the given arc.
614 614
    DigraphCopy& arc(const Arc& arc, TArc& tarc) {
615 615
      _arc_maps.push_back(new _core_bits::ItemCopy<From, Arc,
616 616
                          ArcRefMap, TArc>(arc, tarc));
617 617
      return *this;
618 618
    }
619 619

	
620 620
    /// \brief Execute copying.
621 621
    ///
622 622
    /// This function executes the copying of the digraph along with the
623 623
    /// copying of the assigned data.
624 624
    void run() {
625 625
      NodeRefMap nodeRefMap(_from);
626 626
      ArcRefMap arcRefMap(_from);
627 627
      _core_bits::DigraphCopySelector<To>::
628 628
        copy(_from, _to, nodeRefMap, arcRefMap);
629 629
      for (int i = 0; i < int(_node_maps.size()); ++i) {
630 630
        _node_maps[i]->copy(_from, nodeRefMap);
631 631
      }
632 632
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
633 633
        _arc_maps[i]->copy(_from, arcRefMap);
634 634
      }
635 635
    }
636 636

	
637 637
  protected:
638 638

	
639 639
    const From& _from;
640 640
    To& _to;
641 641

	
642 642
    std::vector<_core_bits::MapCopyBase<From, Node, NodeRefMap>* >
643 643
      _node_maps;
644 644

	
645 645
    std::vector<_core_bits::MapCopyBase<From, Arc, ArcRefMap>* >
646 646
      _arc_maps;
647 647

	
648 648
  };
649 649

	
650 650
  /// \brief Copy a digraph to another digraph.
651 651
  ///
652 652
  /// This function copies a digraph to another digraph.
653 653
  /// The complete usage of it is detailed in the DigraphCopy class, but
654 654
  /// a short example shows a basic work:
655 655
  ///\code
656 656
  /// digraphCopy(src, trg).nodeRef(nr).arcCrossRef(acr).run();
657 657
  ///\endcode
658 658
  ///
659 659
  /// After the copy the \c nr map will contain the mapping from the
660 660
  /// nodes of the \c from digraph to the nodes of the \c to digraph and
661 661
  /// \c acr will contain the mapping from the arcs of the \c to digraph
662 662
  /// to the arcs of the \c from digraph.
663 663
  ///
664 664
  /// \see DigraphCopy
665 665
  template <typename From, typename To>
666 666
  DigraphCopy<From, To> digraphCopy(const From& from, To& to) {
667 667
    return DigraphCopy<From, To>(from, to);
668 668
  }
669 669

	
670 670
  /// \brief Class to copy a graph.
671 671
  ///
672 672
  /// Class to copy a graph to another graph (duplicate a graph). The
673 673
  /// simplest way of using it is through the \c graphCopy() function.
674 674
  ///
675 675
  /// This class not only make a copy of a graph, but it can create
676 676
  /// references and cross references between the nodes, edges and arcs of
677 677
  /// the two graphs, and it can copy maps for using with the newly created
678 678
  /// graph.
679 679
  ///
680 680
  /// To make a copy from a graph, first an instance of GraphCopy
681 681
  /// should be created, then the data belongs to the graph should
682 682
  /// assigned to copy. In the end, the \c run() member should be
683 683
  /// called.
684 684
  ///
685 685
  /// The next code copies a graph with several data:
686 686
  ///\code
687 687
  ///  GraphCopy<OrigGraph, NewGraph> cg(orig_graph, new_graph);
688 688
  ///  // Create references for the nodes
689 689
  ///  OrigGraph::NodeMap<NewGraph::Node> nr(orig_graph);
690 690
  ///  cg.nodeRef(nr);
691 691
  ///  // Create cross references (inverse) for the edges
692 692
  ///  NewGraph::EdgeMap<OrigGraph::Edge> ecr(new_graph);
693 693
  ///  cg.edgeCrossRef(ecr);
694 694
  ///  // Copy an edge map
695 695
  ///  OrigGraph::EdgeMap<double> oemap(orig_graph);
696 696
  ///  NewGraph::EdgeMap<double> nemap(new_graph);
697 697
  ///  cg.edgeMap(oemap, nemap);
698 698
  ///  // Copy a node
699 699
  ///  OrigGraph::Node on;
700 700
  ///  NewGraph::Node nn;
701 701
  ///  cg.node(on, nn);
702 702
  ///  // Execute copying
703 703
  ///  cg.run();
704 704
  ///\endcode
705 705
  template <typename From, typename To>
706 706
  class GraphCopy {
707 707
  private:
708 708

	
709 709
    typedef typename From::Node Node;
710 710
    typedef typename From::NodeIt NodeIt;
711 711
    typedef typename From::Arc Arc;
712 712
    typedef typename From::ArcIt ArcIt;
713 713
    typedef typename From::Edge Edge;
714 714
    typedef typename From::EdgeIt EdgeIt;
715 715

	
716 716
    typedef typename To::Node TNode;
717 717
    typedef typename To::Arc TArc;
718 718
    typedef typename To::Edge TEdge;
719 719

	
720 720
    typedef typename From::template NodeMap<TNode> NodeRefMap;
721 721
    typedef typename From::template EdgeMap<TEdge> EdgeRefMap;
722 722

	
723 723
    struct ArcRefMap {
724 724
      ArcRefMap(const From& from, const To& to,
725 725
                const EdgeRefMap& edge_ref, const NodeRefMap& node_ref)
726 726
        : _from(from), _to(to),
727 727
          _edge_ref(edge_ref), _node_ref(node_ref) {}
728 728

	
729 729
      typedef typename From::Arc Key;
730 730
      typedef typename To::Arc Value;
731 731

	
732 732
      Value operator[](const Key& key) const {
733 733
        bool forward = _from.u(key) != _from.v(key) ?
734 734
          _node_ref[_from.source(key)] ==
735 735
          _to.source(_to.direct(_edge_ref[key], true)) :
736 736
          _from.direction(key);
737 737
        return _to.direct(_edge_ref[key], forward);
738 738
      }
739 739

	
740 740
      const From& _from;
741 741
      const To& _to;
742 742
      const EdgeRefMap& _edge_ref;
743 743
      const NodeRefMap& _node_ref;
744 744
    };
745 745

	
746 746
  public:
747 747

	
748 748
    /// \brief Constructor of GraphCopy.
749 749
    ///
750 750
    /// Constructor of GraphCopy for copying the content of the
751 751
    /// \c from graph into the \c to graph.
752 752
    GraphCopy(const From& from, To& to)
753 753
      : _from(from), _to(to) {}
754 754

	
755 755
    /// \brief Destructor of GraphCopy
756 756
    ///
757 757
    /// Destructor of GraphCopy.
758 758
    ~GraphCopy() {
759 759
      for (int i = 0; i < int(_node_maps.size()); ++i) {
760 760
        delete _node_maps[i];
761 761
      }
762 762
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
763 763
        delete _arc_maps[i];
764 764
      }
765 765
      for (int i = 0; i < int(_edge_maps.size()); ++i) {
766 766
        delete _edge_maps[i];
767 767
      }
768 768
    }
769 769

	
770 770
    /// \brief Copy the node references into the given map.
771 771
    ///
772 772
    /// This function copies the node references into the given map.
773 773
    /// The parameter should be a map, whose key type is the Node type of
774 774
    /// the source graph, while the value type is the Node type of the
775 775
    /// destination graph.
776 776
    template <typename NodeRef>
777 777
    GraphCopy& nodeRef(NodeRef& map) {
778 778
      _node_maps.push_back(new _core_bits::RefCopy<From, Node,
779 779
                           NodeRefMap, NodeRef>(map));
780 780
      return *this;
781 781
    }
782 782

	
783 783
    /// \brief Copy the node cross references into the given map.
784 784
    ///
785 785
    /// This function copies the node cross references (reverse references)
786 786
    /// into the given map. The parameter should be a map, whose key type
787 787
    /// is the Node type of the destination graph, while the value type is
788 788
    /// the Node type of the source graph.
789 789
    template <typename NodeCrossRef>
790 790
    GraphCopy& nodeCrossRef(NodeCrossRef& map) {
791 791
      _node_maps.push_back(new _core_bits::CrossRefCopy<From, Node,
792 792
                           NodeRefMap, NodeCrossRef>(map));
793 793
      return *this;
794 794
    }
795 795

	
796 796
    /// \brief Make a copy of the given node map.
797 797
    ///
798 798
    /// This function makes a copy of the given node map for the newly
799 799
    /// created graph.
800 800
    /// The key type of the new map \c tmap should be the Node type of the
801 801
    /// destination graph, and the key type of the original map \c map
802 802
    /// should be the Node type of the source graph.
803 803
    template <typename FromMap, typename ToMap>
804 804
    GraphCopy& nodeMap(const FromMap& map, ToMap& tmap) {
805 805
      _node_maps.push_back(new _core_bits::MapCopy<From, Node,
806 806
                           NodeRefMap, FromMap, ToMap>(map, tmap));
807 807
      return *this;
808 808
    }
809 809

	
810 810
    /// \brief Make a copy of the given node.
811 811
    ///
812 812
    /// This function makes a copy of the given node.
813 813
    GraphCopy& node(const Node& node, TNode& tnode) {
814 814
      _node_maps.push_back(new _core_bits::ItemCopy<From, Node,
815 815
                           NodeRefMap, TNode>(node, tnode));
816 816
      return *this;
817 817
    }
818 818

	
819 819
    /// \brief Copy the arc references into the given map.
820 820
    ///
821 821
    /// This function copies the arc references into the given map.
822 822
    /// The parameter should be a map, whose key type is the Arc type of
823 823
    /// the source graph, while the value type is the Arc type of the
824 824
    /// destination graph.
825 825
    template <typename ArcRef>
826 826
    GraphCopy& arcRef(ArcRef& map) {
827 827
      _arc_maps.push_back(new _core_bits::RefCopy<From, Arc,
828 828
                          ArcRefMap, ArcRef>(map));
829 829
      return *this;
830 830
    }
831 831

	
832 832
    /// \brief Copy the arc cross references into the given map.
833 833
    ///
834 834
    /// This function copies the arc cross references (reverse references)
835 835
    /// into the given map. The parameter should be a map, whose key type
836 836
    /// is the Arc type of the destination graph, while the value type is
837 837
    /// the Arc type of the source graph.
838 838
    template <typename ArcCrossRef>
839 839
    GraphCopy& arcCrossRef(ArcCrossRef& map) {
840 840
      _arc_maps.push_back(new _core_bits::CrossRefCopy<From, Arc,
841 841
                          ArcRefMap, ArcCrossRef>(map));
842 842
      return *this;
843 843
    }
844 844

	
845 845
    /// \brief Make a copy of the given arc map.
846 846
    ///
847 847
    /// This function makes a copy of the given arc map for the newly
848 848
    /// created graph.
849 849
    /// The key type of the new map \c tmap should be the Arc type of the
850 850
    /// destination graph, and the key type of the original map \c map
851 851
    /// should be the Arc type of the source graph.
852 852
    template <typename FromMap, typename ToMap>
853 853
    GraphCopy& arcMap(const FromMap& map, ToMap& tmap) {
854 854
      _arc_maps.push_back(new _core_bits::MapCopy<From, Arc,
855 855
                          ArcRefMap, FromMap, ToMap>(map, tmap));
856 856
      return *this;
857 857
    }
858 858

	
859 859
    /// \brief Make a copy of the given arc.
860 860
    ///
861 861
    /// This function makes a copy of the given arc.
862 862
    GraphCopy& arc(const Arc& arc, TArc& tarc) {
863 863
      _arc_maps.push_back(new _core_bits::ItemCopy<From, Arc,
864 864
                          ArcRefMap, TArc>(arc, tarc));
865 865
      return *this;
866 866
    }
867 867

	
868 868
    /// \brief Copy the edge references into the given map.
869 869
    ///
870 870
    /// This function copies the edge references into the given map.
871 871
    /// The parameter should be a map, whose key type is the Edge type of
872 872
    /// the source graph, while the value type is the Edge type of the
873 873
    /// destination graph.
874 874
    template <typename EdgeRef>
875 875
    GraphCopy& edgeRef(EdgeRef& map) {
876 876
      _edge_maps.push_back(new _core_bits::RefCopy<From, Edge,
877 877
                           EdgeRefMap, EdgeRef>(map));
878 878
      return *this;
879 879
    }
880 880

	
881 881
    /// \brief Copy the edge cross references into the given map.
882 882
    ///
883 883
    /// This function copies the edge cross references (reverse references)
884 884
    /// into the given map. The parameter should be a map, whose key type
885 885
    /// is the Edge type of the destination graph, while the value type is
886 886
    /// the Edge type of the source graph.
887 887
    template <typename EdgeCrossRef>
888 888
    GraphCopy& edgeCrossRef(EdgeCrossRef& map) {
889 889
      _edge_maps.push_back(new _core_bits::CrossRefCopy<From,
890 890
                           Edge, EdgeRefMap, EdgeCrossRef>(map));
891 891
      return *this;
892 892
    }
893 893

	
894 894
    /// \brief Make a copy of the given edge map.
895 895
    ///
896 896
    /// This function makes a copy of the given edge map for the newly
897 897
    /// created graph.
898 898
    /// The key type of the new map \c tmap should be the Edge type of the
899 899
    /// destination graph, and the key type of the original map \c map
900 900
    /// should be the Edge type of the source graph.
901 901
    template <typename FromMap, typename ToMap>
902 902
    GraphCopy& edgeMap(const FromMap& map, ToMap& tmap) {
903 903
      _edge_maps.push_back(new _core_bits::MapCopy<From, Edge,
904 904
                           EdgeRefMap, FromMap, ToMap>(map, tmap));
905 905
      return *this;
906 906
    }
907 907

	
908 908
    /// \brief Make a copy of the given edge.
909 909
    ///
910 910
    /// This function makes a copy of the given edge.
911 911
    GraphCopy& edge(const Edge& edge, TEdge& tedge) {
912 912
      _edge_maps.push_back(new _core_bits::ItemCopy<From, Edge,
913 913
                           EdgeRefMap, TEdge>(edge, tedge));
914 914
      return *this;
915 915
    }
916 916

	
917 917
    /// \brief Execute copying.
918 918
    ///
919 919
    /// This function executes the copying of the graph along with the
920 920
    /// copying of the assigned data.
921 921
    void run() {
922 922
      NodeRefMap nodeRefMap(_from);
923 923
      EdgeRefMap edgeRefMap(_from);
924 924
      ArcRefMap arcRefMap(_from, _to, edgeRefMap, nodeRefMap);
925 925
      _core_bits::GraphCopySelector<To>::
926 926
        copy(_from, _to, nodeRefMap, edgeRefMap);
927 927
      for (int i = 0; i < int(_node_maps.size()); ++i) {
928 928
        _node_maps[i]->copy(_from, nodeRefMap);
929 929
      }
930 930
      for (int i = 0; i < int(_edge_maps.size()); ++i) {
931 931
        _edge_maps[i]->copy(_from, edgeRefMap);
932 932
      }
933 933
      for (int i = 0; i < int(_arc_maps.size()); ++i) {
934 934
        _arc_maps[i]->copy(_from, arcRefMap);
935 935
      }
936 936
    }
937 937

	
938 938
  private:
939 939

	
940 940
    const From& _from;
941 941
    To& _to;
942 942

	
943 943
    std::vector<_core_bits::MapCopyBase<From, Node, NodeRefMap>* >
944 944
      _node_maps;
945 945

	
946 946
    std::vector<_core_bits::MapCopyBase<From, Arc, ArcRefMap>* >
947 947
      _arc_maps;
948 948

	
949 949
    std::vector<_core_bits::MapCopyBase<From, Edge, EdgeRefMap>* >
950 950
      _edge_maps;
951 951

	
952 952
  };
953 953

	
954 954
  /// \brief Copy a graph to another graph.
955 955
  ///
956 956
  /// This function copies a graph to another graph.
957 957
  /// The complete usage of it is detailed in the GraphCopy class,
958 958
  /// but a short example shows a basic work:
959 959
  ///\code
960 960
  /// graphCopy(src, trg).nodeRef(nr).edgeCrossRef(ecr).run();
961 961
  ///\endcode
962 962
  ///
963 963
  /// After the copy the \c nr map will contain the mapping from the
964 964
  /// nodes of the \c from graph to the nodes of the \c to graph and
965 965
  /// \c ecr will contain the mapping from the edges of the \c to graph
966 966
  /// to the edges of the \c from graph.
967 967
  ///
968 968
  /// \see GraphCopy
969 969
  template <typename From, typename To>
970 970
  GraphCopy<From, To>
971 971
  graphCopy(const From& from, To& to) {
972 972
    return GraphCopy<From, To>(from, to);
973 973
  }
974 974

	
975 975
  namespace _core_bits {
976 976

	
977 977
    template <typename Graph, typename Enable = void>
978 978
    struct FindArcSelector {
979 979
      typedef typename Graph::Node Node;
980 980
      typedef typename Graph::Arc Arc;
981 981
      static Arc find(const Graph &g, Node u, Node v, Arc e) {
982 982
        if (e == INVALID) {
983 983
          g.firstOut(e, u);
984 984
        } else {
985 985
          g.nextOut(e);
986 986
        }
987 987
        while (e != INVALID && g.target(e) != v) {
988 988
          g.nextOut(e);
989 989
        }
990 990
        return e;
991 991
      }
992 992
    };
993 993

	
994 994
    template <typename Graph>
995 995
    struct FindArcSelector<
996 996
      Graph,
997 997
      typename enable_if<typename Graph::FindArcTag, void>::type>
998 998
    {
999 999
      typedef typename Graph::Node Node;
1000 1000
      typedef typename Graph::Arc Arc;
1001 1001
      static Arc find(const Graph &g, Node u, Node v, Arc prev) {
1002 1002
        return g.findArc(u, v, prev);
1003 1003
      }
1004 1004
    };
1005 1005
  }
1006 1006

	
1007 1007
  /// \brief Find an arc between two nodes of a digraph.
1008 1008
  ///
1009 1009
  /// This function finds an arc from node \c u to node \c v in the
1010 1010
  /// digraph \c g.
1011 1011
  ///
1012 1012
  /// If \c prev is \ref INVALID (this is the default value), then
1013 1013
  /// it finds the first arc from \c u to \c v. Otherwise it looks for
1014 1014
  /// the next arc from \c u to \c v after \c prev.
1015 1015
  /// \return The found arc or \ref INVALID if there is no such an arc.
1016 1016
  ///
1017 1017
  /// Thus you can iterate through each arc from \c u to \c v as it follows.
1018 1018
  ///\code
1019 1019
  /// for(Arc e = findArc(g,u,v); e != INVALID; e = findArc(g,u,v,e)) {
1020 1020
  ///   ...
1021 1021
  /// }
1022 1022
  ///\endcode
1023 1023
  ///
1024 1024
  /// \note \ref ConArcIt provides iterator interface for the same
1025 1025
  /// functionality.
1026 1026
  ///
1027 1027
  ///\sa ConArcIt
1028 1028
  ///\sa ArcLookUp, AllArcLookUp, DynArcLookUp
1029 1029
  template <typename Graph>
1030 1030
  inline typename Graph::Arc
1031 1031
  findArc(const Graph &g, typename Graph::Node u, typename Graph::Node v,
1032 1032
          typename Graph::Arc prev = INVALID) {
1033 1033
    return _core_bits::FindArcSelector<Graph>::find(g, u, v, prev);
1034 1034
  }
1035 1035

	
1036 1036
  /// \brief Iterator for iterating on parallel arcs connecting the same nodes.
1037 1037
  ///
1038 1038
  /// Iterator for iterating on parallel arcs connecting the same nodes. It is
1039 1039
  /// a higher level interface for the \ref findArc() function. You can
1040 1040
  /// use it the following way:
1041 1041
  ///\code
1042 1042
  /// for (ConArcIt<Graph> it(g, src, trg); it != INVALID; ++it) {
1043 1043
  ///   ...
1044 1044
  /// }
1045 1045
  ///\endcode
1046 1046
  ///
1047 1047
  ///\sa findArc()
1048 1048
  ///\sa ArcLookUp, AllArcLookUp, DynArcLookUp
1049 1049
  template <typename GR>
1050 1050
  class ConArcIt : public GR::Arc {
1051 1051
    typedef typename GR::Arc Parent;
1052 1052

	
1053 1053
  public:
1054 1054

	
1055 1055
    typedef typename GR::Arc Arc;
1056 1056
    typedef typename GR::Node Node;
1057 1057

	
1058 1058
    /// \brief Constructor.
1059 1059
    ///
1060 1060
    /// Construct a new ConArcIt iterating on the arcs that
1061 1061
    /// connects nodes \c u and \c v.
1062 1062
    ConArcIt(const GR& g, Node u, Node v) : _graph(g) {
1063 1063
      Parent::operator=(findArc(_graph, u, v));
1064 1064
    }
1065 1065

	
1066 1066
    /// \brief Constructor.
1067 1067
    ///
1068 1068
    /// Construct a new ConArcIt that continues the iterating from arc \c a.
1069 1069
    ConArcIt(const GR& g, Arc a) : Parent(a), _graph(g) {}
1070 1070

	
1071 1071
    /// \brief Increment operator.
1072 1072
    ///
1073 1073
    /// It increments the iterator and gives back the next arc.
1074 1074
    ConArcIt& operator++() {
1075 1075
      Parent::operator=(findArc(_graph, _graph.source(*this),
1076 1076
                                _graph.target(*this), *this));
1077 1077
      return *this;
1078 1078
    }
1079 1079
  private:
1080 1080
    const GR& _graph;
1081 1081
  };
1082 1082

	
1083 1083
  namespace _core_bits {
1084 1084

	
1085 1085
    template <typename Graph, typename Enable = void>
1086 1086
    struct FindEdgeSelector {
1087 1087
      typedef typename Graph::Node Node;
1088 1088
      typedef typename Graph::Edge Edge;
1089 1089
      static Edge find(const Graph &g, Node u, Node v, Edge e) {
1090 1090
        bool b;
1091 1091
        if (u != v) {
1092 1092
          if (e == INVALID) {
1093 1093
            g.firstInc(e, b, u);
1094 1094
          } else {
1095 1095
            b = g.u(e) == u;
1096 1096
            g.nextInc(e, b);
1097 1097
          }
1098 1098
          while (e != INVALID && (b ? g.v(e) : g.u(e)) != v) {
1099 1099
            g.nextInc(e, b);
1100 1100
          }
1101 1101
        } else {
1102 1102
          if (e == INVALID) {
1103 1103
            g.firstInc(e, b, u);
1104 1104
          } else {
1105 1105
            b = true;
1106 1106
            g.nextInc(e, b);
1107 1107
          }
1108 1108
          while (e != INVALID && (!b || g.v(e) != v)) {
1109 1109
            g.nextInc(e, b);
1110 1110
          }
1111 1111
        }
1112 1112
        return e;
1113 1113
      }
1114 1114
    };
1115 1115

	
1116 1116
    template <typename Graph>
1117 1117
    struct FindEdgeSelector<
1118 1118
      Graph,
1119 1119
      typename enable_if<typename Graph::FindEdgeTag, void>::type>
1120 1120
    {
1121 1121
      typedef typename Graph::Node Node;
1122 1122
      typedef typename Graph::Edge Edge;
1123 1123
      static Edge find(const Graph &g, Node u, Node v, Edge prev) {
1124 1124
        return g.findEdge(u, v, prev);
1125 1125
      }
1126 1126
    };
1127 1127
  }
1128 1128

	
1129 1129
  /// \brief Find an edge between two nodes of a graph.
1130 1130
  ///
1131 1131
  /// This function finds an edge from node \c u to node \c v in graph \c g.
1132 1132
  /// If node \c u and node \c v is equal then each loop edge
1133 1133
  /// will be enumerated once.
1134 1134
  ///
1135 1135
  /// If \c prev is \ref INVALID (this is the default value), then
1136 1136
  /// it finds the first edge from \c u to \c v. Otherwise it looks for
1137 1137
  /// the next edge from \c u to \c v after \c prev.
1138 1138
  /// \return The found edge or \ref INVALID if there is no such an edge.
1139 1139
  ///
1140 1140
  /// Thus you can iterate through each edge between \c u and \c v
1141 1141
  /// as it follows.
1142 1142
  ///\code
1143 1143
  /// for(Edge e = findEdge(g,u,v); e != INVALID; e = findEdge(g,u,v,e)) {
1144 1144
  ///   ...
1145 1145
  /// }
1146 1146
  ///\endcode
1147 1147
  ///
1148 1148
  /// \note \ref ConEdgeIt provides iterator interface for the same
1149 1149
  /// functionality.
1150 1150
  ///
1151 1151
  ///\sa ConEdgeIt
1152 1152
  template <typename Graph>
1153 1153
  inline typename Graph::Edge
1154 1154
  findEdge(const Graph &g, typename Graph::Node u, typename Graph::Node v,
1155 1155
            typename Graph::Edge p = INVALID) {
1156 1156
    return _core_bits::FindEdgeSelector<Graph>::find(g, u, v, p);
1157 1157
  }
1158 1158

	
1159 1159
  /// \brief Iterator for iterating on parallel edges connecting the same nodes.
1160 1160
  ///
1161 1161
  /// Iterator for iterating on parallel edges connecting the same nodes.
1162 1162
  /// It is a higher level interface for the findEdge() function. You can
1163 1163
  /// use it the following way:
1164 1164
  ///\code
1165 1165
  /// for (ConEdgeIt<Graph> it(g, u, v); it != INVALID; ++it) {
1166 1166
  ///   ...
1167 1167
  /// }
1168 1168
  ///\endcode
1169 1169
  ///
1170 1170
  ///\sa findEdge()
1171 1171
  template <typename GR>
1172 1172
  class ConEdgeIt : public GR::Edge {
1173 1173
    typedef typename GR::Edge Parent;
1174 1174

	
1175 1175
  public:
1176 1176

	
1177 1177
    typedef typename GR::Edge Edge;
1178 1178
    typedef typename GR::Node Node;
1179 1179

	
1180 1180
    /// \brief Constructor.
1181 1181
    ///
1182 1182
    /// Construct a new ConEdgeIt iterating on the edges that
1183 1183
    /// connects nodes \c u and \c v.
1184 1184
    ConEdgeIt(const GR& g, Node u, Node v) : _graph(g), _u(u), _v(v) {
1185 1185
      Parent::operator=(findEdge(_graph, _u, _v));
1186 1186
    }
1187 1187

	
1188 1188
    /// \brief Constructor.
1189 1189
    ///
1190 1190
    /// Construct a new ConEdgeIt that continues iterating from edge \c e.
1191 1191
    ConEdgeIt(const GR& g, Edge e) : Parent(e), _graph(g) {}
1192 1192

	
1193 1193
    /// \brief Increment operator.
1194 1194
    ///
1195 1195
    /// It increments the iterator and gives back the next edge.
1196 1196
    ConEdgeIt& operator++() {
1197 1197
      Parent::operator=(findEdge(_graph, _u, _v, *this));
1198 1198
      return *this;
1199 1199
    }
1200 1200
  private:
1201 1201
    const GR& _graph;
1202 1202
    Node _u, _v;
1203 1203
  };
1204 1204

	
1205 1205

	
1206 1206
  ///Dynamic arc look-up between given endpoints.
1207 1207

	
1208 1208
  ///Using this class, you can find an arc in a digraph from a given
1209 1209
  ///source to a given target in amortized time <em>O</em>(log<em>d</em>),
1210 1210
  ///where <em>d</em> is the out-degree of the source node.
1211 1211
  ///
1212 1212
  ///It is possible to find \e all parallel arcs between two nodes with
1213 1213
  ///the \c operator() member.
1214 1214
  ///
1215 1215
  ///This is a dynamic data structure. Consider to use \ref ArcLookUp or
1216 1216
  ///\ref AllArcLookUp if your digraph is not changed so frequently.
1217 1217
  ///
1218 1218
  ///This class uses a self-adjusting binary search tree, the Splay tree
1219 1219
  ///of Sleator and Tarjan to guarantee the logarithmic amortized
1220 1220
  ///time bound for arc look-ups. This class also guarantees the
1221 1221
  ///optimal time bound in a constant factor for any distribution of
1222 1222
  ///queries.
1223 1223
  ///
1224 1224
  ///\tparam GR The type of the underlying digraph.
1225 1225
  ///
1226 1226
  ///\sa ArcLookUp
1227 1227
  ///\sa AllArcLookUp
1228 1228
  template <typename GR>
1229 1229
  class DynArcLookUp
1230 1230
    : protected ItemSetTraits<GR, typename GR::Arc>::ItemNotifier::ObserverBase
1231 1231
  {
1232 1232
    typedef typename ItemSetTraits<GR, typename GR::Arc>
1233 1233
    ::ItemNotifier::ObserverBase Parent;
1234 1234

	
1235 1235
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
1236 1236

	
1237 1237
  public:
1238 1238

	
1239 1239
    /// The Digraph type
1240 1240
    typedef GR Digraph;
1241 1241

	
1242 1242
  protected:
1243 1243

	
1244
    class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type {
1244
    class AutoNodeMap : public ItemSetTraits<GR, Node>::template Map<Arc>::Type
1245
    {
1245 1246
      typedef typename ItemSetTraits<GR, Node>::template Map<Arc>::Type Parent;
1246 1247

	
1247 1248
    public:
1248 1249

	
1249 1250
      AutoNodeMap(const GR& digraph) : Parent(digraph, INVALID) {}
1250 1251

	
1251 1252
      virtual void add(const Node& node) {
1252 1253
        Parent::add(node);
1253 1254
        Parent::set(node, INVALID);
1254 1255
      }
1255 1256

	
1256 1257
      virtual void add(const std::vector<Node>& nodes) {
1257 1258
        Parent::add(nodes);
1258 1259
        for (int i = 0; i < int(nodes.size()); ++i) {
1259 1260
          Parent::set(nodes[i], INVALID);
1260 1261
        }
1261 1262
      }
1262 1263

	
1263 1264
      virtual void build() {
1264 1265
        Parent::build();
1265 1266
        Node it;
1266 1267
        typename Parent::Notifier* nf = Parent::notifier();
1267 1268
        for (nf->first(it); it != INVALID; nf->next(it)) {
1268 1269
          Parent::set(it, INVALID);
1269 1270
        }
1270 1271
      }
1271 1272
    };
1272 1273

	
1273 1274
    class ArcLess {
1274 1275
      const Digraph &g;
1275 1276
    public:
1276 1277
      ArcLess(const Digraph &_g) : g(_g) {}
1277 1278
      bool operator()(Arc a,Arc b) const
1278 1279
      {
1279 1280
        return g.target(a)<g.target(b);
1280 1281
      }
1281 1282
    };
1282 1283

	
1283
  protected: 
1284
  protected:
1284 1285

	
1285 1286
    const Digraph &_g;
1286 1287
    AutoNodeMap _head;
1287 1288
    typename Digraph::template ArcMap<Arc> _parent;
1288 1289
    typename Digraph::template ArcMap<Arc> _left;
1289 1290
    typename Digraph::template ArcMap<Arc> _right;
1290 1291

	
1291 1292
  public:
1292 1293

	
1293 1294
    ///Constructor
1294 1295

	
1295 1296
    ///Constructor.
1296 1297
    ///
1297 1298
    ///It builds up the search database.
1298 1299
    DynArcLookUp(const Digraph &g)
1299 1300
      : _g(g),_head(g),_parent(g),_left(g),_right(g)
1300 1301
    {
1301 1302
      Parent::attach(_g.notifier(typename Digraph::Arc()));
1302 1303
      refresh();
1303 1304
    }
1304 1305

	
1305 1306
  protected:
1306 1307

	
1307 1308
    virtual void add(const Arc& arc) {
1308 1309
      insert(arc);
1309 1310
    }
1310 1311

	
1311 1312
    virtual void add(const std::vector<Arc>& arcs) {
1312 1313
      for (int i = 0; i < int(arcs.size()); ++i) {
1313 1314
        insert(arcs[i]);
1314 1315
      }
1315 1316
    }
1316 1317

	
1317 1318
    virtual void erase(const Arc& arc) {
1318 1319
      remove(arc);
1319 1320
    }
1320 1321

	
1321 1322
    virtual void erase(const std::vector<Arc>& arcs) {
1322 1323
      for (int i = 0; i < int(arcs.size()); ++i) {
1323 1324
        remove(arcs[i]);
1324 1325
      }
1325 1326
    }
1326 1327

	
1327 1328
    virtual void build() {
1328 1329
      refresh();
1329 1330
    }
1330 1331

	
1331 1332
    virtual void clear() {
1332 1333
      for(NodeIt n(_g);n!=INVALID;++n) {
1333 1334
        _head[n] = INVALID;
1334 1335
      }
1335 1336
    }
1336 1337

	
1337 1338
    void insert(Arc arc) {
1338 1339
      Node s = _g.source(arc);
1339 1340
      Node t = _g.target(arc);
1340 1341
      _left[arc] = INVALID;
1341 1342
      _right[arc] = INVALID;
1342 1343

	
1343 1344
      Arc e = _head[s];
1344 1345
      if (e == INVALID) {
1345 1346
        _head[s] = arc;
1346 1347
        _parent[arc] = INVALID;
1347 1348
        return;
1348 1349
      }
1349 1350
      while (true) {
1350 1351
        if (t < _g.target(e)) {
1351 1352
          if (_left[e] == INVALID) {
1352 1353
            _left[e] = arc;
1353 1354
            _parent[arc] = e;
1354 1355
            splay(arc);
1355 1356
            return;
1356 1357
          } else {
1357 1358
            e = _left[e];
1358 1359
          }
1359 1360
        } else {
1360 1361
          if (_right[e] == INVALID) {
1361 1362
            _right[e] = arc;
1362 1363
            _parent[arc] = e;
1363 1364
            splay(arc);
1364 1365
            return;
1365 1366
          } else {
1366 1367
            e = _right[e];
1367 1368
          }
1368 1369
        }
1369 1370
      }
1370 1371
    }
1371 1372

	
1372 1373
    void remove(Arc arc) {
1373 1374
      if (_left[arc] == INVALID) {
1374 1375
        if (_right[arc] != INVALID) {
1375 1376
          _parent[_right[arc]] = _parent[arc];
1376 1377
        }
1377 1378
        if (_parent[arc] != INVALID) {
1378 1379
          if (_left[_parent[arc]] == arc) {
1379 1380
            _left[_parent[arc]] = _right[arc];
1380 1381
          } else {
1381 1382
            _right[_parent[arc]] = _right[arc];
1382 1383
          }
1383 1384
        } else {
1384 1385
          _head[_g.source(arc)] = _right[arc];
1385 1386
        }
1386 1387
      } else if (_right[arc] == INVALID) {
1387 1388
        _parent[_left[arc]] = _parent[arc];
1388 1389
        if (_parent[arc] != INVALID) {
1389 1390
          if (_left[_parent[arc]] == arc) {
1390 1391
            _left[_parent[arc]] = _left[arc];
1391 1392
          } else {
1392 1393
            _right[_parent[arc]] = _left[arc];
1393 1394
          }
1394 1395
        } else {
1395 1396
          _head[_g.source(arc)] = _left[arc];
1396 1397
        }
1397 1398
      } else {
1398 1399
        Arc e = _left[arc];
1399 1400
        if (_right[e] != INVALID) {
1400 1401
          e = _right[e];
1401 1402
          while (_right[e] != INVALID) {
1402 1403
            e = _right[e];
1403 1404
          }
1404 1405
          Arc s = _parent[e];
1405 1406
          _right[_parent[e]] = _left[e];
1406 1407
          if (_left[e] != INVALID) {
1407 1408
            _parent[_left[e]] = _parent[e];
1408 1409
          }
1409 1410

	
1410 1411
          _left[e] = _left[arc];
1411 1412
          _parent[_left[arc]] = e;
1412 1413
          _right[e] = _right[arc];
1413 1414
          _parent[_right[arc]] = e;
1414 1415

	
1415 1416
          _parent[e] = _parent[arc];
1416 1417
          if (_parent[arc] != INVALID) {
1417 1418
            if (_left[_parent[arc]] == arc) {
1418 1419
              _left[_parent[arc]] = e;
1419 1420
            } else {
1420 1421
              _right[_parent[arc]] = e;
1421 1422
            }
1422 1423
          }
1423 1424
          splay(s);
1424 1425
        } else {
1425 1426
          _right[e] = _right[arc];
1426 1427
          _parent[_right[arc]] = e;
1427 1428
          _parent[e] = _parent[arc];
1428 1429

	
1429 1430
          if (_parent[arc] != INVALID) {
1430 1431
            if (_left[_parent[arc]] == arc) {
1431 1432
              _left[_parent[arc]] = e;
1432 1433
            } else {
1433 1434
              _right[_parent[arc]] = e;
1434 1435
            }
1435 1436
          } else {
1436 1437
            _head[_g.source(arc)] = e;
1437 1438
          }
1438 1439
        }
1439 1440
      }
1440 1441
    }
1441 1442

	
1442 1443
    Arc refreshRec(std::vector<Arc> &v,int a,int b)
1443 1444
    {
1444 1445
      int m=(a+b)/2;
1445 1446
      Arc me=v[m];
1446 1447
      if (a < m) {
1447 1448
        Arc left = refreshRec(v,a,m-1);
1448 1449
        _left[me] = left;
1449 1450
        _parent[left] = me;
1450 1451
      } else {
1451 1452
        _left[me] = INVALID;
1452 1453
      }
1453 1454
      if (m < b) {
1454 1455
        Arc right = refreshRec(v,m+1,b);
1455 1456
        _right[me] = right;
1456 1457
        _parent[right] = me;
1457 1458
      } else {
1458 1459
        _right[me] = INVALID;
1459 1460
      }
1460 1461
      return me;
1461 1462
    }
1462 1463

	
1463 1464
    void refresh() {
1464 1465
      for(NodeIt n(_g);n!=INVALID;++n) {
1465 1466
        std::vector<Arc> v;
1466 1467
        for(OutArcIt a(_g,n);a!=INVALID;++a) v.push_back(a);
1467 1468
        if (!v.empty()) {
1468 1469
          std::sort(v.begin(),v.end(),ArcLess(_g));
1469 1470
          Arc head = refreshRec(v,0,v.size()-1);
1470 1471
          _head[n] = head;
1471 1472
          _parent[head] = INVALID;
1472 1473
        }
1473 1474
        else _head[n] = INVALID;
1474 1475
      }
1475 1476
    }
1476 1477

	
1477 1478
    void zig(Arc v) {
1478 1479
      Arc w = _parent[v];
1479 1480
      _parent[v] = _parent[w];
1480 1481
      _parent[w] = v;
1481 1482
      _left[w] = _right[v];
1482 1483
      _right[v] = w;
1483 1484
      if (_parent[v] != INVALID) {
1484 1485
        if (_right[_parent[v]] == w) {
1485 1486
          _right[_parent[v]] = v;
1486 1487
        } else {
1487 1488
          _left[_parent[v]] = v;
1488 1489
        }
1489 1490
      }
1490 1491
      if (_left[w] != INVALID){
1491 1492
        _parent[_left[w]] = w;
1492 1493
      }
1493 1494
    }
1494 1495

	
1495 1496
    void zag(Arc v) {
1496 1497
      Arc w = _parent[v];
1497 1498
      _parent[v] = _parent[w];
1498 1499
      _parent[w] = v;
1499 1500
      _right[w] = _left[v];
1500 1501
      _left[v] = w;
1501 1502
      if (_parent[v] != INVALID){
1502 1503
        if (_left[_parent[v]] == w) {
1503 1504
          _left[_parent[v]] = v;
1504 1505
        } else {
1505 1506
          _right[_parent[v]] = v;
1506 1507
        }
1507 1508
      }
1508 1509
      if (_right[w] != INVALID){
1509 1510
        _parent[_right[w]] = w;
1510 1511
      }
1511 1512
    }
1512 1513

	
1513 1514
    void splay(Arc v) {
1514 1515
      while (_parent[v] != INVALID) {
1515 1516
        if (v == _left[_parent[v]]) {
1516 1517
          if (_parent[_parent[v]] == INVALID) {
1517 1518
            zig(v);
1518 1519
          } else {
1519 1520
            if (_parent[v] == _left[_parent[_parent[v]]]) {
1520 1521
              zig(_parent[v]);
1521 1522
              zig(v);
1522 1523
            } else {
1523 1524
              zig(v);
1524 1525
              zag(v);
1525 1526
            }
1526 1527
          }
1527 1528
        } else {
1528 1529
          if (_parent[_parent[v]] == INVALID) {
1529 1530
            zag(v);
1530 1531
          } else {
1531 1532
            if (_parent[v] == _left[_parent[_parent[v]]]) {
1532 1533
              zag(v);
1533 1534
              zig(v);
1534 1535
            } else {
1535 1536
              zag(_parent[v]);
1536 1537
              zag(v);
1537 1538
            }
1538 1539
          }
1539 1540
        }
1540 1541
      }
1541 1542
      _head[_g.source(v)] = v;
1542 1543
    }
1543 1544

	
1544 1545

	
1545 1546
  public:
1546 1547

	
1547 1548
    ///Find an arc between two nodes.
1548 1549

	
1549 1550
    ///Find an arc between two nodes.
1550 1551
    ///\param s The source node.
1551 1552
    ///\param t The target node.
1552 1553
    ///\param p The previous arc between \c s and \c t. It it is INVALID or
1553 1554
    ///not given, the operator finds the first appropriate arc.
1554 1555
    ///\return An arc from \c s to \c t after \c p or
1555 1556
    ///\ref INVALID if there is no more.
1556 1557
    ///
1557 1558
    ///For example, you can count the number of arcs from \c u to \c v in the
1558 1559
    ///following way.
1559 1560
    ///\code
1560 1561
    ///DynArcLookUp<ListDigraph> ae(g);
1561 1562
    ///...
1562 1563
    ///int n = 0;
1563 1564
    ///for(Arc a = ae(u,v); a != INVALID; a = ae(u,v,a)) n++;
1564 1565
    ///\endcode
1565 1566
    ///
1566 1567
    ///Finding the arcs take at most <em>O</em>(log<em>d</em>)
1567 1568
    ///amortized time, specifically, the time complexity of the lookups
1568 1569
    ///is equal to the optimal search tree implementation for the
1569 1570
    ///current query distribution in a constant factor.
1570 1571
    ///
1571 1572
    ///\note This is a dynamic data structure, therefore the data
1572 1573
    ///structure is updated after each graph alteration. Thus although
1573 1574
    ///this data structure is theoretically faster than \ref ArcLookUp
1574 1575
    ///and \ref AllArcLookUp, it often provides worse performance than
1575 1576
    ///them.
1576 1577
    Arc operator()(Node s, Node t, Arc p = INVALID) const  {
1577 1578
      if (p == INVALID) {
1578 1579
        Arc a = _head[s];
1579 1580
        if (a == INVALID) return INVALID;
1580 1581
        Arc r = INVALID;
1581 1582
        while (true) {
1582 1583
          if (_g.target(a) < t) {
1583 1584
            if (_right[a] == INVALID) {
1584 1585
              const_cast<DynArcLookUp&>(*this).splay(a);
1585 1586
              return r;
1586 1587
            } else {
1587 1588
              a = _right[a];
1588 1589
            }
1589 1590
          } else {
1590 1591
            if (_g.target(a) == t) {
1591 1592
              r = a;
1592 1593
            }
1593 1594
            if (_left[a] == INVALID) {
1594 1595
              const_cast<DynArcLookUp&>(*this).splay(a);
1595 1596
              return r;
1596 1597
            } else {
1597 1598
              a = _left[a];
1598 1599
            }
1599 1600
          }
1600 1601
        }
1601 1602
      } else {
1602 1603
        Arc a = p;
1603 1604
        if (_right[a] != INVALID) {
1604 1605
          a = _right[a];
1605 1606
          while (_left[a] != INVALID) {
1606 1607
            a = _left[a];
1607 1608
          }
1608 1609
          const_cast<DynArcLookUp&>(*this).splay(a);
1609 1610
        } else {
1610 1611
          while (_parent[a] != INVALID && _right[_parent[a]] ==  a) {
1611 1612
            a = _parent[a];
1612 1613
          }
1613 1614
          if (_parent[a] == INVALID) {
1614 1615
            return INVALID;
1615 1616
          } else {
1616 1617
            a = _parent[a];
1617 1618
            const_cast<DynArcLookUp&>(*this).splay(a);
1618 1619
          }
1619 1620
        }
1620 1621
        if (_g.target(a) == t) return a;
1621 1622
        else return INVALID;
1622 1623
      }
1623 1624
    }
1624 1625

	
1625 1626
  };
1626 1627

	
1627 1628
  ///Fast arc look-up between given endpoints.
1628 1629

	
1629 1630
  ///Using this class, you can find an arc in a digraph from a given
1630 1631
  ///source to a given target in time <em>O</em>(log<em>d</em>),
1631 1632
  ///where <em>d</em> is the out-degree of the source node.
1632 1633
  ///
1633 1634
  ///It is not possible to find \e all parallel arcs between two nodes.
1634 1635
  ///Use \ref AllArcLookUp for this purpose.
1635 1636
  ///
1636 1637
  ///\warning This class is static, so you should call refresh() (or at
1637 1638
  ///least refresh(Node)) to refresh this data structure whenever the
1638 1639
  ///digraph changes. This is a time consuming (superlinearly proportional
1639 1640
  ///(<em>O</em>(<em>m</em> log<em>m</em>)) to the number of arcs).
1640 1641
  ///
1641 1642
  ///\tparam GR The type of the underlying digraph.
1642 1643
  ///
1643 1644
  ///\sa DynArcLookUp
1644 1645
  ///\sa AllArcLookUp
1645 1646
  template<class GR>
1646 1647
  class ArcLookUp
1647 1648
  {
1648 1649
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
1649 1650

	
1650 1651
  public:
1651 1652

	
1652 1653
    /// The Digraph type
1653 1654
    typedef GR Digraph;
1654 1655

	
1655 1656
  protected:
1656 1657
    const Digraph &_g;
1657 1658
    typename Digraph::template NodeMap<Arc> _head;
1658 1659
    typename Digraph::template ArcMap<Arc> _left;
1659 1660
    typename Digraph::template ArcMap<Arc> _right;
1660 1661

	
1661 1662
    class ArcLess {
1662 1663
      const Digraph &g;
1663 1664
    public:
1664 1665
      ArcLess(const Digraph &_g) : g(_g) {}
1665 1666
      bool operator()(Arc a,Arc b) const
1666 1667
      {
1667 1668
        return g.target(a)<g.target(b);
1668 1669
      }
1669 1670
    };
1670 1671

	
1671 1672
  public:
1672 1673

	
1673 1674
    ///Constructor
1674 1675

	
1675 1676
    ///Constructor.
1676 1677
    ///
1677 1678
    ///It builds up the search database, which remains valid until the digraph
1678 1679
    ///changes.
1679 1680
    ArcLookUp(const Digraph &g) :_g(g),_head(g),_left(g),_right(g) {refresh();}
1680 1681

	
1681 1682
  private:
1682 1683
    Arc refreshRec(std::vector<Arc> &v,int a,int b)
1683 1684
    {
1684 1685
      int m=(a+b)/2;
1685 1686
      Arc me=v[m];
1686 1687
      _left[me] = a<m?refreshRec(v,a,m-1):INVALID;
1687 1688
      _right[me] = m<b?refreshRec(v,m+1,b):INVALID;
1688 1689
      return me;
1689 1690
    }
1690 1691
  public:
1691 1692
    ///Refresh the search data structure at a node.
1692 1693

	
1693 1694
    ///Build up the search database of node \c n.
1694 1695
    ///
1695 1696
    ///It runs in time <em>O</em>(<em>d</em> log<em>d</em>), where <em>d</em>
1696 1697
    ///is the number of the outgoing arcs of \c n.
1697 1698
    void refresh(Node n)
1698 1699
    {
1699 1700
      std::vector<Arc> v;
1700 1701
      for(OutArcIt e(_g,n);e!=INVALID;++e) v.push_back(e);
1701 1702
      if(v.size()) {
1702 1703
        std::sort(v.begin(),v.end(),ArcLess(_g));
1703 1704
        _head[n]=refreshRec(v,0,v.size()-1);
1704 1705
      }
1705 1706
      else _head[n]=INVALID;
1706 1707
    }
1707 1708
    ///Refresh the full data structure.
1708 1709

	
1709 1710
    ///Build up the full search database. In fact, it simply calls
1710 1711
    ///\ref refresh(Node) "refresh(n)" for each node \c n.
1711 1712
    ///
1712 1713
    ///It runs in time <em>O</em>(<em>m</em> log<em>D</em>), where <em>m</em> is
1713 1714
    ///the number of the arcs in the digraph and <em>D</em> is the maximum
1714 1715
    ///out-degree of the digraph.
1715 1716
    void refresh()
1716 1717
    {
1717 1718
      for(NodeIt n(_g);n!=INVALID;++n) refresh(n);
1718 1719
    }
1719 1720

	
1720 1721
    ///Find an arc between two nodes.
1721 1722

	
1722 1723
    ///Find an arc between two nodes in time <em>O</em>(log<em>d</em>),
1723 1724
    ///where <em>d</em> is the number of outgoing arcs of \c s.
1724 1725
    ///\param s The source node.
1725 1726
    ///\param t The target node.
1726 1727
    ///\return An arc from \c s to \c t if there exists,
1727 1728
    ///\ref INVALID otherwise.
1728 1729
    ///
1729 1730
    ///\warning If you change the digraph, refresh() must be called before using
1730 1731
    ///this operator. If you change the outgoing arcs of
1731 1732
    ///a single node \c n, then \ref refresh(Node) "refresh(n)" is enough.
1732 1733
    Arc operator()(Node s, Node t) const
1733 1734
    {
1734 1735
      Arc e;
1735 1736
      for(e=_head[s];
1736 1737
          e!=INVALID&&_g.target(e)!=t;
1737 1738
          e = t < _g.target(e)?_left[e]:_right[e]) ;
1738 1739
      return e;
1739 1740
    }
1740 1741

	
1741 1742
  };
1742 1743

	
1743 1744
  ///Fast look-up of all arcs between given endpoints.
1744 1745

	
1745 1746
  ///This class is the same as \ref ArcLookUp, with the addition
1746 1747
  ///that it makes it possible to find all parallel arcs between given
1747 1748
  ///endpoints.
1748 1749
  ///
1749 1750
  ///\warning This class is static, so you should call refresh() (or at
1750 1751
  ///least refresh(Node)) to refresh this data structure whenever the
1751 1752
  ///digraph changes. This is a time consuming (superlinearly proportional
1752 1753
  ///(<em>O</em>(<em>m</em> log<em>m</em>)) to the number of arcs).
1753 1754
  ///
1754 1755
  ///\tparam GR The type of the underlying digraph.
1755 1756
  ///
1756 1757
  ///\sa DynArcLookUp
1757 1758
  ///\sa ArcLookUp
1758 1759
  template<class GR>
1759 1760
  class AllArcLookUp : public ArcLookUp<GR>
1760 1761
  {
1761 1762
    using ArcLookUp<GR>::_g;
1762 1763
    using ArcLookUp<GR>::_right;
1763 1764
    using ArcLookUp<GR>::_left;
1764 1765
    using ArcLookUp<GR>::_head;
1765 1766

	
1766 1767
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
1767 1768

	
1768 1769
    typename GR::template ArcMap<Arc> _next;
1769 1770

	
1770 1771
    Arc refreshNext(Arc head,Arc next=INVALID)
1771 1772
    {
1772 1773
      if(head==INVALID) return next;
1773 1774
      else {
1774 1775
        next=refreshNext(_right[head],next);
1775 1776
        _next[head]=( next!=INVALID && _g.target(next)==_g.target(head))
1776 1777
          ? next : INVALID;
1777 1778
        return refreshNext(_left[head],head);
1778 1779
      }
1779 1780
    }
1780 1781

	
1781 1782
    void refreshNext()
1782 1783
    {
1783 1784
      for(NodeIt n(_g);n!=INVALID;++n) refreshNext(_head[n]);
1784 1785
    }
1785 1786

	
1786 1787
  public:
1787 1788

	
1788 1789
    /// The Digraph type
1789 1790
    typedef GR Digraph;
1790 1791

	
1791 1792
    ///Constructor
1792 1793

	
1793 1794
    ///Constructor.
1794 1795
    ///
1795 1796
    ///It builds up the search database, which remains valid until the digraph
1796 1797
    ///changes.
1797 1798
    AllArcLookUp(const Digraph &g) : ArcLookUp<GR>(g), _next(g) {refreshNext();}
1798 1799

	
1799 1800
    ///Refresh the data structure at a node.
1800 1801

	
1801 1802
    ///Build up the search database of node \c n.
1802 1803
    ///
1803 1804
    ///It runs in time <em>O</em>(<em>d</em> log<em>d</em>), where <em>d</em> is
1804 1805
    ///the number of the outgoing arcs of \c n.
1805 1806
    void refresh(Node n)
1806 1807
    {
1807 1808
      ArcLookUp<GR>::refresh(n);
1808 1809
      refreshNext(_head[n]);
1809 1810
    }
1810 1811

	
1811 1812
    ///Refresh the full data structure.
1812 1813

	
1813 1814
    ///Build up the full search database. In fact, it simply calls
1814 1815
    ///\ref refresh(Node) "refresh(n)" for each node \c n.
1815 1816
    ///
1816 1817
    ///It runs in time <em>O</em>(<em>m</em> log<em>D</em>), where <em>m</em> is
1817 1818
    ///the number of the arcs in the digraph and <em>D</em> is the maximum
1818 1819
    ///out-degree of the digraph.
1819 1820
    void refresh()
1820 1821
    {
1821 1822
      for(NodeIt n(_g);n!=INVALID;++n) refresh(_head[n]);
1822 1823
    }
1823 1824

	
1824 1825
    ///Find an arc between two nodes.
1825 1826

	
1826 1827
    ///Find an arc between two nodes.
1827 1828
    ///\param s The source node.
1828 1829
    ///\param t The target node.
1829 1830
    ///\param prev The previous arc between \c s and \c t. It it is INVALID or
1830 1831
    ///not given, the operator finds the first appropriate arc.
1831 1832
    ///\return An arc from \c s to \c t after \c prev or
1832 1833
    ///\ref INVALID if there is no more.
1833 1834
    ///
1834 1835
    ///For example, you can count the number of arcs from \c u to \c v in the
1835 1836
    ///following way.
1836 1837
    ///\code
1837 1838
    ///AllArcLookUp<ListDigraph> ae(g);
1838 1839
    ///...
1839 1840
    ///int n = 0;
1840 1841
    ///for(Arc a = ae(u,v); a != INVALID; a=ae(u,v,a)) n++;
1841 1842
    ///\endcode
1842 1843
    ///
1843 1844
    ///Finding the first arc take <em>O</em>(log<em>d</em>) time,
1844 1845
    ///where <em>d</em> is the number of outgoing arcs of \c s. Then the
1845 1846
    ///consecutive arcs are found in constant time.
1846 1847
    ///
1847 1848
    ///\warning If you change the digraph, refresh() must be called before using
1848 1849
    ///this operator. If you change the outgoing arcs of
1849 1850
    ///a single node \c n, then \ref refresh(Node) "refresh(n)" is enough.
1850 1851
    ///
1851 1852
#ifdef DOXYGEN
1852 1853
    Arc operator()(Node s, Node t, Arc prev=INVALID) const {}
1853 1854
#else
1854 1855
    using ArcLookUp<GR>::operator() ;
1855 1856
    Arc operator()(Node s, Node t, Arc prev) const
1856 1857
    {
1857 1858
      return prev==INVALID?(*this)(s,t):_next[prev];
1858 1859
    }
1859 1860
#endif
1860 1861

	
1861 1862
  };
1862 1863

	
1863 1864
  /// @}
1864 1865

	
1865 1866
} //namespace lemon
1866 1867

	
1867 1868
#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 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
  /// This class can be used in the same way as \ref Counter however it
215
  /// This class can be used in the same way as \ref Counter, but 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-2009
5
 * Copyright (C) 2003-2010
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
#include <cstring>
22 22

	
23 23
#include <lemon/cplex.h>
24 24

	
25 25
extern "C" {
26 26
#include <ilcplex/cplex.h>
27 27
}
28 28

	
29 29

	
30 30
///\file
31 31
///\brief Implementation of the LEMON-CPLEX lp solver interface.
32 32
namespace lemon {
33 33

	
34 34
  CplexEnv::LicenseError::LicenseError(int status) {
35 35
    if (!CPXgeterrorstring(0, status, _message)) {
36 36
      std::strcpy(_message, "Cplex unknown error");
37 37
    }
38 38
  }
39 39

	
40 40
  CplexEnv::CplexEnv() {
41 41
    int status;
42 42
    _cnt = new int;
43 43
    _env = CPXopenCPLEX(&status);
44 44
    if (_env == 0) {
45 45
      delete _cnt;
46 46
      _cnt = 0;
47 47
      throw LicenseError(status);
48 48
    }
49 49
  }
50 50

	
51 51
  CplexEnv::CplexEnv(const CplexEnv& other) {
52 52
    _env = other._env;
53 53
    _cnt = other._cnt;
54 54
    ++(*_cnt);
55 55
  }
56 56

	
57 57
  CplexEnv& CplexEnv::operator=(const CplexEnv& other) {
58 58
    _env = other._env;
59 59
    _cnt = other._cnt;
60 60
    ++(*_cnt);
61 61
    return *this;
62 62
  }
63 63

	
64 64
  CplexEnv::~CplexEnv() {
65 65
    --(*_cnt);
66 66
    if (*_cnt == 0) {
67 67
      delete _cnt;
68 68
      CPXcloseCPLEX(&_env);
69 69
    }
70 70
  }
71 71

	
72 72
  CplexBase::CplexBase() : LpBase() {
73 73
    int status;
74 74
    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
75 75
    messageLevel(MESSAGE_NOTHING);
76 76
  }
77 77

	
78 78
  CplexBase::CplexBase(const CplexEnv& env)
79 79
    : LpBase(), _env(env) {
80 80
    int status;
81 81
    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
82 82
    messageLevel(MESSAGE_NOTHING);
83 83
  }
84 84

	
85 85
  CplexBase::CplexBase(const CplexBase& cplex)
86 86
    : LpBase() {
87 87
    int status;
88 88
    _prob = CPXcloneprob(cplexEnv(), cplex._prob, &status);
89 89
    rows = cplex.rows;
90 90
    cols = cplex.cols;
91 91
    messageLevel(MESSAGE_NOTHING);
92 92
  }
93 93

	
94 94
  CplexBase::~CplexBase() {
95 95
    CPXfreeprob(cplexEnv(),&_prob);
96 96
  }
97 97

	
98 98
  int CplexBase::_addCol() {
99 99
    int i = CPXgetnumcols(cplexEnv(), _prob);
100 100
    double lb = -INF, ub = INF;
101 101
    CPXnewcols(cplexEnv(), _prob, 1, 0, &lb, &ub, 0, 0);
102 102
    return i;
103 103
  }
104 104

	
105 105

	
106 106
  int CplexBase::_addRow() {
107 107
    int i = CPXgetnumrows(cplexEnv(), _prob);
108 108
    const double ub = INF;
109 109
    const char s = 'L';
110 110
    CPXnewrows(cplexEnv(), _prob, 1, &ub, &s, 0, 0);
111 111
    return i;
112 112
  }
113 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
  }
114 147

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

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

	
123 156
  void CplexBase::_eraseColId(int i) {
124 157
    cols.eraseIndex(i);
125 158
    cols.shiftIndices(i);
126 159
  }
127 160
  void CplexBase::_eraseRowId(int i) {
128 161
    rows.eraseIndex(i);
129 162
    rows.shiftIndices(i);
130 163
  }
131 164

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

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

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

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

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

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

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

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

	
196 229
  void CplexBase::_setRowCoeffs(int i, ExprIterator b,
197 230
                                      ExprIterator e)
198 231
  {
199 232
    std::vector<int> indices;
200 233
    std::vector<int> rowlist;
201 234
    std::vector<Value> values;
202 235

	
203 236
    for(ExprIterator it=b; it!=e; ++it) {
204 237
      indices.push_back(it->first);
205 238
      values.push_back(it->second);
206 239
      rowlist.push_back(i);
207 240
    }
208 241

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

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

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

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

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

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

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

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

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

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

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

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

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

	
264 297
  }
265 298

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

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

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

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

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

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

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

	
304 337
    switch (s) {
305 338
    case 'G':
306 339
    case 'R':
307 340
    case 'E':
308 341
      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
309 342
      return res <= -CPX_INFBOUND ? -INF : res;
310 343
    default:
311 344
      return -INF;
312 345
    }
313 346
  }
314 347

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

	
320 353
    switch (s) {
321 354
    case 'L':
322 355
    case 'E':
323 356
      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
324 357
      return res >= CPX_INFBOUND ? INF : res;
325 358
    case 'R':
326 359
      CPXgetrhs(cplexEnv(), _prob, &res, i, i);
327 360
      {
328 361
        double rng;
329 362
        CPXgetrngval(cplexEnv(), _prob, &rng, i, i);
330 363
        res += rng;
331 364
      }
332 365
      return res >= CPX_INFBOUND ? INF : res;
333 366
    default:
334 367
      return INF;
335 368
    }
336 369
  }
337 370

	
338 371
  //This is easier to implement
339 372
  void CplexBase::_set_row_bounds(int i, Value lb, Value ub) {
340 373
    if (lb == -INF) {
341 374
      const char s = 'L';
342 375
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
343 376
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &ub);
344 377
    } else if (ub == INF) {
345 378
      const char s = 'G';
346 379
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
347 380
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
348 381
    } else if (lb == ub){
349 382
      const char s = 'E';
350 383
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
351 384
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
352 385
    } else {
353 386
      const char s = 'R';
354 387
      CPXchgsense(cplexEnv(), _prob, 1, &i, &s);
355 388
      CPXchgrhs(cplexEnv(), _prob, 1, &i, &lb);
356 389
      double len = ub - lb;
357 390
      CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
358 391
    }
359 392
  }
360 393

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

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

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

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

	
385 418
  }
386 419

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

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

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

	
406 439
  CplexBase::Value CplexBase::_getObjCoeff(int i) const
407 440
  {
408 441
    Value x;
409 442
    CPXgetobj(cplexEnv(), _prob, &x, i, i);
410 443
    return x;
411 444
  }
412 445

	
413 446
  void CplexBase::_setSense(CplexBase::Sense sense) {
414 447
    switch (sense) {
415 448
    case MIN:
416 449
      CPXchgobjsen(cplexEnv(), _prob, CPX_MIN);
417 450
      break;
418 451
    case MAX:
419 452
      CPXchgobjsen(cplexEnv(), _prob, CPX_MAX);
420 453
      break;
421 454
    }
422 455
  }
423 456

	
424 457
  CplexBase::Sense CplexBase::_getSense() const {
425 458
    switch (CPXgetobjsen(cplexEnv(), _prob)) {
426 459
    case CPX_MIN:
427 460
      return MIN;
428 461
    case CPX_MAX:
429 462
      return MAX;
430 463
    default:
431 464
      LEMON_ASSERT(false, "Invalid sense");
432 465
      return CplexBase::Sense();
433 466
    }
434 467
  }
435 468

	
436 469
  void CplexBase::_clear() {
437 470
    CPXfreeprob(cplexEnv(),&_prob);
438 471
    int status;
439 472
    _prob = CPXcreateprob(cplexEnv(), &status, "Cplex problem");
440 473
    rows.clear();
441 474
    cols.clear();
442 475
  }
443 476

	
444 477
  void CplexBase::_messageLevel(MessageLevel level) {
445 478
    switch (level) {
446 479
    case MESSAGE_NOTHING:
447 480
      _message_enabled = false;
448 481
      break;
449 482
    case MESSAGE_ERROR:
450 483
    case MESSAGE_WARNING:
451 484
    case MESSAGE_NORMAL:
452 485
    case MESSAGE_VERBOSE:
453 486
      _message_enabled = true;
454 487
      break;
455 488
    }
456 489
  }
457 490

	
458 491
  void CplexBase::_applyMessageLevel() {
459
    CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND, 
492
    CPXsetintparam(cplexEnv(), CPX_PARAM_SCRIND,
460 493
                   _message_enabled ? CPX_ON : CPX_OFF);
461 494
  }
462 495

	
463 496
  // CplexLp members
464 497

	
465 498
  CplexLp::CplexLp()
466 499
    : LpBase(), LpSolver(), CplexBase() {}
467 500

	
468 501
  CplexLp::CplexLp(const CplexEnv& env)
469 502
    : LpBase(), LpSolver(), CplexBase(env) {}
470 503

	
471 504
  CplexLp::CplexLp(const CplexLp& other)
472 505
    : LpBase(), LpSolver(), CplexBase(other) {}
473 506

	
474 507
  CplexLp::~CplexLp() {}
475 508

	
476 509
  CplexLp* CplexLp::newSolver() const { return new CplexLp; }
477 510
  CplexLp* CplexLp::cloneSolver() const {return new CplexLp(*this); }
478 511

	
479 512
  const char* CplexLp::_solverName() const { return "CplexLp"; }
480 513

	
481 514
  void CplexLp::_clear_temporals() {
482 515
    _col_status.clear();
483 516
    _row_status.clear();
484 517
    _primal_ray.clear();
485 518
    _dual_ray.clear();
486 519
  }
487 520

	
488 521
  // The routine returns zero unless an error occurred during the
489 522
  // optimization. Examples of errors include exhausting available
490 523
  // memory (CPXERR_NO_MEMORY) or encountering invalid data in the
491 524
  // CPLEX problem object (CPXERR_NO_PROBLEM). Exceeding a
492 525
  // user-specified CPLEX limit, or proving the model infeasible or
493 526
  // unbounded, are not considered errors. Note that a zero return
494 527
  // value does not necessarily mean that a solution exists. Use query
495 528
  // routines CPXsolninfo, CPXgetstat, and CPXsolution to obtain
496 529
  // further information about the status of the optimization.
497 530
  CplexLp::SolveExitStatus CplexLp::convertStatus(int status) {
498 531
#if CPX_VERSION >= 800
499 532
    if (status == 0) {
500 533
      switch (CPXgetstat(cplexEnv(), _prob)) {
501 534
      case CPX_STAT_OPTIMAL:
502 535
      case CPX_STAT_INFEASIBLE:
503 536
      case CPX_STAT_UNBOUNDED:
504 537
        return SOLVED;
505 538
      default:
506 539
        return UNSOLVED;
507 540
      }
508 541
    } else {
509 542
      return UNSOLVED;
510 543
    }
511 544
#else
512 545
    if (status == 0) {
513 546
      //We want to exclude some cases
514 547
      switch (CPXgetstat(cplexEnv(), _prob)) {
515 548
      case CPX_OBJ_LIM:
516 549
      case CPX_IT_LIM_FEAS:
517 550
      case CPX_IT_LIM_INFEAS:
518 551
      case CPX_TIME_LIM_FEAS:
519 552
      case CPX_TIME_LIM_INFEAS:
520 553
        return UNSOLVED;
521 554
      default:
522 555
        return SOLVED;
523 556
      }
524 557
    } else {
525 558
      return UNSOLVED;
526 559
    }
527 560
#endif
528 561
  }
529 562

	
530 563
  CplexLp::SolveExitStatus CplexLp::_solve() {
531 564
    _clear_temporals();
532 565
    _applyMessageLevel();
533 566
    return convertStatus(CPXlpopt(cplexEnv(), _prob));
534 567
  }
535 568

	
536 569
  CplexLp::SolveExitStatus CplexLp::solvePrimal() {
537 570
    _clear_temporals();
538 571
    _applyMessageLevel();
539 572
    return convertStatus(CPXprimopt(cplexEnv(), _prob));
540 573
  }
541 574

	
542 575
  CplexLp::SolveExitStatus CplexLp::solveDual() {
543 576
    _clear_temporals();
544 577
    _applyMessageLevel();
545 578
    return convertStatus(CPXdualopt(cplexEnv(), _prob));
546 579
  }
547 580

	
548 581
  CplexLp::SolveExitStatus CplexLp::solveBarrier() {
549 582
    _clear_temporals();
550 583
    _applyMessageLevel();
551 584
    return convertStatus(CPXbaropt(cplexEnv(), _prob));
552 585
  }
553 586

	
554 587
  CplexLp::Value CplexLp::_getPrimal(int i) const {
555 588
    Value x;
556 589
    CPXgetx(cplexEnv(), _prob, &x, i, i);
557 590
    return x;
558 591
  }
559 592

	
560 593
  CplexLp::Value CplexLp::_getDual(int i) const {
561 594
    Value y;
562 595
    CPXgetpi(cplexEnv(), _prob, &y, i, i);
563 596
    return y;
564 597
  }
565 598

	
566 599
  CplexLp::Value CplexLp::_getPrimalValue() const {
567 600
    Value objval;
568 601
    CPXgetobjval(cplexEnv(), _prob, &objval);
569 602
    return objval;
570 603
  }
571 604

	
572 605
  CplexLp::VarStatus CplexLp::_getColStatus(int i) const {
573 606
    if (_col_status.empty()) {
574 607
      _col_status.resize(CPXgetnumcols(cplexEnv(), _prob));
575 608
      CPXgetbase(cplexEnv(), _prob, &_col_status.front(), 0);
576 609
    }
577 610
    switch (_col_status[i]) {
578 611
    case CPX_BASIC:
579 612
      return BASIC;
580 613
    case CPX_FREE_SUPER:
581 614
      return FREE;
582 615
    case CPX_AT_LOWER:
583 616
      return LOWER;
584 617
    case CPX_AT_UPPER:
585 618
      return UPPER;
586 619
    default:
587 620
      LEMON_ASSERT(false, "Wrong column status");
588 621
      return CplexLp::VarStatus();
589 622
    }
590 623
  }
591 624

	
592 625
  CplexLp::VarStatus CplexLp::_getRowStatus(int i) const {
593 626
    if (_row_status.empty()) {
594 627
      _row_status.resize(CPXgetnumrows(cplexEnv(), _prob));
595 628
      CPXgetbase(cplexEnv(), _prob, 0, &_row_status.front());
596 629
    }
597 630
    switch (_row_status[i]) {
598 631
    case CPX_BASIC:
599 632
      return BASIC;
600 633
    case CPX_AT_LOWER:
601 634
      {
602 635
        char s;
603 636
        CPXgetsense(cplexEnv(), _prob, &s, i, i);
604 637
        return s != 'L' ? LOWER : UPPER;
605 638
      }
606 639
    case CPX_AT_UPPER:
607 640
      return UPPER;
608 641
    default:
609 642
      LEMON_ASSERT(false, "Wrong row status");
610 643
      return CplexLp::VarStatus();
611 644
    }
612 645
  }
613 646

	
614 647
  CplexLp::Value CplexLp::_getPrimalRay(int i) const {
615 648
    if (_primal_ray.empty()) {
616 649
      _primal_ray.resize(CPXgetnumcols(cplexEnv(), _prob));
617 650
      CPXgetray(cplexEnv(), _prob, &_primal_ray.front());
618 651
    }
619 652
    return _primal_ray[i];
620 653
  }
621 654

	
622 655
  CplexLp::Value CplexLp::_getDualRay(int i) const {
623 656
    if (_dual_ray.empty()) {
624 657

	
625 658
    }
626 659
    return _dual_ray[i];
627 660
  }
628 661

	
629 662
  // Cplex 7.0 status values
630 663
  // This table lists the statuses, returned by the CPXgetstat()
631 664
  // routine, for solutions to LP problems or mixed integer problems. If
632 665
  // no solution exists, the return value is zero.
633 666

	
634 667
  // For Simplex, Barrier
635 668
  // 1          CPX_OPTIMAL
636 669
  //          Optimal solution found
637 670
  // 2          CPX_INFEASIBLE
638 671
  //          Problem infeasible
639 672
  // 3    CPX_UNBOUNDED
640 673
  //          Problem unbounded
641 674
  // 4          CPX_OBJ_LIM
642 675
  //          Objective limit exceeded in Phase II
643 676
  // 5          CPX_IT_LIM_FEAS
644 677
  //          Iteration limit exceeded in Phase II
645 678
  // 6          CPX_IT_LIM_INFEAS
646 679
  //          Iteration limit exceeded in Phase I
647 680
  // 7          CPX_TIME_LIM_FEAS
648 681
  //          Time limit exceeded in Phase II
649 682
  // 8          CPX_TIME_LIM_INFEAS
650 683
  //          Time limit exceeded in Phase I
651 684
  // 9          CPX_NUM_BEST_FEAS
652 685
  //          Problem non-optimal, singularities in Phase II
653 686
  // 10         CPX_NUM_BEST_INFEAS
654 687
  //          Problem non-optimal, singularities in Phase I
655 688
  // 11         CPX_OPTIMAL_INFEAS
656 689
  //          Optimal solution found, unscaled infeasibilities
657 690
  // 12         CPX_ABORT_FEAS
658 691
  //          Aborted in Phase II
659 692
  // 13         CPX_ABORT_INFEAS
660 693
  //          Aborted in Phase I
661 694
  // 14          CPX_ABORT_DUAL_INFEAS
662 695
  //          Aborted in barrier, dual infeasible
663 696
  // 15          CPX_ABORT_PRIM_INFEAS
664 697
  //          Aborted in barrier, primal infeasible
665 698
  // 16          CPX_ABORT_PRIM_DUAL_INFEAS
666 699
  //          Aborted in barrier, primal and dual infeasible
667 700
  // 17          CPX_ABORT_PRIM_DUAL_FEAS
668 701
  //          Aborted in barrier, primal and dual feasible
669 702
  // 18          CPX_ABORT_CROSSOVER
670 703
  //          Aborted in crossover
671 704
  // 19          CPX_INForUNBD
672 705
  //          Infeasible or unbounded
673 706
  // 20   CPX_PIVOT
674 707
  //       User pivot used
675 708
  //
676 709
  // Pending return values
677 710
  // ??case CPX_ABORT_DUAL_INFEAS
678 711
  // ??case CPX_ABORT_CROSSOVER
679 712
  // ??case CPX_INForUNBD
680 713
  // ??case CPX_PIVOT
681 714

	
682 715
  //Some more interesting stuff:
683 716

	
684 717
  // CPX_PARAM_PROBMETHOD  1062  int  LPMETHOD
685 718
  // 0 Automatic
686 719
  // 1 Primal Simplex
687 720
  // 2 Dual Simplex
688 721
  // 3 Network Simplex
689 722
  // 4 Standard Barrier
690 723
  // Default: 0
691 724
  // Description: Method for linear optimization.
692 725
  // Determines which algorithm is used when CPXlpopt() (or "optimize"
693 726
  // in the Interactive Optimizer) is called. Currently the behavior of
694 727
  // the "Automatic" setting is that CPLEX simply invokes the dual
695 728
  // simplex method, but this capability may be expanded in the future
696 729
  // so that CPLEX chooses the method based on problem characteristics
697 730
#if CPX_VERSION < 900
698 731
  void statusSwitch(CPXENVptr cplexEnv(),int& stat){
699 732
    int lpmethod;
700 733
    CPXgetintparam (cplexEnv(),CPX_PARAM_PROBMETHOD,&lpmethod);
701 734
    if (lpmethod==2){
702 735
      if (stat==CPX_UNBOUNDED){
703 736
        stat=CPX_INFEASIBLE;
704 737
      }
705 738
      else{
706 739
        if (stat==CPX_INFEASIBLE)
707 740
          stat=CPX_UNBOUNDED;
708 741
      }
709 742
    }
710 743
  }
711 744
#else
712 745
  void statusSwitch(CPXENVptr,int&){}
713 746
#endif
714 747

	
715 748
  CplexLp::ProblemType CplexLp::_getPrimalType() const {
716 749
    // Unboundedness not treated well: the following is from cplex 9.0 doc
717 750
    // About Unboundedness
718 751

	
719 752
    // The treatment of models that are unbounded involves a few
720 753
    // subtleties. Specifically, a declaration of unboundedness means that
721 754
    // ILOG CPLEX has determined that the model has an unbounded
722 755
    // ray. Given any feasible solution x with objective z, a multiple of
723 756
    // the unbounded ray can be added to x to give a feasible solution
724 757
    // with objective z-1 (or z+1 for maximization models). Thus, if a
725 758
    // feasible solution exists, then the optimal objective is
726 759
    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
727 760
    // a feasible solution exists. Users can call the routine CPXsolninfo
728 761
    // to determine whether ILOG CPLEX has also concluded that the model
729 762
    // has a feasible solution.
730 763

	
731 764
    int stat = CPXgetstat(cplexEnv(), _prob);
732 765
#if CPX_VERSION >= 800
733 766
    switch (stat)
734 767
      {
735 768
      case CPX_STAT_OPTIMAL:
736 769
        return OPTIMAL;
737 770
      case CPX_STAT_UNBOUNDED:
738 771
        return UNBOUNDED;
739 772
      case CPX_STAT_INFEASIBLE:
740 773
        return INFEASIBLE;
741 774
      default:
742 775
        return UNDEFINED;
743 776
      }
744 777
#else
745 778
    statusSwitch(cplexEnv(),stat);
746 779
    //CPXgetstat(cplexEnv(), _prob);
747 780
    switch (stat) {
748 781
    case 0:
749 782
      return UNDEFINED; //Undefined
750 783
    case CPX_OPTIMAL://Optimal
751 784
      return OPTIMAL;
752 785
    case CPX_UNBOUNDED://Unbounded
753 786
      return INFEASIBLE;//In case of dual simplex
754 787
      //return UNBOUNDED;
755 788
    case CPX_INFEASIBLE://Infeasible
756 789
      //    case CPX_IT_LIM_INFEAS:
757 790
      //     case CPX_TIME_LIM_INFEAS:
758 791
      //     case CPX_NUM_BEST_INFEAS:
759 792
      //     case CPX_OPTIMAL_INFEAS:
760 793
      //     case CPX_ABORT_INFEAS:
761 794
      //     case CPX_ABORT_PRIM_INFEAS:
762 795
      //     case CPX_ABORT_PRIM_DUAL_INFEAS:
763 796
      return UNBOUNDED;//In case of dual simplex
764 797
      //return INFEASIBLE;
765 798
      //     case CPX_OBJ_LIM:
766 799
      //     case CPX_IT_LIM_FEAS:
767 800
      //     case CPX_TIME_LIM_FEAS:
768 801
      //     case CPX_NUM_BEST_FEAS:
769 802
      //     case CPX_ABORT_FEAS:
770 803
      //     case CPX_ABORT_PRIM_DUAL_FEAS:
771 804
      //       return FEASIBLE;
772 805
    default:
773 806
      return UNDEFINED; //Everything else comes here
774 807
      //FIXME error
775 808
    }
776 809
#endif
777 810
  }
778 811

	
779 812
  // Cplex 9.0 status values
780 813
  // CPX_STAT_ABORT_DUAL_OBJ_LIM
781 814
  // CPX_STAT_ABORT_IT_LIM
782 815
  // CPX_STAT_ABORT_OBJ_LIM
783 816
  // CPX_STAT_ABORT_PRIM_OBJ_LIM
784 817
  // CPX_STAT_ABORT_TIME_LIM
785 818
  // CPX_STAT_ABORT_USER
786 819
  // CPX_STAT_FEASIBLE_RELAXED
787 820
  // CPX_STAT_INFEASIBLE
788 821
  // CPX_STAT_INForUNBD
789 822
  // CPX_STAT_NUM_BEST
790 823
  // CPX_STAT_OPTIMAL
791 824
  // CPX_STAT_OPTIMAL_FACE_UNBOUNDED
792 825
  // CPX_STAT_OPTIMAL_INFEAS
793 826
  // CPX_STAT_OPTIMAL_RELAXED
794 827
  // CPX_STAT_UNBOUNDED
795 828

	
796 829
  CplexLp::ProblemType CplexLp::_getDualType() const {
797 830
    int stat = CPXgetstat(cplexEnv(), _prob);
798 831
#if CPX_VERSION >= 800
799 832
    switch (stat) {
800 833
    case CPX_STAT_OPTIMAL:
801 834
      return OPTIMAL;
802 835
    case CPX_STAT_UNBOUNDED:
803 836
      return INFEASIBLE;
804 837
    default:
805 838
      return UNDEFINED;
806 839
    }
807 840
#else
808 841
    statusSwitch(cplexEnv(),stat);
809 842
    switch (stat) {
810 843
    case 0:
811 844
      return UNDEFINED; //Undefined
812 845
    case CPX_OPTIMAL://Optimal
813 846
      return OPTIMAL;
814 847
    case CPX_UNBOUNDED:
815 848
      return INFEASIBLE;
816 849
    default:
817 850
      return UNDEFINED; //Everything else comes here
818 851
      //FIXME error
819 852
    }
820 853
#endif
821 854
  }
822 855

	
823 856
  // CplexMip members
824 857

	
825 858
  CplexMip::CplexMip()
826 859
    : LpBase(), MipSolver(), CplexBase() {
827 860

	
828 861
#if CPX_VERSION < 800
829 862
    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
830 863
#else
831 864
    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
832 865
#endif
833 866
  }
834 867

	
835 868
  CplexMip::CplexMip(const CplexEnv& env)
836 869
    : LpBase(), MipSolver(), CplexBase(env) {
837 870

	
838 871
#if CPX_VERSION < 800
839 872
    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MIP);
840 873
#else
841 874
    CPXchgprobtype(cplexEnv(),  _prob, CPXPROB_MILP);
842 875
#endif
843 876

	
844 877
  }
845 878

	
846 879
  CplexMip::CplexMip(const CplexMip& other)
847 880
    : LpBase(), MipSolver(), CplexBase(other) {}
848 881

	
849 882
  CplexMip::~CplexMip() {}
850 883

	
851 884
  CplexMip* CplexMip::newSolver() const { return new CplexMip; }
852 885
  CplexMip* CplexMip::cloneSolver() const {return new CplexMip(*this); }
853 886

	
854 887
  const char* CplexMip::_solverName() const { return "CplexMip"; }
855 888

	
856 889
  void CplexMip::_setColType(int i, CplexMip::ColTypes col_type) {
857 890

	
858 891
    // Note If a variable is to be changed to binary, a call to CPXchgbds
859 892
    // should also be made to change the bounds to 0 and 1.
860 893

	
861 894
    switch (col_type){
862 895
    case INTEGER: {
863 896
      const char t = 'I';
864 897
      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
865 898
    } break;
866 899
    case REAL: {
867 900
      const char t = 'C';
868 901
      CPXchgctype (cplexEnv(), _prob, 1, &i, &t);
869 902
    } break;
870 903
    default:
871 904
      break;
872 905
    }
873 906
  }
874 907

	
875 908
  CplexMip::ColTypes CplexMip::_getColType(int i) const {
876 909
    char t;
877 910
    CPXgetctype (cplexEnv(), _prob, &t, i, i);
878 911
    switch (t) {
879 912
    case 'I':
880 913
      return INTEGER;
881 914
    case 'C':
882 915
      return REAL;
883 916
    default:
884 917
      LEMON_ASSERT(false, "Invalid column type");
885 918
      return ColTypes();
886 919
    }
887 920

	
888 921
  }
889 922

	
890 923
  CplexMip::SolveExitStatus CplexMip::_solve() {
891 924
    int status;
892 925
    _applyMessageLevel();
893 926
    status = CPXmipopt (cplexEnv(), _prob);
894 927
    if (status==0)
895 928
      return SOLVED;
896 929
    else
897 930
      return UNSOLVED;
898 931

	
899 932
  }
900 933

	
901 934

	
902 935
  CplexMip::ProblemType CplexMip::_getType() const {
903 936

	
904 937
    int stat = CPXgetstat(cplexEnv(), _prob);
905 938

	
906 939
    //Fortunately, MIP statuses did not change for cplex 8.0
907 940
    switch (stat) {
908 941
    case CPXMIP_OPTIMAL:
909 942
      // Optimal integer solution has been found.
910 943
    case CPXMIP_OPTIMAL_TOL:
911 944
      // Optimal soluton with the tolerance defined by epgap or epagap has
912 945
      // been found.
913 946
      return OPTIMAL;
914 947
      //This also exists in later issues
915 948
      //    case CPXMIP_UNBOUNDED:
916 949
      //return UNBOUNDED;
917 950
      case CPXMIP_INFEASIBLE:
918 951
        return INFEASIBLE;
919 952
    default:
920 953
      return UNDEFINED;
921 954
    }
922 955
    //Unboundedness not treated well: the following is from cplex 9.0 doc
923 956
    // About Unboundedness
924 957

	
925 958
    // The treatment of models that are unbounded involves a few
926 959
    // subtleties. Specifically, a declaration of unboundedness means that
927 960
    // ILOG CPLEX has determined that the model has an unbounded
928 961
    // ray. Given any feasible solution x with objective z, a multiple of
929 962
    // the unbounded ray can be added to x to give a feasible solution
930 963
    // with objective z-1 (or z+1 for maximization models). Thus, if a
931 964
    // feasible solution exists, then the optimal objective is
932 965
    // unbounded. Note that ILOG CPLEX has not necessarily concluded that
933 966
    // a feasible solution exists. Users can call the routine CPXsolninfo
934 967
    // to determine whether ILOG CPLEX has also concluded that the model
935 968
    // has a feasible solution.
936 969
  }
937 970

	
938 971
  CplexMip::Value CplexMip::_getSol(int i) const {
939 972
    Value x;
940 973
    CPXgetmipx(cplexEnv(), _prob, &x, i, i);
941 974
    return x;
942 975
  }
943 976

	
944 977
  CplexMip::Value CplexMip::_getSolValue() const {
945 978
    Value objval;
946 979
    CPXgetmipobjval(cplexEnv(), _prob, &objval);
947 980
    return objval;
948 981
  }
949 982

	
950 983
} //namespace lemon
951 984

	
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 19
#ifndef LEMON_CPLEX_H
20 20
#define LEMON_CPLEX_H
21 21

	
22 22
///\file
23 23
///\brief Header of the LEMON-CPLEX lp solver interface.
24 24

	
25 25
#include <lemon/lp_base.h>
26 26

	
27 27
struct cpxenv;
28 28
struct cpxlp;
29 29

	
30 30
namespace lemon {
31 31

	
32 32
  /// \brief Reference counted wrapper around cpxenv pointer
33 33
  ///
34 34
  /// The cplex uses environment object which is responsible for
35 35
  /// checking the proper license usage. This class provides a simple
36 36
  /// interface for share the environment object between different
37 37
  /// problems.
38 38
  class CplexEnv {
39 39
    friend class CplexBase;
40 40
  private:
41 41
    cpxenv* _env;
42 42
    mutable int* _cnt;
43 43

	
44 44
  public:
45 45

	
46 46
    /// \brief This exception is thrown when the license check is not
47 47
    /// sufficient
48 48
    class LicenseError : public Exception {
49 49
      friend class CplexEnv;
50 50
    private:
51 51

	
52 52
      LicenseError(int status);
53 53
      char _message[510];
54 54

	
55 55
    public:
56 56

	
57 57
      /// The short error message
58 58
      virtual const char* what() const throw() {
59 59
        return _message;
60 60
      }
61 61
    };
62 62

	
63 63
    /// Constructor
64 64
    CplexEnv();
65 65
    /// Shallow copy constructor
66 66
    CplexEnv(const CplexEnv&);
67 67
    /// Shallow assignement
68 68
    CplexEnv& operator=(const CplexEnv&);
69 69
    /// Destructor
70 70
    virtual ~CplexEnv();
71 71

	
72 72
  protected:
73 73

	
74 74
    cpxenv* cplexEnv() { return _env; }
75 75
    const cpxenv* cplexEnv() const { return _env; }
76 76
  };
77 77

	
78 78
  /// \brief Base interface for the CPLEX LP and MIP solver
79 79
  ///
80 80
  /// This class implements the common interface of the CPLEX LP and
81 81
  /// MIP solvers.
82 82
  /// \ingroup lp_group
83 83
  class CplexBase : virtual public LpBase {
84 84
  protected:
85 85

	
86 86
    CplexEnv _env;
87 87
    cpxlp* _prob;
88 88

	
89 89
    CplexBase();
90 90
    CplexBase(const CplexEnv&);
91 91
    CplexBase(const CplexBase &);
92 92
    virtual ~CplexBase();
93 93

	
94 94
    virtual int _addCol();
95 95
    virtual int _addRow();
96
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
96 97

	
97 98
    virtual void _eraseCol(int i);
98 99
    virtual void _eraseRow(int i);
99 100

	
100 101
    virtual void _eraseColId(int i);
101 102
    virtual void _eraseRowId(int i);
102 103

	
103 104
    virtual void _getColName(int col, std::string& name) const;
104 105
    virtual void _setColName(int col, const std::string& name);
105 106
    virtual int _colByName(const std::string& name) const;
106 107

	
107 108
    virtual void _getRowName(int row, std::string& name) const;
108 109
    virtual void _setRowName(int row, const std::string& name);
109 110
    virtual int _rowByName(const std::string& name) const;
110 111

	
111 112
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
112 113
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
113 114

	
114 115
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
115 116
    virtual void _getColCoeffs(int i, InsertIterator b) const;
116 117

	
117 118
    virtual void _setCoeff(int row, int col, Value value);
118 119
    virtual Value _getCoeff(int row, int col) const;
119 120

	
120 121
    virtual void _setColLowerBound(int i, Value value);
121 122
    virtual Value _getColLowerBound(int i) const;
122 123

	
123 124
    virtual void _setColUpperBound(int i, Value value);
124 125
    virtual Value _getColUpperBound(int i) const;
125 126

	
126 127
  private:
127 128
    void _set_row_bounds(int i, Value lb, Value ub);
128 129
  protected:
129 130

	
130 131
    virtual void _setRowLowerBound(int i, Value value);
131 132
    virtual Value _getRowLowerBound(int i) const;
132 133

	
133 134
    virtual void _setRowUpperBound(int i, Value value);
134 135
    virtual Value _getRowUpperBound(int i) const;
135 136

	
136 137
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
137 138
    virtual void _getObjCoeffs(InsertIterator b) const;
138 139

	
139 140
    virtual void _setObjCoeff(int i, Value obj_coef);
140 141
    virtual Value _getObjCoeff(int i) const;
141 142

	
142 143
    virtual void _setSense(Sense sense);
143 144
    virtual Sense _getSense() const;
144 145

	
145 146
    virtual void _clear();
146 147

	
147 148
    virtual void _messageLevel(MessageLevel level);
148 149
    void _applyMessageLevel();
149 150

	
150 151
    bool _message_enabled;
151 152

	
152 153
  public:
153 154

	
154 155
    /// Returns the used \c CplexEnv instance
155 156
    const CplexEnv& env() const { return _env; }
156 157

	
157 158
    /// \brief Returns the const cpxenv pointer
158 159
    ///
159 160
    /// \note The cpxenv might be destructed with the solver.
160 161
    const cpxenv* cplexEnv() const { return _env.cplexEnv(); }
161 162

	
162 163
    /// \brief Returns the const cpxenv pointer
163 164
    ///
164 165
    /// \note The cpxenv might be destructed with the solver.
165 166
    cpxenv* cplexEnv() { return _env.cplexEnv(); }
166 167

	
167 168
    /// Returns the cplex problem object
168 169
    cpxlp* cplexLp() { return _prob; }
169 170
    /// Returns the cplex problem object
170 171
    const cpxlp* cplexLp() const { return _prob; }
171 172

	
172 173
  };
173 174

	
174 175
  /// \brief Interface for the CPLEX LP solver
175 176
  ///
176 177
  /// This class implements an interface for the CPLEX LP solver.
177 178
  ///\ingroup lp_group
178 179
  class CplexLp : public LpSolver, public CplexBase {
179 180
  public:
180 181
    /// \e
181 182
    CplexLp();
182 183
    /// \e
183 184
    CplexLp(const CplexEnv&);
184 185
    /// \e
185 186
    CplexLp(const CplexLp&);
186 187
    /// \e
187 188
    virtual ~CplexLp();
188 189

	
189 190
    /// \e
190 191
    virtual CplexLp* cloneSolver() const;
191 192
    /// \e
192 193
    virtual CplexLp* newSolver() const;
193 194

	
194 195
  private:
195 196

	
196 197
    // these values cannot retrieved element by element
197 198
    mutable std::vector<int> _col_status;
198 199
    mutable std::vector<int> _row_status;
199 200

	
200 201
    mutable std::vector<Value> _primal_ray;
201 202
    mutable std::vector<Value> _dual_ray;
202 203

	
203 204
    void _clear_temporals();
204 205

	
205 206
    SolveExitStatus convertStatus(int status);
206 207

	
207 208
  protected:
208 209

	
209 210
    virtual const char* _solverName() const;
210 211

	
211 212
    virtual SolveExitStatus _solve();
212 213
    virtual Value _getPrimal(int i) const;
213 214
    virtual Value _getDual(int i) const;
214 215
    virtual Value _getPrimalValue() const;
215 216

	
216 217
    virtual VarStatus _getColStatus(int i) const;
217 218
    virtual VarStatus _getRowStatus(int i) const;
218 219

	
219 220
    virtual Value _getPrimalRay(int i) const;
220 221
    virtual Value _getDualRay(int i) const;
221 222

	
222 223
    virtual ProblemType _getPrimalType() const;
223 224
    virtual ProblemType _getDualType() const;
224 225

	
225 226
  public:
226 227

	
227 228
    /// Solve with primal simplex method
228 229
    SolveExitStatus solvePrimal();
229 230

	
230 231
    /// Solve with dual simplex method
231 232
    SolveExitStatus solveDual();
232 233

	
233 234
    /// Solve with barrier method
234 235
    SolveExitStatus solveBarrier();
235 236

	
236 237
  };
237 238

	
238 239
  /// \brief Interface for the CPLEX MIP solver
239 240
  ///
240 241
  /// This class implements an interface for the CPLEX MIP solver.
241 242
  ///\ingroup lp_group
242 243
  class CplexMip : public MipSolver, public CplexBase {
243 244
  public:
244 245
    /// \e
245 246
    CplexMip();
246 247
    /// \e
247 248
    CplexMip(const CplexEnv&);
248 249
    /// \e
249 250
    CplexMip(const CplexMip&);
250 251
    /// \e
251 252
    virtual ~CplexMip();
252 253

	
253 254
    /// \e
254 255
    virtual CplexMip* cloneSolver() const;
255 256
    /// \e
256 257
    virtual CplexMip* newSolver() const;
257 258

	
258 259
  protected:
259 260

	
260 261

	
261 262
    virtual const char* _solverName() const;
262 263

	
263 264
    virtual ColTypes _getColType(int col) const;
264 265
    virtual void _setColType(int col, ColTypes col_type);
265 266

	
266 267
    virtual SolveExitStatus _solve();
267 268
    virtual ProblemType _getType() const;
268 269
    virtual Value _getSol(int i) const;
269 270
    virtual Value _getSolValue() const;
270 271

	
271 272
  };
272 273

	
273 274
} //END OF NAMESPACE LEMON
274 275

	
275 276
#endif //LEMON_CPLEX_H
276 277

	
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-2009
5
 * Copyright (C) 2003-2010
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 52
    ///Instantiates a \c PredMap.
53 53

	
54 54
    ///This function instantiates a \ref PredMap.
55 55
    ///\param g is the digraph, to which we would like to define the
56 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 68
    ///Instantiates a \c ProcessedMap.
68 69

	
69 70
    ///This function instantiates a \ref ProcessedMap.
70 71
    ///\param g is the digraph, to which
71 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
86
    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
85 87
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
86 88
    ///Instantiates a \c ReachedMap.
87 89

	
88 90
    ///This function instantiates a \ref ReachedMap.
89 91
    ///\param g is the digraph, to which
90 92
    ///we would like to define the \ref ReachedMap.
91 93
    static ReachedMap *createReachedMap(const Digraph &g)
92 94
    {
93 95
      return new ReachedMap(g);
94 96
    }
95 97

	
96 98
    ///The type of the map that stores the distances of the nodes.
97 99

	
98 100
    ///The type of the map that stores the distances of the nodes.
99
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
101
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
100 102
    typedef typename Digraph::template NodeMap<int> DistMap;
101 103
    ///Instantiates a \c DistMap.
102 104

	
103 105
    ///This function instantiates a \ref DistMap.
104 106
    ///\param g is the digraph, to which we would like to define the
105 107
    ///\ref DistMap.
106 108
    static DistMap *createDistMap(const Digraph &g)
107 109
    {
108 110
      return new DistMap(g);
109 111
    }
110 112
  };
111 113

	
112 114
  ///%DFS algorithm class.
113 115

	
114 116
  ///\ingroup search
115 117
  ///This class provides an efficient implementation of the %DFS algorithm.
116 118
  ///
117 119
  ///There is also a \ref dfs() "function-type interface" for the DFS
118 120
  ///algorithm, which is convenient in the simplier cases and it can be
119 121
  ///used easier.
120 122
  ///
121 123
  ///\tparam GR The type of the digraph the algorithm runs on.
122 124
  ///The default type is \ref ListDigraph.
125
  ///\tparam TR The traits class that defines various types used by the
126
  ///algorithm. By default, it is \ref DfsDefaultTraits
127
  ///"DfsDefaultTraits<GR>".
128
  ///In most cases, this parameter should not be set directly,
129
  ///consider to use the named template parameters instead.
123 130
#ifdef DOXYGEN
124 131
  template <typename GR,
125 132
            typename TR>
126 133
#else
127 134
  template <typename GR=ListDigraph,
128 135
            typename TR=DfsDefaultTraits<GR> >
129 136
#endif
130 137
  class Dfs {
131 138
  public:
132 139

	
133 140
    ///The type of the digraph the algorithm runs on.
134 141
    typedef typename TR::Digraph Digraph;
135 142

	
136 143
    ///\brief The type of the map that stores the predecessor arcs of the
137 144
    ///DFS paths.
138 145
    typedef typename TR::PredMap PredMap;
139 146
    ///The type of the map that stores the distances of the nodes.
140 147
    typedef typename TR::DistMap DistMap;
141 148
    ///The type of the map that indicates which nodes are reached.
142 149
    typedef typename TR::ReachedMap ReachedMap;
143 150
    ///The type of the map that indicates which nodes are processed.
144 151
    typedef typename TR::ProcessedMap ProcessedMap;
145 152
    ///The type of the paths.
146 153
    typedef PredMapPath<Digraph, PredMap> Path;
147 154

	
148 155
    ///The \ref DfsDefaultTraits "traits class" of the algorithm.
149 156
    typedef TR Traits;
150 157

	
151 158
  private:
152 159

	
153 160
    typedef typename Digraph::Node Node;
154 161
    typedef typename Digraph::NodeIt NodeIt;
155 162
    typedef typename Digraph::Arc Arc;
156 163
    typedef typename Digraph::OutArcIt OutArcIt;
157 164

	
158 165
    //Pointer to the underlying digraph.
159 166
    const Digraph *G;
160 167
    //Pointer to the map of predecessor arcs.
161 168
    PredMap *_pred;
162 169
    //Indicates if _pred is locally allocated (true) or not.
163 170
    bool local_pred;
164 171
    //Pointer to the map of distances.
165 172
    DistMap *_dist;
166 173
    //Indicates if _dist is locally allocated (true) or not.
167 174
    bool local_dist;
168 175
    //Pointer to the map of reached status of the nodes.
169 176
    ReachedMap *_reached;
170 177
    //Indicates if _reached is locally allocated (true) or not.
171 178
    bool local_reached;
172 179
    //Pointer to the map of processed status of the nodes.
173 180
    ProcessedMap *_processed;
174 181
    //Indicates if _processed is locally allocated (true) or not.
175 182
    bool local_processed;
176 183

	
177 184
    std::vector<typename Digraph::OutArcIt> _stack;
178 185
    int _stack_head;
179 186

	
180 187
    //Creates the maps if necessary.
181 188
    void create_maps()
182 189
    {
183 190
      if(!_pred) {
184 191
        local_pred = true;
185 192
        _pred = Traits::createPredMap(*G);
186 193
      }
187 194
      if(!_dist) {
188 195
        local_dist = true;
189 196
        _dist = Traits::createDistMap(*G);
190 197
      }
191 198
      if(!_reached) {
192 199
        local_reached = true;
193 200
        _reached = Traits::createReachedMap(*G);
194 201
      }
195 202
      if(!_processed) {
196 203
        local_processed = true;
197 204
        _processed = Traits::createProcessedMap(*G);
198 205
      }
199 206
    }
200 207

	
201 208
  protected:
202 209

	
203 210
    Dfs() {}
204 211

	
205 212
  public:
206 213

	
207 214
    typedef Dfs Create;
208 215

	
209 216
    ///\name Named Template Parameters
210 217

	
211 218
    ///@{
212 219

	
213 220
    template <class T>
214 221
    struct SetPredMapTraits : public Traits {
215 222
      typedef T PredMap;
216 223
      static PredMap *createPredMap(const Digraph &)
217 224
      {
218 225
        LEMON_ASSERT(false, "PredMap is not initialized");
219 226
        return 0; // ignore warnings
220 227
      }
221 228
    };
222 229
    ///\brief \ref named-templ-param "Named parameter" for setting
223 230
    ///\c PredMap type.
224 231
    ///
225 232
    ///\ref named-templ-param "Named parameter" for setting
226 233
    ///\c PredMap type.
227
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
234
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
228 235
    template <class T>
229 236
    struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
230 237
      typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
231 238
    };
232 239

	
233 240
    template <class T>
234 241
    struct SetDistMapTraits : public Traits {
235 242
      typedef T DistMap;
236 243
      static DistMap *createDistMap(const Digraph &)
237 244
      {
238 245
        LEMON_ASSERT(false, "DistMap is not initialized");
239 246
        return 0; // ignore warnings
240 247
      }
241 248
    };
242 249
    ///\brief \ref named-templ-param "Named parameter" for setting
243 250
    ///\c DistMap type.
244 251
    ///
245 252
    ///\ref named-templ-param "Named parameter" for setting
246 253
    ///\c DistMap type.
247
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
254
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
248 255
    template <class T>
249 256
    struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
250 257
      typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
251 258
    };
252 259

	
253 260
    template <class T>
254 261
    struct SetReachedMapTraits : public Traits {
255 262
      typedef T ReachedMap;
256 263
      static ReachedMap *createReachedMap(const Digraph &)
257 264
      {
258 265
        LEMON_ASSERT(false, "ReachedMap is not initialized");
259 266
        return 0; // ignore warnings
260 267
      }
261 268
    };
262 269
    ///\brief \ref named-templ-param "Named parameter" for setting
263 270
    ///\c ReachedMap type.
264 271
    ///
265 272
    ///\ref named-templ-param "Named parameter" for setting
266 273
    ///\c ReachedMap type.
267
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
274
    ///It must conform to
275
    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
268 276
    template <class T>
269 277
    struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
270 278
      typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
271 279
    };
272 280

	
273 281
    template <class T>
274 282
    struct SetProcessedMapTraits : public Traits {
275 283
      typedef T ProcessedMap;
276 284
      static ProcessedMap *createProcessedMap(const Digraph &)
277 285
      {
278 286
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
279 287
        return 0; // ignore warnings
280 288
      }
281 289
    };
282 290
    ///\brief \ref named-templ-param "Named parameter" for setting
283 291
    ///\c ProcessedMap type.
284 292
    ///
285 293
    ///\ref named-templ-param "Named parameter" for setting
286 294
    ///\c ProcessedMap type.
287
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
295
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
288 296
    template <class T>
289 297
    struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
290 298
      typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
291 299
    };
292 300

	
293 301
    struct SetStandardProcessedMapTraits : public Traits {
294 302
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
295 303
      static ProcessedMap *createProcessedMap(const Digraph &g)
296 304
      {
297 305
        return new ProcessedMap(g);
298 306
      }
299 307
    };
300 308
    ///\brief \ref named-templ-param "Named parameter" for setting
301 309
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
302 310
    ///
303 311
    ///\ref named-templ-param "Named parameter" for setting
304 312
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
305 313
    ///If you don't set it explicitly, it will be automatically allocated.
306 314
    struct SetStandardProcessedMap :
307 315
      public Dfs< Digraph, SetStandardProcessedMapTraits > {
308 316
      typedef Dfs< Digraph, SetStandardProcessedMapTraits > Create;
309 317
    };
310 318

	
311 319
    ///@}
312 320

	
313 321
  public:
314 322

	
315 323
    ///Constructor.
316 324

	
317 325
    ///Constructor.
318 326
    ///\param g The digraph the algorithm runs on.
319 327
    Dfs(const Digraph &g) :
320 328
      G(&g),
321 329
      _pred(NULL), local_pred(false),
322 330
      _dist(NULL), local_dist(false),
323 331
      _reached(NULL), local_reached(false),
324 332
      _processed(NULL), local_processed(false)
325 333
    { }
326 334

	
327 335
    ///Destructor.
328 336
    ~Dfs()
329 337
    {
330 338
      if(local_pred) delete _pred;
331 339
      if(local_dist) delete _dist;
332 340
      if(local_reached) delete _reached;
333 341
      if(local_processed) delete _processed;
334 342
    }
335 343

	
336 344
    ///Sets the map that stores the predecessor arcs.
337 345

	
338 346
    ///Sets the map that stores the predecessor arcs.
339 347
    ///If you don't use this function before calling \ref run(Node) "run()"
340 348
    ///or \ref init(), an instance will be allocated automatically.
341 349
    ///The destructor deallocates this automatically allocated map,
342 350
    ///of course.
343 351
    ///\return <tt> (*this) </tt>
344 352
    Dfs &predMap(PredMap &m)
345 353
    {
346 354
      if(local_pred) {
347 355
        delete _pred;
348 356
        local_pred=false;
349 357
      }
350 358
      _pred = &m;
351 359
      return *this;
352 360
    }
353 361

	
354 362
    ///Sets the map that indicates which nodes are reached.
355 363

	
356 364
    ///Sets the map that indicates which nodes are reached.
357 365
    ///If you don't use this function before calling \ref run(Node) "run()"
358 366
    ///or \ref init(), an instance will be allocated automatically.
359 367
    ///The destructor deallocates this automatically allocated map,
360 368
    ///of course.
361 369
    ///\return <tt> (*this) </tt>
362 370
    Dfs &reachedMap(ReachedMap &m)
363 371
    {
364 372
      if(local_reached) {
365 373
        delete _reached;
366 374
        local_reached=false;
367 375
      }
368 376
      _reached = &m;
369 377
      return *this;
370 378
    }
371 379

	
372 380
    ///Sets the map that indicates which nodes are processed.
373 381

	
374 382
    ///Sets the map that indicates which nodes are processed.
375 383
    ///If you don't use this function before calling \ref run(Node) "run()"
376 384
    ///or \ref init(), an instance will be allocated automatically.
377 385
    ///The destructor deallocates this automatically allocated map,
378 386
    ///of course.
379 387
    ///\return <tt> (*this) </tt>
380 388
    Dfs &processedMap(ProcessedMap &m)
381 389
    {
382 390
      if(local_processed) {
383 391
        delete _processed;
384 392
        local_processed=false;
385 393
      }
386 394
      _processed = &m;
387 395
      return *this;
388 396
    }
389 397

	
390 398
    ///Sets the map that stores the distances of the nodes.
391 399

	
392 400
    ///Sets the map that stores the distances of the nodes calculated by
393 401
    ///the algorithm.
394 402
    ///If you don't use this function before calling \ref run(Node) "run()"
395 403
    ///or \ref init(), an instance will be allocated automatically.
396 404
    ///The destructor deallocates this automatically allocated map,
397 405
    ///of course.
398 406
    ///\return <tt> (*this) </tt>
399 407
    Dfs &distMap(DistMap &m)
400 408
    {
401 409
      if(local_dist) {
402 410
        delete _dist;
403 411
        local_dist=false;
404 412
      }
405 413
      _dist = &m;
406 414
      return *this;
407 415
    }
408 416

	
409 417
  public:
410 418

	
411 419
    ///\name Execution Control
412 420
    ///The simplest way to execute the DFS algorithm is to use one of the
413 421
    ///member functions called \ref run(Node) "run()".\n
414
    ///If you need more control on the execution, first you have to call
415
    ///\ref init(), then you can add a source node with \ref addSource()
422
    ///If you need better control on the execution, you have to call
423
    ///\ref init() first, then you can add a source node with \ref addSource()
416 424
    ///and perform the actual computation with \ref start().
417 425
    ///This procedure can be repeated if there are nodes that have not
418 426
    ///been reached.
419 427

	
420 428
    ///@{
421 429

	
422 430
    ///\brief Initializes the internal data structures.
423 431
    ///
424 432
    ///Initializes the internal data structures.
425 433
    void init()
426 434
    {
427 435
      create_maps();
428 436
      _stack.resize(countNodes(*G));
429 437
      _stack_head=-1;
430 438
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
431 439
        _pred->set(u,INVALID);
432 440
        _reached->set(u,false);
433 441
        _processed->set(u,false);
434 442
      }
435 443
    }
436 444

	
437 445
    ///Adds a new source node.
438 446

	
439 447
    ///Adds a new source node to the set of nodes to be processed.
440 448
    ///
441 449
    ///\pre The stack must be empty. Otherwise the algorithm gives
442 450
    ///wrong results. (One of the outgoing arcs of all the source nodes
443 451
    ///except for the last one will not be visited and distances will
444 452
    ///also be wrong.)
445 453
    void addSource(Node s)
446 454
    {
447 455
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
448 456
      if(!(*_reached)[s])
449 457
        {
450 458
          _reached->set(s,true);
451 459
          _pred->set(s,INVALID);
452 460
          OutArcIt e(*G,s);
453 461
          if(e!=INVALID) {
454 462
            _stack[++_stack_head]=e;
455 463
            _dist->set(s,_stack_head);
456 464
          }
457 465
          else {
458 466
            _processed->set(s,true);
459 467
            _dist->set(s,0);
460 468
          }
461 469
        }
462 470
    }
463 471

	
464 472
    ///Processes the next arc.
465 473

	
466 474
    ///Processes the next arc.
467 475
    ///
468 476
    ///\return The processed arc.
469 477
    ///
470 478
    ///\pre The stack must not be empty.
471 479
    Arc processNextArc()
472 480
    {
473 481
      Node m;
474 482
      Arc e=_stack[_stack_head];
475 483
      if(!(*_reached)[m=G->target(e)]) {
476 484
        _pred->set(m,e);
477 485
        _reached->set(m,true);
478 486
        ++_stack_head;
479 487
        _stack[_stack_head] = OutArcIt(*G, m);
480 488
        _dist->set(m,_stack_head);
481 489
      }
482 490
      else {
483 491
        m=G->source(e);
484 492
        ++_stack[_stack_head];
485 493
      }
486 494
      while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
487 495
        _processed->set(m,true);
488 496
        --_stack_head;
489 497
        if(_stack_head>=0) {
490 498
          m=G->source(_stack[_stack_head]);
491 499
          ++_stack[_stack_head];
492 500
        }
493 501
      }
494 502
      return e;
495 503
    }
496 504

	
497 505
    ///Next arc to be processed.
498 506

	
499 507
    ///Next arc to be processed.
500 508
    ///
501 509
    ///\return The next arc to be processed or \c INVALID if the stack
502 510
    ///is empty.
503 511
    OutArcIt nextArc() const
504 512
    {
505 513
      return _stack_head>=0?_stack[_stack_head]:INVALID;
506 514
    }
507 515

	
508 516
    ///Returns \c false if there are nodes to be processed.
509 517

	
510 518
    ///Returns \c false if there are nodes to be processed
511 519
    ///in the queue (stack).
512 520
    bool emptyQueue() const { return _stack_head<0; }
513 521

	
514 522
    ///Returns the number of the nodes to be processed.
515 523

	
516 524
    ///Returns the number of the nodes to be processed
517 525
    ///in the queue (stack).
518 526
    int queueSize() const { return _stack_head+1; }
519 527

	
520 528
    ///Executes the algorithm.
521 529

	
522 530
    ///Executes the algorithm.
523 531
    ///
524 532
    ///This method runs the %DFS algorithm from the root node
525 533
    ///in order to compute the DFS path to each node.
526 534
    ///
527 535
    /// The algorithm computes
528 536
    ///- the %DFS tree,
529 537
    ///- the distance of each node from the root in the %DFS tree.
530 538
    ///
531 539
    ///\pre init() must be called and a root node should be
532 540
    ///added with addSource() before using this function.
533 541
    ///
534 542
    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
535 543
    ///\code
536 544
    ///  while ( !d.emptyQueue() ) {
537 545
    ///    d.processNextArc();
538 546
    ///  }
539 547
    ///\endcode
540 548
    void start()
541 549
    {
542 550
      while ( !emptyQueue() ) processNextArc();
543 551
    }
544 552

	
545 553
    ///Executes the algorithm until the given target node is reached.
546 554

	
547 555
    ///Executes the algorithm until the given target node is reached.
548 556
    ///
549 557
    ///This method runs the %DFS algorithm from the root node
550 558
    ///in order to compute the DFS path to \c t.
551 559
    ///
552 560
    ///The algorithm computes
553 561
    ///- the %DFS path to \c t,
554 562
    ///- the distance of \c t from the root in the %DFS tree.
555 563
    ///
556 564
    ///\pre init() must be called and a root node should be
557 565
    ///added with addSource() before using this function.
558 566
    void start(Node t)
559 567
    {
560 568
      while ( !emptyQueue() && !(*_reached)[t] )
561 569
        processNextArc();
562 570
    }
563 571

	
564 572
    ///Executes the algorithm until a condition is met.
565 573

	
566 574
    ///Executes the algorithm until a condition is met.
567 575
    ///
568 576
    ///This method runs the %DFS algorithm from the root node
569 577
    ///until an arc \c a with <tt>am[a]</tt> true is found.
570 578
    ///
571 579
    ///\param am A \c bool (or convertible) arc map. The algorithm
572 580
    ///will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
573 581
    ///
574 582
    ///\return The reached arc \c a with <tt>am[a]</tt> true or
575 583
    ///\c INVALID if no such arc was found.
576 584
    ///
577 585
    ///\pre init() must be called and a root node should be
578 586
    ///added with addSource() before using this function.
579 587
    ///
580 588
    ///\warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
581 589
    ///not a node map.
582 590
    template<class ArcBoolMap>
583 591
    Arc start(const ArcBoolMap &am)
584 592
    {
585 593
      while ( !emptyQueue() && !am[_stack[_stack_head]] )
586 594
        processNextArc();
587 595
      return emptyQueue() ? INVALID : _stack[_stack_head];
588 596
    }
589 597

	
590 598
    ///Runs the algorithm from the given source node.
591 599

	
592 600
    ///This method runs the %DFS algorithm from node \c s
593 601
    ///in order to compute the DFS path to each node.
594 602
    ///
595 603
    ///The algorithm computes
596 604
    ///- the %DFS tree,
597 605
    ///- the distance of each node from the root in the %DFS tree.
598 606
    ///
599 607
    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
600 608
    ///\code
601 609
    ///  d.init();
602 610
    ///  d.addSource(s);
603 611
    ///  d.start();
604 612
    ///\endcode
605 613
    void run(Node s) {
606 614
      init();
607 615
      addSource(s);
608 616
      start();
609 617
    }
610 618

	
611 619
    ///Finds the %DFS path between \c s and \c t.
612 620

	
613 621
    ///This method runs the %DFS algorithm from node \c s
614 622
    ///in order to compute the DFS path to node \c t
615 623
    ///(it stops searching when \c t is processed)
616 624
    ///
617 625
    ///\return \c true if \c t is reachable form \c s.
618 626
    ///
619 627
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is
620 628
    ///just a shortcut of the following code.
621 629
    ///\code
622 630
    ///  d.init();
623 631
    ///  d.addSource(s);
624 632
    ///  d.start(t);
625 633
    ///\endcode
626 634
    bool run(Node s,Node t) {
627 635
      init();
628 636
      addSource(s);
629 637
      start(t);
630 638
      return reached(t);
631 639
    }
632 640

	
633 641
    ///Runs the algorithm to visit all nodes in the digraph.
634 642

	
635
    ///This method runs the %DFS algorithm in order to compute the
636
    ///%DFS path to each node.
637
    ///
638
    ///The algorithm computes
639
    ///- the %DFS tree (forest),
640
    ///- the distance of each node from the root(s) in the %DFS tree.
643
    ///This method runs the %DFS algorithm in order to visit all nodes
644
    ///in the digraph.
641 645
    ///
642 646
    ///\note <tt>d.run()</tt> is just a shortcut of the following code.
643 647
    ///\code
644 648
    ///  d.init();
645 649
    ///  for (NodeIt n(digraph); n != INVALID; ++n) {
646 650
    ///    if (!d.reached(n)) {
647 651
    ///      d.addSource(n);
648 652
    ///      d.start();
649 653
    ///    }
650 654
    ///  }
651 655
    ///\endcode
652 656
    void run() {
653 657
      init();
654 658
      for (NodeIt it(*G); it != INVALID; ++it) {
655 659
        if (!reached(it)) {
656 660
          addSource(it);
657 661
          start();
658 662
        }
659 663
      }
660 664
    }
661 665

	
662 666
    ///@}
663 667

	
664 668
    ///\name Query Functions
665 669
    ///The results of the DFS algorithm can be obtained using these
666 670
    ///functions.\n
667 671
    ///Either \ref run(Node) "run()" or \ref start() should be called
668 672
    ///before using them.
669 673

	
670 674
    ///@{
671 675

	
672
    ///The DFS path to a node.
676
    ///The DFS path to the given node.
673 677

	
674
    ///Returns the DFS path to a node.
678
    ///Returns the DFS path to the given node from the root(s).
675 679
    ///
676 680
    ///\warning \c t should be reached from the root(s).
677 681
    ///
678 682
    ///\pre Either \ref run(Node) "run()" or \ref init()
679 683
    ///must be called before using this function.
680 684
    Path path(Node t) const { return Path(*G, *_pred, t); }
681 685

	
682
    ///The distance of a node from the root(s).
686
    ///The distance of the given node from the root(s).
683 687

	
684
    ///Returns the distance of a node from the root(s).
688
    ///Returns the distance of the given node from the root(s).
685 689
    ///
686 690
    ///\warning If node \c v is not reached from the root(s), then
687 691
    ///the return value of this function is undefined.
688 692
    ///
689 693
    ///\pre Either \ref run(Node) "run()" or \ref init()
690 694
    ///must be called before using this function.
691 695
    int dist(Node v) const { return (*_dist)[v]; }
692 696

	
693
    ///Returns the 'previous arc' of the %DFS tree for a node.
697
    ///Returns the 'previous arc' of the %DFS tree for the given node.
694 698

	
695 699
    ///This function returns the 'previous arc' of the %DFS tree for the
696 700
    ///node \c v, i.e. it returns the last arc of a %DFS path from a
697 701
    ///root to \c v. It is \c INVALID if \c v is not reached from the
698 702
    ///root(s) or if \c v is a root.
699 703
    ///
700 704
    ///The %DFS tree used here is equal to the %DFS tree used in
701
    ///\ref predNode().
705
    ///\ref predNode() and \ref predMap().
702 706
    ///
703 707
    ///\pre Either \ref run(Node) "run()" or \ref init()
704 708
    ///must be called before using this function.
705 709
    Arc predArc(Node v) const { return (*_pred)[v];}
706 710

	
707
    ///Returns the 'previous node' of the %DFS tree.
711
    ///Returns the 'previous node' of the %DFS tree for the given node.
708 712

	
709 713
    ///This function returns the 'previous node' of the %DFS
710 714
    ///tree for the node \c v, i.e. it returns the last but one node
711
    ///from a %DFS path from a root to \c v. It is \c INVALID
715
    ///of a %DFS path from a root to \c v. It is \c INVALID
712 716
    ///if \c v is not reached from the root(s) or if \c v is a root.
713 717
    ///
714 718
    ///The %DFS tree used here is equal to the %DFS tree used in
715
    ///\ref predArc().
719
    ///\ref predArc() and \ref predMap().
716 720
    ///
717 721
    ///\pre Either \ref run(Node) "run()" or \ref init()
718 722
    ///must be called before using this function.
719 723
    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
720 724
                                  G->source((*_pred)[v]); }
721 725

	
722 726
    ///\brief Returns a const reference to the node map that stores the
723 727
    ///distances of the nodes.
724 728
    ///
725 729
    ///Returns a const reference to the node map that stores the
726 730
    ///distances of the nodes calculated by the algorithm.
727 731
    ///
728 732
    ///\pre Either \ref run(Node) "run()" or \ref init()
729 733
    ///must be called before using this function.
730 734
    const DistMap &distMap() const { return *_dist;}
731 735

	
732 736
    ///\brief Returns a const reference to the node map that stores the
733 737
    ///predecessor arcs.
734 738
    ///
735 739
    ///Returns a const reference to the node map that stores the predecessor
736
    ///arcs, which form the DFS tree.
740
    ///arcs, which form the DFS tree (forest).
737 741
    ///
738 742
    ///\pre Either \ref run(Node) "run()" or \ref init()
739 743
    ///must be called before using this function.
740 744
    const PredMap &predMap() const { return *_pred;}
741 745

	
742
    ///Checks if a node is reached from the root(s).
746
    ///Checks if the given node. node is reached from the root(s).
743 747

	
744 748
    ///Returns \c true if \c v is reached from the root(s).
745 749
    ///
746 750
    ///\pre Either \ref run(Node) "run()" or \ref init()
747 751
    ///must be called before using this function.
748 752
    bool reached(Node v) const { return (*_reached)[v]; }
749 753

	
750 754
    ///@}
751 755
  };
752 756

	
753 757
  ///Default traits class of dfs() function.
754 758

	
755 759
  ///Default traits class of dfs() function.
756 760
  ///\tparam GR Digraph type.
757 761
  template<class GR>
758 762
  struct DfsWizardDefaultTraits
759 763
  {
760 764
    ///The type of the digraph the algorithm runs on.
761 765
    typedef GR Digraph;
762 766

	
763 767
    ///\brief The type of the map that stores the predecessor
764 768
    ///arcs of the %DFS paths.
765 769
    ///
766 770
    ///The type of the map that stores the predecessor
767 771
    ///arcs of the %DFS paths.
768
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
772
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
769 773
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
770 774
    ///Instantiates a PredMap.
771 775

	
772 776
    ///This function instantiates a PredMap.
773 777
    ///\param g is the digraph, to which we would like to define the
774 778
    ///PredMap.
775 779
    static PredMap *createPredMap(const Digraph &g)
776 780
    {
777 781
      return new PredMap(g);
778 782
    }
779 783

	
780 784
    ///The type of the map that indicates which nodes are processed.
781 785

	
782 786
    ///The type of the map that indicates which nodes are processed.
783
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
784
    ///By default it is a NullMap.
787
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
788
    ///By default, it is a NullMap.
785 789
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
786 790
    ///Instantiates a ProcessedMap.
787 791

	
788 792
    ///This function instantiates a ProcessedMap.
789 793
    ///\param g is the digraph, to which
790 794
    ///we would like to define the ProcessedMap.
791 795
#ifdef DOXYGEN
792 796
    static ProcessedMap *createProcessedMap(const Digraph &g)
793 797
#else
794 798
    static ProcessedMap *createProcessedMap(const Digraph &)
795 799
#endif
796 800
    {
797 801
      return new ProcessedMap();
798 802
    }
799 803

	
800 804
    ///The type of the map that indicates which nodes are reached.
801 805

	
802 806
    ///The type of the map that indicates which nodes are reached.
803
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
807
    ///It must conform to
808
    ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
804 809
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
805 810
    ///Instantiates a ReachedMap.
806 811

	
807 812
    ///This function instantiates a ReachedMap.
808 813
    ///\param g is the digraph, to which
809 814
    ///we would like to define the ReachedMap.
810 815
    static ReachedMap *createReachedMap(const Digraph &g)
811 816
    {
812 817
      return new ReachedMap(g);
813 818
    }
814 819

	
815 820
    ///The type of the map that stores the distances of the nodes.
816 821

	
817 822
    ///The type of the map that stores the distances of the nodes.
818
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
823
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
819 824
    typedef typename Digraph::template NodeMap<int> DistMap;
820 825
    ///Instantiates a DistMap.
821 826

	
822 827
    ///This function instantiates a DistMap.
823 828
    ///\param g is the digraph, to which we would like to define
824 829
    ///the DistMap
825 830
    static DistMap *createDistMap(const Digraph &g)
826 831
    {
827 832
      return new DistMap(g);
828 833
    }
829 834

	
830 835
    ///The type of the DFS paths.
831 836

	
832 837
    ///The type of the DFS paths.
833
    ///It must meet the \ref concepts::Path "Path" concept.
838
    ///It must conform to the \ref concepts::Path "Path" concept.
834 839
    typedef lemon::Path<Digraph> Path;
835 840
  };
836 841

	
837 842
  /// Default traits class used by DfsWizard
838 843

	
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.
844
  /// Default traits class used by DfsWizard.
845
  /// \tparam GR The type of the digraph.
845 846
  template<class GR>
846 847
  class DfsWizardBase : public DfsWizardDefaultTraits<GR>
847 848
  {
848 849

	
849 850
    typedef DfsWizardDefaultTraits<GR> Base;
850 851
  protected:
851 852
    //The type of the nodes in the digraph.
852 853
    typedef typename Base::Digraph::Node Node;
853 854

	
854 855
    //Pointer to the digraph the algorithm runs on.
855 856
    void *_g;
856 857
    //Pointer to the map of reached nodes.
857 858
    void *_reached;
858 859
    //Pointer to the map of processed nodes.
859 860
    void *_processed;
860 861
    //Pointer to the map of predecessors arcs.
861 862
    void *_pred;
862 863
    //Pointer to the map of distances.
863 864
    void *_dist;
864 865
    //Pointer to the DFS path to the target node.
865 866
    void *_path;
866 867
    //Pointer to the distance of the target node.
867 868
    int *_di;
868 869

	
869 870
    public:
870 871
    /// Constructor.
871 872

	
872
    /// This constructor does not require parameters, therefore it initiates
873
    /// This constructor does not require parameters, it initiates
873 874
    /// all of the attributes to \c 0.
874 875
    DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
875 876
                      _dist(0), _path(0), _di(0) {}
876 877

	
877 878
    /// Constructor.
878 879

	
879 880
    /// This constructor requires one parameter,
880 881
    /// others are initiated to \c 0.
881 882
    /// \param g The digraph the algorithm runs on.
882 883
    DfsWizardBase(const GR &g) :
883 884
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
884 885
      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
885 886

	
886 887
  };
887 888

	
888 889
  /// Auxiliary class for the function-type interface of DFS algorithm.
889 890

	
890 891
  /// This auxiliary class is created to implement the
891 892
  /// \ref dfs() "function-type interface" of \ref Dfs algorithm.
892 893
  /// It does not have own \ref run(Node) "run()" method, it uses the
893 894
  /// functions and features of the plain \ref Dfs.
894 895
  ///
895 896
  /// This class should only be used through the \ref dfs() function,
896 897
  /// which makes it easier to use the algorithm.
898
  ///
899
  /// \tparam TR The traits class that defines various types used by the
900
  /// algorithm.
897 901
  template<class TR>
898 902
  class DfsWizard : public TR
899 903
  {
900 904
    typedef TR Base;
901 905

	
902
    ///The type of the digraph the algorithm runs on.
903 906
    typedef typename TR::Digraph Digraph;
904 907

	
905 908
    typedef typename Digraph::Node Node;
906 909
    typedef typename Digraph::NodeIt NodeIt;
907 910
    typedef typename Digraph::Arc Arc;
908 911
    typedef typename Digraph::OutArcIt OutArcIt;
909 912

	
910
    ///\brief The type of the map that stores the predecessor
911
    ///arcs of the DFS paths.
912 913
    typedef typename TR::PredMap PredMap;
913
    ///\brief The type of the map that stores the distances of the nodes.
914 914
    typedef typename TR::DistMap DistMap;
915
    ///\brief The type of the map that indicates which nodes are reached.
916 915
    typedef typename TR::ReachedMap ReachedMap;
917
    ///\brief The type of the map that indicates which nodes are processed.
918 916
    typedef typename TR::ProcessedMap ProcessedMap;
919
    ///The type of the DFS paths
920 917
    typedef typename TR::Path Path;
921 918

	
922 919
  public:
923 920

	
924 921
    /// Constructor.
925 922
    DfsWizard() : TR() {}
926 923

	
927 924
    /// Constructor that requires parameters.
928 925

	
929 926
    /// Constructor that requires parameters.
930 927
    /// These parameters will be the default values for the traits class.
931 928
    /// \param g The digraph the algorithm runs on.
932 929
    DfsWizard(const Digraph &g) :
933 930
      TR(g) {}
934 931

	
935 932
    ///Copy constructor
936 933
    DfsWizard(const TR &b) : TR(b) {}
937 934

	
938 935
    ~DfsWizard() {}
939 936

	
940 937
    ///Runs DFS algorithm from the given source node.
941 938

	
942 939
    ///This method runs DFS algorithm from node \c s
943 940
    ///in order to compute the DFS path to each node.
944 941
    void run(Node s)
945 942
    {
946 943
      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
947 944
      if (Base::_pred)
948 945
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
949 946
      if (Base::_dist)
950 947
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
951 948
      if (Base::_reached)
952 949
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
953 950
      if (Base::_processed)
954 951
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
955 952
      if (s!=INVALID)
956 953
        alg.run(s);
957 954
      else
958 955
        alg.run();
959 956
    }
960 957

	
961 958
    ///Finds the DFS path between \c s and \c t.
962 959

	
963 960
    ///This method runs DFS algorithm from node \c s
964 961
    ///in order to compute the DFS path to node \c t
965 962
    ///(it stops searching when \c t is processed).
966 963
    ///
967 964
    ///\return \c true if \c t is reachable form \c s.
968 965
    bool run(Node s, Node t)
969 966
    {
970 967
      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
971 968
      if (Base::_pred)
972 969
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
973 970
      if (Base::_dist)
974 971
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
975 972
      if (Base::_reached)
976 973
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
977 974
      if (Base::_processed)
978 975
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
979 976
      alg.run(s,t);
980 977
      if (Base::_path)
981 978
        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
982 979
      if (Base::_di)
983 980
        *Base::_di = alg.dist(t);
984 981
      return alg.reached(t);
985 982
      }
986 983

	
987 984
    ///Runs DFS algorithm to visit all nodes in the digraph.
988 985

	
989
    ///This method runs DFS algorithm in order to compute
990
    ///the DFS path to each node.
986
    ///This method runs DFS algorithm in order to visit all nodes
987
    ///in the digraph.
991 988
    void run()
992 989
    {
993 990
      run(INVALID);
994 991
    }
995 992

	
996 993
    template<class T>
997 994
    struct SetPredMapBase : public Base {
998 995
      typedef T PredMap;
999 996
      static PredMap *createPredMap(const Digraph &) { return 0; };
1000 997
      SetPredMapBase(const TR &b) : TR(b) {}
1001 998
    };
1002
    ///\brief \ref named-func-param "Named parameter"
1003
    ///for setting PredMap object.
999

	
1000
    ///\brief \ref named-templ-param "Named parameter" for setting
1001
    ///the predecessor map.
1004 1002
    ///
1005
    ///\ref named-func-param "Named parameter"
1006
    ///for setting PredMap object.
1003
    ///\ref named-templ-param "Named parameter" function for setting
1004
    ///the map that stores the predecessor arcs of the nodes.
1007 1005
    template<class T>
1008 1006
    DfsWizard<SetPredMapBase<T> > predMap(const T &t)
1009 1007
    {
1010 1008
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1011 1009
      return DfsWizard<SetPredMapBase<T> >(*this);
1012 1010
    }
1013 1011

	
1014 1012
    template<class T>
1015 1013
    struct SetReachedMapBase : public Base {
1016 1014
      typedef T ReachedMap;
1017 1015
      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
1018 1016
      SetReachedMapBase(const TR &b) : TR(b) {}
1019 1017
    };
1020
    ///\brief \ref named-func-param "Named parameter"
1021
    ///for setting ReachedMap object.
1018

	
1019
    ///\brief \ref named-templ-param "Named parameter" for setting
1020
    ///the reached map.
1022 1021
    ///
1023
    /// \ref named-func-param "Named parameter"
1024
    ///for setting ReachedMap object.
1022
    ///\ref named-templ-param "Named parameter" function for setting
1023
    ///the map that indicates which nodes are reached.
1025 1024
    template<class T>
1026 1025
    DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
1027 1026
    {
1028 1027
      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
1029 1028
      return DfsWizard<SetReachedMapBase<T> >(*this);
1030 1029
    }
1031 1030

	
1032 1031
    template<class T>
1033 1032
    struct SetDistMapBase : public Base {
1034 1033
      typedef T DistMap;
1035 1034
      static DistMap *createDistMap(const Digraph &) { return 0; };
1036 1035
      SetDistMapBase(const TR &b) : TR(b) {}
1037 1036
    };
1038
    ///\brief \ref named-func-param "Named parameter"
1039
    ///for setting DistMap object.
1037

	
1038
    ///\brief \ref named-templ-param "Named parameter" for setting
1039
    ///the distance map.
1040 1040
    ///
1041
    /// \ref named-func-param "Named parameter"
1042
    ///for setting DistMap object.
1041
    ///\ref named-templ-param "Named parameter" function for setting
1042
    ///the map that stores the distances of the nodes calculated
1043
    ///by the algorithm.
1043 1044
    template<class T>
1044 1045
    DfsWizard<SetDistMapBase<T> > distMap(const T &t)
1045 1046
    {
1046 1047
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1047 1048
      return DfsWizard<SetDistMapBase<T> >(*this);
1048 1049
    }
1049 1050

	
1050 1051
    template<class T>
1051 1052
    struct SetProcessedMapBase : public Base {
1052 1053
      typedef T ProcessedMap;
1053 1054
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1054 1055
      SetProcessedMapBase(const TR &b) : TR(b) {}
1055 1056
    };
1056
    ///\brief \ref named-func-param "Named parameter"
1057
    ///for setting ProcessedMap object.
1057

	
1058
    ///\brief \ref named-func-param "Named parameter" for setting
1059
    ///the processed map.
1058 1060
    ///
1059
    /// \ref named-func-param "Named parameter"
1060
    ///for setting ProcessedMap object.
1061
    ///\ref named-templ-param "Named parameter" function for setting
1062
    ///the map that indicates which nodes are processed.
1061 1063
    template<class T>
1062 1064
    DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
1063 1065
    {
1064 1066
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1065 1067
      return DfsWizard<SetProcessedMapBase<T> >(*this);
1066 1068
    }
1067 1069

	
1068 1070
    template<class T>
1069 1071
    struct SetPathBase : public Base {
1070 1072
      typedef T Path;
1071 1073
      SetPathBase(const TR &b) : TR(b) {}
1072 1074
    };
1073 1075
    ///\brief \ref named-func-param "Named parameter"
1074 1076
    ///for getting the DFS path to the target node.
1075 1077
    ///
1076 1078
    ///\ref named-func-param "Named parameter"
1077 1079
    ///for getting the DFS path to the target node.
1078 1080
    template<class T>
1079 1081
    DfsWizard<SetPathBase<T> > path(const T &t)
1080 1082
    {
1081 1083
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1082 1084
      return DfsWizard<SetPathBase<T> >(*this);
1083 1085
    }
1084 1086

	
1085 1087
    ///\brief \ref named-func-param "Named parameter"
1086 1088
    ///for getting the distance of the target node.
1087 1089
    ///
1088 1090
    ///\ref named-func-param "Named parameter"
1089 1091
    ///for getting the distance of the target node.
1090 1092
    DfsWizard dist(const int &d)
1091 1093
    {
1092 1094
      Base::_di=const_cast<int*>(&d);
1093 1095
      return *this;
1094 1096
    }
1095 1097

	
1096 1098
  };
1097 1099

	
1098 1100
  ///Function-type interface for DFS algorithm.
1099 1101

	
1100 1102
  ///\ingroup search
1101 1103
  ///Function-type interface for DFS algorithm.
1102 1104
  ///
1103 1105
  ///This function also has several \ref named-func-param "named parameters",
1104 1106
  ///they are declared as the members of class \ref DfsWizard.
1105 1107
  ///The following examples show how to use these parameters.
1106 1108
  ///\code
1107 1109
  ///  // Compute the DFS tree
1108 1110
  ///  dfs(g).predMap(preds).distMap(dists).run(s);
1109 1111
  ///
1110 1112
  ///  // Compute the DFS path from s to t
1111 1113
  ///  bool reached = dfs(g).path(p).dist(d).run(s,t);
1112 1114
  ///\endcode
1113 1115
  ///\warning Don't forget to put the \ref DfsWizard::run(Node) "run()"
1114 1116
  ///to the end of the parameter list.
1115 1117
  ///\sa DfsWizard
1116 1118
  ///\sa Dfs
1117 1119
  template<class GR>
1118 1120
  DfsWizard<DfsWizardBase<GR> >
1119 1121
  dfs(const GR &digraph)
1120 1122
  {
1121 1123
    return DfsWizard<DfsWizardBase<GR> >(digraph);
1122 1124
  }
1123 1125

	
1124 1126
#ifdef DOXYGEN
1125 1127
  /// \brief Visitor class for DFS.
1126 1128
  ///
1127 1129
  /// This class defines the interface of the DfsVisit events, and
1128 1130
  /// it could be the base of a real visitor class.
1129 1131
  template <typename GR>
1130 1132
  struct DfsVisitor {
1131 1133
    typedef GR Digraph;
1132 1134
    typedef typename Digraph::Arc Arc;
1133 1135
    typedef typename Digraph::Node Node;
1134 1136
    /// \brief Called for the source node of the DFS.
1135 1137
    ///
1136 1138
    /// This function is called for the source node of the DFS.
1137 1139
    void start(const Node& node) {}
1138 1140
    /// \brief Called when the source node is leaved.
1139 1141
    ///
1140 1142
    /// This function is called when the source node is leaved.
1141 1143
    void stop(const Node& node) {}
1142 1144
    /// \brief Called when a node is reached first time.
1143 1145
    ///
1144 1146
    /// This function is called when a node is reached first time.
1145 1147
    void reach(const Node& node) {}
1146 1148
    /// \brief Called when an arc reaches a new node.
1147 1149
    ///
1148 1150
    /// This function is called when the DFS finds an arc whose target node
1149 1151
    /// is not reached yet.
1150 1152
    void discover(const Arc& arc) {}
1151 1153
    /// \brief Called when an arc is examined but its target node is
1152 1154
    /// already discovered.
1153 1155
    ///
1154 1156
    /// This function is called when an arc is examined but its target node is
1155 1157
    /// already discovered.
1156 1158
    void examine(const Arc& arc) {}
1157 1159
    /// \brief Called when the DFS steps back from a node.
1158 1160
    ///
1159 1161
    /// This function is called when the DFS steps back from a node.
1160 1162
    void leave(const Node& node) {}
1161 1163
    /// \brief Called when the DFS steps back on an arc.
1162 1164
    ///
1163 1165
    /// This function is called when the DFS steps back on an arc.
1164 1166
    void backtrack(const Arc& arc) {}
1165 1167
  };
1166 1168
#else
1167 1169
  template <typename GR>
1168 1170
  struct DfsVisitor {
1169 1171
    typedef GR Digraph;
1170 1172
    typedef typename Digraph::Arc Arc;
1171 1173
    typedef typename Digraph::Node Node;
1172 1174
    void start(const Node&) {}
1173 1175
    void stop(const Node&) {}
1174 1176
    void reach(const Node&) {}
1175 1177
    void discover(const Arc&) {}
1176 1178
    void examine(const Arc&) {}
1177 1179
    void leave(const Node&) {}
1178 1180
    void backtrack(const Arc&) {}
1179 1181

	
1180 1182
    template <typename _Visitor>
1181 1183
    struct Constraints {
1182 1184
      void constraints() {
1183 1185
        Arc arc;
1184 1186
        Node node;
1185 1187
        visitor.start(node);
1186 1188
        visitor.stop(arc);
1187 1189
        visitor.reach(node);
1188 1190
        visitor.discover(arc);
1189 1191
        visitor.examine(arc);
1190 1192
        visitor.leave(node);
1191 1193
        visitor.backtrack(arc);
1192 1194
      }
1193 1195
      _Visitor& visitor;
1194 1196
    };
1195 1197
  };
1196 1198
#endif
1197 1199

	
1198 1200
  /// \brief Default traits class of DfsVisit class.
1199 1201
  ///
1200 1202
  /// Default traits class of DfsVisit class.
1201 1203
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
1202 1204
  template<class GR>
1203 1205
  struct DfsVisitDefaultTraits {
1204 1206

	
1205 1207
    /// \brief The type of the digraph the algorithm runs on.
1206 1208
    typedef GR Digraph;
1207 1209

	
1208 1210
    /// \brief The type of the map that indicates which nodes are reached.
1209 1211
    ///
1210 1212
    /// The type of the map that indicates which nodes are reached.
1211
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1213
    /// It must conform to the
1214
    /// \ref concepts::ReadWriteMap "ReadWriteMap" concept.
1212 1215
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
1213 1216

	
1214 1217
    /// \brief Instantiates a ReachedMap.
1215 1218
    ///
1216 1219
    /// This function instantiates a ReachedMap.
1217 1220
    /// \param digraph is the digraph, to which
1218 1221
    /// we would like to define the ReachedMap.
1219 1222
    static ReachedMap *createReachedMap(const Digraph &digraph) {
1220 1223
      return new ReachedMap(digraph);
1221 1224
    }
1222 1225

	
1223 1226
  };
1224 1227

	
1225 1228
  /// \ingroup search
1226 1229
  ///
1227 1230
  /// \brief DFS algorithm class with visitor interface.
1228 1231
  ///
1229 1232
  /// This class provides an efficient implementation of the DFS algorithm
1230 1233
  /// with visitor interface.
1231 1234
  ///
1232 1235
  /// The DfsVisit class provides an alternative interface to the Dfs
1233 1236
  /// class. It works with callback mechanism, the DfsVisit object calls
1234 1237
  /// the member functions of the \c Visitor class on every DFS event.
1235 1238
  ///
1236 1239
  /// This interface of the DFS algorithm should be used in special cases
1237 1240
  /// when extra actions have to be performed in connection with certain
1238 1241
  /// events of the DFS algorithm. Otherwise consider to use Dfs or dfs()
1239 1242
  /// instead.
1240 1243
  ///
1241 1244
  /// \tparam GR The type of the digraph the algorithm runs on.
1242 1245
  /// The default type is \ref ListDigraph.
1243 1246
  /// The value of GR is not used directly by \ref DfsVisit,
1244 1247
  /// it is only passed to \ref DfsVisitDefaultTraits.
1245 1248
  /// \tparam VS The Visitor type that is used by the algorithm.
1246 1249
  /// \ref DfsVisitor "DfsVisitor<GR>" is an empty visitor, which
1247 1250
  /// does not observe the DFS events. If you want to observe the DFS
1248 1251
  /// events, you should implement your own visitor class.
1249
  /// \tparam TR Traits class to set various data types used by the
1250
  /// algorithm. The default traits class is
1251
  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<GR>".
1252
  /// See \ref DfsVisitDefaultTraits for the documentation of
1253
  /// a DFS visit traits class.
1252
  /// \tparam TR The traits class that defines various types used by the
1253
  /// algorithm. By default, it is \ref DfsVisitDefaultTraits
1254
  /// "DfsVisitDefaultTraits<GR>".
1255
  /// In most cases, this parameter should not be set directly,
1256
  /// consider to use the named template parameters instead.
1254 1257
#ifdef DOXYGEN
1255 1258
  template <typename GR, typename VS, typename TR>
1256 1259
#else
1257 1260
  template <typename GR = ListDigraph,
1258 1261
            typename VS = DfsVisitor<GR>,
1259 1262
            typename TR = DfsVisitDefaultTraits<GR> >
1260 1263
#endif
1261 1264
  class DfsVisit {
1262 1265
  public:
1263 1266

	
1264 1267
    ///The traits class.
1265 1268
    typedef TR Traits;
1266 1269

	
1267 1270
    ///The type of the digraph the algorithm runs on.
1268 1271
    typedef typename Traits::Digraph Digraph;
1269 1272

	
1270 1273
    ///The visitor type used by the algorithm.
1271 1274
    typedef VS Visitor;
1272 1275

	
1273 1276
    ///The type of the map that indicates which nodes are reached.
1274 1277
    typedef typename Traits::ReachedMap ReachedMap;
1275 1278

	
1276 1279
  private:
1277 1280

	
1278 1281
    typedef typename Digraph::Node Node;
1279 1282
    typedef typename Digraph::NodeIt NodeIt;
1280 1283
    typedef typename Digraph::Arc Arc;
1281 1284
    typedef typename Digraph::OutArcIt OutArcIt;
1282 1285

	
1283 1286
    //Pointer to the underlying digraph.
1284 1287
    const Digraph *_digraph;
1285 1288
    //Pointer to the visitor object.
1286 1289
    Visitor *_visitor;
1287 1290
    //Pointer to the map of reached status of the nodes.
1288 1291
    ReachedMap *_reached;
1289 1292
    //Indicates if _reached is locally allocated (true) or not.
1290 1293
    bool local_reached;
1291 1294

	
1292 1295
    std::vector<typename Digraph::Arc> _stack;
1293 1296
    int _stack_head;
1294 1297

	
1295 1298
    //Creates the maps if necessary.
1296 1299
    void create_maps() {
1297 1300
      if(!_reached) {
1298 1301
        local_reached = true;
1299 1302
        _reached = Traits::createReachedMap(*_digraph);
1300 1303
      }
1301 1304
    }
1302 1305

	
1303 1306
  protected:
1304 1307

	
1305 1308
    DfsVisit() {}
1306 1309

	
1307 1310
  public:
1308 1311

	
1309 1312
    typedef DfsVisit Create;
1310 1313

	
1311 1314
    /// \name Named Template Parameters
1312 1315

	
1313 1316
    ///@{
1314 1317
    template <class T>
1315 1318
    struct SetReachedMapTraits : public Traits {
1316 1319
      typedef T ReachedMap;
1317 1320
      static ReachedMap *createReachedMap(const Digraph &digraph) {
1318 1321
        LEMON_ASSERT(false, "ReachedMap is not initialized");
1319 1322
        return 0; // ignore warnings
1320 1323
      }
1321 1324
    };
1322 1325
    /// \brief \ref named-templ-param "Named parameter" for setting
1323 1326
    /// ReachedMap type.
1324 1327
    ///
1325 1328
    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
1326 1329
    template <class T>
1327 1330
    struct SetReachedMap : public DfsVisit< Digraph, Visitor,
1328 1331
                                            SetReachedMapTraits<T> > {
1329 1332
      typedef DfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
1330 1333
    };
1331 1334
    ///@}
1332 1335

	
1333 1336
  public:
1334 1337

	
1335 1338
    /// \brief Constructor.
1336 1339
    ///
1337 1340
    /// Constructor.
1338 1341
    ///
1339 1342
    /// \param digraph The digraph the algorithm runs on.
1340 1343
    /// \param visitor The visitor object of the algorithm.
1341 1344
    DfsVisit(const Digraph& digraph, Visitor& visitor)
1342 1345
      : _digraph(&digraph), _visitor(&visitor),
1343 1346
        _reached(0), local_reached(false) {}
1344 1347

	
1345 1348
    /// \brief Destructor.
1346 1349
    ~DfsVisit() {
1347 1350
      if(local_reached) delete _reached;
1348 1351
    }
1349 1352

	
1350 1353
    /// \brief Sets the map that indicates which nodes are reached.
1351 1354
    ///
1352 1355
    /// Sets the map that indicates which nodes are reached.
1353 1356
    /// If you don't use this function before calling \ref run(Node) "run()"
1354 1357
    /// or \ref init(), an instance will be allocated automatically.
1355 1358
    /// The destructor deallocates this automatically allocated map,
1356 1359
    /// of course.
1357 1360
    /// \return <tt> (*this) </tt>
1358 1361
    DfsVisit &reachedMap(ReachedMap &m) {
1359 1362
      if(local_reached) {
1360 1363
        delete _reached;
1361 1364
        local_reached=false;
1362 1365
      }
1363 1366
      _reached = &m;
1364 1367
      return *this;
1365 1368
    }
1366 1369

	
1367 1370
  public:
1368 1371

	
1369 1372
    /// \name Execution Control
1370 1373
    /// The simplest way to execute the DFS algorithm is to use one of the
1371 1374
    /// member functions called \ref run(Node) "run()".\n
1372
    /// If you need more control on the execution, first you have to call
1373
    /// \ref init(), then you can add a source node with \ref addSource()
1375
    /// If you need better control on the execution, you have to call
1376
    /// \ref init() first, then you can add a source node with \ref addSource()
1374 1377
    /// and perform the actual computation with \ref start().
1375 1378
    /// This procedure can be repeated if there are nodes that have not
1376 1379
    /// been reached.
1377 1380

	
1378 1381
    /// @{
1379 1382

	
1380 1383
    /// \brief Initializes the internal data structures.
1381 1384
    ///
1382 1385
    /// Initializes the internal data structures.
1383 1386
    void init() {
1384 1387
      create_maps();
1385 1388
      _stack.resize(countNodes(*_digraph));
1386 1389
      _stack_head = -1;
1387 1390
      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
1388 1391
        _reached->set(u, false);
1389 1392
      }
1390 1393
    }
1391 1394

	
1392 1395
    /// \brief Adds a new source node.
1393 1396
    ///
1394 1397
    /// Adds a new source node to the set of nodes to be processed.
1395 1398
    ///
1396 1399
    /// \pre The stack must be empty. Otherwise the algorithm gives
1397 1400
    /// wrong results. (One of the outgoing arcs of all the source nodes
1398 1401
    /// except for the last one will not be visited and distances will
1399 1402
    /// also be wrong.)
1400 1403
    void addSource(Node s)
1401 1404
    {
1402 1405
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
1403 1406
      if(!(*_reached)[s]) {
1404 1407
          _reached->set(s,true);
1405 1408
          _visitor->start(s);
1406 1409
          _visitor->reach(s);
1407 1410
          Arc e;
1408 1411
          _digraph->firstOut(e, s);
1409 1412
          if (e != INVALID) {
1410 1413
            _stack[++_stack_head] = e;
1411 1414
          } else {
1412 1415
            _visitor->leave(s);
1413 1416
            _visitor->stop(s);
1414 1417
          }
1415 1418
        }
1416 1419
    }
1417 1420

	
1418 1421
    /// \brief Processes the next arc.
1419 1422
    ///
1420 1423
    /// Processes the next arc.
1421 1424
    ///
1422 1425
    /// \return The processed arc.
1423 1426
    ///
1424 1427
    /// \pre The stack must not be empty.
1425 1428
    Arc processNextArc() {
1426 1429
      Arc e = _stack[_stack_head];
1427 1430
      Node m = _digraph->target(e);
1428 1431
      if(!(*_reached)[m]) {
1429 1432
        _visitor->discover(e);
1430 1433
        _visitor->reach(m);
1431 1434
        _reached->set(m, true);
1432 1435
        _digraph->firstOut(_stack[++_stack_head], m);
1433 1436
      } else {
1434 1437
        _visitor->examine(e);
1435 1438
        m = _digraph->source(e);
1436 1439
        _digraph->nextOut(_stack[_stack_head]);
1437 1440
      }
1438 1441
      while (_stack_head>=0 && _stack[_stack_head] == INVALID) {
1439 1442
        _visitor->leave(m);
1440 1443
        --_stack_head;
1441 1444
        if (_stack_head >= 0) {
1442 1445
          _visitor->backtrack(_stack[_stack_head]);
1443 1446
          m = _digraph->source(_stack[_stack_head]);
1444 1447
          _digraph->nextOut(_stack[_stack_head]);
1445 1448
        } else {
1446 1449
          _visitor->stop(m);
1447 1450
        }
1448 1451
      }
1449 1452
      return e;
1450 1453
    }
1451 1454

	
1452 1455
    /// \brief Next arc to be processed.
1453 1456
    ///
1454 1457
    /// Next arc to be processed.
1455 1458
    ///
1456 1459
    /// \return The next arc to be processed or INVALID if the stack is
1457 1460
    /// empty.
1458 1461
    Arc nextArc() const {
1459 1462
      return _stack_head >= 0 ? _stack[_stack_head] : INVALID;
1460 1463
    }
1461 1464

	
1462 1465
    /// \brief Returns \c false if there are nodes
1463 1466
    /// to be processed.
1464 1467
    ///
1465 1468
    /// Returns \c false if there are nodes
1466 1469
    /// to be processed in the queue (stack).
1467 1470
    bool emptyQueue() const { return _stack_head < 0; }
1468 1471

	
1469 1472
    /// \brief Returns the number of the nodes to be processed.
1470 1473
    ///
1471 1474
    /// Returns the number of the nodes to be processed in the queue (stack).
1472 1475
    int queueSize() const { return _stack_head + 1; }
1473 1476

	
1474 1477
    /// \brief Executes the algorithm.
1475 1478
    ///
1476 1479
    /// Executes the algorithm.
1477 1480
    ///
1478 1481
    /// This method runs the %DFS algorithm from the root node
1479 1482
    /// in order to compute the %DFS path to each node.
1480 1483
    ///
1481 1484
    /// The algorithm computes
1482 1485
    /// - the %DFS tree,
1483 1486
    /// - the distance of each node from the root in the %DFS tree.
1484 1487
    ///
1485 1488
    /// \pre init() must be called and a root node should be
1486 1489
    /// added with addSource() before using this function.
1487 1490
    ///
1488 1491
    /// \note <tt>d.start()</tt> is just a shortcut of the following code.
1489 1492
    /// \code
1490 1493
    ///   while ( !d.emptyQueue() ) {
1491 1494
    ///     d.processNextArc();
1492 1495
    ///   }
1493 1496
    /// \endcode
1494 1497
    void start() {
1495 1498
      while ( !emptyQueue() ) processNextArc();
1496 1499
    }
1497 1500

	
1498 1501
    /// \brief Executes the algorithm until the given target node is reached.
1499 1502
    ///
1500 1503
    /// Executes the algorithm until the given target node is reached.
1501 1504
    ///
1502 1505
    /// This method runs the %DFS algorithm from the root node
1503 1506
    /// in order to compute the DFS path to \c t.
1504 1507
    ///
1505 1508
    /// The algorithm computes
1506 1509
    /// - the %DFS path to \c t,
1507 1510
    /// - the distance of \c t from the root in the %DFS tree.
1508 1511
    ///
1509 1512
    /// \pre init() must be called and a root node should be added
1510 1513
    /// with addSource() before using this function.
1511 1514
    void start(Node t) {
1512 1515
      while ( !emptyQueue() && !(*_reached)[t] )
1513 1516
        processNextArc();
1514 1517
    }
1515 1518

	
1516 1519
    /// \brief Executes the algorithm until a condition is met.
1517 1520
    ///
1518 1521
    /// Executes the algorithm until a condition is met.
1519 1522
    ///
1520 1523
    /// This method runs the %DFS algorithm from the root node
1521 1524
    /// until an arc \c a with <tt>am[a]</tt> true is found.
1522 1525
    ///
1523 1526
    /// \param am A \c bool (or convertible) arc map. The algorithm
1524 1527
    /// will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
1525 1528
    ///
1526 1529
    /// \return The reached arc \c a with <tt>am[a]</tt> true or
1527 1530
    /// \c INVALID if no such arc was found.
1528 1531
    ///
1529 1532
    /// \pre init() must be called and a root node should be added
1530 1533
    /// with addSource() before using this function.
1531 1534
    ///
1532 1535
    /// \warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
1533 1536
    /// not a node map.
1534 1537
    template <typename AM>
1535 1538
    Arc start(const AM &am) {
1536 1539
      while ( !emptyQueue() && !am[_stack[_stack_head]] )
1537 1540
        processNextArc();
1538 1541
      return emptyQueue() ? INVALID : _stack[_stack_head];
1539 1542
    }
1540 1543

	
1541 1544
    /// \brief Runs the algorithm from the given source node.
1542 1545
    ///
1543 1546
    /// This method runs the %DFS algorithm from node \c s.
1544 1547
    /// in order to compute the DFS path to each node.
1545 1548
    ///
1546 1549
    /// The algorithm computes
1547 1550
    /// - the %DFS tree,
1548 1551
    /// - the distance of each node from the root in the %DFS tree.
1549 1552
    ///
1550 1553
    /// \note <tt>d.run(s)</tt> is just a shortcut of the following code.
1551 1554
    ///\code
1552 1555
    ///   d.init();
1553 1556
    ///   d.addSource(s);
1554 1557
    ///   d.start();
1555 1558
    ///\endcode
1556 1559
    void run(Node s) {
1557 1560
      init();
1558 1561
      addSource(s);
1559 1562
      start();
1560 1563
    }
1561 1564

	
1562 1565
    /// \brief Finds the %DFS path between \c s and \c t.
1563 1566

	
1564 1567
    /// This method runs the %DFS algorithm from node \c s
1565 1568
    /// in order to compute the DFS path to node \c t
1566 1569
    /// (it stops searching when \c t is processed).
1567 1570
    ///
1568 1571
    /// \return \c true if \c t is reachable form \c s.
1569 1572
    ///
1570 1573
    /// \note Apart from the return value, <tt>d.run(s,t)</tt> is
1571 1574
    /// just a shortcut of the following code.
1572 1575
    ///\code
1573 1576
    ///   d.init();
1574 1577
    ///   d.addSource(s);
1575 1578
    ///   d.start(t);
1576 1579
    ///\endcode
1577 1580
    bool run(Node s,Node t) {
1578 1581
      init();
1579 1582
      addSource(s);
1580 1583
      start(t);
1581 1584
      return reached(t);
1582 1585
    }
1583 1586

	
1584 1587
    /// \brief Runs the algorithm to visit all nodes in the digraph.
1585 1588

	
1586
    /// This method runs the %DFS algorithm in order to
1587
    /// compute the %DFS path to each node.
1588
    ///
1589
    /// The algorithm computes
1590
    /// - the %DFS tree (forest),
1591
    /// - the distance of each node from the root(s) in the %DFS tree.
1589
    /// This method runs the %DFS algorithm in order to visit all nodes
1590
    /// in the digraph.
1592 1591
    ///
1593 1592
    /// \note <tt>d.run()</tt> is just a shortcut of the following code.
1594 1593
    ///\code
1595 1594
    ///   d.init();
1596 1595
    ///   for (NodeIt n(digraph); n != INVALID; ++n) {
1597 1596
    ///     if (!d.reached(n)) {
1598 1597
    ///       d.addSource(n);
1599 1598
    ///       d.start();
1600 1599
    ///     }
1601 1600
    ///   }
1602 1601
    ///\endcode
1603 1602
    void run() {
1604 1603
      init();
1605 1604
      for (NodeIt it(*_digraph); it != INVALID; ++it) {
1606 1605
        if (!reached(it)) {
1607 1606
          addSource(it);
1608 1607
          start();
1609 1608
        }
1610 1609
      }
1611 1610
    }
1612 1611

	
1613 1612
    ///@}
1614 1613

	
1615 1614
    /// \name Query Functions
1616 1615
    /// The results of the DFS algorithm can be obtained using these
1617 1616
    /// functions.\n
1618 1617
    /// Either \ref run(Node) "run()" or \ref start() should be called
1619 1618
    /// before using them.
1620 1619

	
1621 1620
    ///@{
1622 1621

	
1623
    /// \brief Checks if a node is reached from the root(s).
1622
    /// \brief Checks if the given node is reached from the root(s).
1624 1623
    ///
1625 1624
    /// Returns \c true if \c v is reached from the root(s).
1626 1625
    ///
1627 1626
    /// \pre Either \ref run(Node) "run()" or \ref init()
1628 1627
    /// must be called before using this function.
1629 1628
    bool reached(Node v) const { return (*_reached)[v]; }
1630 1629

	
1631 1630
    ///@}
1632 1631

	
1633 1632
  };
1634 1633

	
1635 1634
} //END OF NAMESPACE LEMON
1636 1635

	
1637 1636
#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-2009
5
 * Copyright (C) 2003-2010
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_DIJKSTRA_H
20 20
#define LEMON_DIJKSTRA_H
21 21

	
22 22
///\ingroup shortest_path
23 23
///\file
24 24
///\brief Dijkstra algorithm.
25 25

	
26 26
#include <limits>
27 27
#include <lemon/list_graph.h>
28 28
#include <lemon/bin_heap.h>
29 29
#include <lemon/bits/path_dump.h>
30 30
#include <lemon/core.h>
31 31
#include <lemon/error.h>
32 32
#include <lemon/maps.h>
33 33
#include <lemon/path.h>
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  /// \brief Default operation traits for the Dijkstra algorithm class.
38 38
  ///
39 39
  /// This operation traits class defines all computational operations and
40 40
  /// constants which are used in the Dijkstra algorithm.
41 41
  template <typename V>
42 42
  struct DijkstraDefaultOperationTraits {
43 43
    /// \e
44 44
    typedef V Value;
45 45
    /// \brief Gives back the zero value of the type.
46 46
    static Value zero() {
47 47
      return static_cast<Value>(0);
48 48
    }
49 49
    /// \brief Gives back the sum of the given two elements.
50 50
    static Value plus(const Value& left, const Value& right) {
51 51
      return left + right;
52 52
    }
53 53
    /// \brief Gives back true only if the first value is less than the second.
54 54
    static bool less(const Value& left, const Value& right) {
55 55
      return left < right;
56 56
    }
57 57
  };
58 58

	
59 59
  ///Default traits class of Dijkstra class.
60 60

	
61 61
  ///Default traits class of Dijkstra class.
62 62
  ///\tparam GR The type of the digraph.
63 63
  ///\tparam LEN The type of the length map.
64 64
  template<typename GR, typename LEN>
65 65
  struct DijkstraDefaultTraits
66 66
  {
67 67
    ///The type of the digraph the algorithm runs on.
68 68
    typedef GR Digraph;
69 69

	
70 70
    ///The type of the map that stores the arc lengths.
71 71

	
72 72
    ///The type of the map that stores the arc lengths.
73
    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
73
    ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
74 74
    typedef LEN LengthMap;
75
    ///The type of the length of the arcs.
75
    ///The type of the arc lengths.
76 76
    typedef typename LEN::Value Value;
77 77

	
78 78
    /// Operation traits for %Dijkstra algorithm.
79 79

	
80 80
    /// This class defines the operations that are used in the algorithm.
81 81
    /// \see DijkstraDefaultOperationTraits
82 82
    typedef DijkstraDefaultOperationTraits<Value> OperationTraits;
83 83

	
84 84
    /// The cross reference type used by the heap.
85 85

	
86 86
    /// The cross reference type used by the heap.
87 87
    /// Usually it is \c Digraph::NodeMap<int>.
88 88
    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
89 89
    ///Instantiates a \c HeapCrossRef.
90 90

	
91 91
    ///This function instantiates a \ref HeapCrossRef.
92 92
    /// \param g is the digraph, to which we would like to define the
93 93
    /// \ref HeapCrossRef.
94 94
    static HeapCrossRef *createHeapCrossRef(const Digraph &g)
95 95
    {
96 96
      return new HeapCrossRef(g);
97 97
    }
98 98

	
99 99
    ///The heap type used by the %Dijkstra algorithm.
100 100

	
101 101
    ///The heap type used by the Dijkstra algorithm.
102 102
    ///
103 103
    ///\sa BinHeap
104 104
    ///\sa Dijkstra
105 105
    typedef BinHeap<typename LEN::Value, HeapCrossRef, std::less<Value> > Heap;
106 106
    ///Instantiates a \c Heap.
107 107

	
108 108
    ///This function instantiates a \ref Heap.
109 109
    static Heap *createHeap(HeapCrossRef& r)
110 110
    {
111 111
      return new Heap(r);
112 112
    }
113 113

	
114 114
    ///\brief The type of the map that stores the predecessor
115 115
    ///arcs of the shortest paths.
116 116
    ///
117 117
    ///The type of the map that stores the predecessor
118 118
    ///arcs of the shortest paths.
119
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
119
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
120 120
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
121 121
    ///Instantiates a \c PredMap.
122 122

	
123 123
    ///This function instantiates a \ref PredMap.
124 124
    ///\param g is the digraph, to which we would like to define the
125 125
    ///\ref PredMap.
126 126
    static PredMap *createPredMap(const Digraph &g)
127 127
    {
128 128
      return new PredMap(g);
129 129
    }
130 130

	
131 131
    ///The type of the map that indicates which nodes are processed.
132 132

	
133 133
    ///The type of the map that indicates which nodes are processed.
134
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
135
    ///By default it is a NullMap.
134
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
135
    ///By default, it is a NullMap.
136 136
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
137 137
    ///Instantiates a \c ProcessedMap.
138 138

	
139 139
    ///This function instantiates a \ref ProcessedMap.
140 140
    ///\param g is the digraph, to which
141 141
    ///we would like to define the \ref ProcessedMap.
142 142
#ifdef DOXYGEN
143 143
    static ProcessedMap *createProcessedMap(const Digraph &g)
144 144
#else
145 145
    static ProcessedMap *createProcessedMap(const Digraph &)
146 146
#endif
147 147
    {
148 148
      return new ProcessedMap();
149 149
    }
150 150

	
151 151
    ///The type of the map that stores the distances of the nodes.
152 152

	
153 153
    ///The type of the map that stores the distances of the nodes.
154
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
154
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
155 155
    typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
156 156
    ///Instantiates a \c DistMap.
157 157

	
158 158
    ///This function instantiates a \ref DistMap.
159 159
    ///\param g is the digraph, to which we would like to define
160 160
    ///the \ref DistMap.
161 161
    static DistMap *createDistMap(const Digraph &g)
162 162
    {
163 163
      return new DistMap(g);
164 164
    }
165 165
  };
166 166

	
167 167
  ///%Dijkstra algorithm class.
168 168

	
169 169
  /// \ingroup shortest_path
170 170
  ///This class provides an efficient implementation of the %Dijkstra algorithm.
171 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
  ///
172 176
  ///The arc lengths are passed to the algorithm using a
173 177
  ///\ref concepts::ReadMap "ReadMap",
174 178
  ///so it is easy to change it to any kind of length.
175 179
  ///The type of the length is determined by the
176 180
  ///\ref concepts::ReadMap::Value "Value" of the length map.
177 181
  ///It is also possible to change the underlying priority heap.
178 182
  ///
179 183
  ///There is also a \ref dijkstra() "function-type interface" for the
180 184
  ///%Dijkstra algorithm, which is convenient in the simplier cases and
181 185
  ///it can be used easier.
182 186
  ///
183 187
  ///\tparam GR The type of the digraph the algorithm runs on.
184 188
  ///The default type is \ref ListDigraph.
185 189
  ///\tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
186 190
  ///the lengths of the arcs.
187 191
  ///It is read once for each arc, so the map may involve in
188 192
  ///relatively time consuming process to compute the arc lengths if
189 193
  ///it is necessary. The default map type is \ref
190 194
  ///concepts::Digraph::ArcMap "GR::ArcMap<int>".
195
  ///\tparam TR The traits class that defines various types used by the
196
  ///algorithm. By default, it is \ref DijkstraDefaultTraits
197
  ///"DijkstraDefaultTraits<GR, LEN>".
198
  ///In most cases, this parameter should not be set directly,
199
  ///consider to use the named template parameters instead.
191 200
#ifdef DOXYGEN
192 201
  template <typename GR, typename LEN, typename TR>
193 202
#else
194 203
  template <typename GR=ListDigraph,
195 204
            typename LEN=typename GR::template ArcMap<int>,
196 205
            typename TR=DijkstraDefaultTraits<GR,LEN> >
197 206
#endif
198 207
  class Dijkstra {
199 208
  public:
200 209

	
201 210
    ///The type of the digraph the algorithm runs on.
202 211
    typedef typename TR::Digraph Digraph;
203 212

	
204
    ///The type of the length of the arcs.
205
    typedef typename TR::LengthMap::Value Value;
213
    ///The type of the arc lengths.
214
    typedef typename TR::Value Value;
206 215
    ///The type of the map that stores the arc lengths.
207 216
    typedef typename TR::LengthMap LengthMap;
208 217
    ///\brief The type of the map that stores the predecessor arcs of the
209 218
    ///shortest paths.
210 219
    typedef typename TR::PredMap PredMap;
211 220
    ///The type of the map that stores the distances of the nodes.
212 221
    typedef typename TR::DistMap DistMap;
213 222
    ///The type of the map that indicates which nodes are processed.
214 223
    typedef typename TR::ProcessedMap ProcessedMap;
215 224
    ///The type of the paths.
216 225
    typedef PredMapPath<Digraph, PredMap> Path;
217 226
    ///The cross reference type used for the current heap.
218 227
    typedef typename TR::HeapCrossRef HeapCrossRef;
219 228
    ///The heap type used by the algorithm.
220 229
    typedef typename TR::Heap Heap;
221 230
    ///\brief The \ref DijkstraDefaultOperationTraits "operation traits class"
222 231
    ///of the algorithm.
223 232
    typedef typename TR::OperationTraits OperationTraits;
224 233

	
225 234
    ///The \ref DijkstraDefaultTraits "traits class" of the algorithm.
226 235
    typedef TR Traits;
227 236

	
228 237
  private:
229 238

	
230 239
    typedef typename Digraph::Node Node;
231 240
    typedef typename Digraph::NodeIt NodeIt;
232 241
    typedef typename Digraph::Arc Arc;
233 242
    typedef typename Digraph::OutArcIt OutArcIt;
234 243

	
235 244
    //Pointer to the underlying digraph.
236 245
    const Digraph *G;
237 246
    //Pointer to the length map.
238 247
    const LengthMap *_length;
239 248
    //Pointer to the map of predecessors arcs.
240 249
    PredMap *_pred;
241 250
    //Indicates if _pred is locally allocated (true) or not.
242 251
    bool local_pred;
243 252
    //Pointer to the map of distances.
244 253
    DistMap *_dist;
245 254
    //Indicates if _dist is locally allocated (true) or not.
246 255
    bool local_dist;
247 256
    //Pointer to the map of processed status of the nodes.
248 257
    ProcessedMap *_processed;
249 258
    //Indicates if _processed is locally allocated (true) or not.
250 259
    bool local_processed;
251 260
    //Pointer to the heap cross references.
252 261
    HeapCrossRef *_heap_cross_ref;
253 262
    //Indicates if _heap_cross_ref is locally allocated (true) or not.
254 263
    bool local_heap_cross_ref;
255 264
    //Pointer to the heap.
256 265
    Heap *_heap;
257 266
    //Indicates if _heap is locally allocated (true) or not.
258 267
    bool local_heap;
259 268

	
260 269
    //Creates the maps if necessary.
261 270
    void create_maps()
262 271
    {
263 272
      if(!_pred) {
264 273
        local_pred = true;
265 274
        _pred = Traits::createPredMap(*G);
266 275
      }
267 276
      if(!_dist) {
268 277
        local_dist = true;
269 278
        _dist = Traits::createDistMap(*G);
270 279
      }
271 280
      if(!_processed) {
272 281
        local_processed = true;
273 282
        _processed = Traits::createProcessedMap(*G);
274 283
      }
275 284
      if (!_heap_cross_ref) {
276 285
        local_heap_cross_ref = true;
277 286
        _heap_cross_ref = Traits::createHeapCrossRef(*G);
278 287
      }
279 288
      if (!_heap) {
280 289
        local_heap = true;
281 290
        _heap = Traits::createHeap(*_heap_cross_ref);
282 291
      }
283 292
    }
284 293

	
285 294
  public:
286 295

	
287 296
    typedef Dijkstra Create;
288 297

	
289 298
    ///\name Named Template Parameters
290 299

	
291 300
    ///@{
292 301

	
293 302
    template <class T>
294 303
    struct SetPredMapTraits : public Traits {
295 304
      typedef T PredMap;
296 305
      static PredMap *createPredMap(const Digraph &)
297 306
      {
298 307
        LEMON_ASSERT(false, "PredMap is not initialized");
299 308
        return 0; // ignore warnings
300 309
      }
301 310
    };
302 311
    ///\brief \ref named-templ-param "Named parameter" for setting
303 312
    ///\c PredMap type.
304 313
    ///
305 314
    ///\ref named-templ-param "Named parameter" for setting
306 315
    ///\c PredMap type.
307
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
316
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
308 317
    template <class T>
309 318
    struct SetPredMap
310 319
      : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
311 320
      typedef Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > Create;
312 321
    };
313 322

	
314 323
    template <class T>
315 324
    struct SetDistMapTraits : public Traits {
316 325
      typedef T DistMap;
317 326
      static DistMap *createDistMap(const Digraph &)
318 327
      {
319 328
        LEMON_ASSERT(false, "DistMap is not initialized");
320 329
        return 0; // ignore warnings
321 330
      }
322 331
    };
323 332
    ///\brief \ref named-templ-param "Named parameter" for setting
324 333
    ///\c DistMap type.
325 334
    ///
326 335
    ///\ref named-templ-param "Named parameter" for setting
327 336
    ///\c DistMap type.
328
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
337
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
329 338
    template <class T>
330 339
    struct SetDistMap
331 340
      : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
332 341
      typedef Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > Create;
333 342
    };
334 343

	
335 344
    template <class T>
336 345
    struct SetProcessedMapTraits : public Traits {
337 346
      typedef T ProcessedMap;
338 347
      static ProcessedMap *createProcessedMap(const Digraph &)
339 348
      {
340 349
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
341 350
        return 0; // ignore warnings
342 351
      }
343 352
    };
344 353
    ///\brief \ref named-templ-param "Named parameter" for setting
345 354
    ///\c ProcessedMap type.
346 355
    ///
347 356
    ///\ref named-templ-param "Named parameter" for setting
348 357
    ///\c ProcessedMap type.
349
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
358
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
350 359
    template <class T>
351 360
    struct SetProcessedMap
352 361
      : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
353 362
      typedef Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > Create;
354 363
    };
355 364

	
356 365
    struct SetStandardProcessedMapTraits : public Traits {
357 366
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
358 367
      static ProcessedMap *createProcessedMap(const Digraph &g)
359 368
      {
360 369
        return new ProcessedMap(g);
361 370
      }
362 371
    };
363 372
    ///\brief \ref named-templ-param "Named parameter" for setting
364 373
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
365 374
    ///
366 375
    ///\ref named-templ-param "Named parameter" for setting
367 376
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
368 377
    ///If you don't set it explicitly, it will be automatically allocated.
369 378
    struct SetStandardProcessedMap
370 379
      : public Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits > {
371 380
      typedef Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits >
372 381
      Create;
373 382
    };
374 383

	
375 384
    template <class H, class CR>
376 385
    struct SetHeapTraits : public Traits {
377 386
      typedef CR HeapCrossRef;
378 387
      typedef H Heap;
379 388
      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
380 389
        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
381 390
        return 0; // ignore warnings
382 391
      }
383 392
      static Heap *createHeap(HeapCrossRef &)
384 393
      {
385 394
        LEMON_ASSERT(false, "Heap is not initialized");
386 395
        return 0; // ignore warnings
387 396
      }
388 397
    };
389 398
    ///\brief \ref named-templ-param "Named parameter" for setting
390 399
    ///heap and cross reference types
391 400
    ///
392 401
    ///\ref named-templ-param "Named parameter" for setting heap and cross
393 402
    ///reference types. If this named parameter is used, then external
394 403
    ///heap and cross reference objects must be passed to the algorithm
395 404
    ///using the \ref heap() function before calling \ref run(Node) "run()"
396 405
    ///or \ref init().
397 406
    ///\sa SetStandardHeap
398 407
    template <class H, class CR = typename Digraph::template NodeMap<int> >
399 408
    struct SetHeap
400 409
      : public Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > {
401 410
      typedef Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > Create;
402 411
    };
403 412

	
404 413
    template <class H, class CR>
405 414
    struct SetStandardHeapTraits : public Traits {
406 415
      typedef CR HeapCrossRef;
407 416
      typedef H Heap;
408 417
      static HeapCrossRef *createHeapCrossRef(const Digraph &G) {
409 418
        return new HeapCrossRef(G);
410 419
      }
411 420
      static Heap *createHeap(HeapCrossRef &R)
412 421
      {
413 422
        return new Heap(R);
414 423
      }
415 424
    };
416 425
    ///\brief \ref named-templ-param "Named parameter" for setting
417 426
    ///heap and cross reference types with automatic allocation
418 427
    ///
419 428
    ///\ref named-templ-param "Named parameter" for setting heap and cross
420 429
    ///reference types with automatic allocation.
421 430
    ///They should have standard constructor interfaces to be able to
422 431
    ///automatically created by the algorithm (i.e. the digraph should be
423 432
    ///passed to the constructor of the cross reference and the cross
424 433
    ///reference should be passed to the constructor of the heap).
425
    ///However external heap and cross reference objects could also be
434
    ///However, external heap and cross reference objects could also be
426 435
    ///passed to the algorithm using the \ref heap() function before
427 436
    ///calling \ref run(Node) "run()" or \ref init().
428 437
    ///\sa SetHeap
429 438
    template <class H, class CR = typename Digraph::template NodeMap<int> >
430 439
    struct SetStandardHeap
431 440
      : public Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> > {
432 441
      typedef Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> >
433 442
      Create;
434 443
    };
435 444

	
436 445
    template <class T>
437 446
    struct SetOperationTraitsTraits : public Traits {
438 447
      typedef T OperationTraits;
439 448
    };
440 449

	
441 450
    /// \brief \ref named-templ-param "Named parameter" for setting
442 451
    ///\c OperationTraits type
443 452
    ///
444 453
    ///\ref named-templ-param "Named parameter" for setting
445 454
    ///\c OperationTraits type.
455
    /// For more information, see \ref DijkstraDefaultOperationTraits.
446 456
    template <class T>
447 457
    struct SetOperationTraits
448 458
      : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
449 459
      typedef Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> >
450 460
      Create;
451 461
    };
452 462

	
453 463
    ///@}
454 464

	
455 465
  protected:
456 466

	
457 467
    Dijkstra() {}
458 468

	
459 469
  public:
460 470

	
461 471
    ///Constructor.
462 472

	
463 473
    ///Constructor.
464 474
    ///\param g The digraph the algorithm runs on.
465 475
    ///\param length The length map used by the algorithm.
466 476
    Dijkstra(const Digraph& g, const LengthMap& length) :
467 477
      G(&g), _length(&length),
468 478
      _pred(NULL), local_pred(false),
469 479
      _dist(NULL), local_dist(false),
470 480
      _processed(NULL), local_processed(false),
471 481
      _heap_cross_ref(NULL), local_heap_cross_ref(false),
472 482
      _heap(NULL), local_heap(false)
473 483
    { }
474 484

	
475 485
    ///Destructor.
476 486
    ~Dijkstra()
477 487
    {
478 488
      if(local_pred) delete _pred;
479 489
      if(local_dist) delete _dist;
480 490
      if(local_processed) delete _processed;
481 491
      if(local_heap_cross_ref) delete _heap_cross_ref;
482 492
      if(local_heap) delete _heap;
483 493
    }
484 494

	
485 495
    ///Sets the length map.
486 496

	
487 497
    ///Sets the length map.
488 498
    ///\return <tt> (*this) </tt>
489 499
    Dijkstra &lengthMap(const LengthMap &m)
490 500
    {
491 501
      _length = &m;
492 502
      return *this;
493 503
    }
494 504

	
495 505
    ///Sets the map that stores the predecessor arcs.
496 506

	
497 507
    ///Sets the map that stores the predecessor arcs.
498 508
    ///If you don't use this function before calling \ref run(Node) "run()"
499 509
    ///or \ref init(), an instance will be allocated automatically.
500 510
    ///The destructor deallocates this automatically allocated map,
501 511
    ///of course.
502 512
    ///\return <tt> (*this) </tt>
503 513
    Dijkstra &predMap(PredMap &m)
504 514
    {
505 515
      if(local_pred) {
506 516
        delete _pred;
507 517
        local_pred=false;
508 518
      }
509 519
      _pred = &m;
510 520
      return *this;
511 521
    }
512 522

	
513 523
    ///Sets the map that indicates which nodes are processed.
514 524

	
515 525
    ///Sets the map that indicates which nodes are processed.
516 526
    ///If you don't use this function before calling \ref run(Node) "run()"
517 527
    ///or \ref init(), an instance will be allocated automatically.
518 528
    ///The destructor deallocates this automatically allocated map,
519 529
    ///of course.
520 530
    ///\return <tt> (*this) </tt>
521 531
    Dijkstra &processedMap(ProcessedMap &m)
522 532
    {
523 533
      if(local_processed) {
524 534
        delete _processed;
525 535
        local_processed=false;
526 536
      }
527 537
      _processed = &m;
528 538
      return *this;
529 539
    }
530 540

	
531 541
    ///Sets the map that stores the distances of the nodes.
532 542

	
533 543
    ///Sets the map that stores the distances of the nodes calculated by the
534 544
    ///algorithm.
535 545
    ///If you don't use this function before calling \ref run(Node) "run()"
536 546
    ///or \ref init(), an instance will be allocated automatically.
537 547
    ///The destructor deallocates this automatically allocated map,
538 548
    ///of course.
539 549
    ///\return <tt> (*this) </tt>
540 550
    Dijkstra &distMap(DistMap &m)
541 551
    {
542 552
      if(local_dist) {
543 553
        delete _dist;
544 554
        local_dist=false;
545 555
      }
546 556
      _dist = &m;
547 557
      return *this;
548 558
    }
549 559

	
550 560
    ///Sets the heap and the cross reference used by algorithm.
551 561

	
552 562
    ///Sets the heap and the cross reference used by algorithm.
553 563
    ///If you don't use this function before calling \ref run(Node) "run()"
554 564
    ///or \ref init(), heap and cross reference instances will be
555 565
    ///allocated automatically.
556 566
    ///The destructor deallocates these automatically allocated objects,
557 567
    ///of course.
558 568
    ///\return <tt> (*this) </tt>
559 569
    Dijkstra &heap(Heap& hp, HeapCrossRef &cr)
560 570
    {
561 571
      if(local_heap_cross_ref) {
562 572
        delete _heap_cross_ref;
563 573
        local_heap_cross_ref=false;
564 574
      }
565 575
      _heap_cross_ref = &cr;
566 576
      if(local_heap) {
567 577
        delete _heap;
568 578
        local_heap=false;
569 579
      }
570 580
      _heap = &hp;
571 581
      return *this;
572 582
    }
573 583

	
574 584
  private:
575 585

	
576 586
    void finalizeNodeData(Node v,Value dst)
577 587
    {
578 588
      _processed->set(v,true);
579 589
      _dist->set(v, dst);
580 590
    }
581 591

	
582 592
  public:
583 593

	
584 594
    ///\name Execution Control
585 595
    ///The simplest way to execute the %Dijkstra algorithm is to use
586 596
    ///one of the member functions called \ref run(Node) "run()".\n
587
    ///If you need more control on the execution, first you have to call
588
    ///\ref init(), then you can add several source nodes with
597
    ///If you need better control on the execution, you have to call
598
    ///\ref init() first, then you can add several source nodes with
589 599
    ///\ref addSource(). Finally the actual path computation can be
590 600
    ///performed with one of the \ref start() functions.
591 601

	
592 602
    ///@{
593 603

	
594 604
    ///\brief Initializes the internal data structures.
595 605
    ///
596 606
    ///Initializes the internal data structures.
597 607
    void init()
598 608
    {
599 609
      create_maps();
600 610
      _heap->clear();
601 611
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
602 612
        _pred->set(u,INVALID);
603 613
        _processed->set(u,false);
604 614
        _heap_cross_ref->set(u,Heap::PRE_HEAP);
605 615
      }
606 616
    }
607 617

	
608 618
    ///Adds a new source node.
609 619

	
610 620
    ///Adds a new source node to the priority heap.
611 621
    ///The optional second parameter is the initial distance of the node.
612 622
    ///
613 623
    ///The function checks if the node has already been added to the heap and
614 624
    ///it is pushed to the heap only if either it was not in the heap
615 625
    ///or the shortest path found till then is shorter than \c dst.
616 626
    void addSource(Node s,Value dst=OperationTraits::zero())
617 627
    {
618 628
      if(_heap->state(s) != Heap::IN_HEAP) {
619 629
        _heap->push(s,dst);
620 630
      } else if(OperationTraits::less((*_heap)[s], dst)) {
621 631
        _heap->set(s,dst);
622 632
        _pred->set(s,INVALID);
623 633
      }
624 634
    }
625 635

	
626 636
    ///Processes the next node in the priority heap
627 637

	
628 638
    ///Processes the next node in the priority heap.
629 639
    ///
630 640
    ///\return The processed node.
631 641
    ///
632 642
    ///\warning The priority heap must not be empty.
633 643
    Node processNextNode()
634 644
    {
635 645
      Node v=_heap->top();
636 646
      Value oldvalue=_heap->prio();
637 647
      _heap->pop();
638 648
      finalizeNodeData(v,oldvalue);
639 649

	
640 650
      for(OutArcIt e(*G,v); e!=INVALID; ++e) {
641 651
        Node w=G->target(e);
642 652
        switch(_heap->state(w)) {
643 653
        case Heap::PRE_HEAP:
644 654
          _heap->push(w,OperationTraits::plus(oldvalue, (*_length)[e]));
645 655
          _pred->set(w,e);
646 656
          break;
647 657
        case Heap::IN_HEAP:
648 658
          {
649 659
            Value newvalue = OperationTraits::plus(oldvalue, (*_length)[e]);
650 660
            if ( OperationTraits::less(newvalue, (*_heap)[w]) ) {
651 661
              _heap->decrease(w, newvalue);
652 662
              _pred->set(w,e);
653 663
            }
654 664
          }
655 665
          break;
656 666
        case Heap::POST_HEAP:
657 667
          break;
658 668
        }
659 669
      }
660 670
      return v;
661 671
    }
662 672

	
663 673
    ///The next node to be processed.
664 674

	
665 675
    ///Returns the next node to be processed or \c INVALID if the
666 676
    ///priority heap is empty.
667 677
    Node nextNode() const
668 678
    {
669 679
      return !_heap->empty()?_heap->top():INVALID;
670 680
    }
671 681

	
672 682
    ///Returns \c false if there are nodes to be processed.
673 683

	
674 684
    ///Returns \c false if there are nodes to be processed
675 685
    ///in the priority heap.
676 686
    bool emptyQueue() const { return _heap->empty(); }
677 687

	
678 688
    ///Returns the number of the nodes to be processed.
679 689

	
680 690
    ///Returns the number of the nodes to be processed
681 691
    ///in the priority heap.
682 692
    int queueSize() const { return _heap->size(); }
683 693

	
684 694
    ///Executes the algorithm.
685 695

	
686 696
    ///Executes the algorithm.
687 697
    ///
688 698
    ///This method runs the %Dijkstra algorithm from the root node(s)
689 699
    ///in order to compute the shortest path to each node.
690 700
    ///
691 701
    ///The algorithm computes
692 702
    ///- the shortest path tree (forest),
693 703
    ///- the distance of each node from the root(s).
694 704
    ///
695 705
    ///\pre init() must be called and at least one root node should be
696 706
    ///added with addSource() before using this function.
697 707
    ///
698 708
    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
699 709
    ///\code
700 710
    ///  while ( !d.emptyQueue() ) {
701 711
    ///    d.processNextNode();
702 712
    ///  }
703 713
    ///\endcode
704 714
    void start()
705 715
    {
706 716
      while ( !emptyQueue() ) processNextNode();
707 717
    }
708 718

	
709 719
    ///Executes the algorithm until the given target node is processed.
710 720

	
711 721
    ///Executes the algorithm until the given target node is processed.
712 722
    ///
713 723
    ///This method runs the %Dijkstra algorithm from the root node(s)
714 724
    ///in order to compute the shortest path to \c t.
715 725
    ///
716 726
    ///The algorithm computes
717 727
    ///- the shortest path to \c t,
718 728
    ///- the distance of \c t from the root(s).
719 729
    ///
720 730
    ///\pre init() must be called and at least one root node should be
721 731
    ///added with addSource() before using this function.
722 732
    void start(Node t)
723 733
    {
724 734
      while ( !_heap->empty() && _heap->top()!=t ) processNextNode();
725 735
      if ( !_heap->empty() ) {
726 736
        finalizeNodeData(_heap->top(),_heap->prio());
727 737
        _heap->pop();
728 738
      }
729 739
    }
730 740

	
731 741
    ///Executes the algorithm until a condition is met.
732 742

	
733 743
    ///Executes the algorithm until a condition is met.
734 744
    ///
735 745
    ///This method runs the %Dijkstra algorithm from the root node(s) in
736 746
    ///order to compute the shortest path to a node \c v with
737 747
    /// <tt>nm[v]</tt> true, if such a node can be found.
738 748
    ///
739 749
    ///\param nm A \c bool (or convertible) node map. The algorithm
740 750
    ///will stop when it reaches a node \c v with <tt>nm[v]</tt> true.
741 751
    ///
742 752
    ///\return The reached node \c v with <tt>nm[v]</tt> true or
743 753
    ///\c INVALID if no such node was found.
744 754
    ///
745 755
    ///\pre init() must be called and at least one root node should be
746 756
    ///added with addSource() before using this function.
747 757
    template<class NodeBoolMap>
748 758
    Node start(const NodeBoolMap &nm)
749 759
    {
750 760
      while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
751 761
      if ( _heap->empty() ) return INVALID;
752 762
      finalizeNodeData(_heap->top(),_heap->prio());
753 763
      return _heap->top();
754 764
    }
755 765

	
756 766
    ///Runs the algorithm from the given source node.
757 767

	
758 768
    ///This method runs the %Dijkstra algorithm from node \c s
759 769
    ///in order to compute the shortest path to each node.
760 770
    ///
761 771
    ///The algorithm computes
762 772
    ///- the shortest path tree,
763 773
    ///- the distance of each node from the root.
764 774
    ///
765 775
    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
766 776
    ///\code
767 777
    ///  d.init();
768 778
    ///  d.addSource(s);
769 779
    ///  d.start();
770 780
    ///\endcode
771 781
    void run(Node s) {
772 782
      init();
773 783
      addSource(s);
774 784
      start();
775 785
    }
776 786

	
777 787
    ///Finds the shortest path between \c s and \c t.
778 788

	
779 789
    ///This method runs the %Dijkstra algorithm from node \c s
780 790
    ///in order to compute the shortest path to node \c t
781 791
    ///(it stops searching when \c t is processed).
782 792
    ///
783 793
    ///\return \c true if \c t is reachable form \c s.
784 794
    ///
785 795
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is just a
786 796
    ///shortcut of the following code.
787 797
    ///\code
788 798
    ///  d.init();
789 799
    ///  d.addSource(s);
790 800
    ///  d.start(t);
791 801
    ///\endcode
792 802
    bool run(Node s,Node t) {
793 803
      init();
794 804
      addSource(s);
795 805
      start(t);
796 806
      return (*_heap_cross_ref)[t] == Heap::POST_HEAP;
797 807
    }
798 808

	
799 809
    ///@}
800 810

	
801 811
    ///\name Query Functions
802 812
    ///The results of the %Dijkstra algorithm can be obtained using these
803 813
    ///functions.\n
804
    ///Either \ref run(Node) "run()" or \ref start() should be called
814
    ///Either \ref run(Node) "run()" or \ref init() should be called
805 815
    ///before using them.
806 816

	
807 817
    ///@{
808 818

	
809
    ///The shortest path to a node.
819
    ///The shortest path to the given node.
810 820

	
811
    ///Returns the shortest path to a node.
821
    ///Returns the shortest path to the given node from the root(s).
812 822
    ///
813 823
    ///\warning \c t should be reached from the root(s).
814 824
    ///
815 825
    ///\pre Either \ref run(Node) "run()" or \ref init()
816 826
    ///must be called before using this function.
817 827
    Path path(Node t) const { return Path(*G, *_pred, t); }
818 828

	
819
    ///The distance of a node from the root(s).
829
    ///The distance of the given node from the root(s).
820 830

	
821
    ///Returns the distance of a node from the root(s).
831
    ///Returns the distance of the given node from the root(s).
822 832
    ///
823 833
    ///\warning If node \c v is not reached from the root(s), then
824 834
    ///the return value of this function is undefined.
825 835
    ///
826 836
    ///\pre Either \ref run(Node) "run()" or \ref init()
827 837
    ///must be called before using this function.
828 838
    Value dist(Node v) const { return (*_dist)[v]; }
829 839

	
830
    ///Returns the 'previous arc' of the shortest path tree for a node.
831

	
840
    ///\brief Returns the 'previous arc' of the shortest path tree for
841
    ///the given node.
842
    ///
832 843
    ///This function returns the 'previous arc' of the shortest path
833 844
    ///tree for the node \c v, i.e. it returns the last arc of a
834 845
    ///shortest path from a root to \c v. It is \c INVALID if \c v
835 846
    ///is not reached from the root(s) or if \c v is a root.
836 847
    ///
837 848
    ///The shortest path tree used here is equal to the shortest path
838
    ///tree used in \ref predNode().
849
    ///tree used in \ref predNode() and \ref predMap().
839 850
    ///
840 851
    ///\pre Either \ref run(Node) "run()" or \ref init()
841 852
    ///must be called before using this function.
842 853
    Arc predArc(Node v) const { return (*_pred)[v]; }
843 854

	
844
    ///Returns the 'previous node' of the shortest path tree for a node.
845

	
855
    ///\brief Returns the 'previous node' of the shortest path tree for
856
    ///the given node.
857
    ///
846 858
    ///This function returns the 'previous node' of the shortest path
847 859
    ///tree for the node \c v, i.e. it returns the last but one node
848
    ///from a shortest path from a root to \c v. It is \c INVALID
860
    ///of a shortest path from a root to \c v. It is \c INVALID
849 861
    ///if \c v is not reached from the root(s) or if \c v is a root.
850 862
    ///
851 863
    ///The shortest path tree used here is equal to the shortest path
852
    ///tree used in \ref predArc().
864
    ///tree used in \ref predArc() and \ref predMap().
853 865
    ///
854 866
    ///\pre Either \ref run(Node) "run()" or \ref init()
855 867
    ///must be called before using this function.
856 868
    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
857 869
                                  G->source((*_pred)[v]); }
858 870

	
859 871
    ///\brief Returns a const reference to the node map that stores the
860 872
    ///distances of the nodes.
861 873
    ///
862 874
    ///Returns a const reference to the node map that stores the distances
863 875
    ///of the nodes calculated by the algorithm.
864 876
    ///
865 877
    ///\pre Either \ref run(Node) "run()" or \ref init()
866 878
    ///must be called before using this function.
867 879
    const DistMap &distMap() const { return *_dist;}
868 880

	
869 881
    ///\brief Returns a const reference to the node map that stores the
870 882
    ///predecessor arcs.
871 883
    ///
872 884
    ///Returns a const reference to the node map that stores the predecessor
873
    ///arcs, which form the shortest path tree.
885
    ///arcs, which form the shortest path tree (forest).
874 886
    ///
875 887
    ///\pre Either \ref run(Node) "run()" or \ref init()
876 888
    ///must be called before using this function.
877 889
    const PredMap &predMap() const { return *_pred;}
878 890

	
879
    ///Checks if a node is reached from the root(s).
891
    ///Checks if the given node is reached from the root(s).
880 892

	
881 893
    ///Returns \c true if \c v is reached from the root(s).
882 894
    ///
883 895
    ///\pre Either \ref run(Node) "run()" or \ref init()
884 896
    ///must be called before using this function.
885 897
    bool reached(Node v) const { return (*_heap_cross_ref)[v] !=
886 898
                                        Heap::PRE_HEAP; }
887 899

	
888 900
    ///Checks if a node is processed.
889 901

	
890 902
    ///Returns \c true if \c v is processed, i.e. the shortest
891 903
    ///path to \c v has already found.
892 904
    ///
893 905
    ///\pre Either \ref run(Node) "run()" or \ref init()
894 906
    ///must be called before using this function.
895 907
    bool processed(Node v) const { return (*_heap_cross_ref)[v] ==
896 908
                                          Heap::POST_HEAP; }
897 909

	
898
    ///The current distance of a node from the root(s).
910
    ///The current distance of the given node from the root(s).
899 911

	
900
    ///Returns the current distance of a node from the root(s).
912
    ///Returns the current distance of the given node from the root(s).
901 913
    ///It may be decreased in the following processes.
902 914
    ///
903 915
    ///\pre Either \ref run(Node) "run()" or \ref init()
904 916
    ///must be called before using this function and
905 917
    ///node \c v must be reached but not necessarily processed.
906 918
    Value currentDist(Node v) const {
907 919
      return processed(v) ? (*_dist)[v] : (*_heap)[v];
908 920
    }
909 921

	
910 922
    ///@}
911 923
  };
912 924

	
913 925

	
914 926
  ///Default traits class of dijkstra() function.
915 927

	
916 928
  ///Default traits class of dijkstra() function.
917 929
  ///\tparam GR The type of the digraph.
918 930
  ///\tparam LEN The type of the length map.
919 931
  template<class GR, class LEN>
920 932
  struct DijkstraWizardDefaultTraits
921 933
  {
922 934
    ///The type of the digraph the algorithm runs on.
923 935
    typedef GR Digraph;
924 936
    ///The type of the map that stores the arc lengths.
925 937

	
926 938
    ///The type of the map that stores the arc lengths.
927
    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
939
    ///It must conform to the \ref concepts::ReadMap "ReadMap" concept.
928 940
    typedef LEN LengthMap;
929
    ///The type of the length of the arcs.
941
    ///The type of the arc lengths.
930 942
    typedef typename LEN::Value Value;
931 943

	
932 944
    /// Operation traits for Dijkstra algorithm.
933 945

	
934 946
    /// This class defines the operations that are used in the algorithm.
935 947
    /// \see DijkstraDefaultOperationTraits
936 948
    typedef DijkstraDefaultOperationTraits<Value> OperationTraits;
937 949

	
938 950
    /// The cross reference type used by the heap.
939 951

	
940 952
    /// The cross reference type used by the heap.
941 953
    /// Usually it is \c Digraph::NodeMap<int>.
942 954
    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
943 955
    ///Instantiates a \ref HeapCrossRef.
944 956

	
945 957
    ///This function instantiates a \ref HeapCrossRef.
946 958
    /// \param g is the digraph, to which we would like to define the
947 959
    /// HeapCrossRef.
948 960
    static HeapCrossRef *createHeapCrossRef(const Digraph &g)
949 961
    {
950 962
      return new HeapCrossRef(g);
951 963
    }
952 964

	
953 965
    ///The heap type used by the Dijkstra algorithm.
954 966

	
955 967
    ///The heap type used by the Dijkstra algorithm.
956 968
    ///
957 969
    ///\sa BinHeap
958 970
    ///\sa Dijkstra
959 971
    typedef BinHeap<Value, typename Digraph::template NodeMap<int>,
960 972
                    std::less<Value> > Heap;
961 973

	
962 974
    ///Instantiates a \ref Heap.
963 975

	
964 976
    ///This function instantiates a \ref Heap.
965 977
    /// \param r is the HeapCrossRef which is used.
966 978
    static Heap *createHeap(HeapCrossRef& r)
967 979
    {
968 980
      return new Heap(r);
969 981
    }
970 982

	
971 983
    ///\brief The type of the map that stores the predecessor
972 984
    ///arcs of the shortest paths.
973 985
    ///
974 986
    ///The type of the map that stores the predecessor
975 987
    ///arcs of the shortest paths.
976
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
988
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
977 989
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
978 990
    ///Instantiates a PredMap.
979 991

	
980 992
    ///This function instantiates a PredMap.
981 993
    ///\param g is the digraph, to which we would like to define the
982 994
    ///PredMap.
983 995
    static PredMap *createPredMap(const Digraph &g)
984 996
    {
985 997
      return new PredMap(g);
986 998
    }
987 999

	
988 1000
    ///The type of the map that indicates which nodes are processed.
989 1001

	
990 1002
    ///The type of the map that indicates which nodes are processed.
991
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
992
    ///By default it is a NullMap.
1003
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
1004
    ///By default, it is a NullMap.
993 1005
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
994 1006
    ///Instantiates a ProcessedMap.
995 1007

	
996 1008
    ///This function instantiates a ProcessedMap.
997 1009
    ///\param g is the digraph, to which
998 1010
    ///we would like to define the ProcessedMap.
999 1011
#ifdef DOXYGEN
1000 1012
    static ProcessedMap *createProcessedMap(const Digraph &g)
1001 1013
#else
1002 1014
    static ProcessedMap *createProcessedMap(const Digraph &)
1003 1015
#endif
1004 1016
    {
1005 1017
      return new ProcessedMap();
1006 1018
    }
1007 1019

	
1008 1020
    ///The type of the map that stores the distances of the nodes.
1009 1021

	
1010 1022
    ///The type of the map that stores the distances of the nodes.
1011
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
1023
    ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
1012 1024
    typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
1013 1025
    ///Instantiates a DistMap.
1014 1026

	
1015 1027
    ///This function instantiates a DistMap.
1016 1028
    ///\param g is the digraph, to which we would like to define
1017 1029
    ///the DistMap
1018 1030
    static DistMap *createDistMap(const Digraph &g)
1019 1031
    {
1020 1032
      return new DistMap(g);
1021 1033
    }
1022 1034

	
1023 1035
    ///The type of the shortest paths.
1024 1036

	
1025 1037
    ///The type of the shortest paths.
1026
    ///It must meet the \ref concepts::Path "Path" concept.
1038
    ///It must conform to the \ref concepts::Path "Path" concept.
1027 1039
    typedef lemon::Path<Digraph> Path;
1028 1040
  };
1029 1041

	
1030 1042
  /// Default traits class used by DijkstraWizard
1031 1043

	
1032
  /// To make it easier to use Dijkstra algorithm
1033
  /// we have created a wizard class.
1034
  /// This \ref DijkstraWizard class needs default traits,
1035
  /// as well as the \ref Dijkstra class.
1036
  /// The \ref DijkstraWizardBase is a class to be the default traits of the
1037
  /// \ref DijkstraWizard class.
1044
  /// Default traits class used by DijkstraWizard.
1045
  /// \tparam GR The type of the digraph.
1046
  /// \tparam LEN The type of the length map.
1038 1047
  template<typename GR, typename LEN>
1039 1048
  class DijkstraWizardBase : public DijkstraWizardDefaultTraits<GR,LEN>
1040 1049
  {
1041 1050
    typedef DijkstraWizardDefaultTraits<GR,LEN> Base;
1042 1051
  protected:
1043 1052
    //The type of the nodes in the digraph.
1044 1053
    typedef typename Base::Digraph::Node Node;
1045 1054

	
1046 1055
    //Pointer to the digraph the algorithm runs on.
1047 1056
    void *_g;
1048 1057
    //Pointer to the length map.
1049 1058
    void *_length;
1050 1059
    //Pointer to the map of processed nodes.
1051 1060
    void *_processed;
1052 1061
    //Pointer to the map of predecessors arcs.
1053 1062
    void *_pred;
1054 1063
    //Pointer to the map of distances.
1055 1064
    void *_dist;
1056 1065
    //Pointer to the shortest path to the target node.
1057 1066
    void *_path;
1058 1067
    //Pointer to the distance of the target node.
1059 1068
    void *_di;
1060 1069

	
1061 1070
  public:
1062 1071
    /// Constructor.
1063 1072

	
1064 1073
    /// This constructor does not require parameters, therefore it initiates
1065 1074
    /// all of the attributes to \c 0.
1066 1075
    DijkstraWizardBase() : _g(0), _length(0), _processed(0), _pred(0),
1067 1076
                           _dist(0), _path(0), _di(0) {}
1068 1077

	
1069 1078
    /// Constructor.
1070 1079

	
1071 1080
    /// This constructor requires two parameters,
1072 1081
    /// others are initiated to \c 0.
1073 1082
    /// \param g The digraph the algorithm runs on.
1074 1083
    /// \param l The length map.
1075 1084
    DijkstraWizardBase(const GR &g,const LEN &l) :
1076 1085
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
1077 1086
      _length(reinterpret_cast<void*>(const_cast<LEN*>(&l))),
1078 1087
      _processed(0), _pred(0), _dist(0), _path(0), _di(0) {}
1079 1088

	
1080 1089
  };
1081 1090

	
1082 1091
  /// Auxiliary class for the function-type interface of Dijkstra algorithm.
1083 1092

	
1084 1093
  /// This auxiliary class is created to implement the
1085 1094
  /// \ref dijkstra() "function-type interface" of \ref Dijkstra algorithm.
1086 1095
  /// It does not have own \ref run(Node) "run()" method, it uses the
1087 1096
  /// functions and features of the plain \ref Dijkstra.
1088 1097
  ///
1089 1098
  /// This class should only be used through the \ref dijkstra() function,
1090 1099
  /// which makes it easier to use the algorithm.
1100
  ///
1101
  /// \tparam TR The traits class that defines various types used by the
1102
  /// algorithm.
1091 1103
  template<class TR>
1092 1104
  class DijkstraWizard : public TR
1093 1105
  {
1094 1106
    typedef TR Base;
1095 1107

	
1096
    ///The type of the digraph the algorithm runs on.
1097 1108
    typedef typename TR::Digraph Digraph;
1098 1109

	
1099 1110
    typedef typename Digraph::Node Node;
1100 1111
    typedef typename Digraph::NodeIt NodeIt;
1101 1112
    typedef typename Digraph::Arc Arc;
1102 1113
    typedef typename Digraph::OutArcIt OutArcIt;
1103 1114

	
1104
    ///The type of the map that stores the arc lengths.
1105 1115
    typedef typename TR::LengthMap LengthMap;
1106
    ///The type of the length of the arcs.
1107 1116
    typedef typename LengthMap::Value Value;
1108
    ///\brief The type of the map that stores the predecessor
1109
    ///arcs of the shortest paths.
1110 1117
    typedef typename TR::PredMap PredMap;
1111
    ///The type of the map that stores the distances of the nodes.
1112 1118
    typedef typename TR::DistMap DistMap;
1113
    ///The type of the map that indicates which nodes are processed.
1114 1119
    typedef typename TR::ProcessedMap ProcessedMap;
1115
    ///The type of the shortest paths
1116 1120
    typedef typename TR::Path Path;
1117
    ///The heap type used by the dijkstra algorithm.
1118 1121
    typedef typename TR::Heap Heap;
1119 1122

	
1120 1123
  public:
1121 1124

	
1122 1125
    /// Constructor.
1123 1126
    DijkstraWizard() : TR() {}
1124 1127

	
1125 1128
    /// Constructor that requires parameters.
1126 1129

	
1127 1130
    /// Constructor that requires parameters.
1128 1131
    /// These parameters will be the default values for the traits class.
1129 1132
    /// \param g The digraph the algorithm runs on.
1130 1133
    /// \param l The length map.
1131 1134
    DijkstraWizard(const Digraph &g, const LengthMap &l) :
1132 1135
      TR(g,l) {}
1133 1136

	
1134 1137
    ///Copy constructor
1135 1138
    DijkstraWizard(const TR &b) : TR(b) {}
1136 1139

	
1137 1140
    ~DijkstraWizard() {}
1138 1141

	
1139 1142
    ///Runs Dijkstra algorithm from the given source node.
1140 1143

	
1141 1144
    ///This method runs %Dijkstra algorithm from the given source node
1142 1145
    ///in order to compute the shortest path to each node.
1143 1146
    void run(Node s)
1144 1147
    {
1145 1148
      Dijkstra<Digraph,LengthMap,TR>
1146 1149
        dijk(*reinterpret_cast<const Digraph*>(Base::_g),
1147 1150
             *reinterpret_cast<const LengthMap*>(Base::_length));
1148 1151
      if (Base::_pred)
1149 1152
        dijk.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1150 1153
      if (Base::_dist)
1151 1154
        dijk.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1152 1155
      if (Base::_processed)
1153 1156
        dijk.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1154 1157
      dijk.run(s);
1155 1158
    }
1156 1159

	
1157 1160
    ///Finds the shortest path between \c s and \c t.
1158 1161

	
1159 1162
    ///This method runs the %Dijkstra algorithm from node \c s
1160 1163
    ///in order to compute the shortest path to node \c t
1161 1164
    ///(it stops searching when \c t is processed).
1162 1165
    ///
1163 1166
    ///\return \c true if \c t is reachable form \c s.
1164 1167
    bool run(Node s, Node t)
1165 1168
    {
1166 1169
      Dijkstra<Digraph,LengthMap,TR>
1167 1170
        dijk(*reinterpret_cast<const Digraph*>(Base::_g),
1168 1171
             *reinterpret_cast<const LengthMap*>(Base::_length));
1169 1172
      if (Base::_pred)
1170 1173
        dijk.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
1171 1174
      if (Base::_dist)
1172 1175
        dijk.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
1173 1176
      if (Base::_processed)
1174 1177
        dijk.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
1175 1178
      dijk.run(s,t);
1176 1179
      if (Base::_path)
1177 1180
        *reinterpret_cast<Path*>(Base::_path) = dijk.path(t);
1178 1181
      if (Base::_di)
1179 1182
        *reinterpret_cast<Value*>(Base::_di) = dijk.dist(t);
1180 1183
      return dijk.reached(t);
1181 1184
    }
1182 1185

	
1183 1186
    template<class T>
1184 1187
    struct SetPredMapBase : public Base {
1185 1188
      typedef T PredMap;
1186 1189
      static PredMap *createPredMap(const Digraph &) { return 0; };
1187 1190
      SetPredMapBase(const TR &b) : TR(b) {}
1188 1191
    };
1189
    ///\brief \ref named-func-param "Named parameter"
1190
    ///for setting PredMap object.
1192

	
1193
    ///\brief \ref named-templ-param "Named parameter" for setting
1194
    ///the predecessor map.
1191 1195
    ///
1192
    ///\ref named-func-param "Named parameter"
1193
    ///for setting PredMap object.
1196
    ///\ref named-templ-param "Named parameter" function for setting
1197
    ///the map that stores the predecessor arcs of the nodes.
1194 1198
    template<class T>
1195 1199
    DijkstraWizard<SetPredMapBase<T> > predMap(const T &t)
1196 1200
    {
1197 1201
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
1198 1202
      return DijkstraWizard<SetPredMapBase<T> >(*this);
1199 1203
    }
1200 1204

	
1201 1205
    template<class T>
1202 1206
    struct SetDistMapBase : public Base {
1203 1207
      typedef T DistMap;
1204 1208
      static DistMap *createDistMap(const Digraph &) { return 0; };
1205 1209
      SetDistMapBase(const TR &b) : TR(b) {}
1206 1210
    };
1207
    ///\brief \ref named-func-param "Named parameter"
1208
    ///for setting DistMap object.
1211

	
1212
    ///\brief \ref named-templ-param "Named parameter" for setting
1213
    ///the distance map.
1209 1214
    ///
1210
    ///\ref named-func-param "Named parameter"
1211
    ///for setting DistMap object.
1215
    ///\ref named-templ-param "Named parameter" function for setting
1216
    ///the map that stores the distances of the nodes calculated
1217
    ///by the algorithm.
1212 1218
    template<class T>
1213 1219
    DijkstraWizard<SetDistMapBase<T> > distMap(const T &t)
1214 1220
    {
1215 1221
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1216 1222
      return DijkstraWizard<SetDistMapBase<T> >(*this);
1217 1223
    }
1218 1224

	
1219 1225
    template<class T>
1220 1226
    struct SetProcessedMapBase : public Base {
1221 1227
      typedef T ProcessedMap;
1222 1228
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
1223 1229
      SetProcessedMapBase(const TR &b) : TR(b) {}
1224 1230
    };
1225
    ///\brief \ref named-func-param "Named parameter"
1226
    ///for setting ProcessedMap object.
1231

	
1232
    ///\brief \ref named-func-param "Named parameter" for setting
1233
    ///the processed map.
1227 1234
    ///
1228
    /// \ref named-func-param "Named parameter"
1229
    ///for setting ProcessedMap object.
1235
    ///\ref named-templ-param "Named parameter" function for setting
1236
    ///the map that indicates which nodes are processed.
1230 1237
    template<class T>
1231 1238
    DijkstraWizard<SetProcessedMapBase<T> > processedMap(const T &t)
1232 1239
    {
1233 1240
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
1234 1241
      return DijkstraWizard<SetProcessedMapBase<T> >(*this);
1235 1242
    }
1236 1243

	
1237 1244
    template<class T>
1238 1245
    struct SetPathBase : public Base {
1239 1246
      typedef T Path;
1240 1247
      SetPathBase(const TR &b) : TR(b) {}
1241 1248
    };
1249

	
1242 1250
    ///\brief \ref named-func-param "Named parameter"
1243 1251
    ///for getting the shortest path to the target node.
1244 1252
    ///
1245 1253
    ///\ref named-func-param "Named parameter"
1246 1254
    ///for getting the shortest path to the target node.
1247 1255
    template<class T>
1248 1256
    DijkstraWizard<SetPathBase<T> > path(const T &t)
1249 1257
    {
1250 1258
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1251 1259
      return DijkstraWizard<SetPathBase<T> >(*this);
1252 1260
    }
1253 1261

	
1254 1262
    ///\brief \ref named-func-param "Named parameter"
1255 1263
    ///for getting the distance of the target node.
1256 1264
    ///
1257 1265
    ///\ref named-func-param "Named parameter"
1258 1266
    ///for getting the distance of the target node.
1259 1267
    DijkstraWizard dist(const Value &d)
1260 1268
    {
1261 1269
      Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
1262 1270
      return *this;
1263 1271
    }
1264 1272

	
1265 1273
  };
1266 1274

	
1267 1275
  ///Function-type interface for Dijkstra algorithm.
1268 1276

	
1269 1277
  /// \ingroup shortest_path
1270 1278
  ///Function-type interface for Dijkstra algorithm.
1271 1279
  ///
1272 1280
  ///This function also has several \ref named-func-param "named parameters",
1273 1281
  ///they are declared as the members of class \ref DijkstraWizard.
1274 1282
  ///The following examples show how to use these parameters.
1275 1283
  ///\code
1276 1284
  ///  // Compute shortest path from node s to each node
1277 1285
  ///  dijkstra(g,length).predMap(preds).distMap(dists).run(s);
1278 1286
  ///
1279 1287
  ///  // Compute shortest path from s to t
1280 1288
  ///  bool reached = dijkstra(g,length).path(p).dist(d).run(s,t);
1281 1289
  ///\endcode
1282 1290
  ///\warning Don't forget to put the \ref DijkstraWizard::run(Node) "run()"
1283 1291
  ///to the end of the parameter list.
1284 1292
  ///\sa DijkstraWizard
1285 1293
  ///\sa Dijkstra
1286 1294
  template<typename GR, typename LEN>
1287 1295
  DijkstraWizard<DijkstraWizardBase<GR,LEN> >
1288 1296
  dijkstra(const GR &digraph, const LEN &length)
1289 1297
  {
1290 1298
    return DijkstraWizard<DijkstraWizardBase<GR,LEN> >(digraph,length);
1291 1299
  }
1292 1300

	
1293 1301
} //END OF NAMESPACE LEMON
1294 1302

	
1295 1303
#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 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-2009
5
 * Copyright (C) 2003-2010
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_DIMACS_H
20 20
#define LEMON_DIMACS_H
21 21

	
22 22
#include <iostream>
23 23
#include <string>
24 24
#include <vector>
25 25
#include <limits>
26 26
#include <lemon/maps.h>
27 27
#include <lemon/error.h>
28 28
/// \ingroup dimacs_group
29 29
/// \file
30 30
/// \brief DIMACS file format reader.
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  /// \addtogroup dimacs_group
35 35
  /// @{
36 36

	
37 37
  /// DIMACS file type descriptor.
38 38
  struct DimacsDescriptor
39 39
  {
40 40
    ///\brief DIMACS file type enum
41 41
    ///
42 42
    ///DIMACS file type enum.
43 43
    enum Type {
44 44
      NONE,  ///< Undefined type.
45 45
      MIN,   ///< DIMACS file type for minimum cost flow problems.
46 46
      MAX,   ///< DIMACS file type for maximum flow problems.
47 47
      SP,    ///< DIMACS file type for shostest path problems.
48 48
      MAT    ///< DIMACS file type for plain graphs and matching problems.
49 49
    };
50 50
    ///The file type
51 51
    Type type;
52 52
    ///The number of nodes in the graph
53 53
    int nodeNum;
54 54
    ///The number of edges in the graph
55 55
    int edgeNum;
56 56
    int lineShift;
57 57
    ///Constructor. It sets the type to \c NONE.
58 58
    DimacsDescriptor() : type(NONE) {}
59 59
  };
60 60

	
61 61
  ///Discover the type of a DIMACS file
62 62

	
63 63
  ///This function starts seeking the beginning of the given file for the
64
  ///problem type and size info. 
64
  ///problem type and size info.
65 65
  ///The found data is returned in a special struct that can be evaluated
66 66
  ///and passed to the appropriate reader function.
67 67
  DimacsDescriptor dimacsType(std::istream& is)
68 68
  {
69 69
    DimacsDescriptor r;
70 70
    std::string problem,str;
71 71
    char c;
72 72
    r.lineShift=0;
73 73
    while (is >> c)
74 74
      switch(c)
75 75
        {
76 76
        case 'p':
77 77
          if(is >> problem >> r.nodeNum >> r.edgeNum)
78 78
            {
79 79
              getline(is, str);
80 80
              r.lineShift++;
81 81
              if(problem=="min") r.type=DimacsDescriptor::MIN;
82 82
              else if(problem=="max") r.type=DimacsDescriptor::MAX;
83 83
              else if(problem=="sp") r.type=DimacsDescriptor::SP;
84 84
              else if(problem=="mat") r.type=DimacsDescriptor::MAT;
85 85
              else throw FormatError("Unknown problem type");
86 86
              return r;
87 87
            }
88 88
          else
89 89
            {
90 90
              throw FormatError("Missing or wrong problem type declaration.");
91 91
            }
92 92
          break;
93 93
        case 'c':
94 94
          getline(is, str);
95 95
          r.lineShift++;
96 96
          break;
97 97
        default:
98 98
          throw FormatError("Unknown DIMACS declaration.");
99 99
        }
100 100
    throw FormatError("Missing problem type declaration.");
101 101
  }
102 102

	
103 103

	
104 104
  /// \brief DIMACS minimum cost flow reader function.
105 105
  ///
106 106
  /// This function reads a minimum cost flow instance from DIMACS format,
107 107
  /// i.e. from a DIMACS file having a line starting with
108 108
  /// \code
109 109
  ///   p min
110 110
  /// \endcode
111 111
  /// At the beginning, \c g is cleared by \c g.clear(). The supply
112 112
  /// amount of the nodes are written to the \c supply node map
113 113
  /// (they are signed values). The lower bounds, capacities and costs
114 114
  /// of the arcs are written to the \c lower, \c capacity and \c cost
115 115
  /// arc maps.
116 116
  ///
117 117
  /// If the capacity of an arc is less than the lower bound, it will
118 118
  /// be set to "infinite" instead. The actual value of "infinite" is
119 119
  /// contolled by the \c infty parameter. If it is 0 (the default value),
120 120
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
121 121
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
122 122
  /// a non-zero value, that value will be used as "infinite".
123 123
  ///
124 124
  /// If the file type was previously evaluated by dimacsType(), then
125 125
  /// the descriptor struct should be given by the \c dest parameter.
126 126
  template <typename Digraph, typename LowerMap,
127 127
            typename CapacityMap, typename CostMap,
128 128
            typename SupplyMap>
129 129
  void readDimacsMin(std::istream& is,
130 130
                     Digraph &g,
131 131
                     LowerMap& lower,
132 132
                     CapacityMap& capacity,
133 133
                     CostMap& cost,
134 134
                     SupplyMap& supply,
135 135
                     typename CapacityMap::Value infty = 0,
136 136
                     DimacsDescriptor desc=DimacsDescriptor())
137 137
  {
138 138
    g.clear();
139 139
    std::vector<typename Digraph::Node> nodes;
140 140
    typename Digraph::Arc e;
141 141
    std::string problem, str;
142 142
    char c;
143 143
    int i, j;
144 144
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
145 145
    if(desc.type!=DimacsDescriptor::MIN)
146 146
      throw FormatError("Problem type mismatch");
147 147

	
148 148
    nodes.resize(desc.nodeNum + 1);
149 149
    for (int k = 1; k <= desc.nodeNum; ++k) {
150 150
      nodes[k] = g.addNode();
151 151
      supply.set(nodes[k], 0);
152 152
    }
153 153

	
154 154
    typename SupplyMap::Value sup;
155 155
    typename CapacityMap::Value low;
156 156
    typename CapacityMap::Value cap;
157 157
    typename CostMap::Value co;
158 158
    typedef typename CapacityMap::Value Capacity;
159 159
    if(infty==0)
160 160
      infty = std::numeric_limits<Capacity>::has_infinity ?
161 161
        std::numeric_limits<Capacity>::infinity() :
162 162
        std::numeric_limits<Capacity>::max();
163 163

	
164 164
    while (is >> c) {
165 165
      switch (c) {
166 166
      case 'c': // comment line
167 167
        getline(is, str);
168 168
        break;
169 169
      case 'n': // node definition line
170 170
        is >> i >> sup;
171 171
        getline(is, str);
172 172
        supply.set(nodes[i], sup);
173 173
        break;
174 174
      case 'a': // arc definition line
175 175
        is >> i >> j >> low >> cap >> co;
176 176
        getline(is, str);
177 177
        e = g.addArc(nodes[i], nodes[j]);
178 178
        lower.set(e, low);
179 179
        if (cap >= low)
180 180
          capacity.set(e, cap);
181 181
        else
182 182
          capacity.set(e, infty);
183 183
        cost.set(e, co);
184 184
        break;
185 185
      }
186 186
    }
187 187
  }
188 188

	
189 189
  template<typename Digraph, typename CapacityMap>
190 190
  void _readDimacs(std::istream& is,
191 191
                   Digraph &g,
192 192
                   CapacityMap& capacity,
193 193
                   typename Digraph::Node &s,
194 194
                   typename Digraph::Node &t,
195 195
                   typename CapacityMap::Value infty = 0,
196 196
                   DimacsDescriptor desc=DimacsDescriptor()) {
197 197
    g.clear();
198 198
    s=t=INVALID;
199 199
    std::vector<typename Digraph::Node> nodes;
200 200
    typename Digraph::Arc e;
201 201
    char c, d;
202 202
    int i, j;
203 203
    typename CapacityMap::Value _cap;
204 204
    std::string str;
205 205
    nodes.resize(desc.nodeNum + 1);
206 206
    for (int k = 1; k <= desc.nodeNum; ++k) {
207 207
      nodes[k] = g.addNode();
208 208
    }
209 209
    typedef typename CapacityMap::Value Capacity;
210 210

	
211 211
    if(infty==0)
212 212
      infty = std::numeric_limits<Capacity>::has_infinity ?
213 213
        std::numeric_limits<Capacity>::infinity() :
214 214
        std::numeric_limits<Capacity>::max();
215
 
215

	
216 216
    while (is >> c) {
217 217
      switch (c) {
218 218
      case 'c': // comment line
219 219
        getline(is, str);
220 220
        break;
221 221
      case 'n': // node definition line
222 222
        if (desc.type==DimacsDescriptor::SP) { // shortest path problem
223 223
          is >> i;
224 224
          getline(is, str);
225 225
          s = nodes[i];
226 226
        }
227 227
        if (desc.type==DimacsDescriptor::MAX) { // max flow problem
228 228
          is >> i >> d;
229 229
          getline(is, str);
230 230
          if (d == 's') s = nodes[i];
231 231
          if (d == 't') t = nodes[i];
232 232
        }
233 233
        break;
234 234
      case 'a': // arc definition line
235 235
        if (desc.type==DimacsDescriptor::SP) {
236 236
          is >> i >> j >> _cap;
237 237
          getline(is, str);
238 238
          e = g.addArc(nodes[i], nodes[j]);
239 239
          capacity.set(e, _cap);
240
        } 
240
        }
241 241
        else if (desc.type==DimacsDescriptor::MAX) {
242 242
          is >> i >> j >> _cap;
243 243
          getline(is, str);
244 244
          e = g.addArc(nodes[i], nodes[j]);
245 245
          if (_cap >= 0)
246 246
            capacity.set(e, _cap);
247 247
          else
248 248
            capacity.set(e, infty);
249 249
        }
250 250
        else {
251 251
          is >> i >> j;
252 252
          getline(is, str);
253 253
          g.addArc(nodes[i], nodes[j]);
254 254
        }
255 255
        break;
256 256
      }
257 257
    }
258 258
  }
259 259

	
260 260
  /// \brief DIMACS maximum flow reader function.
261 261
  ///
262 262
  /// This function reads a maximum flow instance from DIMACS format,
263 263
  /// i.e. from a DIMACS file having a line starting with
264 264
  /// \code
265 265
  ///   p max
266 266
  /// \endcode
267 267
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
268 268
  /// capacities are written to the \c capacity arc map and \c s and
269 269
  /// \c t are set to the source and the target nodes.
270 270
  ///
271 271
  /// If the capacity of an arc is negative, it will
272 272
  /// be set to "infinite" instead. The actual value of "infinite" is
273 273
  /// contolled by the \c infty parameter. If it is 0 (the default value),
274 274
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
275 275
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
276 276
  /// a non-zero value, that value will be used as "infinite".
277 277
  ///
278 278
  /// If the file type was previously evaluated by dimacsType(), then
279 279
  /// the descriptor struct should be given by the \c dest parameter.
280 280
  template<typename Digraph, typename CapacityMap>
281 281
  void readDimacsMax(std::istream& is,
282 282
                     Digraph &g,
283 283
                     CapacityMap& capacity,
284 284
                     typename Digraph::Node &s,
285 285
                     typename Digraph::Node &t,
286 286
                     typename CapacityMap::Value infty = 0,
287 287
                     DimacsDescriptor desc=DimacsDescriptor()) {
288 288
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
289 289
    if(desc.type!=DimacsDescriptor::MAX)
290 290
      throw FormatError("Problem type mismatch");
291 291
    _readDimacs(is,g,capacity,s,t,infty,desc);
292 292
  }
293 293

	
294 294
  /// \brief DIMACS shortest path reader function.
295 295
  ///
296 296
  /// This function reads a shortest path instance from DIMACS format,
297 297
  /// i.e. from a DIMACS file having a line starting with
298 298
  /// \code
299 299
  ///   p sp
300 300
  /// \endcode
301 301
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
302 302
  /// lengths are written to the \c length arc map and \c s is set to the
303 303
  /// source node.
304 304
  ///
305 305
  /// If the file type was previously evaluated by dimacsType(), then
306 306
  /// the descriptor struct should be given by the \c dest parameter.
307 307
  template<typename Digraph, typename LengthMap>
308 308
  void readDimacsSp(std::istream& is,
309 309
                    Digraph &g,
310 310
                    LengthMap& length,
311 311
                    typename Digraph::Node &s,
312 312
                    DimacsDescriptor desc=DimacsDescriptor()) {
313 313
    typename Digraph::Node t;
314 314
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
315 315
    if(desc.type!=DimacsDescriptor::SP)
316 316
      throw FormatError("Problem type mismatch");
317 317
    _readDimacs(is, g, length, s, t, 0, desc);
318 318
  }
319 319

	
320 320
  /// \brief DIMACS capacitated digraph reader function.
321 321
  ///
322 322
  /// This function reads an arc capacitated digraph instance from
323 323
  /// DIMACS 'max' or 'sp' format.
324 324
  /// At the beginning, \c g is cleared by \c g.clear()
325 325
  /// and the arc capacities/lengths are written to the \c capacity
326 326
  /// arc map.
327 327
  ///
328 328
  /// In case of the 'max' format, if the capacity of an arc is negative,
329 329
  /// it will
330 330
  /// be set to "infinite" instead. The actual value of "infinite" is
331 331
  /// contolled by the \c infty parameter. If it is 0 (the default value),
332 332
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
333 333
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
334 334
  /// a non-zero value, that value will be used as "infinite".
335 335
  ///
336 336
  /// If the file type was previously evaluated by dimacsType(), then
337 337
  /// the descriptor struct should be given by the \c dest parameter.
338 338
  template<typename Digraph, typename CapacityMap>
339 339
  void readDimacsCap(std::istream& is,
340 340
                     Digraph &g,
341 341
                     CapacityMap& capacity,
342 342
                     typename CapacityMap::Value infty = 0,
343 343
                     DimacsDescriptor desc=DimacsDescriptor()) {
344 344
    typename Digraph::Node u,v;
345 345
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
346 346
    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
347 347
      throw FormatError("Problem type mismatch");
348 348
    _readDimacs(is, g, capacity, u, v, infty, desc);
349 349
  }
350 350

	
351 351
  template<typename Graph>
352 352
  typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
353 353
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
354 354
              dummy<0> = 0)
355 355
  {
356 356
    g.addEdge(s,t);
357 357
  }
358 358
  template<typename Graph>
359 359
  typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
360 360
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
361 361
              dummy<1> = 1)
362 362
  {
363 363
    g.addArc(s,t);
364 364
  }
365
  
365

	
366 366
  /// \brief DIMACS plain (di)graph reader function.
367 367
  ///
368 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 
369
  /// and maps (e.g. a matching instance) from DIMACS format, i.e. from
370 370
  /// DIMACS files having a line starting with
371 371
  /// \code
372 372
  ///   p mat
373 373
  /// \endcode
374 374
  /// At the beginning, \c g is cleared by \c g.clear().
375 375
  ///
376 376
  /// If the file type was previously evaluated by dimacsType(), then
377 377
  /// the descriptor struct should be given by the \c dest parameter.
378 378
  template<typename Graph>
379 379
  void readDimacsMat(std::istream& is, Graph &g,
380 380
                     DimacsDescriptor desc=DimacsDescriptor())
381 381
  {
382 382
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
383 383
    if(desc.type!=DimacsDescriptor::MAT)
384 384
      throw FormatError("Problem type mismatch");
385 385

	
386 386
    g.clear();
387 387
    std::vector<typename Graph::Node> nodes;
388 388
    char c;
389 389
    int i, j;
390 390
    std::string str;
391 391
    nodes.resize(desc.nodeNum + 1);
392 392
    for (int k = 1; k <= desc.nodeNum; ++k) {
393 393
      nodes[k] = g.addNode();
394 394
    }
395
    
395

	
396 396
    while (is >> c) {
397 397
      switch (c) {
398 398
      case 'c': // comment line
399 399
        getline(is, str);
400 400
        break;
401 401
      case 'n': // node definition line
402 402
        break;
403 403
      case 'a': // arc definition line
404 404
        is >> i >> j;
405 405
        getline(is, str);
406 406
        _addArcEdge(g,nodes[i], nodes[j]);
407 407
        break;
408 408
      }
409 409
    }
410 410
  }
411 411

	
412 412
  /// DIMACS plain digraph writer function.
413 413
  ///
414 414
  /// This function writes a digraph without any designated nodes and
415 415
  /// maps into DIMACS format, i.e. into DIMACS file having a line
416 416
  /// starting with
417 417
  /// \code
418 418
  ///   p mat
419 419
  /// \endcode
420 420
  /// If \c comment is not empty, then it will be printed in the first line
421 421
  /// prefixed by 'c'.
422 422
  template<typename Digraph>
423 423
  void writeDimacsMat(std::ostream& os, const Digraph &g,
424 424
                      std::string comment="") {
425 425
    typedef typename Digraph::NodeIt NodeIt;
426 426
    typedef typename Digraph::ArcIt ArcIt;
427 427

	
428 428
    if(!comment.empty())
429 429
      os << "c " << comment << std::endl;
430 430
    os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
431 431

	
432 432
    typename Digraph::template NodeMap<int> nodes(g);
433 433
    int i = 1;
434 434
    for(NodeIt v(g); v != INVALID; ++v) {
435 435
      nodes.set(v, i);
436 436
      ++i;
437 437
    }
438 438
    for(ArcIt e(g); e != INVALID; ++e) {
439 439
      os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
440 440
         << std::endl;
441 441
    }
442 442
  }
443 443

	
444 444
  /// @}
445 445

	
446 446
} //namespace lemon
447 447

	
448 448
#endif //LEMON_DIMACS_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-2010
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_EDGE_SET_H
20 20
#define LEMON_EDGE_SET_H
21 21

	
22 22
#include <lemon/core.h>
23 23
#include <lemon/bits/edge_set_extender.h>
24 24

	
25 25
/// \ingroup graphs
26 26
/// \file
27 27
/// \brief ArcSet and EdgeSet classes.
28 28
///
29 29
/// Graphs which use another graph's node-set as own.
30 30
namespace lemon {
31 31

	
32 32
  template <typename GR>
33 33
  class ListArcSetBase {
34 34
  public:
35 35

	
36 36
    typedef typename GR::Node Node;
37 37
    typedef typename GR::NodeIt NodeIt;
38 38

	
39 39
  protected:
40 40

	
41 41
    struct NodeT {
42 42
      int first_out, first_in;
43 43
      NodeT() : first_out(-1), first_in(-1) {}
44 44
    };
45 45

	
46 46
    typedef typename ItemSetTraits<GR, Node>::
47 47
    template Map<NodeT>::Type NodesImplBase;
48 48

	
49 49
    NodesImplBase* _nodes;
50 50

	
51 51
    struct ArcT {
52 52
      Node source, target;
53 53
      int next_out, next_in;
54 54
      int prev_out, prev_in;
55 55
      ArcT() : prev_out(-1), prev_in(-1) {}
56 56
    };
57 57

	
58 58
    std::vector<ArcT> arcs;
59 59

	
60 60
    int first_arc;
61 61
    int first_free_arc;
62 62

	
63 63
    const GR* _graph;
64 64

	
65 65
    void initalize(const GR& graph, NodesImplBase& nodes) {
66 66
      _graph = &graph;
67 67
      _nodes = &nodes;
68 68
    }
69 69

	
70 70
  public:
71 71

	
72 72
    class Arc {
73 73
      friend class ListArcSetBase<GR>;
74 74
    protected:
75 75
      Arc(int _id) : id(_id) {}
76 76
      int id;
77 77
    public:
78 78
      Arc() {}
79 79
      Arc(Invalid) : id(-1) {}
80 80
      bool operator==(const Arc& arc) const { return id == arc.id; }
81 81
      bool operator!=(const Arc& arc) const { return id != arc.id; }
82 82
      bool operator<(const Arc& arc) const { return id < arc.id; }
83 83
    };
84 84

	
85 85
    ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
86 86

	
87 87
    Node addNode() {
88 88
      LEMON_ASSERT(false,
89 89
        "This graph structure does not support node insertion");
90 90
      return INVALID; // avoid warning
91 91
    }
92 92

	
93 93
    Arc addArc(const Node& u, const Node& v) {
94 94
      int n;
95 95
      if (first_free_arc == -1) {
96 96
        n = arcs.size();
97 97
        arcs.push_back(ArcT());
98 98
      } else {
99 99
        n = first_free_arc;
100 100
        first_free_arc = arcs[first_free_arc].next_in;
101 101
      }
102 102
      arcs[n].next_in = (*_nodes)[v].first_in;
103 103
      if ((*_nodes)[v].first_in != -1) {
104 104
        arcs[(*_nodes)[v].first_in].prev_in = n;
105 105
      }
106 106
      (*_nodes)[v].first_in = n;
107 107
      arcs[n].next_out = (*_nodes)[u].first_out;
108 108
      if ((*_nodes)[u].first_out != -1) {
109 109
        arcs[(*_nodes)[u].first_out].prev_out = n;
110 110
      }
111 111
      (*_nodes)[u].first_out = n;
112 112
      arcs[n].source = u;
113 113
      arcs[n].target = v;
114 114
      return Arc(n);
115 115
    }
116 116

	
117 117
    void erase(const Arc& arc) {
118 118
      int n = arc.id;
119 119
      if (arcs[n].prev_in != -1) {
120 120
        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
121 121
      } else {
122 122
        (*_nodes)[arcs[n].target].first_in = arcs[n].next_in;
123 123
      }
124 124
      if (arcs[n].next_in != -1) {
125 125
        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
126 126
      }
127 127

	
128 128
      if (arcs[n].prev_out != -1) {
129 129
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
130 130
      } else {
131 131
        (*_nodes)[arcs[n].source].first_out = arcs[n].next_out;
132 132
      }
133 133
      if (arcs[n].next_out != -1) {
134 134
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
135 135
      }
136 136

	
137 137
    }
138 138

	
139 139
    void clear() {
140 140
      Node node;
141 141
      for (first(node); node != INVALID; next(node)) {
142 142
        (*_nodes)[node].first_in = -1;
143 143
        (*_nodes)[node].first_out = -1;
144 144
      }
145 145
      arcs.clear();
146 146
      first_arc = -1;
147 147
      first_free_arc = -1;
148 148
    }
149 149

	
150 150
    void first(Node& node) const {
151 151
      _graph->first(node);
152 152
    }
153 153

	
154 154
    void next(Node& node) const {
155 155
      _graph->next(node);
156 156
    }
157 157

	
158 158
    void first(Arc& arc) const {
159 159
      Node node;
160 160
      first(node);
161 161
      while (node != INVALID && (*_nodes)[node].first_in == -1) {
162 162
        next(node);
163 163
      }
164 164
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
165 165
    }
166 166

	
167 167
    void next(Arc& arc) const {
168 168
      if (arcs[arc.id].next_in != -1) {
169 169
        arc.id = arcs[arc.id].next_in;
170 170
      } else {
171 171
        Node node = arcs[arc.id].target;
172 172
        next(node);
173 173
        while (node != INVALID && (*_nodes)[node].first_in == -1) {
174 174
          next(node);
175 175
        }
176 176
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
177 177
      }
178 178
    }
179 179

	
180 180
    void firstOut(Arc& arc, const Node& node) const {
181 181
      arc.id = (*_nodes)[node].first_out;
182 182
    }
183 183

	
184 184
    void nextOut(Arc& arc) const {
185 185
      arc.id = arcs[arc.id].next_out;
186 186
    }
187 187

	
188 188
    void firstIn(Arc& arc, const Node& node) const {
189 189
      arc.id = (*_nodes)[node].first_in;
190 190
    }
191 191

	
192 192
    void nextIn(Arc& arc) const {
193 193
      arc.id = arcs[arc.id].next_in;
194 194
    }
195 195

	
196 196
    int id(const Node& node) const { return _graph->id(node); }
197 197
    int id(const Arc& arc) const { return arc.id; }
198 198

	
199 199
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
200 200
    Arc arcFromId(int ix) const { return Arc(ix); }
201 201

	
202 202
    int maxNodeId() const { return _graph->maxNodeId(); };
203 203
    int maxArcId() const { return arcs.size() - 1; }
204 204

	
205 205
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
206 206
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
207 207

	
208 208
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
209 209

	
210 210
    NodeNotifier& notifier(Node) const {
211 211
      return _graph->notifier(Node());
212 212
    }
213 213

	
214 214
    template <typename V>
215 215
    class NodeMap : public GR::template NodeMap<V> {
216 216
      typedef typename GR::template NodeMap<V> Parent;
217 217

	
218 218
    public:
219 219

	
220 220
      explicit NodeMap(const ListArcSetBase<GR>& arcset)
221 221
        : Parent(*arcset._graph) {}
222 222

	
223 223
      NodeMap(const ListArcSetBase<GR>& arcset, const V& value)
224 224
        : Parent(*arcset._graph, value) {}
225 225

	
226 226
      NodeMap& operator=(const NodeMap& cmap) {
227 227
        return operator=<NodeMap>(cmap);
228 228
      }
229 229

	
230 230
      template <typename CMap>
231 231
      NodeMap& operator=(const CMap& cmap) {
232 232
        Parent::operator=(cmap);
233 233
        return *this;
234 234
      }
235 235
    };
236 236

	
237 237
  };
238 238

	
239 239
  /// \ingroup graphs
240 240
  ///
241 241
  /// \brief Digraph using a node set of another digraph or graph and
242 242
  /// an own arc set.
243 243
  ///
244 244
  /// This structure can be used to establish another directed graph
245 245
  /// over a node set of an existing one. This class uses the same
246 246
  /// Node type as the underlying graph, and each valid node of the
247 247
  /// original graph is valid in this arc set, therefore the node
248 248
  /// objects of the original graph can be used directly with this
249 249
  /// class. The node handling functions (id handling, observing, and
250 250
  /// iterators) works equivalently as in the original graph.
251 251
  ///
252 252
  /// This implementation is based on doubly-linked lists, from each
253 253
  /// node the outgoing and the incoming arcs make up lists, therefore
254 254
  /// one arc can be erased in constant time. It also makes possible,
255 255
  /// that node can be removed from the underlying graph, in this case
256 256
  /// all arcs incident to the given node is erased from the arc set.
257 257
  ///
258
  /// This class fully conforms to the \ref concepts::Digraph
259
  /// "Digraph" concept.
260
  /// It provides only linear time counting for nodes and arcs.
261
  ///
258 262
  /// \param GR The type of the graph which shares its node set with
259 263
  /// this class. Its interface must conform to the
260 264
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
261 265
  /// concept.
262
  ///
263
  /// This class fully conforms to the \ref concepts::Digraph
264
  /// "Digraph" concept.
265 266
  template <typename GR>
266 267
  class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
267 268
    typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
268 269

	
269 270
  public:
270 271

	
271 272
    typedef typename Parent::Node Node;
272 273
    typedef typename Parent::Arc Arc;
273 274

	
274 275
    typedef typename Parent::NodesImplBase NodesImplBase;
275 276

	
276 277
    void eraseNode(const Node& node) {
277 278
      Arc arc;
278 279
      Parent::firstOut(arc, node);
279 280
      while (arc != INVALID ) {
280 281
        erase(arc);
281 282
        Parent::firstOut(arc, node);
282 283
      }
283 284

	
284 285
      Parent::firstIn(arc, node);
285 286
      while (arc != INVALID ) {
286 287
        erase(arc);
287 288
        Parent::firstIn(arc, node);
288 289
      }
289 290
    }
290 291

	
291 292
    void clearNodes() {
292 293
      Parent::clear();
293 294
    }
294 295

	
295 296
    class NodesImpl : public NodesImplBase {
296 297
      typedef NodesImplBase Parent;
297 298

	
298 299
    public:
299 300
      NodesImpl(const GR& graph, ListArcSet& arcset)
300 301
        : Parent(graph), _arcset(arcset) {}
301 302

	
302 303
      virtual ~NodesImpl() {}
303 304

	
304 305
    protected:
305 306

	
306 307
      virtual void erase(const Node& node) {
307 308
        _arcset.eraseNode(node);
308 309
        Parent::erase(node);
309 310
      }
310 311
      virtual void erase(const std::vector<Node>& nodes) {
311 312
        for (int i = 0; i < int(nodes.size()); ++i) {
312 313
          _arcset.eraseNode(nodes[i]);
313 314
        }
314 315
        Parent::erase(nodes);
315 316
      }
316 317
      virtual void clear() {
317 318
        _arcset.clearNodes();
318 319
        Parent::clear();
319 320
      }
320 321

	
321 322
    private:
322 323
      ListArcSet& _arcset;
323 324
    };
324 325

	
325 326
    NodesImpl _nodes;
326 327

	
327 328
  public:
328 329

	
329 330
    /// \brief Constructor of the ArcSet.
330 331
    ///
331 332
    /// Constructor of the ArcSet.
332 333
    ListArcSet(const GR& graph) : _nodes(graph, *this) {
333 334
      Parent::initalize(graph, _nodes);
334 335
    }
335 336

	
336 337
    /// \brief Add a new arc to the digraph.
337 338
    ///
338 339
    /// Add a new arc to the digraph with source node \c s
339 340
    /// and target node \c t.
340 341
    /// \return The new arc.
341 342
    Arc addArc(const Node& s, const Node& t) {
342 343
      return Parent::addArc(s, t);
343 344
    }
344 345

	
345 346
    /// \brief Erase an arc from the digraph.
346 347
    ///
347 348
    /// Erase an arc \c a from the digraph.
348 349
    void erase(const Arc& a) {
349 350
      return Parent::erase(a);
350 351
    }
351 352

	
352 353
  };
353 354

	
354 355
  template <typename GR>
355 356
  class ListEdgeSetBase {
356 357
  public:
357 358

	
358 359
    typedef typename GR::Node Node;
359 360
    typedef typename GR::NodeIt NodeIt;
360 361

	
361 362
  protected:
362 363

	
363 364
    struct NodeT {
364 365
      int first_out;
365 366
      NodeT() : first_out(-1) {}
366 367
    };
367 368

	
368 369
    typedef typename ItemSetTraits<GR, Node>::
369 370
    template Map<NodeT>::Type NodesImplBase;
370 371

	
371 372
    NodesImplBase* _nodes;
372 373

	
373 374
    struct ArcT {
374 375
      Node target;
375 376
      int prev_out, next_out;
376 377
      ArcT() : prev_out(-1), next_out(-1) {}
377 378
    };
378 379

	
379 380
    std::vector<ArcT> arcs;
380 381

	
381 382
    int first_arc;
382 383
    int first_free_arc;
383 384

	
384 385
    const GR* _graph;
385 386

	
386 387
    void initalize(const GR& graph, NodesImplBase& nodes) {
387 388
      _graph = &graph;
388 389
      _nodes = &nodes;
389 390
    }
390 391

	
391 392
  public:
392 393

	
393 394
    class Edge {
394 395
      friend class ListEdgeSetBase;
395 396
    protected:
396 397

	
397 398
      int id;
398 399
      explicit Edge(int _id) { id = _id;}
399 400

	
400 401
    public:
401 402
      Edge() {}
402 403
      Edge (Invalid) { id = -1; }
403 404
      bool operator==(const Edge& arc) const {return id == arc.id;}
404 405
      bool operator!=(const Edge& arc) const {return id != arc.id;}
405 406
      bool operator<(const Edge& arc) const {return id < arc.id;}
406 407
    };
407 408

	
408 409
    class Arc {
409 410
      friend class ListEdgeSetBase;
410 411
    protected:
411 412
      Arc(int _id) : id(_id) {}
412 413
      int id;
413 414
    public:
414 415
      operator Edge() const { return edgeFromId(id / 2); }
415 416

	
416 417
      Arc() {}
417 418
      Arc(Invalid) : id(-1) {}
418 419
      bool operator==(const Arc& arc) const { return id == arc.id; }
419 420
      bool operator!=(const Arc& arc) const { return id != arc.id; }
420 421
      bool operator<(const Arc& arc) const { return id < arc.id; }
421 422
    };
422 423

	
423 424
    ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
424 425

	
425 426
    Node addNode() {
426 427
      LEMON_ASSERT(false,
427 428
        "This graph structure does not support node insertion");
428 429
      return INVALID; // avoid warning
429 430
    }
430 431

	
431 432
    Edge addEdge(const Node& u, const Node& v) {
432 433
      int n;
433 434

	
434 435
      if (first_free_arc == -1) {
435 436
        n = arcs.size();
436 437
        arcs.push_back(ArcT());
437 438
        arcs.push_back(ArcT());
438 439
      } else {
439 440
        n = first_free_arc;
440 441
        first_free_arc = arcs[n].next_out;
441 442
      }
442 443

	
443 444
      arcs[n].target = u;
444 445
      arcs[n | 1].target = v;
445 446

	
446 447
      arcs[n].next_out = (*_nodes)[v].first_out;
447 448
      if ((*_nodes)[v].first_out != -1) {
448 449
        arcs[(*_nodes)[v].first_out].prev_out = n;
449 450
      }
450 451
      (*_nodes)[v].first_out = n;
451 452
      arcs[n].prev_out = -1;
452 453

	
453 454
      if ((*_nodes)[u].first_out != -1) {
454 455
        arcs[(*_nodes)[u].first_out].prev_out = (n | 1);
455 456
      }
456 457
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
457 458
      (*_nodes)[u].first_out = (n | 1);
458 459
      arcs[n | 1].prev_out = -1;
459 460

	
460 461
      return Edge(n / 2);
461 462
    }
462 463

	
463 464
    void erase(const Edge& arc) {
464 465
      int n = arc.id * 2;
465 466

	
466 467
      if (arcs[n].next_out != -1) {
467 468
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
468 469
      }
469 470

	
470 471
      if (arcs[n].prev_out != -1) {
471 472
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
472 473
      } else {
473 474
        (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
474 475
      }
475 476

	
476 477
      if (arcs[n | 1].next_out != -1) {
477 478
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
478 479
      }
479 480

	
480 481
      if (arcs[n | 1].prev_out != -1) {
481 482
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
482 483
      } else {
483 484
        (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
484 485
      }
485 486

	
486 487
      arcs[n].next_out = first_free_arc;
487 488
      first_free_arc = n;
488 489

	
489 490
    }
490 491

	
491 492
    void clear() {
492 493
      Node node;
493 494
      for (first(node); node != INVALID; next(node)) {
494 495
        (*_nodes)[node].first_out = -1;
495 496
      }
496 497
      arcs.clear();
497 498
      first_arc = -1;
498 499
      first_free_arc = -1;
499 500
    }
500 501

	
501 502
    void first(Node& node) const {
502 503
      _graph->first(node);
503 504
    }
504 505

	
505 506
    void next(Node& node) const {
506 507
      _graph->next(node);
507 508
    }
508 509

	
509 510
    void first(Arc& arc) const {
510 511
      Node node;
511 512
      first(node);
512 513
      while (node != INVALID && (*_nodes)[node].first_out == -1) {
513 514
        next(node);
514 515
      }
515 516
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
516 517
    }
517 518

	
518 519
    void next(Arc& arc) const {
519 520
      if (arcs[arc.id].next_out != -1) {
520 521
        arc.id = arcs[arc.id].next_out;
521 522
      } else {
522 523
        Node node = arcs[arc.id ^ 1].target;
523 524
        next(node);
524 525
        while(node != INVALID && (*_nodes)[node].first_out == -1) {
525 526
          next(node);
526 527
        }
527 528
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
528 529
      }
529 530
    }
530 531

	
531 532
    void first(Edge& edge) const {
532 533
      Node node;
533 534
      first(node);
534 535
      while (node != INVALID) {
535 536
        edge.id = (*_nodes)[node].first_out;
536 537
        while ((edge.id & 1) != 1) {
537 538
          edge.id = arcs[edge.id].next_out;
538 539
        }
539 540
        if (edge.id != -1) {
540 541
          edge.id /= 2;
541 542
          return;
542 543
        }
543 544
        next(node);
544 545
      }
545 546
      edge.id = -1;
546 547
    }
547 548

	
548 549
    void next(Edge& edge) const {
549 550
      Node node = arcs[edge.id * 2].target;
550 551
      edge.id = arcs[(edge.id * 2) | 1].next_out;
551 552
      while ((edge.id & 1) != 1) {
552 553
        edge.id = arcs[edge.id].next_out;
553 554
      }
554 555
      if (edge.id != -1) {
555 556
        edge.id /= 2;
556 557
        return;
557 558
      }
558 559
      next(node);
559 560
      while (node != INVALID) {
560 561
        edge.id = (*_nodes)[node].first_out;
561 562
        while ((edge.id & 1) != 1) {
562 563
          edge.id = arcs[edge.id].next_out;
563 564
        }
564 565
        if (edge.id != -1) {
565 566
          edge.id /= 2;
566 567
          return;
567 568
        }
568 569
        next(node);
569 570
      }
570 571
      edge.id = -1;
571 572
    }
572 573

	
573 574
    void firstOut(Arc& arc, const Node& node) const {
574 575
      arc.id = (*_nodes)[node].first_out;
575 576
    }
576 577

	
577 578
    void nextOut(Arc& arc) const {
578 579
      arc.id = arcs[arc.id].next_out;
579 580
    }
580 581

	
581 582
    void firstIn(Arc& arc, const Node& node) const {
582 583
      arc.id = (((*_nodes)[node].first_out) ^ 1);
583 584
      if (arc.id == -2) arc.id = -1;
584 585
    }
585 586

	
586 587
    void nextIn(Arc& arc) const {
587 588
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
588 589
      if (arc.id == -2) arc.id = -1;
589 590
    }
590 591

	
591 592
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
592 593
      int de = (*_nodes)[node].first_out;
593 594
      if (de != -1 ) {
594 595
        arc.id = de / 2;
595 596
        dir = ((de & 1) == 1);
596 597
      } else {
597 598
        arc.id = -1;
598 599
        dir = true;
599 600
      }
600 601
    }
601 602
    void nextInc(Edge &arc, bool& dir) const {
602 603
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
603 604
      if (de != -1 ) {
604 605
        arc.id = de / 2;
605 606
        dir = ((de & 1) == 1);
606 607
      } else {
607 608
        arc.id = -1;
608 609
        dir = true;
609 610
      }
610 611
    }
611 612

	
612 613
    static bool direction(Arc arc) {
613 614
      return (arc.id & 1) == 1;
614 615
    }
615 616

	
616 617
    static Arc direct(Edge edge, bool dir) {
617 618
      return Arc(edge.id * 2 + (dir ? 1 : 0));
618 619
    }
619 620

	
620 621
    int id(const Node& node) const { return _graph->id(node); }
621 622
    static int id(Arc e) { return e.id; }
622 623
    static int id(Edge e) { return e.id; }
623 624

	
624 625
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
625 626
    static Arc arcFromId(int id) { return Arc(id);}
626 627
    static Edge edgeFromId(int id) { return Edge(id);}
627 628

	
628 629
    int maxNodeId() const { return _graph->maxNodeId(); };
629 630
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
630 631
    int maxArcId() const { return arcs.size()-1; }
631 632

	
632 633
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
633 634
    Node target(Arc e) const { return arcs[e.id].target; }
634 635

	
635 636
    Node u(Edge e) const { return arcs[2 * e.id].target; }
636 637
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
637 638

	
638 639
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
639 640

	
640 641
    NodeNotifier& notifier(Node) const {
641 642
      return _graph->notifier(Node());
642 643
    }
643 644

	
644 645
    template <typename V>
645 646
    class NodeMap : public GR::template NodeMap<V> {
646 647
      typedef typename GR::template NodeMap<V> Parent;
647 648

	
648 649
    public:
649 650

	
650 651
      explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
651 652
        : Parent(*arcset._graph) {}
652 653

	
653 654
      NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
654 655
        : Parent(*arcset._graph, value) {}
655 656

	
656 657
      NodeMap& operator=(const NodeMap& cmap) {
657 658
        return operator=<NodeMap>(cmap);
658 659
      }
659 660

	
660 661
      template <typename CMap>
661 662
      NodeMap& operator=(const CMap& cmap) {
662 663
        Parent::operator=(cmap);
663 664
        return *this;
664 665
      }
665 666
    };
666 667

	
667 668
  };
668 669

	
669 670
  /// \ingroup graphs
670 671
  ///
671 672
  /// \brief Graph using a node set of another digraph or graph and an
672 673
  /// own edge set.
673 674
  ///
674 675
  /// This structure can be used to establish another graph over a
675 676
  /// node set of an existing one. This class uses the same Node type
676 677
  /// as the underlying graph, and each valid node of the original
677 678
  /// graph is valid in this arc set, therefore the node objects of
678 679
  /// the original graph can be used directly with this class. The
679 680
  /// node handling functions (id handling, observing, and iterators)
680 681
  /// works equivalently as in the original graph.
681 682
  ///
682 683
  /// This implementation is based on doubly-linked lists, from each
683 684
  /// node the incident edges make up lists, therefore one edge can be
684 685
  /// erased in constant time. It also makes possible, that node can
685 686
  /// be removed from the underlying graph, in this case all edges
686 687
  /// incident to the given node is erased from the arc set.
687 688
  ///
689
  /// This class fully conforms to the \ref concepts::Graph "Graph"
690
  /// concept.
691
  /// It provides only linear time counting for nodes, edges and arcs.
692
  ///
688 693
  /// \param GR The type of the graph which shares its node set
689 694
  /// with this class. Its interface must conform to the
690 695
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
691 696
  /// concept.
692
  ///
693
  /// This class fully conforms to the \ref concepts::Graph "Graph"
694
  /// concept.
695 697
  template <typename GR>
696 698
  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
697 699
    typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
698 700

	
699 701
  public:
700 702

	
701 703
    typedef typename Parent::Node Node;
702 704
    typedef typename Parent::Arc Arc;
703 705
    typedef typename Parent::Edge Edge;
704 706

	
705 707
    typedef typename Parent::NodesImplBase NodesImplBase;
706 708

	
707 709
    void eraseNode(const Node& node) {
708 710
      Arc arc;
709 711
      Parent::firstOut(arc, node);
710 712
      while (arc != INVALID ) {
711 713
        erase(arc);
712 714
        Parent::firstOut(arc, node);
713 715
      }
714 716

	
715 717
    }
716 718

	
717 719
    void clearNodes() {
718 720
      Parent::clear();
719 721
    }
720 722

	
721 723
    class NodesImpl : public NodesImplBase {
722 724
      typedef NodesImplBase Parent;
723 725

	
724 726
    public:
725 727
      NodesImpl(const GR& graph, ListEdgeSet& arcset)
726 728
        : Parent(graph), _arcset(arcset) {}
727 729

	
728 730
      virtual ~NodesImpl() {}
729 731

	
730 732
    protected:
731 733

	
732 734
      virtual void erase(const Node& node) {
733 735
        _arcset.eraseNode(node);
734 736
        Parent::erase(node);
735 737
      }
736 738
      virtual void erase(const std::vector<Node>& nodes) {
737 739
        for (int i = 0; i < int(nodes.size()); ++i) {
738 740
          _arcset.eraseNode(nodes[i]);
739 741
        }
740 742
        Parent::erase(nodes);
741 743
      }
742 744
      virtual void clear() {
743 745
        _arcset.clearNodes();
744 746
        Parent::clear();
745 747
      }
746 748

	
747 749
    private:
748 750
      ListEdgeSet& _arcset;
749 751
    };
750 752

	
751 753
    NodesImpl _nodes;
752 754

	
753 755
  public:
754 756

	
755 757
    /// \brief Constructor of the EdgeSet.
756 758
    ///
757 759
    /// Constructor of the EdgeSet.
758 760
    ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
759 761
      Parent::initalize(graph, _nodes);
760 762
    }
761 763

	
762 764
    /// \brief Add a new edge to the graph.
763 765
    ///
764 766
    /// Add a new edge to the graph with node \c u
765 767
    /// and node \c v endpoints.
766 768
    /// \return The new edge.
767 769
    Edge addEdge(const Node& u, const Node& v) {
768 770
      return Parent::addEdge(u, v);
769 771
    }
770 772

	
771 773
    /// \brief Erase an edge from the graph.
772 774
    ///
773 775
    /// Erase the edge \c e from the graph.
774 776
    void erase(const Edge& e) {
775 777
      return Parent::erase(e);
776 778
    }
777 779

	
778 780
  };
779 781

	
780 782
  template <typename GR>
781 783
  class SmartArcSetBase {
782 784
  public:
783 785

	
784 786
    typedef typename GR::Node Node;
785 787
    typedef typename GR::NodeIt NodeIt;
786 788

	
787 789
  protected:
788 790

	
789 791
    struct NodeT {
790 792
      int first_out, first_in;
791 793
      NodeT() : first_out(-1), first_in(-1) {}
792 794
    };
793 795

	
794 796
    typedef typename ItemSetTraits<GR, Node>::
795 797
    template Map<NodeT>::Type NodesImplBase;
796 798

	
797 799
    NodesImplBase* _nodes;
798 800

	
799 801
    struct ArcT {
800 802
      Node source, target;
801 803
      int next_out, next_in;
802 804
      ArcT() {}
803 805
    };
804 806

	
805 807
    std::vector<ArcT> arcs;
806 808

	
807 809
    const GR* _graph;
808 810

	
809 811
    void initalize(const GR& graph, NodesImplBase& nodes) {
810 812
      _graph = &graph;
811 813
      _nodes = &nodes;
812 814
    }
813 815

	
814 816
  public:
815 817

	
816 818
    class Arc {
817 819
      friend class SmartArcSetBase<GR>;
818 820
    protected:
819 821
      Arc(int _id) : id(_id) {}
820 822
      int id;
821 823
    public:
822 824
      Arc() {}
823 825
      Arc(Invalid) : id(-1) {}
824 826
      bool operator==(const Arc& arc) const { return id == arc.id; }
825 827
      bool operator!=(const Arc& arc) const { return id != arc.id; }
826 828
      bool operator<(const Arc& arc) const { return id < arc.id; }
827 829
    };
828 830

	
829 831
    SmartArcSetBase() {}
830 832

	
831 833
    Node addNode() {
832 834
      LEMON_ASSERT(false,
833 835
        "This graph structure does not support node insertion");
834 836
      return INVALID; // avoid warning
835 837
    }
836 838

	
837 839
    Arc addArc(const Node& u, const Node& v) {
838 840
      int n = arcs.size();
839 841
      arcs.push_back(ArcT());
840 842
      arcs[n].next_in = (*_nodes)[v].first_in;
841 843
      (*_nodes)[v].first_in = n;
842 844
      arcs[n].next_out = (*_nodes)[u].first_out;
843 845
      (*_nodes)[u].first_out = n;
844 846
      arcs[n].source = u;
845 847
      arcs[n].target = v;
846 848
      return Arc(n);
847 849
    }
848 850

	
849 851
    void clear() {
850 852
      Node node;
851 853
      for (first(node); node != INVALID; next(node)) {
852 854
        (*_nodes)[node].first_in = -1;
853 855
        (*_nodes)[node].first_out = -1;
854 856
      }
855 857
      arcs.clear();
856 858
    }
857 859

	
858 860
    void first(Node& node) const {
859 861
      _graph->first(node);
860 862
    }
861 863

	
862 864
    void next(Node& node) const {
863 865
      _graph->next(node);
864 866
    }
865 867

	
866 868
    void first(Arc& arc) const {
867 869
      arc.id = arcs.size() - 1;
868 870
    }
869 871

	
870
    void next(Arc& arc) const {
872
    static void next(Arc& arc) {
871 873
      --arc.id;
872 874
    }
873 875

	
874 876
    void firstOut(Arc& arc, const Node& node) const {
875 877
      arc.id = (*_nodes)[node].first_out;
876 878
    }
877 879

	
878 880
    void nextOut(Arc& arc) const {
879 881
      arc.id = arcs[arc.id].next_out;
880 882
    }
881 883

	
882 884
    void firstIn(Arc& arc, const Node& node) const {
883 885
      arc.id = (*_nodes)[node].first_in;
884 886
    }
885 887

	
886 888
    void nextIn(Arc& arc) const {
887 889
      arc.id = arcs[arc.id].next_in;
888 890
    }
889 891

	
890 892
    int id(const Node& node) const { return _graph->id(node); }
891 893
    int id(const Arc& arc) const { return arc.id; }
892 894

	
893 895
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
894 896
    Arc arcFromId(int ix) const { return Arc(ix); }
895 897

	
896 898
    int maxNodeId() const { return _graph->maxNodeId(); };
897 899
    int maxArcId() const { return arcs.size() - 1; }
898 900

	
899 901
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
900 902
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
901 903

	
902 904
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
903 905

	
904 906
    NodeNotifier& notifier(Node) const {
905 907
      return _graph->notifier(Node());
906 908
    }
907 909

	
908 910
    template <typename V>
909 911
    class NodeMap : public GR::template NodeMap<V> {
910 912
      typedef typename GR::template NodeMap<V> Parent;
911 913

	
912 914
    public:
913 915

	
914 916
      explicit NodeMap(const SmartArcSetBase<GR>& arcset)
915 917
        : Parent(*arcset._graph) { }
916 918

	
917 919
      NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
918 920
        : Parent(*arcset._graph, value) { }
919 921

	
920 922
      NodeMap& operator=(const NodeMap& cmap) {
921 923
        return operator=<NodeMap>(cmap);
922 924
      }
923 925

	
924 926
      template <typename CMap>
925 927
      NodeMap& operator=(const CMap& cmap) {
926 928
        Parent::operator=(cmap);
927 929
        return *this;
928 930
      }
929 931
    };
930 932

	
931 933
  };
932 934

	
933 935

	
934 936
  /// \ingroup graphs
935 937
  ///
936 938
  /// \brief Digraph using a node set of another digraph or graph and
937 939
  /// an own arc set.
938 940
  ///
939 941
  /// This structure can be used to establish another directed graph
940 942
  /// over a node set of an existing one. This class uses the same
941 943
  /// Node type as the underlying graph, and each valid node of the
942 944
  /// original graph is valid in this arc set, therefore the node
943 945
  /// objects of the original graph can be used directly with this
944 946
  /// class. The node handling functions (id handling, observing, and
945 947
  /// iterators) works equivalently as in the original graph.
946 948
  ///
947 949
  /// \param GR The type of the graph which shares its node set with
948 950
  /// this class. Its interface must conform to the
949 951
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
950 952
  /// concept.
951 953
  ///
952 954
  /// This implementation is slightly faster than the \c ListArcSet,
953 955
  /// because it uses continuous storage for arcs and it uses just
954 956
  /// single-linked lists for enumerate outgoing and incoming
955 957
  /// arcs. Therefore the arcs cannot be erased from the arc sets.
956 958
  ///
959
  /// This class fully conforms to the \ref concepts::Digraph "Digraph"
960
  /// concept.
961
  /// It provides only linear time counting for nodes and arcs.
962
  ///
957 963
  /// \warning If a node is erased from the underlying graph and this
958 964
  /// node is the source or target of one arc in the arc set, then
959 965
  /// the arc set is invalidated, and it cannot be used anymore. The
960 966
  /// 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 967
  template <typename GR>
965 968
  class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
966 969
    typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
967 970

	
968 971
  public:
969 972

	
970 973
    typedef typename Parent::Node Node;
971 974
    typedef typename Parent::Arc Arc;
972 975

	
973 976
  protected:
974 977

	
975 978
    typedef typename Parent::NodesImplBase NodesImplBase;
976 979

	
977 980
    void eraseNode(const Node& node) {
978 981
      if (typename Parent::InArcIt(*this, node) == INVALID &&
979 982
          typename Parent::OutArcIt(*this, node) == INVALID) {
980 983
        return;
981 984
      }
982 985
      throw typename NodesImplBase::Notifier::ImmediateDetach();
983 986
    }
984 987

	
985 988
    void clearNodes() {
986 989
      Parent::clear();
987 990
    }
988 991

	
989 992
    class NodesImpl : public NodesImplBase {
990 993
      typedef NodesImplBase Parent;
991 994

	
992 995
    public:
993 996
      NodesImpl(const GR& graph, SmartArcSet& arcset)
994 997
        : Parent(graph), _arcset(arcset) {}
995 998

	
996 999
      virtual ~NodesImpl() {}
997 1000

	
998 1001
      bool attached() const {
999 1002
        return Parent::attached();
1000 1003
      }
1001 1004

	
1002 1005
    protected:
1003 1006

	
1004 1007
      virtual void erase(const Node& node) {
1005 1008
        try {
1006 1009
          _arcset.eraseNode(node);
1007 1010
          Parent::erase(node);
1008 1011
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1009 1012
          Parent::clear();
1010 1013
          throw;
1011 1014
        }
1012 1015
      }
1013 1016
      virtual void erase(const std::vector<Node>& nodes) {
1014 1017
        try {
1015 1018
          for (int i = 0; i < int(nodes.size()); ++i) {
1016 1019
            _arcset.eraseNode(nodes[i]);
1017 1020
          }
1018 1021
          Parent::erase(nodes);
1019 1022
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1020 1023
          Parent::clear();
1021 1024
          throw;
1022 1025
        }
1023 1026
      }
1024 1027
      virtual void clear() {
1025 1028
        _arcset.clearNodes();
1026 1029
        Parent::clear();
1027 1030
      }
1028 1031

	
1029 1032
    private:
1030 1033
      SmartArcSet& _arcset;
1031 1034
    };
1032 1035

	
1033 1036
    NodesImpl _nodes;
1034 1037

	
1035 1038
  public:
1036 1039

	
1037 1040
    /// \brief Constructor of the ArcSet.
1038 1041
    ///
1039 1042
    /// Constructor of the ArcSet.
1040 1043
    SmartArcSet(const GR& graph) : _nodes(graph, *this) {
1041 1044
      Parent::initalize(graph, _nodes);
1042 1045
    }
1043 1046

	
1044 1047
    /// \brief Add a new arc to the digraph.
1045 1048
    ///
1046 1049
    /// Add a new arc to the digraph with source node \c s
1047 1050
    /// and target node \c t.
1048 1051
    /// \return The new arc.
1049 1052
    Arc addArc(const Node& s, const Node& t) {
1050 1053
      return Parent::addArc(s, t);
1051 1054
    }
1052 1055

	
1053 1056
    /// \brief Validity check
1054 1057
    ///
1055 1058
    /// This functions gives back false if the ArcSet is
1056 1059
    /// invalidated. It occurs when a node in the underlying graph is
1057 1060
    /// erased and it is not isolated in the ArcSet.
1058 1061
    bool valid() const {
1059 1062
      return _nodes.attached();
1060 1063
    }
1061 1064

	
1062 1065
  };
1063 1066

	
1064 1067

	
1065 1068
  template <typename GR>
1066 1069
  class SmartEdgeSetBase {
1067 1070
  public:
1068 1071

	
1069 1072
    typedef typename GR::Node Node;
1070 1073
    typedef typename GR::NodeIt NodeIt;
1071 1074

	
1072 1075
  protected:
1073 1076

	
1074 1077
    struct NodeT {
1075 1078
      int first_out;
1076 1079
      NodeT() : first_out(-1) {}
1077 1080
    };
1078 1081

	
1079 1082
    typedef typename ItemSetTraits<GR, Node>::
1080 1083
    template Map<NodeT>::Type NodesImplBase;
1081 1084

	
1082 1085
    NodesImplBase* _nodes;
1083 1086

	
1084 1087
    struct ArcT {
1085 1088
      Node target;
1086 1089
      int next_out;
1087 1090
      ArcT() {}
1088 1091
    };
1089 1092

	
1090 1093
    std::vector<ArcT> arcs;
1091 1094

	
1092 1095
    const GR* _graph;
1093 1096

	
1094 1097
    void initalize(const GR& graph, NodesImplBase& nodes) {
1095 1098
      _graph = &graph;
1096 1099
      _nodes = &nodes;
1097 1100
    }
1098 1101

	
1099 1102
  public:
1100 1103

	
1101 1104
    class Edge {
1102 1105
      friend class SmartEdgeSetBase;
1103 1106
    protected:
1104 1107

	
1105 1108
      int id;
1106 1109
      explicit Edge(int _id) { id = _id;}
1107 1110

	
1108 1111
    public:
1109 1112
      Edge() {}
1110 1113
      Edge (Invalid) { id = -1; }
1111 1114
      bool operator==(const Edge& arc) const {return id == arc.id;}
1112 1115
      bool operator!=(const Edge& arc) const {return id != arc.id;}
1113 1116
      bool operator<(const Edge& arc) const {return id < arc.id;}
1114 1117
    };
1115 1118

	
1116 1119
    class Arc {
1117 1120
      friend class SmartEdgeSetBase;
1118 1121
    protected:
1119 1122
      Arc(int _id) : id(_id) {}
1120 1123
      int id;
1121 1124
    public:
1122 1125
      operator Edge() const { return edgeFromId(id / 2); }
1123 1126

	
1124 1127
      Arc() {}
1125 1128
      Arc(Invalid) : id(-1) {}
1126 1129
      bool operator==(const Arc& arc) const { return id == arc.id; }
1127 1130
      bool operator!=(const Arc& arc) const { return id != arc.id; }
1128 1131
      bool operator<(const Arc& arc) const { return id < arc.id; }
1129 1132
    };
1130 1133

	
1131 1134
    SmartEdgeSetBase() {}
1132 1135

	
1133 1136
    Node addNode() {
1134 1137
      LEMON_ASSERT(false,
1135 1138
        "This graph structure does not support node insertion");
1136 1139
      return INVALID; // avoid warning
1137 1140
    }
1138 1141

	
1139 1142
    Edge addEdge(const Node& u, const Node& v) {
1140 1143
      int n = arcs.size();
1141 1144
      arcs.push_back(ArcT());
1142 1145
      arcs.push_back(ArcT());
1143 1146

	
1144 1147
      arcs[n].target = u;
1145 1148
      arcs[n | 1].target = v;
1146 1149

	
1147 1150
      arcs[n].next_out = (*_nodes)[v].first_out;
1148 1151
      (*_nodes)[v].first_out = n;
1149 1152

	
1150 1153
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
1151 1154
      (*_nodes)[u].first_out = (n | 1);
1152 1155

	
1153 1156
      return Edge(n / 2);
1154 1157
    }
1155 1158

	
1156 1159
    void clear() {
1157 1160
      Node node;
1158 1161
      for (first(node); node != INVALID; next(node)) {
1159 1162
        (*_nodes)[node].first_out = -1;
1160 1163
      }
1161 1164
      arcs.clear();
1162 1165
    }
1163 1166

	
1164 1167
    void first(Node& node) const {
1165 1168
      _graph->first(node);
1166 1169
    }
1167 1170

	
1168 1171
    void next(Node& node) const {
1169 1172
      _graph->next(node);
1170 1173
    }
1171 1174

	
1172 1175
    void first(Arc& arc) const {
1173 1176
      arc.id = arcs.size() - 1;
1174 1177
    }
1175 1178

	
1176
    void next(Arc& arc) const {
1179
    static void next(Arc& arc) {
1177 1180
      --arc.id;
1178 1181
    }
1179 1182

	
1180 1183
    void first(Edge& arc) const {
1181 1184
      arc.id = arcs.size() / 2 - 1;
1182 1185
    }
1183 1186

	
1184
    void next(Edge& arc) const {
1187
    static void next(Edge& arc) {
1185 1188
      --arc.id;
1186 1189
    }
1187 1190

	
1188 1191
    void firstOut(Arc& arc, const Node& node) const {
1189 1192
      arc.id = (*_nodes)[node].first_out;
1190 1193
    }
1191 1194

	
1192 1195
    void nextOut(Arc& arc) const {
1193 1196
      arc.id = arcs[arc.id].next_out;
1194 1197
    }
1195 1198

	
1196 1199
    void firstIn(Arc& arc, const Node& node) const {
1197 1200
      arc.id = (((*_nodes)[node].first_out) ^ 1);
1198 1201
      if (arc.id == -2) arc.id = -1;
1199 1202
    }
1200 1203

	
1201 1204
    void nextIn(Arc& arc) const {
1202 1205
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
1203 1206
      if (arc.id == -2) arc.id = -1;
1204 1207
    }
1205 1208

	
1206 1209
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
1207 1210
      int de = (*_nodes)[node].first_out;
1208 1211
      if (de != -1 ) {
1209 1212
        arc.id = de / 2;
1210 1213
        dir = ((de & 1) == 1);
1211 1214
      } else {
1212 1215
        arc.id = -1;
1213 1216
        dir = true;
1214 1217
      }
1215 1218
    }
1216 1219
    void nextInc(Edge &arc, bool& dir) const {
1217 1220
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
1218 1221
      if (de != -1 ) {
1219 1222
        arc.id = de / 2;
1220 1223
        dir = ((de & 1) == 1);
1221 1224
      } else {
1222 1225
        arc.id = -1;
1223 1226
        dir = true;
1224 1227
      }
1225 1228
    }
1226 1229

	
1227 1230
    static bool direction(Arc arc) {
1228 1231
      return (arc.id & 1) == 1;
1229 1232
    }
1230 1233

	
1231 1234
    static Arc direct(Edge edge, bool dir) {
1232 1235
      return Arc(edge.id * 2 + (dir ? 1 : 0));
1233 1236
    }
1234 1237

	
1235 1238
    int id(Node node) const { return _graph->id(node); }
1236 1239
    static int id(Arc arc) { return arc.id; }
1237 1240
    static int id(Edge arc) { return arc.id; }
1238 1241

	
1239 1242
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
1240 1243
    static Arc arcFromId(int id) { return Arc(id); }
1241 1244
    static Edge edgeFromId(int id) { return Edge(id);}
1242 1245

	
1243 1246
    int maxNodeId() const { return _graph->maxNodeId(); };
1244 1247
    int maxArcId() const { return arcs.size() - 1; }
1245 1248
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
1246 1249

	
1247 1250
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
1248 1251
    Node target(Arc e) const { return arcs[e.id].target; }
1249 1252

	
1250 1253
    Node u(Edge e) const { return arcs[2 * e.id].target; }
1251 1254
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
1252 1255

	
1253 1256
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
1254 1257

	
1255 1258
    NodeNotifier& notifier(Node) const {
1256 1259
      return _graph->notifier(Node());
1257 1260
    }
1258 1261

	
1259 1262
    template <typename V>
1260 1263
    class NodeMap : public GR::template NodeMap<V> {
1261 1264
      typedef typename GR::template NodeMap<V> Parent;
1262 1265

	
1263 1266
    public:
1264 1267

	
1265 1268
      explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
1266 1269
        : Parent(*arcset._graph) { }
1267 1270

	
1268 1271
      NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
1269 1272
        : Parent(*arcset._graph, value) { }
1270 1273

	
1271 1274
      NodeMap& operator=(const NodeMap& cmap) {
1272 1275
        return operator=<NodeMap>(cmap);
1273 1276
      }
1274 1277

	
1275 1278
      template <typename CMap>
1276 1279
      NodeMap& operator=(const CMap& cmap) {
1277 1280
        Parent::operator=(cmap);
1278 1281
        return *this;
1279 1282
      }
1280 1283
    };
1281 1284

	
1282 1285
  };
1283 1286

	
1284 1287
  /// \ingroup graphs
1285 1288
  ///
1286 1289
  /// \brief Graph using a node set of another digraph or graph and an
1287 1290
  /// own edge set.
1288 1291
  ///
1289 1292
  /// This structure can be used to establish another graph over a
1290 1293
  /// node set of an existing one. This class uses the same Node type
1291 1294
  /// as the underlying graph, and each valid node of the original
1292 1295
  /// graph is valid in this arc set, therefore the node objects of
1293 1296
  /// the original graph can be used directly with this class. The
1294 1297
  /// node handling functions (id handling, observing, and iterators)
1295 1298
  /// works equivalently as in the original graph.
1296 1299
  ///
1297 1300
  /// \param GR The type of the graph which shares its node set
1298 1301
  /// with this class. Its interface must conform to the
1299 1302
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
1300 1303
  ///  concept.
1301 1304
  ///
1302 1305
  /// This implementation is slightly faster than the \c ListEdgeSet,
1303 1306
  /// because it uses continuous storage for edges and it uses just
1304 1307
  /// single-linked lists for enumerate incident edges. Therefore the
1305 1308
  /// edges cannot be erased from the edge sets.
1306 1309
  ///
1310
  /// This class fully conforms to the \ref concepts::Graph "Graph"
1311
  /// concept.
1312
  /// It provides only linear time counting for nodes, edges and arcs.
1313
  ///
1307 1314
  /// \warning If a node is erased from the underlying graph and this
1308 1315
  /// node is incident to one edge in the edge set, then the edge set
1309 1316
  /// is invalidated, and it cannot be used anymore. The validity can
1310 1317
  /// be checked with the \c valid() member function.
1311
  ///
1312
  /// This class fully conforms to the \ref concepts::Graph
1313
  /// "Graph" concept.
1314 1318
  template <typename GR>
1315 1319
  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
1316 1320
    typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
1317 1321

	
1318 1322
  public:
1319 1323

	
1320 1324
    typedef typename Parent::Node Node;
1321 1325
    typedef typename Parent::Arc Arc;
1322 1326
    typedef typename Parent::Edge Edge;
1323 1327

	
1324 1328
  protected:
1325 1329

	
1326 1330
    typedef typename Parent::NodesImplBase NodesImplBase;
1327 1331

	
1328 1332
    void eraseNode(const Node& node) {
1329 1333
      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
1330 1334
        return;
1331 1335
      }
1332 1336
      throw typename NodesImplBase::Notifier::ImmediateDetach();
1333 1337
    }
1334 1338

	
1335 1339
    void clearNodes() {
1336 1340
      Parent::clear();
1337 1341
    }
1338 1342

	
1339 1343
    class NodesImpl : public NodesImplBase {
1340 1344
      typedef NodesImplBase Parent;
1341 1345

	
1342 1346
    public:
1343 1347
      NodesImpl(const GR& graph, SmartEdgeSet& arcset)
1344 1348
        : Parent(graph), _arcset(arcset) {}
1345 1349

	
1346 1350
      virtual ~NodesImpl() {}
1347 1351

	
1348 1352
      bool attached() const {
1349 1353
        return Parent::attached();
1350 1354
      }
1351 1355

	
1352 1356
    protected:
1353 1357

	
1354 1358
      virtual void erase(const Node& node) {
1355 1359
        try {
1356 1360
          _arcset.eraseNode(node);
1357 1361
          Parent::erase(node);
1358 1362
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1359 1363
          Parent::clear();
1360 1364
          throw;
1361 1365
        }
1362 1366
      }
1363 1367
      virtual void erase(const std::vector<Node>& nodes) {
1364 1368
        try {
1365 1369
          for (int i = 0; i < int(nodes.size()); ++i) {
1366 1370
            _arcset.eraseNode(nodes[i]);
1367 1371
          }
1368 1372
          Parent::erase(nodes);
1369 1373
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1370 1374
          Parent::clear();
1371 1375
          throw;
1372 1376
        }
1373 1377
      }
1374 1378
      virtual void clear() {
1375 1379
        _arcset.clearNodes();
1376 1380
        Parent::clear();
1377 1381
      }
1378 1382

	
1379 1383
    private:
1380 1384
      SmartEdgeSet& _arcset;
1381 1385
    };
1382 1386

	
1383 1387
    NodesImpl _nodes;
1384 1388

	
1385 1389
  public:
1386 1390

	
1387 1391
    /// \brief Constructor of the EdgeSet.
1388 1392
    ///
1389 1393
    /// Constructor of the EdgeSet.
1390 1394
    SmartEdgeSet(const GR& graph) : _nodes(graph, *this) {
1391 1395
      Parent::initalize(graph, _nodes);
1392 1396
    }
1393 1397

	
1394 1398
    /// \brief Add a new edge to the graph.
1395 1399
    ///
1396 1400
    /// Add a new edge to the graph with node \c u
1397 1401
    /// and node \c v endpoints.
1398 1402
    /// \return The new edge.
1399 1403
    Edge addEdge(const Node& u, const Node& v) {
1400 1404
      return Parent::addEdge(u, v);
1401 1405
    }
1402 1406

	
1403 1407
    /// \brief Validity check
1404 1408
    ///
1405 1409
    /// This functions gives back false if the EdgeSet is
1406 1410
    /// invalidated. It occurs when a node in the underlying graph is
1407 1411
    /// erased and it is not isolated in the EdgeSet.
1408 1412
    bool valid() const {
1409 1413
      return _nodes.attached();
1410 1414
    }
1411 1415

	
1412 1416
  };
1413 1417

	
1414 1418
}
1415 1419

	
1416 1420
#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-2009
5
 * Copyright (C) 2003-2010
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_EULER_H
20 20
#define LEMON_EULER_H
21 21

	
22 22
#include<lemon/core.h>
23 23
#include<lemon/adaptors.h>
24 24
#include<lemon/connectivity.h>
25 25
#include <list>
26 26

	
27 27
/// \ingroup graph_properties
28 28
/// \file
29
/// \brief Euler tour iterators and a function for checking the \e Eulerian 
29
/// \brief Euler tour iterators and a function for checking the \e Eulerian
30 30
/// property.
31 31
///
32 32
///This file provides Euler tour iterators and a function to check
33 33
///if a (di)graph is \e Eulerian.
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  ///Euler tour iterator for digraphs.
38 38

	
39 39
  /// \ingroup graph_prop
40 40
  ///This iterator provides an Euler tour (Eulerian circuit) of a \e directed
41 41
  ///graph (if there exists) and it converts to the \c Arc type of the digraph.
42 42
  ///
43 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 
44
  ///non-trivial component and the in-degree is equal to the out-degree
45 45
  ///for all nodes), then the following code will put the arcs of \c g
46 46
  ///to the vector \c et according to an Euler tour of \c g.
47 47
  ///\code
48 48
  ///  std::vector<ListDigraph::Arc> et;
49 49
  ///  for(DiEulerIt<ListDigraph> e(g); e!=INVALID; ++e)
50 50
  ///    et.push_back(e);
51 51
  ///\endcode
52 52
  ///If \c g has no Euler tour, then the resulted walk will not be closed
53 53
  ///or not contain all arcs.
54 54
  ///\sa EulerIt
55 55
  template<typename GR>
56 56
  class DiEulerIt
57 57
  {
58 58
    typedef typename GR::Node Node;
59 59
    typedef typename GR::NodeIt NodeIt;
60 60
    typedef typename GR::Arc Arc;
61 61
    typedef typename GR::ArcIt ArcIt;
62 62
    typedef typename GR::OutArcIt OutArcIt;
63 63
    typedef typename GR::InArcIt InArcIt;
64 64

	
65 65
    const GR &g;
66 66
    typename GR::template NodeMap<OutArcIt> narc;
67 67
    std::list<Arc> euler;
68 68

	
69 69
  public:
70 70

	
71 71
    ///Constructor
72 72

	
73 73
    ///Constructor.
74 74
    ///\param gr A digraph.
75 75
    ///\param start The starting point of the tour. If it is not given,
76 76
    ///the tour will start from the first node that has an outgoing arc.
77 77
    DiEulerIt(const GR &gr, typename GR::Node start = INVALID)
78 78
      : g(gr), narc(g)
79 79
    {
80 80
      if (start==INVALID) {
81 81
        NodeIt n(g);
82 82
        while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
83 83
        start=n;
84 84
      }
85 85
      if (start!=INVALID) {
86 86
        for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
87 87
        while (narc[start]!=INVALID) {
88 88
          euler.push_back(narc[start]);
89 89
          Node next=g.target(narc[start]);
90 90
          ++narc[start];
91 91
          start=next;
92 92
        }
93 93
      }
94 94
    }
95 95

	
96 96
    ///Arc conversion
97 97
    operator Arc() { return euler.empty()?INVALID:euler.front(); }
98 98
    ///Compare with \c INVALID
99 99
    bool operator==(Invalid) { return euler.empty(); }
100 100
    ///Compare with \c INVALID
101 101
    bool operator!=(Invalid) { return !euler.empty(); }
102 102

	
103 103
    ///Next arc of the tour
104 104

	
105 105
    ///Next arc of the tour
106 106
    ///
107 107
    DiEulerIt &operator++() {
108 108
      Node s=g.target(euler.front());
109 109
      euler.pop_front();
110 110
      typename std::list<Arc>::iterator next=euler.begin();
111 111
      while(narc[s]!=INVALID) {
112 112
        euler.insert(next,narc[s]);
113 113
        Node n=g.target(narc[s]);
114 114
        ++narc[s];
115 115
        s=n;
116 116
      }
117 117
      return *this;
118 118
    }
119 119
    ///Postfix incrementation
120 120

	
121 121
    /// Postfix incrementation.
122 122
    ///
123 123
    ///\warning This incrementation
124 124
    ///returns an \c Arc, not a \ref DiEulerIt, as one may
125 125
    ///expect.
126 126
    Arc operator++(int)
127 127
    {
128 128
      Arc e=*this;
129 129
      ++(*this);
130 130
      return e;
131 131
    }
132 132
  };
133 133

	
134 134
  ///Euler tour iterator for graphs.
135 135

	
136 136
  /// \ingroup graph_properties
137 137
  ///This iterator provides an Euler tour (Eulerian circuit) of an
138 138
  ///\e undirected graph (if there exists) and it converts to the \c Arc
139 139
  ///and \c Edge types of the graph.
140 140
  ///
141
  ///For example, if the given graph has an Euler tour (i.e it has only one 
141
  ///For example, if the given graph has an Euler tour (i.e it has only one
142 142
  ///non-trivial component and the degree of each node is even),
143 143
  ///the following code will print the arc IDs according to an
144 144
  ///Euler tour of \c g.
145 145
  ///\code
146 146
  ///  for(EulerIt<ListGraph> e(g); e!=INVALID; ++e) {
147 147
  ///    std::cout << g.id(Edge(e)) << std::eol;
148 148
  ///  }
149 149
  ///\endcode
150
  ///Although this iterator is for undirected graphs, it still returns 
150
  ///Although this iterator is for undirected graphs, it still returns
151 151
  ///arcs in order to indicate the direction of the tour.
152 152
  ///(But arcs convert to edges, of course.)
153 153
  ///
154 154
  ///If \c g has no Euler tour, then the resulted walk will not be closed
155 155
  ///or not contain all edges.
156 156
  template<typename GR>
157 157
  class EulerIt
158 158
  {
159 159
    typedef typename GR::Node Node;
160 160
    typedef typename GR::NodeIt NodeIt;
161 161
    typedef typename GR::Arc Arc;
162 162
    typedef typename GR::Edge Edge;
163 163
    typedef typename GR::ArcIt ArcIt;
164 164
    typedef typename GR::OutArcIt OutArcIt;
165 165
    typedef typename GR::InArcIt InArcIt;
166 166

	
167 167
    const GR &g;
168 168
    typename GR::template NodeMap<OutArcIt> narc;
169 169
    typename GR::template EdgeMap<bool> visited;
170 170
    std::list<Arc> euler;
171 171

	
172 172
  public:
173 173

	
174 174
    ///Constructor
175 175

	
176 176
    ///Constructor.
177 177
    ///\param gr A graph.
178 178
    ///\param start The starting point of the tour. If it is not given,
179 179
    ///the tour will start from the first node that has an incident edge.
180 180
    EulerIt(const GR &gr, typename GR::Node start = INVALID)
181 181
      : g(gr), narc(g), visited(g, false)
182 182
    {
183 183
      if (start==INVALID) {
184 184
        NodeIt n(g);
185 185
        while (n!=INVALID && OutArcIt(g,n)==INVALID) ++n;
186 186
        start=n;
187 187
      }
188 188
      if (start!=INVALID) {
189 189
        for (NodeIt n(g); n!=INVALID; ++n) narc[n]=OutArcIt(g,n);
190 190
        while(narc[start]!=INVALID) {
191 191
          euler.push_back(narc[start]);
192 192
          visited[narc[start]]=true;
193 193
          Node next=g.target(narc[start]);
194 194
          ++narc[start];
195 195
          start=next;
196 196
          while(narc[start]!=INVALID && visited[narc[start]]) ++narc[start];
197 197
        }
198 198
      }
199 199
    }
200 200

	
201 201
    ///Arc conversion
202 202
    operator Arc() const { return euler.empty()?INVALID:euler.front(); }
203 203
    ///Edge conversion
204 204
    operator Edge() const { return euler.empty()?INVALID:euler.front(); }
205 205
    ///Compare with \c INVALID
206 206
    bool operator==(Invalid) const { return euler.empty(); }
207 207
    ///Compare with \c INVALID
208 208
    bool operator!=(Invalid) const { return !euler.empty(); }
209 209

	
210 210
    ///Next arc of the tour
211 211

	
212 212
    ///Next arc of the tour
213 213
    ///
214 214
    EulerIt &operator++() {
215 215
      Node s=g.target(euler.front());
216 216
      euler.pop_front();
217 217
      typename std::list<Arc>::iterator next=euler.begin();
218 218
      while(narc[s]!=INVALID) {
219 219
        while(narc[s]!=INVALID && visited[narc[s]]) ++narc[s];
220 220
        if(narc[s]==INVALID) break;
221 221
        else {
222 222
          euler.insert(next,narc[s]);
223 223
          visited[narc[s]]=true;
224 224
          Node n=g.target(narc[s]);
225 225
          ++narc[s];
226 226
          s=n;
227 227
        }
228 228
      }
229 229
      return *this;
230 230
    }
231 231

	
232 232
    ///Postfix incrementation
233 233

	
234 234
    /// Postfix incrementation.
235 235
    ///
236
    ///\warning This incrementation returns an \c Arc (which converts to 
236
    ///\warning This incrementation returns an \c Arc (which converts to
237 237
    ///an \c Edge), not an \ref EulerIt, as one may expect.
238 238
    Arc operator++(int)
239 239
    {
240 240
      Arc e=*this;
241 241
      ++(*this);
242 242
      return e;
243 243
    }
244 244
  };
245 245

	
246 246

	
247 247
  ///Check if the given graph is Eulerian
248 248

	
249 249
  /// \ingroup graph_properties
250 250
  ///This function checks if the given graph is Eulerian.
251 251
  ///It works for both directed and undirected graphs.
252 252
  ///
253 253
  ///By definition, a digraph is called \e Eulerian if
254 254
  ///and only if it is connected and the number of incoming and outgoing
255 255
  ///arcs are the same for each node.
256 256
  ///Similarly, an undirected graph is called \e Eulerian if
257 257
  ///and only if it is connected and the number of incident edges is even
258 258
  ///for each node.
259 259
  ///
260 260
  ///\note There are (di)graphs that are not Eulerian, but still have an
261 261
  /// Euler tour, since they may contain isolated nodes.
262 262
  ///
263 263
  ///\sa DiEulerIt, EulerIt
264 264
  template<typename GR>
265 265
#ifdef DOXYGEN
266 266
  bool
267 267
#else
268 268
  typename enable_if<UndirectedTagIndicator<GR>,bool>::type
269 269
  eulerian(const GR &g)
270 270
  {
271 271
    for(typename GR::NodeIt n(g);n!=INVALID;++n)
272 272
      if(countIncEdges(g,n)%2) return false;
273 273
    return connected(g);
274 274
  }
275 275
  template<class GR>
276 276
  typename disable_if<UndirectedTagIndicator<GR>,bool>::type
277 277
#endif
278 278
  eulerian(const GR &g)
279 279
  {
280 280
    for(typename GR::NodeIt n(g);n!=INVALID;++n)
281 281
      if(countInArcs(g,n)!=countOutArcs(g,n)) return false;
282 282
    return connected(undirector(g));
283 283
  }
284 284

	
285 285
}
286 286

	
287 287
#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 19
#ifndef LEMON_FIB_HEAP_H
20 20
#define LEMON_FIB_HEAP_H
21 21

	
22 22
///\file
23
///\ingroup auxdat
24
///\brief Fibonacci Heap implementation.
23
///\ingroup heaps
24
///\brief Fibonacci heap implementation.
25 25

	
26 26
#include <vector>
27
#include <utility>
27 28
#include <functional>
28 29
#include <lemon/math.h>
29 30

	
30 31
namespace lemon {
31 32

	
32
  /// \ingroup auxdat
33
  /// \ingroup heaps
33 34
  ///
34
  ///\brief Fibonacci Heap.
35
  /// \brief Fibonacci heap data structure.
35 36
  ///
36
  ///This class implements the \e Fibonacci \e heap data structure. A \e heap
37
  ///is a data structure for storing items with specified values called \e
38
  ///priorities in such a way that finding the item with minimum priority is
39
  ///efficient. \c CMP specifies the ordering of the priorities. In a heap
40
  ///one can change the priority of an item, add or erase an item, etc.
37
  /// This class implements the \e Fibonacci \e heap data structure.
38
  /// It fully conforms to the \ref concepts::Heap "heap concept".
41 39
  ///
42
  ///The methods \ref increase and \ref erase are not efficient in a Fibonacci
43
  ///heap. In case of many calls to these operations, it is better to use a
44
  ///\ref BinHeap "binary heap".
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".
45 43
  ///
46
  ///\param PRIO Type of the priority of the items.
47
  ///\param IM A read and writable Item int map, used internally
48
  ///to handle the cross references.
49
  ///\param CMP A class for the ordering of the priorities. The
50
  ///default is \c std::less<PRIO>.
51
  ///
52
  ///\sa BinHeap
53
  ///\sa Dijkstra
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>.
54 49
#ifdef DOXYGEN
55
  template <typename PRIO, typename IM, typename CMP>
50
  template <typename PR, typename IM, typename CMP>
56 51
#else
57
  template <typename PRIO, typename IM, typename CMP = std::less<PRIO> >
52
  template <typename PR, typename IM, typename CMP = std::less<PR> >
58 53
#endif
59 54
  class FibHeap {
60 55
  public:
61
    ///\e
56

	
57
    /// Type of the item-int map.
62 58
    typedef IM ItemIntMap;
63
    ///\e
64
    typedef PRIO Prio;
65
    ///\e
59
    /// Type of the priorities.
60
    typedef PR Prio;
61
    /// Type of the items stored in the heap.
66 62
    typedef typename ItemIntMap::Key Item;
67
    ///\e
63
    /// Type of the item-priority pairs.
68 64
    typedef std::pair<Item,Prio> Pair;
69
    ///\e
65
    /// Functor type for comparing the priorities.
70 66
    typedef CMP Compare;
71 67

	
72 68
  private:
73 69
    class Store;
74 70

	
75 71
    std::vector<Store> _data;
76 72
    int _minimum;
77 73
    ItemIntMap &_iim;
78 74
    Compare _comp;
79 75
    int _num;
80 76

	
81 77
  public:
82 78

	
83
    /// \brief Type to represent the items states.
79
    /// \brief Type to represent the states of the items.
84 80
    ///
85
    /// Each Item element have a state associated to it. It may be "in heap",
86
    /// "pre heap" or "post heap". The latter two are indifferent from the
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
87 83
    /// heap's point of view, but may be useful to the user.
88 84
    ///
89 85
    /// The item-int map must be initialized in such way that it assigns
90 86
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
91 87
    enum State {
92 88
      IN_HEAP = 0,    ///< = 0.
93 89
      PRE_HEAP = -1,  ///< = -1.
94 90
      POST_HEAP = -2  ///< = -2.
95 91
    };
96 92

	
97
    /// \brief The constructor
93
    /// \brief Constructor.
98 94
    ///
99
    /// \c map should be given to the constructor, since it is
100
    ///   used internally to handle the cross references.
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.
101 99
    explicit FibHeap(ItemIntMap &map)
102 100
      : _minimum(0), _iim(map), _num() {}
103 101

	
104
    /// \brief The constructor
102
    /// \brief Constructor.
105 103
    ///
106
    /// \c map should be given to the constructor, since it is used
107
    /// internally to handle the cross references. \c comp is an
108
    /// object for ordering of the priorities.
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 109
    FibHeap(ItemIntMap &map, const Compare &comp)
110 110
      : _minimum(0), _iim(map), _comp(comp), _num() {}
111 111

	
112 112
    /// \brief The number of items stored in the heap.
113 113
    ///
114
    /// Returns the number of items stored in the heap.
114
    /// This function returns the number of items stored in the heap.
115 115
    int size() const { return _num; }
116 116

	
117
    /// \brief Checks if the heap stores no items.
117
    /// \brief Check if the heap is empty.
118 118
    ///
119
    ///   Returns \c true if and only if the heap stores no items.
119
    /// This function returns \c true if the heap is empty.
120 120
    bool empty() const { return _num==0; }
121 121

	
122
    /// \brief Make empty this heap.
122
    /// \brief Make the heap empty.
123 123
    ///
124
    /// Make empty this heap. It does not change the cross reference
125
    /// map.  If you want to reuse a heap what is not surely empty you
126
    /// should first clear the heap and after that you should set the
127
    /// cross reference map for each item to \c PRE_HEAP.
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.
128 129
    void clear() {
129 130
      _data.clear(); _minimum = 0; _num = 0;
130 131
    }
131 132

	
132
    /// \brief \c item gets to the heap with priority \c value independently
133
    /// if \c item was already there.
133
    /// \brief Insert an item into the heap with the given priority.
134 134
    ///
135
    /// This method calls \ref push(\c item, \c value) if \c item is not
136
    /// stored in the heap and it calls \ref decrease(\c item, \c value) or
137
    /// \ref increase(\c item, \c value) otherwise.
138
    void set (const Item& item, const Prio& value) {
139
      int i=_iim[item];
140
      if ( i >= 0 && _data[i].in ) {
141
        if ( _comp(value, _data[i].prio) ) decrease(item, value);
142
        if ( _comp(_data[i].prio, value) ) increase(item, value);
143
      } else push(item, value);
144
    }
145

	
146
    /// \brief Adds \c item to the heap with priority \c value.
147
    ///
148
    /// Adds \c item to the heap with priority \c value.
149
    /// \pre \c item must not be stored in the heap.
150
    void push (const Item& item, const Prio& value) {
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) {
151 141
      int i=_iim[item];
152 142
      if ( i < 0 ) {
153 143
        int s=_data.size();
154 144
        _iim.set( item, s );
155 145
        Store st;
156 146
        st.name=item;
157 147
        _data.push_back(st);
158 148
        i=s;
159 149
      } else {
160 150
        _data[i].parent=_data[i].child=-1;
161 151
        _data[i].degree=0;
162 152
        _data[i].in=true;
163 153
        _data[i].marked=false;
164 154
      }
165 155

	
166 156
      if ( _num ) {
167 157
        _data[_data[_minimum].right_neighbor].left_neighbor=i;
168 158
        _data[i].right_neighbor=_data[_minimum].right_neighbor;
169 159
        _data[_minimum].right_neighbor=i;
170 160
        _data[i].left_neighbor=_minimum;
171
        if ( _comp( value, _data[_minimum].prio) ) _minimum=i;
161
        if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
172 162
      } else {
173 163
        _data[i].right_neighbor=_data[i].left_neighbor=i;
174 164
        _minimum=i;
175 165
      }
176
      _data[i].prio=value;
166
      _data[i].prio=prio;
177 167
      ++_num;
178 168
    }
179 169

	
180
    /// \brief Returns the item with minimum priority relative to \c Compare.
170
    /// \brief Return the item having minimum priority.
181 171
    ///
182
    /// This method returns the item with minimum priority relative to \c
183
    /// Compare.
184
    /// \pre The heap must be nonempty.
172
    /// This function returns the item having minimum priority.
173
    /// \pre The heap must be non-empty.
185 174
    Item top() const { return _data[_minimum].name; }
186 175

	
187
    /// \brief Returns the minimum priority relative to \c Compare.
176
    /// \brief The minimum priority.
188 177
    ///
189
    /// It returns the minimum priority relative to \c Compare.
190
    /// \pre The heap must be nonempty.
191
    const Prio& prio() const { return _data[_minimum].prio; }
178
    /// This function returns the minimum priority.
179
    /// \pre The heap must be non-empty.
180
    Prio prio() const { return _data[_minimum].prio; }
192 181

	
193
    /// \brief Returns the priority of \c item.
182
    /// \brief Remove the item having minimum priority.
194 183
    ///
195
    /// It returns the priority of \c item.
196
    /// \pre \c item must be in the heap.
197
    const Prio& operator[](const Item& item) const {
198
      return _data[_iim[item]].prio;
199
    }
200

	
201
    /// \brief Deletes the item with minimum priority relative to \c Compare.
202
    ///
203
    /// This method deletes the item with minimum priority relative to \c
204
    /// Compare from the heap.
184
    /// This function removes the item having minimum priority.
205 185
    /// \pre The heap must be non-empty.
206 186
    void pop() {
207 187
      /*The first case is that there are only one root.*/
208 188
      if ( _data[_minimum].left_neighbor==_minimum ) {
209 189
        _data[_minimum].in=false;
210 190
        if ( _data[_minimum].degree!=0 ) {
211
          makeroot(_data[_minimum].child);
191
          makeRoot(_data[_minimum].child);
212 192
          _minimum=_data[_minimum].child;
213 193
          balance();
214 194
        }
215 195
      } else {
216 196
        int right=_data[_minimum].right_neighbor;
217 197
        unlace(_minimum);
218 198
        _data[_minimum].in=false;
219 199
        if ( _data[_minimum].degree > 0 ) {
220 200
          int left=_data[_minimum].left_neighbor;
221 201
          int child=_data[_minimum].child;
222 202
          int last_child=_data[child].left_neighbor;
223 203

	
224
          makeroot(child);
204
          makeRoot(child);
225 205

	
226 206
          _data[left].right_neighbor=child;
227 207
          _data[child].left_neighbor=left;
228 208
          _data[right].left_neighbor=last_child;
229 209
          _data[last_child].right_neighbor=right;
230 210
        }
231 211
        _minimum=right;
232 212
        balance();
233 213
      } // the case where there are more roots
234 214
      --_num;
235 215
    }
236 216

	
237
    /// \brief Deletes \c item from the heap.
217
    /// \brief Remove the given item from the heap.
238 218
    ///
239
    /// This method deletes \c item from the heap, if \c item was already
240
    /// stored in the heap. It is quite inefficient in Fibonacci heaps.
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.
241 223
    void erase (const Item& item) {
242 224
      int i=_iim[item];
243 225

	
244 226
      if ( i >= 0 && _data[i].in ) {
245 227
        if ( _data[i].parent!=-1 ) {
246 228
          int p=_data[i].parent;
247 229
          cut(i,p);
248 230
          cascade(p);
249 231
        }
250 232
        _minimum=i;     //As if its prio would be -infinity
251 233
        pop();
252 234
      }
253 235
    }
254 236

	
255
    /// \brief Decreases the priority of \c item to \c value.
237
    /// \brief The priority of the given item.
256 238
    ///
257
    /// This method decreases the priority of \c item to \c value.
258
    /// \pre \c item must be stored in the heap with priority at least \c
259
    ///   value relative to \c Compare.
260
    void decrease (Item item, const Prio& value) {
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) {
261 255
      int i=_iim[item];
262
      _data[i].prio=value;
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;
263 271
      int p=_data[i].parent;
264 272

	
265
      if ( p!=-1 && _comp(value, _data[p].prio) ) {
273
      if ( p!=-1 && _comp(prio, _data[p].prio) ) {
266 274
        cut(i,p);
267 275
        cascade(p);
268 276
      }
269
      if ( _comp(value, _data[_minimum].prio) ) _minimum=i;
277
      if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
270 278
    }
271 279

	
272
    /// \brief Increases the priority of \c item to \c value.
280
    /// \brief Increase the priority of an item to the given value.
273 281
    ///
274
    /// This method sets the priority of \c item to \c value. Though
275
    /// there is no precondition on the priority of \c item, this
276
    /// method should be used only if it is indeed necessary to increase
277
    /// (relative to \c Compare) the priority of \c item, because this
278
    /// method is inefficient.
279
    void increase (Item item, const Prio& value) {
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) {
280 287
      erase(item);
281
      push(item, value);
288
      push(item, prio);
282 289
    }
283 290

	
284

	
285
    /// \brief Returns if \c item is in, has already been in, or has never
286
    /// been in the heap.
291
    /// \brief Return the state of an item.
287 292
    ///
288
    /// This method returns PRE_HEAP if \c item has never been in the
289
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
290
    /// otherwise. In the latter case it is possible that \c item will
291
    /// get back to the heap again.
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.
292 299
    State state(const Item &item) const {
293 300
      int i=_iim[item];
294 301
      if( i>=0 ) {
295 302
        if ( _data[i].in ) i=0;
296 303
        else i=-2;
297 304
      }
298 305
      return State(i);
299 306
    }
300 307

	
301
    /// \brief Sets the state of the \c item in the heap.
308
    /// \brief Set the state of an item in the heap.
302 309
    ///
303
    /// Sets the state of the \c item in the heap. It can be used to
304
    /// manually clear the heap when it is important to achive the
305
    /// better time _complexity.
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.
306 313
    /// \param i The item.
307 314
    /// \param st The state. It should not be \c IN_HEAP.
308 315
    void state(const Item& i, State st) {
309 316
      switch (st) {
310 317
      case POST_HEAP:
311 318
      case PRE_HEAP:
312 319
        if (state(i) == IN_HEAP) {
313 320
          erase(i);
314 321
        }
315 322
        _iim[i] = st;
316 323
        break;
317 324
      case IN_HEAP:
318 325
        break;
319 326
      }
320 327
    }
321 328

	
322 329
  private:
323 330

	
324 331
    void balance() {
325 332

	
326 333
      int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
327 334

	
328 335
      std::vector<int> A(maxdeg,-1);
329 336

	
330 337
      /*
331 338
       *Recall that now minimum does not point to the minimum prio element.
332 339
       *We set minimum to this during balance().
333 340
       */
334 341
      int anchor=_data[_minimum].left_neighbor;
335 342
      int next=_minimum;
336 343
      bool end=false;
337 344

	
338 345
      do {
339 346
        int active=next;
340 347
        if ( anchor==active ) end=true;
341 348
        int d=_data[active].degree;
342 349
        next=_data[active].right_neighbor;
343 350

	
344 351
        while (A[d]!=-1) {
345 352
          if( _comp(_data[active].prio, _data[A[d]].prio) ) {
346 353
            fuse(active,A[d]);
347 354
          } else {
348 355
            fuse(A[d],active);
349 356
            active=A[d];
350 357
          }
351 358
          A[d]=-1;
352 359
          ++d;
353 360
        }
354 361
        A[d]=active;
355 362
      } while ( !end );
356 363

	
357 364

	
358 365
      while ( _data[_minimum].parent >=0 )
359 366
        _minimum=_data[_minimum].parent;
360 367
      int s=_minimum;
361 368
      int m=_minimum;
362 369
      do {
363 370
        if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
364 371
        s=_data[s].right_neighbor;
365 372
      } while ( s != m );
366 373
    }
367 374

	
368
    void makeroot(int c) {
375
    void makeRoot(int c) {
369 376
      int s=c;
370 377
      do {
371 378
        _data[s].parent=-1;
372 379
        s=_data[s].right_neighbor;
373 380
      } while ( s != c );
374 381
    }
375 382

	
376 383
    void cut(int a, int b) {
377 384
      /*
378 385
       *Replacing a from the children of b.
379 386
       */
380 387
      --_data[b].degree;
381 388

	
382 389
      if ( _data[b].degree !=0 ) {
383 390
        int child=_data[b].child;
384 391
        if ( child==a )
385 392
          _data[b].child=_data[child].right_neighbor;
386 393
        unlace(a);
387 394
      }
388 395

	
389 396

	
390 397
      /*Lacing a to the roots.*/
391 398
      int right=_data[_minimum].right_neighbor;
392 399
      _data[_minimum].right_neighbor=a;
393 400
      _data[a].left_neighbor=_minimum;
394 401
      _data[a].right_neighbor=right;
395 402
      _data[right].left_neighbor=a;
396 403

	
397 404
      _data[a].parent=-1;
398 405
      _data[a].marked=false;
399 406
    }
400 407

	
401 408
    void cascade(int a) {
402 409
      if ( _data[a].parent!=-1 ) {
403 410
        int p=_data[a].parent;
404 411

	
405 412
        if ( _data[a].marked==false ) _data[a].marked=true;
406 413
        else {
407 414
          cut(a,p);
408 415
          cascade(p);
409 416
        }
410 417
      }
411 418
    }
412 419

	
413 420
    void fuse(int a, int b) {
414 421
      unlace(b);
415 422

	
416 423
      /*Lacing b under a.*/
417 424
      _data[b].parent=a;
418 425

	
419 426
      if (_data[a].degree==0) {
420 427
        _data[b].left_neighbor=b;
421 428
        _data[b].right_neighbor=b;
422 429
        _data[a].child=b;
423 430
      } else {
424 431
        int child=_data[a].child;
425 432
        int last_child=_data[child].left_neighbor;
426 433
        _data[child].left_neighbor=b;
427 434
        _data[b].right_neighbor=child;
428 435
        _data[last_child].right_neighbor=b;
429 436
        _data[b].left_neighbor=last_child;
430 437
      }
431 438

	
432 439
      ++_data[a].degree;
433 440

	
434 441
      _data[b].marked=false;
435 442
    }
436 443

	
437 444
    /*
438 445
     *It is invoked only if a has siblings.
439 446
     */
440 447
    void unlace(int a) {
441 448
      int leftn=_data[a].left_neighbor;
442 449
      int rightn=_data[a].right_neighbor;
443 450
      _data[leftn].right_neighbor=rightn;
444 451
      _data[rightn].left_neighbor=leftn;
445 452
    }
446 453

	
447 454

	
448 455
    class Store {
449 456
      friend class FibHeap;
450 457

	
451 458
      Item name;
452 459
      int parent;
453 460
      int left_neighbor;
454 461
      int right_neighbor;
455 462
      int child;
456 463
      int degree;
457 464
      bool marked;
458 465
      bool in;
459 466
      Prio prio;
460 467

	
461 468
      Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
462 469
    };
463 470
  };
464 471

	
465 472
} //namespace lemon
466 473

	
467 474
#endif //LEMON_FIB_HEAP_H
468 475

	
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-2009
5
 * Copyright (C) 2003-2010
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_FULL_GRAPH_H
20 20
#define LEMON_FULL_GRAPH_H
21 21

	
22 22
#include <lemon/core.h>
23 23
#include <lemon/bits/graph_extender.h>
24 24

	
25 25
///\ingroup graphs
26 26
///\file
27
///\brief FullGraph and FullDigraph classes.
27
///\brief FullDigraph and FullGraph classes.
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  class FullDigraphBase {
32 32
  public:
33 33

	
34 34
    typedef FullDigraphBase Digraph;
35 35

	
36 36
    class Node;
37 37
    class Arc;
38 38

	
39 39
  protected:
40 40

	
41 41
    int _node_num;
42 42
    int _arc_num;
43 43

	
44 44
    FullDigraphBase() {}
45 45

	
46 46
    void construct(int n) { _node_num = n; _arc_num = n * n; }
47 47

	
48 48
  public:
49 49

	
50 50
    typedef True NodeNumTag;
51 51
    typedef True ArcNumTag;
52 52

	
53 53
    Node operator()(int ix) const { return Node(ix); }
54
    int index(const Node& node) const { return node._id; }
54
    static int index(const Node& node) { return node._id; }
55 55

	
56 56
    Arc arc(const Node& s, const Node& t) const {
57 57
      return Arc(s._id * _node_num + t._id);
58 58
    }
59 59

	
60 60
    int nodeNum() const { return _node_num; }
61 61
    int arcNum() const { return _arc_num; }
62 62

	
63 63
    int maxNodeId() const { return _node_num - 1; }
64 64
    int maxArcId() const { return _arc_num - 1; }
65 65

	
66 66
    Node source(Arc arc) const { return arc._id / _node_num; }
67 67
    Node target(Arc arc) const { return arc._id % _node_num; }
68 68

	
69 69
    static int id(Node node) { return node._id; }
70 70
    static int id(Arc arc) { return arc._id; }
71 71

	
72 72
    static Node nodeFromId(int id) { return Node(id);}
73 73
    static Arc arcFromId(int id) { return Arc(id);}
74 74

	
75 75
    typedef True FindArcTag;
76 76

	
77 77
    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
78 78
      return prev == INVALID ? arc(s, t) : INVALID;
79 79
    }
80 80

	
81 81
    class Node {
82 82
      friend class FullDigraphBase;
83 83

	
84 84
    protected:
85 85
      int _id;
86 86
      Node(int id) : _id(id) {}
87 87
    public:
88 88
      Node() {}
89 89
      Node (Invalid) : _id(-1) {}
90 90
      bool operator==(const Node node) const {return _id == node._id;}
91 91
      bool operator!=(const Node node) const {return _id != node._id;}
92 92
      bool operator<(const Node node) const {return _id < node._id;}
93 93
    };
94 94

	
95 95
    class Arc {
96 96
      friend class FullDigraphBase;
97 97

	
98 98
    protected:
99 99
      int _id;  // _node_num * source + target;
100 100

	
101 101
      Arc(int id) : _id(id) {}
102 102

	
103 103
    public:
104 104
      Arc() { }
105 105
      Arc (Invalid) { _id = -1; }
106 106
      bool operator==(const Arc arc) const {return _id == arc._id;}
107 107
      bool operator!=(const Arc arc) const {return _id != arc._id;}
108 108
      bool operator<(const Arc arc) const {return _id < arc._id;}
109 109
    };
110 110

	
111 111
    void first(Node& node) const {
112 112
      node._id = _node_num - 1;
113 113
    }
114 114

	
115 115
    static void next(Node& node) {
116 116
      --node._id;
117 117
    }
118 118

	
119 119
    void first(Arc& arc) const {
120 120
      arc._id = _arc_num - 1;
121 121
    }
122 122

	
123 123
    static void next(Arc& arc) {
124 124
      --arc._id;
125 125
    }
126 126

	
127 127
    void firstOut(Arc& arc, const Node& node) const {
128 128
      arc._id = (node._id + 1) * _node_num - 1;
129 129
    }
130 130

	
131 131
    void nextOut(Arc& arc) const {
132 132
      if (arc._id % _node_num == 0) arc._id = 0;
133 133
      --arc._id;
134 134
    }
135 135

	
136 136
    void firstIn(Arc& arc, const Node& node) const {
137 137
      arc._id = _arc_num + node._id - _node_num;
138 138
    }
139 139

	
140 140
    void nextIn(Arc& arc) const {
141 141
      arc._id -= _node_num;
142 142
      if (arc._id < 0) arc._id = -1;
143 143
    }
144 144

	
145 145
  };
146 146

	
147 147
  typedef DigraphExtender<FullDigraphBase> ExtendedFullDigraphBase;
148 148

	
149 149
  /// \ingroup graphs
150 150
  ///
151
  /// \brief A full digraph class.
151
  /// \brief A directed full graph class.
152 152
  ///
153
  /// This is a simple and fast directed full graph implementation.
154
  /// From each node go arcs to each node (including the source node),
155
  /// therefore the number of the arcs in the digraph is the square of
156
  /// the node number. This digraph type is completely static, so you
157
  /// can neither add nor delete either arcs or nodes, and it needs
158
  /// constant space in memory.
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().
159 160
  ///
160
  /// This class fully conforms to the \ref concepts::Digraph
161
  /// "Digraph concept".
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.
162 164
  ///
163
  /// The \c FullDigraph and \c FullGraph classes are very similar,
165
  /// This class provides constant time counting for nodes and arcs.
166
  ///
167
  /// \note FullDigraph and FullGraph classes are very similar,
164 168
  /// but there are two differences. While this class conforms only
165
  /// to the \ref concepts::Digraph "Digraph" concept, the \c FullGraph
166
  /// class conforms to the \ref concepts::Graph "Graph" concept,
167
  /// moreover \c FullGraph does not contain a loop arc for each
168
  /// node as \c FullDigraph does.
169
  /// to the \ref concepts::Digraph "Digraph" concept, FullGraph
170
  /// conforms to the \ref concepts::Graph "Graph" concept,
171
  /// moreover FullGraph does not contain a loop for each
172
  /// node as this class does.
169 173
  ///
170 174
  /// \sa FullGraph
171 175
  class FullDigraph : public ExtendedFullDigraphBase {
172 176
    typedef ExtendedFullDigraphBase Parent;
173 177

	
174 178
  public:
175 179

	
176
    /// \brief Constructor
180
    /// \brief Default constructor.
181
    ///
182
    /// Default constructor. The number of nodes and arcs will be zero.
177 183
    FullDigraph() { construct(0); }
178 184

	
179 185
    /// \brief Constructor
180 186
    ///
181 187
    /// Constructor.
182 188
    /// \param n The number of the nodes.
183 189
    FullDigraph(int n) { construct(n); }
184 190

	
185 191
    /// \brief Resizes the digraph
186 192
    ///
187
    /// Resizes the digraph. The function will fully destroy and
188
    /// rebuild the digraph. This cause that the maps of the digraph will
193
    /// This function resizes the digraph. It fully destroys and
194
    /// rebuilds the structure, therefore the maps of the digraph will be
189 195
    /// reallocated automatically and the previous values will be lost.
190 196
    void resize(int n) {
191 197
      Parent::notifier(Arc()).clear();
192 198
      Parent::notifier(Node()).clear();
193 199
      construct(n);
194 200
      Parent::notifier(Node()).build();
195 201
      Parent::notifier(Arc()).build();
196 202
    }
197 203

	
198 204
    /// \brief Returns the node with the given index.
199 205
    ///
200
    /// Returns the node with the given index. Since it is a static
201
    /// digraph its nodes can be indexed with integers from the range
202
    /// <tt>[0..nodeNum()-1]</tt>.
206
    /// Returns the node with the given index. Since this structure is
207
    /// completely static, the nodes can be indexed with integers from
208
    /// the range <tt>[0..nodeNum()-1]</tt>.
209
    /// The index of a node is the same as its ID.
203 210
    /// \sa index()
204 211
    Node operator()(int ix) const { return Parent::operator()(ix); }
205 212

	
206 213
    /// \brief Returns the index of the given node.
207 214
    ///
208
    /// Returns the index of the given node. Since it is a static
209
    /// digraph its nodes can be indexed with integers from the range
210
    /// <tt>[0..nodeNum()-1]</tt>.
211
    /// \sa operator()
212
    int index(const Node& node) const { return Parent::index(node); }
215
    /// Returns the index of the given node. Since this structure is
216
    /// completely static, the nodes can be indexed with integers from
217
    /// the range <tt>[0..nodeNum()-1]</tt>.
218
    /// The index of a node is the same as its ID.
219
    /// \sa operator()()
220
    static int index(const Node& node) { return Parent::index(node); }
213 221

	
214 222
    /// \brief Returns the arc connecting the given nodes.
215 223
    ///
216 224
    /// Returns the arc connecting the given nodes.
217
    Arc arc(const Node& u, const Node& v) const {
225
    Arc arc(Node u, Node v) const {
218 226
      return Parent::arc(u, v);
219 227
    }
220 228

	
221 229
    /// \brief Number of nodes.
222 230
    int nodeNum() const { return Parent::nodeNum(); }
223 231
    /// \brief Number of arcs.
224 232
    int arcNum() const { return Parent::arcNum(); }
225 233
  };
226 234

	
227 235

	
228 236
  class FullGraphBase {
229 237
  public:
230 238

	
231 239
    typedef FullGraphBase Graph;
232 240

	
233 241
    class Node;
234 242
    class Arc;
235 243
    class Edge;
236 244

	
237 245
  protected:
238 246

	
239 247
    int _node_num;
240 248
    int _edge_num;
241 249

	
242 250
    FullGraphBase() {}
243 251

	
244 252
    void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; }
245 253

	
246 254
    int _uid(int e) const {
247 255
      int u = e / _node_num;
248 256
      int v = e % _node_num;
249 257
      return u < v ? u : _node_num - 2 - u;
250 258
    }
251 259

	
252 260
    int _vid(int e) const {
253 261
      int u = e / _node_num;
254 262
      int v = e % _node_num;
255 263
      return u < v ? v : _node_num - 1 - v;
256 264
    }
257 265

	
258 266
    void _uvid(int e, int& u, int& v) const {
259 267
      u = e / _node_num;
260 268
      v = e % _node_num;
261 269
      if  (u >= v) {
262 270
        u = _node_num - 2 - u;
263 271
        v = _node_num - 1 - v;
264 272
      }
265 273
    }
266 274

	
267 275
    void _stid(int a, int& s, int& t) const {
268 276
      if ((a & 1) == 1) {
269 277
        _uvid(a >> 1, s, t);
270 278
      } else {
271 279
        _uvid(a >> 1, t, s);
272 280
      }
273 281
    }
274 282

	
275 283
    int _eid(int u, int v) const {
276 284
      if (u < (_node_num - 1) / 2) {
277 285
        return u * _node_num + v;
278 286
      } else {
279 287
        return (_node_num - 1 - u) * _node_num - v - 1;
280 288
      }
281 289
    }
282 290

	
283 291
  public:
284 292

	
285 293
    Node operator()(int ix) const { return Node(ix); }
286
    int index(const Node& node) const { return node._id; }
294
    static int index(const Node& node) { return node._id; }
287 295

	
288 296
    Edge edge(const Node& u, const Node& v) const {
289 297
      if (u._id < v._id) {
290 298
        return Edge(_eid(u._id, v._id));
291 299
      } else if (u._id != v._id) {
292 300
        return Edge(_eid(v._id, u._id));
293 301
      } else {
294 302
        return INVALID;
295 303
      }
296 304
    }
297 305

	
298 306
    Arc arc(const Node& s, const Node& t) const {
299 307
      if (s._id < t._id) {
300 308
        return Arc((_eid(s._id, t._id) << 1) | 1);
301 309
      } else if (s._id != t._id) {
302 310
        return Arc(_eid(t._id, s._id) << 1);
303 311
      } else {
304 312
        return INVALID;
305 313
      }
306 314
    }
307 315

	
308 316
    typedef True NodeNumTag;
309 317
    typedef True ArcNumTag;
310 318
    typedef True EdgeNumTag;
311 319

	
312 320
    int nodeNum() const { return _node_num; }
313 321
    int arcNum() const { return 2 * _edge_num; }
314 322
    int edgeNum() const { return _edge_num; }
315 323

	
316 324
    static int id(Node node) { return node._id; }
317 325
    static int id(Arc arc) { return arc._id; }
318 326
    static int id(Edge edge) { return edge._id; }
319 327

	
320 328
    int maxNodeId() const { return _node_num-1; }
321 329
    int maxArcId() const { return 2 * _edge_num-1; }
322 330
    int maxEdgeId() const { return _edge_num-1; }
323 331

	
324 332
    static Node nodeFromId(int id) { return Node(id);}
325 333
    static Arc arcFromId(int id) { return Arc(id);}
326 334
    static Edge edgeFromId(int id) { return Edge(id);}
327 335

	
328 336
    Node u(Edge edge) const {
329 337
      return Node(_uid(edge._id));
330 338
    }
331 339

	
332 340
    Node v(Edge edge) const {
333 341
      return Node(_vid(edge._id));
334 342
    }
335 343

	
336 344
    Node source(Arc arc) const {
337 345
      return Node((arc._id & 1) == 1 ?
338 346
                  _uid(arc._id >> 1) : _vid(arc._id >> 1));
339 347
    }
340 348

	
341 349
    Node target(Arc arc) const {
342 350
      return Node((arc._id & 1) == 1 ?
343 351
                  _vid(arc._id >> 1) : _uid(arc._id >> 1));
344 352
    }
345 353

	
346 354
    typedef True FindEdgeTag;
347 355
    typedef True FindArcTag;
348 356

	
349 357
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
350 358
      return prev != INVALID ? INVALID : edge(u, v);
351 359
    }
352 360

	
353 361
    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
354 362
      return prev != INVALID ? INVALID : arc(s, t);
355 363
    }
356 364

	
357 365
    class Node {
358 366
      friend class FullGraphBase;
359 367

	
360 368
    protected:
361 369
      int _id;
362 370
      Node(int id) : _id(id) {}
363 371
    public:
364 372
      Node() {}
365 373
      Node (Invalid) { _id = -1; }
366 374
      bool operator==(const Node node) const {return _id == node._id;}
367 375
      bool operator!=(const Node node) const {return _id != node._id;}
368 376
      bool operator<(const Node node) const {return _id < node._id;}
369 377
    };
370 378

	
371 379
    class Edge {
372 380
      friend class FullGraphBase;
373 381
      friend class Arc;
374 382

	
375 383
    protected:
376 384
      int _id;
377 385

	
378 386
      Edge(int id) : _id(id) {}
379 387

	
380 388
    public:
381 389
      Edge() { }
382 390
      Edge (Invalid) { _id = -1; }
383 391

	
384 392
      bool operator==(const Edge edge) const {return _id == edge._id;}
385 393
      bool operator!=(const Edge edge) const {return _id != edge._id;}
386 394
      bool operator<(const Edge edge) const {return _id < edge._id;}
387 395
    };
388 396

	
389 397
    class Arc {
390 398
      friend class FullGraphBase;
391 399

	
392 400
    protected:
393 401
      int _id;
394 402

	
395 403
      Arc(int id) : _id(id) {}
396 404

	
397 405
    public:
398 406
      Arc() { }
399 407
      Arc (Invalid) { _id = -1; }
400 408

	
401 409
      operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -1); }
402 410

	
403 411
      bool operator==(const Arc arc) const {return _id == arc._id;}
404 412
      bool operator!=(const Arc arc) const {return _id != arc._id;}
405 413
      bool operator<(const Arc arc) const {return _id < arc._id;}
406 414
    };
407 415

	
408 416
    static bool direction(Arc arc) {
409 417
      return (arc._id & 1) == 1;
410 418
    }
411 419

	
412 420
    static Arc direct(Edge edge, bool dir) {
413 421
      return Arc((edge._id << 1) | (dir ? 1 : 0));
414 422
    }
415 423

	
416 424
    void first(Node& node) const {
417 425
      node._id = _node_num - 1;
418 426
    }
419 427

	
420 428
    static void next(Node& node) {
421 429
      --node._id;
422 430
    }
423 431

	
424 432
    void first(Arc& arc) const {
425 433
      arc._id = (_edge_num << 1) - 1;
426 434
    }
427 435

	
428 436
    static void next(Arc& arc) {
429 437
      --arc._id;
430 438
    }
431 439

	
432 440
    void first(Edge& edge) const {
433 441
      edge._id = _edge_num - 1;
434 442
    }
435 443

	
436 444
    static void next(Edge& edge) {
437 445
      --edge._id;
438 446
    }
439 447

	
440 448
    void firstOut(Arc& arc, const Node& node) const {
441 449
      int s = node._id, t = _node_num - 1;
442 450
      if (s < t) {
443 451
        arc._id = (_eid(s, t) << 1) | 1;
444 452
      } else {
445 453
        --t;
446 454
        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
447 455
      }
448 456
    }
449 457

	
450 458
    void nextOut(Arc& arc) const {
451 459
      int s, t;
452 460
      _stid(arc._id, s, t);
453 461
      --t;
454 462
      if (s < t) {
455 463
        arc._id = (_eid(s, t) << 1) | 1;
456 464
      } else {
457 465
        if (s == t) --t;
458 466
        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
459 467
      }
460 468
    }
461 469

	
462 470
    void firstIn(Arc& arc, const Node& node) const {
463 471
      int s = _node_num - 1, t = node._id;
464 472
      if (s > t) {
465 473
        arc._id = (_eid(t, s) << 1);
466 474
      } else {
467 475
        --s;
468 476
        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
469 477
      }
470 478
    }
471 479

	
472 480
    void nextIn(Arc& arc) const {
473 481
      int s, t;
474 482
      _stid(arc._id, s, t);
475 483
      --s;
476 484
      if (s > t) {
477 485
        arc._id = (_eid(t, s) << 1);
478 486
      } else {
479 487
        if (s == t) --s;
480 488
        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
481 489
      }
482 490
    }
483 491

	
484 492
    void firstInc(Edge& edge, bool& dir, const Node& node) const {
485 493
      int u = node._id, v = _node_num - 1;
486 494
      if (u < v) {
487 495
        edge._id = _eid(u, v);
488 496
        dir = true;
489 497
      } else {
490 498
        --v;
491 499
        edge._id = (v != -1 ? _eid(v, u) : -1);
492 500
        dir = false;
493 501
      }
494 502
    }
495 503

	
496 504
    void nextInc(Edge& edge, bool& dir) const {
497 505
      int u, v;
498 506
      if (dir) {
499 507
        _uvid(edge._id, u, v);
500 508
        --v;
501 509
        if (u < v) {
502 510
          edge._id = _eid(u, v);
503 511
        } else {
504 512
          --v;
505 513
          edge._id = (v != -1 ? _eid(v, u) : -1);
506 514
          dir = false;
507 515
        }
508 516
      } else {
509 517
        _uvid(edge._id, v, u);
510 518
        --v;
511 519
        edge._id = (v != -1 ? _eid(v, u) : -1);
512 520
      }
513 521
    }
514 522

	
515 523
  };
516 524

	
517 525
  typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
518 526

	
519 527
  /// \ingroup graphs
520 528
  ///
521 529
  /// \brief An undirected full graph class.
522 530
  ///
523
  /// This is a simple and fast undirected full graph
524
  /// implementation. From each node go edge to each other node,
525
  /// therefore the number of edges in the graph is \f$n(n-1)/2\f$.
526
  /// This graph type is completely static, so you can neither
527
  /// add nor delete either edges or nodes, and it needs constant
528
  /// space in memory.
531
  /// FullGraph is a simple and fast implmenetation of undirected full
532
  /// (complete) graphs. It contains an edge between every distinct pair
533
  /// of nodes, therefore the number of edges is <tt>n(n-1)/2</tt>.
534
  /// This class is completely static and it needs constant memory space.
535
  /// Thus you can neither add nor delete nodes or edges, however
536
  /// the structure can be resized using resize().
529 537
  ///
530
  /// This class fully conforms to the \ref concepts::Graph "Graph concept".
538
  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
539
  /// Most of its member functions and nested classes are documented
540
  /// only in the concept class.
531 541
  ///
532
  /// The \c FullGraph and \c FullDigraph classes are very similar,
533
  /// but there are two differences. While the \c FullDigraph class
542
  /// This class provides constant time counting for nodes, edges and arcs.
543
  ///
544
  /// \note FullDigraph and FullGraph classes are very similar,
545
  /// but there are two differences. While FullDigraph
534 546
  /// conforms only to the \ref concepts::Digraph "Digraph" concept,
535 547
  /// this class conforms to the \ref concepts::Graph "Graph" concept,
536
  /// moreover \c FullGraph does not contain a loop arc for each
537
  /// node as \c FullDigraph does.
548
  /// moreover this class does not contain a loop for each
549
  /// node as FullDigraph does.
538 550
  ///
539 551
  /// \sa FullDigraph
540 552
  class FullGraph : public ExtendedFullGraphBase {
541 553
    typedef ExtendedFullGraphBase Parent;
542 554

	
543 555
  public:
544 556

	
545
    /// \brief Constructor
557
    /// \brief Default constructor.
558
    ///
559
    /// Default constructor. The number of nodes and edges will be zero.
546 560
    FullGraph() { construct(0); }
547 561

	
548 562
    /// \brief Constructor
549 563
    ///
550 564
    /// Constructor.
551 565
    /// \param n The number of the nodes.
552 566
    FullGraph(int n) { construct(n); }
553 567

	
554 568
    /// \brief Resizes the graph
555 569
    ///
556
    /// Resizes the graph. The function will fully destroy and
557
    /// rebuild the graph. This cause that the maps of the graph will
570
    /// This function resizes the graph. It fully destroys and
571
    /// rebuilds the structure, therefore the maps of the graph will be
558 572
    /// reallocated automatically and the previous values will be lost.
559 573
    void resize(int n) {
560 574
      Parent::notifier(Arc()).clear();
561 575
      Parent::notifier(Edge()).clear();
562 576
      Parent::notifier(Node()).clear();
563 577
      construct(n);
564 578
      Parent::notifier(Node()).build();
565 579
      Parent::notifier(Edge()).build();
566 580
      Parent::notifier(Arc()).build();
567 581
    }
568 582

	
569 583
    /// \brief Returns the node with the given index.
570 584
    ///
571
    /// Returns the node with the given index. Since it is a static
572
    /// graph its nodes can be indexed with integers from the range
573
    /// <tt>[0..nodeNum()-1]</tt>.
585
    /// Returns the node with the given index. Since this structure is
586
    /// completely static, the nodes can be indexed with integers from
587
    /// the range <tt>[0..nodeNum()-1]</tt>.
588
    /// The index of a node is the same as its ID.
574 589
    /// \sa index()
575 590
    Node operator()(int ix) const { return Parent::operator()(ix); }
576 591

	
577 592
    /// \brief Returns the index of the given node.
578 593
    ///
579
    /// Returns the index of the given node. Since it is a static
580
    /// graph its nodes can be indexed with integers from the range
581
    /// <tt>[0..nodeNum()-1]</tt>.
582
    /// \sa operator()
583
    int index(const Node& node) const { return Parent::index(node); }
594
    /// Returns the index of the given node. Since this structure is
595
    /// completely static, the nodes can be indexed with integers from
596
    /// the range <tt>[0..nodeNum()-1]</tt>.
597
    /// The index of a node is the same as its ID.
598
    /// \sa operator()()
599
    static int index(const Node& node) { return Parent::index(node); }
584 600

	
585 601
    /// \brief Returns the arc connecting the given nodes.
586 602
    ///
587 603
    /// Returns the arc connecting the given nodes.
588
    Arc arc(const Node& s, const Node& t) const {
604
    Arc arc(Node s, Node t) const {
589 605
      return Parent::arc(s, t);
590 606
    }
591 607

	
592
    /// \brief Returns the edge connects the given nodes.
608
    /// \brief Returns the edge connecting the given nodes.
593 609
    ///
594
    /// Returns the edge connects the given nodes.
595
    Edge edge(const Node& u, const Node& v) const {
610
    /// Returns the edge connecting the given nodes.
611
    Edge edge(Node u, Node v) const {
596 612
      return Parent::edge(u, v);
597 613
    }
598 614

	
599 615
    /// \brief Number of nodes.
600 616
    int nodeNum() const { return Parent::nodeNum(); }
601 617
    /// \brief Number of arcs.
602 618
    int arcNum() const { return Parent::arcNum(); }
603 619
    /// \brief Number of edges.
604 620
    int edgeNum() const { return Parent::edgeNum(); }
605 621

	
606 622
  };
607 623

	
608 624

	
609 625
} //namespace lemon
610 626

	
611 627

	
612 628
#endif //LEMON_FULL_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-2009
5
 * Copyright (C) 2003-2010
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 Implementation of the LEMON GLPK LP and MIP solver interface.
21 21

	
22 22
#include <lemon/glpk.h>
23 23
#include <glpk.h>
24 24

	
25 25
#include <lemon/assert.h>
26 26

	
27 27
namespace lemon {
28 28

	
29 29
  // GlpkBase members
30 30

	
31 31
  GlpkBase::GlpkBase() : LpBase() {
32 32
    lp = glp_create_prob();
33 33
    glp_create_index(lp);
34 34
    messageLevel(MESSAGE_NOTHING);
35 35
  }
36 36

	
37 37
  GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
38 38
    lp = glp_create_prob();
39 39
    glp_copy_prob(lp, other.lp, GLP_ON);
40 40
    glp_create_index(lp);
41 41
    rows = other.rows;
42 42
    cols = other.cols;
43 43
    messageLevel(MESSAGE_NOTHING);
44 44
  }
45 45

	
46 46
  GlpkBase::~GlpkBase() {
47 47
    glp_delete_prob(lp);
48 48
  }
49 49

	
50 50
  int GlpkBase::_addCol() {
51 51
    int i = glp_add_cols(lp, 1);
52 52
    glp_set_col_bnds(lp, i, GLP_FR, 0.0, 0.0);
53 53
    return i;
54 54
  }
55 55

	
56 56
  int GlpkBase::_addRow() {
57 57
    int i = glp_add_rows(lp, 1);
58 58
    glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0);
59 59
    return i;
60 60
  }
61 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

	
62 98
  void GlpkBase::_eraseCol(int i) {
63 99
    int ca[2];
64 100
    ca[1] = i;
65 101
    glp_del_cols(lp, 1, ca);
66 102
  }
67 103

	
68 104
  void GlpkBase::_eraseRow(int i) {
69 105
    int ra[2];
70 106
    ra[1] = i;
71 107
    glp_del_rows(lp, 1, ra);
72 108
  }
73 109

	
74 110
  void GlpkBase::_eraseColId(int i) {
75 111
    cols.eraseIndex(i);
76 112
    cols.shiftIndices(i);
77 113
  }
78 114

	
79 115
  void GlpkBase::_eraseRowId(int i) {
80 116
    rows.eraseIndex(i);
81 117
    rows.shiftIndices(i);
82 118
  }
83 119

	
84 120
  void GlpkBase::_getColName(int c, std::string& name) const {
85 121
    const char *str = glp_get_col_name(lp, c);
86 122
    if (str) name = str;
87 123
    else name.clear();
88 124
  }
89 125

	
90 126
  void GlpkBase::_setColName(int c, const std::string & name) {
91 127
    glp_set_col_name(lp, c, const_cast<char*>(name.c_str()));
92 128

	
93 129
  }
94 130

	
95 131
  int GlpkBase::_colByName(const std::string& name) const {
96 132
    int k = glp_find_col(lp, const_cast<char*>(name.c_str()));
97 133
    return k > 0 ? k : -1;
98 134
  }
99 135

	
100 136
  void GlpkBase::_getRowName(int r, std::string& name) const {
101 137
    const char *str = glp_get_row_name(lp, r);
102 138
    if (str) name = str;
103 139
    else name.clear();
104 140
  }
105 141

	
106 142
  void GlpkBase::_setRowName(int r, const std::string & name) {
107 143
    glp_set_row_name(lp, r, const_cast<char*>(name.c_str()));
108 144

	
109 145
  }
110 146

	
111 147
  int GlpkBase::_rowByName(const std::string& name) const {
112 148
    int k = glp_find_row(lp, const_cast<char*>(name.c_str()));
113 149
    return k > 0 ? k : -1;
114 150
  }
115 151

	
116 152
  void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
117 153
    std::vector<int> indexes;
118 154
    std::vector<Value> values;
119 155

	
120 156
    indexes.push_back(0);
121 157
    values.push_back(0);
122 158

	
123 159
    for(ExprIterator it = b; it != e; ++it) {
124 160
      indexes.push_back(it->first);
125 161
      values.push_back(it->second);
126 162
    }
127 163

	
128 164
    glp_set_mat_row(lp, i, values.size() - 1,
129 165
                    &indexes.front(), &values.front());
130 166
  }
131 167

	
132 168
  void GlpkBase::_getRowCoeffs(int ix, InsertIterator b) const {
133 169
    int length = glp_get_mat_row(lp, ix, 0, 0);
134 170

	
135 171
    std::vector<int> indexes(length + 1);
136 172
    std::vector<Value> values(length + 1);
137 173

	
138 174
    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
139 175

	
140 176
    for (int i = 1; i <= length; ++i) {
141 177
      *b = std::make_pair(indexes[i], values[i]);
142 178
      ++b;
143 179
    }
144 180
  }
145 181

	
146 182
  void GlpkBase::_setColCoeffs(int ix, ExprIterator b,
147 183
                                     ExprIterator e) {
148 184

	
149 185
    std::vector<int> indexes;
150 186
    std::vector<Value> values;
151 187

	
152 188
    indexes.push_back(0);
153 189
    values.push_back(0);
154 190

	
155 191
    for(ExprIterator it = b; it != e; ++it) {
156 192
      indexes.push_back(it->first);
157 193
      values.push_back(it->second);
158 194
    }
159 195

	
160 196
    glp_set_mat_col(lp, ix, values.size() - 1,
161 197
                    &indexes.front(), &values.front());
162 198
  }
163 199

	
164 200
  void GlpkBase::_getColCoeffs(int ix, InsertIterator b) const {
165 201
    int length = glp_get_mat_col(lp, ix, 0, 0);
166 202

	
167 203
    std::vector<int> indexes(length + 1);
168 204
    std::vector<Value> values(length + 1);
169 205

	
170 206
    glp_get_mat_col(lp, ix, &indexes.front(), &values.front());
171 207

	
172 208
    for (int i = 1; i  <= length; ++i) {
173 209
      *b = std::make_pair(indexes[i], values[i]);
174 210
      ++b;
175 211
    }
176 212
  }
177 213

	
178 214
  void GlpkBase::_setCoeff(int ix, int jx, Value value) {
179 215

	
180 216
    if (glp_get_num_cols(lp) < glp_get_num_rows(lp)) {
181 217

	
182 218
      int length = glp_get_mat_row(lp, ix, 0, 0);
183 219

	
184 220
      std::vector<int> indexes(length + 2);
185 221
      std::vector<Value> values(length + 2);
186 222

	
187 223
      glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
188 224

	
189 225
      //The following code does not suppose that the elements of the
190 226
      //array indexes are sorted
191 227
      bool found = false;
192 228
      for (int i = 1; i  <= length; ++i) {
193 229
        if (indexes[i] == jx) {
194 230
          found = true;
195 231
          values[i] = value;
196 232
          break;
197 233
        }
198 234
      }
199 235
      if (!found) {
200 236
        ++length;
201 237
        indexes[length] = jx;
202 238
        values[length] = value;
203 239
      }
204 240

	
205 241
      glp_set_mat_row(lp, ix, length, &indexes.front(), &values.front());
206 242

	
207 243
    } else {
208 244

	
209 245
      int length = glp_get_mat_col(lp, jx, 0, 0);
210 246

	
211 247
      std::vector<int> indexes(length + 2);
212 248
      std::vector<Value> values(length + 2);
213 249

	
214 250
      glp_get_mat_col(lp, jx, &indexes.front(), &values.front());
215 251

	
216 252
      //The following code does not suppose that the elements of the
217 253
      //array indexes are sorted
218 254
      bool found = false;
219 255
      for (int i = 1; i <= length; ++i) {
220 256
        if (indexes[i] == ix) {
221 257
          found = true;
222 258
          values[i] = value;
223 259
          break;
224 260
        }
225 261
      }
226 262
      if (!found) {
227 263
        ++length;
228 264
        indexes[length] = ix;
229 265
        values[length] = value;
230 266
      }
231 267

	
232 268
      glp_set_mat_col(lp, jx, length, &indexes.front(), &values.front());
233 269
    }
234 270

	
235 271
  }
236 272

	
237 273
  GlpkBase::Value GlpkBase::_getCoeff(int ix, int jx) const {
238 274

	
239 275
    int length = glp_get_mat_row(lp, ix, 0, 0);
240 276

	
241 277
    std::vector<int> indexes(length + 1);
242 278
    std::vector<Value> values(length + 1);
243 279

	
244 280
    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
245 281

	
246 282
    for (int i = 1; i  <= length; ++i) {
247 283
      if (indexes[i] == jx) {
248 284
        return values[i];
249 285
      }
250 286
    }
251 287

	
252 288
    return 0;
253 289
  }
254 290

	
255 291
  void GlpkBase::_setColLowerBound(int i, Value lo) {
256 292
    LEMON_ASSERT(lo != INF, "Invalid bound");
257 293

	
258 294
    int b = glp_get_col_type(lp, i);
259 295
    double up = glp_get_col_ub(lp, i);
260 296
    if (lo == -INF) {
261 297
      switch (b) {
262 298
      case GLP_FR:
263 299
      case GLP_LO:
264 300
        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
265 301
        break;
266 302
      case GLP_UP:
267 303
        break;
268 304
      case GLP_DB:
269 305
      case GLP_FX:
270 306
        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
271 307
        break;
272 308
      default:
273 309
        break;
274 310
      }
275 311
    } else {
276 312
      switch (b) {
277 313
      case GLP_FR:
278 314
      case GLP_LO:
279 315
        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
280 316
        break;
281 317
      case GLP_UP:
282 318
      case GLP_DB:
283 319
      case GLP_FX:
284 320
        if (lo == up)
285 321
          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
286 322
        else
287 323
          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
288 324
        break;
289 325
      default:
290 326
        break;
291 327
      }
292 328
    }
293 329
  }
294 330

	
295 331
  GlpkBase::Value GlpkBase::_getColLowerBound(int i) const {
296 332
    int b = glp_get_col_type(lp, i);
297 333
    switch (b) {
298 334
    case GLP_LO:
299 335
    case GLP_DB:
300 336
    case GLP_FX:
301 337
      return glp_get_col_lb(lp, i);
302 338
    default:
303 339
      return -INF;
304 340
    }
305 341
  }
306 342

	
307 343
  void GlpkBase::_setColUpperBound(int i, Value up) {
308 344
    LEMON_ASSERT(up != -INF, "Invalid bound");
309 345

	
310 346
    int b = glp_get_col_type(lp, i);
311 347
    double lo = glp_get_col_lb(lp, i);
312 348
    if (up == INF) {
313 349
      switch (b) {
314 350
      case GLP_FR:
315 351
      case GLP_LO:
316 352
        break;
317 353
      case GLP_UP:
318 354
        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
319 355
        break;
320 356
      case GLP_DB:
321 357
      case GLP_FX:
322 358
        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
323 359
        break;
324 360
      default:
325 361
        break;
326 362
      }
327 363
    } else {
328 364
      switch (b) {
329 365
      case GLP_FR:
330 366
        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
331 367
        break;
332 368
      case GLP_UP:
333 369
        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
334 370
        break;
335 371
      case GLP_LO:
336 372
      case GLP_DB:
337 373
      case GLP_FX:
338 374
        if (lo == up)
339 375
          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
340 376
        else
341 377
          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
342 378
        break;
343 379
      default:
344 380
        break;
345 381
      }
346 382
    }
347 383

	
348 384
  }
349 385

	
350 386
  GlpkBase::Value GlpkBase::_getColUpperBound(int i) const {
351 387
    int b = glp_get_col_type(lp, i);
352 388
      switch (b) {
353 389
      case GLP_UP:
354 390
      case GLP_DB:
355 391
      case GLP_FX:
356 392
        return glp_get_col_ub(lp, i);
357 393
      default:
358 394
        return INF;
359 395
      }
360 396
  }
361 397

	
362 398
  void GlpkBase::_setRowLowerBound(int i, Value lo) {
363 399
    LEMON_ASSERT(lo != INF, "Invalid bound");
364 400

	
365 401
    int b = glp_get_row_type(lp, i);
366 402
    double up = glp_get_row_ub(lp, i);
367 403
    if (lo == -INF) {
368 404
      switch (b) {
369 405
      case GLP_FR:
370 406
      case GLP_LO:
371 407
        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
372 408
        break;
373 409
      case GLP_UP:
374 410
        break;
375 411
      case GLP_DB:
376 412
      case GLP_FX:
377 413
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
378 414
        break;
379 415
      default:
380 416
        break;
381 417
      }
382 418
    } else {
383 419
      switch (b) {
384 420
      case GLP_FR:
385 421
      case GLP_LO:
386 422
        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
387 423
        break;
388 424
      case GLP_UP:
389 425
      case GLP_DB:
390 426
      case GLP_FX:
391 427
        if (lo == up)
392 428
          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
393 429
        else
394 430
          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
395 431
        break;
396 432
      default:
397 433
        break;
398 434
      }
399 435
    }
400 436

	
401 437
  }
402 438

	
403 439
  GlpkBase::Value GlpkBase::_getRowLowerBound(int i) const {
404 440
    int b = glp_get_row_type(lp, i);
405 441
    switch (b) {
406 442
    case GLP_LO:
407 443
    case GLP_DB:
408 444
    case GLP_FX:
409 445
      return glp_get_row_lb(lp, i);
410 446
    default:
411 447
      return -INF;
412 448
    }
413 449
  }
414 450

	
415 451
  void GlpkBase::_setRowUpperBound(int i, Value up) {
416 452
    LEMON_ASSERT(up != -INF, "Invalid bound");
417 453

	
418 454
    int b = glp_get_row_type(lp, i);
419 455
    double lo = glp_get_row_lb(lp, i);
420 456
    if (up == INF) {
421 457
      switch (b) {
422 458
      case GLP_FR:
423 459
      case GLP_LO:
424 460
        break;
425 461
      case GLP_UP:
426 462
        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
427 463
        break;
428 464
      case GLP_DB:
429 465
      case GLP_FX:
430 466
        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
431 467
        break;
432 468
      default:
433 469
        break;
434 470
      }
435 471
    } else {
436 472
      switch (b) {
437 473
      case GLP_FR:
438 474
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
439 475
        break;
440 476
      case GLP_UP:
441 477
        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
442 478
        break;
443 479
      case GLP_LO:
444 480
      case GLP_DB:
445 481
      case GLP_FX:
446 482
        if (lo == up)
447 483
          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
448 484
        else
449 485
          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
450 486
        break;
451 487
      default:
452 488
        break;
453 489
      }
454 490
    }
455 491
  }
456 492

	
457 493
  GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const {
458 494
    int b = glp_get_row_type(lp, i);
459 495
    switch (b) {
460 496
    case GLP_UP:
461 497
    case GLP_DB:
462 498
    case GLP_FX:
463 499
      return glp_get_row_ub(lp, i);
464 500
    default:
465 501
      return INF;
466 502
    }
467 503
  }
468 504

	
469 505
  void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) {
470 506
    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
471 507
      glp_set_obj_coef(lp, i, 0.0);
472 508
    }
473 509
    for (ExprIterator it = b; it != e; ++it) {
474 510
      glp_set_obj_coef(lp, it->first, it->second);
475 511
    }
476 512
  }
477 513

	
478 514
  void GlpkBase::_getObjCoeffs(InsertIterator b) const {
479 515
    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
480 516
      Value val = glp_get_obj_coef(lp, i);
481 517
      if (val != 0.0) {
482 518
        *b = std::make_pair(i, val);
483 519
        ++b;
484 520
      }
485 521
    }
486 522
  }
487 523

	
488 524
  void GlpkBase::_setObjCoeff(int i, Value obj_coef) {
489 525
    //i = 0 means the constant term (shift)
490 526
    glp_set_obj_coef(lp, i, obj_coef);
491 527
  }
492 528

	
493 529
  GlpkBase::Value GlpkBase::_getObjCoeff(int i) const {
494 530
    //i = 0 means the constant term (shift)
495 531
    return glp_get_obj_coef(lp, i);
496 532
  }
497 533

	
498 534
  void GlpkBase::_setSense(GlpkBase::Sense sense) {
499 535
    switch (sense) {
500 536
    case MIN:
501 537
      glp_set_obj_dir(lp, GLP_MIN);
502 538
      break;
503 539
    case MAX:
504 540
      glp_set_obj_dir(lp, GLP_MAX);
505 541
      break;
506 542
    }
507 543
  }
508 544

	
509 545
  GlpkBase::Sense GlpkBase::_getSense() const {
510 546
    switch(glp_get_obj_dir(lp)) {
511 547
    case GLP_MIN:
512 548
      return MIN;
513 549
    case GLP_MAX:
514 550
      return MAX;
515 551
    default:
516 552
      LEMON_ASSERT(false, "Wrong sense");
517 553
      return GlpkBase::Sense();
518 554
    }
519 555
  }
520 556

	
521 557
  void GlpkBase::_clear() {
522 558
    glp_erase_prob(lp);
523 559
    rows.clear();
524 560
    cols.clear();
525 561
  }
526 562

	
527 563
  void GlpkBase::freeEnv() {
528 564
    glp_free_env();
529 565
  }
530 566

	
531 567
  void GlpkBase::_messageLevel(MessageLevel level) {
532 568
    switch (level) {
533 569
    case MESSAGE_NOTHING:
534 570
      _message_level = GLP_MSG_OFF;
535 571
      break;
536 572
    case MESSAGE_ERROR:
537 573
      _message_level = GLP_MSG_ERR;
538 574
      break;
539 575
    case MESSAGE_WARNING:
540 576
      _message_level = GLP_MSG_ERR;
541 577
      break;
542 578
    case MESSAGE_NORMAL:
543 579
      _message_level = GLP_MSG_ON;
544 580
      break;
545 581
    case MESSAGE_VERBOSE:
546 582
      _message_level = GLP_MSG_ALL;
547 583
      break;
548 584
    }
549 585
  }
550 586

	
551 587
  GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
552 588

	
553 589
  // GlpkLp members
554 590

	
555 591
  GlpkLp::GlpkLp()
556 592
    : LpBase(), LpSolver(), GlpkBase() {
557 593
    presolver(false);
558 594
  }
559 595

	
560 596
  GlpkLp::GlpkLp(const GlpkLp& other)
561 597
    : LpBase(other), LpSolver(other), GlpkBase(other) {
562 598
    presolver(false);
563 599
  }
564 600

	
565 601
  GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
566 602
  GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
567 603

	
568 604
  const char* GlpkLp::_solverName() const { return "GlpkLp"; }
569 605

	
570 606
  void GlpkLp::_clear_temporals() {
571 607
    _primal_ray.clear();
572 608
    _dual_ray.clear();
573 609
  }
574 610

	
575 611
  GlpkLp::SolveExitStatus GlpkLp::_solve() {
576 612
    return solvePrimal();
577 613
  }
578 614

	
579 615
  GlpkLp::SolveExitStatus GlpkLp::solvePrimal() {
580 616
    _clear_temporals();
581 617

	
582 618
    glp_smcp smcp;
583 619
    glp_init_smcp(&smcp);
584 620

	
585 621
    smcp.msg_lev = _message_level;
586 622
    smcp.presolve = _presolve;
587 623

	
588 624
    // If the basis is not valid we get an error return value.
589 625
    // In this case we can try to create a new basis.
590 626
    switch (glp_simplex(lp, &smcp)) {
591 627
    case 0:
592 628
      break;
593 629
    case GLP_EBADB:
594 630
    case GLP_ESING:
595 631
    case GLP_ECOND:
596 632
      glp_term_out(false);
597 633
      glp_adv_basis(lp, 0);
598 634
      glp_term_out(true);
599 635
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
600 636
      break;
601 637
    default:
602 638
      return UNSOLVED;
603 639
    }
604 640

	
605 641
    return SOLVED;
606 642
  }
607 643

	
608 644
  GlpkLp::SolveExitStatus GlpkLp::solveDual() {
609 645
    _clear_temporals();
610 646

	
611 647
    glp_smcp smcp;
612 648
    glp_init_smcp(&smcp);
613 649

	
614 650
    smcp.msg_lev = _message_level;
615 651
    smcp.meth = GLP_DUAL;
616 652
    smcp.presolve = _presolve;
617 653

	
618 654
    // If the basis is not valid we get an error return value.
619 655
    // In this case we can try to create a new basis.
620 656
    switch (glp_simplex(lp, &smcp)) {
621 657
    case 0:
622 658
      break;
623 659
    case GLP_EBADB:
624 660
    case GLP_ESING:
625 661
    case GLP_ECOND:
626 662
      glp_term_out(false);
627 663
      glp_adv_basis(lp, 0);
628 664
      glp_term_out(true);
629 665
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
630 666
      break;
631 667
    default:
632 668
      return UNSOLVED;
633 669
    }
634 670
    return SOLVED;
635 671
  }
636 672

	
637 673
  GlpkLp::Value GlpkLp::_getPrimal(int i) const {
638 674
    return glp_get_col_prim(lp, i);
639 675
  }
640 676

	
641 677
  GlpkLp::Value GlpkLp::_getDual(int i) const {
642 678
    return glp_get_row_dual(lp, i);
643 679
  }
644 680

	
645 681
  GlpkLp::Value GlpkLp::_getPrimalValue() const {
646 682
    return glp_get_obj_val(lp);
647 683
  }
648 684

	
649 685
  GlpkLp::VarStatus GlpkLp::_getColStatus(int i) const {
650 686
    switch (glp_get_col_stat(lp, i)) {
651 687
    case GLP_BS:
652 688
      return BASIC;
653 689
    case GLP_UP:
654 690
      return UPPER;
655 691
    case GLP_LO:
656 692
      return LOWER;
657 693
    case GLP_NF:
658 694
      return FREE;
659 695
    case GLP_NS:
660 696
      return FIXED;
661 697
    default:
662 698
      LEMON_ASSERT(false, "Wrong column status");
663 699
      return GlpkLp::VarStatus();
664 700
    }
665 701
  }
666 702

	
667 703
  GlpkLp::VarStatus GlpkLp::_getRowStatus(int i) const {
668 704
    switch (glp_get_row_stat(lp, i)) {
669 705
    case GLP_BS:
670 706
      return BASIC;
671 707
    case GLP_UP:
672 708
      return UPPER;
673 709
    case GLP_LO:
674 710
      return LOWER;
675 711
    case GLP_NF:
676 712
      return FREE;
677 713
    case GLP_NS:
678 714
      return FIXED;
679 715
    default:
680 716
      LEMON_ASSERT(false, "Wrong row status");
681 717
      return GlpkLp::VarStatus();
682 718
    }
683 719
  }
684 720

	
685 721
  GlpkLp::Value GlpkLp::_getPrimalRay(int i) const {
686 722
    if (_primal_ray.empty()) {
687 723
      int row_num = glp_get_num_rows(lp);
688 724
      int col_num = glp_get_num_cols(lp);
689 725

	
690 726
      _primal_ray.resize(col_num + 1, 0.0);
691 727

	
692 728
      int index = glp_get_unbnd_ray(lp);
693 729
      if (index != 0) {
694 730
        // The primal ray is found in primal simplex second phase
695 731
        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
696 732
                      glp_get_col_stat(lp, index - row_num)) != GLP_BS,
697 733
                     "Wrong primal ray");
698 734

	
699 735
        bool negate = glp_get_obj_dir(lp) == GLP_MAX;
700 736

	
701 737
        if (index > row_num) {
702 738
          _primal_ray[index - row_num] = 1.0;
703 739
          if (glp_get_col_dual(lp, index - row_num) > 0) {
704 740
            negate = !negate;
705 741
          }
706 742
        } else {
707 743
          if (glp_get_row_dual(lp, index) > 0) {
708 744
            negate = !negate;
709 745
          }
710 746
        }
711 747

	
712 748
        std::vector<int> ray_indexes(row_num + 1);
713 749
        std::vector<Value> ray_values(row_num + 1);
714 750
        int ray_length = glp_eval_tab_col(lp, index, &ray_indexes.front(),
715 751
                                          &ray_values.front());
716 752

	
717 753
        for (int i = 1; i <= ray_length; ++i) {
718 754
          if (ray_indexes[i] > row_num) {
719 755
            _primal_ray[ray_indexes[i] - row_num] = ray_values[i];
720 756
          }
721 757
        }
722 758

	
723 759
        if (negate) {
724 760
          for (int i = 1; i <= col_num; ++i) {
725 761
            _primal_ray[i] = - _primal_ray[i];
726 762
          }
727 763
        }
728 764
      } else {
729 765
        for (int i = 1; i <= col_num; ++i) {
730 766
          _primal_ray[i] = glp_get_col_prim(lp, i);
731 767
        }
732 768
      }
733 769
    }
734 770
    return _primal_ray[i];
735 771
  }
736 772

	
737 773
  GlpkLp::Value GlpkLp::_getDualRay(int i) const {
738 774
    if (_dual_ray.empty()) {
739 775
      int row_num = glp_get_num_rows(lp);
740 776

	
741 777
      _dual_ray.resize(row_num + 1, 0.0);
742 778

	
743 779
      int index = glp_get_unbnd_ray(lp);
744 780
      if (index != 0) {
745 781
        // The dual ray is found in dual simplex second phase
746 782
        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
747 783
                      glp_get_col_stat(lp, index - row_num)) == GLP_BS,
748 784

	
749 785
                     "Wrong dual ray");
750 786

	
751 787
        int idx;
752 788
        bool negate = false;
753 789

	
754 790
        if (index > row_num) {
755 791
          idx = glp_get_col_bind(lp, index - row_num);
756 792
          if (glp_get_col_prim(lp, index - row_num) >
757 793
              glp_get_col_ub(lp, index - row_num)) {
758 794
            negate = true;
759 795
          }
760 796
        } else {
761 797
          idx = glp_get_row_bind(lp, index);
762 798
          if (glp_get_row_prim(lp, index) > glp_get_row_ub(lp, index)) {
763 799
            negate = true;
764 800
          }
765 801
        }
766 802

	
767 803
        _dual_ray[idx] = negate ?  - 1.0 : 1.0;
768 804

	
769 805
        glp_btran(lp, &_dual_ray.front());
770 806
      } else {
771 807
        double eps = 1e-7;
772 808
        // The dual ray is found in primal simplex first phase
773 809
        // We assume that the glpk minimizes the slack to get feasible solution
774 810
        for (int i = 1; i <= row_num; ++i) {
775 811
          int index = glp_get_bhead(lp, i);
776 812
          if (index <= row_num) {
777 813
            double res = glp_get_row_prim(lp, index);
778 814
            if (res > glp_get_row_ub(lp, index) + eps) {
779 815
              _dual_ray[i] = -1;
780 816
            } else if (res < glp_get_row_lb(lp, index) - eps) {
781 817
              _dual_ray[i] = 1;
782 818
            } else {
783 819
              _dual_ray[i] = 0;
784 820
            }
785 821
            _dual_ray[i] *= glp_get_rii(lp, index);
786 822
          } else {
787 823
            double res = glp_get_col_prim(lp, index - row_num);
788 824
            if (res > glp_get_col_ub(lp, index - row_num) + eps) {
789 825
              _dual_ray[i] = -1;
790 826
            } else if (res < glp_get_col_lb(lp, index - row_num) - eps) {
791 827
              _dual_ray[i] = 1;
792 828
            } else {
793 829
              _dual_ray[i] = 0;
794 830
            }
795 831
            _dual_ray[i] /= glp_get_sjj(lp, index - row_num);
796 832
          }
797 833
        }
798 834

	
799 835
        glp_btran(lp, &_dual_ray.front());
800 836

	
801 837
        for (int i = 1; i <= row_num; ++i) {
802 838
          _dual_ray[i] /= glp_get_rii(lp, i);
803 839
        }
804 840
      }
805 841
    }
806 842
    return _dual_ray[i];
807 843
  }
808 844

	
809 845
  GlpkLp::ProblemType GlpkLp::_getPrimalType() const {
810 846
    if (glp_get_status(lp) == GLP_OPT)
811 847
      return OPTIMAL;
812 848
    switch (glp_get_prim_stat(lp)) {
813 849
    case GLP_UNDEF:
814 850
      return UNDEFINED;
815 851
    case GLP_FEAS:
816 852
    case GLP_INFEAS:
817 853
      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
818 854
        return UNBOUNDED;
819 855
      } else {
820 856
        return UNDEFINED;
821 857
      }
822 858
    case GLP_NOFEAS:
823 859
      return INFEASIBLE;
824 860
    default:
825 861
      LEMON_ASSERT(false, "Wrong primal type");
826 862
      return  GlpkLp::ProblemType();
827 863
    }
828 864
  }
829 865

	
830 866
  GlpkLp::ProblemType GlpkLp::_getDualType() const {
831 867
    if (glp_get_status(lp) == GLP_OPT)
832 868
      return OPTIMAL;
833 869
    switch (glp_get_dual_stat(lp)) {
834 870
    case GLP_UNDEF:
835 871
      return UNDEFINED;
836 872
    case GLP_FEAS:
837 873
    case GLP_INFEAS:
838 874
      if (glp_get_prim_stat(lp) == GLP_NOFEAS) {
839 875
        return UNBOUNDED;
840 876
      } else {
841 877
        return UNDEFINED;
842 878
      }
843 879
    case GLP_NOFEAS:
844 880
      return INFEASIBLE;
845 881
    default:
846 882
      LEMON_ASSERT(false, "Wrong primal type");
847 883
      return  GlpkLp::ProblemType();
848 884
    }
849 885
  }
850 886

	
851 887
  void GlpkLp::presolver(bool presolve) {
852 888
    _presolve = presolve;
853 889
  }
854 890

	
855 891
  // GlpkMip members
856 892

	
857 893
  GlpkMip::GlpkMip()
858 894
    : LpBase(), MipSolver(), GlpkBase() {
859 895
  }
860 896

	
861 897
  GlpkMip::GlpkMip(const GlpkMip& other)
862 898
    : LpBase(), MipSolver(), GlpkBase(other) {
863 899
  }
864 900

	
865 901
  void GlpkMip::_setColType(int i, GlpkMip::ColTypes col_type) {
866 902
    switch (col_type) {
867 903
    case INTEGER:
868 904
      glp_set_col_kind(lp, i, GLP_IV);
869 905
      break;
870 906
    case REAL:
871 907
      glp_set_col_kind(lp, i, GLP_CV);
872 908
      break;
873 909
    }
874 910
  }
875 911

	
876 912
  GlpkMip::ColTypes GlpkMip::_getColType(int i) const {
877 913
    switch (glp_get_col_kind(lp, i)) {
878 914
    case GLP_IV:
879 915
    case GLP_BV:
880 916
      return INTEGER;
881 917
    default:
882 918
      return REAL;
883 919
    }
884 920

	
885 921
  }
886 922

	
887 923
  GlpkMip::SolveExitStatus GlpkMip::_solve() {
888 924
    glp_smcp smcp;
889 925
    glp_init_smcp(&smcp);
890 926

	
891 927
    smcp.msg_lev = _message_level;
892 928
    smcp.meth = GLP_DUAL;
893 929

	
894 930
    // If the basis is not valid we get an error return value.
895 931
    // In this case we can try to create a new basis.
896 932
    switch (glp_simplex(lp, &smcp)) {
897 933
    case 0:
898 934
      break;
899 935
    case GLP_EBADB:
900 936
    case GLP_ESING:
901 937
    case GLP_ECOND:
902 938
      glp_term_out(false);
903 939
      glp_adv_basis(lp, 0);
904 940
      glp_term_out(true);
905 941
      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
906 942
      break;
907 943
    default:
908 944
      return UNSOLVED;
909 945
    }
910 946

	
911 947
    if (glp_get_status(lp) != GLP_OPT) return SOLVED;
912 948

	
913 949
    glp_iocp iocp;
914 950
    glp_init_iocp(&iocp);
915 951

	
916 952
    iocp.msg_lev = _message_level;
917 953

	
918 954
    if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
919 955
    return SOLVED;
920 956
  }
921 957

	
922 958

	
923 959
  GlpkMip::ProblemType GlpkMip::_getType() const {
924 960
    switch (glp_get_status(lp)) {
925 961
    case GLP_OPT:
926 962
      switch (glp_mip_status(lp)) {
927 963
      case GLP_UNDEF:
928 964
        return UNDEFINED;
929 965
      case GLP_NOFEAS:
930 966
        return INFEASIBLE;
931 967
      case GLP_FEAS:
932 968
        return FEASIBLE;
933 969
      case GLP_OPT:
934 970
        return OPTIMAL;
935 971
      default:
936 972
        LEMON_ASSERT(false, "Wrong problem type.");
937 973
        return GlpkMip::ProblemType();
938 974
      }
939 975
    case GLP_NOFEAS:
940 976
      return INFEASIBLE;
941 977
    case GLP_INFEAS:
942 978
    case GLP_FEAS:
943 979
      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
944 980
        return UNBOUNDED;
945 981
      } else {
946 982
        return UNDEFINED;
947 983
      }
948 984
    default:
949 985
      LEMON_ASSERT(false, "Wrong problem type.");
950 986
      return GlpkMip::ProblemType();
951 987
    }
952 988
  }
953 989

	
954 990
  GlpkMip::Value GlpkMip::_getSol(int i) const {
955 991
    return glp_mip_col_val(lp, i);
956 992
  }
957 993

	
958 994
  GlpkMip::Value GlpkMip::_getSolValue() const {
959 995
    return glp_mip_obj_val(lp);
960 996
  }
961 997

	
962 998
  GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; }
963 999
  GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); }
964 1000

	
965 1001
  const char* GlpkMip::_solverName() const { return "GlpkMip"; }
966 1002

	
967 1003
} //END OF 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-2010
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_GLPK_H
20 20
#define LEMON_GLPK_H
21 21

	
22 22
///\file
23 23
///\brief Header of the LEMON-GLPK lp solver interface.
24 24
///\ingroup lp_group
25 25

	
26 26
#include <lemon/lp_base.h>
27 27

	
28 28
namespace lemon {
29 29

	
30 30
  namespace _solver_bits {
31 31
    class VoidPtr {
32 32
    private:
33
      void *_ptr;      
33
      void *_ptr;
34 34
    public:
35 35
      VoidPtr() : _ptr(0) {}
36 36

	
37 37
      template <typename T>
38 38
      VoidPtr(T* ptr) : _ptr(reinterpret_cast<void*>(ptr)) {}
39 39

	
40 40
      template <typename T>
41
      VoidPtr& operator=(T* ptr) { 
42
        _ptr = reinterpret_cast<void*>(ptr); 
41
      VoidPtr& operator=(T* ptr) {
42
        _ptr = reinterpret_cast<void*>(ptr);
43 43
        return *this;
44 44
      }
45 45

	
46 46
      template <typename T>
47 47
      operator T*() const { return reinterpret_cast<T*>(_ptr); }
48 48
    };
49 49
  }
50 50

	
51 51
  /// \brief Base interface for the GLPK LP and MIP solver
52 52
  ///
53 53
  /// This class implements the common interface of the GLPK LP and MIP solver.
54 54
  /// \ingroup lp_group
55 55
  class GlpkBase : virtual public LpBase {
56 56
  protected:
57 57

	
58 58
    _solver_bits::VoidPtr lp;
59 59

	
60 60
    GlpkBase();
61 61
    GlpkBase(const GlpkBase&);
62 62
    virtual ~GlpkBase();
63 63

	
64 64
  protected:
65 65

	
66 66
    virtual int _addCol();
67 67
    virtual int _addRow();
68
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
68 69

	
69 70
    virtual void _eraseCol(int i);
70 71
    virtual void _eraseRow(int i);
71 72

	
72 73
    virtual void _eraseColId(int i);
73 74
    virtual void _eraseRowId(int i);
74 75

	
75 76
    virtual void _getColName(int col, std::string& name) const;
76 77
    virtual void _setColName(int col, const std::string& name);
77 78
    virtual int _colByName(const std::string& name) const;
78 79

	
79 80
    virtual void _getRowName(int row, std::string& name) const;
80 81
    virtual void _setRowName(int row, const std::string& name);
81 82
    virtual int _rowByName(const std::string& name) const;
82 83

	
83 84
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
84 85
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
85 86

	
86 87
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
87 88
    virtual void _getColCoeffs(int i, InsertIterator b) const;
88 89

	
89 90
    virtual void _setCoeff(int row, int col, Value value);
90 91
    virtual Value _getCoeff(int row, int col) const;
91 92

	
92 93
    virtual void _setColLowerBound(int i, Value value);
93 94
    virtual Value _getColLowerBound(int i) const;
94 95

	
95 96
    virtual void _setColUpperBound(int i, Value value);
96 97
    virtual Value _getColUpperBound(int i) const;
97 98

	
98 99
    virtual void _setRowLowerBound(int i, Value value);
99 100
    virtual Value _getRowLowerBound(int i) const;
100 101

	
101 102
    virtual void _setRowUpperBound(int i, Value value);
102 103
    virtual Value _getRowUpperBound(int i) const;
103 104

	
104 105
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
105 106
    virtual void _getObjCoeffs(InsertIterator b) const;
106 107

	
107 108
    virtual void _setObjCoeff(int i, Value obj_coef);
108 109
    virtual Value _getObjCoeff(int i) const;
109 110

	
110 111
    virtual void _setSense(Sense);
111 112
    virtual Sense _getSense() const;
112 113

	
113 114
    virtual void _clear();
114 115

	
115 116
    virtual void _messageLevel(MessageLevel level);
116 117

	
117 118
  private:
118 119

	
119 120
    static void freeEnv();
120 121

	
121 122
    struct FreeEnvHelper {
122 123
      ~FreeEnvHelper() {
123 124
        freeEnv();
124 125
      }
125 126
    };
126
    
127

	
127 128
    static FreeEnvHelper freeEnvHelper;
128 129

	
129 130
  protected:
130
    
131

	
131 132
    int _message_level;
132
    
133

	
133 134
  public:
134 135

	
135 136
    ///Pointer to the underlying GLPK data structure.
136 137
    _solver_bits::VoidPtr lpx() {return lp;}
137 138
    ///Const pointer to the underlying GLPK data structure.
138 139
    _solver_bits::VoidPtr lpx() const {return lp;}
139 140

	
140 141
    ///Returns the constraint identifier understood by GLPK.
141 142
    int lpxRow(Row r) const { return rows(id(r)); }
142 143

	
143 144
    ///Returns the variable identifier understood by GLPK.
144 145
    int lpxCol(Col c) const { return cols(id(c)); }
145 146

	
146 147
  };
147 148

	
148 149
  /// \brief Interface for the GLPK LP solver
149 150
  ///
150 151
  /// This class implements an interface for the GLPK LP solver.
151 152
  ///\ingroup lp_group
152 153
  class GlpkLp : public LpSolver, public GlpkBase {
153 154
  public:
154 155

	
155 156
    ///\e
156 157
    GlpkLp();
157 158
    ///\e
158 159
    GlpkLp(const GlpkLp&);
159 160

	
160 161
    ///\e
161 162
    virtual GlpkLp* cloneSolver() const;
162 163
    ///\e
163 164
    virtual GlpkLp* newSolver() const;
164 165

	
165 166
  private:
166 167

	
167 168
    mutable std::vector<double> _primal_ray;
168 169
    mutable std::vector<double> _dual_ray;
169 170

	
170 171
    void _clear_temporals();
171 172

	
172 173
  protected:
173 174

	
174 175
    virtual const char* _solverName() const;
175 176

	
176 177
    virtual SolveExitStatus _solve();
177 178
    virtual Value _getPrimal(int i) const;
178 179
    virtual Value _getDual(int i) const;
179 180

	
180 181
    virtual Value _getPrimalValue() const;
181 182

	
182 183
    virtual VarStatus _getColStatus(int i) const;
183 184
    virtual VarStatus _getRowStatus(int i) const;
184 185

	
185 186
    virtual Value _getPrimalRay(int i) const;
186 187
    virtual Value _getDualRay(int i) const;
187 188

	
188 189
    virtual ProblemType _getPrimalType() const;
189 190
    virtual ProblemType _getDualType() const;
190 191

	
191 192
  public:
192 193

	
193 194
    ///Solve with primal simplex
194 195
    SolveExitStatus solvePrimal();
195 196

	
196 197
    ///Solve with dual simplex
197 198
    SolveExitStatus solveDual();
198 199

	
199 200
  private:
200 201

	
201 202
    bool _presolve;
202 203

	
203 204
  public:
204 205

	
205 206
    ///Turns on or off the presolver
206 207

	
207 208
    ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
208 209
    ///
209 210
    ///The presolver is off by default.
210 211
    void presolver(bool presolve);
211 212

	
212 213
  };
213 214

	
214 215
  /// \brief Interface for the GLPK MIP solver
215 216
  ///
216 217
  /// This class implements an interface for the GLPK MIP solver.
217 218
  ///\ingroup lp_group
218 219
  class GlpkMip : public MipSolver, public GlpkBase {
219 220
  public:
220 221

	
221 222
    ///\e
222 223
    GlpkMip();
223 224
    ///\e
224 225
    GlpkMip(const GlpkMip&);
225 226

	
226 227
    virtual GlpkMip* cloneSolver() const;
227 228
    virtual GlpkMip* newSolver() const;
228 229

	
229 230
  protected:
230 231

	
231 232
    virtual const char* _solverName() const;
232 233

	
233 234
    virtual ColTypes _getColType(int col) const;
234 235
    virtual void _setColType(int col, ColTypes col_type);
235 236

	
236 237
    virtual SolveExitStatus _solve();
237 238
    virtual ProblemType _getType() const;
238 239
    virtual Value _getSol(int i) const;
239 240
    virtual Value _getSolValue() const;
240 241

	
241 242
  };
242 243

	
243 244

	
244 245
} //END OF NAMESPACE LEMON
245 246

	
246 247
#endif //LEMON_GLPK_H
247 248

	
Ignore white space 6 line context
1
/* -*- C++ -*-
1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3
 * This file is a part of LEMON, a generic C++ optimization library
3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2008
5
 * Copyright (C) 2003-2010
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_GOMORY_HU_TREE_H
20 20
#define LEMON_GOMORY_HU_TREE_H
21 21

	
22 22
#include <limits>
23 23

	
24 24
#include <lemon/core.h>
25 25
#include <lemon/preflow.h>
26 26
#include <lemon/concept_check.h>
27 27
#include <lemon/concepts/maps.h>
28 28

	
29 29
/// \ingroup min_cut
30
/// \file 
30
/// \file
31 31
/// \brief Gomory-Hu cut tree in graphs.
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  /// \ingroup min_cut
36 36
  ///
37 37
  /// \brief Gomory-Hu cut tree algorithm
38 38
  ///
39 39
  /// The Gomory-Hu tree is a tree on the node set of a given graph, but it
40 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 
41
  /// property that the minimum capacity edge of the path between two nodes
42 42
  /// in this tree has the same weight as the minimum cut in the graph
43 43
  /// between these nodes. Moreover the components obtained by removing
44 44
  /// this edge from the tree determine the corresponding minimum cut.
45 45
  /// Therefore once this tree is computed, the minimum cut between any pair
46 46
  /// of nodes can easily be obtained.
47
  /// 
47
  ///
48 48
  /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
49 49
  /// the \ref Preflow algorithm), thus it has \f$O(n^3\sqrt{e})\f$ overall
50 50
  /// time complexity. It calculates a rooted Gomory-Hu tree.
51 51
  /// The structure of the tree and the edge weights can be
52 52
  /// obtained using \c predNode(), \c predValue() and \c rootDist().
53 53
  /// The functions \c minCutMap() and \c minCutValue() calculate
54 54
  /// the minimum cut and the minimum cut value between any two nodes
55 55
  /// in the graph. You can also list (iterate on) the nodes and the
56 56
  /// edges of the cuts using \c MinCutNodeIt and \c MinCutEdgeIt.
57 57
  ///
58 58
  /// \tparam GR The type of the undirected graph the algorithm runs on.
59 59
  /// \tparam CAP The type of the edge map containing the capacities.
60 60
  /// The default map type is \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
61 61
#ifdef DOXYGEN
62 62
  template <typename GR,
63
	    typename CAP>
63
            typename CAP>
64 64
#else
65 65
  template <typename GR,
66
	    typename CAP = typename GR::template EdgeMap<int> >
66
            typename CAP = typename GR::template EdgeMap<int> >
67 67
#endif
68 68
  class GomoryHu {
69 69
  public:
70 70

	
71 71
    /// The graph type of the algorithm
72 72
    typedef GR Graph;
73 73
    /// The capacity map type of the algorithm
74 74
    typedef CAP Capacity;
75 75
    /// The value type of capacities
76 76
    typedef typename Capacity::Value Value;
77
    
77

	
78 78
  private:
79 79

	
80 80
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
81 81

	
82 82
    const Graph& _graph;
83 83
    const Capacity& _capacity;
84 84

	
85 85
    Node _root;
86 86
    typename Graph::template NodeMap<Node>* _pred;
87 87
    typename Graph::template NodeMap<Value>* _weight;
88 88
    typename Graph::template NodeMap<int>* _order;
89 89

	
90 90
    void createStructures() {
91 91
      if (!_pred) {
92
	_pred = new typename Graph::template NodeMap<Node>(_graph);
92
        _pred = new typename Graph::template NodeMap<Node>(_graph);
93 93
      }
94 94
      if (!_weight) {
95
	_weight = new typename Graph::template NodeMap<Value>(_graph);
95
        _weight = new typename Graph::template NodeMap<Value>(_graph);
96 96
      }
97 97
      if (!_order) {
98
	_order = new typename Graph::template NodeMap<int>(_graph);
98
        _order = new typename Graph::template NodeMap<int>(_graph);
99 99
      }
100 100
    }
101 101

	
102 102
    void destroyStructures() {
103 103
      if (_pred) {
104
	delete _pred;
104
        delete _pred;
105 105
      }
106 106
      if (_weight) {
107
	delete _weight;
107
        delete _weight;
108 108
      }
109 109
      if (_order) {
110
	delete _order;
110
        delete _order;
111 111
      }
112 112
    }
113
  
113

	
114 114
  public:
115 115

	
116 116
    /// \brief Constructor
117 117
    ///
118 118
    /// Constructor.
119 119
    /// \param graph The undirected graph the algorithm runs on.
120 120
    /// \param capacity The edge capacity map.
121
    GomoryHu(const Graph& graph, const Capacity& capacity) 
121
    GomoryHu(const Graph& graph, const Capacity& capacity)
122 122
      : _graph(graph), _capacity(capacity),
123
	_pred(0), _weight(0), _order(0) 
123
        _pred(0), _weight(0), _order(0)
124 124
    {
125 125
      checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
126 126
    }
127 127

	
128 128

	
129 129
    /// \brief Destructor
130 130
    ///
131 131
    /// Destructor.
132 132
    ~GomoryHu() {
133 133
      destroyStructures();
134 134
    }
135 135

	
136 136
  private:
137
  
137

	
138 138
    // Initialize the internal data structures
139 139
    void init() {
140 140
      createStructures();
141 141

	
142 142
      _root = NodeIt(_graph);
143 143
      for (NodeIt n(_graph); n != INVALID; ++n) {
144 144
        (*_pred)[n] = _root;
145 145
        (*_order)[n] = -1;
146 146
      }
147 147
      (*_pred)[_root] = INVALID;
148
      (*_weight)[_root] = std::numeric_limits<Value>::max(); 
148
      (*_weight)[_root] = std::numeric_limits<Value>::max();
149 149
    }
150 150

	
151 151

	
152 152
    // Start the algorithm
153 153
    void start() {
154 154
      Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
155 155

	
156 156
      for (NodeIt n(_graph); n != INVALID; ++n) {
157
	if (n == _root) continue;
157
        if (n == _root) continue;
158 158

	
159
	Node pn = (*_pred)[n];
160
	fa.source(n);
161
	fa.target(pn);
159
        Node pn = (*_pred)[n];
160
        fa.source(n);
161
        fa.target(pn);
162 162

	
163
	fa.runMinCut();
163
        fa.runMinCut();
164 164

	
165
	(*_weight)[n] = fa.flowValue();
165
        (*_weight)[n] = fa.flowValue();
166 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
	}
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 178
      }
179 179

	
180 180
      (*_order)[_root] = 0;
181 181
      int index = 1;
182 182

	
183 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
	}
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 194
      }
195 195
    }
196 196

	
197 197
  public:
198 198

	
199 199
    ///\name Execution Control
200
 
200

	
201 201
    ///@{
202 202

	
203 203
    /// \brief Run the Gomory-Hu algorithm.
204 204
    ///
205 205
    /// This function runs the Gomory-Hu algorithm.
206 206
    void run() {
207 207
      init();
208 208
      start();
209 209
    }
210
    
210

	
211 211
    /// @}
212 212

	
213 213
    ///\name Query Functions
214 214
    ///The results of the algorithm can be obtained using these
215 215
    ///functions.\n
216 216
    ///\ref run() should be called before using them.\n
217 217
    ///See also \ref MinCutNodeIt and \ref MinCutEdgeIt.
218 218

	
219 219
    ///@{
220 220

	
221 221
    /// \brief Return the predecessor node in the Gomory-Hu tree.
222 222
    ///
223 223
    /// This function returns the predecessor node of the given node
224 224
    /// in the Gomory-Hu tree.
225 225
    /// If \c node is the root of the tree, then it returns \c INVALID.
226 226
    ///
227 227
    /// \pre \ref run() must be called before using this function.
228 228
    Node predNode(const Node& node) const {
229 229
      return (*_pred)[node];
230 230
    }
231 231

	
232 232
    /// \brief Return the weight of the predecessor edge in the
233 233
    /// Gomory-Hu tree.
234 234
    ///
235
    /// This function returns the weight of the predecessor edge of the 
235
    /// This function returns the weight of the predecessor edge of the
236 236
    /// given node in the Gomory-Hu tree.
237 237
    /// If \c node is the root of the tree, the result is undefined.
238 238
    ///
239 239
    /// \pre \ref run() must be called before using this function.
240 240
    Value predValue(const Node& node) const {
241 241
      return (*_weight)[node];
242 242
    }
243 243

	
244 244
    /// \brief Return the distance from the root node in the Gomory-Hu tree.
245 245
    ///
246 246
    /// This function returns the distance of the given node from the root
247 247
    /// node in the Gomory-Hu tree.
248 248
    ///
249 249
    /// \pre \ref run() must be called before using this function.
250 250
    int rootDist(const Node& node) const {
251 251
      return (*_order)[node];
252 252
    }
253 253

	
254 254
    /// \brief Return the minimum cut value between two nodes
255 255
    ///
256 256
    /// This function returns the minimum cut value between the nodes
257
    /// \c s and \c t. 
257
    /// \c s and \c t.
258 258
    /// It finds the nearest common ancestor of the given nodes in the
259 259
    /// Gomory-Hu tree and calculates the minimum weight edge on the
260 260
    /// paths to the ancestor.
261 261
    ///
262 262
    /// \pre \ref run() must be called before using this function.
263 263
    Value minCutValue(const Node& s, const Node& t) const {
264 264
      Node sn = s, tn = t;
265 265
      Value value = std::numeric_limits<Value>::max();
266
      
266

	
267 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
	}
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 275
      }
276 276
      return value;
277 277
    }
278 278

	
279 279
    /// \brief Return the minimum cut between two nodes
280 280
    ///
281 281
    /// This function returns the minimum cut between the nodes \c s and \c t
282 282
    /// in the \c cutMap parameter by setting the nodes in the component of
283 283
    /// \c s to \c true and the other nodes to \c false.
284 284
    ///
285 285
    /// For higher level interfaces see MinCutNodeIt and MinCutEdgeIt.
286 286
    ///
287 287
    /// \param s The base node.
288 288
    /// \param t The node you want to separate from node \c s.
289 289
    /// \param cutMap The cut will be returned in this map.
290 290
    /// It must be a \c bool (or convertible) \ref concepts::ReadWriteMap
291 291
    /// "ReadWriteMap" on the graph nodes.
292 292
    ///
293 293
    /// \return The value of the minimum cut between \c s and \c t.
294 294
    ///
295 295
    /// \pre \ref run() must be called before using this function.
296 296
    template <typename CutMap>
297
    Value minCutMap(const Node& s, ///< 
297
    Value minCutMap(const Node& s,
298 298
                    const Node& t,
299
                    ///< 
300 299
                    CutMap& cutMap
301
                    ///< 
302 300
                    ) const {
303 301
      Node sn = s, tn = t;
304 302
      bool s_root=false;
305 303
      Node rn = INVALID;
306 304
      Value value = std::numeric_limits<Value>::max();
307
      
305

	
308 306
      while (sn != tn) {
309
	if ((*_order)[sn] < (*_order)[tn]) {
310
	  if ((*_weight)[tn] <= value) {
311
	    rn = tn;
307
        if ((*_order)[sn] < (*_order)[tn]) {
308
          if ((*_weight)[tn] <= value) {
309
            rn = tn;
312 310
            s_root = false;
313
	    value = (*_weight)[tn];
314
	  }
315
	  tn = (*_pred)[tn];
316
	} else {
317
	  if ((*_weight)[sn] <= value) {
318
	    rn = sn;
311
            value = (*_weight)[tn];
312
          }
313
          tn = (*_pred)[tn];
314
        } else {
315
          if ((*_weight)[sn] <= value) {
316
            rn = sn;
319 317
            s_root = true;
320
	    value = (*_weight)[sn];
321
	  }
322
	  sn = (*_pred)[sn];
323
	}
318
            value = (*_weight)[sn];
319
          }
320
          sn = (*_pred)[sn];
321
        }
324 322
      }
325 323

	
326 324
      typename Graph::template NodeMap<bool> reached(_graph, false);
327 325
      reached[_root] = true;
328 326
      cutMap.set(_root, !s_root);
329 327
      reached[rn] = true;
330 328
      cutMap.set(rn, s_root);
331 329

	
332 330
      std::vector<Node> st;
333 331
      for (NodeIt n(_graph); n != INVALID; ++n) {
334
	st.clear();
332
        st.clear();
335 333
        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
	}
334
        while (!reached[nn]) {
335
          st.push_back(nn);
336
          nn = (*_pred)[nn];
337
        }
338
        while (!st.empty()) {
339
          cutMap.set(st.back(), cutMap[nn]);
340
          st.pop_back();
341
        }
344 342
      }
345
      
343

	
346 344
      return value;
347 345
    }
348 346

	
349 347
    ///@}
350 348

	
351 349
    friend class MinCutNodeIt;
352 350

	
353 351
    /// Iterate on the nodes of a minimum cut
354
    
352

	
355 353
    /// This iterator class lists the nodes of a minimum cut found by
356 354
    /// GomoryHu. Before using it, you must allocate a GomoryHu class
357 355
    /// and call its \ref GomoryHu::run() "run()" method.
358 356
    ///
359 357
    /// This example counts the nodes in the minimum cut separating \c s from
360 358
    /// \c t.
361 359
    /// \code
362
    /// GomoruHu<Graph> gom(g, capacities);
360
    /// GomoryHu<Graph> gom(g, capacities);
363 361
    /// gom.run();
364 362
    /// int cnt=0;
365
    /// for(GomoruHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
363
    /// for(GomoryHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
366 364
    /// \endcode
367 365
    class MinCutNodeIt
368 366
    {
369 367
      bool _side;
370 368
      typename Graph::NodeIt _node_it;
371 369
      typename Graph::template NodeMap<bool> _cut;
372 370
    public:
373 371
      /// Constructor
374 372

	
375 373
      /// Constructor.
376 374
      ///
377 375
      MinCutNodeIt(GomoryHu const &gomory,
378 376
                   ///< The GomoryHu class. You must call its
379 377
                   ///  run() method
380 378
                   ///  before initializing this iterator.
381 379
                   const Node& s, ///< The base node.
382 380
                   const Node& t,
383 381
                   ///< The node you want to separate from node \c s.
384 382
                   bool side=true
385 383
                   ///< If it is \c true (default) then the iterator lists
386 384
                   ///  the nodes of the component containing \c s,
387 385
                   ///  otherwise it lists the other component.
388 386
                   /// \note As the minimum cut is not always unique,
389 387
                   /// \code
390 388
                   /// MinCutNodeIt(gomory, s, t, true);
391 389
                   /// \endcode
392 390
                   /// and
393 391
                   /// \code
394 392
                   /// MinCutNodeIt(gomory, t, s, false);
395 393
                   /// \endcode
396 394
                   /// does not necessarily give the same set of nodes.
397
                   /// However it is ensured that
395
                   /// However, it is ensured that
398 396
                   /// \code
399 397
                   /// MinCutNodeIt(gomory, s, t, true);
400 398
                   /// \endcode
401 399
                   /// and
402 400
                   /// \code
403 401
                   /// MinCutNodeIt(gomory, s, t, false);
404 402
                   /// \endcode
405 403
                   /// together list each node exactly once.
406 404
                   )
407 405
        : _side(side), _cut(gomory._graph)
408 406
      {
409 407
        gomory.minCutMap(s,t,_cut);
410 408
        for(_node_it=typename Graph::NodeIt(gomory._graph);
411 409
            _node_it!=INVALID && _cut[_node_it]!=_side;
412 410
            ++_node_it) {}
413 411
      }
414 412
      /// Conversion to \c Node
415 413

	
416 414
      /// Conversion to \c Node.
417 415
      ///
418 416
      operator typename Graph::Node() const
419 417
      {
420 418
        return _node_it;
421 419
      }
422 420
      bool operator==(Invalid) { return _node_it==INVALID; }
423 421
      bool operator!=(Invalid) { return _node_it!=INVALID; }
424 422
      /// Next node
425 423

	
426 424
      /// Next node.
427 425
      ///
428 426
      MinCutNodeIt &operator++()
429 427
      {
430 428
        for(++_node_it;_node_it!=INVALID&&_cut[_node_it]!=_side;++_node_it) {}
431 429
        return *this;
432 430
      }
433 431
      /// Postfix incrementation
434 432

	
435 433
      /// Postfix incrementation.
436 434
      ///
437 435
      /// \warning This incrementation
438 436
      /// returns a \c Node, not a \c MinCutNodeIt, as one may
439 437
      /// expect.
440 438
      typename Graph::Node operator++(int)
441 439
      {
442 440
        typename Graph::Node n=*this;
443 441
        ++(*this);
444 442
        return n;
445 443
      }
446 444
    };
447
    
445

	
448 446
    friend class MinCutEdgeIt;
449
    
447

	
450 448
    /// Iterate on the edges of a minimum cut
451
    
449

	
452 450
    /// This iterator class lists the edges of a minimum cut found by
453 451
    /// GomoryHu. Before using it, you must allocate a GomoryHu class
454 452
    /// and call its \ref GomoryHu::run() "run()" method.
455 453
    ///
456 454
    /// This example computes the value of the minimum cut separating \c s from
457 455
    /// \c t.
458 456
    /// \code
459
    /// GomoruHu<Graph> gom(g, capacities);
457
    /// GomoryHu<Graph> gom(g, capacities);
460 458
    /// gom.run();
461 459
    /// int value=0;
462
    /// for(GomoruHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
460
    /// for(GomoryHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
463 461
    ///   value+=capacities[e];
464 462
    /// \endcode
465 463
    /// The result will be the same as the value returned by
466 464
    /// \ref GomoryHu::minCutValue() "gom.minCutValue(s,t)".
467 465
    class MinCutEdgeIt
468 466
    {
469 467
      bool _side;
470 468
      const Graph &_graph;
471 469
      typename Graph::NodeIt _node_it;
472 470
      typename Graph::OutArcIt _arc_it;
473 471
      typename Graph::template NodeMap<bool> _cut;
474 472
      void step()
475 473
      {
476 474
        ++_arc_it;
477 475
        while(_node_it!=INVALID && _arc_it==INVALID)
478 476
          {
479 477
            for(++_node_it;_node_it!=INVALID&&!_cut[_node_it];++_node_it) {}
480 478
            if(_node_it!=INVALID)
481 479
              _arc_it=typename Graph::OutArcIt(_graph,_node_it);
482 480
          }
483 481
      }
484
      
482

	
485 483
    public:
486 484
      /// Constructor
487 485

	
488 486
      /// Constructor.
489 487
      ///
490 488
      MinCutEdgeIt(GomoryHu const &gomory,
491 489
                   ///< The GomoryHu class. You must call its
492 490
                   ///  run() method
493 491
                   ///  before initializing this iterator.
494 492
                   const Node& s,  ///< The base node.
495 493
                   const Node& t,
496 494
                   ///< The node you want to separate from node \c s.
497 495
                   bool side=true
498 496
                   ///< If it is \c true (default) then the listed arcs
499 497
                   ///  will be oriented from the
500 498
                   ///  nodes of the component containing \c s,
501 499
                   ///  otherwise they will be oriented in the opposite
502 500
                   ///  direction.
503 501
                   )
504 502
        : _graph(gomory._graph), _cut(_graph)
505 503
      {
506 504
        gomory.minCutMap(s,t,_cut);
507 505
        if(!side)
508 506
          for(typename Graph::NodeIt n(_graph);n!=INVALID;++n)
509 507
            _cut[n]=!_cut[n];
510 508

	
511 509
        for(_node_it=typename Graph::NodeIt(_graph);
512 510
            _node_it!=INVALID && !_cut[_node_it];
513 511
            ++_node_it) {}
514 512
        _arc_it = _node_it!=INVALID ?
515 513
          typename Graph::OutArcIt(_graph,_node_it) : INVALID;
516 514
        while(_node_it!=INVALID && _arc_it == INVALID)
517 515
          {
518 516
            for(++_node_it; _node_it!=INVALID&&!_cut[_node_it]; ++_node_it) {}
519 517
            if(_node_it!=INVALID)
520 518
              _arc_it= typename Graph::OutArcIt(_graph,_node_it);
521 519
          }
522 520
        while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
523 521
      }
524 522
      /// Conversion to \c Arc
525 523

	
526 524
      /// Conversion to \c Arc.
527 525
      ///
528 526
      operator typename Graph::Arc() const
529 527
      {
530 528
        return _arc_it;
531 529
      }
532 530
      /// Conversion to \c Edge
533 531

	
534 532
      /// Conversion to \c Edge.
535 533
      ///
536 534
      operator typename Graph::Edge() const
537 535
      {
538 536
        return _arc_it;
539 537
      }
540 538
      bool operator==(Invalid) { return _node_it==INVALID; }
541 539
      bool operator!=(Invalid) { return _node_it!=INVALID; }
542 540
      /// Next edge
543 541

	
544 542
      /// Next edge.
545 543
      ///
546 544
      MinCutEdgeIt &operator++()
547 545
      {
548 546
        step();
549 547
        while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
550 548
        return *this;
551 549
      }
552 550
      /// Postfix incrementation
553
      
551

	
554 552
      /// Postfix incrementation.
555 553
      ///
556 554
      /// \warning This incrementation
557 555
      /// returns an \c Arc, not a \c MinCutEdgeIt, as one may expect.
558 556
      typename Graph::Arc operator++(int)
559 557
      {
560 558
        typename Graph::Arc e=*this;
561 559
        ++(*this);
562 560
        return e;
563 561
      }
564 562
    };
565 563

	
566 564
  };
567 565

	
568 566
}
569 567

	
570 568
#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-2009
5
 * Copyright (C) 2003-2010
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 67
///\param GR is the type of the underlying graph.
68 68
template<class GR>
69 69
struct DefaultGraphToEpsTraits
70 70
{
71 71
  typedef GR Graph;
72 72
  typedef GR Digraph;
73 73
  typedef typename Graph::Node Node;
74 74
  typedef typename Graph::NodeIt NodeIt;
75 75
  typedef typename Graph::Arc Arc;
76 76
  typedef typename Graph::ArcIt ArcIt;
77 77
  typedef typename Graph::InArcIt InArcIt;
78 78
  typedef typename Graph::OutArcIt OutArcIt;
79 79

	
80 80

	
81 81
  const Graph &g;
82 82

	
83 83
  std::ostream& os;
84 84

	
85 85
  typedef ConstMap<typename Graph::Node,dim2::Point<double> > CoordsMapType;
86 86
  CoordsMapType _coords;
87 87
  ConstMap<typename Graph::Node,double > _nodeSizes;
88 88
  ConstMap<typename Graph::Node,int > _nodeShapes;
89 89

	
90 90
  ConstMap<typename Graph::Node,Color > _nodeColors;
91 91
  ConstMap<typename Graph::Arc,Color > _arcColors;
92 92

	
93 93
  ConstMap<typename Graph::Arc,double > _arcWidths;
94 94

	
95 95
  double _arcWidthScale;
96 96

	
97 97
  double _nodeScale;
98 98
  double _xBorder, _yBorder;
99 99
  double _scale;
100 100
  double _nodeBorderQuotient;
101 101

	
102 102
  bool _drawArrows;
103 103
  double _arrowLength, _arrowWidth;
104 104

	
105 105
  bool _showNodes, _showArcs;
106 106

	
107 107
  bool _enableParallel;
108 108
  double _parArcDist;
109 109

	
110 110
  bool _showNodeText;
111 111
  ConstMap<typename Graph::Node,bool > _nodeTexts;
112 112
  double _nodeTextSize;
113 113

	
114 114
  bool _showNodePsText;
115 115
  ConstMap<typename Graph::Node,bool > _nodePsTexts;
116 116
  char *_nodePsTextsPreamble;
117 117

	
118 118
  bool _undirected;
119 119

	
120 120
  bool _pleaseRemoveOsStream;
121 121

	
122 122
  bool _scaleToA4;
123 123

	
124 124
  std::string _title;
125 125
  std::string _copyright;
126 126

	
127 127
  enum NodeTextColorType
128 128
    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
129 129
  ConstMap<typename Graph::Node,Color > _nodeTextColors;
130 130

	
131 131
  bool _autoNodeScale;
132 132
  bool _autoArcWidthScale;
133 133

	
134 134
  bool _absoluteNodeSizes;
135 135
  bool _absoluteArcWidths;
136 136

	
137 137
  bool _negY;
138 138

	
139 139
  bool _preScale;
140 140
  ///Constructor
141 141

	
142 142
  ///Constructor
143 143
  ///\param gr  Reference to the graph to be printed.
144 144
  ///\param ost Reference to the output stream.
145
  ///By default it is <tt>std::cout</tt>.
145
  ///By default, it is <tt>std::cout</tt>.
146 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 148
  DefaultGraphToEpsTraits(const GR &gr, std::ostream& ost = std::cout,
149 149
                          bool pros = false) :
150 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 161
    _undirected(lemon::UndirectedTagIndicator<GR>::value),
162 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 245
  typedef typename T::Digraph Digraph;
246 246
  typedef typename Graph::Node Node;
247 247
  typedef typename Graph::NodeIt NodeIt;
248 248
  typedef typename Graph::Arc Arc;
249 249
  typedef typename Graph::ArcIt ArcIt;
250 250
  typedef typename Graph::InArcIt InArcIt;
251 251
  typedef typename Graph::OutArcIt OutArcIt;
252 252

	
253 253
  static const int INTERPOL_PREC;
254 254
  static const double A4HEIGHT;
255 255
  static const double A4WIDTH;
256 256
  static const double A4BORDER;
257 257

	
258 258
  bool dontPrint;
259 259

	
260 260
public:
261 261
  ///Node shapes
262 262

	
263 263
  ///Node shapes.
264 264
  ///
265 265
  enum NodeShapes {
266 266
    /// = 0
267 267
    ///\image html nodeshape_0.png
268 268
    ///\image latex nodeshape_0.eps "CIRCLE shape (0)" width=2cm
269 269
    CIRCLE=0,
270 270
    /// = 1
271 271
    ///\image html nodeshape_1.png
272 272
    ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
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 277
    DIAMOND=2,
278 278
    /// = 3
279 279
    ///\image html nodeshape_3.png
280 280
    ///\image latex nodeshape_3.eps "MALE shape (3)" width=2cm
281 281
    MALE=3,
282 282
    /// = 4
283 283
    ///\image html nodeshape_4.png
284 284
    ///\image latex nodeshape_4.eps "FEMALE shape (4)" width=2cm
285 285
    FEMALE=4
286 286
  };
287 287

	
288 288
private:
289 289
  class arcLess {
290 290
    const Graph &g;
291 291
  public:
292 292
    arcLess(const Graph &_g) : g(_g) {}
293 293
    bool operator()(Arc a,Arc b) const
294 294
    {
295 295
      Node ai=std::min(g.source(a),g.target(a));
296 296
      Node aa=std::max(g.source(a),g.target(a));
297 297
      Node bi=std::min(g.source(b),g.target(b));
298 298
      Node ba=std::max(g.source(b),g.target(b));
299 299
      return ai<bi ||
300 300
        (ai==bi && (aa < ba ||
301 301
                    (aa==ba && ai==g.source(a) && bi==g.target(b))));
302 302
    }
303 303
  };
304 304
  bool isParallel(Arc e,Arc f) const
305 305
  {
306 306
    return (g.source(e)==g.source(f)&&
307 307
            g.target(e)==g.target(f)) ||
308 308
      (g.source(e)==g.target(f)&&
309 309
       g.target(e)==g.source(f));
310 310
  }
311 311
  template<class TT>
312 312
  static std::string psOut(const dim2::Point<TT> &p)
313 313
    {
314 314
      std::ostringstream os;
315 315
      os << p.x << ' ' << p.y;
316 316
      return os.str();
317 317
    }
318 318
  static std::string psOut(const Color &c)
319 319
    {
320 320
      std::ostringstream os;
321 321
      os << c.red() << ' ' << c.green() << ' ' << c.blue();
322 322
      return os.str();
323 323
    }
324 324

	
325 325
public:
326 326
  GraphToEps(const T &t) : T(t), dontPrint(false) {};
327 327

	
328 328
  template<class X> struct CoordsTraits : public T {
329 329
  typedef X CoordsMapType;
330 330
    const X &_coords;
331 331
    CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
332 332
  };
333 333
  ///Sets the map of the node coordinates
334 334

	
335 335
  ///Sets the map of the node coordinates.
336 336
  ///\param x must be a node map with \ref dim2::Point "dim2::Point<double>" or
337 337
  ///\ref dim2::Point "dim2::Point<int>" values.
338 338
  template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
339 339
    dontPrint=true;
340 340
    return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
341 341
  }
342 342
  template<class X> struct NodeSizesTraits : public T {
343 343
    const X &_nodeSizes;
344 344
    NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
345 345
  };
346 346
  ///Sets the map of the node sizes
347 347

	
348 348
  ///Sets the map of the node sizes.
349 349
  ///\param x must be a node map with \c double (or convertible) values.
350 350
  template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
351 351
  {
352 352
    dontPrint=true;
353 353
    return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
354 354
  }
355 355
  template<class X> struct NodeShapesTraits : public T {
356 356
    const X &_nodeShapes;
357 357
    NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
358 358
  };
359 359
  ///Sets the map of the node shapes
360 360

	
361 361
  ///Sets the map of the node shapes.
362 362
  ///The available shape values
363 363
  ///can be found in \ref NodeShapes "enum NodeShapes".
364 364
  ///\param x must be a node map with \c int (or convertible) values.
365 365
  ///\sa NodeShapes
366 366
  template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
367 367
  {
368 368
    dontPrint=true;
369 369
    return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x));
370 370
  }
371 371
  template<class X> struct NodeTextsTraits : public T {
372 372
    const X &_nodeTexts;
373 373
    NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
374 374
  };
375 375
  ///Sets the text printed on the nodes
376 376

	
377 377
  ///Sets the text printed on the nodes.
378 378
  ///\param x must be a node map with type that can be pushed to a standard
379 379
  ///\c ostream.
380 380
  template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
381 381
  {
382 382
    dontPrint=true;
383 383
    _showNodeText=true;
384 384
    return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
385 385
  }
386 386
  template<class X> struct NodePsTextsTraits : public T {
387 387
    const X &_nodePsTexts;
388 388
    NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {}
389 389
  };
390 390
  ///Inserts a PostScript block to the nodes
391 391

	
392 392
  ///With this command it is possible to insert a verbatim PostScript
393 393
  ///block to the nodes.
394 394
  ///The PS current point will be moved to the center of the node before
395 395
  ///the PostScript block inserted.
396 396
  ///
397 397
  ///Before and after the block a newline character is inserted so you
398 398
  ///don't have to bother with the separators.
399 399
  ///
400 400
  ///\param x must be a node map with type that can be pushed to a standard
401 401
  ///\c ostream.
402 402
  ///
403 403
  ///\sa nodePsTextsPreamble()
404 404
  template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
405 405
  {
406 406
    dontPrint=true;
407 407
    _showNodePsText=true;
408 408
    return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
409 409
  }
410 410
  template<class X> struct ArcWidthsTraits : public T {
411 411
    const X &_arcWidths;
412 412
    ArcWidthsTraits(const T &t,const X &x) : T(t), _arcWidths(x) {}
413 413
  };
414 414
  ///Sets the map of the arc widths
415 415

	
416 416
  ///Sets the map of the arc widths.
417 417
  ///\param x must be an arc map with \c double (or convertible) values.
418 418
  template<class X> GraphToEps<ArcWidthsTraits<X> > arcWidths(const X &x)
419 419
  {
420 420
    dontPrint=true;
421 421
    return GraphToEps<ArcWidthsTraits<X> >(ArcWidthsTraits<X>(*this,x));
422 422
  }
423 423

	
424 424
  template<class X> struct NodeColorsTraits : public T {
425 425
    const X &_nodeColors;
426 426
    NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
427 427
  };
428 428
  ///Sets the map of the node colors
429 429

	
430 430
  ///Sets the map of the node colors.
431 431
  ///\param x must be a node map with \ref Color values.
432 432
  ///
433 433
  ///\sa Palette
434 434
  template<class X> GraphToEps<NodeColorsTraits<X> >
435 435
  nodeColors(const X &x)
436 436
  {
437 437
    dontPrint=true;
438 438
    return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
439 439
  }
440 440
  template<class X> struct NodeTextColorsTraits : public T {
441 441
    const X &_nodeTextColors;
442 442
    NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {}
443 443
  };
444 444
  ///Sets the map of the node text colors
445 445

	
446 446
  ///Sets the map of the node text colors.
447 447
  ///\param x must be a node map with \ref Color values.
448 448
  ///
449 449
  ///\sa Palette
450 450
  template<class X> GraphToEps<NodeTextColorsTraits<X> >
451 451
  nodeTextColors(const X &x)
452 452
  {
453 453
    dontPrint=true;
454 454
    _nodeTextColorType=CUST_COL;
455 455
    return GraphToEps<NodeTextColorsTraits<X> >
456 456
      (NodeTextColorsTraits<X>(*this,x));
457 457
  }
458 458
  template<class X> struct ArcColorsTraits : public T {
459 459
    const X &_arcColors;
460 460
    ArcColorsTraits(const T &t,const X &x) : T(t), _arcColors(x) {}
461 461
  };
462 462
  ///Sets the map of the arc colors
463 463

	
464 464
  ///Sets the map of the arc colors.
465 465
  ///\param x must be an arc map with \ref Color values.
466 466
  ///
467 467
  ///\sa Palette
468 468
  template<class X> GraphToEps<ArcColorsTraits<X> >
469 469
  arcColors(const X &x)
470 470
  {
471 471
    dontPrint=true;
472 472
    return GraphToEps<ArcColorsTraits<X> >(ArcColorsTraits<X>(*this,x));
473 473
  }
474 474
  ///Sets a global scale factor for node sizes
475 475

	
476 476
  ///Sets a global scale factor for node sizes.
477 477
  ///
478 478
  /// If nodeSizes() is not given, this function simply sets the node
479 479
  /// sizes to \c d.  If nodeSizes() is given, but
480 480
  /// autoNodeScale() is not, then the node size given by
481 481
  /// nodeSizes() will be multiplied by the value \c d.
482 482
  /// If both nodeSizes() and autoNodeScale() are used, then the
483 483
  /// node sizes will be scaled in such a way that the greatest size will be
484 484
  /// equal to \c d.
485 485
  /// \sa nodeSizes()
486 486
  /// \sa autoNodeScale()
487 487
  GraphToEps<T> &nodeScale(double d=.01) {_nodeScale=d;return *this;}
488 488
  ///Turns on/off the automatic node size scaling.
489 489

	
490 490
  ///Turns on/off the automatic node size scaling.
491 491
  ///
492 492
  ///\sa nodeScale()
493 493
  ///
494 494
  GraphToEps<T> &autoNodeScale(bool b=true) {
495 495
    _autoNodeScale=b;return *this;
496 496
  }
497 497

	
498 498
  ///Turns on/off the absolutematic node size scaling.
499 499

	
500 500
  ///Turns on/off the absolutematic node size scaling.
501 501
  ///
502 502
  ///\sa nodeScale()
503 503
  ///
504 504
  GraphToEps<T> &absoluteNodeSizes(bool b=true) {
505 505
    _absoluteNodeSizes=b;return *this;
506 506
  }
507 507

	
508 508
  ///Negates the Y coordinates.
509 509
  GraphToEps<T> &negateY(bool b=true) {
510 510
    _negY=b;return *this;
511 511
  }
512 512

	
513 513
  ///Turn on/off pre-scaling
514 514

	
515
  ///By default graphToEps() rescales the whole image in order to avoid
515
  ///By default, graphToEps() rescales the whole image in order to avoid
516 516
  ///very big or very small bounding boxes.
517 517
  ///
518 518
  ///This (p)rescaling can be turned off with this function.
519 519
  ///
520 520
  GraphToEps<T> &preScale(bool b=true) {
521 521
    _preScale=b;return *this;
522 522
  }
523 523

	
524 524
  ///Sets a global scale factor for arc widths
525 525

	
526 526
  /// Sets a global scale factor for arc widths.
527 527
  ///
528 528
  /// If arcWidths() is not given, this function simply sets the arc
529 529
  /// widths to \c d.  If arcWidths() is given, but
530 530
  /// autoArcWidthScale() is not, then the arc withs given by
531 531
  /// arcWidths() will be multiplied by the value \c d.
532 532
  /// If both arcWidths() and autoArcWidthScale() are used, then the
533 533
  /// arc withs will be scaled in such a way that the greatest width will be
534 534
  /// equal to \c d.
535 535
  GraphToEps<T> &arcWidthScale(double d=.003) {_arcWidthScale=d;return *this;}
536 536
  ///Turns on/off the automatic arc width scaling.
537 537

	
538 538
  ///Turns on/off the automatic arc width scaling.
539 539
  ///
540 540
  ///\sa arcWidthScale()
541 541
  ///
542 542
  GraphToEps<T> &autoArcWidthScale(bool b=true) {
543 543
    _autoArcWidthScale=b;return *this;
544 544
  }
545 545
  ///Turns on/off the absolutematic arc width scaling.
546 546

	
547 547
  ///Turns on/off the absolutematic arc width scaling.
548 548
  ///
549 549
  ///\sa arcWidthScale()
550 550
  ///
551 551
  GraphToEps<T> &absoluteArcWidths(bool b=true) {
552 552
    _absoluteArcWidths=b;return *this;
553 553
  }
554 554
  ///Sets a global scale factor for the whole picture
555 555
  GraphToEps<T> &scale(double d) {_scale=d;return *this;}
556 556
  ///Sets the width of the border around the picture
557 557
  GraphToEps<T> &border(double b=10) {_xBorder=_yBorder=b;return *this;}
558 558
  ///Sets the width of the border around the picture
559 559
  GraphToEps<T> &border(double x, double y) {
560 560
    _xBorder=x;_yBorder=y;return *this;
561 561
  }
562 562
  ///Sets whether to draw arrows
563 563
  GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
564 564
  ///Sets the length of the arrowheads
565 565
  GraphToEps<T> &arrowLength(double d=1.0) {_arrowLength*=d;return *this;}
566 566
  ///Sets the width of the arrowheads
567 567
  GraphToEps<T> &arrowWidth(double d=.3) {_arrowWidth*=d;return *this;}
568 568

	
569 569
  ///Scales the drawing to fit to A4 page
570 570
  GraphToEps<T> &scaleToA4() {_scaleToA4=true;return *this;}
571 571

	
572 572
  ///Enables parallel arcs
573 573
  GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
574 574

	
575 575
  ///Sets the distance between parallel arcs
576 576
  GraphToEps<T> &parArcDist(double d) {_parArcDist*=d;return *this;}
577 577

	
578 578
  ///Hides the arcs
579 579
  GraphToEps<T> &hideArcs(bool b=true) {_showArcs=!b;return *this;}
580 580
  ///Hides the nodes
581 581
  GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
582 582

	
583 583
  ///Sets the size of the node texts
584 584
  GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
585 585

	
586 586
  ///Sets the color of the node texts to be different from the node color
587 587

	
588 588
  ///Sets the color of the node texts to be as different from the node color
589 589
  ///as it is possible.
590 590
  GraphToEps<T> &distantColorNodeTexts()
591 591
  {_nodeTextColorType=DIST_COL;return *this;}
592 592
  ///Sets the color of the node texts to be black or white and always visible.
593 593

	
594 594
  ///Sets the color of the node texts to be black or white according to
595 595
  ///which is more different from the node color.
596 596
  GraphToEps<T> &distantBWNodeTexts()
597 597
  {_nodeTextColorType=DIST_BW;return *this;}
598 598

	
599 599
  ///Gives a preamble block for node Postscript block.
600 600

	
601 601
  ///Gives a preamble block for node Postscript block.
602 602
  ///
603 603
  ///\sa nodePsTexts()
604 604
  GraphToEps<T> & nodePsTextsPreamble(const char *str) {
605 605
    _nodePsTextsPreamble=str ;return *this;
606 606
  }
607 607
  ///Sets whether the graph is undirected
608 608

	
609 609
  ///Sets whether the graph is undirected.
610 610
  ///
611 611
  ///This setting is the default for undirected graphs.
612 612
  ///
613 613
  ///\sa directed()
614 614
   GraphToEps<T> &undirected(bool b=true) {_undirected=b;return *this;}
615 615

	
616 616
  ///Sets whether the graph is directed
617 617

	
618 618
  ///Sets whether the graph is directed.
619 619
  ///Use it to show the edges as a pair of directed ones.
620 620
  ///
621 621
  ///This setting is the default for digraphs.
622 622
  ///
623 623
  ///\sa undirected()
624 624
  GraphToEps<T> &directed(bool b=true) {_undirected=!b;return *this;}
625 625

	
626 626
  ///Sets the title.
627 627

	
628 628
  ///Sets the title of the generated image,
629 629
  ///namely it inserts a <tt>%%Title:</tt> DSC field to the header of
630 630
  ///the EPS file.
631 631
  GraphToEps<T> &title(const std::string &t) {_title=t;return *this;}
632 632
  ///Sets the copyright statement.
633 633

	
634 634
  ///Sets the copyright statement of the generated image,
635 635
  ///namely it inserts a <tt>%%Copyright:</tt> DSC field to the header of
636 636
  ///the EPS file.
637 637
  GraphToEps<T> &copyright(const std::string &t) {_copyright=t;return *this;}
638 638

	
639 639
protected:
640 640
  bool isInsideNode(dim2::Point<double> p, double r,int t)
641 641
  {
642 642
    switch(t) {
643 643
    case CIRCLE:
644 644
    case MALE:
645 645
    case FEMALE:
646 646
      return p.normSquare()<=r*r;
647 647
    case SQUARE:
648 648
      return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
649 649
    case DIAMOND:
650 650
      return p.x+p.y<=r && p.x-p.y<=r && -p.x+p.y<=r && -p.x-p.y<=r;
651 651
    }
652 652
    return false;
653 653
  }
654 654

	
655 655
public:
656 656
  ~GraphToEps() { }
657 657

	
658 658
  ///Draws the graph.
659 659

	
660 660
  ///Like other functions using
661 661
  ///\ref named-templ-func-param "named template parameters",
662 662
  ///this function calls the algorithm itself, i.e. in this case
663 663
  ///it draws the graph.
664 664
  void run() {
665 665
    const double EPSILON=1e-9;
666 666
    if(dontPrint) return;
667 667

	
668 668
    _graph_to_eps_bits::_NegY<typename T::CoordsMapType>
669 669
      mycoords(_coords,_negY);
670 670

	
671 671
    os << "%!PS-Adobe-2.0 EPSF-2.0\n";
672 672
    if(_title.size()>0) os << "%%Title: " << _title << '\n';
673 673
     if(_copyright.size()>0) os << "%%Copyright: " << _copyright << '\n';
674 674
    os << "%%Creator: LEMON, graphToEps()\n";
675 675

	
676 676
    {
677 677
      os << "%%CreationDate: ";
678 678
#ifndef WIN32
679 679
      timeval tv;
680 680
      gettimeofday(&tv, 0);
681 681

	
682 682
      char cbuf[26];
683 683
      ctime_r(&tv.tv_sec,cbuf);
684 684
      os << cbuf;
685 685
#else
686 686
      os << bits::getWinFormattedDate();
687 687
      os << std::endl;
688 688
#endif
689 689
    }
690 690

	
691 691
    if (_autoArcWidthScale) {
692 692
      double max_w=0;
693 693
      for(ArcIt e(g);e!=INVALID;++e)
694 694
        max_w=std::max(double(_arcWidths[e]),max_w);
695 695
      if(max_w>EPSILON) {
696 696
        _arcWidthScale/=max_w;
697 697
      }
698 698
    }
699 699

	
700 700
    if (_autoNodeScale) {
701 701
      double max_s=0;
702 702
      for(NodeIt n(g);n!=INVALID;++n)
703 703
        max_s=std::max(double(_nodeSizes[n]),max_s);
704 704
      if(max_s>EPSILON) {
705 705
        _nodeScale/=max_s;
706 706
      }
707 707
    }
708 708

	
709 709
    double diag_len = 1;
710 710
    if(!(_absoluteNodeSizes&&_absoluteArcWidths)) {
711 711
      dim2::Box<double> bb;
712 712
      for(NodeIt n(g);n!=INVALID;++n) bb.add(mycoords[n]);
713 713
      if (bb.empty()) {
714 714
        bb = dim2::Box<double>(dim2::Point<double>(0,0));
715 715
      }
716 716
      diag_len = std::sqrt((bb.bottomLeft()-bb.topRight()).normSquare());
717 717
      if(diag_len<EPSILON) diag_len = 1;
718 718
      if(!_absoluteNodeSizes) _nodeScale*=diag_len;
719 719
      if(!_absoluteArcWidths) _arcWidthScale*=diag_len;
720 720
    }
721 721

	
722 722
    dim2::Box<double> bb;
723 723
    for(NodeIt n(g);n!=INVALID;++n) {
724 724
      double ns=_nodeSizes[n]*_nodeScale;
725 725
      dim2::Point<double> p(ns,ns);
726 726
      switch(_nodeShapes[n]) {
727 727
      case CIRCLE:
728 728
      case SQUARE:
729 729
      case DIAMOND:
730 730
        bb.add(p+mycoords[n]);
731 731
        bb.add(-p+mycoords[n]);
732 732
        break;
733 733
      case MALE:
734 734
        bb.add(-p+mycoords[n]);
735 735
        bb.add(dim2::Point<double>(1.5*ns,1.5*std::sqrt(3.0)*ns)+mycoords[n]);
736 736
        break;
737 737
      case FEMALE:
738 738
        bb.add(p+mycoords[n]);
739 739
        bb.add(dim2::Point<double>(-ns,-3.01*ns)+mycoords[n]);
740 740
        break;
741 741
      }
742 742
    }
743 743
    if (bb.empty()) {
744 744
      bb = dim2::Box<double>(dim2::Point<double>(0,0));
745 745
    }
746 746

	
747 747
    if(_scaleToA4)
748 748
      os <<"%%BoundingBox: 0 0 596 842\n%%DocumentPaperSizes: a4\n";
749 749
    else {
750 750
      if(_preScale) {
751 751
        //Rescale so that BoundingBox won't be neither to big nor too small.
752 752
        while(bb.height()*_scale>1000||bb.width()*_scale>1000) _scale/=10;
753 753
        while(bb.height()*_scale<100||bb.width()*_scale<100) _scale*=10;
754 754
      }
755 755

	
756 756
      os << "%%BoundingBox: "
757 757
         << int(floor(bb.left()   * _scale - _xBorder)) << ' '
758 758
         << int(floor(bb.bottom() * _scale - _yBorder)) << ' '
759 759
         << int(ceil(bb.right()  * _scale + _xBorder)) << ' '
760 760
         << int(ceil(bb.top()    * _scale + _yBorder)) << '\n';
761 761
    }
762 762

	
763 763
    os << "%%EndComments\n";
764 764

	
765 765
    //x1 y1 x2 y2 x3 y3 cr cg cb w
766 766
    os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
767 767
       << "      4 2 roll 1 index 1 index curveto stroke } bind def\n";
768 768
    os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke }"
769 769
       << " bind def\n";
770 770
    //x y r
771 771
    os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath }"
772 772
       << " bind def\n";
773 773
    //x y r
774 774
    os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
775 775
       << "      2 index 1 index sub 2 index 2 index add lineto\n"
776 776
       << "      2 index 1 index sub 2 index 2 index sub lineto\n"
777 777
       << "      2 index 1 index add 2 index 2 index sub lineto\n"
778 778
       << "      closepath pop pop pop} bind def\n";
779 779
    //x y r
780 780
    os << "/di { newpath 2 index 1 index add 2 index moveto\n"
781 781
       << "      2 index             2 index 2 index add lineto\n"
782 782
       << "      2 index 1 index sub 2 index             lineto\n"
783 783
       << "      2 index             2 index 2 index sub lineto\n"
784 784
       << "      closepath pop pop pop} bind def\n";
785 785
    // x y r cr cg cb
786 786
    os << "/nc { 0 0 0 setrgbcolor 5 index 5 index 5 index c fill\n"
787 787
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
788 788
       << "   } bind def\n";
789 789
    os << "/nsq { 0 0 0 setrgbcolor 5 index 5 index 5 index sq fill\n"
790 790
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div sq fill\n"
791 791
       << "   } bind def\n";
792 792
    os << "/ndi { 0 0 0 setrgbcolor 5 index 5 index 5 index di fill\n"
793 793
       << "     setrgbcolor " << 1+_nodeBorderQuotient << " div di fill\n"
794 794
       << "   } bind def\n";
795 795
    os << "/nfemale { 0 0 0 setrgbcolor 3 index "
796 796
       << _nodeBorderQuotient/(1+_nodeBorderQuotient)
797 797
       << " 1.5 mul mul setlinewidth\n"
798 798
       << "  newpath 5 index 5 index moveto "
799 799
       << "5 index 5 index 5 index 3.01 mul sub\n"
800 800
       << "  lineto 5 index 4 index .7 mul sub 5 index 5 index 2.2 mul sub"
801 801
       << " moveto\n"
802 802
       << "  5 index 4 index .7 mul add 5 index 5 index 2.2 mul sub lineto "
803 803
       << "stroke\n"
804 804
       << "  5 index 5 index 5 index c fill\n"
805 805
       << "  setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
806 806
       << "  } bind def\n";
807 807
    os << "/nmale {\n"
808 808
       << "  0 0 0 setrgbcolor 3 index "
809 809
       << _nodeBorderQuotient/(1+_nodeBorderQuotient)
810 810
       <<" 1.5 mul mul setlinewidth\n"
811 811
       << "  newpath 5 index 5 index moveto\n"
812 812
       << "  5 index 4 index 1 mul 1.5 mul add\n"
813 813
       << "  5 index 5 index 3 sqrt 1.5 mul mul add\n"
814 814
       << "  1 index 1 index lineto\n"
815 815
       << "  1 index 1 index 7 index sub moveto\n"
816 816
       << "  1 index 1 index lineto\n"
817 817
       << "  exch 5 index 3 sqrt .5 mul mul sub exch 5 index .5 mul sub"
818 818
       << " lineto\n"
819 819
       << "  stroke\n"
820 820
       << "  5 index 5 index 5 index c fill\n"
821 821
       << "  setrgbcolor " << 1+_nodeBorderQuotient << " div c fill\n"
822 822
       << "  } bind def\n";
823 823

	
824 824

	
825 825
    os << "/arrl " << _arrowLength << " def\n";
826 826
    os << "/arrw " << _arrowWidth << " def\n";
827 827
    // l dx_norm dy_norm
828 828
    os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
829 829
    //len w dx_norm dy_norm x1 y1 cr cg cb
830 830
    os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx "
831 831
       << "exch def\n"
832 832
       << "       /w exch def /len exch def\n"
833 833
      //<< "0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
834 834
       << "       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
835 835
       << "       len w sub arrl sub dx dy lrl\n"
836 836
       << "       arrw dy dx neg lrl\n"
837 837
       << "       dx arrl w add mul dy w 2 div arrw add mul sub\n"
838 838
       << "       dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
839 839
       << "       dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
840 840
       << "       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
841 841
       << "       arrw dy dx neg lrl\n"
842 842
       << "       len w sub arrl sub neg dx dy lrl\n"
843 843
       << "       closepath fill } bind def\n";
844 844
    os << "/cshow { 2 index 2 index moveto dup stringwidth pop\n"
845 845
       << "         neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n";
846 846

	
847 847
    os << "\ngsave\n";
848 848
    if(_scaleToA4)
849 849
      if(bb.height()>bb.width()) {
850 850
        double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.height(),
851 851
                  (A4WIDTH-2*A4BORDER)/bb.width());
852 852
        os << ((A4WIDTH -2*A4BORDER)-sc*bb.width())/2 + A4BORDER << ' '
853 853
           << ((A4HEIGHT-2*A4BORDER)-sc*bb.height())/2 + A4BORDER
854 854
           << " translate\n"
855 855
           << sc << " dup scale\n"
856 856
           << -bb.left() << ' ' << -bb.bottom() << " translate\n";
857 857
      }
858 858
      else {
859 859
        double sc= std::min((A4HEIGHT-2*A4BORDER)/bb.width(),
860 860
                  (A4WIDTH-2*A4BORDER)/bb.height());
861 861
        os << ((A4WIDTH -2*A4BORDER)-sc*bb.height())/2 + A4BORDER << ' '
862 862
           << ((A4HEIGHT-2*A4BORDER)-sc*bb.width())/2 + A4BORDER
863 863
           << " translate\n"
864 864
           << sc << " dup scale\n90 rotate\n"
865 865
           << -bb.left() << ' ' << -bb.top() << " translate\n";
866 866
        }
867 867
    else if(_scale!=1.0) os << _scale << " dup scale\n";
868 868

	
869 869
    if(_showArcs) {
870 870
      os << "%Arcs:\ngsave\n";
871 871
      if(_enableParallel) {
872 872
        std::vector<Arc> el;
873 873
        for(ArcIt e(g);e!=INVALID;++e)
874 874
          if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
875 875
             &&g.source(e)!=g.target(e))
876 876
            el.push_back(e);
877 877
        std::sort(el.begin(),el.end(),arcLess(g));
878 878

	
879 879
        typename std::vector<Arc>::iterator j;
880 880
        for(typename std::vector<Arc>::iterator i=el.begin();i!=el.end();i=j) {
881 881
          for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ;
882 882

	
883 883
          double sw=0;
884 884
          for(typename std::vector<Arc>::iterator e=i;e!=j;++e)
885 885
            sw+=_arcWidths[*e]*_arcWidthScale+_parArcDist;
886 886
          sw-=_parArcDist;
887 887
          sw/=-2.0;
888 888
          dim2::Point<double>
889 889
            dvec(mycoords[g.target(*i)]-mycoords[g.source(*i)]);
890 890
          double l=std::sqrt(dvec.normSquare());
891 891
          dim2::Point<double> d(dvec/std::max(l,EPSILON));
892 892
          dim2::Point<double> m;
893 893
//           m=dim2::Point<double>(mycoords[g.target(*i)]+
894 894
//                                 mycoords[g.source(*i)])/2.0;
895 895

	
896 896
//            m=dim2::Point<double>(mycoords[g.source(*i)])+
897 897
//             dvec*(double(_nodeSizes[g.source(*i)])/
898 898
//                (_nodeSizes[g.source(*i)]+_nodeSizes[g.target(*i)]));
899 899

	
900 900
          m=dim2::Point<double>(mycoords[g.source(*i)])+
901 901
            d*(l+_nodeSizes[g.source(*i)]-_nodeSizes[g.target(*i)])/2.0;
902 902

	
903 903
          for(typename std::vector<Arc>::iterator e=i;e!=j;++e) {
904 904
            sw+=_arcWidths[*e]*_arcWidthScale/2.0;
905 905
            dim2::Point<double> mm=m+rot90(d)*sw/.75;
906 906
            if(_drawArrows) {
907 907
              int node_shape;
908 908
              dim2::Point<double> s=mycoords[g.source(*e)];
909 909
              dim2::Point<double> t=mycoords[g.target(*e)];
910 910
              double rn=_nodeSizes[g.target(*e)]*_nodeScale;
911 911
              node_shape=_nodeShapes[g.target(*e)];
912 912
              dim2::Bezier3 bez(s,mm,mm,t);
913 913
              double t1=0,t2=1;
914 914
              for(int ii=0;ii<INTERPOL_PREC;++ii)
915 915
                if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t2=(t1+t2)/2;
916 916
                else t1=(t1+t2)/2;
917 917
              dim2::Point<double> apoint=bez((t1+t2)/2);
918 918
              rn = _arrowLength+_arcWidths[*e]*_arcWidthScale;
919 919
              rn*=rn;
920 920
              t2=(t1+t2)/2;t1=0;
921 921
              for(int ii=0;ii<INTERPOL_PREC;++ii)
922 922
                if((bez((t1+t2)/2)-apoint).normSquare()>rn) t1=(t1+t2)/2;
923 923
                else t2=(t1+t2)/2;
924 924
              dim2::Point<double> linend=bez((t1+t2)/2);
925 925
              bez=bez.before((t1+t2)/2);
926 926
//               rn=_nodeSizes[g.source(*e)]*_nodeScale;
927 927
//               node_shape=_nodeShapes[g.source(*e)];
928 928
//               t1=0;t2=1;
929 929
//               for(int i=0;i<INTERPOL_PREC;++i)
930 930
//                 if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape))
931 931
//                   t1=(t1+t2)/2;
932 932
//                 else t2=(t1+t2)/2;
933 933
//               bez=bez.after((t1+t2)/2);
934 934
              os << _arcWidths[*e]*_arcWidthScale << " setlinewidth "
935 935
                 << _arcColors[*e].red() << ' '
936 936
                 << _arcColors[*e].green() << ' '
937 937
                 << _arcColors[*e].blue() << " setrgbcolor newpath\n"
938 938
                 << bez.p1.x << ' ' <<  bez.p1.y << " moveto\n"
939 939
                 << bez.p2.x << ' ' << bez.p2.y << ' '
940 940
                 << bez.p3.x << ' ' << bez.p3.y << ' '
941 941
                 << bez.p4.x << ' ' << bez.p4.y << " curveto stroke\n";
942 942
              dim2::Point<double> dd(rot90(linend-apoint));
943 943
              dd*=(.5*_arcWidths[*e]*_arcWidthScale+_arrowWidth)/
944 944
                std::sqrt(dd.normSquare());
945 945
              os << "newpath " << psOut(apoint) << " moveto "
946 946
                 << psOut(linend+dd) << " lineto "
947 947
                 << psOut(linend-dd) << " lineto closepath fill\n";
948 948
            }
949 949
            else {
950 950
              os << mycoords[g.source(*e)].x << ' '
951 951
                 << mycoords[g.source(*e)].y << ' '
952 952
                 << mm.x << ' ' << mm.y << ' '
953 953
                 << mycoords[g.target(*e)].x << ' '
954 954
                 << mycoords[g.target(*e)].y << ' '
955 955
                 << _arcColors[*e].red() << ' '
956 956
                 << _arcColors[*e].green() << ' '
957 957
                 << _arcColors[*e].blue() << ' '
958 958
                 << _arcWidths[*e]*_arcWidthScale << " lb\n";
959 959
            }
960 960
            sw+=_arcWidths[*e]*_arcWidthScale/2.0+_parArcDist;
961 961
          }
962 962
        }
963 963
      }
964 964
      else for(ArcIt e(g);e!=INVALID;++e)
965 965
        if((!_undirected||g.source(e)<g.target(e))&&_arcWidths[e]>0
966 966
           &&g.source(e)!=g.target(e)) {
967 967
          if(_drawArrows) {
968 968
            dim2::Point<double> d(mycoords[g.target(e)]-mycoords[g.source(e)]);
969 969
            double rn=_nodeSizes[g.target(e)]*_nodeScale;
970 970
            int node_shape=_nodeShapes[g.target(e)];
971 971
            double t1=0,t2=1;
972 972
            for(int i=0;i<INTERPOL_PREC;++i)
973 973
              if(isInsideNode((-(t1+t2)/2)*d,rn,node_shape)) t1=(t1+t2)/2;
974 974
              else t2=(t1+t2)/2;
975 975
            double l=std::sqrt(d.normSquare());
976 976
            d/=l;
977 977

	
978 978
            os << l*(1-(t1+t2)/2) << ' '
979 979
               << _arcWidths[e]*_arcWidthScale << ' '
980 980
               << d.x << ' ' << d.y << ' '
981 981
               << mycoords[g.source(e)].x << ' '
982 982
               << mycoords[g.source(e)].y << ' '
983 983
               << _arcColors[e].red() << ' '
984 984
               << _arcColors[e].green() << ' '
985 985
               << _arcColors[e].blue() << " arr\n";
986 986
          }
987 987
          else os << mycoords[g.source(e)].x << ' '
988 988
                  << mycoords[g.source(e)].y << ' '
989 989
                  << mycoords[g.target(e)].x << ' '
990 990
                  << mycoords[g.target(e)].y << ' '
991 991
                  << _arcColors[e].red() << ' '
992 992
                  << _arcColors[e].green() << ' '
993 993
                  << _arcColors[e].blue() << ' '
994 994
                  << _arcWidths[e]*_arcWidthScale << " l\n";
995 995
        }
996 996
      os << "grestore\n";
997 997
    }
998 998
    if(_showNodes) {
999 999
      os << "%Nodes:\ngsave\n";
1000 1000
      for(NodeIt n(g);n!=INVALID;++n) {
1001 1001
        os << mycoords[n].x << ' ' << mycoords[n].y << ' '
1002 1002
           << _nodeSizes[n]*_nodeScale << ' '
1003 1003
           << _nodeColors[n].red() << ' '
1004 1004
           << _nodeColors[n].green() << ' '
1005 1005
           << _nodeColors[n].blue() << ' ';
1006 1006
        switch(_nodeShapes[n]) {
1007 1007
        case CIRCLE:
1008 1008
          os<< "nc";break;
1009 1009
        case SQUARE:
1010 1010
          os<< "nsq";break;
1011 1011
        case DIAMOND:
1012 1012
          os<< "ndi";break;
1013 1013
        case MALE:
1014 1014
          os<< "nmale";break;
1015 1015
        case FEMALE:
1016 1016
          os<< "nfemale";break;
1017 1017
        }
1018 1018
        os<<'\n';
1019 1019
      }
1020 1020
      os << "grestore\n";
1021 1021
    }
1022 1022
    if(_showNodeText) {
1023 1023
      os << "%Node texts:\ngsave\n";
1024 1024
      os << "/fosi " << _nodeTextSize << " def\n";
1025 1025
      os << "(Helvetica) findfont fosi scalefont setfont\n";
1026 1026
      for(NodeIt n(g);n!=INVALID;++n) {
1027 1027
        switch(_nodeTextColorType) {
1028 1028
        case DIST_COL:
1029 1029
          os << psOut(distantColor(_nodeColors[n])) << " setrgbcolor\n";
1030 1030
          break;
1031 1031
        case DIST_BW:
1032 1032
          os << psOut(distantBW(_nodeColors[n])) << " setrgbcolor\n";
1033 1033
          break;
1034 1034
        case CUST_COL:
1035 1035
          os << psOut(distantColor(_nodeTextColors[n])) << " setrgbcolor\n";
1036 1036
          break;
1037 1037
        default:
1038 1038
          os << "0 0 0 setrgbcolor\n";
1039 1039
        }
1040 1040
        os << mycoords[n].x << ' ' << mycoords[n].y
1041 1041
           << " (" << _nodeTexts[n] << ") cshow\n";
1042 1042
      }
1043 1043
      os << "grestore\n";
1044 1044
    }
1045 1045
    if(_showNodePsText) {
1046 1046
      os << "%Node PS blocks:\ngsave\n";
1047 1047
      for(NodeIt n(g);n!=INVALID;++n)
1048 1048
        os << mycoords[n].x << ' ' << mycoords[n].y
1049 1049
           << " moveto\n" << _nodePsTexts[n] << "\n";
1050 1050
      os << "grestore\n";
1051 1051
    }
1052 1052

	
1053 1053
    os << "grestore\nshowpage\n";
1054 1054

	
1055 1055
    //CleanUp:
1056 1056
    if(_pleaseRemoveOsStream) {delete &os;}
1057 1057
  }
1058 1058

	
1059 1059
  ///\name Aliases
1060 1060
  ///These are just some aliases to other parameter setting functions.
1061 1061

	
1062 1062
  ///@{
1063 1063

	
1064 1064
  ///An alias for arcWidths()
1065 1065
  template<class X> GraphToEps<ArcWidthsTraits<X> > edgeWidths(const X &x)
1066 1066
  {
1067 1067
    return arcWidths(x);
1068 1068
  }
1069 1069

	
1070 1070
  ///An alias for arcColors()
1071 1071
  template<class X> GraphToEps<ArcColorsTraits<X> >
1072 1072
  edgeColors(const X &x)
1073 1073
  {
1074 1074
    return arcColors(x);
1075 1075
  }
1076 1076

	
1077 1077
  ///An alias for arcWidthScale()
1078 1078
  GraphToEps<T> &edgeWidthScale(double d) {return arcWidthScale(d);}
1079 1079

	
1080 1080
  ///An alias for autoArcWidthScale()
1081 1081
  GraphToEps<T> &autoEdgeWidthScale(bool b=true)
1082 1082
  {
1083 1083
    return autoArcWidthScale(b);
1084 1084
  }
1085 1085

	
1086 1086
  ///An alias for absoluteArcWidths()
1087 1087
  GraphToEps<T> &absoluteEdgeWidths(bool b=true)
1088 1088
  {
1089 1089
    return absoluteArcWidths(b);
1090 1090
  }
1091 1091

	
1092 1092
  ///An alias for parArcDist()
1093 1093
  GraphToEps<T> &parEdgeDist(double d) {return parArcDist(d);}
1094 1094

	
1095 1095
  ///An alias for hideArcs()
1096 1096
  GraphToEps<T> &hideEdges(bool b=true) {return hideArcs(b);}
1097 1097

	
1098 1098
  ///@}
1099 1099
};
1100 1100

	
1101 1101
template<class T>
1102 1102
const int GraphToEps<T>::INTERPOL_PREC = 20;
1103 1103
template<class T>
1104 1104
const double GraphToEps<T>::A4HEIGHT = 841.8897637795276;
1105 1105
template<class T>
1106 1106
const double GraphToEps<T>::A4WIDTH  = 595.275590551181;
1107 1107
template<class T>
1108 1108
const double GraphToEps<T>::A4BORDER = 15;
1109 1109

	
1110 1110

	
1111 1111
///Generates an EPS file from a graph
1112 1112

	
1113 1113
///\ingroup eps_io
1114 1114
///Generates an EPS file from a graph.
1115 1115
///\param g Reference to the graph to be printed.
1116 1116
///\param os Reference to the output stream.
1117
///By default it is <tt>std::cout</tt>.
1117
///By default, it is <tt>std::cout</tt>.
1118 1118
///
1119 1119
///This function also has a lot of
1120 1120
///\ref named-templ-func-param "named parameters",
1121 1121
///they are declared as the members of class \ref GraphToEps. The following
1122 1122
///example shows how to use these parameters.
1123 1123
///\code
1124 1124
/// graphToEps(g,os).scale(10).coords(coords)
1125 1125
///              .nodeScale(2).nodeSizes(sizes)
1126 1126
///              .arcWidthScale(.4).run();
1127 1127
///\endcode
1128 1128
///
1129
///For more detailed examples see the \ref graph_to_eps_demo.cc demo file.
1129
///For more detailed examples, see the \ref graph_to_eps_demo.cc demo file.
1130 1130
///
1131 1131
///\warning Don't forget to put the \ref GraphToEps::run() "run()"
1132 1132
///to the end of the parameter list.
1133 1133
///\sa GraphToEps
1134 1134
///\sa graphToEps(GR &g, const char *file_name)
1135 1135
template<class GR>
1136 1136
GraphToEps<DefaultGraphToEpsTraits<GR> >
1137 1137
graphToEps(GR &g, std::ostream& os=std::cout)
1138 1138
{
1139 1139
  return
1140 1140
    GraphToEps<DefaultGraphToEpsTraits<GR> >(DefaultGraphToEpsTraits<GR>(g,os));
1141 1141
}
1142 1142

	
1143 1143
///Generates an EPS file from a graph
1144 1144

	
1145 1145
///\ingroup eps_io
1146 1146
///This function does the same as
1147 1147
///\ref graphToEps(GR &g,std::ostream& os)
1148 1148
///but it writes its output into the file \c file_name
1149 1149
///instead of a stream.
1150 1150
///\sa graphToEps(GR &g, std::ostream& os)
1151 1151
template<class GR>
1152 1152
GraphToEps<DefaultGraphToEpsTraits<GR> >
1153 1153
graphToEps(GR &g,const char *file_name)
1154 1154
{
1155 1155
  std::ostream* os = new std::ofstream(file_name);
1156 1156
  if (!(*os)) {
1157 1157
    delete os;
1158 1158
    throw IoError("Cannot write file", file_name);
1159 1159
  }
1160 1160
  return GraphToEps<DefaultGraphToEpsTraits<GR> >
1161 1161
    (DefaultGraphToEpsTraits<GR>(g,*os,true));
1162 1162
}
1163 1163

	
1164 1164
///Generates an EPS file from a graph
1165 1165

	
1166 1166
///\ingroup eps_io
1167 1167
///This function does the same as
1168 1168
///\ref graphToEps(GR &g,std::ostream& os)
1169 1169
///but it writes its output into the file \c file_name
1170 1170
///instead of a stream.
1171 1171
///\sa graphToEps(GR &g, std::ostream& os)
1172 1172
template<class GR>
1173 1173
GraphToEps<DefaultGraphToEpsTraits<GR> >
1174 1174
graphToEps(GR &g,const std::string& file_name)
1175 1175
{
1176 1176
  std::ostream* os = new std::ofstream(file_name.c_str());
1177 1177
  if (!(*os)) {
1178 1178
    delete os;
1179 1179
    throw IoError("Cannot write file", file_name);
1180 1180
  }
1181 1181
  return GraphToEps<DefaultGraphToEpsTraits<GR> >
1182 1182
    (DefaultGraphToEpsTraits<GR>(g,*os,true));
1183 1183
}
1184 1184

	
1185 1185
} //END OF NAMESPACE LEMON
1186 1186

	
1187 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 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 GRID_GRAPH_H
20 20
#define GRID_GRAPH_H
21 21

	
22 22
#include <lemon/core.h>
23 23
#include <lemon/bits/graph_extender.h>
24 24
#include <lemon/dim2.h>
25 25
#include <lemon/assert.h>
26 26

	
27 27
///\ingroup graphs
28 28
///\file
29 29
///\brief GridGraph class.
30 30

	
31 31
namespace lemon {
32 32

	
33 33
  class GridGraphBase {
34 34

	
35 35
  public:
36 36

	
37 37
    typedef GridGraphBase Graph;
38 38

	
39 39
    class Node;
40 40
    class Edge;
41 41
    class Arc;
42 42

	
43 43
  public:
44 44

	
45 45
    GridGraphBase() {}
46 46

	
47 47
  protected:
48 48

	
49 49
    void construct(int width, int height) {
50 50
       _width = width; _height = height;
51 51
      _node_num = width * height;
52 52
      _edge_num = 2 * _node_num - width - height;
53 53
      _edge_limit = _node_num - _width;
54 54
    }
55 55

	
56 56
  public:
57 57

	
58 58
    Node operator()(int i, int j) const {
59 59
      LEMON_DEBUG(0 <= i && i < _width &&
60 60
                  0 <= j  && j < _height, "Index out of range");
61 61
      return Node(i + j * _width);
62 62
    }
63 63

	
64 64
    int col(Node n) const {
65 65
      return n._id % _width;
66 66
    }
67 67

	
68 68
    int row(Node n) const {
69 69
      return n._id / _width;
70 70
    }
71 71

	
72 72
    dim2::Point<int> pos(Node n) const {
73 73
      return dim2::Point<int>(col(n), row(n));
74 74
    }
75 75

	
76 76
    int width() const {
77 77
      return _width;
78 78
    }
79 79

	
80 80
    int height() const {
81 81
      return _height;
82 82
    }
83 83

	
84 84
    typedef True NodeNumTag;
85 85
    typedef True EdgeNumTag;
86 86
    typedef True ArcNumTag;
87 87

	
88 88
    int nodeNum() const { return _node_num; }
89 89
    int edgeNum() const { return _edge_num; }
90 90
    int arcNum() const { return 2 * _edge_num; }
91 91

	
92 92
    Node u(Edge edge) const {
93 93
      if (edge._id < _edge_limit) {
94 94
        return edge._id;
95 95
      } else {
96 96
        return (edge._id - _edge_limit) % (_width - 1) +
97 97
          (edge._id - _edge_limit) / (_width - 1) * _width;
98 98
      }
99 99
    }
100 100

	
101 101
    Node v(Edge edge) const {
102 102
      if (edge._id < _edge_limit) {
103 103
        return edge._id + _width;
104 104
      } else {
105 105
        return (edge._id - _edge_limit) % (_width - 1) +
106 106
          (edge._id - _edge_limit) / (_width - 1) * _width + 1;
107 107
      }
108 108
    }
109 109

	
110 110
    Node source(Arc arc) const {
111 111
      return (arc._id & 1) == 1 ? u(arc) : v(arc);
112 112
    }
113 113

	
114 114
    Node target(Arc arc) const {
115 115
      return (arc._id & 1) == 1 ? v(arc) : u(arc);
116 116
    }
117 117

	
118 118
    static int id(Node node) { return node._id; }
119 119
    static int id(Edge edge) { return edge._id; }
120 120
    static int id(Arc arc) { return arc._id; }
121 121

	
122 122
    int maxNodeId() const { return _node_num - 1; }
123 123
    int maxEdgeId() const { return _edge_num - 1; }
124 124
    int maxArcId() const { return 2 * _edge_num - 1; }
125 125

	
126 126
    static Node nodeFromId(int id) { return Node(id);}
127 127
    static Edge edgeFromId(int id) { return Edge(id);}
128 128
    static Arc arcFromId(int id) { return Arc(id);}
129 129

	
130 130
    typedef True FindEdgeTag;
131 131
    typedef True FindArcTag;
132 132

	
133 133
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
134 134
      if (prev != INVALID) return INVALID;
135 135
      if (v._id > u._id) {
136 136
        if (v._id - u._id == _width)
137 137
          return Edge(u._id);
138 138
        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
139 139
          return Edge(u._id / _width * (_width - 1) +
140 140
                      u._id % _width + _edge_limit);
141 141
        }
142 142
      } else {
143 143
        if (u._id - v._id == _width)
144 144
          return Edge(v._id);
145 145
        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
146 146
          return Edge(v._id / _width * (_width - 1) +
147 147
                      v._id % _width + _edge_limit);
148 148
        }
149 149
      }
150 150
      return INVALID;
151 151
    }
152 152

	
153 153
    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
154 154
      if (prev != INVALID) return INVALID;
155 155
      if (v._id > u._id) {
156 156
        if (v._id - u._id == _width)
157 157
          return Arc((u._id << 1) | 1);
158 158
        if (v._id - u._id == 1 && u._id % _width < _width - 1) {
159 159
          return Arc(((u._id / _width * (_width - 1) +
160 160
                       u._id % _width + _edge_limit) << 1) | 1);
161 161
        }
162 162
      } else {
163 163
        if (u._id - v._id == _width)
164 164
          return Arc(v._id << 1);
165 165
        if (u._id - v._id == 1 && v._id % _width < _width - 1) {
166 166
          return Arc((v._id / _width * (_width - 1) +
167 167
                       v._id % _width + _edge_limit) << 1);
168 168
        }
169 169
      }
170 170
      return INVALID;
171 171
    }
172 172

	
173 173
    class Node {
174 174
      friend class GridGraphBase;
175 175

	
176 176
    protected:
177 177
      int _id;
178 178
      Node(int id) : _id(id) {}
179 179
    public:
180 180
      Node() {}
181 181
      Node (Invalid) : _id(-1) {}
182 182
      bool operator==(const Node node) const {return _id == node._id;}
183 183
      bool operator!=(const Node node) const {return _id != node._id;}
184 184
      bool operator<(const Node node) const {return _id < node._id;}
185 185
    };
186 186

	
187 187
    class Edge {
188 188
      friend class GridGraphBase;
189 189
      friend class Arc;
190 190

	
191 191
    protected:
192 192
      int _id;
193 193

	
194 194
      Edge(int id) : _id(id) {}
195 195

	
196 196
    public:
197 197
      Edge() {}
198 198
      Edge (Invalid) : _id(-1) {}
199 199
      bool operator==(const Edge edge) const {return _id == edge._id;}
200 200
      bool operator!=(const Edge edge) const {return _id != edge._id;}
201 201
      bool operator<(const Edge edge) const {return _id < edge._id;}
202 202
    };
203 203

	
204 204
    class Arc {
205 205
      friend class GridGraphBase;
206 206

	
207 207
    protected:
208 208
      int _id;
209 209

	
210 210
      Arc(int id) : _id(id) {}
211 211

	
212 212
    public:
213 213
      Arc() {}
214 214
      Arc (Invalid) : _id(-1) {}
215 215
      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
216 216
      bool operator==(const Arc arc) const {return _id == arc._id;}
217 217
      bool operator!=(const Arc arc) const {return _id != arc._id;}
218 218
      bool operator<(const Arc arc) const {return _id < arc._id;}
219 219
    };
220 220

	
221 221
    static bool direction(Arc arc) {
222 222
      return (arc._id & 1) == 1;
223 223
    }
224 224

	
225 225
    static Arc direct(Edge edge, bool dir) {
226 226
      return Arc((edge._id << 1) | (dir ? 1 : 0));
227 227
    }
228 228

	
229 229
    void first(Node& node) const {
230 230
      node._id = _node_num - 1;
231 231
    }
232 232

	
233 233
    static void next(Node& node) {
234 234
      --node._id;
235 235
    }
236 236

	
237 237
    void first(Edge& edge) const {
238 238
      edge._id = _edge_num - 1;
239 239
    }
240 240

	
241 241
    static void next(Edge& edge) {
242 242
      --edge._id;
243 243
    }
244 244

	
245 245
    void first(Arc& arc) const {
246 246
      arc._id = 2 * _edge_num - 1;
247 247
    }
248 248

	
249 249
    static void next(Arc& arc) {
250 250
      --arc._id;
251 251
    }
252 252

	
253 253
    void firstOut(Arc& arc, const Node& node) const {
254 254
      if (node._id % _width < _width - 1) {
255 255
        arc._id = (_edge_limit + node._id % _width +
256 256
                   (node._id / _width) * (_width - 1)) << 1 | 1;
257 257
        return;
258 258
      }
259 259
      if (node._id < _node_num - _width) {
260 260
        arc._id = node._id << 1 | 1;
261 261
        return;
262 262
      }
263 263
      if (node._id % _width > 0) {
264 264
        arc._id = (_edge_limit + node._id % _width +
265 265
                   (node._id / _width) * (_width - 1) - 1) << 1;
266 266
        return;
267 267
      }
268 268
      if (node._id >= _width) {
269 269
        arc._id = (node._id - _width) << 1;
270 270
        return;
271 271
      }
272 272
      arc._id = -1;
273 273
    }
274 274

	
275 275
    void nextOut(Arc& arc) const {
276 276
      int nid = arc._id >> 1;
277 277
      if ((arc._id & 1) == 1) {
278 278
        if (nid >= _edge_limit) {
279 279
          nid = (nid - _edge_limit) % (_width - 1) +
280 280
            (nid - _edge_limit) / (_width - 1) * _width;
281 281
          if (nid < _node_num - _width) {
282 282
            arc._id = nid << 1 | 1;
283 283
            return;
284 284
          }
285 285
        }
286 286
        if (nid % _width > 0) {
287 287
          arc._id = (_edge_limit + nid % _width +
288 288
                     (nid / _width) * (_width - 1) - 1) << 1;
289 289
          return;
290 290
        }
291 291
        if (nid >= _width) {
292 292
          arc._id = (nid - _width) << 1;
293 293
          return;
294 294
        }
295 295
      } else {
296 296
        if (nid >= _edge_limit) {
297 297
          nid = (nid - _edge_limit) % (_width - 1) +
298 298
            (nid - _edge_limit) / (_width - 1) * _width + 1;
299 299
          if (nid >= _width) {
300 300
            arc._id = (nid - _width) << 1;
301 301
            return;
302 302
          }
303 303
        }
304 304
      }
305 305
      arc._id = -1;
306 306
    }
307 307

	
308 308
    void firstIn(Arc& arc, const Node& node) const {
309 309
      if (node._id % _width < _width - 1) {
310 310
        arc._id = (_edge_limit + node._id % _width +
311 311
                   (node._id / _width) * (_width - 1)) << 1;
312 312
        return;
313 313
      }
314 314
      if (node._id < _node_num - _width) {
315 315
        arc._id = node._id << 1;
316 316
        return;
317 317
      }
318 318
      if (node._id % _width > 0) {
319 319
        arc._id = (_edge_limit + node._id % _width +
320 320
                   (node._id / _width) * (_width - 1) - 1) << 1 | 1;
321 321
        return;
322 322
      }
323 323
      if (node._id >= _width) {
324 324
        arc._id = (node._id - _width) << 1 | 1;
325 325
        return;
326 326
      }
327 327
      arc._id = -1;
328 328
    }
329 329

	
330 330
    void nextIn(Arc& arc) const {
331 331
      int nid = arc._id >> 1;
332 332
      if ((arc._id & 1) == 0) {
333 333
        if (nid >= _edge_limit) {
334 334
          nid = (nid - _edge_limit) % (_width - 1) +
335 335
            (nid - _edge_limit) / (_width - 1) * _width;
336 336
          if (nid < _node_num - _width) {
337 337
            arc._id = nid << 1;
338 338
            return;
339 339
          }
340 340
        }
341 341
        if (nid % _width > 0) {
342 342
          arc._id = (_edge_limit + nid % _width +
343 343
                     (nid / _width) * (_width - 1) - 1) << 1 | 1;
344 344
          return;
345 345
        }
346 346
        if (nid >= _width) {
347 347
          arc._id = (nid - _width) << 1 | 1;
348 348
          return;
349 349
        }
350 350
      } else {
351 351
        if (nid >= _edge_limit) {
352 352
          nid = (nid - _edge_limit) % (_width - 1) +
353 353
            (nid - _edge_limit) / (_width - 1) * _width + 1;
354 354
          if (nid >= _width) {
355 355
            arc._id = (nid - _width) << 1 | 1;
356 356
            return;
357 357
          }
358 358
        }
359 359
      }
360 360
      arc._id = -1;
361 361
    }
362 362

	
363 363
    void firstInc(Edge& edge, bool& dir, const Node& node) const {
364 364
      if (node._id % _width < _width - 1) {
365 365
        edge._id = _edge_limit + node._id % _width +
366 366
          (node._id / _width) * (_width - 1);
367 367
        dir = true;
368 368
        return;
369 369
      }
370 370
      if (node._id < _node_num - _width) {
371 371
        edge._id = node._id;
372 372
        dir = true;
373 373
        return;
374 374
      }
375 375
      if (node._id % _width > 0) {
376 376
        edge._id = _edge_limit + node._id % _width +
377 377
          (node._id / _width) * (_width - 1) - 1;
378 378
        dir = false;
379 379
        return;
380 380
      }
381 381
      if (node._id >= _width) {
382 382
        edge._id = node._id - _width;
383 383
        dir = false;
384 384
        return;
385 385
      }
386 386
      edge._id = -1;
387 387
      dir = true;
388 388
    }
389 389

	
390 390
    void nextInc(Edge& edge, bool& dir) const {
391 391
      int nid = edge._id;
392 392
      if (dir) {
393 393
        if (nid >= _edge_limit) {
394 394
          nid = (nid - _edge_limit) % (_width - 1) +
395 395
            (nid - _edge_limit) / (_width - 1) * _width;
396 396
          if (nid < _node_num - _width) {
397 397
            edge._id = nid;
398 398
            return;
399 399
          }
400 400
        }
401 401
        if (nid % _width > 0) {
402 402
          edge._id = _edge_limit + nid % _width +
403 403
            (nid / _width) * (_width - 1) - 1;
404 404
          dir = false;
405 405
          return;
406 406
        }
407 407
        if (nid >= _width) {
408 408
          edge._id = nid - _width;
409 409
          dir = false;
410 410
          return;
411 411
        }
412 412
      } else {
413 413
        if (nid >= _edge_limit) {
414 414
          nid = (nid - _edge_limit) % (_width - 1) +
415 415
            (nid - _edge_limit) / (_width - 1) * _width + 1;
416 416
          if (nid >= _width) {
417 417
            edge._id = nid - _width;
418 418
            return;
419 419
          }
420 420
        }
421 421
      }
422 422
      edge._id = -1;
423 423
      dir = true;
424 424
    }
425 425

	
426 426
    Arc right(Node n) const {
427 427
      if (n._id % _width < _width - 1) {
428 428
        return Arc(((_edge_limit + n._id % _width +
429 429
                    (n._id / _width) * (_width - 1)) << 1) | 1);
430 430
      } else {
431 431
        return INVALID;
432 432
      }
433 433
    }
434 434

	
435 435
    Arc left(Node n) const {
436 436
      if (n._id % _width > 0) {
437 437
        return Arc((_edge_limit + n._id % _width +
438 438
                     (n._id / _width) * (_width - 1) - 1) << 1);
439 439
      } else {
440 440
        return INVALID;
441 441
      }
442 442
    }
443 443

	
444 444
    Arc up(Node n) const {
445 445
      if (n._id < _edge_limit) {
446 446
        return Arc((n._id << 1) | 1);
447 447
      } else {
448 448
        return INVALID;
449 449
      }
450 450
    }
451 451

	
452 452
    Arc down(Node n) const {
453 453
      if (n._id >= _width) {
454 454
        return Arc((n._id - _width) << 1);
455 455
      } else {
456 456
        return INVALID;
457 457
      }
458 458
    }
459 459

	
460 460
  private:
461 461
    int _width, _height;
462 462
    int _node_num, _edge_num;
463 463
    int _edge_limit;
464 464
  };
465 465

	
466 466

	
467 467
  typedef GraphExtender<GridGraphBase> ExtendedGridGraphBase;
468 468

	
469 469
  /// \ingroup graphs
470 470
  ///
471 471
  /// \brief Grid graph class
472 472
  ///
473
  /// This class implements a special graph type. The nodes of the
474
  /// graph can be indexed by two integer \c (i,j) value where \c i is
475
  /// in the \c [0..width()-1] range and j is in the \c
476
  /// [0..height()-1] range.  Two nodes are connected in the graph if
477
  /// the indexes differ exactly on one position and exactly one is
478
  /// the difference. The nodes of the graph can be indexed by position
479
  /// with the \c operator()() function. The positions of the nodes can be
480
  /// get with \c pos(), \c col() and \c row() members. The outgoing
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 481
  /// arcs can be retrieved with the \c right(), \c up(), \c left()
482 482
  /// and \c down() functions, where the bottom-left corner is the
483 483
  /// origin.
484 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
  ///
485 489
  /// \image html grid_graph.png
486 490
  /// \image latex grid_graph.eps "Grid graph" width=\textwidth
487 491
  ///
488 492
  /// A short example about the basic usage:
489 493
  ///\code
490 494
  /// GridGraph graph(rows, cols);
491 495
  /// GridGraph::NodeMap<int> val(graph);
492 496
  /// for (int i = 0; i < graph.width(); ++i) {
493 497
  ///   for (int j = 0; j < graph.height(); ++j) {
494 498
  ///     val[graph(i, j)] = i + j;
495 499
  ///   }
496 500
  /// }
497 501
  ///\endcode
498 502
  ///
499
  /// This graph type fully conforms to the \ref concepts::Graph
500
  /// "Graph concept".
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
  ///
507
  /// This class provides constant time counting for nodes, edges and arcs.
501 508
  class GridGraph : public ExtendedGridGraphBase {
502 509
    typedef ExtendedGridGraphBase Parent;
503 510

	
504 511
  public:
505 512

	
506
    /// \brief Map to get the indices of the nodes as dim2::Point<int>.
513
    /// \brief Map to get the indices of the nodes as \ref dim2::Point
514
    /// "dim2::Point<int>".
507 515
    ///
508
    /// Map to get the indices of the nodes as dim2::Point<int>.
516
    /// Map to get the indices of the nodes as \ref dim2::Point
517
    /// "dim2::Point<int>".
509 518
    class IndexMap {
510 519
    public:
511 520
      /// \brief The key type of the map
512 521
      typedef GridGraph::Node Key;
513 522
      /// \brief The value type of the map
514 523
      typedef dim2::Point<int> Value;
515 524

	
516 525
      /// \brief Constructor
517
      ///
518
      /// Constructor
519 526
      IndexMap(const GridGraph& graph) : _graph(graph) {}
520 527

	
521 528
      /// \brief The subscript operator
522
      ///
523
      /// The subscript operator.
524 529
      Value operator[](Key key) const {
525 530
        return _graph.pos(key);
526 531
      }
527 532

	
528 533
    private:
529 534
      const GridGraph& _graph;
530 535
    };
531 536

	
532 537
    /// \brief Map to get the column of the nodes.
533 538
    ///
534 539
    /// Map to get the column of the nodes.
535 540
    class ColMap {
536 541
    public:
537 542
      /// \brief The key type of the map
538 543
      typedef GridGraph::Node Key;
539 544
      /// \brief The value type of the map
540 545
      typedef int Value;
541 546

	
542 547
      /// \brief Constructor
543
      ///
544
      /// Constructor
545 548
      ColMap(const GridGraph& graph) : _graph(graph) {}
546 549

	
547 550
      /// \brief The subscript operator
548
      ///
549
      /// The subscript operator.
550 551
      Value operator[](Key key) const {
551 552
        return _graph.col(key);
552 553
      }
553 554

	
554 555
    private:
555 556
      const GridGraph& _graph;
556 557
    };
557 558

	
558 559
    /// \brief Map to get the row of the nodes.
559 560
    ///
560 561
    /// Map to get the row of the nodes.
561 562
    class RowMap {
562 563
    public:
563 564
      /// \brief The key type of the map
564 565
      typedef GridGraph::Node Key;
565 566
      /// \brief The value type of the map
566 567
      typedef int Value;
567 568

	
568 569
      /// \brief Constructor
569
      ///
570
      /// Constructor
571 570
      RowMap(const GridGraph& graph) : _graph(graph) {}
572 571

	
573 572
      /// \brief The subscript operator
574
      ///
575
      /// The subscript operator.
576 573
      Value operator[](Key key) const {
577 574
        return _graph.row(key);
578 575
      }
579 576

	
580 577
    private:
581 578
      const GridGraph& _graph;
582 579
    };
583 580

	
584 581
    /// \brief Constructor
585 582
    ///
586
    /// Construct a grid graph with given size.
583
    /// Construct a grid graph with the given size.
587 584
    GridGraph(int width, int height) { construct(width, height); }
588 585

	
589
    /// \brief Resize the graph
586
    /// \brief Resizes the graph
590 587
    ///
591
    /// Resize the graph. The function will fully destroy and rebuild
592
    /// the graph.  This cause that the maps of the graph will
593
    /// reallocated automatically and the previous values will be
594
    /// lost.
588
    /// This function resizes the graph. It fully destroys and
589
    /// rebuilds the structure, therefore the maps of the graph will be
590
    /// reallocated automatically and the previous values will be lost.
595 591
    void resize(int width, int height) {
596 592
      Parent::notifier(Arc()).clear();
597 593
      Parent::notifier(Edge()).clear();
598 594
      Parent::notifier(Node()).clear();
599 595
      construct(width, height);
600 596
      Parent::notifier(Node()).build();
601 597
      Parent::notifier(Edge()).build();
602 598
      Parent::notifier(Arc()).build();
603 599
    }
604 600

	
605 601
    /// \brief The node on the given position.
606 602
    ///
607 603
    /// Gives back the node on the given position.
608 604
    Node operator()(int i, int j) const {
609 605
      return Parent::operator()(i, j);
610 606
    }
611 607

	
612
    /// \brief Gives back the column index of the node.
608
    /// \brief The column index of the node.
613 609
    ///
614 610
    /// Gives back the column index of the node.
615 611
    int col(Node n) const {
616 612
      return Parent::col(n);
617 613
    }
618 614

	
619
    /// \brief Gives back the row index of the node.
615
    /// \brief The row index of the node.
620 616
    ///
621 617
    /// Gives back the row index of the node.
622 618
    int row(Node n) const {
623 619
      return Parent::row(n);
624 620
    }
625 621

	
626
    /// \brief Gives back the position of the node.
622
    /// \brief The position of the node.
627 623
    ///
628 624
    /// Gives back the position of the node, ie. the <tt>(col,row)</tt> pair.
629 625
    dim2::Point<int> pos(Node n) const {
630 626
      return Parent::pos(n);
631 627
    }
632 628

	
633
    /// \brief Gives back the number of the columns.
629
    /// \brief The number of the columns.
634 630
    ///
635 631
    /// Gives back the number of the columns.
636 632
    int width() const {
637 633
      return Parent::width();
638 634
    }
639 635

	
640
    /// \brief Gives back the number of the rows.
636
    /// \brief The number of the rows.
641 637
    ///
642 638
    /// Gives back the number of the rows.
643 639
    int height() const {
644 640
      return Parent::height();
645 641
    }
646 642

	
647
    /// \brief Gives back the arc goes right from the node.
643
    /// \brief The arc goes right from the node.
648 644
    ///
649 645
    /// Gives back the arc goes right from the node. If there is not
650 646
    /// outgoing arc then it gives back INVALID.
651 647
    Arc right(Node n) const {
652 648
      return Parent::right(n);
653 649
    }
654 650

	
655
    /// \brief Gives back the arc goes left from the node.
651
    /// \brief The arc goes left from the node.
656 652
    ///
657 653
    /// Gives back the arc goes left from the node. If there is not
658 654
    /// outgoing arc then it gives back INVALID.
659 655
    Arc left(Node n) const {
660 656
      return Parent::left(n);
661 657
    }
662 658

	
663
    /// \brief Gives back the arc goes up from the node.
659
    /// \brief The arc goes up from the node.
664 660
    ///
665 661
    /// Gives back the arc goes up from the node. If there is not
666 662
    /// outgoing arc then it gives back INVALID.
667 663
    Arc up(Node n) const {
668 664
      return Parent::up(n);
669 665
    }
670 666

	
671
    /// \brief Gives back the arc goes down from the node.
667
    /// \brief The arc goes down from the node.
672 668
    ///
673 669
    /// Gives back the arc goes down from the node. If there is not
674 670
    /// outgoing arc then it gives back INVALID.
675 671
    Arc down(Node n) const {
676 672
      return Parent::down(n);
677 673
    }
678 674

	
679 675
    /// \brief Index map of the grid graph
680 676
    ///
681 677
    /// Just returns an IndexMap for the grid graph.
682 678
    IndexMap indexMap() const {
683 679
      return IndexMap(*this);
684 680
    }
685 681

	
686 682
    /// \brief Row map of the grid graph
687 683
    ///
688 684
    /// Just returns a RowMap for the grid graph.
689 685
    RowMap rowMap() const {
690 686
      return RowMap(*this);
691 687
    }
692 688

	
693 689
    /// \brief Column map of the grid graph
694 690
    ///
695 691
    /// Just returns a ColMap for the grid graph.
696 692
    ColMap colMap() const {
697 693
      return ColMap(*this);
698 694
    }
699 695

	
700 696
  };
701 697

	
702 698
}
703 699
#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-2009
5
 * Copyright (C) 2003-2010
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_HAO_ORLIN_H
20 20
#define LEMON_HAO_ORLIN_H
21 21

	
22 22
#include <vector>
23 23
#include <list>
24 24
#include <limits>
25 25

	
26 26
#include <lemon/maps.h>
27 27
#include <lemon/core.h>
28 28
#include <lemon/tolerance.h>
29 29

	
30 30
/// \file
31 31
/// \ingroup min_cut
32 32
/// \brief Implementation of the Hao-Orlin algorithm.
33 33
///
34
/// Implementation of the Hao-Orlin algorithm for finding a minimum cut 
34
/// Implementation of the Hao-Orlin algorithm for finding a minimum cut
35 35
/// in a digraph.
36 36

	
37 37
namespace lemon {
38 38

	
39 39
  /// \ingroup min_cut
40 40
  ///
41 41
  /// \brief Hao-Orlin algorithm for finding a minimum cut in a digraph.
42 42
  ///
43 43
  /// This class implements the Hao-Orlin algorithm for finding a minimum
44
  /// value cut in a directed graph \f$D=(V,A)\f$. 
44
  /// value cut in a directed graph \f$D=(V,A)\f$.
45 45
  /// It takes a fixed node \f$ source \in V \f$ and
46 46
  /// consists of two phases: in the first phase it determines a
47 47
  /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
48 48
  /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal outgoing
49 49
  /// capacity) and in the second phase it determines a minimum cut
50 50
  /// with \f$ source \f$ on the sink-side (i.e. a set
51 51
  /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal outgoing
52 52
  /// capacity). Obviously, the smaller of these two cuts will be a
53 53
  /// minimum cut of \f$ D \f$. The algorithm is a modified
54 54
  /// preflow push-relabel algorithm. Our implementation calculates
55 55
  /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
56 56
  /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The
57 57
  /// purpose of such algorithm is e.g. testing network reliability.
58 58
  ///
59 59
  /// For an undirected graph you can run just the first phase of the
60 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$ 
61
  /// which solves the undirected problem in \f$ O(nm + n^2 \log n) \f$
62 62
  /// time. It is implemented in the NagamochiIbaraki algorithm class.
63 63
  ///
64 64
  /// \tparam GR The type of the digraph the algorithm runs on.
65 65
  /// \tparam CAP The type of the arc map containing the capacities,
66 66
  /// which can be any numreric type. The default map type is
67 67
  /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
68 68
  /// \tparam TOL Tolerance class for handling inexact computations. The
69 69
  /// default tolerance type is \ref Tolerance "Tolerance<CAP::Value>".
70 70
#ifdef DOXYGEN
71 71
  template <typename GR, typename CAP, typename TOL>
72 72
#else
73 73
  template <typename GR,
74 74
            typename CAP = typename GR::template ArcMap<int>,
75 75
            typename TOL = Tolerance<typename CAP::Value> >
76 76
#endif
77 77
  class HaoOrlin {
78 78
  public:
79
   
79

	
80 80
    /// The digraph type of the algorithm
81 81
    typedef GR Digraph;
82 82
    /// The capacity map type of the algorithm
83 83
    typedef CAP CapacityMap;
84 84
    /// The tolerance type of the algorithm
85 85
    typedef TOL Tolerance;
86 86

	
87 87
  private:
88 88

	
89 89
    typedef typename CapacityMap::Value Value;
90 90

	
91 91
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
92 92

	
93 93
    const Digraph& _graph;
94 94
    const CapacityMap* _capacity;
95 95

	
96 96
    typedef typename Digraph::template ArcMap<Value> FlowMap;
97 97
    FlowMap* _flow;
98 98

	
99 99
    Node _source;
100 100

	
101 101
    int _node_num;
102 102

	
103 103
    // Bucketing structure
104 104
    std::vector<Node> _first, _last;
105 105
    typename Digraph::template NodeMap<Node>* _next;
106 106
    typename Digraph::template NodeMap<Node>* _prev;
107 107
    typename Digraph::template NodeMap<bool>* _active;
108 108
    typename Digraph::template NodeMap<int>* _bucket;
109 109

	
110 110
    std::vector<bool> _dormant;
111 111

	
112 112
    std::list<std::list<int> > _sets;
113 113
    std::list<int>::iterator _highest;
114 114

	
115 115
    typedef typename Digraph::template NodeMap<Value> ExcessMap;
116 116
    ExcessMap* _excess;
117 117

	
118 118
    typedef typename Digraph::template NodeMap<bool> SourceSetMap;
119 119
    SourceSetMap* _source_set;
120 120

	
121 121
    Value _min_cut;
122 122

	
123 123
    typedef typename Digraph::template NodeMap<bool> MinCutMap;
124 124
    MinCutMap* _min_cut_map;
125 125

	
126 126
    Tolerance _tolerance;
127 127

	
128 128
  public:
129 129

	
130 130
    /// \brief Constructor
131 131
    ///
132 132
    /// Constructor of the algorithm class.
133 133
    HaoOrlin(const Digraph& graph, const CapacityMap& capacity,
134 134
             const Tolerance& tolerance = Tolerance()) :
135 135
      _graph(graph), _capacity(&capacity), _flow(0), _source(),
136 136
      _node_num(), _first(), _last(), _next(0), _prev(0),
137 137
      _active(0), _bucket(0), _dormant(), _sets(), _highest(),
138 138
      _excess(0), _source_set(0), _min_cut(), _min_cut_map(0),
139 139
      _tolerance(tolerance) {}
140 140

	
141 141
    ~HaoOrlin() {
142 142
      if (_min_cut_map) {
143 143
        delete _min_cut_map;
144 144
      }
145 145
      if (_source_set) {
146 146
        delete _source_set;
147 147
      }
148 148
      if (_excess) {
149 149
        delete _excess;
150 150
      }
151 151
      if (_next) {
152 152
        delete _next;
153 153
      }
154 154
      if (_prev) {
155 155
        delete _prev;
156 156
      }
157 157
      if (_active) {
158 158
        delete _active;
159 159
      }
160 160
      if (_bucket) {
161 161
        delete _bucket;
162 162
      }
163 163
      if (_flow) {
164 164
        delete _flow;
165 165
      }
166 166
    }
167 167

	
168
    /// \brief Set the tolerance used by the algorithm.
169
    ///
170
    /// This function sets the tolerance object used by the algorithm.
171
    /// \return <tt>(*this)</tt>
172
    HaoOrlin& tolerance(const Tolerance& tolerance) {
173
      _tolerance = tolerance;
174
      return *this;
175
    }
176

	
177
    /// \brief Returns a const reference to the tolerance.
178
    ///
179
    /// This function returns a const reference to the tolerance object
180
    /// used by the algorithm.
181
    const Tolerance& tolerance() const {
182
      return _tolerance;
183
    }
184

	
168 185
  private:
169 186

	
170 187
    void activate(const Node& i) {
171 188
      (*_active)[i] = true;
172 189

	
173 190
      int bucket = (*_bucket)[i];
174 191

	
175 192
      if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return;
176 193
      //unlace
177 194
      (*_next)[(*_prev)[i]] = (*_next)[i];
178 195
      if ((*_next)[i] != INVALID) {
179 196
        (*_prev)[(*_next)[i]] = (*_prev)[i];
180 197
      } else {
181 198
        _last[bucket] = (*_prev)[i];
182 199
      }
183 200
      //lace
184 201
      (*_next)[i] = _first[bucket];
185 202
      (*_prev)[_first[bucket]] = i;
186 203
      (*_prev)[i] = INVALID;
187 204
      _first[bucket] = i;
188 205
    }
189 206

	
190 207
    void deactivate(const Node& i) {
191 208
      (*_active)[i] = false;
192 209
      int bucket = (*_bucket)[i];
193 210

	
194 211
      if ((*_next)[i] == INVALID || !(*_active)[(*_next)[i]]) return;
195 212

	
196 213
      //unlace
197 214
      (*_prev)[(*_next)[i]] = (*_prev)[i];
198 215
      if ((*_prev)[i] != INVALID) {
199 216
        (*_next)[(*_prev)[i]] = (*_next)[i];
200 217
      } else {
201 218
        _first[bucket] = (*_next)[i];
202 219
      }
203 220
      //lace
204 221
      (*_prev)[i] = _last[bucket];
205 222
      (*_next)[_last[bucket]] = i;
206 223
      (*_next)[i] = INVALID;
207 224
      _last[bucket] = i;
208 225
    }
209 226

	
210 227
    void addItem(const Node& i, int bucket) {
211 228
      (*_bucket)[i] = bucket;
212 229
      if (_last[bucket] != INVALID) {
213 230
        (*_prev)[i] = _last[bucket];
214 231
        (*_next)[_last[bucket]] = i;
215 232
        (*_next)[i] = INVALID;
216 233
        _last[bucket] = i;
217 234
      } else {
218 235
        (*_prev)[i] = INVALID;
219 236
        _first[bucket] = i;
220 237
        (*_next)[i] = INVALID;
221 238
        _last[bucket] = i;
222 239
      }
223 240
    }
224 241

	
225 242
    void findMinCutOut() {
226 243

	
227 244
      for (NodeIt n(_graph); n != INVALID; ++n) {
228 245
        (*_excess)[n] = 0;
229 246
        (*_source_set)[n] = false;
230 247
      }
231 248

	
232 249
      for (ArcIt a(_graph); a != INVALID; ++a) {
233 250
        (*_flow)[a] = 0;
234 251
      }
235 252

	
236 253
      int bucket_num = 0;
237 254
      std::vector<Node> queue(_node_num);
238 255
      int qfirst = 0, qlast = 0, qsep = 0;
239 256

	
240 257
      {
241 258
        typename Digraph::template NodeMap<bool> reached(_graph, false);
242 259

	
243 260
        reached[_source] = true;
244 261
        bool first_set = true;
245 262

	
246 263
        for (NodeIt t(_graph); t != INVALID; ++t) {
247 264
          if (reached[t]) continue;
248 265
          _sets.push_front(std::list<int>());
249 266

	
250 267
          queue[qlast++] = t;
251 268
          reached[t] = true;
252 269

	
253 270
          while (qfirst != qlast) {
254 271
            if (qsep == qfirst) {
255 272
              ++bucket_num;
256 273
              _sets.front().push_front(bucket_num);
257 274
              _dormant[bucket_num] = !first_set;
258 275
              _first[bucket_num] = _last[bucket_num] = INVALID;
259 276
              qsep = qlast;
260 277
            }
261 278

	
262 279
            Node n = queue[qfirst++];
263 280
            addItem(n, bucket_num);
264 281

	
265 282
            for (InArcIt a(_graph, n); a != INVALID; ++a) {
266 283
              Node u = _graph.source(a);
267 284
              if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
268 285
                reached[u] = true;
269 286
                queue[qlast++] = u;
270 287
              }
271 288
            }
272 289
          }
273 290
          first_set = false;
274 291
        }
275 292

	
276 293
        ++bucket_num;
277 294
        (*_bucket)[_source] = 0;
278 295
        _dormant[0] = true;
279 296
      }
280 297
      (*_source_set)[_source] = true;
281 298

	
282 299
      Node target = _last[_sets.back().back()];
283 300
      {
284 301
        for (OutArcIt a(_graph, _source); a != INVALID; ++a) {
285 302
          if (_tolerance.positive((*_capacity)[a])) {
286 303
            Node u = _graph.target(a);
287 304
            (*_flow)[a] = (*_capacity)[a];
288 305
            (*_excess)[u] += (*_capacity)[a];
289 306
            if (!(*_active)[u] && u != _source) {
290 307
              activate(u);
291 308
            }
292 309
          }
293 310
        }
294 311

	
295 312
        if ((*_active)[target]) {
296 313
          deactivate(target);
297 314
        }
298 315

	
299 316
        _highest = _sets.back().begin();
300 317
        while (_highest != _sets.back().end() &&
301 318
               !(*_active)[_first[*_highest]]) {
302 319
          ++_highest;
303 320
        }
304 321
      }
305 322

	
306 323
      while (true) {
307 324
        while (_highest != _sets.back().end()) {
308 325
          Node n = _first[*_highest];
309 326
          Value excess = (*_excess)[n];
310 327
          int next_bucket = _node_num;
311 328

	
312 329
          int under_bucket;
313 330
          if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
314 331
            under_bucket = -1;
315 332
          } else {
316 333
            under_bucket = *(++std::list<int>::iterator(_highest));
317 334
          }
318 335

	
319 336
          for (OutArcIt a(_graph, n); a != INVALID; ++a) {
320 337
            Node v = _graph.target(a);
321 338
            if (_dormant[(*_bucket)[v]]) continue;
322 339
            Value rem = (*_capacity)[a] - (*_flow)[a];
323 340
            if (!_tolerance.positive(rem)) continue;
324 341
            if ((*_bucket)[v] == under_bucket) {
325 342
              if (!(*_active)[v] && v != target) {
326 343
                activate(v);
327 344
              }
328 345
              if (!_tolerance.less(rem, excess)) {
329 346
                (*_flow)[a] += excess;
330 347
                (*_excess)[v] += excess;
331 348
                excess = 0;
332 349
                goto no_more_push;
333 350
              } else {
334 351
                excess -= rem;
335 352
                (*_excess)[v] += rem;
336 353
                (*_flow)[a] = (*_capacity)[a];
337 354
              }
338 355
            } else if (next_bucket > (*_bucket)[v]) {
339 356
              next_bucket = (*_bucket)[v];
340 357
            }
341 358
          }
342 359

	
343 360
          for (InArcIt a(_graph, n); a != INVALID; ++a) {
344 361
            Node v = _graph.source(a);
345 362
            if (_dormant[(*_bucket)[v]]) continue;
346 363
            Value rem = (*_flow)[a];
347 364
            if (!_tolerance.positive(rem)) continue;
348 365
            if ((*_bucket)[v] == under_bucket) {
349 366
              if (!(*_active)[v] && v != target) {
350 367
                activate(v);
351 368
              }
352 369
              if (!_tolerance.less(rem, excess)) {
353 370
                (*_flow)[a] -= excess;
354 371
                (*_excess)[v] += excess;
355 372
                excess = 0;
356 373
                goto no_more_push;
357 374
              } else {
358 375
                excess -= rem;
359 376
                (*_excess)[v] += rem;
360 377
                (*_flow)[a] = 0;
361 378
              }
362 379
            } else if (next_bucket > (*_bucket)[v]) {
363 380
              next_bucket = (*_bucket)[v];
364 381
            }
365 382
          }
366 383

	
367 384
        no_more_push:
368 385

	
369 386
          (*_excess)[n] = excess;
370 387

	
371 388
          if (excess != 0) {
372 389
            if ((*_next)[n] == INVALID) {
373 390
              typename std::list<std::list<int> >::iterator new_set =
374 391
                _sets.insert(--_sets.end(), std::list<int>());
375 392
              new_set->splice(new_set->end(), _sets.back(),
376 393
                              _sets.back().begin(), ++_highest);
377 394
              for (std::list<int>::iterator it = new_set->begin();
378 395
                   it != new_set->end(); ++it) {
379 396
                _dormant[*it] = true;
380 397
              }
381 398
              while (_highest != _sets.back().end() &&
382 399
                     !(*_active)[_first[*_highest]]) {
383 400
                ++_highest;
384 401
              }
385 402
            } else if (next_bucket == _node_num) {
386 403
              _first[(*_bucket)[n]] = (*_next)[n];
387 404
              (*_prev)[(*_next)[n]] = INVALID;
388 405

	
389 406
              std::list<std::list<int> >::iterator new_set =
390 407
                _sets.insert(--_sets.end(), std::list<int>());
391 408

	
392 409
              new_set->push_front(bucket_num);
393 410
              (*_bucket)[n] = bucket_num;
394 411
              _first[bucket_num] = _last[bucket_num] = n;
395 412
              (*_next)[n] = INVALID;
396 413
              (*_prev)[n] = INVALID;
397 414
              _dormant[bucket_num] = true;
398 415
              ++bucket_num;
399 416

	
400 417
              while (_highest != _sets.back().end() &&
401 418
                     !(*_active)[_first[*_highest]]) {
402 419
                ++_highest;
403 420
              }
404 421
            } else {
405 422
              _first[*_highest] = (*_next)[n];
406 423
              (*_prev)[(*_next)[n]] = INVALID;
407 424

	
408 425
              while (next_bucket != *_highest) {
409 426
                --_highest;
410 427
              }
411 428

	
412 429
              if (_highest == _sets.back().begin()) {
413 430
                _sets.back().push_front(bucket_num);
414 431
                _dormant[bucket_num] = false;
415 432
                _first[bucket_num] = _last[bucket_num] = INVALID;
416 433
                ++bucket_num;
417 434
              }
418 435
              --_highest;
419 436

	
420 437
              (*_bucket)[n] = *_highest;
421 438
              (*_next)[n] = _first[*_highest];
422 439
              if (_first[*_highest] != INVALID) {
423 440
                (*_prev)[_first[*_highest]] = n;
424 441
              } else {
425 442
                _last[*_highest] = n;
426 443
              }
427 444
              _first[*_highest] = n;
428 445
            }
429 446
          } else {
430 447

	
431 448
            deactivate(n);
432 449
            if (!(*_active)[_first[*_highest]]) {
433 450
              ++_highest;
434 451
              if (_highest != _sets.back().end() &&
435 452
                  !(*_active)[_first[*_highest]]) {
436 453
                _highest = _sets.back().end();
437 454
              }
438 455
            }
439 456
          }
440 457
        }
441 458

	
442 459
        if ((*_excess)[target] < _min_cut) {
443 460
          _min_cut = (*_excess)[target];
444 461
          for (NodeIt i(_graph); i != INVALID; ++i) {
445 462
            (*_min_cut_map)[i] = true;
446 463
          }
447 464
          for (std::list<int>::iterator it = _sets.back().begin();
448 465
               it != _sets.back().end(); ++it) {
449 466
            Node n = _first[*it];
450 467
            while (n != INVALID) {
451 468
              (*_min_cut_map)[n] = false;
452 469
              n = (*_next)[n];
453 470
            }
454 471
          }
455 472
        }
456 473

	
457 474
        {
458 475
          Node new_target;
459 476
          if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
460 477
            if ((*_next)[target] == INVALID) {
461 478
              _last[(*_bucket)[target]] = (*_prev)[target];
462 479
              new_target = (*_prev)[target];
463 480
            } else {
464 481
              (*_prev)[(*_next)[target]] = (*_prev)[target];
465 482
              new_target = (*_next)[target];
466 483
            }
467 484
            if ((*_prev)[target] == INVALID) {
468 485
              _first[(*_bucket)[target]] = (*_next)[target];
469 486
            } else {
470 487
              (*_next)[(*_prev)[target]] = (*_next)[target];
471 488
            }
472 489
          } else {
473 490
            _sets.back().pop_back();
474 491
            if (_sets.back().empty()) {
475 492
              _sets.pop_back();
476 493
              if (_sets.empty())
477 494
                break;
478 495
              for (std::list<int>::iterator it = _sets.back().begin();
479 496
                   it != _sets.back().end(); ++it) {
480 497
                _dormant[*it] = false;
481 498
              }
482 499
            }
483 500
            new_target = _last[_sets.back().back()];
484 501
          }
485 502

	
486 503
          (*_bucket)[target] = 0;
487 504

	
488 505
          (*_source_set)[target] = true;
489 506
          for (OutArcIt a(_graph, target); a != INVALID; ++a) {
490 507
            Value rem = (*_capacity)[a] - (*_flow)[a];
491 508
            if (!_tolerance.positive(rem)) continue;
492 509
            Node v = _graph.target(a);
493 510
            if (!(*_active)[v] && !(*_source_set)[v]) {
494 511
              activate(v);
495 512
            }
496 513
            (*_excess)[v] += rem;
497 514
            (*_flow)[a] = (*_capacity)[a];
498 515
          }
499 516

	
500 517
          for (InArcIt a(_graph, target); a != INVALID; ++a) {
501 518
            Value rem = (*_flow)[a];
502 519
            if (!_tolerance.positive(rem)) continue;
503 520
            Node v = _graph.source(a);
504 521
            if (!(*_active)[v] && !(*_source_set)[v]) {
505 522
              activate(v);
506 523
            }
507 524
            (*_excess)[v] += rem;
508 525
            (*_flow)[a] = 0;
509 526
          }
510 527

	
511 528
          target = new_target;
512 529
          if ((*_active)[target]) {
513 530
            deactivate(target);
514 531
          }
515 532

	
516 533
          _highest = _sets.back().begin();
517 534
          while (_highest != _sets.back().end() &&
518 535
                 !(*_active)[_first[*_highest]]) {
519 536
            ++_highest;
520 537
          }
521 538
        }
522 539
      }
523 540
    }
524 541

	
525 542
    void findMinCutIn() {
526 543

	
527 544
      for (NodeIt n(_graph); n != INVALID; ++n) {
528 545
        (*_excess)[n] = 0;
529 546
        (*_source_set)[n] = false;
530 547
      }
531 548

	
532 549
      for (ArcIt a(_graph); a != INVALID; ++a) {
533 550
        (*_flow)[a] = 0;
534 551
      }
535 552

	
536 553
      int bucket_num = 0;
537 554
      std::vector<Node> queue(_node_num);
538 555
      int qfirst = 0, qlast = 0, qsep = 0;
539 556

	
540 557
      {
541 558
        typename Digraph::template NodeMap<bool> reached(_graph, false);
542 559

	
543 560
        reached[_source] = true;
544 561

	
545 562
        bool first_set = true;
546 563

	
547 564
        for (NodeIt t(_graph); t != INVALID; ++t) {
548 565
          if (reached[t]) continue;
549 566
          _sets.push_front(std::list<int>());
550 567

	
551 568
          queue[qlast++] = t;
552 569
          reached[t] = true;
553 570

	
554 571
          while (qfirst != qlast) {
555 572
            if (qsep == qfirst) {
556 573
              ++bucket_num;
557 574
              _sets.front().push_front(bucket_num);
558 575
              _dormant[bucket_num] = !first_set;
559 576
              _first[bucket_num] = _last[bucket_num] = INVALID;
560 577
              qsep = qlast;
561 578
            }
562 579

	
563 580
            Node n = queue[qfirst++];
564 581
            addItem(n, bucket_num);
565 582

	
566 583
            for (OutArcIt a(_graph, n); a != INVALID; ++a) {
567 584
              Node u = _graph.target(a);
568 585
              if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
569 586
                reached[u] = true;
570 587
                queue[qlast++] = u;
571 588
              }
572 589
            }
573 590
          }
574 591
          first_set = false;
575 592
        }
576 593

	
577 594
        ++bucket_num;
578 595
        (*_bucket)[_source] = 0;
579 596
        _dormant[0] = true;
580 597
      }
581 598
      (*_source_set)[_source] = true;
582 599

	
583 600
      Node target = _last[_sets.back().back()];
584 601
      {
585 602
        for (InArcIt a(_graph, _source); a != INVALID; ++a) {
586 603
          if (_tolerance.positive((*_capacity)[a])) {
587 604
            Node u = _graph.source(a);
588 605
            (*_flow)[a] = (*_capacity)[a];
589 606
            (*_excess)[u] += (*_capacity)[a];
590 607
            if (!(*_active)[u] && u != _source) {
591 608
              activate(u);
592 609
            }
593 610
          }
594 611
        }
595 612
        if ((*_active)[target]) {
596 613
          deactivate(target);
597 614
        }
598 615

	
599 616
        _highest = _sets.back().begin();
600 617
        while (_highest != _sets.back().end() &&
601 618
               !(*_active)[_first[*_highest]]) {
602 619
          ++_highest;
603 620
        }
604 621
      }
605 622

	
606 623

	
607 624
      while (true) {
608 625
        while (_highest != _sets.back().end()) {
609 626
          Node n = _first[*_highest];
610 627
          Value excess = (*_excess)[n];
611 628
          int next_bucket = _node_num;
612 629

	
613 630
          int under_bucket;
614 631
          if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
615 632
            under_bucket = -1;
616 633
          } else {
617 634
            under_bucket = *(++std::list<int>::iterator(_highest));
618 635
          }
619 636

	
620 637
          for (InArcIt a(_graph, n); a != INVALID; ++a) {
621 638
            Node v = _graph.source(a);
622 639
            if (_dormant[(*_bucket)[v]]) continue;
623 640
            Value rem = (*_capacity)[a] - (*_flow)[a];
624 641
            if (!_tolerance.positive(rem)) continue;
625 642
            if ((*_bucket)[v] == under_bucket) {
626 643
              if (!(*_active)[v] && v != target) {
627 644
                activate(v);
628 645
              }
629 646
              if (!_tolerance.less(rem, excess)) {
630 647
                (*_flow)[a] += excess;
631 648
                (*_excess)[v] += excess;
632 649
                excess = 0;
633 650
                goto no_more_push;
634 651
              } else {
635 652
                excess -= rem;
636 653
                (*_excess)[v] += rem;
637 654
                (*_flow)[a] = (*_capacity)[a];
638 655
              }
639 656
            } else if (next_bucket > (*_bucket)[v]) {
640 657
              next_bucket = (*_bucket)[v];
641 658
            }
642 659
          }
643 660

	
644 661
          for (OutArcIt a(_graph, n); a != INVALID; ++a) {
645 662
            Node v = _graph.target(a);
646 663
            if (_dormant[(*_bucket)[v]]) continue;
647 664
            Value rem = (*_flow)[a];
648 665
            if (!_tolerance.positive(rem)) continue;
649 666
            if ((*_bucket)[v] == under_bucket) {
650 667
              if (!(*_active)[v] && v != target) {
651 668
                activate(v);
652 669
              }
653 670
              if (!_tolerance.less(rem, excess)) {
654 671
                (*_flow)[a] -= excess;
655 672
                (*_excess)[v] += excess;
656 673
                excess = 0;
657 674
                goto no_more_push;
658 675
              } else {
659 676
                excess -= rem;
660 677
                (*_excess)[v] += rem;
661 678
                (*_flow)[a] = 0;
662 679
              }
663 680
            } else if (next_bucket > (*_bucket)[v]) {
664 681
              next_bucket = (*_bucket)[v];
665 682
            }
666 683
          }
667 684

	
668 685
        no_more_push:
669 686

	
670 687
          (*_excess)[n] = excess;
671 688

	
672 689
          if (excess != 0) {
673 690
            if ((*_next)[n] == INVALID) {
674 691
              typename std::list<std::list<int> >::iterator new_set =
675 692
                _sets.insert(--_sets.end(), std::list<int>());
676 693
              new_set->splice(new_set->end(), _sets.back(),
677 694
                              _sets.back().begin(), ++_highest);
678 695
              for (std::list<int>::iterator it = new_set->begin();
679 696
                   it != new_set->end(); ++it) {
680 697
                _dormant[*it] = true;
681 698
              }
682 699
              while (_highest != _sets.back().end() &&
683 700
                     !(*_active)[_first[*_highest]]) {
684 701
                ++_highest;
685 702
              }
686 703
            } else if (next_bucket == _node_num) {
687 704
              _first[(*_bucket)[n]] = (*_next)[n];
688 705
              (*_prev)[(*_next)[n]] = INVALID;
689 706

	
690 707
              std::list<std::list<int> >::iterator new_set =
691 708
                _sets.insert(--_sets.end(), std::list<int>());
692 709

	
693 710
              new_set->push_front(bucket_num);
694 711
              (*_bucket)[n] = bucket_num;
695 712
              _first[bucket_num] = _last[bucket_num] = n;
696 713
              (*_next)[n] = INVALID;
697 714
              (*_prev)[n] = INVALID;
698 715
              _dormant[bucket_num] = true;
699 716
              ++bucket_num;
700 717

	
701 718
              while (_highest != _sets.back().end() &&
702 719
                     !(*_active)[_first[*_highest]]) {
703 720
                ++_highest;
704 721
              }
705 722
            } else {
706 723
              _first[*_highest] = (*_next)[n];
707 724
              (*_prev)[(*_next)[n]] = INVALID;
708 725

	
709 726
              while (next_bucket != *_highest) {
710 727
                --_highest;
711 728
              }
712 729
              if (_highest == _sets.back().begin()) {
713 730
                _sets.back().push_front(bucket_num);
714 731
                _dormant[bucket_num] = false;
715 732
                _first[bucket_num] = _last[bucket_num] = INVALID;
716 733
                ++bucket_num;
717 734
              }
718 735
              --_highest;
719 736

	
720 737
              (*_bucket)[n] = *_highest;
721 738
              (*_next)[n] = _first[*_highest];
722 739
              if (_first[*_highest] != INVALID) {
723 740
                (*_prev)[_first[*_highest]] = n;
724 741
              } else {
725 742
                _last[*_highest] = n;
726 743
              }
727 744
              _first[*_highest] = n;
728 745
            }
729 746
          } else {
730 747

	
731 748
            deactivate(n);
732 749
            if (!(*_active)[_first[*_highest]]) {
733 750
              ++_highest;
734 751
              if (_highest != _sets.back().end() &&
735 752
                  !(*_active)[_first[*_highest]]) {
736 753
                _highest = _sets.back().end();
737 754
              }
738 755
            }
739 756
          }
740 757
        }
741 758

	
742 759
        if ((*_excess)[target] < _min_cut) {
743 760
          _min_cut = (*_excess)[target];
744 761
          for (NodeIt i(_graph); i != INVALID; ++i) {
745 762
            (*_min_cut_map)[i] = false;
746 763
          }
747 764
          for (std::list<int>::iterator it = _sets.back().begin();
748 765
               it != _sets.back().end(); ++it) {
749 766
            Node n = _first[*it];
750 767
            while (n != INVALID) {
751 768
              (*_min_cut_map)[n] = true;
752 769
              n = (*_next)[n];
753 770
            }
754 771
          }
755 772
        }
756 773

	
757 774
        {
758 775
          Node new_target;
759 776
          if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
760 777
            if ((*_next)[target] == INVALID) {
761 778
              _last[(*_bucket)[target]] = (*_prev)[target];
762 779
              new_target = (*_prev)[target];
763 780
            } else {
764 781
              (*_prev)[(*_next)[target]] = (*_prev)[target];
765 782
              new_target = (*_next)[target];
766 783
            }
767 784
            if ((*_prev)[target] == INVALID) {
768 785
              _first[(*_bucket)[target]] = (*_next)[target];
769 786
            } else {
770 787
              (*_next)[(*_prev)[target]] = (*_next)[target];
771 788
            }
772 789
          } else {
773 790
            _sets.back().pop_back();
774 791
            if (_sets.back().empty()) {
775 792
              _sets.pop_back();
776 793
              if (_sets.empty())
777 794
                break;
778 795
              for (std::list<int>::iterator it = _sets.back().begin();
779 796
                   it != _sets.back().end(); ++it) {
780 797
                _dormant[*it] = false;
781 798
              }
782 799
            }
783 800
            new_target = _last[_sets.back().back()];
784 801
          }
785 802

	
786 803
          (*_bucket)[target] = 0;
787 804

	
788 805
          (*_source_set)[target] = true;
789 806
          for (InArcIt a(_graph, target); a != INVALID; ++a) {
790 807
            Value rem = (*_capacity)[a] - (*_flow)[a];
791 808
            if (!_tolerance.positive(rem)) continue;
792 809
            Node v = _graph.source(a);
793 810
            if (!(*_active)[v] && !(*_source_set)[v]) {
794 811
              activate(v);
795 812
            }
796 813
            (*_excess)[v] += rem;
797 814
            (*_flow)[a] = (*_capacity)[a];
798 815
          }
799 816

	
800 817
          for (OutArcIt a(_graph, target); a != INVALID; ++a) {
801 818
            Value rem = (*_flow)[a];
802 819
            if (!_tolerance.positive(rem)) continue;
803 820
            Node v = _graph.target(a);
804 821
            if (!(*_active)[v] && !(*_source_set)[v]) {
805 822
              activate(v);
806 823
            }
807 824
            (*_excess)[v] += rem;
808 825
            (*_flow)[a] = 0;
809 826
          }
810 827

	
811 828
          target = new_target;
812 829
          if ((*_active)[target]) {
813 830
            deactivate(target);
814 831
          }
815 832

	
816 833
          _highest = _sets.back().begin();
817 834
          while (_highest != _sets.back().end() &&
818 835
                 !(*_active)[_first[*_highest]]) {
819 836
            ++_highest;
820 837
          }
821 838
        }
822 839
      }
823 840
    }
824 841

	
825 842
  public:
826 843

	
827 844
    /// \name Execution Control
828 845
    /// The simplest way to execute the algorithm is to use
829 846
    /// one of the member functions called \ref run().
830 847
    /// \n
831 848
    /// If you need better control on the execution,
832 849
    /// you have to call one of the \ref init() functions first, then
833 850
    /// \ref calculateOut() and/or \ref calculateIn().
834 851

	
835 852
    /// @{
836 853

	
837 854
    /// \brief Initialize the internal data structures.
838 855
    ///
839 856
    /// This function initializes the internal data structures. It creates
840 857
    /// the maps and some bucket structures for the algorithm.
841 858
    /// The first node is used as the source node for the push-relabel
842 859
    /// algorithm.
843 860
    void init() {
844 861
      init(NodeIt(_graph));
845 862
    }
846 863

	
847 864
    /// \brief Initialize the internal data structures.
848 865
    ///
849 866
    /// This function initializes the internal data structures. It creates
850
    /// the maps and some bucket structures for the algorithm. 
867
    /// the maps and some bucket structures for the algorithm.
851 868
    /// The given node is used as the source node for the push-relabel
852 869
    /// algorithm.
853 870
    void init(const Node& source) {
854 871
      _source = source;
855 872

	
856 873
      _node_num = countNodes(_graph);
857 874

	
858 875
      _first.resize(_node_num);
859 876
      _last.resize(_node_num);
860 877

	
861 878
      _dormant.resize(_node_num);
862 879

	
863 880
      if (!_flow) {
864 881
        _flow = new FlowMap(_graph);
865 882
      }
866 883
      if (!_next) {
867 884
        _next = new typename Digraph::template NodeMap<Node>(_graph);
868 885
      }
869 886
      if (!_prev) {
870 887
        _prev = new typename Digraph::template NodeMap<Node>(_graph);
871 888
      }
872 889
      if (!_active) {
873 890
        _active = new typename Digraph::template NodeMap<bool>(_graph);
874 891
      }
875 892
      if (!_bucket) {
876 893
        _bucket = new typename Digraph::template NodeMap<int>(_graph);
877 894
      }
878 895
      if (!_excess) {
879 896
        _excess = new ExcessMap(_graph);
880 897
      }
881 898
      if (!_source_set) {
882 899
        _source_set = new SourceSetMap(_graph);
883 900
      }
884 901
      if (!_min_cut_map) {
885 902
        _min_cut_map = new MinCutMap(_graph);
886 903
      }
887 904

	
888 905
      _min_cut = std::numeric_limits<Value>::max();
889 906
    }
890 907

	
891 908

	
892 909
    /// \brief Calculate a minimum cut with \f$ source \f$ on the
893 910
    /// source-side.
894 911
    ///
895 912
    /// This function calculates a minimum cut with \f$ source \f$ on the
896 913
    /// source-side (i.e. a set \f$ X\subsetneq V \f$ with
897 914
    /// \f$ source \in X \f$ and minimal outgoing capacity).
898 915
    ///
899 916
    /// \pre \ref init() must be called before using this function.
900 917
    void calculateOut() {
901 918
      findMinCutOut();
902 919
    }
903 920

	
904 921
    /// \brief Calculate a minimum cut with \f$ source \f$ on the
905 922
    /// sink-side.
906 923
    ///
907 924
    /// This function calculates a minimum cut with \f$ source \f$ on the
908 925
    /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with
909 926
    /// \f$ source \notin X \f$ and minimal outgoing capacity).
910 927
    ///
911 928
    /// \pre \ref init() must be called before using this function.
912 929
    void calculateIn() {
913 930
      findMinCutIn();
914 931
    }
915 932

	
916 933

	
917 934
    /// \brief Run the algorithm.
918 935
    ///
919 936
    /// This function runs the algorithm. It finds nodes \c source and
920 937
    /// \c target arbitrarily and then calls \ref init(), \ref calculateOut()
921 938
    /// and \ref calculateIn().
922 939
    void run() {
923 940
      init();
924 941
      calculateOut();
925 942
      calculateIn();
926 943
    }
927 944

	
928 945
    /// \brief Run the algorithm.
929 946
    ///
930
    /// This function runs the algorithm. It uses the given \c source node, 
947
    /// This function runs the algorithm. It uses the given \c source node,
931 948
    /// finds a proper \c target node and then calls the \ref init(),
932 949
    /// \ref calculateOut() and \ref calculateIn().
933 950
    void run(const Node& s) {
934 951
      init(s);
935 952
      calculateOut();
936 953
      calculateIn();
937 954
    }
938 955

	
939 956
    /// @}
940 957

	
941 958
    /// \name Query Functions
942 959
    /// The result of the %HaoOrlin algorithm
943 960
    /// can be obtained using these functions.\n
944
    /// \ref run(), \ref calculateOut() or \ref calculateIn() 
961
    /// \ref run(), \ref calculateOut() or \ref calculateIn()
945 962
    /// should be called before using them.
946 963

	
947 964
    /// @{
948 965

	
949 966
    /// \brief Return the value of the minimum cut.
950 967
    ///
951 968
    /// This function returns the value of the minimum cut.
952 969
    ///
953
    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 
970
    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
954 971
    /// must be called before using this function.
955 972
    Value minCutValue() const {
956 973
      return _min_cut;
957 974
    }
958 975

	
959 976

	
960 977
    /// \brief Return a minimum cut.
961 978
    ///
962 979
    /// This function sets \c cutMap to the characteristic vector of a
963 980
    /// minimum value cut: it will give a non-empty set \f$ X\subsetneq V \f$
964 981
    /// with minimal outgoing capacity (i.e. \c cutMap will be \c true exactly
965 982
    /// for the nodes of \f$ X \f$).
966 983
    ///
967 984
    /// \param cutMap A \ref concepts::WriteMap "writable" node map with
968 985
    /// \c bool (or convertible) value type.
969 986
    ///
970 987
    /// \return The value of the minimum cut.
971 988
    ///
972
    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn() 
989
    /// \pre \ref run(), \ref calculateOut() or \ref calculateIn()
973 990
    /// must be called before using this function.
974 991
    template <typename CutMap>
975 992
    Value minCutMap(CutMap& cutMap) const {
976 993
      for (NodeIt it(_graph); it != INVALID; ++it) {
977 994
        cutMap.set(it, (*_min_cut_map)[it]);
978 995
      }
979 996
      return _min_cut;
980 997
    }
981 998

	
982 999
    /// @}
983 1000

	
984 1001
  }; //class HaoOrlin
985 1002

	
986 1003
} //namespace lemon
987 1004

	
988 1005
#endif //LEMON_HAO_ORLIN_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 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 HYPERCUBE_GRAPH_H
20 20
#define HYPERCUBE_GRAPH_H
21 21

	
22 22
#include <vector>
23 23
#include <lemon/core.h>
24 24
#include <lemon/assert.h>
25 25
#include <lemon/bits/graph_extender.h>
26 26

	
27 27
///\ingroup graphs
28 28
///\file
29 29
///\brief HypercubeGraph class.
30 30

	
31 31
namespace lemon {
32 32

	
33 33
  class HypercubeGraphBase {
34 34

	
35 35
  public:
36 36

	
37 37
    typedef HypercubeGraphBase Graph;
38 38

	
39 39
    class Node;
40 40
    class Edge;
41 41
    class Arc;
42 42

	
43 43
  public:
44 44

	
45 45
    HypercubeGraphBase() {}
46 46

	
47 47
  protected:
48 48

	
49 49
    void construct(int dim) {
50 50
      LEMON_ASSERT(dim >= 1, "The number of dimensions must be at least 1.");
51 51
      _dim = dim;
52 52
      _node_num = 1 << dim;
53 53
      _edge_num = dim * (1 << (dim-1));
54 54
    }
55 55

	
56 56
  public:
57 57

	
58 58
    typedef True NodeNumTag;
59 59
    typedef True EdgeNumTag;
60 60
    typedef True ArcNumTag;
61 61

	
62 62
    int nodeNum() const { return _node_num; }
63 63
    int edgeNum() const { return _edge_num; }
64 64
    int arcNum() const { return 2 * _edge_num; }
65 65

	
66 66
    int maxNodeId() const { return _node_num - 1; }
67 67
    int maxEdgeId() const { return _edge_num - 1; }
68 68
    int maxArcId() const { return 2 * _edge_num - 1; }
69 69

	
70 70
    static Node nodeFromId(int id) { return Node(id); }
71 71
    static Edge edgeFromId(int id) { return Edge(id); }
72 72
    static Arc arcFromId(int id) { return Arc(id); }
73 73

	
74 74
    static int id(Node node) { return node._id; }
75 75
    static int id(Edge edge) { return edge._id; }
76 76
    static int id(Arc arc) { return arc._id; }
77 77

	
78 78
    Node u(Edge edge) const {
79 79
      int base = edge._id & ((1 << (_dim-1)) - 1);
80 80
      int k = edge._id >> (_dim-1);
81 81
      return ((base >> k) << (k+1)) | (base & ((1 << k) - 1));
82 82
    }
83 83

	
84 84
    Node v(Edge edge) const {
85 85
      int base = edge._id & ((1 << (_dim-1)) - 1);
86 86
      int k = edge._id >> (_dim-1);
87 87
      return ((base >> k) << (k+1)) | (base & ((1 << k) - 1)) | (1 << k);
88 88
    }
89 89

	
90 90
    Node source(Arc arc) const {
91 91
      return (arc._id & 1) == 1 ? u(arc) : v(arc);
92 92
    }
93 93

	
94 94
    Node target(Arc arc) const {
95 95
      return (arc._id & 1) == 1 ? v(arc) : u(arc);
96 96
    }
97 97

	
98 98
    typedef True FindEdgeTag;
99 99
    typedef True FindArcTag;
100 100

	
101 101
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
102 102
      if (prev != INVALID) return INVALID;
103 103
      int d = u._id ^ v._id;
104 104
      int k = 0;
105 105
      if (d == 0) return INVALID;
106 106
      for ( ; (d & 1) == 0; d >>= 1) ++k;
107 107
      if (d >> 1 != 0) return INVALID;
108 108
      return (k << (_dim-1)) | ((u._id >> (k+1)) << k) |
109 109
        (u._id & ((1 << k) - 1));
110 110
    }
111 111

	
112 112
    Arc findArc(Node u, Node v, Arc prev = INVALID) const {
113 113
      Edge edge = findEdge(u, v, prev);
114 114
      if (edge == INVALID) return INVALID;
115 115
      int k = edge._id >> (_dim-1);
116 116
      return ((u._id >> k) & 1) == 1 ? edge._id << 1 : (edge._id << 1) | 1;
117 117
    }
118 118

	
119 119
    class Node {
120 120
      friend class HypercubeGraphBase;
121 121

	
122 122
    protected:
123 123
      int _id;
124 124
      Node(int id) : _id(id) {}
125 125
    public:
126 126
      Node() {}
127 127
      Node (Invalid) : _id(-1) {}
128 128
      bool operator==(const Node node) const {return _id == node._id;}
129 129
      bool operator!=(const Node node) const {return _id != node._id;}
130 130
      bool operator<(const Node node) const {return _id < node._id;}
131 131
    };
132 132

	
133 133
    class Edge {
134 134
      friend class HypercubeGraphBase;
135 135
      friend class Arc;
136 136

	
137 137
    protected:
138 138
      int _id;
139 139

	
140 140
      Edge(int id) : _id(id) {}
141 141

	
142 142
    public:
143 143
      Edge() {}
144 144
      Edge (Invalid) : _id(-1) {}
145 145
      bool operator==(const Edge edge) const {return _id == edge._id;}
146 146
      bool operator!=(const Edge edge) const {return _id != edge._id;}
147 147
      bool operator<(const Edge edge) const {return _id < edge._id;}
148 148
    };
149 149

	
150 150
    class Arc {
151 151
      friend class HypercubeGraphBase;
152 152

	
153 153
    protected:
154 154
      int _id;
155 155

	
156 156
      Arc(int id) : _id(id) {}
157 157

	
158 158
    public:
159 159
      Arc() {}
160 160
      Arc (Invalid) : _id(-1) {}
161 161
      operator Edge() const { return _id != -1 ? Edge(_id >> 1) : INVALID; }
162 162
      bool operator==(const Arc arc) const {return _id == arc._id;}
163 163
      bool operator!=(const Arc arc) const {return _id != arc._id;}
164 164
      bool operator<(const Arc arc) const {return _id < arc._id;}
165 165
    };
166 166

	
167 167
    void first(Node& node) const {
168 168
      node._id = _node_num - 1;
169 169
    }
170 170

	
171 171
    static void next(Node& node) {
172 172
      --node._id;
173 173
    }
174 174

	
175 175
    void first(Edge& edge) const {
176 176
      edge._id = _edge_num - 1;
177 177
    }
178 178

	
179 179
    static void next(Edge& edge) {
180 180
      --edge._id;
181 181
    }
182 182

	
183 183
    void first(Arc& arc) const {
184 184
      arc._id = 2 * _edge_num - 1;
185 185
    }
186 186

	
187 187
    static void next(Arc& arc) {
188 188
      --arc._id;
189 189
    }
190 190

	
191 191
    void firstInc(Edge& edge, bool& dir, const Node& node) const {
192 192
      edge._id = node._id >> 1;
193 193
      dir = (node._id & 1) == 0;
194 194
    }
195 195

	
196 196
    void nextInc(Edge& edge, bool& dir) const {
197 197
      Node n = dir ? u(edge) : v(edge);
198 198
      int k = (edge._id >> (_dim-1)) + 1;
199 199
      if (k < _dim) {
200 200
        edge._id = (k << (_dim-1)) |
201 201
          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
202 202
        dir = ((n._id >> k) & 1) == 0;
203 203
      } else {
204 204
        edge._id = -1;
205 205
        dir = true;
206 206
      }
207 207
    }
208 208

	
209 209
    void firstOut(Arc& arc, const Node& node) const {
210 210
      arc._id = ((node._id >> 1) << 1) | (~node._id & 1);
211 211
    }
212 212

	
213 213
    void nextOut(Arc& arc) const {
214 214
      Node n = (arc._id & 1) == 1 ? u(arc) : v(arc);
215 215
      int k = (arc._id >> _dim) + 1;
216 216
      if (k < _dim) {
217 217
        arc._id = (k << (_dim-1)) |
218 218
          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
219 219
        arc._id = (arc._id << 1) | (~(n._id >> k) & 1);
220 220
      } else {
221 221
        arc._id = -1;
222 222
      }
223 223
    }
224 224

	
225 225
    void firstIn(Arc& arc, const Node& node) const {
226 226
      arc._id = ((node._id >> 1) << 1) | (node._id & 1);
227 227
    }
228 228

	
229 229
    void nextIn(Arc& arc) const {
230 230
      Node n = (arc._id & 1) == 1 ? v(arc) : u(arc);
231 231
      int k = (arc._id >> _dim) + 1;
232 232
      if (k < _dim) {
233 233
        arc._id = (k << (_dim-1)) |
234 234
          ((n._id >> (k+1)) << k) | (n._id & ((1 << k) - 1));
235 235
        arc._id = (arc._id << 1) | ((n._id >> k) & 1);
236 236
      } else {
237 237
        arc._id = -1;
238 238
      }
239 239
    }
240 240

	
241 241
    static bool direction(Arc arc) {
242 242
      return (arc._id & 1) == 1;
243 243
    }
244 244

	
245 245
    static Arc direct(Edge edge, bool dir) {
246 246
      return Arc((edge._id << 1) | (dir ? 1 : 0));
247 247
    }
248 248

	
249 249
    int dimension() const {
250 250
      return _dim;
251 251
    }
252 252

	
253 253
    bool projection(Node node, int n) const {
254 254
      return static_cast<bool>(node._id & (1 << n));
255 255
    }
256 256

	
257 257
    int dimension(Edge edge) const {
258 258
      return edge._id >> (_dim-1);
259 259
    }
260 260

	
261 261
    int dimension(Arc arc) const {
262 262
      return arc._id >> _dim;
263 263
    }
264 264

	
265
    int index(Node node) const {
265
    static int index(Node node) {
266 266
      return node._id;
267 267
    }
268 268

	
269 269
    Node operator()(int ix) const {
270 270
      return Node(ix);
271 271
    }
272 272

	
273 273
  private:
274 274
    int _dim;
275 275
    int _node_num, _edge_num;
276 276
  };
277 277

	
278 278

	
279 279
  typedef GraphExtender<HypercubeGraphBase> ExtendedHypercubeGraphBase;
280 280

	
281 281
  /// \ingroup graphs
282 282
  ///
283 283
  /// \brief Hypercube graph class
284 284
  ///
285
  /// This class implements a special graph type. The nodes of the graph
286
  /// are indiced with integers with at most \c dim binary digits.
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 287
  /// Two nodes are connected in the graph if and only if their indices
288 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
  /// This class provides constant time counting for nodes, edges and arcs.
289 298
  ///
290 299
  /// \note The type of the indices is chosen to \c int for efficiency
291 300
  /// reasons. Thus the maximum dimension of this implementation is 26
292 301
  /// (assuming that the size of \c int is 32 bit).
293
  ///
294
  /// This graph type fully conforms to the \ref concepts::Graph
295
  /// "Graph concept".
296 302
  class HypercubeGraph : public ExtendedHypercubeGraphBase {
297 303
    typedef ExtendedHypercubeGraphBase Parent;
298 304

	
299 305
  public:
300 306

	
301 307
    /// \brief Constructs a hypercube graph with \c dim dimensions.
302 308
    ///
303 309
    /// Constructs a hypercube graph with \c dim dimensions.
304 310
    HypercubeGraph(int dim) { construct(dim); }
305 311

	
312
    /// \brief Resizes the graph
313
    ///
314
    /// This function resizes the graph. It fully destroys and
315
    /// rebuilds the structure, therefore the maps of the graph will be
316
    /// reallocated automatically and the previous values will be lost.
317
    void resize(int dim) {
318
      Parent::notifier(Arc()).clear();
319
      Parent::notifier(Edge()).clear();
320
      Parent::notifier(Node()).clear();
321
      construct(dim);
322
      Parent::notifier(Node()).build();
323
      Parent::notifier(Edge()).build();
324
      Parent::notifier(Arc()).build();
325
    }
326

	
306 327
    /// \brief The number of dimensions.
307 328
    ///
308 329
    /// Gives back the number of dimensions.
309 330
    int dimension() const {
310 331
      return Parent::dimension();
311 332
    }
312 333

	
313 334
    /// \brief Returns \c true if the n'th bit of the node is one.
314 335
    ///
315 336
    /// Returns \c true if the n'th bit of the node is one.
316 337
    bool projection(Node node, int n) const {
317 338
      return Parent::projection(node, n);
318 339
    }
319 340

	
320 341
    /// \brief The dimension id of an edge.
321 342
    ///
322 343
    /// Gives back the dimension id of the given edge.
323
    /// It is in the [0..dim-1] range.
344
    /// It is in the range <tt>[0..dim-1]</tt>.
324 345
    int dimension(Edge edge) const {
325 346
      return Parent::dimension(edge);
326 347
    }
327 348

	
328 349
    /// \brief The dimension id of an arc.
329 350
    ///
330 351
    /// Gives back the dimension id of the given arc.
331
    /// It is in the [0..dim-1] range.
352
    /// It is in the range <tt>[0..dim-1]</tt>.
332 353
    int dimension(Arc arc) const {
333 354
      return Parent::dimension(arc);
334 355
    }
335 356

	
336 357
    /// \brief The index of a node.
337 358
    ///
338 359
    /// Gives back the index of the given node.
339 360
    /// The lower bits of the integer describes the node.
340
    int index(Node node) const {
361
    static int index(Node node) {
341 362
      return Parent::index(node);
342 363
    }
343 364

	
344 365
    /// \brief Gives back a node by its index.
345 366
    ///
346 367
    /// Gives back a node by its index.
347 368
    Node operator()(int ix) const {
348 369
      return Parent::operator()(ix);
349 370
    }
350 371

	
351 372
    /// \brief Number of nodes.
352 373
    int nodeNum() const { return Parent::nodeNum(); }
353 374
    /// \brief Number of edges.
354 375
    int edgeNum() const { return Parent::edgeNum(); }
355 376
    /// \brief Number of arcs.
356 377
    int arcNum() const { return Parent::arcNum(); }
357 378

	
358 379
    /// \brief Linear combination map.
359 380
    ///
360 381
    /// This map makes possible to give back a linear combination
361 382
    /// for each node. It works like the \c std::accumulate function,
362 383
    /// so it accumulates the \c bf binary function with the \c fv first
363 384
    /// value. The map accumulates only on that positions (dimensions)
364 385
    /// where the index of the node is one. The values that have to be
365 386
    /// accumulated should be given by the \c begin and \c end iterators
366 387
    /// and the length of this range should be equal to the dimension
367 388
    /// number of the graph.
368 389
    ///
369 390
    ///\code
370 391
    /// const int DIM = 3;
371 392
    /// HypercubeGraph graph(DIM);
372 393
    /// dim2::Point<double> base[DIM];
373 394
    /// for (int k = 0; k < DIM; ++k) {
374 395
    ///   base[k].x = rnd();
375 396
    ///   base[k].y = rnd();
376 397
    /// }
377 398
    /// HypercubeGraph::HyperMap<dim2::Point<double> >
378 399
    ///   pos(graph, base, base + DIM, dim2::Point<double>(0.0, 0.0));
379 400
    ///\endcode
380 401
    ///
381 402
    /// \see HypercubeGraph
382 403
    template <typename T, typename BF = std::plus<T> >
383 404
    class HyperMap {
384 405
    public:
385 406

	
386 407
      /// \brief The key type of the map
387 408
      typedef Node Key;
388 409
      /// \brief The value type of the map
389 410
      typedef T Value;
390 411

	
391 412
      /// \brief Constructor for HyperMap.
392 413
      ///
393 414
      /// Construct a HyperMap for the given graph. The values that have
394 415
      /// to be accumulated should be given by the \c begin and \c end
395 416
      /// iterators and the length of this range should be equal to the
396 417
      /// dimension number of the graph.
397 418
      ///
398 419
      /// This map accumulates the \c bf binary function with the \c fv
399 420
      /// first value on that positions (dimensions) where the index of
400 421
      /// the node is one.
401 422
      template <typename It>
402 423
      HyperMap(const Graph& graph, It begin, It end,
403 424
               T fv = 0, const BF& bf = BF())
404 425
        : _graph(graph), _values(begin, end), _first_value(fv), _bin_func(bf)
405 426
      {
406 427
        LEMON_ASSERT(_values.size() == graph.dimension(),
407 428
                     "Wrong size of range");
408 429
      }
409 430

	
410 431
      /// \brief The partial accumulated value.
411 432
      ///
412 433
      /// Gives back the partial accumulated value.
413 434
      Value operator[](const Key& k) const {
414 435
        Value val = _first_value;
415 436
        int id = _graph.index(k);
416 437
        int n = 0;
417 438
        while (id != 0) {
418 439
          if (id & 1) {
419 440
            val = _bin_func(val, _values[n]);
420 441
          }
421 442
          id >>= 1;
422 443
          ++n;
423 444
        }
424 445
        return val;
425 446
      }
426 447

	
427 448
    private:
428 449
      const Graph& _graph;
429 450
      std::vector<T> _values;
430 451
      T _first_value;
431 452
      BF _bin_func;
432 453
    };
433 454

	
434 455
  };
435 456

	
436 457
}
437 458

	
438 459
#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-2011
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 104
    template <typename _GR, bool _dir, typename _Map,
105 105
              typename _Converter = DefaultConverter<typename _Map::Value> >
106 106
    class GraphArcMapStorage : public MapStorageBase<typename _GR::Edge> {
107 107
    public:
108 108
      typedef _Map Map;
109 109
      typedef _Converter Converter;
110 110
      typedef _GR GR;
111 111
      typedef typename GR::Edge Item;
112 112
      static const bool dir = _dir;
113 113

	
114 114
    private:
115 115
      const GR& _graph;
116 116
      Map& _map;
117 117
      Converter _converter;
118 118

	
119 119
    public:
120 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 176
    template <typename GR>
177 177
    struct GraphArcLookUpConverter {
178 178
      const GR& _graph;
179 179
      const std::map<std::string, typename GR::Edge>& _map;
180 180

	
181 181
      GraphArcLookUpConverter(const GR& graph,
182 182
                              const std::map<std::string,
183 183
                                             typename GR::Edge>& map)
184 184
        : _graph(graph), _map(map) {}
185 185

	
186 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 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 390
  template <typename DGR>
391 391
  class DigraphReader;
392 392

	
393 393
  template <typename TDGR>
394 394
  DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is = std::cin);
395 395
  template <typename TDGR>
396 396
  DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn);
397 397
  template <typename TDGR>
398 398
  DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
399 399

	
400 400
  /// \ingroup lemon_io
401 401
  ///
402 402
  /// \brief \ref lgf-format "LGF" reader for directed graphs
403 403
  ///
404 404
  /// This utility reads an \ref lgf-format "LGF" file.
405 405
  ///
406 406
  /// The reading method does a batch processing. The user creates a
407 407
  /// reader object, then various reading rules can be added to the
408 408
  /// reader, and eventually the reading is executed with the \c run()
409 409
  /// member function. A map reading rule can be added to the reader
410 410
  /// with the \c nodeMap() or \c arcMap() members. An optional
411 411
  /// converter parameter can also be added as a standard functor
412 412
  /// converting from \c std::string to the value type of the map. If it
413 413
  /// is set, it will determine how the tokens in the file should be
414 414
  /// converted to the value type of the map. If the functor is not set,
415 415
  /// then a default conversion will be used. One map can be read into
416 416
  /// multiple map objects at the same time. The \c attribute(), \c
417 417
  /// node() and \c arc() functions are used to add attribute reading
418 418
  /// rules.
419 419
  ///
420 420
  ///\code
421 421
  /// DigraphReader<DGR>(digraph, std::cin).
422 422
  ///   nodeMap("coordinates", coord_map).
423 423
  ///   arcMap("capacity", cap_map).
424 424
  ///   node("source", src).
425 425
  ///   node("target", trg).
426 426
  ///   attribute("caption", caption).
427 427
  ///   run();
428 428
  ///\endcode
429 429
  ///
430
  /// By default the reader uses the first section in the file of the
430
  /// By default, the reader uses the first section in the file of the
431 431
  /// proper type. If a section has an optional name, then it can be
432 432
  /// selected for reading by giving an optional name parameter to the
433 433
  /// \c nodes(), \c arcs() or \c attributes() functions.
434 434
  ///
435 435
  /// The \c useNodes() and \c useArcs() functions are used to tell the reader
436 436
  /// that the nodes or arcs should not be constructed (added to the
437 437
  /// graph) during the reading, but instead the label map of the items
438 438
  /// are given as a parameter of these functions. An
439 439
  /// application of these functions is multipass reading, which is
440 440
  /// important if two \c \@arcs sections must be read from the
441 441
  /// file. In this case the first phase would read the node set and one
442 442
  /// of the arc sets, while the second phase would read the second arc
443 443
  /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
444 444
  /// The previously read label node map should be passed to the \c
445 445
  /// useNodes() functions. Another application of multipass reading when
446 446
  /// paths are given as a node map or an arc map.
447 447
  /// It is impossible to read this in
448 448
  /// a single pass, because the arcs are not constructed when the node
449 449
  /// maps are read.
450 450
  template <typename DGR>
451 451
  class DigraphReader {
452 452
  public:
453 453

	
454 454
    typedef DGR Digraph;
455 455

	
456 456
  private:
457 457

	
458 458
    TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
459 459

	
460 460
    std::istream* _is;
461 461
    bool local_is;
462 462
    std::string _filename;
463 463

	
464 464
    DGR& _digraph;
465 465

	
466 466
    std::string _nodes_caption;
467 467
    std::string _arcs_caption;
468 468
    std::string _attributes_caption;
469 469

	
470 470
    typedef std::map<std::string, Node> NodeIndex;
471 471
    NodeIndex _node_index;
472 472
    typedef std::map<std::string, Arc> ArcIndex;
473 473
    ArcIndex _arc_index;
474 474

	
475 475
    typedef std::vector<std::pair<std::string,
476 476
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
477 477
    NodeMaps _node_maps;
478 478

	
479 479
    typedef std::vector<std::pair<std::string,
480 480
      _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
481 481
    ArcMaps _arc_maps;
482 482

	
483 483
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
484 484
      Attributes;
485 485
    Attributes _attributes;
486 486

	
487 487
    bool _use_nodes;
488 488
    bool _use_arcs;
489 489

	
490 490
    bool _skip_nodes;
491 491
    bool _skip_arcs;
492 492

	
493 493
    int line_num;
494 494
    std::istringstream line;
495 495

	
496 496
  public:
497 497

	
498 498
    /// \brief Constructor
499 499
    ///
500 500
    /// Construct a directed graph reader, which reads from the given
501 501
    /// input stream.
502 502
    DigraphReader(DGR& digraph, std::istream& is = std::cin)
503 503
      : _is(&is), local_is(false), _digraph(digraph),
504 504
        _use_nodes(false), _use_arcs(false),
505 505
        _skip_nodes(false), _skip_arcs(false) {}
506 506

	
507 507
    /// \brief Constructor
508 508
    ///
509 509
    /// Construct a directed graph reader, which reads from the given
510 510
    /// file.
511 511
    DigraphReader(DGR& digraph, const std::string& fn)
512 512
      : _is(new std::ifstream(fn.c_str())), local_is(true),
513 513
        _filename(fn), _digraph(digraph),
514 514
        _use_nodes(false), _use_arcs(false),
515 515
        _skip_nodes(false), _skip_arcs(false) {
516 516
      if (!(*_is)) {
517 517
        delete _is;
518 518
        throw IoError("Cannot open file", fn);
519 519
      }
520 520
    }
521 521

	
522 522
    /// \brief Constructor
523 523
    ///
524 524
    /// Construct a directed graph reader, which reads from the given
525 525
    /// file.
526 526
    DigraphReader(DGR& digraph, const char* fn)
527 527
      : _is(new std::ifstream(fn)), local_is(true),
528 528
        _filename(fn), _digraph(digraph),
529 529
        _use_nodes(false), _use_arcs(false),
530 530
        _skip_nodes(false), _skip_arcs(false) {
531 531
      if (!(*_is)) {
532 532
        delete _is;
533 533
        throw IoError("Cannot open file", fn);
534 534
      }
535 535
    }
536 536

	
537 537
    /// \brief Destructor
538 538
    ~DigraphReader() {
539 539
      for (typename NodeMaps::iterator it = _node_maps.begin();
540 540
           it != _node_maps.end(); ++it) {
541 541
        delete it->second;
542 542
      }
543 543

	
544 544
      for (typename ArcMaps::iterator it = _arc_maps.begin();
545 545
           it != _arc_maps.end(); ++it) {
546 546
        delete it->second;
547 547
      }
548 548

	
549 549
      for (typename Attributes::iterator it = _attributes.begin();
550 550
           it != _attributes.end(); ++it) {
551 551
        delete it->second;
552 552
      }
553 553

	
554 554
      if (local_is) {
555 555
        delete _is;
556 556
      }
557 557

	
558 558
    }
559 559

	
560 560
  private:
561 561

	
562 562
    template <typename TDGR>
563 563
    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is);
564 564
    template <typename TDGR>
565
    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, 
565
    friend DigraphReader<TDGR> digraphReader(TDGR& digraph,
566 566
                                             const std::string& fn);
567 567
    template <typename TDGR>
568 568
    friend DigraphReader<TDGR> digraphReader(TDGR& digraph, const char *fn);
569 569

	
570 570
    DigraphReader(DigraphReader& other)
571 571
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
572 572
        _use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
573 573
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
574 574

	
575 575
      other._is = 0;
576 576
      other.local_is = false;
577 577

	
578 578
      _node_index.swap(other._node_index);
579 579
      _arc_index.swap(other._arc_index);
580 580

	
581 581
      _node_maps.swap(other._node_maps);
582 582
      _arc_maps.swap(other._arc_maps);
583 583
      _attributes.swap(other._attributes);
584 584

	
585 585
      _nodes_caption = other._nodes_caption;
586 586
      _arcs_caption = other._arcs_caption;
587 587
      _attributes_caption = other._attributes_caption;
588 588

	
589 589
    }
590 590

	
591 591
    DigraphReader& operator=(const DigraphReader&);
592 592

	
593 593
  public:
594 594

	
595 595
    /// \name Reading Rules
596 596
    /// @{
597 597

	
598 598
    /// \brief Node map reading rule
599 599
    ///
600 600
    /// Add a node map reading rule to the reader.
601 601
    template <typename Map>
602 602
    DigraphReader& nodeMap(const std::string& caption, Map& map) {
603 603
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
604 604
      _reader_bits::MapStorageBase<Node>* storage =
605 605
        new _reader_bits::MapStorage<Node, Map>(map);
606 606
      _node_maps.push_back(std::make_pair(caption, storage));
607 607
      return *this;
608 608
    }
609 609

	
610 610
    /// \brief Node map reading rule
611 611
    ///
612 612
    /// Add a node map reading rule with specialized converter to the
613 613
    /// reader.
614 614
    template <typename Map, typename Converter>
615 615
    DigraphReader& nodeMap(const std::string& caption, Map& map,
616 616
                           const Converter& converter = Converter()) {
617 617
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
618 618
      _reader_bits::MapStorageBase<Node>* storage =
619 619
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
620 620
      _node_maps.push_back(std::make_pair(caption, storage));
621 621
      return *this;
622 622
    }
623 623

	
624 624
    /// \brief Arc map reading rule
625 625
    ///
626 626
    /// Add an arc map reading rule to the reader.
627 627
    template <typename Map>
628 628
    DigraphReader& arcMap(const std::string& caption, Map& map) {
629 629
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
630 630
      _reader_bits::MapStorageBase<Arc>* storage =
631 631
        new _reader_bits::MapStorage<Arc, Map>(map);
632 632
      _arc_maps.push_back(std::make_pair(caption, storage));
633 633
      return *this;
634 634
    }
635 635

	
636 636
    /// \brief Arc map reading rule
637 637
    ///
638 638
    /// Add an arc map reading rule with specialized converter to the
639 639
    /// reader.
640 640
    template <typename Map, typename Converter>
641 641
    DigraphReader& arcMap(const std::string& caption, Map& map,
642 642
                          const Converter& converter = Converter()) {
643 643
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
644 644
      _reader_bits::MapStorageBase<Arc>* storage =
645 645
        new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
646 646
      _arc_maps.push_back(std::make_pair(caption, storage));
647 647
      return *this;
648 648
    }
649 649

	
650 650
    /// \brief Attribute reading rule
651 651
    ///
652 652
    /// Add an attribute reading rule to the reader.
653 653
    template <typename Value>
654 654
    DigraphReader& attribute(const std::string& caption, Value& value) {
655 655
      _reader_bits::ValueStorageBase* storage =
656 656
        new _reader_bits::ValueStorage<Value>(value);
657 657
      _attributes.insert(std::make_pair(caption, storage));
658 658
      return *this;
659 659
    }
660 660

	
661 661
    /// \brief Attribute reading rule
662 662
    ///
663 663
    /// Add an attribute reading rule with specialized converter to the
664 664
    /// reader.
665 665
    template <typename Value, typename Converter>
666 666
    DigraphReader& attribute(const std::string& caption, Value& value,
667 667
                             const Converter& converter = Converter()) {
668 668
      _reader_bits::ValueStorageBase* storage =
669 669
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
670 670
      _attributes.insert(std::make_pair(caption, storage));
671 671
      return *this;
672 672
    }
673 673

	
674 674
    /// \brief Node reading rule
675 675
    ///
676 676
    /// Add a node reading rule to reader.
677 677
    DigraphReader& node(const std::string& caption, Node& node) {
678 678
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
679 679
      Converter converter(_node_index);
680 680
      _reader_bits::ValueStorageBase* storage =
681 681
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
682 682
      _attributes.insert(std::make_pair(caption, storage));
683 683
      return *this;
684 684
    }
685 685

	
686 686
    /// \brief Arc reading rule
687 687
    ///
688 688
    /// Add an arc reading rule to reader.
689 689
    DigraphReader& arc(const std::string& caption, Arc& arc) {
690 690
      typedef _reader_bits::MapLookUpConverter<Arc> Converter;
691 691
      Converter converter(_arc_index);
692 692
      _reader_bits::ValueStorageBase* storage =
693 693
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
694 694
      _attributes.insert(std::make_pair(caption, storage));
695 695
      return *this;
696 696
    }
697 697

	
698 698
    /// @}
699 699

	
700 700
    /// \name Select Section by Name
701 701
    /// @{
702 702

	
703 703
    /// \brief Set \c \@nodes section to be read
704 704
    ///
705 705
    /// Set \c \@nodes section to be read
706 706
    DigraphReader& nodes(const std::string& caption) {
707 707
      _nodes_caption = caption;
708 708
      return *this;
709 709
    }
710 710

	
711 711
    /// \brief Set \c \@arcs section to be read
712 712
    ///
713 713
    /// Set \c \@arcs section to be read
714 714
    DigraphReader& arcs(const std::string& caption) {
715 715
      _arcs_caption = caption;
716 716
      return *this;
717 717
    }
718 718

	
719 719
    /// \brief Set \c \@attributes section to be read
720 720
    ///
721 721
    /// Set \c \@attributes section to be read
722 722
    DigraphReader& attributes(const std::string& caption) {
723 723
      _attributes_caption = caption;
724 724
      return *this;
725 725
    }
726 726

	
727 727
    /// @}
728 728

	
729 729
    /// \name Using Previously Constructed Node or Arc Set
730 730
    /// @{
731 731

	
732 732
    /// \brief Use previously constructed node set
733 733
    ///
734 734
    /// Use previously constructed node set, and specify the node
735 735
    /// label map.
736 736
    template <typename Map>
737 737
    DigraphReader& useNodes(const Map& map) {
738 738
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
739 739
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
740 740
      _use_nodes = true;
741 741
      _writer_bits::DefaultConverter<typename Map::Value> converter;
742 742
      for (NodeIt n(_digraph); n != INVALID; ++n) {
743 743
        _node_index.insert(std::make_pair(converter(map[n]), n));
744 744
      }
745 745
      return *this;
746 746
    }
747 747

	
748 748
    /// \brief Use previously constructed node set
749 749
    ///
750 750
    /// Use previously constructed node set, and specify the node
751 751
    /// label map and a functor which converts the label map values to
752 752
    /// \c std::string.
753 753
    template <typename Map, typename Converter>
754 754
    DigraphReader& useNodes(const Map& map,
755 755
                            const Converter& converter = Converter()) {
756 756
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
757 757
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
758 758
      _use_nodes = true;
759 759
      for (NodeIt n(_digraph); n != INVALID; ++n) {
760 760
        _node_index.insert(std::make_pair(converter(map[n]), n));
761 761
      }
762 762
      return *this;
763 763
    }
764 764

	
765 765
    /// \brief Use previously constructed arc set
766 766
    ///
767 767
    /// Use previously constructed arc set, and specify the arc
768 768
    /// label map.
769 769
    template <typename Map>
770 770
    DigraphReader& useArcs(const Map& map) {
771 771
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
772 772
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
773 773
      _use_arcs = true;
774 774
      _writer_bits::DefaultConverter<typename Map::Value> converter;
775 775
      for (ArcIt a(_digraph); a != INVALID; ++a) {
776 776
        _arc_index.insert(std::make_pair(converter(map[a]), a));
777 777
      }
778 778
      return *this;
779 779
    }
780 780

	
781 781
    /// \brief Use previously constructed arc set
782 782
    ///
783 783
    /// Use previously constructed arc set, and specify the arc
784 784
    /// label map and a functor which converts the label map values to
785 785
    /// \c std::string.
786 786
    template <typename Map, typename Converter>
787 787
    DigraphReader& useArcs(const Map& map,
788 788
                           const Converter& converter = Converter()) {
789 789
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
790 790
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
791 791
      _use_arcs = true;
792 792
      for (ArcIt a(_digraph); a != INVALID; ++a) {
793 793
        _arc_index.insert(std::make_pair(converter(map[a]), a));
794 794
      }
795 795
      return *this;
796 796
    }
797 797

	
798 798
    /// \brief Skips the reading of node section
799 799
    ///
800 800
    /// Omit the reading of the node section. This implies that each node
801 801
    /// map reading rule will be abandoned, and the nodes of the graph
802 802
    /// will not be constructed, which usually cause that the arc set
803 803
    /// could not be read due to lack of node name resolving.
804 804
    /// Therefore \c skipArcs() function should also be used, or
805 805
    /// \c useNodes() should be used to specify the label of the nodes.
806 806
    DigraphReader& skipNodes() {
807 807
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
808 808
      _skip_nodes = true;
809 809
      return *this;
810 810
    }
811 811

	
812 812
    /// \brief Skips the reading of arc section
813 813
    ///
814 814
    /// Omit the reading of the arc section. This implies that each arc
815 815
    /// map reading rule will be abandoned, and the arcs of the graph
816 816
    /// will not be constructed.
817 817
    DigraphReader& skipArcs() {
818 818
      LEMON_ASSERT(!_skip_arcs, "Skip arcs already set");
819 819
      _skip_arcs = true;
820 820
      return *this;
821 821
    }
822 822

	
823 823
    /// @}
824 824

	
825 825
  private:
826 826

	
827 827
    bool readLine() {
828 828
      std::string str;
829 829
      while(++line_num, std::getline(*_is, str)) {
830 830
        line.clear(); line.str(str);
831 831
        char c;
832 832
        if (line >> std::ws >> c && c != '#') {
833 833
          line.putback(c);
834 834
          return true;
835 835
        }
836 836
      }
837 837
      return false;
838 838
    }
839 839

	
840 840
    bool readSuccess() {
841 841
      return static_cast<bool>(*_is);
842 842
    }
843 843

	
844 844
    void skipSection() {
845 845
      char c;
846 846
      while (readSuccess() && line >> c && c != '@') {
847 847
        readLine();
848 848
      }
849 849
      if (readSuccess()) {
850 850
        line.putback(c);
851 851
      }
852 852
    }
853 853

	
854 854
    void readNodes() {
855 855

	
856 856
      std::vector<int> map_index(_node_maps.size());
857 857
      int map_num, label_index;
858 858

	
859 859
      char c;
860 860
      if (!readLine() || !(line >> c) || c == '@') {
861 861
        if (readSuccess() && line) line.putback(c);
862 862
        if (!_node_maps.empty())
863 863
          throw FormatError("Cannot find map names");
864 864
        return;
865 865
      }
866 866
      line.putback(c);
867 867

	
868 868
      {
869 869
        std::map<std::string, int> maps;
870 870

	
871 871
        std::string map;
872 872
        int index = 0;
873 873
        while (_reader_bits::readToken(line, map)) {
874 874
          if (maps.find(map) != maps.end()) {
875 875
            std::ostringstream msg;
876 876
            msg << "Multiple occurence of node map: " << map;
877 877
            throw FormatError(msg.str());
878 878
          }
879 879
          maps.insert(std::make_pair(map, index));
880 880
          ++index;
881 881
        }
882 882

	
883 883
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
884 884
          std::map<std::string, int>::iterator jt =
885 885
            maps.find(_node_maps[i].first);
886 886
          if (jt == maps.end()) {
887 887
            std::ostringstream msg;
888 888
            msg << "Map not found: " << _node_maps[i].first;
889 889
            throw FormatError(msg.str());
890 890
          }
891 891
          map_index[i] = jt->second;
892 892
        }
893 893

	
894 894
        {
895 895
          std::map<std::string, int>::iterator jt = maps.find("label");
896 896
          if (jt != maps.end()) {
897 897
            label_index = jt->second;
898 898
          } else {
899 899
            label_index = -1;
900 900
          }
901 901
        }
902 902
        map_num = maps.size();
903 903
      }
904 904

	
905 905
      while (readLine() && line >> c && c != '@') {
906 906
        line.putback(c);
907 907

	
908 908
        std::vector<std::string> tokens(map_num);
909 909
        for (int i = 0; i < map_num; ++i) {
910 910
          if (!_reader_bits::readToken(line, tokens[i])) {
911 911
            std::ostringstream msg;
912 912
            msg << "Column not found (" << i + 1 << ")";
913 913
            throw FormatError(msg.str());
914 914
          }
915 915
        }
916 916
        if (line >> std::ws >> c)
917 917
          throw FormatError("Extra character at the end of line");
918 918

	
919 919
        Node n;
920 920
        if (!_use_nodes) {
921 921
          n = _digraph.addNode();
922 922
          if (label_index != -1)
923 923
            _node_index.insert(std::make_pair(tokens[label_index], n));
924 924
        } else {
925 925
          if (label_index == -1)
926 926
            throw FormatError("Label map not found");
927 927
          typename std::map<std::string, Node>::iterator it =
928 928
            _node_index.find(tokens[label_index]);
929 929
          if (it == _node_index.end()) {
930 930
            std::ostringstream msg;
931 931
            msg << "Node with label not found: " << tokens[label_index];
932 932
            throw FormatError(msg.str());
933 933
          }
934 934
          n = it->second;
935 935
        }
936 936

	
937 937
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
938 938
          _node_maps[i].second->set(n, tokens[map_index[i]]);
939 939
        }
940 940

	
941 941
      }
942 942
      if (readSuccess()) {
943 943
        line.putback(c);
944 944
      }
945 945
    }
946 946

	
947 947
    void readArcs() {
948 948

	
949 949
      std::vector<int> map_index(_arc_maps.size());
950 950
      int map_num, label_index;
951 951

	
952 952
      char c;
953 953
      if (!readLine() || !(line >> c) || c == '@') {
954 954
        if (readSuccess() && line) line.putback(c);
955 955
        if (!_arc_maps.empty())
956 956
          throw FormatError("Cannot find map names");
957 957
        return;
958 958
      }
959 959
      line.putback(c);
960 960

	
961 961
      {
962 962
        std::map<std::string, int> maps;
963 963

	
964 964
        std::string map;
965 965
        int index = 0;
966 966
        while (_reader_bits::readToken(line, map)) {
967 967
          if(map == "-") {
968 968
              if(index!=0)
969 969
                throw FormatError("'-' is not allowed as a map name");
970 970
              else if (line >> std::ws >> c)
971 971
                throw FormatError("Extra character at the end of line");
972 972
              else break;
973 973
            }
974 974
          if (maps.find(map) != maps.end()) {
975 975
            std::ostringstream msg;
976 976
            msg << "Multiple occurence of arc map: " << map;
977 977
            throw FormatError(msg.str());
978 978
          }
979 979
          maps.insert(std::make_pair(map, index));
980 980
          ++index;
981 981
        }
982 982

	
983 983
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
984 984
          std::map<std::string, int>::iterator jt =
985 985
            maps.find(_arc_maps[i].first);
986 986
          if (jt == maps.end()) {
987 987
            std::ostringstream msg;
988 988
            msg << "Map not found: " << _arc_maps[i].first;
989 989
            throw FormatError(msg.str());
990 990
          }
991 991
          map_index[i] = jt->second;
992 992
        }
993 993

	
994 994
        {
995 995
          std::map<std::string, int>::iterator jt = maps.find("label");
996 996
          if (jt != maps.end()) {
997 997
            label_index = jt->second;
998 998
          } else {
999 999
            label_index = -1;
1000 1000
          }
1001 1001
        }
1002 1002
        map_num = maps.size();
1003 1003
      }
1004 1004

	
1005 1005
      while (readLine() && line >> c && c != '@') {
1006 1006
        line.putback(c);
1007 1007

	
1008 1008
        std::string source_token;
1009 1009
        std::string target_token;
1010 1010

	
1011 1011
        if (!_reader_bits::readToken(line, source_token))
1012 1012
          throw FormatError("Source not found");
1013 1013

	
1014 1014
        if (!_reader_bits::readToken(line, target_token))
1015 1015
          throw FormatError("Target not found");
1016 1016

	
1017 1017
        std::vector<std::string> tokens(map_num);
1018 1018
        for (int i = 0; i < map_num; ++i) {
1019 1019
          if (!_reader_bits::readToken(line, tokens[i])) {
1020 1020
            std::ostringstream msg;
1021 1021
            msg << "Column not found (" << i + 1 << ")";
1022 1022
            throw FormatError(msg.str());
1023 1023
          }
1024 1024
        }
1025 1025
        if (line >> std::ws >> c)
1026 1026
          throw FormatError("Extra character at the end of line");
1027 1027

	
1028 1028
        Arc a;
1029 1029
        if (!_use_arcs) {
1030 1030

	
1031 1031
          typename NodeIndex::iterator it;
1032 1032

	
1033 1033
          it = _node_index.find(source_token);
1034 1034
          if (it == _node_index.end()) {
1035 1035
            std::ostringstream msg;
1036 1036
            msg << "Item not found: " << source_token;
1037 1037
            throw FormatError(msg.str());
1038 1038
          }
1039 1039
          Node source = it->second;
1040 1040

	
1041 1041
          it = _node_index.find(target_token);
1042 1042
          if (it == _node_index.end()) {
1043 1043
            std::ostringstream msg;
1044 1044
            msg << "Item not found: " << target_token;
1045 1045
            throw FormatError(msg.str());
1046 1046
          }
1047 1047
          Node target = it->second;
1048 1048

	
1049 1049
          a = _digraph.addArc(source, target);
1050 1050
          if (label_index != -1)
1051 1051
            _arc_index.insert(std::make_pair(tokens[label_index], a));
1052 1052
        } else {
1053 1053
          if (label_index == -1)
1054 1054
            throw FormatError("Label map not found");
1055 1055
          typename std::map<std::string, Arc>::iterator it =
1056 1056
            _arc_index.find(tokens[label_index]);
1057 1057
          if (it == _arc_index.end()) {
1058 1058
            std::ostringstream msg;
1059 1059
            msg << "Arc with label not found: " << tokens[label_index];
1060 1060
            throw FormatError(msg.str());
1061 1061
          }
1062 1062
          a = it->second;
1063 1063
        }
1064 1064

	
1065 1065
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1066 1066
          _arc_maps[i].second->set(a, tokens[map_index[i]]);
1067 1067
        }
1068 1068

	
1069 1069
      }
1070 1070
      if (readSuccess()) {
1071 1071
        line.putback(c);
1072 1072
      }
1073 1073
    }
1074 1074

	
1075 1075
    void readAttributes() {
1076 1076

	
1077 1077
      std::set<std::string> read_attr;
1078 1078

	
1079 1079
      char c;
1080 1080
      while (readLine() && line >> c && c != '@') {
1081 1081
        line.putback(c);
1082 1082

	
1083 1083
        std::string attr, token;
1084 1084
        if (!_reader_bits::readToken(line, attr))
1085 1085
          throw FormatError("Attribute name not found");
1086 1086
        if (!_reader_bits::readToken(line, token))
1087 1087
          throw FormatError("Attribute value not found");
1088 1088
        if (line >> c)
1089 1089
          throw FormatError("Extra character at the end of line");
1090 1090

	
1091 1091
        {
1092 1092
          std::set<std::string>::iterator it = read_attr.find(attr);
1093 1093
          if (it != read_attr.end()) {
1094 1094
            std::ostringstream msg;
1095 1095
            msg << "Multiple occurence of attribute: " << attr;
1096 1096
            throw FormatError(msg.str());
1097 1097
          }
1098 1098
          read_attr.insert(attr);
1099 1099
        }
1100 1100

	
1101 1101
        {
1102 1102
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1103 1103
          while (it != _attributes.end() && it->first == attr) {
1104 1104
            it->second->set(token);
1105 1105
            ++it;
1106 1106
          }
1107 1107
        }
1108 1108

	
1109 1109
      }
1110 1110
      if (readSuccess()) {
1111 1111
        line.putback(c);
1112 1112
      }
1113 1113
      for (typename Attributes::iterator it = _attributes.begin();
1114 1114
           it != _attributes.end(); ++it) {
1115 1115
        if (read_attr.find(it->first) == read_attr.end()) {
1116 1116
          std::ostringstream msg;
1117 1117
          msg << "Attribute not found: " << it->first;
1118 1118
          throw FormatError(msg.str());
1119 1119
        }
1120 1120
      }
1121 1121
    }
1122 1122

	
1123 1123
  public:
1124 1124

	
1125 1125
    /// \name Execution of the Reader
1126 1126
    /// @{
1127 1127

	
1128 1128
    /// \brief Start the batch processing
1129 1129
    ///
1130 1130
    /// This function starts the batch processing
1131 1131
    void run() {
1132 1132
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1133 1133

	
1134 1134
      bool nodes_done = _skip_nodes;
1135 1135
      bool arcs_done = _skip_arcs;
1136 1136
      bool attributes_done = false;
1137 1137

	
1138 1138
      line_num = 0;
1139 1139
      readLine();
1140 1140
      skipSection();
1141 1141

	
1142 1142
      while (readSuccess()) {
1143 1143
        try {
1144 1144
          char c;
1145 1145
          std::string section, caption;
1146 1146
          line >> c;
1147 1147
          _reader_bits::readToken(line, section);
1148 1148
          _reader_bits::readToken(line, caption);
1149 1149

	
1150 1150
          if (line >> c)
1151 1151
            throw FormatError("Extra character at the end of line");
1152 1152

	
1153 1153
          if (section == "nodes" && !nodes_done) {
1154 1154
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1155 1155
              readNodes();
1156 1156
              nodes_done = true;
1157 1157
            }
1158 1158
          } else if ((section == "arcs" || section == "edges") &&
1159 1159
                     !arcs_done) {
1160 1160
            if (_arcs_caption.empty() || _arcs_caption == caption) {
1161 1161
              readArcs();
1162 1162
              arcs_done = true;
1163 1163
            }
1164 1164
          } else if (section == "attributes" && !attributes_done) {
1165 1165
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1166 1166
              readAttributes();
1167 1167
              attributes_done = true;
1168 1168
            }
1169 1169
          } else {
1170 1170
            readLine();
1171 1171
            skipSection();
1172 1172
          }
1173 1173
        } catch (FormatError& error) {
1174 1174
          error.line(line_num);
1175 1175
          error.file(_filename);
1176 1176
          throw;
1177 1177
        }
1178 1178
      }
1179 1179

	
1180 1180
      if (!nodes_done) {
1181 1181
        throw FormatError("Section @nodes not found");
1182 1182
      }
1183 1183

	
1184 1184
      if (!arcs_done) {
1185 1185
        throw FormatError("Section @arcs not found");
1186 1186
      }
1187 1187

	
1188 1188
      if (!attributes_done && !_attributes.empty()) {
1189 1189
        throw FormatError("Section @attributes not found");
1190 1190
      }
1191 1191

	
1192 1192
    }
1193 1193

	
1194 1194
    /// @}
1195 1195

	
1196 1196
  };
1197
  
1197

	
1198 1198
  /// \ingroup lemon_io
1199 1199
  ///
1200 1200
  /// \brief Return a \ref DigraphReader class
1201 1201
  ///
1202 1202
  /// This function just returns a \ref DigraphReader class.
1203 1203
  ///
1204
  /// With this function a digraph can be read from an 
1204
  /// With this function a digraph can be read from an
1205 1205
  /// \ref lgf-format "LGF" file or input stream with several maps and
1206 1206
  /// attributes. For example, there is network flow problem on a
1207 1207
  /// digraph, i.e. a digraph with a \e capacity map on the arcs and
1208 1208
  /// \e source and \e target nodes. This digraph can be read with the
1209 1209
  /// following code:
1210 1210
  ///
1211 1211
  ///\code
1212 1212
  ///ListDigraph digraph;
1213 1213
  ///ListDigraph::ArcMap<int> cm(digraph);
1214 1214
  ///ListDigraph::Node src, trg;
1215 1215
  ///digraphReader(digraph, std::cin).
1216 1216
  ///  arcMap("capacity", cap).
1217 1217
  ///  node("source", src).
1218 1218
  ///  node("target", trg).
1219 1219
  ///  run();
1220 1220
  ///\endcode
1221 1221
  ///
1222 1222
  /// For a complete documentation, please see the \ref DigraphReader
1223 1223
  /// class documentation.
1224 1224
  /// \warning Don't forget to put the \ref DigraphReader::run() "run()"
1225 1225
  /// to the end of the parameter list.
1226 1226
  /// \relates DigraphReader
1227 1227
  /// \sa digraphReader(TDGR& digraph, const std::string& fn)
1228 1228
  /// \sa digraphReader(TDGR& digraph, const char* fn)
1229 1229
  template <typename TDGR>
1230 1230
  DigraphReader<TDGR> digraphReader(TDGR& digraph, std::istream& is) {
1231 1231
    DigraphReader<TDGR> tmp(digraph, is);
1232 1232
    return tmp;
1233 1233
  }
1234 1234

	
1235 1235
  /// \brief Return a \ref DigraphReader class
1236 1236
  ///
1237 1237
  /// This function just returns a \ref DigraphReader class.
1238 1238
  /// \relates DigraphReader
1239 1239
  /// \sa digraphReader(TDGR& digraph, std::istream& is)
1240 1240
  template <typename TDGR>
1241 1241
  DigraphReader<TDGR> digraphReader(TDGR& digraph, const std::string& fn) {
1242 1242
    DigraphReader<TDGR> tmp(digraph, fn);
1243 1243
    return tmp;
1244 1244
  }
1245 1245

	
1246 1246
  /// \brief Return a \ref DigraphReader class
1247 1247
  ///
1248 1248
  /// This function just returns a \ref DigraphReader class.
1249 1249
  /// \relates DigraphReader
1250 1250
  /// \sa digraphReader(TDGR& digraph, std::istream& is)
1251 1251
  template <typename TDGR>
1252 1252
  DigraphReader<TDGR> digraphReader(TDGR& digraph, const char* fn) {
1253 1253
    DigraphReader<TDGR> tmp(digraph, fn);
1254 1254
    return tmp;
1255 1255
  }
1256 1256

	
1257 1257
  template <typename GR>
1258 1258
  class GraphReader;
1259
 
1259

	
1260 1260
  template <typename TGR>
1261 1261
  GraphReader<TGR> graphReader(TGR& graph, std::istream& is = std::cin);
1262 1262
  template <typename TGR>
1263 1263
  GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
1264 1264
  template <typename TGR>
1265 1265
  GraphReader<TGR> graphReader(TGR& graph, const char *fn);
1266 1266

	
1267 1267
  /// \ingroup lemon_io
1268 1268
  ///
1269 1269
  /// \brief \ref lgf-format "LGF" reader for undirected graphs
1270 1270
  ///
1271 1271
  /// This utility reads an \ref lgf-format "LGF" file.
1272 1272
  ///
1273 1273
  /// It can be used almost the same way as \c DigraphReader.
1274 1274
  /// The only difference is that this class can handle edges and
1275 1275
  /// edge maps as well as arcs and arc maps.
1276 1276
  ///
1277 1277
  /// The columns in the \c \@edges (or \c \@arcs) section are the
1278 1278
  /// edge maps. However, if there are two maps with the same name
1279 1279
  /// prefixed with \c '+' and \c '-', then these can be read into an
1280 1280
  /// arc map.  Similarly, an attribute can be read into an arc, if
1281 1281
  /// it's value is an edge label prefixed with \c '+' or \c '-'.
1282 1282
  template <typename GR>
1283 1283
  class GraphReader {
1284 1284
  public:
1285 1285

	
1286 1286
    typedef GR Graph;
1287 1287

	
1288 1288
  private:
1289 1289

	
1290 1290
    TEMPLATE_GRAPH_TYPEDEFS(GR);
1291 1291

	
1292 1292
    std::istream* _is;
1293 1293
    bool local_is;
1294 1294
    std::string _filename;
1295 1295

	
1296 1296
    GR& _graph;
1297 1297

	
1298 1298
    std::string _nodes_caption;
1299 1299
    std::string _edges_caption;
1300 1300
    std::string _attributes_caption;
1301 1301

	
1302 1302
    typedef std::map<std::string, Node> NodeIndex;
1303 1303
    NodeIndex _node_index;
1304 1304
    typedef std::map<std::string, Edge> EdgeIndex;
1305 1305
    EdgeIndex _edge_index;
1306 1306

	
1307 1307
    typedef std::vector<std::pair<std::string,
1308 1308
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1309 1309
    NodeMaps _node_maps;
1310 1310

	
1311 1311
    typedef std::vector<std::pair<std::string,
1312 1312
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1313 1313
    EdgeMaps _edge_maps;
1314 1314

	
1315 1315
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1316 1316
      Attributes;
1317 1317
    Attributes _attributes;
1318 1318

	
1319 1319
    bool _use_nodes;
1320 1320
    bool _use_edges;
1321 1321

	
1322 1322
    bool _skip_nodes;
1323 1323
    bool _skip_edges;
1324 1324

	
1325 1325
    int line_num;
1326 1326
    std::istringstream line;
1327 1327

	
1328 1328
  public:
1329 1329

	
1330 1330
    /// \brief Constructor
1331 1331
    ///
1332 1332
    /// Construct an undirected graph reader, which reads from the given
1333 1333
    /// input stream.
1334 1334
    GraphReader(GR& graph, std::istream& is = std::cin)
1335 1335
      : _is(&is), local_is(false), _graph(graph),
1336 1336
        _use_nodes(false), _use_edges(false),
1337 1337
        _skip_nodes(false), _skip_edges(false) {}
1338 1338

	
1339 1339
    /// \brief Constructor
1340 1340
    ///
1341 1341
    /// Construct an undirected graph reader, which reads from the given
1342 1342
    /// file.
1343 1343
    GraphReader(GR& graph, const std::string& fn)
1344 1344
      : _is(new std::ifstream(fn.c_str())), local_is(true),
1345 1345
        _filename(fn), _graph(graph),
1346 1346
        _use_nodes(false), _use_edges(false),
1347 1347
        _skip_nodes(false), _skip_edges(false) {
1348 1348
      if (!(*_is)) {
1349 1349
        delete _is;
1350 1350
        throw IoError("Cannot open file", fn);
1351 1351
      }
1352 1352
    }
1353 1353

	
1354 1354
    /// \brief Constructor
1355 1355
    ///
1356 1356
    /// Construct an undirected graph reader, which reads from the given
1357 1357
    /// file.
1358 1358
    GraphReader(GR& graph, const char* fn)
1359 1359
      : _is(new std::ifstream(fn)), local_is(true),
1360 1360
        _filename(fn), _graph(graph),
1361 1361
        _use_nodes(false), _use_edges(false),
1362 1362
        _skip_nodes(false), _skip_edges(false) {
1363 1363
      if (!(*_is)) {
1364 1364
        delete _is;
1365 1365
        throw IoError("Cannot open file", fn);
1366 1366
      }
1367 1367
    }
1368 1368

	
1369 1369
    /// \brief Destructor
1370 1370
    ~GraphReader() {
1371 1371
      for (typename NodeMaps::iterator it = _node_maps.begin();
1372 1372
           it != _node_maps.end(); ++it) {
1373 1373
        delete it->second;
1374 1374
      }
1375 1375

	
1376 1376
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1377 1377
           it != _edge_maps.end(); ++it) {
1378 1378
        delete it->second;
1379 1379
      }
1380 1380

	
1381 1381
      for (typename Attributes::iterator it = _attributes.begin();
1382 1382
           it != _attributes.end(); ++it) {
1383 1383
        delete it->second;
1384 1384
      }
1385 1385

	
1386 1386
      if (local_is) {
1387 1387
        delete _is;
1388 1388
      }
1389 1389

	
1390 1390
    }
1391 1391

	
1392 1392
  private:
1393 1393
    template <typename TGR>
1394 1394
    friend GraphReader<TGR> graphReader(TGR& graph, std::istream& is);
1395 1395
    template <typename TGR>
1396
    friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn); 
1396
    friend GraphReader<TGR> graphReader(TGR& graph, const std::string& fn);
1397 1397
    template <typename TGR>
1398 1398
    friend GraphReader<TGR> graphReader(TGR& graph, const char *fn);
1399 1399

	
1400 1400
    GraphReader(GraphReader& other)
1401 1401
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1402 1402
        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
1403 1403
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1404 1404

	
1405 1405
      other._is = 0;
1406 1406
      other.local_is = false;
1407 1407

	
1408 1408
      _node_index.swap(other._node_index);
1409 1409
      _edge_index.swap(other._edge_index);
1410 1410

	
1411 1411
      _node_maps.swap(other._node_maps);
1412 1412
      _edge_maps.swap(other._edge_maps);
1413 1413
      _attributes.swap(other._attributes);
1414 1414

	
1415 1415
      _nodes_caption = other._nodes_caption;
1416 1416
      _edges_caption = other._edges_caption;
1417 1417
      _attributes_caption = other._attributes_caption;
1418 1418

	
1419 1419
    }
1420 1420

	
1421 1421
    GraphReader& operator=(const GraphReader&);
1422 1422

	
1423 1423
  public:
1424 1424

	
1425 1425
    /// \name Reading Rules
1426 1426
    /// @{
1427 1427

	
1428 1428
    /// \brief Node map reading rule
1429 1429
    ///
1430 1430
    /// Add a node map reading rule to the reader.
1431 1431
    template <typename Map>
1432 1432
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1433 1433
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1434 1434
      _reader_bits::MapStorageBase<Node>* storage =
1435 1435
        new _reader_bits::MapStorage<Node, Map>(map);
1436 1436
      _node_maps.push_back(std::make_pair(caption, storage));
1437 1437
      return *this;
1438 1438
    }
1439 1439

	
1440 1440
    /// \brief Node map reading rule
1441 1441
    ///
1442 1442
    /// Add a node map reading rule with specialized converter to the
1443 1443
    /// reader.
1444 1444
    template <typename Map, typename Converter>
1445 1445
    GraphReader& nodeMap(const std::string& caption, Map& map,
1446 1446
                           const Converter& converter = Converter()) {
1447 1447
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1448 1448
      _reader_bits::MapStorageBase<Node>* storage =
1449 1449
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1450 1450
      _node_maps.push_back(std::make_pair(caption, storage));
1451 1451
      return *this;
1452 1452
    }
1453 1453

	
1454 1454
    /// \brief Edge map reading rule
1455 1455
    ///
1456 1456
    /// Add an edge map reading rule to the reader.
1457 1457
    template <typename Map>
1458 1458
    GraphReader& edgeMap(const std::string& caption, Map& map) {
1459 1459
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1460 1460
      _reader_bits::MapStorageBase<Edge>* storage =
1461 1461
        new _reader_bits::MapStorage<Edge, Map>(map);
1462 1462
      _edge_maps.push_back(std::make_pair(caption, storage));
1463 1463
      return *this;
1464 1464
    }
1465 1465

	
1466 1466
    /// \brief Edge map reading rule
1467 1467
    ///
1468 1468
    /// Add an edge map reading rule with specialized converter to the
1469 1469
    /// reader.
1470 1470
    template <typename Map, typename Converter>
1471 1471
    GraphReader& edgeMap(const std::string& caption, Map& map,
1472 1472
                          const Converter& converter = Converter()) {
1473 1473
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1474 1474
      _reader_bits::MapStorageBase<Edge>* storage =
1475 1475
        new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1476 1476
      _edge_maps.push_back(std::make_pair(caption, storage));
1477 1477
      return *this;
1478 1478
    }
1479 1479

	
1480 1480
    /// \brief Arc map reading rule
1481 1481
    ///
1482 1482
    /// Add an arc map reading rule to the reader.
1483 1483
    template <typename Map>
1484 1484
    GraphReader& arcMap(const std::string& caption, Map& map) {
1485 1485
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1486 1486
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1487 1487
        new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1488 1488
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1489 1489
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1490 1490
        new _reader_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
1491 1491
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1492 1492
      return *this;
1493 1493
    }
1494 1494

	
1495 1495
    /// \brief Arc map reading rule
1496 1496
    ///
1497 1497
    /// Add an arc map reading rule with specialized converter to the
1498 1498
    /// reader.
1499 1499
    template <typename Map, typename Converter>
1500 1500
    GraphReader& arcMap(const std::string& caption, Map& map,
1501 1501
                          const Converter& converter = Converter()) {
1502 1502
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1503 1503
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1504 1504
        new _reader_bits::GraphArcMapStorage<GR, true, Map, Converter>
1505 1505
        (_graph, map, converter);
1506 1506
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1507 1507
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1508 1508
        new _reader_bits::GraphArcMapStorage<GR, false, Map, Converter>
1509 1509
        (_graph, map, converter);
1510 1510
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1511 1511
      return *this;
1512 1512
    }
1513 1513

	
1514 1514
    /// \brief Attribute reading rule
1515 1515
    ///
1516 1516
    /// Add an attribute reading rule to the reader.
1517 1517
    template <typename Value>
1518 1518
    GraphReader& attribute(const std::string& caption, Value& value) {
1519 1519
      _reader_bits::ValueStorageBase* storage =
1520 1520
        new _reader_bits::ValueStorage<Value>(value);
1521 1521
      _attributes.insert(std::make_pair(caption, storage));
1522 1522
      return *this;
1523 1523
    }
1524 1524

	
1525 1525
    /// \brief Attribute reading rule
1526 1526
    ///
1527 1527
    /// Add an attribute reading rule with specialized converter to the
1528 1528
    /// reader.
1529 1529
    template <typename Value, typename Converter>
1530 1530
    GraphReader& attribute(const std::string& caption, Value& value,
1531 1531
                             const Converter& converter = Converter()) {
1532 1532
      _reader_bits::ValueStorageBase* storage =
1533 1533
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1534 1534
      _attributes.insert(std::make_pair(caption, storage));
1535 1535
      return *this;
1536 1536
    }
1537 1537

	
1538 1538
    /// \brief Node reading rule
1539 1539
    ///
1540 1540
    /// Add a node reading rule to reader.
1541 1541
    GraphReader& node(const std::string& caption, Node& node) {
1542 1542
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
1543 1543
      Converter converter(_node_index);
1544 1544
      _reader_bits::ValueStorageBase* storage =
1545 1545
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1546 1546
      _attributes.insert(std::make_pair(caption, storage));
1547 1547
      return *this;
1548 1548
    }
1549 1549

	
1550 1550
    /// \brief Edge reading rule
1551 1551
    ///
1552 1552
    /// Add an edge reading rule to reader.
1553 1553
    GraphReader& edge(const std::string& caption, Edge& edge) {
1554 1554
      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1555 1555
      Converter converter(_edge_index);
1556 1556
      _reader_bits::ValueStorageBase* storage =
1557 1557
        new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1558 1558
      _attributes.insert(std::make_pair(caption, storage));
1559 1559
      return *this;
1560 1560
    }
1561 1561

	
1562 1562
    /// \brief Arc reading rule
1563 1563
    ///
1564 1564
    /// Add an arc reading rule to reader.
1565 1565
    GraphReader& arc(const std::string& caption, Arc& arc) {
1566 1566
      typedef _reader_bits::GraphArcLookUpConverter<GR> Converter;
1567 1567
      Converter converter(_graph, _edge_index);
1568 1568
      _reader_bits::ValueStorageBase* storage =
1569 1569
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1570 1570
      _attributes.insert(std::make_pair(caption, storage));
1571 1571
      return *this;
1572 1572
    }
1573 1573

	
1574 1574
    /// @}
1575 1575

	
1576 1576
    /// \name Select Section by Name
1577 1577
    /// @{
1578 1578

	
1579 1579
    /// \brief Set \c \@nodes section to be read
1580 1580
    ///
1581 1581
    /// Set \c \@nodes section to be read.
1582 1582
    GraphReader& nodes(const std::string& caption) {
1583 1583
      _nodes_caption = caption;
1584 1584
      return *this;
1585 1585
    }
1586 1586

	
1587 1587
    /// \brief Set \c \@edges section to be read
1588 1588
    ///
1589 1589
    /// Set \c \@edges section to be read.
1590 1590
    GraphReader& edges(const std::string& caption) {
1591 1591
      _edges_caption = caption;
1592 1592
      return *this;
1593 1593
    }
1594 1594

	
1595 1595
    /// \brief Set \c \@attributes section to be read
1596 1596
    ///
1597 1597
    /// Set \c \@attributes section to be read.
1598 1598
    GraphReader& attributes(const std::string& caption) {
1599 1599
      _attributes_caption = caption;
1600 1600
      return *this;
1601 1601
    }
1602 1602

	
1603 1603
    /// @}
1604 1604

	
1605 1605
    /// \name Using Previously Constructed Node or Edge Set
1606 1606
    /// @{
1607 1607

	
1608 1608
    /// \brief Use previously constructed node set
1609 1609
    ///
1610 1610
    /// Use previously constructed node set, and specify the node
1611 1611
    /// label map.
1612 1612
    template <typename Map>
1613 1613
    GraphReader& useNodes(const Map& map) {
1614 1614
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1615 1615
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1616 1616
      _use_nodes = true;
1617 1617
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1618 1618
      for (NodeIt n(_graph); n != INVALID; ++n) {
1619 1619
        _node_index.insert(std::make_pair(converter(map[n]), n));
1620 1620
      }
1621 1621
      return *this;
1622 1622
    }
1623 1623

	
1624 1624
    /// \brief Use previously constructed node set
1625 1625
    ///
1626 1626
    /// Use previously constructed node set, and specify the node
1627 1627
    /// label map and a functor which converts the label map values to
1628 1628
    /// \c std::string.
1629 1629
    template <typename Map, typename Converter>
1630 1630
    GraphReader& useNodes(const Map& map,
1631 1631
                            const Converter& converter = Converter()) {
1632 1632
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1633 1633
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1634 1634
      _use_nodes = true;
1635 1635
      for (NodeIt n(_graph); n != INVALID; ++n) {
1636 1636
        _node_index.insert(std::make_pair(converter(map[n]), n));
1637 1637
      }
1638 1638
      return *this;
1639 1639
    }
1640 1640

	
1641 1641
    /// \brief Use previously constructed edge set
1642 1642
    ///
1643 1643
    /// Use previously constructed edge set, and specify the edge
1644 1644
    /// label map.
1645 1645
    template <typename Map>
1646 1646
    GraphReader& useEdges(const Map& map) {
1647 1647
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1648 1648
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1649 1649
      _use_edges = true;
1650 1650
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1651 1651
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1652 1652
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1653 1653
      }
1654 1654
      return *this;
1655 1655
    }
1656 1656

	
1657 1657
    /// \brief Use previously constructed edge set
1658 1658
    ///
1659 1659
    /// Use previously constructed edge set, and specify the edge
1660 1660
    /// label map and a functor which converts the label map values to
1661 1661
    /// \c std::string.
1662 1662
    template <typename Map, typename Converter>
1663 1663
    GraphReader& useEdges(const Map& map,
1664 1664
                            const Converter& converter = Converter()) {
1665 1665
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1666 1666
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1667 1667
      _use_edges = true;
1668 1668
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1669 1669
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1670 1670
      }
1671 1671
      return *this;
1672 1672
    }
1673 1673

	
1674 1674
    /// \brief Skip the reading of node section
1675 1675
    ///
1676 1676
    /// Omit the reading of the node section. This implies that each node
1677 1677
    /// map reading rule will be abandoned, and the nodes of the graph
1678 1678
    /// will not be constructed, which usually cause that the edge set
1679 1679
    /// could not be read due to lack of node name
1680 1680
    /// could not be read due to lack of node name resolving.
1681 1681
    /// Therefore \c skipEdges() function should also be used, or
1682 1682
    /// \c useNodes() should be used to specify the label of the nodes.
1683 1683
    GraphReader& skipNodes() {
1684 1684
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
1685 1685
      _skip_nodes = true;
1686 1686
      return *this;
1687 1687
    }
1688 1688

	
1689 1689
    /// \brief Skip the reading of edge section
1690 1690
    ///
1691 1691
    /// Omit the reading of the edge section. This implies that each edge
1692 1692
    /// map reading rule will be abandoned, and the edges of the graph
1693 1693
    /// will not be constructed.
1694 1694
    GraphReader& skipEdges() {
1695 1695
      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
1696 1696
      _skip_edges = true;
1697 1697
      return *this;
1698 1698
    }
1699 1699

	
1700 1700
    /// @}
1701 1701

	
1702 1702
  private:
1703 1703

	
1704 1704
    bool readLine() {
1705 1705
      std::string str;
1706 1706
      while(++line_num, std::getline(*_is, str)) {
1707 1707
        line.clear(); line.str(str);
1708 1708
        char c;
1709 1709
        if (line >> std::ws >> c && c != '#') {
1710 1710
          line.putback(c);
1711 1711
          return true;
1712 1712
        }
1713 1713
      }
1714 1714
      return false;
1715 1715
    }
1716 1716

	
1717 1717
    bool readSuccess() {
1718 1718
      return static_cast<bool>(*_is);
1719 1719
    }
1720 1720

	
1721 1721
    void skipSection() {
1722 1722
      char c;
1723 1723
      while (readSuccess() && line >> c && c != '@') {
1724 1724
        readLine();
1725 1725
      }
1726 1726
      if (readSuccess()) {
1727 1727
        line.putback(c);
1728 1728
      }
1729 1729
    }
1730 1730

	
1731 1731
    void readNodes() {
1732 1732

	
1733 1733
      std::vector<int> map_index(_node_maps.size());
1734 1734
      int map_num, label_index;
1735 1735

	
1736 1736
      char c;
1737 1737
      if (!readLine() || !(line >> c) || c == '@') {
1738 1738
        if (readSuccess() && line) line.putback(c);
1739 1739
        if (!_node_maps.empty())
1740 1740
          throw FormatError("Cannot find map names");
1741 1741
        return;
1742 1742
      }
1743 1743
      line.putback(c);
1744 1744

	
1745 1745
      {
1746 1746
        std::map<std::string, int> maps;
1747 1747

	
1748 1748
        std::string map;
1749 1749
        int index = 0;
1750 1750
        while (_reader_bits::readToken(line, map)) {
1751 1751
          if (maps.find(map) != maps.end()) {
1752 1752
            std::ostringstream msg;
1753 1753
            msg << "Multiple occurence of node map: " << map;
1754 1754
            throw FormatError(msg.str());
1755 1755
          }
1756 1756
          maps.insert(std::make_pair(map, index));
1757 1757
          ++index;
1758 1758
        }
1759 1759

	
1760 1760
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1761 1761
          std::map<std::string, int>::iterator jt =
1762 1762
            maps.find(_node_maps[i].first);
1763 1763
          if (jt == maps.end()) {
1764 1764
            std::ostringstream msg;
1765 1765
            msg << "Map not found: " << _node_maps[i].first;
1766 1766
            throw FormatError(msg.str());
1767 1767
          }
1768 1768
          map_index[i] = jt->second;
1769 1769
        }
1770 1770

	
1771 1771
        {
1772 1772
          std::map<std::string, int>::iterator jt = maps.find("label");
1773 1773
          if (jt != maps.end()) {
1774 1774
            label_index = jt->second;
1775 1775
          } else {
1776 1776
            label_index = -1;
1777 1777
          }
1778 1778
        }
1779 1779
        map_num = maps.size();
1780 1780
      }
1781 1781

	
1782 1782
      while (readLine() && line >> c && c != '@') {
1783 1783
        line.putback(c);
1784 1784

	
1785 1785
        std::vector<std::string> tokens(map_num);
1786 1786
        for (int i = 0; i < map_num; ++i) {
1787 1787
          if (!_reader_bits::readToken(line, tokens[i])) {
1788 1788
            std::ostringstream msg;
1789 1789
            msg << "Column not found (" << i + 1 << ")";
1790 1790
            throw FormatError(msg.str());
1791 1791
          }
1792 1792
        }
1793 1793
        if (line >> std::ws >> c)
1794 1794
          throw FormatError("Extra character at the end of line");
1795 1795

	
1796 1796
        Node n;
1797 1797
        if (!_use_nodes) {
1798 1798
          n = _graph.addNode();
1799 1799
          if (label_index != -1)
1800 1800
            _node_index.insert(std::make_pair(tokens[label_index], n));
1801 1801
        } else {
1802 1802
          if (label_index == -1)
1803 1803
            throw FormatError("Label map not found");
1804 1804
          typename std::map<std::string, Node>::iterator it =
1805 1805
            _node_index.find(tokens[label_index]);
1806 1806
          if (it == _node_index.end()) {
1807 1807
            std::ostringstream msg;
1808 1808
            msg << "Node with label not found: " << tokens[label_index];
1809 1809
            throw FormatError(msg.str());
1810 1810
          }
1811 1811
          n = it->second;
1812 1812
        }
1813 1813

	
1814 1814
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1815 1815
          _node_maps[i].second->set(n, tokens[map_index[i]]);
1816 1816
        }
1817 1817

	
1818 1818
      }
1819 1819
      if (readSuccess()) {
1820 1820
        line.putback(c);
1821 1821
      }
1822 1822
    }
1823 1823

	
1824 1824
    void readEdges() {
1825 1825

	
1826 1826
      std::vector<int> map_index(_edge_maps.size());
1827 1827
      int map_num, label_index;
1828 1828

	
1829 1829
      char c;
1830 1830
      if (!readLine() || !(line >> c) || c == '@') {
1831 1831
        if (readSuccess() && line) line.putback(c);
1832 1832
        if (!_edge_maps.empty())
1833 1833
          throw FormatError("Cannot find map names");
1834 1834
        return;
1835 1835
      }
1836 1836
      line.putback(c);
1837 1837

	
1838 1838
      {
1839 1839
        std::map<std::string, int> maps;
1840 1840

	
1841 1841
        std::string map;
1842 1842
        int index = 0;
1843 1843
        while (_reader_bits::readToken(line, map)) {
1844 1844
          if(map == "-") {
1845 1845
              if(index!=0)
1846 1846
                throw FormatError("'-' is not allowed as a map name");
1847 1847
              else if (line >> std::ws >> c)
1848 1848
                throw FormatError("Extra character at the end of line");
1849 1849
              else break;
1850 1850
            }
1851 1851
          if (maps.find(map) != maps.end()) {
1852 1852
            std::ostringstream msg;
1853 1853
            msg << "Multiple occurence of edge map: " << map;
1854 1854
            throw FormatError(msg.str());
1855 1855
          }
1856 1856
          maps.insert(std::make_pair(map, index));
1857 1857
          ++index;
1858 1858
        }
1859 1859

	
1860 1860
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1861 1861
          std::map<std::string, int>::iterator jt =
1862 1862
            maps.find(_edge_maps[i].first);
1863 1863
          if (jt == maps.end()) {
1864 1864
            std::ostringstream msg;
1865 1865
            msg << "Map not found: " << _edge_maps[i].first;
1866 1866
            throw FormatError(msg.str());
1867 1867
          }
1868 1868
          map_index[i] = jt->second;
1869 1869
        }
1870 1870

	
1871 1871
        {
1872 1872
          std::map<std::string, int>::iterator jt = maps.find("label");
1873 1873
          if (jt != maps.end()) {
1874 1874
            label_index = jt->second;
1875 1875
          } else {
1876 1876
            label_index = -1;
1877 1877
          }
1878 1878
        }
1879 1879
        map_num = maps.size();
1880 1880
      }
1881 1881

	
1882 1882
      while (readLine() && line >> c && c != '@') {
1883 1883
        line.putback(c);
1884 1884

	
1885 1885
        std::string source_token;
1886 1886
        std::string target_token;
1887 1887

	
1888 1888
        if (!_reader_bits::readToken(line, source_token))
1889 1889
          throw FormatError("Node u not found");
1890 1890

	
1891 1891
        if (!_reader_bits::readToken(line, target_token))
1892 1892
          throw FormatError("Node v not found");
1893 1893

	
1894 1894
        std::vector<std::string> tokens(map_num);
1895 1895
        for (int i = 0; i < map_num; ++i) {
1896 1896
          if (!_reader_bits::readToken(line, tokens[i])) {
1897 1897
            std::ostringstream msg;
1898 1898
            msg << "Column not found (" << i + 1 << ")";
1899 1899
            throw FormatError(msg.str());
1900 1900
          }
1901 1901
        }
1902 1902
        if (line >> std::ws >> c)
1903 1903
          throw FormatError("Extra character at the end of line");
1904 1904

	
1905 1905
        Edge e;
1906 1906
        if (!_use_edges) {
1907 1907

	
1908 1908
          typename NodeIndex::iterator it;
1909 1909

	
1910 1910
          it = _node_index.find(source_token);
1911 1911
          if (it == _node_index.end()) {
1912 1912
            std::ostringstream msg;
1913 1913
            msg << "Item not found: " << source_token;
1914 1914
            throw FormatError(msg.str());
1915 1915
          }
1916 1916
          Node source = it->second;
1917 1917

	
1918 1918
          it = _node_index.find(target_token);
1919 1919
          if (it == _node_index.end()) {
1920 1920
            std::ostringstream msg;
1921 1921
            msg << "Item not found: " << target_token;
1922 1922
            throw FormatError(msg.str());
1923 1923
          }
1924 1924
          Node target = it->second;
1925 1925

	
1926 1926
          e = _graph.addEdge(source, target);
1927 1927
          if (label_index != -1)
1928 1928
            _edge_index.insert(std::make_pair(tokens[label_index], e));
1929 1929
        } else {
1930 1930
          if (label_index == -1)
1931 1931
            throw FormatError("Label map not found");
1932 1932
          typename std::map<std::string, Edge>::iterator it =
1933 1933
            _edge_index.find(tokens[label_index]);
1934 1934
          if (it == _edge_index.end()) {
1935 1935
            std::ostringstream msg;
1936 1936
            msg << "Edge with label not found: " << tokens[label_index];
1937 1937
            throw FormatError(msg.str());
1938 1938
          }
1939 1939
          e = it->second;
1940 1940
        }
1941 1941

	
1942 1942
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1943 1943
          _edge_maps[i].second->set(e, tokens[map_index[i]]);
1944 1944
        }
1945 1945

	
1946 1946
      }
1947 1947
      if (readSuccess()) {
1948 1948
        line.putback(c);
1949 1949
      }
1950 1950
    }
1951 1951

	
1952 1952
    void readAttributes() {
1953 1953

	
1954 1954
      std::set<std::string> read_attr;
1955 1955

	
1956 1956
      char c;
1957 1957
      while (readLine() && line >> c && c != '@') {
1958 1958
        line.putback(c);
1959 1959

	
1960 1960
        std::string attr, token;
1961 1961
        if (!_reader_bits::readToken(line, attr))
1962 1962
          throw FormatError("Attribute name not found");
1963 1963
        if (!_reader_bits::readToken(line, token))
1964 1964
          throw FormatError("Attribute value not found");
1965 1965
        if (line >> c)
1966 1966
          throw FormatError("Extra character at the end of line");
1967 1967

	
1968 1968
        {
1969 1969
          std::set<std::string>::iterator it = read_attr.find(attr);
1970 1970
          if (it != read_attr.end()) {
1971 1971
            std::ostringstream msg;
1972 1972
            msg << "Multiple occurence of attribute: " << attr;
1973 1973
            throw FormatError(msg.str());
1974 1974
          }
1975 1975
          read_attr.insert(attr);
1976 1976
        }
1977 1977

	
1978 1978
        {
1979 1979
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1980 1980
          while (it != _attributes.end() && it->first == attr) {
1981 1981
            it->second->set(token);
1982 1982
            ++it;
1983 1983
          }
1984 1984
        }
1985 1985

	
1986 1986
      }
1987 1987
      if (readSuccess()) {
1988 1988
        line.putback(c);
1989 1989
      }
1990 1990
      for (typename Attributes::iterator it = _attributes.begin();
1991 1991
           it != _attributes.end(); ++it) {
1992 1992
        if (read_attr.find(it->first) == read_attr.end()) {
1993 1993
          std::ostringstream msg;
1994 1994
          msg << "Attribute not found: " << it->first;
1995 1995
          throw FormatError(msg.str());
1996 1996
        }
1997 1997
      }
1998 1998
    }
1999 1999

	
2000 2000
  public:
2001 2001

	
2002 2002
    /// \name Execution of the Reader
2003 2003
    /// @{
2004 2004

	
2005 2005
    /// \brief Start the batch processing
2006 2006
    ///
2007 2007
    /// This function starts the batch processing
2008 2008
    void run() {
2009 2009

	
2010 2010
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2011 2011

	
2012 2012
      bool nodes_done = _skip_nodes;
2013 2013
      bool edges_done = _skip_edges;
2014 2014
      bool attributes_done = false;
2015 2015

	
2016 2016
      line_num = 0;
2017 2017
      readLine();
2018 2018
      skipSection();
2019 2019

	
2020 2020
      while (readSuccess()) {
2021 2021
        try {
2022 2022
          char c;
2023 2023
          std::string section, caption;
2024 2024
          line >> c;
2025 2025
          _reader_bits::readToken(line, section);
2026 2026
          _reader_bits::readToken(line, caption);
2027 2027

	
2028 2028
          if (line >> c)
2029 2029
            throw FormatError("Extra character at the end of line");
2030 2030

	
2031 2031
          if (section == "nodes" && !nodes_done) {
2032 2032
            if (_nodes_caption.empty() || _nodes_caption == caption) {
2033 2033
              readNodes();
2034 2034
              nodes_done = true;
2035 2035
            }
2036 2036
          } else if ((section == "edges" || section == "arcs") &&
2037 2037
                     !edges_done) {
2038 2038
            if (_edges_caption.empty() || _edges_caption == caption) {
2039 2039
              readEdges();
2040 2040
              edges_done = true;
2041 2041
            }
2042 2042
          } else if (section == "attributes" && !attributes_done) {
2043 2043
            if (_attributes_caption.empty() || _attributes_caption == caption) {
2044 2044
              readAttributes();
2045 2045
              attributes_done = true;
2046 2046
            }
2047 2047
          } else {
2048 2048
            readLine();
2049 2049
            skipSection();
2050 2050
          }
2051 2051
        } catch (FormatError& error) {
2052 2052
          error.line(line_num);
2053 2053
          error.file(_filename);
2054 2054
          throw;
2055 2055
        }
2056 2056
      }
2057 2057

	
2058 2058
      if (!nodes_done) {
2059 2059
        throw FormatError("Section @nodes not found");
2060 2060
      }
2061 2061

	
2062 2062
      if (!edges_done) {
2063 2063
        throw FormatError("Section @edges not found");
2064 2064
      }
2065 2065

	
2066 2066
      if (!attributes_done && !_attributes.empty()) {
2067 2067
        throw FormatError("Section @attributes not found");
2068 2068
      }
2069 2069

	
2070 2070
    }
2071 2071

	
2072 2072
    /// @}
2073 2073

	
2074 2074
  };
2075 2075

	
2076 2076
  /// \ingroup lemon_io
2077 2077
  ///
2078 2078
  /// \brief Return a \ref GraphReader class
2079 2079
  ///
2080
  /// This function just returns a \ref GraphReader class. 
2080
  /// This function just returns a \ref GraphReader class.
2081 2081
  ///
2082
  /// With this function a graph can be read from an 
2082
  /// With this function a graph can be read from an
2083 2083
  /// \ref lgf-format "LGF" file or input stream with several maps and
2084 2084
  /// attributes. For example, there is weighted matching problem on a
2085 2085
  /// graph, i.e. a graph with a \e weight map on the edges. This
2086 2086
  /// graph can be read with the following code:
2087 2087
  ///
2088 2088
  ///\code
2089 2089
  ///ListGraph graph;
2090 2090
  ///ListGraph::EdgeMap<int> weight(graph);
2091 2091
  ///graphReader(graph, std::cin).
2092 2092
  ///  edgeMap("weight", weight).
2093 2093
  ///  run();
2094 2094
  ///\endcode
2095 2095
  ///
2096 2096
  /// For a complete documentation, please see the \ref GraphReader
2097 2097
  /// class documentation.
2098 2098
  /// \warning Don't forget to put the \ref GraphReader::run() "run()"
2099 2099
  /// to the end of the parameter list.
2100 2100
  /// \relates GraphReader
2101 2101
  /// \sa graphReader(TGR& graph, const std::string& fn)
2102 2102
  /// \sa graphReader(TGR& graph, const char* fn)
2103 2103
  template <typename TGR>
2104 2104
  GraphReader<TGR> graphReader(TGR& graph, std::istream& is) {
2105 2105
    GraphReader<TGR> tmp(graph, is);
2106 2106
    return tmp;
2107 2107
  }
2108 2108

	
2109 2109
  /// \brief Return a \ref GraphReader class
2110 2110
  ///
2111 2111
  /// This function just returns a \ref GraphReader class.
2112 2112
  /// \relates GraphReader
2113 2113
  /// \sa graphReader(TGR& graph, std::istream& is)
2114 2114
  template <typename TGR>
2115 2115
  GraphReader<TGR> graphReader(TGR& graph, const std::string& fn) {
2116 2116
    GraphReader<TGR> tmp(graph, fn);
2117 2117
    return tmp;
2118 2118
  }
2119 2119

	
2120 2120
  /// \brief Return a \ref GraphReader class
2121 2121
  ///
2122 2122
  /// This function just returns a \ref GraphReader class.
2123 2123
  /// \relates GraphReader
2124 2124
  /// \sa graphReader(TGR& graph, std::istream& is)
2125 2125
  template <typename TGR>
2126 2126
  GraphReader<TGR> graphReader(TGR& graph, const char* fn) {
2127 2127
    GraphReader<TGR> tmp(graph, fn);
2128 2128
    return tmp;
2129 2129
  }
2130 2130

	
2131 2131
  class SectionReader;
2132 2132

	
2133 2133
  SectionReader sectionReader(std::istream& is);
2134 2134
  SectionReader sectionReader(const std::string& fn);
2135 2135
  SectionReader sectionReader(const char* fn);
2136 2136

	
2137 2137
  /// \ingroup lemon_io
2138 2138
  ///
2139 2139
  /// \brief Section reader class
2140 2140
  ///
2141 2141
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
2142 2142
  /// which contain any data in arbitrary format. Such sections can be
2143 2143
  /// read with this class. A reading rule can be added to the class
2144 2144
  /// with two different functions. With the \c sectionLines() function a
2145 2145
  /// functor can process the section line-by-line, while with the \c
2146 2146
  /// sectionStream() member the section can be read from an input
2147 2147
  /// stream.
2148 2148
  class SectionReader {
2149 2149
  private:
2150 2150

	
2151 2151
    std::istream* _is;
2152 2152
    bool local_is;
2153 2153
    std::string _filename;
2154 2154

	
2155 2155
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2156 2156
    Sections _sections;
2157 2157

	
2158 2158
    int line_num;
2159 2159
    std::istringstream line;
2160 2160

	
2161 2161
  public:
2162 2162

	
2163 2163
    /// \brief Constructor
2164 2164
    ///
2165 2165
    /// Construct a section reader, which reads from the given input
2166 2166
    /// stream.
2167 2167
    SectionReader(std::istream& is)
2168 2168
      : _is(&is), local_is(false) {}
2169 2169

	
2170 2170
    /// \brief Constructor
2171 2171
    ///
2172 2172
    /// Construct a section reader, which reads from the given file.
2173 2173
    SectionReader(const std::string& fn)
2174 2174
      : _is(new std::ifstream(fn.c_str())), local_is(true),
2175 2175
        _filename(fn) {
2176 2176
      if (!(*_is)) {
2177 2177
        delete _is;
2178 2178
        throw IoError("Cannot open file", fn);
2179 2179
      }
2180 2180
    }
2181 2181

	
2182 2182
    /// \brief Constructor
2183 2183
    ///
2184 2184
    /// Construct a section reader, which reads from the given file.
2185 2185
    SectionReader(const char* fn)
2186 2186
      : _is(new std::ifstream(fn)), local_is(true),
2187 2187
        _filename(fn) {
2188 2188
      if (!(*_is)) {
2189 2189
        delete _is;
2190 2190
        throw IoError("Cannot open file", fn);
2191 2191
      }
2192 2192
    }
2193 2193

	
2194 2194
    /// \brief Destructor
2195 2195
    ~SectionReader() {
2196 2196
      for (Sections::iterator it = _sections.begin();
2197 2197
           it != _sections.end(); ++it) {
2198 2198
        delete it->second;
2199 2199
      }
2200 2200

	
2201 2201
      if (local_is) {
2202 2202
        delete _is;
2203 2203
      }
2204 2204

	
2205 2205
    }
2206 2206

	
2207 2207
  private:
2208 2208

	
2209 2209
    friend SectionReader sectionReader(std::istream& is);
2210 2210
    friend SectionReader sectionReader(const std::string& fn);
2211 2211
    friend SectionReader sectionReader(const char* fn);
2212 2212

	
2213 2213
    SectionReader(SectionReader& other)
2214 2214
      : _is(other._is), local_is(other.local_is) {
2215 2215

	
2216 2216
      other._is = 0;
2217 2217
      other.local_is = false;
2218 2218

	
2219 2219
      _sections.swap(other._sections);
2220 2220
    }
2221 2221

	
2222 2222
    SectionReader& operator=(const SectionReader&);
2223 2223

	
2224 2224
  public:
2225 2225

	
2226 2226
    /// \name Section Readers
2227 2227
    /// @{
2228 2228

	
2229 2229
    /// \brief Add a section processor with line oriented reading
2230 2230
    ///
2231 2231
    /// The first parameter is the type descriptor of the section, the
2232 2232
    /// second is a functor, which takes just one \c std::string
2233 2233
    /// parameter. At the reading process, each line of the section
2234 2234
    /// will be given to the functor object. However, the empty lines
2235 2235
    /// and the comment lines are filtered out, and the leading
2236 2236
    /// whitespaces are trimmed from each processed string.
2237 2237
    ///
2238
    /// For example let's see a section, which contain several
2238
    /// For example, let's see a section, which contain several
2239 2239
    /// integers, which should be inserted into a vector.
2240 2240
    ///\code
2241 2241
    ///  @numbers
2242 2242
    ///  12 45 23
2243 2243
    ///  4
2244 2244
    ///  23 6
2245 2245
    ///\endcode
2246 2246
    ///
2247 2247
    /// The functor is implemented as a struct:
2248 2248
    ///\code
2249 2249
    ///  struct NumberSection {
2250 2250
    ///    std::vector<int>& _data;
2251 2251
    ///    NumberSection(std::vector<int>& data) : _data(data) {}
2252 2252
    ///    void operator()(const std::string& line) {
2253 2253
    ///      std::istringstream ls(line);
2254 2254
    ///      int value;
2255 2255
    ///      while (ls >> value) _data.push_back(value);
2256 2256
    ///    }
2257 2257
    ///  };
2258 2258
    ///
2259 2259
    ///  // ...
2260 2260
    ///
2261 2261
    ///  reader.sectionLines("numbers", NumberSection(vec));
2262 2262
    ///\endcode
2263 2263
    template <typename Functor>
2264 2264
    SectionReader& sectionLines(const std::string& type, Functor functor) {
2265 2265
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2266 2266
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2267 2267
                   "Multiple reading of section.");
2268 2268
      _sections.insert(std::make_pair(type,
2269 2269
        new _reader_bits::LineSection<Functor>(functor)));
2270 2270
      return *this;
2271 2271
    }
2272 2272

	
2273 2273

	
2274 2274
    /// \brief Add a section processor with stream oriented reading
2275 2275
    ///
2276 2276
    /// The first parameter is the type of the section, the second is
2277 2277
    /// a functor, which takes an \c std::istream& and an \c int&
2278 2278
    /// parameter, the latter regard to the line number of stream. The
2279 2279
    /// functor can read the input while the section go on, and the
2280 2280
    /// line number should be modified accordingly.
2281 2281
    template <typename Functor>
2282 2282
    SectionReader& sectionStream(const std::string& type, Functor functor) {
2283 2283
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2284 2284
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2285 2285
                   "Multiple reading of section.");
2286 2286
      _sections.insert(std::make_pair(type,
2287 2287
         new _reader_bits::StreamSection<Functor>(functor)));
2288 2288
      return *this;
2289 2289
    }
2290 2290

	
2291 2291
    /// @}
2292 2292

	
2293 2293
  private:
2294 2294

	
2295 2295
    bool readLine() {
2296 2296
      std::string str;
2297 2297
      while(++line_num, std::getline(*_is, str)) {
2298 2298
        line.clear(); line.str(str);
2299 2299
        char c;
2300 2300
        if (line >> std::ws >> c && c != '#') {
2301 2301
          line.putback(c);
2302 2302
          return true;
2303 2303
        }
2304 2304
      }
2305 2305
      return false;
2306 2306
    }
2307 2307

	
2308 2308
    bool readSuccess() {
2309 2309
      return static_cast<bool>(*_is);
2310 2310
    }
2311 2311

	
2312 2312
    void skipSection() {
2313 2313
      char c;
2314 2314
      while (readSuccess() && line >> c && c != '@') {
2315 2315
        readLine();
2316 2316
      }
2317 2317
      if (readSuccess()) {
2318 2318
        line.putback(c);
2319 2319
      }
2320 2320
    }
2321 2321

	
2322 2322
  public:
2323 2323

	
2324 2324

	
2325 2325
    /// \name Execution of the Reader
2326 2326
    /// @{
2327 2327

	
2328 2328
    /// \brief Start the batch processing
2329 2329
    ///
2330 2330
    /// This function starts the batch processing.
2331 2331
    void run() {
2332 2332

	
2333 2333
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2334 2334

	
2335 2335
      std::set<std::string> extra_sections;
2336 2336

	
2337 2337
      line_num = 0;
2338 2338
      readLine();
2339 2339
      skipSection();
2340 2340

	
2341 2341
      while (readSuccess()) {
2342 2342
        try {
2343 2343
          char c;
2344 2344
          std::string section, caption;
2345 2345
          line >> c;
2346 2346
          _reader_bits::readToken(line, section);
2347 2347
          _reader_bits::readToken(line, caption);
2348 2348

	
2349 2349
          if (line >> c)
2350 2350
            throw FormatError("Extra character at the end of line");
2351 2351

	
2352 2352
          if (extra_sections.find(section) != extra_sections.end()) {
2353 2353
            std::ostringstream msg;
2354 2354
            msg << "Multiple occurence of section: " << section;
2355 2355
            throw FormatError(msg.str());
2356 2356
          }
2357 2357
          Sections::iterator it = _sections.find(section);
2358 2358
          if (it != _sections.end()) {
2359 2359
            extra_sections.insert(section);
2360 2360
            it->second->process(*_is, line_num);
2361 2361
          }
2362 2362
          readLine();
2363 2363
          skipSection();
2364 2364
        } catch (FormatError& error) {
2365 2365
          error.line(line_num);
2366 2366
          error.file(_filename);
2367 2367
          throw;
2368 2368
        }
2369 2369
      }
2370 2370
      for (Sections::iterator it = _sections.begin();
2371 2371
           it != _sections.end(); ++it) {
2372 2372
        if (extra_sections.find(it->first) == extra_sections.end()) {
2373 2373
          std::ostringstream os;
2374 2374
          os << "Cannot find section: " << it->first;
2375 2375
          throw FormatError(os.str());
2376 2376
        }
2377 2377
      }
2378 2378
    }
2379 2379

	
2380 2380
    /// @}
2381 2381

	
2382 2382
  };
2383 2383

	
2384 2384
  /// \ingroup lemon_io
2385 2385
  ///
2386 2386
  /// \brief Return a \ref SectionReader class
2387 2387
  ///
2388 2388
  /// This function just returns a \ref SectionReader class.
2389 2389
  ///
2390 2390
  /// Please see SectionReader documentation about the custom section
2391 2391
  /// input.
2392 2392
  ///
2393 2393
  /// \relates SectionReader
2394 2394
  /// \sa sectionReader(const std::string& fn)
2395 2395
  /// \sa sectionReader(const char *fn)
2396 2396
  inline SectionReader sectionReader(std::istream& is) {
2397 2397
    SectionReader tmp(is);
2398 2398
    return tmp;
2399 2399
  }
2400 2400

	
2401 2401
  /// \brief Return a \ref SectionReader class
2402 2402
  ///
2403 2403
  /// This function just returns a \ref SectionReader class.
2404 2404
  /// \relates SectionReader
2405 2405
  /// \sa sectionReader(std::istream& is)
2406 2406
  inline SectionReader sectionReader(const std::string& fn) {
2407 2407
    SectionReader tmp(fn);
2408 2408
    return tmp;
2409 2409
  }
2410 2410

	
2411 2411
  /// \brief Return a \ref SectionReader class
2412 2412
  ///
2413 2413
  /// This function just returns a \ref SectionReader class.
2414 2414
  /// \relates SectionReader
2415 2415
  /// \sa sectionReader(std::istream& is)
2416 2416
  inline SectionReader sectionReader(const char* fn) {
2417 2417
    SectionReader tmp(fn);
2418 2418
    return tmp;
2419 2419
  }
2420 2420

	
2421 2421
  /// \ingroup lemon_io
2422 2422
  ///
2423 2423
  /// \brief Reader for the contents of the \ref lgf-format "LGF" file
2424 2424
  ///
2425 2425
  /// This class can be used to read the sections, the map names and
2426 2426
  /// the attributes from a file. Usually, the LEMON programs know
2427 2427
  /// that, which type of graph, which maps and which attributes
2428 2428
  /// should be read from a file, but in general tools (like glemon)
2429 2429
  /// the contents of an LGF file should be guessed somehow. This class
2430 2430
  /// reads the graph and stores the appropriate information for
2431 2431
  /// reading the graph.
2432 2432
  ///
2433 2433
  ///\code
2434 2434
  /// LgfContents contents("graph.lgf");
2435 2435
  /// contents.run();
2436 2436
  ///
2437 2437
  /// // Does it contain any node section and arc section?
2438 2438
  /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
2439 2439
  ///   std::cerr << "Failure, cannot find graph." << std::endl;
2440 2440
  ///   return -1;
2441 2441
  /// }
2442 2442
  /// std::cout << "The name of the default node section: "
2443 2443
  ///           << contents.nodeSection(0) << std::endl;
2444 2444
  /// std::cout << "The number of the arc maps: "
2445 2445
  ///           << contents.arcMaps(0).size() << std::endl;
2446 2446
  /// std::cout << "The name of second arc map: "
2447 2447
  ///           << contents.arcMaps(0)[1] << std::endl;
2448 2448
  ///\endcode
2449 2449
  class LgfContents {
2450 2450
  private:
2451 2451

	
2452 2452
    std::istream* _is;
2453 2453
    bool local_is;
2454 2454

	
2455 2455
    std::vector<std::string> _node_sections;
2456 2456
    std::vector<std::string> _edge_sections;
2457 2457
    std::vector<std::string> _attribute_sections;
2458 2458
    std::vector<std::string> _extra_sections;
2459 2459

	
2460 2460
    std::vector<bool> _arc_sections;
2461 2461

	
2462 2462
    std::vector<std::vector<std::string> > _node_maps;
2463 2463
    std::vector<std::vector<std::string> > _edge_maps;
2464 2464

	
2465 2465
    std::vector<std::vector<std::string> > _attributes;
2466 2466

	
2467 2467

	
2468 2468
    int line_num;
2469 2469
    std::istringstream line;
2470 2470

	
2471 2471
  public:
2472 2472

	
2473 2473
    /// \brief Constructor
2474 2474
    ///
2475 2475
    /// Construct an \e LGF contents reader, which reads from the given
2476 2476
    /// input stream.
2477 2477
    LgfContents(std::istream& is)
2478 2478
      : _is(&is), local_is(false) {}
2479 2479

	
2480 2480
    /// \brief Constructor
2481 2481
    ///
2482 2482
    /// Construct an \e LGF contents reader, which reads from the given
2483 2483
    /// file.
2484 2484
    LgfContents(const std::string& fn)
2485 2485
      : _is(new std::ifstream(fn.c_str())), local_is(true) {
2486 2486
      if (!(*_is)) {
2487 2487
        delete _is;
2488 2488
        throw IoError("Cannot open file", fn);
2489 2489
      }
2490 2490
    }
2491 2491

	
2492 2492
    /// \brief Constructor
2493 2493
    ///
2494 2494
    /// Construct an \e LGF contents reader, which reads from the given
2495 2495
    /// file.
2496 2496
    LgfContents(const char* fn)
2497 2497
      : _is(new std::ifstream(fn)), local_is(true) {
2498 2498
      if (!(*_is)) {
2499 2499
        delete _is;
2500 2500
        throw IoError("Cannot open file", fn);
2501 2501
      }
2502 2502
    }
2503 2503

	
2504 2504
    /// \brief Destructor
2505 2505
    ~LgfContents() {
2506 2506
      if (local_is) delete _is;
2507 2507
    }
2508 2508

	
2509 2509
  private:
2510 2510

	
2511 2511
    LgfContents(const LgfContents&);
2512 2512
    LgfContents& operator=(const LgfContents&);
2513 2513

	
2514 2514
  public:
2515 2515

	
2516 2516

	
2517 2517
    /// \name Node Sections
2518 2518
    /// @{
2519 2519

	
2520 2520
    /// \brief Gives back the number of node sections in the file.
2521 2521
    ///
2522 2522
    /// Gives back the number of node sections in the file.
2523 2523
    int nodeSectionNum() const {
2524 2524
      return _node_sections.size();
2525 2525
    }
2526 2526

	
2527 2527
    /// \brief Returns the node section name at the given position.
2528 2528
    ///
2529 2529
    /// Returns the node section name at the given position.
2530 2530
    const std::string& nodeSection(int i) const {
2531 2531
      return _node_sections[i];
2532 2532
    }
2533 2533

	
2534 2534
    /// \brief Gives back the node maps for the given section.
2535 2535
    ///
2536 2536
    /// Gives back the node maps for the given section.
2537 2537
    const std::vector<std::string>& nodeMapNames(int i) const {
2538 2538
      return _node_maps[i];
2539 2539
    }
2540 2540

	
2541 2541
    /// @}
2542 2542

	
2543 2543
    /// \name Arc/Edge Sections
2544 2544
    /// @{
2545 2545

	
2546 2546
    /// \brief Gives back the number of arc/edge sections in the file.
2547 2547
    ///
2548 2548
    /// Gives back the number of arc/edge sections in the file.
2549 2549
    /// \note It is synonym of \c edgeSectionNum().
2550 2550
    int arcSectionNum() const {
2551 2551
      return _edge_sections.size();
2552 2552
    }
2553 2553

	
2554 2554
    /// \brief Returns the arc/edge section name at the given position.
2555 2555
    ///
2556 2556
    /// Returns the arc/edge section name at the given position.
2557 2557
    /// \note It is synonym of \c edgeSection().
2558 2558
    const std::string& arcSection(int i) const {
2559 2559
      return _edge_sections[i];
2560 2560
    }
2561 2561

	
2562 2562
    /// \brief Gives back the arc/edge maps for the given section.
2563 2563
    ///
2564 2564
    /// Gives back the arc/edge maps for the given section.
2565 2565
    /// \note It is synonym of \c edgeMapNames().
2566 2566
    const std::vector<std::string>& arcMapNames(int i) const {
2567 2567
      return _edge_maps[i];
2568 2568
    }
2569 2569

	
2570 2570
    /// @}
2571 2571

	
2572 2572
    /// \name Synonyms
2573 2573
    /// @{
2574 2574

	
2575 2575
    /// \brief Gives back the number of arc/edge sections in the file.
2576 2576
    ///
2577 2577
    /// Gives back the number of arc/edge sections in the file.
2578 2578
    /// \note It is synonym of \c arcSectionNum().
2579 2579
    int edgeSectionNum() const {
2580 2580
      return _edge_sections.size();
2581 2581
    }
2582 2582

	
2583 2583
    /// \brief Returns the section name at the given position.
2584 2584
    ///
2585 2585
    /// Returns the section name at the given position.
2586 2586
    /// \note It is synonym of \c arcSection().
2587 2587
    const std::string& edgeSection(int i) const {
2588 2588
      return _edge_sections[i];
2589 2589
    }
2590 2590

	
2591 2591
    /// \brief Gives back the edge maps for the given section.
2592 2592
    ///
2593 2593
    /// Gives back the edge maps for the given section.
2594 2594
    /// \note It is synonym of \c arcMapNames().
2595 2595
    const std::vector<std::string>& edgeMapNames(int i) const {
2596 2596
      return _edge_maps[i];
2597 2597
    }
2598 2598

	
2599 2599
    /// @}
2600 2600

	
2601 2601
    /// \name Attribute Sections
2602 2602
    /// @{
2603 2603

	
2604 2604
    /// \brief Gives back the number of attribute sections in the file.
2605 2605
    ///
2606 2606
    /// Gives back the number of attribute sections in the file.
2607 2607
    int attributeSectionNum() const {
2608 2608
      return _attribute_sections.size();
2609 2609
    }
2610 2610

	
2611 2611
    /// \brief Returns the attribute section name at the given position.
2612 2612
    ///
2613 2613
    /// Returns the attribute section name at the given position.
2614 2614
    const std::string& attributeSectionNames(int i) const {
2615 2615
      return _attribute_sections[i];
2616 2616
    }
2617 2617

	
2618 2618
    /// \brief Gives back the attributes for the given section.
2619 2619
    ///
2620 2620
    /// Gives back the attributes for the given section.
2621 2621
    const std::vector<std::string>& attributes(int i) const {
2622 2622
      return _attributes[i];
2623 2623
    }
2624 2624

	
2625 2625
    /// @}
2626 2626

	
2627 2627
    /// \name Extra Sections
2628 2628
    /// @{
2629 2629

	
2630 2630
    /// \brief Gives back the number of extra sections in the file.
2631 2631
    ///
2632 2632
    /// Gives back the number of extra sections in the file.
2633 2633
    int extraSectionNum() const {
2634 2634
      return _extra_sections.size();
2635 2635
    }
2636 2636

	
2637 2637
    /// \brief Returns the extra section type at the given position.
2638 2638
    ///
2639 2639
    /// Returns the section type at the given position.
2640 2640
    const std::string& extraSection(int i) const {
2641 2641
      return _extra_sections[i];
2642 2642
    }
2643 2643

	
2644 2644
    /// @}
2645 2645

	
2646 2646
  private:
2647 2647

	
2648 2648
    bool readLine() {
2649 2649
      std::string str;
2650 2650
      while(++line_num, std::getline(*_is, str)) {
2651 2651
        line.clear(); line.str(str);
2652 2652
        char c;
2653 2653
        if (line >> std::ws >> c && c != '#') {
2654 2654
          line.putback(c);
2655 2655
          return true;
2656 2656
        }
2657 2657
      }
2658 2658
      return false;
2659 2659
    }
2660 2660

	
2661 2661
    bool readSuccess() {
2662 2662
      return static_cast<bool>(*_is);
2663 2663
    }
2664 2664

	
2665 2665
    void skipSection() {
2666 2666
      char c;
2667 2667
      while (readSuccess() && line >> c && c != '@') {
2668 2668
        readLine();
2669 2669
      }
2670 2670
      if (readSuccess()) {
2671 2671
        line.putback(c);
2672 2672
      }
2673 2673
    }
2674 2674

	
2675 2675
    void readMaps(std::vector<std::string>& maps) {
2676 2676
      char c;
2677 2677
      if (!readLine() || !(line >> c) || c == '@') {
2678 2678
        if (readSuccess() && line) line.putback(c);
2679 2679
        return;
2680 2680
      }
2681 2681
      line.putback(c);
2682 2682
      std::string map;
2683 2683
      while (_reader_bits::readToken(line, map)) {
2684 2684
        maps.push_back(map);
2685 2685
      }
2686 2686
    }
2687 2687

	
2688 2688
    void readAttributes(std::vector<std::string>& attrs) {
2689 2689
      readLine();
2690 2690
      char c;
2691 2691
      while (readSuccess() && line >> c && c != '@') {
2692 2692
        line.putback(c);
2693 2693
        std::string attr;
2694 2694
        _reader_bits::readToken(line, attr);
2695 2695
        attrs.push_back(attr);
2696 2696
        readLine();
2697 2697
      }
2698 2698
      line.putback(c);
2699 2699
    }
2700 2700

	
2701 2701
  public:
2702 2702

	
2703 2703
    /// \name Execution of the Contents Reader
2704 2704
    /// @{
2705 2705

	
2706 2706
    /// \brief Starts the reading
2707 2707
    ///
2708 2708
    /// This function starts the reading.
2709 2709
    void run() {
2710 2710

	
2711 2711
      readLine();
2712 2712
      skipSection();
2713 2713

	
2714 2714
      while (readSuccess()) {
2715 2715

	
2716 2716
        char c;
2717 2717
        line >> c;
2718 2718

	
2719 2719
        std::string section, caption;
2720 2720
        _reader_bits::readToken(line, section);
2721 2721
        _reader_bits::readToken(line, caption);
2722 2722

	
2723 2723
        if (section == "nodes") {
2724 2724
          _node_sections.push_back(caption);
2725 2725
          _node_maps.push_back(std::vector<std::string>());
2726 2726
          readMaps(_node_maps.back());
2727 2727
          readLine(); skipSection();
2728 2728
        } else if (section == "arcs" || section == "edges") {
2729 2729
          _edge_sections.push_back(caption);
2730 2730
          _arc_sections.push_back(section == "arcs");
2731 2731
          _edge_maps.push_back(std::vector<std::string>());
2732 2732
          readMaps(_edge_maps.back());
2733 2733
          readLine(); skipSection();
2734 2734
        } else if (section == "attributes") {
2735 2735
          _attribute_sections.push_back(caption);
2736 2736
          _attributes.push_back(std::vector<std::string>());
2737 2737
          readAttributes(_attributes.back());
2738 2738
        } else {
2739 2739
          _extra_sections.push_back(section);
2740 2740
          readLine(); skipSection();
2741 2741
        }
2742 2742
      }
2743 2743
    }
2744 2744

	
2745 2745
    /// @}
2746 2746

	
2747 2747
  };
2748 2748
}
2749 2749

	
2750 2750
#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-2009
5
 * Copyright (C) 2003-2010
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 350
  template <typename DGR>
351 351
  class DigraphWriter;
352 352

	
353 353
  template <typename TDGR>
354
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
354
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
355 355
                                   std::ostream& os = std::cout);
356 356
  template <typename TDGR>
357 357
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const std::string& fn);
358 358

	
359 359
  template <typename TDGR>
360 360
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn);
361 361

	
362 362

	
363 363
  /// \ingroup lemon_io
364 364
  ///
365 365
  /// \brief \ref lgf-format "LGF" writer for directed graphs
366 366
  ///
367 367
  /// This utility writes an \ref lgf-format "LGF" file.
368 368
  ///
369 369
  /// The writing method does a batch processing. The user creates a
370 370
  /// writer object, then various writing rules can be added to the
371 371
  /// writer, and eventually the writing is executed with the \c run()
372 372
  /// member function. A map writing rule can be added to the writer
373 373
  /// with the \c nodeMap() or \c arcMap() members. An optional
374 374
  /// converter parameter can also be added as a standard functor
375 375
  /// converting from the value type of the map to \c std::string. If it
376 376
  /// is set, it will determine how the value type of the map is written to
377 377
  /// the output stream. If the functor is not set, then a default
378 378
  /// conversion will be used. The \c attribute(), \c node() and \c
379 379
  /// arc() functions are used to add attribute writing rules.
380 380
  ///
381 381
  ///\code
382 382
  /// DigraphWriter<DGR>(digraph, std::cout).
383 383
  ///   nodeMap("coordinates", coord_map).
384 384
  ///   nodeMap("size", size).
385 385
  ///   nodeMap("title", title).
386 386
  ///   arcMap("capacity", cap_map).
387 387
  ///   node("source", src).
388 388
  ///   node("target", trg).
389 389
  ///   attribute("caption", caption).
390 390
  ///   run();
391 391
  ///\endcode
392 392
  ///
393 393
  ///
394 394
  /// By default, the writer does not write additional captions to the
395 395
  /// sections, but they can be give as an optional parameter of
396 396
  /// the \c nodes(), \c arcs() or \c
397 397
  /// attributes() functions.
398 398
  ///
399 399
  /// The \c skipNodes() and \c skipArcs() functions forbid the
400 400
  /// writing of the sections. If two arc sections should be written
401 401
  /// to the output, it can be done in two passes, the first pass
402 402
  /// writes the node section and the first arc section, then the
403 403
  /// second pass skips the node section and writes just the arc
404 404
  /// section to the stream. The output stream can be retrieved with
405 405
  /// the \c ostream() function, hence the second pass can append its
406 406
  /// output to the output of the first pass.
407 407
  template <typename DGR>
408 408
  class DigraphWriter {
409 409
  public:
410 410

	
411 411
    typedef DGR Digraph;
412 412
    TEMPLATE_DIGRAPH_TYPEDEFS(DGR);
413 413

	
414 414
  private:
415 415

	
416 416

	
417 417
    std::ostream* _os;
418 418
    bool local_os;
419 419

	
420 420
    const DGR& _digraph;
421 421

	
422 422
    std::string _nodes_caption;
423 423
    std::string _arcs_caption;
424 424
    std::string _attributes_caption;
425 425

	
426 426
    typedef std::map<Node, std::string> NodeIndex;
427 427
    NodeIndex _node_index;
428 428
    typedef std::map<Arc, std::string> ArcIndex;
429 429
    ArcIndex _arc_index;
430 430

	
431 431
    typedef std::vector<std::pair<std::string,
432 432
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
433 433
    NodeMaps _node_maps;
434 434

	
435 435
    typedef std::vector<std::pair<std::string,
436 436
      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
437 437
    ArcMaps _arc_maps;
438 438

	
439 439
    typedef std::vector<std::pair<std::string,
440 440
      _writer_bits::ValueStorageBase*> > Attributes;
441 441
    Attributes _attributes;
442 442

	
443 443
    bool _skip_nodes;
444 444
    bool _skip_arcs;
445 445

	
446 446
  public:
447 447

	
448 448
    /// \brief Constructor
449 449
    ///
450 450
    /// Construct a directed graph writer, which writes to the given
451 451
    /// output stream.
452 452
    DigraphWriter(const DGR& digraph, std::ostream& os = std::cout)
453 453
      : _os(&os), local_os(false), _digraph(digraph),
454 454
        _skip_nodes(false), _skip_arcs(false) {}
455 455

	
456 456
    /// \brief Constructor
457 457
    ///
458 458
    /// Construct a directed graph writer, which writes to the given
459 459
    /// output file.
460 460
    DigraphWriter(const DGR& digraph, const std::string& fn)
461 461
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
462 462
        _skip_nodes(false), _skip_arcs(false) {
463 463
      if (!(*_os)) {
464 464
        delete _os;
465 465
        throw IoError("Cannot write file", fn);
466 466
      }
467 467
    }
468 468

	
469 469
    /// \brief Constructor
470 470
    ///
471 471
    /// Construct a directed graph writer, which writes to the given
472 472
    /// output file.
473 473
    DigraphWriter(const DGR& digraph, const char* fn)
474 474
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
475 475
        _skip_nodes(false), _skip_arcs(false) {
476 476
      if (!(*_os)) {
477 477
        delete _os;
478 478
        throw IoError("Cannot write file", fn);
479 479
      }
480 480
    }
481 481

	
482 482
    /// \brief Destructor
483 483
    ~DigraphWriter() {
484 484
      for (typename NodeMaps::iterator it = _node_maps.begin();
485 485
           it != _node_maps.end(); ++it) {
486 486
        delete it->second;
487 487
      }
488 488

	
489 489
      for (typename ArcMaps::iterator it = _arc_maps.begin();
490 490
           it != _arc_maps.end(); ++it) {
491 491
        delete it->second;
492 492
      }
493 493

	
494 494
      for (typename Attributes::iterator it = _attributes.begin();
495 495
           it != _attributes.end(); ++it) {
496 496
        delete it->second;
497 497
      }
498 498

	
499 499
      if (local_os) {
500 500
        delete _os;
501 501
      }
502 502
    }
503 503

	
504 504
  private:
505 505

	
506 506
    template <typename TDGR>
507
    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
507
    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
508 508
                                             std::ostream& os);
509 509
    template <typename TDGR>
510 510
    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
511 511
                                             const std::string& fn);
512 512
    template <typename TDGR>
513 513
    friend DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
514 514
                                             const char *fn);
515 515

	
516 516
    DigraphWriter(DigraphWriter& other)
517 517
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
518 518
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
519 519

	
520 520
      other._os = 0;
521 521
      other.local_os = false;
522 522

	
523 523
      _node_index.swap(other._node_index);
524 524
      _arc_index.swap(other._arc_index);
525 525

	
526 526
      _node_maps.swap(other._node_maps);
527 527
      _arc_maps.swap(other._arc_maps);
528 528
      _attributes.swap(other._attributes);
529 529

	
530 530
      _nodes_caption = other._nodes_caption;
531 531
      _arcs_caption = other._arcs_caption;
532 532
      _attributes_caption = other._attributes_caption;
533 533
    }
534 534

	
535 535
    DigraphWriter& operator=(const DigraphWriter&);
536 536

	
537 537
  public:
538 538

	
539 539
    /// \name Writing Rules
540 540
    /// @{
541 541

	
542 542
    /// \brief Node map writing rule
543 543
    ///
544 544
    /// Add a node map writing rule to the writer.
545 545
    template <typename Map>
546 546
    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
547 547
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
548 548
      _writer_bits::MapStorageBase<Node>* storage =
549 549
        new _writer_bits::MapStorage<Node, Map>(map);
550 550
      _node_maps.push_back(std::make_pair(caption, storage));
551 551
      return *this;
552 552
    }
553 553

	
554 554
    /// \brief Node map writing rule
555 555
    ///
556 556
    /// Add a node map writing rule with specialized converter to the
557 557
    /// writer.
558 558
    template <typename Map, typename Converter>
559 559
    DigraphWriter& nodeMap(const std::string& caption, const Map& map,
560 560
                           const Converter& converter = Converter()) {
561 561
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
562 562
      _writer_bits::MapStorageBase<Node>* storage =
563 563
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
564 564
      _node_maps.push_back(std::make_pair(caption, storage));
565 565
      return *this;
566 566
    }
567 567

	
568 568
    /// \brief Arc map writing rule
569 569
    ///
570 570
    /// Add an arc map writing rule to the writer.
571 571
    template <typename Map>
572 572
    DigraphWriter& arcMap(const std::string& caption, const Map& map) {
573 573
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
574 574
      _writer_bits::MapStorageBase<Arc>* storage =
575 575
        new _writer_bits::MapStorage<Arc, Map>(map);
576 576
      _arc_maps.push_back(std::make_pair(caption, storage));
577 577
      return *this;
578 578
    }
579 579

	
580 580
    /// \brief Arc map writing rule
581 581
    ///
582 582
    /// Add an arc map writing rule with specialized converter to the
583 583
    /// writer.
584 584
    template <typename Map, typename Converter>
585 585
    DigraphWriter& arcMap(const std::string& caption, const Map& map,
586 586
                          const Converter& converter = Converter()) {
587 587
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
588 588
      _writer_bits::MapStorageBase<Arc>* storage =
589 589
        new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
590 590
      _arc_maps.push_back(std::make_pair(caption, storage));
591 591
      return *this;
592 592
    }
593 593

	
594 594
    /// \brief Attribute writing rule
595 595
    ///
596 596
    /// Add an attribute writing rule to the writer.
597 597
    template <typename Value>
598 598
    DigraphWriter& attribute(const std::string& caption, const Value& value) {
599 599
      _writer_bits::ValueStorageBase* storage =
600 600
        new _writer_bits::ValueStorage<Value>(value);
601 601
      _attributes.push_back(std::make_pair(caption, storage));
602 602
      return *this;
603 603
    }
604 604

	
605 605
    /// \brief Attribute writing rule
606 606
    ///
607 607
    /// Add an attribute writing rule with specialized converter to the
608 608
    /// writer.
609 609
    template <typename Value, typename Converter>
610 610
    DigraphWriter& attribute(const std::string& caption, const Value& value,
611 611
                             const Converter& converter = Converter()) {
612 612
      _writer_bits::ValueStorageBase* storage =
613 613
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
614 614
      _attributes.push_back(std::make_pair(caption, storage));
615 615
      return *this;
616 616
    }
617 617

	
618 618
    /// \brief Node writing rule
619 619
    ///
620 620
    /// Add a node writing rule to the writer.
621 621
    DigraphWriter& node(const std::string& caption, const Node& node) {
622 622
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
623 623
      Converter converter(_node_index);
624 624
      _writer_bits::ValueStorageBase* storage =
625 625
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
626 626
      _attributes.push_back(std::make_pair(caption, storage));
627 627
      return *this;
628 628
    }
629 629

	
630 630
    /// \brief Arc writing rule
631 631
    ///
632 632
    /// Add an arc writing rule to writer.
633 633
    DigraphWriter& arc(const std::string& caption, const Arc& arc) {
634 634
      typedef _writer_bits::MapLookUpConverter<Arc> Converter;
635 635
      Converter converter(_arc_index);
636 636
      _writer_bits::ValueStorageBase* storage =
637 637
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
638 638
      _attributes.push_back(std::make_pair(caption, storage));
639 639
      return *this;
640 640
    }
641 641

	
642 642
    /// \name Section Captions
643 643
    /// @{
644 644

	
645 645
    /// \brief Add an additional caption to the \c \@nodes section
646 646
    ///
647 647
    /// Add an additional caption to the \c \@nodes section.
648 648
    DigraphWriter& nodes(const std::string& caption) {
649 649
      _nodes_caption = caption;
650 650
      return *this;
651 651
    }
652 652

	
653 653
    /// \brief Add an additional caption to the \c \@arcs section
654 654
    ///
655 655
    /// Add an additional caption to the \c \@arcs section.
656 656
    DigraphWriter& arcs(const std::string& caption) {
657 657
      _arcs_caption = caption;
658 658
      return *this;
659 659
    }
660 660

	
661 661
    /// \brief Add an additional caption to the \c \@attributes section
662 662
    ///
663 663
    /// Add an additional caption to the \c \@attributes section.
664 664
    DigraphWriter& attributes(const std::string& caption) {
665 665
      _attributes_caption = caption;
666 666
      return *this;
667 667
    }
668 668

	
669 669
    /// \name Skipping Section
670 670
    /// @{
671 671

	
672 672
    /// \brief Skip writing the node set
673 673
    ///
674 674
    /// The \c \@nodes section will not be written to the stream.
675 675
    DigraphWriter& skipNodes() {
676 676
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
677 677
      _skip_nodes = true;
678 678
      return *this;
679 679
    }
680 680

	
681 681
    /// \brief Skip writing arc set
682 682
    ///
683 683
    /// The \c \@arcs section will not be written to the stream.
684 684
    DigraphWriter& skipArcs() {
685 685
      LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
686 686
      _skip_arcs = true;
687 687
      return *this;
688 688
    }
689 689

	
690 690
    /// @}
691 691

	
692 692
  private:
693 693

	
694 694
    void writeNodes() {
695 695
      _writer_bits::MapStorageBase<Node>* label = 0;
696 696
      for (typename NodeMaps::iterator it = _node_maps.begin();
697 697
           it != _node_maps.end(); ++it) {
698 698
        if (it->first == "label") {
699 699
          label = it->second;
700 700
          break;
701 701
        }
702 702
      }
703 703

	
704 704
      *_os << "@nodes";
705 705
      if (!_nodes_caption.empty()) {
706 706
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
707 707
      }
708 708
      *_os << std::endl;
709 709

	
710 710
      if (label == 0) {
711 711
        *_os << "label" << '\t';
712 712
      }
713 713
      for (typename NodeMaps::iterator it = _node_maps.begin();
714 714
           it != _node_maps.end(); ++it) {
715 715
        _writer_bits::writeToken(*_os, it->first) << '\t';
716 716
      }
717 717
      *_os << std::endl;
718 718

	
719 719
      std::vector<Node> nodes;
720 720
      for (NodeIt n(_digraph); n != INVALID; ++n) {
721 721
        nodes.push_back(n);
722 722
      }
723 723

	
724 724
      if (label == 0) {
725 725
        IdMap<DGR, Node> id_map(_digraph);
726 726
        _writer_bits::MapLess<IdMap<DGR, Node> > id_less(id_map);
727 727
        std::sort(nodes.begin(), nodes.end(), id_less);
728 728
      } else {
729 729
        label->sort(nodes);
730 730
      }
731 731

	
732 732
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
733 733
        Node n = nodes[i];
734 734
        if (label == 0) {
735 735
          std::ostringstream os;
736 736
          os << _digraph.id(n);
737 737
          _writer_bits::writeToken(*_os, os.str());
738 738
          *_os << '\t';
739 739
          _node_index.insert(std::make_pair(n, os.str()));
740 740
        }
741 741
        for (typename NodeMaps::iterator it = _node_maps.begin();
742 742
             it != _node_maps.end(); ++it) {
743 743
          std::string value = it->second->get(n);
744 744
          _writer_bits::writeToken(*_os, value);
745 745
          if (it->first == "label") {
746 746
            _node_index.insert(std::make_pair(n, value));
747 747
          }
748 748
          *_os << '\t';
749 749
        }
750 750
        *_os << std::endl;
751 751
      }
752 752
    }
753 753

	
754 754
    void createNodeIndex() {
755 755
      _writer_bits::MapStorageBase<Node>* label = 0;
756 756
      for (typename NodeMaps::iterator it = _node_maps.begin();
757 757
           it != _node_maps.end(); ++it) {
758 758
        if (it->first == "label") {
759 759
          label = it->second;
760 760
          break;
761 761
        }
762 762
      }
763 763

	
764 764
      if (label == 0) {
765 765
        for (NodeIt n(_digraph); n != INVALID; ++n) {
766 766
          std::ostringstream os;
767 767
          os << _digraph.id(n);
768 768
          _node_index.insert(std::make_pair(n, os.str()));
769 769
        }
770 770
      } else {
771 771
        for (NodeIt n(_digraph); n != INVALID; ++n) {
772 772
          std::string value = label->get(n);
773 773
          _node_index.insert(std::make_pair(n, value));
774 774
        }
775 775
      }
776 776
    }
777 777

	
778 778
    void writeArcs() {
779 779
      _writer_bits::MapStorageBase<Arc>* label = 0;
780 780
      for (typename ArcMaps::iterator it = _arc_maps.begin();
781 781
           it != _arc_maps.end(); ++it) {
782 782
        if (it->first == "label") {
783 783
          label = it->second;
784 784
          break;
785 785
        }
786 786
      }
787 787

	
788 788
      *_os << "@arcs";
789 789
      if (!_arcs_caption.empty()) {
790 790
        _writer_bits::writeToken(*_os << ' ', _arcs_caption);
791 791
      }
792 792
      *_os << std::endl;
793 793

	
794 794
      *_os << '\t' << '\t';
795 795
      if (label == 0) {
796 796
        *_os << "label" << '\t';
797 797
      }
798 798
      for (typename ArcMaps::iterator it = _arc_maps.begin();
799 799
           it != _arc_maps.end(); ++it) {
800 800
        _writer_bits::writeToken(*_os, it->first) << '\t';
801 801
      }
802 802
      *_os << std::endl;
803 803

	
804 804
      std::vector<Arc> arcs;
805 805
      for (ArcIt n(_digraph); n != INVALID; ++n) {
806 806
        arcs.push_back(n);
807 807
      }
808 808

	
809 809
      if (label == 0) {
810 810
        IdMap<DGR, Arc> id_map(_digraph);
811 811
        _writer_bits::MapLess<IdMap<DGR, Arc> > id_less(id_map);
812 812
        std::sort(arcs.begin(), arcs.end(), id_less);
813 813
      } else {
814 814
        label->sort(arcs);
815 815
      }
816 816

	
817 817
      for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
818 818
        Arc a = arcs[i];
819 819
        _writer_bits::writeToken(*_os, _node_index.
820 820
                                 find(_digraph.source(a))->second);
821 821
        *_os << '\t';
822 822
        _writer_bits::writeToken(*_os, _node_index.
823 823
                                 find(_digraph.target(a))->second);
824 824
        *_os << '\t';
825 825
        if (label == 0) {
826 826
          std::ostringstream os;
827 827
          os << _digraph.id(a);
828 828
          _writer_bits::writeToken(*_os, os.str());
829 829
          *_os << '\t';
830 830
          _arc_index.insert(std::make_pair(a, os.str()));
831 831
        }
832 832
        for (typename ArcMaps::iterator it = _arc_maps.begin();
833 833
             it != _arc_maps.end(); ++it) {
834 834
          std::string value = it->second->get(a);
835 835
          _writer_bits::writeToken(*_os, value);
836 836
          if (it->first == "label") {
837 837
            _arc_index.insert(std::make_pair(a, value));
838 838
          }
839 839
          *_os << '\t';
840 840
        }
841 841
        *_os << std::endl;
842 842
      }
843 843
    }
844 844

	
845 845
    void createArcIndex() {
846 846
      _writer_bits::MapStorageBase<Arc>* label = 0;
847 847
      for (typename ArcMaps::iterator it = _arc_maps.begin();
848 848
           it != _arc_maps.end(); ++it) {
849 849
        if (it->first == "label") {
850 850
          label = it->second;
851 851
          break;
852 852
        }
853 853
      }
854 854

	
855 855
      if (label == 0) {
856 856
        for (ArcIt a(_digraph); a != INVALID; ++a) {
857 857
          std::ostringstream os;
858 858
          os << _digraph.id(a);
859 859
          _arc_index.insert(std::make_pair(a, os.str()));
860 860
        }
861 861
      } else {
862 862
        for (ArcIt a(_digraph); a != INVALID; ++a) {
863 863
          std::string value = label->get(a);
864 864
          _arc_index.insert(std::make_pair(a, value));
865 865
        }
866 866
      }
867 867
    }
868 868

	
869 869
    void writeAttributes() {
870 870
      if (_attributes.empty()) return;
871 871
      *_os << "@attributes";
872 872
      if (!_attributes_caption.empty()) {
873 873
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
874 874
      }
875 875
      *_os << std::endl;
876 876
      for (typename Attributes::iterator it = _attributes.begin();
877 877
           it != _attributes.end(); ++it) {
878 878
        _writer_bits::writeToken(*_os, it->first) << ' ';
879 879
        _writer_bits::writeToken(*_os, it->second->get());
880 880
        *_os << std::endl;
881 881
      }
882 882
    }
883 883

	
884 884
  public:
885 885

	
886 886
    /// \name Execution of the Writer
887 887
    /// @{
888 888

	
889 889
    /// \brief Start the batch processing
890 890
    ///
891 891
    /// This function starts the batch processing.
892 892
    void run() {
893 893
      if (!_skip_nodes) {
894 894
        writeNodes();
895 895
      } else {
896 896
        createNodeIndex();
897 897
      }
898 898
      if (!_skip_arcs) {
899 899
        writeArcs();
900 900
      } else {
901 901
        createArcIndex();
902 902
      }
903 903
      writeAttributes();
904 904
    }
905 905

	
906 906
    /// \brief Give back the stream of the writer
907 907
    ///
908 908
    /// Give back the stream of the writer.
909 909
    std::ostream& ostream() {
910 910
      return *_os;
911 911
    }
912 912

	
913 913
    /// @}
914 914
  };
915 915

	
916 916
  /// \ingroup lemon_io
917 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 921
  ///
922 922
  /// With this function a digraph can be write to a file or output
923 923
  /// stream in \ref lgf-format "LGF" format with several maps and
924 924
  /// attributes. For example, with the following code a network flow
925 925
  /// problem can be written to the standard output, i.e. a digraph
926 926
  /// with a \e capacity map on the arcs and \e source and \e target
927 927
  /// nodes:
928 928
  ///
929 929
  ///\code
930 930
  ///ListDigraph digraph;
931 931
  ///ListDigraph::ArcMap<int> cap(digraph);
932 932
  ///ListDigraph::Node src, trg;
933 933
  ///  // Setting the capacity map and source and target nodes
934 934
  ///digraphWriter(digraph, std::cout).
935 935
  ///  arcMap("capacity", cap).
936 936
  ///  node("source", src).
937 937
  ///  node("target", trg).
938 938
  ///  run();
939 939
  ///\endcode
940 940
  ///
941 941
  /// For a complete documentation, please see the \ref DigraphWriter
942 942
  /// class documentation.
943 943
  /// \warning Don't forget to put the \ref DigraphWriter::run() "run()"
944 944
  /// to the end of the parameter list.
945 945
  /// \relates DigraphWriter
946 946
  /// \sa digraphWriter(const TDGR& digraph, const std::string& fn)
947 947
  /// \sa digraphWriter(const TDGR& digraph, const char* fn)
948 948
  template <typename TDGR>
949 949
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, std::ostream& os) {
950 950
    DigraphWriter<TDGR> tmp(digraph, os);
951 951
    return tmp;
952 952
  }
953 953

	
954 954
  /// \brief Return a \ref DigraphWriter class
955 955
  ///
956 956
  /// This function just returns a \ref DigraphWriter class.
957 957
  /// \relates DigraphWriter
958 958
  /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
959 959
  template <typename TDGR>
960
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, 
960
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph,
961 961
                                    const std::string& fn) {
962 962
    DigraphWriter<TDGR> tmp(digraph, fn);
963 963
    return tmp;
964 964
  }
965 965

	
966 966
  /// \brief Return a \ref DigraphWriter class
967 967
  ///
968 968
  /// This function just returns a \ref DigraphWriter class.
969 969
  /// \relates DigraphWriter
970 970
  /// \sa digraphWriter(const TDGR& digraph, std::ostream& os)
971 971
  template <typename TDGR>
972 972
  DigraphWriter<TDGR> digraphWriter(const TDGR& digraph, const char* fn) {
973 973
    DigraphWriter<TDGR> tmp(digraph, fn);
974 974
    return tmp;
975 975
  }
976 976

	
977 977
  template <typename GR>
978 978
  class GraphWriter;
979 979

	
980 980
  template <typename TGR>
981 981
  GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os = std::cout);
982 982
  template <typename TGR>
983 983
  GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn);
984 984
  template <typename TGR>
985 985
  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn);
986 986

	
987 987
  /// \ingroup lemon_io
988 988
  ///
989 989
  /// \brief \ref lgf-format "LGF" writer for directed graphs
990 990
  ///
991 991
  /// This utility writes an \ref lgf-format "LGF" file.
992 992
  ///
993 993
  /// It can be used almost the same way as \c DigraphWriter.
994 994
  /// The only difference is that this class can handle edges and
995 995
  /// edge maps as well as arcs and arc maps.
996 996
  ///
997 997
  /// The arc maps are written into the file as two columns, the
998 998
  /// caption of the columns are the name of the map prefixed with \c
999 999
  /// '+' and \c '-'. The arcs are written into the \c \@attributes
1000 1000
  /// section as a \c '+' or a \c '-' prefix (depends on the direction
1001 1001
  /// of the arc) and the label of corresponding edge.
1002 1002
  template <typename GR>
1003 1003
  class GraphWriter {
1004 1004
  public:
1005 1005

	
1006 1006
    typedef GR Graph;
1007 1007
    TEMPLATE_GRAPH_TYPEDEFS(GR);
1008 1008

	
1009 1009
  private:
1010 1010

	
1011 1011

	
1012 1012
    std::ostream* _os;
1013 1013
    bool local_os;
1014 1014

	
1015 1015
    const GR& _graph;
1016 1016

	
1017 1017
    std::string _nodes_caption;
1018 1018
    std::string _edges_caption;
1019 1019
    std::string _attributes_caption;
1020 1020

	
1021 1021
    typedef std::map<Node, std::string> NodeIndex;
1022 1022
    NodeIndex _node_index;
1023 1023
    typedef std::map<Edge, std::string> EdgeIndex;
1024 1024
    EdgeIndex _edge_index;
1025 1025

	
1026 1026
    typedef std::vector<std::pair<std::string,
1027 1027
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
1028 1028
    NodeMaps _node_maps;
1029 1029

	
1030 1030
    typedef std::vector<std::pair<std::string,
1031 1031
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
1032 1032
    EdgeMaps _edge_maps;
1033 1033

	
1034 1034
    typedef std::vector<std::pair<std::string,
1035 1035
      _writer_bits::ValueStorageBase*> > Attributes;
1036 1036
    Attributes _attributes;
1037 1037

	
1038 1038
    bool _skip_nodes;
1039 1039
    bool _skip_edges;
1040 1040

	
1041 1041
  public:
1042 1042

	
1043 1043
    /// \brief Constructor
1044 1044
    ///
1045 1045
    /// Construct a directed graph writer, which writes to the given
1046 1046
    /// output stream.
1047 1047
    GraphWriter(const GR& graph, std::ostream& os = std::cout)
1048 1048
      : _os(&os), local_os(false), _graph(graph),
1049 1049
        _skip_nodes(false), _skip_edges(false) {}
1050 1050

	
1051 1051
    /// \brief Constructor
1052 1052
    ///
1053 1053
    /// Construct a directed graph writer, which writes to the given
1054 1054
    /// output file.
1055 1055
    GraphWriter(const GR& graph, const std::string& fn)
1056 1056
      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
1057 1057
        _skip_nodes(false), _skip_edges(false) {
1058 1058
      if (!(*_os)) {
1059 1059
        delete _os;
1060 1060
        throw IoError("Cannot write file", fn);
1061 1061
      }
1062 1062
    }
1063 1063

	
1064 1064
    /// \brief Constructor
1065 1065
    ///
1066 1066
    /// Construct a directed graph writer, which writes to the given
1067 1067
    /// output file.
1068 1068
    GraphWriter(const GR& graph, const char* fn)
1069 1069
      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
1070 1070
        _skip_nodes(false), _skip_edges(false) {
1071 1071
      if (!(*_os)) {
1072 1072
        delete _os;
1073 1073
        throw IoError("Cannot write file", fn);
1074 1074
      }
1075 1075
    }
1076 1076

	
1077 1077
    /// \brief Destructor
1078 1078
    ~GraphWriter() {
1079 1079
      for (typename NodeMaps::iterator it = _node_maps.begin();
1080 1080
           it != _node_maps.end(); ++it) {
1081 1081
        delete it->second;
1082 1082
      }
1083 1083

	
1084 1084
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1085 1085
           it != _edge_maps.end(); ++it) {
1086 1086
        delete it->second;
1087 1087
      }
1088 1088

	
1089 1089
      for (typename Attributes::iterator it = _attributes.begin();
1090 1090
           it != _attributes.end(); ++it) {
1091 1091
        delete it->second;
1092 1092
      }
1093 1093

	
1094 1094
      if (local_os) {
1095 1095
        delete _os;
1096 1096
      }
1097 1097
    }
1098 1098

	
1099 1099
  private:
1100 1100

	
1101 1101
    template <typename TGR>
1102 1102
    friend GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os);
1103 1103
    template <typename TGR>
1104
    friend GraphWriter<TGR> graphWriter(const TGR& graph, 
1104
    friend GraphWriter<TGR> graphWriter(const TGR& graph,
1105 1105
                                        const std::string& fn);
1106 1106
    template <typename TGR>
1107 1107
    friend GraphWriter<TGR> graphWriter(const TGR& graph, const char *fn);
1108
    
1108

	
1109 1109
    GraphWriter(GraphWriter& other)
1110 1110
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
1111 1111
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1112 1112

	
1113 1113
      other._os = 0;
1114 1114
      other.local_os = false;
1115 1115

	
1116 1116
      _node_index.swap(other._node_index);
1117 1117
      _edge_index.swap(other._edge_index);
1118 1118

	
1119 1119
      _node_maps.swap(other._node_maps);
1120 1120
      _edge_maps.swap(other._edge_maps);
1121 1121
      _attributes.swap(other._attributes);
1122 1122

	
1123 1123
      _nodes_caption = other._nodes_caption;
1124 1124
      _edges_caption = other._edges_caption;
1125 1125
      _attributes_caption = other._attributes_caption;
1126 1126
    }
1127 1127

	
1128 1128
    GraphWriter& operator=(const GraphWriter&);
1129 1129

	
1130 1130
  public:
1131 1131

	
1132 1132
    /// \name Writing Rules
1133 1133
    /// @{
1134 1134

	
1135 1135
    /// \brief Node map writing rule
1136 1136
    ///
1137 1137
    /// Add a node map writing rule to the writer.
1138 1138
    template <typename Map>
1139 1139
    GraphWriter& nodeMap(const std::string& caption, const Map& map) {
1140 1140
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1141 1141
      _writer_bits::MapStorageBase<Node>* storage =
1142 1142
        new _writer_bits::MapStorage<Node, Map>(map);
1143 1143
      _node_maps.push_back(std::make_pair(caption, storage));
1144 1144
      return *this;
1145 1145
    }
1146 1146

	
1147 1147
    /// \brief Node map writing rule
1148 1148
    ///
1149 1149
    /// Add a node map writing rule with specialized converter to the
1150 1150
    /// writer.
1151 1151
    template <typename Map, typename Converter>
1152 1152
    GraphWriter& nodeMap(const std::string& caption, const Map& map,
1153 1153
                           const Converter& converter = Converter()) {
1154 1154
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1155 1155
      _writer_bits::MapStorageBase<Node>* storage =
1156 1156
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1157 1157
      _node_maps.push_back(std::make_pair(caption, storage));
1158 1158
      return *this;
1159 1159
    }
1160 1160

	
1161 1161
    /// \brief Edge map writing rule
1162 1162
    ///
1163 1163
    /// Add an edge map writing rule to the writer.
1164 1164
    template <typename Map>
1165 1165
    GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1166 1166
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1167 1167
      _writer_bits::MapStorageBase<Edge>* storage =
1168 1168
        new _writer_bits::MapStorage<Edge, Map>(map);
1169 1169
      _edge_maps.push_back(std::make_pair(caption, storage));
1170 1170
      return *this;
1171 1171
    }
1172 1172

	
1173 1173
    /// \brief Edge map writing rule
1174 1174
    ///
1175 1175
    /// Add an edge map writing rule with specialized converter to the
1176 1176
    /// writer.
1177 1177
    template <typename Map, typename Converter>
1178 1178
    GraphWriter& edgeMap(const std::string& caption, const Map& map,
1179 1179
                          const Converter& converter = Converter()) {
1180 1180
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1181 1181
      _writer_bits::MapStorageBase<Edge>* storage =
1182 1182
        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1183 1183
      _edge_maps.push_back(std::make_pair(caption, storage));
1184 1184
      return *this;
1185 1185
    }
1186 1186

	
1187 1187
    /// \brief Arc map writing rule
1188 1188
    ///
1189 1189
    /// Add an arc map writing rule to the writer.
1190 1190
    template <typename Map>
1191 1191
    GraphWriter& arcMap(const std::string& caption, const Map& map) {
1192 1192
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1193 1193
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1194 1194
        new _writer_bits::GraphArcMapStorage<GR, true, Map>(_graph, map);
1195 1195
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1196 1196
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1197 1197
        new _writer_bits::GraphArcMapStorage<GR, false, Map>(_graph, map);
1198 1198
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1199 1199
      return *this;
1200 1200
    }
1201 1201

	
1202 1202
    /// \brief Arc map writing rule
1203 1203
    ///
1204 1204
    /// Add an arc map writing rule with specialized converter to the
1205 1205
    /// writer.
1206 1206
    template <typename Map, typename Converter>
1207 1207
    GraphWriter& arcMap(const std::string& caption, const Map& map,
1208 1208
                          const Converter& converter = Converter()) {
1209 1209
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1210 1210
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1211 1211
        new _writer_bits::GraphArcMapStorage<GR, true, Map, Converter>
1212 1212
        (_graph, map, converter);
1213 1213
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1214 1214
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1215 1215
        new _writer_bits::GraphArcMapStorage<GR, false, Map, Converter>
1216 1216
        (_graph, map, converter);
1217 1217
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1218 1218
      return *this;
1219 1219
    }
1220 1220

	
1221 1221
    /// \brief Attribute writing rule
1222 1222
    ///
1223 1223
    /// Add an attribute writing rule to the writer.
1224 1224
    template <typename Value>
1225 1225
    GraphWriter& attribute(const std::string& caption, const Value& value) {
1226 1226
      _writer_bits::ValueStorageBase* storage =
1227 1227
        new _writer_bits::ValueStorage<Value>(value);
1228 1228
      _attributes.push_back(std::make_pair(caption, storage));
1229 1229
      return *this;
1230 1230
    }
1231 1231

	
1232 1232
    /// \brief Attribute writing rule
1233 1233
    ///
1234 1234
    /// Add an attribute writing rule with specialized converter to the
1235 1235
    /// writer.
1236 1236
    template <typename Value, typename Converter>
1237 1237
    GraphWriter& attribute(const std::string& caption, const Value& value,
1238 1238
                             const Converter& converter = Converter()) {
1239 1239
      _writer_bits::ValueStorageBase* storage =
1240 1240
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1241 1241
      _attributes.push_back(std::make_pair(caption, storage));
1242 1242
      return *this;
1243 1243
    }
1244 1244

	
1245 1245
    /// \brief Node writing rule
1246 1246
    ///
1247 1247
    /// Add a node writing rule to the writer.
1248 1248
    GraphWriter& node(const std::string& caption, const Node& node) {
1249 1249
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
1250 1250
      Converter converter(_node_index);
1251 1251
      _writer_bits::ValueStorageBase* storage =
1252 1252
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1253 1253
      _attributes.push_back(std::make_pair(caption, storage));
1254 1254
      return *this;
1255 1255
    }
1256 1256

	
1257 1257
    /// \brief Edge writing rule
1258 1258
    ///
1259 1259
    /// Add an edge writing rule to writer.
1260 1260
    GraphWriter& edge(const std::string& caption, const Edge& edge) {
1261 1261
      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1262 1262
      Converter converter(_edge_index);
1263 1263
      _writer_bits::ValueStorageBase* storage =
1264 1264
        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1265 1265
      _attributes.push_back(std::make_pair(caption, storage));
1266 1266
      return *this;
1267 1267
    }
1268 1268

	
1269 1269
    /// \brief Arc writing rule
1270 1270
    ///
1271 1271
    /// Add an arc writing rule to writer.
1272 1272
    GraphWriter& arc(const std::string& caption, const Arc& arc) {
1273 1273
      typedef _writer_bits::GraphArcLookUpConverter<GR> Converter;
1274 1274
      Converter converter(_graph, _edge_index);
1275 1275
      _writer_bits::ValueStorageBase* storage =
1276 1276
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1277 1277
      _attributes.push_back(std::make_pair(caption, storage));
1278 1278
      return *this;
1279 1279
    }
1280 1280

	
1281 1281
    /// \name Section Captions
1282 1282
    /// @{
1283 1283

	
1284 1284
    /// \brief Add an additional caption to the \c \@nodes section
1285 1285
    ///
1286 1286
    /// Add an additional caption to the \c \@nodes section.
1287 1287
    GraphWriter& nodes(const std::string& caption) {
1288 1288
      _nodes_caption = caption;
1289 1289
      return *this;
1290 1290
    }
1291 1291

	
1292 1292
    /// \brief Add an additional caption to the \c \@arcs section
1293 1293
    ///
1294 1294
    /// Add an additional caption to the \c \@arcs section.
1295 1295
    GraphWriter& edges(const std::string& caption) {
1296 1296
      _edges_caption = caption;
1297 1297
      return *this;
1298 1298
    }
1299 1299

	
1300 1300
    /// \brief Add an additional caption to the \c \@attributes section
1301 1301
    ///
1302 1302
    /// Add an additional caption to the \c \@attributes section.
1303 1303
    GraphWriter& attributes(const std::string& caption) {
1304 1304
      _attributes_caption = caption;
1305 1305
      return *this;
1306 1306
    }
1307 1307

	
1308 1308
    /// \name Skipping Section
1309 1309
    /// @{
1310 1310

	
1311 1311
    /// \brief Skip writing the node set
1312 1312
    ///
1313 1313
    /// The \c \@nodes section will not be written to the stream.
1314 1314
    GraphWriter& skipNodes() {
1315 1315
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1316 1316
      _skip_nodes = true;
1317 1317
      return *this;
1318 1318
    }
1319 1319

	
1320 1320
    /// \brief Skip writing edge set
1321 1321
    ///
1322 1322
    /// The \c \@edges section will not be written to the stream.
1323 1323
    GraphWriter& skipEdges() {
1324 1324
      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1325 1325
      _skip_edges = true;
1326 1326
      return *this;
1327 1327
    }
1328 1328

	
1329 1329
    /// @}
1330 1330

	
1331 1331
  private:
1332 1332

	
1333 1333
    void writeNodes() {
1334 1334
      _writer_bits::MapStorageBase<Node>* label = 0;
1335 1335
      for (typename NodeMaps::iterator it = _node_maps.begin();
1336 1336
           it != _node_maps.end(); ++it) {
1337 1337
        if (it->first == "label") {
1338 1338
          label = it->second;
1339 1339
          break;
1340 1340
        }
1341 1341
      }
1342 1342

	
1343 1343
      *_os << "@nodes";
1344 1344
      if (!_nodes_caption.empty()) {
1345 1345
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1346 1346
      }
1347 1347
      *_os << std::endl;
1348 1348

	
1349 1349
      if (label == 0) {
1350 1350
        *_os << "label" << '\t';
1351 1351
      }
1352 1352
      for (typename NodeMaps::iterator it = _node_maps.begin();
1353 1353
           it != _node_maps.end(); ++it) {
1354 1354
        _writer_bits::writeToken(*_os, it->first) << '\t';
1355 1355
      }
1356 1356
      *_os << std::endl;
1357 1357

	
1358 1358
      std::vector<Node> nodes;
1359 1359
      for (NodeIt n(_graph); n != INVALID; ++n) {
1360 1360
        nodes.push_back(n);
1361 1361
      }
1362 1362

	
1363 1363
      if (label == 0) {
1364 1364
        IdMap<GR, Node> id_map(_graph);
1365 1365
        _writer_bits::MapLess<IdMap<GR, Node> > id_less(id_map);
1366 1366
        std::sort(nodes.begin(), nodes.end(), id_less);
1367 1367
      } else {
1368 1368
        label->sort(nodes);
1369 1369
      }
1370 1370

	
1371 1371
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1372 1372
        Node n = nodes[i];
1373 1373
        if (label == 0) {
1374 1374
          std::ostringstream os;
1375 1375
          os << _graph.id(n);
1376 1376
          _writer_bits::writeToken(*_os, os.str());
1377 1377
          *_os << '\t';
1378 1378
          _node_index.insert(std::make_pair(n, os.str()));
1379 1379
        }
1380 1380
        for (typename NodeMaps::iterator it = _node_maps.begin();
1381 1381
             it != _node_maps.end(); ++it) {
1382 1382
          std::string value = it->second->get(n);
1383 1383
          _writer_bits::writeToken(*_os, value);
1384 1384
          if (it->first == "label") {
1385 1385
            _node_index.insert(std::make_pair(n, value));
1386 1386
          }
1387 1387
          *_os << '\t';
1388 1388
        }
1389 1389
        *_os << std::endl;
1390 1390
      }
1391 1391
    }
1392 1392

	
1393 1393
    void createNodeIndex() {
1394 1394
      _writer_bits::MapStorageBase<Node>* label = 0;
1395 1395
      for (typename NodeMaps::iterator it = _node_maps.begin();
1396 1396
           it != _node_maps.end(); ++it) {
1397 1397
        if (it->first == "label") {
1398 1398
          label = it->second;
1399 1399
          break;
1400 1400
        }
1401 1401
      }
1402 1402

	
1403 1403
      if (label == 0) {
1404 1404
        for (NodeIt n(_graph); n != INVALID; ++n) {
1405 1405
          std::ostringstream os;
1406 1406
          os << _graph.id(n);
1407 1407
          _node_index.insert(std::make_pair(n, os.str()));
1408 1408
        }
1409 1409
      } else {
1410 1410
        for (NodeIt n(_graph); n != INVALID; ++n) {
1411 1411
          std::string value = label->get(n);
1412 1412
          _node_index.insert(std::make_pair(n, value));
1413 1413
        }
1414 1414
      }
1415 1415
    }
1416 1416

	
1417 1417
    void writeEdges() {
1418 1418
      _writer_bits::MapStorageBase<Edge>* label = 0;
1419 1419
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1420 1420
           it != _edge_maps.end(); ++it) {
1421 1421
        if (it->first == "label") {
1422 1422
          label = it->second;
1423 1423
          break;
1424 1424
        }
1425 1425
      }
1426 1426

	
1427 1427
      *_os << "@edges";
1428 1428
      if (!_edges_caption.empty()) {
1429 1429
        _writer_bits::writeToken(*_os << ' ', _edges_caption);
1430 1430
      }
1431 1431
      *_os << std::endl;
1432 1432

	
1433 1433
      *_os << '\t' << '\t';
1434 1434
      if (label == 0) {
1435 1435
        *_os << "label" << '\t';
1436 1436
      }
1437 1437
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1438 1438
           it != _edge_maps.end(); ++it) {
1439 1439
        _writer_bits::writeToken(*_os, it->first) << '\t';
1440 1440
      }
1441 1441
      *_os << std::endl;
1442 1442

	
1443 1443
      std::vector<Edge> edges;
1444 1444
      for (EdgeIt n(_graph); n != INVALID; ++n) {
1445 1445
        edges.push_back(n);
1446 1446
      }
1447 1447

	
1448 1448
      if (label == 0) {
1449 1449
        IdMap<GR, Edge> id_map(_graph);
1450 1450
        _writer_bits::MapLess<IdMap<GR, Edge> > id_less(id_map);
1451 1451
        std::sort(edges.begin(), edges.end(), id_less);
1452 1452
      } else {
1453 1453
        label->sort(edges);
1454 1454
      }
1455 1455

	
1456 1456
      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1457 1457
        Edge e = edges[i];
1458 1458
        _writer_bits::writeToken(*_os, _node_index.
1459 1459
                                 find(_graph.u(e))->second);
1460 1460
        *_os << '\t';
1461 1461
        _writer_bits::writeToken(*_os, _node_index.
1462 1462
                                 find(_graph.v(e))->second);
1463 1463
        *_os << '\t';
1464 1464
        if (label == 0) {
1465 1465
          std::ostringstream os;
1466 1466
          os << _graph.id(e);
1467 1467
          _writer_bits::writeToken(*_os, os.str());
1468 1468
          *_os << '\t';
1469 1469
          _edge_index.insert(std::make_pair(e, os.str()));
1470 1470
        }
1471 1471
        for (typename EdgeMaps::iterator it = _edge_maps.begin();
1472 1472
             it != _edge_maps.end(); ++it) {
1473 1473
          std::string value = it->second->get(e);
1474 1474
          _writer_bits::writeToken(*_os, value);
1475 1475
          if (it->first == "label") {
1476 1476
            _edge_index.insert(std::make_pair(e, value));
1477 1477
          }
1478 1478
          *_os << '\t';
1479 1479
        }
1480 1480
        *_os << std::endl;
1481 1481
      }
1482 1482
    }
1483 1483

	
1484 1484
    void createEdgeIndex() {
1485 1485
      _writer_bits::MapStorageBase<Edge>* label = 0;
1486 1486
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1487 1487
           it != _edge_maps.end(); ++it) {
1488 1488
        if (it->first == "label") {
1489 1489
          label = it->second;
1490 1490
          break;
1491 1491
        }
1492 1492
      }
1493 1493

	
1494 1494
      if (label == 0) {
1495 1495
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1496 1496
          std::ostringstream os;
1497 1497
          os << _graph.id(e);
1498 1498
          _edge_index.insert(std::make_pair(e, os.str()));
1499 1499
        }
1500 1500
      } else {
1501 1501
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1502 1502
          std::string value = label->get(e);
1503 1503
          _edge_index.insert(std::make_pair(e, value));
1504 1504
        }
1505 1505
      }
1506 1506
    }
1507 1507

	
1508 1508
    void writeAttributes() {
1509 1509
      if (_attributes.empty()) return;
1510 1510
      *_os << "@attributes";
1511 1511
      if (!_attributes_caption.empty()) {
1512 1512
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1513 1513
      }
1514 1514
      *_os << std::endl;
1515 1515
      for (typename Attributes::iterator it = _attributes.begin();
1516 1516
           it != _attributes.end(); ++it) {
1517 1517
        _writer_bits::writeToken(*_os, it->first) << ' ';
1518 1518
        _writer_bits::writeToken(*_os, it->second->get());
1519 1519
        *_os << std::endl;
1520 1520
      }
1521 1521
    }
1522 1522

	
1523 1523
  public:
1524 1524

	
1525 1525
    /// \name Execution of the Writer
1526 1526
    /// @{
1527 1527

	
1528 1528
    /// \brief Start the batch processing
1529 1529
    ///
1530 1530
    /// This function starts the batch processing.
1531 1531
    void run() {
1532 1532
      if (!_skip_nodes) {
1533 1533
        writeNodes();
1534 1534
      } else {
1535 1535
        createNodeIndex();
1536 1536
      }
1537 1537
      if (!_skip_edges) {
1538 1538
        writeEdges();
1539 1539
      } else {
1540 1540
        createEdgeIndex();
1541 1541
      }
1542 1542
      writeAttributes();
1543 1543
    }
1544 1544

	
1545 1545
    /// \brief Give back the stream of the writer
1546 1546
    ///
1547 1547
    /// Give back the stream of the writer
1548 1548
    std::ostream& ostream() {
1549 1549
      return *_os;
1550 1550
    }
1551 1551

	
1552 1552
    /// @}
1553 1553
  };
1554 1554

	
1555 1555
  /// \ingroup lemon_io
1556 1556
  ///
1557 1557
  /// \brief Return a \ref GraphWriter class
1558 1558
  ///
1559
  /// This function just returns a \ref GraphWriter class. 
1559
  /// This function just returns a \ref GraphWriter class.
1560 1560
  ///
1561 1561
  /// With this function a graph can be write to a file or output
1562 1562
  /// stream in \ref lgf-format "LGF" format with several maps and
1563 1563
  /// attributes. For example, with the following code a weighted
1564 1564
  /// matching problem can be written to the standard output, i.e. a
1565 1565
  /// graph with a \e weight map on the edges:
1566 1566
  ///
1567 1567
  ///\code
1568 1568
  ///ListGraph graph;
1569 1569
  ///ListGraph::EdgeMap<int> weight(graph);
1570 1570
  ///  // Setting the weight map
1571 1571
  ///graphWriter(graph, std::cout).
1572 1572
  ///  edgeMap("weight", weight).
1573 1573
  ///  run();
1574 1574
  ///\endcode
1575 1575
  ///
1576 1576
  /// For a complete documentation, please see the \ref GraphWriter
1577 1577
  /// class documentation.
1578 1578
  /// \warning Don't forget to put the \ref GraphWriter::run() "run()"
1579 1579
  /// to the end of the parameter list.
1580 1580
  /// \relates GraphWriter
1581 1581
  /// \sa graphWriter(const TGR& graph, const std::string& fn)
1582 1582
  /// \sa graphWriter(const TGR& graph, const char* fn)
1583 1583
  template <typename TGR>
1584 1584
  GraphWriter<TGR> graphWriter(const TGR& graph, std::ostream& os) {
1585 1585
    GraphWriter<TGR> tmp(graph, os);
1586 1586
    return tmp;
1587 1587
  }
1588 1588

	
1589 1589
  /// \brief Return a \ref GraphWriter class
1590 1590
  ///
1591 1591
  /// This function just returns a \ref GraphWriter class.
1592 1592
  /// \relates GraphWriter
1593 1593
  /// \sa graphWriter(const TGR& graph, std::ostream& os)
1594 1594
  template <typename TGR>
1595 1595
  GraphWriter<TGR> graphWriter(const TGR& graph, const std::string& fn) {
1596 1596
    GraphWriter<TGR> tmp(graph, fn);
1597 1597
    return tmp;
1598 1598
  }
1599 1599

	
1600 1600
  /// \brief Return a \ref GraphWriter class
1601 1601
  ///
1602 1602
  /// This function just returns a \ref GraphWriter class.
1603 1603
  /// \relates GraphWriter
1604 1604
  /// \sa graphWriter(const TGR& graph, std::ostream& os)
1605 1605
  template <typename TGR>
1606 1606
  GraphWriter<TGR> graphWriter(const TGR& graph, const char* fn) {
1607 1607
    GraphWriter<TGR> tmp(graph, fn);
1608 1608
    return tmp;
1609 1609
  }
1610 1610

	
1611 1611
  class SectionWriter;
1612 1612

	
1613 1613
  SectionWriter sectionWriter(std::istream& is);
1614 1614
  SectionWriter sectionWriter(const std::string& fn);
1615 1615
  SectionWriter sectionWriter(const char* fn);
1616 1616

	
1617 1617
  /// \ingroup lemon_io
1618 1618
  ///
1619 1619
  /// \brief Section writer class
1620 1620
  ///
1621 1621
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
1622 1622
  /// which contain any data in arbitrary format. Such sections can be
1623 1623
  /// written with this class. A writing rule can be added to the
1624 1624
  /// class with two different functions. With the \c sectionLines()
1625 1625
  /// function a generator can write the section line-by-line, while
1626 1626
  /// with the \c sectionStream() member the section can be written to
1627 1627
  /// an output stream.
1628 1628
  class SectionWriter {
1629 1629
  private:
1630 1630

	
1631 1631
    std::ostream* _os;
1632 1632
    bool local_os;
1633 1633

	
1634 1634
    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
1635 1635
    Sections;
1636 1636

	
1637 1637
    Sections _sections;
1638 1638

	
1639 1639
  public:
1640 1640

	
1641 1641
    /// \brief Constructor
1642 1642
    ///
1643 1643
    /// Construct a section writer, which writes to the given output
1644 1644
    /// stream.
1645 1645
    SectionWriter(std::ostream& os)
1646 1646
      : _os(&os), local_os(false) {}
1647 1647

	
1648 1648
    /// \brief Constructor
1649 1649
    ///
1650 1650
    /// Construct a section writer, which writes into the given file.
1651 1651
    SectionWriter(const std::string& fn)
1652 1652
      : _os(new std::ofstream(fn.c_str())), local_os(true) {
1653 1653
      if (!(*_os)) {
1654 1654
        delete _os;
1655 1655
        throw IoError("Cannot write file", fn);
1656 1656
      }
1657 1657
    }
1658 1658

	
1659 1659
    /// \brief Constructor
1660 1660
    ///
1661 1661
    /// Construct a section writer, which writes into the given file.
1662 1662
    SectionWriter(const char* fn)
1663 1663
      : _os(new std::ofstream(fn)), local_os(true) {
1664 1664
      if (!(*_os)) {
1665 1665
        delete _os;
1666 1666
        throw IoError("Cannot write file", fn);
1667 1667
      }
1668 1668
    }
1669 1669

	
1670 1670
    /// \brief Destructor
1671 1671
    ~SectionWriter() {
1672 1672
      for (Sections::iterator it = _sections.begin();
1673 1673
           it != _sections.end(); ++it) {
1674 1674
        delete it->second;
1675 1675
      }
1676 1676

	
1677 1677
      if (local_os) {
1678 1678
        delete _os;
1679 1679
      }
1680 1680

	
1681 1681
    }
1682 1682

	
1683 1683
  private:
1684 1684

	
1685 1685
    friend SectionWriter sectionWriter(std::ostream& os);
1686 1686
    friend SectionWriter sectionWriter(const std::string& fn);
1687 1687
    friend SectionWriter sectionWriter(const char* fn);
1688 1688

	
1689 1689
    SectionWriter(SectionWriter& other)
1690 1690
      : _os(other._os), local_os(other.local_os) {
1691 1691

	
1692 1692
      other._os = 0;
1693 1693
      other.local_os = false;
1694 1694

	
1695 1695
      _sections.swap(other._sections);
1696 1696
    }
1697 1697

	
1698 1698
    SectionWriter& operator=(const SectionWriter&);
1699 1699

	
1700 1700
  public:
1701 1701

	
1702 1702
    /// \name Section Writers
1703 1703
    /// @{
1704 1704

	
1705 1705
    /// \brief Add a section writer with line oriented writing
1706 1706
    ///
1707 1707
    /// The first parameter is the type descriptor of the section, the
1708 1708
    /// second is a generator with std::string values. At the writing
1709 1709
    /// process, the returned \c std::string will be written into the
1710 1710
    /// output file until it is an empty string.
1711 1711
    ///
1712 1712
    /// For example, an integer vector is written into a section.
1713 1713
    ///\code
1714 1714
    ///  @numbers
1715 1715
    ///  12 45 23 78
1716 1716
    ///  4 28 38 28
1717 1717
    ///  23 6 16
1718 1718
    ///\endcode
1719 1719
    ///
1720 1720
    /// The generator is implemented as a struct.
1721 1721
    ///\code
1722 1722
    ///  struct NumberSection {
1723 1723
    ///    std::vector<int>::const_iterator _it, _end;
1724 1724
    ///    NumberSection(const std::vector<int>& data)
1725 1725
    ///      : _it(data.begin()), _end(data.end()) {}
1726 1726
    ///    std::string operator()() {
1727 1727
    ///      int rem_in_line = 4;
1728 1728
    ///      std::ostringstream ls;
1729 1729
    ///      while (rem_in_line > 0 && _it != _end) {
1730 1730
    ///        ls << *(_it++) << ' ';
1731 1731
    ///        --rem_in_line;
1732 1732
    ///      }
1733 1733
    ///      return ls.str();
1734 1734
    ///    }
1735 1735
    ///  };
1736 1736
    ///
1737 1737
    ///  // ...
1738 1738
    ///
1739 1739
    ///  writer.sectionLines("numbers", NumberSection(vec));
1740 1740
    ///\endcode
1741 1741
    template <typename Functor>
1742 1742
    SectionWriter& sectionLines(const std::string& type, Functor functor) {
1743 1743
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1744 1744
      _sections.push_back(std::make_pair(type,
1745 1745
        new _writer_bits::LineSection<Functor>(functor)));
1746 1746
      return *this;
1747 1747
    }
1748 1748

	
1749 1749

	
1750 1750
    /// \brief Add a section writer with stream oriented writing
1751 1751
    ///
1752 1752
    /// The first parameter is the type of the section, the second is
1753 1753
    /// a functor, which takes a \c std::ostream& parameter. The
1754 1754
    /// functor writes the section to the output stream.
1755 1755
    /// \warning The last line must be closed with end-line character.
1756 1756
    template <typename Functor>
1757 1757
    SectionWriter& sectionStream(const std::string& type, Functor functor) {
1758 1758
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1759 1759
      _sections.push_back(std::make_pair(type,
1760 1760
         new _writer_bits::StreamSection<Functor>(functor)));
1761 1761
      return *this;
1762 1762
    }
1763 1763

	
1764 1764
    /// @}
1765 1765

	
1766 1766
  public:
1767 1767

	
1768 1768

	
1769 1769
    /// \name Execution of the Writer
1770 1770
    /// @{
1771 1771

	
1772 1772
    /// \brief Start the batch processing
1773 1773
    ///
1774 1774
    /// This function starts the batch processing.
1775 1775
    void run() {
1776 1776

	
1777 1777
      LEMON_ASSERT(_os != 0, "This writer is assigned to an other writer");
1778 1778

	
1779 1779
      for (Sections::iterator it = _sections.begin();
1780 1780
           it != _sections.end(); ++it) {
1781 1781
        (*_os) << '@' << it->first << std::endl;
1782 1782
        it->second->process(*_os);
1783 1783
      }
1784 1784
    }
1785 1785

	
1786 1786
    /// \brief Give back the stream of the writer
1787 1787
    ///
1788 1788
    /// Returns the stream of the writer
1789 1789
    std::ostream& ostream() {
1790 1790
      return *_os;
1791 1791
    }
1792 1792

	
1793 1793
    /// @}
1794 1794

	
1795 1795
  };
1796 1796

	
1797 1797
  /// \ingroup lemon_io
1798 1798
  ///
1799 1799
  /// \brief Return a \ref SectionWriter class
1800 1800
  ///
1801 1801
  /// This function just returns a \ref SectionWriter class.
1802 1802
  ///
1803 1803
  /// Please see SectionWriter documentation about the custom section
1804 1804
  /// output.
1805 1805
  ///
1806 1806
  /// \relates SectionWriter
1807 1807
  /// \sa sectionWriter(const std::string& fn)
1808 1808
  /// \sa sectionWriter(const char *fn)
1809 1809
  inline SectionWriter sectionWriter(std::ostream& os) {
1810 1810
    SectionWriter tmp(os);
1811 1811
    return tmp;
1812 1812
  }
1813 1813

	
1814 1814
  /// \brief Return a \ref SectionWriter class
1815 1815
  ///
1816 1816
  /// This function just returns a \ref SectionWriter class.
1817 1817
  /// \relates SectionWriter
1818 1818
  /// \sa sectionWriter(std::ostream& os)
1819 1819
  inline SectionWriter sectionWriter(const std::string& fn) {
1820 1820
    SectionWriter tmp(fn);
1821 1821
    return tmp;
1822 1822
  }
1823 1823

	
1824 1824
  /// \brief Return a \ref SectionWriter class
1825 1825
  ///
1826 1826
  /// This function just returns a \ref SectionWriter class.
1827 1827
  /// \relates SectionWriter
1828 1828
  /// \sa sectionWriter(std::ostream& os)
1829 1829
  inline SectionWriter sectionWriter(const char* fn) {
1830 1830
    SectionWriter tmp(fn);
1831 1831
    return tmp;
1832 1832
  }
1833 1833
}
1834 1834

	
1835 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-2009
5
 * Copyright (C) 2003-2010
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
  ///
327
  ///This class provides only linear time counting for nodes and arcs.
328
  ///
323 329
  ///\sa concepts::Digraph
324

	
330
  ///\sa ListGraph
325 331
  class ListDigraph : public ExtendedListDigraphBase {
326 332
    typedef ExtendedListDigraphBase Parent;
327 333

	
328 334
  private:
329
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
330

	
331
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
332
    ///
335
    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
333 336
    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
334
    ///\brief Assignment of ListDigraph to another one is \e not allowed.
335
    ///Use copyDigraph() instead.
336

	
337
    ///Assignment of ListDigraph to another one is \e not allowed.
338
    ///Use copyDigraph() instead.
337
    /// \brief Assignment of a digraph to another one is \e not allowed.
338
    /// Use DigraphCopy instead.
339 339
    void operator=(const ListDigraph &) {}
340 340
  public:
341 341

	
342 342
    /// Constructor
343 343

	
344 344
    /// Constructor.
345 345
    ///
346 346
    ListDigraph() {}
347 347

	
348 348
    ///Add a new node to the digraph.
349 349

	
350
    ///Add a new node to the digraph.
350
    ///This function adds a new node to the digraph.
351 351
    ///\return The new node.
352 352
    Node addNode() { return Parent::addNode(); }
353 353

	
354 354
    ///Add a new arc to the digraph.
355 355

	
356
    ///Add a new arc to the digraph with source node \c s
356
    ///This function adds a new arc to the digraph with source node \c s
357 357
    ///and target node \c t.
358 358
    ///\return The new arc.
359
    Arc addArc(const Node& s, const Node& t) {
359
    Arc addArc(Node s, Node t) {
360 360
      return Parent::addArc(s, t);
361 361
    }
362 362

	
363 363
    ///\brief Erase a node from the digraph.
364 364
    ///
365
    ///Erase a node from the digraph.
365
    ///This function erases the given node along with its outgoing and
366
    ///incoming arcs from the digraph.
366 367
    ///
367
    void erase(const Node& n) { Parent::erase(n); }
368
    ///\note All iterators referencing the removed node or the connected
369
    ///arcs are invalidated, of course.
370
    void erase(Node n) { Parent::erase(n); }
368 371

	
369 372
    ///\brief Erase an arc from the digraph.
370 373
    ///
371
    ///Erase an arc from the digraph.
374
    ///This function erases the given arc from the digraph.
372 375
    ///
373
    void erase(const Arc& a) { Parent::erase(a); }
376
    ///\note All iterators referencing the removed arc are invalidated,
377
    ///of course.
378
    void erase(Arc a) { Parent::erase(a); }
374 379

	
375 380
    /// Node validity check
376 381

	
377
    /// This function gives back true if the given node is valid,
378
    /// ie. it is a real node of the graph.
382
    /// This function gives back \c true if the given node is valid,
383
    /// i.e. it is a real node of the digraph.
379 384
    ///
380
    /// \warning A Node pointing to a removed item
381
    /// could become valid again later if new nodes are
382
    /// added to the graph.
385
    /// \warning A removed node could become valid again if new nodes are
386
    /// added to the digraph.
383 387
    bool valid(Node n) const { return Parent::valid(n); }
384 388

	
385 389
    /// Arc validity check
386 390

	
387
    /// This function gives back true if the given arc is valid,
388
    /// ie. it is a real arc of the graph.
391
    /// This function gives back \c true if the given arc is valid,
392
    /// i.e. it is a real arc of the digraph.
389 393
    ///
390
    /// \warning An Arc pointing to a removed item
391
    /// could become valid again later if new nodes are
392
    /// added to the graph.
394
    /// \warning A removed arc could become valid again if new arcs are
395
    /// added to the digraph.
393 396
    bool valid(Arc a) const { return Parent::valid(a); }
394 397

	
395
    /// Change the target of \c a to \c n
398
    /// Change the target node of an arc
396 399

	
397
    /// Change the target of \c a to \c n
400
    /// This function changes the target node of the given arc \c a to \c n.
398 401
    ///
399
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
400
    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
401
    ///invalidated.
402
    ///\note \c ArcIt and \c OutArcIt iterators referencing the changed
403
    ///arc remain valid, but \c InArcIt iterators are invalidated.
402 404
    ///
403 405
    ///\warning This functionality cannot be used together with the Snapshot
404 406
    ///feature.
405 407
    void changeTarget(Arc a, Node n) {
406 408
      Parent::changeTarget(a,n);
407 409
    }
408
    /// Change the source of \c a to \c n
410
    /// Change the source node of an arc
409 411

	
410
    /// Change the source of \c a to \c n
412
    /// This function changes the source node of the given arc \c a to \c n.
411 413
    ///
412
    ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
413
    ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
414
    ///invalidated.
414
    ///\note \c InArcIt iterators referencing the changed arc remain
415
    ///valid, but \c ArcIt and \c OutArcIt iterators are invalidated.
415 416
    ///
416 417
    ///\warning This functionality cannot be used together with the Snapshot
417 418
    ///feature.
418 419
    void changeSource(Arc a, Node n) {
419 420
      Parent::changeSource(a,n);
420 421
    }
421 422

	
422
    /// Invert the direction of an arc.
423
    /// Reverse the direction of an arc.
423 424

	
424
    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
425
    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
426
    ///invalidated.
425
    /// This function reverses the direction of the given arc.
426
    ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing
427
    ///the changed arc are invalidated.
427 428
    ///
428 429
    ///\warning This functionality cannot be used together with the Snapshot
429 430
    ///feature.
430
    void reverseArc(Arc e) {
431
      Node t=target(e);
432
      changeTarget(e,source(e));
433
      changeSource(e,t);
431
    void reverseArc(Arc a) {
432
      Node t=target(a);
433
      changeTarget(a,source(a));
434
      changeSource(a,t);
434 435
    }
435 436

	
436
    /// Reserve memory for nodes.
437

	
438
    /// Using this function it is possible to avoid the superfluous memory
439
    /// allocation: if you know that the digraph you want to build will
440
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
441
    /// then it is worth reserving space for this amount before starting
442
    /// to build the digraph.
443
    /// \sa reserveArc
444
    void reserveNode(int n) { nodes.reserve(n); };
445

	
446
    /// Reserve memory for arcs.
447

	
448
    /// Using this function it is possible to avoid the superfluous memory
449
    /// allocation: if you know that the digraph you want to build will
450
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
451
    /// then it is worth reserving space for this amount before starting
452
    /// to build the digraph.
453
    /// \sa reserveNode
454
    void reserveArc(int m) { arcs.reserve(m); };
455

	
456 437
    ///Contract two nodes.
457 438

	
458
    ///This function contracts two nodes.
459
    ///Node \p b will be removed but instead of deleting
460
    ///incident arcs, they will be joined to \p a.
461
    ///The last parameter \p r controls whether to remove loops. \c true
462
    ///means that loops will be removed.
439
    ///This function contracts the given two nodes.
440
    ///Node \c v is removed, but instead of deleting its
441
    ///incident arcs, they are joined to node \c u.
442
    ///If the last parameter \c r is \c true (this is the default value),
443
    ///then the newly created loops are removed.
463 444
    ///
464
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
465
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
466
    ///may be invalidated.
445
    ///\note The moved arcs are joined to node \c u using changeSource()
446
    ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are
447
    ///invalidated for the outgoing arcs of node \c v and \c InArcIt
448
    ///iterators are invalidated for the incomming arcs of \c v.
449
    ///Moreover all iterators referencing node \c v or the removed
450
    ///loops are also invalidated. Other iterators remain valid.
467 451
    ///
468 452
    ///\warning This functionality cannot be used together with the Snapshot
469 453
    ///feature.
470
    void contract(Node a, Node b, bool r = true)
454
    void contract(Node u, Node v, bool r = true)
471 455
    {
472
      for(OutArcIt e(*this,b);e!=INVALID;) {
456
      for(OutArcIt e(*this,v);e!=INVALID;) {
473 457
        OutArcIt f=e;
474 458
        ++f;
475
        if(r && target(e)==a) erase(e);
476
        else changeSource(e,a);
459
        if(r && target(e)==u) erase(e);
460
        else changeSource(e,u);
477 461
        e=f;
478 462
      }
479
      for(InArcIt e(*this,b);e!=INVALID;) {
463
      for(InArcIt e(*this,v);e!=INVALID;) {
480 464
        InArcIt f=e;
481 465
        ++f;
482
        if(r && source(e)==a) erase(e);
483
        else changeTarget(e,a);
466
        if(r && source(e)==u) erase(e);
467
        else changeTarget(e,u);
484 468
        e=f;
485 469
      }
486
      erase(b);
470
      erase(v);
487 471
    }
488 472

	
489 473
    ///Split a node.
490 474

	
491
    ///This function splits a node. First a new node is added to the digraph,
492
    ///then the source of each outgoing arc of \c n is moved to this new node.
493
    ///If \c connect is \c true (this is the default value), then a new arc
494
    ///from \c n to the newly created node is also added.
475
    ///This function splits the given node. First, a new node is added
476
    ///to the digraph, then the source of each outgoing arc of node \c n
477
    ///is moved to this new node.
478
    ///If the second parameter \c connect is \c true (this is the default
479
    ///value), then a new arc from node \c n to the newly created node
480
    ///is also added.
495 481
    ///\return The newly created node.
496 482
    ///
497
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
498
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
499
    ///be invalidated.
483
    ///\note All iterators remain valid.
500 484
    ///
501
    ///\warning This functionality cannot be used in conjunction with the
485
    ///\warning This functionality cannot be used together with the
502 486
    ///Snapshot feature.
503 487
    Node split(Node n, bool connect = true) {
504 488
      Node b = addNode();
505
      for(OutArcIt e(*this,n);e!=INVALID;) {
506
        OutArcIt f=e;
507
        ++f;
508
        changeSource(e,b);
509
        e=f;
489
      nodes[b.id].first_out=nodes[n.id].first_out;
490
      nodes[n.id].first_out=-1;
491
      for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) {
492
        arcs[i].source=b.id;
510 493
      }
511 494
      if (connect) addArc(n,b);
512 495
      return b;
513 496
    }
514 497

	
515 498
    ///Split an arc.
516 499

	
517
    ///This function splits an arc. First a new node \c b is added to
518
    ///the digraph, then the original arc is re-targeted to \c
519
    ///b. Finally an arc from \c b to the original target is added.
500
    ///This function splits the given arc. First, a new node \c v is
501
    ///added to the digraph, then the target node of the original arc
502
    ///is set to \c v. Finally, an arc from \c v to the original target
503
    ///is added.
504
    ///\return The newly created node.
520 505
    ///
521
    ///\return The newly created node.
506
    ///\note \c InArcIt iterators referencing the original arc are
507
    ///invalidated. Other iterators remain valid.
522 508
    ///
523 509
    ///\warning This functionality cannot be used together with the
524 510
    ///Snapshot feature.
525
    Node split(Arc e) {
526
      Node b = addNode();
527
      addArc(b,target(e));
528
      changeTarget(e,b);
529
      return b;
511
    Node split(Arc a) {
512
      Node v = addNode();
513
      addArc(v,target(a));
514
      changeTarget(a,v);
515
      return v;
530 516
    }
531 517

	
518
    ///Clear the digraph.
519

	
520
    ///This function erases all nodes and arcs from the digraph.
521
    ///
522
    ///\note All iterators of the digraph are invalidated, of course.
523
    void clear() {
524
      Parent::clear();
525
    }
526

	
527
    /// Reserve memory for nodes.
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 reserveArc()
535
    void reserveNode(int n) { nodes.reserve(n); };
536

	
537
    /// Reserve memory for arcs.
538

	
539
    /// Using this function, it is possible to avoid superfluous memory
540
    /// allocation: if you know that the digraph you want to build will
541
    /// be large (e.g. it will contain millions of nodes and/or arcs),
542
    /// then it is worth reserving space for this amount before starting
543
    /// to build the digraph.
544
    /// \sa reserveNode()
545
    void reserveArc(int m) { arcs.reserve(m); };
546

	
532 547
    /// \brief Class to make a snapshot of the digraph and restore
533 548
    /// it later.
534 549
    ///
535 550
    /// Class to make a snapshot of the digraph and restore it later.
536 551
    ///
537 552
    /// The newly added nodes and arcs can be removed using the
538 553
    /// restore() function.
539 554
    ///
540
    /// \warning Arc and node deletions and other modifications (e.g.
541
    /// contracting, splitting, reversing arcs or nodes) cannot be
555
    /// \note After a state is restored, you cannot restore a later state,
556
    /// i.e. you cannot add the removed nodes and arcs again using
557
    /// another Snapshot instance.
558
    ///
559
    /// \warning Node and arc deletions and other modifications (e.g.
560
    /// reversing, contracting, splitting arcs or nodes) cannot be
542 561
    /// restored. These events invalidate the snapshot.
562
    /// However, the arcs and nodes that were added to the digraph after
563
    /// making the current snapshot can be removed without invalidating it.
543 564
    class Snapshot {
544 565
    protected:
545 566

	
546 567
      typedef Parent::NodeNotifier NodeNotifier;
547 568

	
548 569
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
549 570
      public:
550 571

	
551 572
        NodeObserverProxy(Snapshot& _snapshot)
552 573
          : snapshot(_snapshot) {}
553 574

	
554 575
        using NodeNotifier::ObserverBase::attach;
555 576
        using NodeNotifier::ObserverBase::detach;
556 577
        using NodeNotifier::ObserverBase::attached;
557 578

	
558 579
      protected:
559 580

	
560 581
        virtual void add(const Node& node) {
561 582
          snapshot.addNode(node);
562 583
        }
563 584
        virtual void add(const std::vector<Node>& nodes) {
564 585
          for (int i = nodes.size() - 1; i >= 0; ++i) {
565 586
            snapshot.addNode(nodes[i]);
566 587
          }
567 588
        }
568 589
        virtual void erase(const Node& node) {
569 590
          snapshot.eraseNode(node);
570 591
        }
571 592
        virtual void erase(const std::vector<Node>& nodes) {
572 593
          for (int i = 0; i < int(nodes.size()); ++i) {
573 594
            snapshot.eraseNode(nodes[i]);
574 595
          }
575 596
        }
576 597
        virtual void build() {
577 598
          Node node;
578 599
          std::vector<Node> nodes;
579 600
          for (notifier()->first(node); node != INVALID;
580 601
               notifier()->next(node)) {
581 602
            nodes.push_back(node);
582 603
          }
583 604
          for (int i = nodes.size() - 1; i >= 0; --i) {
584 605
            snapshot.addNode(nodes[i]);
585 606
          }
586 607
        }
587 608
        virtual void clear() {
588 609
          Node node;
589 610
          for (notifier()->first(node); node != INVALID;
590 611
               notifier()->next(node)) {
591 612
            snapshot.eraseNode(node);
592 613
          }
593 614
        }
594 615

	
595 616
        Snapshot& snapshot;
596 617
      };
597 618

	
598 619
      class ArcObserverProxy : public ArcNotifier::ObserverBase {
599 620
      public:
600 621

	
601 622
        ArcObserverProxy(Snapshot& _snapshot)
602 623
          : snapshot(_snapshot) {}
603 624

	
604 625
        using ArcNotifier::ObserverBase::attach;
605 626
        using ArcNotifier::ObserverBase::detach;
606 627
        using ArcNotifier::ObserverBase::attached;
607 628

	
608 629
      protected:
609 630

	
610 631
        virtual void add(const Arc& arc) {
611 632
          snapshot.addArc(arc);
612 633
        }
613 634
        virtual void add(const std::vector<Arc>& arcs) {
614 635
          for (int i = arcs.size() - 1; i >= 0; ++i) {
615 636
            snapshot.addArc(arcs[i]);
616 637
          }
617 638
        }
618 639
        virtual void erase(const Arc& arc) {
619 640
          snapshot.eraseArc(arc);
620 641
        }
621 642
        virtual void erase(const std::vector<Arc>& arcs) {
622 643
          for (int i = 0; i < int(arcs.size()); ++i) {
623 644
            snapshot.eraseArc(arcs[i]);
624 645
          }
625 646
        }
626 647
        virtual void build() {
627 648
          Arc arc;
628 649
          std::vector<Arc> arcs;
629 650
          for (notifier()->first(arc); arc != INVALID;
630 651
               notifier()->next(arc)) {
631 652
            arcs.push_back(arc);
632 653
          }
633 654
          for (int i = arcs.size() - 1; i >= 0; --i) {
634 655
            snapshot.addArc(arcs[i]);
635 656
          }
636 657
        }
637 658
        virtual void clear() {
638 659
          Arc arc;
639 660
          for (notifier()->first(arc); arc != INVALID;
640 661
               notifier()->next(arc)) {
641 662
            snapshot.eraseArc(arc);
642 663
          }
643 664
        }
644 665

	
645 666
        Snapshot& snapshot;
646 667
      };
647 668

	
648 669
      ListDigraph *digraph;
649 670

	
650 671
      NodeObserverProxy node_observer_proxy;
651 672
      ArcObserverProxy arc_observer_proxy;
652 673

	
653 674
      std::list<Node> added_nodes;
654 675
      std::list<Arc> added_arcs;
655 676

	
656 677

	
657 678
      void addNode(const Node& node) {
658 679
        added_nodes.push_front(node);
659 680
      }
660 681
      void eraseNode(const Node& node) {
661 682
        std::list<Node>::iterator it =
662 683
          std::find(added_nodes.begin(), added_nodes.end(), node);
663 684
        if (it == added_nodes.end()) {
664 685
          clear();
665 686
          arc_observer_proxy.detach();
666 687
          throw NodeNotifier::ImmediateDetach();
667 688
        } else {
668 689
          added_nodes.erase(it);
669 690
        }
670 691
      }
671 692

	
672 693
      void addArc(const Arc& arc) {
673 694
        added_arcs.push_front(arc);
674 695
      }
675 696
      void eraseArc(const Arc& arc) {
676 697
        std::list<Arc>::iterator it =
677 698
          std::find(added_arcs.begin(), added_arcs.end(), arc);
678 699
        if (it == added_arcs.end()) {
679 700
          clear();
680 701
          node_observer_proxy.detach();
681 702
          throw ArcNotifier::ImmediateDetach();
682 703
        } else {
683 704
          added_arcs.erase(it);
684 705
        }
685 706
      }
686 707

	
687 708
      void attach(ListDigraph &_digraph) {
688 709
        digraph = &_digraph;
689 710
        node_observer_proxy.attach(digraph->notifier(Node()));
690 711
        arc_observer_proxy.attach(digraph->notifier(Arc()));
691 712
      }
692 713

	
693 714
      void detach() {
694 715
        node_observer_proxy.detach();
695 716
        arc_observer_proxy.detach();
696 717
      }
697 718

	
698 719
      bool attached() const {
699 720
        return node_observer_proxy.attached();
700 721
      }
701 722

	
702 723
      void clear() {
703 724
        added_nodes.clear();
704 725
        added_arcs.clear();
705 726
      }
706 727

	
707 728
    public:
708 729

	
709 730
      /// \brief Default constructor.
710 731
      ///
711 732
      /// Default constructor.
712
      /// To actually make a snapshot you must call save().
733
      /// You have to call save() to actually make a snapshot.
713 734
      Snapshot()
714 735
        : digraph(0), node_observer_proxy(*this),
715 736
          arc_observer_proxy(*this) {}
716 737

	
717 738
      /// \brief Constructor that immediately makes a snapshot.
718 739
      ///
719
      /// This constructor immediately makes a snapshot of the digraph.
720
      /// \param _digraph The digraph we make a snapshot of.
721
      Snapshot(ListDigraph &_digraph)
740
      /// This constructor immediately makes a snapshot of the given digraph.
741
      Snapshot(ListDigraph &gr)
722 742
        : node_observer_proxy(*this),
723 743
          arc_observer_proxy(*this) {
724
        attach(_digraph);
744
        attach(gr);
725 745
      }
726 746

	
727 747
      /// \brief Make a snapshot.
728 748
      ///
729
      /// Make a snapshot of the digraph.
730
      ///
731
      /// This function can be called more than once. In case of a repeated
749
      /// This function makes a snapshot of the given digraph.
750
      /// It can be called more than once. In case of a repeated
732 751
      /// call, the previous snapshot gets lost.
733
      /// \param _digraph The digraph we make the snapshot of.
734
      void save(ListDigraph &_digraph) {
752
      void save(ListDigraph &gr) {
735 753
        if (attached()) {
736 754
          detach();
737 755
          clear();
738 756
        }
739
        attach(_digraph);
757
        attach(gr);
740 758
      }
741 759

	
742 760
      /// \brief Undo the changes until the last snapshot.
743
      //
744
      /// Undo the changes until the last snapshot created by save().
761
      ///
762
      /// This function undos the changes until the last snapshot
763
      /// created by save() or Snapshot(ListDigraph&).
764
      ///
765
      /// \warning This method invalidates the snapshot, i.e. repeated
766
      /// restoring is not supported unless you call save() again.
745 767
      void restore() {
746 768
        detach();
747 769
        for(std::list<Arc>::iterator it = added_arcs.begin();
748 770
            it != added_arcs.end(); ++it) {
749 771
          digraph->erase(*it);
750 772
        }
751 773
        for(std::list<Node>::iterator it = added_nodes.begin();
752 774
            it != added_nodes.end(); ++it) {
753 775
          digraph->erase(*it);
754 776
        }
755 777
        clear();
756 778
      }
757 779

	
758
      /// \brief Gives back true when the snapshot is valid.
780
      /// \brief Returns \c true if the snapshot is valid.
759 781
      ///
760
      /// Gives back true when the snapshot is valid.
782
      /// This function returns \c true if the snapshot is valid.
761 783
      bool valid() const {
762 784
        return attached();
763 785
      }
764 786
    };
765 787

	
766 788
  };
767 789

	
768 790
  ///@}
769 791

	
770 792
  class ListGraphBase {
771 793

	
772 794
  protected:
773 795

	
774 796
    struct NodeT {
775 797
      int first_out;
776 798
      int prev, next;
777 799
    };
778 800

	
779 801
    struct ArcT {
780 802
      int target;
781 803
      int prev_out, next_out;
782 804
    };
783 805

	
784 806
    std::vector<NodeT> nodes;
785 807

	
786 808
    int first_node;
787 809

	
788 810
    int first_free_node;
789 811

	
790 812
    std::vector<ArcT> arcs;
791 813

	
792 814
    int first_free_arc;
793 815

	
794 816
  public:
795 817

	
796 818
    typedef ListGraphBase Graph;
797 819

	
798
    class Node;
799
    class Arc;
800
    class Edge;
801

	
802 820
    class Node {
803 821
      friend class ListGraphBase;
804 822
    protected:
805 823

	
806 824
      int id;
807 825
      explicit Node(int pid) { id = pid;}
808 826

	
809 827
    public:
810 828
      Node() {}
811 829
      Node (Invalid) { id = -1; }
812 830
      bool operator==(const Node& node) const {return id == node.id;}
813 831
      bool operator!=(const Node& node) const {return id != node.id;}
814 832
      bool operator<(const Node& node) const {return id < node.id;}
815 833
    };
816 834

	
817 835
    class Edge {
818 836
      friend class ListGraphBase;
819 837
    protected:
820 838

	
821 839
      int id;
822 840
      explicit Edge(int pid) { id = pid;}
823 841

	
824 842
    public:
825 843
      Edge() {}
826 844
      Edge (Invalid) { id = -1; }
827 845
      bool operator==(const Edge& edge) const {return id == edge.id;}
828 846
      bool operator!=(const Edge& edge) const {return id != edge.id;}
829 847
      bool operator<(const Edge& edge) const {return id < edge.id;}
830 848
    };
831 849

	
832 850
    class Arc {
833 851
      friend class ListGraphBase;
834 852
    protected:
835 853

	
836 854
      int id;
837 855
      explicit Arc(int pid) { id = pid;}
838 856

	
839 857
    public:
840 858
      operator Edge() const {
841 859
        return id != -1 ? edgeFromId(id / 2) : INVALID;
842 860
      }
843 861

	
844 862
      Arc() {}
845 863
      Arc (Invalid) { id = -1; }
846 864
      bool operator==(const Arc& arc) const {return id == arc.id;}
847 865
      bool operator!=(const Arc& arc) const {return id != arc.id;}
848 866
      bool operator<(const Arc& arc) const {return id < arc.id;}
849 867
    };
850 868

	
851

	
852

	
853 869
    ListGraphBase()
854 870
      : nodes(), first_node(-1),
855 871
        first_free_node(-1), arcs(), first_free_arc(-1) {}
856 872

	
857 873

	
858 874
    int maxNodeId() const { return nodes.size()-1; }
859 875
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
860 876
    int maxArcId() const { return arcs.size()-1; }
861 877

	
862 878
    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
863 879
    Node target(Arc e) const { return Node(arcs[e.id].target); }
864 880

	
865 881
    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
866 882
    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
867 883

	
868 884
    static bool direction(Arc e) {
869 885
      return (e.id & 1) == 1;
870 886
    }
871 887

	
872 888
    static Arc direct(Edge e, bool d) {
873 889
      return Arc(e.id * 2 + (d ? 1 : 0));
874 890
    }
875 891

	
876 892
    void first(Node& node) const {
877 893
      node.id = first_node;
878 894
    }
879 895

	
880 896
    void next(Node& node) const {
881 897
      node.id = nodes[node.id].next;
882 898
    }
883 899

	
884 900
    void first(Arc& e) const {
885 901
      int n = first_node;
886 902
      while (n != -1 && nodes[n].first_out == -1) {
887 903
        n = nodes[n].next;
888 904
      }
889 905
      e.id = (n == -1) ? -1 : nodes[n].first_out;
890 906
    }
891 907

	
892 908
    void next(Arc& e) const {
893 909
      if (arcs[e.id].next_out != -1) {
894 910
        e.id = arcs[e.id].next_out;
895 911
      } else {
896 912
        int n = nodes[arcs[e.id ^ 1].target].next;
897 913
        while(n != -1 && nodes[n].first_out == -1) {
898 914
          n = nodes[n].next;
899 915
        }
900 916
        e.id = (n == -1) ? -1 : nodes[n].first_out;
901 917
      }
902 918
    }
903 919

	
904 920
    void first(Edge& e) const {
905 921
      int n = first_node;
906 922
      while (n != -1) {
907 923
        e.id = nodes[n].first_out;
908 924
        while ((e.id & 1) != 1) {
909 925
          e.id = arcs[e.id].next_out;
910 926
        }
911 927
        if (e.id != -1) {
912 928
          e.id /= 2;
913 929
          return;
914 930
        }
915 931
        n = nodes[n].next;
916 932
      }
917 933
      e.id = -1;
918 934
    }
919 935

	
920 936
    void next(Edge& e) const {
921 937
      int n = arcs[e.id * 2].target;
922 938
      e.id = arcs[(e.id * 2) | 1].next_out;
923 939
      while ((e.id & 1) != 1) {
924 940
        e.id = arcs[e.id].next_out;
925 941
      }
926 942
      if (e.id != -1) {
927 943
        e.id /= 2;
928 944
        return;
929 945
      }
930 946
      n = nodes[n].next;
931 947
      while (n != -1) {
932 948
        e.id = nodes[n].first_out;
933 949
        while ((e.id & 1) != 1) {
934 950
          e.id = arcs[e.id].next_out;
935 951
        }
936 952
        if (e.id != -1) {
937 953
          e.id /= 2;
938 954
          return;
939 955
        }
940 956
        n = nodes[n].next;
941 957
      }
942 958
      e.id = -1;
943 959
    }
944 960

	
945 961
    void firstOut(Arc &e, const Node& v) const {
946 962
      e.id = nodes[v.id].first_out;
947 963
    }
948 964
    void nextOut(Arc &e) const {
949 965
      e.id = arcs[e.id].next_out;
950 966
    }
951 967

	
952 968
    void firstIn(Arc &e, const Node& v) const {
953 969
      e.id = ((nodes[v.id].first_out) ^ 1);
954 970
      if (e.id == -2) e.id = -1;
955 971
    }
956 972
    void nextIn(Arc &e) const {
957 973
      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
958 974
      if (e.id == -2) e.id = -1;
959 975
    }
960 976

	
961 977
    void firstInc(Edge &e, bool& d, const Node& v) const {
962 978
      int a = nodes[v.id].first_out;
963 979
      if (a != -1 ) {
964 980
        e.id = a / 2;
965 981
        d = ((a & 1) == 1);
966 982
      } else {
967 983
        e.id = -1;
968 984
        d = true;
969 985
      }
970 986
    }
971 987
    void nextInc(Edge &e, bool& d) const {
972 988
      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
973 989
      if (a != -1 ) {
974 990
        e.id = a / 2;
975 991
        d = ((a & 1) == 1);
976 992
      } else {
977 993
        e.id = -1;
978 994
        d = true;
979 995
      }
980 996
    }
981 997

	
982 998
    static int id(Node v) { return v.id; }
983 999
    static int id(Arc e) { return e.id; }
984 1000
    static int id(Edge e) { return e.id; }
985 1001

	
986 1002
    static Node nodeFromId(int id) { return Node(id);}
987 1003
    static Arc arcFromId(int id) { return Arc(id);}
988 1004
    static Edge edgeFromId(int id) { return Edge(id);}
989 1005

	
990 1006
    bool valid(Node n) const {
991 1007
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
992 1008
        nodes[n.id].prev != -2;
993 1009
    }
994 1010

	
995 1011
    bool valid(Arc a) const {
996 1012
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
997 1013
        arcs[a.id].prev_out != -2;
998 1014
    }
999 1015

	
1000 1016
    bool valid(Edge e) const {
1001 1017
      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
1002 1018
        arcs[2 * e.id].prev_out != -2;
1003 1019
    }
1004 1020

	
1005 1021
    Node addNode() {
1006 1022
      int n;
1007 1023

	
1008 1024
      if(first_free_node==-1) {
1009 1025
        n = nodes.size();
1010 1026
        nodes.push_back(NodeT());
1011 1027
      } else {
1012 1028
        n = first_free_node;
1013 1029
        first_free_node = nodes[n].next;
1014 1030
      }
1015 1031

	
1016 1032
      nodes[n].next = first_node;
1017 1033
      if (first_node != -1) nodes[first_node].prev = n;
1018 1034
      first_node = n;
1019 1035
      nodes[n].prev = -1;
1020 1036

	
1021 1037
      nodes[n].first_out = -1;
1022 1038

	
1023 1039
      return Node(n);
1024 1040
    }
1025 1041

	
1026 1042
    Edge addEdge(Node u, Node v) {
1027 1043
      int n;
1028 1044

	
1029 1045
      if (first_free_arc == -1) {
1030 1046
        n = arcs.size();
1031 1047
        arcs.push_back(ArcT());
1032 1048
        arcs.push_back(ArcT());
1033 1049
      } else {
1034 1050
        n = first_free_arc;
1035 1051
        first_free_arc = arcs[n].next_out;
1036 1052
      }
1037 1053

	
1038 1054
      arcs[n].target = u.id;
1039 1055
      arcs[n | 1].target = v.id;
1040 1056

	
1041 1057
      arcs[n].next_out = nodes[v.id].first_out;
1042 1058
      if (nodes[v.id].first_out != -1) {
1043 1059
        arcs[nodes[v.id].first_out].prev_out = n;
1044 1060
      }
1045 1061
      arcs[n].prev_out = -1;
1046 1062
      nodes[v.id].first_out = n;
1047 1063

	
1048 1064
      arcs[n | 1].next_out = nodes[u.id].first_out;
1049 1065
      if (nodes[u.id].first_out != -1) {
1050 1066
        arcs[nodes[u.id].first_out].prev_out = (n | 1);
1051 1067
      }
1052 1068
      arcs[n | 1].prev_out = -1;
1053 1069
      nodes[u.id].first_out = (n | 1);
1054 1070

	
1055 1071
      return Edge(n / 2);
1056 1072
    }
1057 1073

	
1058 1074
    void erase(const Node& node) {
1059 1075
      int n = node.id;
1060 1076

	
1061 1077
      if(nodes[n].next != -1) {
1062 1078
        nodes[nodes[n].next].prev = nodes[n].prev;
1063 1079
      }
1064 1080

	
1065 1081
      if(nodes[n].prev != -1) {
1066 1082
        nodes[nodes[n].prev].next = nodes[n].next;
1067 1083
      } else {
1068 1084
        first_node = nodes[n].next;
1069 1085
      }
1070 1086

	
1071 1087
      nodes[n].next = first_free_node;
1072 1088
      first_free_node = n;
1073 1089
      nodes[n].prev = -2;
1074 1090
    }
1075 1091

	
1076 1092
    void erase(const Edge& edge) {
1077 1093
      int n = edge.id * 2;
1078 1094

	
1079 1095
      if (arcs[n].next_out != -1) {
1080 1096
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1081 1097
      }
1082 1098

	
1083 1099
      if (arcs[n].prev_out != -1) {
1084 1100
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1085 1101
      } else {
1086 1102
        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1087 1103
      }
1088 1104

	
1089 1105
      if (arcs[n | 1].next_out != -1) {
1090 1106
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1091 1107
      }
1092 1108

	
1093 1109
      if (arcs[n | 1].prev_out != -1) {
1094 1110
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1095 1111
      } else {
1096 1112
        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1097 1113
      }
1098 1114

	
1099 1115
      arcs[n].next_out = first_free_arc;
1100 1116
      first_free_arc = n;
1101 1117
      arcs[n].prev_out = -2;
1102 1118
      arcs[n | 1].prev_out = -2;
1103 1119

	
1104 1120
    }
1105 1121

	
1106 1122
    void clear() {
1107 1123
      arcs.clear();
1108 1124
      nodes.clear();
1109 1125
      first_node = first_free_node = first_free_arc = -1;
1110 1126
    }
1111 1127

	
1112 1128
  protected:
1113 1129

	
1114 1130
    void changeV(Edge e, Node n) {
1115 1131
      if(arcs[2 * e.id].next_out != -1) {
1116 1132
        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1117 1133
      }
1118 1134
      if(arcs[2 * e.id].prev_out != -1) {
1119 1135
        arcs[arcs[2 * e.id].prev_out].next_out =
1120 1136
          arcs[2 * e.id].next_out;
1121 1137
      } else {
1122 1138
        nodes[arcs[(2 * e.id) | 1].target].first_out =
1123 1139
          arcs[2 * e.id].next_out;
1124 1140
      }
1125 1141

	
1126 1142
      if (nodes[n.id].first_out != -1) {
1127 1143
        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1128 1144
      }
1129 1145
      arcs[(2 * e.id) | 1].target = n.id;
1130 1146
      arcs[2 * e.id].prev_out = -1;
1131 1147
      arcs[2 * e.id].next_out = nodes[n.id].first_out;
1132 1148
      nodes[n.id].first_out = 2 * e.id;
1133 1149
    }
1134 1150

	
1135 1151
    void changeU(Edge e, Node n) {
1136 1152
      if(arcs[(2 * e.id) | 1].next_out != -1) {
1137 1153
        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
1138 1154
          arcs[(2 * e.id) | 1].prev_out;
1139 1155
      }
1140 1156
      if(arcs[(2 * e.id) | 1].prev_out != -1) {
1141 1157
        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
1142 1158
          arcs[(2 * e.id) | 1].next_out;
1143 1159
      } else {
1144 1160
        nodes[arcs[2 * e.id].target].first_out =
1145 1161
          arcs[(2 * e.id) | 1].next_out;
1146 1162
      }
1147 1163

	
1148 1164
      if (nodes[n.id].first_out != -1) {
1149 1165
        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1150 1166
      }
1151 1167
      arcs[2 * e.id].target = n.id;
1152 1168
      arcs[(2 * e.id) | 1].prev_out = -1;
1153 1169
      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1154 1170
      nodes[n.id].first_out = ((2 * e.id) | 1);
1155 1171
    }
1156 1172

	
1157 1173
  };
1158 1174

	
1159 1175
  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1160 1176

	
1161 1177

	
1162 1178
  /// \addtogroup graphs
1163 1179
  /// @{
1164 1180

	
1165 1181
  ///A general undirected graph structure.
1166 1182

	
1167
  ///\ref ListGraph is a simple and fast <em>undirected graph</em>
1168
  ///implementation based on static linked lists that are stored in
1183
  ///\ref ListGraph is a versatile and fast undirected graph
1184
  ///implementation based on linked lists that are stored in
1169 1185
  ///\c std::vector structures.
1170 1186
  ///
1171
  ///It conforms to the \ref concepts::Graph "Graph concept" and it
1172
  ///also provides several useful additional functionalities.
1173
  ///Most of the member functions and nested classes are documented
1187
  ///This type fully conforms to the \ref concepts::Graph "Graph concept"
1188
  ///and it also provides several useful additional functionalities.
1189
  ///Most of its member functions and nested classes are documented
1174 1190
  ///only in the concept class.
1175 1191
  ///
1192
  ///This class provides only linear time counting for nodes, edges and arcs.
1193
  ///
1176 1194
  ///\sa concepts::Graph
1177

	
1195
  ///\sa ListDigraph
1178 1196
  class ListGraph : public ExtendedListGraphBase {
1179 1197
    typedef ExtendedListGraphBase Parent;
1180 1198

	
1181 1199
  private:
1182
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1183

	
1184
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1185
    ///
1200
    /// Graphs are \e not copy constructible. Use GraphCopy instead.
1186 1201
    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
1187
    ///\brief Assignment of ListGraph to another one is \e not allowed.
1188
    ///Use copyGraph() instead.
1189

	
1190
    ///Assignment of ListGraph to another one is \e not allowed.
1191
    ///Use copyGraph() instead.
1202
    /// \brief Assignment of a graph to another one is \e not allowed.
1203
    /// Use GraphCopy instead.
1192 1204
    void operator=(const ListGraph &) {}
1193 1205
  public:
1194 1206
    /// Constructor
1195 1207

	
1196 1208
    /// Constructor.
1197 1209
    ///
1198 1210
    ListGraph() {}
1199 1211

	
1200 1212
    typedef Parent::OutArcIt IncEdgeIt;
1201 1213

	
1202 1214
    /// \brief Add a new node to the graph.
1203 1215
    ///
1204
    /// Add a new node to the graph.
1216
    /// This function adds a new node to the graph.
1205 1217
    /// \return The new node.
1206 1218
    Node addNode() { return Parent::addNode(); }
1207 1219

	
1208 1220
    /// \brief Add a new edge to the graph.
1209 1221
    ///
1210
    /// Add a new edge to the graph with source node \c s
1211
    /// and target node \c t.
1222
    /// This function adds a new edge to the graph between nodes
1223
    /// \c u and \c v with inherent orientation from node \c u to
1224
    /// node \c v.
1212 1225
    /// \return The new edge.
1213
    Edge addEdge(const Node& s, const Node& t) {
1214
      return Parent::addEdge(s, t);
1226
    Edge addEdge(Node u, Node v) {
1227
      return Parent::addEdge(u, v);
1215 1228
    }
1216 1229

	
1217
    /// \brief Erase a node from the graph.
1230
    ///\brief Erase a node from the graph.
1218 1231
    ///
1219
    /// Erase a node from the graph.
1232
    /// This function erases the given node along with its incident arcs
1233
    /// from the graph.
1220 1234
    ///
1221
    void erase(const Node& n) { Parent::erase(n); }
1235
    /// \note All iterators referencing the removed node or the incident
1236
    /// edges are invalidated, of course.
1237
    void erase(Node n) { Parent::erase(n); }
1222 1238

	
1223
    /// \brief Erase an edge from the graph.
1239
    ///\brief Erase an edge from the graph.
1224 1240
    ///
1225
    /// Erase an edge from the graph.
1241
    /// This function erases the given edge from the graph.
1226 1242
    ///
1227
    void erase(const Edge& e) { Parent::erase(e); }
1243
    /// \note All iterators referencing the removed edge are invalidated,
1244
    /// of course.
1245
    void erase(Edge e) { Parent::erase(e); }
1228 1246
    /// Node validity check
1229 1247

	
1230
    /// This function gives back true if the given node is valid,
1231
    /// ie. it is a real node of the graph.
1248
    /// This function gives back \c true if the given node is valid,
1249
    /// i.e. it is a real node of the graph.
1232 1250
    ///
1233
    /// \warning A Node pointing to a removed item
1234
    /// could become valid again later if new nodes are
1251
    /// \warning A removed node could become valid again if new nodes are
1235 1252
    /// added to the graph.
1236 1253
    bool valid(Node n) const { return Parent::valid(n); }
1254
    /// Edge validity check
1255

	
1256
    /// This function gives back \c true if the given edge is valid,
1257
    /// i.e. it is a real edge of the graph.
1258
    ///
1259
    /// \warning A removed edge could become valid again if new edges are
1260
    /// added to the graph.
1261
    bool valid(Edge e) const { return Parent::valid(e); }
1237 1262
    /// Arc validity check
1238 1263

	
1239
    /// This function gives back true if the given arc is valid,
1240
    /// ie. it is a real arc of the graph.
1264
    /// This function gives back \c true if the given arc is valid,
1265
    /// i.e. it is a real arc of the graph.
1241 1266
    ///
1242
    /// \warning An Arc pointing to a removed item
1243
    /// could become valid again later if new edges are
1267
    /// \warning A removed arc could become valid again if new edges are
1244 1268
    /// added to the graph.
1245 1269
    bool valid(Arc a) const { return Parent::valid(a); }
1246
    /// Edge validity check
1247 1270

	
1248
    /// This function gives back true if the given edge is valid,
1249
    /// ie. it is a real arc of the graph.
1271
    /// \brief Change the first node of an edge.
1250 1272
    ///
1251
    /// \warning A Edge pointing to a removed item
1252
    /// could become valid again later if new edges are
1253
    /// added to the graph.
1254
    bool valid(Edge e) const { return Parent::valid(e); }
1255
    /// \brief Change the end \c u of \c e to \c n
1273
    /// This function changes the first node of the given edge \c e to \c n.
1256 1274
    ///
1257
    /// This function changes the end \c u of \c e to node \c n.
1258
    ///
1259
    ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
1260
    ///changed edge are invalidated and if the changed node is the
1261
    ///base node of an iterator then this iterator is also
1262
    ///invalidated.
1275
    ///\note \c EdgeIt and \c ArcIt iterators referencing the
1276
    ///changed edge are invalidated and all other iterators whose
1277
    ///base node is the changed node are also invalidated.
1263 1278
    ///
1264 1279
    ///\warning This functionality cannot be used together with the
1265 1280
    ///Snapshot feature.
1266 1281
    void changeU(Edge e, Node n) {
1267 1282
      Parent::changeU(e,n);
1268 1283
    }
1269
    /// \brief Change the end \c v of \c e to \c n
1284
    /// \brief Change the second node of an edge.
1270 1285
    ///
1271
    /// This function changes the end \c v of \c e to \c n.
1286
    /// This function changes the second node of the given edge \c e to \c n.
1272 1287
    ///
1273
    ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
1274
    ///valid, however <tt>ArcIt</tt>s and if the changed node is the
1275
    ///base node of an iterator then this iterator is invalidated.
1288
    ///\note \c EdgeIt iterators referencing the changed edge remain
1289
    ///valid, but \c ArcIt iterators referencing the changed edge and
1290
    ///all other iterators whose base node is the changed node are also
1291
    ///invalidated.
1276 1292
    ///
1277 1293
    ///\warning This functionality cannot be used together with the
1278 1294
    ///Snapshot feature.
1279 1295
    void changeV(Edge e, Node n) {
1280 1296
      Parent::changeV(e,n);
1281 1297
    }
1298

	
1282 1299
    /// \brief Contract two nodes.
1283 1300
    ///
1284
    /// This function contracts two nodes.
1285
    /// Node \p b will be removed but instead of deleting
1286
    /// its neighboring arcs, they will be joined to \p a.
1287
    /// The last parameter \p r controls whether to remove loops. \c true
1288
    /// means that loops will be removed.
1301
    /// This function contracts the given two nodes.
1302
    /// Node \c b is removed, but instead of deleting
1303
    /// its incident edges, they are joined to node \c a.
1304
    /// If the last parameter \c r is \c true (this is the default value),
1305
    /// then the newly created loops are removed.
1289 1306
    ///
1290
    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
1291
    /// valid.
1307
    /// \note The moved edges are joined to node \c a using changeU()
1308
    /// or changeV(), thus all edge and arc iterators whose base node is
1309
    /// \c b are invalidated.
1310
    /// Moreover all iterators referencing node \c b or the removed
1311
    /// loops are also invalidated. Other iterators remain valid.
1292 1312
    ///
1293 1313
    ///\warning This functionality cannot be used together with the
1294 1314
    ///Snapshot feature.
1295 1315
    void contract(Node a, Node b, bool r = true) {
1296 1316
      for(IncEdgeIt e(*this, b); e!=INVALID;) {
1297 1317
        IncEdgeIt f = e; ++f;
1298 1318
        if (r && runningNode(e) == a) {
1299 1319
          erase(e);
1300 1320
        } else if (u(e) == b) {
1301 1321
          changeU(e, a);
1302 1322
        } else {
1303 1323
          changeV(e, a);
1304 1324
        }
1305 1325
        e = f;
1306 1326
      }
1307 1327
      erase(b);
1308 1328
    }
1309 1329

	
1330
    ///Clear the graph.
1331

	
1332
    ///This function erases all nodes and arcs from the graph.
1333
    ///
1334
    ///\note All iterators of the graph are invalidated, of course.
1335
    void clear() {
1336
      Parent::clear();
1337
    }
1338

	
1339
    /// Reserve memory for nodes.
1340

	
1341
    /// Using this function, it is possible to avoid superfluous memory
1342
    /// allocation: if you know that the graph you want to build will
1343
    /// be large (e.g. it will contain millions of nodes and/or edges),
1344
    /// then it is worth reserving space for this amount before starting
1345
    /// to build the graph.
1346
    /// \sa reserveEdge()
1347
    void reserveNode(int n) { nodes.reserve(n); };
1348

	
1349
    /// Reserve memory for edges.
1350

	
1351
    /// Using this function, it is possible to avoid superfluous memory
1352
    /// allocation: if you know that the graph you want to build will
1353
    /// be large (e.g. it will contain millions of nodes and/or edges),
1354
    /// then it is worth reserving space for this amount before starting
1355
    /// to build the graph.
1356
    /// \sa reserveNode()
1357
    void reserveEdge(int m) { arcs.reserve(2 * m); };
1310 1358

	
1311 1359
    /// \brief Class to make a snapshot of the graph and restore
1312 1360
    /// it later.
1313 1361
    ///
1314 1362
    /// Class to make a snapshot of the graph and restore it later.
1315 1363
    ///
1316 1364
    /// The newly added nodes and edges can be removed
1317 1365
    /// using the restore() function.
1318 1366
    ///
1319
    /// \warning Edge and node deletions and other modifications
1320
    /// (e.g. changing nodes of edges, contracting nodes) cannot be
1321
    /// restored. These events invalidate the snapshot.
1367
    /// \note After a state is restored, you cannot restore a later state,
1368
    /// i.e. you cannot add the removed nodes and edges again using
1369
    /// another Snapshot instance.
1370
    ///
1371
    /// \warning Node and edge deletions and other modifications
1372
    /// (e.g. changing the end-nodes of edges or contracting nodes)
1373
    /// cannot be restored. These events invalidate the snapshot.
1374
    /// However, the edges and nodes that were added to the graph after
1375
    /// making the current snapshot can be removed without invalidating it.
1322 1376
    class Snapshot {
1323 1377
    protected:
1324 1378

	
1325 1379
      typedef Parent::NodeNotifier NodeNotifier;
1326 1380

	
1327 1381
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
1328 1382
      public:
1329 1383

	
1330 1384
        NodeObserverProxy(Snapshot& _snapshot)
1331 1385
          : snapshot(_snapshot) {}
1332 1386

	
1333 1387
        using NodeNotifier::ObserverBase::attach;
1334 1388
        using NodeNotifier::ObserverBase::detach;
1335 1389
        using NodeNotifier::ObserverBase::attached;
1336 1390

	
1337 1391
      protected:
1338 1392

	
1339 1393
        virtual void add(const Node& node) {
1340 1394
          snapshot.addNode(node);
1341 1395
        }
1342 1396
        virtual void add(const std::vector<Node>& nodes) {
1343 1397
          for (int i = nodes.size() - 1; i >= 0; ++i) {
1344 1398
            snapshot.addNode(nodes[i]);
1345 1399
          }
1346 1400
        }
1347 1401
        virtual void erase(const Node& node) {
1348 1402
          snapshot.eraseNode(node);
1349 1403
        }
1350 1404
        virtual void erase(const std::vector<Node>& nodes) {
1351 1405
          for (int i = 0; i < int(nodes.size()); ++i) {
1352 1406
            snapshot.eraseNode(nodes[i]);
1353 1407
          }
1354 1408
        }
1355 1409
        virtual void build() {
1356 1410
          Node node;
1357 1411
          std::vector<Node> nodes;
1358 1412
          for (notifier()->first(node); node != INVALID;
1359 1413
               notifier()->next(node)) {
1360 1414
            nodes.push_back(node);
1361 1415
          }
1362 1416
          for (int i = nodes.size() - 1; i >= 0; --i) {
1363 1417
            snapshot.addNode(nodes[i]);
1364 1418
          }
1365 1419
        }
1366 1420
        virtual void clear() {
1367 1421
          Node node;
1368 1422
          for (notifier()->first(node); node != INVALID;
1369 1423
               notifier()->next(node)) {
1370 1424
            snapshot.eraseNode(node);
1371 1425
          }
1372 1426
        }
1373 1427

	
1374 1428
        Snapshot& snapshot;
1375 1429
      };
1376 1430

	
1377 1431
      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1378 1432
      public:
1379 1433

	
1380 1434
        EdgeObserverProxy(Snapshot& _snapshot)
1381 1435
          : snapshot(_snapshot) {}
1382 1436

	
1383 1437
        using EdgeNotifier::ObserverBase::attach;
1384 1438
        using EdgeNotifier::ObserverBase::detach;
1385 1439
        using EdgeNotifier::ObserverBase::attached;
1386 1440

	
1387 1441
      protected:
1388 1442

	
1389 1443
        virtual void add(const Edge& edge) {
1390 1444
          snapshot.addEdge(edge);
1391 1445
        }
1392 1446
        virtual void add(const std::vector<Edge>& edges) {
1393 1447
          for (int i = edges.size() - 1; i >= 0; ++i) {
1394 1448
            snapshot.addEdge(edges[i]);
1395 1449
          }
1396 1450
        }
1397 1451
        virtual void erase(const Edge& edge) {
1398 1452
          snapshot.eraseEdge(edge);
1399 1453
        }
1400 1454
        virtual void erase(const std::vector<Edge>& edges) {
1401 1455
          for (int i = 0; i < int(edges.size()); ++i) {
1402 1456
            snapshot.eraseEdge(edges[i]);
1403 1457
          }
1404 1458
        }
1405 1459
        virtual void build() {
1406 1460
          Edge edge;
1407 1461
          std::vector<Edge> edges;
1408 1462
          for (notifier()->first(edge); edge != INVALID;
1409 1463
               notifier()->next(edge)) {
1410 1464
            edges.push_back(edge);
1411 1465
          }
1412 1466
          for (int i = edges.size() - 1; i >= 0; --i) {
1413 1467
            snapshot.addEdge(edges[i]);
1414 1468
          }
1415 1469
        }
1416 1470
        virtual void clear() {
1417 1471
          Edge edge;
1418 1472
          for (notifier()->first(edge); edge != INVALID;
1419 1473
               notifier()->next(edge)) {
1420 1474
            snapshot.eraseEdge(edge);
1421 1475
          }
1422 1476
        }
1423 1477

	
1424 1478
        Snapshot& snapshot;
1425 1479
      };
1426 1480

	
1427 1481
      ListGraph *graph;
1428 1482

	
1429 1483
      NodeObserverProxy node_observer_proxy;
1430 1484
      EdgeObserverProxy edge_observer_proxy;
1431 1485

	
1432 1486
      std::list<Node> added_nodes;
1433 1487
      std::list<Edge> added_edges;
1434 1488

	
1435 1489

	
1436 1490
      void addNode(const Node& node) {
1437 1491
        added_nodes.push_front(node);
1438 1492
      }
1439 1493
      void eraseNode(const Node& node) {
1440 1494
        std::list<Node>::iterator it =
1441 1495
          std::find(added_nodes.begin(), added_nodes.end(), node);
1442 1496
        if (it == added_nodes.end()) {
1443 1497
          clear();
1444 1498
          edge_observer_proxy.detach();
1445 1499
          throw NodeNotifier::ImmediateDetach();
1446 1500
        } else {
1447 1501
          added_nodes.erase(it);
1448 1502
        }
1449 1503
      }
1450 1504

	
1451 1505
      void addEdge(const Edge& edge) {
1452 1506
        added_edges.push_front(edge);
1453 1507
      }
1454 1508
      void eraseEdge(const Edge& edge) {
1455 1509
        std::list<Edge>::iterator it =
1456 1510
          std::find(added_edges.begin(), added_edges.end(), edge);
1457 1511
        if (it == added_edges.end()) {
1458 1512
          clear();
1459 1513
          node_observer_proxy.detach();
1460 1514
          throw EdgeNotifier::ImmediateDetach();
1461 1515
        } else {
1462 1516
          added_edges.erase(it);
1463 1517
        }
1464 1518
      }
1465 1519

	
1466 1520
      void attach(ListGraph &_graph) {
1467 1521
        graph = &_graph;
1468 1522
        node_observer_proxy.attach(graph->notifier(Node()));
1469 1523
        edge_observer_proxy.attach(graph->notifier(Edge()));
1470 1524
      }
1471 1525

	
1472 1526
      void detach() {
1473 1527
        node_observer_proxy.detach();
1474 1528
        edge_observer_proxy.detach();
1475 1529
      }
1476 1530

	
1477 1531
      bool attached() const {
1478 1532
        return node_observer_proxy.attached();
1479 1533
      }
1480 1534

	
1481 1535
      void clear() {
1482 1536
        added_nodes.clear();
1483 1537
        added_edges.clear();
1484 1538
      }
1485 1539

	
1486 1540
    public:
1487 1541

	
1488 1542
      /// \brief Default constructor.
1489 1543
      ///
1490 1544
      /// Default constructor.
1491
      /// To actually make a snapshot you must call save().
1545
      /// You have to call save() to actually make a snapshot.
1492 1546
      Snapshot()
1493 1547
        : graph(0), node_observer_proxy(*this),
1494 1548
          edge_observer_proxy(*this) {}
1495 1549

	
1496 1550
      /// \brief Constructor that immediately makes a snapshot.
1497 1551
      ///
1498
      /// This constructor immediately makes a snapshot of the graph.
1499
      /// \param _graph The graph we make a snapshot of.
1500
      Snapshot(ListGraph &_graph)
1552
      /// This constructor immediately makes a snapshot of the given graph.
1553
      Snapshot(ListGraph &gr)
1501 1554
        : node_observer_proxy(*this),
1502 1555
          edge_observer_proxy(*this) {
1503
        attach(_graph);
1556
        attach(gr);
1504 1557
      }
1505 1558

	
1506 1559
      /// \brief Make a snapshot.
1507 1560
      ///
1508
      /// Make a snapshot of the graph.
1509
      ///
1510
      /// This function can be called more than once. In case of a repeated
1561
      /// This function makes a snapshot of the given graph.
1562
      /// It can be called more than once. In case of a repeated
1511 1563
      /// call, the previous snapshot gets lost.
1512
      /// \param _graph The graph we make the snapshot of.
1513
      void save(ListGraph &_graph) {
1564
      void save(ListGraph &gr) {
1514 1565
        if (attached()) {
1515 1566
          detach();
1516 1567
          clear();
1517 1568
        }
1518
        attach(_graph);
1569
        attach(gr);
1519 1570
      }
1520 1571

	
1521 1572
      /// \brief Undo the changes until the last snapshot.
1522
      //
1523
      /// Undo the changes until the last snapshot created by save().
1573
      ///
1574
      /// This function undos the changes until the last snapshot
1575
      /// created by save() or Snapshot(ListGraph&).
1576
      ///
1577
      /// \warning This method invalidates the snapshot, i.e. repeated
1578
      /// restoring is not supported unless you call save() again.
1524 1579
      void restore() {
1525 1580
        detach();
1526 1581
        for(std::list<Edge>::iterator it = added_edges.begin();
1527 1582
            it != added_edges.end(); ++it) {
1528 1583
          graph->erase(*it);
1529 1584
        }
1530 1585
        for(std::list<Node>::iterator it = added_nodes.begin();
1531 1586
            it != added_nodes.end(); ++it) {
1532 1587
          graph->erase(*it);
1533 1588
        }
1534 1589
        clear();
1535 1590
      }
1536 1591

	
1537
      /// \brief Gives back true when the snapshot is valid.
1592
      /// \brief Returns \c true if the snapshot is valid.
1538 1593
      ///
1539
      /// Gives back true when the snapshot is valid.
1594
      /// This function returns \c true if the snapshot is valid.
1540 1595
      bool valid() const {
1541 1596
        return attached();
1542 1597
      }
1543 1598
    };
1544 1599
  };
1545 1600

	
1546 1601
  /// @}
1547 1602
} //namespace lemon
1548 1603

	
1549 1604

	
1550 1605
#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-2010
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_LP_H
20 20
#define LEMON_LP_H
21 21

	
22 22
#include<lemon/config.h>
23 23

	
24 24

	
25 25
#ifdef LEMON_HAVE_GLPK
26 26
#include <lemon/glpk.h>
27 27
#elif LEMON_HAVE_CPLEX
28 28
#include <lemon/cplex.h>
29 29
#elif LEMON_HAVE_SOPLEX
30 30
#include <lemon/soplex.h>
31 31
#elif LEMON_HAVE_CLP
32 32
#include <lemon/clp.h>
33 33
#endif
34 34

	
35 35
///\file
36 36
///\brief Defines a default LP solver
37 37
///\ingroup lp_group
38 38
namespace lemon {
39 39

	
40 40
#ifdef DOXYGEN
41 41
  ///The default LP solver identifier
42 42

	
43 43
  ///The default LP solver identifier.
44 44
  ///\ingroup lp_group
45 45
  ///
46 46
  ///Currently, the possible values are \c GLPK, \c CPLEX,
47 47
  ///\c SOPLEX or \c CLP
48 48
#define LEMON_DEFAULT_LP SOLVER
49 49
  ///The default LP solver
50 50

	
51 51
  ///The default LP solver.
52 52
  ///\ingroup lp_group
53 53
  ///
54 54
  ///Currently, it is either \c GlpkLp, \c CplexLp, \c SoplexLp or \c ClpLp
55 55
  typedef GlpkLp Lp;
56 56

	
57 57
  ///The default MIP solver identifier
58 58

	
59 59
  ///The default MIP solver identifier.
60 60
  ///\ingroup lp_group
61 61
  ///
62 62
  ///Currently, the possible values are \c GLPK or \c CPLEX
63 63
#define LEMON_DEFAULT_MIP SOLVER
64 64
  ///The default MIP solver.
65 65

	
66 66
  ///The default MIP solver.
67 67
  ///\ingroup lp_group
68 68
  ///
69 69
  ///Currently, it is either \c GlpkMip or \c CplexMip
70 70
  typedef GlpkMip Mip;
71 71
#else
72 72
#ifdef LEMON_HAVE_GLPK
73 73
# define LEMON_DEFAULT_LP GLPK
74 74
  typedef GlpkLp Lp;
75 75
# define LEMON_DEFAULT_MIP GLPK
76 76
  typedef GlpkMip Mip;
77 77
#elif LEMON_HAVE_CPLEX
78 78
# define LEMON_DEFAULT_LP CPLEX
79 79
  typedef CplexLp Lp;
80 80
# define LEMON_DEFAULT_MIP CPLEX
81 81
  typedef CplexMip Mip;
82 82
#elif LEMON_HAVE_SOPLEX
83 83
# define DEFAULT_LP SOPLEX
84 84
  typedef SoplexLp Lp;
85 85
#elif LEMON_HAVE_CLP
86 86
# define DEFAULT_LP CLP
87
  typedef ClpLp Lp;  
87
  typedef ClpLp Lp;
88 88
#endif
89 89
#endif
90 90

	
91 91
} //namespace lemon
92 92

	
93 93
#endif //LEMON_LP_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-2010
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 The implementation of the LP solver interface.
21 21

	
22 22
#include <lemon/lp_base.h>
23 23
namespace lemon {
24 24

	
25 25
  const LpBase::Value LpBase::INF =
26 26
    std::numeric_limits<LpBase::Value>::infinity();
27 27
  const LpBase::Value LpBase::NaN =
28 28
    std::numeric_limits<LpBase::Value>::quiet_NaN();
29 29

	
30 30
} //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-2010
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_LP_BASE_H
20 20
#define LEMON_LP_BASE_H
21 21

	
22 22
#include<iostream>
23 23
#include<vector>
24 24
#include<map>
25 25
#include<limits>
26 26
#include<lemon/math.h>
27 27

	
28 28
#include<lemon/error.h>
29 29
#include<lemon/assert.h>
30 30

	
31 31
#include<lemon/core.h>
32 32
#include<lemon/bits/solver_bits.h>
33 33

	
34 34
///\file
35 35
///\brief The interface of the LP solver interface.
36 36
///\ingroup lp_group
37 37
namespace lemon {
38 38

	
39 39
  ///Common base class for LP and MIP solvers
40 40

	
41 41
  ///Usually this class is not used directly, please use one of the concrete
42 42
  ///implementations of the solver interface.
43 43
  ///\ingroup lp_group
44 44
  class LpBase {
45 45

	
46 46
  protected:
47 47

	
48 48
    _solver_bits::VarIndex rows;
49 49
    _solver_bits::VarIndex cols;
50 50

	
51 51
  public:
52 52

	
53 53
    ///Possible outcomes of an LP solving procedure
54 54
    enum SolveExitStatus {
55 55
      /// = 0. It means that the problem has been successfully solved: either
56 56
      ///an optimal solution has been found or infeasibility/unboundedness
57 57
      ///has been proved.
58 58
      SOLVED = 0,
59 59
      /// = 1. Any other case (including the case when some user specified
60 60
      ///limit has been exceeded).
61 61
      UNSOLVED = 1
62 62
    };
63 63

	
64 64
    ///Direction of the optimization
65 65
    enum Sense {
66 66
      /// Minimization
67 67
      MIN,
68 68
      /// Maximization
69 69
      MAX
70 70
    };
71 71

	
72 72
    ///Enum for \c messageLevel() parameter
73 73
    enum MessageLevel {
74 74
      /// No output (default value).
75 75
      MESSAGE_NOTHING,
76 76
      /// Error messages only.
77 77
      MESSAGE_ERROR,
78 78
      /// Warnings.
79 79
      MESSAGE_WARNING,
80 80
      /// Normal output.
81 81
      MESSAGE_NORMAL,
82 82
      /// Verbose output.
83 83
      MESSAGE_VERBOSE
84 84
    };
85
    
85

	
86 86

	
87 87
    ///The floating point type used by the solver
88 88
    typedef double Value;
89 89
    ///The infinity constant
90 90
    static const Value INF;
91 91
    ///The not a number constant
92 92
    static const Value NaN;
93 93

	
94 94
    friend class Col;
95 95
    friend class ColIt;
96 96
    friend class Row;
97 97
    friend class RowIt;
98 98

	
99 99
    ///Refer to a column of the LP.
100 100

	
101 101
    ///This type is used to refer to a column of the LP.
102 102
    ///
103 103
    ///Its value remains valid and correct even after the addition or erase of
104 104
    ///other columns.
105 105
    ///
106 106
    ///\note This class is similar to other Item types in LEMON, like
107 107
    ///Node and Arc types in digraph.
108 108
    class Col {
109 109
      friend class LpBase;
110 110
    protected:
111 111
      int _id;
112 112
      explicit Col(int id) : _id(id) {}
113 113
    public:
114 114
      typedef Value ExprValue;
115 115
      typedef True LpCol;
116 116
      /// Default constructor
117
      
117

	
118 118
      /// \warning The default constructor sets the Col to an
119 119
      /// undefined value.
120 120
      Col() {}
121 121
      /// Invalid constructor \& conversion.
122
      
122

	
123 123
      /// This constructor initializes the Col to be invalid.
124
      /// \sa Invalid for more details.      
124
      /// \sa Invalid for more details.
125 125
      Col(const Invalid&) : _id(-1) {}
126 126
      /// Equality operator
127 127

	
128 128
      /// Two \ref Col "Col"s are equal if and only if they point to
129 129
      /// the same LP column or both are invalid.
130 130
      bool operator==(Col c) const  {return _id == c._id;}
131 131
      /// Inequality operator
132 132

	
133 133
      /// \sa operator==(Col c)
134 134
      ///
135 135
      bool operator!=(Col c) const  {return _id != c._id;}
136 136
      /// Artificial ordering operator.
137 137

	
138 138
      /// To allow the use of this object in std::map or similar
139 139
      /// associative container we require this.
140 140
      ///
141 141
      /// \note This operator only have to define some strict ordering of
142 142
      /// the items; this order has nothing to do with the iteration
143 143
      /// ordering of the items.
144 144
      bool operator<(Col c) const  {return _id < c._id;}
145 145
    };
146 146

	
147 147
    ///Iterator for iterate over the columns of an LP problem
148 148

	
149
    /// Its usage is quite simple, for example you can count the number
149
    /// Its usage is quite simple, for example, you can count the number
150 150
    /// of columns in an LP \c lp:
151 151
    ///\code
152 152
    /// int count=0;
153 153
    /// for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count;
154 154
    ///\endcode
155 155
    class ColIt : public Col {
156 156
      const LpBase *_solver;
157 157
    public:
158 158
      /// Default constructor
159
      
159

	
160 160
      /// \warning The default constructor sets the iterator
161 161
      /// to an undefined value.
162 162
      ColIt() {}
163 163
      /// Sets the iterator to the first Col
164
      
164

	
165 165
      /// Sets the iterator to the first Col.
166 166
      ///
167 167
      ColIt(const LpBase &solver) : _solver(&solver)
168 168
      {
169 169
        _solver->cols.firstItem(_id);
170 170
      }
171 171
      /// Invalid constructor \& conversion
172
      
172

	
173 173
      /// Initialize the iterator to be invalid.
174 174
      /// \sa Invalid for more details.
175 175
      ColIt(const Invalid&) : Col(INVALID) {}
176 176
      /// Next column
177
      
177

	
178 178
      /// Assign the iterator to the next column.
179 179
      ///
180 180
      ColIt &operator++()
181 181
      {
182 182
        _solver->cols.nextItem(_id);
183 183
        return *this;
184 184
      }
185 185
    };
186 186

	
187 187
    /// \brief Returns the ID of the column.
188 188
    static int id(const Col& col) { return col._id; }
189 189
    /// \brief Returns the column with the given ID.
190 190
    ///
191 191
    /// \pre The argument should be a valid column ID in the LP problem.
192 192
    static Col colFromId(int id) { return Col(id); }
193 193

	
194 194
    ///Refer to a row of the LP.
195 195

	
196 196
    ///This type is used to refer to a row of the LP.
197 197
    ///
198 198
    ///Its value remains valid and correct even after the addition or erase of
199 199
    ///other rows.
200 200
    ///
201 201
    ///\note This class is similar to other Item types in LEMON, like
202 202
    ///Node and Arc types in digraph.
203 203
    class Row {
204 204
      friend class LpBase;
205 205
    protected:
206 206
      int _id;
207 207
      explicit Row(int id) : _id(id) {}
208 208
    public:
209 209
      typedef Value ExprValue;
210 210
      typedef True LpRow;
211 211
      /// Default constructor
212
      
212

	
213 213
      /// \warning The default constructor sets the Row to an
214 214
      /// undefined value.
215 215
      Row() {}
216 216
      /// Invalid constructor \& conversion.
217
      
217

	
218 218
      /// This constructor initializes the Row to be invalid.
219
      /// \sa Invalid for more details.      
219
      /// \sa Invalid for more details.
220 220
      Row(const Invalid&) : _id(-1) {}
221 221
      /// Equality operator
222 222

	
223 223
      /// Two \ref Row "Row"s are equal if and only if they point to
224 224
      /// the same LP row or both are invalid.
225 225
      bool operator==(Row r) const  {return _id == r._id;}
226 226
      /// Inequality operator
227
      
227

	
228 228
      /// \sa operator==(Row r)
229 229
      ///
230 230
      bool operator!=(Row r) const  {return _id != r._id;}
231 231
      /// Artificial ordering operator.
232 232

	
233 233
      /// To allow the use of this object in std::map or similar
234 234
      /// associative container we require this.
235 235
      ///
236 236
      /// \note This operator only have to define some strict ordering of
237 237
      /// the items; this order has nothing to do with the iteration
238 238
      /// ordering of the items.
239 239
      bool operator<(Row r) const  {return _id < r._id;}
240 240
    };
241 241

	
242 242
    ///Iterator for iterate over the rows of an LP problem
243 243

	
244
    /// Its usage is quite simple, for example you can count the number
244
    /// Its usage is quite simple, for example, you can count the number
245 245
    /// of rows in an LP \c lp:
246 246
    ///\code
247 247
    /// int count=0;
248 248
    /// for (LpBase::RowIt c(lp); c!=INVALID; ++c) ++count;
249 249
    ///\endcode
250 250
    class RowIt : public Row {
251 251
      const LpBase *_solver;
252 252
    public:
253 253
      /// Default constructor
254
      
254

	
255 255
      /// \warning The default constructor sets the iterator
256 256
      /// to an undefined value.
257 257
      RowIt() {}
258 258
      /// Sets the iterator to the first Row
259
      
259

	
260 260
      /// Sets the iterator to the first Row.
261 261
      ///
262 262
      RowIt(const LpBase &solver) : _solver(&solver)
263 263
      {
264 264
        _solver->rows.firstItem(_id);
265 265
      }
266 266
      /// Invalid constructor \& conversion
267
      
267

	
268 268
      /// Initialize the iterator to be invalid.
269 269
      /// \sa Invalid for more details.
270 270
      RowIt(const Invalid&) : Row(INVALID) {}
271 271
      /// Next row
272
      
272

	
273 273
      /// Assign the iterator to the next row.
274 274
      ///
275 275
      RowIt &operator++()
276 276
      {
277 277
        _solver->rows.nextItem(_id);
278 278
        return *this;
279 279
      }
280 280
    };
281 281

	
282 282
    /// \brief Returns the ID of the row.
283 283
    static int id(const Row& row) { return row._id; }
284 284
    /// \brief Returns the row with the given ID.
285 285
    ///
286 286
    /// \pre The argument should be a valid row ID in the LP problem.
287 287
    static Row rowFromId(int id) { return Row(id); }
288 288

	
289 289
  public:
290 290

	
291 291
    ///Linear expression of variables and a constant component
292 292

	
293 293
    ///This data structure stores a linear expression of the variables
294 294
    ///(\ref Col "Col"s) and also has a constant component.
295 295
    ///
296 296
    ///There are several ways to access and modify the contents of this
297 297
    ///container.
298 298
    ///\code
299 299
    ///e[v]=5;
300 300
    ///e[v]+=12;
301 301
    ///e.erase(v);
302 302
    ///\endcode
303 303
    ///or you can also iterate through its elements.
304 304
    ///\code
305 305
    ///double s=0;
306 306
    ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
307 307
    ///  s+=*i * primal(i);
308 308
    ///\endcode
309 309
    ///(This code computes the primal value of the expression).
310 310
    ///- Numbers (<tt>double</tt>'s)
311 311
    ///and variables (\ref Col "Col"s) directly convert to an
312 312
    ///\ref Expr and the usual linear operations are defined, so
313 313
    ///\code
314 314
    ///v+w
315 315
    ///2*v-3.12*(v-w/2)+2
316 316
    ///v*2.1+(3*v+(v*12+w+6)*3)/2
317 317
    ///\endcode
318 318
    ///are valid expressions.
319 319
    ///The usual assignment operations are also defined.
320 320
    ///\code
321 321
    ///e=v+w;
322 322
    ///e+=2*v-3.12*(v-w/2)+2;
323 323
    ///e*=3.4;
324 324
    ///e/=5;
325 325
    ///\endcode
326 326
    ///- The constant member can be set and read by dereference
327 327
    ///  operator (unary *)
328 328
    ///
329 329
    ///\code
330 330
    ///*e=12;
331 331
    ///double c=*e;
332 332
    ///\endcode
333 333
    ///
334 334
    ///\sa Constr
335 335
    class Expr {
336 336
      friend class LpBase;
337 337
    public:
338 338
      /// The key type of the expression
339 339
      typedef LpBase::Col Key;
340 340
      /// The value type of the expression
341 341
      typedef LpBase::Value Value;
342 342

	
343 343
    protected:
344 344
      Value const_comp;
345 345
      std::map<int, Value> comps;
346 346

	
347 347
    public:
348 348
      typedef True SolverExpr;
349 349
      /// Default constructor
350
      
350

	
351 351
      /// Construct an empty expression, the coefficients and
352 352
      /// the constant component are initialized to zero.
353 353
      Expr() : const_comp(0) {}
354 354
      /// Construct an expression from a column
355 355

	
356 356
      /// Construct an expression, which has a term with \c c variable
357 357
      /// and 1.0 coefficient.
358 358
      Expr(const Col &c) : const_comp(0) {
359 359
        typedef std::map<int, Value>::value_type pair_type;
360 360
        comps.insert(pair_type(id(c), 1));
361 361
      }
362 362
      /// Construct an expression from a constant
363 363

	
364 364
      /// Construct an expression, which's constant component is \c v.
365 365
      ///
366 366
      Expr(const Value &v) : const_comp(v) {}
367 367
      /// Returns the coefficient of the column
368 368
      Value operator[](const Col& c) const {
369 369
        std::map<int, Value>::const_iterator it=comps.find(id(c));
370 370
        if (it != comps.end()) {
371 371
          return it->second;
372 372
        } else {
373 373
          return 0;
374 374
        }
375 375
      }
376 376
      /// Returns the coefficient of the column
377 377
      Value& operator[](const Col& c) {
378 378
        return comps[id(c)];
379 379
      }
380 380
      /// Sets the coefficient of the column
381 381
      void set(const Col &c, const Value &v) {
382 382
        if (v != 0.0) {
383 383
          typedef std::map<int, Value>::value_type pair_type;
384 384
          comps.insert(pair_type(id(c), v));
385 385
        } else {
386 386
          comps.erase(id(c));
387 387
        }
388 388
      }
389 389
      /// Returns the constant component of the expression
390 390
      Value& operator*() { return const_comp; }
391 391
      /// Returns the constant component of the expression
392 392
      const Value& operator*() const { return const_comp; }
393 393
      /// \brief Removes the coefficients which's absolute value does
394 394
      /// not exceed \c epsilon. It also sets to zero the constant
395 395
      /// component, if it does not exceed epsilon in absolute value.
396 396
      void simplify(Value epsilon = 0.0) {
397 397
        std::map<int, Value>::iterator it=comps.begin();
398 398
        while (it != comps.end()) {
399 399
          std::map<int, Value>::iterator jt=it;
400 400
          ++jt;
401 401
          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
402 402
          it=jt;
403 403
        }
404 404
        if (std::fabs(const_comp) <= epsilon) const_comp = 0;
405 405
      }
406 406

	
407 407
      void simplify(Value epsilon = 0.0) const {
408 408
        const_cast<Expr*>(this)->simplify(epsilon);
409 409
      }
410 410

	
411 411
      ///Sets all coefficients and the constant component to 0.
412 412
      void clear() {
413 413
        comps.clear();
414 414
        const_comp=0;
415 415
      }
416 416

	
417 417
      ///Compound assignment
418 418
      Expr &operator+=(const Expr &e) {
419 419
        for (std::map<int, Value>::const_iterator it=e.comps.begin();
420 420
             it!=e.comps.end(); ++it)
421 421
          comps[it->first]+=it->second;
422 422
        const_comp+=e.const_comp;
423 423
        return *this;
424 424
      }
425 425
      ///Compound assignment
426 426
      Expr &operator-=(const Expr &e) {
427 427
        for (std::map<int, Value>::const_iterator it=e.comps.begin();
428 428
             it!=e.comps.end(); ++it)
429 429
          comps[it->first]-=it->second;
430 430
        const_comp-=e.const_comp;
431 431
        return *this;
432 432
      }
433 433
      ///Multiply with a constant
434 434
      Expr &operator*=(const Value &v) {
435 435
        for (std::map<int, Value>::iterator it=comps.begin();
436 436
             it!=comps.end(); ++it)
437 437
          it->second*=v;
438 438
        const_comp*=v;
439 439
        return *this;
440 440
      }
441 441
      ///Division with a constant
442 442
      Expr &operator/=(const Value &c) {
443 443
        for (std::map<int, Value>::iterator it=comps.begin();
444 444
             it!=comps.end(); ++it)
445 445
          it->second/=c;
446 446
        const_comp/=c;
447 447
        return *this;
448 448
      }
449 449

	
450 450
      ///Iterator over the expression
451
      
452
      ///The iterator iterates over the terms of the expression. 
453
      /// 
451

	
452
      ///The iterator iterates over the terms of the expression.
453
      ///
454 454
      ///\code
455 455
      ///double s=0;
456 456
      ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i)
457 457
      ///  s+= *i * primal(i);
458 458
      ///\endcode
459 459
      class CoeffIt {
460 460
      private:
461 461

	
462 462
        std::map<int, Value>::iterator _it, _end;
463 463

	
464 464
      public:
465 465

	
466 466
        /// Sets the iterator to the first term
467
        
467

	
468 468
        /// Sets the iterator to the first term of the expression.
469 469
        ///
470 470
        CoeffIt(Expr& e)
471 471
          : _it(e.comps.begin()), _end(e.comps.end()){}
472 472

	
473 473
        /// Convert the iterator to the column of the term
474 474
        operator Col() const {
475 475
          return colFromId(_it->first);
476 476
        }
477 477

	
478 478
        /// Returns the coefficient of the term
479 479
        Value& operator*() { return _it->second; }
480 480

	
481 481
        /// Returns the coefficient of the term
482 482
        const Value& operator*() const { return _it->second; }
483 483
        /// Next term
484
        
484

	
485 485
        /// Assign the iterator to the next term.
486 486
        ///
487 487
        CoeffIt& operator++() { ++_it; return *this; }
488 488

	
489 489
        /// Equality operator
490 490
        bool operator==(Invalid) const { return _it == _end; }
491 491
        /// Inequality operator
492 492
        bool operator!=(Invalid) const { return _it != _end; }
493 493
      };
494 494

	
495 495
      /// Const iterator over the expression
496
      
497
      ///The iterator iterates over the terms of the expression. 
498
      /// 
496

	
497
      ///The iterator iterates over the terms of the expression.
498
      ///
499 499
      ///\code
500 500
      ///double s=0;
501 501
      ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i)
502 502
      ///  s+=*i * primal(i);
503 503
      ///\endcode
504 504
      class ConstCoeffIt {
505 505
      private:
506 506

	
507 507
        std::map<int, Value>::const_iterator _it, _end;
508 508

	
509 509
      public:
510 510

	
511 511
        /// Sets the iterator to the first term
512
        
512

	
513 513
        /// Sets the iterator to the first term of the expression.
514 514
        ///
515 515
        ConstCoeffIt(const Expr& e)
516 516
          : _it(e.comps.begin()), _end(e.comps.end()){}
517 517

	
518 518
        /// Convert the iterator to the column of the term
519 519
        operator Col() const {
520 520
          return colFromId(_it->first);
521 521
        }
522 522

	
523 523
        /// Returns the coefficient of the term
524 524
        const Value& operator*() const { return _it->second; }
525 525

	
526 526
        /// Next term
527
        
527

	
528 528
        /// Assign the iterator to the next term.
529 529
        ///
530 530
        ConstCoeffIt& operator++() { ++_it; return *this; }
531 531

	
532 532
        /// Equality operator
533 533
        bool operator==(Invalid) const { return _it == _end; }
534 534
        /// Inequality operator
535 535
        bool operator!=(Invalid) const { return _it != _end; }
536 536
      };
537 537

	
538 538
    };
539 539

	
540 540
    ///Linear constraint
541 541

	
542 542
    ///This data stucture represents a linear constraint in the LP.
543 543
    ///Basically it is a linear expression with a lower or an upper bound
544 544
    ///(or both). These parts of the constraint can be obtained by the member
545 545
    ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
546 546
    ///respectively.
547 547
    ///There are two ways to construct a constraint.
548 548
    ///- You can set the linear expression and the bounds directly
549 549
    ///  by the functions above.
550 550
    ///- The operators <tt>\<=</tt>, <tt>==</tt> and  <tt>\>=</tt>
551 551
    ///  are defined between expressions, or even between constraints whenever
552 552
    ///  it makes sense. Therefore if \c e and \c f are linear expressions and
553 553
    ///  \c s and \c t are numbers, then the followings are valid expressions
554 554
    ///  and thus they can be used directly e.g. in \ref addRow() whenever
555 555
    ///  it makes sense.
556 556
    ///\code
557 557
    ///  e<=s
558 558
    ///  e<=f
559 559
    ///  e==f
560 560
    ///  s<=e<=t
561 561
    ///  e>=t
562 562
    ///\endcode
563 563
    ///\warning The validity of a constraint is checked only at run
564 564
    ///time, so e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will
565 565
    ///compile, but will fail an assertion.
566 566
    class Constr
567 567
    {
568 568
    public:
569 569
      typedef LpBase::Expr Expr;
570 570
      typedef Expr::Key Key;
571 571
      typedef Expr::Value Value;
572 572

	
573 573
    protected:
574 574
      Expr _expr;
575 575
      Value _lb,_ub;
576 576
    public:
577 577
      ///\e
578 578
      Constr() : _expr(), _lb(NaN), _ub(NaN) {}
579 579
      ///\e
580 580
      Constr(Value lb, const Expr &e, Value ub) :
581 581
        _expr(e), _lb(lb), _ub(ub) {}
582 582
      Constr(const Expr &e) :
583 583
        _expr(e), _lb(NaN), _ub(NaN) {}
584 584
      ///\e
585 585
      void clear()
586 586
      {
587 587
        _expr.clear();
588 588
        _lb=_ub=NaN;
589 589
      }
590 590

	
591 591
      ///Reference to the linear expression
592 592
      Expr &expr() { return _expr; }
593 593
      ///Cont reference to the linear expression
594 594
      const Expr &expr() const { return _expr; }
595 595
      ///Reference to the lower bound.
596 596

	
597 597
      ///\return
598 598
      ///- \ref INF "INF": the constraint is lower unbounded.
599 599
      ///- \ref NaN "NaN": lower bound has not been set.
600 600
      ///- finite number: the lower bound
601 601
      Value &lowerBound() { return _lb; }
602 602
      ///The const version of \ref lowerBound()
603 603
      const Value &lowerBound() const { return _lb; }
604 604
      ///Reference to the upper bound.
605 605

	
606 606
      ///\return
607 607
      ///- \ref INF "INF": the constraint is upper unbounded.
608 608
      ///- \ref NaN "NaN": upper bound has not been set.
609 609
      ///- finite number: the upper bound
610 610
      Value &upperBound() { return _ub; }
611 611
      ///The const version of \ref upperBound()
612 612
      const Value &upperBound() const { return _ub; }
613 613
      ///Is the constraint lower bounded?
614 614
      bool lowerBounded() const {
615 615
        return _lb != -INF && !isNaN(_lb);
616 616
      }
617 617
      ///Is the constraint upper bounded?
618 618
      bool upperBounded() const {
619 619
        return _ub != INF && !isNaN(_ub);
620 620
      }
621 621

	
622 622
    };
623 623

	
624 624
    ///Linear expression of rows
625 625

	
626 626
    ///This data structure represents a column of the matrix,
627 627
    ///thas is it strores a linear expression of the dual variables
628 628
    ///(\ref Row "Row"s).
629 629
    ///
630 630
    ///There are several ways to access and modify the contents of this
631 631
    ///container.
632 632
    ///\code
633 633
    ///e[v]=5;
634 634
    ///e[v]+=12;
635 635
    ///e.erase(v);
636 636
    ///\endcode
637 637
    ///or you can also iterate through its elements.
638 638
    ///\code
639 639
    ///double s=0;
640 640
    ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
641 641
    ///  s+=*i;
642 642
    ///\endcode
643 643
    ///(This code computes the sum of all coefficients).
644 644
    ///- Numbers (<tt>double</tt>'s)
645 645
    ///and variables (\ref Row "Row"s) directly convert to an
646 646
    ///\ref DualExpr and the usual linear operations are defined, so
647 647
    ///\code
648 648
    ///v+w
649 649
    ///2*v-3.12*(v-w/2)
650 650
    ///v*2.1+(3*v+(v*12+w)*3)/2
651 651
    ///\endcode
652 652
    ///are valid \ref DualExpr dual expressions.
653 653
    ///The usual assignment operations are also defined.
654 654
    ///\code
655 655
    ///e=v+w;
656 656
    ///e+=2*v-3.12*(v-w/2);
657 657
    ///e*=3.4;
658 658
    ///e/=5;
659 659
    ///\endcode
660 660
    ///
661 661
    ///\sa Expr
662 662
    class DualExpr {
663 663
      friend class LpBase;
664 664
    public:
665 665
      /// The key type of the expression
666 666
      typedef LpBase::Row Key;
667 667
      /// The value type of the expression
668 668
      typedef LpBase::Value Value;
669 669

	
670 670
    protected:
671 671
      std::map<int, Value> comps;
672 672

	
673 673
    public:
674 674
      typedef True SolverExpr;
675 675
      /// Default constructor
676
      
676

	
677 677
      /// Construct an empty expression, the coefficients are
678 678
      /// initialized to zero.
679 679
      DualExpr() {}
680 680
      /// Construct an expression from a row
681 681

	
682 682
      /// Construct an expression, which has a term with \c r dual
683 683
      /// variable and 1.0 coefficient.
684 684
      DualExpr(const Row &r) {
685 685
        typedef std::map<int, Value>::value_type pair_type;
686 686
        comps.insert(pair_type(id(r), 1));
687 687
      }
688 688
      /// Returns the coefficient of the row
689 689
      Value operator[](const Row& r) const {
690 690
        std::map<int, Value>::const_iterator it = comps.find(id(r));
691 691
        if (it != comps.end()) {
692 692
          return it->second;
693 693
        } else {
694 694
          return 0;
695 695
        }
696 696
      }
697 697
      /// Returns the coefficient of the row
698 698
      Value& operator[](const Row& r) {
699 699
        return comps[id(r)];
700 700
      }
701 701
      /// Sets the coefficient of the row
702 702
      void set(const Row &r, const Value &v) {
703 703
        if (v != 0.0) {
704 704
          typedef std::map<int, Value>::value_type pair_type;
705 705
          comps.insert(pair_type(id(r), v));
706 706
        } else {
707 707
          comps.erase(id(r));
708 708
        }
709 709
      }
710 710
      /// \brief Removes the coefficients which's absolute value does
711
      /// not exceed \c epsilon. 
711
      /// not exceed \c epsilon.
712 712
      void simplify(Value epsilon = 0.0) {
713 713
        std::map<int, Value>::iterator it=comps.begin();
714 714
        while (it != comps.end()) {
715 715
          std::map<int, Value>::iterator jt=it;
716 716
          ++jt;
717 717
          if (std::fabs((*it).second) <= epsilon) comps.erase(it);
718 718
          it=jt;
719 719
        }
720 720
      }
721 721

	
722 722
      void simplify(Value epsilon = 0.0) const {
723 723
        const_cast<DualExpr*>(this)->simplify(epsilon);
724 724
      }
725 725

	
726 726
      ///Sets all coefficients to 0.
727 727
      void clear() {
728 728
        comps.clear();
729 729
      }
730 730
      ///Compound assignment
731 731
      DualExpr &operator+=(const DualExpr &e) {
732 732
        for (std::map<int, Value>::const_iterator it=e.comps.begin();
733 733
             it!=e.comps.end(); ++it)
734 734
          comps[it->first]+=it->second;
735 735
        return *this;
736 736
      }
737 737
      ///Compound assignment
738 738
      DualExpr &operator-=(const DualExpr &e) {
739 739
        for (std::map<int, Value>::const_iterator it=e.comps.begin();
740 740
             it!=e.comps.end(); ++it)
741 741
          comps[it->first]-=it->second;
742 742
        return *this;
743 743
      }
744 744
      ///Multiply with a constant
745 745
      DualExpr &operator*=(const Value &v) {
746 746
        for (std::map<int, Value>::iterator it=comps.begin();
747 747
             it!=comps.end(); ++it)
748 748
          it->second*=v;
749 749
        return *this;
750 750
      }
751 751
      ///Division with a constant
752 752
      DualExpr &operator/=(const Value &v) {
753 753
        for (std::map<int, Value>::iterator it=comps.begin();
754 754
             it!=comps.end(); ++it)
755 755
          it->second/=v;
756 756
        return *this;
757 757
      }
758 758

	
759 759
      ///Iterator over the expression
760
      
761
      ///The iterator iterates over the terms of the expression. 
762
      /// 
760

	
761
      ///The iterator iterates over the terms of the expression.
762
      ///
763 763
      ///\code
764 764
      ///double s=0;
765 765
      ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i)
766 766
      ///  s+= *i * dual(i);
767 767
      ///\endcode
768 768
      class CoeffIt {
769 769
      private:
770 770

	
771 771
        std::map<int, Value>::iterator _it, _end;
772 772

	
773 773
      public:
774 774

	
775 775
        /// Sets the iterator to the first term
776
        
776

	
777 777
        /// Sets the iterator to the first term of the expression.
778 778
        ///
779 779
        CoeffIt(DualExpr& e)
780 780
          : _it(e.comps.begin()), _end(e.comps.end()){}
781 781

	
782 782
        /// Convert the iterator to the row of the term
783 783
        operator Row() const {
784 784
          return rowFromId(_it->first);
785 785
        }
786 786

	
787 787
        /// Returns the coefficient of the term
788 788
        Value& operator*() { return _it->second; }
789 789

	
790 790
        /// Returns the coefficient of the term
791 791
        const Value& operator*() const { return _it->second; }
792 792

	
793 793
        /// Next term
794
        
794

	
795 795
        /// Assign the iterator to the next term.
796 796
        ///
797 797
        CoeffIt& operator++() { ++_it; return *this; }
798 798

	
799 799
        /// Equality operator
800 800
        bool operator==(Invalid) const { return _it == _end; }
801 801
        /// Inequality operator
802 802
        bool operator!=(Invalid) const { return _it != _end; }
803 803
      };
804 804

	
805 805
      ///Iterator over the expression
806
      
807
      ///The iterator iterates over the terms of the expression. 
808
      /// 
806

	
807
      ///The iterator iterates over the terms of the expression.
808
      ///
809 809
      ///\code
810 810
      ///double s=0;
811 811
      ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i)
812 812
      ///  s+= *i * dual(i);
813 813
      ///\endcode
814 814
      class ConstCoeffIt {
815 815
      private:
816 816

	
817 817
        std::map<int, Value>::const_iterator _it, _end;
818 818

	
819 819
      public:
820 820

	
821 821
        /// Sets the iterator to the first term
822
        
822

	
823 823
        /// Sets the iterator to the first term of the expression.
824 824
        ///
825 825
        ConstCoeffIt(const DualExpr& e)
826 826
          : _it(e.comps.begin()), _end(e.comps.end()){}
827 827

	
828 828
        /// Convert the iterator to the row of the term
829 829
        operator Row() const {
830 830
          return rowFromId(_it->first);
831 831
        }
832 832

	
833 833
        /// Returns the coefficient of the term
834 834
        const Value& operator*() const { return _it->second; }
835 835

	
836 836
        /// Next term
837
        
837

	
838 838
        /// Assign the iterator to the next term.
839 839
        ///
840 840
        ConstCoeffIt& operator++() { ++_it; return *this; }
841 841

	
842 842
        /// Equality operator
843 843
        bool operator==(Invalid) const { return _it == _end; }
844 844
        /// Inequality operator
845 845
        bool operator!=(Invalid) const { return _it != _end; }
846 846
      };
847 847
    };
848 848

	
849 849

	
850 850
  protected:
851 851

	
852 852
    class InsertIterator {
853 853
    private:
854 854

	
855 855
      std::map<int, Value>& _host;
856 856
      const _solver_bits::VarIndex& _index;
857 857

	
858 858
    public:
859 859

	
860 860
      typedef std::output_iterator_tag iterator_category;
861 861
      typedef void difference_type;
862 862
      typedef void value_type;
863 863
      typedef void reference;
864 864
      typedef void pointer;
865 865

	
866 866
      InsertIterator(std::map<int, Value>& host,
867 867
                   const _solver_bits::VarIndex& index)
868 868
        : _host(host), _index(index) {}
869 869

	
870 870
      InsertIterator& operator=(const std::pair<int, Value>& value) {
871 871
        typedef std::map<int, Value>::value_type pair_type;
872 872
        _host.insert(pair_type(_index[value.first], value.second));
873 873
        return *this;
874 874
      }
875 875

	
876 876
      InsertIterator& operator*() { return *this; }
877 877
      InsertIterator& operator++() { return *this; }
878 878
      InsertIterator operator++(int) { return *this; }
879 879

	
880 880
    };
881 881

	
882 882
    class ExprIterator {
883 883
    private:
884 884
      std::map<int, Value>::const_iterator _host_it;
885 885
      const _solver_bits::VarIndex& _index;
886 886
    public:
887 887

	
888 888
      typedef std::bidirectional_iterator_tag iterator_category;
889 889
      typedef std::ptrdiff_t difference_type;
890 890
      typedef const std::pair<int, Value> value_type;
891 891
      typedef value_type reference;
892 892

	
893 893
      class pointer {
894 894
      public:
895 895
        pointer(value_type& _value) : value(_value) {}
896 896
        value_type* operator->() { return &value; }
897 897
      private:
898 898
        value_type value;
899 899
      };
900 900

	
901 901
      ExprIterator(const std::map<int, Value>::const_iterator& host_it,
902 902
                   const _solver_bits::VarIndex& index)
903 903
        : _host_it(host_it), _index(index) {}
904 904

	
905 905
      reference operator*() {
906 906
        return std::make_pair(_index(_host_it->first), _host_it->second);
907 907
      }
908 908

	
909 909
      pointer operator->() {
910 910
        return pointer(operator*());
911 911
      }
912 912

	
913 913
      ExprIterator& operator++() { ++_host_it; return *this; }
914 914
      ExprIterator operator++(int) {
915 915
        ExprIterator tmp(*this); ++_host_it; return tmp;
916 916
      }
917 917

	
918 918
      ExprIterator& operator--() { --_host_it; return *this; }
919 919
      ExprIterator operator--(int) {
920 920
        ExprIterator tmp(*this); --_host_it; return tmp;
921 921
      }
922 922

	
923 923
      bool operator==(const ExprIterator& it) const {
924 924
        return _host_it == it._host_it;
925 925
      }
926 926

	
927 927
      bool operator!=(const ExprIterator& it) const {
928 928
        return _host_it != it._host_it;
929 929
      }
930 930

	
931 931
    };
932 932

	
933 933
  protected:
934 934

	
935 935
    //Abstract virtual functions
936 936

	
937 937
    virtual int _addColId(int col) { return cols.addIndex(col); }
938 938
    virtual int _addRowId(int row) { return rows.addIndex(row); }
939 939

	
940 940
    virtual void _eraseColId(int col) { cols.eraseIndex(col); }
941 941
    virtual void _eraseRowId(int row) { rows.eraseIndex(row); }
942 942

	
943 943
    virtual int _addCol() = 0;
944 944
    virtual int _addRow() = 0;
945 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

	
946 954
    virtual void _eraseCol(int col) = 0;
947 955
    virtual void _eraseRow(int row) = 0;
948 956

	
949 957
    virtual void _getColName(int col, std::string& name) const = 0;
950 958
    virtual void _setColName(int col, const std::string& name) = 0;
951 959
    virtual int _colByName(const std::string& name) const = 0;
952 960

	
953 961
    virtual void _getRowName(int row, std::string& name) const = 0;
954 962
    virtual void _setRowName(int row, const std::string& name) = 0;
955 963
    virtual int _rowByName(const std::string& name) const = 0;
956 964

	
957 965
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
958 966
    virtual void _getRowCoeffs(int i, InsertIterator b) const = 0;
959 967

	
960 968
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e) = 0;
961 969
    virtual void _getColCoeffs(int i, InsertIterator b) const = 0;
962 970

	
963 971
    virtual void _setCoeff(int row, int col, Value value) = 0;
964 972
    virtual Value _getCoeff(int row, int col) const = 0;
965 973

	
966 974
    virtual void _setColLowerBound(int i, Value value) = 0;
967 975
    virtual Value _getColLowerBound(int i) const = 0;
968 976

	
969 977
    virtual void _setColUpperBound(int i, Value value) = 0;
970 978
    virtual Value _getColUpperBound(int i) const = 0;
971 979

	
972 980
    virtual void _setRowLowerBound(int i, Value value) = 0;
973 981
    virtual Value _getRowLowerBound(int i) const = 0;
974 982

	
975 983
    virtual void _setRowUpperBound(int i, Value value) = 0;
976 984
    virtual Value _getRowUpperBound(int i) const = 0;
977 985

	
978 986
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e) = 0;
979 987
    virtual void _getObjCoeffs(InsertIterator b) const = 0;
980 988

	
981 989
    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
982 990
    virtual Value _getObjCoeff(int i) const = 0;
983 991

	
984 992
    virtual void _setSense(Sense) = 0;
985 993
    virtual Sense _getSense() const = 0;
986 994

	
987 995
    virtual void _clear() = 0;
988 996

	
989 997
    virtual const char* _solverName() const = 0;
990 998

	
991 999
    virtual void _messageLevel(MessageLevel level) = 0;
992 1000

	
993 1001
    //Own protected stuff
994 1002

	
995 1003
    //Constant component of the objective function
996 1004
    Value obj_const_comp;
997 1005

	
998 1006
    LpBase() : rows(), cols(), obj_const_comp(0) {}
999 1007

	
1000 1008
  public:
1001 1009

	
1002 1010
    /// Virtual destructor
1003 1011
    virtual ~LpBase() {}
1004 1012

	
1005 1013
    ///Gives back the name of the solver.
1006 1014
    const char* solverName() const {return _solverName();}
1007 1015

	
1008 1016
    ///\name Build Up and Modify the LP
1009 1017

	
1010 1018
    ///@{
1011 1019

	
1012 1020
    ///Add a new empty column (i.e a new variable) to the LP
1013 1021
    Col addCol() { Col c; c._id = _addColId(_addCol()); return c;}
1014 1022

	
1015 1023
    ///\brief Adds several new columns (i.e variables) at once
1016 1024
    ///
1017 1025
    ///This magic function takes a container as its argument and fills
1018 1026
    ///its elements with new columns (i.e. variables)
1019 1027
    ///\param t can be
1020 1028
    ///- a standard STL compatible iterable container with
1021 1029
    ///\ref Col as its \c values_type like
1022 1030
    ///\code
1023 1031
    ///std::vector<LpBase::Col>
1024 1032
    ///std::list<LpBase::Col>
1025 1033
    ///\endcode
1026 1034
    ///- a standard STL compatible iterable container with
1027 1035
    ///\ref Col as its \c mapped_type like
1028 1036
    ///\code
1029 1037
    ///std::map<AnyType,LpBase::Col>
1030 1038
    ///\endcode
1031 1039
    ///- an iterable lemon \ref concepts::WriteMap "write map" like
1032 1040
    ///\code
1033 1041
    ///ListGraph::NodeMap<LpBase::Col>
1034 1042
    ///ListGraph::ArcMap<LpBase::Col>
1035 1043
    ///\endcode
1036 1044
    ///\return The number of the created column.
1037 1045
#ifdef DOXYGEN
1038 1046
    template<class T>
1039 1047
    int addColSet(T &t) { return 0;}
1040 1048
#else
1041 1049
    template<class T>
1042 1050
    typename enable_if<typename T::value_type::LpCol,int>::type
1043 1051
    addColSet(T &t,dummy<0> = 0) {
1044 1052
      int s=0;
1045 1053
      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
1046 1054
      return s;
1047 1055
    }
1048 1056
    template<class T>
1049 1057
    typename enable_if<typename T::value_type::second_type::LpCol,
1050 1058
                       int>::type
1051 1059
    addColSet(T &t,dummy<1> = 1) {
1052 1060
      int s=0;
1053 1061
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1054 1062
        i->second=addCol();
1055 1063
        s++;
1056 1064
      }
1057 1065
      return s;
1058 1066
    }
1059 1067
    template<class T>
1060 1068
    typename enable_if<typename T::MapIt::Value::LpCol,
1061 1069
                       int>::type
1062 1070
    addColSet(T &t,dummy<2> = 2) {
1063 1071
      int s=0;
1064 1072
      for(typename T::MapIt i(t); i!=INVALID; ++i)
1065 1073
        {
1066 1074
          i.set(addCol());
1067 1075
          s++;
1068 1076
        }
1069 1077
      return s;
1070 1078
    }
1071 1079
#endif
1072 1080

	
1073 1081
    ///Set a column (i.e a dual constraint) of the LP
1074 1082

	
1075 1083
    ///\param c is the column to be modified
1076 1084
    ///\param e is a dual linear expression (see \ref DualExpr)
1077 1085
    ///a better one.
1078 1086
    void col(Col c, const DualExpr &e) {
1079 1087
      e.simplify();
1080 1088
      _setColCoeffs(cols(id(c)), ExprIterator(e.comps.begin(), rows),
1081 1089
                    ExprIterator(e.comps.end(), rows));
1082 1090
    }
1083 1091

	
1084 1092
    ///Get a column (i.e a dual constraint) of the LP
1085 1093

	
1086 1094
    ///\param c is the column to get
1087 1095
    ///\return the dual expression associated to the column
1088 1096
    DualExpr col(Col c) const {
1089 1097
      DualExpr e;
1090 1098
      _getColCoeffs(cols(id(c)), InsertIterator(e.comps, rows));
1091 1099
      return e;
1092 1100
    }
1093 1101

	
1094 1102
    ///Add a new column to the LP
1095 1103

	
1096 1104
    ///\param e is a dual linear expression (see \ref DualExpr)
1097 1105
    ///\param o is the corresponding component of the objective
1098 1106
    ///function. It is 0 by default.
1099 1107
    ///\return The created column.
1100 1108
    Col addCol(const DualExpr &e, Value o = 0) {
1101 1109
      Col c=addCol();
1102 1110
      col(c,e);
1103 1111
      objCoeff(c,o);
1104 1112
      return c;
1105 1113
    }
1106 1114

	
1107 1115
    ///Add a new empty row (i.e a new constraint) to the LP
1108 1116

	
1109 1117
    ///This function adds a new empty row (i.e a new constraint) to the LP.
1110 1118
    ///\return The created row
1111 1119
    Row addRow() { Row r; r._id = _addRowId(_addRow()); return r;}
1112 1120

	
1113 1121
    ///\brief Add several new rows (i.e constraints) at once
1114 1122
    ///
1115 1123
    ///This magic function takes a container as its argument and fills
1116 1124
    ///its elements with new row (i.e. variables)
1117 1125
    ///\param t can be
1118 1126
    ///- a standard STL compatible iterable container with
1119 1127
    ///\ref Row as its \c values_type like
1120 1128
    ///\code
1121 1129
    ///std::vector<LpBase::Row>
1122 1130
    ///std::list<LpBase::Row>
1123 1131
    ///\endcode
1124 1132
    ///- a standard STL compatible iterable container with
1125 1133
    ///\ref Row as its \c mapped_type like
1126 1134
    ///\code
1127 1135
    ///std::map<AnyType,LpBase::Row>
1128 1136
    ///\endcode
1129 1137
    ///- an iterable lemon \ref concepts::WriteMap "write map" like
1130 1138
    ///\code
1131 1139
    ///ListGraph::NodeMap<LpBase::Row>
1132 1140
    ///ListGraph::ArcMap<LpBase::Row>
1133 1141
    ///\endcode
1134 1142
    ///\return The number of rows created.
1135 1143
#ifdef DOXYGEN
1136 1144
    template<class T>
1137 1145
    int addRowSet(T &t) { return 0;}
1138 1146
#else
1139 1147
    template<class T>
1140 1148
    typename enable_if<typename T::value_type::LpRow,int>::type
1141 1149
    addRowSet(T &t, dummy<0> = 0) {
1142 1150
      int s=0;
1143 1151
      for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
1144 1152
      return s;
1145 1153
    }
1146 1154
    template<class T>
1147 1155
    typename enable_if<typename T::value_type::second_type::LpRow, int>::type
1148 1156
    addRowSet(T &t, dummy<1> = 1) {
1149 1157
      int s=0;
1150 1158
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1151 1159
        i->second=addRow();
1152 1160
        s++;
1153 1161
      }
1154 1162
      return s;
1155 1163
    }
1156 1164
    template<class T>
1157 1165
    typename enable_if<typename T::MapIt::Value::LpRow, int>::type
1158 1166
    addRowSet(T &t, dummy<2> = 2) {
1159 1167
      int s=0;
1160 1168
      for(typename T::MapIt i(t); i!=INVALID; ++i)
1161 1169
        {
1162 1170
          i.set(addRow());
1163 1171
          s++;
1164 1172
        }
1165 1173
      return s;
1166 1174
    }
1167 1175
#endif
1168 1176

	
1169 1177
    ///Set a row (i.e a constraint) of the LP
1170 1178

	
1171 1179
    ///\param r is the row to be modified
1172 1180
    ///\param l is lower bound (-\ref INF means no bound)
1173 1181
    ///\param e is a linear expression (see \ref Expr)
1174 1182
    ///\param u is the upper bound (\ref INF means no bound)
1175 1183
    void row(Row r, Value l, const Expr &e, Value u) {
1176 1184
      e.simplify();
1177 1185
      _setRowCoeffs(rows(id(r)), ExprIterator(e.comps.begin(), cols),
1178 1186
                    ExprIterator(e.comps.end(), cols));
1179 1187
      _setRowLowerBound(rows(id(r)),l - *e);
1180 1188
      _setRowUpperBound(rows(id(r)),u - *e);
1181 1189
    }
1182 1190

	
1183 1191
    ///Set a row (i.e a constraint) of the LP
1184 1192

	
1185 1193
    ///\param r is the row to be modified
1186 1194
    ///\param c is a linear expression (see \ref Constr)
1187 1195
    void row(Row r, const Constr &c) {
1188 1196
      row(r, c.lowerBounded()?c.lowerBound():-INF,
1189 1197
          c.expr(), c.upperBounded()?c.upperBound():INF);
1190 1198
    }
1191 1199

	
1192 1200

	
1193 1201
    ///Get a row (i.e a constraint) of the LP
1194 1202

	
1195 1203
    ///\param r is the row to get
1196 1204
    ///\return the expression associated to the row
1197 1205
    Expr row(Row r) const {
1198 1206
      Expr e;
1199 1207
      _getRowCoeffs(rows(id(r)), InsertIterator(e.comps, cols));
1200 1208
      return e;
1201 1209
    }
1202 1210

	
1203 1211
    ///Add a new row (i.e a new constraint) to the LP
1204 1212

	
1205 1213
    ///\param l is the lower bound (-\ref INF means no bound)
1206 1214
    ///\param e is a linear expression (see \ref Expr)
1207 1215
    ///\param u is the upper bound (\ref INF means no bound)
1208 1216
    ///\return The created row.
1209 1217
    Row addRow(Value l,const Expr &e, Value u) {
1210
      Row r=addRow();
1211
      row(r,l,e,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));
1212 1222
      return r;
1213 1223
    }
1214 1224

	
1215 1225
    ///Add a new row (i.e a new constraint) to the LP
1216 1226

	
1217 1227
    ///\param c is a linear expression (see \ref Constr)
1218 1228
    ///\return The created row.
1219 1229
    Row addRow(const Constr &c) {
1220
      Row r=addRow();
1221
      row(r,c);
1230
      Row r;
1231
      c.expr().simplify();
1232
      r._id = _addRowId(_addRow(c.lowerBounded()?c.lowerBound()-*c.expr():-INF,
1233
                                ExprIterator(c.expr().comps.begin(), cols),
1234
                                ExprIterator(c.expr().comps.end(), cols),
1235
                                c.upperBounded()?c.upperBound()-*c.expr():INF));
1222 1236
      return r;
1223 1237
    }
1224 1238
    ///Erase a column (i.e a variable) from the LP
1225 1239

	
1226 1240
    ///\param c is the column to be deleted
1227 1241
    void erase(Col c) {
1228 1242
      _eraseCol(cols(id(c)));
1229 1243
      _eraseColId(cols(id(c)));
1230 1244
    }
1231 1245
    ///Erase a row (i.e a constraint) from the LP
1232 1246

	
1233 1247
    ///\param r is the row to be deleted
1234 1248
    void erase(Row r) {
1235 1249
      _eraseRow(rows(id(r)));
1236 1250
      _eraseRowId(rows(id(r)));
1237 1251
    }
1238 1252

	
1239 1253
    /// Get the name of a column
1240 1254

	
1241 1255
    ///\param c is the coresponding column
1242 1256
    ///\return The name of the colunm
1243 1257
    std::string colName(Col c) const {
1244 1258
      std::string name;
1245 1259
      _getColName(cols(id(c)), name);
1246 1260
      return name;
1247 1261
    }
1248 1262

	
1249 1263
    /// Set the name of a column
1250 1264

	
1251 1265
    ///\param c is the coresponding column
1252 1266
    ///\param name The name to be given
1253 1267
    void colName(Col c, const std::string& name) {
1254 1268
      _setColName(cols(id(c)), name);
1255 1269
    }
1256 1270

	
1257 1271
    /// Get the column by its name
1258 1272

	
1259 1273
    ///\param name The name of the column
1260 1274
    ///\return the proper column or \c INVALID
1261 1275
    Col colByName(const std::string& name) const {
1262 1276
      int k = _colByName(name);
1263 1277
      return k != -1 ? Col(cols[k]) : Col(INVALID);
1264 1278
    }
1265 1279

	
1266 1280
    /// Get the name of a row
1267 1281

	
1268 1282
    ///\param r is the coresponding row
1269 1283
    ///\return The name of the row
1270 1284
    std::string rowName(Row r) const {
1271 1285
      std::string name;
1272 1286
      _getRowName(rows(id(r)), name);
1273 1287
      return name;
1274 1288
    }
1275 1289

	
1276 1290
    /// Set the name of a row
1277 1291

	
1278 1292
    ///\param r is the coresponding row
1279 1293
    ///\param name The name to be given
1280 1294
    void rowName(Row r, const std::string& name) {
1281 1295
      _setRowName(rows(id(r)), name);
1282 1296
    }
1283 1297

	
1284 1298
    /// Get the row by its name
1285 1299

	
1286 1300
    ///\param name The name of the row
1287 1301
    ///\return the proper row or \c INVALID
1288 1302
    Row rowByName(const std::string& name) const {
1289 1303
      int k = _rowByName(name);
1290 1304
      return k != -1 ? Row(rows[k]) : Row(INVALID);
1291 1305
    }
1292 1306

	
1293 1307
    /// Set an element of the coefficient matrix of the LP
1294 1308

	
1295 1309
    ///\param r is the row of the element to be modified
1296 1310
    ///\param c is the column of the element to be modified
1297 1311
    ///\param val is the new value of the coefficient
1298 1312
    void coeff(Row r, Col c, Value val) {
1299 1313
      _setCoeff(rows(id(r)),cols(id(c)), val);
1300 1314
    }
1301 1315

	
1302 1316
    /// Get an element of the coefficient matrix of the LP
1303 1317

	
1304 1318
    ///\param r is the row of the element
1305 1319
    ///\param c is the column of the element
1306 1320
    ///\return the corresponding coefficient
1307 1321
    Value coeff(Row r, Col c) const {
1308 1322
      return _getCoeff(rows(id(r)),cols(id(c)));
1309 1323
    }
1310 1324

	
1311 1325
    /// Set the lower bound of a column (i.e a variable)
1312 1326

	
1313 1327
    /// The lower bound of a variable (column) has to be given by an
1314 1328
    /// extended number of type Value, i.e. a finite number of type
1315 1329
    /// Value or -\ref INF.
1316 1330
    void colLowerBound(Col c, Value value) {
1317 1331
      _setColLowerBound(cols(id(c)),value);
1318 1332
    }
1319 1333

	
1320 1334
    /// Get the lower bound of a column (i.e a variable)
1321 1335

	
1322 1336
    /// This function returns the lower bound for column (variable) \c c
1323 1337
    /// (this might be -\ref INF as well).
1324 1338
    ///\return The lower bound for column \c c
1325 1339
    Value colLowerBound(Col c) const {
1326 1340
      return _getColLowerBound(cols(id(c)));
1327 1341
    }
1328 1342

	
1329 1343
    ///\brief Set the lower bound of  several columns
1330 1344
    ///(i.e variables) at once
1331 1345
    ///
1332 1346
    ///This magic function takes a container as its argument
1333 1347
    ///and applies the function on all of its elements.
1334 1348
    ///The lower bound of a variable (column) has to be given by an
1335 1349
    ///extended number of type Value, i.e. a finite number of type
1336 1350
    ///Value or -\ref INF.
1337 1351
#ifdef DOXYGEN
1338 1352
    template<class T>
1339 1353
    void colLowerBound(T &t, Value value) { return 0;}
1340 1354
#else
1341 1355
    template<class T>
1342 1356
    typename enable_if<typename T::value_type::LpCol,void>::type
1343 1357
    colLowerBound(T &t, Value value,dummy<0> = 0) {
1344 1358
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1345 1359
        colLowerBound(*i, value);
1346 1360
      }
1347 1361
    }
1348 1362
    template<class T>
1349 1363
    typename enable_if<typename T::value_type::second_type::LpCol,
1350 1364
                       void>::type
1351 1365
    colLowerBound(T &t, Value value,dummy<1> = 1) {
1352 1366
      for(typename T::iterator i=t.begin();i!=t.end();++i) {
1353 1367
        colLowerBound(i->second, value);
1354 1368
      }
1355 1369
    }
1356 1370
    template<class T>
1357 1371
    typename enable_if<typename T::MapIt::Value::LpCol,
1358 1372
                       void>::type
1359 1373
    colLowerBound(T &t, Value value,dummy<2> = 2) {
1360 1374
      for(typename T::MapIt i(t); i!=INVALID; ++i){
1361 1375
        colLowerBound(*i, value);
1362 1376
      }
1363 1377
    }
1364 1378
#endif
1365 1379

	
1366 1380
    /// Set the upper bound of a column (i.e a variable)
1367 1381

	
1368 1382
    /// The upper bound of a variable (column) has to be given by an
1369 1383
    /// extended number of type Value, i.e. a finite number of type
1370 1384
    /// Value or \ref INF.
1371 1385
    void colUpperBound(Col c, Value value) {
1372 1386
      _setColUpperBound(cols(id(c)),value);
1373 1387
    };
1374 1388

	
1375 1389
    /// Get the upper bound of a column (i.e a variable)
1376 1390

	
1377 1391
    /// This function returns the upper bound for column (variable) \c c
1378 1392
    /// (this might be \ref INF as well).
1379 1393
    /// \return The upper bound for column \c c
1380 1394
    Value colUpperBound(Col c) const {
1381 1395
      return _getColUpperBound(cols(id(c)));
1382 1396
    }
1383 1397

	
1384 1398
    ///\brief Set the upper bound of  several columns
1385 1399
    ///(i.e variables) at once
1386 1400
    ///
1387 1401
    ///This magic function takes a container as its argument
1388 1402
    ///and applies the function on all of its elements.
1389 1403
    ///The upper bound of a variable (column) has to be given by an
1390 1404
    ///extended number of type Value, i.e. a finite number of type
1391 1405
    ///Value or \ref INF.
1392 1406
#ifdef DOXYGEN
1393 1407
    template<class T>
1394 1408
    void colUpperBound(T &t, Value value) { return 0;}
1395 1409
#else
1396 1410
    template<class T1>
1397 1411
    typename enable_if<typename T1::value_type::LpCol,void>::type
1398 1412
    colUpperBound(T1 &t, Value value,dummy<0> = 0) {
1399 1413
      for(typename T1::iterator i=t.begin();i!=t.end();++i) {
1400 1414
        colUpperBound(*i, value);
1401 1415
      }
1402 1416
    }
1403 1417
    template<class T1>
1404 1418
    typename enable_if<typename T1::value_type::second_type::LpCol,
1405 1419
                       void>::type
1406 1420
    colUpperBound(T1 &t, Value value,dummy<1> = 1) {
1407 1421
      for(typename T1::iterator i=t.begin();i!=t.end();++i) {
1408 1422
        colUpperBound(i->second, value);
1409 1423
      }
1410 1424
    }
1411 1425
    template<class T1>
1412 1426
    typename enable_if<typename T1::MapIt::Value::LpCol,
1413 1427
                       void>::type
1414 1428
    colUpperBound(T1 &t, Value value,dummy<2> = 2) {
1415 1429
      for(typename T1::MapIt i(t); i!=INVALID; ++i){
1416 1430
        colUpperBound(*i, value);
1417 1431
      }
1418 1432
    }
1419 1433
#endif
1420 1434

	
1421 1435
    /// Set the lower and the upper bounds of a column (i.e a variable)
1422 1436

	
1423 1437
    /// The lower and the upper bounds of
1424 1438
    /// a variable (column) have to be given by an
1425 1439
    /// extended number of type Value, i.e. a finite number of type
1426 1440
    /// Value, -\ref INF or \ref INF.
1427 1441
    void colBounds(Col c, Value lower, Value upper) {
1428 1442
      _setColLowerBound(cols(id(c)),lower);
1429 1443
      _setColUpperBound(cols(id(c)),upper);
1430 1444
    }
1431 1445

	
1432 1446
    ///\brief Set the lower and the upper bound of several columns
1433 1447
    ///(i.e variables) at once
1434 1448
    ///
1435 1449
    ///This magic function takes a container as its argument
1436 1450
    ///and applies the function on all of its elements.
1437 1451
    /// The lower and the upper bounds of
1438 1452
    /// a variable (column) have to be given by an
1439 1453
    /// extended number of type Value, i.e. a finite number of type
1440 1454
    /// Value, -\ref INF or \ref INF.
1441 1455
#ifdef DOXYGEN
1442 1456
    template<class T>
1443 1457
    void colBounds(T &t, Value lower, Value upper) { return 0;}
1444 1458
#else
1445 1459
    template<class T2>
1446 1460
    typename enable_if<typename T2::value_type::LpCol,void>::type
1447 1461
    colBounds(T2 &t, Value lower, Value upper,dummy<0> = 0) {
1448 1462
      for(typename T2::iterator i=t.begin();i!=t.end();++i) {
1449 1463
        colBounds(*i, lower, upper);
1450 1464
      }
1451 1465
    }
1452 1466
    template<class T2>
1453 1467
    typename enable_if<typename T2::value_type::second_type::LpCol, void>::type
1454 1468
    colBounds(T2 &t, Value lower, Value upper,dummy<1> = 1) {
1455 1469
      for(typename T2::iterator i=t.begin();i!=t.end();++i) {
1456 1470
        colBounds(i->second, lower, upper);
1457 1471
      }
1458 1472
    }
1459 1473
    template<class T2>
1460 1474
    typename enable_if<typename T2::MapIt::Value::LpCol, void>::type
1461 1475
    colBounds(T2 &t, Value lower, Value upper,dummy<2> = 2) {
1462 1476
      for(typename T2::MapIt i(t); i!=INVALID; ++i){
1463 1477
        colBounds(*i, lower, upper);
1464 1478
      }
1465 1479
    }
1466 1480
#endif
1467 1481

	
1468 1482
    /// Set the lower bound of a row (i.e a constraint)
1469 1483

	
1470 1484
    /// The lower bound of a constraint (row) has to be given by an
1471 1485
    /// extended number of type Value, i.e. a finite number of type
1472 1486
    /// Value or -\ref INF.
1473 1487
    void rowLowerBound(Row r, Value value) {
1474 1488
      _setRowLowerBound(rows(id(r)),value);
1475 1489
    }
1476 1490

	
1477 1491
    /// Get the lower bound of a row (i.e a constraint)
1478 1492

	
1479 1493
    /// This function returns the lower bound for row (constraint) \c c
1480 1494
    /// (this might be -\ref INF as well).
1481 1495
    ///\return The lower bound for row \c r
1482 1496
    Value rowLowerBound(Row r) const {
1483 1497
      return _getRowLowerBound(rows(id(r)));
1484 1498
    }
1485 1499

	
1486 1500
    /// Set the upper bound of a row (i.e a constraint)
1487 1501

	
1488 1502
    /// The upper bound of a constraint (row) has to be given by an
1489 1503
    /// extended number of type Value, i.e. a finite number of type
1490 1504
    /// Value or -\ref INF.
1491 1505
    void rowUpperBound(Row r, Value value) {
1492 1506
      _setRowUpperBound(rows(id(r)),value);
1493 1507
    }
1494 1508

	
1495 1509
    /// Get the upper bound of a row (i.e a constraint)
1496 1510

	
1497 1511
    /// This function returns the upper bound for row (constraint) \c c
1498 1512
    /// (this might be -\ref INF as well).
1499 1513
    ///\return The upper bound for row \c r
1500 1514
    Value rowUpperBound(Row r) const {
1501 1515
      return _getRowUpperBound(rows(id(r)));
1502 1516
    }
1503 1517

	
1504 1518
    ///Set an element of the objective function
1505 1519
    void objCoeff(Col c, Value v) {_setObjCoeff(cols(id(c)),v); };
1506 1520

	
1507 1521
    ///Get an element of the objective function
1508 1522
    Value objCoeff(Col c) const { return _getObjCoeff(cols(id(c))); };
1509 1523

	
1510 1524
    ///Set the objective function
1511 1525

	
1512 1526
    ///\param e is a linear expression of type \ref Expr.
1513 1527
    ///
1514 1528
    void obj(const Expr& e) {
1515 1529
      _setObjCoeffs(ExprIterator(e.comps.begin(), cols),
1516 1530
                    ExprIterator(e.comps.end(), cols));
1517 1531
      obj_const_comp = *e;
1518 1532
    }
1519 1533

	
1520 1534
    ///Get the objective function
1521 1535

	
1522 1536
    ///\return the objective function as a linear expression of type
1523 1537
    ///Expr.
1524 1538
    Expr obj() const {
1525 1539
      Expr e;
1526 1540
      _getObjCoeffs(InsertIterator(e.comps, cols));
1527 1541
      *e = obj_const_comp;
1528 1542
      return e;
1529 1543
    }
1530 1544

	
1531 1545

	
1532 1546
    ///Set the direction of optimization
1533 1547
    void sense(Sense sense) { _setSense(sense); }
1534 1548

	
1535 1549
    ///Query the direction of the optimization
1536 1550
    Sense sense() const {return _getSense(); }
1537 1551

	
1538 1552
    ///Set the sense to maximization
1539 1553
    void max() { _setSense(MAX); }
1540 1554

	
1541 1555
    ///Set the sense to maximization
1542 1556
    void min() { _setSense(MIN); }
1543 1557

	
1544 1558
    ///Clears the problem
1545 1559
    void clear() { _clear(); }
1546 1560

	
1547 1561
    /// Sets the message level of the solver
1548 1562
    void messageLevel(MessageLevel level) { _messageLevel(level); }
1549 1563

	
1550 1564
    ///@}
1551 1565

	
1552 1566
  };
1553 1567

	
1554 1568
  /// Addition
1555 1569

	
1556 1570
  ///\relates LpBase::Expr
1557 1571
  ///
1558 1572
  inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) {
1559 1573
    LpBase::Expr tmp(a);
1560 1574
    tmp+=b;
1561 1575
    return tmp;
1562 1576
  }
1563 1577
  ///Substraction
1564 1578

	
1565 1579
  ///\relates LpBase::Expr
1566 1580
  ///
1567 1581
  inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) {
1568 1582
    LpBase::Expr tmp(a);
1569 1583
    tmp-=b;
1570 1584
    return tmp;
1571 1585
  }
1572 1586
  ///Multiply with constant
1573 1587

	
1574 1588
  ///\relates LpBase::Expr
1575 1589
  ///
1576 1590
  inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) {
1577 1591
    LpBase::Expr tmp(a);
1578 1592
    tmp*=b;
1579 1593
    return tmp;
1580 1594
  }
1581 1595

	
1582 1596
  ///Multiply with constant
1583 1597

	
1584 1598
  ///\relates LpBase::Expr
1585 1599
  ///
1586 1600
  inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) {
1587 1601
    LpBase::Expr tmp(b);
1588 1602
    tmp*=a;
1589 1603
    return tmp;
1590 1604
  }
1591 1605
  ///Divide with constant
1592 1606

	
1593 1607
  ///\relates LpBase::Expr
1594 1608
  ///
1595 1609
  inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) {
1596 1610
    LpBase::Expr tmp(a);
1597 1611
    tmp/=b;
1598 1612
    return tmp;
1599 1613
  }
1600 1614

	
1601 1615
  ///Create constraint
1602 1616

	
1603 1617
  ///\relates LpBase::Constr
1604 1618
  ///
1605 1619
  inline LpBase::Constr operator<=(const LpBase::Expr &e,
1606 1620
                                   const LpBase::Expr &f) {
1607 1621
    return LpBase::Constr(0, f - e, LpBase::NaN);
1608 1622
  }
1609 1623

	
1610 1624
  ///Create constraint
1611 1625

	
1612 1626
  ///\relates LpBase::Constr
1613 1627
  ///
1614 1628
  inline LpBase::Constr operator<=(const LpBase::Value &e,
1615 1629
                                   const LpBase::Expr &f) {
1616 1630
    return LpBase::Constr(e, f, LpBase::NaN);
1617 1631
  }
1618 1632

	
1619 1633
  ///Create constraint
1620 1634

	
1621 1635
  ///\relates LpBase::Constr
1622 1636
  ///
1623 1637
  inline LpBase::Constr operator<=(const LpBase::Expr &e,
1624 1638
                                   const LpBase::Value &f) {
1625 1639
    return LpBase::Constr(LpBase::NaN, e, f);
1626 1640
  }
1627 1641

	
1628 1642
  ///Create constraint
1629 1643

	
1630 1644
  ///\relates LpBase::Constr
1631 1645
  ///
1632 1646
  inline LpBase::Constr operator>=(const LpBase::Expr &e,
1633 1647
                                   const LpBase::Expr &f) {
1634 1648
    return LpBase::Constr(0, e - f, LpBase::NaN);
1635 1649
  }
1636 1650

	
1637 1651

	
1638 1652
  ///Create constraint
1639 1653

	
1640 1654
  ///\relates LpBase::Constr
1641 1655
  ///
1642 1656
  inline LpBase::Constr operator>=(const LpBase::Value &e,
1643 1657
                                   const LpBase::Expr &f) {
1644 1658
    return LpBase::Constr(LpBase::NaN, f, e);
1645 1659
  }
1646 1660

	
1647 1661

	
1648 1662
  ///Create constraint
1649 1663

	
1650 1664
  ///\relates LpBase::Constr
1651 1665
  ///
1652 1666
  inline LpBase::Constr operator>=(const LpBase::Expr &e,
1653 1667
                                   const LpBase::Value &f) {
1654 1668
    return LpBase::Constr(f, e, LpBase::NaN);
1655 1669
  }
1656 1670

	
1657 1671
  ///Create constraint
1658 1672

	
1659 1673
  ///\relates LpBase::Constr
1660 1674
  ///
1661 1675
  inline LpBase::Constr operator==(const LpBase::Expr &e,
1662 1676
                                   const LpBase::Value &f) {
1663 1677
    return LpBase::Constr(f, e, f);
1664 1678
  }
1665 1679

	
1666 1680
  ///Create constraint
1667 1681

	
1668 1682
  ///\relates LpBase::Constr
1669 1683
  ///
1670 1684
  inline LpBase::Constr operator==(const LpBase::Expr &e,
1671 1685
                                   const LpBase::Expr &f) {
1672 1686
    return LpBase::Constr(0, f - e, 0);
1673 1687
  }
1674 1688

	
1675 1689
  ///Create constraint
1676 1690

	
1677 1691
  ///\relates LpBase::Constr
1678 1692
  ///
1679 1693
  inline LpBase::Constr operator<=(const LpBase::Value &n,
1680 1694
                                   const LpBase::Constr &c) {
1681 1695
    LpBase::Constr tmp(c);
1682 1696
    LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
1683 1697
    tmp.lowerBound()=n;
1684 1698
    return tmp;
1685 1699
  }
1686 1700
  ///Create constraint
1687 1701

	
1688 1702
  ///\relates LpBase::Constr
1689 1703
  ///
1690 1704
  inline LpBase::Constr operator<=(const LpBase::Constr &c,
1691 1705
                                   const LpBase::Value &n)
1692 1706
  {
1693 1707
    LpBase::Constr tmp(c);
1694 1708
    LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
1695 1709
    tmp.upperBound()=n;
1696 1710
    return tmp;
1697 1711
  }
1698 1712

	
1699 1713
  ///Create constraint
1700 1714

	
1701 1715
  ///\relates LpBase::Constr
1702 1716
  ///
1703 1717
  inline LpBase::Constr operator>=(const LpBase::Value &n,
1704 1718
                                   const LpBase::Constr &c) {
1705 1719
    LpBase::Constr tmp(c);
1706 1720
    LEMON_ASSERT(isNaN(tmp.upperBound()), "Wrong LP constraint");
1707 1721
    tmp.upperBound()=n;
1708 1722
    return tmp;
1709 1723
  }
1710 1724
  ///Create constraint
1711 1725

	
1712 1726
  ///\relates LpBase::Constr
1713 1727
  ///
1714 1728
  inline LpBase::Constr operator>=(const LpBase::Constr &c,
1715 1729
                                   const LpBase::Value &n)
1716 1730
  {
1717 1731
    LpBase::Constr tmp(c);
1718 1732
    LEMON_ASSERT(isNaN(tmp.lowerBound()), "Wrong LP constraint");
1719 1733
    tmp.lowerBound()=n;
1720 1734
    return tmp;
1721 1735
  }
1722 1736

	
1723 1737
  ///Addition
1724 1738

	
1725 1739
  ///\relates LpBase::DualExpr
1726 1740
  ///
1727 1741
  inline LpBase::DualExpr operator+(const LpBase::DualExpr &a,
1728 1742
                                    const LpBase::DualExpr &b) {
1729 1743
    LpBase::DualExpr tmp(a);
1730 1744
    tmp+=b;
1731 1745
    return tmp;
1732 1746
  }
1733 1747
  ///Substraction
1734 1748

	
1735 1749
  ///\relates LpBase::DualExpr
1736 1750
  ///
1737 1751
  inline LpBase::DualExpr operator-(const LpBase::DualExpr &a,
1738 1752
                                    const LpBase::DualExpr &b) {
1739 1753
    LpBase::DualExpr tmp(a);
1740 1754
    tmp-=b;
1741 1755
    return tmp;
1742 1756
  }
1743 1757
  ///Multiply with constant
1744 1758

	
1745 1759
  ///\relates LpBase::DualExpr
1746 1760
  ///
1747 1761
  inline LpBase::DualExpr operator*(const LpBase::DualExpr &a,
1748 1762
                                    const LpBase::Value &b) {
1749 1763
    LpBase::DualExpr tmp(a);
1750 1764
    tmp*=b;
1751 1765
    return tmp;
1752 1766
  }
1753 1767

	
1754 1768
  ///Multiply with constant
1755 1769

	
1756 1770
  ///\relates LpBase::DualExpr
1757 1771
  ///
1758 1772
  inline LpBase::DualExpr operator*(const LpBase::Value &a,
1759 1773
                                    const LpBase::DualExpr &b) {
1760 1774
    LpBase::DualExpr tmp(b);
1761 1775
    tmp*=a;
1762 1776
    return tmp;
1763 1777
  }
1764 1778
  ///Divide with constant
1765 1779

	
1766 1780
  ///\relates LpBase::DualExpr
1767 1781
  ///
1768 1782
  inline LpBase::DualExpr operator/(const LpBase::DualExpr &a,
1769 1783
                                    const LpBase::Value &b) {
1770 1784
    LpBase::DualExpr tmp(a);
1771 1785
    tmp/=b;
1772 1786
    return tmp;
1773 1787
  }
1774 1788

	
1775 1789
  /// \ingroup lp_group
1776 1790
  ///
1777 1791
  /// \brief Common base class for LP solvers
1778 1792
  ///
1779 1793
  /// This class is an abstract base class for LP solvers. This class
1780 1794
  /// provides a full interface for set and modify an LP problem,
1781 1795
  /// solve it and retrieve the solution. You can use one of the
1782 1796
  /// descendants as a concrete implementation, or the \c Lp
1783 1797
  /// default LP solver. However, if you would like to handle LP
1784 1798
  /// solvers as reference or pointer in a generic way, you can use
1785 1799
  /// this class directly.
1786 1800
  class LpSolver : virtual public LpBase {
1787 1801
  public:
1788 1802

	
1789 1803
    /// The problem types for primal and dual problems
1790 1804
    enum ProblemType {
1791 1805
      /// = 0. Feasible solution hasn't been found (but may exist).
1792 1806
      UNDEFINED = 0,
1793 1807
      /// = 1. The problem has no feasible solution.
1794 1808
      INFEASIBLE = 1,
1795 1809
      /// = 2. Feasible solution found.
1796 1810
      FEASIBLE = 2,
1797 1811
      /// = 3. Optimal solution exists and found.
1798 1812
      OPTIMAL = 3,
1799 1813
      /// = 4. The cost function is unbounded.
1800 1814
      UNBOUNDED = 4
1801 1815
    };
1802 1816

	
1803 1817
    ///The basis status of variables
1804 1818
    enum VarStatus {
1805 1819
      /// The variable is in the basis
1806
      BASIC, 
1820
      BASIC,
1807 1821
      /// The variable is free, but not basic
1808 1822
      FREE,
1809
      /// The variable has active lower bound 
1823
      /// The variable has active lower bound
1810 1824
      LOWER,
1811 1825
      /// The variable has active upper bound
1812 1826
      UPPER,
1813 1827
      /// The variable is non-basic and fixed
1814 1828
      FIXED
1815 1829
    };
1816 1830

	
1817 1831
  protected:
1818 1832

	
1819 1833
    virtual SolveExitStatus _solve() = 0;
1820 1834

	
1821 1835
    virtual Value _getPrimal(int i) const = 0;
1822 1836
    virtual Value _getDual(int i) const = 0;
1823 1837

	
1824 1838
    virtual Value _getPrimalRay(int i) const = 0;
1825 1839
    virtual Value _getDualRay(int i) const = 0;
1826 1840

	
1827 1841
    virtual Value _getPrimalValue() const = 0;
1828 1842

	
1829 1843
    virtual VarStatus _getColStatus(int i) const = 0;
1830 1844
    virtual VarStatus _getRowStatus(int i) const = 0;
1831 1845

	
1832 1846
    virtual ProblemType _getPrimalType() const = 0;
1833 1847
    virtual ProblemType _getDualType() const = 0;
1834 1848

	
1835 1849
  public:
1836 1850

	
1837 1851
    ///Allocate a new LP problem instance
1838 1852
    virtual LpSolver* newSolver() const = 0;
1839 1853
    ///Make a copy of the LP problem
1840 1854
    virtual LpSolver* cloneSolver() const = 0;
1841 1855

	
1842 1856
    ///\name Solve the LP
1843 1857

	
1844 1858
    ///@{
1845 1859

	
1846 1860
    ///\e Solve the LP problem at hand
1847 1861
    ///
1848 1862
    ///\return The result of the optimization procedure. Possible
1849 1863
    ///values and their meanings can be found in the documentation of
1850 1864
    ///\ref SolveExitStatus.
1851 1865
    SolveExitStatus solve() { return _solve(); }
1852 1866

	
1853 1867
    ///@}
1854 1868

	
1855 1869
    ///\name Obtain the Solution
1856 1870

	
1857 1871
    ///@{
1858 1872

	
1859 1873
    /// The type of the primal problem
1860 1874
    ProblemType primalType() const {
1861 1875
      return _getPrimalType();
1862 1876
    }
1863 1877

	
1864 1878
    /// The type of the dual problem
1865 1879
    ProblemType dualType() const {
1866 1880
      return _getDualType();
1867 1881
    }
1868 1882

	
1869 1883
    /// Return the primal value of the column
1870 1884

	
1871 1885
    /// Return the primal value of the column.
1872 1886
    /// \pre The problem is solved.
1873 1887
    Value primal(Col c) const { return _getPrimal(cols(id(c))); }
1874 1888

	
1875 1889
    /// Return the primal value of the expression
1876 1890

	
1877 1891
    /// Return the primal value of the expression, i.e. the dot
1878 1892
    /// product of the primal solution and the expression.
1879 1893
    /// \pre The problem is solved.
1880 1894
    Value primal(const Expr& e) const {
1881 1895
      double res = *e;
1882 1896
      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
1883 1897
        res += *c * primal(c);
1884 1898
      }
1885 1899
      return res;
1886 1900
    }
1887 1901
    /// Returns a component of the primal ray
1888
    
1902

	
1889 1903
    /// The primal ray is solution of the modified primal problem,
1890 1904
    /// where we change each finite bound to 0, and we looking for a
1891 1905
    /// negative objective value in case of minimization, and positive
1892 1906
    /// objective value for maximization. If there is such solution,
1893 1907
    /// that proofs the unsolvability of the dual problem, and if a
1894 1908
    /// feasible primal solution exists, then the unboundness of
1895 1909
    /// primal problem.
1896 1910
    ///
1897 1911
    /// \pre The problem is solved and the dual problem is infeasible.
1898 1912
    /// \note Some solvers does not provide primal ray calculation
1899 1913
    /// functions.
1900 1914
    Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); }
1901 1915

	
1902 1916
    /// Return the dual value of the row
1903 1917

	
1904 1918
    /// Return the dual value of the row.
1905 1919
    /// \pre The problem is solved.
1906 1920
    Value dual(Row r) const { return _getDual(rows(id(r))); }
1907 1921

	
1908 1922
    /// Return the dual value of the dual expression
1909 1923

	
1910 1924
    /// Return the dual value of the dual expression, i.e. the dot
1911 1925
    /// product of the dual solution and the dual expression.
1912 1926
    /// \pre The problem is solved.
1913 1927
    Value dual(const DualExpr& e) const {
1914 1928
      double res = 0.0;
1915 1929
      for (DualExpr::ConstCoeffIt r(e); r != INVALID; ++r) {
1916 1930
        res += *r * dual(r);
1917 1931
      }
1918 1932
      return res;
1919 1933
    }
1920 1934

	
1921 1935
    /// Returns a component of the dual ray
1922
    
1936

	
1923 1937
    /// The dual ray is solution of the modified primal problem, where
1924 1938
    /// we change each finite bound to 0 (i.e. the objective function
1925 1939
    /// coefficients in the primal problem), and we looking for a
1926 1940
    /// ositive objective value. If there is such solution, that
1927 1941
    /// proofs the unsolvability of the primal problem, and if a
1928 1942
    /// feasible dual solution exists, then the unboundness of
1929 1943
    /// dual problem.
1930 1944
    ///
1931 1945
    /// \pre The problem is solved and the primal problem is infeasible.
1932 1946
    /// \note Some solvers does not provide dual ray calculation
1933 1947
    /// functions.
1934 1948
    Value dualRay(Row r) const { return _getDualRay(rows(id(r))); }
1935 1949

	
1936 1950
    /// Return the basis status of the column
1937 1951

	
1938 1952
    /// \see VarStatus
1939 1953
    VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); }
1940 1954

	
1941 1955
    /// Return the basis status of the row
1942 1956

	
1943 1957
    /// \see VarStatus
1944 1958
    VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); }
1945 1959

	
1946 1960
    ///The value of the objective function
1947 1961

	
1948 1962
    ///\return
1949 1963
    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
1950 1964
    /// of the primal problem, depending on whether we minimize or maximize.
1951 1965
    ///- \ref NaN if no primal solution is found.
1952 1966
    ///- The (finite) objective value if an optimal solution is found.
1953 1967
    Value primal() const { return _getPrimalValue()+obj_const_comp;}
1954 1968
    ///@}
1955 1969

	
1956 1970
  protected:
1957 1971

	
1958 1972
  };
1959 1973

	
1960 1974

	
1961 1975
  /// \ingroup lp_group
1962 1976
  ///
1963 1977
  /// \brief Common base class for MIP solvers
1964 1978
  ///
1965 1979
  /// This class is an abstract base class for MIP solvers. This class
1966 1980
  /// provides a full interface for set and modify an MIP problem,
1967 1981
  /// solve it and retrieve the solution. You can use one of the
1968 1982
  /// descendants as a concrete implementation, or the \c Lp
1969 1983
  /// default MIP solver. However, if you would like to handle MIP
1970 1984
  /// solvers as reference or pointer in a generic way, you can use
1971 1985
  /// this class directly.
1972 1986
  class MipSolver : virtual public LpBase {
1973 1987
  public:
1974 1988

	
1975 1989
    /// The problem types for MIP problems
1976 1990
    enum ProblemType {
1977 1991
      /// = 0. Feasible solution hasn't been found (but may exist).
1978 1992
      UNDEFINED = 0,
1979 1993
      /// = 1. The problem has no feasible solution.
1980 1994
      INFEASIBLE = 1,
1981 1995
      /// = 2. Feasible solution found.
1982 1996
      FEASIBLE = 2,
1983 1997
      /// = 3. Optimal solution exists and found.
1984 1998
      OPTIMAL = 3,
1985 1999
      /// = 4. The cost function is unbounded.
1986 2000
      ///The Mip or at least the relaxed problem is unbounded.
1987 2001
      UNBOUNDED = 4
1988 2002
    };
1989 2003

	
1990 2004
    ///Allocate a new MIP problem instance
1991 2005
    virtual MipSolver* newSolver() const = 0;
1992 2006
    ///Make a copy of the MIP problem
1993 2007
    virtual MipSolver* cloneSolver() const = 0;
1994 2008

	
1995 2009
    ///\name Solve the MIP
1996 2010

	
1997 2011
    ///@{
1998 2012

	
1999 2013
    /// Solve the MIP problem at hand
2000 2014
    ///
2001 2015
    ///\return The result of the optimization procedure. Possible
2002 2016
    ///values and their meanings can be found in the documentation of
2003 2017
    ///\ref SolveExitStatus.
2004 2018
    SolveExitStatus solve() { return _solve(); }
2005 2019

	
2006 2020
    ///@}
2007 2021

	
2008 2022
    ///\name Set Column Type
2009 2023
    ///@{
2010 2024

	
2011 2025
    ///Possible variable (column) types (e.g. real, integer, binary etc.)
2012 2026
    enum ColTypes {
2013 2027
      /// = 0. Continuous variable (default).
2014 2028
      REAL = 0,
2015 2029
      /// = 1. Integer variable.
2016 2030
      INTEGER = 1
2017 2031
    };
2018 2032

	
2019 2033
    ///Sets the type of the given column to the given type
2020 2034

	
2021 2035
    ///Sets the type of the given column to the given type.
2022 2036
    ///
2023 2037
    void colType(Col c, ColTypes col_type) {
2024 2038
      _setColType(cols(id(c)),col_type);
2025 2039
    }
2026 2040

	
2027 2041
    ///Gives back the type of the column.
2028 2042

	
2029 2043
    ///Gives back the type of the column.
2030 2044
    ///
2031 2045
    ColTypes colType(Col c) const {
2032 2046
      return _getColType(cols(id(c)));
2033 2047
    }
2034 2048
    ///@}
2035 2049

	
2036 2050
    ///\name Obtain the Solution
2037 2051

	
2038 2052
    ///@{
2039 2053

	
2040 2054
    /// The type of the MIP problem
2041 2055
    ProblemType type() const {
2042 2056
      return _getType();
2043 2057
    }
2044 2058

	
2045 2059
    /// Return the value of the row in the solution
2046 2060

	
2047 2061
    ///  Return the value of the row in the solution.
2048 2062
    /// \pre The problem is solved.
2049 2063
    Value sol(Col c) const { return _getSol(cols(id(c))); }
2050 2064

	
2051 2065
    /// Return the value of the expression in the solution
2052 2066

	
2053 2067
    /// Return the value of the expression in the solution, i.e. the
2054 2068
    /// dot product of the solution and the expression.
2055 2069
    /// \pre The problem is solved.
2056 2070
    Value sol(const Expr& e) const {
2057 2071
      double res = *e;
2058 2072
      for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) {
2059 2073
        res += *c * sol(c);
2060 2074
      }
2061 2075
      return res;
2062 2076
    }
2063 2077
    ///The value of the objective function
2064
    
2078

	
2065 2079
    ///\return
2066 2080
    ///- \ref INF or -\ref INF means either infeasibility or unboundedness
2067 2081
    /// of the problem, depending on whether we minimize or maximize.
2068 2082
    ///- \ref NaN if no primal solution is found.
2069 2083
    ///- The (finite) objective value if an optimal solution is found.
2070 2084
    Value solValue() const { return _getSolValue()+obj_const_comp;}
2071 2085
    ///@}
2072 2086

	
2073 2087
  protected:
2074 2088

	
2075 2089
    virtual SolveExitStatus _solve() = 0;
2076 2090
    virtual ColTypes _getColType(int col) const = 0;
2077 2091
    virtual void _setColType(int col, ColTypes col_type) = 0;
2078 2092
    virtual ProblemType _getType() const = 0;
2079 2093
    virtual Value _getSol(int i) const = 0;
2080 2094
    virtual Value _getSolValue() const = 0;
2081 2095

	
2082 2096
  };
2083 2097

	
2084 2098

	
2085 2099

	
2086 2100
} //namespace lemon
2087 2101

	
2088 2102
#endif //LEMON_LP_BASE_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-2010
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/lp_skeleton.h>
20 20

	
21 21
///\file
22 22
///\brief A skeleton file to implement LP solver interfaces
23 23
namespace lemon {
24 24

	
25 25
  int SkeletonSolverBase::_addCol()
26 26
  {
27 27
    return ++col_num;
28 28
  }
29 29

	
30 30
  int SkeletonSolverBase::_addRow()
31 31
  {
32 32
    return ++row_num;
33 33
  }
34 34

	
35
  int SkeletonSolverBase::_addRow(Value, ExprIterator, ExprIterator, Value)
36
  {
37
    return ++row_num;
38
  }
39

	
35 40
  void SkeletonSolverBase::_eraseCol(int) {}
36 41
  void SkeletonSolverBase::_eraseRow(int) {}
37 42

	
38 43
  void SkeletonSolverBase::_getColName(int, std::string &) const {}
39 44
  void SkeletonSolverBase::_setColName(int, const std::string &) {}
40 45
  int SkeletonSolverBase::_colByName(const std::string&) const { return -1; }
41 46

	
42 47
  void SkeletonSolverBase::_getRowName(int, std::string &) const {}
43 48
  void SkeletonSolverBase::_setRowName(int, const std::string &) {}
44 49
  int SkeletonSolverBase::_rowByName(const std::string&) const { return -1; }
45 50

	
46 51
  void SkeletonSolverBase::_setRowCoeffs(int, ExprIterator, ExprIterator) {}
47 52
  void SkeletonSolverBase::_getRowCoeffs(int, InsertIterator) const {}
48 53

	
49 54
  void SkeletonSolverBase::_setColCoeffs(int, ExprIterator, ExprIterator) {}
50 55
  void SkeletonSolverBase::_getColCoeffs(int, InsertIterator) const {}
51 56

	
52 57
  void SkeletonSolverBase::_setCoeff(int, int, Value) {}
53 58
  SkeletonSolverBase::Value SkeletonSolverBase::_getCoeff(int, int) const
54 59
  { return 0; }
55 60

	
56 61
  void SkeletonSolverBase::_setColLowerBound(int, Value) {}
57 62
  SkeletonSolverBase::Value SkeletonSolverBase::_getColLowerBound(int) const
58 63
  {  return 0; }
59 64

	
60 65
  void SkeletonSolverBase::_setColUpperBound(int, Value) {}
61 66
  SkeletonSolverBase::Value SkeletonSolverBase::_getColUpperBound(int) const
62 67
  {  return 0; }
63 68

	
64 69
  void SkeletonSolverBase::_setRowLowerBound(int, Value) {}
65 70
  SkeletonSolverBase::Value SkeletonSolverBase::_getRowLowerBound(int) const
66 71
  {  return 0; }
67 72

	
68 73
  void SkeletonSolverBase::_setRowUpperBound(int, Value) {}
69 74
  SkeletonSolverBase::Value SkeletonSolverBase::_getRowUpperBound(int) const
70 75
  {  return 0; }
71 76

	
72 77
  void SkeletonSolverBase::_setObjCoeffs(ExprIterator, ExprIterator) {}
73 78
  void SkeletonSolverBase::_getObjCoeffs(InsertIterator) const {};
74 79

	
75 80
  void SkeletonSolverBase::_setObjCoeff(int, Value) {}
76 81
  SkeletonSolverBase::Value SkeletonSolverBase::_getObjCoeff(int) const
77 82
  {  return 0; }
78 83

	
79 84
  void SkeletonSolverBase::_setSense(Sense) {}
80 85
  SkeletonSolverBase::Sense SkeletonSolverBase::_getSense() const
81 86
  { return MIN; }
82 87

	
83 88
  void SkeletonSolverBase::_clear() {
84 89
    row_num = col_num = 0;
85 90
  }
86 91

	
87 92
  void SkeletonSolverBase::_messageLevel(MessageLevel) {}
88 93

	
89 94
  LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
90 95

	
91 96
  LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
92 97
  LpSkeleton::Value LpSkeleton::_getDual(int) const { return 0; }
93 98
  LpSkeleton::Value LpSkeleton::_getPrimalValue() const { return 0; }
94 99

	
95 100
  LpSkeleton::Value LpSkeleton::_getPrimalRay(int) const { return 0; }
96 101
  LpSkeleton::Value LpSkeleton::_getDualRay(int) const { return 0; }
97 102

	
98 103
  LpSkeleton::ProblemType LpSkeleton::_getPrimalType() const
99 104
  { return UNDEFINED; }
100 105

	
101 106
  LpSkeleton::ProblemType LpSkeleton::_getDualType() const
102 107
  { return UNDEFINED; }
103 108

	
104 109
  LpSkeleton::VarStatus LpSkeleton::_getColStatus(int) const
105 110
  { return BASIC; }
106 111

	
107 112
  LpSkeleton::VarStatus LpSkeleton::_getRowStatus(int) const
108 113
  { return BASIC; }
109 114

	
110 115
  LpSkeleton* LpSkeleton::newSolver() const
111 116
  { return static_cast<LpSkeleton*>(0); }
112 117

	
113 118
  LpSkeleton* LpSkeleton::cloneSolver() const
114 119
  { return static_cast<LpSkeleton*>(0); }
115 120

	
116 121
  const char* LpSkeleton::_solverName() const { return "LpSkeleton"; }
117 122

	
118 123
  MipSkeleton::SolveExitStatus MipSkeleton::_solve()
119 124
  { return SOLVED; }
120 125

	
121 126
  MipSkeleton::Value MipSkeleton::_getSol(int) const { return 0; }
122 127
  MipSkeleton::Value MipSkeleton::_getSolValue() const { return 0; }
123 128

	
124 129
  MipSkeleton::ProblemType MipSkeleton::_getType() const
125 130
  { return UNDEFINED; }
126 131

	
127 132
  MipSkeleton* MipSkeleton::newSolver() const
128 133
  { return static_cast<MipSkeleton*>(0); }
129 134

	
130 135
  MipSkeleton* MipSkeleton::cloneSolver() const
131 136
  { return static_cast<MipSkeleton*>(0); }
132 137

	
133 138
  const char* MipSkeleton::_solverName() const { return "MipSkeleton"; }
134 139

	
135 140
} //namespace lemon
136 141

	
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-2010
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_LP_SKELETON_H
20 20
#define LEMON_LP_SKELETON_H
21 21

	
22 22
#include <lemon/lp_base.h>
23 23

	
24 24
///\file
25 25
///\brief Skeleton file to implement LP/MIP solver interfaces
26
///  
26
///
27 27
///The classes in this file do nothing, but they can serve as skeletons when
28 28
///implementing an interface to new solvers.
29 29
namespace lemon {
30 30

	
31 31
  ///A skeleton class to implement LP/MIP solver base interface
32
  
32

	
33 33
  ///This class does nothing, but it can serve as a skeleton when
34 34
  ///implementing an interface to new solvers.
35 35
  class SkeletonSolverBase : public virtual LpBase {
36 36
    int col_num,row_num;
37 37

	
38 38
  protected:
39 39

	
40 40
    SkeletonSolverBase()
41 41
      : col_num(-1), row_num(-1) {}
42 42

	
43 43
    /// \e
44 44
    virtual int _addCol();
45 45
    /// \e
46 46
    virtual int _addRow();
47 47
    /// \e
48
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
49
    /// \e
48 50
    virtual void _eraseCol(int i);
49 51
    /// \e
50 52
    virtual void _eraseRow(int i);
51 53

	
52 54
    /// \e
53 55
    virtual void _getColName(int col, std::string& name) const;
54 56
    /// \e
55 57
    virtual void _setColName(int col, const std::string& name);
56 58
    /// \e
57 59
    virtual int _colByName(const std::string& name) const;
58 60

	
59 61
    /// \e
60 62
    virtual void _getRowName(int row, std::string& name) const;
61 63
    /// \e
62 64
    virtual void _setRowName(int row, const std::string& name);
63 65
    /// \e
64 66
    virtual int _rowByName(const std::string& name) const;
65 67

	
66 68
    /// \e
67 69
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
68 70
    /// \e
69 71
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
70 72
    /// \e
71 73
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
72 74
    /// \e
73 75
    virtual void _getColCoeffs(int i, InsertIterator b) const;
74 76

	
75 77
    /// Set one element of the coefficient matrix
76 78
    virtual void _setCoeff(int row, int col, Value value);
77 79

	
78 80
    /// Get one element of the coefficient matrix
79 81
    virtual Value _getCoeff(int row, int col) const;
80 82

	
81 83
    /// The lower bound of a variable (column) have to be given by an
82 84
    /// extended number of type Value, i.e. a finite number of type
83 85
    /// Value or -\ref INF.
84 86
    virtual void _setColLowerBound(int i, Value value);
85 87
    /// \e
86 88

	
87 89
    /// The lower bound of a variable (column) is an
88 90
    /// extended number of type Value, i.e. a finite number of type
89 91
    /// Value or -\ref INF.
90 92
    virtual Value _getColLowerBound(int i) const;
91 93

	
92 94
    /// The upper bound of a variable (column) have to be given by an
93 95
    /// extended number of type Value, i.e. a finite number of type
94 96
    /// Value or \ref INF.
95 97
    virtual void _setColUpperBound(int i, Value value);
96 98
    /// \e
97 99

	
98 100
    /// The upper bound of a variable (column) is an
99 101
    /// extended number of type Value, i.e. a finite number of type
100 102
    /// Value or \ref INF.
101 103
    virtual Value _getColUpperBound(int i) const;
102 104

	
103 105
    /// The lower bound of a constraint (row) have to be given by an
104 106
    /// extended number of type Value, i.e. a finite number of type
105 107
    /// Value or -\ref INF.
106 108
    virtual void _setRowLowerBound(int i, Value value);
107 109
    /// \e
108 110

	
109 111
    /// The lower bound of a constraint (row) is an
110 112
    /// extended number of type Value, i.e. a finite number of type
111 113
    /// Value or -\ref INF.
112 114
    virtual Value _getRowLowerBound(int i) const;
113 115

	
114 116
    /// The upper bound of a constraint (row) have to be given by an
115 117
    /// extended number of type Value, i.e. a finite number of type
116 118
    /// Value or \ref INF.
117 119
    virtual void _setRowUpperBound(int i, Value value);
118 120
    /// \e
119 121

	
120 122
    /// The upper bound of a constraint (row) is an
121 123
    /// extended number of type Value, i.e. a finite number of type
122 124
    /// Value or \ref INF.
123 125
    virtual Value _getRowUpperBound(int i) const;
124 126

	
125 127
    /// \e
126 128
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
127 129
    /// \e
128 130
    virtual void _getObjCoeffs(InsertIterator b) const;
129 131

	
130 132
    /// \e
131 133
    virtual void _setObjCoeff(int i, Value obj_coef);
132 134
    /// \e
133 135
    virtual Value _getObjCoeff(int i) const;
134 136

	
135 137
    ///\e
136 138
    virtual void _setSense(Sense);
137 139
    ///\e
138 140
    virtual Sense _getSense() const;
139 141

	
140 142
    ///\e
141 143
    virtual void _clear();
142 144

	
143 145
    ///\e
144 146
    virtual void _messageLevel(MessageLevel);
145 147
  };
146 148

	
147 149
  /// \brief Skeleton class for an LP solver interface
148 150
  ///
149 151
  ///This class does nothing, but it can serve as a skeleton when
150 152
  ///implementing an interface to new solvers.
151 153

	
152 154
  ///\ingroup lp_group
153 155
  class LpSkeleton : public LpSolver, public SkeletonSolverBase {
154 156
  public:
155 157
    ///\e
156 158
    LpSkeleton() : LpSolver(), SkeletonSolverBase() {}
157 159
    ///\e
158 160
    virtual LpSkeleton* newSolver() const;
159 161
    ///\e
160 162
    virtual LpSkeleton* cloneSolver() const;
161 163
  protected:
162 164

	
163 165
    ///\e
164 166
    virtual SolveExitStatus _solve();
165 167

	
166 168
    ///\e
167 169
    virtual Value _getPrimal(int i) const;
168 170
    ///\e
169 171
    virtual Value _getDual(int i) const;
170 172

	
171 173
    ///\e
172 174
    virtual Value _getPrimalValue() const;
173 175

	
174 176
    ///\e
175 177
    virtual Value _getPrimalRay(int i) const;
176 178
    ///\e
177 179
    virtual Value _getDualRay(int i) const;
178 180

	
179 181
    ///\e
180 182
    virtual ProblemType _getPrimalType() const;
181 183
    ///\e
182 184
    virtual ProblemType _getDualType() const;
183 185

	
184 186
    ///\e
185 187
    virtual VarStatus _getColStatus(int i) const;
186 188
    ///\e
187 189
    virtual VarStatus _getRowStatus(int i) const;
188 190

	
189 191
    ///\e
190 192
    virtual const char* _solverName() const;
191 193

	
192 194
  };
193 195

	
194 196
  /// \brief Skeleton class for a MIP solver interface
195 197
  ///
196 198
  ///This class does nothing, but it can serve as a skeleton when
197 199
  ///implementing an interface to new solvers.
198 200
  ///\ingroup lp_group
199 201
  class MipSkeleton : public MipSolver, public SkeletonSolverBase {
200 202
  public:
201 203
    ///\e
202 204
    MipSkeleton() : MipSolver(), SkeletonSolverBase() {}
203 205
    ///\e
204 206
    virtual MipSkeleton* newSolver() const;
205 207
    ///\e
206 208
    virtual MipSkeleton* cloneSolver() const;
207 209

	
208 210
  protected:
209 211
    ///\e
210 212
    virtual SolveExitStatus _solve();
211 213

	
212 214
    ///\e
213 215
    virtual Value _getSol(int i) const;
214 216

	
215 217
    ///\e
216 218
    virtual Value _getSolValue() const;
217 219

	
218 220
    ///\e
219 221
    virtual ProblemType _getType() const;
220 222

	
221 223
    ///\e
222 224
    virtual const char* _solverName() const;
223 225
  };
224 226

	
225 227
} //namespace lemon
226 228

	
227 229
#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-2009
5
 * Copyright (C) 2003-2010
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 65
    ///\e
67 66
    typedef K Key;
68 67
    ///\e
69 68
    typedef V Value;
70 69

	
71 70
    /// Gives back a default constructed element.
72 71
    Value operator[](const Key&) const { return Value(); }
73 72
    /// Absorbs the value.
74 73
    void set(const Key&, const Value&) {}
75 74
  };
76 75

	
77 76
  /// Returns a \c NullMap class
78 77

	
79 78
  /// This function just returns a \c NullMap class.
80 79
  /// \relates NullMap
81 80
  template <typename K, typename V>
82 81
  NullMap<K, V> nullMap() {
83 82
    return NullMap<K, V>();
84 83
  }
85 84

	
86 85

	
87 86
  /// Constant map.
88 87

	
89 88
  /// This \ref concepts::ReadMap "readable map" assigns a specified
90 89
  /// value to each key.
91 90
  ///
92 91
  /// In other aspects it is equivalent to \c NullMap.
93
  /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
92
  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
94 93
  /// concept, but it absorbs the data written to it.
95 94
  ///
96 95
  /// The simplest way of using this map is through the constMap()
97 96
  /// function.
98 97
  ///
99 98
  /// \sa NullMap
100 99
  /// \sa IdentityMap
101 100
  template<typename K, typename V>
102 101
  class ConstMap : public MapBase<K, V> {
103 102
  private:
104 103
    V _value;
105 104
  public:
106 105
    ///\e
107 106
    typedef K Key;
108 107
    ///\e
109 108
    typedef V Value;
110 109

	
111 110
    /// Default constructor
112 111

	
113 112
    /// Default constructor.
114 113
    /// The value of the map will be default constructed.
115 114
    ConstMap() {}
116 115

	
117 116
    /// Constructor with specified initial value
118 117

	
119 118
    /// Constructor with specified initial value.
120 119
    /// \param v The initial value of the map.
121 120
    ConstMap(const Value &v) : _value(v) {}
122 121

	
123 122
    /// Gives back the specified value.
124 123
    Value operator[](const Key&) const { return _value; }
125 124

	
126 125
    /// Absorbs the value.
127 126
    void set(const Key&, const Value&) {}
128 127

	
129 128
    /// Sets the value that is assigned to each key.
130 129
    void setAll(const Value &v) {
131 130
      _value = v;
132 131
    }
133 132

	
134 133
    template<typename V1>
135 134
    ConstMap(const ConstMap<K, V1> &, const Value &v) : _value(v) {}
136 135
  };
137 136

	
138 137
  /// Returns a \c ConstMap class
139 138

	
140 139
  /// This function just returns a \c ConstMap class.
141 140
  /// \relates ConstMap
142 141
  template<typename K, typename V>
143 142
  inline ConstMap<K, V> constMap(const V &v) {
144 143
    return ConstMap<K, V>(v);
145 144
  }
146 145

	
147 146
  template<typename K, typename V>
148 147
  inline ConstMap<K, V> constMap() {
149 148
    return ConstMap<K, V>();
150 149
  }
151 150

	
152 151

	
153 152
  template<typename T, T v>
154 153
  struct Const {};
155 154

	
156 155
  /// Constant map with inlined constant value.
157 156

	
158 157
  /// This \ref concepts::ReadMap "readable map" assigns a specified
159 158
  /// value to each key.
160 159
  ///
161 160
  /// In other aspects it is equivalent to \c NullMap.
162
  /// So it conforms the \ref concepts::ReadWriteMap "ReadWriteMap"
161
  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
163 162
  /// concept, but it absorbs the data written to it.
164 163
  ///
165 164
  /// The simplest way of using this map is through the constMap()
166 165
  /// function.
167 166
  ///
168 167
  /// \sa NullMap
169 168
  /// \sa IdentityMap
170 169
  template<typename K, typename V, V v>
171 170
  class ConstMap<K, Const<V, v> > : public MapBase<K, V> {
172 171
  public:
173 172
    ///\e
174 173
    typedef K Key;
175 174
    ///\e
176 175
    typedef V Value;
177 176

	
178 177
    /// Constructor.
179 178
    ConstMap() {}
180 179

	
181 180
    /// Gives back the specified value.
182 181
    Value operator[](const Key&) const { return v; }
183 182

	
184 183
    /// Absorbs the value.
185 184
    void set(const Key&, const Value&) {}
186 185
  };
187 186

	
188 187
  /// Returns a \c ConstMap class with inlined constant value
189 188

	
190 189
  /// This function just returns a \c ConstMap class with inlined
191 190
  /// constant value.
192 191
  /// \relates ConstMap
193 192
  template<typename K, typename V, V v>
194 193
  inline ConstMap<K, Const<V, v> > constMap() {
195 194
    return ConstMap<K, Const<V, v> >();
196 195
  }
197 196

	
198 197

	
199 198
  /// Identity map.
200 199

	
201 200
  /// This \ref concepts::ReadMap "read-only map" gives back the given
202 201
  /// key as value without any modification.
203 202
  ///
204 203
  /// \sa ConstMap
205 204
  template <typename T>
206 205
  class IdentityMap : public MapBase<T, T> {
207 206
  public:
208 207
    ///\e
209 208
    typedef T Key;
210 209
    ///\e
211 210
    typedef T Value;
212 211

	
213 212
    /// Gives back the given value without any modification.
214 213
    Value operator[](const Key &k) const {
215 214
      return k;
216 215
    }
217 216
  };
218 217

	
219 218
  /// Returns an \c IdentityMap class
220 219

	
221 220
  /// This function just returns an \c IdentityMap class.
222 221
  /// \relates IdentityMap
223 222
  template<typename T>
224 223
  inline IdentityMap<T> identityMap() {
225 224
    return IdentityMap<T>();
226 225
  }
227 226

	
228 227

	
229 228
  /// \brief Map for storing values for integer keys from the range
230 229
  /// <tt>[0..size-1]</tt>.
231 230
  ///
232 231
  /// This map is essentially a wrapper for \c std::vector. It assigns
233 232
  /// values to integer keys from the range <tt>[0..size-1]</tt>.
234
  /// It can be used with some data structures, for example
235
  /// \c UnionFind, \c BinHeap, when the used items are small
236
  /// integers. This map conforms the \ref concepts::ReferenceMap
233
  /// It can be used together with some data structures, e.g.
234
  /// heap types and \c UnionFind, when the used items are small
235
  /// integers. This map conforms to the \ref concepts::ReferenceMap
237 236
  /// "ReferenceMap" concept.
238 237
  ///
239 238
  /// The simplest way of using this map is through the rangeMap()
240 239
  /// function.
241 240
  template <typename V>
242 241
  class RangeMap : public MapBase<int, V> {
243 242
    template <typename V1>
244 243
    friend class RangeMap;
245 244
  private:
246 245

	
247 246
    typedef std::vector<V> Vector;
248 247
    Vector _vector;
249 248

	
250 249
  public:
251 250

	
252 251
    /// Key type
253 252
    typedef int Key;
254 253
    /// Value type
255 254
    typedef V Value;
256 255
    /// Reference type
257 256
    typedef typename Vector::reference Reference;
258 257
    /// Const reference type
259 258
    typedef typename Vector::const_reference ConstReference;
260 259

	
261 260
    typedef True ReferenceMapTag;
262 261

	
263 262
  public:
264 263

	
265 264
    /// Constructor with specified default value.
266 265
    RangeMap(int size = 0, const Value &value = Value())
267 266
      : _vector(size, value) {}
268 267

	
269 268
    /// Constructs the map from an appropriate \c std::vector.
270 269
    template <typename V1>
271 270
    RangeMap(const std::vector<V1>& vector)
272 271
      : _vector(vector.begin(), vector.end()) {}
273 272

	
274 273
    /// Constructs the map from another \c RangeMap.
275 274
    template <typename V1>
276 275
    RangeMap(const RangeMap<V1> &c)
277 276
      : _vector(c._vector.begin(), c._vector.end()) {}
278 277

	
279 278
    /// Returns the size of the map.
280 279
    int size() {
281 280
      return _vector.size();
282 281
    }
283 282

	
284 283
    /// Resizes the map.
285 284

	
286 285
    /// Resizes the underlying \c std::vector container, so changes the
287 286
    /// keyset of the map.
288 287
    /// \param size The new size of the map. The new keyset will be the
289 288
    /// range <tt>[0..size-1]</tt>.
290 289
    /// \param value The default value to assign to the new keys.
291 290
    void resize(int size, const Value &value = Value()) {
292 291
      _vector.resize(size, value);
293 292
    }
294 293

	
295 294
  private:
296 295

	
297 296
    RangeMap& operator=(const RangeMap&);
298 297

	
299 298
  public:
300 299

	
301 300
    ///\e
302 301
    Reference operator[](const Key &k) {
303 302
      return _vector[k];
304 303
    }
305 304

	
306 305
    ///\e
307 306
    ConstReference operator[](const Key &k) const {
308 307
      return _vector[k];
309 308
    }
310 309

	
311 310
    ///\e
312 311
    void set(const Key &k, const Value &v) {
313 312
      _vector[k] = v;
314 313
    }
315 314
  };
316 315

	
317 316
  /// Returns a \c RangeMap class
318 317

	
319 318
  /// This function just returns a \c RangeMap class.
320 319
  /// \relates RangeMap
321 320
  template<typename V>
322 321
  inline RangeMap<V> rangeMap(int size = 0, const V &value = V()) {
323 322
    return RangeMap<V>(size, value);
324 323
  }
325 324

	
326 325
  /// \brief Returns a \c RangeMap class created from an appropriate
327 326
  /// \c std::vector
328 327

	
329 328
  /// This function just returns a \c RangeMap class created from an
330 329
  /// appropriate \c std::vector.
331 330
  /// \relates RangeMap
332 331
  template<typename V>
333 332
  inline RangeMap<V> rangeMap(const std::vector<V> &vector) {
334 333
    return RangeMap<V>(vector);
335 334
  }
336 335

	
337 336

	
338 337
  /// Map type based on \c std::map
339 338

	
340 339
  /// This map is essentially a wrapper for \c std::map with addition
341 340
  /// that you can specify a default value for the keys that are not
342 341
  /// stored actually. This value can be different from the default
343 342
  /// contructed value (i.e. \c %Value()).
344
  /// This type conforms the \ref concepts::ReferenceMap "ReferenceMap"
343
  /// This type conforms to the \ref concepts::ReferenceMap "ReferenceMap"
345 344
  /// concept.
346 345
  ///
347 346
  /// This map is useful if a default value should be assigned to most of
348 347
  /// the keys and different values should be assigned only to a few
349 348
  /// keys (i.e. the map is "sparse").
350 349
  /// The name of this type also refers to this important usage.
351 350
  ///
352
  /// Apart form that this map can be used in many other cases since it
351
  /// Apart form that, this map can be used in many other cases since it
353 352
  /// is based on \c std::map, which is a general associative container.
354
  /// However keep in mind that it is usually not as efficient as other
353
  /// However, keep in mind that it is usually not as efficient as other
355 354
  /// maps.
356 355
  ///
357 356
  /// The simplest way of using this map is through the sparseMap()
358 357
  /// function.
359 358
  template <typename K, typename V, typename Comp = std::less<K> >
360 359
  class SparseMap : public MapBase<K, V> {
361 360
    template <typename K1, typename V1, typename C1>
362 361
    friend class SparseMap;
363 362
  public:
364 363

	
365 364
    /// Key type
366 365
    typedef K Key;
367 366
    /// Value type
368 367
    typedef V Value;
369 368
    /// Reference type
370 369
    typedef Value& Reference;
371 370
    /// Const reference type
372 371
    typedef const Value& ConstReference;
373 372

	
374 373
    typedef True ReferenceMapTag;
375 374

	
376 375
  private:
377 376

	
378 377
    typedef std::map<K, V, Comp> Map;
379 378
    Map _map;
380 379
    Value _value;
381 380

	
382 381
  public:
383 382

	
384 383
    /// \brief Constructor with specified default value.
385 384
    SparseMap(const Value &value = Value()) : _value(value) {}
386 385
    /// \brief Constructs the map from an appropriate \c std::map, and
387 386
    /// explicitly specifies a default value.
388 387
    template <typename V1, typename Comp1>
389 388
    SparseMap(const std::map<Key, V1, Comp1> &map,
390 389
              const Value &value = Value())
391 390
      : _map(map.begin(), map.end()), _value(value) {}
392 391

	
393 392
    /// \brief Constructs the map from another \c SparseMap.
394 393
    template<typename V1, typename Comp1>
395 394
    SparseMap(const SparseMap<Key, V1, Comp1> &c)
396 395
      : _map(c._map.begin(), c._map.end()), _value(c._value) {}
397 396

	
398 397
  private:
399 398

	
400 399
    SparseMap& operator=(const SparseMap&);
401 400

	
402 401
  public:
403 402

	
404 403
    ///\e
405 404
    Reference operator[](const Key &k) {
406 405
      typename Map::iterator it = _map.lower_bound(k);
407 406
      if (it != _map.end() && !_map.key_comp()(k, it->first))
408 407
        return it->second;
409 408
      else
410 409
        return _map.insert(it, std::make_pair(k, _value))->second;
411 410
    }
412 411

	
413 412
    ///\e
414 413
    ConstReference operator[](const Key &k) const {
415 414
      typename Map::const_iterator it = _map.find(k);
416 415
      if (it != _map.end())
417 416
        return it->second;
418 417
      else
419 418
        return _value;
420 419
    }
421 420

	
422 421
    ///\e
423 422
    void set(const Key &k, const Value &v) {
424 423
      typename Map::iterator it = _map.lower_bound(k);
425 424
      if (it != _map.end() && !_map.key_comp()(k, it->first))
426 425
        it->second = v;
427 426
      else
428 427
        _map.insert(it, std::make_pair(k, v));
429 428
    }
430 429

	
431 430
    ///\e
432 431
    void setAll(const Value &v) {
433 432
      _value = v;
434 433
      _map.clear();
435 434
    }
436 435
  };
437 436

	
438 437
  /// Returns a \c SparseMap class
439 438

	
440 439
  /// This function just returns a \c SparseMap class with specified
441 440
  /// default value.
442 441
  /// \relates SparseMap
443 442
  template<typename K, typename V, typename Compare>
444 443
  inline SparseMap<K, V, Compare> sparseMap(const V& value = V()) {
445 444
    return SparseMap<K, V, Compare>(value);
446 445
  }
447 446

	
448 447
  template<typename K, typename V>
449 448
  inline SparseMap<K, V, std::less<K> > sparseMap(const V& value = V()) {
450 449
    return SparseMap<K, V, std::less<K> >(value);
451 450
  }
452 451

	
453 452
  /// \brief Returns a \c SparseMap class created from an appropriate
454 453
  /// \c std::map
455 454

	
456 455
  /// This function just returns a \c SparseMap class created from an
457 456
  /// appropriate \c std::map.
458 457
  /// \relates SparseMap
459 458
  template<typename K, typename V, typename Compare>
460 459
  inline SparseMap<K, V, Compare>
461 460
    sparseMap(const std::map<K, V, Compare> &map, const V& value = V())
462 461
  {
463 462
    return SparseMap<K, V, Compare>(map, value);
464 463
  }
465 464

	
466 465
  /// @}
467 466

	
468 467
  /// \addtogroup map_adaptors
469 468
  /// @{
470 469

	
471 470
  /// Composition of two maps
472 471

	
473 472
  /// This \ref concepts::ReadMap "read-only map" returns the
474 473
  /// composition of two given maps. That is to say, if \c m1 is of
475 474
  /// type \c M1 and \c m2 is of \c M2, then for
476 475
  /// \code
477 476
  ///   ComposeMap<M1, M2> cm(m1,m2);
478 477
  /// \endcode
479 478
  /// <tt>cm[x]</tt> will be equal to <tt>m1[m2[x]]</tt>.
480 479
  ///
481 480
  /// The \c Key type of the map is inherited from \c M2 and the
482 481
  /// \c Value type is from \c M1.
483 482
  /// \c M2::Value must be convertible to \c M1::Key.
484 483
  ///
485 484
  /// The simplest way of using this map is through the composeMap()
486 485
  /// function.
487 486
  ///
488 487
  /// \sa CombineMap
489 488
  template <typename M1, typename M2>
490 489
  class ComposeMap : public MapBase<typename M2::Key, typename M1::Value> {
491 490
    const M1 &_m1;
492 491
    const M2 &_m2;
493 492
  public:
494 493
    ///\e
495 494
    typedef typename M2::Key Key;
496 495
    ///\e
497 496
    typedef typename M1::Value Value;
498 497

	
499 498
    /// Constructor
500 499
    ComposeMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
501 500

	
502 501
    ///\e
503 502
    typename MapTraits<M1>::ConstReturnValue
504 503
    operator[](const Key &k) const { return _m1[_m2[k]]; }
505 504
  };
506 505

	
507 506
  /// Returns a \c ComposeMap class
508 507

	
509 508
  /// This function just returns a \c ComposeMap class.
510 509
  ///
511 510
  /// If \c m1 and \c m2 are maps and the \c Value type of \c m2 is
512 511
  /// convertible to the \c Key of \c m1, then <tt>composeMap(m1,m2)[x]</tt>
513 512
  /// will be equal to <tt>m1[m2[x]]</tt>.
514 513
  ///
515 514
  /// \relates ComposeMap
516 515
  template <typename M1, typename M2>
517 516
  inline ComposeMap<M1, M2> composeMap(const M1 &m1, const M2 &m2) {
518 517
    return ComposeMap<M1, M2>(m1, m2);
519 518
  }
520 519

	
521 520

	
522 521
  /// Combination of two maps using an STL (binary) functor.
523 522

	
524 523
  /// This \ref concepts::ReadMap "read-only map" takes two maps and a
525 524
  /// binary functor and returns the combination of the two given maps
526 525
  /// using the functor.
527 526
  /// That is to say, if \c m1 is of type \c M1 and \c m2 is of \c M2
528 527
  /// and \c f is of \c F, then for
529 528
  /// \code
530 529
  ///   CombineMap<M1,M2,F,V> cm(m1,m2,f);
531 530
  /// \endcode
532 531
  /// <tt>cm[x]</tt> will be equal to <tt>f(m1[x],m2[x])</tt>.
533 532
  ///
534 533
  /// The \c Key type of the map is inherited from \c M1 (\c M1::Key
535 534
  /// must be convertible to \c M2::Key) and the \c Value type is \c V.
536 535
  /// \c M2::Value and \c M1::Value must be convertible to the
537 536
  /// corresponding input parameter of \c F and the return type of \c F
538 537
  /// must be convertible to \c V.
539 538
  ///
540 539
  /// The simplest way of using this map is through the combineMap()
541 540
  /// function.
542 541
  ///
543 542
  /// \sa ComposeMap
544 543
  template<typename M1, typename M2, typename F,
545 544
           typename V = typename F::result_type>
546 545
  class CombineMap : public MapBase<typename M1::Key, V> {
547 546
    const M1 &_m1;
548 547
    const M2 &_m2;
549 548
    F _f;
550 549
  public:
551 550
    ///\e
552 551
    typedef typename M1::Key Key;
553 552
    ///\e
554 553
    typedef V Value;
555 554

	
556 555
    /// Constructor
557 556
    CombineMap(const M1 &m1, const M2 &m2, const F &f = F())
558 557
      : _m1(m1), _m2(m2), _f(f) {}
559 558
    ///\e
560 559
    Value operator[](const Key &k) const { return _f(_m1[k],_m2[k]); }
561 560
  };
562 561

	
563 562
  /// Returns a \c CombineMap class
564 563

	
565 564
  /// This function just returns a \c CombineMap class.
566 565
  ///
567 566
  /// For example, if \c m1 and \c m2 are both maps with \c double
568 567
  /// values, then
569 568
  /// \code
570 569
  ///   combineMap(m1,m2,std::plus<double>())
571 570
  /// \endcode
572 571
  /// is equivalent to
573 572
  /// \code
574 573
  ///   addMap(m1,m2)
575 574
  /// \endcode
576 575
  ///
577 576
  /// This function is specialized for adaptable binary function
578 577
  /// classes and C++ functions.
579 578
  ///
580 579
  /// \relates CombineMap
581 580
  template<typename M1, typename M2, typename F, typename V>
582 581
  inline CombineMap<M1, M2, F, V>
583 582
  combineMap(const M1 &m1, const M2 &m2, const F &f) {
584 583
    return CombineMap<M1, M2, F, V>(m1,m2,f);
585 584
  }
586 585

	
587 586
  template<typename M1, typename M2, typename F>
588 587
  inline CombineMap<M1, M2, F, typename F::result_type>
589 588
  combineMap(const M1 &m1, const M2 &m2, const F &f) {
590 589
    return combineMap<M1, M2, F, typename F::result_type>(m1,m2,f);
591 590
  }
592 591

	
593 592
  template<typename M1, typename M2, typename K1, typename K2, typename V>
594 593
  inline CombineMap<M1, M2, V (*)(K1, K2), V>
595 594
  combineMap(const M1 &m1, const M2 &m2, V (*f)(K1, K2)) {
596 595
    return combineMap<M1, M2, V (*)(K1, K2), V>(m1,m2,f);
597 596
  }
598 597

	
599 598

	
600 599
  /// Converts an STL style (unary) functor to a map
601 600

	
602 601
  /// This \ref concepts::ReadMap "read-only map" returns the value
603 602
  /// of a given functor. Actually, it just wraps the functor and
604 603
  /// provides the \c Key and \c Value typedefs.
605 604
  ///
606 605
  /// Template parameters \c K and \c V will become its \c Key and
607 606
  /// \c Value. In most cases they have to be given explicitly because
608 607
  /// a functor typically does not provide \c argument_type and
609 608
  /// \c result_type typedefs.
610 609
  /// Parameter \c F is the type of the used functor.
611 610
  ///
612 611
  /// The simplest way of using this map is through the functorToMap()
613 612
  /// function.
614 613
  ///
615 614
  /// \sa MapToFunctor
616 615
  template<typename F,
617 616
           typename K = typename F::argument_type,
618 617
           typename V = typename F::result_type>
619 618
  class FunctorToMap : public MapBase<K, V> {
620 619
    F _f;
621 620
  public:
622 621
    ///\e
623 622
    typedef K Key;
624 623
    ///\e
625 624
    typedef V Value;
626 625

	
627 626
    /// Constructor
628 627
    FunctorToMap(const F &f = F()) : _f(f) {}
629 628
    ///\e
630 629
    Value operator[](const Key &k) const { return _f(k); }
631 630
  };
632 631

	
633 632
  /// Returns a \c FunctorToMap class
634 633

	
635 634
  /// This function just returns a \c FunctorToMap class.
636 635
  ///
637 636
  /// This function is specialized for adaptable binary function
638 637
  /// classes and C++ functions.
639 638
  ///
640 639
  /// \relates FunctorToMap
641 640
  template<typename K, typename V, typename F>
642 641
  inline FunctorToMap<F, K, V> functorToMap(const F &f) {
643 642
    return FunctorToMap<F, K, V>(f);
644 643
  }
645 644

	
646 645
  template <typename F>
647 646
  inline FunctorToMap<F, typename F::argument_type, typename F::result_type>
648 647
    functorToMap(const F &f)
649 648
  {
650 649
    return FunctorToMap<F, typename F::argument_type,
651 650
      typename F::result_type>(f);
652 651
  }
653 652

	
654 653
  template <typename K, typename V>
655 654
  inline FunctorToMap<V (*)(K), K, V> functorToMap(V (*f)(K)) {
656 655
    return FunctorToMap<V (*)(K), K, V>(f);
657 656
  }
658 657

	
659 658

	
660 659
  /// Converts a map to an STL style (unary) functor
661 660

	
662 661
  /// This class converts a map to an STL style (unary) functor.
663 662
  /// That is it provides an <tt>operator()</tt> to read its values.
664 663
  ///
665 664
  /// For the sake of convenience it also works as a usual
666 665
  /// \ref concepts::ReadMap "readable map", i.e. <tt>operator[]</tt>
667 666
  /// and the \c Key and \c Value typedefs also exist.
668 667
  ///
669 668
  /// The simplest way of using this map is through the mapToFunctor()
670 669
  /// function.
671 670
  ///
672 671
  ///\sa FunctorToMap
673 672
  template <typename M>
674 673
  class MapToFunctor : public MapBase<typename M::Key, typename M::Value> {
675 674
    const M &_m;
676 675
  public:
677 676
    ///\e
678 677
    typedef typename M::Key Key;
679 678
    ///\e
680 679
    typedef typename M::Value Value;
681 680

	
682 681
    typedef typename M::Key argument_type;
683 682
    typedef typename M::Value result_type;
684 683

	
685 684
    /// Constructor
686 685
    MapToFunctor(const M &m) : _m(m) {}
687 686
    ///\e
688 687
    Value operator()(const Key &k) const { return _m[k]; }
689 688
    ///\e
690 689
    Value operator[](const Key &k) const { return _m[k]; }
691 690
  };
692 691

	
693 692
  /// Returns a \c MapToFunctor class
694 693

	
695 694
  /// This function just returns a \c MapToFunctor class.
696 695
  /// \relates MapToFunctor
697 696
  template<typename M>
698 697
  inline MapToFunctor<M> mapToFunctor(const M &m) {
699 698
    return MapToFunctor<M>(m);
700 699
  }
701 700

	
702 701

	
703 702
  /// \brief Map adaptor to convert the \c Value type of a map to
704 703
  /// another type using the default conversion.
705 704

	
706 705
  /// Map adaptor to convert the \c Value type of a \ref concepts::ReadMap
707 706
  /// "readable map" to another type using the default conversion.
708 707
  /// The \c Key type of it is inherited from \c M and the \c Value
709 708
  /// type is \c V.
710
  /// This type conforms the \ref concepts::ReadMap "ReadMap" concept.
709
  /// This type conforms to the \ref concepts::ReadMap "ReadMap" concept.
711 710
  ///
712 711
  /// The simplest way of using this map is through the convertMap()
713 712
  /// function.
714 713
  template <typename M, typename V>
715 714
  class ConvertMap : public MapBase<typename M::Key, V> {
716 715
    const M &_m;
717 716
  public:
718 717
    ///\e
719 718
    typedef typename M::Key Key;
720 719
    ///\e
721 720
    typedef V Value;
722 721

	
723 722
    /// Constructor
724 723

	
725 724
    /// Constructor.
726 725
    /// \param m The underlying map.
727 726
    ConvertMap(const M &m) : _m(m) {}
728 727

	
729 728
    ///\e
730 729
    Value operator[](const Key &k) const { return _m[k]; }
731 730
  };
732 731

	
733 732
  /// Returns a \c ConvertMap class
734 733

	
735 734
  /// This function just returns a \c ConvertMap class.
736 735
  /// \relates ConvertMap
737 736
  template<typename V, typename M>
738 737
  inline ConvertMap<M, V> convertMap(const M &map) {
739 738
    return ConvertMap<M, V>(map);
740 739
  }
741 740

	
742 741

	
743 742
  /// Applies all map setting operations to two maps
744 743

	
745 744
  /// This map has two \ref concepts::WriteMap "writable map" parameters
746 745
  /// and each write request will be passed to both of them.
747 746
  /// If \c M1 is also \ref concepts::ReadMap "readable", then the read
748 747
  /// operations will return the corresponding values of \c M1.
749 748
  ///
750 749
  /// The \c Key and \c Value types are inherited from \c M1.
751 750
  /// The \c Key and \c Value of \c M2 must be convertible from those
752 751
  /// of \c M1.
753 752
  ///
754 753
  /// The simplest way of using this map is through the forkMap()
755 754
  /// function.
756 755
  template<typename  M1, typename M2>
757 756
  class ForkMap : public MapBase<typename M1::Key, typename M1::Value> {
758 757
    M1 &_m1;
759 758
    M2 &_m2;
760 759
  public:
761 760
    ///\e
762 761
    typedef typename M1::Key Key;
763 762
    ///\e
764 763
    typedef typename M1::Value Value;
765 764

	
766 765
    /// Constructor
767 766
    ForkMap(M1 &m1, M2 &m2) : _m1(m1), _m2(m2) {}
768 767
    /// Returns the value associated with the given key in the first map.
769 768
    Value operator[](const Key &k) const { return _m1[k]; }
770 769
    /// Sets the value associated with the given key in both maps.
771 770
    void set(const Key &k, const Value &v) { _m1.set(k,v); _m2.set(k,v); }
772 771
  };
773 772

	
774 773
  /// Returns a \c ForkMap class
775 774

	
776 775
  /// This function just returns a \c ForkMap class.
777 776
  /// \relates ForkMap
778 777
  template <typename M1, typename M2>
779 778
  inline ForkMap<M1,M2> forkMap(M1 &m1, M2 &m2) {
780 779
    return ForkMap<M1,M2>(m1,m2);
781 780
  }
782 781

	
783 782

	
784 783
  /// Sum of two maps
785 784

	
786 785
  /// This \ref concepts::ReadMap "read-only map" returns the sum
787 786
  /// of the values of the two given maps.
788 787
  /// Its \c Key and \c Value types are inherited from \c M1.
789 788
  /// The \c Key and \c Value of \c M2 must be convertible to those of
790 789
  /// \c M1.
791 790
  ///
792 791
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
793 792
  /// \code
794 793
  ///   AddMap<M1,M2> am(m1,m2);
795 794
  /// \endcode
796 795
  /// <tt>am[x]</tt> will be equal to <tt>m1[x]+m2[x]</tt>.
797 796
  ///
798 797
  /// The simplest way of using this map is through the addMap()
799 798
  /// function.
800 799
  ///
801 800
  /// \sa SubMap, MulMap, DivMap
802 801
  /// \sa ShiftMap, ShiftWriteMap
803 802
  template<typename M1, typename M2>
804 803
  class AddMap : public MapBase<typename M1::Key, typename M1::Value> {
805 804
    const M1 &_m1;
806 805
    const M2 &_m2;
807 806
  public:
808 807
    ///\e
809 808
    typedef typename M1::Key Key;
810 809
    ///\e
811 810
    typedef typename M1::Value Value;
812 811

	
813 812
    /// Constructor
814 813
    AddMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
815 814
    ///\e
816 815
    Value operator[](const Key &k) const { return _m1[k]+_m2[k]; }
817 816
  };
818 817

	
819 818
  /// Returns an \c AddMap class
820 819

	
821 820
  /// This function just returns an \c AddMap class.
822 821
  ///
823 822
  /// For example, if \c m1 and \c m2 are both maps with \c double
824 823
  /// values, then <tt>addMap(m1,m2)[x]</tt> will be equal to
825 824
  /// <tt>m1[x]+m2[x]</tt>.
826 825
  ///
827 826
  /// \relates AddMap
828 827
  template<typename M1, typename M2>
829 828
  inline AddMap<M1, M2> addMap(const M1 &m1, const M2 &m2) {
830 829
    return AddMap<M1, M2>(m1,m2);
831 830
  }
832 831

	
833 832

	
834 833
  /// Difference of two maps
835 834

	
836 835
  /// This \ref concepts::ReadMap "read-only map" returns the difference
837 836
  /// of the values of the two given maps.
838 837
  /// Its \c Key and \c Value types are inherited from \c M1.
839 838
  /// The \c Key and \c Value of \c M2 must be convertible to those of
840 839
  /// \c M1.
841 840
  ///
842 841
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
843 842
  /// \code
844 843
  ///   SubMap<M1,M2> sm(m1,m2);
845 844
  /// \endcode
846 845
  /// <tt>sm[x]</tt> will be equal to <tt>m1[x]-m2[x]</tt>.
847 846
  ///
848 847
  /// The simplest way of using this map is through the subMap()
849 848
  /// function.
850 849
  ///
851 850
  /// \sa AddMap, MulMap, DivMap
852 851
  template<typename M1, typename M2>
853 852
  class SubMap : public MapBase<typename M1::Key, typename M1::Value> {
854 853
    const M1 &_m1;
855 854
    const M2 &_m2;
856 855
  public:
857 856
    ///\e
858 857
    typedef typename M1::Key Key;
859 858
    ///\e
860 859
    typedef typename M1::Value Value;
861 860

	
862 861
    /// Constructor
863 862
    SubMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
864 863
    ///\e
865 864
    Value operator[](const Key &k) const { return _m1[k]-_m2[k]; }
866 865
  };
867 866

	
868 867
  /// Returns a \c SubMap class
869 868

	
870 869
  /// This function just returns a \c SubMap class.
871 870
  ///
872 871
  /// For example, if \c m1 and \c m2 are both maps with \c double
873 872
  /// values, then <tt>subMap(m1,m2)[x]</tt> will be equal to
874 873
  /// <tt>m1[x]-m2[x]</tt>.
875 874
  ///
876 875
  /// \relates SubMap
877 876
  template<typename M1, typename M2>
878 877
  inline SubMap<M1, M2> subMap(const M1 &m1, const M2 &m2) {
879 878
    return SubMap<M1, M2>(m1,m2);
880 879
  }
881 880

	
882 881

	
883 882
  /// Product of two maps
884 883

	
885 884
  /// This \ref concepts::ReadMap "read-only map" returns the product
886 885
  /// of the values of the two given maps.
887 886
  /// Its \c Key and \c Value types are inherited from \c M1.
888 887
  /// The \c Key and \c Value of \c M2 must be convertible to those of
889 888
  /// \c M1.
890 889
  ///
891 890
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
892 891
  /// \code
893 892
  ///   MulMap<M1,M2> mm(m1,m2);
894 893
  /// \endcode
895 894
  /// <tt>mm[x]</tt> will be equal to <tt>m1[x]*m2[x]</tt>.
896 895
  ///
897 896
  /// The simplest way of using this map is through the mulMap()
898 897
  /// function.
899 898
  ///
900 899
  /// \sa AddMap, SubMap, DivMap
901 900
  /// \sa ScaleMap, ScaleWriteMap
902 901
  template<typename M1, typename M2>
903 902
  class MulMap : public MapBase<typename M1::Key, typename M1::Value> {
904 903
    const M1 &_m1;
905 904
    const M2 &_m2;
906 905
  public:
907 906
    ///\e
908 907
    typedef typename M1::Key Key;
909 908
    ///\e
910 909
    typedef typename M1::Value Value;
911 910

	
912 911
    /// Constructor
913 912
    MulMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
914 913
    ///\e
915 914
    Value operator[](const Key &k) const { return _m1[k]*_m2[k]; }
916 915
  };
917 916

	
918 917
  /// Returns a \c MulMap class
919 918

	
920 919
  /// This function just returns a \c MulMap class.
921 920
  ///
922 921
  /// For example, if \c m1 and \c m2 are both maps with \c double
923 922
  /// values, then <tt>mulMap(m1,m2)[x]</tt> will be equal to
924 923
  /// <tt>m1[x]*m2[x]</tt>.
925 924
  ///
926 925
  /// \relates MulMap
927 926
  template<typename M1, typename M2>
928 927
  inline MulMap<M1, M2> mulMap(const M1 &m1,const M2 &m2) {
929 928
    return MulMap<M1, M2>(m1,m2);
930 929
  }
931 930

	
932 931

	
933 932
  /// Quotient of two maps
934 933

	
935 934
  /// This \ref concepts::ReadMap "read-only map" returns the quotient
936 935
  /// of the values of the two given maps.
937 936
  /// Its \c Key and \c Value types are inherited from \c M1.
938 937
  /// The \c Key and \c Value of \c M2 must be convertible to those of
939 938
  /// \c M1.
940 939
  ///
941 940
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
942 941
  /// \code
943 942
  ///   DivMap<M1,M2> dm(m1,m2);
944 943
  /// \endcode
945 944
  /// <tt>dm[x]</tt> will be equal to <tt>m1[x]/m2[x]</tt>.
946 945
  ///
947 946
  /// The simplest way of using this map is through the divMap()
948 947
  /// function.
949 948
  ///
950 949
  /// \sa AddMap, SubMap, MulMap
951 950
  template<typename M1, typename M2>
952 951
  class DivMap : public MapBase<typename M1::Key, typename M1::Value> {
953 952
    const M1 &_m1;
954 953
    const M2 &_m2;
955 954
  public:
956 955
    ///\e
957 956
    typedef typename M1::Key Key;
958 957
    ///\e
959 958
    typedef typename M1::Value Value;
960 959

	
961 960
    /// Constructor
962 961
    DivMap(const M1 &m1,const M2 &m2) : _m1(m1), _m2(m2) {}
963 962
    ///\e
964 963
    Value operator[](const Key &k) const { return _m1[k]/_m2[k]; }
965 964
  };
966 965

	
967 966
  /// Returns a \c DivMap class
968 967

	
969 968
  /// This function just returns a \c DivMap class.
970 969
  ///
971 970
  /// For example, if \c m1 and \c m2 are both maps with \c double
972 971
  /// values, then <tt>divMap(m1,m2)[x]</tt> will be equal to
973 972
  /// <tt>m1[x]/m2[x]</tt>.
974 973
  ///
975 974
  /// \relates DivMap
976 975
  template<typename M1, typename M2>
977 976
  inline DivMap<M1, M2> divMap(const M1 &m1,const M2 &m2) {
978 977
    return DivMap<M1, M2>(m1,m2);
979 978
  }
980 979

	
981 980

	
982 981
  /// Shifts a map with a constant.
983 982

	
984 983
  /// This \ref concepts::ReadMap "read-only map" returns the sum of
985 984
  /// the given map and a constant value (i.e. it shifts the map with
986 985
  /// the constant). Its \c Key and \c Value are inherited from \c M.
987 986
  ///
988 987
  /// Actually,
989 988
  /// \code
990 989
  ///   ShiftMap<M> sh(m,v);
991 990
  /// \endcode
992 991
  /// is equivalent to
993 992
  /// \code
994 993
  ///   ConstMap<M::Key, M::Value> cm(v);
995 994
  ///   AddMap<M, ConstMap<M::Key, M::Value> > sh(m,cm);
996 995
  /// \endcode
997 996
  ///
998 997
  /// The simplest way of using this map is through the shiftMap()
999 998
  /// function.
1000 999
  ///
1001 1000
  /// \sa ShiftWriteMap
1002 1001
  template<typename M, typename C = typename M::Value>
1003 1002
  class ShiftMap : public MapBase<typename M::Key, typename M::Value> {
1004 1003
    const M &_m;
1005 1004
    C _v;
1006 1005
  public:
1007 1006
    ///\e
1008 1007
    typedef typename M::Key Key;
1009 1008
    ///\e
1010 1009
    typedef typename M::Value Value;
1011 1010

	
1012 1011
    /// Constructor
1013 1012

	
1014 1013
    /// Constructor.
1015 1014
    /// \param m The undelying map.
1016 1015
    /// \param v The constant value.
1017 1016
    ShiftMap(const M &m, const C &v) : _m(m), _v(v) {}
1018 1017
    ///\e
1019 1018
    Value operator[](const Key &k) const { return _m[k]+_v; }
1020 1019
  };
1021 1020

	
1022 1021
  /// Shifts a map with a constant (read-write version).
1023 1022

	
1024 1023
  /// This \ref concepts::ReadWriteMap "read-write map" returns the sum
1025 1024
  /// of the given map and a constant value (i.e. it shifts the map with
1026 1025
  /// the constant). Its \c Key and \c Value are inherited from \c M.
1027 1026
  /// It makes also possible to write the map.
1028 1027
  ///
1029 1028
  /// The simplest way of using this map is through the shiftWriteMap()
1030 1029
  /// function.
1031 1030
  ///
1032 1031
  /// \sa ShiftMap
1033 1032
  template<typename M, typename C = typename M::Value>
1034 1033
  class ShiftWriteMap : public MapBase<typename M::Key, typename M::Value> {
1035 1034
    M &_m;
1036 1035
    C _v;
1037 1036
  public:
1038 1037
    ///\e
1039 1038
    typedef typename M::Key Key;
1040 1039
    ///\e
1041 1040
    typedef typename M::Value Value;
1042 1041

	
1043 1042
    /// Constructor
1044 1043

	
1045 1044
    /// Constructor.
1046 1045
    /// \param m The undelying map.
1047 1046
    /// \param v The constant value.
1048 1047
    ShiftWriteMap(M &m, const C &v) : _m(m), _v(v) {}
1049 1048
    ///\e
1050 1049
    Value operator[](const Key &k) const { return _m[k]+_v; }
1051 1050
    ///\e
1052 1051
    void set(const Key &k, const Value &v) { _m.set(k, v-_v); }
1053 1052
  };
1054 1053

	
1055 1054
  /// Returns a \c ShiftMap class
1056 1055

	
1057 1056
  /// This function just returns a \c ShiftMap class.
1058 1057
  ///
1059 1058
  /// For example, if \c m is a map with \c double values and \c v is
1060 1059
  /// \c double, then <tt>shiftMap(m,v)[x]</tt> will be equal to
1061 1060
  /// <tt>m[x]+v</tt>.
1062 1061
  ///
1063 1062
  /// \relates ShiftMap
1064 1063
  template<typename M, typename C>
1065 1064
  inline ShiftMap<M, C> shiftMap(const M &m, const C &v) {
1066 1065
    return ShiftMap<M, C>(m,v);
1067 1066
  }
1068 1067

	
1069 1068
  /// Returns a \c ShiftWriteMap class
1070 1069

	
1071 1070
  /// This function just returns a \c ShiftWriteMap class.
1072 1071
  ///
1073 1072
  /// For example, if \c m is a map with \c double values and \c v is
1074 1073
  /// \c double, then <tt>shiftWriteMap(m,v)[x]</tt> will be equal to
1075 1074
  /// <tt>m[x]+v</tt>.
1076 1075
  /// Moreover it makes also possible to write the map.
1077 1076
  ///
1078 1077
  /// \relates ShiftWriteMap
1079 1078
  template<typename M, typename C>
1080 1079
  inline ShiftWriteMap<M, C> shiftWriteMap(M &m, const C &v) {
1081 1080
    return ShiftWriteMap<M, C>(m,v);
1082 1081
  }
1083 1082

	
1084 1083

	
1085 1084
  /// Scales a map with a constant.
1086 1085

	
1087 1086
  /// This \ref concepts::ReadMap "read-only map" returns the value of
1088 1087
  /// the given map multiplied from the left side with a constant value.
1089 1088
  /// Its \c Key and \c Value are inherited from \c M.
1090 1089
  ///
1091 1090
  /// Actually,
1092 1091
  /// \code
1093 1092
  ///   ScaleMap<M> sc(m,v);
1094 1093
  /// \endcode
1095 1094
  /// is equivalent to
1096 1095
  /// \code
1097 1096
  ///   ConstMap<M::Key, M::Value> cm(v);
1098 1097
  ///   MulMap<ConstMap<M::Key, M::Value>, M> sc(cm,m);
1099 1098
  /// \endcode
1100 1099
  ///
1101 1100
  /// The simplest way of using this map is through the scaleMap()
1102 1101
  /// function.
1103 1102
  ///
1104 1103
  /// \sa ScaleWriteMap
1105 1104
  template<typename M, typename C = typename M::Value>
1106 1105
  class ScaleMap : public MapBase<typename M::Key, typename M::Value> {
1107 1106
    const M &_m;
1108 1107
    C _v;
1109 1108
  public:
1110 1109
    ///\e
1111 1110
    typedef typename M::Key Key;
1112 1111
    ///\e
1113 1112
    typedef typename M::Value Value;
1114 1113

	
1115 1114
    /// Constructor
1116 1115

	
1117 1116
    /// Constructor.
1118 1117
    /// \param m The undelying map.
1119 1118
    /// \param v The constant value.
1120 1119
    ScaleMap(const M &m, const C &v) : _m(m), _v(v) {}
1121 1120
    ///\e
1122 1121
    Value operator[](const Key &k) const { return _v*_m[k]; }
1123 1122
  };
1124 1123

	
1125 1124
  /// Scales a map with a constant (read-write version).
1126 1125

	
1127 1126
  /// This \ref concepts::ReadWriteMap "read-write map" returns the value of
1128 1127
  /// the given map multiplied from the left side with a constant value.
1129 1128
  /// Its \c Key and \c Value are inherited from \c M.
1130 1129
  /// It can also be used as write map if the \c / operator is defined
1131 1130
  /// between \c Value and \c C and the given multiplier is not zero.
1132 1131
  ///
1133 1132
  /// The simplest way of using this map is through the scaleWriteMap()
1134 1133
  /// function.
1135 1134
  ///
1136 1135
  /// \sa ScaleMap
1137 1136
  template<typename M, typename C = typename M::Value>
1138 1137
  class ScaleWriteMap : public MapBase<typename M::Key, typename M::Value> {
1139 1138
    M &_m;
1140 1139
    C _v;
1141 1140
  public:
1142 1141
    ///\e
1143 1142
    typedef typename M::Key Key;
1144 1143
    ///\e
1145 1144
    typedef typename M::Value Value;
1146 1145

	
1147 1146
    /// Constructor
1148 1147

	
1149 1148
    /// Constructor.
1150 1149
    /// \param m The undelying map.
1151 1150
    /// \param v The constant value.
1152 1151
    ScaleWriteMap(M &m, const C &v) : _m(m), _v(v) {}
1153 1152
    ///\e
1154 1153
    Value operator[](const Key &k) const { return _v*_m[k]; }
1155 1154
    ///\e
1156 1155
    void set(const Key &k, const Value &v) { _m.set(k, v/_v); }
1157 1156
  };
1158 1157

	
1159 1158
  /// Returns a \c ScaleMap class
1160 1159

	
1161 1160
  /// This function just returns a \c ScaleMap class.
1162 1161
  ///
1163 1162
  /// For example, if \c m is a map with \c double values and \c v is
1164 1163
  /// \c double, then <tt>scaleMap(m,v)[x]</tt> will be equal to
1165 1164
  /// <tt>v*m[x]</tt>.
1166 1165
  ///
1167 1166
  /// \relates ScaleMap
1168 1167
  template<typename M, typename C>
1169 1168
  inline ScaleMap<M, C> scaleMap(const M &m, const C &v) {
1170 1169
    return ScaleMap<M, C>(m,v);
1171 1170
  }
1172 1171

	
1173 1172
  /// Returns a \c ScaleWriteMap class
1174 1173

	
1175 1174
  /// This function just returns a \c ScaleWriteMap class.
1176 1175
  ///
1177 1176
  /// For example, if \c m is a map with \c double values and \c v is
1178 1177
  /// \c double, then <tt>scaleWriteMap(m,v)[x]</tt> will be equal to
1179 1178
  /// <tt>v*m[x]</tt>.
1180 1179
  /// Moreover it makes also possible to write the map.
1181 1180
  ///
1182 1181
  /// \relates ScaleWriteMap
1183 1182
  template<typename M, typename C>
1184 1183
  inline ScaleWriteMap<M, C> scaleWriteMap(M &m, const C &v) {
1185 1184
    return ScaleWriteMap<M, C>(m,v);
1186 1185
  }
1187 1186

	
1188 1187

	
1189 1188
  /// Negative of a map
1190 1189

	
1191 1190
  /// This \ref concepts::ReadMap "read-only map" returns the negative
1192 1191
  /// of the values of the given map (using the unary \c - operator).
1193 1192
  /// Its \c Key and \c Value are inherited from \c M.
1194 1193
  ///
1195 1194
  /// If M::Value is \c int, \c double etc., then
1196 1195
  /// \code
1197 1196
  ///   NegMap<M> neg(m);
1198 1197
  /// \endcode
1199 1198
  /// is equivalent to
1200 1199
  /// \code
1201 1200
  ///   ScaleMap<M> neg(m,-1);
1202 1201
  /// \endcode
1203 1202
  ///
1204 1203
  /// The simplest way of using this map is through the negMap()
1205 1204
  /// function.
1206 1205
  ///
1207 1206
  /// \sa NegWriteMap
1208 1207
  template<typename M>
1209 1208
  class NegMap : public MapBase<typename M::Key, typename M::Value> {
1210 1209
    const M& _m;
1211 1210
  public:
1212 1211
    ///\e
1213 1212
    typedef typename M::Key Key;
1214 1213
    ///\e
1215 1214
    typedef typename M::Value Value;
1216 1215

	
1217 1216
    /// Constructor
1218 1217
    NegMap(const M &m) : _m(m) {}
1219 1218
    ///\e
1220 1219
    Value operator[](const Key &k) const { return -_m[k]; }
1221 1220
  };
1222 1221

	
1223 1222
  /// Negative of a map (read-write version)
1224 1223

	
1225 1224
  /// This \ref concepts::ReadWriteMap "read-write map" returns the
1226 1225
  /// negative of the values of the given map (using the unary \c -
1227 1226
  /// operator).
1228 1227
  /// Its \c Key and \c Value are inherited from \c M.
1229 1228
  /// It makes also possible to write the map.
1230 1229
  ///
1231 1230
  /// If M::Value is \c int, \c double etc., then
1232 1231
  /// \code
1233 1232
  ///   NegWriteMap<M> neg(m);
1234 1233
  /// \endcode
1235 1234
  /// is equivalent to
1236 1235
  /// \code
1237 1236
  ///   ScaleWriteMap<M> neg(m,-1);
1238 1237
  /// \endcode
1239 1238
  ///
1240 1239
  /// The simplest way of using this map is through the negWriteMap()
1241 1240
  /// function.
1242 1241
  ///
1243 1242
  /// \sa NegMap
1244 1243
  template<typename M>
1245 1244
  class NegWriteMap : public MapBase<typename M::Key, typename M::Value> {
1246 1245
    M &_m;
1247 1246
  public:
1248 1247
    ///\e
1249 1248
    typedef typename M::Key Key;
1250 1249
    ///\e
1251 1250
    typedef typename M::Value Value;
1252 1251

	
1253 1252
    /// Constructor
1254 1253
    NegWriteMap(M &m) : _m(m) {}
1255 1254
    ///\e
1256 1255
    Value operator[](const Key &k) const { return -_m[k]; }
1257 1256
    ///\e
1258 1257
    void set(const Key &k, const Value &v) { _m.set(k, -v); }
1259 1258
  };
1260 1259

	
1261 1260
  /// Returns a \c NegMap class
1262 1261

	
1263 1262
  /// This function just returns a \c NegMap class.
1264 1263
  ///
1265 1264
  /// For example, if \c m is a map with \c double values, then
1266 1265
  /// <tt>negMap(m)[x]</tt> will be equal to <tt>-m[x]</tt>.
1267 1266
  ///
1268 1267
  /// \relates NegMap
1269 1268
  template <typename M>
1270 1269
  inline NegMap<M> negMap(const M &m) {
1271 1270
    return NegMap<M>(m);
1272 1271
  }
1273 1272

	
1274 1273
  /// Returns a \c NegWriteMap class
1275 1274

	
1276 1275
  /// This function just returns a \c NegWriteMap class.
1277 1276
  ///
1278 1277
  /// For example, if \c m is a map with \c double values, then
1279 1278
  /// <tt>negWriteMap(m)[x]</tt> will be equal to <tt>-m[x]</tt>.
1280 1279
  /// Moreover it makes also possible to write the map.
1281 1280
  ///
1282 1281
  /// \relates NegWriteMap
1283 1282
  template <typename M>
1284 1283
  inline NegWriteMap<M> negWriteMap(M &m) {
1285 1284
    return NegWriteMap<M>(m);
1286 1285
  }
1287 1286

	
1288 1287

	
1289 1288
  /// Absolute value of a map
1290 1289

	
1291 1290
  /// This \ref concepts::ReadMap "read-only map" returns the absolute
1292 1291
  /// value of the values of the given map.
1293 1292
  /// Its \c Key and \c Value are inherited from \c M.
1294 1293
  /// \c Value must be comparable to \c 0 and the unary \c -
1295 1294
  /// operator must be defined for it, of course.
1296 1295
  ///
1297 1296
  /// The simplest way of using this map is through the absMap()
1298 1297
  /// function.
1299 1298
  template<typename M>
1300 1299
  class AbsMap : public MapBase<typename M::Key, typename M::Value> {
1301 1300
    const M &_m;
1302 1301
  public:
1303 1302
    ///\e
1304 1303
    typedef typename M::Key Key;
1305 1304
    ///\e
1306 1305
    typedef typename M::Value Value;
1307 1306

	
1308 1307
    /// Constructor
1309 1308
    AbsMap(const M &m) : _m(m) {}
1310 1309
    ///\e
1311 1310
    Value operator[](const Key &k) const {
1312 1311
      Value tmp = _m[k];
1313 1312
      return tmp >= 0 ? tmp : -tmp;
1314 1313
    }
1315 1314

	
1316 1315
  };
1317 1316

	
1318 1317
  /// Returns an \c AbsMap class
1319 1318

	
1320 1319
  /// This function just returns an \c AbsMap class.
1321 1320
  ///
1322 1321
  /// For example, if \c m is a map with \c double values, then
1323 1322
  /// <tt>absMap(m)[x]</tt> will be equal to <tt>m[x]</tt> if
1324 1323
  /// it is positive or zero and <tt>-m[x]</tt> if <tt>m[x]</tt> is
1325 1324
  /// negative.
1326 1325
  ///
1327 1326
  /// \relates AbsMap
1328 1327
  template<typename M>
1329 1328
  inline AbsMap<M> absMap(const M &m) {
1330 1329
    return AbsMap<M>(m);
1331 1330
  }
1332 1331

	
1333 1332
  /// @}
1334 1333

	
1335 1334
  // Logical maps and map adaptors:
1336 1335

	
1337 1336
  /// \addtogroup maps
1338 1337
  /// @{
1339 1338

	
1340 1339
  /// Constant \c true map.
1341 1340

	
1342 1341
  /// This \ref concepts::ReadMap "read-only map" assigns \c true to
1343 1342
  /// each key.
1344 1343
  ///
1345 1344
  /// Note that
1346 1345
  /// \code
1347 1346
  ///   TrueMap<K> tm;
1348 1347
  /// \endcode
1349 1348
  /// is equivalent to
1350 1349
  /// \code
1351 1350
  ///   ConstMap<K,bool> tm(true);
1352 1351
  /// \endcode
1353 1352
  ///
1354 1353
  /// \sa FalseMap
1355 1354
  /// \sa ConstMap
1356 1355
  template <typename K>
1357 1356
  class TrueMap : public MapBase<K, bool> {
1358 1357
  public:
1359 1358
    ///\e
1360 1359
    typedef K Key;
1361 1360
    ///\e
1362 1361
    typedef bool Value;
1363 1362

	
1364 1363
    /// Gives back \c true.
1365 1364
    Value operator[](const Key&) const { return true; }
1366 1365
  };
1367 1366

	
1368 1367
  /// Returns a \c TrueMap class
1369 1368

	
1370 1369
  /// This function just returns a \c TrueMap class.
1371 1370
  /// \relates TrueMap
1372 1371
  template<typename K>
1373 1372
  inline TrueMap<K> trueMap() {
1374 1373
    return TrueMap<K>();
1375 1374
  }
1376 1375

	
1377 1376

	
1378 1377
  /// Constant \c false map.
1379 1378

	
1380 1379
  /// This \ref concepts::ReadMap "read-only map" assigns \c false to
1381 1380
  /// each key.
1382 1381
  ///
1383 1382
  /// Note that
1384 1383
  /// \code
1385 1384
  ///   FalseMap<K> fm;
1386 1385
  /// \endcode
1387 1386
  /// is equivalent to
1388 1387
  /// \code
1389 1388
  ///   ConstMap<K,bool> fm(false);
1390 1389
  /// \endcode
1391 1390
  ///
1392 1391
  /// \sa TrueMap
1393 1392
  /// \sa ConstMap
1394 1393
  template <typename K>
1395 1394
  class FalseMap : public MapBase<K, bool> {
1396 1395
  public:
1397 1396
    ///\e
1398 1397
    typedef K Key;
1399 1398
    ///\e
1400 1399
    typedef bool Value;
1401 1400

	
1402 1401
    /// Gives back \c false.
1403 1402
    Value operator[](const Key&) const { return false; }
1404 1403
  };
1405 1404

	
1406 1405
  /// Returns a \c FalseMap class
1407 1406

	
1408 1407
  /// This function just returns a \c FalseMap class.
1409 1408
  /// \relates FalseMap
1410 1409
  template<typename K>
1411 1410
  inline FalseMap<K> falseMap() {
1412 1411
    return FalseMap<K>();
1413 1412
  }
1414 1413

	
1415 1414
  /// @}
1416 1415

	
1417 1416
  /// \addtogroup map_adaptors
1418 1417
  /// @{
1419 1418

	
1420 1419
  /// Logical 'and' of two maps
1421 1420

	
1422 1421
  /// This \ref concepts::ReadMap "read-only map" returns the logical
1423 1422
  /// 'and' of the values of the two given maps.
1424 1423
  /// Its \c Key type is inherited from \c M1 and its \c Value type is
1425 1424
  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
1426 1425
  ///
1427 1426
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
1428 1427
  /// \code
1429 1428
  ///   AndMap<M1,M2> am(m1,m2);
1430 1429
  /// \endcode
1431 1430
  /// <tt>am[x]</tt> will be equal to <tt>m1[x]&&m2[x]</tt>.
1432 1431
  ///
1433 1432
  /// The simplest way of using this map is through the andMap()
1434 1433
  /// function.
1435 1434
  ///
1436 1435
  /// \sa OrMap
1437 1436
  /// \sa NotMap, NotWriteMap
1438 1437
  template<typename M1, typename M2>
1439 1438
  class AndMap : public MapBase<typename M1::Key, bool> {
1440 1439
    const M1 &_m1;
1441 1440
    const M2 &_m2;
1442 1441
  public:
1443 1442
    ///\e
1444 1443
    typedef typename M1::Key Key;
1445 1444
    ///\e
1446 1445
    typedef bool Value;
1447 1446

	
1448 1447
    /// Constructor
1449 1448
    AndMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
1450 1449
    ///\e
1451 1450
    Value operator[](const Key &k) const { return _m1[k]&&_m2[k]; }
1452 1451
  };
1453 1452

	
1454 1453
  /// Returns an \c AndMap class
1455 1454

	
1456 1455
  /// This function just returns an \c AndMap class.
1457 1456
  ///
1458 1457
  /// For example, if \c m1 and \c m2 are both maps with \c bool values,
1459 1458
  /// then <tt>andMap(m1,m2)[x]</tt> will be equal to
1460 1459
  /// <tt>m1[x]&&m2[x]</tt>.
1461 1460
  ///
1462 1461
  /// \relates AndMap
1463 1462
  template<typename M1, typename M2>
1464 1463
  inline AndMap<M1, M2> andMap(const M1 &m1, const M2 &m2) {
1465 1464
    return AndMap<M1, M2>(m1,m2);
1466 1465
  }
1467 1466

	
1468 1467

	
1469 1468
  /// Logical 'or' of two maps
1470 1469

	
1471 1470
  /// This \ref concepts::ReadMap "read-only map" returns the logical
1472 1471
  /// 'or' of the values of the two given maps.
1473 1472
  /// Its \c Key type is inherited from \c M1 and its \c Value type is
1474 1473
  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
1475 1474
  ///
1476 1475
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
1477 1476
  /// \code
1478 1477
  ///   OrMap<M1,M2> om(m1,m2);
1479 1478
  /// \endcode
1480 1479
  /// <tt>om[x]</tt> will be equal to <tt>m1[x]||m2[x]</tt>.
1481 1480
  ///
1482 1481
  /// The simplest way of using this map is through the orMap()
1483 1482
  /// function.
1484 1483
  ///
1485 1484
  /// \sa AndMap
1486 1485
  /// \sa NotMap, NotWriteMap
1487 1486
  template<typename M1, typename M2>
1488 1487
  class OrMap : public MapBase<typename M1::Key, bool> {
1489 1488
    const M1 &_m1;
1490 1489
    const M2 &_m2;
1491 1490
  public:
1492 1491
    ///\e
1493 1492
    typedef typename M1::Key Key;
1494 1493
    ///\e
1495 1494
    typedef bool Value;
1496 1495

	
1497 1496
    /// Constructor
1498 1497
    OrMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
1499 1498
    ///\e
1500 1499
    Value operator[](const Key &k) const { return _m1[k]||_m2[k]; }
1501 1500
  };
1502 1501

	
1503 1502
  /// Returns an \c OrMap class
1504 1503

	
1505 1504
  /// This function just returns an \c OrMap class.
1506 1505
  ///
1507 1506
  /// For example, if \c m1 and \c m2 are both maps with \c bool values,
1508 1507
  /// then <tt>orMap(m1,m2)[x]</tt> will be equal to
1509 1508
  /// <tt>m1[x]||m2[x]</tt>.
1510 1509
  ///
1511 1510
  /// \relates OrMap
1512 1511
  template<typename M1, typename M2>
1513 1512
  inline OrMap<M1, M2> orMap(const M1 &m1, const M2 &m2) {
1514 1513
    return OrMap<M1, M2>(m1,m2);
1515 1514
  }
1516 1515

	
1517 1516

	
1518 1517
  /// Logical 'not' of a map
1519 1518

	
1520 1519
  /// This \ref concepts::ReadMap "read-only map" returns the logical
1521 1520
  /// negation of the values of the given map.
1522 1521
  /// Its \c Key is inherited from \c M and its \c Value is \c bool.
1523 1522
  ///
1524 1523
  /// The simplest way of using this map is through the notMap()
1525 1524
  /// function.
1526 1525
  ///
1527 1526
  /// \sa NotWriteMap
1528 1527
  template <typename M>
1529 1528
  class NotMap : public MapBase<typename M::Key, bool> {
1530 1529
    const M &_m;
1531 1530
  public:
1532 1531
    ///\e
1533 1532
    typedef typename M::Key Key;
1534 1533
    ///\e
1535 1534
    typedef bool Value;
1536 1535

	
1537 1536
    /// Constructor
1538 1537
    NotMap(const M &m) : _m(m) {}
1539 1538
    ///\e
1540 1539
    Value operator[](const Key &k) const { return !_m[k]; }
1541 1540
  };
1542 1541

	
1543 1542
  /// Logical 'not' of a map (read-write version)
1544 1543

	
1545 1544
  /// This \ref concepts::ReadWriteMap "read-write map" returns the
1546 1545
  /// logical negation of the values of the given map.
1547 1546
  /// Its \c Key is inherited from \c M and its \c Value is \c bool.
1548 1547
  /// It makes also possible to write the map. When a value is set,
1549 1548
  /// the opposite value is set to the original map.
1550 1549
  ///
1551 1550
  /// The simplest way of using this map is through the notWriteMap()
1552 1551
  /// function.
1553 1552
  ///
1554 1553
  /// \sa NotMap
1555 1554
  template <typename M>
1556 1555
  class NotWriteMap : public MapBase<typename M::Key, bool> {
1557 1556
    M &_m;
1558 1557
  public:
1559 1558
    ///\e
1560 1559
    typedef typename M::Key Key;
1561 1560
    ///\e
1562 1561
    typedef bool Value;
1563 1562

	
1564 1563
    /// Constructor
1565 1564
    NotWriteMap(M &m) : _m(m) {}
1566 1565
    ///\e
1567 1566
    Value operator[](const Key &k) const { return !_m[k]; }
1568 1567
    ///\e
1569 1568
    void set(const Key &k, bool v) { _m.set(k, !v); }
1570 1569
  };
1571 1570

	
1572 1571
  /// Returns a \c NotMap class
1573 1572

	
1574 1573
  /// This function just returns a \c NotMap class.
1575 1574
  ///
1576 1575
  /// For example, if \c m is a map with \c bool values, then
1577 1576
  /// <tt>notMap(m)[x]</tt> will be equal to <tt>!m[x]</tt>.
1578 1577
  ///
1579 1578
  /// \relates NotMap
1580 1579
  template <typename M>
1581 1580
  inline NotMap<M> notMap(const M &m) {
1582 1581
    return NotMap<M>(m);
1583 1582
  }
1584 1583

	
1585 1584
  /// Returns a \c NotWriteMap class
1586 1585

	
1587 1586
  /// This function just returns a \c NotWriteMap class.
1588 1587
  ///
1589 1588
  /// For example, if \c m is a map with \c bool values, then
1590 1589
  /// <tt>notWriteMap(m)[x]</tt> will be equal to <tt>!m[x]</tt>.
1591 1590
  /// Moreover it makes also possible to write the map.
1592 1591
  ///
1593 1592
  /// \relates NotWriteMap
1594 1593
  template <typename M>
1595 1594
  inline NotWriteMap<M> notWriteMap(M &m) {
1596 1595
    return NotWriteMap<M>(m);
1597 1596
  }
1598 1597

	
1599 1598

	
1600 1599
  /// Combination of two maps using the \c == operator
1601 1600

	
1602 1601
  /// This \ref concepts::ReadMap "read-only map" assigns \c true to
1603 1602
  /// the keys for which the corresponding values of the two maps are
1604 1603
  /// equal.
1605 1604
  /// Its \c Key type is inherited from \c M1 and its \c Value type is
1606 1605
  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
1607 1606
  ///
1608 1607
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
1609 1608
  /// \code
1610 1609
  ///   EqualMap<M1,M2> em(m1,m2);
1611 1610
  /// \endcode
1612 1611
  /// <tt>em[x]</tt> will be equal to <tt>m1[x]==m2[x]</tt>.
1613 1612
  ///
1614 1613
  /// The simplest way of using this map is through the equalMap()
1615 1614
  /// function.
1616 1615
  ///
1617 1616
  /// \sa LessMap
1618 1617
  template<typename M1, typename M2>
1619 1618
  class EqualMap : public MapBase<typename M1::Key, bool> {
1620 1619
    const M1 &_m1;
1621 1620
    const M2 &_m2;
1622 1621
  public:
1623 1622
    ///\e
1624 1623
    typedef typename M1::Key Key;
1625 1624
    ///\e
1626 1625
    typedef bool Value;
1627 1626

	
1628 1627
    /// Constructor
1629 1628
    EqualMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
1630 1629
    ///\e
1631 1630
    Value operator[](const Key &k) const { return _m1[k]==_m2[k]; }
1632 1631
  };
1633 1632

	
1634 1633
  /// Returns an \c EqualMap class
1635 1634

	
1636 1635
  /// This function just returns an \c EqualMap class.
1637 1636
  ///
1638 1637
  /// For example, if \c m1 and \c m2 are maps with keys and values of
1639 1638
  /// the same type, then <tt>equalMap(m1,m2)[x]</tt> will be equal to
1640 1639
  /// <tt>m1[x]==m2[x]</tt>.
1641 1640
  ///
1642 1641
  /// \relates EqualMap
1643 1642
  template<typename M1, typename M2>
1644 1643
  inline EqualMap<M1, M2> equalMap(const M1 &m1, const M2 &m2) {
1645 1644
    return EqualMap<M1, M2>(m1,m2);
1646 1645
  }
1647 1646

	
1648 1647

	
1649 1648
  /// Combination of two maps using the \c < operator
1650 1649

	
1651 1650
  /// This \ref concepts::ReadMap "read-only map" assigns \c true to
1652 1651
  /// the keys for which the corresponding value of the first map is
1653 1652
  /// less then the value of the second map.
1654 1653
  /// Its \c Key type is inherited from \c M1 and its \c Value type is
1655 1654
  /// \c bool. \c M2::Key must be convertible to \c M1::Key.
1656 1655
  ///
1657 1656
  /// If \c m1 is of type \c M1 and \c m2 is of \c M2, then for
1658 1657
  /// \code
1659 1658
  ///   LessMap<M1,M2> lm(m1,m2);
1660 1659
  /// \endcode
1661 1660
  /// <tt>lm[x]</tt> will be equal to <tt>m1[x]<m2[x]</tt>.
1662 1661
  ///
1663 1662
  /// The simplest way of using this map is through the lessMap()
1664 1663
  /// function.
1665 1664
  ///
1666 1665
  /// \sa EqualMap
1667 1666
  template<typename M1, typename M2>
1668 1667
  class LessMap : public MapBase<typename M1::Key, bool> {
1669 1668
    const M1 &_m1;
1670 1669
    const M2 &_m2;
1671 1670
  public:
1672 1671
    ///\e
1673 1672
    typedef typename M1::Key Key;
1674 1673
    ///\e
1675 1674
    typedef bool Value;
1676 1675

	
1677 1676
    /// Constructor
1678 1677
    LessMap(const M1 &m1, const M2 &m2) : _m1(m1), _m2(m2) {}
1679 1678
    ///\e
1680 1679
    Value operator[](const Key &k) const { return _m1[k]<_m2[k]; }
1681 1680
  };
1682 1681

	
1683 1682
  /// Returns an \c LessMap class
1684 1683

	
1685 1684
  /// This function just returns an \c LessMap class.
1686 1685
  ///
1687 1686
  /// For example, if \c m1 and \c m2 are maps with keys and values of
1688 1687
  /// the same type, then <tt>lessMap(m1,m2)[x]</tt> will be equal to
1689 1688
  /// <tt>m1[x]<m2[x]</tt>.
1690 1689
  ///
1691 1690
  /// \relates LessMap
1692 1691
  template<typename M1, typename M2>
1693 1692
  inline LessMap<M1, M2> lessMap(const M1 &m1, const M2 &m2) {
1694 1693
    return LessMap<M1, M2>(m1,m2);
1695 1694
  }
1696 1695

	
1697 1696
  namespace _maps_bits {
1698 1697

	
1699 1698
    template <typename _Iterator, typename Enable = void>
1700 1699
    struct IteratorTraits {
1701 1700
      typedef typename std::iterator_traits<_Iterator>::value_type Value;
1702 1701
    };
1703 1702

	
1704 1703
    template <typename _Iterator>
1705 1704
    struct IteratorTraits<_Iterator,
1706 1705
      typename exists<typename _Iterator::container_type>::type>
1707 1706
    {
1708 1707
      typedef typename _Iterator::container_type::value_type Value;
1709 1708
    };
1710 1709

	
1711 1710
  }
1712 1711

	
1713 1712
  /// @}
1714 1713

	
1715 1714
  /// \addtogroup maps
1716 1715
  /// @{
1717 1716

	
1718 1717
  /// \brief Writable bool map for logging each \c true assigned element
1719 1718
  ///
1720 1719
  /// A \ref concepts::WriteMap "writable" bool map for logging
1721 1720
  /// each \c true assigned element, i.e it copies subsequently each
1722 1721
  /// keys set to \c true to the given iterator.
1723 1722
  /// The most important usage of it is storing certain nodes or arcs
1724 1723
  /// that were marked \c true by an algorithm.
1725 1724
  ///
1726 1725
  /// There are several algorithms that provide solutions through bool
1727 1726
  /// maps and most of them assign \c true at most once for each key.
1728 1727
  /// In these cases it is a natural request to store each \c true
1729 1728
  /// assigned elements (in order of the assignment), which can be
1730 1729
  /// easily done with LoggerBoolMap.
1731 1730
  ///
1732 1731
  /// The simplest way of using this map is through the loggerBoolMap()
1733 1732
  /// function.
1734 1733
  ///
1735 1734
  /// \tparam IT The type of the iterator.
1736 1735
  /// \tparam KEY The key type of the map. The default value set
1737 1736
  /// according to the iterator type should work in most cases.
1738 1737
  ///
1739 1738
  /// \note The container of the iterator must contain enough space
1740 1739
  /// for the elements or the iterator should be an inserter iterator.
1741 1740
#ifdef DOXYGEN
1742 1741
  template <typename IT, typename KEY>
1743 1742
#else
1744 1743
  template <typename IT,
1745 1744
            typename KEY = typename _maps_bits::IteratorTraits<IT>::Value>
1746 1745
#endif
1747 1746
  class LoggerBoolMap : public MapBase<KEY, bool> {
1748 1747
  public:
1749 1748

	
1750 1749
    ///\e
1751 1750
    typedef KEY Key;
1752 1751
    ///\e
1753 1752
    typedef bool Value;
1754 1753
    ///\e
1755 1754
    typedef IT Iterator;
1756 1755

	
1757 1756
    /// Constructor
1758 1757
    LoggerBoolMap(Iterator it)
1759 1758
      : _begin(it), _end(it) {}
1760 1759

	
1761 1760
    /// Gives back the given iterator set for the first key
1762 1761
    Iterator begin() const {
1763 1762
      return _begin;
1764 1763
    }
1765 1764

	
1766 1765
    /// Gives back the the 'after the last' iterator
1767 1766
    Iterator end() const {
1768 1767
      return _end;
1769 1768
    }
1770 1769

	
1771 1770
    /// The set function of the map
1772 1771
    void set(const Key& key, Value value) {
1773 1772
      if (value) {
1774 1773
        *_end++ = key;
1775 1774
      }
1776 1775
    }
1777 1776

	
1778 1777
  private:
1779 1778
    Iterator _begin;
1780 1779
    Iterator _end;
1781 1780
  };
1782 1781

	
1783 1782
  /// Returns a \c LoggerBoolMap class
1784 1783

	
1785 1784
  /// This function just returns a \c LoggerBoolMap class.
1786 1785
  ///
1787 1786
  /// The most important usage of it is storing certain nodes or arcs
1788 1787
  /// that were marked \c true by an algorithm.
1789
  /// For example it makes easier to store the nodes in the processing
1788
  /// For example, it makes easier to store the nodes in the processing
1790 1789
  /// order of Dfs algorithm, as the following examples show.
1791 1790
  /// \code
1792 1791
  ///   std::vector<Node> v;
1793
  ///   dfs(g,s).processedMap(loggerBoolMap(std::back_inserter(v))).run();
1792
  ///   dfs(g).processedMap(loggerBoolMap(std::back_inserter(v))).run(s);
1794 1793
  /// \endcode
1795 1794
  /// \code
1796 1795
  ///   std::vector<Node> v(countNodes(g));
1797
  ///   dfs(g,s).processedMap(loggerBoolMap(v.begin())).run();
1796
  ///   dfs(g).processedMap(loggerBoolMap(v.begin())).run(s);
1798 1797
  /// \endcode
1799 1798
  ///
1800 1799
  /// \note The container of the iterator must contain enough space
1801 1800
  /// for the elements or the iterator should be an inserter iterator.
1802 1801
  ///
1803 1802
  /// \note LoggerBoolMap is just \ref concepts::WriteMap "writable", so
1804
  /// it cannot be used when a readable map is needed, for example as
1803
  /// it cannot be used when a readable map is needed, for example, as
1805 1804
  /// \c ReachedMap for \c Bfs, \c Dfs and \c Dijkstra algorithms.
1806 1805
  ///
1807 1806
  /// \relates LoggerBoolMap
1808 1807
  template<typename Iterator>
1809 1808
  inline LoggerBoolMap<Iterator> loggerBoolMap(Iterator it) {
1810 1809
    return LoggerBoolMap<Iterator>(it);
1811 1810
  }
1812 1811

	
1813 1812
  /// @}
1814 1813

	
1815 1814
  /// \addtogroup graph_maps
1816 1815
  /// @{
1817 1816

	
1818 1817
  /// \brief Provides an immutable and unique id for each item in a graph.
1819 1818
  ///
1820 1819
  /// IdMap provides a unique and immutable id for each item of the
1821
  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is 
1820
  /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
1822 1821
  ///  - \b unique: different items get different ids,
1823 1822
  ///  - \b immutable: the id of an item does not change (even if you
1824 1823
  ///    delete other nodes).
1825 1824
  ///
1826 1825
  /// Using this map you get access (i.e. can read) the inner id values of
1827 1826
  /// the items stored in the graph, which is returned by the \c id()
1828 1827
  /// function of the graph. This map can be inverted with its member
1829
  /// class \c InverseMap or with the \c operator() member.
1828
  /// class \c InverseMap or with the \c operator()() member.
1830 1829
  ///
1831 1830
  /// \tparam GR The graph type.
1832 1831
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
1833 1832
  /// \c GR::Edge).
1834 1833
  ///
1835 1834
  /// \see RangeIdMap
1836 1835
  template <typename GR, typename K>
1837 1836
  class IdMap : public MapBase<K, int> {
1838 1837
  public:
1839 1838
    /// The graph type of IdMap.
1840 1839
    typedef GR Graph;
1841 1840
    typedef GR Digraph;
1842 1841
    /// The key type of IdMap (\c Node, \c Arc or \c Edge).
1843 1842
    typedef K Item;
1844 1843
    /// The key type of IdMap (\c Node, \c Arc or \c Edge).
1845 1844
    typedef K Key;
1846 1845
    /// The value type of IdMap.
1847 1846
    typedef int Value;
1848 1847

	
1849 1848
    /// \brief Constructor.
1850 1849
    ///
1851 1850
    /// Constructor of the map.
1852 1851
    explicit IdMap(const Graph& graph) : _graph(&graph) {}
1853 1852

	
1854 1853
    /// \brief Gives back the \e id of the item.
1855 1854
    ///
1856 1855
    /// Gives back the immutable and unique \e id of the item.
1857 1856
    int operator[](const Item& item) const { return _graph->id(item);}
1858 1857

	
1859 1858
    /// \brief Gives back the \e item by its id.
1860 1859
    ///
1861 1860
    /// Gives back the \e item by its id.
1862 1861
    Item operator()(int id) { return _graph->fromId(id, Item()); }
1863 1862

	
1864 1863
  private:
1865 1864
    const Graph* _graph;
1866 1865

	
1867 1866
  public:
1868 1867

	
1869
    /// \brief This class represents the inverse of its owner (IdMap).
1868
    /// \brief The inverse map type of IdMap.
1870 1869
    ///
1871
    /// This 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.
1872 1873
    /// \see inverse()
1873 1874
    class InverseMap {
1874 1875
    public:
1875 1876

	
1876 1877
      /// \brief Constructor.
1877 1878
      ///
1878 1879
      /// Constructor for creating an id-to-item map.
1879 1880
      explicit InverseMap(const Graph& graph) : _graph(&graph) {}
1880 1881

	
1881 1882
      /// \brief Constructor.
1882 1883
      ///
1883 1884
      /// Constructor for creating an id-to-item map.
1884 1885
      explicit InverseMap(const IdMap& map) : _graph(map._graph) {}
1885 1886

	
1886
      /// \brief Gives back the given item from its id.
1887
      /// \brief Gives back an item by its id.
1887 1888
      ///
1888
      /// Gives back the given item from its id.
1889
      /// Gives back an item by its id.
1889 1890
      Item operator[](int id) const { return _graph->fromId(id, Item());}
1890 1891

	
1891 1892
    private:
1892 1893
      const Graph* _graph;
1893 1894
    };
1894 1895

	
1895 1896
    /// \brief Gives back the inverse of the map.
1896 1897
    ///
1897 1898
    /// Gives back the inverse of the IdMap.
1898 1899
    InverseMap inverse() const { return InverseMap(*_graph);}
1899 1900
  };
1900 1901

	
1902
  /// \brief Returns an \c IdMap class.
1903
  ///
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
  }
1901 1910

	
1902 1911
  /// \brief General cross reference graph map type.
1903 1912

	
1904 1913
  /// This class provides simple invertable graph maps.
1905 1914
  /// It wraps a standard graph map (\c NodeMap, \c ArcMap or \c EdgeMap)
1906 1915
  /// and if a key is set to a new value, then stores it in the inverse map.
1907
  /// The values of the map can be accessed
1908
  /// with stl compatible forward iterator.
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, but
1926
  /// it does not have \c InverseMap.
1909 1927
  ///
1910 1928
  /// This type is not reference map, so it cannot be modified with
1911 1929
  /// the subscript operator.
1912 1930
  ///
1913 1931
  /// \tparam GR The graph type.
1914 1932
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
1915 1933
  /// \c GR::Edge).
1916 1934
  /// \tparam V The value type of the map.
1917 1935
  ///
1918 1936
  /// \see IterableValueMap
1919 1937
  template <typename GR, typename K, typename V>
1920 1938
  class CrossRefMap
1921 1939
    : protected ItemSetTraits<GR, K>::template Map<V>::Type {
1922 1940
  private:
1923 1941

	
1924 1942
    typedef typename ItemSetTraits<GR, K>::
1925 1943
      template Map<V>::Type Map;
1926 1944

	
1927 1945
    typedef std::multimap<V, K> Container;
1928 1946
    Container _inv_map;
1929 1947

	
1930 1948
  public:
1931 1949

	
1932 1950
    /// The graph type of CrossRefMap.
1933 1951
    typedef GR Graph;
1934 1952
    typedef GR Digraph;
1935 1953
    /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
1936 1954
    typedef K Item;
1937 1955
    /// The key type of CrossRefMap (\c Node, \c Arc or \c Edge).
1938 1956
    typedef K Key;
1939 1957
    /// The value type of CrossRefMap.
1940 1958
    typedef V Value;
1941 1959

	
1942 1960
    /// \brief Constructor.
1943 1961
    ///
1944 1962
    /// Construct a new CrossRefMap for the given graph.
1945 1963
    explicit CrossRefMap(const Graph& graph) : Map(graph) {}
1946 1964

	
1947 1965
    /// \brief Forward iterator for values.
1948 1966
    ///
1949
    /// This iterator is an stl compatible forward
1967
    /// This iterator is an STL compatible forward
1950 1968
    /// iterator on the values of the map. The values can
1951 1969
    /// be accessed in the <tt>[beginValue, endValue)</tt> range.
1952 1970
    /// They are considered with multiplicity, so each value is
1953 1971
    /// traversed for each item it is assigned to.
1954
    class ValueIterator
1972
    class ValueIt
1955 1973
      : public std::iterator<std::forward_iterator_tag, Value> {
1956 1974
      friend class CrossRefMap;
1957 1975
    private:
1958
      ValueIterator(typename Container::const_iterator _it)
1976
      ValueIt(typename Container::const_iterator _it)
1959 1977
        : it(_it) {}
1960 1978
    public:
1961 1979

	
1962
      ValueIterator() {}
1963

	
1964
      ValueIterator& operator++() { ++it; return *this; }
1965
      ValueIterator operator++(int) {
1966
        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);
1967 1988
        operator++();
1968 1989
        return tmp;
1969 1990
      }
1970 1991

	
1992
      /// \e
1971 1993
      const Value& operator*() const { return it->first; }
1994
      /// \e
1972 1995
      const Value* operator->() const { return &(it->first); }
1973 1996

	
1974
      bool operator==(ValueIterator jt) const { return it == jt.it; }
1975
      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; }
1976 2001

	
1977 2002
    private:
1978 2003
      typename Container::const_iterator it;
1979 2004
    };
1980 2005

	
2006
    /// Alias for \c ValueIt
2007
    typedef ValueIt ValueIterator;
2008

	
1981 2009
    /// \brief Returns an iterator to the first value.
1982 2010
    ///
1983
    /// Returns an stl compatible iterator to the
2011
    /// Returns an STL compatible iterator to the
1984 2012
    /// first value of the map. The values of the
1985 2013
    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
1986 2014
    /// range.
1987
    ValueIterator beginValue() const {
1988
      return ValueIterator(_inv_map.begin());
2015
    ValueIt beginValue() const {
2016
      return ValueIt(_inv_map.begin());
1989 2017
    }
1990 2018

	
1991 2019
    /// \brief Returns an iterator after the last value.
1992 2020
    ///
1993
    /// Returns an stl compatible iterator after the
2021
    /// Returns an STL compatible iterator after the
1994 2022
    /// last value of the map. The values of the
1995 2023
    /// map can be accessed in the <tt>[beginValue, endValue)</tt>
1996 2024
    /// range.
1997
    ValueIterator endValue() const {
1998
      return ValueIterator(_inv_map.end());
2025
    ValueIt endValue() const {
2026
      return ValueIt(_inv_map.end());
1999 2027
    }
2000 2028

	
2001 2029
    /// \brief Sets the value associated with the given key.
2002 2030
    ///
2003 2031
    /// Sets the value associated with the given key.
2004 2032
    void set(const Key& key, const Value& val) {
2005 2033
      Value oldval = Map::operator[](key);
2006 2034
      typename Container::iterator it;
2007 2035
      for (it = _inv_map.equal_range(oldval).first;
2008 2036
           it != _inv_map.equal_range(oldval).second; ++it) {
2009 2037
        if (it->second == key) {
2010 2038
          _inv_map.erase(it);
2011 2039
          break;
2012 2040
        }
2013 2041
      }
2014 2042
      _inv_map.insert(std::make_pair(val, key));
2015 2043
      Map::set(key, val);
2016 2044
    }
2017 2045

	
2018 2046
    /// \brief Returns the value associated with the given key.
2019 2047
    ///
2020 2048
    /// Returns the value associated with the given key.
2021 2049
    typename MapTraits<Map>::ConstReturnValue
2022 2050
    operator[](const Key& key) const {
2023 2051
      return Map::operator[](key);
2024 2052
    }
2025 2053

	
2026 2054
    /// \brief Gives back an item by its value.
2027 2055
    ///
2028 2056
    /// This function gives back an item that is assigned to
2029 2057
    /// the given value or \c INVALID if no such item exists.
2030 2058
    /// If there are more items with the same associated value,
2031 2059
    /// only one of them is returned.
2032 2060
    Key operator()(const Value& val) const {
2033 2061
      typename Container::const_iterator it = _inv_map.find(val);
2034 2062
      return it != _inv_map.end() ? it->second : INVALID;
2035 2063
    }
2036 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
    }
2072

	
2037 2073
  protected:
2038 2074

	
2039 2075
    /// \brief Erase the key from the map and the inverse map.
2040 2076
    ///
2041 2077
    /// Erase the key from the map and the inverse map. It is called by the
2042 2078
    /// \c AlterationNotifier.
2043 2079
    virtual void erase(const Key& key) {
2044 2080
      Value val = Map::operator[](key);
2045 2081
      typename Container::iterator it;
2046 2082
      for (it = _inv_map.equal_range(val).first;
2047 2083
           it != _inv_map.equal_range(val).second; ++it) {
2048 2084
        if (it->second == key) {
2049 2085
          _inv_map.erase(it);
2050 2086
          break;
2051 2087
        }
2052 2088
      }
2053 2089
      Map::erase(key);
2054 2090
    }
2055 2091

	
2056 2092
    /// \brief Erase more keys from the map and the inverse map.
2057 2093
    ///
2058 2094
    /// Erase more keys from the map and the inverse map. It is called by the
2059 2095
    /// \c AlterationNotifier.
2060 2096
    virtual void erase(const std::vector<Key>& keys) {
2061 2097
      for (int i = 0; i < int(keys.size()); ++i) {
2062 2098
        Value val = Map::operator[](keys[i]);
2063 2099
        typename Container::iterator it;
2064 2100
        for (it = _inv_map.equal_range(val).first;
2065 2101
             it != _inv_map.equal_range(val).second; ++it) {
2066 2102
          if (it->second == keys[i]) {
2067 2103
            _inv_map.erase(it);
2068 2104
            break;
2069 2105
          }
2070 2106
        }
2071 2107
      }
2072 2108
      Map::erase(keys);
2073 2109
    }
2074 2110

	
2075 2111
    /// \brief Clear the keys from the map and the inverse map.
2076 2112
    ///
2077 2113
    /// Clear the keys from the map and the inverse map. It is called by the
2078 2114
    /// \c AlterationNotifier.
2079 2115
    virtual void clear() {
2080 2116
      _inv_map.clear();
2081 2117
      Map::clear();
2082 2118
    }
2083 2119

	
2084 2120
  public:
2085 2121

	
2086
    /// \brief The inverse map type.
2122
    /// \brief The inverse map type of CrossRefMap.
2087 2123
    ///
2088
    /// The inverse of this map. The subscript operator of the map
2089
    /// gives back the item that 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()
2090 2128
    class InverseMap {
2091 2129
    public:
2092 2130
      /// \brief Constructor
2093 2131
      ///
2094 2132
      /// Constructor of the InverseMap.
2095 2133
      explicit InverseMap(const CrossRefMap& inverted)
2096 2134
        : _inverted(inverted) {}
2097 2135

	
2098 2136
      /// The value type of the InverseMap.
2099 2137
      typedef typename CrossRefMap::Key Value;
2100 2138
      /// The key type of the InverseMap.
2101 2139
      typedef typename CrossRefMap::Value Key;
2102 2140

	
2103 2141
      /// \brief Subscript operator.
2104 2142
      ///
2105 2143
      /// Subscript operator. It gives back an item
2106 2144
      /// that is assigned to the given value or \c INVALID
2107 2145
      /// if no such item exists.
2108 2146
      Value operator[](const Key& key) const {
2109 2147
        return _inverted(key);
2110 2148
      }
2111 2149

	
2112 2150
    private:
2113 2151
      const CrossRefMap& _inverted;
2114 2152
    };
2115 2153

	
2116
    /// \brief It gives back the read-only inverse map.
2154
    /// \brief Gives back the inverse of the map.
2117 2155
    ///
2118
    /// It gives back the read-only inverse map.
2156
    /// Gives back the inverse of the CrossRefMap.
2119 2157
    InverseMap inverse() const {
2120 2158
      return InverseMap(*this);
2121 2159
    }
2122 2160

	
2123 2161
  };
2124 2162

	
2125
  /// \brief Provides continuous and unique ID for the
2163
  /// \brief Provides continuous and unique id for the
2126 2164
  /// items of a graph.
2127 2165
  ///
2128 2166
  /// RangeIdMap provides a unique and continuous
2129
  /// ID for each item of a given type (\c Node, \c Arc or
2167
  /// id for each item of a given type (\c Node, \c Arc or
2130 2168
  /// \c Edge) in a graph. This id is
2131 2169
  ///  - \b unique: different items get different ids,
2132 2170
  ///  - \b continuous: the range of the ids is the set of integers
2133 2171
  ///    between 0 and \c n-1, where \c n is the number of the items of
2134 2172
  ///    this type (\c Node, \c Arc or \c Edge).
2135 2173
  ///  - So, the ids can change when deleting an item of the same type.
2136 2174
  ///
2137 2175
  /// Thus this id is not (necessarily) the same as what can get using
2138 2176
  /// the \c id() function of the graph or \ref IdMap.
2139 2177
  /// This map can be inverted with its member class \c InverseMap,
2140
  /// or with the \c operator() member.
2178
  /// or with the \c operator()() member.
2141 2179
  ///
2142 2180
  /// \tparam GR The graph type.
2143 2181
  /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
2144 2182
  /// \c GR::Edge).
2145 2183
  ///
2146 2184
  /// \see IdMap
2147 2185
  template <typename GR, typename K>
2148 2186
  class RangeIdMap
2149 2187
    : protected ItemSetTraits<GR, K>::template Map<int>::Type {
2150 2188

	
2151 2189
    typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Map;
2152 2190

	
2153 2191
  public:
2154 2192
    /// The graph type of RangeIdMap.
2155 2193
    typedef GR Graph;
2156 2194
    typedef GR Digraph;
2157 2195
    /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
2158 2196
    typedef K Item;
2159 2197
    /// The key type of RangeIdMap (\c Node, \c Arc or \c Edge).
2160 2198
    typedef K Key;
2161 2199
    /// The value type of RangeIdMap.
2162 2200
    typedef int Value;
2163 2201

	
2164 2202
    /// \brief Constructor.
2165 2203
    ///
2166 2204
    /// Constructor.
2167 2205
    explicit RangeIdMap(const Graph& gr) : Map(gr) {
2168 2206
      Item it;
2169 2207
      const typename Map::Notifier* nf = Map::notifier();
2170 2208
      for (nf->first(it); it != INVALID; nf->next(it)) {
2171 2209
        Map::set(it, _inv_map.size());
2172 2210
        _inv_map.push_back(it);
2173 2211
      }
2174 2212
    }
2175 2213

	
2176 2214
  protected:
2177 2215

	
2178 2216
    /// \brief Adds a new key to the map.
2179 2217
    ///
2180 2218
    /// Add a new key to the map. It is called by the
2181 2219
    /// \c AlterationNotifier.
2182 2220
    virtual void add(const Item& item) {
2183 2221
      Map::add(item);
2184 2222
      Map::set(item, _inv_map.size());
2185 2223
      _inv_map.push_back(item);
2186 2224
    }
2187 2225

	
2188 2226
    /// \brief Add more new keys to the map.
2189 2227
    ///
2190 2228
    /// Add more new keys to the map. It is called by the
2191 2229
    /// \c AlterationNotifier.
2192 2230
    virtual void add(const std::vector<Item>& items) {
2193 2231
      Map::add(items);
2194 2232
      for (int i = 0; i < int(items.size()); ++i) {
2195 2233
        Map::set(items[i], _inv_map.size());
2196 2234
        _inv_map.push_back(items[i]);
2197 2235
      }
2198 2236
    }
2199 2237

	
2200 2238
    /// \brief Erase the key from the map.
2201 2239
    ///
2202 2240
    /// Erase the key from the map. It is called by the
2203 2241
    /// \c AlterationNotifier.
2204 2242
    virtual void erase(const Item& item) {
2205 2243
      Map::set(_inv_map.back(), Map::operator[](item));
2206 2244
      _inv_map[Map::operator[](item)] = _inv_map.back();
2207 2245
      _inv_map.pop_back();
2208 2246
      Map::erase(item);
2209 2247
    }
2210 2248

	
2211 2249
    /// \brief Erase more keys from the map.
2212 2250
    ///
2213 2251
    /// Erase more keys from the map. It is called by the
2214 2252
    /// \c AlterationNotifier.
2215 2253
    virtual void erase(const std::vector<Item>& items) {
2216 2254
      for (int i = 0; i < int(items.size()); ++i) {
2217 2255
        Map::set(_inv_map.back(), Map::operator[](items[i]));
2218 2256
        _inv_map[Map::operator[](items[i])] = _inv_map.back();
2219 2257
        _inv_map.pop_back();
2220 2258
      }
2221 2259
      Map::erase(items);
2222 2260
    }
2223 2261

	
2224 2262
    /// \brief Build the unique map.
2225 2263
    ///
2226 2264
    /// Build the unique map. It is called by the
2227 2265
    /// \c AlterationNotifier.
2228 2266
    virtual void build() {
2229 2267
      Map::build();
2230 2268
      Item it;
2231 2269
      const typename Map::Notifier* nf = Map::notifier();
2232 2270
      for (nf->first(it); it != INVALID; nf->next(it)) {
2233 2271
        Map::set(it, _inv_map.size());
2234 2272
        _inv_map.push_back(it);
2235 2273
      }
2236 2274
    }
2237 2275

	
2238 2276
    /// \brief Clear the keys from the map.
2239 2277
    ///
2240 2278
    /// Clear the keys from the map. It is called by the
2241 2279
    /// \c AlterationNotifier.
2242 2280
    virtual void clear() {
2243 2281
      _inv_map.clear();
2244 2282
      Map::clear();
2245 2283
    }
2246 2284

	
2247 2285
  public:
2248 2286

	
2249 2287
    /// \brief Returns the maximal value plus one.
2250 2288
    ///
2251 2289
    /// Returns the maximal value plus one in the map.
2252 2290
    unsigned int size() const {
2253 2291
      return _inv_map.size();
2254 2292
    }
2255 2293

	
2256 2294
    /// \brief Swaps the position of the two items in the map.
2257 2295
    ///
2258 2296
    /// Swaps the position of the two items in the map.
2259 2297
    void swap(const Item& p, const Item& q) {
2260 2298
      int pi = Map::operator[](p);
2261 2299
      int qi = Map::operator[](q);
2262 2300
      Map::set(p, qi);
2263 2301
      _inv_map[qi] = p;
2264 2302
      Map::set(q, pi);
2265 2303
      _inv_map[pi] = q;
2266 2304
    }
2267 2305

	
2268
    /// \brief Gives back the \e RangeId of the item
2306
    /// \brief Gives back the \e range \e id of the item
2269 2307
    ///
2270
    /// Gives back the \e RangeId of the item.
2308
    /// Gives back the \e range \e id of the item.
2271 2309
    int operator[](const Item& item) const {
2272 2310
      return Map::operator[](item);
2273 2311
    }
2274 2312

	
2275
    /// \brief Gives back the item belonging to a \e RangeId
2276
    /// 
2277
    /// Gives back the item belonging to a \e RangeId.
2313
    /// \brief Gives back the item belonging to a \e range \e id
2314
    ///
2315
    /// Gives back the item belonging to the given \e range \e id.
2278 2316
    Item operator()(int id) const {
2279 2317
      return _inv_map[id];
2280 2318
    }
2281 2319

	
2282 2320
  private:
2283 2321

	
2284 2322
    typedef std::vector<Item> Container;
2285 2323
    Container _inv_map;
2286 2324

	
2287 2325
  public:
2288 2326

	
2289 2327
    /// \brief The inverse map type of RangeIdMap.
2290 2328
    ///
2291
    /// The inverse map type of RangeIdMap.
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.
2292 2332
    class InverseMap {
2293 2333
    public:
2294 2334
      /// \brief Constructor
2295 2335
      ///
2296 2336
      /// Constructor of the InverseMap.
2297 2337
      explicit InverseMap(const RangeIdMap& inverted)
2298 2338
        : _inverted(inverted) {}
2299 2339

	
2300 2340

	
2301 2341
      /// The value type of the InverseMap.
2302 2342
      typedef typename RangeIdMap::Key Value;
2303 2343
      /// The key type of the InverseMap.
2304 2344
      typedef typename RangeIdMap::Value Key;
2305 2345

	
2306 2346
      /// \brief Subscript operator.
2307 2347
      ///
2308 2348
      /// Subscript operator. It gives back the item
2309
      /// that the descriptor currently belongs to.
2349
      /// that the given \e range \e id currently belongs to.
2310 2350
      Value operator[](const Key& key) const {
2311 2351
        return _inverted(key);
2312 2352
      }
2313 2353

	
2314 2354
      /// \brief Size of the map.
2315 2355
      ///
2316 2356
      /// Returns the size of the map.
2317 2357
      unsigned int size() const {
2318 2358
        return _inverted.size();
2319 2359
      }
2320 2360

	
2321 2361
    private:
2322 2362
      const RangeIdMap& _inverted;
2323 2363
    };
2324 2364

	
2325 2365
    /// \brief Gives back the inverse of the map.
2326 2366
    ///
2327
    /// Gives back the inverse of the map.
2367
    /// Gives back the inverse of the RangeIdMap.
2328 2368
    const InverseMap inverse() const {
2329 2369
      return InverseMap(*this);
2330 2370
    }
2331 2371
  };
2332 2372

	
2373
  /// \brief Returns a \c RangeIdMap class.
2374
  ///
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
      lace(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

	
2333 3293
  /// \brief Map of the source nodes of arcs in a digraph.
2334 3294
  ///
2335 3295
  /// SourceMap provides access for the source node of each arc in a digraph,
2336 3296
  /// which is returned by the \c source() function of the digraph.
2337 3297
  /// \tparam GR The digraph type.
2338 3298
  /// \see TargetMap
2339 3299
  template <typename GR>
2340 3300
  class SourceMap {
2341 3301
  public:
2342 3302

	
2343
    ///\e
3303
    /// The key type (the \c Arc type of the digraph).
2344 3304
    typedef typename GR::Arc Key;
2345
    ///\e
3305
    /// The value type (the \c Node type of the digraph).
2346 3306
    typedef typename GR::Node Value;
2347 3307

	
2348 3308
    /// \brief Constructor
2349 3309
    ///
2350 3310
    /// Constructor.
2351 3311
    /// \param digraph The digraph that the map belongs to.
2352 3312
    explicit SourceMap(const GR& digraph) : _graph(digraph) {}
2353 3313

	
2354 3314
    /// \brief Returns the source node of the given arc.
2355 3315
    ///
2356 3316
    /// Returns the source node of the given arc.
2357 3317
    Value operator[](const Key& arc) const {
2358 3318
      return _graph.source(arc);
2359 3319
    }
2360 3320

	
2361 3321
  private:
2362 3322
    const GR& _graph;
2363 3323
  };
2364 3324

	
2365 3325
  /// \brief Returns a \c SourceMap class.
2366 3326
  ///
2367 3327
  /// This function just returns an \c SourceMap class.
2368 3328
  /// \relates SourceMap
2369 3329
  template <typename GR>
2370 3330
  inline SourceMap<GR> sourceMap(const GR& graph) {
2371 3331
    return SourceMap<GR>(graph);
2372 3332
  }
2373 3333

	
2374 3334
  /// \brief Map of the target nodes of arcs in a digraph.
2375 3335
  ///
2376 3336
  /// TargetMap provides access for the target node of each arc in a digraph,
2377 3337
  /// which is returned by the \c target() function of the digraph.
2378 3338
  /// \tparam GR The digraph type.
2379 3339
  /// \see SourceMap
2380 3340
  template <typename GR>
2381 3341
  class TargetMap {
2382 3342
  public:
2383 3343

	
2384
    ///\e
3344
    /// The key type (the \c Arc type of the digraph).
2385 3345
    typedef typename GR::Arc Key;
2386
    ///\e
3346
    /// The value type (the \c Node type of the digraph).
2387 3347
    typedef typename GR::Node Value;
2388 3348

	
2389 3349
    /// \brief Constructor
2390 3350
    ///
2391 3351
    /// Constructor.
2392 3352
    /// \param digraph The digraph that the map belongs to.
2393 3353
    explicit TargetMap(const GR& digraph) : _graph(digraph) {}
2394 3354

	
2395 3355
    /// \brief Returns the target node of the given arc.
2396 3356
    ///
2397 3357
    /// Returns the target node of the given arc.
2398 3358
    Value operator[](const Key& e) const {
2399 3359
      return _graph.target(e);
2400 3360
    }
2401 3361

	
2402 3362
  private:
2403 3363
    const GR& _graph;
2404 3364
  };
2405 3365

	
2406 3366
  /// \brief Returns a \c TargetMap class.
2407 3367
  ///
2408 3368
  /// This function just returns a \c TargetMap class.
2409 3369
  /// \relates TargetMap
2410 3370
  template <typename GR>
2411 3371
  inline TargetMap<GR> targetMap(const GR& graph) {
2412 3372
    return TargetMap<GR>(graph);
2413 3373
  }
2414 3374

	
2415 3375
  /// \brief Map of the "forward" directed arc view of edges in a graph.
2416 3376
  ///
2417 3377
  /// ForwardMap provides access for the "forward" directed arc view of
2418 3378
  /// each edge in a graph, which is returned by the \c direct() function
2419 3379
  /// of the graph with \c true parameter.
2420 3380
  /// \tparam GR The graph type.
2421 3381
  /// \see BackwardMap
2422 3382
  template <typename GR>
2423 3383
  class ForwardMap {
2424 3384
  public:
2425 3385

	
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).
2426 3389
    typedef typename GR::Arc Value;
2427
    typedef typename GR::Edge Key;
2428 3390

	
2429 3391
    /// \brief Constructor
2430 3392
    ///
2431 3393
    /// Constructor.
2432 3394
    /// \param graph The graph that the map belongs to.
2433 3395
    explicit ForwardMap(const GR& graph) : _graph(graph) {}
2434 3396

	
2435 3397
    /// \brief Returns the "forward" directed arc view of the given edge.
2436 3398
    ///
2437 3399
    /// Returns the "forward" directed arc view of the given edge.
2438 3400
    Value operator[](const Key& key) const {
2439 3401
      return _graph.direct(key, true);
2440 3402
    }
2441 3403

	
2442 3404
  private:
2443 3405
    const GR& _graph;
2444 3406
  };
2445 3407

	
2446 3408
  /// \brief Returns a \c ForwardMap class.
2447 3409
  ///
2448 3410
  /// This function just returns an \c ForwardMap class.
2449 3411
  /// \relates ForwardMap
2450 3412
  template <typename GR>
2451 3413
  inline ForwardMap<GR> forwardMap(const GR& graph) {
2452 3414
    return ForwardMap<GR>(graph);
2453 3415
  }
2454 3416

	
2455 3417
  /// \brief Map of the "backward" directed arc view of edges in a graph.
2456 3418
  ///
2457 3419
  /// BackwardMap provides access for the "backward" directed arc view of
2458 3420
  /// each edge in a graph, which is returned by the \c direct() function
2459 3421
  /// of the graph with \c false parameter.
2460 3422
  /// \tparam GR The graph type.
2461 3423
  /// \see ForwardMap
2462 3424
  template <typename GR>
2463 3425
  class BackwardMap {
2464 3426
  public:
2465 3427

	
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).
2466 3431
    typedef typename GR::Arc Value;
2467
    typedef typename GR::Edge Key;
2468 3432

	
2469 3433
    /// \brief Constructor
2470 3434
    ///
2471 3435
    /// Constructor.
2472 3436
    /// \param graph The graph that the map belongs to.
2473 3437
    explicit BackwardMap(const GR& graph) : _graph(graph) {}
2474 3438

	
2475 3439
    /// \brief Returns the "backward" directed arc view of the given edge.
2476 3440
    ///
2477 3441
    /// Returns the "backward" directed arc view of the given edge.
2478 3442
    Value operator[](const Key& key) const {
2479 3443
      return _graph.direct(key, false);
2480 3444
    }
2481 3445

	
2482 3446
  private:
2483 3447
    const GR& _graph;
2484 3448
  };
2485 3449

	
2486 3450
  /// \brief Returns a \c BackwardMap class
2487 3451

	
2488 3452
  /// This function just returns a \c BackwardMap class.
2489 3453
  /// \relates BackwardMap
2490 3454
  template <typename GR>
2491 3455
  inline BackwardMap<GR> backwardMap(const GR& graph) {
2492 3456
    return BackwardMap<GR>(graph);
2493 3457
  }
2494 3458

	
2495 3459
  /// \brief Map of the in-degrees of nodes in a digraph.
2496 3460
  ///
2497 3461
  /// This map returns the in-degree of a node. Once it is constructed,
2498 3462
  /// the degrees are stored in a standard \c NodeMap, so each query is done
2499 3463
  /// in constant time. On the other hand, the values are updated automatically
2500 3464
  /// whenever the digraph changes.
2501 3465
  ///
2502
  /// \warning Besides \c addNode() and \c addArc(), a digraph structure 
3466
  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
2503 3467
  /// may provide alternative ways to modify the digraph.
2504 3468
  /// The correct behavior of InDegMap is not guarantied if these additional
2505
  /// features are used. For example the functions
3469
  /// features are used. For example, the functions
2506 3470
  /// \ref ListDigraph::changeSource() "changeSource()",
2507 3471
  /// \ref ListDigraph::changeTarget() "changeTarget()" and
2508 3472
  /// \ref ListDigraph::reverseArc() "reverseArc()"
2509 3473
  /// of \ref ListDigraph will \e not update the degree values correctly.
2510 3474
  ///
2511 3475
  /// \sa OutDegMap
2512 3476
  template <typename GR>
2513 3477
  class InDegMap
2514 3478
    : protected ItemSetTraits<GR, typename GR::Arc>
2515 3479
      ::ItemNotifier::ObserverBase {
2516 3480

	
2517 3481
  public:
2518
    
3482

	
2519 3483
    /// The graph type of InDegMap
2520 3484
    typedef GR Graph;
2521 3485
    typedef GR Digraph;
2522 3486
    /// The key type
2523 3487
    typedef typename Digraph::Node Key;
2524 3488
    /// The value type
2525 3489
    typedef int Value;
2526 3490

	
2527 3491
    typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
2528 3492
    ::ItemNotifier::ObserverBase Parent;
2529 3493

	
2530 3494
  private:
2531 3495

	
2532 3496
    class AutoNodeMap
2533 3497
      : public ItemSetTraits<Digraph, Key>::template Map<int>::Type {
2534 3498
    public:
2535 3499

	
2536 3500
      typedef typename ItemSetTraits<Digraph, Key>::
2537 3501
      template Map<int>::Type Parent;
2538 3502

	
2539 3503
      AutoNodeMap(const Digraph& digraph) : Parent(digraph, 0) {}
2540 3504

	
2541 3505
      virtual void add(const Key& key) {
2542 3506
        Parent::add(key);
2543 3507
        Parent::set(key, 0);
2544 3508
      }
2545 3509

	
2546 3510
      virtual void add(const std::vector<Key>& keys) {
2547 3511
        Parent::add(keys);
2548 3512
        for (int i = 0; i < int(keys.size()); ++i) {
2549 3513
          Parent::set(keys[i], 0);
2550 3514
        }
2551 3515
      }
2552 3516

	
2553 3517
      virtual void build() {
2554 3518
        Parent::build();
2555 3519
        Key it;
2556 3520
        typename Parent::Notifier* nf = Parent::notifier();
2557 3521
        for (nf->first(it); it != INVALID; nf->next(it)) {
2558 3522
          Parent::set(it, 0);
2559 3523
        }
2560 3524
      }
2561 3525
    };
2562 3526

	
2563 3527
  public:
2564 3528

	
2565 3529
    /// \brief Constructor.
2566 3530
    ///
2567 3531
    /// Constructor for creating an in-degree map.
2568 3532
    explicit InDegMap(const Digraph& graph)
2569 3533
      : _digraph(graph), _deg(graph) {
2570 3534
      Parent::attach(_digraph.notifier(typename Digraph::Arc()));
2571 3535

	
2572 3536
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2573 3537
        _deg[it] = countInArcs(_digraph, it);
2574 3538
      }
2575 3539
    }
2576 3540

	
2577 3541
    /// \brief Gives back the in-degree of a Node.
2578 3542
    ///
2579 3543
    /// Gives back the in-degree of a Node.
2580 3544
    int operator[](const Key& key) const {
2581 3545
      return _deg[key];
2582 3546
    }
2583 3547

	
2584 3548
  protected:
2585 3549

	
2586 3550
    typedef typename Digraph::Arc Arc;
2587 3551

	
2588 3552
    virtual void add(const Arc& arc) {
2589 3553
      ++_deg[_digraph.target(arc)];
2590 3554
    }
2591 3555

	
2592 3556
    virtual void add(const std::vector<Arc>& arcs) {
2593 3557
      for (int i = 0; i < int(arcs.size()); ++i) {
2594 3558
        ++_deg[_digraph.target(arcs[i])];
2595 3559
      }
2596 3560
    }
2597 3561

	
2598 3562
    virtual void erase(const Arc& arc) {
2599 3563
      --_deg[_digraph.target(arc)];
2600 3564
    }
2601 3565

	
2602 3566
    virtual void erase(const std::vector<Arc>& arcs) {
2603 3567
      for (int i = 0; i < int(arcs.size()); ++i) {
2604 3568
        --_deg[_digraph.target(arcs[i])];
2605 3569
      }
2606 3570
    }
2607 3571

	
2608 3572
    virtual void build() {
2609 3573
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2610 3574
        _deg[it] = countInArcs(_digraph, it);
2611 3575
      }
2612 3576
    }
2613 3577

	
2614 3578
    virtual void clear() {
2615 3579
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2616 3580
        _deg[it] = 0;
2617 3581
      }
2618 3582
    }
2619 3583
  private:
2620 3584

	
2621 3585
    const Digraph& _digraph;
2622 3586
    AutoNodeMap _deg;
2623 3587
  };
2624 3588

	
2625 3589
  /// \brief Map of the out-degrees of nodes in a digraph.
2626 3590
  ///
2627 3591
  /// This map returns the out-degree of a node. Once it is constructed,
2628 3592
  /// the degrees are stored in a standard \c NodeMap, so each query is done
2629 3593
  /// in constant time. On the other hand, the values are updated automatically
2630 3594
  /// whenever the digraph changes.
2631 3595
  ///
2632
  /// \warning Besides \c addNode() and \c addArc(), a digraph structure 
3596
  /// \warning Besides \c addNode() and \c addArc(), a digraph structure
2633 3597
  /// may provide alternative ways to modify the digraph.
2634 3598
  /// The correct behavior of OutDegMap is not guarantied if these additional
2635
  /// features are used. For example the functions
3599
  /// features are used. For example, the functions
2636 3600
  /// \ref ListDigraph::changeSource() "changeSource()",
2637 3601
  /// \ref ListDigraph::changeTarget() "changeTarget()" and
2638 3602
  /// \ref ListDigraph::reverseArc() "reverseArc()"
2639 3603
  /// of \ref ListDigraph will \e not update the degree values correctly.
2640 3604
  ///
2641 3605
  /// \sa InDegMap
2642 3606
  template <typename GR>
2643 3607
  class OutDegMap
2644 3608
    : protected ItemSetTraits<GR, typename GR::Arc>
2645 3609
      ::ItemNotifier::ObserverBase {
2646 3610

	
2647 3611
  public:
2648 3612

	
2649 3613
    /// The graph type of OutDegMap
2650 3614
    typedef GR Graph;
2651 3615
    typedef GR Digraph;
2652 3616
    /// The key type
2653 3617
    typedef typename Digraph::Node Key;
2654 3618
    /// The value type
2655 3619
    typedef int Value;
2656 3620

	
2657 3621
    typedef typename ItemSetTraits<Digraph, typename Digraph::Arc>
2658 3622
    ::ItemNotifier::ObserverBase Parent;
2659 3623

	
2660 3624
  private:
2661 3625

	
2662 3626
    class AutoNodeMap
2663 3627
      : public ItemSetTraits<Digraph, Key>::template Map<int>::Type {
2664 3628
    public:
2665 3629

	
2666 3630
      typedef typename ItemSetTraits<Digraph, Key>::
2667 3631
      template Map<int>::Type Parent;
2668 3632

	
2669 3633
      AutoNodeMap(const Digraph& digraph) : Parent(digraph, 0) {}
2670 3634

	
2671 3635
      virtual void add(const Key& key) {
2672 3636
        Parent::add(key);
2673 3637
        Parent::set(key, 0);
2674 3638
      }
2675 3639
      virtual void add(const std::vector<Key>& keys) {
2676 3640
        Parent::add(keys);
2677 3641
        for (int i = 0; i < int(keys.size()); ++i) {
2678 3642
          Parent::set(keys[i], 0);
2679 3643
        }
2680 3644
      }
2681 3645
      virtual void build() {
2682 3646
        Parent::build();
2683 3647
        Key it;
2684 3648
        typename Parent::Notifier* nf = Parent::notifier();
2685 3649
        for (nf->first(it); it != INVALID; nf->next(it)) {
2686 3650
          Parent::set(it, 0);
2687 3651
        }
2688 3652
      }
2689 3653
    };
2690 3654

	
2691 3655
  public:
2692 3656

	
2693 3657
    /// \brief Constructor.
2694 3658
    ///
2695 3659
    /// Constructor for creating an out-degree map.
2696 3660
    explicit OutDegMap(const Digraph& graph)
2697 3661
      : _digraph(graph), _deg(graph) {
2698 3662
      Parent::attach(_digraph.notifier(typename Digraph::Arc()));
2699 3663

	
2700 3664
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2701 3665
        _deg[it] = countOutArcs(_digraph, it);
2702 3666
      }
2703 3667
    }
2704 3668

	
2705 3669
    /// \brief Gives back the out-degree of a Node.
2706 3670
    ///
2707 3671
    /// Gives back the out-degree of a Node.
2708 3672
    int operator[](const Key& key) const {
2709 3673
      return _deg[key];
2710 3674
    }
2711 3675

	
2712 3676
  protected:
2713 3677

	
2714 3678
    typedef typename Digraph::Arc Arc;
2715 3679

	
2716 3680
    virtual void add(const Arc& arc) {
2717 3681
      ++_deg[_digraph.source(arc)];
2718 3682
    }
2719 3683

	
2720 3684
    virtual void add(const std::vector<Arc>& arcs) {
2721 3685
      for (int i = 0; i < int(arcs.size()); ++i) {
2722 3686
        ++_deg[_digraph.source(arcs[i])];
2723 3687
      }
2724 3688
    }
2725 3689

	
2726 3690
    virtual void erase(const Arc& arc) {
2727 3691
      --_deg[_digraph.source(arc)];
2728 3692
    }
2729 3693

	
2730 3694
    virtual void erase(const std::vector<Arc>& arcs) {
2731 3695
      for (int i = 0; i < int(arcs.size()); ++i) {
2732 3696
        --_deg[_digraph.source(arcs[i])];
2733 3697
      }
2734 3698
    }
2735 3699

	
2736 3700
    virtual void build() {
2737 3701
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2738 3702
        _deg[it] = countOutArcs(_digraph, it);
2739 3703
      }
2740 3704
    }
2741 3705

	
2742 3706
    virtual void clear() {
2743 3707
      for(typename Digraph::NodeIt it(_digraph); it != INVALID; ++it) {
2744 3708
        _deg[it] = 0;
2745 3709
      }
2746 3710
    }
2747 3711
  private:
2748 3712

	
2749 3713
    const Digraph& _digraph;
2750 3714
    AutoNodeMap _deg;
2751 3715
  };
2752 3716

	
2753 3717
  /// \brief Potential difference map
2754 3718
  ///
2755 3719
  /// PotentialDifferenceMap returns the difference between the potentials of
2756 3720
  /// the source and target nodes of each arc in a digraph, i.e. it returns
2757 3721
  /// \code
2758 3722
  ///   potential[gr.target(arc)] - potential[gr.source(arc)].
2759 3723
  /// \endcode
2760 3724
  /// \tparam GR The digraph type.
2761 3725
  /// \tparam POT A node map storing the potentials.
2762 3726
  template <typename GR, typename POT>
2763 3727
  class PotentialDifferenceMap {
2764 3728
  public:
2765 3729
    /// Key type
2766 3730
    typedef typename GR::Arc Key;
2767 3731
    /// Value type
2768 3732
    typedef typename POT::Value Value;
2769 3733

	
2770 3734
    /// \brief Constructor
2771 3735
    ///
2772 3736
    /// Contructor of the map.
2773 3737
    explicit PotentialDifferenceMap(const GR& gr,
2774 3738
                                    const POT& potential)
2775 3739
      : _digraph(gr), _potential(potential) {}
2776 3740

	
2777 3741
    /// \brief Returns the potential difference for the given arc.
2778 3742
    ///
2779 3743
    /// Returns the potential difference for the given arc, i.e.
2780 3744
    /// \code
2781 3745
    ///   potential[gr.target(arc)] - potential[gr.source(arc)].
2782 3746
    /// \endcode
2783 3747
    Value operator[](const Key& arc) const {
2784 3748
      return _potential[_digraph.target(arc)] -
2785 3749
        _potential[_digraph.source(arc)];
2786 3750
    }
2787 3751

	
2788 3752
  private:
2789 3753
    const GR& _digraph;
2790 3754
    const POT& _potential;
2791 3755
  };
2792 3756

	
2793 3757
  /// \brief Returns a PotentialDifferenceMap.
2794 3758
  ///
2795 3759
  /// This function just returns a PotentialDifferenceMap.
2796 3760
  /// \relates PotentialDifferenceMap
2797 3761
  template <typename GR, typename POT>
2798 3762
  PotentialDifferenceMap<GR, POT>
2799 3763
  potentialDifferenceMap(const GR& gr, const POT& potential) {
2800 3764
    return PotentialDifferenceMap<GR, POT>(gr, potential);
2801 3765
  }
2802 3766

	
3767

	
3768
  /// \brief Copy the values of a graph map to another map.
3769
  ///
3770
  /// This function copies the values of a graph map to another graph map.
3771
  /// \c To::Key must be equal or convertible to \c From::Key and
3772
  /// \c From::Value must be equal or convertible to \c To::Value.
3773
  ///
3774
  /// For example, an edge map of \c int value type can be copied to
3775
  /// an arc map of \c double value type in an undirected graph, but
3776
  /// an arc map cannot be copied to an edge map.
3777
  /// Note that even a \ref ConstMap can be copied to a standard graph map,
3778
  /// but \ref mapFill() can also be used for this purpose.
3779
  ///
3780
  /// \param gr The graph for which the maps are defined.
3781
  /// \param from The map from which the values have to be copied.
3782
  /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
3783
  /// \param to The map to which the values have to be copied.
3784
  /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
3785
  template <typename GR, typename From, typename To>
3786
  void mapCopy(const GR& gr, const From& from, To& to) {
3787
    typedef typename To::Key Item;
3788
    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
3789

	
3790
    for (ItemIt it(gr); it != INVALID; ++it) {
3791
      to.set(it, from[it]);
3792
    }
3793
  }
3794

	
3795
  /// \brief Compare two graph maps.
3796
  ///
3797
  /// This function compares the values of two graph maps. It returns
3798
  /// \c true if the maps assign the same value for all items in the graph.
3799
  /// The \c Key type of the maps (\c Node, \c Arc or \c Edge) must be equal
3800
  /// and their \c Value types must be comparable using \c %operator==().
3801
  ///
3802
  /// \param gr The graph for which the maps are defined.
3803
  /// \param map1 The first map.
3804
  /// \param map2 The second map.
3805
  template <typename GR, typename Map1, typename Map2>
3806
  bool mapCompare(const GR& gr, const Map1& map1, const Map2& map2) {
3807
    typedef typename Map2::Key Item;
3808
    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
3809

	
3810
    for (ItemIt it(gr); it != INVALID; ++it) {
3811
      if (!(map1[it] == map2[it])) return false;
3812
    }
3813
    return true;
3814
  }
3815

	
3816
  /// \brief Return an item having minimum value of a graph map.
3817
  ///
3818
  /// This function returns an item (\c Node, \c Arc or \c Edge) having
3819
  /// minimum value of the given graph map.
3820
  /// If the item set is empty, it returns \c INVALID.
3821
  ///
3822
  /// \param gr The graph for which the map is defined.
3823
  /// \param map The graph map.
3824
  template <typename GR, typename Map>
3825
  typename Map::Key mapMin(const GR& gr, const Map& map) {
3826
    return mapMin(gr, map, std::less<typename Map::Value>());
3827
  }
3828

	
3829
  /// \brief Return an item having minimum value of a graph map.
3830
  ///
3831
  /// This function returns an item (\c Node, \c Arc or \c Edge) having
3832
  /// minimum value of the given graph map.
3833
  /// If the item set is empty, it returns \c INVALID.
3834
  ///
3835
  /// \param gr The graph for which the map is defined.
3836
  /// \param map The graph map.
3837
  /// \param comp Comparison function object.
3838
  template <typename GR, typename Map, typename Comp>
3839
  typename Map::Key mapMin(const GR& gr, const Map& map, const Comp& comp) {
3840
    typedef typename Map::Key Item;
3841
    typedef typename Map::Value Value;
3842
    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
3843

	
3844
    ItemIt min_item(gr);
3845
    if (min_item == INVALID) return INVALID;
3846
    Value min = map[min_item];
3847
    for (ItemIt it(gr); it != INVALID; ++it) {
3848
      if (comp(map[it], min)) {
3849
        min = map[it];
3850
        min_item = it;
3851
      }
3852
    }
3853
    return min_item;
3854
  }
3855

	
3856
  /// \brief Return an item having maximum value of a graph map.
3857
  ///
3858
  /// This function returns an item (\c Node, \c Arc or \c Edge) having
3859
  /// maximum value of the given graph map.
3860
  /// If the item set is empty, it returns \c INVALID.
3861
  ///
3862
  /// \param gr The graph for which the map is defined.
3863
  /// \param map The graph map.
3864
  template <typename GR, typename Map>
3865
  typename Map::Key mapMax(const GR& gr, const Map& map) {
3866
    return mapMax(gr, map, std::less<typename Map::Value>());
3867
  }
3868

	
3869
  /// \brief Return an item having maximum value of a graph map.
3870
  ///
3871
  /// This function returns an item (\c Node, \c Arc or \c Edge) having
3872
  /// maximum value of the given graph map.
3873
  /// If the item set is empty, it returns \c INVALID.
3874
  ///
3875
  /// \param gr The graph for which the map is defined.
3876
  /// \param map The graph map.
3877
  /// \param comp Comparison function object.
3878
  template <typename GR, typename Map, typename Comp>
3879
  typename Map::Key mapMax(const GR& gr, const Map& map, const Comp& comp) {
3880
    typedef typename Map::Key Item;
3881
    typedef typename Map::Value Value;
3882
    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
3883

	
3884
    ItemIt max_item(gr);
3885
    if (max_item == INVALID) return INVALID;
3886
    Value max = map[max_item];
3887
    for (ItemIt it(gr); it != INVALID; ++it) {
3888
      if (comp(max, map[it])) {
3889
        max = map[it];
3890
        max_item = it;
3891
      }
3892
    }
3893
    return max_item;
3894
  }
3895

	
3896
  /// \brief Return the minimum value of a graph map.
3897
  ///
3898
  /// This function returns the minimum value of the given graph map.
3899
  /// The corresponding item set of the graph must not be empty.
3900
  ///
3901
  /// \param gr The graph for which the map is defined.
3902
  /// \param map The graph map.
3903
  template <typename GR, typename Map>
3904
  typename Map::Value mapMinValue(const GR& gr, const Map& map) {
3905
    return map[mapMin(gr, map, std::less<typename Map::Value>())];
3906
  }
3907

	
3908
  /// \brief Return the minimum value of a graph map.
3909
  ///
3910
  /// This function returns the minimum value of the given graph map.
3911
  /// The corresponding item set of the graph must not be empty.
3912
  ///
3913
  /// \param gr The graph for which the map is defined.
3914
  /// \param map The graph map.
3915
  /// \param comp Comparison function object.
3916
  template <typename GR, typename Map, typename Comp>
3917
  typename Map::Value
3918
  mapMinValue(const GR& gr, const Map& map, const Comp& comp) {
3919
    return map[mapMin(gr, map, comp)];
3920
  }
3921

	
3922
  /// \brief Return the maximum value of a graph map.
3923
  ///
3924
  /// This function returns the maximum value of the given graph map.
3925
  /// The corresponding item set of the graph must not be empty.
3926
  ///
3927
  /// \param gr The graph for which the map is defined.
3928
  /// \param map The graph map.
3929
  template <typename GR, typename Map>
3930
  typename Map::Value mapMaxValue(const GR& gr, const Map& map) {
3931
    return map[mapMax(gr, map, std::less<typename Map::Value>())];
3932
  }
3933

	
3934
  /// \brief Return the maximum value of a graph map.
3935
  ///
3936
  /// This function returns the maximum value of the given graph map.
3937
  /// The corresponding item set of the graph must not be empty.
3938
  ///
3939
  /// \param gr The graph for which the map is defined.
3940
  /// \param map The graph map.
3941
  /// \param comp Comparison function object.
3942
  template <typename GR, typename Map, typename Comp>
3943
  typename Map::Value
3944
  mapMaxValue(const GR& gr, const Map& map, const Comp& comp) {
3945
    return map[mapMax(gr, map, comp)];
3946
  }
3947

	
3948
  /// \brief Return an item having a specified value in a graph map.
3949
  ///
3950
  /// This function returns an item (\c Node, \c Arc or \c Edge) having
3951
  /// the specified assigned value in the given graph map.
3952
  /// If no such item exists, it returns \c INVALID.
3953
  ///
3954
  /// \param gr The graph for which the map is defined.
3955
  /// \param map The graph map.
3956
  /// \param val The value that have to be found.
3957
  template <typename GR, typename Map>
3958
  typename Map::Key
3959
  mapFind(const GR& gr, const Map& map, const typename Map::Value& val) {
3960
    typedef typename Map::Key Item;
3961
    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
3962

	
3963
    for (ItemIt it(gr); it != INVALID; ++it) {
3964
      if (map[it] == val) return it;
3965
    }
3966
    return INVALID;
3967
  }
3968

	
3969
  /// \brief Return an item having value for which a certain predicate is
3970
  /// true in a graph map.
3971
  ///
3972
  /// This function returns an item (\c Node, \c Arc or \c Edge) having
3973
  /// such assigned value for which the specified predicate is true
3974
  /// in the given graph map.
3975
  /// If no such item exists, it returns \c INVALID.
3976
  ///
3977
  /// \param gr The graph for which the map is defined.
3978
  /// \param map The graph map.
3979
  /// \param pred The predicate function object.
3980
  template <typename GR, typename Map, typename Pred>
3981
  typename Map::Key
3982
  mapFindIf(const GR& gr, const Map& map, const Pred& pred) {
3983
    typedef typename Map::Key Item;
3984
    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
3985

	
3986
    for (ItemIt it(gr); it != INVALID; ++it) {
3987
      if (pred(map[it])) return it;
3988
    }
3989
    return INVALID;
3990
  }
3991

	
3992
  /// \brief Return the number of items having a specified value in a
3993
  /// graph map.
3994
  ///
3995
  /// This function returns the number of items (\c Node, \c Arc or \c Edge)
3996
  /// having the specified assigned value in the given graph map.
3997
  ///
3998
  /// \param gr The graph for which the map is defined.
3999
  /// \param map The graph map.
4000
  /// \param val The value that have to be counted.
4001
  template <typename GR, typename Map>
4002
  int mapCount(const GR& gr, const Map& map, const typename Map::Value& val) {
4003
    typedef typename Map::Key Item;
4004
    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
4005

	
4006
    int cnt = 0;
4007
    for (ItemIt it(gr); it != INVALID; ++it) {
4008
      if (map[it] == val) ++cnt;
4009
    }
4010
    return cnt;
4011
  }
4012

	
4013
  /// \brief Return the number of items having values for which a certain
4014
  /// predicate is true in a graph map.
4015
  ///
4016
  /// This function returns the number of items (\c Node, \c Arc or \c Edge)
4017
  /// having such assigned values for which the specified predicate is true
4018
  /// in the given graph map.
4019
  ///
4020
  /// \param gr The graph for which the map is defined.
4021
  /// \param map The graph map.
4022
  /// \param pred The predicate function object.
4023
  template <typename GR, typename Map, typename Pred>
4024
  int mapCountIf(const GR& gr, const Map& map, const Pred& pred) {
4025
    typedef typename Map::Key Item;
4026
    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
4027

	
4028
    int cnt = 0;
4029
    for (ItemIt it(gr); it != INVALID; ++it) {
4030
      if (pred(map[it])) ++cnt;
4031
    }
4032
    return cnt;
4033
  }
4034

	
4035
  /// \brief Fill a graph map with a certain value.
4036
  ///
4037
  /// This function sets the specified value for all items (\c Node,
4038
  /// \c Arc or \c Edge) in the given graph map.
4039
  ///
4040
  /// \param gr The graph for which the map is defined.
4041
  /// \param map The graph map. It must conform to the
4042
  /// \ref concepts::WriteMap "WriteMap" concept.
4043
  /// \param val The value.
4044
  template <typename GR, typename Map>
4045
  void mapFill(const GR& gr, Map& map, const typename Map::Value& val) {
4046
    typedef typename Map::Key Item;
4047
    typedef typename ItemSetTraits<GR, Item>::ItemIt ItemIt;
4048

	
4049
    for (ItemIt it(gr); it != INVALID; ++it) {
4050
      map.set(it, val);
4051
    }
4052
  }
4053

	
2803 4054
  /// @}
2804 4055
}
2805 4056

	
2806 4057
#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-2009
5
 * Copyright (C) 2003-2010
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_MAX_MATCHING_H
20
#define LEMON_MAX_MATCHING_H
19
#ifndef LEMON_MATCHING_H
20
#define LEMON_MATCHING_H
21 21

	
22 22
#include <vector>
23 23
#include <queue>
24 24
#include <set>
25 25
#include <limits>
26 26

	
27 27
#include <lemon/core.h>
28 28
#include <lemon/unionfind.h>
29 29
#include <lemon/bin_heap.h>
30 30
#include <lemon/maps.h>
31
#include <lemon/fractional_matching.h>
31 32

	
32 33
///\ingroup matching
33 34
///\file
34 35
///\brief Maximum matching algorithms in general graphs.
35 36

	
36 37
namespace lemon {
37 38

	
38 39
  /// \ingroup matching
39 40
  ///
40 41
  /// \brief Maximum cardinality matching in general graphs
41 42
  ///
42 43
  /// This class implements Edmonds' alternating forest matching algorithm
43 44
  /// for finding a maximum cardinality matching in a general undirected graph.
44
  /// It can be started from an arbitrary initial matching 
45
  /// It can be started from an arbitrary initial matching
45 46
  /// (the default is the empty one).
46 47
  ///
47 48
  /// The dual solution of the problem is a map of the nodes to
48 49
  /// \ref MaxMatching::Status "Status", having values \c EVEN (or \c D),
49 50
  /// \c ODD (or \c A) and \c MATCHED (or \c C) defining the Gallai-Edmonds
50 51
  /// decomposition of the graph. The nodes in \c EVEN/D induce a subgraph
51 52
  /// with factor-critical components, the nodes in \c ODD/A form the
52 53
  /// canonical barrier, and the nodes in \c MATCHED/C induce a graph having
53 54
  /// a perfect matching. The number of the factor-critical components
54 55
  /// minus the number of barrier nodes is a lower bound on the
55 56
  /// unmatched nodes, and the matching is optimal if and only if this bound is
56 57
  /// tight. This decomposition can be obtained using \ref status() or
57 58
  /// \ref statusMap() after running the algorithm.
58 59
  ///
59 60
  /// \tparam GR The undirected graph type the algorithm runs on.
60 61
  template <typename GR>
61 62
  class MaxMatching {
62 63
  public:
63 64

	
64 65
    /// The graph type of the algorithm
65 66
    typedef GR Graph;
66 67
    /// The type of the matching map
67 68
    typedef typename Graph::template NodeMap<typename Graph::Arc>
68 69
    MatchingMap;
69 70

	
70 71
    ///\brief Status constants for Gallai-Edmonds decomposition.
71 72
    ///
72
    ///These constants are used for indicating the Gallai-Edmonds 
73
    ///These constants are used for indicating the Gallai-Edmonds
73 74
    ///decomposition of a graph. The nodes with status \c EVEN (or \c D)
74 75
    ///induce a subgraph with factor-critical components, the nodes with
75 76
    ///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
    ///with status \c MATCHED (or \c C) induce a subgraph having a
77 78
    ///perfect matching.
78 79
    enum Status {
79 80
      EVEN = 1,       ///< = 1. (\c D is an alias for \c EVEN.)
80 81
      D = 1,
81 82
      MATCHED = 0,    ///< = 0. (\c C is an alias for \c MATCHED.)
82 83
      C = 0,
83 84
      ODD = -1,       ///< = -1. (\c A is an alias for \c ODD.)
84 85
      A = -1,
85 86
      UNMATCHED = -2  ///< = -2.
86 87
    };
87 88

	
88 89
    /// The type of the status map
89 90
    typedef typename Graph::template NodeMap<Status> StatusMap;
90 91

	
91 92
  private:
92 93

	
93 94
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
94 95

	
95 96
    typedef UnionFindEnum<IntNodeMap> BlossomSet;
96 97
    typedef ExtendFindEnum<IntNodeMap> TreeSet;
97 98
    typedef RangeMap<Node> NodeIntMap;
98 99
    typedef MatchingMap EarMap;
99 100
    typedef std::vector<Node> NodeQueue;
100 101

	
101 102
    const Graph& _graph;
102 103
    MatchingMap* _matching;
103 104
    StatusMap* _status;
104 105

	
105 106
    EarMap* _ear;
106 107

	
107 108
    IntNodeMap* _blossom_set_index;
108 109
    BlossomSet* _blossom_set;
109 110
    NodeIntMap* _blossom_rep;
110 111

	
111 112
    IntNodeMap* _tree_set_index;
112 113
    TreeSet* _tree_set;
113 114

	
114 115
    NodeQueue _node_queue;
115 116
    int _process, _postpone, _last;
116 117

	
117 118
    int _node_num;
118 119

	
119 120
  private:
120 121

	
121 122
    void createStructures() {
122 123
      _node_num = countNodes(_graph);
123 124
      if (!_matching) {
124 125
        _matching = new MatchingMap(_graph);
125 126
      }
126 127
      if (!_status) {
127 128
        _status = new StatusMap(_graph);
128 129
      }
129 130
      if (!_ear) {
130 131
        _ear = new EarMap(_graph);
131 132
      }
132 133
      if (!_blossom_set) {
133 134
        _blossom_set_index = new IntNodeMap(_graph);
134 135
        _blossom_set = new BlossomSet(*_blossom_set_index);
135 136
      }
136 137
      if (!_blossom_rep) {
137 138
        _blossom_rep = new NodeIntMap(_node_num);
138 139
      }
139 140
      if (!_tree_set) {
140 141
        _tree_set_index = new IntNodeMap(_graph);
141 142
        _tree_set = new TreeSet(*_tree_set_index);
142 143
      }
143 144
      _node_queue.resize(_node_num);
144 145
    }
145 146

	
146 147
    void destroyStructures() {
147 148
      if (_matching) {
148 149
        delete _matching;
149 150
      }
150 151
      if (_status) {
151 152
        delete _status;
152 153
      }
153 154
      if (_ear) {
154 155
        delete _ear;
155 156
      }
156 157
      if (_blossom_set) {
157 158
        delete _blossom_set;
158 159
        delete _blossom_set_index;
159 160
      }
160 161
      if (_blossom_rep) {
161 162
        delete _blossom_rep;
162 163
      }
163 164
      if (_tree_set) {
164 165
        delete _tree_set_index;
165 166
        delete _tree_set;
166 167
      }
167 168
    }
168 169

	
169 170
    void processDense(const Node& n) {
170 171
      _process = _postpone = _last = 0;
171 172
      _node_queue[_last++] = n;
172 173

	
173 174
      while (_process != _last) {
174 175
        Node u = _node_queue[_process++];
175 176
        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
176 177
          Node v = _graph.target(a);
177 178
          if ((*_status)[v] == MATCHED) {
178 179
            extendOnArc(a);
179 180
          } else if ((*_status)[v] == UNMATCHED) {
180 181
            augmentOnArc(a);
181 182
            return;
182 183
          }
183 184
        }
184 185
      }
185 186

	
186 187
      while (_postpone != _last) {
187 188
        Node u = _node_queue[_postpone++];
188 189

	
189 190
        for (OutArcIt a(_graph, u); a != INVALID ; ++a) {
190 191
          Node v = _graph.target(a);
191 192

	
192 193
          if ((*_status)[v] == EVEN) {
193 194
            if (_blossom_set->find(u) != _blossom_set->find(v)) {
194 195
              shrinkOnEdge(a);
195 196
            }
196 197
          }
197 198

	
198 199
          while (_process != _last) {
199 200
            Node w = _node_queue[_process++];
200 201
            for (OutArcIt b(_graph, w); b != INVALID; ++b) {
201 202
              Node x = _graph.target(b);
202 203
              if ((*_status)[x] == MATCHED) {
203 204
                extendOnArc(b);
204 205
              } else if ((*_status)[x] == UNMATCHED) {
205 206
                augmentOnArc(b);
206 207
                return;
207 208
              }
208 209
            }
209 210
          }
210 211
        }
211 212
      }
212 213
    }
213 214

	
214 215
    void processSparse(const Node& n) {
215 216
      _process = _last = 0;
216 217
      _node_queue[_last++] = n;
217 218
      while (_process != _last) {
218 219
        Node u = _node_queue[_process++];
219 220
        for (OutArcIt a(_graph, u); a != INVALID; ++a) {
220 221
          Node v = _graph.target(a);
221 222

	
222 223
          if ((*_status)[v] == EVEN) {
223 224
            if (_blossom_set->find(u) != _blossom_set->find(v)) {
224 225
              shrinkOnEdge(a);
225 226
            }
226 227
          } else if ((*_status)[v] == MATCHED) {
227 228
            extendOnArc(a);
228 229
          } else if ((*_status)[v] == UNMATCHED) {
229 230
            augmentOnArc(a);
230 231
            return;
231 232
          }
232 233
        }
233 234
      }
234 235
    }
235 236

	
236 237
    void shrinkOnEdge(const Edge& e) {
237 238
      Node nca = INVALID;
238 239

	
239 240
      {
240 241
        std::set<Node> left_set, right_set;
241 242

	
242 243
        Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))];
243 244
        left_set.insert(left);
244 245

	
245 246
        Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))];
246 247
        right_set.insert(right);
247 248

	
248 249
        while (true) {
249 250
          if ((*_matching)[left] == INVALID) break;
250 251
          left = _graph.target((*_matching)[left]);
251 252
          left = (*_blossom_rep)[_blossom_set->
252 253
                                 find(_graph.target((*_ear)[left]))];
253 254
          if (right_set.find(left) != right_set.end()) {
254 255
            nca = left;
255 256
            break;
256 257
          }
257 258
          left_set.insert(left);
258 259

	
259 260
          if ((*_matching)[right] == INVALID) break;
260 261
          right = _graph.target((*_matching)[right]);
261 262
          right = (*_blossom_rep)[_blossom_set->
262 263
                                  find(_graph.target((*_ear)[right]))];
263 264
          if (left_set.find(right) != left_set.end()) {
264 265
            nca = right;
265 266
            break;
266 267
          }
267 268
          right_set.insert(right);
268 269
        }
269 270

	
270 271
        if (nca == INVALID) {
271 272
          if ((*_matching)[left] == INVALID) {
272 273
            nca = right;
273 274
            while (left_set.find(nca) == left_set.end()) {
274 275
              nca = _graph.target((*_matching)[nca]);
275 276
              nca =(*_blossom_rep)[_blossom_set->
276 277
                                   find(_graph.target((*_ear)[nca]))];
277 278
            }
278 279
          } else {
279 280
            nca = left;
280 281
            while (right_set.find(nca) == right_set.end()) {
281 282
              nca = _graph.target((*_matching)[nca]);
282 283
              nca = (*_blossom_rep)[_blossom_set->
283 284
                                   find(_graph.target((*_ear)[nca]))];
284 285
            }
285 286
          }
286 287
        }
287 288
      }
288 289

	
289 290
      {
290 291

	
291 292
        Node node = _graph.u(e);
292 293
        Arc arc = _graph.direct(e, true);
293 294
        Node base = (*_blossom_rep)[_blossom_set->find(node)];
294 295

	
295 296
        while (base != nca) {
296 297
          (*_ear)[node] = arc;
297 298

	
298 299
          Node n = node;
299 300
          while (n != base) {
300 301
            n = _graph.target((*_matching)[n]);
301 302
            Arc a = (*_ear)[n];
302 303
            n = _graph.target(a);
303 304
            (*_ear)[n] = _graph.oppositeArc(a);
304 305
          }
305 306
          node = _graph.target((*_matching)[base]);
306 307
          _tree_set->erase(base);
307 308
          _tree_set->erase(node);
308 309
          _blossom_set->insert(node, _blossom_set->find(base));
309 310
          (*_status)[node] = EVEN;
310 311
          _node_queue[_last++] = node;
311 312
          arc = _graph.oppositeArc((*_ear)[node]);
312 313
          node = _graph.target((*_ear)[node]);
313 314
          base = (*_blossom_rep)[_blossom_set->find(node)];
314 315
          _blossom_set->join(_graph.target(arc), base);
315 316
        }
316 317
      }
317 318

	
318 319
      (*_blossom_rep)[_blossom_set->find(nca)] = nca;
319 320

	
320 321
      {
321 322

	
322 323
        Node node = _graph.v(e);
323 324
        Arc arc = _graph.direct(e, false);
324 325
        Node base = (*_blossom_rep)[_blossom_set->find(node)];
325 326

	
326 327
        while (base != nca) {
327 328
          (*_ear)[node] = arc;
328 329

	
329 330
          Node n = node;
330 331
          while (n != base) {
331 332
            n = _graph.target((*_matching)[n]);
332 333
            Arc a = (*_ear)[n];
333 334
            n = _graph.target(a);
334 335
            (*_ear)[n] = _graph.oppositeArc(a);
335 336
          }
336 337
          node = _graph.target((*_matching)[base]);
337 338
          _tree_set->erase(base);
338 339
          _tree_set->erase(node);
339 340
          _blossom_set->insert(node, _blossom_set->find(base));
340 341
          (*_status)[node] = EVEN;
341 342
          _node_queue[_last++] = node;
342 343
          arc = _graph.oppositeArc((*_ear)[node]);
343 344
          node = _graph.target((*_ear)[node]);
344 345
          base = (*_blossom_rep)[_blossom_set->find(node)];
345 346
          _blossom_set->join(_graph.target(arc), base);
346 347
        }
347 348
      }
348 349

	
349 350
      (*_blossom_rep)[_blossom_set->find(nca)] = nca;
350 351
    }
351 352

	
352 353
    void extendOnArc(const Arc& a) {
353 354
      Node base = _graph.source(a);
354 355
      Node odd = _graph.target(a);
355 356

	
356 357
      (*_ear)[odd] = _graph.oppositeArc(a);
357 358
      Node even = _graph.target((*_matching)[odd]);
358 359
      (*_blossom_rep)[_blossom_set->insert(even)] = even;
359 360
      (*_status)[odd] = ODD;
360 361
      (*_status)[even] = EVEN;
361 362
      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]);
362 363
      _tree_set->insert(odd, tree);
363 364
      _tree_set->insert(even, tree);
364 365
      _node_queue[_last++] = even;
365 366

	
366 367
    }
367 368

	
368 369
    void augmentOnArc(const Arc& a) {
369 370
      Node even = _graph.source(a);
370 371
      Node odd = _graph.target(a);
371 372

	
372 373
      int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]);
373 374

	
374 375
      (*_matching)[odd] = _graph.oppositeArc(a);
375 376
      (*_status)[odd] = MATCHED;
376 377

	
377 378
      Arc arc = (*_matching)[even];
378 379
      (*_matching)[even] = a;
379 380

	
380 381
      while (arc != INVALID) {
381 382
        odd = _graph.target(arc);
382 383
        arc = (*_ear)[odd];
383 384
        even = _graph.target(arc);
384 385
        (*_matching)[odd] = arc;
385 386
        arc = (*_matching)[even];
386 387
        (*_matching)[even] = _graph.oppositeArc((*_matching)[odd]);
387 388
      }
388 389

	
389 390
      for (typename TreeSet::ItemIt it(*_tree_set, tree);
390 391
           it != INVALID; ++it) {
391 392
        if ((*_status)[it] == ODD) {
392 393
          (*_status)[it] = MATCHED;
393 394
        } else {
394 395
          int blossom = _blossom_set->find(it);
395 396
          for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
396 397
               jt != INVALID; ++jt) {
397 398
            (*_status)[jt] = MATCHED;
398 399
          }
399 400
          _blossom_set->eraseClass(blossom);
400 401
        }
401 402
      }
402 403
      _tree_set->eraseClass(tree);
403 404

	
404 405
    }
405 406

	
406 407
  public:
407 408

	
408 409
    /// \brief Constructor
409 410
    ///
410 411
    /// Constructor.
411 412
    MaxMatching(const Graph& graph)
412 413
      : _graph(graph), _matching(0), _status(0), _ear(0),
413 414
        _blossom_set_index(0), _blossom_set(0), _blossom_rep(0),
414 415
        _tree_set_index(0), _tree_set(0) {}
415 416

	
416 417
    ~MaxMatching() {
417 418
      destroyStructures();
418 419
    }
419 420

	
420 421
    /// \name Execution Control
421 422
    /// The simplest way to execute the algorithm is to use the
422 423
    /// \c run() member function.\n
423 424
    /// If you need better control on the execution, you have to call
424 425
    /// one of the functions \ref init(), \ref greedyInit() or
425 426
    /// \ref matchingInit() first, then you can start the algorithm with
426 427
    /// \ref startSparse() or \ref startDense().
427 428

	
428 429
    ///@{
429 430

	
430 431
    /// \brief Set the initial matching to the empty matching.
431 432
    ///
432 433
    /// This function sets the initial matching to the empty matching.
433 434
    void init() {
434 435
      createStructures();
435 436
      for(NodeIt n(_graph); n != INVALID; ++n) {
436 437
        (*_matching)[n] = INVALID;
437 438
        (*_status)[n] = UNMATCHED;
438 439
      }
439 440
    }
440 441

	
441 442
    /// \brief Find an initial matching in a greedy way.
442 443
    ///
443 444
    /// This function finds an initial matching in a greedy way.
444 445
    void greedyInit() {
445 446
      createStructures();
446 447
      for (NodeIt n(_graph); n != INVALID; ++n) {
447 448
        (*_matching)[n] = INVALID;
448 449
        (*_status)[n] = UNMATCHED;
449 450
      }
450 451
      for (NodeIt n(_graph); n != INVALID; ++n) {
451 452
        if ((*_matching)[n] == INVALID) {
452 453
          for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
453 454
            Node v = _graph.target(a);
454 455
            if ((*_matching)[v] == INVALID && v != n) {
455 456
              (*_matching)[n] = a;
456 457
              (*_status)[n] = MATCHED;
457 458
              (*_matching)[v] = _graph.oppositeArc(a);
458 459
              (*_status)[v] = MATCHED;
459 460
              break;
460 461
            }
461 462
          }
462 463
        }
463 464
      }
464 465
    }
465 466

	
466 467

	
467 468
    /// \brief Initialize the matching from a map.
468 469
    ///
469 470
    /// This function initializes the matching from a \c bool valued edge
470 471
    /// map. This map should have the property that there are no two incident
471 472
    /// edges with \c true value, i.e. it really contains a matching.
472 473
    /// \return \c true if the map contains a matching.
473 474
    template <typename MatchingMap>
474 475
    bool matchingInit(const MatchingMap& matching) {
475 476
      createStructures();
476 477

	
477 478
      for (NodeIt n(_graph); n != INVALID; ++n) {
478 479
        (*_matching)[n] = INVALID;
479 480
        (*_status)[n] = UNMATCHED;
480 481
      }
481 482
      for(EdgeIt e(_graph); e!=INVALID; ++e) {
482 483
        if (matching[e]) {
483 484

	
484 485
          Node u = _graph.u(e);
485 486
          if ((*_matching)[u] != INVALID) return false;
486 487
          (*_matching)[u] = _graph.direct(e, true);
487 488
          (*_status)[u] = MATCHED;
488 489

	
489 490
          Node v = _graph.v(e);
490 491
          if ((*_matching)[v] != INVALID) return false;
491 492
          (*_matching)[v] = _graph.direct(e, false);
492 493
          (*_status)[v] = MATCHED;
493 494
        }
494 495
      }
495 496
      return true;
496 497
    }
497 498

	
498 499
    /// \brief Start Edmonds' algorithm
499 500
    ///
500 501
    /// This function runs the original Edmonds' algorithm.
501 502
    ///
502 503
    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
503 504
    /// called before using this function.
504 505
    void startSparse() {
505 506
      for(NodeIt n(_graph); n != INVALID; ++n) {
506 507
        if ((*_status)[n] == UNMATCHED) {
507 508
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
508 509
          _tree_set->insert(n);
509 510
          (*_status)[n] = EVEN;
510 511
          processSparse(n);
511 512
        }
512 513
      }
513 514
    }
514 515

	
515
    /// \brief Start Edmonds' algorithm with a heuristic improvement 
516
    /// \brief Start Edmonds' algorithm with a heuristic improvement
516 517
    /// for dense graphs
517 518
    ///
518 519
    /// This function runs Edmonds' algorithm with a heuristic of postponing
519 520
    /// shrinks, therefore resulting in a faster algorithm for dense graphs.
520 521
    ///
521 522
    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
522 523
    /// called before using this function.
523 524
    void startDense() {
524 525
      for(NodeIt n(_graph); n != INVALID; ++n) {
525 526
        if ((*_status)[n] == UNMATCHED) {
526 527
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
527 528
          _tree_set->insert(n);
528 529
          (*_status)[n] = EVEN;
529 530
          processDense(n);
530 531
        }
531 532
      }
532 533
    }
533 534

	
534 535

	
535 536
    /// \brief Run Edmonds' algorithm
536 537
    ///
537
    /// This function runs Edmonds' algorithm. An additional heuristic of 
538
    /// postponing shrinks is used for relatively dense graphs 
538
    /// This function runs Edmonds' algorithm. An additional heuristic of
539
    /// postponing shrinks is used for relatively dense graphs
539 540
    /// (for which <tt>m>=2*n</tt> holds).
540 541
    void run() {
541 542
      if (countEdges(_graph) < 2 * countNodes(_graph)) {
542 543
        greedyInit();
543 544
        startSparse();
544 545
      } else {
545 546
        init();
546 547
        startDense();
547 548
      }
548 549
    }
549 550

	
550 551
    /// @}
551 552

	
552 553
    /// \name Primal Solution
553 554
    /// Functions to get the primal solution, i.e. the maximum matching.
554 555

	
555 556
    /// @{
556 557

	
557 558
    /// \brief Return the size (cardinality) of the matching.
558 559
    ///
559
    /// This function returns the size (cardinality) of the current matching. 
560
    /// This function returns the size (cardinality) of the current matching.
560 561
    /// After run() it returns the size of the maximum matching in the graph.
561 562
    int matchingSize() const {
562 563
      int size = 0;
563 564
      for (NodeIt n(_graph); n != INVALID; ++n) {
564 565
        if ((*_matching)[n] != INVALID) {
565 566
          ++size;
566 567
        }
567 568
      }
568 569
      return size / 2;
569 570
    }
570 571

	
571 572
    /// \brief Return \c true if the given edge is in the matching.
572 573
    ///
573
    /// This function returns \c true if the given edge is in the current 
574
    /// This function returns \c true if the given edge is in the current
574 575
    /// matching.
575 576
    bool matching(const Edge& edge) const {
576 577
      return edge == (*_matching)[_graph.u(edge)];
577 578
    }
578 579

	
579 580
    /// \brief Return the matching arc (or edge) incident to the given node.
580 581
    ///
581 582
    /// 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
    /// given node in the current matching or \c INVALID if the node is
583 584
    /// not covered by the matching.
584 585
    Arc matching(const Node& n) const {
585 586
      return (*_matching)[n];
586 587
    }
587 588

	
588 589
    /// \brief Return a const reference to the matching map.
589 590
    ///
590 591
    /// This function returns a const reference to a node map that stores
591 592
    /// the matching arc (or edge) incident to each node.
592 593
    const MatchingMap& matchingMap() const {
593 594
      return *_matching;
594 595
    }
595 596

	
596 597
    /// \brief Return the mate of the given node.
597 598
    ///
598
    /// This function returns the mate of the given node in the current 
599
    /// This function returns the mate of the given node in the current
599 600
    /// matching or \c INVALID if the node is not covered by the matching.
600 601
    Node mate(const Node& n) const {
601 602
      return (*_matching)[n] != INVALID ?
602 603
        _graph.target((*_matching)[n]) : INVALID;
603 604
    }
604 605

	
605 606
    /// @}
606 607

	
607 608
    /// \name Dual Solution
608
    /// Functions to get the dual solution, i.e. the Gallai-Edmonds 
609
    /// Functions to get the dual solution, i.e. the Gallai-Edmonds
609 610
    /// decomposition.
610 611

	
611 612
    /// @{
612 613

	
613 614
    /// \brief Return the status of the given node in the Edmonds-Gallai
614 615
    /// decomposition.
615 616
    ///
616 617
    /// This function returns the \ref Status "status" of the given node
617 618
    /// in the Edmonds-Gallai decomposition.
618 619
    Status status(const Node& n) const {
619 620
      return (*_status)[n];
620 621
    }
621 622

	
622 623
    /// \brief Return a const reference to the status map, which stores
623 624
    /// the Edmonds-Gallai decomposition.
624 625
    ///
625 626
    /// This function returns a const reference to a node map that stores the
626 627
    /// \ref Status "status" of each node in the Edmonds-Gallai decomposition.
627 628
    const StatusMap& statusMap() const {
628 629
      return *_status;
629 630
    }
630 631

	
631 632
    /// \brief Return \c true if the given node is in the barrier.
632 633
    ///
633 634
    /// This function returns \c true if the given node is in the barrier.
634 635
    bool barrier(const Node& n) const {
635 636
      return (*_status)[n] == ODD;
636 637
    }
637 638

	
638 639
    /// @}
639 640

	
640 641
  };
641 642

	
642 643
  /// \ingroup matching
643 644
  ///
644 645
  /// \brief Weighted matching in general graphs
645 646
  ///
646 647
  /// This class provides an efficient implementation of Edmond's
647 648
  /// maximum weighted matching algorithm. The implementation is based
648 649
  /// on extensive use of priority queues and provides
649 650
  /// \f$O(nm\log n)\f$ time complexity.
650 651
  ///
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 
652
  /// The maximum weighted matching problem is to find a subset of the
653
  /// edges in an undirected graph with maximum overall weight for which
653 654
  /// each node has at most one incident edge.
654 655
  /// It can be formulated with the following linear program.
655 656
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
656 657
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
657 658
      \quad \forall B\in\mathcal{O}\f] */
658 659
  /// \f[x_e \ge 0\quad \forall e\in E\f]
659 660
  /// \f[\max \sum_{e\in E}x_ew_e\f]
660 661
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
661 662
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
662 663
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
663 664
  /// subsets of the nodes.
664 665
  ///
665 666
  /// The algorithm calculates an optimal matching and a proof of the
666 667
  /// optimality. The solution of the dual problem can be used to check
667 668
  /// the result of the algorithm. The dual linear problem is the
668 669
  /// following.
669 670
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
670 671
      z_B \ge w_{uv} \quad \forall uv\in E\f] */
671 672
  /// \f[y_u \ge 0 \quad \forall u \in V\f]
672 673
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
673 674
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
674 675
      \frac{\vert B \vert - 1}{2}z_B\f] */
675 676
  ///
676
  /// The algorithm can be executed with the run() function. 
677
  /// The algorithm can be executed with the run() function.
677 678
  /// 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. 
679
  /// can be obtained using the query functions and the
680
  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class,
681
  /// which is able to iterate on the nodes of a blossom.
681 682
  /// If the value type is integer, then the dual solution is multiplied
682 683
  /// by \ref MaxWeightedMatching::dualScale "4".
683 684
  ///
684 685
  /// \tparam GR The undirected graph type the algorithm runs on.
685
  /// \tparam WM The type edge weight map. The default type is 
686
  /// \tparam WM The type edge weight map. The default type is
686 687
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
687 688
#ifdef DOXYGEN
688 689
  template <typename GR, typename WM>
689 690
#else
690 691
  template <typename GR,
691 692
            typename WM = typename GR::template EdgeMap<int> >
692 693
#endif
693 694
  class MaxWeightedMatching {
694 695
  public:
695 696

	
696 697
    /// The graph type of the algorithm
697 698
    typedef GR Graph;
698 699
    /// The type of the edge weight map
699 700
    typedef WM WeightMap;
700 701
    /// The value type of the edge weights
701 702
    typedef typename WeightMap::Value Value;
702 703

	
703 704
    /// The type of the matching map
704 705
    typedef typename Graph::template NodeMap<typename Graph::Arc>
705 706
    MatchingMap;
706 707

	
707 708
    /// \brief Scaling factor for dual solution
708 709
    ///
709 710
    /// Scaling factor for dual solution. It is equal to 4 or 1
710 711
    /// according to the value type.
711 712
    static const int dualScale =
712 713
      std::numeric_limits<Value>::is_integer ? 4 : 1;
713 714

	
714 715
  private:
715 716

	
716 717
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
717 718

	
718 719
    typedef typename Graph::template NodeMap<Value> NodePotential;
719 720
    typedef std::vector<Node> BlossomNodeList;
720 721

	
721 722
    struct BlossomVariable {
722 723
      int begin, end;
723 724
      Value value;
724 725

	
725 726
      BlossomVariable(int _begin, int _end, Value _value)
726 727
        : begin(_begin), end(_end), value(_value) {}
727 728

	
728 729
    };
729 730

	
730 731
    typedef std::vector<BlossomVariable> BlossomPotential;
731 732

	
732 733
    const Graph& _graph;
733 734
    const WeightMap& _weight;
734 735

	
735 736
    MatchingMap* _matching;
736 737

	
737 738
    NodePotential* _node_potential;
738 739

	
739 740
    BlossomPotential _blossom_potential;
740 741
    BlossomNodeList _blossom_node_list;
741 742

	
742 743
    int _node_num;
743 744
    int _blossom_num;
744 745

	
745 746
    typedef RangeMap<int> IntIntMap;
746 747

	
747 748
    enum Status {
748
      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
749
      EVEN = -1, MATCHED = 0, ODD = 1
749 750
    };
750 751

	
751 752
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
752 753
    struct BlossomData {
753 754
      int tree;
754 755
      Status status;
755 756
      Arc pred, next;
756 757
      Value pot, offset;
757 758
      Node base;
758 759
    };
759 760

	
760 761
    IntNodeMap *_blossom_index;
761 762
    BlossomSet *_blossom_set;
762 763
    RangeMap<BlossomData>* _blossom_data;
763 764

	
764 765
    IntNodeMap *_node_index;
765 766
    IntArcMap *_node_heap_index;
766 767

	
767 768
    struct NodeData {
768 769

	
769 770
      NodeData(IntArcMap& node_heap_index)
770 771
        : heap(node_heap_index) {}
771 772

	
772 773
      int blossom;
773 774
      Value pot;
774 775
      BinHeap<Value, IntArcMap> heap;
775 776
      std::map<int, Arc> heap_index;
776 777

	
777 778
      int tree;
778 779
    };
779 780

	
780 781
    RangeMap<NodeData>* _node_data;
781 782

	
782 783
    typedef ExtendFindEnum<IntIntMap> TreeSet;
783 784

	
784 785
    IntIntMap *_tree_set_index;
785 786
    TreeSet *_tree_set;
786 787

	
787 788
    IntNodeMap *_delta1_index;
788 789
    BinHeap<Value, IntNodeMap> *_delta1;
789 790

	
790 791
    IntIntMap *_delta2_index;
791 792
    BinHeap<Value, IntIntMap> *_delta2;
792 793

	
793 794
    IntEdgeMap *_delta3_index;
794 795
    BinHeap<Value, IntEdgeMap> *_delta3;
795 796

	
796 797
    IntIntMap *_delta4_index;
797 798
    BinHeap<Value, IntIntMap> *_delta4;
798 799

	
799 800
    Value _delta_sum;
801
    int _unmatched;
802

	
803
    typedef MaxWeightedFractionalMatching<Graph, WeightMap> FractionalMatching;
804
    FractionalMatching *_fractional;
800 805

	
801 806
    void createStructures() {
802 807
      _node_num = countNodes(_graph);
803 808
      _blossom_num = _node_num * 3 / 2;
804 809

	
805 810
      if (!_matching) {
806 811
        _matching = new MatchingMap(_graph);
807 812
      }
808 813

	
809 814
      if (!_node_potential) {
810 815
        _node_potential = new NodePotential(_graph);
811 816
      }
812 817

	
813 818
      if (!_blossom_set) {
814 819
        _blossom_index = new IntNodeMap(_graph);
815 820
        _blossom_set = new BlossomSet(*_blossom_index);
816 821
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
817 822
      } else if (_blossom_data->size() != _blossom_num) {
818 823
        delete _blossom_data;
819 824
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
820 825
      }
821 826

	
822 827
      if (!_node_index) {
823 828
        _node_index = new IntNodeMap(_graph);
824 829
        _node_heap_index = new IntArcMap(_graph);
825 830
        _node_data = new RangeMap<NodeData>(_node_num,
826 831
                                            NodeData(*_node_heap_index));
827 832
      } else {
828 833
        delete _node_data;
829 834
        _node_data = new RangeMap<NodeData>(_node_num,
830 835
                                            NodeData(*_node_heap_index));
831 836
      }
832 837

	
833 838
      if (!_tree_set) {
834 839
        _tree_set_index = new IntIntMap(_blossom_num);
835 840
        _tree_set = new TreeSet(*_tree_set_index);
836 841
      } else {
837 842
        _tree_set_index->resize(_blossom_num);
838 843
      }
839 844

	
840 845
      if (!_delta1) {
841 846
        _delta1_index = new IntNodeMap(_graph);
842 847
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
843 848
      }
844 849

	
845 850
      if (!_delta2) {
846 851
        _delta2_index = new IntIntMap(_blossom_num);
847 852
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
848 853
      } else {
849 854
        _delta2_index->resize(_blossom_num);
850 855
      }
851 856

	
852 857
      if (!_delta3) {
853 858
        _delta3_index = new IntEdgeMap(_graph);
854 859
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
855 860
      }
856 861

	
857 862
      if (!_delta4) {
858 863
        _delta4_index = new IntIntMap(_blossom_num);
859 864
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
860 865
      } else {
861 866
        _delta4_index->resize(_blossom_num);
862 867
      }
863 868
    }
864 869

	
865 870
    void destroyStructures() {
866
      _node_num = countNodes(_graph);
867
      _blossom_num = _node_num * 3 / 2;
868

	
869 871
      if (_matching) {
870 872
        delete _matching;
871 873
      }
872 874
      if (_node_potential) {
873 875
        delete _node_potential;
874 876
      }
875 877
      if (_blossom_set) {
876 878
        delete _blossom_index;
877 879
        delete _blossom_set;
878 880
        delete _blossom_data;
879 881
      }
880 882

	
881 883
      if (_node_index) {
882 884
        delete _node_index;
883 885
        delete _node_heap_index;
884 886
        delete _node_data;
885 887
      }
886 888

	
887 889
      if (_tree_set) {
888 890
        delete _tree_set_index;
889 891
        delete _tree_set;
890 892
      }
891 893
      if (_delta1) {
892 894
        delete _delta1_index;
893 895
        delete _delta1;
894 896
      }
895 897
      if (_delta2) {
896 898
        delete _delta2_index;
897 899
        delete _delta2;
898 900
      }
899 901
      if (_delta3) {
900 902
        delete _delta3_index;
901 903
        delete _delta3;
902 904
      }
903 905
      if (_delta4) {
904 906
        delete _delta4_index;
905 907
        delete _delta4;
906 908
      }
907 909
    }
908 910

	
909 911
    void matchedToEven(int blossom, int tree) {
910 912
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
911 913
        _delta2->erase(blossom);
912 914
      }
913 915

	
914 916
      if (!_blossom_set->trivial(blossom)) {
915 917
        (*_blossom_data)[blossom].pot -=
916 918
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
917 919
      }
918 920

	
919 921
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
920 922
           n != INVALID; ++n) {
921 923

	
922 924
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
923 925
        int ni = (*_node_index)[n];
924 926

	
925 927
        (*_node_data)[ni].heap.clear();
926 928
        (*_node_data)[ni].heap_index.clear();
927 929

	
928 930
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
929 931

	
930 932
        _delta1->push(n, (*_node_data)[ni].pot);
931 933

	
932 934
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
933 935
          Node v = _graph.source(e);
934 936
          int vb = _blossom_set->find(v);
935 937
          int vi = (*_node_index)[v];
936 938

	
937 939
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
938 940
            dualScale * _weight[e];
939 941

	
940 942
          if ((*_blossom_data)[vb].status == EVEN) {
941 943
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
942 944
              _delta3->push(e, rw / 2);
943 945
            }
944
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
945
            if (_delta3->state(e) != _delta3->IN_HEAP) {
946
              _delta3->push(e, rw);
947
            }
948 946
          } else {
949 947
            typename std::map<int, Arc>::iterator it =
950 948
              (*_node_data)[vi].heap_index.find(tree);
951 949

	
952 950
            if (it != (*_node_data)[vi].heap_index.end()) {
953 951
              if ((*_node_data)[vi].heap[it->second] > rw) {
954 952
                (*_node_data)[vi].heap.replace(it->second, e);
955 953
                (*_node_data)[vi].heap.decrease(e, rw);
956 954
                it->second = e;
957 955
              }
958 956
            } else {
959 957
              (*_node_data)[vi].heap.push(e, rw);
960 958
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
961 959
            }
962 960

	
963 961
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
964 962
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
965 963

	
966 964
              if ((*_blossom_data)[vb].status == MATCHED) {
967 965
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
968 966
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
969 967
                               (*_blossom_data)[vb].offset);
970 968
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
971
                           (*_blossom_data)[vb].offset){
972
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
973
                                   (*_blossom_data)[vb].offset);
974
                }
975
              }
976
            }
977
          }
978
        }
979
      }
980
      (*_blossom_data)[blossom].offset = 0;
981
    }
982

	
983
    void matchedToOdd(int blossom) {
984
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
985
        _delta2->erase(blossom);
986
      }
987
      (*_blossom_data)[blossom].offset += _delta_sum;
988
      if (!_blossom_set->trivial(blossom)) {
989
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
990
                     (*_blossom_data)[blossom].offset);
991
      }
992
    }
993

	
994
    void evenToMatched(int blossom, int tree) {
995
      if (!_blossom_set->trivial(blossom)) {
996
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
997
      }
998

	
999
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1000
           n != INVALID; ++n) {
1001
        int ni = (*_node_index)[n];
1002
        (*_node_data)[ni].pot -= _delta_sum;
1003

	
1004
        _delta1->erase(n);
1005

	
1006
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1007
          Node v = _graph.source(e);
1008
          int vb = _blossom_set->find(v);
1009
          int vi = (*_node_index)[v];
1010

	
1011
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1012
            dualScale * _weight[e];
1013

	
1014
          if (vb == blossom) {
1015
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1016
              _delta3->erase(e);
1017
            }
1018
          } else if ((*_blossom_data)[vb].status == EVEN) {
1019

	
1020
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1021
              _delta3->erase(e);
1022
            }
1023

	
1024
            int vt = _tree_set->find(vb);
1025

	
1026
            if (vt != tree) {
1027

	
1028
              Arc r = _graph.oppositeArc(e);
1029

	
1030
              typename std::map<int, Arc>::iterator it =
1031
                (*_node_data)[ni].heap_index.find(vt);
1032

	
1033
              if (it != (*_node_data)[ni].heap_index.end()) {
1034
                if ((*_node_data)[ni].heap[it->second] > rw) {
1035
                  (*_node_data)[ni].heap.replace(it->second, r);
1036
                  (*_node_data)[ni].heap.decrease(r, rw);
1037
                  it->second = r;
1038
                }
1039
              } else {
1040
                (*_node_data)[ni].heap.push(r, rw);
1041
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1042
              }
1043

	
1044
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1045
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1046

	
1047
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1048
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1049
                               (*_blossom_data)[blossom].offset);
1050
                } else if ((*_delta2)[blossom] >
1051
                           _blossom_set->classPrio(blossom) -
1052
                           (*_blossom_data)[blossom].offset){
1053
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1054
                                   (*_blossom_data)[blossom].offset);
1055
                }
1056
              }
1057
            }
1058

	
1059
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1060
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1061
              _delta3->erase(e);
1062
            }
1063
          } else {
1064

	
1065
            typename std::map<int, Arc>::iterator it =
1066
              (*_node_data)[vi].heap_index.find(tree);
1067

	
1068
            if (it != (*_node_data)[vi].heap_index.end()) {
1069
              (*_node_data)[vi].heap.erase(it->second);
1070
              (*_node_data)[vi].heap_index.erase(it);
1071
              if ((*_node_data)[vi].heap.empty()) {
1072
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
1073
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
1074
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
1075
              }
1076

	
1077
              if ((*_blossom_data)[vb].status == MATCHED) {
1078
                if (_blossom_set->classPrio(vb) ==
1079
                    std::numeric_limits<Value>::max()) {
1080
                  _delta2->erase(vb);
1081
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
1082
                           (*_blossom_data)[vb].offset) {
1083
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
1084
                                   (*_blossom_data)[vb].offset);
1085
                }
1086
              }
1087
            }
1088
          }
1089
        }
1090
      }
1091
    }
1092

	
1093
    void oddToMatched(int blossom) {
1094
      (*_blossom_data)[blossom].offset -= _delta_sum;
1095

	
1096
      if (_blossom_set->classPrio(blossom) !=
1097
          std::numeric_limits<Value>::max()) {
1098
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1099
                       (*_blossom_data)[blossom].offset);
1100
      }
1101

	
1102
      if (!_blossom_set->trivial(blossom)) {
1103
        _delta4->erase(blossom);
1104
      }
1105
    }
1106

	
1107
    void oddToEven(int blossom, int tree) {
1108
      if (!_blossom_set->trivial(blossom)) {
1109
        _delta4->erase(blossom);
1110
        (*_blossom_data)[blossom].pot -=
1111
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
1112
      }
1113

	
1114
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1115
           n != INVALID; ++n) {
1116
        int ni = (*_node_index)[n];
1117

	
1118
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1119

	
1120
        (*_node_data)[ni].heap.clear();
1121
        (*_node_data)[ni].heap_index.clear();
1122
        (*_node_data)[ni].pot +=
1123
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
1124

	
1125
        _delta1->push(n, (*_node_data)[ni].pot);
1126

	
1127
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1128
          Node v = _graph.source(e);
1129
          int vb = _blossom_set->find(v);
1130
          int vi = (*_node_index)[v];
1131

	
1132
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1133
            dualScale * _weight[e];
1134

	
1135
          if ((*_blossom_data)[vb].status == EVEN) {
1136
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
1137
              _delta3->push(e, rw / 2);
1138
            }
1139
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1140
            if (_delta3->state(e) != _delta3->IN_HEAP) {
1141
              _delta3->push(e, rw);
1142
            }
1143
          } else {
1144

	
1145
            typename std::map<int, Arc>::iterator it =
1146
              (*_node_data)[vi].heap_index.find(tree);
1147

	
1148
            if (it != (*_node_data)[vi].heap_index.end()) {
1149
              if ((*_node_data)[vi].heap[it->second] > rw) {
1150
                (*_node_data)[vi].heap.replace(it->second, e);
1151
                (*_node_data)[vi].heap.decrease(e, rw);
1152
                it->second = e;
1153
              }
1154
            } else {
1155
              (*_node_data)[vi].heap.push(e, rw);
1156
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
1157
            }
1158

	
1159
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
1160
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
1161

	
1162
              if ((*_blossom_data)[vb].status == MATCHED) {
1163
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
1164
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
1165
                               (*_blossom_data)[vb].offset);
1166
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
1167 969
                           (*_blossom_data)[vb].offset) {
1168 970
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
1169 971
                                   (*_blossom_data)[vb].offset);
1170 972
                }
1171 973
              }
1172 974
            }
1173 975
          }
1174 976
        }
1175 977
      }
1176 978
      (*_blossom_data)[blossom].offset = 0;
1177 979
    }
1178 980

	
1179

	
1180
    void matchedToUnmatched(int blossom) {
981
    void matchedToOdd(int blossom) {
1181 982
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
1182 983
        _delta2->erase(blossom);
1183 984
      }
985
      (*_blossom_data)[blossom].offset += _delta_sum;
986
      if (!_blossom_set->trivial(blossom)) {
987
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
988
                      (*_blossom_data)[blossom].offset);
989
      }
990
    }
991

	
992
    void evenToMatched(int blossom, int tree) {
993
      if (!_blossom_set->trivial(blossom)) {
994
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
995
      }
1184 996

	
1185 997
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1186 998
           n != INVALID; ++n) {
1187 999
        int ni = (*_node_index)[n];
1188

	
1189
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1190

	
1191
        (*_node_data)[ni].heap.clear();
1192
        (*_node_data)[ni].heap_index.clear();
1193

	
1194
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1195
          Node v = _graph.target(e);
1000
        (*_node_data)[ni].pot -= _delta_sum;
1001

	
1002
        _delta1->erase(n);
1003

	
1004
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1005
          Node v = _graph.source(e);
1196 1006
          int vb = _blossom_set->find(v);
1197 1007
          int vi = (*_node_index)[v];
1198 1008

	
1199 1009
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1200 1010
            dualScale * _weight[e];
1201 1011

	
1202
          if ((*_blossom_data)[vb].status == EVEN) {
1203
            if (_delta3->state(e) != _delta3->IN_HEAP) {
1204
              _delta3->push(e, rw);
1012
          if (vb == blossom) {
1013
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1014
              _delta3->erase(e);
1015
            }
1016
          } else if ((*_blossom_data)[vb].status == EVEN) {
1017

	
1018
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1019
              _delta3->erase(e);
1020
            }
1021

	
1022
            int vt = _tree_set->find(vb);
1023

	
1024
            if (vt != tree) {
1025

	
1026
              Arc r = _graph.oppositeArc(e);
1027

	
1028
              typename std::map<int, Arc>::iterator it =
1029
                (*_node_data)[ni].heap_index.find(vt);
1030

	
1031
              if (it != (*_node_data)[ni].heap_index.end()) {
1032
                if ((*_node_data)[ni].heap[it->second] > rw) {
1033
                  (*_node_data)[ni].heap.replace(it->second, r);
1034
                  (*_node_data)[ni].heap.decrease(r, rw);
1035
                  it->second = r;
1036
                }
1037
              } else {
1038
                (*_node_data)[ni].heap.push(r, rw);
1039
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1040
              }
1041

	
1042
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1043
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1044

	
1045
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1046
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1047
                               (*_blossom_data)[blossom].offset);
1048
                } else if ((*_delta2)[blossom] >
1049
                           _blossom_set->classPrio(blossom) -
1050
                           (*_blossom_data)[blossom].offset){
1051
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1052
                                   (*_blossom_data)[blossom].offset);
1053
                }
1054
              }
1055
            }
1056
          } else {
1057

	
1058
            typename std::map<int, Arc>::iterator it =
1059
              (*_node_data)[vi].heap_index.find(tree);
1060

	
1061
            if (it != (*_node_data)[vi].heap_index.end()) {
1062
              (*_node_data)[vi].heap.erase(it->second);
1063
              (*_node_data)[vi].heap_index.erase(it);
1064
              if ((*_node_data)[vi].heap.empty()) {
1065
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
1066
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
1067
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
1068
              }
1069

	
1070
              if ((*_blossom_data)[vb].status == MATCHED) {
1071
                if (_blossom_set->classPrio(vb) ==
1072
                    std::numeric_limits<Value>::max()) {
1073
                  _delta2->erase(vb);
1074
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
1075
                           (*_blossom_data)[vb].offset) {
1076
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
1077
                                   (*_blossom_data)[vb].offset);
1078
                }
1079
              }
1205 1080
            }
1206 1081
          }
1207 1082
        }
1208 1083
      }
1209 1084
    }
1210 1085

	
1211
    void unmatchedToMatched(int blossom) {
1086
    void oddToMatched(int blossom) {
1087
      (*_blossom_data)[blossom].offset -= _delta_sum;
1088

	
1089
      if (_blossom_set->classPrio(blossom) !=
1090
          std::numeric_limits<Value>::max()) {
1091
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1092
                      (*_blossom_data)[blossom].offset);
1093
      }
1094

	
1095
      if (!_blossom_set->trivial(blossom)) {
1096
        _delta4->erase(blossom);
1097
      }
1098
    }
1099

	
1100
    void oddToEven(int blossom, int tree) {
1101
      if (!_blossom_set->trivial(blossom)) {
1102
        _delta4->erase(blossom);
1103
        (*_blossom_data)[blossom].pot -=
1104
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
1105
      }
1106

	
1212 1107
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1213 1108
           n != INVALID; ++n) {
1214 1109
        int ni = (*_node_index)[n];
1215 1110

	
1111
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1112

	
1113
        (*_node_data)[ni].heap.clear();
1114
        (*_node_data)[ni].heap_index.clear();
1115
        (*_node_data)[ni].pot +=
1116
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
1117

	
1118
        _delta1->push(n, (*_node_data)[ni].pot);
1119

	
1216 1120
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1217 1121
          Node v = _graph.source(e);
1218 1122
          int vb = _blossom_set->find(v);
1219 1123
          int vi = (*_node_index)[v];
1220 1124

	
1221 1125
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1222 1126
            dualScale * _weight[e];
1223 1127

	
1224
          if (vb == blossom) {
1225
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1226
              _delta3->erase(e);
1128
          if ((*_blossom_data)[vb].status == EVEN) {
1129
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
1130
              _delta3->push(e, rw / 2);
1227 1131
            }
1228
          } else if ((*_blossom_data)[vb].status == EVEN) {
1229

	
1230
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1231
              _delta3->erase(e);
1232
            }
1233

	
1234
            int vt = _tree_set->find(vb);
1235

	
1236
            Arc r = _graph.oppositeArc(e);
1132
          } else {
1237 1133

	
1238 1134
            typename std::map<int, Arc>::iterator it =
1239
              (*_node_data)[ni].heap_index.find(vt);
1240

	
1241
            if (it != (*_node_data)[ni].heap_index.end()) {
1242
              if ((*_node_data)[ni].heap[it->second] > rw) {
1243
                (*_node_data)[ni].heap.replace(it->second, r);
1244
                (*_node_data)[ni].heap.decrease(r, rw);
1245
                it->second = r;
1135
              (*_node_data)[vi].heap_index.find(tree);
1136

	
1137
            if (it != (*_node_data)[vi].heap_index.end()) {
1138
              if ((*_node_data)[vi].heap[it->second] > rw) {
1139
                (*_node_data)[vi].heap.replace(it->second, e);
1140
                (*_node_data)[vi].heap.decrease(e, rw);
1141
                it->second = e;
1246 1142
              }
1247 1143
            } else {
1248
              (*_node_data)[ni].heap.push(r, rw);
1249
              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1144
              (*_node_data)[vi].heap.push(e, rw);
1145
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
1250 1146
            }
1251 1147

	
1252
            if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1253
              _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1254

	
1255
              if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1256
                _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1257
                             (*_blossom_data)[blossom].offset);
1258
              } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
1259
                         (*_blossom_data)[blossom].offset){
1260
                _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1261
                                 (*_blossom_data)[blossom].offset);
1148
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
1149
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
1150

	
1151
              if ((*_blossom_data)[vb].status == MATCHED) {
1152
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
1153
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
1154
                               (*_blossom_data)[vb].offset);
1155
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
1156
                           (*_blossom_data)[vb].offset) {
1157
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
1158
                                   (*_blossom_data)[vb].offset);
1159
                }
1262 1160
              }
1263 1161
            }
1264

	
1265
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1266
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1267
              _delta3->erase(e);
1268
            }
1269 1162
          }
1270 1163
        }
1271 1164
      }
1165
      (*_blossom_data)[blossom].offset = 0;
1272 1166
    }
1273 1167

	
1274 1168
    void alternatePath(int even, int tree) {
1275 1169
      int odd;
1276 1170

	
1277 1171
      evenToMatched(even, tree);
1278 1172
      (*_blossom_data)[even].status = MATCHED;
1279 1173

	
1280 1174
      while ((*_blossom_data)[even].pred != INVALID) {
1281 1175
        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
1282 1176
        (*_blossom_data)[odd].status = MATCHED;
1283 1177
        oddToMatched(odd);
1284 1178
        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
1285 1179

	
1286 1180
        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
1287 1181
        (*_blossom_data)[even].status = MATCHED;
1288 1182
        evenToMatched(even, tree);
1289 1183
        (*_blossom_data)[even].next =
1290 1184
          _graph.oppositeArc((*_blossom_data)[odd].pred);
1291 1185
      }
1292 1186

	
1293 1187
    }
1294 1188

	
1295 1189
    void destroyTree(int tree) {
1296 1190
      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
1297 1191
        if ((*_blossom_data)[b].status == EVEN) {
1298 1192
          (*_blossom_data)[b].status = MATCHED;
1299 1193
          evenToMatched(b, tree);
1300 1194
        } else if ((*_blossom_data)[b].status == ODD) {
1301 1195
          (*_blossom_data)[b].status = MATCHED;
1302 1196
          oddToMatched(b);
1303 1197
        }
1304 1198
      }
1305 1199
      _tree_set->eraseClass(tree);
1306 1200
    }
1307 1201

	
1308 1202

	
1309 1203
    void unmatchNode(const Node& node) {
1310 1204
      int blossom = _blossom_set->find(node);
1311 1205
      int tree = _tree_set->find(blossom);
1312 1206

	
1313 1207
      alternatePath(blossom, tree);
1314 1208
      destroyTree(tree);
1315 1209

	
1316
      (*_blossom_data)[blossom].status = UNMATCHED;
1317 1210
      (*_blossom_data)[blossom].base = node;
1318
      matchedToUnmatched(blossom);
1211
      (*_blossom_data)[blossom].next = INVALID;
1319 1212
    }
1320 1213

	
1321

	
1322 1214
    void augmentOnEdge(const Edge& edge) {
1323 1215

	
1324 1216
      int left = _blossom_set->find(_graph.u(edge));
1325 1217
      int right = _blossom_set->find(_graph.v(edge));
1326 1218

	
1327
      if ((*_blossom_data)[left].status == EVEN) {
1328
        int left_tree = _tree_set->find(left);
1329
        alternatePath(left, left_tree);
1330
        destroyTree(left_tree);
1331
      } else {
1332
        (*_blossom_data)[left].status = MATCHED;
1333
        unmatchedToMatched(left);
1334
      }
1335

	
1336
      if ((*_blossom_data)[right].status == EVEN) {
1337
        int right_tree = _tree_set->find(right);
1338
        alternatePath(right, right_tree);
1339
        destroyTree(right_tree);
1340
      } else {
1341
        (*_blossom_data)[right].status = MATCHED;
1342
        unmatchedToMatched(right);
1343
      }
1219
      int left_tree = _tree_set->find(left);
1220
      alternatePath(left, left_tree);
1221
      destroyTree(left_tree);
1222

	
1223
      int right_tree = _tree_set->find(right);
1224
      alternatePath(right, right_tree);
1225
      destroyTree(right_tree);
1344 1226

	
1345 1227
      (*_blossom_data)[left].next = _graph.direct(edge, true);
1346 1228
      (*_blossom_data)[right].next = _graph.direct(edge, false);
1347 1229
    }
1348 1230

	
1231
    void augmentOnArc(const Arc& arc) {
1232

	
1233
      int left = _blossom_set->find(_graph.source(arc));
1234
      int right = _blossom_set->find(_graph.target(arc));
1235

	
1236
      (*_blossom_data)[left].status = MATCHED;
1237

	
1238
      int right_tree = _tree_set->find(right);
1239
      alternatePath(right, right_tree);
1240
      destroyTree(right_tree);
1241

	
1242
      (*_blossom_data)[left].next = arc;
1243
      (*_blossom_data)[right].next = _graph.oppositeArc(arc);
1244
    }
1245

	
1349 1246
    void extendOnArc(const Arc& arc) {
1350 1247
      int base = _blossom_set->find(_graph.target(arc));
1351 1248
      int tree = _tree_set->find(base);
1352 1249

	
1353 1250
      int odd = _blossom_set->find(_graph.source(arc));
1354 1251
      _tree_set->insert(odd, tree);
1355 1252
      (*_blossom_data)[odd].status = ODD;
1356 1253
      matchedToOdd(odd);
1357 1254
      (*_blossom_data)[odd].pred = arc;
1358 1255

	
1359 1256
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
1360 1257
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
1361 1258
      _tree_set->insert(even, tree);
1362 1259
      (*_blossom_data)[even].status = EVEN;
1363 1260
      matchedToEven(even, tree);
1364 1261
    }
1365 1262

	
1366 1263
    void shrinkOnEdge(const Edge& edge, int tree) {
1367 1264
      int nca = -1;
1368 1265
      std::vector<int> left_path, right_path;
1369 1266

	
1370 1267
      {
1371 1268
        std::set<int> left_set, right_set;
1372 1269
        int left = _blossom_set->find(_graph.u(edge));
1373 1270
        left_path.push_back(left);
1374 1271
        left_set.insert(left);
1375 1272

	
1376 1273
        int right = _blossom_set->find(_graph.v(edge));
1377 1274
        right_path.push_back(right);
1378 1275
        right_set.insert(right);
1379 1276

	
1380 1277
        while (true) {
1381 1278

	
1382 1279
          if ((*_blossom_data)[left].pred == INVALID) break;
1383 1280

	
1384 1281
          left =
1385 1282
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
1386 1283
          left_path.push_back(left);
1387 1284
          left =
1388 1285
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
1389 1286
          left_path.push_back(left);
1390 1287

	
1391 1288
          left_set.insert(left);
1392 1289

	
1393 1290
          if (right_set.find(left) != right_set.end()) {
1394 1291
            nca = left;
1395 1292
            break;
1396 1293
          }
1397 1294

	
1398 1295
          if ((*_blossom_data)[right].pred == INVALID) break;
1399 1296

	
1400 1297
          right =
1401 1298
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
1402 1299
          right_path.push_back(right);
1403 1300
          right =
1404 1301
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
1405 1302
          right_path.push_back(right);
1406 1303

	
1407 1304
          right_set.insert(right);
1408 1305

	
1409 1306
          if (left_set.find(right) != left_set.end()) {
1410 1307
            nca = right;
1411 1308
            break;
1412 1309
          }
1413 1310

	
1414 1311
        }
1415 1312

	
1416 1313
        if (nca == -1) {
1417 1314
          if ((*_blossom_data)[left].pred == INVALID) {
1418 1315
            nca = right;
1419 1316
            while (left_set.find(nca) == left_set.end()) {
1420 1317
              nca =
1421 1318
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1422 1319
              right_path.push_back(nca);
1423 1320
              nca =
1424 1321
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1425 1322
              right_path.push_back(nca);
1426 1323
            }
1427 1324
          } else {
1428 1325
            nca = left;
1429 1326
            while (right_set.find(nca) == right_set.end()) {
1430 1327
              nca =
1431 1328
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1432 1329
              left_path.push_back(nca);
1433 1330
              nca =
1434 1331
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1435 1332
              left_path.push_back(nca);
1436 1333
            }
1437 1334
          }
1438 1335
        }
1439 1336
      }
1440 1337

	
1441 1338
      std::vector<int> subblossoms;
1442 1339
      Arc prev;
1443 1340

	
1444 1341
      prev = _graph.direct(edge, true);
1445 1342
      for (int i = 0; left_path[i] != nca; i += 2) {
1446 1343
        subblossoms.push_back(left_path[i]);
1447 1344
        (*_blossom_data)[left_path[i]].next = prev;
1448 1345
        _tree_set->erase(left_path[i]);
1449 1346

	
1450 1347
        subblossoms.push_back(left_path[i + 1]);
1451 1348
        (*_blossom_data)[left_path[i + 1]].status = EVEN;
1452 1349
        oddToEven(left_path[i + 1], tree);
1453 1350
        _tree_set->erase(left_path[i + 1]);
1454 1351
        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
1455 1352
      }
1456 1353

	
1457 1354
      int k = 0;
1458 1355
      while (right_path[k] != nca) ++k;
1459 1356

	
1460 1357
      subblossoms.push_back(nca);
1461 1358
      (*_blossom_data)[nca].next = prev;
1462 1359

	
1463 1360
      for (int i = k - 2; i >= 0; i -= 2) {
1464 1361
        subblossoms.push_back(right_path[i + 1]);
1465 1362
        (*_blossom_data)[right_path[i + 1]].status = EVEN;
1466 1363
        oddToEven(right_path[i + 1], tree);
1467 1364
        _tree_set->erase(right_path[i + 1]);
1468 1365

	
1469 1366
        (*_blossom_data)[right_path[i + 1]].next =
1470 1367
          (*_blossom_data)[right_path[i + 1]].pred;
1471 1368

	
1472 1369
        subblossoms.push_back(right_path[i]);
1473 1370
        _tree_set->erase(right_path[i]);
1474 1371
      }
1475 1372

	
1476 1373
      int surface =
1477 1374
        _blossom_set->join(subblossoms.begin(), subblossoms.end());
1478 1375

	
1479 1376
      for (int i = 0; i < int(subblossoms.size()); ++i) {
1480 1377
        if (!_blossom_set->trivial(subblossoms[i])) {
1481 1378
          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
1482 1379
        }
1483 1380
        (*_blossom_data)[subblossoms[i]].status = MATCHED;
1484 1381
      }
1485 1382

	
1486 1383
      (*_blossom_data)[surface].pot = -2 * _delta_sum;
1487 1384
      (*_blossom_data)[surface].offset = 0;
1488 1385
      (*_blossom_data)[surface].status = EVEN;
1489 1386
      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
1490 1387
      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
1491 1388

	
1492 1389
      _tree_set->insert(surface, tree);
1493 1390
      _tree_set->erase(nca);
1494 1391
    }
1495 1392

	
1496 1393
    void splitBlossom(int blossom) {
1497 1394
      Arc next = (*_blossom_data)[blossom].next;
1498 1395
      Arc pred = (*_blossom_data)[blossom].pred;
1499 1396

	
1500 1397
      int tree = _tree_set->find(blossom);
1501 1398

	
1502 1399
      (*_blossom_data)[blossom].status = MATCHED;
1503 1400
      oddToMatched(blossom);
1504 1401
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
1505 1402
        _delta2->erase(blossom);
1506 1403
      }
1507 1404

	
1508 1405
      std::vector<int> subblossoms;
1509 1406
      _blossom_set->split(blossom, std::back_inserter(subblossoms));
1510 1407

	
1511 1408
      Value offset = (*_blossom_data)[blossom].offset;
1512 1409
      int b = _blossom_set->find(_graph.source(pred));
1513 1410
      int d = _blossom_set->find(_graph.source(next));
1514 1411

	
1515 1412
      int ib = -1, id = -1;
1516 1413
      for (int i = 0; i < int(subblossoms.size()); ++i) {
1517 1414
        if (subblossoms[i] == b) ib = i;
1518 1415
        if (subblossoms[i] == d) id = i;
1519 1416

	
1520 1417
        (*_blossom_data)[subblossoms[i]].offset = offset;
1521 1418
        if (!_blossom_set->trivial(subblossoms[i])) {
1522 1419
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
1523 1420
        }
1524 1421
        if (_blossom_set->classPrio(subblossoms[i]) !=
1525 1422
            std::numeric_limits<Value>::max()) {
1526 1423
          _delta2->push(subblossoms[i],
1527 1424
                        _blossom_set->classPrio(subblossoms[i]) -
1528 1425
                        (*_blossom_data)[subblossoms[i]].offset);
1529 1426
        }
1530 1427
      }
1531 1428

	
1532 1429
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
1533 1430
        for (int i = (id + 1) % subblossoms.size();
1534 1431
             i != ib; i = (i + 2) % subblossoms.size()) {
1535 1432
          int sb = subblossoms[i];
1536 1433
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1537 1434
          (*_blossom_data)[sb].next =
1538 1435
            _graph.oppositeArc((*_blossom_data)[tb].next);
1539 1436
        }
1540 1437

	
1541 1438
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
1542 1439
          int sb = subblossoms[i];
1543 1440
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1544 1441
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1545 1442

	
1546 1443
          (*_blossom_data)[sb].status = ODD;
1547 1444
          matchedToOdd(sb);
1548 1445
          _tree_set->insert(sb, tree);
1549 1446
          (*_blossom_data)[sb].pred = pred;
1550 1447
          (*_blossom_data)[sb].next =
1551
                           _graph.oppositeArc((*_blossom_data)[tb].next);
1448
            _graph.oppositeArc((*_blossom_data)[tb].next);
1552 1449

	
1553 1450
          pred = (*_blossom_data)[ub].next;
1554 1451

	
1555 1452
          (*_blossom_data)[tb].status = EVEN;
1556 1453
          matchedToEven(tb, tree);
1557 1454
          _tree_set->insert(tb, tree);
1558 1455
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
1559 1456
        }
1560 1457

	
1561 1458
        (*_blossom_data)[subblossoms[id]].status = ODD;
1562 1459
        matchedToOdd(subblossoms[id]);
1563 1460
        _tree_set->insert(subblossoms[id], tree);
1564 1461
        (*_blossom_data)[subblossoms[id]].next = next;
1565 1462
        (*_blossom_data)[subblossoms[id]].pred = pred;
1566 1463

	
1567 1464
      } else {
1568 1465

	
1569 1466
        for (int i = (ib + 1) % subblossoms.size();
1570 1467
             i != id; i = (i + 2) % subblossoms.size()) {
1571 1468
          int sb = subblossoms[i];
1572 1469
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1573 1470
          (*_blossom_data)[sb].next =
1574 1471
            _graph.oppositeArc((*_blossom_data)[tb].next);
1575 1472
        }
1576 1473

	
1577 1474
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
1578 1475
          int sb = subblossoms[i];
1579 1476
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1580 1477
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1581 1478

	
1582 1479
          (*_blossom_data)[sb].status = ODD;
1583 1480
          matchedToOdd(sb);
1584 1481
          _tree_set->insert(sb, tree);
1585 1482
          (*_blossom_data)[sb].next = next;
1586 1483
          (*_blossom_data)[sb].pred =
1587 1484
            _graph.oppositeArc((*_blossom_data)[tb].next);
1588 1485

	
1589 1486
          (*_blossom_data)[tb].status = EVEN;
1590 1487
          matchedToEven(tb, tree);
1591 1488
          _tree_set->insert(tb, tree);
1592 1489
          (*_blossom_data)[tb].pred =
1593 1490
            (*_blossom_data)[tb].next =
1594 1491
            _graph.oppositeArc((*_blossom_data)[ub].next);
1595 1492
          next = (*_blossom_data)[ub].next;
1596 1493
        }
1597 1494

	
1598 1495
        (*_blossom_data)[subblossoms[ib]].status = ODD;
1599 1496
        matchedToOdd(subblossoms[ib]);
1600 1497
        _tree_set->insert(subblossoms[ib], tree);
1601 1498
        (*_blossom_data)[subblossoms[ib]].next = next;
1602 1499
        (*_blossom_data)[subblossoms[ib]].pred = pred;
1603 1500
      }
1604 1501
      _tree_set->erase(blossom);
1605 1502
    }
1606 1503

	
1607 1504
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
1608 1505
      if (_blossom_set->trivial(blossom)) {
1609 1506
        int bi = (*_node_index)[base];
1610 1507
        Value pot = (*_node_data)[bi].pot;
1611 1508

	
1612 1509
        (*_matching)[base] = matching;
1613 1510
        _blossom_node_list.push_back(base);
1614 1511
        (*_node_potential)[base] = pot;
1615 1512
      } else {
1616 1513

	
1617 1514
        Value pot = (*_blossom_data)[blossom].pot;
1618 1515
        int bn = _blossom_node_list.size();
1619 1516

	
1620 1517
        std::vector<int> subblossoms;
1621 1518
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
1622 1519
        int b = _blossom_set->find(base);
1623 1520
        int ib = -1;
1624 1521
        for (int i = 0; i < int(subblossoms.size()); ++i) {
1625 1522
          if (subblossoms[i] == b) { ib = i; break; }
1626 1523
        }
1627 1524

	
1628 1525
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
1629 1526
          int sb = subblossoms[(ib + i) % subblossoms.size()];
1630 1527
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
1631 1528

	
1632 1529
          Arc m = (*_blossom_data)[tb].next;
1633 1530
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
1634 1531
          extractBlossom(tb, _graph.source(m), m);
1635 1532
        }
1636 1533
        extractBlossom(subblossoms[ib], base, matching);
1637 1534

	
1638 1535
        int en = _blossom_node_list.size();
1639 1536

	
1640 1537
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
1641 1538
      }
1642 1539
    }
1643 1540

	
1644 1541
    void extractMatching() {
1645 1542
      std::vector<int> blossoms;
1646 1543
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
1647 1544
        blossoms.push_back(c);
1648 1545
      }
1649 1546

	
1650 1547
      for (int i = 0; i < int(blossoms.size()); ++i) {
1651
        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
1548
        if ((*_blossom_data)[blossoms[i]].next != INVALID) {
1652 1549

	
1653 1550
          Value offset = (*_blossom_data)[blossoms[i]].offset;
1654 1551
          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
1655 1552
          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
1656 1553
               n != INVALID; ++n) {
1657 1554
            (*_node_data)[(*_node_index)[n]].pot -= offset;
1658 1555
          }
1659 1556

	
1660 1557
          Arc matching = (*_blossom_data)[blossoms[i]].next;
1661 1558
          Node base = _graph.source(matching);
1662 1559
          extractBlossom(blossoms[i], base, matching);
1663 1560
        } else {
1664 1561
          Node base = (*_blossom_data)[blossoms[i]].base;
1665 1562
          extractBlossom(blossoms[i], base, INVALID);
1666 1563
        }
1667 1564
      }
1668 1565
    }
1669 1566

	
1670 1567
  public:
1671 1568

	
1672 1569
    /// \brief Constructor
1673 1570
    ///
1674 1571
    /// Constructor.
1675 1572
    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
1676 1573
      : _graph(graph), _weight(weight), _matching(0),
1677 1574
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
1678 1575
        _node_num(0), _blossom_num(0),
1679 1576

	
1680 1577
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
1681 1578
        _node_index(0), _node_heap_index(0), _node_data(0),
1682 1579
        _tree_set_index(0), _tree_set(0),
1683 1580

	
1684 1581
        _delta1_index(0), _delta1(0),
1685 1582
        _delta2_index(0), _delta2(0),
1686 1583
        _delta3_index(0), _delta3(0),
1687 1584
        _delta4_index(0), _delta4(0),
1688 1585

	
1689
        _delta_sum() {}
1586
        _delta_sum(), _unmatched(0),
1587

	
1588
        _fractional(0)
1589
    {}
1690 1590

	
1691 1591
    ~MaxWeightedMatching() {
1692 1592
      destroyStructures();
1593
      if (_fractional) {
1594
        delete _fractional;
1595
      }
1693 1596
    }
1694 1597

	
1695 1598
    /// \name Execution Control
1696 1599
    /// The simplest way to execute the algorithm is to use the
1697 1600
    /// \ref run() member function.
1698 1601

	
1699 1602
    ///@{
1700 1603

	
1701 1604
    /// \brief Initialize the algorithm
1702 1605
    ///
1703 1606
    /// This function initializes the algorithm.
1704 1607
    void init() {
1705 1608
      createStructures();
1706 1609

	
1707 1610
      _blossom_node_list.clear();
1708 1611
      _blossom_potential.clear();
1709 1612

	
1710 1613
      for (ArcIt e(_graph); e != INVALID; ++e) {
1711 1614
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
1712 1615
      }
1713 1616
      for (NodeIt n(_graph); n != INVALID; ++n) {
1714 1617
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1715 1618
      }
1716 1619
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1717 1620
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1718 1621
      }
1719 1622
      for (int i = 0; i < _blossom_num; ++i) {
1720 1623
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
1721 1624
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
1722 1625
      }
1723
      
1626

	
1627
      _unmatched = _node_num;
1628

	
1724 1629
      _delta1->clear();
1725 1630
      _delta2->clear();
1726 1631
      _delta3->clear();
1727 1632
      _delta4->clear();
1728 1633
      _blossom_set->clear();
1729 1634
      _tree_set->clear();
1730 1635

	
1731 1636
      int index = 0;
1732 1637
      for (NodeIt n(_graph); n != INVALID; ++n) {
1733 1638
        Value max = 0;
1734 1639
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1735 1640
          if (_graph.target(e) == n) continue;
1736 1641
          if ((dualScale * _weight[e]) / 2 > max) {
1737 1642
            max = (dualScale * _weight[e]) / 2;
1738 1643
          }
1739 1644
        }
1740 1645
        (*_node_index)[n] = index;
1741 1646
        (*_node_data)[index].heap_index.clear();
1742 1647
        (*_node_data)[index].heap.clear();
1743 1648
        (*_node_data)[index].pot = max;
1744 1649
        _delta1->push(n, max);
1745 1650
        int blossom =
1746 1651
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
1747 1652

	
1748 1653
        _tree_set->insert(blossom);
1749 1654

	
1750 1655
        (*_blossom_data)[blossom].status = EVEN;
1751 1656
        (*_blossom_data)[blossom].pred = INVALID;
1752 1657
        (*_blossom_data)[blossom].next = INVALID;
1753 1658
        (*_blossom_data)[blossom].pot = 0;
1754 1659
        (*_blossom_data)[blossom].offset = 0;
1755 1660
        ++index;
1756 1661
      }
1757 1662
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1758 1663
        int si = (*_node_index)[_graph.u(e)];
1759 1664
        int ti = (*_node_index)[_graph.v(e)];
1760 1665
        if (_graph.u(e) != _graph.v(e)) {
1761 1666
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
1762 1667
                            dualScale * _weight[e]) / 2);
1763 1668
        }
1764 1669
      }
1765 1670
    }
1766 1671

	
1672
    /// \brief Initialize the algorithm with fractional matching
1673
    ///
1674
    /// This function initializes the algorithm with a fractional
1675
    /// matching. This initialization is also called jumpstart heuristic.
1676
    void fractionalInit() {
1677
      createStructures();
1678

	
1679
      _blossom_node_list.clear();
1680
      _blossom_potential.clear();
1681

	
1682
      if (_fractional == 0) {
1683
        _fractional = new FractionalMatching(_graph, _weight, false);
1684
      }
1685
      _fractional->run();
1686

	
1687
      for (ArcIt e(_graph); e != INVALID; ++e) {
1688
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
1689
      }
1690
      for (NodeIt n(_graph); n != INVALID; ++n) {
1691
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1692
      }
1693
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1694
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1695
      }
1696
      for (int i = 0; i < _blossom_num; ++i) {
1697
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
1698
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
1699
      }
1700

	
1701
      _unmatched = 0;
1702

	
1703
      _delta1->clear();
1704
      _delta2->clear();
1705
      _delta3->clear();
1706
      _delta4->clear();
1707
      _blossom_set->clear();
1708
      _tree_set->clear();
1709

	
1710
      int index = 0;
1711
      for (NodeIt n(_graph); n != INVALID; ++n) {
1712
        Value pot = _fractional->nodeValue(n);
1713
        (*_node_index)[n] = index;
1714
        (*_node_data)[index].pot = pot;
1715
        (*_node_data)[index].heap_index.clear();
1716
        (*_node_data)[index].heap.clear();
1717
        int blossom =
1718
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
1719

	
1720
        (*_blossom_data)[blossom].status = MATCHED;
1721
        (*_blossom_data)[blossom].pred = INVALID;
1722
        (*_blossom_data)[blossom].next = _fractional->matching(n);
1723
        if (_fractional->matching(n) == INVALID) {
1724
          (*_blossom_data)[blossom].base = n;
1725
        }
1726
        (*_blossom_data)[blossom].pot = 0;
1727
        (*_blossom_data)[blossom].offset = 0;
1728
        ++index;
1729
      }
1730

	
1731
      typename Graph::template NodeMap<bool> processed(_graph, false);
1732
      for (NodeIt n(_graph); n != INVALID; ++n) {
1733
        if (processed[n]) continue;
1734
        processed[n] = true;
1735
        if (_fractional->matching(n) == INVALID) continue;
1736
        int num = 1;
1737
        Node v = _graph.target(_fractional->matching(n));
1738
        while (n != v) {
1739
          processed[v] = true;
1740
          v = _graph.target(_fractional->matching(v));
1741
          ++num;
1742
        }
1743

	
1744
        if (num % 2 == 1) {
1745
          std::vector<int> subblossoms(num);
1746

	
1747
          subblossoms[--num] = _blossom_set->find(n);
1748
          _delta1->push(n, _fractional->nodeValue(n));
1749
          v = _graph.target(_fractional->matching(n));
1750
          while (n != v) {
1751
            subblossoms[--num] = _blossom_set->find(v);
1752
            _delta1->push(v, _fractional->nodeValue(v));
1753
            v = _graph.target(_fractional->matching(v));
1754
          }
1755

	
1756
          int surface =
1757
            _blossom_set->join(subblossoms.begin(), subblossoms.end());
1758
          (*_blossom_data)[surface].status = EVEN;
1759
          (*_blossom_data)[surface].pred = INVALID;
1760
          (*_blossom_data)[surface].next = INVALID;
1761
          (*_blossom_data)[surface].pot = 0;
1762
          (*_blossom_data)[surface].offset = 0;
1763

	
1764
          _tree_set->insert(surface);
1765
          ++_unmatched;
1766
        }
1767
      }
1768

	
1769
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1770
        int si = (*_node_index)[_graph.u(e)];
1771
        int sb = _blossom_set->find(_graph.u(e));
1772
        int ti = (*_node_index)[_graph.v(e)];
1773
        int tb = _blossom_set->find(_graph.v(e));
1774
        if ((*_blossom_data)[sb].status == EVEN &&
1775
            (*_blossom_data)[tb].status == EVEN && sb != tb) {
1776
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
1777
                            dualScale * _weight[e]) / 2);
1778
        }
1779
      }
1780

	
1781
      for (NodeIt n(_graph); n != INVALID; ++n) {
1782
        int nb = _blossom_set->find(n);
1783
        if ((*_blossom_data)[nb].status != MATCHED) continue;
1784
        int ni = (*_node_index)[n];
1785

	
1786
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1787
          Node v = _graph.target(e);
1788
          int vb = _blossom_set->find(v);
1789
          int vi = (*_node_index)[v];
1790

	
1791
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1792
            dualScale * _weight[e];
1793

	
1794
          if ((*_blossom_data)[vb].status == EVEN) {
1795

	
1796
            int vt = _tree_set->find(vb);
1797

	
1798
            typename std::map<int, Arc>::iterator it =
1799
              (*_node_data)[ni].heap_index.find(vt);
1800

	
1801
            if (it != (*_node_data)[ni].heap_index.end()) {
1802
              if ((*_node_data)[ni].heap[it->second] > rw) {
1803
                (*_node_data)[ni].heap.replace(it->second, e);
1804
                (*_node_data)[ni].heap.decrease(e, rw);
1805
                it->second = e;
1806
              }
1807
            } else {
1808
              (*_node_data)[ni].heap.push(e, rw);
1809
              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
1810
            }
1811
          }
1812
        }
1813

	
1814
        if (!(*_node_data)[ni].heap.empty()) {
1815
          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1816
          _delta2->push(nb, _blossom_set->classPrio(nb));
1817
        }
1818
      }
1819
    }
1820

	
1767 1821
    /// \brief Start the algorithm
1768 1822
    ///
1769 1823
    /// This function starts the algorithm.
1770 1824
    ///
1771
    /// \pre \ref init() must be called before using this function.
1825
    /// \pre \ref init() or \ref fractionalInit() must be called
1826
    /// before using this function.
1772 1827
    void start() {
1773 1828
      enum OpType {
1774 1829
        D1, D2, D3, D4
1775 1830
      };
1776 1831

	
1777
      int unmatched = _node_num;
1778
      while (unmatched > 0) {
1832
      while (_unmatched > 0) {
1779 1833
        Value d1 = !_delta1->empty() ?
1780 1834
          _delta1->prio() : std::numeric_limits<Value>::max();
1781 1835

	
1782 1836
        Value d2 = !_delta2->empty() ?
1783 1837
          _delta2->prio() : std::numeric_limits<Value>::max();
1784 1838

	
1785 1839
        Value d3 = !_delta3->empty() ?
1786 1840
          _delta3->prio() : std::numeric_limits<Value>::max();
1787 1841

	
1788 1842
        Value d4 = !_delta4->empty() ?
1789 1843
          _delta4->prio() : std::numeric_limits<Value>::max();
1790 1844

	
1791
        _delta_sum = d1; OpType ot = D1;
1845
        _delta_sum = d3; OpType ot = D3;
1846
        if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
1792 1847
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1793
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
1794 1848
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
1795 1849

	
1796

	
1797 1850
        switch (ot) {
1798 1851
        case D1:
1799 1852
          {
1800 1853
            Node n = _delta1->top();
1801 1854
            unmatchNode(n);
1802
            --unmatched;
1855
            --_unmatched;
1803 1856
          }
1804 1857
          break;
1805 1858
        case D2:
1806 1859
          {
1807 1860
            int blossom = _delta2->top();
1808 1861
            Node n = _blossom_set->classTop(blossom);
1809
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
1810
            extendOnArc(e);
1862
            Arc a = (*_node_data)[(*_node_index)[n]].heap.top();
1863
            if ((*_blossom_data)[blossom].next == INVALID) {
1864
              augmentOnArc(a);
1865
              --_unmatched;
1866
            } else {
1867
              extendOnArc(a);
1868
            }
1811 1869
          }
1812 1870
          break;
1813 1871
        case D3:
1814 1872
          {
1815 1873
            Edge e = _delta3->top();
1816 1874

	
1817 1875
            int left_blossom = _blossom_set->find(_graph.u(e));
1818 1876
            int right_blossom = _blossom_set->find(_graph.v(e));
1819 1877

	
1820 1878
            if (left_blossom == right_blossom) {
1821 1879
              _delta3->pop();
1822 1880
            } else {
1823
              int left_tree;
1824
              if ((*_blossom_data)[left_blossom].status == EVEN) {
1825
                left_tree = _tree_set->find(left_blossom);
1826
              } else {
1827
                left_tree = -1;
1828
                ++unmatched;
1829
              }
1830
              int right_tree;
1831
              if ((*_blossom_data)[right_blossom].status == EVEN) {
1832
                right_tree = _tree_set->find(right_blossom);
1833
              } else {
1834
                right_tree = -1;
1835
                ++unmatched;
1836
              }
1881
              int left_tree = _tree_set->find(left_blossom);
1882
              int right_tree = _tree_set->find(right_blossom);
1837 1883

	
1838 1884
              if (left_tree == right_tree) {
1839 1885
                shrinkOnEdge(e, left_tree);
1840 1886
              } else {
1841 1887
                augmentOnEdge(e);
1842
                unmatched -= 2;
1888
                _unmatched -= 2;
1843 1889
              }
1844 1890
            }
1845 1891
          } break;
1846 1892
        case D4:
1847 1893
          splitBlossom(_delta4->top());
1848 1894
          break;
1849 1895
        }
1850 1896
      }
1851 1897
      extractMatching();
1852 1898
    }
1853 1899

	
1854 1900
    /// \brief Run the algorithm.
1855 1901
    ///
1856 1902
    /// This method runs the \c %MaxWeightedMatching algorithm.
1857 1903
    ///
1858 1904
    /// \note mwm.run() is just a shortcut of the following code.
1859 1905
    /// \code
1860
    ///   mwm.init();
1906
    ///   mwm.fractionalInit();
1861 1907
    ///   mwm.start();
1862 1908
    /// \endcode
1863 1909
    void run() {
1864
      init();
1910
      fractionalInit();
1865 1911
      start();
1866 1912
    }
1867 1913

	
1868 1914
    /// @}
1869 1915

	
1870 1916
    /// \name Primal Solution
1871
    /// Functions to get the primal solution, i.e. the maximum weighted 
1917
    /// Functions to get the primal solution, i.e. the maximum weighted
1872 1918
    /// matching.\n
1873 1919
    /// Either \ref run() or \ref start() function should be called before
1874 1920
    /// using them.
1875 1921

	
1876 1922
    /// @{
1877 1923

	
1878 1924
    /// \brief Return the weight of the matching.
1879 1925
    ///
1880 1926
    /// This function returns the weight of the found matching.
1881 1927
    ///
1882 1928
    /// \pre Either run() or start() must be called before using this function.
1883 1929
    Value matchingWeight() const {
1884 1930
      Value sum = 0;
1885 1931
      for (NodeIt n(_graph); n != INVALID; ++n) {
1886 1932
        if ((*_matching)[n] != INVALID) {
1887 1933
          sum += _weight[(*_matching)[n]];
1888 1934
        }
1889 1935
      }
1890
      return sum /= 2;
1936
      return sum / 2;
1891 1937
    }
1892 1938

	
1893 1939
    /// \brief Return the size (cardinality) of the matching.
1894 1940
    ///
1895 1941
    /// This function returns the size (cardinality) of the found matching.
1896 1942
    ///
1897 1943
    /// \pre Either run() or start() must be called before using this function.
1898 1944
    int matchingSize() const {
1899 1945
      int num = 0;
1900 1946
      for (NodeIt n(_graph); n != INVALID; ++n) {
1901 1947
        if ((*_matching)[n] != INVALID) {
1902 1948
          ++num;
1903 1949
        }
1904 1950
      }
1905 1951
      return num /= 2;
1906 1952
    }
1907 1953

	
1908 1954
    /// \brief Return \c true if the given edge is in the matching.
1909 1955
    ///
1910
    /// This function returns \c true if the given edge is in the found 
1956
    /// This function returns \c true if the given edge is in the found
1911 1957
    /// matching.
1912 1958
    ///
1913 1959
    /// \pre Either run() or start() must be called before using this function.
1914 1960
    bool matching(const Edge& edge) const {
1915 1961
      return edge == (*_matching)[_graph.u(edge)];
1916 1962
    }
1917 1963

	
1918 1964
    /// \brief Return the matching arc (or edge) incident to the given node.
1919 1965
    ///
1920 1966
    /// This function returns the matching arc (or edge) incident to the
1921
    /// given node in the found matching or \c INVALID if the node is 
1967
    /// given node in the found matching or \c INVALID if the node is
1922 1968
    /// not covered by the matching.
1923 1969
    ///
1924 1970
    /// \pre Either run() or start() must be called before using this function.
1925 1971
    Arc matching(const Node& node) const {
1926 1972
      return (*_matching)[node];
1927 1973
    }
1928 1974

	
1929 1975
    /// \brief Return a const reference to the matching map.
1930 1976
    ///
1931 1977
    /// This function returns a const reference to a node map that stores
1932 1978
    /// the matching arc (or edge) incident to each node.
1933 1979
    const MatchingMap& matchingMap() const {
1934 1980
      return *_matching;
1935 1981
    }
1936 1982

	
1937 1983
    /// \brief Return the mate of the given node.
1938 1984
    ///
1939
    /// This function returns the mate of the given node in the found 
1985
    /// This function returns the mate of the given node in the found
1940 1986
    /// matching or \c INVALID if the node is not covered by the matching.
1941 1987
    ///
1942 1988
    /// \pre Either run() or start() must be called before using this function.
1943 1989
    Node mate(const Node& node) const {
1944 1990
      return (*_matching)[node] != INVALID ?
1945 1991
        _graph.target((*_matching)[node]) : INVALID;
1946 1992
    }
1947 1993

	
1948 1994
    /// @}
1949 1995

	
1950 1996
    /// \name Dual Solution
1951 1997
    /// Functions to get the dual solution.\n
1952 1998
    /// Either \ref run() or \ref start() function should be called before
1953 1999
    /// using them.
1954 2000

	
1955 2001
    /// @{
1956 2002

	
1957 2003
    /// \brief Return the value of the dual solution.
1958 2004
    ///
1959
    /// This function returns the value of the dual solution. 
1960
    /// It should be equal to the primal value scaled by \ref dualScale 
2005
    /// This function returns the value of the dual solution.
2006
    /// It should be equal to the primal value scaled by \ref dualScale
1961 2007
    /// "dual scale".
1962 2008
    ///
1963 2009
    /// \pre Either run() or start() must be called before using this function.
1964 2010
    Value dualValue() const {
1965 2011
      Value sum = 0;
1966 2012
      for (NodeIt n(_graph); n != INVALID; ++n) {
1967 2013
        sum += nodeValue(n);
1968 2014
      }
1969 2015
      for (int i = 0; i < blossomNum(); ++i) {
1970 2016
        sum += blossomValue(i) * (blossomSize(i) / 2);
1971 2017
      }
1972 2018
      return sum;
1973 2019
    }
1974 2020

	
1975 2021
    /// \brief Return the dual value (potential) of the given node.
1976 2022
    ///
1977 2023
    /// This function returns the dual value (potential) of the given node.
1978 2024
    ///
1979 2025
    /// \pre Either run() or start() must be called before using this function.
1980 2026
    Value nodeValue(const Node& n) const {
1981 2027
      return (*_node_potential)[n];
1982 2028
    }
1983 2029

	
1984 2030
    /// \brief Return the number of the blossoms in the basis.
1985 2031
    ///
1986 2032
    /// This function returns the number of the blossoms in the basis.
1987 2033
    ///
1988 2034
    /// \pre Either run() or start() must be called before using this function.
1989 2035
    /// \see BlossomIt
1990 2036
    int blossomNum() const {
1991 2037
      return _blossom_potential.size();
1992 2038
    }
1993 2039

	
1994 2040
    /// \brief Return the number of the nodes in the given blossom.
1995 2041
    ///
1996 2042
    /// This function returns the number of the nodes in the given blossom.
1997 2043
    ///
1998 2044
    /// \pre Either run() or start() must be called before using this function.
1999 2045
    /// \see BlossomIt
2000 2046
    int blossomSize(int k) const {
2001 2047
      return _blossom_potential[k].end - _blossom_potential[k].begin;
2002 2048
    }
2003 2049

	
2004 2050
    /// \brief Return the dual value (ptential) of the given blossom.
2005 2051
    ///
2006 2052
    /// This function returns the dual value (ptential) of the given blossom.
2007 2053
    ///
2008 2054
    /// \pre Either run() or start() must be called before using this function.
2009 2055
    Value blossomValue(int k) const {
2010 2056
      return _blossom_potential[k].value;
2011 2057
    }
2012 2058

	
2013 2059
    /// \brief Iterator for obtaining the nodes of a blossom.
2014 2060
    ///
2015
    /// This class provides an iterator for obtaining the nodes of the 
2061
    /// This class provides an iterator for obtaining the nodes of the
2016 2062
    /// given blossom. It lists a subset of the nodes.
2017
    /// Before using this iterator, you must allocate a 
2063
    /// Before using this iterator, you must allocate a
2018 2064
    /// MaxWeightedMatching class and execute it.
2019 2065
    class BlossomIt {
2020 2066
    public:
2021 2067

	
2022 2068
      /// \brief Constructor.
2023 2069
      ///
2024 2070
      /// Constructor to get the nodes of the given variable.
2025 2071
      ///
2026
      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 
2027
      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 
2072
      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or
2073
      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be
2028 2074
      /// called before initializing this iterator.
2029 2075
      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
2030 2076
        : _algorithm(&algorithm)
2031 2077
      {
2032 2078
        _index = _algorithm->_blossom_potential[variable].begin;
2033 2079
        _last = _algorithm->_blossom_potential[variable].end;
2034 2080
      }
2035 2081

	
2036 2082
      /// \brief Conversion to \c Node.
2037 2083
      ///
2038 2084
      /// Conversion to \c Node.
2039 2085
      operator Node() const {
2040 2086
        return _algorithm->_blossom_node_list[_index];
2041 2087
      }
2042 2088

	
2043 2089
      /// \brief Increment operator.
2044 2090
      ///
2045 2091
      /// Increment operator.
2046 2092
      BlossomIt& operator++() {
2047 2093
        ++_index;
2048 2094
        return *this;
2049 2095
      }
2050 2096

	
2051 2097
      /// \brief Validity checking
2052 2098
      ///
2053 2099
      /// Checks whether the iterator is invalid.
2054 2100
      bool operator==(Invalid) const { return _index == _last; }
2055 2101

	
2056 2102
      /// \brief Validity checking
2057 2103
      ///
2058 2104
      /// Checks whether the iterator is valid.
2059 2105
      bool operator!=(Invalid) const { return _index != _last; }
2060 2106

	
2061 2107
    private:
2062 2108
      const MaxWeightedMatching* _algorithm;
2063 2109
      int _last;
2064 2110
      int _index;
2065 2111
    };
2066 2112

	
2067 2113
    /// @}
2068 2114

	
2069 2115
  };
2070 2116

	
2071 2117
  /// \ingroup matching
2072 2118
  ///
2073 2119
  /// \brief Weighted perfect matching in general graphs
2074 2120
  ///
2075 2121
  /// This class provides an efficient implementation of Edmond's
2076 2122
  /// maximum weighted perfect matching algorithm. The implementation
2077 2123
  /// is based on extensive use of priority queues and provides
2078 2124
  /// \f$O(nm\log n)\f$ time complexity.
2079 2125
  ///
2080
  /// The maximum weighted perfect matching problem is to find a subset of 
2081
  /// the edges in an undirected graph with maximum overall weight for which 
2126
  /// The maximum weighted perfect matching problem is to find a subset of
2127
  /// the edges in an undirected graph with maximum overall weight for which
2082 2128
  /// each node has exactly one incident edge.
2083 2129
  /// It can be formulated with the following linear program.
2084 2130
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
2085 2131
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
2086 2132
      \quad \forall B\in\mathcal{O}\f] */
2087 2133
  /// \f[x_e \ge 0\quad \forall e\in E\f]
2088 2134
  /// \f[\max \sum_{e\in E}x_ew_e\f]
2089 2135
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
2090 2136
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
2091 2137
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
2092 2138
  /// subsets of the nodes.
2093 2139
  ///
2094 2140
  /// The algorithm calculates an optimal matching and a proof of the
2095 2141
  /// optimality. The solution of the dual problem can be used to check
2096 2142
  /// the result of the algorithm. The dual linear problem is the
2097 2143
  /// following.
2098 2144
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
2099 2145
      w_{uv} \quad \forall uv\in E\f] */
2100 2146
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
2101 2147
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
2102 2148
      \frac{\vert B \vert - 1}{2}z_B\f] */
2103 2149
  ///
2104
  /// The algorithm can be executed with the run() function. 
2150
  /// The algorithm can be executed with the run() function.
2105 2151
  /// After it the matching (the primal solution) and the dual solution
2106
  /// can be obtained using the query functions and the 
2107
  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
2108
  /// which is able to iterate on the nodes of a blossom. 
2152
  /// can be obtained using the query functions and the
2153
  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class,
2154
  /// which is able to iterate on the nodes of a blossom.
2109 2155
  /// If the value type is integer, then the dual solution is multiplied
2110 2156
  /// by \ref MaxWeightedMatching::dualScale "4".
2111 2157
  ///
2112 2158
  /// \tparam GR The undirected graph type the algorithm runs on.
2113
  /// \tparam WM The type edge weight map. The default type is 
2159
  /// \tparam WM The type edge weight map. The default type is
2114 2160
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
2115 2161
#ifdef DOXYGEN
2116 2162
  template <typename GR, typename WM>
2117 2163
#else
2118 2164
  template <typename GR,
2119 2165
            typename WM = typename GR::template EdgeMap<int> >
2120 2166
#endif
2121 2167
  class MaxWeightedPerfectMatching {
2122 2168
  public:
2123 2169

	
2124 2170
    /// The graph type of the algorithm
2125 2171
    typedef GR Graph;
2126 2172
    /// The type of the edge weight map
2127 2173
    typedef WM WeightMap;
2128 2174
    /// The value type of the edge weights
2129 2175
    typedef typename WeightMap::Value Value;
2130 2176

	
2131 2177
    /// \brief Scaling factor for dual solution
2132 2178
    ///
2133 2179
    /// Scaling factor for dual solution, it is equal to 4 or 1
2134 2180
    /// according to the value type.
2135 2181
    static const int dualScale =
2136 2182
      std::numeric_limits<Value>::is_integer ? 4 : 1;
2137 2183

	
2138 2184
    /// The type of the matching map
2139 2185
    typedef typename Graph::template NodeMap<typename Graph::Arc>
2140 2186
    MatchingMap;
2141 2187

	
2142 2188
  private:
2143 2189

	
2144 2190
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2145 2191

	
2146 2192
    typedef typename Graph::template NodeMap<Value> NodePotential;
2147 2193
    typedef std::vector<Node> BlossomNodeList;
2148 2194

	
2149 2195
    struct BlossomVariable {
2150 2196
      int begin, end;
2151 2197
      Value value;
2152 2198

	
2153 2199
      BlossomVariable(int _begin, int _end, Value _value)
2154 2200
        : begin(_begin), end(_end), value(_value) {}
2155 2201

	
2156 2202
    };
2157 2203

	
2158 2204
    typedef std::vector<BlossomVariable> BlossomPotential;
2159 2205

	
2160 2206
    const Graph& _graph;
2161 2207
    const WeightMap& _weight;
2162 2208

	
2163 2209
    MatchingMap* _matching;
2164 2210

	
2165 2211
    NodePotential* _node_potential;
2166 2212

	
2167 2213
    BlossomPotential _blossom_potential;
2168 2214
    BlossomNodeList _blossom_node_list;
2169 2215

	
2170 2216
    int _node_num;
2171 2217
    int _blossom_num;
2172 2218

	
2173 2219
    typedef RangeMap<int> IntIntMap;
2174 2220

	
2175 2221
    enum Status {
2176 2222
      EVEN = -1, MATCHED = 0, ODD = 1
2177 2223
    };
2178 2224

	
2179 2225
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
2180 2226
    struct BlossomData {
2181 2227
      int tree;
2182 2228
      Status status;
2183 2229
      Arc pred, next;
2184 2230
      Value pot, offset;
2185 2231
    };
2186 2232

	
2187 2233
    IntNodeMap *_blossom_index;
2188 2234
    BlossomSet *_blossom_set;
2189 2235
    RangeMap<BlossomData>* _blossom_data;
2190 2236

	
2191 2237
    IntNodeMap *_node_index;
2192 2238
    IntArcMap *_node_heap_index;
2193 2239

	
2194 2240
    struct NodeData {
2195 2241

	
2196 2242
      NodeData(IntArcMap& node_heap_index)
2197 2243
        : heap(node_heap_index) {}
2198 2244

	
2199 2245
      int blossom;
2200 2246
      Value pot;
2201 2247
      BinHeap<Value, IntArcMap> heap;
2202 2248
      std::map<int, Arc> heap_index;
2203 2249

	
2204 2250
      int tree;
2205 2251
    };
2206 2252

	
2207 2253
    RangeMap<NodeData>* _node_data;
2208 2254

	
2209 2255
    typedef ExtendFindEnum<IntIntMap> TreeSet;
2210 2256

	
2211 2257
    IntIntMap *_tree_set_index;
2212 2258
    TreeSet *_tree_set;
2213 2259

	
2214 2260
    IntIntMap *_delta2_index;
2215 2261
    BinHeap<Value, IntIntMap> *_delta2;
2216 2262

	
2217 2263
    IntEdgeMap *_delta3_index;
2218 2264
    BinHeap<Value, IntEdgeMap> *_delta3;
2219 2265

	
2220 2266
    IntIntMap *_delta4_index;
2221 2267
    BinHeap<Value, IntIntMap> *_delta4;
2222 2268

	
2223 2269
    Value _delta_sum;
2270
    int _unmatched;
2271

	
2272
    typedef MaxWeightedPerfectFractionalMatching<Graph, WeightMap>
2273
    FractionalMatching;
2274
    FractionalMatching *_fractional;
2224 2275

	
2225 2276
    void createStructures() {
2226 2277
      _node_num = countNodes(_graph);
2227 2278
      _blossom_num = _node_num * 3 / 2;
2228 2279

	
2229 2280
      if (!_matching) {
2230 2281
        _matching = new MatchingMap(_graph);
2231 2282
      }
2232 2283

	
2233 2284
      if (!_node_potential) {
2234 2285
        _node_potential = new NodePotential(_graph);
2235 2286
      }
2236 2287

	
2237 2288
      if (!_blossom_set) {
2238 2289
        _blossom_index = new IntNodeMap(_graph);
2239 2290
        _blossom_set = new BlossomSet(*_blossom_index);
2240 2291
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
2241 2292
      } else if (_blossom_data->size() != _blossom_num) {
2242 2293
        delete _blossom_data;
2243 2294
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
2244 2295
      }
2245 2296

	
2246 2297
      if (!_node_index) {
2247 2298
        _node_index = new IntNodeMap(_graph);
2248 2299
        _node_heap_index = new IntArcMap(_graph);
2249 2300
        _node_data = new RangeMap<NodeData>(_node_num,
2250 2301
                                            NodeData(*_node_heap_index));
2251 2302
      } else if (_node_data->size() != _node_num) {
2252 2303
        delete _node_data;
2253 2304
        _node_data = new RangeMap<NodeData>(_node_num,
2254 2305
                                            NodeData(*_node_heap_index));
2255 2306
      }
2256 2307

	
2257 2308
      if (!_tree_set) {
2258 2309
        _tree_set_index = new IntIntMap(_blossom_num);
2259 2310
        _tree_set = new TreeSet(*_tree_set_index);
2260 2311
      } else {
2261 2312
        _tree_set_index->resize(_blossom_num);
2262 2313
      }
2263 2314

	
2264 2315
      if (!_delta2) {
2265 2316
        _delta2_index = new IntIntMap(_blossom_num);
2266 2317
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
2267 2318
      } else {
2268 2319
        _delta2_index->resize(_blossom_num);
2269 2320
      }
2270 2321

	
2271 2322
      if (!_delta3) {
2272 2323
        _delta3_index = new IntEdgeMap(_graph);
2273 2324
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
2274 2325
      }
2275 2326

	
2276 2327
      if (!_delta4) {
2277 2328
        _delta4_index = new IntIntMap(_blossom_num);
2278 2329
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
2279 2330
      } else {
2280 2331
        _delta4_index->resize(_blossom_num);
2281 2332
      }
2282 2333
    }
2283 2334

	
2284 2335
    void destroyStructures() {
2285
      _node_num = countNodes(_graph);
2286
      _blossom_num = _node_num * 3 / 2;
2287

	
2288 2336
      if (_matching) {
2289 2337
        delete _matching;
2290 2338
      }
2291 2339
      if (_node_potential) {
2292 2340
        delete _node_potential;
2293 2341
      }
2294 2342
      if (_blossom_set) {
2295 2343
        delete _blossom_index;
2296 2344
        delete _blossom_set;
2297 2345
        delete _blossom_data;
2298 2346
      }
2299 2347

	
2300 2348
      if (_node_index) {
2301 2349
        delete _node_index;
2302 2350
        delete _node_heap_index;
2303 2351
        delete _node_data;
2304 2352
      }
2305 2353

	
2306 2354
      if (_tree_set) {
2307 2355
        delete _tree_set_index;
2308 2356
        delete _tree_set;
2309 2357
      }
2310 2358
      if (_delta2) {
2311 2359
        delete _delta2_index;
2312 2360
        delete _delta2;
2313 2361
      }
2314 2362
      if (_delta3) {
2315 2363
        delete _delta3_index;
2316 2364
        delete _delta3;
2317 2365
      }
2318 2366
      if (_delta4) {
2319 2367
        delete _delta4_index;
2320 2368
        delete _delta4;
2321 2369
      }
2322 2370
    }
2323 2371

	
2324 2372
    void matchedToEven(int blossom, int tree) {
2325 2373
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2326 2374
        _delta2->erase(blossom);
2327 2375
      }
2328 2376

	
2329 2377
      if (!_blossom_set->trivial(blossom)) {
2330 2378
        (*_blossom_data)[blossom].pot -=
2331 2379
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
2332 2380
      }
2333 2381

	
2334 2382
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2335 2383
           n != INVALID; ++n) {
2336 2384

	
2337 2385
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
2338 2386
        int ni = (*_node_index)[n];
2339 2387

	
2340 2388
        (*_node_data)[ni].heap.clear();
2341 2389
        (*_node_data)[ni].heap_index.clear();
2342 2390

	
2343 2391
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
2344 2392

	
2345 2393
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2346 2394
          Node v = _graph.source(e);
2347 2395
          int vb = _blossom_set->find(v);
2348 2396
          int vi = (*_node_index)[v];
2349 2397

	
2350 2398
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2351 2399
            dualScale * _weight[e];
2352 2400

	
2353 2401
          if ((*_blossom_data)[vb].status == EVEN) {
2354 2402
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
2355 2403
              _delta3->push(e, rw / 2);
2356 2404
            }
2357 2405
          } else {
2358 2406
            typename std::map<int, Arc>::iterator it =
2359 2407
              (*_node_data)[vi].heap_index.find(tree);
2360 2408

	
2361 2409
            if (it != (*_node_data)[vi].heap_index.end()) {
2362 2410
              if ((*_node_data)[vi].heap[it->second] > rw) {
2363 2411
                (*_node_data)[vi].heap.replace(it->second, e);
2364 2412
                (*_node_data)[vi].heap.decrease(e, rw);
2365 2413
                it->second = e;
2366 2414
              }
2367 2415
            } else {
2368 2416
              (*_node_data)[vi].heap.push(e, rw);
2369 2417
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
2370 2418
            }
2371 2419

	
2372 2420
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
2373 2421
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
2374 2422

	
2375 2423
              if ((*_blossom_data)[vb].status == MATCHED) {
2376 2424
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
2377 2425
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
2378 2426
                               (*_blossom_data)[vb].offset);
2379 2427
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
2380 2428
                           (*_blossom_data)[vb].offset){
2381 2429
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
2382 2430
                                   (*_blossom_data)[vb].offset);
2383 2431
                }
2384 2432
              }
2385 2433
            }
2386 2434
          }
2387 2435
        }
2388 2436
      }
2389 2437
      (*_blossom_data)[blossom].offset = 0;
2390 2438
    }
2391 2439

	
2392 2440
    void matchedToOdd(int blossom) {
2393 2441
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2394 2442
        _delta2->erase(blossom);
2395 2443
      }
2396 2444
      (*_blossom_data)[blossom].offset += _delta_sum;
2397 2445
      if (!_blossom_set->trivial(blossom)) {
2398 2446
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
2399 2447
                     (*_blossom_data)[blossom].offset);
2400 2448
      }
2401 2449
    }
2402 2450

	
2403 2451
    void evenToMatched(int blossom, int tree) {
2404 2452
      if (!_blossom_set->trivial(blossom)) {
2405 2453
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
2406 2454
      }
2407 2455

	
2408 2456
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2409 2457
           n != INVALID; ++n) {
2410 2458
        int ni = (*_node_index)[n];
2411 2459
        (*_node_data)[ni].pot -= _delta_sum;
2412 2460

	
2413 2461
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2414 2462
          Node v = _graph.source(e);
2415 2463
          int vb = _blossom_set->find(v);
2416 2464
          int vi = (*_node_index)[v];
2417 2465

	
2418 2466
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2419 2467
            dualScale * _weight[e];
2420 2468

	
2421 2469
          if (vb == blossom) {
2422 2470
            if (_delta3->state(e) == _delta3->IN_HEAP) {
2423 2471
              _delta3->erase(e);
2424 2472
            }
2425 2473
          } else if ((*_blossom_data)[vb].status == EVEN) {
2426 2474

	
2427 2475
            if (_delta3->state(e) == _delta3->IN_HEAP) {
2428 2476
              _delta3->erase(e);
2429 2477
            }
2430 2478

	
2431 2479
            int vt = _tree_set->find(vb);
2432 2480

	
2433 2481
            if (vt != tree) {
2434 2482

	
2435 2483
              Arc r = _graph.oppositeArc(e);
2436 2484

	
2437 2485
              typename std::map<int, Arc>::iterator it =
2438 2486
                (*_node_data)[ni].heap_index.find(vt);
2439 2487

	
2440 2488
              if (it != (*_node_data)[ni].heap_index.end()) {
2441 2489
                if ((*_node_data)[ni].heap[it->second] > rw) {
2442 2490
                  (*_node_data)[ni].heap.replace(it->second, r);
2443 2491
                  (*_node_data)[ni].heap.decrease(r, rw);
2444 2492
                  it->second = r;
2445 2493
                }
2446 2494
              } else {
2447 2495
                (*_node_data)[ni].heap.push(r, rw);
2448 2496
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
2449 2497
              }
2450 2498

	
2451 2499
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
2452 2500
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
2453 2501

	
2454 2502
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
2455 2503
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
2456 2504
                               (*_blossom_data)[blossom].offset);
2457 2505
                } else if ((*_delta2)[blossom] >
2458 2506
                           _blossom_set->classPrio(blossom) -
2459 2507
                           (*_blossom_data)[blossom].offset){
2460 2508
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
2461 2509
                                   (*_blossom_data)[blossom].offset);
2462 2510
                }
2463 2511
              }
2464 2512
            }
2465 2513
          } else {
2466 2514

	
2467 2515
            typename std::map<int, Arc>::iterator it =
2468 2516
              (*_node_data)[vi].heap_index.find(tree);
2469 2517

	
2470 2518
            if (it != (*_node_data)[vi].heap_index.end()) {
2471 2519
              (*_node_data)[vi].heap.erase(it->second);
2472 2520
              (*_node_data)[vi].heap_index.erase(it);
2473 2521
              if ((*_node_data)[vi].heap.empty()) {
2474 2522
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
2475 2523
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
2476 2524
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
2477 2525
              }
2478 2526

	
2479 2527
              if ((*_blossom_data)[vb].status == MATCHED) {
2480 2528
                if (_blossom_set->classPrio(vb) ==
2481 2529
                    std::numeric_limits<Value>::max()) {
2482 2530
                  _delta2->erase(vb);
2483 2531
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
2484 2532
                           (*_blossom_data)[vb].offset) {
2485 2533
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
2486 2534
                                   (*_blossom_data)[vb].offset);
2487 2535
                }
2488 2536
              }
2489 2537
            }
2490 2538
          }
2491 2539
        }
2492 2540
      }
2493 2541
    }
2494 2542

	
2495 2543
    void oddToMatched(int blossom) {
2496 2544
      (*_blossom_data)[blossom].offset -= _delta_sum;
2497 2545

	
2498 2546
      if (_blossom_set->classPrio(blossom) !=
2499 2547
          std::numeric_limits<Value>::max()) {
2500 2548
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
2501 2549
                       (*_blossom_data)[blossom].offset);
2502 2550
      }
2503 2551

	
2504 2552
      if (!_blossom_set->trivial(blossom)) {
2505 2553
        _delta4->erase(blossom);
2506 2554
      }
2507 2555
    }
2508 2556

	
2509 2557
    void oddToEven(int blossom, int tree) {
2510 2558
      if (!_blossom_set->trivial(blossom)) {
2511 2559
        _delta4->erase(blossom);
2512 2560
        (*_blossom_data)[blossom].pot -=
2513 2561
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
2514 2562
      }
2515 2563

	
2516 2564
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2517 2565
           n != INVALID; ++n) {
2518 2566
        int ni = (*_node_index)[n];
2519 2567

	
2520 2568
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
2521 2569

	
2522 2570
        (*_node_data)[ni].heap.clear();
2523 2571
        (*_node_data)[ni].heap_index.clear();
2524 2572
        (*_node_data)[ni].pot +=
2525 2573
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
2526 2574

	
2527 2575
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2528 2576
          Node v = _graph.source(e);
2529 2577
          int vb = _blossom_set->find(v);
2530 2578
          int vi = (*_node_index)[v];
2531 2579

	
2532 2580
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2533 2581
            dualScale * _weight[e];
2534 2582

	
2535 2583
          if ((*_blossom_data)[vb].status == EVEN) {
2536 2584
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
2537 2585
              _delta3->push(e, rw / 2);
2538 2586
            }
2539 2587
          } else {
2540 2588

	
2541 2589
            typename std::map<int, Arc>::iterator it =
2542 2590
              (*_node_data)[vi].heap_index.find(tree);
2543 2591

	
2544 2592
            if (it != (*_node_data)[vi].heap_index.end()) {
2545 2593
              if ((*_node_data)[vi].heap[it->second] > rw) {
2546 2594
                (*_node_data)[vi].heap.replace(it->second, e);
2547 2595
                (*_node_data)[vi].heap.decrease(e, rw);
2548 2596
                it->second = e;
2549 2597
              }
2550 2598
            } else {
2551 2599
              (*_node_data)[vi].heap.push(e, rw);
2552 2600
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
2553 2601
            }
2554 2602

	
2555 2603
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
2556 2604
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
2557 2605

	
2558 2606
              if ((*_blossom_data)[vb].status == MATCHED) {
2559 2607
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
2560 2608
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
2561 2609
                               (*_blossom_data)[vb].offset);
2562 2610
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
2563 2611
                           (*_blossom_data)[vb].offset) {
2564 2612
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
2565 2613
                                   (*_blossom_data)[vb].offset);
2566 2614
                }
2567 2615
              }
2568 2616
            }
2569 2617
          }
2570 2618
        }
2571 2619
      }
2572 2620
      (*_blossom_data)[blossom].offset = 0;
2573 2621
    }
2574 2622

	
2575 2623
    void alternatePath(int even, int tree) {
2576 2624
      int odd;
2577 2625

	
2578 2626
      evenToMatched(even, tree);
2579 2627
      (*_blossom_data)[even].status = MATCHED;
2580 2628

	
2581 2629
      while ((*_blossom_data)[even].pred != INVALID) {
2582 2630
        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
2583 2631
        (*_blossom_data)[odd].status = MATCHED;
2584 2632
        oddToMatched(odd);
2585 2633
        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
2586 2634

	
2587 2635
        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
2588 2636
        (*_blossom_data)[even].status = MATCHED;
2589 2637
        evenToMatched(even, tree);
2590 2638
        (*_blossom_data)[even].next =
2591 2639
          _graph.oppositeArc((*_blossom_data)[odd].pred);
2592 2640
      }
2593 2641

	
2594 2642
    }
2595 2643

	
2596 2644
    void destroyTree(int tree) {
2597 2645
      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
2598 2646
        if ((*_blossom_data)[b].status == EVEN) {
2599 2647
          (*_blossom_data)[b].status = MATCHED;
2600 2648
          evenToMatched(b, tree);
2601 2649
        } else if ((*_blossom_data)[b].status == ODD) {
2602 2650
          (*_blossom_data)[b].status = MATCHED;
2603 2651
          oddToMatched(b);
2604 2652
        }
2605 2653
      }
2606 2654
      _tree_set->eraseClass(tree);
2607 2655
    }
2608 2656

	
2609 2657
    void augmentOnEdge(const Edge& edge) {
2610 2658

	
2611 2659
      int left = _blossom_set->find(_graph.u(edge));
2612 2660
      int right = _blossom_set->find(_graph.v(edge));
2613 2661

	
2614 2662
      int left_tree = _tree_set->find(left);
2615 2663
      alternatePath(left, left_tree);
2616 2664
      destroyTree(left_tree);
2617 2665

	
2618 2666
      int right_tree = _tree_set->find(right);
2619 2667
      alternatePath(right, right_tree);
2620 2668
      destroyTree(right_tree);
2621 2669

	
2622 2670
      (*_blossom_data)[left].next = _graph.direct(edge, true);
2623 2671
      (*_blossom_data)[right].next = _graph.direct(edge, false);
2624 2672
    }
2625 2673

	
2626 2674
    void extendOnArc(const Arc& arc) {
2627 2675
      int base = _blossom_set->find(_graph.target(arc));
2628 2676
      int tree = _tree_set->find(base);
2629 2677

	
2630 2678
      int odd = _blossom_set->find(_graph.source(arc));
2631 2679
      _tree_set->insert(odd, tree);
2632 2680
      (*_blossom_data)[odd].status = ODD;
2633 2681
      matchedToOdd(odd);
2634 2682
      (*_blossom_data)[odd].pred = arc;
2635 2683

	
2636 2684
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
2637 2685
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
2638 2686
      _tree_set->insert(even, tree);
2639 2687
      (*_blossom_data)[even].status = EVEN;
2640 2688
      matchedToEven(even, tree);
2641 2689
    }
2642 2690

	
2643 2691
    void shrinkOnEdge(const Edge& edge, int tree) {
2644 2692
      int nca = -1;
2645 2693
      std::vector<int> left_path, right_path;
2646 2694

	
2647 2695
      {
2648 2696
        std::set<int> left_set, right_set;
2649 2697
        int left = _blossom_set->find(_graph.u(edge));
2650 2698
        left_path.push_back(left);
2651 2699
        left_set.insert(left);
2652 2700

	
2653 2701
        int right = _blossom_set->find(_graph.v(edge));
2654 2702
        right_path.push_back(right);
2655 2703
        right_set.insert(right);
2656 2704

	
2657 2705
        while (true) {
2658 2706

	
2659 2707
          if ((*_blossom_data)[left].pred == INVALID) break;
2660 2708

	
2661 2709
          left =
2662 2710
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
2663 2711
          left_path.push_back(left);
2664 2712
          left =
2665 2713
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
2666 2714
          left_path.push_back(left);
2667 2715

	
2668 2716
          left_set.insert(left);
2669 2717

	
2670 2718
          if (right_set.find(left) != right_set.end()) {
2671 2719
            nca = left;
2672 2720
            break;
2673 2721
          }
2674 2722

	
2675 2723
          if ((*_blossom_data)[right].pred == INVALID) break;
2676 2724

	
2677 2725
          right =
2678 2726
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
2679 2727
          right_path.push_back(right);
2680 2728
          right =
2681 2729
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
2682 2730
          right_path.push_back(right);
2683 2731

	
2684 2732
          right_set.insert(right);
2685 2733

	
2686 2734
          if (left_set.find(right) != left_set.end()) {
2687 2735
            nca = right;
2688 2736
            break;
2689 2737
          }
2690 2738

	
2691 2739
        }
2692 2740

	
2693 2741
        if (nca == -1) {
2694 2742
          if ((*_blossom_data)[left].pred == INVALID) {
2695 2743
            nca = right;
2696 2744
            while (left_set.find(nca) == left_set.end()) {
2697 2745
              nca =
2698 2746
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2699 2747
              right_path.push_back(nca);
2700 2748
              nca =
2701 2749
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2702 2750
              right_path.push_back(nca);
2703 2751
            }
2704 2752
          } else {
2705 2753
            nca = left;
2706 2754
            while (right_set.find(nca) == right_set.end()) {
2707 2755
              nca =
2708 2756
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2709 2757
              left_path.push_back(nca);
2710 2758
              nca =
2711 2759
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2712 2760
              left_path.push_back(nca);
2713 2761
            }
2714 2762
          }
2715 2763
        }
2716 2764
      }
2717 2765

	
2718 2766
      std::vector<int> subblossoms;
2719 2767
      Arc prev;
2720 2768

	
2721 2769
      prev = _graph.direct(edge, true);
2722 2770
      for (int i = 0; left_path[i] != nca; i += 2) {
2723 2771
        subblossoms.push_back(left_path[i]);
2724 2772
        (*_blossom_data)[left_path[i]].next = prev;
2725 2773
        _tree_set->erase(left_path[i]);
2726 2774

	
2727 2775
        subblossoms.push_back(left_path[i + 1]);
2728 2776
        (*_blossom_data)[left_path[i + 1]].status = EVEN;
2729 2777
        oddToEven(left_path[i + 1], tree);
2730 2778
        _tree_set->erase(left_path[i + 1]);
2731 2779
        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
2732 2780
      }
2733 2781

	
2734 2782
      int k = 0;
2735 2783
      while (right_path[k] != nca) ++k;
2736 2784

	
2737 2785
      subblossoms.push_back(nca);
2738 2786
      (*_blossom_data)[nca].next = prev;
2739 2787

	
2740 2788
      for (int i = k - 2; i >= 0; i -= 2) {
2741 2789
        subblossoms.push_back(right_path[i + 1]);
2742 2790
        (*_blossom_data)[right_path[i + 1]].status = EVEN;
2743 2791
        oddToEven(right_path[i + 1], tree);
2744 2792
        _tree_set->erase(right_path[i + 1]);
2745 2793

	
2746 2794
        (*_blossom_data)[right_path[i + 1]].next =
2747 2795
          (*_blossom_data)[right_path[i + 1]].pred;
2748 2796

	
2749 2797
        subblossoms.push_back(right_path[i]);
2750 2798
        _tree_set->erase(right_path[i]);
2751 2799
      }
2752 2800

	
2753 2801
      int surface =
2754 2802
        _blossom_set->join(subblossoms.begin(), subblossoms.end());
2755 2803

	
2756 2804
      for (int i = 0; i < int(subblossoms.size()); ++i) {
2757 2805
        if (!_blossom_set->trivial(subblossoms[i])) {
2758 2806
          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
2759 2807
        }
2760 2808
        (*_blossom_data)[subblossoms[i]].status = MATCHED;
2761 2809
      }
2762 2810

	
2763 2811
      (*_blossom_data)[surface].pot = -2 * _delta_sum;
2764 2812
      (*_blossom_data)[surface].offset = 0;
2765 2813
      (*_blossom_data)[surface].status = EVEN;
2766 2814
      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
2767 2815
      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
2768 2816

	
2769 2817
      _tree_set->insert(surface, tree);
2770 2818
      _tree_set->erase(nca);
2771 2819
    }
2772 2820

	
2773 2821
    void splitBlossom(int blossom) {
2774 2822
      Arc next = (*_blossom_data)[blossom].next;
2775 2823
      Arc pred = (*_blossom_data)[blossom].pred;
2776 2824

	
2777 2825
      int tree = _tree_set->find(blossom);
2778 2826

	
2779 2827
      (*_blossom_data)[blossom].status = MATCHED;
2780 2828
      oddToMatched(blossom);
2781 2829
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2782 2830
        _delta2->erase(blossom);
2783 2831
      }
2784 2832

	
2785 2833
      std::vector<int> subblossoms;
2786 2834
      _blossom_set->split(blossom, std::back_inserter(subblossoms));
2787 2835

	
2788 2836
      Value offset = (*_blossom_data)[blossom].offset;
2789 2837
      int b = _blossom_set->find(_graph.source(pred));
2790 2838
      int d = _blossom_set->find(_graph.source(next));
2791 2839

	
2792 2840
      int ib = -1, id = -1;
2793 2841
      for (int i = 0; i < int(subblossoms.size()); ++i) {
2794 2842
        if (subblossoms[i] == b) ib = i;
2795 2843
        if (subblossoms[i] == d) id = i;
2796 2844

	
2797 2845
        (*_blossom_data)[subblossoms[i]].offset = offset;
2798 2846
        if (!_blossom_set->trivial(subblossoms[i])) {
2799 2847
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
2800 2848
        }
2801 2849
        if (_blossom_set->classPrio(subblossoms[i]) !=
2802 2850
            std::numeric_limits<Value>::max()) {
2803 2851
          _delta2->push(subblossoms[i],
2804 2852
                        _blossom_set->classPrio(subblossoms[i]) -
2805 2853
                        (*_blossom_data)[subblossoms[i]].offset);
2806 2854
        }
2807 2855
      }
2808 2856

	
2809 2857
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
2810 2858
        for (int i = (id + 1) % subblossoms.size();
2811 2859
             i != ib; i = (i + 2) % subblossoms.size()) {
2812 2860
          int sb = subblossoms[i];
2813 2861
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2814 2862
          (*_blossom_data)[sb].next =
2815 2863
            _graph.oppositeArc((*_blossom_data)[tb].next);
2816 2864
        }
2817 2865

	
2818 2866
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
2819 2867
          int sb = subblossoms[i];
2820 2868
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2821 2869
          int ub = subblossoms[(i + 2) % subblossoms.size()];
2822 2870

	
2823 2871
          (*_blossom_data)[sb].status = ODD;
2824 2872
          matchedToOdd(sb);
2825 2873
          _tree_set->insert(sb, tree);
2826 2874
          (*_blossom_data)[sb].pred = pred;
2827 2875
          (*_blossom_data)[sb].next =
2828 2876
                           _graph.oppositeArc((*_blossom_data)[tb].next);
2829 2877

	
2830 2878
          pred = (*_blossom_data)[ub].next;
2831 2879

	
2832 2880
          (*_blossom_data)[tb].status = EVEN;
2833 2881
          matchedToEven(tb, tree);
2834 2882
          _tree_set->insert(tb, tree);
2835 2883
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
2836 2884
        }
2837 2885

	
2838 2886
        (*_blossom_data)[subblossoms[id]].status = ODD;
2839 2887
        matchedToOdd(subblossoms[id]);
2840 2888
        _tree_set->insert(subblossoms[id], tree);
2841 2889
        (*_blossom_data)[subblossoms[id]].next = next;
2842 2890
        (*_blossom_data)[subblossoms[id]].pred = pred;
2843 2891

	
2844 2892
      } else {
2845 2893

	
2846 2894
        for (int i = (ib + 1) % subblossoms.size();
2847 2895
             i != id; i = (i + 2) % subblossoms.size()) {
2848 2896
          int sb = subblossoms[i];
2849 2897
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2850 2898
          (*_blossom_data)[sb].next =
2851 2899
            _graph.oppositeArc((*_blossom_data)[tb].next);
2852 2900
        }
2853 2901

	
2854 2902
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
2855 2903
          int sb = subblossoms[i];
2856 2904
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2857 2905
          int ub = subblossoms[(i + 2) % subblossoms.size()];
2858 2906

	
2859 2907
          (*_blossom_data)[sb].status = ODD;
2860 2908
          matchedToOdd(sb);
2861 2909
          _tree_set->insert(sb, tree);
2862 2910
          (*_blossom_data)[sb].next = next;
2863 2911
          (*_blossom_data)[sb].pred =
2864 2912
            _graph.oppositeArc((*_blossom_data)[tb].next);
2865 2913

	
2866 2914
          (*_blossom_data)[tb].status = EVEN;
2867 2915
          matchedToEven(tb, tree);
2868 2916
          _tree_set->insert(tb, tree);
2869 2917
          (*_blossom_data)[tb].pred =
2870 2918
            (*_blossom_data)[tb].next =
2871 2919
            _graph.oppositeArc((*_blossom_data)[ub].next);
2872 2920
          next = (*_blossom_data)[ub].next;
2873 2921
        }
2874 2922

	
2875 2923
        (*_blossom_data)[subblossoms[ib]].status = ODD;
2876 2924
        matchedToOdd(subblossoms[ib]);
2877 2925
        _tree_set->insert(subblossoms[ib], tree);
2878 2926
        (*_blossom_data)[subblossoms[ib]].next = next;
2879 2927
        (*_blossom_data)[subblossoms[ib]].pred = pred;
2880 2928
      }
2881 2929
      _tree_set->erase(blossom);
2882 2930
    }
2883 2931

	
2884 2932
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
2885 2933
      if (_blossom_set->trivial(blossom)) {
2886 2934
        int bi = (*_node_index)[base];
2887 2935
        Value pot = (*_node_data)[bi].pot;
2888 2936

	
2889 2937
        (*_matching)[base] = matching;
2890 2938
        _blossom_node_list.push_back(base);
2891 2939
        (*_node_potential)[base] = pot;
2892 2940
      } else {
2893 2941

	
2894 2942
        Value pot = (*_blossom_data)[blossom].pot;
2895 2943
        int bn = _blossom_node_list.size();
2896 2944

	
2897 2945
        std::vector<int> subblossoms;
2898 2946
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
2899 2947
        int b = _blossom_set->find(base);
2900 2948
        int ib = -1;
2901 2949
        for (int i = 0; i < int(subblossoms.size()); ++i) {
2902 2950
          if (subblossoms[i] == b) { ib = i; break; }
2903 2951
        }
2904 2952

	
2905 2953
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
2906 2954
          int sb = subblossoms[(ib + i) % subblossoms.size()];
2907 2955
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
2908 2956

	
2909 2957
          Arc m = (*_blossom_data)[tb].next;
2910 2958
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
2911 2959
          extractBlossom(tb, _graph.source(m), m);
2912 2960
        }
2913 2961
        extractBlossom(subblossoms[ib], base, matching);
2914 2962

	
2915 2963
        int en = _blossom_node_list.size();
2916 2964

	
2917 2965
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
2918 2966
      }
2919 2967
    }
2920 2968

	
2921 2969
    void extractMatching() {
2922 2970
      std::vector<int> blossoms;
2923 2971
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
2924 2972
        blossoms.push_back(c);
2925 2973
      }
2926 2974

	
2927 2975
      for (int i = 0; i < int(blossoms.size()); ++i) {
2928 2976

	
2929 2977
        Value offset = (*_blossom_data)[blossoms[i]].offset;
2930 2978
        (*_blossom_data)[blossoms[i]].pot += 2 * offset;
2931 2979
        for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
2932 2980
             n != INVALID; ++n) {
2933 2981
          (*_node_data)[(*_node_index)[n]].pot -= offset;
2934 2982
        }
2935 2983

	
2936 2984
        Arc matching = (*_blossom_data)[blossoms[i]].next;
2937 2985
        Node base = _graph.source(matching);
2938 2986
        extractBlossom(blossoms[i], base, matching);
2939 2987
      }
2940 2988
    }
2941 2989

	
2942 2990
  public:
2943 2991

	
2944 2992
    /// \brief Constructor
2945 2993
    ///
2946 2994
    /// Constructor.
2947 2995
    MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
2948 2996
      : _graph(graph), _weight(weight), _matching(0),
2949 2997
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
2950 2998
        _node_num(0), _blossom_num(0),
2951 2999

	
2952 3000
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
2953 3001
        _node_index(0), _node_heap_index(0), _node_data(0),
2954 3002
        _tree_set_index(0), _tree_set(0),
2955 3003

	
2956 3004
        _delta2_index(0), _delta2(0),
2957 3005
        _delta3_index(0), _delta3(0),
2958 3006
        _delta4_index(0), _delta4(0),
2959 3007

	
2960
        _delta_sum() {}
3008
        _delta_sum(), _unmatched(0),
3009

	
3010
        _fractional(0)
3011
    {}
2961 3012

	
2962 3013
    ~MaxWeightedPerfectMatching() {
2963 3014
      destroyStructures();
3015
      if (_fractional) {
3016
        delete _fractional;
3017
      }
2964 3018
    }
2965 3019

	
2966 3020
    /// \name Execution Control
2967 3021
    /// The simplest way to execute the algorithm is to use the
2968 3022
    /// \ref run() member function.
2969 3023

	
2970 3024
    ///@{
2971 3025

	
2972 3026
    /// \brief Initialize the algorithm
2973 3027
    ///
2974 3028
    /// This function initializes the algorithm.
2975 3029
    void init() {
2976 3030
      createStructures();
2977 3031

	
2978 3032
      _blossom_node_list.clear();
2979 3033
      _blossom_potential.clear();
2980 3034

	
2981 3035
      for (ArcIt e(_graph); e != INVALID; ++e) {
2982 3036
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
2983 3037
      }
2984 3038
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2985 3039
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
2986 3040
      }
2987 3041
      for (int i = 0; i < _blossom_num; ++i) {
2988 3042
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
2989 3043
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
2990 3044
      }
2991 3045

	
3046
      _unmatched = _node_num;
3047

	
2992 3048
      _delta2->clear();
2993 3049
      _delta3->clear();
2994 3050
      _delta4->clear();
2995 3051
      _blossom_set->clear();
2996 3052
      _tree_set->clear();
2997 3053

	
2998 3054
      int index = 0;
2999 3055
      for (NodeIt n(_graph); n != INVALID; ++n) {
3000 3056
        Value max = - std::numeric_limits<Value>::max();
3001 3057
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
3002 3058
          if (_graph.target(e) == n) continue;
3003 3059
          if ((dualScale * _weight[e]) / 2 > max) {
3004 3060
            max = (dualScale * _weight[e]) / 2;
3005 3061
          }
3006 3062
        }
3007 3063
        (*_node_index)[n] = index;
3008 3064
        (*_node_data)[index].heap_index.clear();
3009 3065
        (*_node_data)[index].heap.clear();
3010 3066
        (*_node_data)[index].pot = max;
3011 3067
        int blossom =
3012 3068
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
3013 3069

	
3014 3070
        _tree_set->insert(blossom);
3015 3071

	
3016 3072
        (*_blossom_data)[blossom].status = EVEN;
3017 3073
        (*_blossom_data)[blossom].pred = INVALID;
3018 3074
        (*_blossom_data)[blossom].next = INVALID;
3019 3075
        (*_blossom_data)[blossom].pot = 0;
3020 3076
        (*_blossom_data)[blossom].offset = 0;
3021 3077
        ++index;
3022 3078
      }
3023 3079
      for (EdgeIt e(_graph); e != INVALID; ++e) {
3024 3080
        int si = (*_node_index)[_graph.u(e)];
3025 3081
        int ti = (*_node_index)[_graph.v(e)];
3026 3082
        if (_graph.u(e) != _graph.v(e)) {
3027 3083
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
3028 3084
                            dualScale * _weight[e]) / 2);
3029 3085
        }
3030 3086
      }
3031 3087
    }
3032 3088

	
3089
    /// \brief Initialize the algorithm with fractional matching
3090
    ///
3091
    /// This function initializes the algorithm with a fractional
3092
    /// matching. This initialization is also called jumpstart heuristic.
3093
    void fractionalInit() {
3094
      createStructures();
3095

	
3096
      _blossom_node_list.clear();
3097
      _blossom_potential.clear();
3098

	
3099
      if (_fractional == 0) {
3100
        _fractional = new FractionalMatching(_graph, _weight, false);
3101
      }
3102
      if (!_fractional->run()) {
3103
        _unmatched = -1;
3104
        return;
3105
      }
3106

	
3107
      for (ArcIt e(_graph); e != INVALID; ++e) {
3108
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
3109
      }
3110
      for (EdgeIt e(_graph); e != INVALID; ++e) {
3111
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
3112
      }
3113
      for (int i = 0; i < _blossom_num; ++i) {
3114
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
3115
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
3116
      }
3117

	
3118
      _unmatched = 0;
3119

	
3120
      _delta2->clear();
3121
      _delta3->clear();
3122
      _delta4->clear();
3123
      _blossom_set->clear();
3124
      _tree_set->clear();
3125

	
3126
      int index = 0;
3127
      for (NodeIt n(_graph); n != INVALID; ++n) {
3128
        Value pot = _fractional->nodeValue(n);
3129
        (*_node_index)[n] = index;
3130
        (*_node_data)[index].pot = pot;
3131
        (*_node_data)[index].heap_index.clear();
3132
        (*_node_data)[index].heap.clear();
3133
        int blossom =
3134
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
3135

	
3136
        (*_blossom_data)[blossom].status = MATCHED;
3137
        (*_blossom_data)[blossom].pred = INVALID;
3138
        (*_blossom_data)[blossom].next = _fractional->matching(n);
3139
        (*_blossom_data)[blossom].pot = 0;
3140
        (*_blossom_data)[blossom].offset = 0;
3141
        ++index;
3142
      }
3143

	
3144
      typename Graph::template NodeMap<bool> processed(_graph, false);
3145
      for (NodeIt n(_graph); n != INVALID; ++n) {
3146
        if (processed[n]) continue;
3147
        processed[n] = true;
3148
        if (_fractional->matching(n) == INVALID) continue;
3149
        int num = 1;
3150
        Node v = _graph.target(_fractional->matching(n));
3151
        while (n != v) {
3152
          processed[v] = true;
3153
          v = _graph.target(_fractional->matching(v));
3154
          ++num;
3155
        }
3156

	
3157
        if (num % 2 == 1) {
3158
          std::vector<int> subblossoms(num);
3159

	
3160
          subblossoms[--num] = _blossom_set->find(n);
3161
          v = _graph.target(_fractional->matching(n));
3162
          while (n != v) {
3163
            subblossoms[--num] = _blossom_set->find(v);
3164
            v = _graph.target(_fractional->matching(v));
3165
          }
3166

	
3167
          int surface =
3168
            _blossom_set->join(subblossoms.begin(), subblossoms.end());
3169
          (*_blossom_data)[surface].status = EVEN;
3170
          (*_blossom_data)[surface].pred = INVALID;
3171
          (*_blossom_data)[surface].next = INVALID;
3172
          (*_blossom_data)[surface].pot = 0;
3173
          (*_blossom_data)[surface].offset = 0;
3174

	
3175
          _tree_set->insert(surface);
3176
          ++_unmatched;
3177
        }
3178
      }
3179

	
3180
      for (EdgeIt e(_graph); e != INVALID; ++e) {
3181
        int si = (*_node_index)[_graph.u(e)];
3182
        int sb = _blossom_set->find(_graph.u(e));
3183
        int ti = (*_node_index)[_graph.v(e)];
3184
        int tb = _blossom_set->find(_graph.v(e));
3185
        if ((*_blossom_data)[sb].status == EVEN &&
3186
            (*_blossom_data)[tb].status == EVEN && sb != tb) {
3187
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
3188
                            dualScale * _weight[e]) / 2);
3189
        }
3190
      }
3191

	
3192
      for (NodeIt n(_graph); n != INVALID; ++n) {
3193
        int nb = _blossom_set->find(n);
3194
        if ((*_blossom_data)[nb].status != MATCHED) continue;
3195
        int ni = (*_node_index)[n];
3196

	
3197
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
3198
          Node v = _graph.target(e);
3199
          int vb = _blossom_set->find(v);
3200
          int vi = (*_node_index)[v];
3201

	
3202
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
3203
            dualScale * _weight[e];
3204

	
3205
          if ((*_blossom_data)[vb].status == EVEN) {
3206

	
3207
            int vt = _tree_set->find(vb);
3208

	
3209
            typename std::map<int, Arc>::iterator it =
3210
              (*_node_data)[ni].heap_index.find(vt);
3211

	
3212
            if (it != (*_node_data)[ni].heap_index.end()) {
3213
              if ((*_node_data)[ni].heap[it->second] > rw) {
3214
                (*_node_data)[ni].heap.replace(it->second, e);
3215
                (*_node_data)[ni].heap.decrease(e, rw);
3216
                it->second = e;
3217
              }
3218
            } else {
3219
              (*_node_data)[ni].heap.push(e, rw);
3220
              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, e));
3221
            }
3222
          }
3223
        }
3224

	
3225
        if (!(*_node_data)[ni].heap.empty()) {
3226
          _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
3227
          _delta2->push(nb, _blossom_set->classPrio(nb));
3228
        }
3229
      }
3230
    }
3231

	
3033 3232
    /// \brief Start the algorithm
3034 3233
    ///
3035 3234
    /// This function starts the algorithm.
3036 3235
    ///
3037
    /// \pre \ref init() must be called before using this function.
3236
    /// \pre \ref init() or \ref fractionalInit() must be called before
3237
    /// using this function.
3038 3238
    bool start() {
3039 3239
      enum OpType {
3040 3240
        D2, D3, D4
3041 3241
      };
3042 3242

	
3043
      int unmatched = _node_num;
3044
      while (unmatched > 0) {
3243
      if (_unmatched == -1) return false;
3244

	
3245
      while (_unmatched > 0) {
3045 3246
        Value d2 = !_delta2->empty() ?
3046 3247
          _delta2->prio() : std::numeric_limits<Value>::max();
3047 3248

	
3048 3249
        Value d3 = !_delta3->empty() ?
3049 3250
          _delta3->prio() : std::numeric_limits<Value>::max();
3050 3251

	
3051 3252
        Value d4 = !_delta4->empty() ?
3052 3253
          _delta4->prio() : std::numeric_limits<Value>::max();
3053 3254

	
3054
        _delta_sum = d2; OpType ot = D2;
3055
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
3255
        _delta_sum = d3; OpType ot = D3;
3256
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
3056 3257
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
3057 3258

	
3058 3259
        if (_delta_sum == std::numeric_limits<Value>::max()) {
3059 3260
          return false;
3060 3261
        }
3061 3262

	
3062 3263
        switch (ot) {
3063 3264
        case D2:
3064 3265
          {
3065 3266
            int blossom = _delta2->top();
3066 3267
            Node n = _blossom_set->classTop(blossom);
3067 3268
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
3068 3269
            extendOnArc(e);
3069 3270
          }
3070 3271
          break;
3071 3272
        case D3:
3072 3273
          {
3073 3274
            Edge e = _delta3->top();
3074 3275

	
3075 3276
            int left_blossom = _blossom_set->find(_graph.u(e));
3076 3277
            int right_blossom = _blossom_set->find(_graph.v(e));
3077 3278

	
3078 3279
            if (left_blossom == right_blossom) {
3079 3280
              _delta3->pop();
3080 3281
            } else {
3081 3282
              int left_tree = _tree_set->find(left_blossom);
3082 3283
              int right_tree = _tree_set->find(right_blossom);
3083 3284

	
3084 3285
              if (left_tree == right_tree) {
3085 3286
                shrinkOnEdge(e, left_tree);
3086 3287
              } else {
3087 3288
                augmentOnEdge(e);
3088
                unmatched -= 2;
3289
                _unmatched -= 2;
3089 3290
              }
3090 3291
            }
3091 3292
          } break;
3092 3293
        case D4:
3093 3294
          splitBlossom(_delta4->top());
3094 3295
          break;
3095 3296
        }
3096 3297
      }
3097 3298
      extractMatching();
3098 3299
      return true;
3099 3300
    }
3100 3301

	
3101 3302
    /// \brief Run the algorithm.
3102 3303
    ///
3103 3304
    /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
3104 3305
    ///
3105 3306
    /// \note mwpm.run() is just a shortcut of the following code.
3106 3307
    /// \code
3107
    ///   mwpm.init();
3308
    ///   mwpm.fractionalInit();
3108 3309
    ///   mwpm.start();
3109 3310
    /// \endcode
3110 3311
    bool run() {
3111
      init();
3312
      fractionalInit();
3112 3313
      return start();
3113 3314
    }
3114 3315

	
3115 3316
    /// @}
3116 3317

	
3117 3318
    /// \name Primal Solution
3118
    /// Functions to get the primal solution, i.e. the maximum weighted 
3319
    /// Functions to get the primal solution, i.e. the maximum weighted
3119 3320
    /// perfect matching.\n
3120 3321
    /// Either \ref run() or \ref start() function should be called before
3121 3322
    /// using them.
3122 3323

	
3123 3324
    /// @{
3124 3325

	
3125 3326
    /// \brief Return the weight of the matching.
3126 3327
    ///
3127 3328
    /// This function returns the weight of the found matching.
3128 3329
    ///
3129 3330
    /// \pre Either run() or start() must be called before using this function.
3130 3331
    Value matchingWeight() const {
3131 3332
      Value sum = 0;
3132 3333
      for (NodeIt n(_graph); n != INVALID; ++n) {
3133 3334
        if ((*_matching)[n] != INVALID) {
3134 3335
          sum += _weight[(*_matching)[n]];
3135 3336
        }
3136 3337
      }
3137
      return sum /= 2;
3338
      return sum / 2;
3138 3339
    }
3139 3340

	
3140 3341
    /// \brief Return \c true if the given edge is in the matching.
3141 3342
    ///
3142
    /// This function returns \c true if the given edge is in the found 
3343
    /// This function returns \c true if the given edge is in the found
3143 3344
    /// matching.
3144 3345
    ///
3145 3346
    /// \pre Either run() or start() must be called before using this function.
3146 3347
    bool matching(const Edge& edge) const {
3147 3348
      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
3148 3349
    }
3149 3350

	
3150 3351
    /// \brief Return the matching arc (or edge) incident to the given node.
3151 3352
    ///
3152 3353
    /// This function returns the matching arc (or edge) incident to the
3153
    /// given node in the found matching or \c INVALID if the node is 
3354
    /// given node in the found matching or \c INVALID if the node is
3154 3355
    /// not covered by the matching.
3155 3356
    ///
3156 3357
    /// \pre Either run() or start() must be called before using this function.
3157 3358
    Arc matching(const Node& node) const {
3158 3359
      return (*_matching)[node];
3159 3360
    }
3160 3361

	
3161 3362
    /// \brief Return a const reference to the matching map.
3162 3363
    ///
3163 3364
    /// This function returns a const reference to a node map that stores
3164 3365
    /// the matching arc (or edge) incident to each node.
3165 3366
    const MatchingMap& matchingMap() const {
3166 3367
      return *_matching;
3167 3368
    }
3168 3369

	
3169 3370
    /// \brief Return the mate of the given node.
3170 3371
    ///
3171
    /// This function returns the mate of the given node in the found 
3372
    /// This function returns the mate of the given node in the found
3172 3373
    /// matching or \c INVALID if the node is not covered by the matching.
3173 3374
    ///
3174 3375
    /// \pre Either run() or start() must be called before using this function.
3175 3376
    Node mate(const Node& node) const {
3176 3377
      return _graph.target((*_matching)[node]);
3177 3378
    }
3178 3379

	
3179 3380
    /// @}
3180 3381

	
3181 3382
    /// \name Dual Solution
3182 3383
    /// Functions to get the dual solution.\n
3183 3384
    /// Either \ref run() or \ref start() function should be called before
3184 3385
    /// using them.
3185 3386

	
3186 3387
    /// @{
3187 3388

	
3188 3389
    /// \brief Return the value of the dual solution.
3189 3390
    ///
3190
    /// This function returns the value of the dual solution. 
3191
    /// It should be equal to the primal value scaled by \ref dualScale 
3391
    /// This function returns the value of the dual solution.
3392
    /// It should be equal to the primal value scaled by \ref dualScale
3192 3393
    /// "dual scale".
3193 3394
    ///
3194 3395
    /// \pre Either run() or start() must be called before using this function.
3195 3396
    Value dualValue() const {
3196 3397
      Value sum = 0;
3197 3398
      for (NodeIt n(_graph); n != INVALID; ++n) {
3198 3399
        sum += nodeValue(n);
3199 3400
      }
3200 3401
      for (int i = 0; i < blossomNum(); ++i) {
3201 3402
        sum += blossomValue(i) * (blossomSize(i) / 2);
3202 3403
      }
3203 3404
      return sum;
3204 3405
    }
3205 3406

	
3206 3407
    /// \brief Return the dual value (potential) of the given node.
3207 3408
    ///
3208 3409
    /// This function returns the dual value (potential) of the given node.
3209 3410
    ///
3210 3411
    /// \pre Either run() or start() must be called before using this function.
3211 3412
    Value nodeValue(const Node& n) const {
3212 3413
      return (*_node_potential)[n];
3213 3414
    }
3214 3415

	
3215 3416
    /// \brief Return the number of the blossoms in the basis.
3216 3417
    ///
3217 3418
    /// This function returns the number of the blossoms in the basis.
3218 3419
    ///
3219 3420
    /// \pre Either run() or start() must be called before using this function.
3220 3421
    /// \see BlossomIt
3221 3422
    int blossomNum() const {
3222 3423
      return _blossom_potential.size();
3223 3424
    }
3224 3425

	
3225 3426
    /// \brief Return the number of the nodes in the given blossom.
3226 3427
    ///
3227 3428
    /// This function returns the number of the nodes in the given blossom.
3228 3429
    ///
3229 3430
    /// \pre Either run() or start() must be called before using this function.
3230 3431
    /// \see BlossomIt
3231 3432
    int blossomSize(int k) const {
3232 3433
      return _blossom_potential[k].end - _blossom_potential[k].begin;
3233 3434
    }
3234 3435

	
3235 3436
    /// \brief Return the dual value (ptential) of the given blossom.
3236 3437
    ///
3237 3438
    /// This function returns the dual value (ptential) of the given blossom.
3238 3439
    ///
3239 3440
    /// \pre Either run() or start() must be called before using this function.
3240 3441
    Value blossomValue(int k) const {
3241 3442
      return _blossom_potential[k].value;
3242 3443
    }
3243 3444

	
3244 3445
    /// \brief Iterator for obtaining the nodes of a blossom.
3245 3446
    ///
3246
    /// This class provides an iterator for obtaining the nodes of the 
3447
    /// This class provides an iterator for obtaining the nodes of the
3247 3448
    /// given blossom. It lists a subset of the nodes.
3248
    /// Before using this iterator, you must allocate a 
3449
    /// Before using this iterator, you must allocate a
3249 3450
    /// MaxWeightedPerfectMatching class and execute it.
3250 3451
    class BlossomIt {
3251 3452
    public:
3252 3453

	
3253 3454
      /// \brief Constructor.
3254 3455
      ///
3255 3456
      /// Constructor to get the nodes of the given variable.
3256 3457
      ///
3257
      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 
3258
      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 
3458
      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()"
3459
      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()"
3259 3460
      /// must be called before initializing this iterator.
3260 3461
      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
3261 3462
        : _algorithm(&algorithm)
3262 3463
      {
3263 3464
        _index = _algorithm->_blossom_potential[variable].begin;
3264 3465
        _last = _algorithm->_blossom_potential[variable].end;
3265 3466
      }
3266 3467

	
3267 3468
      /// \brief Conversion to \c Node.
3268 3469
      ///
3269 3470
      /// Conversion to \c Node.
3270 3471
      operator Node() const {
3271 3472
        return _algorithm->_blossom_node_list[_index];
3272 3473
      }
3273 3474

	
3274 3475
      /// \brief Increment operator.
3275 3476
      ///
3276 3477
      /// Increment operator.
3277 3478
      BlossomIt& operator++() {
3278 3479
        ++_index;
3279 3480
        return *this;
3280 3481
      }
3281 3482

	
3282 3483
      /// \brief Validity checking
3283 3484
      ///
3284 3485
      /// This function checks whether the iterator is invalid.
3285 3486
      bool operator==(Invalid) const { return _index == _last; }
3286 3487

	
3287 3488
      /// \brief Validity checking
3288 3489
      ///
3289 3490
      /// This function checks whether the iterator is valid.
3290 3491
      bool operator!=(Invalid) const { return _index != _last; }
3291 3492

	
3292 3493
    private:
3293 3494
      const MaxWeightedPerfectMatching* _algorithm;
3294 3495
      int _last;
3295 3496
      int _index;
3296 3497
    };
3297 3498

	
3298 3499
    /// @}
3299 3500

	
3300 3501
  };
3301 3502

	
3302 3503
} //END OF NAMESPACE LEMON
3303 3504

	
3304
#endif //LEMON_MAX_MATCHING_H
3505
#endif //LEMON_MATCHING_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-2009
5
 * Copyright (C) 2003-2010
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 58
  ///Check whether the parameter is NaN or not
59
  
59

	
60 60
  ///This function checks whether the parameter is NaN or not.
61 61
  ///Is should be equivalent with std::isnan(), but it is not
62 62
  ///provided by all compilers.
63 63
  inline bool isNaN(double v)
64 64
    {
65 65
      return v!=v;
66 66
    }
67 67

	
68 68
  /// @}
69 69

	
70 70
} //namespace lemon
71 71

	
72 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-2010
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_MIN_COST_ARBORESCENCE_H
20 20
#define LEMON_MIN_COST_ARBORESCENCE_H
21 21

	
22 22
///\ingroup spantree
23 23
///\file
24 24
///\brief Minimum Cost Arborescence algorithm.
25 25

	
26 26
#include <vector>
27 27

	
28 28
#include <lemon/list_graph.h>
29 29
#include <lemon/bin_heap.h>
30 30
#include <lemon/assert.h>
31 31

	
32 32
namespace lemon {
33 33

	
34 34

	
35 35
  /// \brief Default traits class for MinCostArborescence class.
36 36
  ///
37 37
  /// Default traits class for MinCostArborescence class.
38 38
  /// \param GR Digraph type.
39 39
  /// \param CM Type of the cost map.
40 40
  template <class GR, class CM>
41 41
  struct MinCostArborescenceDefaultTraits{
42 42

	
43 43
    /// \brief The digraph type the algorithm runs on.
44 44
    typedef GR Digraph;
45 45

	
46 46
    /// \brief The type of the map that stores the arc costs.
47 47
    ///
48 48
    /// The type of the map that stores the arc costs.
49 49
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
50 50
    typedef CM CostMap;
51 51

	
52 52
    /// \brief The value type of the costs.
53 53
    ///
54 54
    /// The value type of the costs.
55 55
    typedef typename CostMap::Value Value;
56 56

	
57 57
    /// \brief The type of the map that stores which arcs are in the
58 58
    /// arborescence.
59 59
    ///
60 60
    /// The type of the map that stores which arcs are in the
61 61
    /// arborescence.  It must conform to the \ref concepts::WriteMap
62 62
    /// "WriteMap" concept, and its value type must be \c bool
63 63
    /// (or convertible). Initially it will be set to \c false on each
64 64
    /// arc, then it will be set on each arborescence arc once.
65 65
    typedef typename Digraph::template ArcMap<bool> ArborescenceMap;
66 66

	
67 67
    /// \brief Instantiates a \c ArborescenceMap.
68 68
    ///
69 69
    /// This function instantiates a \c ArborescenceMap.
70 70
    /// \param digraph The digraph to which we would like to calculate
71 71
    /// the \c ArborescenceMap.
72 72
    static ArborescenceMap *createArborescenceMap(const Digraph &digraph){
73 73
      return new ArborescenceMap(digraph);
74 74
    }
75 75

	
76 76
    /// \brief The type of the \c PredMap
77 77
    ///
78 78
    /// The type of the \c PredMap. It must confrom to the
79 79
    /// \ref concepts::WriteMap "WriteMap" concept, and its value type
80 80
    /// must be the \c Arc type of the digraph.
81 81
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
82 82

	
83 83
    /// \brief Instantiates a \c PredMap.
84 84
    ///
85 85
    /// This function instantiates a \c PredMap.
86 86
    /// \param digraph The digraph to which we would like to define the
87 87
    /// \c PredMap.
88 88
    static PredMap *createPredMap(const Digraph &digraph){
89 89
      return new PredMap(digraph);
90 90
    }
91 91

	
92 92
  };
93 93

	
94 94
  /// \ingroup spantree
95 95
  ///
96 96
  /// \brief Minimum Cost Arborescence algorithm class.
97 97
  ///
98 98
  /// This class provides an efficient implementation of the
99 99
  /// Minimum Cost Arborescence algorithm. The arborescence is a tree
100 100
  /// which is directed from a given source node of the digraph. One or
101 101
  /// more sources should be given to the algorithm and it will calculate
102 102
  /// the minimum cost subgraph that is the union of arborescences with the
103 103
  /// given sources and spans all the nodes which are reachable from the
104 104
  /// sources. The time complexity of the algorithm is O(n<sup>2</sup>+e).
105 105
  ///
106 106
  /// The algorithm also provides an optimal dual solution, therefore
107 107
  /// the optimality of the solution can be checked.
108 108
  ///
109 109
  /// \param GR The digraph type the algorithm runs on.
110 110
  /// \param CM A read-only arc map storing the costs of the
111 111
  /// arcs. It is read once for each arc, so the map may involve in
112 112
  /// relatively time consuming process to compute the arc costs if
113 113
  /// it is necessary. The default map type is \ref
114 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
115
  /// \tparam TR The traits class that defines various types used by the
116
  /// algorithm. By default, it is \ref MinCostArborescenceDefaultTraits
118 117
  /// "MinCostArborescenceDefaultTraits<GR, CM>".
118
  /// In most cases, this parameter should not be set directly,
119
  /// consider to use the named template parameters instead.
119 120
#ifndef DOXYGEN
120 121
  template <typename GR,
121 122
            typename CM = typename GR::template ArcMap<int>,
122 123
            typename TR =
123 124
              MinCostArborescenceDefaultTraits<GR, CM> >
124 125
#else
125
  template <typename GR, typename CM, typedef TR>
126
  template <typename GR, typename CM, typename TR>
126 127
#endif
127 128
  class MinCostArborescence {
128 129
  public:
129 130

	
130
    /// \brief The \ref MinCostArborescenceDefaultTraits "traits class" 
131
    /// of the algorithm. 
131
    /// \brief The \ref MinCostArborescenceDefaultTraits "traits class"
132
    /// of the algorithm.
132 133
    typedef TR Traits;
133 134
    /// The type of the underlying digraph.
134 135
    typedef typename Traits::Digraph Digraph;
135 136
    /// The type of the map that stores the arc costs.
136 137
    typedef typename Traits::CostMap CostMap;
137 138
    ///The type of the costs of the arcs.
138 139
    typedef typename Traits::Value Value;
139 140
    ///The type of the predecessor map.
140 141
    typedef typename Traits::PredMap PredMap;
141 142
    ///The type of the map that stores which arcs are in the arborescence.
142 143
    typedef typename Traits::ArborescenceMap ArborescenceMap;
143 144

	
144 145
    typedef MinCostArborescence Create;
145 146

	
146 147
  private:
147 148

	
148 149
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
149 150

	
150 151
    struct CostArc {
151 152

	
152 153
      Arc arc;
153 154
      Value value;
154 155

	
155 156
      CostArc() {}
156 157
      CostArc(Arc _arc, Value _value) : arc(_arc), value(_value) {}
157 158

	
158 159
    };
159 160

	
160 161
    const Digraph *_digraph;
161 162
    const CostMap *_cost;
162 163

	
163 164
    PredMap *_pred;
164 165
    bool local_pred;
165 166

	
166 167
    ArborescenceMap *_arborescence;
167 168
    bool local_arborescence;
168 169

	
169 170
    typedef typename Digraph::template ArcMap<int> ArcOrder;
170 171
    ArcOrder *_arc_order;
171 172

	
172 173
    typedef typename Digraph::template NodeMap<int> NodeOrder;
173 174
    NodeOrder *_node_order;
174 175

	
175 176
    typedef typename Digraph::template NodeMap<CostArc> CostArcMap;
176 177
    CostArcMap *_cost_arcs;
177 178

	
178 179
    struct StackLevel {
179 180

	
180 181
      std::vector<CostArc> arcs;
181 182
      int node_level;
182 183

	
183 184
    };
184 185

	
185 186
    std::vector<StackLevel> level_stack;
186 187
    std::vector<Node> queue;
187 188

	
188 189
    typedef std::vector<typename Digraph::Node> DualNodeList;
189 190

	
190 191
    DualNodeList _dual_node_list;
191 192

	
192 193
    struct DualVariable {
193 194
      int begin, end;
194 195
      Value value;
195 196

	
196 197
      DualVariable(int _begin, int _end, Value _value)
197 198
        : begin(_begin), end(_end), value(_value) {}
198 199

	
199 200
    };
200 201

	
201 202
    typedef std::vector<DualVariable> DualVariables;
202 203

	
203 204
    DualVariables _dual_variables;
204 205

	
205 206
    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
206 207

	
207 208
    HeapCrossRef *_heap_cross_ref;
208 209

	
209 210
    typedef BinHeap<int, HeapCrossRef> Heap;
210 211

	
211 212
    Heap *_heap;
212 213

	
213 214
  protected:
214 215

	
215 216
    MinCostArborescence() {}
216 217

	
217 218
  private:
218 219

	
219 220
    void createStructures() {
220 221
      if (!_pred) {
221 222
        local_pred = true;
222 223
        _pred = Traits::createPredMap(*_digraph);
223 224
      }
224 225
      if (!_arborescence) {
225 226
        local_arborescence = true;
226 227
        _arborescence = Traits::createArborescenceMap(*_digraph);
227 228
      }
228 229
      if (!_arc_order) {
229 230
        _arc_order = new ArcOrder(*_digraph);
230 231
      }
231 232
      if (!_node_order) {
232 233
        _node_order = new NodeOrder(*_digraph);
233 234
      }
234 235
      if (!_cost_arcs) {
235 236
        _cost_arcs = new CostArcMap(*_digraph);
236 237
      }
237 238
      if (!_heap_cross_ref) {
238 239
        _heap_cross_ref = new HeapCrossRef(*_digraph, -1);
239 240
      }
240 241
      if (!_heap) {
241 242
        _heap = new Heap(*_heap_cross_ref);
242 243
      }
243 244
    }
244 245

	
245 246
    void destroyStructures() {
246 247
      if (local_arborescence) {
247 248
        delete _arborescence;
248 249
      }
249 250
      if (local_pred) {
250 251
        delete _pred;
251 252
      }
252 253
      if (_arc_order) {
253 254
        delete _arc_order;
254 255
      }
255 256
      if (_node_order) {
256 257
        delete _node_order;
257 258
      }
258 259
      if (_cost_arcs) {
259 260
        delete _cost_arcs;
260 261
      }
261 262
      if (_heap) {
262 263
        delete _heap;
263 264
      }
264 265
      if (_heap_cross_ref) {
265 266
        delete _heap_cross_ref;
266 267
      }
267 268
    }
268 269

	
269 270
    Arc prepare(Node node) {
270 271
      std::vector<Node> nodes;
271 272
      (*_node_order)[node] = _dual_node_list.size();
272 273
      StackLevel level;
273 274
      level.node_level = _dual_node_list.size();
274 275
      _dual_node_list.push_back(node);
275 276
      for (InArcIt it(*_digraph, node); it != INVALID; ++it) {
276 277
        Arc arc = it;
277 278
        Node source = _digraph->source(arc);
278 279
        Value value = (*_cost)[it];
279 280
        if (source == node || (*_node_order)[source] == -3) continue;
280 281
        if ((*_cost_arcs)[source].arc == INVALID) {
281 282
          (*_cost_arcs)[source].arc = arc;
282 283
          (*_cost_arcs)[source].value = value;
283 284
          nodes.push_back(source);
284 285
        } else {
285 286
          if ((*_cost_arcs)[source].value > value) {
286 287
            (*_cost_arcs)[source].arc = arc;
287 288
            (*_cost_arcs)[source].value = value;
288 289
          }
289 290
        }
290 291
      }
291 292
      CostArc minimum = (*_cost_arcs)[nodes[0]];
292 293
      for (int i = 1; i < int(nodes.size()); ++i) {
293 294
        if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
294 295
          minimum = (*_cost_arcs)[nodes[i]];
295 296
        }
296 297
      }
297 298
      (*_arc_order)[minimum.arc] = _dual_variables.size();
298 299
      DualVariable var(_dual_node_list.size() - 1,
299 300
                       _dual_node_list.size(), minimum.value);
300 301
      _dual_variables.push_back(var);
301 302
      for (int i = 0; i < int(nodes.size()); ++i) {
302 303
        (*_cost_arcs)[nodes[i]].value -= minimum.value;
303 304
        level.arcs.push_back((*_cost_arcs)[nodes[i]]);
304 305
        (*_cost_arcs)[nodes[i]].arc = INVALID;
305 306
      }
306 307
      level_stack.push_back(level);
307 308
      return minimum.arc;
308 309
    }
309 310

	
310 311
    Arc contract(Node node) {
311 312
      int node_bottom = bottom(node);
312 313
      std::vector<Node> nodes;
313 314
      while (!level_stack.empty() &&
314 315
             level_stack.back().node_level >= node_bottom) {
315 316
        for (int i = 0; i < int(level_stack.back().arcs.size()); ++i) {
316 317
          Arc arc = level_stack.back().arcs[i].arc;
317 318
          Node source = _digraph->source(arc);
318 319
          Value value = level_stack.back().arcs[i].value;
319 320
          if ((*_node_order)[source] >= node_bottom) continue;
320 321
          if ((*_cost_arcs)[source].arc == INVALID) {
321 322
            (*_cost_arcs)[source].arc = arc;
322 323
            (*_cost_arcs)[source].value = value;
323 324
            nodes.push_back(source);
324 325
          } else {
325 326
            if ((*_cost_arcs)[source].value > value) {
326 327
              (*_cost_arcs)[source].arc = arc;
327 328
              (*_cost_arcs)[source].value = value;
328 329
            }
329 330
          }
330 331
        }
331 332
        level_stack.pop_back();
332 333
      }
333 334
      CostArc minimum = (*_cost_arcs)[nodes[0]];
334 335
      for (int i = 1; i < int(nodes.size()); ++i) {
335 336
        if ((*_cost_arcs)[nodes[i]].value < minimum.value) {
336 337
          minimum = (*_cost_arcs)[nodes[i]];
337 338
        }
338 339
      }
339 340
      (*_arc_order)[minimum.arc] = _dual_variables.size();
340 341
      DualVariable var(node_bottom, _dual_node_list.size(), minimum.value);
341 342
      _dual_variables.push_back(var);
342 343
      StackLevel level;
343 344
      level.node_level = node_bottom;
344 345
      for (int i = 0; i < int(nodes.size()); ++i) {
345 346
        (*_cost_arcs)[nodes[i]].value -= minimum.value;
346 347
        level.arcs.push_back((*_cost_arcs)[nodes[i]]);
347 348
        (*_cost_arcs)[nodes[i]].arc = INVALID;
348 349
      }
349 350
      level_stack.push_back(level);
350 351
      return minimum.arc;
351 352
    }
352 353

	
353 354
    int bottom(Node node) {
354 355
      int k = level_stack.size() - 1;
355 356
      while (level_stack[k].node_level > (*_node_order)[node]) {
356 357
        --k;
357 358
      }
358 359
      return level_stack[k].node_level;
359 360
    }
360 361

	
361 362
    void finalize(Arc arc) {
362 363
      Node node = _digraph->target(arc);
363 364
      _heap->push(node, (*_arc_order)[arc]);
364 365
      _pred->set(node, arc);
365 366
      while (!_heap->empty()) {
366 367
        Node source = _heap->top();
367 368
        _heap->pop();
368 369
        (*_node_order)[source] = -1;
369 370
        for (OutArcIt it(*_digraph, source); it != INVALID; ++it) {
370 371
          if ((*_arc_order)[it] < 0) continue;
371 372
          Node target = _digraph->target(it);
372 373
          switch(_heap->state(target)) {
373 374
          case Heap::PRE_HEAP:
374 375
            _heap->push(target, (*_arc_order)[it]);
375 376
            _pred->set(target, it);
376 377
            break;
377 378
          case Heap::IN_HEAP:
378 379
            if ((*_arc_order)[it] < (*_heap)[target]) {
379 380
              _heap->decrease(target, (*_arc_order)[it]);
380 381
              _pred->set(target, it);
381 382
            }
382 383
            break;
383 384
          case Heap::POST_HEAP:
384 385
            break;
385 386
          }
386 387
        }
387 388
        _arborescence->set((*_pred)[source], true);
388 389
      }
389 390
    }
390 391

	
391 392

	
392 393
  public:
393 394

	
394 395
    /// \name Named Template Parameters
395 396

	
396 397
    /// @{
397 398

	
398 399
    template <class T>
399 400
    struct SetArborescenceMapTraits : public Traits {
400 401
      typedef T ArborescenceMap;
401 402
      static ArborescenceMap *createArborescenceMap(const Digraph &)
402 403
      {
403 404
        LEMON_ASSERT(false, "ArborescenceMap is not initialized");
404 405
        return 0; // ignore warnings
405 406
      }
406 407
    };
407 408

	
408 409
    /// \brief \ref named-templ-param "Named parameter" for
409 410
    /// setting \c ArborescenceMap type
410 411
    ///
411 412
    /// \ref named-templ-param "Named parameter" for setting
412 413
    /// \c ArborescenceMap type.
413 414
    /// It must conform to the \ref concepts::WriteMap "WriteMap" concept,
414 415
    /// and its value type must be \c bool (or convertible).
415 416
    /// Initially it will be set to \c false on each arc,
416 417
    /// then it will be set on each arborescence arc once.
417 418
    template <class T>
418 419
    struct SetArborescenceMap
419 420
      : public MinCostArborescence<Digraph, CostMap,
420 421
                                   SetArborescenceMapTraits<T> > {
421 422
    };
422 423

	
423 424
    template <class T>
424 425
    struct SetPredMapTraits : public Traits {
425 426
      typedef T PredMap;
426 427
      static PredMap *createPredMap(const Digraph &)
427 428
      {
428 429
        LEMON_ASSERT(false, "PredMap is not initialized");
429 430
        return 0; // ignore warnings
430 431
      }
431 432
    };
432 433

	
433 434
    /// \brief \ref named-templ-param "Named parameter" for
434 435
    /// setting \c PredMap type
435 436
    ///
436 437
    /// \ref named-templ-param "Named parameter" for setting
437 438
    /// \c PredMap type.
438
    /// It must meet the \ref concepts::WriteMap "WriteMap" concept, 
439
    /// It must meet the \ref concepts::WriteMap "WriteMap" concept,
439 440
    /// and its value type must be the \c Arc type of the digraph.
440 441
    template <class T>
441 442
    struct SetPredMap
442 443
      : public MinCostArborescence<Digraph, CostMap, SetPredMapTraits<T> > {
443 444
    };
444 445

	
445 446
    /// @}
446 447

	
447 448
    /// \brief Constructor.
448 449
    ///
449 450
    /// \param digraph The digraph the algorithm will run on.
450 451
    /// \param cost The cost map used by the algorithm.
451 452
    MinCostArborescence(const Digraph& digraph, const CostMap& cost)
452 453
      : _digraph(&digraph), _cost(&cost), _pred(0), local_pred(false),
453 454
        _arborescence(0), local_arborescence(false),
454 455
        _arc_order(0), _node_order(0), _cost_arcs(0),
455 456
        _heap_cross_ref(0), _heap(0) {}
456 457

	
457 458
    /// \brief Destructor.
458 459
    ~MinCostArborescence() {
459 460
      destroyStructures();
460 461
    }
461 462

	
462 463
    /// \brief Sets the arborescence map.
463 464
    ///
464 465
    /// Sets the arborescence map.
465 466
    /// \return <tt>(*this)</tt>
466 467
    MinCostArborescence& arborescenceMap(ArborescenceMap& m) {
467 468
      if (local_arborescence) {
468 469
        delete _arborescence;
469 470
      }
470 471
      local_arborescence = false;
471 472
      _arborescence = &m;
472 473
      return *this;
473 474
    }
474 475

	
475 476
    /// \brief Sets the predecessor map.
476 477
    ///
477 478
    /// Sets the predecessor map.
478 479
    /// \return <tt>(*this)</tt>
479 480
    MinCostArborescence& predMap(PredMap& m) {
480 481
      if (local_pred) {
481 482
        delete _pred;
482 483
      }
483 484
      local_pred = false;
484 485
      _pred = &m;
485 486
      return *this;
486 487
    }
487 488

	
488 489
    /// \name Execution Control
489 490
    /// The simplest way to execute the algorithm is to use
490 491
    /// one of the member functions called \c run(...). \n
491
    /// If you need more control on the execution,
492
    /// first you must call \ref init(), then you can add several
492
    /// If you need better control on the execution,
493
    /// you have to call \ref init() first, then you can add several
493 494
    /// source nodes with \ref addSource().
494 495
    /// Finally \ref start() will perform the arborescence
495 496
    /// computation.
496 497

	
497 498
    ///@{
498 499

	
499 500
    /// \brief Initializes the internal data structures.
500 501
    ///
501 502
    /// Initializes the internal data structures.
502 503
    ///
503 504
    void init() {
504 505
      createStructures();
505 506
      _heap->clear();
506 507
      for (NodeIt it(*_digraph); it != INVALID; ++it) {
507 508
        (*_cost_arcs)[it].arc = INVALID;
508 509
        (*_node_order)[it] = -3;
509 510
        (*_heap_cross_ref)[it] = Heap::PRE_HEAP;
510 511
        _pred->set(it, INVALID);
511 512
      }
512 513
      for (ArcIt it(*_digraph); it != INVALID; ++it) {
513 514
        _arborescence->set(it, false);
514 515
        (*_arc_order)[it] = -1;
515 516
      }
516 517
      _dual_node_list.clear();
517 518
      _dual_variables.clear();
518 519
    }
519 520

	
520 521
    /// \brief Adds a new source node.
521 522
    ///
522 523
    /// Adds a new source node to the algorithm.
523 524
    void addSource(Node source) {
524 525
      std::vector<Node> nodes;
525 526
      nodes.push_back(source);
526 527
      while (!nodes.empty()) {
527 528
        Node node = nodes.back();
528 529
        nodes.pop_back();
529 530
        for (OutArcIt it(*_digraph, node); it != INVALID; ++it) {
530 531
          Node target = _digraph->target(it);
531 532
          if ((*_node_order)[target] == -3) {
532 533
            (*_node_order)[target] = -2;
533 534
            nodes.push_back(target);
534 535
            queue.push_back(target);
535 536
          }
536 537
        }
537 538
      }
538 539
      (*_node_order)[source] = -1;
539 540
    }
540 541

	
541 542
    /// \brief Processes the next node in the priority queue.
542 543
    ///
543 544
    /// Processes the next node in the priority queue.
544 545
    ///
545 546
    /// \return The processed node.
546 547
    ///
547 548
    /// \warning The queue must not be empty.
548 549
    Node processNextNode() {
549 550
      Node node = queue.back();
550 551
      queue.pop_back();
551 552
      if ((*_node_order)[node] == -2) {
552 553
        Arc arc = prepare(node);
553 554
        Node source = _digraph->source(arc);
554 555
        while ((*_node_order)[source] != -1) {
555 556
          if ((*_node_order)[source] >= 0) {
556 557
            arc = contract(source);
557 558
          } else {
558 559
            arc = prepare(source);
559 560
          }
560 561
          source = _digraph->source(arc);
561 562
        }
562 563
        finalize(arc);
563 564
        level_stack.clear();
564 565
      }
565 566
      return node;
566 567
    }
567 568

	
568 569
    /// \brief Returns the number of the nodes to be processed.
569 570
    ///
570 571
    /// Returns the number of the nodes to be processed in the priority
571 572
    /// queue.
572 573
    int queueSize() const {
573 574
      return queue.size();
574 575
    }
575 576

	
576 577
    /// \brief Returns \c false if there are nodes to be processed.
577 578
    ///
578 579
    /// Returns \c false if there are nodes to be processed.
579 580
    bool emptyQueue() const {
580 581
      return queue.empty();
581 582
    }
582 583

	
583 584
    /// \brief Executes the algorithm.
584 585
    ///
585 586
    /// Executes the algorithm.
586 587
    ///
587 588
    /// \pre init() must be called and at least one node should be added
588 589
    /// with addSource() before using this function.
589 590
    ///
590 591
    ///\note mca.start() is just a shortcut of the following code.
591 592
    ///\code
592 593
    ///while (!mca.emptyQueue()) {
593 594
    ///  mca.processNextNode();
594 595
    ///}
595 596
    ///\endcode
596 597
    void start() {
597 598
      while (!emptyQueue()) {
598 599
        processNextNode();
599 600
      }
600 601
    }
601 602

	
602 603
    /// \brief Runs %MinCostArborescence algorithm from node \c s.
603 604
    ///
604 605
    /// This method runs the %MinCostArborescence algorithm from
605 606
    /// a root node \c s.
606 607
    ///
607 608
    /// \note mca.run(s) is just a shortcut of the following code.
608 609
    /// \code
609 610
    /// mca.init();
610 611
    /// mca.addSource(s);
611 612
    /// mca.start();
612 613
    /// \endcode
613 614
    void run(Node s) {
614 615
      init();
615 616
      addSource(s);
616 617
      start();
617 618
    }
618 619

	
619 620
    ///@}
620 621

	
621 622
    /// \name Query Functions
622 623
    /// The result of the %MinCostArborescence algorithm can be obtained
623 624
    /// using these functions.\n
624 625
    /// Either run() or start() must be called before using them.
625 626

	
626 627
    /// @{
627 628

	
628 629
    /// \brief Returns the cost of the arborescence.
629 630
    ///
630 631
    /// Returns the cost of the arborescence.
631 632
    Value arborescenceCost() const {
632 633
      Value sum = 0;
633 634
      for (ArcIt it(*_digraph); it != INVALID; ++it) {
634 635
        if (arborescence(it)) {
635 636
          sum += (*_cost)[it];
636 637
        }
637 638
      }
638 639
      return sum;
639 640
    }
640 641

	
641 642
    /// \brief Returns \c true if the arc is in the arborescence.
642 643
    ///
643 644
    /// Returns \c true if the given arc is in the arborescence.
644 645
    /// \param arc An arc of the digraph.
645 646
    /// \pre \ref run() must be called before using this function.
646 647
    bool arborescence(Arc arc) const {
647 648
      return (*_pred)[_digraph->target(arc)] == arc;
648 649
    }
649 650

	
650 651
    /// \brief Returns a const reference to the arborescence map.
651 652
    ///
652 653
    /// Returns a const reference to the arborescence map.
653 654
    /// \pre \ref run() must be called before using this function.
654 655
    const ArborescenceMap& arborescenceMap() const {
655 656
      return *_arborescence;
656 657
    }
657 658

	
658 659
    /// \brief Returns the predecessor arc of the given node.
659 660
    ///
660 661
    /// Returns the predecessor arc of the given node.
661 662
    /// \pre \ref run() must be called before using this function.
662 663
    Arc pred(Node node) const {
663 664
      return (*_pred)[node];
664 665
    }
665 666

	
666 667
    /// \brief Returns a const reference to the pred map.
667 668
    ///
668 669
    /// Returns a const reference to the pred map.
669 670
    /// \pre \ref run() must be called before using this function.
670 671
    const PredMap& predMap() const {
671 672
      return *_pred;
672 673
    }
673 674

	
674 675
    /// \brief Indicates that a node is reachable from the sources.
675 676
    ///
676 677
    /// Indicates that a node is reachable from the sources.
677 678
    bool reached(Node node) const {
678 679
      return (*_node_order)[node] != -3;
679 680
    }
680 681

	
681 682
    /// \brief Indicates that a node is processed.
682 683
    ///
683 684
    /// Indicates that a node is processed. The arborescence path exists
684 685
    /// from the source to the given node.
685 686
    bool processed(Node node) const {
686 687
      return (*_node_order)[node] == -1;
687 688
    }
688 689

	
689 690
    /// \brief Returns the number of the dual variables in basis.
690 691
    ///
691 692
    /// Returns the number of the dual variables in basis.
692 693
    int dualNum() const {
693 694
      return _dual_variables.size();
694 695
    }
695 696

	
696 697
    /// \brief Returns the value of the dual solution.
697 698
    ///
698 699
    /// Returns the value of the dual solution. It should be
699 700
    /// equal to the arborescence value.
700 701
    Value dualValue() const {
701 702
      Value sum = 0;
702 703
      for (int i = 0; i < int(_dual_variables.size()); ++i) {
703 704
        sum += _dual_variables[i].value;
704 705
      }
705 706
      return sum;
706 707
    }
707 708

	
708 709
    /// \brief Returns the number of the nodes in the dual variable.
709 710
    ///
710 711
    /// Returns the number of the nodes in the dual variable.
711 712
    int dualSize(int k) const {
712 713
      return _dual_variables[k].end - _dual_variables[k].begin;
713 714
    }
714 715

	
715 716
    /// \brief Returns the value of the dual variable.
716 717
    ///
717 718
    /// Returns the the value of the dual variable.
718 719
    Value dualValue(int k) const {
719 720
      return _dual_variables[k].value;
720 721
    }
721 722

	
722 723
    /// \brief LEMON iterator for getting a dual variable.
723 724
    ///
724 725
    /// This class provides a common style LEMON iterator for getting a
725 726
    /// dual variable of \ref MinCostArborescence algorithm.
726 727
    /// It iterates over a subset of the nodes.
727 728
    class DualIt {
728 729
    public:
729 730

	
730 731
      /// \brief Constructor.
731 732
      ///
732 733
      /// Constructor for getting the nodeset of the dual variable
733 734
      /// of \ref MinCostArborescence algorithm.
734 735
      DualIt(const MinCostArborescence& algorithm, int variable)
735 736
        : _algorithm(&algorithm)
736 737
      {
737 738
        _index = _algorithm->_dual_variables[variable].begin;
738 739
        _last = _algorithm->_dual_variables[variable].end;
739 740
      }
740 741

	
741 742
      /// \brief Conversion to \c Node.
742 743
      ///
743 744
      /// Conversion to \c Node.
744 745
      operator Node() const {
745 746
        return _algorithm->_dual_node_list[_index];
746 747
      }
747 748

	
748 749
      /// \brief Increment operator.
749 750
      ///
750 751
      /// Increment operator.
751 752
      DualIt& operator++() {
752 753
        ++_index;
753 754
        return *this;
754 755
      }
755 756

	
756 757
      /// \brief Validity checking
757 758
      ///
758 759
      /// Checks whether the iterator is invalid.
759 760
      bool operator==(Invalid) const {
760 761
        return _index == _last;
761 762
      }
762 763

	
763 764
      /// \brief Validity checking
764 765
      ///
765 766
      /// Checks whether the iterator is valid.
766 767
      bool operator!=(Invalid) const {
767 768
        return _index != _last;
768 769
      }
769 770

	
770 771
    private:
771 772
      const MinCostArborescence* _algorithm;
772 773
      int _index, _last;
773 774
    };
774 775

	
775 776
    /// @}
776 777

	
777 778
  };
778 779

	
779 780
  /// \ingroup spantree
780 781
  ///
781 782
  /// \brief Function type interface for MinCostArborescence algorithm.
782 783
  ///
783 784
  /// Function type interface for MinCostArborescence algorithm.
784 785
  /// \param digraph The digraph the algorithm runs on.
785 786
  /// \param cost An arc map storing the costs.
786 787
  /// \param source The source node of the arborescence.
787 788
  /// \retval arborescence An arc map with \c bool (or convertible) value
788 789
  /// type that stores the arborescence.
789 790
  /// \return The total cost of the arborescence.
790 791
  ///
791 792
  /// \sa MinCostArborescence
792 793
  template <typename Digraph, typename CostMap, typename ArborescenceMap>
793 794
  typename CostMap::Value minCostArborescence(const Digraph& digraph,
794 795
                                              const CostMap& cost,
795 796
                                              typename Digraph::Node source,
796 797
                                              ArborescenceMap& arborescence) {
797 798
    typename MinCostArborescence<Digraph, CostMap>
798 799
      ::template SetArborescenceMap<ArborescenceMap>
799 800
      ::Create mca(digraph, cost);
800 801
    mca.arborescenceMap(arborescence);
801 802
    mca.run(source);
802 803
    return mca.arborescenceCost();
803 804
  }
804 805

	
805 806
}
806 807

	
807 808
#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-2009
5
 * Copyright (C) 2003-2010
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_NETWORK_SIMPLEX_H
20 20
#define LEMON_NETWORK_SIMPLEX_H
21 21

	
22 22
/// \ingroup min_cost_flow_algs
23 23
///
24 24
/// \file
25 25
/// \brief Network Simplex algorithm for finding a minimum cost flow.
26 26

	
27 27
#include <vector>
28 28
#include <limits>
29 29
#include <algorithm>
30 30

	
31 31
#include <lemon/core.h>
32 32
#include <lemon/math.h>
33 33

	
34 34
namespace lemon {
35 35

	
36 36
  /// \addtogroup min_cost_flow_algs
37 37
  /// @{
38 38

	
39 39
  /// \brief Implementation of the primal Network Simplex algorithm
40 40
  /// for finding a \ref min_cost_flow "minimum cost flow".
41 41
  ///
42 42
  /// \ref NetworkSimplex implements the primal Network Simplex algorithm
43
  /// for finding a \ref min_cost_flow "minimum cost flow".
44
  /// This algorithm is a specialized version of the linear programming
45
  /// simplex method directly for the minimum cost flow problem.
46
  /// It is one of the most efficient solution methods.
43
  /// for finding a \ref min_cost_flow "minimum cost flow"
44
  /// \ref amo93networkflows, \ref dantzig63linearprog,
45
  /// \ref kellyoneill91netsimplex.
46
  /// This algorithm is a highly efficient specialized version of the
47
  /// linear programming simplex method directly for the minimum cost
48
  /// flow problem.
47 49
  ///
48
  /// In general this class is the fastest implementation available
49
  /// in LEMON for the minimum cost flow problem.
50
  /// Moreover it supports both directions of the supply/demand inequality
51
  /// constraints. For more information see \ref SupplyType.
50
  /// In general, %NetworkSimplex is the fastest implementation available
51
  /// in LEMON for this problem.
52
  /// Moreover, it supports both directions of the supply/demand inequality
53
  /// constraints. For more information, see \ref SupplyType.
52 54
  ///
53 55
  /// Most of the parameters of the problem (except for the digraph)
54 56
  /// can be given using separate functions, and the algorithm can be
55 57
  /// executed using the \ref run() function. If some parameters are not
56 58
  /// specified, then default values will be used.
57 59
  ///
58 60
  /// \tparam GR The digraph type the algorithm runs on.
59
  /// \tparam V The value type used for flow amounts, capacity bounds
60
  /// and supply values in the algorithm. By default it is \c int.
61
  /// \tparam C The value type used for costs and potentials in the
62
  /// algorithm. By default it is the same as \c V.
61
  /// \tparam V The number type used for flow amounts, capacity bounds
62
  /// and supply values in the algorithm. By default, it is \c int.
63
  /// \tparam C The number type used for costs and potentials in the
64
  /// algorithm. By default, it is the same as \c V.
63 65
  ///
64
  /// \warning Both value types must be signed and all input data must
66
  /// \warning Both number types must be signed and all input data must
65 67
  /// be integer.
66 68
  ///
67 69
  /// \note %NetworkSimplex provides five different pivot rule
68 70
  /// implementations, from which the most efficient one is used
69
  /// by default. For more information see \ref PivotRule.
71
  /// by default. For more information, see \ref PivotRule.
70 72
  template <typename GR, typename V = int, typename C = V>
71 73
  class NetworkSimplex
72 74
  {
73 75
  public:
74 76

	
75 77
    /// The type of the flow amounts, capacity bounds and supply values
76 78
    typedef V Value;
77 79
    /// The type of the arc costs
78 80
    typedef C Cost;
79 81

	
80 82
  public:
81 83

	
82 84
    /// \brief Problem type constants for the \c run() function.
83 85
    ///
84 86
    /// Enum type containing the problem type constants that can be
85 87
    /// returned by the \ref run() function of the algorithm.
86 88
    enum ProblemType {
87 89
      /// The problem has no feasible solution (flow).
88 90
      INFEASIBLE,
89 91
      /// The problem has optimal solution (i.e. it is feasible and
90 92
      /// bounded), and the algorithm has found optimal flow and node
91 93
      /// potentials (primal and dual solutions).
92 94
      OPTIMAL,
93 95
      /// The objective function of the problem is unbounded, i.e.
94 96
      /// there is a directed cycle having negative total cost and
95 97
      /// infinite upper bound.
96 98
      UNBOUNDED
97 99
    };
98
    
100

	
99 101
    /// \brief Constants for selecting the type of the supply constraints.
100 102
    ///
101 103
    /// Enum type containing constants for selecting the supply type,
102 104
    /// i.e. the direction of the inequalities in the supply/demand
103 105
    /// constraints of the \ref min_cost_flow "minimum cost flow problem".
104 106
    ///
105 107
    /// The default supply type is \c GEQ, the \c LEQ type can be
106 108
    /// selected using \ref supplyType().
107 109
    /// The equality form is a special case of both supply types.
108 110
    enum SupplyType {
109 111
      /// This option means that there are <em>"greater or equal"</em>
110 112
      /// supply/demand constraints in the definition of the problem.
111 113
      GEQ,
112 114
      /// This option means that there are <em>"less or equal"</em>
113 115
      /// supply/demand constraints in the definition of the problem.
114 116
      LEQ
115 117
    };
116
    
118

	
117 119
    /// \brief Constants for selecting the pivot rule.
118 120
    ///
119 121
    /// Enum type containing constants for selecting the pivot rule for
120 122
    /// the \ref run() function.
121 123
    ///
122 124
    /// \ref NetworkSimplex provides five different pivot rule
123 125
    /// implementations that significantly affect the running time
124 126
    /// of the algorithm.
125
    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
127
    /// By default, \ref BLOCK_SEARCH "Block Search" is used, which
126 128
    /// proved to be the most efficient and the most robust on various
127
    /// test inputs according to our benchmark tests.
128
    /// However another pivot rule can be selected using the \ref run()
129
    /// test inputs.
130
    /// However, another pivot rule can be selected using the \ref run()
129 131
    /// function with the proper parameter.
130 132
    enum PivotRule {
131 133

	
132
      /// The First Eligible pivot rule.
134
      /// The \e First \e Eligible pivot rule.
133 135
      /// The next eligible arc is selected in a wraparound fashion
134 136
      /// in every iteration.
135 137
      FIRST_ELIGIBLE,
136 138

	
137
      /// The Best Eligible pivot rule.
139
      /// The \e Best \e Eligible pivot rule.
138 140
      /// The best eligible arc is selected in every iteration.
139 141
      BEST_ELIGIBLE,
140 142

	
141
      /// The Block Search pivot rule.
143
      /// The \e Block \e Search pivot rule.
142 144
      /// A specified number of arcs are examined in every iteration
143 145
      /// in a wraparound fashion and the best eligible arc is selected
144 146
      /// from this block.
145 147
      BLOCK_SEARCH,
146 148

	
147
      /// The Candidate List pivot rule.
149
      /// The \e Candidate \e List pivot rule.
148 150
      /// In a major iteration a candidate list is built from eligible arcs
149 151
      /// in a wraparound fashion and in the following minor iterations
150 152
      /// the best eligible arc is selected from this list.
151 153
      CANDIDATE_LIST,
152 154

	
153
      /// The Altering Candidate List pivot rule.
155
      /// The \e Altering \e Candidate \e List pivot rule.
154 156
      /// It is a modified version of the Candidate List method.
155 157
      /// It keeps only the several best eligible arcs from the former
156 158
      /// candidate list and extends this list in every iteration.
157 159
      ALTERING_LIST
158 160
    };
159
    
161

	
160 162
  private:
161 163

	
162 164
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
163 165

	
164
    typedef std::vector<Arc> ArcVector;
165
    typedef std::vector<Node> NodeVector;
166 166
    typedef std::vector<int> IntVector;
167
    typedef std::vector<bool> BoolVector;
168 167
    typedef std::vector<Value> ValueVector;
169 168
    typedef std::vector<Cost> CostVector;
169
    typedef std::vector<char> BoolVector;
170
    // Note: vector<char> is used instead of vector<bool> for efficiency reasons
170 171

	
171 172
    // State constants for arcs
172
    enum ArcStateEnum {
173
    enum ArcState {
173 174
      STATE_UPPER = -1,
174 175
      STATE_TREE  =  0,
175 176
      STATE_LOWER =  1
176 177
    };
177 178

	
179
    typedef std::vector<signed char> StateVector;
180
    // Note: vector<signed char> is used instead of vector<ArcState> for
181
    // efficiency reasons
182

	
178 183
  private:
179 184

	
180 185
    // Data related to the underlying digraph
181 186
    const GR &_graph;
182 187
    int _node_num;
183 188
    int _arc_num;
184 189
    int _all_arc_num;
185 190
    int _search_arc_num;
186 191

	
187 192
    // Parameters of the problem
188 193
    bool _have_lower;
189 194
    SupplyType _stype;
190 195
    Value _sum_supply;
191 196

	
192 197
    // Data structures for storing the digraph
193 198
    IntNodeMap _node_id;
194 199
    IntArcMap _arc_id;
195 200
    IntVector _source;
196 201
    IntVector _target;
202
    bool _arc_mixing;
197 203

	
198 204
    // Node and arc data
199 205
    ValueVector _lower;
200 206
    ValueVector _upper;
201 207
    ValueVector _cap;
202 208
    CostVector _cost;
203 209
    ValueVector _supply;
204 210
    ValueVector _flow;
205 211
    CostVector _pi;
206 212

	
207 213
    // Data for storing the spanning tree structure
208 214
    IntVector _parent;
209 215
    IntVector _pred;
210 216
    IntVector _thread;
211 217
    IntVector _rev_thread;
212 218
    IntVector _succ_num;
213 219
    IntVector _last_succ;
214 220
    IntVector _dirty_revs;
215 221
    BoolVector _forward;
216
    IntVector _state;
222
    StateVector _state;
217 223
    int _root;
218 224

	
219 225
    // Temporary data used in the current pivot iteration
220 226
    int in_arc, join, u_in, v_in, u_out, v_out;
221 227
    int first, second, right, last;
222 228
    int stem, par_stem, new_stem;
223 229
    Value delta;
224 230

	
231
    const Value MAX;
232

	
225 233
  public:
226
  
234

	
227 235
    /// \brief Constant for infinite upper bounds (capacities).
228 236
    ///
229 237
    /// Constant for infinite upper bounds (capacities).
230 238
    /// It is \c std::numeric_limits<Value>::infinity() if available,
231 239
    /// \c std::numeric_limits<Value>::max() otherwise.
232 240
    const Value INF;
233 241

	
234 242
  private:
235 243

	
236 244
    // Implementation of the First Eligible pivot rule
237 245
    class FirstEligiblePivotRule
238 246
    {
239 247
    private:
240 248

	
241 249
      // References to the NetworkSimplex class
242 250
      const IntVector  &_source;
243 251
      const IntVector  &_target;
244 252
      const CostVector &_cost;
245
      const IntVector  &_state;
253
      const StateVector &_state;
246 254
      const CostVector &_pi;
247 255
      int &_in_arc;
248 256
      int _search_arc_num;
249 257

	
250 258
      // Pivot rule data
251 259
      int _next_arc;
252 260

	
253 261
    public:
254 262

	
255 263
      // Constructor
256 264
      FirstEligiblePivotRule(NetworkSimplex &ns) :
257 265
        _source(ns._source), _target(ns._target),
258 266
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
259 267
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
260 268
        _next_arc(0)
261 269
      {}
262 270

	
263 271
      // Find next entering arc
264 272
      bool findEnteringArc() {
265 273
        Cost c;
266
        for (int e = _next_arc; e < _search_arc_num; ++e) {
274
        for (int e = _next_arc; e != _search_arc_num; ++e) {
267 275
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
268 276
          if (c < 0) {
269 277
            _in_arc = e;
270 278
            _next_arc = e + 1;
271 279
            return true;
272 280
          }
273 281
        }
274
        for (int e = 0; e < _next_arc; ++e) {
282
        for (int e = 0; e != _next_arc; ++e) {
275 283
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
276 284
          if (c < 0) {
277 285
            _in_arc = e;
278 286
            _next_arc = e + 1;
279 287
            return true;
280 288
          }
281 289
        }
282 290
        return false;
283 291
      }
284 292

	
285 293
    }; //class FirstEligiblePivotRule
286 294

	
287 295

	
288 296
    // Implementation of the Best Eligible pivot rule
289 297
    class BestEligiblePivotRule
290 298
    {
291 299
    private:
292 300

	
293 301
      // References to the NetworkSimplex class
294 302
      const IntVector  &_source;
295 303
      const IntVector  &_target;
296 304
      const CostVector &_cost;
297
      const IntVector  &_state;
305
      const StateVector &_state;
298 306
      const CostVector &_pi;
299 307
      int &_in_arc;
300 308
      int _search_arc_num;
301 309

	
302 310
    public:
303 311

	
304 312
      // Constructor
305 313
      BestEligiblePivotRule(NetworkSimplex &ns) :
306 314
        _source(ns._source), _target(ns._target),
307 315
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
308 316
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num)
309 317
      {}
310 318

	
311 319
      // Find next entering arc
312 320
      bool findEnteringArc() {
313 321
        Cost c, min = 0;
314
        for (int e = 0; e < _search_arc_num; ++e) {
322
        for (int e = 0; e != _search_arc_num; ++e) {
315 323
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
316 324
          if (c < min) {
317 325
            min = c;
318 326
            _in_arc = e;
319 327
          }
320 328
        }
321 329
        return min < 0;
322 330
      }
323 331

	
324 332
    }; //class BestEligiblePivotRule
325 333

	
326 334

	
327 335
    // Implementation of the Block Search pivot rule
328 336
    class BlockSearchPivotRule
329 337
    {
330 338
    private:
331 339

	
332 340
      // References to the NetworkSimplex class
333 341
      const IntVector  &_source;
334 342
      const IntVector  &_target;
335 343
      const CostVector &_cost;
336
      const IntVector  &_state;
344
      const StateVector &_state;
337 345
      const CostVector &_pi;
338 346
      int &_in_arc;
339 347
      int _search_arc_num;
340 348

	
341 349
      // Pivot rule data
342 350
      int _block_size;
343 351
      int _next_arc;
344 352

	
345 353
    public:
346 354

	
347 355
      // Constructor
348 356
      BlockSearchPivotRule(NetworkSimplex &ns) :
349 357
        _source(ns._source), _target(ns._target),
350 358
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
351 359
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
352 360
        _next_arc(0)
353 361
      {
354 362
        // The main parameters of the pivot rule
355
        const double BLOCK_SIZE_FACTOR = 0.5;
363
        const double BLOCK_SIZE_FACTOR = 1.0;
356 364
        const int MIN_BLOCK_SIZE = 10;
357 365

	
358 366
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
359 367
                                    std::sqrt(double(_search_arc_num))),
360 368
                                MIN_BLOCK_SIZE );
361 369
      }
362 370

	
363 371
      // Find next entering arc
364 372
      bool findEnteringArc() {
365 373
        Cost c, min = 0;
366 374
        int cnt = _block_size;
367
        int e, min_arc = _next_arc;
368
        for (e = _next_arc; e < _search_arc_num; ++e) {
375
        int e;
376
        for (e = _next_arc; e != _search_arc_num; ++e) {
369 377
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
370 378
          if (c < min) {
371 379
            min = c;
372
            min_arc = e;
380
            _in_arc = e;
373 381
          }
374 382
          if (--cnt == 0) {
375
            if (min < 0) break;
383
            if (min < 0) goto search_end;
376 384
            cnt = _block_size;
377 385
          }
378 386
        }
379
        if (min == 0 || cnt > 0) {
380
          for (e = 0; e < _next_arc; ++e) {
381
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
382
            if (c < min) {
383
              min = c;
384
              min_arc = e;
385
            }
386
            if (--cnt == 0) {
387
              if (min < 0) break;
388
              cnt = _block_size;
389
            }
387
        for (e = 0; e != _next_arc; ++e) {
388
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
389
          if (c < min) {
390
            min = c;
391
            _in_arc = e;
392
          }
393
          if (--cnt == 0) {
394
            if (min < 0) goto search_end;
395
            cnt = _block_size;
390 396
          }
391 397
        }
392 398
        if (min >= 0) return false;
393
        _in_arc = min_arc;
399

	
400
      search_end:
394 401
        _next_arc = e;
395 402
        return true;
396 403
      }
397 404

	
398 405
    }; //class BlockSearchPivotRule
399 406

	
400 407

	
401 408
    // Implementation of the Candidate List pivot rule
402 409
    class CandidateListPivotRule
403 410
    {
404 411
    private:
405 412

	
406 413
      // References to the NetworkSimplex class
407 414
      const IntVector  &_source;
408 415
      const IntVector  &_target;
409 416
      const CostVector &_cost;
410
      const IntVector  &_state;
417
      const StateVector &_state;
411 418
      const CostVector &_pi;
412 419
      int &_in_arc;
413 420
      int _search_arc_num;
414 421

	
415 422
      // Pivot rule data
416 423
      IntVector _candidates;
417 424
      int _list_length, _minor_limit;
418 425
      int _curr_length, _minor_count;
419 426
      int _next_arc;
420 427

	
421 428
    public:
422 429

	
423 430
      /// Constructor
424 431
      CandidateListPivotRule(NetworkSimplex &ns) :
425 432
        _source(ns._source), _target(ns._target),
426 433
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
427 434
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
428 435
        _next_arc(0)
429 436
      {
430 437
        // The main parameters of the pivot rule
431
        const double LIST_LENGTH_FACTOR = 1.0;
438
        const double LIST_LENGTH_FACTOR = 0.25;
432 439
        const int MIN_LIST_LENGTH = 10;
433 440
        const double MINOR_LIMIT_FACTOR = 0.1;
434 441
        const int MIN_MINOR_LIMIT = 3;
435 442

	
436 443
        _list_length = std::max( int(LIST_LENGTH_FACTOR *
437 444
                                     std::sqrt(double(_search_arc_num))),
438 445
                                 MIN_LIST_LENGTH );
439 446
        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
440 447
                                 MIN_MINOR_LIMIT );
441 448
        _curr_length = _minor_count = 0;
442 449
        _candidates.resize(_list_length);
443 450
      }
444 451

	
445 452
      /// Find next entering arc
446 453
      bool findEnteringArc() {
447 454
        Cost min, c;
448
        int e, min_arc = _next_arc;
455
        int e;
449 456
        if (_curr_length > 0 && _minor_count < _minor_limit) {
450 457
          // Minor iteration: select the best eligible arc from the
451 458
          // current candidate list
452 459
          ++_minor_count;
453 460
          min = 0;
454 461
          for (int i = 0; i < _curr_length; ++i) {
455 462
            e = _candidates[i];
456 463
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
457 464
            if (c < min) {
458 465
              min = c;
459
              min_arc = e;
466
              _in_arc = e;
460 467
            }
461
            if (c >= 0) {
468
            else if (c >= 0) {
462 469
              _candidates[i--] = _candidates[--_curr_length];
463 470
            }
464 471
          }
465
          if (min < 0) {
466
            _in_arc = min_arc;
467
            return true;
468
          }
472
          if (min < 0) return true;
469 473
        }
470 474

	
471 475
        // Major iteration: build a new candidate list
472 476
        min = 0;
473 477
        _curr_length = 0;
474
        for (e = _next_arc; e < _search_arc_num; ++e) {
478
        for (e = _next_arc; e != _search_arc_num; ++e) {
475 479
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
476 480
          if (c < 0) {
477 481
            _candidates[_curr_length++] = e;
478 482
            if (c < min) {
479 483
              min = c;
480
              min_arc = e;
484
              _in_arc = e;
481 485
            }
482
            if (_curr_length == _list_length) break;
486
            if (_curr_length == _list_length) goto search_end;
483 487
          }
484 488
        }
485
        if (_curr_length < _list_length) {
486
          for (e = 0; e < _next_arc; ++e) {
487
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
488
            if (c < 0) {
489
              _candidates[_curr_length++] = e;
490
              if (c < min) {
491
                min = c;
492
                min_arc = e;
493
              }
494
              if (_curr_length == _list_length) break;
489
        for (e = 0; e != _next_arc; ++e) {
490
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
491
          if (c < 0) {
492
            _candidates[_curr_length++] = e;
493
            if (c < min) {
494
              min = c;
495
              _in_arc = e;
495 496
            }
497
            if (_curr_length == _list_length) goto search_end;
496 498
          }
497 499
        }
498 500
        if (_curr_length == 0) return false;
501

	
502
      search_end:
499 503
        _minor_count = 1;
500
        _in_arc = min_arc;
501 504
        _next_arc = e;
502 505
        return true;
503 506
      }
504 507

	
505 508
    }; //class CandidateListPivotRule
506 509

	
507 510

	
508 511
    // Implementation of the Altering Candidate List pivot rule
509 512
    class AlteringListPivotRule
510 513
    {
511 514
    private:
512 515

	
513 516
      // References to the NetworkSimplex class
514 517
      const IntVector  &_source;
515 518
      const IntVector  &_target;
516 519
      const CostVector &_cost;
517
      const IntVector  &_state;
520
      const StateVector &_state;
518 521
      const CostVector &_pi;
519 522
      int &_in_arc;
520 523
      int _search_arc_num;
521 524

	
522 525
      // Pivot rule data
523 526
      int _block_size, _head_length, _curr_length;
524 527
      int _next_arc;
525 528
      IntVector _candidates;
526 529
      CostVector _cand_cost;
527 530

	
528 531
      // Functor class to compare arcs during sort of the candidate list
529 532
      class SortFunc
530 533
      {
531 534
      private:
532 535
        const CostVector &_map;
533 536
      public:
534 537
        SortFunc(const CostVector &map) : _map(map) {}
535 538
        bool operator()(int left, int right) {
536 539
          return _map[left] > _map[right];
537 540
        }
538 541
      };
539 542

	
540 543
      SortFunc _sort_func;
541 544

	
542 545
    public:
543 546

	
544 547
      // Constructor
545 548
      AlteringListPivotRule(NetworkSimplex &ns) :
546 549
        _source(ns._source), _target(ns._target),
547 550
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
548 551
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
549 552
        _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
550 553
      {
551 554
        // The main parameters of the pivot rule
552
        const double BLOCK_SIZE_FACTOR = 1.5;
555
        const double BLOCK_SIZE_FACTOR = 1.0;
553 556
        const int MIN_BLOCK_SIZE = 10;
554 557
        const double HEAD_LENGTH_FACTOR = 0.1;
555 558
        const int MIN_HEAD_LENGTH = 3;
556 559

	
557 560
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
558 561
                                    std::sqrt(double(_search_arc_num))),
559 562
                                MIN_BLOCK_SIZE );
560 563
        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
561 564
                                 MIN_HEAD_LENGTH );
562 565
        _candidates.resize(_head_length + _block_size);
563 566
        _curr_length = 0;
564 567
      }
565 568

	
566 569
      // Find next entering arc
567 570
      bool findEnteringArc() {
568 571
        // Check the current candidate list
569 572
        int e;
570
        for (int i = 0; i < _curr_length; ++i) {
573
        for (int i = 0; i != _curr_length; ++i) {
571 574
          e = _candidates[i];
572 575
          _cand_cost[e] = _state[e] *
573 576
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
574 577
          if (_cand_cost[e] >= 0) {
575 578
            _candidates[i--] = _candidates[--_curr_length];
576 579
          }
577 580
        }
578 581

	
579 582
        // Extend the list
580 583
        int cnt = _block_size;
581
        int last_arc = 0;
582 584
        int limit = _head_length;
583 585

	
584
        for (int e = _next_arc; e < _search_arc_num; ++e) {
586
        for (e = _next_arc; e != _search_arc_num; ++e) {
585 587
          _cand_cost[e] = _state[e] *
586 588
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
587 589
          if (_cand_cost[e] < 0) {
588 590
            _candidates[_curr_length++] = e;
589
            last_arc = e;
590 591
          }
591 592
          if (--cnt == 0) {
592
            if (_curr_length > limit) break;
593
            if (_curr_length > limit) goto search_end;
593 594
            limit = 0;
594 595
            cnt = _block_size;
595 596
          }
596 597
        }
597
        if (_curr_length <= limit) {
598
          for (int e = 0; e < _next_arc; ++e) {
599
            _cand_cost[e] = _state[e] *
600
              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
601
            if (_cand_cost[e] < 0) {
602
              _candidates[_curr_length++] = e;
603
              last_arc = e;
604
            }
605
            if (--cnt == 0) {
606
              if (_curr_length > limit) break;
607
              limit = 0;
608
              cnt = _block_size;
609
            }
598
        for (e = 0; e != _next_arc; ++e) {
599
          _cand_cost[e] = _state[e] *
600
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
601
          if (_cand_cost[e] < 0) {
602
            _candidates[_curr_length++] = e;
603
          }
604
          if (--cnt == 0) {
605
            if (_curr_length > limit) goto search_end;
606
            limit = 0;
607
            cnt = _block_size;
610 608
          }
611 609
        }
612 610
        if (_curr_length == 0) return false;
613
        _next_arc = last_arc + 1;
611

	
612
      search_end:
614 613

	
615 614
        // Make heap of the candidate list (approximating a partial sort)
616 615
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
617 616
                   _sort_func );
618 617

	
619 618
        // Pop the first element of the heap
620 619
        _in_arc = _candidates[0];
620
        _next_arc = e;
621 621
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
622 622
                  _sort_func );
623 623
        _curr_length = std::min(_head_length, _curr_length - 1);
624 624
        return true;
625 625
      }
626 626

	
627 627
    }; //class AlteringListPivotRule
628 628

	
629 629
  public:
630 630

	
631 631
    /// \brief Constructor.
632 632
    ///
633 633
    /// The constructor of the class.
634 634
    ///
635 635
    /// \param graph The digraph the algorithm runs on.
636
    NetworkSimplex(const GR& graph) :
636
    /// \param arc_mixing Indicate if the arcs have to be stored in a
637
    /// mixed order in the internal data structure.
638
    /// In special cases, it could lead to better overall performance,
639
    /// but it is usually slower. Therefore it is disabled by default.
640
    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
637 641
      _graph(graph), _node_id(graph), _arc_id(graph),
642
      _arc_mixing(arc_mixing),
643
      MAX(std::numeric_limits<Value>::max()),
638 644
      INF(std::numeric_limits<Value>::has_infinity ?
639
          std::numeric_limits<Value>::infinity() :
640
          std::numeric_limits<Value>::max())
645
          std::numeric_limits<Value>::infinity() : MAX)
641 646
    {
642
      // Check the value types
647
      // Check the number types
643 648
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
644 649
        "The flow type of NetworkSimplex must be signed");
645 650
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
646 651
        "The cost type of NetworkSimplex must be signed");
647
        
648
      // Resize vectors
649
      _node_num = countNodes(_graph);
650
      _arc_num = countArcs(_graph);
651
      int all_node_num = _node_num + 1;
652
      int max_arc_num = _arc_num + 2 * _node_num;
653 652

	
654
      _source.resize(max_arc_num);
655
      _target.resize(max_arc_num);
656

	
657
      _lower.resize(_arc_num);
658
      _upper.resize(_arc_num);
659
      _cap.resize(max_arc_num);
660
      _cost.resize(max_arc_num);
661
      _supply.resize(all_node_num);
662
      _flow.resize(max_arc_num);
663
      _pi.resize(all_node_num);
664

	
665
      _parent.resize(all_node_num);
666
      _pred.resize(all_node_num);
667
      _forward.resize(all_node_num);
668
      _thread.resize(all_node_num);
669
      _rev_thread.resize(all_node_num);
670
      _succ_num.resize(all_node_num);
671
      _last_succ.resize(all_node_num);
672
      _state.resize(max_arc_num);
673

	
674
      // Copy the graph (store the arcs in a mixed order)
675
      int i = 0;
676
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
677
        _node_id[n] = i;
678
      }
679
      int k = std::max(int(std::sqrt(double(_arc_num))), 10);
680
      i = 0;
681
      for (ArcIt a(_graph); a != INVALID; ++a) {
682
        _arc_id[a] = i;
683
        _source[i] = _node_id[_graph.source(a)];
684
        _target[i] = _node_id[_graph.target(a)];
685
        if ((i += k) >= _arc_num) i = (i % k) + 1;
686
      }
687
      
688
      // Initialize maps
689
      for (int i = 0; i != _node_num; ++i) {
690
        _supply[i] = 0;
691
      }
692
      for (int i = 0; i != _arc_num; ++i) {
693
        _lower[i] = 0;
694
        _upper[i] = INF;
695
        _cost[i] = 1;
696
      }
697
      _have_lower = false;
698
      _stype = GEQ;
653
      // Reset data structures
654
      reset();
699 655
    }
700 656

	
701 657
    /// \name Parameters
702 658
    /// The parameters of the algorithm can be specified using these
703 659
    /// functions.
704 660

	
705 661
    /// @{
706 662

	
707 663
    /// \brief Set the lower bounds on the arcs.
708 664
    ///
709 665
    /// This function sets the lower bounds on the arcs.
710 666
    /// If it is not used before calling \ref run(), the lower bounds
711 667
    /// will be set to zero on all arcs.
712 668
    ///
713 669
    /// \param map An arc map storing the lower bounds.
714 670
    /// Its \c Value type must be convertible to the \c Value type
715 671
    /// of the algorithm.
716 672
    ///
717 673
    /// \return <tt>(*this)</tt>
718 674
    template <typename LowerMap>
719 675
    NetworkSimplex& lowerMap(const LowerMap& map) {
720 676
      _have_lower = true;
721 677
      for (ArcIt a(_graph); a != INVALID; ++a) {
722 678
        _lower[_arc_id[a]] = map[a];
723 679
      }
724 680
      return *this;
725 681
    }
726 682

	
727 683
    /// \brief Set the upper bounds (capacities) on the arcs.
728 684
    ///
729 685
    /// This function sets the upper bounds (capacities) on the arcs.
730 686
    /// If it is not used before calling \ref run(), the upper bounds
731 687
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
732
    /// unbounded from above on each arc).
688
    /// unbounded from above).
733 689
    ///
734 690
    /// \param map An arc map storing the upper bounds.
735 691
    /// Its \c Value type must be convertible to the \c Value type
736 692
    /// of the algorithm.
737 693
    ///
738 694
    /// \return <tt>(*this)</tt>
739 695
    template<typename UpperMap>
740 696
    NetworkSimplex& upperMap(const UpperMap& map) {
741 697
      for (ArcIt a(_graph); a != INVALID; ++a) {
742 698
        _upper[_arc_id[a]] = map[a];
743 699
      }
744 700
      return *this;
745 701
    }
746 702

	
747 703
    /// \brief Set the costs of the arcs.
748 704
    ///
749 705
    /// This function sets the costs of the arcs.
750 706
    /// If it is not used before calling \ref run(), the costs
751 707
    /// will be set to \c 1 on all arcs.
752 708
    ///
753 709
    /// \param map An arc map storing the costs.
754 710
    /// Its \c Value type must be convertible to the \c Cost type
755 711
    /// of the algorithm.
756 712
    ///
757 713
    /// \return <tt>(*this)</tt>
758 714
    template<typename CostMap>
759 715
    NetworkSimplex& costMap(const CostMap& map) {
760 716
      for (ArcIt a(_graph); a != INVALID; ++a) {
761 717
        _cost[_arc_id[a]] = map[a];
762 718
      }
763 719
      return *this;
764 720
    }
765 721

	
766 722
    /// \brief Set the supply values of the nodes.
767 723
    ///
768 724
    /// This function sets the supply values of the nodes.
769 725
    /// If neither this function nor \ref stSupply() is used before
770 726
    /// calling \ref run(), the supply of each node will be set to zero.
771
    /// (It makes sense only if non-zero lower bounds are given.)
772 727
    ///
773 728
    /// \param map A node map storing the supply values.
774 729
    /// Its \c Value type must be convertible to the \c Value type
775 730
    /// of the algorithm.
776 731
    ///
777 732
    /// \return <tt>(*this)</tt>
778 733
    template<typename SupplyMap>
779 734
    NetworkSimplex& supplyMap(const SupplyMap& map) {
780 735
      for (NodeIt n(_graph); n != INVALID; ++n) {
781 736
        _supply[_node_id[n]] = map[n];
782 737
      }
783 738
      return *this;
784 739
    }
785 740

	
786 741
    /// \brief Set single source and target nodes and a supply value.
787 742
    ///
788 743
    /// This function sets a single source node and a single target node
789 744
    /// and the required flow value.
790 745
    /// If neither this function nor \ref supplyMap() is used before
791 746
    /// calling \ref run(), the supply of each node will be set to zero.
792
    /// (It makes sense only if non-zero lower bounds are given.)
793 747
    ///
794 748
    /// Using this function has the same effect as using \ref supplyMap()
795 749
    /// with such a map in which \c k is assigned to \c s, \c -k is
796 750
    /// assigned to \c t and all other nodes have zero supply value.
797 751
    ///
798 752
    /// \param s The source node.
799 753
    /// \param t The target node.
800 754
    /// \param k The required amount of flow from node \c s to node \c t
801 755
    /// (i.e. the supply of \c s and the demand of \c t).
802 756
    ///
803 757
    /// \return <tt>(*this)</tt>
804 758
    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
805 759
      for (int i = 0; i != _node_num; ++i) {
806 760
        _supply[i] = 0;
807 761
      }
808 762
      _supply[_node_id[s]] =  k;
809 763
      _supply[_node_id[t]] = -k;
810 764
      return *this;
811 765
    }
812
    
766

	
813 767
    /// \brief Set the type of the supply constraints.
814 768
    ///
815 769
    /// This function sets the type of the supply/demand constraints.
816 770
    /// If it is not used before calling \ref run(), the \ref GEQ supply
817 771
    /// type will be used.
818 772
    ///
819
    /// For more information see \ref SupplyType.
773
    /// For more information, see \ref SupplyType.
820 774
    ///
821 775
    /// \return <tt>(*this)</tt>
822 776
    NetworkSimplex& supplyType(SupplyType supply_type) {
823 777
      _stype = supply_type;
824 778
      return *this;
825 779
    }
826 780

	
827 781
    /// @}
828 782

	
829 783
    /// \name Execution Control
830 784
    /// The algorithm can be executed using \ref run().
831 785

	
832 786
    /// @{
833 787

	
834 788
    /// \brief Run the algorithm.
835 789
    ///
836 790
    /// This function runs the algorithm.
837 791
    /// The paramters can be specified using functions \ref lowerMap(),
838
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 
792
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
839 793
    /// \ref supplyType().
840 794
    /// For example,
841 795
    /// \code
842 796
    ///   NetworkSimplex<ListDigraph> ns(graph);
843 797
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
844 798
    ///     .supplyMap(sup).run();
845 799
    /// \endcode
846 800
    ///
847
    /// This function can be called more than once. All the parameters
848
    /// that have been given are kept for the next call, unless
849
    /// \ref reset() is called, thus only the modified parameters
850
    /// have to be set again. See \ref reset() for examples.
851
    /// However the underlying digraph must not be modified after this
852
    /// class have been constructed, since it copies and extends the graph.
801
    /// This function can be called more than once. All the given parameters
802
    /// are kept for the next call, unless \ref resetParams() or \ref reset()
803
    /// is used, thus only the modified parameters have to be set again.
804
    /// If the underlying digraph was also modified after the construction
805
    /// of the class (or the last \ref reset() call), then the \ref reset()
806
    /// function must be called.
853 807
    ///
854 808
    /// \param pivot_rule The pivot rule that will be used during the
855
    /// algorithm. For more information see \ref PivotRule.
809
    /// algorithm. For more information, see \ref PivotRule.
856 810
    ///
857 811
    /// \return \c INFEASIBLE if no feasible flow exists,
858 812
    /// \n \c OPTIMAL if the problem has optimal solution
859 813
    /// (i.e. it is feasible and bounded), and the algorithm has found
860 814
    /// optimal flow and node potentials (primal and dual solutions),
861 815
    /// \n \c UNBOUNDED if the objective function of the problem is
862 816
    /// unbounded, i.e. there is a directed cycle having negative total
863 817
    /// cost and infinite upper bound.
864 818
    ///
865 819
    /// \see ProblemType, PivotRule
820
    /// \see resetParams(), reset()
866 821
    ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
867 822
      if (!init()) return INFEASIBLE;
868 823
      return start(pivot_rule);
869 824
    }
870 825

	
871 826
    /// \brief Reset all the parameters that have been given before.
872 827
    ///
873 828
    /// This function resets all the paramaters that have been given
874 829
    /// before using functions \ref lowerMap(), \ref upperMap(),
875 830
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
876 831
    ///
877
    /// It is useful for multiple run() calls. If this function is not
878
    /// used, all the parameters given before are kept for the next
879
    /// \ref run() call.
880
    /// However the underlying digraph must not be modified after this
881
    /// class have been constructed, since it copies and extends the graph.
832
    /// It is useful for multiple \ref run() calls. Basically, all the given
833
    /// parameters are kept for the next \ref run() call, unless
834
    /// \ref resetParams() or \ref reset() is used.
835
    /// If the underlying digraph was also modified after the construction
836
    /// of the class or the last \ref reset() call, then the \ref reset()
837
    /// function must be used, otherwise \ref resetParams() is sufficient.
882 838
    ///
883 839
    /// For example,
884 840
    /// \code
885 841
    ///   NetworkSimplex<ListDigraph> ns(graph);
886 842
    ///
887 843
    ///   // First run
888 844
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
889 845
    ///     .supplyMap(sup).run();
890 846
    ///
891
    ///   // Run again with modified cost map (reset() is not called,
847
    ///   // Run again with modified cost map (resetParams() is not called,
892 848
    ///   // so only the cost map have to be set again)
893 849
    ///   cost[e] += 100;
894 850
    ///   ns.costMap(cost).run();
895 851
    ///
896
    ///   // Run again from scratch using reset()
852
    ///   // Run again from scratch using resetParams()
897 853
    ///   // (the lower bounds will be set to zero on all arcs)
898
    ///   ns.reset();
854
    ///   ns.resetParams();
899 855
    ///   ns.upperMap(capacity).costMap(cost)
900 856
    ///     .supplyMap(sup).run();
901 857
    /// \endcode
902 858
    ///
903 859
    /// \return <tt>(*this)</tt>
904
    NetworkSimplex& reset() {
860
    ///
861
    /// \see reset(), run()
862
    NetworkSimplex& resetParams() {
905 863
      for (int i = 0; i != _node_num; ++i) {
906 864
        _supply[i] = 0;
907 865
      }
908 866
      for (int i = 0; i != _arc_num; ++i) {
909 867
        _lower[i] = 0;
910 868
        _upper[i] = INF;
911 869
        _cost[i] = 1;
912 870
      }
913 871
      _have_lower = false;
914 872
      _stype = GEQ;
915 873
      return *this;
916 874
    }
917 875

	
876
    /// \brief Reset the internal data structures and all the parameters
877
    /// that have been given before.
878
    ///
879
    /// This function resets the internal data structures and all the
880
    /// paramaters that have been given before using functions \ref lowerMap(),
881
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
882
    /// \ref supplyType().
883
    ///
884
    /// It is useful for multiple \ref run() calls. Basically, all the given
885
    /// parameters are kept for the next \ref run() call, unless
886
    /// \ref resetParams() or \ref reset() is used.
887
    /// If the underlying digraph was also modified after the construction
888
    /// of the class or the last \ref reset() call, then the \ref reset()
889
    /// function must be used, otherwise \ref resetParams() is sufficient.
890
    ///
891
    /// See \ref resetParams() for examples.
892
    ///
893
    /// \return <tt>(*this)</tt>
894
    ///
895
    /// \see resetParams(), run()
896
    NetworkSimplex& reset() {
897
      // Resize vectors
898
      _node_num = countNodes(_graph);
899
      _arc_num = countArcs(_graph);
900
      int all_node_num = _node_num + 1;
901
      int max_arc_num = _arc_num + 2 * _node_num;
902

	
903
      _source.resize(max_arc_num);
904
      _target.resize(max_arc_num);
905

	
906
      _lower.resize(_arc_num);
907
      _upper.resize(_arc_num);
908
      _cap.resize(max_arc_num);
909
      _cost.resize(max_arc_num);
910
      _supply.resize(all_node_num);
911
      _flow.resize(max_arc_num);
912
      _pi.resize(all_node_num);
913

	
914
      _parent.resize(all_node_num);
915
      _pred.resize(all_node_num);
916
      _forward.resize(all_node_num);
917
      _thread.resize(all_node_num);
918
      _rev_thread.resize(all_node_num);
919
      _succ_num.resize(all_node_num);
920
      _last_succ.resize(all_node_num);
921
      _state.resize(max_arc_num);
922

	
923
      // Copy the graph
924
      int i = 0;
925
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
926
        _node_id[n] = i;
927
      }
928
      if (_arc_mixing) {
929
        // Store the arcs in a mixed order
930
        int k = std::max(int(std::sqrt(double(_arc_num))), 10);
931
        int i = 0, j = 0;
932
        for (ArcIt a(_graph); a != INVALID; ++a) {
933
          _arc_id[a] = i;
934
          _source[i] = _node_id[_graph.source(a)];
935
          _target[i] = _node_id[_graph.target(a)];
936
          if ((i += k) >= _arc_num) i = ++j;
937
        }
938
      } else {
939
        // Store the arcs in the original order
940
        int i = 0;
941
        for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
942
          _arc_id[a] = i;
943
          _source[i] = _node_id[_graph.source(a)];
944
          _target[i] = _node_id[_graph.target(a)];
945
        }
946
      }
947

	
948
      // Reset parameters
949
      resetParams();
950
      return *this;
951
    }
952

	
918 953
    /// @}
919 954

	
920 955
    /// \name Query Functions
921 956
    /// The results of the algorithm can be obtained using these
922 957
    /// functions.\n
923 958
    /// The \ref run() function must be called before using them.
924 959

	
925 960
    /// @{
926 961

	
927 962
    /// \brief Return the total cost of the found flow.
928 963
    ///
929 964
    /// This function returns the total cost of the found flow.
930 965
    /// Its complexity is O(e).
931 966
    ///
932 967
    /// \note The return type of the function can be specified as a
933 968
    /// template parameter. For example,
934 969
    /// \code
935 970
    ///   ns.totalCost<double>();
936 971
    /// \endcode
937 972
    /// It is useful if the total cost cannot be stored in the \c Cost
938 973
    /// type of the algorithm, which is the default return type of the
939 974
    /// function.
940 975
    ///
941 976
    /// \pre \ref run() must be called before using this function.
942 977
    template <typename Number>
943 978
    Number totalCost() const {
944 979
      Number c = 0;
945 980
      for (ArcIt a(_graph); a != INVALID; ++a) {
946 981
        int i = _arc_id[a];
947 982
        c += Number(_flow[i]) * Number(_cost[i]);
948 983
      }
949 984
      return c;
950 985
    }
951 986

	
952 987
#ifndef DOXYGEN
953 988
    Cost totalCost() const {
954 989
      return totalCost<Cost>();
955 990
    }
956 991
#endif
957 992

	
958 993
    /// \brief Return the flow on the given arc.
959 994
    ///
960 995
    /// This function returns the flow on the given arc.
961 996
    ///
962 997
    /// \pre \ref run() must be called before using this function.
963 998
    Value flow(const Arc& a) const {
964 999
      return _flow[_arc_id[a]];
965 1000
    }
966 1001

	
967 1002
    /// \brief Return the flow map (the primal solution).
968 1003
    ///
969 1004
    /// This function copies the flow value on each arc into the given
970 1005
    /// map. The \c Value type of the algorithm must be convertible to
971 1006
    /// the \c Value type of the map.
972 1007
    ///
973 1008
    /// \pre \ref run() must be called before using this function.
974 1009
    template <typename FlowMap>
975 1010
    void flowMap(FlowMap &map) const {
976 1011
      for (ArcIt a(_graph); a != INVALID; ++a) {
977 1012
        map.set(a, _flow[_arc_id[a]]);
978 1013
      }
979 1014
    }
980 1015

	
981 1016
    /// \brief Return the potential (dual value) of the given node.
982 1017
    ///
983 1018
    /// This function returns the potential (dual value) of the
984 1019
    /// given node.
985 1020
    ///
986 1021
    /// \pre \ref run() must be called before using this function.
987 1022
    Cost potential(const Node& n) const {
988 1023
      return _pi[_node_id[n]];
989 1024
    }
990 1025

	
991 1026
    /// \brief Return the potential map (the dual solution).
992 1027
    ///
993 1028
    /// This function copies the potential (dual value) of each node
994 1029
    /// into the given map.
995 1030
    /// The \c Cost type of the algorithm must be convertible to the
996 1031
    /// \c Value type of the map.
997 1032
    ///
998 1033
    /// \pre \ref run() must be called before using this function.
999 1034
    template <typename PotentialMap>
1000 1035
    void potentialMap(PotentialMap &map) const {
1001 1036
      for (NodeIt n(_graph); n != INVALID; ++n) {
1002 1037
        map.set(n, _pi[_node_id[n]]);
1003 1038
      }
1004 1039
    }
1005 1040

	
1006 1041
    /// @}
1007 1042

	
1008 1043
  private:
1009 1044

	
1010 1045
    // Initialize internal data structures
1011 1046
    bool init() {
1012 1047
      if (_node_num == 0) return false;
1013 1048

	
1014 1049
      // Check the sum of supply values
1015 1050
      _sum_supply = 0;
1016 1051
      for (int i = 0; i != _node_num; ++i) {
1017 1052
        _sum_supply += _supply[i];
1018 1053
      }
1019 1054
      if ( !((_stype == GEQ && _sum_supply <= 0) ||
1020 1055
             (_stype == LEQ && _sum_supply >= 0)) ) return false;
1021 1056

	
1022 1057
      // Remove non-zero lower bounds
1023 1058
      if (_have_lower) {
1024 1059
        for (int i = 0; i != _arc_num; ++i) {
1025 1060
          Value c = _lower[i];
1026 1061
          if (c >= 0) {
1027
            _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
1062
            _cap[i] = _upper[i] < MAX ? _upper[i] - c : INF;
1028 1063
          } else {
1029
            _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
1064
            _cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF;
1030 1065
          }
1031 1066
          _supply[_source[i]] -= c;
1032 1067
          _supply[_target[i]] += c;
1033 1068
        }
1034 1069
      } else {
1035 1070
        for (int i = 0; i != _arc_num; ++i) {
1036 1071
          _cap[i] = _upper[i];
1037 1072
        }
1038 1073
      }
1039 1074

	
1040 1075
      // Initialize artifical cost
1041 1076
      Cost ART_COST;
1042 1077
      if (std::numeric_limits<Cost>::is_exact) {
1043 1078
        ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
1044 1079
      } else {
1045 1080
        ART_COST = 0;
1046 1081
        for (int i = 0; i != _arc_num; ++i) {
1047 1082
          if (_cost[i] > ART_COST) ART_COST = _cost[i];
1048 1083
        }
1049 1084
        ART_COST = (ART_COST + 1) * _node_num;
1050 1085
      }
1051 1086

	
1052 1087
      // Initialize arc maps
1053 1088
      for (int i = 0; i != _arc_num; ++i) {
1054 1089
        _flow[i] = 0;
1055 1090
        _state[i] = STATE_LOWER;
1056 1091
      }
1057
      
1092

	
1058 1093
      // Set data for the artificial root node
1059 1094
      _root = _node_num;
1060 1095
      _parent[_root] = -1;
1061 1096
      _pred[_root] = -1;
1062 1097
      _thread[_root] = 0;
1063 1098
      _rev_thread[0] = _root;
1064 1099
      _succ_num[_root] = _node_num + 1;
1065 1100
      _last_succ[_root] = _root - 1;
1066 1101
      _supply[_root] = -_sum_supply;
1067 1102
      _pi[_root] = 0;
1068 1103

	
1069 1104
      // Add artificial arcs and initialize the spanning tree data structure
1070 1105
      if (_sum_supply == 0) {
1071 1106
        // EQ supply constraints
1072 1107
        _search_arc_num = _arc_num;
1073 1108
        _all_arc_num = _arc_num + _node_num;
1074 1109
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1075 1110
          _parent[u] = _root;
1076 1111
          _pred[u] = e;
1077 1112
          _thread[u] = u + 1;
1078 1113
          _rev_thread[u + 1] = u;
1079 1114
          _succ_num[u] = 1;
1080 1115
          _last_succ[u] = u;
1081 1116
          _cap[e] = INF;
1082 1117
          _state[e] = STATE_TREE;
1083 1118
          if (_supply[u] >= 0) {
1084 1119
            _forward[u] = true;
1085 1120
            _pi[u] = 0;
1086 1121
            _source[e] = u;
1087 1122
            _target[e] = _root;
1088 1123
            _flow[e] = _supply[u];
1089 1124
            _cost[e] = 0;
1090 1125
          } else {
1091 1126
            _forward[u] = false;
1092 1127
            _pi[u] = ART_COST;
1093 1128
            _source[e] = _root;
1094 1129
            _target[e] = u;
1095 1130
            _flow[e] = -_supply[u];
1096 1131
            _cost[e] = ART_COST;
1097 1132
          }
1098 1133
        }
1099 1134
      }
1100 1135
      else if (_sum_supply > 0) {
1101 1136
        // LEQ supply constraints
1102 1137
        _search_arc_num = _arc_num + _node_num;
1103 1138
        int f = _arc_num + _node_num;
1104 1139
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1105 1140
          _parent[u] = _root;
1106 1141
          _thread[u] = u + 1;
1107 1142
          _rev_thread[u + 1] = u;
1108 1143
          _succ_num[u] = 1;
1109 1144
          _last_succ[u] = u;
1110 1145
          if (_supply[u] >= 0) {
1111 1146
            _forward[u] = true;
1112 1147
            _pi[u] = 0;
1113 1148
            _pred[u] = e;
1114 1149
            _source[e] = u;
1115 1150
            _target[e] = _root;
1116 1151
            _cap[e] = INF;
1117 1152
            _flow[e] = _supply[u];
1118 1153
            _cost[e] = 0;
1119 1154
            _state[e] = STATE_TREE;
1120 1155
          } else {
1121 1156
            _forward[u] = false;
1122 1157
            _pi[u] = ART_COST;
1123 1158
            _pred[u] = f;
1124 1159
            _source[f] = _root;
1125 1160
            _target[f] = u;
1126 1161
            _cap[f] = INF;
1127 1162
            _flow[f] = -_supply[u];
1128 1163
            _cost[f] = ART_COST;
1129 1164
            _state[f] = STATE_TREE;
1130 1165
            _source[e] = u;
1131 1166
            _target[e] = _root;
1132 1167
            _cap[e] = INF;
1133 1168
            _flow[e] = 0;
1134 1169
            _cost[e] = 0;
1135 1170
            _state[e] = STATE_LOWER;
1136 1171
            ++f;
1137 1172
          }
1138 1173
        }
1139 1174
        _all_arc_num = f;
1140 1175
      }
1141 1176
      else {
1142 1177
        // GEQ supply constraints
1143 1178
        _search_arc_num = _arc_num + _node_num;
1144 1179
        int f = _arc_num + _node_num;
1145 1180
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1146 1181
          _parent[u] = _root;
1147 1182
          _thread[u] = u + 1;
1148 1183
          _rev_thread[u + 1] = u;
1149 1184
          _succ_num[u] = 1;
1150 1185
          _last_succ[u] = u;
1151 1186
          if (_supply[u] <= 0) {
1152 1187
            _forward[u] = false;
1153 1188
            _pi[u] = 0;
1154 1189
            _pred[u] = e;
1155 1190
            _source[e] = _root;
1156 1191
            _target[e] = u;
1157 1192
            _cap[e] = INF;
1158 1193
            _flow[e] = -_supply[u];
1159 1194
            _cost[e] = 0;
1160 1195
            _state[e] = STATE_TREE;
1161 1196
          } else {
1162 1197
            _forward[u] = true;
1163 1198
            _pi[u] = -ART_COST;
1164 1199
            _pred[u] = f;
1165 1200
            _source[f] = u;
1166 1201
            _target[f] = _root;
1167 1202
            _cap[f] = INF;
1168 1203
            _flow[f] = _supply[u];
1169 1204
            _state[f] = STATE_TREE;
1170 1205
            _cost[f] = ART_COST;
1171 1206
            _source[e] = _root;
1172 1207
            _target[e] = u;
1173 1208
            _cap[e] = INF;
1174 1209
            _flow[e] = 0;
1175 1210
            _cost[e] = 0;
1176 1211
            _state[e] = STATE_LOWER;
1177 1212
            ++f;
1178 1213
          }
1179 1214
        }
1180 1215
        _all_arc_num = f;
1181 1216
      }
1182 1217

	
1183 1218
      return true;
1184 1219
    }
1185 1220

	
1186 1221
    // Find the join node
1187 1222
    void findJoinNode() {
1188 1223
      int u = _source[in_arc];
1189 1224
      int v = _target[in_arc];
1190 1225
      while (u != v) {
1191 1226
        if (_succ_num[u] < _succ_num[v]) {
1192 1227
          u = _parent[u];
1193 1228
        } else {
1194 1229
          v = _parent[v];
1195 1230
        }
1196 1231
      }
1197 1232
      join = u;
1198 1233
    }
1199 1234

	
1200 1235
    // Find the leaving arc of the cycle and returns true if the
1201 1236
    // leaving arc is not the same as the entering arc
1202 1237
    bool findLeavingArc() {
1203 1238
      // Initialize first and second nodes according to the direction
1204 1239
      // of the cycle
1205 1240
      if (_state[in_arc] == STATE_LOWER) {
1206 1241
        first  = _source[in_arc];
1207 1242
        second = _target[in_arc];
1208 1243
      } else {
1209 1244
        first  = _target[in_arc];
1210 1245
        second = _source[in_arc];
1211 1246
      }
1212 1247
      delta = _cap[in_arc];
1213 1248
      int result = 0;
1214 1249
      Value d;
1215 1250
      int e;
1216 1251

	
1217 1252
      // Search the cycle along the path form the first node to the root
1218 1253
      for (int u = first; u != join; u = _parent[u]) {
1219 1254
        e = _pred[u];
1220 1255
        d = _forward[u] ?
1221
          _flow[e] : (_cap[e] == INF ? INF : _cap[e] - _flow[e]);
1256
          _flow[e] : (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]);
1222 1257
        if (d < delta) {
1223 1258
          delta = d;
1224 1259
          u_out = u;
1225 1260
          result = 1;
1226 1261
        }
1227 1262
      }
1228 1263
      // Search the cycle along the path form the second node to the root
1229 1264
      for (int u = second; u != join; u = _parent[u]) {
1230 1265
        e = _pred[u];
1231
        d = _forward[u] ? 
1232
          (_cap[e] == INF ? INF : _cap[e] - _flow[e]) : _flow[e];
1266
        d = _forward[u] ?
1267
          (_cap[e] >= MAX ? INF : _cap[e] - _flow[e]) : _flow[e];
1233 1268
        if (d <= delta) {
1234 1269
          delta = d;
1235 1270
          u_out = u;
1236 1271
          result = 2;
1237 1272
        }
1238 1273
      }
1239 1274

	
1240 1275
      if (result == 1) {
1241 1276
        u_in = first;
1242 1277
        v_in = second;
1243 1278
      } else {
1244 1279
        u_in = second;
1245 1280
        v_in = first;
1246 1281
      }
1247 1282
      return result != 0;
1248 1283
    }
1249 1284

	
1250 1285
    // Change _flow and _state vectors
1251 1286
    void changeFlow(bool change) {
1252 1287
      // Augment along the cycle
1253 1288
      if (delta > 0) {
1254 1289
        Value val = _state[in_arc] * delta;
1255 1290
        _flow[in_arc] += val;
1256 1291
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
1257 1292
          _flow[_pred[u]] += _forward[u] ? -val : val;
1258 1293
        }
1259 1294
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
1260 1295
          _flow[_pred[u]] += _forward[u] ? val : -val;
1261 1296
        }
1262 1297
      }
1263 1298
      // Update the state of the entering and leaving arcs
1264 1299
      if (change) {
1265 1300
        _state[in_arc] = STATE_TREE;
1266 1301
        _state[_pred[u_out]] =
1267 1302
          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
1268 1303
      } else {
1269 1304
        _state[in_arc] = -_state[in_arc];
1270 1305
      }
1271 1306
    }
1272 1307

	
1273 1308
    // Update the tree structure
1274 1309
    void updateTreeStructure() {
1275 1310
      int u, w;
1276 1311
      int old_rev_thread = _rev_thread[u_out];
1277 1312
      int old_succ_num = _succ_num[u_out];
1278 1313
      int old_last_succ = _last_succ[u_out];
1279 1314
      v_out = _parent[u_out];
1280 1315

	
1281 1316
      u = _last_succ[u_in];  // the last successor of u_in
1282 1317
      right = _thread[u];    // the node after it
1283 1318

	
1284 1319
      // Handle the case when old_rev_thread equals to v_in
1285 1320
      // (it also means that join and v_out coincide)
1286 1321
      if (old_rev_thread == v_in) {
1287 1322
        last = _thread[_last_succ[u_out]];
1288 1323
      } else {
1289 1324
        last = _thread[v_in];
1290 1325
      }
1291 1326

	
1292 1327
      // Update _thread and _parent along the stem nodes (i.e. the nodes
1293 1328
      // between u_in and u_out, whose parent have to be changed)
1294 1329
      _thread[v_in] = stem = u_in;
1295 1330
      _dirty_revs.clear();
1296 1331
      _dirty_revs.push_back(v_in);
1297 1332
      par_stem = v_in;
1298 1333
      while (stem != u_out) {
1299 1334
        // Insert the next stem node into the thread list
1300 1335
        new_stem = _parent[stem];
1301 1336
        _thread[u] = new_stem;
1302 1337
        _dirty_revs.push_back(u);
1303 1338

	
1304 1339
        // Remove the subtree of stem from the thread list
1305 1340
        w = _rev_thread[stem];
1306 1341
        _thread[w] = right;
1307 1342
        _rev_thread[right] = w;
1308 1343

	
1309 1344
        // Change the parent node and shift stem nodes
1310 1345
        _parent[stem] = par_stem;
1311 1346
        par_stem = stem;
1312 1347
        stem = new_stem;
1313 1348

	
1314 1349
        // Update u and right
1315 1350
        u = _last_succ[stem] == _last_succ[par_stem] ?
1316 1351
          _rev_thread[par_stem] : _last_succ[stem];
1317 1352
        right = _thread[u];
1318 1353
      }
1319 1354
      _parent[u_out] = par_stem;
1320 1355
      _thread[u] = last;
1321 1356
      _rev_thread[last] = u;
1322 1357
      _last_succ[u_out] = u;
1323 1358

	
1324 1359
      // Remove the subtree of u_out from the thread list except for
1325 1360
      // the case when old_rev_thread equals to v_in
1326 1361
      // (it also means that join and v_out coincide)
1327 1362
      if (old_rev_thread != v_in) {
1328 1363
        _thread[old_rev_thread] = right;
1329 1364
        _rev_thread[right] = old_rev_thread;
1330 1365
      }
1331 1366

	
1332 1367
      // Update _rev_thread using the new _thread values
1333
      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
1368
      for (int i = 0; i != int(_dirty_revs.size()); ++i) {
1334 1369
        u = _dirty_revs[i];
1335 1370
        _rev_thread[_thread[u]] = u;
1336 1371
      }
1337 1372

	
1338 1373
      // Update _pred, _forward, _last_succ and _succ_num for the
1339 1374
      // stem nodes from u_out to u_in
1340 1375
      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
1341 1376
      u = u_out;
1342 1377
      while (u != u_in) {
1343 1378
        w = _parent[u];
1344 1379
        _pred[u] = _pred[w];
1345 1380
        _forward[u] = !_forward[w];
1346 1381
        tmp_sc += _succ_num[u] - _succ_num[w];
1347 1382
        _succ_num[u] = tmp_sc;
1348 1383
        _last_succ[w] = tmp_ls;
1349 1384
        u = w;
1350 1385
      }
1351 1386
      _pred[u_in] = in_arc;
1352 1387
      _forward[u_in] = (u_in == _source[in_arc]);
1353 1388
      _succ_num[u_in] = old_succ_num;
1354 1389

	
1355 1390
      // Set limits for updating _last_succ form v_in and v_out
1356 1391
      // towards the root
1357 1392
      int up_limit_in = -1;
1358 1393
      int up_limit_out = -1;
1359 1394
      if (_last_succ[join] == v_in) {
1360 1395
        up_limit_out = join;
1361 1396
      } else {
1362 1397
        up_limit_in = join;
1363 1398
      }
1364 1399

	
1365 1400
      // Update _last_succ from v_in towards the root
1366 1401
      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
1367 1402
           u = _parent[u]) {
1368 1403
        _last_succ[u] = _last_succ[u_out];
1369 1404
      }
1370 1405
      // Update _last_succ from v_out towards the root
1371 1406
      if (join != old_rev_thread && v_in != old_rev_thread) {
1372 1407
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1373 1408
             u = _parent[u]) {
1374 1409
          _last_succ[u] = old_rev_thread;
1375 1410
        }
1376 1411
      } else {
1377 1412
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1378 1413
             u = _parent[u]) {
1379 1414
          _last_succ[u] = _last_succ[u_out];
1380 1415
        }
1381 1416
      }
1382 1417

	
1383 1418
      // Update _succ_num from v_in to join
1384 1419
      for (u = v_in; u != join; u = _parent[u]) {
1385 1420
        _succ_num[u] += old_succ_num;
1386 1421
      }
1387 1422
      // Update _succ_num from v_out to join
1388 1423
      for (u = v_out; u != join; u = _parent[u]) {
1389 1424
        _succ_num[u] -= old_succ_num;
1390 1425
      }
1391 1426
    }
1392 1427

	
1393 1428
    // Update potentials
1394 1429
    void updatePotential() {
1395 1430
      Cost sigma = _forward[u_in] ?
1396 1431
        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
1397 1432
        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
1398 1433
      // Update potentials in the subtree, which has been moved
1399 1434
      int end = _thread[_last_succ[u_in]];
1400 1435
      for (int u = u_in; u != end; u = _thread[u]) {
1401 1436
        _pi[u] += sigma;
1402 1437
      }
1403 1438
    }
1404 1439

	
1440
    // Heuristic initial pivots
1441
    bool initialPivots() {
1442
      Value curr, total = 0;
1443
      std::vector<Node> supply_nodes, demand_nodes;
1444
      for (NodeIt u(_graph); u != INVALID; ++u) {
1445
        curr = _supply[_node_id[u]];
1446
        if (curr > 0) {
1447
          total += curr;
1448
          supply_nodes.push_back(u);
1449
        }
1450
        else if (curr < 0) {
1451
          demand_nodes.push_back(u);
1452
        }
1453
      }
1454
      if (_sum_supply > 0) total -= _sum_supply;
1455
      if (total <= 0) return true;
1456

	
1457
      IntVector arc_vector;
1458
      if (_sum_supply >= 0) {
1459
        if (supply_nodes.size() == 1 && demand_nodes.size() == 1) {
1460
          // Perform a reverse graph search from the sink to the source
1461
          typename GR::template NodeMap<bool> reached(_graph, false);
1462
          Node s = supply_nodes[0], t = demand_nodes[0];
1463
          std::vector<Node> stack;
1464
          reached[t] = true;
1465
          stack.push_back(t);
1466
          while (!stack.empty()) {
1467
            Node u, v = stack.back();
1468
            stack.pop_back();
1469
            if (v == s) break;
1470
            for (InArcIt a(_graph, v); a != INVALID; ++a) {
1471
              if (reached[u = _graph.source(a)]) continue;
1472
              int j = _arc_id[a];
1473
              if (_cap[j] >= total) {
1474
                arc_vector.push_back(j);
1475
                reached[u] = true;
1476
                stack.push_back(u);
1477
              }
1478
            }
1479
          }
1480
        } else {
1481
          // Find the min. cost incomming arc for each demand node
1482
          for (int i = 0; i != int(demand_nodes.size()); ++i) {
1483
            Node v = demand_nodes[i];
1484
            Cost c, min_cost = std::numeric_limits<Cost>::max();
1485
            Arc min_arc = INVALID;
1486
            for (InArcIt a(_graph, v); a != INVALID; ++a) {
1487
              c = _cost[_arc_id[a]];
1488
              if (c < min_cost) {
1489
                min_cost = c;
1490
                min_arc = a;
1491
              }
1492
            }
1493
            if (min_arc != INVALID) {
1494
              arc_vector.push_back(_arc_id[min_arc]);
1495
            }
1496
          }
1497
        }
1498
      } else {
1499
        // Find the min. cost outgoing arc for each supply node
1500
        for (int i = 0; i != int(supply_nodes.size()); ++i) {
1501
          Node u = supply_nodes[i];
1502
          Cost c, min_cost = std::numeric_limits<Cost>::max();
1503
          Arc min_arc = INVALID;
1504
          for (OutArcIt a(_graph, u); a != INVALID; ++a) {
1505
            c = _cost[_arc_id[a]];
1506
            if (c < min_cost) {
1507
              min_cost = c;
1508
              min_arc = a;
1509
            }
1510
          }
1511
          if (min_arc != INVALID) {
1512
            arc_vector.push_back(_arc_id[min_arc]);
1513
          }
1514
        }
1515
      }
1516

	
1517
      // Perform heuristic initial pivots
1518
      for (int i = 0; i != int(arc_vector.size()); ++i) {
1519
        in_arc = arc_vector[i];
1520
        if (_state[in_arc] * (_cost[in_arc] + _pi[_source[in_arc]] -
1521
            _pi[_target[in_arc]]) >= 0) continue;
1522
        findJoinNode();
1523
        bool change = findLeavingArc();
1524
        if (delta >= MAX) return false;
1525
        changeFlow(change);
1526
        if (change) {
1527
          updateTreeStructure();
1528
          updatePotential();
1529
        }
1530
      }
1531
      return true;
1532
    }
1533

	
1405 1534
    // Execute the algorithm
1406 1535
    ProblemType start(PivotRule pivot_rule) {
1407 1536
      // Select the pivot rule implementation
1408 1537
      switch (pivot_rule) {
1409 1538
        case FIRST_ELIGIBLE:
1410 1539
          return start<FirstEligiblePivotRule>();
1411 1540
        case BEST_ELIGIBLE:
1412 1541
          return start<BestEligiblePivotRule>();
1413 1542
        case BLOCK_SEARCH:
1414 1543
          return start<BlockSearchPivotRule>();
1415 1544
        case CANDIDATE_LIST:
1416 1545
          return start<CandidateListPivotRule>();
1417 1546
        case ALTERING_LIST:
1418 1547
          return start<AlteringListPivotRule>();
1419 1548
      }
1420 1549
      return INFEASIBLE; // avoid warning
1421 1550
    }
1422 1551

	
1423 1552
    template <typename PivotRuleImpl>
1424 1553
    ProblemType start() {
1425 1554
      PivotRuleImpl pivot(*this);
1426 1555

	
1556
      // Perform heuristic initial pivots
1557
      if (!initialPivots()) return UNBOUNDED;
1558

	
1427 1559
      // Execute the Network Simplex algorithm
1428 1560
      while (pivot.findEnteringArc()) {
1429 1561
        findJoinNode();
1430 1562
        bool change = findLeavingArc();
1431
        if (delta >= INF) return UNBOUNDED;
1563
        if (delta >= MAX) return UNBOUNDED;
1432 1564
        changeFlow(change);
1433 1565
        if (change) {
1434 1566
          updateTreeStructure();
1435 1567
          updatePotential();
1436 1568
        }
1437 1569
      }
1438
      
1570

	
1439 1571
      // Check feasibility
1440 1572
      for (int e = _search_arc_num; e != _all_arc_num; ++e) {
1441 1573
        if (_flow[e] != 0) return INFEASIBLE;
1442 1574
      }
1443 1575

	
1444 1576
      // Transform the solution and the supply map to the original form
1445 1577
      if (_have_lower) {
1446 1578
        for (int i = 0; i != _arc_num; ++i) {
1447 1579
          Value c = _lower[i];
1448 1580
          if (c != 0) {
1449 1581
            _flow[i] += c;
1450 1582
            _supply[_source[i]] += c;
1451 1583
            _supply[_target[i]] -= c;
1452 1584
          }
1453 1585
        }
1454 1586
      }
1455
      
1587

	
1456 1588
      // Shift potentials to meet the requirements of the GEQ/LEQ type
1457 1589
      // optimality conditions
1458 1590
      if (_sum_supply == 0) {
1459 1591
        if (_stype == GEQ) {
1460 1592
          Cost max_pot = -std::numeric_limits<Cost>::max();
1461 1593
          for (int i = 0; i != _node_num; ++i) {
1462 1594
            if (_pi[i] > max_pot) max_pot = _pi[i];
1463 1595
          }
1464 1596
          if (max_pot > 0) {
1465 1597
            for (int i = 0; i != _node_num; ++i)
1466 1598
              _pi[i] -= max_pot;
1467 1599
          }
1468 1600
        } else {
1469 1601
          Cost min_pot = std::numeric_limits<Cost>::max();
1470 1602
          for (int i = 0; i != _node_num; ++i) {
1471 1603
            if (_pi[i] < min_pot) min_pot = _pi[i];
1472 1604
          }
1473 1605
          if (min_pot < 0) {
1474 1606
            for (int i = 0; i != _node_num; ++i)
1475 1607
              _pi[i] -= min_pot;
1476 1608
          }
1477 1609
        }
1478 1610
      }
1479 1611

	
1480 1612
      return OPTIMAL;
1481 1613
    }
1482 1614

	
1483 1615
  }; //class NetworkSimplex
1484 1616

	
1485 1617
  ///@}
1486 1618

	
1487 1619
} //namespace lemon
1488 1620

	
1489 1621
#endif //LEMON_NETWORK_SIMPLEX_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-2009
5
 * Copyright (C) 2003-2010
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 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 55
  template <typename GR>
56 56
  class Path {
57 57
  public:
58 58

	
59 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 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 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 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 243
  template <typename GR>
244 244
  class SimplePath {
245 245
  public:
246 246

	
247 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 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 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 407
  template <typename GR>
408 408
  class ListPath {
409 409
  public:
410 410

	
411 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 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 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 749
  template <typename GR>
750 750
  class StaticPath {
751 751
  public:
752 752

	
753 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 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-2009
5
 * Copyright (C) 2003-2010
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_PREFLOW_H
20 20
#define LEMON_PREFLOW_H
21 21

	
22 22
#include <lemon/tolerance.h>
23 23
#include <lemon/elevator.h>
24 24

	
25 25
/// \file
26 26
/// \ingroup max_flow
27 27
/// \brief Implementation of the preflow algorithm.
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  /// \brief Default traits class of Preflow class.
32 32
  ///
33 33
  /// Default traits class of Preflow class.
34 34
  /// \tparam GR Digraph type.
35 35
  /// \tparam CAP Capacity map type.
36 36
  template <typename GR, typename CAP>
37 37
  struct PreflowDefaultTraits {
38 38

	
39 39
    /// \brief The type of the digraph the algorithm runs on.
40 40
    typedef GR Digraph;
41 41

	
42 42
    /// \brief The type of the map that stores the arc capacities.
43 43
    ///
44 44
    /// The type of the map that stores the arc capacities.
45 45
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
46 46
    typedef CAP CapacityMap;
47 47

	
48 48
    /// \brief The type of the flow values.
49 49
    typedef typename CapacityMap::Value Value;
50 50

	
51 51
    /// \brief The type of the map that stores the flow values.
52 52
    ///
53 53
    /// The type of the map that stores the flow values.
54 54
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
55
#ifdef DOXYGEN
56
    typedef GR::ArcMap<Value> FlowMap;
57
#else
55 58
    typedef typename Digraph::template ArcMap<Value> FlowMap;
59
#endif
56 60

	
57 61
    /// \brief Instantiates a FlowMap.
58 62
    ///
59 63
    /// This function instantiates a \ref FlowMap.
60 64
    /// \param digraph The digraph for which we would like to define
61 65
    /// the flow map.
62 66
    static FlowMap* createFlowMap(const Digraph& digraph) {
63 67
      return new FlowMap(digraph);
64 68
    }
65 69

	
66 70
    /// \brief The elevator type used by Preflow algorithm.
67 71
    ///
68 72
    /// The elevator type used by Preflow algorithm.
69 73
    ///
70
    /// \sa Elevator
71
    /// \sa LinkedElevator
72
    typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
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
73 80

	
74 81
    /// \brief Instantiates an Elevator.
75 82
    ///
76 83
    /// This function instantiates an \ref Elevator.
77 84
    /// \param digraph The digraph for which we would like to define
78 85
    /// the elevator.
79 86
    /// \param max_level The maximum level of the elevator.
80 87
    static Elevator* createElevator(const Digraph& digraph, int max_level) {
81 88
      return new Elevator(digraph, max_level);
82 89
    }
83 90

	
84 91
    /// \brief The tolerance used by the algorithm
85 92
    ///
86 93
    /// The tolerance used by the algorithm to handle inexact computation.
87 94
    typedef lemon::Tolerance<Value> Tolerance;
88 95

	
89 96
  };
90 97

	
91 98

	
92 99
  /// \ingroup max_flow
93 100
  ///
94 101
  /// \brief %Preflow algorithm class.
95 102
  ///
96 103
  /// This class provides an implementation of Goldberg-Tarjan's \e preflow
97 104
  /// \e push-relabel algorithm producing a \ref max_flow
98
  /// "flow of maximum value" in a digraph.
105
  /// "flow of maximum value" in a digraph \ref clrs01algorithms,
106
  /// \ref amo93networkflows, \ref goldberg88newapproach.
99 107
  /// The preflow algorithms are the fastest known maximum
100
  /// flow algorithms. The current implementation use a mixture of the
108
  /// flow algorithms. The current implementation uses a mixture of the
101 109
  /// \e "highest label" and the \e "bound decrease" heuristics.
102 110
  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
103 111
  ///
104 112
  /// The algorithm consists of two phases. After the first phase
105 113
  /// the maximum flow value and the minimum cut is obtained. The
106 114
  /// second phase constructs a feasible maximum flow on each arc.
107 115
  ///
116
  /// \warning This implementation cannot handle infinite or very large
117
  /// capacities (e.g. the maximum value of \c CAP::Value).
118
  ///
108 119
  /// \tparam GR The type of the digraph the algorithm runs on.
109 120
  /// \tparam CAP The type of the capacity map. The default map
110 121
  /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
122
  /// \tparam TR The traits class that defines various types used by the
123
  /// algorithm. By default, it is \ref PreflowDefaultTraits
124
  /// "PreflowDefaultTraits<GR, CAP>".
125
  /// In most cases, this parameter should not be set directly,
126
  /// consider to use the named template parameters instead.
111 127
#ifdef DOXYGEN
112 128
  template <typename GR, typename CAP, typename TR>
113 129
#else
114 130
  template <typename GR,
115 131
            typename CAP = typename GR::template ArcMap<int>,
116 132
            typename TR = PreflowDefaultTraits<GR, CAP> >
117 133
#endif
118 134
  class Preflow {
119 135
  public:
120 136

	
121 137
    ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
122 138
    typedef TR Traits;
123 139
    ///The type of the digraph the algorithm runs on.
124 140
    typedef typename Traits::Digraph Digraph;
125 141
    ///The type of the capacity map.
126 142
    typedef typename Traits::CapacityMap CapacityMap;
127 143
    ///The type of the flow values.
128 144
    typedef typename Traits::Value Value;
129 145

	
130 146
    ///The type of the flow map.
131 147
    typedef typename Traits::FlowMap FlowMap;
132 148
    ///The type of the elevator.
133 149
    typedef typename Traits::Elevator Elevator;
134 150
    ///The type of the tolerance.
135 151
    typedef typename Traits::Tolerance Tolerance;
136 152

	
137 153
  private:
138 154

	
139 155
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
140 156

	
141 157
    const Digraph& _graph;
142 158
    const CapacityMap* _capacity;
143 159

	
144 160
    int _node_num;
145 161

	
146 162
    Node _source, _target;
147 163

	
148 164
    FlowMap* _flow;
149 165
    bool _local_flow;
150 166

	
151 167
    Elevator* _level;
152 168
    bool _local_level;
153 169

	
154 170
    typedef typename Digraph::template NodeMap<Value> ExcessMap;
155 171
    ExcessMap* _excess;
156 172

	
157 173
    Tolerance _tolerance;
158 174

	
159 175
    bool _phase;
160 176

	
161 177

	
162 178
    void createStructures() {
163 179
      _node_num = countNodes(_graph);
164 180

	
165 181
      if (!_flow) {
166 182
        _flow = Traits::createFlowMap(_graph);
167 183
        _local_flow = true;
168 184
      }
169 185
      if (!_level) {
170 186
        _level = Traits::createElevator(_graph, _node_num);
171 187
        _local_level = true;
172 188
      }
173 189
      if (!_excess) {
174 190
        _excess = new ExcessMap(_graph);
175 191
      }
176 192
    }
177 193

	
178 194
    void destroyStructures() {
179 195
      if (_local_flow) {
180 196
        delete _flow;
181 197
      }
182 198
      if (_local_level) {
183 199
        delete _level;
184 200
      }
185 201
      if (_excess) {
186 202
        delete _excess;
187 203
      }
188 204
    }
189 205

	
190 206
  public:
191 207

	
192 208
    typedef Preflow Create;
193 209

	
194 210
    ///\name Named Template Parameters
195 211

	
196 212
    ///@{
197 213

	
198 214
    template <typename T>
199 215
    struct SetFlowMapTraits : public Traits {
200 216
      typedef T FlowMap;
201 217
      static FlowMap *createFlowMap(const Digraph&) {
202 218
        LEMON_ASSERT(false, "FlowMap is not initialized");
203 219
        return 0; // ignore warnings
204 220
      }
205 221
    };
206 222

	
207 223
    /// \brief \ref named-templ-param "Named parameter" for setting
208 224
    /// FlowMap type
209 225
    ///
210 226
    /// \ref named-templ-param "Named parameter" for setting FlowMap
211 227
    /// type.
212 228
    template <typename T>
213 229
    struct SetFlowMap
214 230
      : public Preflow<Digraph, CapacityMap, SetFlowMapTraits<T> > {
215 231
      typedef Preflow<Digraph, CapacityMap,
216 232
                      SetFlowMapTraits<T> > Create;
217 233
    };
218 234

	
219 235
    template <typename T>
220 236
    struct SetElevatorTraits : public Traits {
221 237
      typedef T Elevator;
222 238
      static Elevator *createElevator(const Digraph&, int) {
223 239
        LEMON_ASSERT(false, "Elevator is not initialized");
224 240
        return 0; // ignore warnings
225 241
      }
226 242
    };
227 243

	
228 244
    /// \brief \ref named-templ-param "Named parameter" for setting
229 245
    /// Elevator type
230 246
    ///
231 247
    /// \ref named-templ-param "Named parameter" for setting Elevator
232 248
    /// type. If this named parameter is used, then an external
233 249
    /// elevator object must be passed to the algorithm using the
234 250
    /// \ref elevator(Elevator&) "elevator()" function before calling
235 251
    /// \ref run() or \ref init().
236 252
    /// \sa SetStandardElevator
237 253
    template <typename T>
238 254
    struct SetElevator
239 255
      : public Preflow<Digraph, CapacityMap, SetElevatorTraits<T> > {
240 256
      typedef Preflow<Digraph, CapacityMap,
241 257
                      SetElevatorTraits<T> > Create;
242 258
    };
243 259

	
244 260
    template <typename T>
245 261
    struct SetStandardElevatorTraits : public Traits {
246 262
      typedef T Elevator;
247 263
      static Elevator *createElevator(const Digraph& digraph, int max_level) {
248 264
        return new Elevator(digraph, max_level);
249 265
      }
250 266
    };
251 267

	
252 268
    /// \brief \ref named-templ-param "Named parameter" for setting
253 269
    /// Elevator type with automatic allocation
254 270
    ///
255 271
    /// \ref named-templ-param "Named parameter" for setting Elevator
256 272
    /// type with automatic allocation.
257 273
    /// The Elevator should have standard constructor interface to be
258 274
    /// able to automatically created by the algorithm (i.e. the
259 275
    /// digraph and the maximum level should be passed to it).
260
    /// However an external elevator object could also be passed to the
276
    /// However, an external elevator object could also be passed to the
261 277
    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
262 278
    /// before calling \ref run() or \ref init().
263 279
    /// \sa SetElevator
264 280
    template <typename T>
265 281
    struct SetStandardElevator
266 282
      : public Preflow<Digraph, CapacityMap,
267 283
                       SetStandardElevatorTraits<T> > {
268 284
      typedef Preflow<Digraph, CapacityMap,
269 285
                      SetStandardElevatorTraits<T> > Create;
270 286
    };
271 287

	
272 288
    /// @}
273 289

	
274 290
  protected:
275 291

	
276 292
    Preflow() {}
277 293

	
278 294
  public:
279 295

	
280 296

	
281 297
    /// \brief The constructor of the class.
282 298
    ///
283 299
    /// The constructor of the class.
284 300
    /// \param digraph The digraph the algorithm runs on.
285 301
    /// \param capacity The capacity of the arcs.
286 302
    /// \param source The source node.
287 303
    /// \param target The target node.
288 304
    Preflow(const Digraph& digraph, const CapacityMap& capacity,
289 305
            Node source, Node target)
290 306
      : _graph(digraph), _capacity(&capacity),
291 307
        _node_num(0), _source(source), _target(target),
292 308
        _flow(0), _local_flow(false),
293 309
        _level(0), _local_level(false),
294 310
        _excess(0), _tolerance(), _phase() {}
295 311

	
296 312
    /// \brief Destructor.
297 313
    ///
298 314
    /// Destructor.
299 315
    ~Preflow() {
300 316
      destroyStructures();
301 317
    }
302 318

	
303 319
    /// \brief Sets the capacity map.
304 320
    ///
305 321
    /// Sets the capacity map.
306 322
    /// \return <tt>(*this)</tt>
307 323
    Preflow& capacityMap(const CapacityMap& map) {
308 324
      _capacity = &map;
309 325
      return *this;
310 326
    }
311 327

	
312 328
    /// \brief Sets the flow map.
313 329
    ///
314 330
    /// Sets the flow map.
315 331
    /// If you don't use this function before calling \ref run() or
316 332
    /// \ref init(), an instance will be allocated automatically.
317 333
    /// The destructor deallocates this automatically allocated map,
318 334
    /// of course.
319 335
    /// \return <tt>(*this)</tt>
320 336
    Preflow& flowMap(FlowMap& map) {
321 337
      if (_local_flow) {
322 338
        delete _flow;
323 339
        _local_flow = false;
324 340
      }
325 341
      _flow = &map;
326 342
      return *this;
327 343
    }
328 344

	
329 345
    /// \brief Sets the source node.
330 346
    ///
331 347
    /// Sets the source node.
332 348
    /// \return <tt>(*this)</tt>
333 349
    Preflow& source(const Node& node) {
334 350
      _source = node;
335 351
      return *this;
336 352
    }
337 353

	
338 354
    /// \brief Sets the target node.
339 355
    ///
340 356
    /// Sets the target node.
341 357
    /// \return <tt>(*this)</tt>
342 358
    Preflow& target(const Node& node) {
343 359
      _target = node;
344 360
      return *this;
345 361
    }
346 362

	
347 363
    /// \brief Sets the elevator used by algorithm.
348 364
    ///
349 365
    /// Sets the elevator used by algorithm.
350 366
    /// If you don't use this function before calling \ref run() or
351 367
    /// \ref init(), an instance will be allocated automatically.
352 368
    /// The destructor deallocates this automatically allocated elevator,
353 369
    /// of course.
354 370
    /// \return <tt>(*this)</tt>
355 371
    Preflow& elevator(Elevator& elevator) {
356 372
      if (_local_level) {
357 373
        delete _level;
358 374
        _local_level = false;
359 375
      }
360 376
      _level = &elevator;
361 377
      return *this;
362 378
    }
363 379

	
364 380
    /// \brief Returns a const reference to the elevator.
365 381
    ///
366 382
    /// Returns a const reference to the elevator.
367 383
    ///
368 384
    /// \pre Either \ref run() or \ref init() must be called before
369 385
    /// using this function.
370 386
    const Elevator& elevator() const {
371 387
      return *_level;
372 388
    }
373 389

	
374
    /// \brief Sets the tolerance used by algorithm.
390
    /// \brief Sets the tolerance used by the algorithm.
375 391
    ///
376
    /// Sets the tolerance used by algorithm.
392
    /// Sets the tolerance object used by the algorithm.
393
    /// \return <tt>(*this)</tt>
377 394
    Preflow& tolerance(const Tolerance& tolerance) {
378 395
      _tolerance = tolerance;
379 396
      return *this;
380 397
    }
381 398

	
382 399
    /// \brief Returns a const reference to the tolerance.
383 400
    ///
384
    /// Returns a const reference to the tolerance.
401
    /// Returns a const reference to the tolerance object used by
402
    /// the algorithm.
385 403
    const Tolerance& tolerance() const {
386 404
      return _tolerance;
387 405
    }
388 406

	
389 407
    /// \name Execution Control
390 408
    /// The simplest way to execute the preflow algorithm is to use
391 409
    /// \ref run() or \ref runMinCut().\n
392
    /// If you need more control on the initial solution or the execution,
393
    /// first you have to call one of the \ref init() functions, then
410
    /// If you need better control on the initial solution or the execution,
411
    /// you have to call one of the \ref init() functions first, then
394 412
    /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
395 413

	
396 414
    ///@{
397 415

	
398 416
    /// \brief Initializes the internal data structures.
399 417
    ///
400 418
    /// Initializes the internal data structures and sets the initial
401 419
    /// flow to zero on each arc.
402 420
    void init() {
403 421
      createStructures();
404 422

	
405 423
      _phase = true;
406 424
      for (NodeIt n(_graph); n != INVALID; ++n) {
407 425
        (*_excess)[n] = 0;
408 426
      }
409 427

	
410 428
      for (ArcIt e(_graph); e != INVALID; ++e) {
411 429
        _flow->set(e, 0);
412 430
      }
413 431

	
414 432
      typename Digraph::template NodeMap<bool> reached(_graph, false);
415 433

	
416 434
      _level->initStart();
417 435
      _level->initAddItem(_target);
418 436

	
419 437
      std::vector<Node> queue;
420 438
      reached[_source] = true;
421 439

	
422 440
      queue.push_back(_target);
423 441
      reached[_target] = true;
424 442
      while (!queue.empty()) {
425 443
        _level->initNewLevel();
426 444
        std::vector<Node> nqueue;
427 445
        for (int i = 0; i < int(queue.size()); ++i) {
428 446
          Node n = queue[i];
429 447
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
430 448
            Node u = _graph.source(e);
431 449
            if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
432 450
              reached[u] = true;
433 451
              _level->initAddItem(u);
434 452
              nqueue.push_back(u);
435 453
            }
436 454
          }
437 455
        }
438 456
        queue.swap(nqueue);
439 457
      }
440 458
      _level->initFinish();
441 459

	
442 460
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
443 461
        if (_tolerance.positive((*_capacity)[e])) {
444 462
          Node u = _graph.target(e);
445 463
          if ((*_level)[u] == _level->maxLevel()) continue;
446 464
          _flow->set(e, (*_capacity)[e]);
447 465
          (*_excess)[u] += (*_capacity)[e];
448 466
          if (u != _target && !_level->active(u)) {
449 467
            _level->activate(u);
450 468
          }
451 469
        }
452 470
      }
453 471
    }
454 472

	
455 473
    /// \brief Initializes the internal data structures using the
456 474
    /// given flow map.
457 475
    ///
458 476
    /// Initializes the internal data structures and sets the initial
459 477
    /// flow to the given \c flowMap. The \c flowMap should contain a
460 478
    /// flow or at least a preflow, i.e. at each node excluding the
461 479
    /// source node the incoming flow should greater or equal to the
462 480
    /// outgoing flow.
463 481
    /// \return \c false if the given \c flowMap is not a preflow.
464 482
    template <typename FlowMap>
465 483
    bool init(const FlowMap& flowMap) {
466 484
      createStructures();
467 485

	
468 486
      for (ArcIt e(_graph); e != INVALID; ++e) {
469 487
        _flow->set(e, flowMap[e]);
470 488
      }
471 489

	
472 490
      for (NodeIt n(_graph); n != INVALID; ++n) {
473 491
        Value excess = 0;
474 492
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
475 493
          excess += (*_flow)[e];
476 494
        }
477 495
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
478 496
          excess -= (*_flow)[e];
479 497
        }
480 498
        if (excess < 0 && n != _source) return false;
481 499
        (*_excess)[n] = excess;
482 500
      }
483 501

	
484 502
      typename Digraph::template NodeMap<bool> reached(_graph, false);
485 503

	
486 504
      _level->initStart();
487 505
      _level->initAddItem(_target);
488 506

	
489 507
      std::vector<Node> queue;
490 508
      reached[_source] = true;
491 509

	
492 510
      queue.push_back(_target);
493 511
      reached[_target] = true;
494 512
      while (!queue.empty()) {
495 513
        _level->initNewLevel();
496 514
        std::vector<Node> nqueue;
497 515
        for (int i = 0; i < int(queue.size()); ++i) {
498 516
          Node n = queue[i];
499 517
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
500 518
            Node u = _graph.source(e);
501 519
            if (!reached[u] &&
502 520
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
503 521
              reached[u] = true;
504 522
              _level->initAddItem(u);
505 523
              nqueue.push_back(u);
506 524
            }
507 525
          }
508 526
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
509 527
            Node v = _graph.target(e);
510 528
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
511 529
              reached[v] = true;
512 530
              _level->initAddItem(v);
513 531
              nqueue.push_back(v);
514 532
            }
515 533
          }
516 534
        }
517 535
        queue.swap(nqueue);
518 536
      }
519 537
      _level->initFinish();
520 538

	
521 539
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
522 540
        Value rem = (*_capacity)[e] - (*_flow)[e];
523 541
        if (_tolerance.positive(rem)) {
524 542
          Node u = _graph.target(e);
525 543
          if ((*_level)[u] == _level->maxLevel()) continue;
526 544
          _flow->set(e, (*_capacity)[e]);
527 545
          (*_excess)[u] += rem;
528 546
        }
529 547
      }
530 548
      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
531 549
        Value rem = (*_flow)[e];
532 550
        if (_tolerance.positive(rem)) {
533 551
          Node v = _graph.source(e);
534 552
          if ((*_level)[v] == _level->maxLevel()) continue;
535 553
          _flow->set(e, 0);
536 554
          (*_excess)[v] += rem;
537 555
        }
538 556
      }
539 557
      for (NodeIt n(_graph); n != INVALID; ++n) 
540 558
        if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n]))
541 559
          _level->activate(n);
542 560
          
543 561
      return true;
544 562
    }
545 563

	
546 564
    /// \brief Starts the first phase of the preflow algorithm.
547 565
    ///
548 566
    /// The preflow algorithm consists of two phases, this method runs
549 567
    /// the first phase. After the first phase the maximum flow value
550 568
    /// and a minimum value cut can already be computed, although a
551 569
    /// maximum flow is not yet obtained. So after calling this method
552 570
    /// \ref flowValue() returns the value of a maximum flow and \ref
553 571
    /// minCut() returns a minimum cut.
554 572
    /// \pre One of the \ref init() functions must be called before
555 573
    /// using this function.
556 574
    void startFirstPhase() {
557 575
      _phase = true;
558 576

	
559 577
      while (true) {
560 578
        int num = _node_num;
561 579

	
562 580
        Node n = INVALID;
563 581
        int level = -1;
564 582

	
565 583
        while (num > 0) {
566 584
          n = _level->highestActive();
567 585
          if (n == INVALID) goto first_phase_done;
568 586
          level = _level->highestActiveLevel();
569 587
          --num;
570 588
          
571 589
          Value excess = (*_excess)[n];
572 590
          int new_level = _level->maxLevel();
573 591

	
574 592
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
575 593
            Value rem = (*_capacity)[e] - (*_flow)[e];
576 594
            if (!_tolerance.positive(rem)) continue;
577 595
            Node v = _graph.target(e);
578 596
            if ((*_level)[v] < level) {
579 597
              if (!_level->active(v) && v != _target) {
580 598
                _level->activate(v);
581 599
              }
582 600
              if (!_tolerance.less(rem, excess)) {
583 601
                _flow->set(e, (*_flow)[e] + excess);
584 602
                (*_excess)[v] += excess;
585 603
                excess = 0;
586 604
                goto no_more_push_1;
587 605
              } else {
588 606
                excess -= rem;
589 607
                (*_excess)[v] += rem;
590 608
                _flow->set(e, (*_capacity)[e]);
591 609
              }
592 610
            } else if (new_level > (*_level)[v]) {
593 611
              new_level = (*_level)[v];
594 612
            }
595 613
          }
596 614

	
597 615
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
598 616
            Value rem = (*_flow)[e];
599 617
            if (!_tolerance.positive(rem)) continue;
600 618
            Node v = _graph.source(e);
601 619
            if ((*_level)[v] < level) {
602 620
              if (!_level->active(v) && v != _target) {
603 621
                _level->activate(v);
604 622
              }
605 623
              if (!_tolerance.less(rem, excess)) {
606 624
                _flow->set(e, (*_flow)[e] - excess);
607 625
                (*_excess)[v] += excess;
608 626
                excess = 0;
609 627
                goto no_more_push_1;
610 628
              } else {
611 629
                excess -= rem;
612 630
                (*_excess)[v] += rem;
613 631
                _flow->set(e, 0);
614 632
              }
615 633
            } else if (new_level > (*_level)[v]) {
616 634
              new_level = (*_level)[v];
617 635
            }
618 636
          }
619 637

	
620 638
        no_more_push_1:
621 639

	
622 640
          (*_excess)[n] = excess;
623 641

	
624 642
          if (excess != 0) {
625 643
            if (new_level + 1 < _level->maxLevel()) {
626 644
              _level->liftHighestActive(new_level + 1);
627 645
            } else {
628 646
              _level->liftHighestActiveToTop();
629 647
            }
630 648
            if (_level->emptyLevel(level)) {
631 649
              _level->liftToTop(level);
632 650
            }
633 651
          } else {
634 652
            _level->deactivate(n);
635 653
          }
636 654
        }
637 655

	
638 656
        num = _node_num * 20;
639 657
        while (num > 0) {
640 658
          while (level >= 0 && _level->activeFree(level)) {
641 659
            --level;
642 660
          }
643 661
          if (level == -1) {
644 662
            n = _level->highestActive();
645 663
            level = _level->highestActiveLevel();
646 664
            if (n == INVALID) goto first_phase_done;
647 665
          } else {
648 666
            n = _level->activeOn(level);
649 667
          }
650 668
          --num;
651 669

	
652 670
          Value excess = (*_excess)[n];
653 671
          int new_level = _level->maxLevel();
654 672

	
655 673
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
656 674
            Value rem = (*_capacity)[e] - (*_flow)[e];
657 675
            if (!_tolerance.positive(rem)) continue;
658 676
            Node v = _graph.target(e);
659 677
            if ((*_level)[v] < level) {
660 678
              if (!_level->active(v) && v != _target) {
661 679
                _level->activate(v);
662 680
              }
663 681
              if (!_tolerance.less(rem, excess)) {
664 682
                _flow->set(e, (*_flow)[e] + excess);
665 683
                (*_excess)[v] += excess;
666 684
                excess = 0;
667 685
                goto no_more_push_2;
668 686
              } else {
669 687
                excess -= rem;
670 688
                (*_excess)[v] += rem;
671 689
                _flow->set(e, (*_capacity)[e]);
672 690
              }
673 691
            } else if (new_level > (*_level)[v]) {
674 692
              new_level = (*_level)[v];
675 693
            }
676 694
          }
677 695

	
678 696
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
679 697
            Value rem = (*_flow)[e];
680 698
            if (!_tolerance.positive(rem)) continue;
681 699
            Node v = _graph.source(e);
682 700
            if ((*_level)[v] < level) {
683 701
              if (!_level->active(v) && v != _target) {
684 702
                _level->activate(v);
685 703
              }
686 704
              if (!_tolerance.less(rem, excess)) {
687 705
                _flow->set(e, (*_flow)[e] - excess);
688 706
                (*_excess)[v] += excess;
689 707
                excess = 0;
690 708
                goto no_more_push_2;
691 709
              } else {
692 710
                excess -= rem;
693 711
                (*_excess)[v] += rem;
694 712
                _flow->set(e, 0);
695 713
              }
696 714
            } else if (new_level > (*_level)[v]) {
697 715
              new_level = (*_level)[v];
698 716
            }
699 717
          }
700 718

	
701 719
        no_more_push_2:
702 720

	
703 721
          (*_excess)[n] = excess;
704 722

	
705 723
          if (excess != 0) {
706 724
            if (new_level + 1 < _level->maxLevel()) {
707 725
              _level->liftActiveOn(level, new_level + 1);
708 726
            } else {
709 727
              _level->liftActiveToTop(level);
710 728
            }
711 729
            if (_level->emptyLevel(level)) {
712 730
              _level->liftToTop(level);
713 731
            }
714 732
          } else {
715 733
            _level->deactivate(n);
716 734
          }
717 735
        }
718 736
      }
719 737
    first_phase_done:;
720 738
    }
721 739

	
722 740
    /// \brief Starts the second phase of the preflow algorithm.
723 741
    ///
724 742
    /// The preflow algorithm consists of two phases, this method runs
725 743
    /// the second phase. After calling one of the \ref init() functions
726 744
    /// and \ref startFirstPhase() and then \ref startSecondPhase(),
727 745
    /// \ref flowMap() returns a maximum flow, \ref flowValue() returns the
728 746
    /// value of a maximum flow, \ref minCut() returns a minimum cut
729 747
    /// \pre One of the \ref init() functions and \ref startFirstPhase()
730 748
    /// must be called before using this function.
731 749
    void startSecondPhase() {
732 750
      _phase = false;
733 751

	
734 752
      typename Digraph::template NodeMap<bool> reached(_graph);
735 753
      for (NodeIt n(_graph); n != INVALID; ++n) {
736 754
        reached[n] = (*_level)[n] < _level->maxLevel();
737 755
      }
738 756

	
739 757
      _level->initStart();
740 758
      _level->initAddItem(_source);
741 759

	
742 760
      std::vector<Node> queue;
743 761
      queue.push_back(_source);
744 762
      reached[_source] = true;
745 763

	
746 764
      while (!queue.empty()) {
747 765
        _level->initNewLevel();
748 766
        std::vector<Node> nqueue;
749 767
        for (int i = 0; i < int(queue.size()); ++i) {
750 768
          Node n = queue[i];
751 769
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
752 770
            Node v = _graph.target(e);
753 771
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
754 772
              reached[v] = true;
755 773
              _level->initAddItem(v);
756 774
              nqueue.push_back(v);
757 775
            }
758 776
          }
759 777
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
760 778
            Node u = _graph.source(e);
761 779
            if (!reached[u] &&
762 780
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
763 781
              reached[u] = true;
764 782
              _level->initAddItem(u);
765 783
              nqueue.push_back(u);
766 784
            }
767 785
          }
768 786
        }
769 787
        queue.swap(nqueue);
770 788
      }
771 789
      _level->initFinish();
772 790

	
773 791
      for (NodeIt n(_graph); n != INVALID; ++n) {
774 792
        if (!reached[n]) {
775 793
          _level->dirtyTopButOne(n);
776 794
        } else if ((*_excess)[n] > 0 && _target != n) {
777 795
          _level->activate(n);
778 796
        }
779 797
      }
780 798

	
781 799
      Node n;
782 800
      while ((n = _level->highestActive()) != INVALID) {
783 801
        Value excess = (*_excess)[n];
784 802
        int level = _level->highestActiveLevel();
785 803
        int new_level = _level->maxLevel();
786 804

	
787 805
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
788 806
          Value rem = (*_capacity)[e] - (*_flow)[e];
789 807
          if (!_tolerance.positive(rem)) continue;
790 808
          Node v = _graph.target(e);
791 809
          if ((*_level)[v] < level) {
792 810
            if (!_level->active(v) && v != _source) {
793 811
              _level->activate(v);
794 812
            }
795 813
            if (!_tolerance.less(rem, excess)) {
796 814
              _flow->set(e, (*_flow)[e] + excess);
797 815
              (*_excess)[v] += excess;
798 816
              excess = 0;
799 817
              goto no_more_push;
800 818
            } else {
801 819
              excess -= rem;
802 820
              (*_excess)[v] += rem;
803 821
              _flow->set(e, (*_capacity)[e]);
804 822
            }
805 823
          } else if (new_level > (*_level)[v]) {
806 824
            new_level = (*_level)[v];
807 825
          }
808 826
        }
809 827

	
810 828
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
811 829
          Value rem = (*_flow)[e];
812 830
          if (!_tolerance.positive(rem)) continue;
813 831
          Node v = _graph.source(e);
814 832
          if ((*_level)[v] < level) {
815 833
            if (!_level->active(v) && v != _source) {
816 834
              _level->activate(v);
817 835
            }
818 836
            if (!_tolerance.less(rem, excess)) {
819 837
              _flow->set(e, (*_flow)[e] - excess);
820 838
              (*_excess)[v] += excess;
821 839
              excess = 0;
822 840
              goto no_more_push;
823 841
            } else {
824 842
              excess -= rem;
825 843
              (*_excess)[v] += rem;
826 844
              _flow->set(e, 0);
827 845
            }
828 846
          } else if (new_level > (*_level)[v]) {
829 847
            new_level = (*_level)[v];
830 848
          }
831 849
        }
832 850

	
833 851
      no_more_push:
834 852

	
835 853
        (*_excess)[n] = excess;
836 854

	
837 855
        if (excess != 0) {
838 856
          if (new_level + 1 < _level->maxLevel()) {
839 857
            _level->liftHighestActive(new_level + 1);
840 858
          } else {
841 859
            // Calculation error
842 860
            _level->liftHighestActiveToTop();
843 861
          }
844 862
          if (_level->emptyLevel(level)) {
845 863
            // Calculation error
846 864
            _level->liftToTop(level);
847 865
          }
848 866
        } else {
849 867
          _level->deactivate(n);
850 868
        }
851 869

	
852 870
      }
853 871
    }
854 872

	
855 873
    /// \brief Runs the preflow algorithm.
856 874
    ///
857 875
    /// Runs the preflow algorithm.
858 876
    /// \note pf.run() is just a shortcut of the following code.
859 877
    /// \code
860 878
    ///   pf.init();
861 879
    ///   pf.startFirstPhase();
862 880
    ///   pf.startSecondPhase();
863 881
    /// \endcode
864 882
    void run() {
865 883
      init();
866 884
      startFirstPhase();
867 885
      startSecondPhase();
868 886
    }
869 887

	
870 888
    /// \brief Runs the preflow algorithm to compute the minimum cut.
871 889
    ///
872 890
    /// Runs the preflow algorithm to compute the minimum cut.
873 891
    /// \note pf.runMinCut() is just a shortcut of the following code.
874 892
    /// \code
875 893
    ///   pf.init();
876 894
    ///   pf.startFirstPhase();
877 895
    /// \endcode
878 896
    void runMinCut() {
879 897
      init();
880 898
      startFirstPhase();
881 899
    }
882 900

	
883 901
    /// @}
884 902

	
885 903
    /// \name Query Functions
886 904
    /// The results of the preflow algorithm can be obtained using these
887 905
    /// functions.\n
888 906
    /// Either one of the \ref run() "run*()" functions or one of the
889 907
    /// \ref startFirstPhase() "start*()" functions should be called
890 908
    /// before using them.
891 909

	
892 910
    ///@{
893 911

	
894 912
    /// \brief Returns the value of the maximum flow.
895 913
    ///
896 914
    /// Returns the value of the maximum flow by returning the excess
897 915
    /// of the target node. This value equals to the value of
898 916
    /// the maximum flow already after the first phase of the algorithm.
899 917
    ///
900 918
    /// \pre Either \ref run() or \ref init() must be called before
901 919
    /// using this function.
902 920
    Value flowValue() const {
903 921
      return (*_excess)[_target];
904 922
    }
905 923

	
906 924
    /// \brief Returns the flow value on the given arc.
907 925
    ///
908 926
    /// Returns the flow value on the given arc. This method can
909 927
    /// be called after the second phase of the algorithm.
910 928
    ///
911 929
    /// \pre Either \ref run() or \ref init() must be called before
912 930
    /// using this function.
913 931
    Value flow(const Arc& arc) const {
914 932
      return (*_flow)[arc];
915 933
    }
916 934

	
917 935
    /// \brief Returns a const reference to the flow map.
918 936
    ///
919 937
    /// Returns a const reference to the arc map storing the found flow.
920 938
    /// This method can be called after the second phase of the algorithm.
921 939
    ///
922 940
    /// \pre Either \ref run() or \ref init() must be called before
923 941
    /// using this function.
924 942
    const FlowMap& flowMap() const {
925 943
      return *_flow;
926 944
    }
927 945

	
928 946
    /// \brief Returns \c true when the node is on the source side of the
929 947
    /// minimum cut.
930 948
    ///
931 949
    /// Returns true when the node is on the source side of the found
932 950
    /// minimum cut. This method can be called both after running \ref
933 951
    /// startFirstPhase() and \ref startSecondPhase().
934 952
    ///
935 953
    /// \pre Either \ref run() or \ref init() must be called before
936 954
    /// using this function.
937 955
    bool minCut(const Node& node) const {
938 956
      return ((*_level)[node] == _level->maxLevel()) == _phase;
939 957
    }
940 958

	
941 959
    /// \brief Gives back a minimum value cut.
942 960
    ///
943 961
    /// Sets \c cutMap to the characteristic vector of a minimum value
944 962
    /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
945 963
    /// node map with \c bool (or convertible) value type.
946 964
    ///
947 965
    /// This method can be called both after running \ref startFirstPhase()
948 966
    /// and \ref startSecondPhase(). The result after the second phase
949 967
    /// could be slightly different if inexact computation is used.
950 968
    ///
951 969
    /// \note This function calls \ref minCut() for each node, so it runs in
952 970
    /// O(n) time.
953 971
    ///
954 972
    /// \pre Either \ref run() or \ref init() must be called before
955 973
    /// using this function.
956 974
    template <typename CutMap>
957 975
    void minCutMap(CutMap& cutMap) const {
958 976
      for (NodeIt n(_graph); n != INVALID; ++n) {
959 977
        cutMap.set(n, minCut(n));
960 978
      }
961 979
    }
962 980

	
963 981
    /// @}
964 982
  };
965 983
}
966 984

	
967 985
#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 19
#ifndef LEMON_RADIX_HEAP_H
20 20
#define LEMON_RADIX_HEAP_H
21 21

	
22
///\ingroup auxdat
22
///\ingroup heaps
23 23
///\file
24
///\brief Radix Heap implementation.
24
///\brief Radix heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <lemon/error.h>
28 28

	
29 29
namespace lemon {
30 30

	
31 31

	
32
  /// \ingroup auxdata
32
  /// \ingroup heaps
33 33
  ///
34
  /// \brief A Radix Heap implementation.
34
  /// \brief Radix heap data structure.
35 35
  ///
36
  /// This class implements the \e radix \e heap data structure. A \e heap
37
  /// is a data structure for storing items with specified values called \e
38
  /// priorities in such a way that finding the item with minimum priority is
39
  /// efficient. This heap type can store only items with \e int priority.
40
  /// In a heap one can change the priority of an item, add or erase an
41
  /// item, but the priority cannot be decreased under the last removed
42
  /// item's priority.
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.
43 41
  ///
44
  /// \param IM A read and writable Item int map, used internally
45
  /// to handle the cross references.
46
  ///
47
  /// \see BinHeap
48
  /// \see Dijkstra
42
  /// \tparam IM A read-writable item map with \c int values, used
43
  /// internally to handle the cross references.
49 44
  template <typename IM>
50 45
  class RadixHeap {
51 46

	
52 47
  public:
53
    typedef typename IM::Key Item;
48

	
49
    /// Type of the item-int map.
50
    typedef IM ItemIntMap;
51
    /// Type of the priorities.
54 52
    typedef int Prio;
55
    typedef IM ItemIntMap;
53
    /// Type of the items stored in the heap.
54
    typedef typename ItemIntMap::Key Item;
56 55

	
57 56
    /// \brief Exception thrown by RadixHeap.
58 57
    ///
59
    /// This Exception is thrown when a smaller priority
60
    /// is inserted into the \e RadixHeap then the last time erased.
58
    /// This exception is thrown when an item is inserted into a
59
    /// RadixHeap with a priority smaller than the last erased one.
61 60
    /// \see RadixHeap
62

	
63
    class UnderFlowPriorityError : public Exception {
61
    class PriorityUnderflowError : public Exception {
64 62
    public:
65 63
      virtual const char* what() const throw() {
66
        return "lemon::RadixHeap::UnderFlowPriorityError";
64
        return "lemon::RadixHeap::PriorityUnderflowError";
67 65
      }
68 66
    };
69 67

	
70
    /// \brief Type to represent the items states.
68
    /// \brief Type to represent the states of the items.
71 69
    ///
72
    /// Each Item element have a state associated to it. It may be "in heap",
73
    /// "pre heap" or "post heap". The latter two are indifferent from the
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
74 72
    /// heap's point of view, but may be useful to the user.
75 73
    ///
76
    /// The ItemIntMap \e should be initialized in such way that it maps
77
    /// PRE_HEAP (-1) to any element to be put in the heap...
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.
78 76
    enum State {
79
      IN_HEAP = 0,
80
      PRE_HEAP = -1,
81
      POST_HEAP = -2
77
      IN_HEAP = 0,    ///< = 0.
78
      PRE_HEAP = -1,  ///< = -1.
79
      POST_HEAP = -2  ///< = -2.
82 80
    };
83 81

	
84 82
  private:
85 83

	
86 84
    struct RadixItem {
87 85
      int prev, next, box;
88 86
      Item item;
89 87
      int prio;
90 88
      RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
91 89
    };
92 90

	
93 91
    struct RadixBox {
94 92
      int first;
95 93
      int min, size;
96 94
      RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
97 95
    };
98 96

	
99
    std::vector<RadixItem> data;
100
    std::vector<RadixBox> boxes;
97
    std::vector<RadixItem> _data;
98
    std::vector<RadixBox> _boxes;
101 99

	
102 100
    ItemIntMap &_iim;
103 101

	
102
  public:
104 103

	
105
  public:
106
    /// \brief The constructor.
104
    /// \brief Constructor.
107 105
    ///
108
    /// The constructor.
109
    ///
110
    /// \param map It should be given to the constructor, since it is used
111
    /// internally to handle the cross references. The value of the map
112
    /// should be PRE_HEAP (-1) for each element.
113
    ///
114
    /// \param minimal The initial minimal value of the heap.
115
    /// \param capacity It determines the initial capacity of the heap.
116
    RadixHeap(ItemIntMap &map, int minimal = 0, int capacity = 0)
117
      : _iim(map) {
118
      boxes.push_back(RadixBox(minimal, 1));
119
      boxes.push_back(RadixBox(minimal + 1, 1));
120
      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
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)) {
121 118
        extend();
122 119
      }
123 120
    }
124 121

	
125
    /// The number of items stored in the heap.
122
    /// \brief The number of items stored in the heap.
126 123
    ///
127
    /// \brief Returns the number of items stored in the heap.
128
    int size() const { return data.size(); }
129
    /// \brief Checks if the heap stores no items.
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.
130 128
    ///
131
    /// Returns \c true if and only if the heap stores no items.
132
    bool empty() const { return data.empty(); }
129
    /// This function returns \c true if the heap is empty.
130
    bool empty() const { return _data.empty(); }
133 131

	
134
    /// \brief Make empty this heap.
132
    /// \brief Make the heap empty.
135 133
    ///
136
    /// Make empty this heap. It does not change the cross reference
137
    /// map.  If you want to reuse a heap what is not surely empty you
138
    /// should first clear the heap and after that you should set the
139
    /// cross reference map for each item to \c PRE_HEAP.
140
    void clear(int minimal = 0, int capacity = 0) {
141
      data.clear(); boxes.clear();
142
      boxes.push_back(RadixBox(minimal, 1));
143
      boxes.push_back(RadixBox(minimal + 1, 1));
144
      while (lower(boxes.size() - 1, capacity + minimal - 1)) {
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)) {
145 146
        extend();
146 147
      }
147 148
    }
148 149

	
149 150
  private:
150 151

	
151 152
    bool upper(int box, Prio pr) {
152
      return pr < boxes[box].min;
153
      return pr < _boxes[box].min;
153 154
    }
154 155

	
155 156
    bool lower(int box, Prio pr) {
156
      return pr >= boxes[box].min + boxes[box].size;
157
      return pr >= _boxes[box].min + _boxes[box].size;
157 158
    }
158 159

	
159
    /// \brief Remove item from the box list.
160
    // Remove item from the box list
160 161
    void remove(int index) {
161
      if (data[index].prev >= 0) {
162
        data[data[index].prev].next = data[index].next;
162
      if (_data[index].prev >= 0) {
163
        _data[_data[index].prev].next = _data[index].next;
163 164
      } else {
164
        boxes[data[index].box].first = data[index].next;
165
        _boxes[_data[index].box].first = _data[index].next;
165 166
      }
166
      if (data[index].next >= 0) {
167
        data[data[index].next].prev = data[index].prev;
167
      if (_data[index].next >= 0) {
168
        _data[_data[index].next].prev = _data[index].prev;
168 169
      }
169 170
    }
170 171

	
171
    /// \brief Insert item into the box list.
172
    // Insert item into the box list
172 173
    void insert(int box, int index) {
173
      if (boxes[box].first == -1) {
174
        boxes[box].first = index;
175
        data[index].next = data[index].prev = -1;
174
      if (_boxes[box].first == -1) {
175
        _boxes[box].first = index;
176
        _data[index].next = _data[index].prev = -1;
176 177
      } else {
177
        data[index].next = boxes[box].first;
178
        data[boxes[box].first].prev = index;
179
        data[index].prev = -1;
180
        boxes[box].first = index;
178
        _data[index].next = _boxes[box].first;
179
        _data[_boxes[box].first].prev = index;
180
        _data[index].prev = -1;
181
        _boxes[box].first = index;
181 182
      }
182
      data[index].box = box;
183
      _data[index].box = box;
183 184
    }
184 185

	
185
    /// \brief Add a new box to the box list.
186
    // Add a new box to the box list
186 187
    void extend() {
187
      int min = boxes.back().min + boxes.back().size;
188
      int bs = 2 * boxes.back().size;
189
      boxes.push_back(RadixBox(min, bs));
188
      int min = _boxes.back().min + _boxes.back().size;
189
      int bs = 2 * _boxes.back().size;
190
      _boxes.push_back(RadixBox(min, bs));
190 191
    }
191 192

	
192
    /// \brief Move an item up into the proper box.
193
    void bubble_up(int index) {
194
      if (!lower(data[index].box, data[index].prio)) return;
193
    // Move an item up into the proper box.
194
    void bubbleUp(int index) {
195
      if (!lower(_data[index].box, _data[index].prio)) return;
195 196
      remove(index);
196
      int box = findUp(data[index].box, data[index].prio);
197
      int box = findUp(_data[index].box, _data[index].prio);
197 198
      insert(box, index);
198 199
    }
199 200

	
200
    /// \brief Find up the proper box for the item with the given prio.
201
    // Find up the proper box for the item with the given priority
201 202
    int findUp(int start, int pr) {
202 203
      while (lower(start, pr)) {
203
        if (++start == int(boxes.size())) {
204
        if (++start == int(_boxes.size())) {
204 205
          extend();
205 206
        }
206 207
      }
207 208
      return start;
208 209
    }
209 210

	
210
    /// \brief Move an item down into the proper box.
211
    void bubble_down(int index) {
212
      if (!upper(data[index].box, data[index].prio)) return;
211
    // Move an item down into the proper box
212
    void bubbleDown(int index) {
213
      if (!upper(_data[index].box, _data[index].prio)) return;
213 214
      remove(index);
214
      int box = findDown(data[index].box, data[index].prio);
215
      int box = findDown(_data[index].box, _data[index].prio);
215 216
      insert(box, index);
216 217
    }
217 218

	
218
    /// \brief Find up the proper box for the item with the given prio.
219
    // Find down the proper box for the item with the given priority
219 220
    int findDown(int start, int pr) {
220 221
      while (upper(start, pr)) {
221
        if (--start < 0) throw UnderFlowPriorityError();
222
        if (--start < 0) throw PriorityUnderflowError();
222 223
      }
223 224
      return start;
224 225
    }
225 226

	
226
    /// \brief Find the first not empty box.
227
    // Find the first non-empty box
227 228
    int findFirst() {
228 229
      int first = 0;
229
      while (boxes[first].first == -1) ++first;
230
      while (_boxes[first].first == -1) ++first;
230 231
      return first;
231 232
    }
232 233

	
233
    /// \brief Gives back the minimal prio of the box.
234
    // Gives back the minimum priority of the given box
234 235
    int minValue(int box) {
235
      int min = data[boxes[box].first].prio;
236
      for (int k = boxes[box].first; k != -1; k = data[k].next) {
237
        if (data[k].prio < min) min = data[k].prio;
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;
238 239
      }
239 240
      return min;
240 241
    }
241 242

	
242
    /// \brief Rearrange the items of the heap and makes the
243
    /// first box not empty.
243
    // Rearrange the items of the heap and make the first box non-empty
244 244
    void moveDown() {
245 245
      int box = findFirst();
246 246
      if (box == 0) return;
247 247
      int min = minValue(box);
248 248
      for (int i = 0; i <= box; ++i) {
249
        boxes[i].min = min;
250
        min += boxes[i].size;
249
        _boxes[i].min = min;
250
        min += _boxes[i].size;
251 251
      }
252
      int curr = boxes[box].first, next;
252
      int curr = _boxes[box].first, next;
253 253
      while (curr != -1) {
254
        next = data[curr].next;
255
        bubble_down(curr);
254
        next = _data[curr].next;
255
        bubbleDown(curr);
256 256
        curr = next;
257 257
      }
258 258
    }
259 259

	
260
    void relocate_last(int index) {
261
      if (index != int(data.size()) - 1) {
262
        data[index] = data.back();
263
        if (data[index].prev != -1) {
264
          data[data[index].prev].next = index;
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 265
        } else {
266
          boxes[data[index].box].first = index;
266
          _boxes[_data[index].box].first = index;
267 267
        }
268
        if (data[index].next != -1) {
269
          data[data[index].next].prev = index;
268
        if (_data[index].next != -1) {
269
          _data[_data[index].next].prev = index;
270 270
        }
271
        _iim[data[index].item] = index;
271
        _iim[_data[index].item] = index;
272 272
      }
273
      data.pop_back();
273
      _data.pop_back();
274 274
    }
275 275

	
276 276
  public:
277 277

	
278 278
    /// \brief Insert an item into the heap with the given priority.
279 279
    ///
280
    /// Adds \c i to the heap with priority \c p.
280
    /// This function inserts the given item into the heap with the
281
    /// given priority.
281 282
    /// \param i The item to insert.
282 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.
283 286
    void push(const Item &i, const Prio &p) {
284
      int n = data.size();
287
      int n = _data.size();
285 288
      _iim.set(i, n);
286
      data.push_back(RadixItem(i, p));
287
      while (lower(boxes.size() - 1, p)) {
289
      _data.push_back(RadixItem(i, p));
290
      while (lower(_boxes.size() - 1, p)) {
288 291
        extend();
289 292
      }
290
      int box = findDown(boxes.size() - 1, p);
293
      int box = findDown(_boxes.size() - 1, p);
291 294
      insert(box, n);
292 295
    }
293 296

	
294
    /// \brief Returns the item with minimum priority.
297
    /// \brief Return the item having minimum priority.
295 298
    ///
296
    /// This method returns the item with minimum priority.
297
    /// \pre The heap must be nonempty.
299
    /// This function returns the item having minimum priority.
300
    /// \pre The heap must be non-empty.
298 301
    Item top() const {
299 302
      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
300
      return data[boxes[0].first].item;
303
      return _data[_boxes[0].first].item;
301 304
    }
302 305

	
303
    /// \brief Returns the minimum priority.
306
    /// \brief The minimum priority.
304 307
    ///
305
    /// It returns the minimum priority.
306
    /// \pre The heap must be nonempty.
308
    /// This function returns the minimum priority.
309
    /// \pre The heap must be non-empty.
307 310
    Prio prio() const {
308 311
      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
309
      return data[boxes[0].first].prio;
312
      return _data[_boxes[0].first].prio;
310 313
     }
311 314

	
312
    /// \brief Deletes the item with minimum priority.
315
    /// \brief Remove the item having minimum priority.
313 316
    ///
314
    /// This method deletes the item with minimum priority.
317
    /// This function removes the item having minimum priority.
315 318
    /// \pre The heap must be non-empty.
316 319
    void pop() {
317 320
      moveDown();
318
      int index = boxes[0].first;
319
      _iim[data[index].item] = POST_HEAP;
321
      int index = _boxes[0].first;
322
      _iim[_data[index].item] = POST_HEAP;
320 323
      remove(index);
321
      relocate_last(index);
324
      relocateLast(index);
322 325
    }
323 326

	
324
    /// \brief Deletes \c i from the heap.
327
    /// \brief Remove the given item from the heap.
325 328
    ///
326
    /// This method deletes item \c i from the heap, if \c i was
327
    /// already stored in the heap.
328
    /// \param i The item to erase.
329
    /// 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.
329 333
    void erase(const Item &i) {
330 334
      int index = _iim[i];
331 335
      _iim[i] = POST_HEAP;
332 336
      remove(index);
333
      relocate_last(index);
337
      relocateLast(index);
334 338
   }
335 339

	
336
    /// \brief Returns the priority of \c i.
340
    /// \brief The priority of the given item.
337 341
    ///
338
    /// This function returns the priority of item \c i.
339
    /// \pre \c i must be in the heap.
342
    /// This function returns the priority of the given item.
340 343
    /// \param i The item.
344
    /// \pre \e i must be in the heap.
341 345
    Prio operator[](const Item &i) const {
342 346
      int idx = _iim[i];
343
      return data[idx].prio;
347
      return _data[idx].prio;
344 348
    }
345 349

	
346
    /// \brief \c i gets to the heap with priority \c p independently
347
    /// if \c i was already there.
350
    /// \brief Set the priority of an item or insert it, if it is
351
    /// not stored in the heap.
348 352
    ///
349
    /// This method calls \ref push(\c i, \c p) if \c i is not stored
350
    /// in the heap and sets the priority of \c i to \c p otherwise.
351
    /// It may throw an \e UnderFlowPriorityException.
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.
352 356
    /// \param i The item.
353 357
    /// \param p The priority.
358
    /// \pre \e i must be in the heap.
359
    /// \warning This method may throw an \c UnderFlowPriorityException.
354 360
    void set(const Item &i, const Prio &p) {
355 361
      int idx = _iim[i];
356 362
      if( idx < 0 ) {
357 363
        push(i, p);
358 364
      }
359
      else if( p >= data[idx].prio ) {
360
        data[idx].prio = p;
361
        bubble_up(idx);
365
      else if( p >= _data[idx].prio ) {
366
        _data[idx].prio = p;
367
        bubbleUp(idx);
362 368
      } else {
363
        data[idx].prio = p;
364
        bubble_down(idx);
369
        _data[idx].prio = p;
370
        bubbleDown(idx);
365 371
      }
366 372
    }
367 373

	
368

	
369
    /// \brief Decreases the priority of \c i to \c p.
374
    /// \brief Decrease the priority of an item to the given value.
370 375
    ///
371
    /// This method decreases the priority of item \c i to \c p.
372
    /// \pre \c i must be stored in the heap with priority at least \c p, and
373
    /// \c should be greater or equal to the last removed item's priority.
376
    /// This function decreases the priority of an item to the given value.
374 377
    /// \param i The item.
375 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.
376 381
    void decrease(const Item &i, const Prio &p) {
377 382
      int idx = _iim[i];
378
      data[idx].prio = p;
379
      bubble_down(idx);
383
      _data[idx].prio = p;
384
      bubbleDown(idx);
380 385
    }
381 386

	
382
    /// \brief Increases the priority of \c i to \c p.
387
    /// \brief Increase the priority of an item to the given value.
383 388
    ///
384
    /// This method sets the priority of item \c i to \c p.
385
    /// \pre \c i must be stored in the heap with priority at most \c p
389
    /// This function increases the priority of an item to the given value.
386 390
    /// \param i The item.
387 391
    /// \param p The priority.
392
    /// \pre \e i must be stored in the heap with priority at most \e p.
388 393
    void increase(const Item &i, const Prio &p) {
389 394
      int idx = _iim[i];
390
      data[idx].prio = p;
391
      bubble_up(idx);
395
      _data[idx].prio = p;
396
      bubbleUp(idx);
392 397
    }
393 398

	
394
    /// \brief Returns if \c item is in, has already been in, or has
395
    /// never been in the heap.
399
    /// \brief Return the state of an item.
396 400
    ///
397
    /// This method returns PRE_HEAP if \c item has never been in the
398
    /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
399
    /// otherwise. In the latter case it is possible that \c item will
400
    /// get back to the heap again.
401
    /// 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.
401 406
    /// \param i The item.
402 407
    State state(const Item &i) const {
403 408
      int s = _iim[i];
404 409
      if( s >= 0 ) s = 0;
405 410
      return State(s);
406 411
    }
407 412

	
408
    /// \brief Sets the state of the \c item in the heap.
413
    /// \brief Set the state of an item in the heap.
409 414
    ///
410
    /// Sets the state of the \c item in the heap. It can be used to
411
    /// manually clear the heap when it is important to achive the
412
    /// better time complexity.
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.
413 418
    /// \param i The item.
414 419
    /// \param st The state. It should not be \c IN_HEAP.
415 420
    void state(const Item& i, State st) {
416 421
      switch (st) {
417 422
      case POST_HEAP:
418 423
      case PRE_HEAP:
419 424
        if (state(i) == IN_HEAP) {
420 425
          erase(i);
421 426
        }
422 427
        _iim[i] = st;
423 428
        break;
424 429
      case IN_HEAP:
425 430
        break;
426 431
      }
427 432
    }
428 433

	
429 434
  }; // class RadixHeap
430 435

	
431 436
} // namespace lemon
432 437

	
433 438
#endif // LEMON_RADIX_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-2009
5
 * Copyright (C) 2003-2010
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 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 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 fully conforms to the \ref concepts::Digraph "Digraph concept".
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).
195 191
  ///
196
  ///\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
  ///This class provides constant time counting for nodes and arcs.
198
  ///
199
  ///\sa concepts::Digraph
200
  ///\sa SmartGraph
197 201
  class SmartDigraph : public ExtendedSmartDigraphBase {
198 202
    typedef ExtendedSmartDigraphBase Parent;
199 203

	
200 204
  private:
201

	
202
    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
203

	
204
    ///SmartDigraph is \e not copy constructible. Use DigraphCopy() instead.
205
    ///
205
    /// Digraphs are \e not copy constructible. Use DigraphCopy instead.
206 206
    SmartDigraph(const SmartDigraph &) : ExtendedSmartDigraphBase() {};
207
    ///\brief Assignment of SmartDigraph to another one is \e not allowed.
208
    ///Use DigraphCopy() instead.
209

	
210
    ///Assignment of SmartDigraph to another one is \e not allowed.
211
    ///Use DigraphCopy() instead.
207
    /// \brief Assignment of a digraph to another one is \e not allowed.
208
    /// Use DigraphCopy instead.
212 209
    void operator=(const SmartDigraph &) {}
213 210

	
214 211
  public:
215 212

	
216 213
    /// Constructor
217 214

	
218 215
    /// Constructor.
219 216
    ///
220 217
    SmartDigraph() {};
221 218

	
222 219
    ///Add a new node to the digraph.
223 220

	
224
    /// Add a new node to the digraph.
225
    /// \return The new node.
221
    ///This function adds a new node to the digraph.
222
    ///\return The new node.
226 223
    Node addNode() { return Parent::addNode(); }
227 224

	
228 225
    ///Add a new arc to the digraph.
229 226

	
230
    ///Add a new arc to the digraph with source node \c s
227
    ///This function adds a new arc to the digraph with source node \c s
231 228
    ///and target node \c t.
232 229
    ///\return The new arc.
233
    Arc addArc(const Node& s, const Node& t) {
230
    Arc addArc(Node s, Node t) {
234 231
      return Parent::addArc(s, t);
235 232
    }
236 233

	
237
    /// \brief Using this it is possible to avoid the superfluous memory
238
    /// allocation.
239

	
240
    /// Using this it is possible to avoid the superfluous memory
241
    /// allocation: if you know that the digraph you want to build will
242
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
243
    /// then it is worth reserving space for this amount before starting
244
    /// to build the digraph.
245
    /// \sa reserveArc
246
    void reserveNode(int n) { nodes.reserve(n); };
247

	
248
    /// \brief Using this it is possible to avoid the superfluous memory
249
    /// allocation.
250

	
251
    /// Using this it is possible to avoid the superfluous memory
252
    /// allocation: if you know that the digraph you want to build will
253
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
254
    /// then it is worth reserving space for this amount before starting
255
    /// to build the digraph.
256
    /// \sa reserveNode
257
    void reserveArc(int m) { arcs.reserve(m); };
258

	
259 234
    /// \brief Node validity check
260 235
    ///
261
    /// This function gives back true if the given node is valid,
262
    /// ie. it is a real node of the graph.
236
    /// This function gives back \c true if the given node is valid,
237
    /// i.e. it is a real node of the digraph.
263 238
    ///
264 239
    /// \warning A removed node (using Snapshot) could become valid again
265
    /// when new nodes are added to the graph.
240
    /// if new nodes are added to the digraph.
266 241
    bool valid(Node n) const { return Parent::valid(n); }
267 242

	
268 243
    /// \brief Arc validity check
269 244
    ///
270
    /// This function gives back true if the given arc is valid,
271
    /// ie. it is a real arc of the graph.
245
    /// This function gives back \c true if the given arc is valid,
246
    /// i.e. it is a real arc of the digraph.
272 247
    ///
273 248
    /// \warning A removed arc (using Snapshot) could become valid again
274
    /// when new arcs are added to the graph.
249
    /// if new arcs are added to the graph.
275 250
    bool valid(Arc a) const { return Parent::valid(a); }
276 251

	
277
    ///Clear the digraph.
278

	
279
    ///Erase all the nodes and arcs from the digraph.
280
    ///
281
    void clear() {
282
      Parent::clear();
283
    }
284

	
285 252
    ///Split a node.
286 253

	
287
    ///This function splits a node. First a new node is added to the digraph,
288
    ///then the source of each outgoing arc of \c n is moved to this new node.
289
    ///If \c connect is \c true (this is the default value), then a new arc
290
    ///from \c n to the newly created node is also added.
254
    ///This function splits the given node. First, a new node is added
255
    ///to the digraph, then the source of each outgoing arc of node \c n
256
    ///is moved to this new node.
257
    ///If the second parameter \c connect is \c true (this is the default
258
    ///value), then a new arc from node \c n to the newly created node
259
    ///is also added.
291 260
    ///\return The newly created node.
292 261
    ///
293
    ///\note The <tt>Arc</tt>s
294
    ///referencing a moved arc remain
295
    ///valid. However <tt>InArc</tt>'s and <tt>OutArc</tt>'s
296
    ///may be invalidated.
262
    ///\note All iterators remain valid.
263
    ///
297 264
    ///\warning This functionality cannot be used together with the Snapshot
298 265
    ///feature.
299 266
    Node split(Node n, bool connect = true)
300 267
    {
301 268
      Node b = addNode();
302 269
      nodes[b._id].first_out=nodes[n._id].first_out;
303 270
      nodes[n._id].first_out=-1;
304 271
      for(int i=nodes[b._id].first_out; i!=-1; i=arcs[i].next_out) {
305 272
        arcs[i].source=b._id;
306 273
      }
307 274
      if(connect) addArc(n,b);
308 275
      return b;
309 276
    }
310 277

	
278
    ///Clear the digraph.
279

	
280
    ///This function erases all nodes and arcs from the digraph.
281
    ///
282
    void clear() {
283
      Parent::clear();
284
    }
285

	
286
    /// Reserve memory for nodes.
287

	
288
    /// Using this function, it is possible to avoid superfluous memory
289
    /// allocation: if you know that the digraph you want to build will
290
    /// be large (e.g. it will contain millions of nodes and/or arcs),
291
    /// then it is worth reserving space for this amount before starting
292
    /// to build the digraph.
293
    /// \sa reserveArc()
294
    void reserveNode(int n) { nodes.reserve(n); };
295

	
296
    /// Reserve memory for arcs.
297

	
298
    /// Using this function, it is possible to avoid superfluous memory
299
    /// allocation: if you know that the digraph you want to build will
300
    /// be large (e.g. it will contain millions of nodes and/or arcs),
301
    /// then it is worth reserving space for this amount before starting
302
    /// to build the digraph.
303
    /// \sa reserveNode()
304
    void reserveArc(int m) { arcs.reserve(m); };
305

	
311 306
  public:
312 307

	
313 308
    class Snapshot;
314 309

	
315 310
  protected:
316 311

	
317 312
    void restoreSnapshot(const Snapshot &s)
318 313
    {
319 314
      while(s.arc_num<arcs.size()) {
320 315
        Arc arc = arcFromId(arcs.size()-1);
321 316
        Parent::notifier(Arc()).erase(arc);
322 317
        nodes[arcs.back().source].first_out=arcs.back().next_out;
323 318
        nodes[arcs.back().target].first_in=arcs.back().next_in;
324 319
        arcs.pop_back();
325 320
      }
326 321
      while(s.node_num<nodes.size()) {
327 322
        Node node = nodeFromId(nodes.size()-1);
328 323
        Parent::notifier(Node()).erase(node);
329 324
        nodes.pop_back();
330 325
      }
331 326
    }
332 327

	
333 328
  public:
334 329

	
335
    ///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.
336 331

	
337
    ///Class to make a snapshot of the digraph and to restrore to it later.
332
    ///Class to make a snapshot of the digraph and to restore it later.
338 333
    ///
339 334
    ///The newly added nodes and arcs can be removed using the
340
    ///restore() function.
341
    ///\note After you restore a state, you cannot restore
342
    ///a later state, in other word you cannot add again the arcs deleted
343
    ///by restore() using another one Snapshot instance.
335
    ///restore() function. This is the only way for deleting nodes and/or
336
    ///arcs from a SmartDigraph structure.
344 337
    ///
345
    ///\warning If you do not use correctly the snapshot that can cause
346
    ///either broken program, invalid state of the digraph, valid but
347
    ///not the restored digraph or no change. Because the runtime performance
348
    ///the validity of the snapshot is not stored.
338
    ///\note After a state is restored, you cannot restore a later state,
339
    ///i.e. you cannot add the removed nodes and arcs again using
340
    ///another Snapshot instance.
341
    ///
342
    ///\warning Node splitting cannot be restored.
343
    ///\warning The validity of the snapshot is not stored due to
344
    ///performance reasons. If you do not use the snapshot correctly,
345
    ///it can cause broken program, invalid or not restored state of
346
    ///the digraph or no change.
349 347
    class Snapshot
350 348
    {
351 349
      SmartDigraph *_graph;
352 350
    protected:
353 351
      friend class SmartDigraph;
354 352
      unsigned int node_num;
355 353
      unsigned int arc_num;
356 354
    public:
357 355
      ///Default constructor.
358 356

	
359 357
      ///Default constructor.
360
      ///To actually make a snapshot you must call save().
361
      ///
358
      ///You have to call save() to actually make a snapshot.
362 359
      Snapshot() : _graph(0) {}
363 360
      ///Constructor that immediately makes a snapshot
364 361

	
365
      ///This constructor immediately makes a snapshot of the digraph.
366
      ///\param graph The digraph we make a snapshot of.
367
      Snapshot(SmartDigraph &graph) : _graph(&graph) {
362
      ///This constructor immediately makes a snapshot of the given digraph.
363
      ///
364
      Snapshot(SmartDigraph &gr) : _graph(&gr) {
368 365
        node_num=_graph->nodes.size();
369 366
        arc_num=_graph->arcs.size();
370 367
      }
371 368

	
372 369
      ///Make a snapshot.
373 370

	
374
      ///Make a snapshot of the digraph.
375
      ///
376
      ///This function can be called more than once. In case of a repeated
371
      ///This function makes a snapshot of the given digraph.
372
      ///It can be called more than once. In case of a repeated
377 373
      ///call, the previous snapshot gets lost.
378
      ///\param graph The digraph we make the snapshot of.
379
      void save(SmartDigraph &graph)
380
      {
381
        _graph=&graph;
374
      void save(SmartDigraph &gr) {
375
        _graph=&gr;
382 376
        node_num=_graph->nodes.size();
383 377
        arc_num=_graph->arcs.size();
384 378
      }
385 379

	
386 380
      ///Undo the changes until a snapshot.
387 381

	
388
      ///Undo the changes until a snapshot created by save().
389
      ///
390
      ///\note After you restored a state, you cannot restore
391
      ///a later state, in other word you cannot add again the arcs deleted
392
      ///by restore().
382
      ///This function undos the changes until the last snapshot
383
      ///created by save() or Snapshot(SmartDigraph&).
393 384
      void restore()
394 385
      {
395 386
        _graph->restoreSnapshot(*this);
396 387
      }
397 388
    };
398 389
  };
399 390

	
400 391

	
401 392
  class SmartGraphBase {
402 393

	
403 394
  protected:
404 395

	
405 396
    struct NodeT {
406 397
      int first_out;
407 398
    };
408 399

	
409 400
    struct ArcT {
410 401
      int target;
411 402
      int next_out;
412 403
    };
413 404

	
414 405
    std::vector<NodeT> nodes;
415 406
    std::vector<ArcT> arcs;
416 407

	
417 408
    int first_free_arc;
418 409

	
419 410
  public:
420 411

	
421 412
    typedef SmartGraphBase Graph;
422 413

	
423 414
    class Node;
424 415
    class Arc;
425 416
    class Edge;
426 417

	
427 418
    class Node {
428 419
      friend class SmartGraphBase;
429 420
    protected:
430 421

	
431 422
      int _id;
432 423
      explicit Node(int id) { _id = id;}
433 424

	
434 425
    public:
435 426
      Node() {}
436 427
      Node (Invalid) { _id = -1; }
437 428
      bool operator==(const Node& node) const {return _id == node._id;}
438 429
      bool operator!=(const Node& node) const {return _id != node._id;}
439 430
      bool operator<(const Node& node) const {return _id < node._id;}
440 431
    };
441 432

	
442 433
    class Edge {
443 434
      friend class SmartGraphBase;
444 435
    protected:
445 436

	
446 437
      int _id;
447 438
      explicit Edge(int id) { _id = id;}
448 439

	
449 440
    public:
450 441
      Edge() {}
451 442
      Edge (Invalid) { _id = -1; }
452 443
      bool operator==(const Edge& arc) const {return _id == arc._id;}
453 444
      bool operator!=(const Edge& arc) const {return _id != arc._id;}
454 445
      bool operator<(const Edge& arc) const {return _id < arc._id;}
455 446
    };
456 447

	
457 448
    class Arc {
458 449
      friend class SmartGraphBase;
459 450
    protected:
460 451

	
461 452
      int _id;
462 453
      explicit Arc(int id) { _id = id;}
463 454

	
464 455
    public:
465 456
      operator Edge() const {
466 457
        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
467 458
      }
468 459

	
469 460
      Arc() {}
470 461
      Arc (Invalid) { _id = -1; }
471 462
      bool operator==(const Arc& arc) const {return _id == arc._id;}
472 463
      bool operator!=(const Arc& arc) const {return _id != arc._id;}
473 464
      bool operator<(const Arc& arc) const {return _id < arc._id;}
474 465
    };
475 466

	
476 467

	
477 468

	
478 469
    SmartGraphBase()
479 470
      : nodes(), arcs() {}
480 471

	
481 472
    typedef True NodeNumTag;
482 473
    typedef True EdgeNumTag;
483 474
    typedef True ArcNumTag;
484 475

	
485 476
    int nodeNum() const { return nodes.size(); }
486 477
    int edgeNum() const { return arcs.size() / 2; }
487 478
    int arcNum() const { return arcs.size(); }
488 479

	
489 480
    int maxNodeId() const { return nodes.size()-1; }
490 481
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
491 482
    int maxArcId() const { return arcs.size()-1; }
492 483

	
493 484
    Node source(Arc e) const { return Node(arcs[e._id ^ 1].target); }
494 485
    Node target(Arc e) const { return Node(arcs[e._id].target); }
495 486

	
496 487
    Node u(Edge e) const { return Node(arcs[2 * e._id].target); }
497 488
    Node v(Edge e) const { return Node(arcs[2 * e._id + 1].target); }
498 489

	
499 490
    static bool direction(Arc e) {
500 491
      return (e._id & 1) == 1;
501 492
    }
502 493

	
503 494
    static Arc direct(Edge e, bool d) {
504 495
      return Arc(e._id * 2 + (d ? 1 : 0));
505 496
    }
506 497

	
507 498
    void first(Node& node) const {
508 499
      node._id = nodes.size() - 1;
509 500
    }
510 501

	
511
    void next(Node& node) const {
502
    static void next(Node& node) {
512 503
      --node._id;
513 504
    }
514 505

	
515 506
    void first(Arc& arc) const {
516 507
      arc._id = arcs.size() - 1;
517 508
    }
518 509

	
519
    void next(Arc& arc) const {
510
    static void next(Arc& arc) {
520 511
      --arc._id;
521 512
    }
522 513

	
523 514
    void first(Edge& arc) const {
524 515
      arc._id = arcs.size() / 2 - 1;
525 516
    }
526 517

	
527
    void next(Edge& arc) const {
518
    static void next(Edge& arc) {
528 519
      --arc._id;
529 520
    }
530 521

	
531 522
    void firstOut(Arc &arc, const Node& v) const {
532 523
      arc._id = nodes[v._id].first_out;
533 524
    }
534 525
    void nextOut(Arc &arc) const {
535 526
      arc._id = arcs[arc._id].next_out;
536 527
    }
537 528

	
538 529
    void firstIn(Arc &arc, const Node& v) const {
539 530
      arc._id = ((nodes[v._id].first_out) ^ 1);
540 531
      if (arc._id == -2) arc._id = -1;
541 532
    }
542 533
    void nextIn(Arc &arc) const {
543 534
      arc._id = ((arcs[arc._id ^ 1].next_out) ^ 1);
544 535
      if (arc._id == -2) arc._id = -1;
545 536
    }
546 537

	
547 538
    void firstInc(Edge &arc, bool& d, const Node& v) const {
548 539
      int de = nodes[v._id].first_out;
549 540
      if (de != -1) {
550 541
        arc._id = de / 2;
551 542
        d = ((de & 1) == 1);
552 543
      } else {
553 544
        arc._id = -1;
554 545
        d = true;
555 546
      }
556 547
    }
557 548
    void nextInc(Edge &arc, bool& d) const {
558 549
      int de = (arcs[(arc._id * 2) | (d ? 1 : 0)].next_out);
559 550
      if (de != -1) {
560 551
        arc._id = de / 2;
561 552
        d = ((de & 1) == 1);
562 553
      } else {
563 554
        arc._id = -1;
564 555
        d = true;
565 556
      }
566 557
    }
567 558

	
568 559
    static int id(Node v) { return v._id; }
569 560
    static int id(Arc e) { return e._id; }
570 561
    static int id(Edge e) { return e._id; }
571 562

	
572 563
    static Node nodeFromId(int id) { return Node(id);}
573 564
    static Arc arcFromId(int id) { return Arc(id);}
574 565
    static Edge edgeFromId(int id) { return Edge(id);}
575 566

	
576 567
    bool valid(Node n) const {
577 568
      return n._id >= 0 && n._id < static_cast<int>(nodes.size());
578 569
    }
579 570
    bool valid(Arc a) const {
580 571
      return a._id >= 0 && a._id < static_cast<int>(arcs.size());
581 572
    }
582 573
    bool valid(Edge e) const {
583 574
      return e._id >= 0 && 2 * e._id < static_cast<int>(arcs.size());
584 575
    }
585 576

	
586 577
    Node addNode() {
587 578
      int n = nodes.size();
588 579
      nodes.push_back(NodeT());
589 580
      nodes[n].first_out = -1;
590 581

	
591 582
      return Node(n);
592 583
    }
593 584

	
594 585
    Edge addEdge(Node u, Node v) {
595 586
      int n = arcs.size();
596 587
      arcs.push_back(ArcT());
597 588
      arcs.push_back(ArcT());
598 589

	
599 590
      arcs[n].target = u._id;
600 591
      arcs[n | 1].target = v._id;
601 592

	
602 593
      arcs[n].next_out = nodes[v._id].first_out;
603 594
      nodes[v._id].first_out = n;
604 595

	
605 596
      arcs[n | 1].next_out = nodes[u._id].first_out;
606 597
      nodes[u._id].first_out = (n | 1);
607 598

	
608 599
      return Edge(n / 2);
609 600
    }
610 601

	
611 602
    void clear() {
612 603
      arcs.clear();
613 604
      nodes.clear();
614 605
    }
615 606

	
616 607
  };
617 608

	
618 609
  typedef GraphExtender<SmartGraphBase> ExtendedSmartGraphBase;
619 610

	
620 611
  /// \ingroup graphs
621 612
  ///
622 613
  /// \brief A smart undirected graph class.
623 614
  ///
624
  /// This is a simple and fast graph implementation.
625
  /// It is also quite memory efficient, but at the price
626
  /// that <b> it does support only limited (only stack-like)
627
  /// node and arc deletions</b>.
628
  /// It fully conforms to the \ref concepts::Graph "Graph concept".
615
  /// \ref SmartGraph is a simple and fast graph implementation.
616
  /// It is also quite memory efficient but at the price
617
  /// that it does not support node and edge deletion
618
  /// (except for the Snapshot feature).
629 619
  ///
630
  /// \sa concepts::Graph.
620
  /// This type fully conforms to the \ref concepts::Graph "Graph concept"
621
  /// and it also provides some additional functionalities.
622
  /// Most of its member functions and nested classes are documented
623
  /// only in the concept class.
624
  ///
625
  /// This class provides constant time counting for nodes, edges and arcs.
626
  ///
627
  /// \sa concepts::Graph
628
  /// \sa SmartDigraph
631 629
  class SmartGraph : public ExtendedSmartGraphBase {
632 630
    typedef ExtendedSmartGraphBase Parent;
633 631

	
634 632
  private:
635

	
636
    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
637

	
638
    ///SmartGraph is \e not copy constructible. Use GraphCopy() instead.
639
    ///
633
    /// Graphs are \e not copy constructible. Use GraphCopy instead.
640 634
    SmartGraph(const SmartGraph &) : ExtendedSmartGraphBase() {};
641

	
642
    ///\brief Assignment of SmartGraph to another one is \e not allowed.
643
    ///Use GraphCopy() instead.
644

	
645
    ///Assignment of SmartGraph to another one is \e not allowed.
646
    ///Use GraphCopy() instead.
635
    /// \brief Assignment of a graph to another one is \e not allowed.
636
    /// Use GraphCopy instead.
647 637
    void operator=(const SmartGraph &) {}
648 638

	
649 639
  public:
650 640

	
651 641
    /// Constructor
652 642

	
653 643
    /// Constructor.
654 644
    ///
655 645
    SmartGraph() {}
656 646

	
657
    ///Add a new node to the graph.
658

	
659
    /// Add a new node to the graph.
647
    /// \brief Add a new node to the graph.
648
    ///
649
    /// This function adds a new node to the graph.
660 650
    /// \return The new node.
661 651
    Node addNode() { return Parent::addNode(); }
662 652

	
663
    ///Add a new edge to the graph.
664

	
665
    ///Add a new edge to the graph with node \c s
666
    ///and \c t.
667
    ///\return The new edge.
668
    Edge addEdge(const Node& s, const Node& t) {
669
      return Parent::addEdge(s, t);
653
    /// \brief Add a new edge to the graph.
654
    ///
655
    /// This function adds a new edge to the graph between nodes
656
    /// \c u and \c v with inherent orientation from node \c u to
657
    /// node \c v.
658
    /// \return The new edge.
659
    Edge addEdge(Node u, Node v) {
660
      return Parent::addEdge(u, v);
670 661
    }
671 662

	
672 663
    /// \brief Node validity check
673 664
    ///
674
    /// This function gives back true if the given node is valid,
675
    /// ie. it is a real node of the graph.
665
    /// This function gives back \c true if the given node is valid,
666
    /// i.e. it is a real node of the graph.
676 667
    ///
677 668
    /// \warning A removed node (using Snapshot) could become valid again
678
    /// when new nodes are added to the graph.
669
    /// if new nodes are added to the graph.
679 670
    bool valid(Node n) const { return Parent::valid(n); }
680 671

	
672
    /// \brief Edge validity check
673
    ///
674
    /// This function gives back \c true if the given edge is valid,
675
    /// i.e. it is a real edge of the graph.
676
    ///
677
    /// \warning A removed edge (using Snapshot) could become valid again
678
    /// if new edges are added to the graph.
679
    bool valid(Edge e) const { return Parent::valid(e); }
680

	
681 681
    /// \brief Arc validity check
682 682
    ///
683
    /// This function gives back true if the given arc is valid,
684
    /// ie. it is a real arc of the graph.
683
    /// This function gives back \c true if the given arc is valid,
684
    /// i.e. it is a real arc of the graph.
685 685
    ///
686 686
    /// \warning A removed arc (using Snapshot) could become valid again
687
    /// when new edges are added to the graph.
687
    /// if new edges are added to the graph.
688 688
    bool valid(Arc a) const { return Parent::valid(a); }
689 689

	
690
    /// \brief Edge validity check
691
    ///
692
    /// This function gives back true if the given edge is valid,
693
    /// ie. it is a real edge of the graph.
694
    ///
695
    /// \warning A removed edge (using Snapshot) could become valid again
696
    /// when new edges are added to the graph.
697
    bool valid(Edge e) const { return Parent::valid(e); }
698

	
699 690
    ///Clear the graph.
700 691

	
701
    ///Erase all the nodes and edges from the graph.
692
    ///This function erases all nodes and arcs from the graph.
702 693
    ///
703 694
    void clear() {
704 695
      Parent::clear();
705 696
    }
706 697

	
698
    /// Reserve memory for nodes.
699

	
700
    /// Using this function, it is possible to avoid superfluous memory
701
    /// allocation: if you know that the graph you want to build will
702
    /// be large (e.g. it will contain millions of nodes and/or edges),
703
    /// then it is worth reserving space for this amount before starting
704
    /// to build the graph.
705
    /// \sa reserveEdge()
706
    void reserveNode(int n) { nodes.reserve(n); };
707

	
708
    /// Reserve memory for edges.
709

	
710
    /// Using this function, it is possible to avoid superfluous memory
711
    /// allocation: if you know that the graph you want to build will
712
    /// be large (e.g. it will contain millions of nodes and/or edges),
713
    /// then it is worth reserving space for this amount before starting
714
    /// to build the graph.
715
    /// \sa reserveNode()
716
    void reserveEdge(int m) { arcs.reserve(2 * m); };
717

	
707 718
  public:
708 719

	
709 720
    class Snapshot;
710 721

	
711 722
  protected:
712 723

	
713 724
    void saveSnapshot(Snapshot &s)
714 725
    {
715 726
      s._graph = this;
716 727
      s.node_num = nodes.size();
717 728
      s.arc_num = arcs.size();
718 729
    }
719 730

	
720 731
    void restoreSnapshot(const Snapshot &s)
721 732
    {
722 733
      while(s.arc_num<arcs.size()) {
723 734
        int n=arcs.size()-1;
724 735
        Edge arc=edgeFromId(n/2);
725 736
        Parent::notifier(Edge()).erase(arc);
726 737
        std::vector<Arc> dir;
727 738
        dir.push_back(arcFromId(n));
728 739
        dir.push_back(arcFromId(n-1));
729 740
        Parent::notifier(Arc()).erase(dir);
730 741
        nodes[arcs[n-1].target].first_out=arcs[n].next_out;
731 742
        nodes[arcs[n].target].first_out=arcs[n-1].next_out;
732 743
        arcs.pop_back();
733 744
        arcs.pop_back();
734 745
      }
735 746
      while(s.node_num<nodes.size()) {
736 747
        int n=nodes.size()-1;
737 748
        Node node = nodeFromId(n);
738 749
        Parent::notifier(Node()).erase(node);
739 750
        nodes.pop_back();
740 751
      }
741 752
    }
742 753

	
743 754
  public:
744 755

	
745
    ///Class to make a snapshot of the digraph and to restrore to it later.
756
    ///Class to make a snapshot of the graph and to restore it later.
746 757

	
747
    ///Class to make a snapshot of the digraph and to restrore to it later.
758
    ///Class to make a snapshot of the graph and to restore it later.
748 759
    ///
749
    ///The newly added nodes and arcs can be removed using the
750
    ///restore() function.
760
    ///The newly added nodes and edges can be removed using the
761
    ///restore() function. This is the only way for deleting nodes and/or
762
    ///edges from a SmartGraph structure.
751 763
    ///
752
    ///\note After you restore a state, you cannot restore
753
    ///a later state, in other word you cannot add again the arcs deleted
754
    ///by restore() using another one Snapshot instance.
764
    ///\note After a state is restored, you cannot restore a later state,
765
    ///i.e. you cannot add the removed nodes and edges again using
766
    ///another Snapshot instance.
755 767
    ///
756
    ///\warning If you do not use correctly the snapshot that can cause
757
    ///either broken program, invalid state of the digraph, valid but
758
    ///not the restored digraph or no change. Because the runtime performance
759
    ///the validity of the snapshot is not stored.
768
    ///\warning The validity of the snapshot is not stored due to
769
    ///performance reasons. If you do not use the snapshot correctly,
770
    ///it can cause broken program, invalid or not restored state of
771
    ///the graph or no change.
760 772
    class Snapshot
761 773
    {
762 774
      SmartGraph *_graph;
763 775
    protected:
764 776
      friend class SmartGraph;
765 777
      unsigned int node_num;
766 778
      unsigned int arc_num;
767 779
    public:
768 780
      ///Default constructor.
769 781

	
770 782
      ///Default constructor.
771
      ///To actually make a snapshot you must call save().
772
      ///
783
      ///You have to call save() to actually make a snapshot.
773 784
      Snapshot() : _graph(0) {}
774 785
      ///Constructor that immediately makes a snapshot
775 786

	
776
      ///This constructor immediately makes a snapshot of the digraph.
777
      ///\param graph The digraph we make a snapshot of.
778
      Snapshot(SmartGraph &graph) {
779
        graph.saveSnapshot(*this);
787
      /// This constructor immediately makes a snapshot of the given graph.
788
      ///
789
      Snapshot(SmartGraph &gr) {
790
        gr.saveSnapshot(*this);
780 791
      }
781 792

	
782 793
      ///Make a snapshot.
783 794

	
784
      ///Make a snapshot of the graph.
785
      ///
786
      ///This function can be called more than once. In case of a repeated
795
      ///This function makes a snapshot of the given graph.
796
      ///It can be called more than once. In case of a repeated
787 797
      ///call, the previous snapshot gets lost.
788
      ///\param graph The digraph we make the snapshot of.
789
      void save(SmartGraph &graph)
798
      void save(SmartGraph &gr)
790 799
      {
791
        graph.saveSnapshot(*this);
800
        gr.saveSnapshot(*this);
792 801
      }
793 802

	
794
      ///Undo the changes until a snapshot.
803
      ///Undo the changes until the last snapshot.
795 804

	
796
      ///Undo the changes until a snapshot created by save().
797
      ///
798
      ///\note After you restored a state, you cannot restore
799
      ///a later state, in other word you cannot add again the arcs deleted
800
      ///by restore().
805
      ///This function undos the changes until the last snapshot
806
      ///created by save() or Snapshot(SmartGraph&).
801 807
      void restore()
802 808
      {
803 809
        _graph->restoreSnapshot(*this);
804 810
      }
805 811
    };
806 812
  };
807 813

	
808 814
} //namespace lemon
809 815

	
810 816

	
811 817
#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-2010
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 <lemon/soplex.h>
21 21

	
22 22
#include <soplex.h>
23 23
#include <spxout.h>
24 24

	
25 25

	
26 26
///\file
27 27
///\brief Implementation of the LEMON-SOPLEX lp solver interface.
28 28
namespace lemon {
29 29

	
30 30
  SoplexLp::SoplexLp() {
31 31
    soplex = new soplex::SoPlex;
32 32
    messageLevel(MESSAGE_NOTHING);
33 33
  }
34 34

	
35 35
  SoplexLp::~SoplexLp() {
36 36
    delete soplex;
37 37
  }
38 38

	
39 39
  SoplexLp::SoplexLp(const SoplexLp& lp) {
40 40
    rows = lp.rows;
41 41
    cols = lp.cols;
42 42

	
43 43
    soplex = new soplex::SoPlex;
44 44
    (*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex);
45 45

	
46 46
    _col_names = lp._col_names;
47 47
    _col_names_ref = lp._col_names_ref;
48 48

	
49 49
    _row_names = lp._row_names;
50 50
    _row_names_ref = lp._row_names_ref;
51 51

	
52 52
    messageLevel(MESSAGE_NOTHING);
53 53
  }
54 54

	
55 55
  void SoplexLp::_clear_temporals() {
56 56
    _primal_values.clear();
57 57
    _dual_values.clear();
58 58
  }
59 59

	
60 60
  SoplexLp* SoplexLp::newSolver() const {
61 61
    SoplexLp* newlp = new SoplexLp();
62 62
    return newlp;
63 63
  }
64 64

	
65 65
  SoplexLp* SoplexLp::cloneSolver() const {
66 66
    SoplexLp* newlp = new SoplexLp(*this);
67 67
    return newlp;
68 68
  }
69 69

	
70 70
  const char* SoplexLp::_solverName() const { return "SoplexLp"; }
71 71

	
72 72
  int SoplexLp::_addCol() {
73 73
    soplex::LPCol c;
74 74
    c.setLower(-soplex::infinity);
75 75
    c.setUpper(soplex::infinity);
76 76
    soplex->addCol(c);
77 77

	
78 78
    _col_names.push_back(std::string());
79 79

	
80 80
    return soplex->nCols() - 1;
81 81
  }
82 82

	
83 83
  int SoplexLp::_addRow() {
84 84
    soplex::LPRow r;
85 85
    r.setLhs(-soplex::infinity);
86 86
    r.setRhs(soplex::infinity);
87 87
    soplex->addRow(r);
88 88

	
89 89
    _row_names.push_back(std::string());
90 90

	
91 91
    return soplex->nRows() - 1;
92 92
  }
93 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

	
94 107

	
95 108
  void SoplexLp::_eraseCol(int i) {
96 109
    soplex->removeCol(i);
97 110
    _col_names_ref.erase(_col_names[i]);
98 111
    _col_names[i] = _col_names.back();
99 112
    _col_names_ref[_col_names.back()] = i;
100 113
    _col_names.pop_back();
101 114
  }
102 115

	
103 116
  void SoplexLp::_eraseRow(int i) {
104 117
    soplex->removeRow(i);
105 118
    _row_names_ref.erase(_row_names[i]);
106 119
    _row_names[i] = _row_names.back();
107 120
    _row_names_ref[_row_names.back()] = i;
108 121
    _row_names.pop_back();
109 122
  }
110 123

	
111 124
  void SoplexLp::_eraseColId(int i) {
112 125
    cols.eraseIndex(i);
113 126
    cols.relocateIndex(i, cols.maxIndex());
114 127
  }
115 128
  void SoplexLp::_eraseRowId(int i) {
116 129
    rows.eraseIndex(i);
117 130
    rows.relocateIndex(i, rows.maxIndex());
118 131
  }
119 132

	
120 133
  void SoplexLp::_getColName(int c, std::string &name) const {
121 134
    name = _col_names[c];
122 135
  }
123 136

	
124 137
  void SoplexLp::_setColName(int c, const std::string &name) {
125 138
    _col_names_ref.erase(_col_names[c]);
126 139
    _col_names[c] = name;
127 140
    if (!name.empty()) {
128 141
      _col_names_ref.insert(std::make_pair(name, c));
129 142
    }
130 143
  }
131 144

	
132 145
  int SoplexLp::_colByName(const std::string& name) const {
133 146
    std::map<std::string, int>::const_iterator it =
134 147
      _col_names_ref.find(name);
135 148
    if (it != _col_names_ref.end()) {
136 149
      return it->second;
137 150
    } else {
138 151
      return -1;
139 152
    }
140 153
  }
141 154

	
142 155
  void SoplexLp::_getRowName(int r, std::string &name) const {
143 156
    name = _row_names[r];
144 157
  }
145 158

	
146 159
  void SoplexLp::_setRowName(int r, const std::string &name) {
147 160
    _row_names_ref.erase(_row_names[r]);
148 161
    _row_names[r] = name;
149 162
    if (!name.empty()) {
150 163
      _row_names_ref.insert(std::make_pair(name, r));
151 164
    }
152 165
  }
153 166

	
154 167
  int SoplexLp::_rowByName(const std::string& name) const {
155 168
    std::map<std::string, int>::const_iterator it =
156 169
      _row_names_ref.find(name);
157 170
    if (it != _row_names_ref.end()) {
158 171
      return it->second;
159 172
    } else {
160 173
      return -1;
161 174
    }
162 175
  }
163 176

	
164 177

	
165 178
  void SoplexLp::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
166 179
    for (int j = 0; j < soplex->nCols(); ++j) {
167 180
      soplex->changeElement(i, j, 0.0);
168 181
    }
169 182
    for(ExprIterator it = b; it != e; ++it) {
170 183
      soplex->changeElement(i, it->first, it->second);
171 184
    }
172 185
  }
173 186

	
174 187
  void SoplexLp::_getRowCoeffs(int i, InsertIterator b) const {
175 188
    const soplex::SVector& vec = soplex->rowVector(i);
176 189
    for (int k = 0; k < vec.size(); ++k) {
177 190
      *b = std::make_pair(vec.index(k), vec.value(k));
178 191
      ++b;
179 192
    }
180 193
  }
181 194

	
182 195
  void SoplexLp::_setColCoeffs(int j, ExprIterator b, ExprIterator e) {
183 196
    for (int i = 0; i < soplex->nRows(); ++i) {
184 197
      soplex->changeElement(i, j, 0.0);
185 198
    }
186 199
    for(ExprIterator it = b; it != e; ++it) {
187 200
      soplex->changeElement(it->first, j, it->second);
188 201
    }
189 202
  }
190 203

	
191 204
  void SoplexLp::_getColCoeffs(int i, InsertIterator b) const {
192 205
    const soplex::SVector& vec = soplex->colVector(i);
193 206
    for (int k = 0; k < vec.size(); ++k) {
194 207
      *b = std::make_pair(vec.index(k), vec.value(k));
195 208
      ++b;
196 209
    }
197 210
  }
198 211

	
199 212
  void SoplexLp::_setCoeff(int i, int j, Value value) {
200 213
    soplex->changeElement(i, j, value);
201 214
  }
202 215

	
203 216
  SoplexLp::Value SoplexLp::_getCoeff(int i, int j) const {
204 217
    return soplex->rowVector(i)[j];
205 218
  }
206 219

	
207 220
  void SoplexLp::_setColLowerBound(int i, Value value) {
208 221
    LEMON_ASSERT(value != INF, "Invalid bound");
209 222
    soplex->changeLower(i, value != -INF ? value : -soplex::infinity);
210 223
  }
211 224

	
212 225
  SoplexLp::Value SoplexLp::_getColLowerBound(int i) const {
213 226
    double value = soplex->lower(i);
214 227
    return value != -soplex::infinity ? value : -INF;
215 228
  }
216 229

	
217 230
  void SoplexLp::_setColUpperBound(int i, Value value) {
218 231
    LEMON_ASSERT(value != -INF, "Invalid bound");
219 232
    soplex->changeUpper(i, value != INF ? value : soplex::infinity);
220 233
  }
221 234

	
222 235
  SoplexLp::Value SoplexLp::_getColUpperBound(int i) const {
223 236
    double value = soplex->upper(i);
224 237
    return value != soplex::infinity ? value : INF;
225 238
  }
226 239

	
227 240
  void SoplexLp::_setRowLowerBound(int i, Value lb) {
228 241
    LEMON_ASSERT(lb != INF, "Invalid bound");
229 242
    soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, soplex->rhs(i));
230 243
  }
231 244

	
232 245
  SoplexLp::Value SoplexLp::_getRowLowerBound(int i) const {
233 246
    double res = soplex->lhs(i);
234 247
    return res == -soplex::infinity ? -INF : res;
235 248
  }
236 249

	
237 250
  void SoplexLp::_setRowUpperBound(int i, Value ub) {
238 251
    LEMON_ASSERT(ub != -INF, "Invalid bound");
239 252
    soplex->changeRange(i, soplex->lhs(i), ub != INF ? ub : soplex::infinity);
240 253
  }
241 254

	
242 255
  SoplexLp::Value SoplexLp::_getRowUpperBound(int i) const {
243 256
    double res = soplex->rhs(i);
244 257
    return res == soplex::infinity ? INF : res;
245 258
  }
246 259

	
247 260
  void SoplexLp::_setObjCoeffs(ExprIterator b, ExprIterator e) {
248 261
    for (int j = 0; j < soplex->nCols(); ++j) {
249 262
      soplex->changeObj(j, 0.0);
250 263
    }
251 264
    for (ExprIterator it = b; it != e; ++it) {
252 265
      soplex->changeObj(it->first, it->second);
253 266
    }
254 267
  }
255 268

	
256 269
  void SoplexLp::_getObjCoeffs(InsertIterator b) const {
257 270
    for (int j = 0; j < soplex->nCols(); ++j) {
258 271
      Value coef = soplex->obj(j);
259 272
      if (coef != 0.0) {
260 273
        *b = std::make_pair(j, coef);
261 274
        ++b;
262 275
      }
263 276
    }
264 277
  }
265 278

	
266 279
  void SoplexLp::_setObjCoeff(int i, Value obj_coef) {
267 280
    soplex->changeObj(i, obj_coef);
268 281
  }
269 282

	
270 283
  SoplexLp::Value SoplexLp::_getObjCoeff(int i) const {
271 284
    return soplex->obj(i);
272 285
  }
273 286

	
274 287
  SoplexLp::SolveExitStatus SoplexLp::_solve() {
275 288

	
276 289
    _clear_temporals();
277
    
290

	
278 291
    _applyMessageLevel();
279 292

	
280 293
    soplex::SPxSolver::Status status = soplex->solve();
281 294

	
282 295
    switch (status) {
283 296
    case soplex::SPxSolver::OPTIMAL:
284 297
    case soplex::SPxSolver::INFEASIBLE:
285 298
    case soplex::SPxSolver::UNBOUNDED:
286 299
      return SOLVED;
287 300
    default:
288 301
      return UNSOLVED;
289 302
    }
290 303
  }
291 304

	
292 305
  SoplexLp::Value SoplexLp::_getPrimal(int i) const {
293 306
    if (_primal_values.empty()) {
294 307
      _primal_values.resize(soplex->nCols());
295 308
      soplex::Vector pv(_primal_values.size(), &_primal_values.front());
296 309
      soplex->getPrimal(pv);
297 310
    }
298 311
    return _primal_values[i];
299 312
  }
300 313

	
301 314
  SoplexLp::Value SoplexLp::_getDual(int i) const {
302 315
    if (_dual_values.empty()) {
303 316
      _dual_values.resize(soplex->nRows());
304 317
      soplex::Vector dv(_dual_values.size(), &_dual_values.front());
305 318
      soplex->getDual(dv);
306 319
    }
307 320
    return _dual_values[i];
308 321
  }
309 322

	
310 323
  SoplexLp::Value SoplexLp::_getPrimalValue() const {
311 324
    return soplex->objValue();
312 325
  }
313 326

	
314 327
  SoplexLp::VarStatus SoplexLp::_getColStatus(int i) const {
315 328
    switch (soplex->getBasisColStatus(i)) {
316 329
    case soplex::SPxSolver::BASIC:
317 330
      return BASIC;
318 331
    case soplex::SPxSolver::ON_UPPER:
319 332
      return UPPER;
320 333
    case soplex::SPxSolver::ON_LOWER:
321 334
      return LOWER;
322 335
    case soplex::SPxSolver::FIXED:
323 336
      return FIXED;
324 337
    case soplex::SPxSolver::ZERO:
325 338
      return FREE;
326 339
    default:
327 340
      LEMON_ASSERT(false, "Wrong column status");
328 341
      return VarStatus();
329 342
    }
330 343
  }
331 344

	
332 345
  SoplexLp::VarStatus SoplexLp::_getRowStatus(int i) const {
333 346
    switch (soplex->getBasisRowStatus(i)) {
334 347
    case soplex::SPxSolver::BASIC:
335 348
      return BASIC;
336 349
    case soplex::SPxSolver::ON_UPPER:
337 350
      return UPPER;
338 351
    case soplex::SPxSolver::ON_LOWER:
339 352
      return LOWER;
340 353
    case soplex::SPxSolver::FIXED:
341 354
      return FIXED;
342 355
    case soplex::SPxSolver::ZERO:
343 356
      return FREE;
344 357
    default:
345 358
      LEMON_ASSERT(false, "Wrong row status");
346 359
      return VarStatus();
347 360
    }
348 361
  }
349 362

	
350 363
  SoplexLp::Value SoplexLp::_getPrimalRay(int i) const {
351 364
    if (_primal_ray.empty()) {
352 365
      _primal_ray.resize(soplex->nCols());
353 366
      soplex::Vector pv(_primal_ray.size(), &_primal_ray.front());
354 367
      soplex->getDualfarkas(pv);
355 368
    }
356 369
    return _primal_ray[i];
357 370
  }
358 371

	
359 372
  SoplexLp::Value SoplexLp::_getDualRay(int i) const {
360 373
    if (_dual_ray.empty()) {
361 374
      _dual_ray.resize(soplex->nRows());
362 375
      soplex::Vector dv(_dual_ray.size(), &_dual_ray.front());
363 376
      soplex->getDualfarkas(dv);
364 377
    }
365 378
    return _dual_ray[i];
366 379
  }
367 380

	
368 381
  SoplexLp::ProblemType SoplexLp::_getPrimalType() const {
369 382
    switch (soplex->status()) {
370 383
    case soplex::SPxSolver::OPTIMAL:
371 384
      return OPTIMAL;
372 385
    case soplex::SPxSolver::UNBOUNDED:
373 386
      return UNBOUNDED;
374 387
    case soplex::SPxSolver::INFEASIBLE:
375 388
      return INFEASIBLE;
376 389
    default:
377 390
      return UNDEFINED;
378 391
    }
379 392
  }
380 393

	
381 394
  SoplexLp::ProblemType SoplexLp::_getDualType() const {
382 395
    switch (soplex->status()) {
383 396
    case soplex::SPxSolver::OPTIMAL:
384 397
      return OPTIMAL;
385 398
    case soplex::SPxSolver::UNBOUNDED:
386 399
      return UNBOUNDED;
387 400
    case soplex::SPxSolver::INFEASIBLE:
388 401
      return INFEASIBLE;
389 402
    default:
390 403
      return UNDEFINED;
391 404
    }
392 405
  }
393 406

	
394 407
  void SoplexLp::_setSense(Sense sense) {
395 408
    switch (sense) {
396 409
    case MIN:
397 410
      soplex->changeSense(soplex::SPxSolver::MINIMIZE);
398 411
      break;
399 412
    case MAX:
400 413
      soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
401 414
    }
402 415
  }
403 416

	
404 417
  SoplexLp::Sense SoplexLp::_getSense() const {
405 418
    switch (soplex->spxSense()) {
406 419
    case soplex::SPxSolver::MAXIMIZE:
407 420
      return MAX;
408 421
    case soplex::SPxSolver::MINIMIZE:
409 422
      return MIN;
410 423
    default:
411 424
      LEMON_ASSERT(false, "Wrong sense.");
412 425
      return SoplexLp::Sense();
413 426
    }
414 427
  }
415 428

	
416 429
  void SoplexLp::_clear() {
417 430
    soplex->clear();
418 431
    _col_names.clear();
419 432
    _col_names_ref.clear();
420 433
    _row_names.clear();
421 434
    _row_names_ref.clear();
422 435
    cols.clear();
423 436
    rows.clear();
424 437
    _clear_temporals();
425 438
  }
426 439

	
427 440
  void SoplexLp::_messageLevel(MessageLevel level) {
428 441
    switch (level) {
429 442
    case MESSAGE_NOTHING:
430 443
      _message_level = -1;
431 444
      break;
432 445
    case MESSAGE_ERROR:
433 446
      _message_level = soplex::SPxOut::ERROR;
434 447
      break;
435 448
    case MESSAGE_WARNING:
436 449
      _message_level = soplex::SPxOut::WARNING;
437 450
      break;
438 451
    case MESSAGE_NORMAL:
439 452
      _message_level = soplex::SPxOut::INFO2;
440 453
      break;
441 454
    case MESSAGE_VERBOSE:
442 455
      _message_level = soplex::SPxOut::DEBUG;
443 456
      break;
444 457
    }
445 458
  }
446 459

	
447 460
  void SoplexLp::_applyMessageLevel() {
448 461
    soplex::Param::setVerbose(_message_level);
449 462
  }
450 463

	
451 464
} //namespace lemon
452 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-2010
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_SOPLEX_H
20 20
#define LEMON_SOPLEX_H
21 21

	
22 22
///\file
23 23
///\brief Header of the LEMON-SOPLEX lp solver interface.
24 24

	
25 25
#include <vector>
26 26
#include <string>
27 27

	
28 28
#include <lemon/lp_base.h>
29 29

	
30 30
// Forward declaration
31 31
namespace soplex {
32 32
  class SoPlex;
33 33
}
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  /// \ingroup lp_group
38 38
  ///
39 39
  /// \brief Interface for the SOPLEX solver
40 40
  ///
41 41
  /// This class implements an interface for the SoPlex LP solver.
42 42
  /// The SoPlex library is an object oriented lp solver library
43 43
  /// developed at the Konrad-Zuse-Zentrum f�r Informationstechnik
44 44
  /// Berlin (ZIB). You can find detailed information about it at the
45 45
  /// <tt>http://soplex.zib.de</tt> address.
46 46
  class SoplexLp : public LpSolver {
47 47
  private:
48 48

	
49 49
    soplex::SoPlex* soplex;
50 50

	
51 51
    std::vector<std::string> _col_names;
52 52
    std::map<std::string, int> _col_names_ref;
53 53

	
54 54
    std::vector<std::string> _row_names;
55 55
    std::map<std::string, int> _row_names_ref;
56 56

	
57 57
  private:
58 58

	
59 59
    // these values cannot be retrieved element by element
60 60
    mutable std::vector<Value> _primal_values;
61 61
    mutable std::vector<Value> _dual_values;
62 62

	
63 63
    mutable std::vector<Value> _primal_ray;
64 64
    mutable std::vector<Value> _dual_ray;
65 65

	
66 66
    void _clear_temporals();
67 67

	
68 68
  public:
69 69

	
70 70
    /// \e
71 71
    SoplexLp();
72 72
    /// \e
73 73
    SoplexLp(const SoplexLp&);
74 74
    /// \e
75 75
    ~SoplexLp();
76 76
    /// \e
77 77
    virtual SoplexLp* newSolver() const;
78 78
    /// \e
79 79
    virtual SoplexLp* cloneSolver() const;
80 80

	
81 81
  protected:
82 82

	
83 83
    virtual const char* _solverName() const;
84 84

	
85 85
    virtual int _addCol();
86 86
    virtual int _addRow();
87
    virtual int _addRow(Value l, ExprIterator b, ExprIterator e, Value u);
87 88

	
88 89
    virtual void _eraseCol(int i);
89 90
    virtual void _eraseRow(int i);
90 91

	
91 92
    virtual void _eraseColId(int i);
92 93
    virtual void _eraseRowId(int i);
93 94

	
94 95
    virtual void _getColName(int col, std::string& name) const;
95 96
    virtual void _setColName(int col, const std::string& name);
96 97
    virtual int _colByName(const std::string& name) const;
97 98

	
98 99
    virtual void _getRowName(int row, std::string& name) const;
99 100
    virtual void _setRowName(int row, const std::string& name);
100 101
    virtual int _rowByName(const std::string& name) const;
101 102

	
102 103
    virtual void _setRowCoeffs(int i, ExprIterator b, ExprIterator e);
103 104
    virtual void _getRowCoeffs(int i, InsertIterator b) const;
104 105

	
105 106
    virtual void _setColCoeffs(int i, ExprIterator b, ExprIterator e);
106 107
    virtual void _getColCoeffs(int i, InsertIterator b) const;
107 108

	
108 109
    virtual void _setCoeff(int row, int col, Value value);
109 110
    virtual Value _getCoeff(int row, int col) const;
110 111

	
111 112
    virtual void _setColLowerBound(int i, Value value);
112 113
    virtual Value _getColLowerBound(int i) const;
113 114
    virtual void _setColUpperBound(int i, Value value);
114 115
    virtual Value _getColUpperBound(int i) const;
115 116

	
116 117
    virtual void _setRowLowerBound(int i, Value value);
117 118
    virtual Value _getRowLowerBound(int i) const;
118 119
    virtual void _setRowUpperBound(int i, Value value);
119 120
    virtual Value _getRowUpperBound(int i) const;
120 121

	
121 122
    virtual void _setObjCoeffs(ExprIterator b, ExprIterator e);
122 123
    virtual void _getObjCoeffs(InsertIterator b) const;
123 124

	
124 125
    virtual void _setObjCoeff(int i, Value obj_coef);
125 126
    virtual Value _getObjCoeff(int i) const;
126 127

	
127 128
    virtual void _setSense(Sense sense);
128 129
    virtual Sense _getSense() const;
129 130

	
130 131
    virtual SolveExitStatus _solve();
131 132
    virtual Value _getPrimal(int i) const;
132 133
    virtual Value _getDual(int i) const;
133 134

	
134 135
    virtual Value _getPrimalValue() const;
135 136

	
136 137
    virtual Value _getPrimalRay(int i) const;
137 138
    virtual Value _getDualRay(int i) const;
138 139

	
139 140
    virtual VarStatus _getColStatus(int i) const;
140 141
    virtual VarStatus _getRowStatus(int i) const;
141 142

	
142 143
    virtual ProblemType _getPrimalType() const;
143 144
    virtual ProblemType _getDualType() const;
144 145

	
145 146
    virtual void _clear();
146 147

	
147 148
    void _messageLevel(MessageLevel m);
148 149
    void _applyMessageLevel();
149 150

	
150 151
    int _message_level;
151 152

	
152 153
  };
153 154

	
154 155
} //END OF NAMESPACE LEMON
155 156

	
156 157
#endif //LEMON_SOPLEX_H
157 158

	
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-2009
5
 * Copyright (C) 2003-2010
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_SUURBALLE_H
20 20
#define LEMON_SUURBALLE_H
21 21

	
22 22
///\ingroup shortest_path
23 23
///\file
24 24
///\brief An algorithm for finding arc-disjoint paths between two
25 25
/// nodes having minimum total length.
26 26

	
27 27
#include <vector>
28 28
#include <limits>
29 29
#include <lemon/bin_heap.h>
30 30
#include <lemon/path.h>
31 31
#include <lemon/list_graph.h>
32
#include <lemon/dijkstra.h>
32 33
#include <lemon/maps.h>
33 34

	
34 35
namespace lemon {
35 36

	
37
  /// \brief Default traits class of Suurballe algorithm.
38
  ///
39
  /// Default traits class of Suurballe algorithm.
40
  /// \tparam GR The digraph type the algorithm runs on.
41
  /// \tparam LEN The type of the length map.
42
  /// The default value is <tt>GR::ArcMap<int></tt>.
43
#ifdef DOXYGEN
44
  template <typename GR, typename LEN>
45
#else
46
  template < typename GR,
47
             typename LEN = typename GR::template ArcMap<int> >
48
#endif
49
  struct SuurballeDefaultTraits
50
  {
51
    /// The type of the digraph.
52
    typedef GR Digraph;
53
    /// The type of the length map.
54
    typedef LEN LengthMap;
55
    /// The type of the lengths.
56
    typedef typename LEN::Value Length;
57
    /// The type of the flow map.
58
    typedef typename GR::template ArcMap<int> FlowMap;
59
    /// The type of the potential map.
60
    typedef typename GR::template NodeMap<Length> PotentialMap;
61

	
62
    /// \brief The path type
63
    ///
64
    /// The type used for storing the found arc-disjoint paths.
65
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
66
    /// and it must have an \c addBack() function.
67
    typedef lemon::Path<Digraph> Path;
68

	
69
    /// The cross reference type used for the heap.
70
    typedef typename GR::template NodeMap<int> HeapCrossRef;
71

	
72
    /// \brief The heap type used for internal Dijkstra computations.
73
    ///
74
    /// The type of the heap used for internal Dijkstra computations.
75
    /// It must conform to the \ref lemon::concepts::Heap "Heap" concept
76
    /// and its priority type must be \c Length.
77
    typedef BinHeap<Length, HeapCrossRef> Heap;
78
  };
79

	
36 80
  /// \addtogroup shortest_path
37 81
  /// @{
38 82

	
39 83
  /// \brief Algorithm for finding arc-disjoint paths between two nodes
40 84
  /// having minimum total length.
41 85
  ///
42 86
  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
43 87
  /// finding arc-disjoint paths having minimum total length (cost)
44 88
  /// from a given source node to a given target node in a digraph.
45 89
  ///
46 90
  /// Note that this problem is a special case of the \ref min_cost_flow
47 91
  /// "minimum cost flow problem". This implementation is actually an
48 92
  /// efficient specialized version of the \ref CapacityScaling
49
  /// "Successive Shortest Path" algorithm directly for this problem.
93
  /// "successive shortest path" algorithm directly for this problem.
50 94
  /// Therefore this class provides query functions for flow values and
51 95
  /// node potentials (the dual solution) just like the minimum cost flow
52 96
  /// algorithms.
53 97
  ///
54 98
  /// \tparam GR The digraph type the algorithm runs on.
55 99
  /// \tparam LEN The type of the length map.
56 100
  /// The default value is <tt>GR::ArcMap<int></tt>.
57 101
  ///
58 102
  /// \warning Length values should be \e non-negative.
59 103
  ///
60
  /// \note For finding node-disjoint paths this algorithm can be used
104
  /// \note For finding \e node-disjoint paths, this algorithm can be used
61 105
  /// along with the \ref SplitNodes adaptor.
62 106
#ifdef DOXYGEN
63
  template <typename GR, typename LEN>
107
  template <typename GR, typename LEN, typename TR>
64 108
#else
65 109
  template < typename GR,
66
             typename LEN = typename GR::template ArcMap<int> >
110
             typename LEN = typename GR::template ArcMap<int>,
111
             typename TR = SuurballeDefaultTraits<GR, LEN> >
67 112
#endif
68 113
  class Suurballe
69 114
  {
70 115
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
71 116

	
72 117
    typedef ConstMap<Arc, int> ConstArcMap;
73 118
    typedef typename GR::template NodeMap<Arc> PredMap;
74 119

	
75 120
  public:
76 121

	
77
    /// The type of the digraph the algorithm runs on.
78
    typedef GR Digraph;
122
    /// The type of the digraph.
123
    typedef typename TR::Digraph Digraph;
79 124
    /// The type of the length map.
80
    typedef LEN LengthMap;
125
    typedef typename TR::LengthMap LengthMap;
81 126
    /// The type of the lengths.
82
    typedef typename LengthMap::Value Length;
83
#ifdef DOXYGEN
127
    typedef typename TR::Length Length;
128

	
84 129
    /// The type of the flow map.
85
    typedef GR::ArcMap<int> FlowMap;
130
    typedef typename TR::FlowMap FlowMap;
86 131
    /// 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
132
    typedef typename TR::PotentialMap PotentialMap;
133
    /// The type of the path structures.
134
    typedef typename TR::Path Path;
135
    /// The cross reference type used for the heap.
136
    typedef typename TR::HeapCrossRef HeapCrossRef;
137
    /// The heap type used for internal Dijkstra computations.
138
    typedef typename TR::Heap Heap;
94 139

	
95
    /// The type of the path structures.
96
    typedef SimplePath<GR> Path;
140
    /// The \ref SuurballeDefaultTraits "traits class" of the algorithm.
141
    typedef TR Traits;
97 142

	
98 143
  private:
99 144

	
100 145
    // ResidualDijkstra is a special implementation of the
101 146
    // Dijkstra algorithm for finding shortest paths in the
102 147
    // residual network with respect to the reduced arc lengths
103 148
    // and modifying the node potentials according to the
104 149
    // distance of the nodes.
105 150
    class ResidualDijkstra
106 151
    {
107
      typedef typename Digraph::template NodeMap<int> HeapCrossRef;
108
      typedef BinHeap<Length, HeapCrossRef> Heap;
152
    private:
153

	
154
      const Digraph &_graph;
155
      const LengthMap &_length;
156
      const FlowMap &_flow;
157
      PotentialMap &_pi;
158
      PredMap &_pred;
159
      Node _s;
160
      Node _t;
161

	
162
      PotentialMap _dist;
163
      std::vector<Node> _proc_nodes;
164

	
165
    public:
166

	
167
      // Constructor
168
      ResidualDijkstra(Suurballe &srb) :
169
        _graph(srb._graph), _length(srb._length),
170
        _flow(*srb._flow), _pi(*srb._potential), _pred(srb._pred),
171
        _s(srb._s), _t(srb._t), _dist(_graph) {}
172

	
173
      // Run the algorithm and return true if a path is found
174
      // from the source node to the target node.
175
      bool run(int cnt) {
176
        return cnt == 0 ? startFirst() : start();
177
      }
109 178

	
110 179
    private:
111 180

	
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() {
181
      // Execute the algorithm for the first time (the flow and potential
182
      // functions have to be identically zero).
183
      bool startFirst() {
145 184
        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
146 185
        Heap heap(heap_cross_ref);
147 186
        heap.push(_s, 0);
148 187
        _pred[_s] = INVALID;
149 188
        _proc_nodes.clear();
150 189

	
151 190
        // Process nodes
152 191
        while (!heap.empty() && heap.top() != _t) {
153 192
          Node u = heap.top(), v;
154
          Length d = heap.prio() + _potential[u], nd;
193
          Length d = heap.prio(), dn;
155 194
          _dist[u] = heap.prio();
195
          _proc_nodes.push_back(u);
156 196
          heap.pop();
197

	
198
          // Traverse outgoing arcs
199
          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
200
            v = _graph.target(e);
201
            switch(heap.state(v)) {
202
              case Heap::PRE_HEAP:
203
                heap.push(v, d + _length[e]);
204
                _pred[v] = e;
205
                break;
206
              case Heap::IN_HEAP:
207
                dn = d + _length[e];
208
                if (dn < heap[v]) {
209
                  heap.decrease(v, dn);
210
                  _pred[v] = e;
211
                }
212
                break;
213
              case Heap::POST_HEAP:
214
                break;
215
            }
216
          }
217
        }
218
        if (heap.empty()) return false;
219

	
220
        // Update potentials of processed nodes
221
        Length t_dist = heap.prio();
222
        for (int i = 0; i < int(_proc_nodes.size()); ++i)
223
          _pi[_proc_nodes[i]] = _dist[_proc_nodes[i]] - t_dist;
224
        return true;
225
      }
226

	
227
      // Execute the algorithm.
228
      bool start() {
229
        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
230
        Heap heap(heap_cross_ref);
231
        heap.push(_s, 0);
232
        _pred[_s] = INVALID;
233
        _proc_nodes.clear();
234

	
235
        // Process nodes
236
        while (!heap.empty() && heap.top() != _t) {
237
          Node u = heap.top(), v;
238
          Length d = heap.prio() + _pi[u], dn;
239
          _dist[u] = heap.prio();
157 240
          _proc_nodes.push_back(u);
241
          heap.pop();
158 242

	
159 243
          // Traverse outgoing arcs
160 244
          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
161 245
            if (_flow[e] == 0) {
162 246
              v = _graph.target(e);
163 247
              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);
248
                case Heap::PRE_HEAP:
249
                  heap.push(v, d + _length[e] - _pi[v]);
172 250
                  _pred[v] = e;
173
                }
174
                break;
175
              case Heap::POST_HEAP:
176
                break;
251
                  break;
252
                case Heap::IN_HEAP:
253
                  dn = d + _length[e] - _pi[v];
254
                  if (dn < heap[v]) {
255
                    heap.decrease(v, dn);
256
                    _pred[v] = e;
257
                  }
258
                  break;
259
                case Heap::POST_HEAP:
260
                  break;
177 261
              }
178 262
            }
179 263
          }
180 264

	
181 265
          // Traverse incoming arcs
182 266
          for (InArcIt e(_graph, u); e != INVALID; ++e) {
183 267
            if (_flow[e] == 1) {
184 268
              v = _graph.source(e);
185 269
              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);
270
                case Heap::PRE_HEAP:
271
                  heap.push(v, d - _length[e] - _pi[v]);
194 272
                  _pred[v] = e;
195
                }
196
                break;
197
              case Heap::POST_HEAP:
198
                break;
273
                  break;
274
                case Heap::IN_HEAP:
275
                  dn = d - _length[e] - _pi[v];
276
                  if (dn < heap[v]) {
277
                    heap.decrease(v, dn);
278
                    _pred[v] = e;
279
                  }
280
                  break;
281
                case Heap::POST_HEAP:
282
                  break;
199 283
              }
200 284
            }
201 285
          }
202 286
        }
203 287
        if (heap.empty()) return false;
204 288

	
205 289
        // Update potentials of processed nodes
206 290
        Length t_dist = heap.prio();
207 291
        for (int i = 0; i < int(_proc_nodes.size()); ++i)
208
          _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
292
          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
209 293
        return true;
210 294
      }
211 295

	
212 296
    }; //class ResidualDijkstra
213 297

	
298
  public:
299

	
300
    /// \name Named Template Parameters
301
    /// @{
302

	
303
    template <typename T>
304
    struct SetFlowMapTraits : public Traits {
305
      typedef T FlowMap;
306
    };
307

	
308
    /// \brief \ref named-templ-param "Named parameter" for setting
309
    /// \c FlowMap type.
310
    ///
311
    /// \ref named-templ-param "Named parameter" for setting
312
    /// \c FlowMap type.
313
    template <typename T>
314
    struct SetFlowMap
315
      : public Suurballe<GR, LEN, SetFlowMapTraits<T> > {
316
      typedef Suurballe<GR, LEN, SetFlowMapTraits<T> > Create;
317
    };
318

	
319
    template <typename T>
320
    struct SetPotentialMapTraits : public Traits {
321
      typedef T PotentialMap;
322
    };
323

	
324
    /// \brief \ref named-templ-param "Named parameter" for setting
325
    /// \c PotentialMap type.
326
    ///
327
    /// \ref named-templ-param "Named parameter" for setting
328
    /// \c PotentialMap type.
329
    template <typename T>
330
    struct SetPotentialMap
331
      : public Suurballe<GR, LEN, SetPotentialMapTraits<T> > {
332
      typedef Suurballe<GR, LEN, SetPotentialMapTraits<T> > Create;
333
    };
334

	
335
    template <typename T>
336
    struct SetPathTraits : public Traits {
337
      typedef T Path;
338
    };
339

	
340
    /// \brief \ref named-templ-param "Named parameter" for setting
341
    /// \c %Path type.
342
    ///
343
    /// \ref named-templ-param "Named parameter" for setting \c %Path type.
344
    /// It must conform to the \ref lemon::concepts::Path "Path" concept
345
    /// and it must have an \c addBack() function.
346
    template <typename T>
347
    struct SetPath
348
      : public Suurballe<GR, LEN, SetPathTraits<T> > {
349
      typedef Suurballe<GR, LEN, SetPathTraits<T> > Create;
350
    };
351

	
352
    template <typename H, typename CR>
353
    struct SetHeapTraits : public Traits {
354
      typedef H Heap;
355
      typedef CR HeapCrossRef;
356
    };
357

	
358
    /// \brief \ref named-templ-param "Named parameter" for setting
359
    /// \c Heap and \c HeapCrossRef types.
360
    ///
361
    /// \ref named-templ-param "Named parameter" for setting \c Heap
362
    /// and \c HeapCrossRef types with automatic allocation.
363
    /// They will be used for internal Dijkstra computations.
364
    /// The heap type must conform to the \ref lemon::concepts::Heap "Heap"
365
    /// concept and its priority type must be \c Length.
366
    template <typename H,
367
              typename CR = typename Digraph::template NodeMap<int> >
368
    struct SetHeap
369
      : public Suurballe<GR, LEN, SetHeapTraits<H, CR> > {
370
      typedef Suurballe<GR, LEN, SetHeapTraits<H, CR> > Create;
371
    };
372

	
373
    /// @}
374

	
214 375
  private:
215 376

	
216 377
    // The digraph the algorithm runs on
217 378
    const Digraph &_graph;
218 379
    // The length map
219 380
    const LengthMap &_length;
220 381

	
221 382
    // Arc map of the current flow
222 383
    FlowMap *_flow;
223 384
    bool _local_flow;
224 385
    // Node map of the current potentials
225 386
    PotentialMap *_potential;
226 387
    bool _local_potential;
227 388

	
228 389
    // The source node
229
    Node _source;
390
    Node _s;
230 391
    // The target node
231
    Node _target;
392
    Node _t;
232 393

	
233 394
    // Container to store the found paths
234
    std::vector< SimplePath<Digraph> > paths;
395
    std::vector<Path> _paths;
235 396
    int _path_num;
236 397

	
237 398
    // The pred arc map
238 399
    PredMap _pred;
239
    // Implementation of the Dijkstra algorithm for finding augmenting
240
    // shortest paths in the residual network
241
    ResidualDijkstra *_dijkstra;
400

	
401
    // Data for full init
402
    PotentialMap *_init_dist;
403
    PredMap *_init_pred;
404
    bool _full_init;
405

	
406
  protected:
407

	
408
    Suurballe() {}
242 409

	
243 410
  public:
244 411

	
245 412
    /// \brief Constructor.
246 413
    ///
247 414
    /// Constructor.
248 415
    ///
249 416
    /// \param graph The digraph the algorithm runs on.
250 417
    /// \param length The length (cost) values of the arcs.
251 418
    Suurballe( const Digraph &graph,
252 419
               const LengthMap &length ) :
253 420
      _graph(graph), _length(length), _flow(0), _local_flow(false),
254
      _potential(0), _local_potential(false), _pred(graph)
421
      _potential(0), _local_potential(false), _pred(graph),
422
      _init_dist(0), _init_pred(0)
255 423
    {}
256 424

	
257 425
    /// Destructor.
258 426
    ~Suurballe() {
259 427
      if (_local_flow) delete _flow;
260 428
      if (_local_potential) delete _potential;
261
      delete _dijkstra;
429
      delete _init_dist;
430
      delete _init_pred;
262 431
    }
263 432

	
264 433
    /// \brief Set the flow map.
265 434
    ///
266 435
    /// This function sets the flow map.
267 436
    /// If it is not used before calling \ref run() or \ref init(),
268 437
    /// an instance will be allocated automatically. The destructor
269 438
    /// deallocates this automatically allocated map, of course.
270 439
    ///
271 440
    /// The found flow contains only 0 and 1 values, since it is the
272 441
    /// union of the found arc-disjoint paths.
273 442
    ///
274 443
    /// \return <tt>(*this)</tt>
275 444
    Suurballe& flowMap(FlowMap &map) {
276 445
      if (_local_flow) {
277 446
        delete _flow;
278 447
        _local_flow = false;
279 448
      }
280 449
      _flow = &map;
281 450
      return *this;
282 451
    }
283 452

	
284 453
    /// \brief Set the potential map.
285 454
    ///
286 455
    /// This function sets the potential map.
287 456
    /// If it is not used before calling \ref run() or \ref init(),
288 457
    /// an instance will be allocated automatically. The destructor
289 458
    /// deallocates this automatically allocated map, of course.
290 459
    ///
291 460
    /// The node potentials provide the dual solution of the underlying
292 461
    /// \ref min_cost_flow "minimum cost flow problem".
293 462
    ///
294 463
    /// \return <tt>(*this)</tt>
295 464
    Suurballe& potentialMap(PotentialMap &map) {
296 465
      if (_local_potential) {
297 466
        delete _potential;
298 467
        _local_potential = false;
299 468
      }
300 469
      _potential = &map;
301 470
      return *this;
302 471
    }
303 472

	
304 473
    /// \name Execution Control
305 474
    /// The simplest way to execute the algorithm is to call the run()
306
    /// function.
307
    /// \n
475
    /// function.\n
476
    /// If you need to execute the algorithm many times using the same
477
    /// source node, then you may call fullInit() once and start()
478
    /// for each target node.\n
308 479
    /// If you only need the flow that is the union of the found
309
    /// arc-disjoint paths, you may call init() and findFlow().
480
    /// arc-disjoint paths, then you may call findFlow() instead of
481
    /// start().
310 482

	
311 483
    /// @{
312 484

	
313 485
    /// \brief Run the algorithm.
314 486
    ///
315 487
    /// This function runs the algorithm.
316 488
    ///
317 489
    /// \param s The source node.
318 490
    /// \param t The target node.
319 491
    /// \param k The number of paths to be found.
320 492
    ///
321 493
    /// \return \c k if there are at least \c k arc-disjoint paths from
322 494
    /// \c s to \c t in the digraph. Otherwise it returns the number of
323 495
    /// arc-disjoint paths found.
324 496
    ///
325 497
    /// \note Apart from the return value, <tt>s.run(s, t, k)</tt> is
326 498
    /// just a shortcut of the following code.
327 499
    /// \code
328 500
    ///   s.init(s);
329
    ///   s.findFlow(t, k);
330
    ///   s.findPaths();
501
    ///   s.start(t, k);
331 502
    /// \endcode
332 503
    int run(const Node& s, const Node& t, int k = 2) {
333 504
      init(s);
334
      findFlow(t, k);
335
      findPaths();
505
      start(t, k);
336 506
      return _path_num;
337 507
    }
338 508

	
339 509
    /// \brief Initialize the algorithm.
340 510
    ///
341
    /// This function initializes the algorithm.
511
    /// This function initializes the algorithm with the given source node.
342 512
    ///
343 513
    /// \param s The source node.
344 514
    void init(const Node& s) {
345
      _source = s;
515
      _s = s;
346 516

	
347 517
      // Initialize maps
348 518
      if (!_flow) {
349 519
        _flow = new FlowMap(_graph);
350 520
        _local_flow = true;
351 521
      }
352 522
      if (!_potential) {
353 523
        _potential = new PotentialMap(_graph);
354 524
        _local_potential = true;
355 525
      }
356
      for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
357
      for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
526
      _full_init = false;
527
    }
528

	
529
    /// \brief Initialize the algorithm and perform Dijkstra.
530
    ///
531
    /// This function initializes the algorithm and performs a full
532
    /// Dijkstra search from the given source node. It makes consecutive
533
    /// executions of \ref start() "start(t, k)" faster, since they
534
    /// have to perform %Dijkstra only k-1 times.
535
    ///
536
    /// This initialization is usually worth using instead of \ref init()
537
    /// if the algorithm is executed many times using the same source node.
538
    ///
539
    /// \param s The source node.
540
    void fullInit(const Node& s) {
541
      // Initialize maps
542
      init(s);
543
      if (!_init_dist) {
544
        _init_dist = new PotentialMap(_graph);
545
      }
546
      if (!_init_pred) {
547
        _init_pred = new PredMap(_graph);
548
      }
549

	
550
      // Run a full Dijkstra
551
      typename Dijkstra<Digraph, LengthMap>
552
        ::template SetStandardHeap<Heap>
553
        ::template SetDistMap<PotentialMap>
554
        ::template SetPredMap<PredMap>
555
        ::Create dijk(_graph, _length);
556
      dijk.distMap(*_init_dist).predMap(*_init_pred);
557
      dijk.run(s);
558

	
559
      _full_init = true;
560
    }
561

	
562
    /// \brief Execute the algorithm.
563
    ///
564
    /// This function executes the algorithm.
565
    ///
566
    /// \param t The target node.
567
    /// \param k The number of paths to be found.
568
    ///
569
    /// \return \c k if there are at least \c k arc-disjoint paths from
570
    /// \c s to \c t in the digraph. Otherwise it returns the number of
571
    /// arc-disjoint paths found.
572
    ///
573
    /// \note Apart from the return value, <tt>s.start(t, k)</tt> is
574
    /// just a shortcut of the following code.
575
    /// \code
576
    ///   s.findFlow(t, k);
577
    ///   s.findPaths();
578
    /// \endcode
579
    int start(const Node& t, int k = 2) {
580
      findFlow(t, k);
581
      findPaths();
582
      return _path_num;
358 583
    }
359 584

	
360 585
    /// \brief Execute the algorithm to find an optimal flow.
361 586
    ///
362 587
    /// This function executes the successive shortest path algorithm to
363 588
    /// find a minimum cost flow, which is the union of \c k (or less)
364 589
    /// arc-disjoint paths.
365 590
    ///
366 591
    /// \param t The target node.
367 592
    /// \param k The number of paths to be found.
368 593
    ///
369 594
    /// \return \c k if there are at least \c k arc-disjoint paths from
370 595
    /// the source node to the given node \c t in the digraph.
371 596
    /// Otherwise it returns the number of arc-disjoint paths found.
372 597
    ///
373 598
    /// \pre \ref init() must be called before using this function.
374 599
    int findFlow(const Node& t, int k = 2) {
375
      _target = t;
376
      _dijkstra =
377
        new ResidualDijkstra( _graph, *_flow, _length, *_potential, _pred,
378
                              _source, _target );
600
      _t = t;
601
      ResidualDijkstra dijkstra(*this);
602

	
603
      // Initialization
604
      for (ArcIt e(_graph); e != INVALID; ++e) {
605
        (*_flow)[e] = 0;
606
      }
607
      if (_full_init) {
608
        for (NodeIt n(_graph); n != INVALID; ++n) {
609
          (*_potential)[n] = (*_init_dist)[n];
610
        }
611
        Node u = _t;
612
        Arc e;
613
        while ((e = (*_init_pred)[u]) != INVALID) {
614
          (*_flow)[e] = 1;
615
          u = _graph.source(e);
616
        }
617
        _path_num = 1;
618
      } else {
619
        for (NodeIt n(_graph); n != INVALID; ++n) {
620
          (*_potential)[n] = 0;
621
        }
622
        _path_num = 0;
623
      }
379 624

	
380 625
      // Find shortest paths
381
      _path_num = 0;
382 626
      while (_path_num < k) {
383 627
        // Run Dijkstra
384
        if (!_dijkstra->run()) break;
628
        if (!dijkstra.run(_path_num)) break;
385 629
        ++_path_num;
386 630

	
387 631
        // Set the flow along the found shortest path
388
        Node u = _target;
632
        Node u = _t;
389 633
        Arc e;
390 634
        while ((e = _pred[u]) != INVALID) {
391 635
          if (u == _graph.target(e)) {
392 636
            (*_flow)[e] = 1;
393 637
            u = _graph.source(e);
394 638
          } else {
395 639
            (*_flow)[e] = 0;
396 640
            u = _graph.target(e);
397 641
          }
398 642
        }
399 643
      }
400 644
      return _path_num;
401 645
    }
402 646

	
403 647
    /// \brief Compute the paths from the flow.
404 648
    ///
405
    /// This function computes the paths from the found minimum cost flow,
406
    /// which is the union of some arc-disjoint paths.
649
    /// This function computes arc-disjoint paths from the found minimum
650
    /// cost flow, which is the union of them.
407 651
    ///
408 652
    /// \pre \ref init() and \ref findFlow() must be called before using
409 653
    /// this function.
410 654
    void findPaths() {
411 655
      FlowMap res_flow(_graph);
412 656
      for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
413 657

	
414
      paths.clear();
415
      paths.resize(_path_num);
658
      _paths.clear();
659
      _paths.resize(_path_num);
416 660
      for (int i = 0; i < _path_num; ++i) {
417
        Node n = _source;
418
        while (n != _target) {
661
        Node n = _s;
662
        while (n != _t) {
419 663
          OutArcIt e(_graph, n);
420 664
          for ( ; res_flow[e] == 0; ++e) ;
421 665
          n = _graph.target(e);
422
          paths[i].addBack(e);
666
          _paths[i].addBack(e);
423 667
          res_flow[e] = 0;
424 668
        }
425 669
      }
426 670
    }
427 671

	
428 672
    /// @}
429 673

	
430 674
    /// \name Query Functions
431 675
    /// The results of the algorithm can be obtained using these
432 676
    /// functions.
433 677
    /// \n The algorithm should be executed before using them.
434 678

	
435 679
    /// @{
436 680

	
437 681
    /// \brief Return the total length of the found paths.
438 682
    ///
439 683
    /// This function returns the total length of the found paths, i.e.
440 684
    /// the total cost of the found flow.
441 685
    /// The complexity of the function is O(e).
442 686
    ///
443 687
    /// \pre \ref run() or \ref findFlow() must be called before using
444 688
    /// this function.
445 689
    Length totalLength() const {
446 690
      Length c = 0;
447 691
      for (ArcIt e(_graph); e != INVALID; ++e)
448 692
        c += (*_flow)[e] * _length[e];
449 693
      return c;
450 694
    }
451 695

	
452 696
    /// \brief Return the flow value on the given arc.
453 697
    ///
454 698
    /// This function returns the flow value on the given arc.
455 699
    /// It is \c 1 if the arc is involved in one of the found arc-disjoint
456 700
    /// paths, otherwise it is \c 0.
457 701
    ///
458 702
    /// \pre \ref run() or \ref findFlow() must be called before using
459 703
    /// this function.
460 704
    int flow(const Arc& arc) const {
461 705
      return (*_flow)[arc];
462 706
    }
463 707

	
464 708
    /// \brief Return a const reference to an arc map storing the
465 709
    /// found flow.
466 710
    ///
467 711
    /// This function returns a const reference to an arc map storing
468 712
    /// the flow that is the union of the found arc-disjoint paths.
469 713
    ///
470 714
    /// \pre \ref run() or \ref findFlow() must be called before using
471 715
    /// this function.
472 716
    const FlowMap& flowMap() const {
473 717
      return *_flow;
474 718
    }
475 719

	
476 720
    /// \brief Return the potential of the given node.
477 721
    ///
478 722
    /// This function returns the potential of the given node.
479 723
    /// The node potentials provide the dual solution of the
480 724
    /// underlying \ref min_cost_flow "minimum cost flow problem".
481 725
    ///
482 726
    /// \pre \ref run() or \ref findFlow() must be called before using
483 727
    /// this function.
484 728
    Length potential(const Node& node) const {
485 729
      return (*_potential)[node];
486 730
    }
487 731

	
488 732
    /// \brief Return a const reference to a node map storing the
489 733
    /// found potentials (the dual solution).
490 734
    ///
491 735
    /// This function returns a const reference to a node map storing
492 736
    /// the found potentials that provide the dual solution of the
493 737
    /// underlying \ref min_cost_flow "minimum cost flow problem".
494 738
    ///
495 739
    /// \pre \ref run() or \ref findFlow() must be called before using
496 740
    /// this function.
497 741
    const PotentialMap& potentialMap() const {
498 742
      return *_potential;
499 743
    }
500 744

	
501 745
    /// \brief Return the number of the found paths.
502 746
    ///
503 747
    /// This function returns the number of the found paths.
504 748
    ///
505 749
    /// \pre \ref run() or \ref findFlow() must be called before using
506 750
    /// this function.
507 751
    int pathNum() const {
508 752
      return _path_num;
509 753
    }
510 754

	
511 755
    /// \brief Return a const reference to the specified path.
512 756
    ///
513 757
    /// This function returns a const reference to the specified path.
514 758
    ///
515 759
    /// \param i The function returns the <tt>i</tt>-th path.
516 760
    /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
517 761
    ///
518 762
    /// \pre \ref run() or \ref findPaths() must be called before using
519 763
    /// this function.
520 764
    const Path& path(int i) const {
521
      return paths[i];
765
      return _paths[i];
522 766
    }
523 767

	
524 768
    /// @}
525 769

	
526 770
  }; //class Suurballe
527 771

	
528 772
  ///@}
529 773

	
530 774
} //namespace lemon
531 775

	
532 776
#endif //LEMON_SUURBALLE_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 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 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
    ///For example the timer
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 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-2009
5
 * Copyright (C) 2003-2010
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
  /// For more features see the \ref UnionFindEnum class.
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 54
  template <typename IM>
55 55
  class UnionFind {
56 56
  public:
57 57

	
58 58
    ///\e
59 59
    typedef IM ItemIntMap;
60 60
    ///\e
61 61
    typedef typename ItemIntMap::Key Item;
62 62

	
63 63
  private:
64 64
    // If the items vector stores negative value for an item then
65 65
    // that item is root item and it has -items[it] component size.
66 66
    // Else the items[it] contains the index of the parent.
67 67
    std::vector<int> items;
68 68
    ItemIntMap& index;
69 69

	
70 70
    bool rep(int idx) const {
71 71
      return items[idx] < 0;
72 72
    }
73 73

	
74 74
    int repIndex(int idx) const {
75 75
      int k = idx;
76 76
      while (!rep(k)) {
77 77
        k = items[k] ;
78 78
      }
79 79
      while (idx != k) {
80 80
        int next = items[idx];
81 81
        const_cast<int&>(items[idx]) = k;
82 82
        idx = next;
83 83
      }
84 84
      return k;
85 85
    }
86 86

	
87 87
  public:
88 88

	
89 89
    /// \brief Constructor
90 90
    ///
91 91
    /// Constructor of the UnionFind class. You should give an item to
92 92
    /// integer map which will be used from the data structure. If you
93 93
    /// modify directly this map that may cause segmentation fault,
94 94
    /// invalid data structure, or infinite loop when you use again
95 95
    /// the union-find.
96 96
    UnionFind(ItemIntMap& m) : index(m) {}
97 97

	
98 98
    /// \brief Returns the index of the element's component.
99 99
    ///
100 100
    /// The method returns the index of the element's component.
101 101
    /// This is an integer between zero and the number of inserted elements.
102 102
    ///
103 103
    int find(const Item& a) {
104 104
      return repIndex(index[a]);
105 105
    }
106 106

	
107 107
    /// \brief Clears the union-find data structure
108 108
    ///
109 109
    /// Erase each item from the data structure.
110 110
    void clear() {
111 111
      items.clear();
112 112
    }
113 113

	
114 114
    /// \brief Inserts a new element into the structure.
115 115
    ///
116 116
    /// This method inserts a new element into the data structure.
117 117
    ///
118 118
    /// The method returns the index of the new component.
119 119
    int insert(const Item& a) {
120 120
      int n = items.size();
121 121
      items.push_back(-1);
122 122
      index.set(a,n);
123 123
      return n;
124 124
    }
125 125

	
126 126
    /// \brief Joining the components of element \e a and element \e b.
127 127
    ///
128 128
    /// This is the \e union operation of the Union-Find structure.
129 129
    /// Joins the component of element \e a and component of
130 130
    /// element \e b. If \e a and \e b are in the same component then
131 131
    /// it returns false otherwise it returns true.
132 132
    bool join(const Item& a, const Item& b) {
133 133
      int ka = repIndex(index[a]);
134 134
      int kb = repIndex(index[b]);
135 135

	
136 136
      if ( ka == kb )
137 137
        return false;
138 138

	
139 139
      if (items[ka] < items[kb]) {
140 140
        items[ka] += items[kb];
141 141
        items[kb] = ka;
142 142
      } else {
143 143
        items[kb] += items[ka];
144 144
        items[ka] = kb;
145 145
      }
146 146
      return true;
147 147
    }
148 148

	
149 149
    /// \brief Returns the size of the component of element \e a.
150 150
    ///
151 151
    /// Returns the size of the component of element \e a.
152 152
    int size(const Item& a) {
153 153
      int k = repIndex(index[a]);
154 154
      return - items[k];
155 155
    }
156 156

	
157 157
  };
158 158

	
159 159
  /// \ingroup auxdat
160 160
  ///
161 161
  /// \brief A \e Union-Find data structure implementation which
162 162
  /// is able to enumerate the components.
163 163
  ///
164 164
  /// The class implements a \e Union-Find data structure
165 165
  /// which is able to enumerate the components and the items in
166 166
  /// a component. If you don't need this feature then perhaps it's
167 167
  /// better to use the \ref UnionFind class which is more efficient.
168 168
  ///
169 169
  /// The union operation uses rank heuristic, while
170 170
  /// the find operation uses path compression.
171 171
  ///
172 172
  /// \pre You need to add all the elements by the \ref insert()
173 173
  /// method.
174 174
  ///
175 175
  template <typename IM>
176 176
  class UnionFindEnum {
177 177
  public:
178 178

	
179 179
    ///\e
180 180
    typedef IM ItemIntMap;
181 181
    ///\e
182 182
    typedef typename ItemIntMap::Key Item;
183 183

	
184 184
  private:
185 185

	
186 186
    ItemIntMap& index;
187 187

	
188 188
    // If the parent stores negative value for an item then that item
189 189
    // is root item and it has ~(items[it].parent) component id.  Else
190 190
    // the items[it].parent contains the index of the parent.
191 191
    //
192 192
    // The \c next and \c prev provides the double-linked
193 193
    // cyclic list of one component's items.
194 194
    struct ItemT {
195 195
      int parent;
196 196
      Item item;
197 197

	
198 198
      int next, prev;
199 199
    };
200 200

	
201 201
    std::vector<ItemT> items;
202 202
    int firstFreeItem;
203 203

	
204 204
    struct ClassT {
205 205
      int size;
206 206
      int firstItem;
207 207
      int next, prev;
208 208
    };
209 209

	
210 210
    std::vector<ClassT> classes;
211 211
    int firstClass, firstFreeClass;
212 212

	
213 213
    int newClass() {
214 214
      if (firstFreeClass == -1) {
215 215
        int cdx = classes.size();
216 216
        classes.push_back(ClassT());
217 217
        return cdx;
218 218
      } else {
219 219
        int cdx = firstFreeClass;
220 220
        firstFreeClass = classes[firstFreeClass].next;
221 221
        return cdx;
222 222
      }
223 223
    }
224 224

	
225 225
    int newItem() {
226 226
      if (firstFreeItem == -1) {
227 227
        int idx = items.size();
228 228
        items.push_back(ItemT());
229 229
        return idx;
230 230
      } else {
231 231
        int idx = firstFreeItem;
232 232
        firstFreeItem = items[firstFreeItem].next;
233 233
        return idx;
234 234
      }
235 235
    }
236 236

	
237 237

	
238 238
    bool rep(int idx) const {
239 239
      return items[idx].parent < 0;
240 240
    }
241 241

	
242 242
    int repIndex(int idx) const {
243 243
      int k = idx;
244 244
      while (!rep(k)) {
245 245
        k = items[k].parent;
246 246
      }
247 247
      while (idx != k) {
248 248
        int next = items[idx].parent;
249 249
        const_cast<int&>(items[idx].parent) = k;
250 250
        idx = next;
251 251
      }
252 252
      return k;
253 253
    }
254 254

	
255 255
    int classIndex(int idx) const {
256 256
      return ~(items[repIndex(idx)].parent);
257 257
    }
258 258

	
259 259
    void singletonItem(int idx) {
260 260
      items[idx].next = idx;
261 261
      items[idx].prev = idx;
262 262
    }
263 263

	
264 264
    void laceItem(int idx, int rdx) {
265 265
      items[idx].prev = rdx;
266 266
      items[idx].next = items[rdx].next;
267 267
      items[items[rdx].next].prev = idx;
268 268
      items[rdx].next = idx;
269 269
    }
270 270

	
271 271
    void unlaceItem(int idx) {
272 272
      items[items[idx].prev].next = items[idx].next;
273 273
      items[items[idx].next].prev = items[idx].prev;
274 274

	
275 275
      items[idx].next = firstFreeItem;
276 276
      firstFreeItem = idx;
277 277
    }
278 278

	
279 279
    void spliceItems(int ak, int bk) {
280 280
      items[items[ak].prev].next = bk;
281 281
      items[items[bk].prev].next = ak;
282 282
      int tmp = items[ak].prev;
283 283
      items[ak].prev = items[bk].prev;
284 284
      items[bk].prev = tmp;
285 285

	
286 286
    }
287 287

	
288 288
    void laceClass(int cls) {
289 289
      if (firstClass != -1) {
290 290
        classes[firstClass].prev = cls;
291 291
      }
292 292
      classes[cls].next = firstClass;
293 293
      classes[cls].prev = -1;
294 294
      firstClass = cls;
295 295
    }
296 296

	
297 297
    void unlaceClass(int cls) {
298 298
      if (classes[cls].prev != -1) {
299 299
        classes[classes[cls].prev].next = classes[cls].next;
300 300
      } else {
301 301
        firstClass = classes[cls].next;
302 302
      }
303 303
      if (classes[cls].next != -1) {
304 304
        classes[classes[cls].next].prev = classes[cls].prev;
305 305
      }
306 306

	
307 307
      classes[cls].next = firstFreeClass;
308 308
      firstFreeClass = cls;
309 309
    }
310 310

	
311 311
  public:
312 312

	
313 313
    UnionFindEnum(ItemIntMap& _index)
314 314
      : index(_index), items(), firstFreeItem(-1),
315 315
        firstClass(-1), firstFreeClass(-1) {}
316 316

	
317 317
    /// \brief Inserts the given element into a new component.
318 318
    ///
319 319
    /// This method creates a new component consisting only of the
320 320
    /// given element.
321 321
    ///
322 322
    int insert(const Item& item) {
323 323
      int idx = newItem();
324 324

	
325 325
      index.set(item, idx);
326 326

	
327 327
      singletonItem(idx);
328 328
      items[idx].item = item;
329 329

	
330 330
      int cdx = newClass();
331 331

	
332 332
      items[idx].parent = ~cdx;
333 333

	
334 334
      laceClass(cdx);
335 335
      classes[cdx].size = 1;
336 336
      classes[cdx].firstItem = idx;
337 337

	
338 338
      firstClass = cdx;
339 339

	
340 340
      return cdx;
341 341
    }
342 342

	
343 343
    /// \brief Inserts the given element into the component of the others.
344 344
    ///
345 345
    /// This methods inserts the element \e a into the component of the
346 346
    /// element \e comp.
347 347
    void insert(const Item& item, int cls) {
348 348
      int rdx = classes[cls].firstItem;
349 349
      int idx = newItem();
350 350

	
351 351
      index.set(item, idx);
352 352

	
353 353
      laceItem(idx, rdx);
354 354

	
355 355
      items[idx].item = item;
356 356
      items[idx].parent = rdx;
357 357

	
358 358
      ++classes[~(items[rdx].parent)].size;
359 359
    }
360 360

	
361 361
    /// \brief Clears the union-find data structure
362 362
    ///
363 363
    /// Erase each item from the data structure.
364 364
    void clear() {
365 365
      items.clear();
366 366
      firstClass = -1;
367 367
      firstFreeItem = -1;
368 368
    }
369 369

	
370 370
    /// \brief Finds the component of the given element.
371 371
    ///
372 372
    /// The method returns the component id of the given element.
373 373
    int find(const Item &item) const {
374 374
      return ~(items[repIndex(index[item])].parent);
375 375
    }
376 376

	
377 377
    /// \brief Joining the component of element \e a and element \e b.
378 378
    ///
379 379
    /// This is the \e union operation of the Union-Find structure.
380 380
    /// Joins the component of element \e a and component of
381 381
    /// element \e b. If \e a and \e b are in the same component then
382 382
    /// returns -1 else returns the remaining class.
383 383
    int join(const Item& a, const Item& b) {
384 384

	
385 385
      int ak = repIndex(index[a]);
386 386
      int bk = repIndex(index[b]);
387 387

	
388 388
      if (ak == bk) {
389 389
        return -1;
390 390
      }
391 391

	
392 392
      int acx = ~(items[ak].parent);
393 393
      int bcx = ~(items[bk].parent);
394 394

	
395 395
      int rcx;
396 396

	
397 397
      if (classes[acx].size > classes[bcx].size) {
398 398
        classes[acx].size += classes[bcx].size;
399 399
        items[bk].parent = ak;
400 400
        unlaceClass(bcx);
401 401
        rcx = acx;
402 402
      } else {
403 403
        classes[bcx].size += classes[acx].size;
404 404
        items[ak].parent = bk;
405 405
        unlaceClass(acx);
406 406
        rcx = bcx;
407 407
      }
408 408
      spliceItems(ak, bk);
409 409

	
410 410
      return rcx;
411 411
    }
412 412

	
413 413
    /// \brief Returns the size of the class.
414 414
    ///
415 415
    /// Returns the size of the class.
416 416
    int size(int cls) const {
417 417
      return classes[cls].size;
418 418
    }
419 419

	
420 420
    /// \brief Splits up the component.
421 421
    ///
422 422
    /// Splitting the component into singleton components (component
423 423
    /// of size one).
424 424
    void split(int cls) {
425 425
      int fdx = classes[cls].firstItem;
426 426
      int idx = items[fdx].next;
427 427
      while (idx != fdx) {
428 428
        int next = items[idx].next;
429 429

	
430 430
        singletonItem(idx);
431 431

	
432 432
        int cdx = newClass();
433 433
        items[idx].parent = ~cdx;
434 434

	
435 435
        laceClass(cdx);
436 436
        classes[cdx].size = 1;
437 437
        classes[cdx].firstItem = idx;
438 438

	
439 439
        idx = next;
440 440
      }
441 441

	
442 442
      items[idx].prev = idx;
443 443
      items[idx].next = idx;
444 444

	
445 445
      classes[~(items[idx].parent)].size = 1;
446 446

	
447 447
    }
448 448

	
449 449
    /// \brief Removes the given element from the structure.
450 450
    ///
451 451
    /// Removes the element from its component and if the component becomes
452 452
    /// empty then removes that component from the component list.
453 453
    ///
454 454
    /// \warning It is an error to remove an element which is not in
455 455
    /// the structure.
456 456
    /// \warning This running time of this operation is proportional to the
457 457
    /// number of the items in this class.
458 458
    void erase(const Item& item) {
459 459
      int idx = index[item];
460 460
      int fdx = items[idx].next;
461 461

	
462 462
      int cdx = classIndex(idx);
463 463
      if (idx == fdx) {
464 464
        unlaceClass(cdx);
465 465
        items[idx].next = firstFreeItem;
466 466
        firstFreeItem = idx;
467 467
        return;
468 468
      } else {
469 469
        classes[cdx].firstItem = fdx;
470 470
        --classes[cdx].size;
471 471
        items[fdx].parent = ~cdx;
472 472

	
473 473
        unlaceItem(idx);
474 474
        idx = items[fdx].next;
475 475
        while (idx != fdx) {
476 476
          items[idx].parent = fdx;
477 477
          idx = items[idx].next;
478 478
        }
479 479

	
480 480
      }
481 481

	
482 482
    }
483 483

	
484 484
    /// \brief Gives back a representant item of the component.
485 485
    ///
486 486
    /// Gives back a representant item of the component.
487 487
    Item item(int cls) const {
488 488
      return items[classes[cls].firstItem].item;
489 489
    }
490 490

	
491 491
    /// \brief Removes the component of the given element from the structure.
492 492
    ///
493 493
    /// Removes the component of the given element from the structure.
494 494
    ///
495 495
    /// \warning It is an error to give an element which is not in the
496 496
    /// structure.
497 497
    void eraseClass(int cls) {
498 498
      int fdx = classes[cls].firstItem;
499 499
      unlaceClass(cls);
500 500
      items[items[fdx].prev].next = firstFreeItem;
501 501
      firstFreeItem = fdx;
502 502
    }
503 503

	
504 504
    /// \brief LEMON style iterator for the representant items.
505 505
    ///
506 506
    /// ClassIt is a lemon style iterator for the components. It iterates
507 507
    /// on the ids of the classes.
508 508
    class ClassIt {
509 509
    public:
510 510
      /// \brief Constructor of the iterator
511 511
      ///
512 512
      /// Constructor of the iterator
513 513
      ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) {
514 514
        cdx = unionFind->firstClass;
515 515
      }
516 516

	
517 517
      /// \brief Constructor to get invalid iterator
518 518
      ///
519 519
      /// Constructor to get invalid iterator
520 520
      ClassIt(Invalid) : unionFind(0), cdx(-1) {}
521 521

	
522 522
      /// \brief Increment operator
523 523
      ///
524 524
      /// It steps to the next representant item.
525 525
      ClassIt& operator++() {
526 526
        cdx = unionFind->classes[cdx].next;
527 527
        return *this;
528 528
      }
529 529

	
530 530
      /// \brief Conversion operator
531 531
      ///
532 532
      /// It converts the iterator to the current representant item.
533 533
      operator int() const {
534 534
        return cdx;
535 535
      }
536 536

	
537 537
      /// \brief Equality operator
538 538
      ///
539 539
      /// Equality operator
540 540
      bool operator==(const ClassIt& i) {
541 541
        return i.cdx == cdx;
542 542
      }
543 543

	
544 544
      /// \brief Inequality operator
545 545
      ///
546 546
      /// Inequality operator
547 547
      bool operator!=(const ClassIt& i) {
548 548
        return i.cdx != cdx;
549 549
      }
550 550

	
551 551
    private:
552 552
      const UnionFindEnum* unionFind;
553 553
      int cdx;
554 554
    };
555 555

	
556 556
    /// \brief LEMON style iterator for the items of a component.
557 557
    ///
558 558
    /// ClassIt is a lemon style iterator for the components. It iterates
559 559
    /// on the items of a class. By example if you want to iterate on
560 560
    /// each items of each classes then you may write the next code.
561 561
    ///\code
562 562
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
563 563
    ///   std::cout << "Class: ";
564 564
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
565 565
    ///     std::cout << toString(iit) << ' ' << std::endl;
566 566
    ///   }
567 567
    ///   std::cout << std::endl;
568 568
    /// }
569 569
    ///\endcode
570 570
    class ItemIt {
571 571
    public:
572 572
      /// \brief Constructor of the iterator
573 573
      ///
574 574
      /// Constructor of the iterator. The iterator iterates
575 575
      /// on the class of the \c item.
576 576
      ItemIt(const UnionFindEnum& ufe, int cls) : unionFind(&ufe) {
577 577
        fdx = idx = unionFind->classes[cls].firstItem;
578 578
      }
579 579

	
580 580
      /// \brief Constructor to get invalid iterator
581 581
      ///
582 582
      /// Constructor to get invalid iterator
583 583
      ItemIt(Invalid) : unionFind(0), idx(-1) {}
584 584

	
585 585
      /// \brief Increment operator
586 586
      ///
587 587
      /// It steps to the next item in the class.
588 588
      ItemIt& operator++() {
589 589
        idx = unionFind->items[idx].next;
590 590
        if (idx == fdx) idx = -1;
591 591
        return *this;
592 592
      }
593 593

	
594 594
      /// \brief Conversion operator
595 595
      ///
596 596
      /// It converts the iterator to the current item.
597 597
      operator const Item&() const {
598 598
        return unionFind->items[idx].item;
599 599
      }
600 600

	
601 601
      /// \brief Equality operator
602 602
      ///
603 603
      /// Equality operator
604 604
      bool operator==(const ItemIt& i) {
605 605
        return i.idx == idx;
606 606
      }
607 607

	
608 608
      /// \brief Inequality operator
609 609
      ///
610 610
      /// Inequality operator
611 611
      bool operator!=(const ItemIt& i) {
612 612
        return i.idx != idx;
613 613
      }
614 614

	
615 615
    private:
616 616
      const UnionFindEnum* unionFind;
617 617
      int idx, fdx;
618 618
    };
619 619

	
620 620
  };
621 621

	
622 622
  /// \ingroup auxdat
623 623
  ///
624 624
  /// \brief A \e Extend-Find data structure implementation which
625 625
  /// is able to enumerate the components.
626 626
  ///
627 627
  /// The class implements an \e Extend-Find data structure which is
628 628
  /// able to enumerate the components and the items in a
629 629
  /// component. The data structure is a simplification of the
630 630
  /// Union-Find structure, and it does not allow to merge two components.
631 631
  ///
632 632
  /// \pre You need to add all the elements by the \ref insert()
633 633
  /// method.
634 634
  template <typename IM>
635 635
  class ExtendFindEnum {
636 636
  public:
637 637

	
638 638
    ///\e
639 639
    typedef IM ItemIntMap;
640 640
    ///\e
641 641
    typedef typename ItemIntMap::Key Item;
642 642

	
643 643
  private:
644 644

	
645 645
    ItemIntMap& index;
646 646

	
647 647
    struct ItemT {
648 648
      int cls;
649 649
      Item item;
650 650
      int next, prev;
651 651
    };
652 652

	
653 653
    std::vector<ItemT> items;
654 654
    int firstFreeItem;
655 655

	
656 656
    struct ClassT {
657 657
      int firstItem;
658 658
      int next, prev;
659 659
    };
660 660

	
661 661
    std::vector<ClassT> classes;
662 662

	
663 663
    int firstClass, firstFreeClass;
664 664

	
665 665
    int newClass() {
666 666
      if (firstFreeClass != -1) {
667 667
        int cdx = firstFreeClass;
668 668
        firstFreeClass = classes[cdx].next;
669 669
        return cdx;
670 670
      } else {
671 671
        classes.push_back(ClassT());
672 672
        return classes.size() - 1;
673 673
      }
674 674
    }
675 675

	
676 676
    int newItem() {
677 677
      if (firstFreeItem != -1) {
678 678
        int idx = firstFreeItem;
679 679
        firstFreeItem = items[idx].next;
680 680
        return idx;
681 681
      } else {
682 682
        items.push_back(ItemT());
683 683
        return items.size() - 1;
684 684
      }
685 685
    }
686 686

	
687 687
  public:
688 688

	
689 689
    /// \brief Constructor
690 690
    ExtendFindEnum(ItemIntMap& _index)
691 691
      : index(_index), items(), firstFreeItem(-1),
692 692
        classes(), firstClass(-1), firstFreeClass(-1) {}
693 693

	
694 694
    /// \brief Inserts the given element into a new component.
695 695
    ///
696 696
    /// This method creates a new component consisting only of the
697 697
    /// given element.
698 698
    int insert(const Item& item) {
699 699
      int cdx = newClass();
700 700
      classes[cdx].prev = -1;
701 701
      classes[cdx].next = firstClass;
702 702
      if (firstClass != -1) {
703 703
        classes[firstClass].prev = cdx;
704 704
      }
705 705
      firstClass = cdx;
706 706

	
707 707
      int idx = newItem();
708 708
      items[idx].item = item;
709 709
      items[idx].cls = cdx;
710 710
      items[idx].prev = idx;
711 711
      items[idx].next = idx;
712 712

	
713 713
      classes[cdx].firstItem = idx;
714 714

	
715 715
      index.set(item, idx);
716 716

	
717 717
      return cdx;
718 718
    }
719 719

	
720 720
    /// \brief Inserts the given element into the given component.
721 721
    ///
722 722
    /// This methods inserts the element \e item a into the \e cls class.
723 723
    void insert(const Item& item, int cls) {
724 724
      int idx = newItem();
725 725
      int rdx = classes[cls].firstItem;
726 726
      items[idx].item = item;
727 727
      items[idx].cls = cls;
728 728

	
729 729
      items[idx].prev = rdx;
730 730
      items[idx].next = items[rdx].next;
731 731
      items[items[rdx].next].prev = idx;
732 732
      items[rdx].next = idx;
733 733

	
734 734
      index.set(item, idx);
735 735
    }
736 736

	
737 737
    /// \brief Clears the union-find data structure
738 738
    ///
739 739
    /// Erase each item from the data structure.
740 740
    void clear() {
741 741
      items.clear();
742 742
      classes.clear();
743 743
      firstClass = firstFreeClass = firstFreeItem = -1;
744 744
    }
745 745

	
746 746
    /// \brief Gives back the class of the \e item.
747 747
    ///
748 748
    /// Gives back the class of the \e item.
749 749
    int find(const Item &item) const {
750 750
      return items[index[item]].cls;
751 751
    }
752 752

	
753 753
    /// \brief Gives back a representant item of the component.
754 754
    ///
755 755
    /// Gives back a representant item of the component.
756 756
    Item item(int cls) const {
757 757
      return items[classes[cls].firstItem].item;
758 758
    }
759 759

	
760 760
    /// \brief Removes the given element from the structure.
761 761
    ///
762 762
    /// Removes the element from its component and if the component becomes
763 763
    /// empty then removes that component from the component list.
764 764
    ///
765 765
    /// \warning It is an error to remove an element which is not in
766 766
    /// the structure.
767 767
    void erase(const Item &item) {
768 768
      int idx = index[item];
769 769
      int cdx = items[idx].cls;
770 770

	
771 771
      if (idx == items[idx].next) {
772 772
        if (classes[cdx].prev != -1) {
773 773
          classes[classes[cdx].prev].next = classes[cdx].next;
774 774
        } else {
775 775
          firstClass = classes[cdx].next;
776 776
        }
777 777
        if (classes[cdx].next != -1) {
778 778
          classes[classes[cdx].next].prev = classes[cdx].prev;
779 779
        }
780 780
        classes[cdx].next = firstFreeClass;
781 781
        firstFreeClass = cdx;
782 782
      } else {
783 783
        classes[cdx].firstItem = items[idx].next;
784 784
        items[items[idx].next].prev = items[idx].prev;
785 785
        items[items[idx].prev].next = items[idx].next;
786 786
      }
787 787
      items[idx].next = firstFreeItem;
788 788
      firstFreeItem = idx;
789 789

	
790 790
    }
791 791

	
792 792

	
793 793
    /// \brief Removes the component of the given element from the structure.
794 794
    ///
795 795
    /// Removes the component of the given element from the structure.
796 796
    ///
797 797
    /// \warning It is an error to give an element which is not in the
798 798
    /// structure.
799 799
    void eraseClass(int cdx) {
800 800
      int idx = classes[cdx].firstItem;
801 801
      items[items[idx].prev].next = firstFreeItem;
802 802
      firstFreeItem = idx;
803 803

	
804 804
      if (classes[cdx].prev != -1) {
805 805
        classes[classes[cdx].prev].next = classes[cdx].next;
806 806
      } else {
807 807
        firstClass = classes[cdx].next;
808 808
      }
809 809
      if (classes[cdx].next != -1) {
810 810
        classes[classes[cdx].next].prev = classes[cdx].prev;
811 811
      }
812 812
      classes[cdx].next = firstFreeClass;
813 813
      firstFreeClass = cdx;
814 814
    }
815 815

	
816 816
    /// \brief LEMON style iterator for the classes.
817 817
    ///
818 818
    /// ClassIt is a lemon style iterator for the components. It iterates
819 819
    /// on the ids of classes.
820 820
    class ClassIt {
821 821
    public:
822 822
      /// \brief Constructor of the iterator
823 823
      ///
824 824
      /// Constructor of the iterator
825 825
      ClassIt(const ExtendFindEnum& ufe) : extendFind(&ufe) {
826 826
        cdx = extendFind->firstClass;
827 827
      }
828 828

	
829 829
      /// \brief Constructor to get invalid iterator
830 830
      ///
831 831
      /// Constructor to get invalid iterator
832 832
      ClassIt(Invalid) : extendFind(0), cdx(-1) {}
833 833

	
834 834
      /// \brief Increment operator
835 835
      ///
836 836
      /// It steps to the next representant item.
837 837
      ClassIt& operator++() {
838 838
        cdx = extendFind->classes[cdx].next;
839 839
        return *this;
840 840
      }
841 841

	
842 842
      /// \brief Conversion operator
843 843
      ///
844 844
      /// It converts the iterator to the current class id.
845 845
      operator int() const {
846 846
        return cdx;
847 847
      }
848 848

	
849 849
      /// \brief Equality operator
850 850
      ///
851 851
      /// Equality operator
852 852
      bool operator==(const ClassIt& i) {
853 853
        return i.cdx == cdx;
854 854
      }
855 855

	
856 856
      /// \brief Inequality operator
857 857
      ///
858 858
      /// Inequality operator
859 859
      bool operator!=(const ClassIt& i) {
860 860
        return i.cdx != cdx;
861 861
      }
862 862

	
863 863
    private:
864 864
      const ExtendFindEnum* extendFind;
865 865
      int cdx;
866 866
    };
867 867

	
868 868
    /// \brief LEMON style iterator for the items of a component.
869 869
    ///
870 870
    /// ClassIt is a lemon style iterator for the components. It iterates
871 871
    /// on the items of a class. By example if you want to iterate on
872 872
    /// each items of each classes then you may write the next code.
873 873
    ///\code
874 874
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
875 875
    ///   std::cout << "Class: ";
876 876
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
877 877
    ///     std::cout << toString(iit) << ' ' << std::endl;
878 878
    ///   }
879 879
    ///   std::cout << std::endl;
880 880
    /// }
881 881
    ///\endcode
882 882
    class ItemIt {
883 883
    public:
884 884
      /// \brief Constructor of the iterator
885 885
      ///
886 886
      /// Constructor of the iterator. The iterator iterates
887 887
      /// on the class of the \c item.
888 888
      ItemIt(const ExtendFindEnum& ufe, int cls) : extendFind(&ufe) {
889 889
        fdx = idx = extendFind->classes[cls].firstItem;
890 890
      }
891 891

	
892 892
      /// \brief Constructor to get invalid iterator
893 893
      ///
894 894
      /// Constructor to get invalid iterator
895 895
      ItemIt(Invalid) : extendFind(0), idx(-1) {}
896 896

	
897 897
      /// \brief Increment operator
898 898
      ///
899 899
      /// It steps to the next item in the class.
900 900
      ItemIt& operator++() {
901 901
        idx = extendFind->items[idx].next;
902 902
        if (fdx == idx) idx = -1;
903 903
        return *this;
904 904
      }
905 905

	
906 906
      /// \brief Conversion operator
907 907
      ///
908 908
      /// It converts the iterator to the current item.
909 909
      operator const Item&() const {
910 910
        return extendFind->items[idx].item;
911 911
      }
912 912

	
913 913
      /// \brief Equality operator
914 914
      ///
915 915
      /// Equality operator
916 916
      bool operator==(const ItemIt& i) {
917 917
        return i.idx == idx;
918 918
      }
919 919

	
920 920
      /// \brief Inequality operator
921 921
      ///
922 922
      /// Inequality operator
923 923
      bool operator!=(const ItemIt& i) {
924 924
        return i.idx != idx;
925 925
      }
926 926

	
927 927
    private:
928 928
      const ExtendFindEnum* extendFind;
929 929
      int idx, fdx;
930 930
    };
931 931

	
932 932
  };
933 933

	
934 934
  /// \ingroup auxdat
935 935
  ///
936 936
  /// \brief A \e Union-Find data structure implementation which
937 937
  /// is able to store a priority for each item and retrieve the minimum of
938 938
  /// each class.
939 939
  ///
940 940
  /// A \e Union-Find data structure implementation which is able to
941 941
  /// store a priority for each item and retrieve the minimum of each
942 942
  /// class. In addition, it supports the joining and splitting the
943 943
  /// components. If you don't need this feature then you makes
944 944
  /// better to use the \ref UnionFind class which is more efficient.
945 945
  ///
946 946
  /// The union-find data strcuture based on a (2, 16)-tree with a
947 947
  /// tournament minimum selection on the internal nodes. The insert
948 948
  /// operation takes O(1), the find, set, decrease and increase takes
949 949
  /// O(log(n)), where n is the number of nodes in the current
950 950
  /// component.  The complexity of join and split is O(log(n)*k),
951 951
  /// where n is the sum of the number of the nodes and k is the
952 952
  /// number of joined components or the number of the components
953 953
  /// after the split.
954 954
  ///
955 955
  /// \pre You need to add all the elements by the \ref insert()
956 956
  /// method.
957 957
  template <typename V, typename IM, typename Comp = std::less<V> >
958 958
  class HeapUnionFind {
959 959
  public:
960 960

	
961 961
    ///\e
962 962
    typedef V Value;
963 963
    ///\e
964 964
    typedef typename IM::Key Item;
965 965
    ///\e
966 966
    typedef IM ItemIntMap;
967 967
    ///\e
968 968
    typedef Comp Compare;
969 969

	
970 970
  private:
971 971

	
972 972
    static const int cmax = 16;
973 973

	
974 974
    ItemIntMap& index;
975 975

	
976 976
    struct ClassNode {
977 977
      int parent;
978 978
      int depth;
979 979

	
980 980
      int left, right;
981 981
      int next, prev;
982 982
    };
983 983

	
984 984
    int first_class;
985 985
    int first_free_class;
986 986
    std::vector<ClassNode> classes;
987 987

	
988 988
    int newClass() {
989 989
      if (first_free_class < 0) {
990 990
        int id = classes.size();
991 991
        classes.push_back(ClassNode());
992 992
        return id;
993 993
      } else {
994 994
        int id = first_free_class;
995 995
        first_free_class = classes[id].next;
996 996
        return id;
997 997
      }
998 998
    }
999 999

	
1000 1000
    void deleteClass(int id) {
1001 1001
      classes[id].next = first_free_class;
1002 1002
      first_free_class = id;
1003 1003
    }
1004 1004

	
1005 1005
    struct ItemNode {
1006 1006
      int parent;
1007 1007
      Item item;
1008 1008
      Value prio;
1009 1009
      int next, prev;
1010 1010
      int left, right;
1011 1011
      int size;
1012 1012
    };
1013 1013

	
1014 1014
    int first_free_node;
1015 1015
    std::vector<ItemNode> nodes;
1016 1016

	
1017 1017
    int newNode() {
1018 1018
      if (first_free_node < 0) {
1019 1019
        int id = nodes.size();
1020 1020
        nodes.push_back(ItemNode());
1021 1021
        return id;
1022 1022
      } else {
1023 1023
        int id = first_free_node;
1024 1024
        first_free_node = nodes[id].next;
1025 1025
        return id;
1026 1026
      }
1027 1027
    }
1028 1028

	
1029 1029
    void deleteNode(int id) {
1030 1030
      nodes[id].next = first_free_node;
1031 1031
      first_free_node = id;
1032 1032
    }
1033 1033

	
1034 1034
    Comp comp;
1035 1035

	
1036 1036
    int findClass(int id) const {
1037 1037
      int kd = id;
1038 1038
      while (kd >= 0) {
1039 1039
        kd = nodes[kd].parent;
1040 1040
      }
1041 1041
      return ~kd;
1042 1042
    }
1043 1043

	
1044 1044
    int leftNode(int id) const {
1045 1045
      int kd = ~(classes[id].parent);
1046 1046
      for (int i = 0; i < classes[id].depth; ++i) {
1047 1047
        kd = nodes[kd].left;
1048 1048
      }
1049 1049
      return kd;
1050 1050
    }
1051 1051

	
1052 1052
    int nextNode(int id) const {
1053 1053
      int depth = 0;
1054 1054
      while (id >= 0 && nodes[id].next == -1) {
1055 1055
        id = nodes[id].parent;
1056 1056
        ++depth;
1057 1057
      }
1058 1058
      if (id < 0) {
1059 1059
        return -1;
1060 1060
      }
1061 1061
      id = nodes[id].next;
1062 1062
      while (depth--) {
1063 1063
        id = nodes[id].left;
1064 1064
      }
1065 1065
      return id;
1066 1066
    }
1067 1067

	
1068 1068

	
1069 1069
    void setPrio(int id) {
1070 1070
      int jd = nodes[id].left;
1071 1071
      nodes[id].prio = nodes[jd].prio;
1072 1072
      nodes[id].item = nodes[jd].item;
1073 1073
      jd = nodes[jd].next;
1074 1074
      while (jd != -1) {
1075 1075
        if (comp(nodes[jd].prio, nodes[id].prio)) {
1076 1076
          nodes[id].prio = nodes[jd].prio;
1077 1077
          nodes[id].item = nodes[jd].item;
1078 1078
        }
1079 1079
        jd = nodes[jd].next;
1080 1080
      }
1081 1081
    }
1082 1082

	
1083 1083
    void push(int id, int jd) {
1084 1084
      nodes[id].size = 1;
1085 1085
      nodes[id].left = nodes[id].right = jd;
1086 1086
      nodes[jd].next = nodes[jd].prev = -1;
1087 1087
      nodes[jd].parent = id;
1088 1088
    }
1089 1089

	
1090 1090
    void pushAfter(int id, int jd) {
1091 1091
      int kd = nodes[id].parent;
1092 1092
      if (nodes[id].next != -1) {
1093 1093
        nodes[nodes[id].next].prev = jd;
1094 1094
        if (kd >= 0) {
1095 1095
          nodes[kd].size += 1;
1096 1096
        }
1097 1097
      } else {
1098 1098
        if (kd >= 0) {
1099 1099
          nodes[kd].right = jd;
1100 1100
          nodes[kd].size += 1;
1101 1101
        }
1102 1102
      }
1103 1103
      nodes[jd].next = nodes[id].next;
1104 1104
      nodes[jd].prev = id;
1105 1105
      nodes[id].next = jd;
1106 1106
      nodes[jd].parent = kd;
1107 1107
    }
1108 1108

	
1109 1109
    void pushRight(int id, int jd) {
1110 1110
      nodes[id].size += 1;
1111 1111
      nodes[jd].prev = nodes[id].right;
1112 1112
      nodes[jd].next = -1;
1113 1113
      nodes[nodes[id].right].next = jd;
1114 1114
      nodes[id].right = jd;
1115 1115
      nodes[jd].parent = id;
1116 1116
    }
1117 1117

	
1118 1118
    void popRight(int id) {
1119 1119
      nodes[id].size -= 1;
1120 1120
      int jd = nodes[id].right;
1121 1121
      nodes[nodes[jd].prev].next = -1;
1122 1122
      nodes[id].right = nodes[jd].prev;
1123 1123
    }
1124 1124

	
1125 1125
    void splice(int id, int jd) {
1126 1126
      nodes[id].size += nodes[jd].size;
1127 1127
      nodes[nodes[id].right].next = nodes[jd].left;
1128 1128
      nodes[nodes[jd].left].prev = nodes[id].right;
1129 1129
      int kd = nodes[jd].left;
1130 1130
      while (kd != -1) {
1131 1131
        nodes[kd].parent = id;
1132 1132
        kd = nodes[kd].next;
1133 1133
      }
1134 1134
      nodes[id].right = nodes[jd].right;
1135 1135
    }
1136 1136

	
1137 1137
    void split(int id, int jd) {
1138 1138
      int kd = nodes[id].parent;
1139 1139
      nodes[kd].right = nodes[id].prev;
1140 1140
      nodes[nodes[id].prev].next = -1;
1141 1141

	
1142 1142
      nodes[jd].left = id;
1143 1143
      nodes[id].prev = -1;
1144 1144
      int num = 0;
1145 1145
      while (id != -1) {
1146 1146
        nodes[id].parent = jd;
1147 1147
        nodes[jd].right = id;
1148 1148
        id = nodes[id].next;
1149 1149
        ++num;
1150 1150
      }
1151 1151
      nodes[kd].size -= num;
1152 1152
      nodes[jd].size = num;
1153 1153
    }
1154 1154

	
1155 1155
    void pushLeft(int id, int jd) {
1156 1156
      nodes[id].size += 1;
1157 1157
      nodes[jd].next = nodes[id].left;
1158 1158
      nodes[jd].prev = -1;
1159 1159
      nodes[nodes[id].left].prev = jd;
1160 1160
      nodes[id].left = jd;
1161 1161
      nodes[jd].parent = id;
1162 1162
    }
1163 1163

	
1164 1164
    void popLeft(int id) {
1165 1165
      nodes[id].size -= 1;
1166 1166
      int jd = nodes[id].left;
1167 1167
      nodes[nodes[jd].next].prev = -1;
1168 1168
      nodes[id].left = nodes[jd].next;
1169 1169
    }
1170 1170

	
1171 1171
    void repairLeft(int id) {
1172 1172
      int jd = ~(classes[id].parent);
1173 1173
      while (nodes[jd].left != -1) {
1174 1174
        int kd = nodes[jd].left;
1175 1175
        if (nodes[jd].size == 1) {
1176 1176
          if (nodes[jd].parent < 0) {
1177 1177
            classes[id].parent = ~kd;
1178 1178
            classes[id].depth -= 1;
1179 1179
            nodes[kd].parent = ~id;
1180 1180
            deleteNode(jd);
1181 1181
            jd = kd;
1182 1182
          } else {
1183 1183
            int pd = nodes[jd].parent;
1184 1184
            if (nodes[nodes[jd].next].size < cmax) {
1185 1185
              pushLeft(nodes[jd].next, nodes[jd].left);
1186 1186
              if (less(jd, nodes[jd].next) ||
1187 1187
                  nodes[jd].item == nodes[pd].item) {
1188 1188
                nodes[nodes[jd].next].prio = nodes[jd].prio;
1189 1189
                nodes[nodes[jd].next].item = nodes[jd].item;
1190 1190
              }
1191 1191
              popLeft(pd);
1192 1192
              deleteNode(jd);
1193 1193
              jd = pd;
1194 1194
            } else {
1195 1195
              int ld = nodes[nodes[jd].next].left;
1196 1196
              popLeft(nodes[jd].next);
1197 1197
              pushRight(jd, ld);
1198 1198
              if (less(ld, nodes[jd].left) ||
1199 1199
                  nodes[ld].item == nodes[pd].item) {
1200 1200
                nodes[jd].item = nodes[ld].item;
1201 1201
                nodes[jd].prio = nodes[ld].prio;
1202 1202
              }
1203 1203
              if (nodes[nodes[jd].next].item == nodes[ld].item) {
1204 1204
                setPrio(nodes[jd].next);
1205 1205
              }
1206 1206
              jd = nodes[jd].left;
1207 1207
            }
1208 1208
          }
1209 1209
        } else {
1210 1210
          jd = nodes[jd].left;
1211 1211
        }
1212 1212
      }
1213 1213
    }
1214 1214

	
1215 1215
    void repairRight(int id) {
1216 1216
      int jd = ~(classes[id].parent);
1217 1217
      while (nodes[jd].right != -1) {
1218 1218
        int kd = nodes[jd].right;
1219 1219
        if (nodes[jd].size == 1) {
1220 1220
          if (nodes[jd].parent < 0) {
1221 1221
            classes[id].parent = ~kd;
1222 1222
            classes[id].depth -= 1;
1223 1223
            nodes[kd].parent = ~id;
1224 1224
            deleteNode(jd);
1225 1225
            jd = kd;
1226 1226
          } else {
1227 1227
            int pd = nodes[jd].parent;
1228 1228
            if (nodes[nodes[jd].prev].size < cmax) {
1229 1229
              pushRight(nodes[jd].prev, nodes[jd].right);
1230 1230
              if (less(jd, nodes[jd].prev) ||
1231 1231
                  nodes[jd].item == nodes[pd].item) {
1232 1232
                nodes[nodes[jd].prev].prio = nodes[jd].prio;
1233 1233
                nodes[nodes[jd].prev].item = nodes[jd].item;
1234 1234
              }
1235 1235
              popRight(pd);
1236 1236
              deleteNode(jd);
1237 1237
              jd = pd;
1238 1238
            } else {
1239 1239
              int ld = nodes[nodes[jd].prev].right;
1240 1240
              popRight(nodes[jd].prev);
1241 1241
              pushLeft(jd, ld);
1242 1242
              if (less(ld, nodes[jd].right) ||
1243 1243
                  nodes[ld].item == nodes[pd].item) {
1244 1244
                nodes[jd].item = nodes[ld].item;
1245 1245
                nodes[jd].prio = nodes[ld].prio;
1246 1246
              }
1247 1247
              if (nodes[nodes[jd].prev].item == nodes[ld].item) {
1248 1248
                setPrio(nodes[jd].prev);
1249 1249
              }
1250 1250
              jd = nodes[jd].right;
1251 1251
            }
1252 1252
          }
1253 1253
        } else {
1254 1254
          jd = nodes[jd].right;
1255 1255
        }
1256 1256
      }
1257 1257
    }
1258 1258

	
1259 1259

	
1260 1260
    bool less(int id, int jd) const {
1261 1261
      return comp(nodes[id].prio, nodes[jd].prio);
1262 1262
    }
1263 1263

	
1264 1264
  public:
1265 1265

	
1266 1266
    /// \brief Returns true when the given class is alive.
1267 1267
    ///
1268 1268
    /// Returns true when the given class is alive, ie. the class is
1269 1269
    /// not nested into other class.
1270 1270
    bool alive(int cls) const {
1271 1271
      return classes[cls].parent < 0;
1272 1272
    }
1273 1273

	
1274 1274
    /// \brief Returns true when the given class is trivial.
1275 1275
    ///
1276 1276
    /// Returns true when the given class is trivial, ie. the class
1277 1277
    /// contains just one item directly.
1278 1278
    bool trivial(int cls) const {
1279 1279
      return classes[cls].left == -1;
1280 1280
    }
1281 1281

	
1282 1282
    /// \brief Constructs the union-find.
1283 1283
    ///
1284 1284
    /// Constructs the union-find.
1285 1285
    /// \brief _index The index map of the union-find. The data
1286 1286
    /// structure uses internally for store references.
1287 1287
    HeapUnionFind(ItemIntMap& _index)
1288 1288
      : index(_index), first_class(-1),
1289 1289
        first_free_class(-1), first_free_node(-1) {}
1290 1290

	
1291 1291
    /// \brief Clears the union-find data structure
1292 1292
    ///
1293 1293
    /// Erase each item from the data structure.
1294 1294
    void clear() {
1295 1295
      nodes.clear();
1296 1296
      classes.clear();
1297 1297
      first_free_node = first_free_class = first_class = -1;
1298 1298
    }
1299 1299

	
1300 1300
    /// \brief Insert a new node into a new component.
1301 1301
    ///
1302 1302
    /// Insert a new node into a new component.
1303 1303
    /// \param item The item of the new node.
1304 1304
    /// \param prio The priority of the new node.
1305 1305
    /// \return The class id of the one-item-heap.
1306 1306
    int insert(const Item& item, const Value& prio) {
1307 1307
      int id = newNode();
1308 1308
      nodes[id].item = item;
1309 1309
      nodes[id].prio = prio;
1310 1310
      nodes[id].size = 0;
1311 1311

	
1312 1312
      nodes[id].prev = -1;
1313 1313
      nodes[id].next = -1;
1314 1314

	
1315 1315
      nodes[id].left = -1;
1316 1316
      nodes[id].right = -1;
1317 1317

	
1318 1318
      nodes[id].item = item;
1319 1319
      index[item] = id;
1320 1320

	
1321 1321
      int class_id = newClass();
1322 1322
      classes[class_id].parent = ~id;
1323 1323
      classes[class_id].depth = 0;
1324 1324

	
1325 1325
      classes[class_id].left = -1;
1326 1326
      classes[class_id].right = -1;
1327 1327

	
1328 1328
      if (first_class != -1) {
1329 1329
        classes[first_class].prev = class_id;
1330 1330
      }
1331 1331
      classes[class_id].next = first_class;
1332 1332
      classes[class_id].prev = -1;
1333 1333
      first_class = class_id;
1334 1334

	
1335 1335
      nodes[id].parent = ~class_id;
1336 1336

	
1337 1337
      return class_id;
1338 1338
    }
1339 1339

	
1340 1340
    /// \brief The class of the item.
1341 1341
    ///
1342 1342
    /// \return The alive class id of the item, which is not nested into
1343 1343
    /// other classes.
1344 1344
    ///
1345 1345
    /// The time complexity is O(log(n)).
1346 1346
    int find(const Item& item) const {
1347 1347
      return findClass(index[item]);
1348 1348
    }
1349 1349

	
1350 1350
    /// \brief Joins the classes.
1351 1351
    ///
1352 1352
    /// The current function joins the given classes. The parameter is
1353 1353
    /// an STL range which should be contains valid class ids. The
1354 1354
    /// time complexity is O(log(n)*k) where n is the overall number
1355 1355
    /// of the joined nodes and k is the number of classes.
1356 1356
    /// \return The class of the joined classes.
1357 1357
    /// \pre The range should contain at least two class ids.
1358 1358
    template <typename Iterator>
1359 1359
    int join(Iterator begin, Iterator end) {
1360 1360
      std::vector<int> cs;
1361 1361
      for (Iterator it = begin; it != end; ++it) {
1362 1362
        cs.push_back(*it);
1363 1363
      }
1364 1364

	
1365 1365
      int class_id = newClass();
1366 1366
      { // creation union-find
1367 1367

	
1368 1368
        if (first_class != -1) {
1369 1369
          classes[first_class].prev = class_id;
1370 1370
        }
1371 1371
        classes[class_id].next = first_class;
1372 1372
        classes[class_id].prev = -1;
1373 1373
        first_class = class_id;
1374 1374

	
1375 1375
        classes[class_id].depth = classes[cs[0]].depth;
1376 1376
        classes[class_id].parent = classes[cs[0]].parent;
1377 1377
        nodes[~(classes[class_id].parent)].parent = ~class_id;
1378 1378

	
1379 1379
        int l = cs[0];
1380 1380

	
1381 1381
        classes[class_id].left = l;
1382 1382
        classes[class_id].right = l;
1383 1383

	
1384 1384
        if (classes[l].next != -1) {
1385 1385
          classes[classes[l].next].prev = classes[l].prev;
1386 1386
        }
1387 1387
        classes[classes[l].prev].next = classes[l].next;
1388 1388

	
1389 1389
        classes[l].prev = -1;
1390 1390
        classes[l].next = -1;
1391 1391

	
1392 1392
        classes[l].depth = leftNode(l);
1393 1393
        classes[l].parent = class_id;
1394 1394

	
1395 1395
      }
1396 1396

	
1397 1397
      { // merging of heap
1398 1398
        int l = class_id;
1399 1399
        for (int ci = 1; ci < int(cs.size()); ++ci) {
1400 1400
          int r = cs[ci];
1401 1401
          int rln = leftNode(r);
1402 1402
          if (classes[l].depth > classes[r].depth) {
1403 1403
            int id = ~(classes[l].parent);
1404 1404
            for (int i = classes[r].depth + 1; i < classes[l].depth; ++i) {
1405 1405
              id = nodes[id].right;
1406 1406
            }
1407 1407
            while (id >= 0 && nodes[id].size == cmax) {
1408 1408
              int new_id = newNode();
1409 1409
              int right_id = nodes[id].right;
1410 1410

	
1411 1411
              popRight(id);
1412 1412
              if (nodes[id].item == nodes[right_id].item) {
1413 1413
                setPrio(id);
1414 1414
              }
1415 1415
              push(new_id, right_id);
1416 1416
              pushRight(new_id, ~(classes[r].parent));
1417 1417

	
1418 1418
              if (less(~classes[r].parent, right_id)) {
1419 1419
                nodes[new_id].item = nodes[~classes[r].parent].item;
1420 1420
                nodes[new_id].prio = nodes[~classes[r].parent].prio;
1421 1421
              } else {
1422 1422
                nodes[new_id].item = nodes[right_id].item;
1423 1423
                nodes[new_id].prio = nodes[right_id].prio;
1424 1424
              }
1425 1425

	
1426 1426
              id = nodes[id].parent;
1427 1427
              classes[r].parent = ~new_id;
1428 1428
            }
1429 1429
            if (id < 0) {
1430 1430
              int new_parent = newNode();
1431 1431
              nodes[new_parent].next = -1;
1432 1432
              nodes[new_parent].prev = -1;
1433 1433
              nodes[new_parent].parent = ~l;
1434 1434

	
1435 1435
              push(new_parent, ~(classes[l].parent));
1436 1436
              pushRight(new_parent, ~(classes[r].parent));
1437 1437
              setPrio(new_parent);
1438 1438

	
1439 1439
              classes[l].parent = ~new_parent;
1440 1440
              classes[l].depth += 1;
1441 1441
            } else {
1442 1442
              pushRight(id, ~(classes[r].parent));
1443 1443
              while (id >= 0 && less(~(classes[r].parent), id)) {
1444 1444
                nodes[id].prio = nodes[~(classes[r].parent)].prio;
1445 1445
                nodes[id].item = nodes[~(classes[r].parent)].item;
1446 1446
                id = nodes[id].parent;
1447 1447
              }
1448 1448
            }
1449 1449
          } else if (classes[r].depth > classes[l].depth) {
1450 1450
            int id = ~(classes[r].parent);
1451 1451
            for (int i = classes[l].depth + 1; i < classes[r].depth; ++i) {
1452 1452
              id = nodes[id].left;
1453 1453
            }
1454 1454
            while (id >= 0 && nodes[id].size == cmax) {
1455 1455
              int new_id = newNode();
1456 1456
              int left_id = nodes[id].left;
1457 1457

	
1458 1458
              popLeft(id);
1459 1459
              if (nodes[id].prio == nodes[left_id].prio) {
1460 1460
                setPrio(id);
1461 1461
              }
1462 1462
              push(new_id, left_id);
1463 1463
              pushLeft(new_id, ~(classes[l].parent));
1464 1464

	
1465 1465
              if (less(~classes[l].parent, left_id)) {
1466 1466
                nodes[new_id].item = nodes[~classes[l].parent].item;
1467 1467
                nodes[new_id].prio = nodes[~classes[l].parent].prio;
1468 1468
              } else {
1469 1469
                nodes[new_id].item = nodes[left_id].item;
1470 1470
                nodes[new_id].prio = nodes[left_id].prio;
1471 1471
              }
1472 1472

	
1473 1473
              id = nodes[id].parent;
1474 1474
              classes[l].parent = ~new_id;
1475 1475

	
1476 1476
            }
1477 1477
            if (id < 0) {
1478 1478
              int new_parent = newNode();
1479 1479
              nodes[new_parent].next = -1;
1480 1480
              nodes[new_parent].prev = -1;
1481 1481
              nodes[new_parent].parent = ~l;
1482 1482

	
1483 1483
              push(new_parent, ~(classes[r].parent));
1484 1484
              pushLeft(new_parent, ~(classes[l].parent));
1485 1485
              setPrio(new_parent);
1486 1486

	
1487 1487
              classes[r].parent = ~new_parent;
1488 1488
              classes[r].depth += 1;
1489 1489
            } else {
1490 1490
              pushLeft(id, ~(classes[l].parent));
1491 1491
              while (id >= 0 && less(~(classes[l].parent), id)) {
1492 1492
                nodes[id].prio = nodes[~(classes[l].parent)].prio;
1493 1493
                nodes[id].item = nodes[~(classes[l].parent)].item;
1494 1494
                id = nodes[id].parent;
1495 1495
              }
1496 1496
            }
1497 1497
            nodes[~(classes[r].parent)].parent = ~l;
1498 1498
            classes[l].parent = classes[r].parent;
1499 1499
            classes[l].depth = classes[r].depth;
1500 1500
          } else {
1501 1501
            if (classes[l].depth != 0 &&
1502 1502
                nodes[~(classes[l].parent)].size +
1503 1503
                nodes[~(classes[r].parent)].size <= cmax) {
1504 1504
              splice(~(classes[l].parent), ~(classes[r].parent));
1505 1505
              deleteNode(~(classes[r].parent));
1506 1506
              if (less(~(classes[r].parent), ~(classes[l].parent))) {
1507 1507
                nodes[~(classes[l].parent)].prio =
1508 1508
                  nodes[~(classes[r].parent)].prio;
1509 1509
                nodes[~(classes[l].parent)].item =
1510 1510
                  nodes[~(classes[r].parent)].item;
1511 1511
              }
1512 1512
            } else {
1513 1513
              int new_parent = newNode();
1514 1514
              nodes[new_parent].next = nodes[new_parent].prev = -1;
1515 1515
              push(new_parent, ~(classes[l].parent));
1516 1516
              pushRight(new_parent, ~(classes[r].parent));
1517 1517
              setPrio(new_parent);
1518 1518

	
1519 1519
              classes[l].parent = ~new_parent;
1520 1520
              classes[l].depth += 1;
1521 1521
              nodes[new_parent].parent = ~l;
1522 1522
            }
1523 1523
          }
1524 1524
          if (classes[r].next != -1) {
1525 1525
            classes[classes[r].next].prev = classes[r].prev;
1526 1526
          }
1527 1527
          classes[classes[r].prev].next = classes[r].next;
1528 1528

	
1529 1529
          classes[r].prev = classes[l].right;
1530 1530
          classes[classes[l].right].next = r;
1531 1531
          classes[l].right = r;
1532 1532
          classes[r].parent = l;
1533 1533

	
1534 1534
          classes[r].next = -1;
1535 1535
          classes[r].depth = rln;
1536 1536
        }
1537 1537
      }
1538 1538
      return class_id;
1539 1539
    }
1540 1540

	
1541 1541
    /// \brief Split the class to subclasses.
1542 1542
    ///
1543 1543
    /// The current function splits the given class. The join, which
1544 1544
    /// made the current class, stored a reference to the
1545 1545
    /// subclasses. The \c splitClass() member restores the classes
1546 1546
    /// and creates the heaps. The parameter is an STL output iterator
1547 1547
    /// which will be filled with the subclass ids. The time
1548 1548
    /// complexity is O(log(n)*k) where n is the overall number of
1549 1549
    /// nodes in the splitted classes and k is the number of the
1550 1550
    /// classes.
1551 1551
    template <typename Iterator>
1552 1552
    void split(int cls, Iterator out) {
1553 1553
      std::vector<int> cs;
1554 1554
      { // splitting union-find
1555 1555
        int id = cls;
1556 1556
        int l = classes[id].left;
1557 1557

	
1558 1558
        classes[l].parent = classes[id].parent;
1559 1559
        classes[l].depth = classes[id].depth;
1560 1560

	
1561 1561
        nodes[~(classes[l].parent)].parent = ~l;
1562 1562

	
1563 1563
        *out++ = l;
1564 1564

	
1565 1565
        while (l != -1) {
1566 1566
          cs.push_back(l);
1567 1567
          l = classes[l].next;
1568 1568
        }
1569 1569

	
1570 1570
        classes[classes[id].right].next = first_class;
1571 1571
        classes[first_class].prev = classes[id].right;
1572 1572
        first_class = classes[id].left;
1573 1573

	
1574 1574
        if (classes[id].next != -1) {
1575 1575
          classes[classes[id].next].prev = classes[id].prev;
1576 1576
        }
1577 1577
        classes[classes[id].prev].next = classes[id].next;
1578 1578

	
1579 1579
        deleteClass(id);
1580 1580
      }
1581 1581

	
1582 1582
      {
1583 1583
        for (int i = 1; i < int(cs.size()); ++i) {
1584 1584
          int l = classes[cs[i]].depth;
1585 1585
          while (nodes[nodes[l].parent].left == l) {
1586 1586
            l = nodes[l].parent;
1587 1587
          }
1588 1588
          int r = l;
1589 1589
          while (nodes[l].parent >= 0) {
1590 1590
            l = nodes[l].parent;
1591 1591
            int new_node = newNode();
1592 1592

	
1593 1593
            nodes[new_node].prev = -1;
1594 1594
            nodes[new_node].next = -1;
1595 1595

	
1596 1596
            split(r, new_node);
1597 1597
            pushAfter(l, new_node);
1598 1598
            setPrio(l);
1599 1599
            setPrio(new_node);
1600 1600
            r = new_node;
1601 1601
          }
1602 1602
          classes[cs[i]].parent = ~r;
1603 1603
          classes[cs[i]].depth = classes[~(nodes[l].parent)].depth;
1604 1604
          nodes[r].parent = ~cs[i];
1605 1605

	
1606 1606
          nodes[l].next = -1;
1607 1607
          nodes[r].prev = -1;
1608 1608

	
1609 1609
          repairRight(~(nodes[l].parent));
1610 1610
          repairLeft(cs[i]);
1611 1611

	
1612 1612
          *out++ = cs[i];
1613 1613
        }
1614 1614
      }
1615 1615
    }
1616 1616

	
1617 1617
    /// \brief Gives back the priority of the current item.
1618 1618
    ///
1619 1619
    /// Gives back the priority of the current item.
1620 1620
    const Value& operator[](const Item& item) const {
1621 1621
      return nodes[index[item]].prio;
1622 1622
    }
1623 1623

	
1624 1624
    /// \brief Sets the priority of the current item.
1625 1625
    ///
1626 1626
    /// Sets the priority of the current item.
1627 1627
    void set(const Item& item, const Value& prio) {
1628 1628
      if (comp(prio, nodes[index[item]].prio)) {
1629 1629
        decrease(item, prio);
1630 1630
      } else if (!comp(prio, nodes[index[item]].prio)) {
1631 1631
        increase(item, prio);
1632 1632
      }
1633 1633
    }
1634 1634

	
1635 1635
    /// \brief Increase the priority of the current item.
1636 1636
    ///
1637 1637
    /// Increase the priority of the current item.
1638 1638
    void increase(const Item& item, const Value& prio) {
1639 1639
      int id = index[item];
1640 1640
      int kd = nodes[id].parent;
1641 1641
      nodes[id].prio = prio;
1642 1642
      while (kd >= 0 && nodes[kd].item == item) {
1643 1643
        setPrio(kd);
1644 1644
        kd = nodes[kd].parent;
1645 1645
      }
1646 1646
    }
1647 1647

	
1648 1648
    /// \brief Increase the priority of the current item.
1649 1649
    ///
1650 1650
    /// Increase the priority of the current item.
1651 1651
    void decrease(const Item& item, const Value& prio) {
1652 1652
      int id = index[item];
1653 1653
      int kd = nodes[id].parent;
1654 1654
      nodes[id].prio = prio;
1655 1655
      while (kd >= 0 && less(id, kd)) {
1656 1656
        nodes[kd].prio = prio;
1657 1657
        nodes[kd].item = item;
1658 1658
        kd = nodes[kd].parent;
1659 1659
      }
1660 1660
    }
1661 1661

	
1662 1662
    /// \brief Gives back the minimum priority of the class.
1663 1663
    ///
1664 1664
    /// Gives back the minimum priority of the class.
1665 1665
    const Value& classPrio(int cls) const {
1666 1666
      return nodes[~(classes[cls].parent)].prio;
1667 1667
    }
1668 1668

	
1669 1669
    /// \brief Gives back the minimum priority item of the class.
1670 1670
    ///
1671 1671
    /// \return Gives back the minimum priority item of the class.
1672 1672
    const Item& classTop(int cls) const {
1673 1673
      return nodes[~(classes[cls].parent)].item;
1674 1674
    }
1675 1675

	
1676 1676
    /// \brief Gives back a representant item of the class.
1677 1677
    ///
1678 1678
    /// Gives back a representant item of the class.
1679 1679
    /// The representant is indpendent from the priorities of the
1680 1680
    /// items.
1681 1681
    const Item& classRep(int id) const {
1682 1682
      int parent = classes[id].parent;
1683 1683
      return nodes[parent >= 0 ? classes[id].depth : leftNode(id)].item;
1684 1684
    }
1685 1685

	
1686 1686
    /// \brief LEMON style iterator for the items of a class.
1687 1687
    ///
1688 1688
    /// ClassIt is a lemon style iterator for the components. It iterates
1689 1689
    /// on the items of a class. By example if you want to iterate on
1690 1690
    /// each items of each classes then you may write the next code.
1691 1691
    ///\code
1692 1692
    /// for (ClassIt cit(huf); cit != INVALID; ++cit) {
1693 1693
    ///   std::cout << "Class: ";
1694 1694
    ///   for (ItemIt iit(huf, cit); iit != INVALID; ++iit) {
1695 1695
    ///     std::cout << toString(iit) << ' ' << std::endl;
1696 1696
    ///   }
1697 1697
    ///   std::cout << std::endl;
1698 1698
    /// }
1699 1699
    ///\endcode
1700 1700
    class ItemIt {
1701 1701
    private:
1702 1702

	
1703 1703
      const HeapUnionFind* _huf;
1704 1704
      int _id, _lid;
1705 1705

	
1706 1706
    public:
1707 1707

	
1708 1708
      /// \brief Default constructor
1709 1709
      ///
1710 1710
      /// Default constructor
1711 1711
      ItemIt() {}
1712 1712

	
1713 1713
      ItemIt(const HeapUnionFind& huf, int cls) : _huf(&huf) {
1714 1714
        int id = cls;
1715 1715
        int parent = _huf->classes[id].parent;
1716 1716
        if (parent >= 0) {
1717 1717
          _id = _huf->classes[id].depth;
1718 1718
          if (_huf->classes[id].next != -1) {
1719 1719
            _lid = _huf->classes[_huf->classes[id].next].depth;
1720 1720
          } else {
1721 1721
            _lid = -1;
1722 1722
          }
1723 1723
        } else {
1724 1724
          _id = _huf->leftNode(id);
1725 1725
          _lid = -1;
1726 1726
        }
1727 1727
      }
1728 1728

	
1729 1729
      /// \brief Increment operator
1730 1730
      ///
1731 1731
      /// It steps to the next item in the class.
1732 1732
      ItemIt& operator++() {
1733 1733
        _id = _huf->nextNode(_id);
1734 1734
        return *this;
1735 1735
      }
1736 1736

	
1737 1737
      /// \brief Conversion operator
1738 1738
      ///
1739 1739
      /// It converts the iterator to the current item.
1740 1740
      operator const Item&() const {
1741 1741
        return _huf->nodes[_id].item;
1742 1742
      }
1743 1743

	
1744 1744
      /// \brief Equality operator
1745 1745
      ///
1746 1746
      /// Equality operator
1747 1747
      bool operator==(const ItemIt& i) {
1748 1748
        return i._id == _id;
1749 1749
      }
1750 1750

	
1751 1751
      /// \brief Inequality operator
1752 1752
      ///
1753 1753
      /// Inequality operator
1754 1754
      bool operator!=(const ItemIt& i) {
1755 1755
        return i._id != _id;
1756 1756
      }
1757 1757

	
1758 1758
      /// \brief Equality operator
1759 1759
      ///
1760 1760
      /// Equality operator
1761 1761
      bool operator==(Invalid) {
1762 1762
        return _id == _lid;
1763 1763
      }
1764 1764

	
1765 1765
      /// \brief Inequality operator
1766 1766
      ///
1767 1767
      /// Inequality operator
1768 1768
      bool operator!=(Invalid) {
1769 1769
        return _id != _lid;
1770 1770
      }
1771 1771

	
1772 1772
    };
1773 1773

	
1774 1774
    /// \brief Class iterator
1775 1775
    ///
1776 1776
    /// The iterator stores
1777 1777
    class ClassIt {
1778 1778
    private:
1779 1779

	
1780 1780
      const HeapUnionFind* _huf;
1781 1781
      int _id;
1782 1782

	
1783 1783
    public:
1784 1784

	
1785 1785
      ClassIt(const HeapUnionFind& huf)
1786 1786
        : _huf(&huf), _id(huf.first_class) {}
1787 1787

	
1788 1788
      ClassIt(const HeapUnionFind& huf, int cls)
1789 1789
        : _huf(&huf), _id(huf.classes[cls].left) {}
1790 1790

	
1791 1791
      ClassIt(Invalid) : _huf(0), _id(-1) {}
1792 1792

	
1793 1793
      const ClassIt& operator++() {
1794 1794
        _id = _huf->classes[_id].next;
1795 1795
        return *this;
1796 1796
      }
1797 1797

	
1798 1798
      /// \brief Equality operator
1799 1799
      ///
1800 1800
      /// Equality operator
1801 1801
      bool operator==(const ClassIt& i) {
1802 1802
        return i._id == _id;
1803 1803
      }
1804 1804

	
1805 1805
      /// \brief Inequality operator
1806 1806
      ///
1807 1807
      /// Inequality operator
1808 1808
      bool operator!=(const ClassIt& i) {
1809 1809
        return i._id != _id;
1810 1810
      }
1811 1811

	
1812 1812
      operator int() const {
1813 1813
        return _id;
1814 1814
      }
1815 1815

	
1816 1816
    };
1817 1817

	
1818 1818
  };
1819 1819

	
1820 1820
  //! @}
1821 1821

	
1822 1822
} //namespace lemon
1823 1823

	
1824 1824
#endif //LEMON_UNION_FIND_H
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 18

	
5 19
from mercurial import ui, hg
6 20
from mercurial import util
7 21

	
8 22
util.rcpath = lambda : []
9 23

	
10 24
if len(sys.argv)>1 and sys.argv[1] in ["-h","--help"]:
11 25
    print """
12 26
This utility just prints the length of the longest path
13 27
in the revision graph from revison 0 to the current one.
14 28
"""
15 29
    exit(0)
16 30

	
17 31
u = ui.ui()
18 32
r = hg.repository(u, ".")
19 33
N = r.changectx(".").rev()
20 34
lengths=[0]*(N+1)
21 35
for i in range(N+1):
22 36
    p=r.changectx(i).parents()
23 37
    if p[0]:
24 38
        p0=lengths[p[0].rev()]
25 39
    else:
26 40
        p0=-1
27 41
    if len(p)>1 and p[1]:
28 42
        p1=lengths[p[1].rev()]
29 43
    else:
30 44
        p1=-1
31 45
    lengths[i]=max(p0,p1)+1
32 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 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 17
YEAR=`date +%Y`
4 18
HGROOT=`hg root`
5 19

	
6 20
function hg_year() {
7 21
    if [ -n "$(hg st $1)" ]; then
8 22
        echo $YEAR
9 23
    else
10 24
        hg log -l 1 --template='{date|isodate}\n' $1 |
11 25
        cut -d '-' -f 1
12 26
    fi
13 27
}
14 28

	
15 29
# file enumaration modes
16 30

	
17 31
function all_files() {
18 32
    hg status -a -m -c |
19 33
    cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' |
20 34
    while read file; do echo $HGROOT/$file; done
21 35
}
22 36

	
23 37
function modified_files() {
24 38
    hg status -a -m |
25 39
    cut -d ' ' -f 2 | grep -E  '(\.(cc|h|dox)$|Makefile\.am$)' |
26 40
    while read file; do echo $HGROOT/$file; done
27 41
}
28 42

	
29 43
function changed_files() {
30 44
    {
31 45
        if [ -n "$HG_PARENT1" ]
32 46
        then
33 47
            hg status --rev $HG_PARENT1:$HG_NODE -a -m
34 48
        fi
35 49
        if [ -n "$HG_PARENT2" ]
36 50
        then
37 51
            hg status --rev $HG_PARENT2:$HG_NODE -a -m
38 52
        fi
39 53
    } | cut -d ' ' -f 2 | grep -E '(\.(cc|h|dox)$|Makefile\.am$)' | 
40 54
    sort | uniq |
41 55
    while read file; do echo $HGROOT/$file; done
42 56
}
43 57

	
44 58
function given_files() {
45 59
    for file in $GIVEN_FILES
46 60
    do
47 61
	echo $file
48 62
    done
49 63
}
50 64

	
51 65
# actions
52 66

	
53 67
function update_action() {
54 68
    if ! diff -q $1 $2 >/dev/null
55 69
    then
56 70
	echo -n " [$3 updated]"
57 71
	rm $2
58 72
	mv $1 $2
59 73
	CHANGED=YES
60 74
    fi
61 75
}
62 76

	
63 77
function update_warning() {
64 78
    echo -n " [$2 warning]"
65 79
    WARNED=YES
66 80
}
67 81

	
68 82
function update_init() {
69 83
    echo Update source files...
70 84
    TOTAL_FILES=0
71 85
    CHANGED_FILES=0
72 86
    WARNED_FILES=0
73 87
}
74 88

	
75 89
function update_done() {
76 90
    echo $CHANGED_FILES out of $TOTAL_FILES files has been changed.
77 91
    echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
78 92
}
79 93

	
80 94
function update_begin() {
81 95
    ((TOTAL_FILES++))
82 96
    CHANGED=NO
83 97
    WARNED=NO
84 98
}
85 99

	
86 100
function update_end() {
87 101
    if [ $CHANGED == YES ]
88 102
    then
89 103
	((++CHANGED_FILES))
90 104
    fi
91 105
    if [ $WARNED == YES ]
92 106
    then
93 107
	((++WARNED_FILES))
94 108
    fi
95 109
}
96 110

	
97 111
function check_action() {
98 112
    if [ "$3" == 'tabs' ]
99 113
    then
100 114
        if echo $2 | grep -q -v -E 'Makefile\.am$'
101 115
        then
102 116
            PATTERN=$(echo -e '\t')
103 117
        else
104 118
            PATTERN='        '
105 119
        fi
106 120
    elif [ "$3" == 'trailing spaces' ]
107 121
    then
108 122
        PATTERN='\ +$'
109 123
    else
110 124
        PATTERN='*'
111 125
    fi
112 126

	
113 127
    if ! diff -q $1 $2 >/dev/null
114 128
    then
115 129
        if [ "$PATTERN" == '*' ]
116 130
        then
117 131
            diff $1 $2 | grep '^[0-9]' | sed "s|^\(.*\)c.*$|$2:\1: check failed: $3|g" |
118 132
              sed "s/:\([0-9]*\),\([0-9]*\):\(.*\)$/:\1:\3 (until line \2)/g"
119 133
        else
120 134
            grep -n -E "$PATTERN" $2 | sed "s|^\([0-9]*\):.*$|$2:\1: check failed: $3|g"
121 135
        fi
122 136
        FAILED=YES
123 137
    fi
124 138
}
125 139

	
126 140
function check_warning() {
127 141
    if [ "$2" == 'long lines' ]
128 142
    then
129 143
        grep -n -E '.{81,}' $1 | sed "s|^\([0-9]*\):.*$|$1:\1: warning: $2|g"
130 144
    else
131 145
        echo "$1: warning: $2"
132 146
    fi
133 147
    WARNED=YES
134 148
}
135 149

	
136 150
function check_init() {
137 151
    echo Check source files...
138 152
    FAILED_FILES=0
139 153
    WARNED_FILES=0
140 154
    TOTAL_FILES=0
141 155
}
142 156

	
143 157
function check_done() {
144 158
    echo $FAILED_FILES out of $TOTAL_FILES files has been failed.
145 159
    echo $WARNED_FILES out of $TOTAL_FILES files triggered warnings.
146 160

	
147 161
    if [ $WARNED_FILES -gt 0 -o $FAILED_FILES -gt 0 ]
148 162
    then
149 163
	if [ "$WARNING" == 'INTERACTIVE' ]
150 164
	then
151 165
	    echo -n "Are the files with errors/warnings acceptable? (yes/no) "
152 166
	    while read answer
153 167
	    do
154 168
		if [ "$answer" == 'yes' ]
155 169
		then
156 170
		    return 0
157 171
		elif [ "$answer" == 'no' ]
158 172
		then
159 173
		    return 1
160 174
		fi
161 175
		echo -n "Are the files with errors/warnings acceptable? (yes/no) "
162 176
	    done
163 177
	elif [ "$WARNING" == 'WERROR' ]
164 178
	then
165 179
	    return 1
166 180
	fi
167 181
    fi
168 182
}
169 183

	
170 184
function check_begin() {
171 185
    ((TOTAL_FILES++))
172 186
    FAILED=NO
173 187
    WARNED=NO
174 188
}
175 189

	
176 190
function check_end() {
177 191
    if [ $FAILED == YES ]
178 192
    then
179 193
	((++FAILED_FILES))
180 194
    fi
181 195
    if [ $WARNED == YES ]
182 196
    then
183 197
	((++WARNED_FILES))
184 198
    fi
185 199
}
186 200

	
187 201

	
188 202

	
189 203
# checks
190 204

	
191 205
function header_check() {
192 206
    if echo $1 | grep -q -E 'Makefile\.am$'
193 207
    then
194 208
	return
195 209
    fi
196 210

	
197 211
    TMP_FILE=`mktemp`
198 212

	
199 213
    (echo "/* -*- mode: C++; indent-tabs-mode: nil; -*-
200 214
 *
201 215
 * This file is a part of LEMON, a generic C++ optimization library.
202 216
 *
203 217
 * Copyright (C) 2003-"$(hg_year $1)"
204 218
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
205 219
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
206 220
 *
207 221
 * Permission to use, modify and distribute this software is granted
208 222
 * provided that this copyright notice appears in all copies. For
209 223
 * precise terms see the accompanying LICENSE file.
210 224
 *
211 225
 * This software is provided \"AS IS\" with no warranty of any kind,
212 226
 * express or implied, and with no claim as to its suitability for any
213 227
 * purpose.
214 228
 *
215 229
 */
216 230
"
217 231
    awk 'BEGIN { pm=0; }
218 232
     pm==3 { print }
219 233
     /\/\* / && pm==0 { pm=1;}
220 234
     /[^:blank:]/ && (pm==0 || pm==2) { pm=3; print;}
221 235
     /\*\// && pm==1 { pm=2;}
222 236
    ' $1
223 237
    ) >$TMP_FILE
224 238

	
225 239
    "$ACTION"_action "$TMP_FILE" "$1" header
226 240
}
227 241

	
228 242
function tabs_check() {
229 243
    if echo $1 | grep -q -v -E 'Makefile\.am$'
230 244
    then
231 245
        OLD_PATTERN=$(echo -e '\t')
232 246
        NEW_PATTERN='        '
233 247
    else
234 248
        OLD_PATTERN='        '
235 249
        NEW_PATTERN=$(echo -e '\t')
236 250
    fi
237 251
    TMP_FILE=`mktemp`
238 252
    cat $1 | sed -e "s/$OLD_PATTERN/$NEW_PATTERN/g" >$TMP_FILE
239 253

	
240 254
    "$ACTION"_action "$TMP_FILE" "$1" 'tabs'
241 255
}
242 256

	
243 257
function spaces_check() {
244 258
    TMP_FILE=`mktemp`
245 259
    cat $1 | sed -e 's/ \+$//g' >$TMP_FILE
246 260

	
247 261
    "$ACTION"_action "$TMP_FILE" "$1" 'trailing spaces'
248 262
}
249 263

	
250 264
function long_lines_check() {
251 265
    if cat $1 | grep -q -E '.{81,}'
252 266
    then
253 267
	"$ACTION"_warning $1 'long lines'
254 268
    fi
255 269
}
256 270

	
257 271
# process the file
258 272

	
259 273
function process_file() {
260 274
    if [ "$ACTION" == 'update' ]
261 275
    then
262 276
        echo -n "    $ACTION $1..."
263 277
    else
264 278
        echo "	  $ACTION $1..."
265 279
    fi
266 280

	
267 281
    CHECKING="header tabs spaces long_lines"
268 282

	
269 283
    "$ACTION"_begin $1
270 284
    for check in $CHECKING
271 285
    do
272 286
	"$check"_check $1
273 287
    done
274 288
    "$ACTION"_end $1
275 289
    if [ "$ACTION" == 'update' ]
276 290
    then
277 291
        echo
278 292
    fi
279 293
}
280 294

	
281 295
function process_all {
282 296
    "$ACTION"_init
283 297
    while read file
284 298
    do
285 299
	process_file $file
286 300
    done < <($FILES)
287 301
    "$ACTION"_done
288 302
}
289 303

	
290 304
while [ $# -gt 0 ]
291 305
do
292 306
    
293 307
    if [ "$1" == '--help' ] || [ "$1" == '-h' ]
294 308
    then
295 309
	echo -n \
296 310
"Usage:
297 311
  $0 [OPTIONS] [files]
298 312
Options:
299 313
  --dry-run|-n
300 314
     Check the files, but do not modify them.
301 315
  --interactive|-i
302 316
     If --dry-run is specified and the checker emits warnings,
303 317
     then the user is asked if the warnings should be considered
304 318
     errors.
305 319
  --werror|-w
306 320
     Make all warnings into errors.
307 321
  --all|-a
308 322
     Check all source files in the repository.
309 323
  --modified|-m
310 324
     Check only the modified (and new) source files. This option is
311 325
     useful to check the modification before making a commit.
312 326
  --changed|-c
313 327
     Check only the changed source files compared to the parent(s) of
314 328
     the current hg node.  This option is useful as hg hook script.
315 329
     To automatically check all your changes before making a commit,
316 330
     add the following section to the appropriate .hg/hgrc file.
317 331

	
318 332
       [hooks]
319 333
       pretxncommit.checksources = scripts/unify-sources.sh -c -n -i
320 334

	
321 335
  --help|-h
322 336
     Print this help message.
323 337
  files
324 338
     The files to check/unify. If no file names are given, the modified
325 339
     source files will be checked/unified (just like using the
326 340
     --modified|-m option).
327 341
"
328 342
        exit 0
329 343
    elif [ "$1" == '--dry-run' ] || [ "$1" == '-n' ]
330 344
    then
331 345
	[ -n "$ACTION" ] && echo "Conflicting action options" >&2 && exit 1
332 346
	ACTION=check
333 347
    elif [ "$1" == "--all" ] || [ "$1" == '-a' ]
334 348
    then
335 349
	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
336 350
	FILES=all_files
337 351
    elif [ "$1" == "--changed" ] || [ "$1" == '-c' ]
338 352
    then
339 353
	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
340 354
	FILES=changed_files
341 355
    elif [ "$1" == "--modified" ] || [ "$1" == '-m' ]
342 356
    then
343 357
	[ -n "$FILES" ] && echo "Conflicting target options" >&2 && exit 1
344 358
	FILES=modified_files
345 359
    elif [ "$1" == "--interactive" ] || [ "$1" == "-i" ]
346 360
    then
347 361
	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
348 362
	WARNING='INTERACTIVE'
349 363
    elif [ "$1" == "--werror" ] || [ "$1" == "-w" ]
350 364
    then
351 365
	[ -n "$WARNING" ] && echo "Conflicting warning options" >&2 && exit 1
352 366
	WARNING='WERROR'
353 367
    elif [ $(echo x$1 | cut -c 2) == '-' ]
354 368
    then
355 369
	echo "Invalid option $1" >&2 && exit 1
356 370
    else
357 371
	[ -n "$FILES" ] && echo "Invalid option $1" >&2 && exit 1
358 372
	GIVEN_FILES=$@
359 373
	FILES=given_files
360 374
	break
361 375
    fi
362 376
    
363 377
    shift
364 378
done
365 379

	
366 380
if [ -z $FILES ]
367 381
then
368 382
    FILES=modified_files
369 383
fi
370 384

	
371 385
if [ -z $ACTION ]
372 386
then
373 387
    ACTION=update
374 388
fi
375 389

	
376 390
process_all
Ignore white space 6 line context
1 1
INCLUDE_DIRECTORIES(
2 2
  ${PROJECT_SOURCE_DIR}
3 3
  ${PROJECT_BINARY_DIR}
4 4
)
5 5

	
6 6
LINK_DIRECTORIES(
7 7
  ${PROJECT_BINARY_DIR}/lemon
8 8
)
9 9

	
10 10
SET(TEST_WITH_VALGRIND "NO" CACHE STRING
11 11
  "Run the test with valgrind (YES/NO).")
12 12
SET(VALGRIND_FLAGS "" CACHE STRING "Valgrind flags used by the tests.")
13 13

	
14 14
SET(TESTS
15 15
  adaptors_test
16
  bellman_ford_test
16 17
  bfs_test
17 18
  circulation_test
18 19
  connectivity_test
19 20
  counter_test
20 21
  dfs_test
21 22
  digraph_test
22 23
  dijkstra_test
23 24
  dim_test
24 25
  edge_set_test
25 26
  error_test
26 27
  euler_test
28
  fractional_matching_test
27 29
  gomory_hu_test
28 30
  graph_copy_test
29 31
  graph_test
30 32
  graph_utils_test
31 33
  hao_orlin_test
32 34
  heap_test
33 35
  kruskal_test
34 36
  lgf_test
35 37
  maps_test
36 38
  matching_test
37 39
  min_cost_arborescence_test
38 40
  min_cost_flow_test
41
  min_mean_cycle_test
39 42
  path_test
43
  planarity_test
40 44
  preflow_test
41 45
  radix_sort_test
42 46
  random_test
43 47
  suurballe_test
44 48
  time_measure_test
45 49
  unionfind_test
46 50
)
47 51

	
48 52
IF(LEMON_HAVE_LP)
49 53
  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
50 54
    ADD_EXECUTABLE(lp_test lp_test.cc)
51 55
  ELSE()
52 56
    ADD_EXECUTABLE(lp_test EXCLUDE_FROM_ALL lp_test.cc)
53 57
  ENDIF()
54 58

	
55 59
  SET(LP_TEST_LIBS lemon)
56 60

	
57 61
  IF(LEMON_HAVE_GLPK)
58 62
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
59 63
  ENDIF()
60 64
  IF(LEMON_HAVE_CPLEX)
61 65
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
62 66
  ENDIF()
63 67
  IF(LEMON_HAVE_CLP)
64 68
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
65 69
  ENDIF()
66 70

	
67 71
  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
68 72
  ADD_TEST(lp_test lp_test)
69 73
  ADD_DEPENDENCIES(check lp_test)
70 74

	
71 75
  IF(WIN32 AND LEMON_HAVE_GLPK)
72 76
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
73 77
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
74 78
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
75 79
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
76 80
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
77 81
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
78 82
    )
79 83
  ENDIF()
80 84

	
81 85
  IF(WIN32 AND LEMON_HAVE_CPLEX)
82 86
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
83 87
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
84 88
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
85 89
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
86 90
    )
87 91
  ENDIF()
88 92
ENDIF()
89 93

	
90 94
IF(LEMON_HAVE_MIP)
91 95
  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
92 96
    ADD_EXECUTABLE(mip_test mip_test.cc)
93 97
  ELSE()
94 98
    ADD_EXECUTABLE(mip_test EXCLUDE_FROM_ALL mip_test.cc)
95 99
  ENDIF()
96 100

	
97 101
  SET(MIP_TEST_LIBS lemon)
98 102

	
99 103
  IF(LEMON_HAVE_GLPK)
100 104
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
101 105
  ENDIF()
102 106
  IF(LEMON_HAVE_CPLEX)
103 107
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
104 108
  ENDIF()
105 109
  IF(LEMON_HAVE_CBC)
106 110
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
107 111
  ENDIF()
108 112

	
109 113
  TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
110 114
  ADD_TEST(mip_test mip_test)
111 115
  ADD_DEPENDENCIES(check mip_test)
112 116

	
113 117
  IF(WIN32 AND LEMON_HAVE_GLPK)
114 118
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
115 119
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
116 120
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
117 121
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
118 122
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
119 123
      COMMAND ${CMAKE_COMMAND} -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
120 124
    )
121 125
  ENDIF()
122 126

	
123 127
  IF(WIN32 AND LEMON_HAVE_CPLEX)
124 128
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
125 129
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
126 130
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
127 131
      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
128 132
    )
129 133
  ENDIF()
130 134
ENDIF()
131 135

	
132 136
FOREACH(TEST_NAME ${TESTS})
133 137
  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
134 138
    ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
135 139
  ELSE()
136 140
    ADD_EXECUTABLE(${TEST_NAME} EXCLUDE_FROM_ALL ${TEST_NAME}.cc)
137 141
  ENDIF()
138 142
  TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
139 143
    IF(TEST_WITH_VALGRIND)
140 144
      ADD_TEST(${TEST_NAME}
141 145
        valgrind --error-exitcode=1 ${VALGRIND_FLAGS}
142 146
        ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME} )
143 147
    ELSE()
144 148
      ADD_TEST(${TEST_NAME} ${TEST_NAME})
145 149
    ENDIF()
146 150
  ADD_DEPENDENCIES(check ${TEST_NAME})
147 151
ENDFOREACH()
Ignore white space 6 line context
1
if USE_VALGRIND
2
TESTS_ENVIRONMENT=$(top_srcdir)/scripts/valgrind-wrapper.sh
3
endif
4

	
1 5
EXTRA_DIST += \
2 6
	test/CMakeLists.txt
3 7

	
4 8
noinst_HEADERS += \
5 9
	test/graph_test.h \
6 10
	test/test_tools.h
7 11

	
8 12
check_PROGRAMS += \
9 13
	test/adaptors_test \
14
	test/bellman_ford_test \
10 15
	test/bfs_test \
11 16
	test/circulation_test \
12 17
	test/connectivity_test \
13 18
	test/counter_test \
14 19
	test/dfs_test \
15 20
	test/digraph_test \
16 21
	test/dijkstra_test \
17 22
	test/dim_test \
18 23
	test/edge_set_test \
19 24
	test/error_test \
20 25
	test/euler_test \
26
	test/fractional_matching_test \
21 27
	test/gomory_hu_test \
22 28
	test/graph_copy_test \
23 29
	test/graph_test \
24 30
	test/graph_utils_test \
25 31
	test/hao_orlin_test \
26 32
	test/heap_test \
27 33
	test/kruskal_test \
28 34
	test/lgf_test \
29 35
	test/maps_test \
30 36
	test/matching_test \
31 37
	test/min_cost_arborescence_test \
32 38
	test/min_cost_flow_test \
39
	test/min_mean_cycle_test \
33 40
	test/path_test \
41
	test/planarity_test \
34 42
	test/preflow_test \
35 43
	test/radix_sort_test \
36 44
	test/random_test \
37 45
	test/suurballe_test \
38 46
	test/test_tools_fail \
39 47
	test/test_tools_pass \
40 48
	test/time_measure_test \
41 49
	test/unionfind_test
42 50

	
43 51
test_test_tools_pass_DEPENDENCIES = demo
44 52

	
45 53
if HAVE_LP
46 54
check_PROGRAMS += test/lp_test
47 55
endif HAVE_LP
48 56
if HAVE_MIP
49 57
check_PROGRAMS += test/mip_test
50 58
endif HAVE_MIP
51 59

	
52 60
TESTS += $(check_PROGRAMS)
53 61
XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
54 62

	
55 63
test_adaptors_test_SOURCES = test/adaptors_test.cc
64
test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
56 65
test_bfs_test_SOURCES = test/bfs_test.cc
57 66
test_circulation_test_SOURCES = test/circulation_test.cc
58 67
test_counter_test_SOURCES = test/counter_test.cc
59 68
test_connectivity_test_SOURCES = test/connectivity_test.cc
60 69
test_dfs_test_SOURCES = test/dfs_test.cc
61 70
test_digraph_test_SOURCES = test/digraph_test.cc
62 71
test_dijkstra_test_SOURCES = test/dijkstra_test.cc
63 72
test_dim_test_SOURCES = test/dim_test.cc
64 73
test_edge_set_test_SOURCES = test/edge_set_test.cc
65 74
test_error_test_SOURCES = test/error_test.cc
66 75
test_euler_test_SOURCES = test/euler_test.cc
76
test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc
67 77
test_gomory_hu_test_SOURCES = test/gomory_hu_test.cc
68 78
test_graph_copy_test_SOURCES = test/graph_copy_test.cc
69 79
test_graph_test_SOURCES = test/graph_test.cc
70 80
test_graph_utils_test_SOURCES = test/graph_utils_test.cc
71 81
test_heap_test_SOURCES = test/heap_test.cc
72 82
test_kruskal_test_SOURCES = test/kruskal_test.cc
73 83
test_hao_orlin_test_SOURCES = test/hao_orlin_test.cc
74 84
test_lgf_test_SOURCES = test/lgf_test.cc
75 85
test_lp_test_SOURCES = test/lp_test.cc
76 86
test_maps_test_SOURCES = test/maps_test.cc
77 87
test_mip_test_SOURCES = test/mip_test.cc
78 88
test_matching_test_SOURCES = test/matching_test.cc
79 89
test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
80 90
test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
91
test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
81 92
test_path_test_SOURCES = test/path_test.cc
93
test_planarity_test_SOURCES = test/planarity_test.cc
82 94
test_preflow_test_SOURCES = test/preflow_test.cc
83 95
test_radix_sort_test_SOURCES = test/radix_sort_test.cc
84 96
test_suurballe_test_SOURCES = test/suurballe_test.cc
85 97
test_random_test_SOURCES = test/random_test.cc
86 98
test_test_tools_fail_SOURCES = test/test_tools_fail.cc
87 99
test_test_tools_pass_SOURCES = test/test_tools_pass.cc
88 100
test_time_measure_test_SOURCES = test/time_measure_test.cc
89 101
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 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 <limits>
21 21

	
22 22
#include <lemon/list_graph.h>
23 23
#include <lemon/grid_graph.h>
24 24
#include <lemon/bfs.h>
25 25
#include <lemon/path.h>
26 26

	
27 27
#include <lemon/concepts/digraph.h>
28 28
#include <lemon/concepts/graph.h>
29 29
#include <lemon/concepts/graph_components.h>
30 30
#include <lemon/concepts/maps.h>
31 31
#include <lemon/concept_check.h>
32 32

	
33 33
#include <lemon/adaptors.h>
34 34

	
35 35
#include "test/test_tools.h"
36 36
#include "test/graph_test.h"
37 37

	
38 38
using namespace lemon;
39 39

	
40 40
void checkReverseDigraph() {
41 41
  // Check concepts
42 42
  checkConcept<concepts::Digraph, ReverseDigraph<concepts::Digraph> >();
43 43
  checkConcept<concepts::Digraph, ReverseDigraph<ListDigraph> >();
44 44
  checkConcept<concepts::AlterableDigraphComponent<>,
45 45
               ReverseDigraph<ListDigraph> >();
46 46
  checkConcept<concepts::ExtendableDigraphComponent<>,
47 47
               ReverseDigraph<ListDigraph> >();
48 48
  checkConcept<concepts::ErasableDigraphComponent<>,
49 49
               ReverseDigraph<ListDigraph> >();
50 50
  checkConcept<concepts::ClearableDigraphComponent<>,
51 51
               ReverseDigraph<ListDigraph> >();
52 52

	
53 53
  // Create a digraph and an adaptor
54 54
  typedef ListDigraph Digraph;
55 55
  typedef ReverseDigraph<Digraph> Adaptor;
56 56

	
57 57
  Digraph digraph;
58 58
  Adaptor adaptor(digraph);
59 59

	
60 60
  // Add nodes and arcs to the original digraph
61 61
  Digraph::Node n1 = digraph.addNode();
62 62
  Digraph::Node n2 = digraph.addNode();
63 63
  Digraph::Node n3 = digraph.addNode();
64 64

	
65 65
  Digraph::Arc a1 = digraph.addArc(n1, n2);
66 66
  Digraph::Arc a2 = digraph.addArc(n1, n3);
67 67
  Digraph::Arc a3 = digraph.addArc(n2, n3);
68 68

	
69 69
  // Check the adaptor
70 70
  checkGraphNodeList(adaptor, 3);
71 71
  checkGraphArcList(adaptor, 3);
72 72
  checkGraphConArcList(adaptor, 3);
73 73

	
74 74
  checkGraphOutArcList(adaptor, n1, 0);
75 75
  checkGraphOutArcList(adaptor, n2, 1);
76 76
  checkGraphOutArcList(adaptor, n3, 2);
77 77

	
78 78
  checkGraphInArcList(adaptor, n1, 2);
79 79
  checkGraphInArcList(adaptor, n2, 1);
80 80
  checkGraphInArcList(adaptor, n3, 0);
81 81

	
82 82
  checkNodeIds(adaptor);
83 83
  checkArcIds(adaptor);
84 84

	
85 85
  checkGraphNodeMap(adaptor);
86 86
  checkGraphArcMap(adaptor);
87 87

	
88 88
  // Check the orientation of the arcs
89 89
  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
90 90
    check(adaptor.source(a) == digraph.target(a), "Wrong reverse");
91 91
    check(adaptor.target(a) == digraph.source(a), "Wrong reverse");
92 92
  }
93 93

	
94 94
  // Add and erase nodes and arcs in the digraph through the adaptor
95 95
  Adaptor::Node n4 = adaptor.addNode();
96 96

	
97 97
  Adaptor::Arc a4 = adaptor.addArc(n4, n3);
98 98
  Adaptor::Arc a5 = adaptor.addArc(n2, n4);
99 99
  Adaptor::Arc a6 = adaptor.addArc(n2, n4);
100 100
  Adaptor::Arc a7 = adaptor.addArc(n1, n4);
101 101
  Adaptor::Arc a8 = adaptor.addArc(n1, n2);
102 102

	
103 103
  adaptor.erase(a1);
104 104
  adaptor.erase(n3);
105 105

	
106 106
  // Check the adaptor
107 107
  checkGraphNodeList(adaptor, 3);
108 108
  checkGraphArcList(adaptor, 4);
109 109
  checkGraphConArcList(adaptor, 4);
110 110

	
111 111
  checkGraphOutArcList(adaptor, n1, 2);
112 112
  checkGraphOutArcList(adaptor, n2, 2);
113 113
  checkGraphOutArcList(adaptor, n4, 0);
114 114

	
115 115
  checkGraphInArcList(adaptor, n1, 0);
116 116
  checkGraphInArcList(adaptor, n2, 1);
117 117
  checkGraphInArcList(adaptor, n4, 3);
118 118

	
119 119
  checkNodeIds(adaptor);
120 120
  checkArcIds(adaptor);
121 121

	
122 122
  checkGraphNodeMap(adaptor);
123 123
  checkGraphArcMap(adaptor);
124 124

	
125 125
  // Check the digraph
126 126
  checkGraphNodeList(digraph, 3);
127 127
  checkGraphArcList(digraph, 4);
128 128
  checkGraphConArcList(digraph, 4);
129 129

	
130 130
  checkGraphOutArcList(digraph, n1, 0);
131 131
  checkGraphOutArcList(digraph, n2, 1);
132 132
  checkGraphOutArcList(digraph, n4, 3);
133 133

	
134 134
  checkGraphInArcList(digraph, n1, 2);
135 135
  checkGraphInArcList(digraph, n2, 2);
136 136
  checkGraphInArcList(digraph, n4, 0);
137 137

	
138 138
  checkNodeIds(digraph);
139 139
  checkArcIds(digraph);
140 140

	
141 141
  checkGraphNodeMap(digraph);
142 142
  checkGraphArcMap(digraph);
143 143

	
144 144
  // Check the conversion of nodes and arcs
145 145
  Digraph::Node nd = n4;
146 146
  nd = n4;
147 147
  Adaptor::Node na = n1;
148 148
  na = n2;
149 149
  Digraph::Arc ad = a4;
150 150
  ad = a5;
151 151
  Adaptor::Arc aa = a1;
152 152
  aa = a2;
153 153
}
154 154

	
155 155
void checkSubDigraph() {
156 156
  // Check concepts
157 157
  checkConcept<concepts::Digraph, SubDigraph<concepts::Digraph> >();
158 158
  checkConcept<concepts::Digraph, SubDigraph<ListDigraph> >();
159 159
  checkConcept<concepts::AlterableDigraphComponent<>,
160 160
               SubDigraph<ListDigraph> >();
161 161
  checkConcept<concepts::ExtendableDigraphComponent<>,
162 162
               SubDigraph<ListDigraph> >();
163 163
  checkConcept<concepts::ErasableDigraphComponent<>,
164 164
               SubDigraph<ListDigraph> >();
165 165
  checkConcept<concepts::ClearableDigraphComponent<>,
166 166
               SubDigraph<ListDigraph> >();
167 167

	
168 168
  // Create a digraph and an adaptor
169 169
  typedef ListDigraph Digraph;
170 170
  typedef Digraph::NodeMap<bool> NodeFilter;
171 171
  typedef Digraph::ArcMap<bool> ArcFilter;
172 172
  typedef SubDigraph<Digraph, NodeFilter, ArcFilter> Adaptor;
173 173

	
174 174
  Digraph digraph;
175 175
  NodeFilter node_filter(digraph);
176 176
  ArcFilter arc_filter(digraph);
177 177
  Adaptor adaptor(digraph, node_filter, arc_filter);
178 178

	
179 179
  // Add nodes and arcs to the original digraph and the adaptor
180 180
  Digraph::Node n1 = digraph.addNode();
181 181
  Digraph::Node n2 = digraph.addNode();
182 182
  Adaptor::Node n3 = adaptor.addNode();
183 183

	
184 184
  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
185 185

	
186 186
  Digraph::Arc a1 = digraph.addArc(n1, n2);
187 187
  Digraph::Arc a2 = digraph.addArc(n1, n3);
188 188
  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
189 189

	
190 190
  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
191 191

	
192 192
  checkGraphNodeList(adaptor, 3);
193 193
  checkGraphArcList(adaptor, 3);
194 194
  checkGraphConArcList(adaptor, 3);
195 195

	
196 196
  checkGraphOutArcList(adaptor, n1, 2);
197 197
  checkGraphOutArcList(adaptor, n2, 1);
198 198
  checkGraphOutArcList(adaptor, n3, 0);
199 199

	
200 200
  checkGraphInArcList(adaptor, n1, 0);
201 201
  checkGraphInArcList(adaptor, n2, 1);
202 202
  checkGraphInArcList(adaptor, n3, 2);
203 203

	
204 204
  checkNodeIds(adaptor);
205 205
  checkArcIds(adaptor);
206 206

	
207 207
  checkGraphNodeMap(adaptor);
208 208
  checkGraphArcMap(adaptor);
209 209

	
210 210
  // Hide an arc
211 211
  adaptor.status(a2, false);
212 212
  adaptor.disable(a3);
213 213
  if (!adaptor.status(a3)) adaptor.enable(a3);
214 214

	
215 215
  checkGraphNodeList(adaptor, 3);
216 216
  checkGraphArcList(adaptor, 2);
217 217
  checkGraphConArcList(adaptor, 2);
218 218

	
219 219
  checkGraphOutArcList(adaptor, n1, 1);
220 220
  checkGraphOutArcList(adaptor, n2, 1);
221 221
  checkGraphOutArcList(adaptor, n3, 0);
222 222

	
223 223
  checkGraphInArcList(adaptor, n1, 0);
224 224
  checkGraphInArcList(adaptor, n2, 1);
225 225
  checkGraphInArcList(adaptor, n3, 1);
226 226

	
227 227
  checkNodeIds(adaptor);
228 228
  checkArcIds(adaptor);
229 229

	
230 230
  checkGraphNodeMap(adaptor);
231 231
  checkGraphArcMap(adaptor);
232 232

	
233 233
  // Hide a node
234 234
  adaptor.status(n1, false);
235 235
  adaptor.disable(n3);
236 236
  if (!adaptor.status(n3)) adaptor.enable(n3);
237 237

	
238 238
  checkGraphNodeList(adaptor, 2);
239 239
  checkGraphArcList(adaptor, 1);
240 240
  checkGraphConArcList(adaptor, 1);
241 241

	
242 242
  checkGraphOutArcList(adaptor, n2, 1);
243 243
  checkGraphOutArcList(adaptor, n3, 0);
244 244

	
245 245
  checkGraphInArcList(adaptor, n2, 0);
246 246
  checkGraphInArcList(adaptor, n3, 1);
247 247

	
248 248
  checkNodeIds(adaptor);
249 249
  checkArcIds(adaptor);
250 250

	
251 251
  checkGraphNodeMap(adaptor);
252 252
  checkGraphArcMap(adaptor);
253 253

	
254 254
  // Hide all nodes and arcs
255 255
  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
256 256
  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
257 257

	
258 258
  checkGraphNodeList(adaptor, 0);
259 259
  checkGraphArcList(adaptor, 0);
260 260
  checkGraphConArcList(adaptor, 0);
261 261

	
262 262
  checkNodeIds(adaptor);
263 263
  checkArcIds(adaptor);
264 264

	
265 265
  checkGraphNodeMap(adaptor);
266 266
  checkGraphArcMap(adaptor);
267 267

	
268 268
  // Check the conversion of nodes and arcs
269 269
  Digraph::Node nd = n3;
270 270
  nd = n3;
271 271
  Adaptor::Node na = n1;
272 272
  na = n2;
273 273
  Digraph::Arc ad = a3;
274 274
  ad = a3;
275 275
  Adaptor::Arc aa = a1;
276 276
  aa = a2;
277 277
}
278 278

	
279 279
void checkFilterNodes1() {
280 280
  // Check concepts
281 281
  checkConcept<concepts::Digraph, FilterNodes<concepts::Digraph> >();
282 282
  checkConcept<concepts::Digraph, FilterNodes<ListDigraph> >();
283 283
  checkConcept<concepts::AlterableDigraphComponent<>,
284 284
               FilterNodes<ListDigraph> >();
285 285
  checkConcept<concepts::ExtendableDigraphComponent<>,
286 286
               FilterNodes<ListDigraph> >();
287 287
  checkConcept<concepts::ErasableDigraphComponent<>,
288 288
               FilterNodes<ListDigraph> >();
289 289
  checkConcept<concepts::ClearableDigraphComponent<>,
290 290
               FilterNodes<ListDigraph> >();
291 291

	
292 292
  // Create a digraph and an adaptor
293 293
  typedef ListDigraph Digraph;
294 294
  typedef Digraph::NodeMap<bool> NodeFilter;
295 295
  typedef FilterNodes<Digraph, NodeFilter> Adaptor;
296 296

	
297 297
  Digraph digraph;
298 298
  NodeFilter node_filter(digraph);
299 299
  Adaptor adaptor(digraph, node_filter);
300 300

	
301 301
  // Add nodes and arcs to the original digraph and the adaptor
302 302
  Digraph::Node n1 = digraph.addNode();
303 303
  Digraph::Node n2 = digraph.addNode();
304 304
  Adaptor::Node n3 = adaptor.addNode();
305 305

	
306 306
  node_filter[n1] = node_filter[n2] = node_filter[n3] = true;
307 307

	
308 308
  Digraph::Arc a1 = digraph.addArc(n1, n2);
309 309
  Digraph::Arc a2 = digraph.addArc(n1, n3);
310 310
  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
311 311

	
312 312
  checkGraphNodeList(adaptor, 3);
313 313
  checkGraphArcList(adaptor, 3);
314 314
  checkGraphConArcList(adaptor, 3);
315 315

	
316 316
  checkGraphOutArcList(adaptor, n1, 2);
317 317
  checkGraphOutArcList(adaptor, n2, 1);
318 318
  checkGraphOutArcList(adaptor, n3, 0);
319 319

	
320 320
  checkGraphInArcList(adaptor, n1, 0);
321 321
  checkGraphInArcList(adaptor, n2, 1);
322 322
  checkGraphInArcList(adaptor, n3, 2);
323 323

	
324 324
  checkNodeIds(adaptor);
325 325
  checkArcIds(adaptor);
326 326

	
327 327
  checkGraphNodeMap(adaptor);
328 328
  checkGraphArcMap(adaptor);
329 329

	
330 330
  // Hide a node
331 331
  adaptor.status(n1, false);
332 332
  adaptor.disable(n3);
333 333
  if (!adaptor.status(n3)) adaptor.enable(n3);
334 334

	
335 335
  checkGraphNodeList(adaptor, 2);
336 336
  checkGraphArcList(adaptor, 1);
337 337
  checkGraphConArcList(adaptor, 1);
338 338

	
339 339
  checkGraphOutArcList(adaptor, n2, 1);
340 340
  checkGraphOutArcList(adaptor, n3, 0);
341 341

	
342 342
  checkGraphInArcList(adaptor, n2, 0);
343 343
  checkGraphInArcList(adaptor, n3, 1);
344 344

	
345 345
  checkNodeIds(adaptor);
346 346
  checkArcIds(adaptor);
347 347

	
348 348
  checkGraphNodeMap(adaptor);
349 349
  checkGraphArcMap(adaptor);
350 350

	
351 351
  // Hide all nodes
352 352
  node_filter[n1] = node_filter[n2] = node_filter[n3] = false;
353 353

	
354 354
  checkGraphNodeList(adaptor, 0);
355 355
  checkGraphArcList(adaptor, 0);
356 356
  checkGraphConArcList(adaptor, 0);
357 357

	
358 358
  checkNodeIds(adaptor);
359 359
  checkArcIds(adaptor);
360 360

	
361 361
  checkGraphNodeMap(adaptor);
362 362
  checkGraphArcMap(adaptor);
363 363

	
364 364
  // Check the conversion of nodes and arcs
365 365
  Digraph::Node nd = n3;
366 366
  nd = n3;
367 367
  Adaptor::Node na = n1;
368 368
  na = n2;
369 369
  Digraph::Arc ad = a3;
370 370
  ad = a3;
371 371
  Adaptor::Arc aa = a1;
372 372
  aa = a2;
373 373
}
374 374

	
375 375
void checkFilterArcs() {
376 376
  // Check concepts
377 377
  checkConcept<concepts::Digraph, FilterArcs<concepts::Digraph> >();
378 378
  checkConcept<concepts::Digraph, FilterArcs<ListDigraph> >();
379 379
  checkConcept<concepts::AlterableDigraphComponent<>,
380 380
               FilterArcs<ListDigraph> >();
381 381
  checkConcept<concepts::ExtendableDigraphComponent<>,
382 382
               FilterArcs<ListDigraph> >();
383 383
  checkConcept<concepts::ErasableDigraphComponent<>,
384 384
               FilterArcs<ListDigraph> >();
385 385
  checkConcept<concepts::ClearableDigraphComponent<>,
386 386
               FilterArcs<ListDigraph> >();
387 387

	
388 388
  // Create a digraph and an adaptor
389 389
  typedef ListDigraph Digraph;
390 390
  typedef Digraph::ArcMap<bool> ArcFilter;
391 391
  typedef FilterArcs<Digraph, ArcFilter> Adaptor;
392 392

	
393 393
  Digraph digraph;
394 394
  ArcFilter arc_filter(digraph);
395 395
  Adaptor adaptor(digraph, arc_filter);
396 396

	
397 397
  // Add nodes and arcs to the original digraph and the adaptor
398 398
  Digraph::Node n1 = digraph.addNode();
399 399
  Digraph::Node n2 = digraph.addNode();
400 400
  Adaptor::Node n3 = adaptor.addNode();
401 401

	
402 402
  Digraph::Arc a1 = digraph.addArc(n1, n2);
403 403
  Digraph::Arc a2 = digraph.addArc(n1, n3);
404 404
  Adaptor::Arc a3 = adaptor.addArc(n2, n3);
405 405

	
406 406
  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = true;
407 407

	
408 408
  checkGraphNodeList(adaptor, 3);
409 409
  checkGraphArcList(adaptor, 3);
410 410
  checkGraphConArcList(adaptor, 3);
411 411

	
412 412
  checkGraphOutArcList(adaptor, n1, 2);
413 413
  checkGraphOutArcList(adaptor, n2, 1);
414 414
  checkGraphOutArcList(adaptor, n3, 0);
415 415

	
416 416
  checkGraphInArcList(adaptor, n1, 0);
417 417
  checkGraphInArcList(adaptor, n2, 1);
418 418
  checkGraphInArcList(adaptor, n3, 2);
419 419

	
420 420
  checkNodeIds(adaptor);
421 421
  checkArcIds(adaptor);
422 422

	
423 423
  checkGraphNodeMap(adaptor);
424 424
  checkGraphArcMap(adaptor);
425 425

	
426 426
  // Hide an arc
427 427
  adaptor.status(a2, false);
428 428
  adaptor.disable(a3);
429 429
  if (!adaptor.status(a3)) adaptor.enable(a3);
430 430

	
431 431
  checkGraphNodeList(adaptor, 3);
432 432
  checkGraphArcList(adaptor, 2);
433 433
  checkGraphConArcList(adaptor, 2);
434 434

	
435 435
  checkGraphOutArcList(adaptor, n1, 1);
436 436
  checkGraphOutArcList(adaptor, n2, 1);
437 437
  checkGraphOutArcList(adaptor, n3, 0);
438 438

	
439 439
  checkGraphInArcList(adaptor, n1, 0);
440 440
  checkGraphInArcList(adaptor, n2, 1);
441 441
  checkGraphInArcList(adaptor, n3, 1);
442 442

	
443 443
  checkNodeIds(adaptor);
444 444
  checkArcIds(adaptor);
445 445

	
446 446
  checkGraphNodeMap(adaptor);
447 447
  checkGraphArcMap(adaptor);
448 448

	
449 449
  // Hide all arcs
450 450
  arc_filter[a1] = arc_filter[a2] = arc_filter[a3] = false;
451 451

	
452 452
  checkGraphNodeList(adaptor, 3);
453 453
  checkGraphArcList(adaptor, 0);
454 454
  checkGraphConArcList(adaptor, 0);
455 455

	
456 456
  checkNodeIds(adaptor);
457 457
  checkArcIds(adaptor);
458 458

	
459 459
  checkGraphNodeMap(adaptor);
460 460
  checkGraphArcMap(adaptor);
461 461

	
462 462
  // Check the conversion of nodes and arcs
463 463
  Digraph::Node nd = n3;
464 464
  nd = n3;
465 465
  Adaptor::Node na = n1;
466 466
  na = n2;
467 467
  Digraph::Arc ad = a3;
468 468
  ad = a3;
469 469
  Adaptor::Arc aa = a1;
470 470
  aa = a2;
471 471
}
472 472

	
473 473
void checkUndirector() {
474 474
  // Check concepts
475 475
  checkConcept<concepts::Graph, Undirector<concepts::Digraph> >();
476 476
  checkConcept<concepts::Graph, Undirector<ListDigraph> >();
477 477
  checkConcept<concepts::AlterableGraphComponent<>,
478 478
               Undirector<ListDigraph> >();
479 479
  checkConcept<concepts::ExtendableGraphComponent<>,
480 480
               Undirector<ListDigraph> >();
481 481
  checkConcept<concepts::ErasableGraphComponent<>,
482 482
               Undirector<ListDigraph> >();
483 483
  checkConcept<concepts::ClearableGraphComponent<>,
484 484
               Undirector<ListDigraph> >();
485 485

	
486 486

	
487 487
  // Create a digraph and an adaptor
488 488
  typedef ListDigraph Digraph;
489 489
  typedef Undirector<Digraph> Adaptor;
490 490

	
491 491
  Digraph digraph;
492 492
  Adaptor adaptor(digraph);
493 493

	
494 494
  // Add nodes and arcs/edges to the original digraph and the adaptor
495 495
  Digraph::Node n1 = digraph.addNode();
496 496
  Digraph::Node n2 = digraph.addNode();
497 497
  Adaptor::Node n3 = adaptor.addNode();
498 498

	
499 499
  Digraph::Arc a1 = digraph.addArc(n1, n2);
500 500
  Digraph::Arc a2 = digraph.addArc(n1, n3);
501 501
  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
502 502

	
503 503
  // Check the original digraph
504 504
  checkGraphNodeList(digraph, 3);
505 505
  checkGraphArcList(digraph, 3);
506 506
  checkGraphConArcList(digraph, 3);
507 507

	
508 508
  checkGraphOutArcList(digraph, n1, 2);
509 509
  checkGraphOutArcList(digraph, n2, 1);
510 510
  checkGraphOutArcList(digraph, n3, 0);
511 511

	
512 512
  checkGraphInArcList(digraph, n1, 0);
513 513
  checkGraphInArcList(digraph, n2, 1);
514 514
  checkGraphInArcList(digraph, n3, 2);
515 515

	
516 516
  checkNodeIds(digraph);
517 517
  checkArcIds(digraph);
518 518

	
519 519
  checkGraphNodeMap(digraph);
520 520
  checkGraphArcMap(digraph);
521 521

	
522 522
  // Check the adaptor
523 523
  checkGraphNodeList(adaptor, 3);
524 524
  checkGraphArcList(adaptor, 6);
525 525
  checkGraphEdgeList(adaptor, 3);
526 526
  checkGraphConArcList(adaptor, 6);
527 527
  checkGraphConEdgeList(adaptor, 3);
528 528

	
529 529
  checkGraphIncEdgeArcLists(adaptor, n1, 2);
530 530
  checkGraphIncEdgeArcLists(adaptor, n2, 2);
531 531
  checkGraphIncEdgeArcLists(adaptor, n3, 2);
532 532

	
533 533
  checkNodeIds(adaptor);
534 534
  checkArcIds(adaptor);
535 535
  checkEdgeIds(adaptor);
536 536

	
537 537
  checkGraphNodeMap(adaptor);
538 538
  checkGraphArcMap(adaptor);
539 539
  checkGraphEdgeMap(adaptor);
540 540

	
541 541
  // Check the edges of the adaptor
542 542
  for (Adaptor::EdgeIt e(adaptor); e != INVALID; ++e) {
543 543
    check(adaptor.u(e) == digraph.source(e), "Wrong undir");
544 544
    check(adaptor.v(e) == digraph.target(e), "Wrong undir");
545 545
  }
546 546

	
547 547
  // Check CombinedArcMap
548 548
  typedef Adaptor::CombinedArcMap
549 549
    <Digraph::ArcMap<int>, Digraph::ArcMap<int> > IntCombinedMap;
550 550
  typedef Adaptor::CombinedArcMap
551 551
    <Digraph::ArcMap<bool>, Digraph::ArcMap<bool> > BoolCombinedMap;
552 552
  checkConcept<concepts::ReferenceMap<Adaptor::Arc, int, int&, const int&>,
553 553
    IntCombinedMap>();
554 554
  checkConcept<concepts::ReferenceMap<Adaptor::Arc, bool, bool&, const bool&>,
555 555
    BoolCombinedMap>();
556 556

	
557 557
  Digraph::ArcMap<int> fw_map(digraph), bk_map(digraph);
558 558
  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
559 559
    fw_map[a] = digraph.id(a);
560 560
    bk_map[a] = -digraph.id(a);
561 561
  }
562 562

	
563 563
  Adaptor::CombinedArcMap<Digraph::ArcMap<int>, Digraph::ArcMap<int> >
564 564
    comb_map(fw_map, bk_map);
565 565
  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
566 566
    if (adaptor.source(a) == digraph.source(a)) {
567 567
      check(comb_map[a] == fw_map[a], "Wrong combined map");
568 568
    } else {
569 569
      check(comb_map[a] == bk_map[a], "Wrong combined map");
570 570
    }
571 571
  }
572 572

	
573 573
  // Check the conversion of nodes and arcs/edges
574 574
  Digraph::Node nd = n3;
575 575
  nd = n3;
576 576
  Adaptor::Node na = n1;
577 577
  na = n2;
578 578
  Digraph::Arc ad = e3;
579 579
  ad = e3;
580 580
  Adaptor::Edge ea = a1;
581 581
  ea = a2;
582 582
}
583 583

	
584 584
void checkResidualDigraph() {
585 585
  // Check concepts
586 586
  checkConcept<concepts::Digraph, ResidualDigraph<concepts::Digraph> >();
587 587
  checkConcept<concepts::Digraph, ResidualDigraph<ListDigraph> >();
588 588

	
589 589
  // Create a digraph and an adaptor
590 590
  typedef ListDigraph Digraph;
591 591
  typedef Digraph::ArcMap<int> IntArcMap;
592 592
  typedef ResidualDigraph<Digraph, IntArcMap> Adaptor;
593 593

	
594 594
  Digraph digraph;
595 595
  IntArcMap capacity(digraph), flow(digraph);
596 596
  Adaptor adaptor(digraph, capacity, flow);
597 597

	
598 598
  Digraph::Node n1 = digraph.addNode();
599 599
  Digraph::Node n2 = digraph.addNode();
600 600
  Digraph::Node n3 = digraph.addNode();
601 601
  Digraph::Node n4 = digraph.addNode();
602 602

	
603 603
  Digraph::Arc a1 = digraph.addArc(n1, n2);
604 604
  Digraph::Arc a2 = digraph.addArc(n1, n3);
605 605
  Digraph::Arc a3 = digraph.addArc(n1, n4);
606 606
  Digraph::Arc a4 = digraph.addArc(n2, n3);
607 607
  Digraph::Arc a5 = digraph.addArc(n2, n4);
608 608
  Digraph::Arc a6 = digraph.addArc(n3, n4);
609 609

	
610 610
  capacity[a1] = 8;
611 611
  capacity[a2] = 6;
612 612
  capacity[a3] = 4;
613 613
  capacity[a4] = 4;
614 614
  capacity[a5] = 6;
615 615
  capacity[a6] = 10;
616 616

	
617 617
  // Check the adaptor with various flow values
618 618
  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
619 619
    flow[a] = 0;
620 620
  }
621 621

	
622 622
  checkGraphNodeList(adaptor, 4);
623 623
  checkGraphArcList(adaptor, 6);
624 624
  checkGraphConArcList(adaptor, 6);
625 625

	
626 626
  checkGraphOutArcList(adaptor, n1, 3);
627 627
  checkGraphOutArcList(adaptor, n2, 2);
628 628
  checkGraphOutArcList(adaptor, n3, 1);
629 629
  checkGraphOutArcList(adaptor, n4, 0);
630 630

	
631 631
  checkGraphInArcList(adaptor, n1, 0);
632 632
  checkGraphInArcList(adaptor, n2, 1);
633 633
  checkGraphInArcList(adaptor, n3, 2);
634 634
  checkGraphInArcList(adaptor, n4, 3);
635 635

	
636 636
  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
637 637
    flow[a] = capacity[a] / 2;
638 638
  }
639 639

	
640 640
  checkGraphNodeList(adaptor, 4);
641 641
  checkGraphArcList(adaptor, 12);
642 642
  checkGraphConArcList(adaptor, 12);
643 643

	
644 644
  checkGraphOutArcList(adaptor, n1, 3);
645 645
  checkGraphOutArcList(adaptor, n2, 3);
646 646
  checkGraphOutArcList(adaptor, n3, 3);
647 647
  checkGraphOutArcList(adaptor, n4, 3);
648 648

	
649 649
  checkGraphInArcList(adaptor, n1, 3);
650 650
  checkGraphInArcList(adaptor, n2, 3);
651 651
  checkGraphInArcList(adaptor, n3, 3);
652 652
  checkGraphInArcList(adaptor, n4, 3);
653 653

	
654 654
  checkNodeIds(adaptor);
655 655
  checkArcIds(adaptor);
656 656

	
657 657
  checkGraphNodeMap(adaptor);
658 658
  checkGraphArcMap(adaptor);
659 659

	
660 660
  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
661 661
    flow[a] = capacity[a];
662 662
  }
663 663

	
664 664
  checkGraphNodeList(adaptor, 4);
665 665
  checkGraphArcList(adaptor, 6);
666 666
  checkGraphConArcList(adaptor, 6);
667 667

	
668 668
  checkGraphOutArcList(adaptor, n1, 0);
669 669
  checkGraphOutArcList(adaptor, n2, 1);
670 670
  checkGraphOutArcList(adaptor, n3, 2);
671 671
  checkGraphOutArcList(adaptor, n4, 3);
672 672

	
673 673
  checkGraphInArcList(adaptor, n1, 3);
674 674
  checkGraphInArcList(adaptor, n2, 2);
675 675
  checkGraphInArcList(adaptor, n3, 1);
676 676
  checkGraphInArcList(adaptor, n4, 0);
677 677

	
678 678
  // Saturate all backward arcs
679 679
  // (set the flow to zero on all forward arcs)
680 680
  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
681 681
    if (adaptor.backward(a))
682 682
      adaptor.augment(a, adaptor.residualCapacity(a));
683 683
  }
684 684

	
685 685
  checkGraphNodeList(adaptor, 4);
686 686
  checkGraphArcList(adaptor, 6);
687 687
  checkGraphConArcList(adaptor, 6);
688 688

	
689 689
  checkGraphOutArcList(adaptor, n1, 3);
690 690
  checkGraphOutArcList(adaptor, n2, 2);
691 691
  checkGraphOutArcList(adaptor, n3, 1);
692 692
  checkGraphOutArcList(adaptor, n4, 0);
693 693

	
694 694
  checkGraphInArcList(adaptor, n1, 0);
695 695
  checkGraphInArcList(adaptor, n2, 1);
696 696
  checkGraphInArcList(adaptor, n3, 2);
697 697
  checkGraphInArcList(adaptor, n4, 3);
698 698

	
699 699
  // Find maximum flow by augmenting along shortest paths
700 700
  int flow_value = 0;
701 701
  Adaptor::ResidualCapacity res_cap(adaptor);
702 702
  while (true) {
703 703

	
704 704
    Bfs<Adaptor> bfs(adaptor);
705 705
    bfs.run(n1, n4);
706 706

	
707 707
    if (!bfs.reached(n4)) break;
708 708

	
709 709
    Path<Adaptor> p = bfs.path(n4);
710 710

	
711 711
    int min = std::numeric_limits<int>::max();
712 712
    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
713 713
      if (res_cap[a] < min) min = res_cap[a];
714 714
    }
715 715

	
716 716
    for (Path<Adaptor>::ArcIt a(p); a != INVALID; ++a) {
717 717
      adaptor.augment(a, min);
718 718
    }
719 719
    flow_value += min;
720 720
  }
721 721

	
722 722
  check(flow_value == 18, "Wrong flow with res graph adaptor");
723 723

	
724 724
  // Check forward() and backward()
725 725
  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
726 726
    check(adaptor.forward(a) != adaptor.backward(a),
727 727
          "Wrong forward() or backward()");
728 728
    check((adaptor.forward(a) && adaptor.forward(Digraph::Arc(a)) == a) ||
729 729
          (adaptor.backward(a) && adaptor.backward(Digraph::Arc(a)) == a),
730 730
          "Wrong forward() or backward()");
731 731
  }
732 732

	
733 733
  // Check the conversion of nodes and arcs
734 734
  Digraph::Node nd = Adaptor::NodeIt(adaptor);
735 735
  nd = ++Adaptor::NodeIt(adaptor);
736 736
  Adaptor::Node na = n1;
737 737
  na = n2;
738 738
  Digraph::Arc ad = Adaptor::ArcIt(adaptor);
739 739
  ad = ++Adaptor::ArcIt(adaptor);
740 740
}
741 741

	
742 742
void checkSplitNodes() {
743 743
  // Check concepts
744 744
  checkConcept<concepts::Digraph, SplitNodes<concepts::Digraph> >();
745 745
  checkConcept<concepts::Digraph, SplitNodes<ListDigraph> >();
746 746

	
747 747
  // Create a digraph and an adaptor
748 748
  typedef ListDigraph Digraph;
749 749
  typedef SplitNodes<Digraph> Adaptor;
750 750

	
751 751
  Digraph digraph;
752 752
  Adaptor adaptor(digraph);
753 753

	
754 754
  Digraph::Node n1 = digraph.addNode();
755 755
  Digraph::Node n2 = digraph.addNode();
756 756
  Digraph::Node n3 = digraph.addNode();
757 757

	
758 758
  Digraph::Arc a1 = digraph.addArc(n1, n2);
759 759
  Digraph::Arc a2 = digraph.addArc(n1, n3);
760 760
  Digraph::Arc a3 = digraph.addArc(n2, n3);
761 761

	
762 762
  checkGraphNodeList(adaptor, 6);
763 763
  checkGraphArcList(adaptor, 6);
764 764
  checkGraphConArcList(adaptor, 6);
765 765

	
766 766
  checkGraphOutArcList(adaptor, adaptor.inNode(n1), 1);
767 767
  checkGraphOutArcList(adaptor, adaptor.outNode(n1), 2);
768 768
  checkGraphOutArcList(adaptor, adaptor.inNode(n2), 1);
769 769
  checkGraphOutArcList(adaptor, adaptor.outNode(n2), 1);
770 770
  checkGraphOutArcList(adaptor, adaptor.inNode(n3), 1);
771 771
  checkGraphOutArcList(adaptor, adaptor.outNode(n3), 0);
772 772

	
773 773
  checkGraphInArcList(adaptor, adaptor.inNode(n1), 0);
774 774
  checkGraphInArcList(adaptor, adaptor.outNode(n1), 1);
775 775
  checkGraphInArcList(adaptor, adaptor.inNode(n2), 1);
776 776
  checkGraphInArcList(adaptor, adaptor.outNode(n2), 1);
777 777
  checkGraphInArcList(adaptor, adaptor.inNode(n3), 2);
778 778
  checkGraphInArcList(adaptor, adaptor.outNode(n3), 1);
779 779

	
780 780
  checkNodeIds(adaptor);
781 781
  checkArcIds(adaptor);
782 782

	
783 783
  checkGraphNodeMap(adaptor);
784 784
  checkGraphArcMap(adaptor);
785 785

	
786 786
  // Check split
787 787
  for (Adaptor::ArcIt a(adaptor); a != INVALID; ++a) {
788 788
    if (adaptor.origArc(a)) {
789 789
      Digraph::Arc oa = a;
790 790
      check(adaptor.source(a) == adaptor.outNode(digraph.source(oa)),
791 791
            "Wrong split");
792 792
      check(adaptor.target(a) == adaptor.inNode(digraph.target(oa)),
793 793
            "Wrong split");
794 794
    } else {
795 795
      Digraph::Node on = a;
796 796
      check(adaptor.source(a) == adaptor.inNode(on), "Wrong split");
797 797
      check(adaptor.target(a) == adaptor.outNode(on), "Wrong split");
798 798
    }
799 799
  }
800 800

	
801 801
  // Check combined node map
802 802
  typedef Adaptor::CombinedNodeMap
803 803
    <Digraph::NodeMap<int>, Digraph::NodeMap<int> > IntCombinedNodeMap;
804 804
  typedef Adaptor::CombinedNodeMap
805 805
    <Digraph::NodeMap<bool>, Digraph::NodeMap<bool> > BoolCombinedNodeMap;
806 806
  checkConcept<concepts::ReferenceMap<Adaptor::Node, int, int&, const int&>,
807 807
    IntCombinedNodeMap>();
808 808
//checkConcept<concepts::ReferenceMap<Adaptor::Node, bool, bool&, const bool&>,
809 809
//  BoolCombinedNodeMap>();
810 810
  checkConcept<concepts::ReadWriteMap<Adaptor::Node, bool>,
811 811
    BoolCombinedNodeMap>();
812 812

	
813 813
  Digraph::NodeMap<int> in_map(digraph), out_map(digraph);
814 814
  for (Digraph::NodeIt n(digraph); n != INVALID; ++n) {
815 815
    in_map[n] = digraph.id(n);
816 816
    out_map[n] = -digraph.id(n);
817 817
  }
818 818

	
819 819
  Adaptor::CombinedNodeMap<Digraph::NodeMap<int>, Digraph::NodeMap<int> >
820 820
    node_map(in_map, out_map);
821 821
  for (Adaptor::NodeIt n(adaptor); n != INVALID; ++n) {
822 822
    if (adaptor.inNode(n)) {
823 823
      check(node_map[n] == in_map[n], "Wrong combined node map");
824 824
    } else {
825 825
      check(node_map[n] == out_map[n], "Wrong combined node map");
826 826
    }
827 827
  }
828 828

	
829 829
  // Check combined arc map
830 830
  typedef Adaptor::CombinedArcMap
831 831
    <Digraph::ArcMap<int>, Digraph::NodeMap<int> > IntCombinedArcMap;
832 832
  typedef Adaptor::CombinedArcMap
833 833
    <Digraph::ArcMap<bool>, Digraph::NodeMap<bool> > BoolCombinedArcMap;
834 834
  checkConcept<concepts::ReferenceMap<Adaptor::Arc, int, int&, const int&>,
835 835
    IntCombinedArcMap>();
836 836
//checkConcept<concepts::ReferenceMap<Adaptor::Arc, bool, bool&, const bool&>,
837 837
//  BoolCombinedArcMap>();
838 838
  checkConcept<concepts::ReadWriteMap<Adaptor::Arc, bool>,
839 839
    BoolCombinedArcMap>();
840 840

	
841 841
  Digraph::ArcMap<int> a_map(digraph);
842 842
  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
843 843
    a_map[a] = digraph.id(a);
844 844
  }
845 845

	
846 846
  Adaptor::CombinedArcMap<Digraph::ArcMap<int>, Digraph::NodeMap<int> >
847 847
    arc_map(a_map, out_map);
848 848
  for (Digraph::ArcIt a(digraph); a != INVALID; ++a) {
849 849
    check(arc_map[adaptor.arc(a)] == a_map[a],  "Wrong combined arc map");
850 850
  }
851 851
  for (Digraph::NodeIt n(digraph); n != INVALID; ++n) {
852 852
    check(arc_map[adaptor.arc(n)] == out_map[n],  "Wrong combined arc map");
853 853
  }
854 854

	
855 855
  // Check the conversion of nodes
856 856
  Digraph::Node nd = adaptor.inNode(n1);
857 857
  check (nd == n1, "Wrong node conversion");
858 858
  nd = adaptor.outNode(n2);
859 859
  check (nd == n2, "Wrong node conversion");
860 860
}
861 861

	
862 862
void checkSubGraph() {
863 863
  // Check concepts
864 864
  checkConcept<concepts::Graph, SubGraph<concepts::Graph> >();
865 865
  checkConcept<concepts::Graph, SubGraph<ListGraph> >();
866 866
  checkConcept<concepts::AlterableGraphComponent<>,
867 867
               SubGraph<ListGraph> >();
868 868
  checkConcept<concepts::ExtendableGraphComponent<>,
869 869
               SubGraph<ListGraph> >();
870 870
  checkConcept<concepts::ErasableGraphComponent<>,
871 871
               SubGraph<ListGraph> >();
872 872
  checkConcept<concepts::ClearableGraphComponent<>,
873 873
               SubGraph<ListGraph> >();
874 874

	
875 875
  // Create a graph and an adaptor
876 876
  typedef ListGraph Graph;
877 877
  typedef Graph::NodeMap<bool> NodeFilter;
878 878
  typedef Graph::EdgeMap<bool> EdgeFilter;
879 879
  typedef SubGraph<Graph, NodeFilter, EdgeFilter> Adaptor;
880 880

	
881 881
  Graph graph;
882 882
  NodeFilter node_filter(graph);
883 883
  EdgeFilter edge_filter(graph);
884 884
  Adaptor adaptor(graph, node_filter, edge_filter);
885 885

	
886 886
  // Add nodes and edges to the original graph and the adaptor
887 887
  Graph::Node n1 = graph.addNode();
888 888
  Graph::Node n2 = graph.addNode();
889 889
  Adaptor::Node n3 = adaptor.addNode();
890 890
  Adaptor::Node n4 = adaptor.addNode();
891 891

	
892 892
  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
893 893

	
894 894
  Graph::Edge e1 = graph.addEdge(n1, n2);
895 895
  Graph::Edge e2 = graph.addEdge(n1, n3);
896 896
  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
897 897
  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
898 898

	
899 899
  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
900 900

	
901 901
  checkGraphNodeList(adaptor, 4);
902 902
  checkGraphArcList(adaptor, 8);
903 903
  checkGraphEdgeList(adaptor, 4);
904 904
  checkGraphConArcList(adaptor, 8);
905 905
  checkGraphConEdgeList(adaptor, 4);
906 906

	
907 907
  checkGraphIncEdgeArcLists(adaptor, n1, 2);
908 908
  checkGraphIncEdgeArcLists(adaptor, n2, 2);
909 909
  checkGraphIncEdgeArcLists(adaptor, n3, 3);
910 910
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
911 911

	
912 912
  checkNodeIds(adaptor);
913 913
  checkArcIds(adaptor);
914 914
  checkEdgeIds(adaptor);
915 915

	
916 916
  checkGraphNodeMap(adaptor);
917 917
  checkGraphArcMap(adaptor);
918 918
  checkGraphEdgeMap(adaptor);
919 919

	
920 920
  // Hide an edge
921 921
  adaptor.status(e2, false);
922 922
  adaptor.disable(e3);
923 923
  if (!adaptor.status(e3)) adaptor.enable(e3);
924 924

	
925 925
  checkGraphNodeList(adaptor, 4);
926 926
  checkGraphArcList(adaptor, 6);
927 927
  checkGraphEdgeList(adaptor, 3);
928 928
  checkGraphConArcList(adaptor, 6);
929 929
  checkGraphConEdgeList(adaptor, 3);
930 930

	
931 931
  checkGraphIncEdgeArcLists(adaptor, n1, 1);
932 932
  checkGraphIncEdgeArcLists(adaptor, n2, 2);
933 933
  checkGraphIncEdgeArcLists(adaptor, n3, 2);
934 934
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
935 935

	
936 936
  checkNodeIds(adaptor);
937 937
  checkArcIds(adaptor);
938 938
  checkEdgeIds(adaptor);
939 939

	
940 940
  checkGraphNodeMap(adaptor);
941 941
  checkGraphArcMap(adaptor);
942 942
  checkGraphEdgeMap(adaptor);
943 943

	
944 944
  // Hide a node
945 945
  adaptor.status(n1, false);
946 946
  adaptor.disable(n3);
947 947
  if (!adaptor.status(n3)) adaptor.enable(n3);
948 948

	
949 949
  checkGraphNodeList(adaptor, 3);
950 950
  checkGraphArcList(adaptor, 4);
951 951
  checkGraphEdgeList(adaptor, 2);
952 952
  checkGraphConArcList(adaptor, 4);
953 953
  checkGraphConEdgeList(adaptor, 2);
954 954

	
955 955
  checkGraphIncEdgeArcLists(adaptor, n2, 1);
956 956
  checkGraphIncEdgeArcLists(adaptor, n3, 2);
957 957
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
958 958

	
959 959
  checkNodeIds(adaptor);
960 960
  checkArcIds(adaptor);
961 961
  checkEdgeIds(adaptor);
962 962

	
963 963
  checkGraphNodeMap(adaptor);
964 964
  checkGraphArcMap(adaptor);
965 965
  checkGraphEdgeMap(adaptor);
966 966

	
967 967
  // Hide all nodes and edges
968 968
  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
969 969
  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
970 970

	
971 971
  checkGraphNodeList(adaptor, 0);
972 972
  checkGraphArcList(adaptor, 0);
973 973
  checkGraphEdgeList(adaptor, 0);
974 974
  checkGraphConArcList(adaptor, 0);
975 975
  checkGraphConEdgeList(adaptor, 0);
976 976

	
977 977
  checkNodeIds(adaptor);
978 978
  checkArcIds(adaptor);
979 979
  checkEdgeIds(adaptor);
980 980

	
981 981
  checkGraphNodeMap(adaptor);
982 982
  checkGraphArcMap(adaptor);
983 983
  checkGraphEdgeMap(adaptor);
984 984

	
985 985
  // Check the conversion of nodes and edges
986 986
  Graph::Node ng = n3;
987 987
  ng = n4;
988 988
  Adaptor::Node na = n1;
989 989
  na = n2;
990 990
  Graph::Edge eg = e3;
991 991
  eg = e4;
992 992
  Adaptor::Edge ea = e1;
993 993
  ea = e2;
994 994
}
995 995

	
996 996
void checkFilterNodes2() {
997 997
  // Check concepts
998 998
  checkConcept<concepts::Graph, FilterNodes<concepts::Graph> >();
999 999
  checkConcept<concepts::Graph, FilterNodes<ListGraph> >();
1000 1000
  checkConcept<concepts::AlterableGraphComponent<>,
1001 1001
               FilterNodes<ListGraph> >();
1002 1002
  checkConcept<concepts::ExtendableGraphComponent<>,
1003 1003
               FilterNodes<ListGraph> >();
1004 1004
  checkConcept<concepts::ErasableGraphComponent<>,
1005 1005
               FilterNodes<ListGraph> >();
1006 1006
  checkConcept<concepts::ClearableGraphComponent<>,
1007 1007
               FilterNodes<ListGraph> >();
1008 1008

	
1009 1009
  // Create a graph and an adaptor
1010 1010
  typedef ListGraph Graph;
1011 1011
  typedef Graph::NodeMap<bool> NodeFilter;
1012 1012
  typedef FilterNodes<Graph, NodeFilter> Adaptor;
1013 1013

	
1014 1014
  // Add nodes and edges to the original graph and the adaptor
1015 1015
  Graph graph;
1016 1016
  NodeFilter node_filter(graph);
1017 1017
  Adaptor adaptor(graph, node_filter);
1018 1018

	
1019 1019
  Graph::Node n1 = graph.addNode();
1020 1020
  Graph::Node n2 = graph.addNode();
1021 1021
  Adaptor::Node n3 = adaptor.addNode();
1022 1022
  Adaptor::Node n4 = adaptor.addNode();
1023 1023

	
1024 1024
  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = true;
1025 1025

	
1026 1026
  Graph::Edge e1 = graph.addEdge(n1, n2);
1027 1027
  Graph::Edge e2 = graph.addEdge(n1, n3);
1028 1028
  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
1029 1029
  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
1030 1030

	
1031 1031
  checkGraphNodeList(adaptor, 4);
1032 1032
  checkGraphArcList(adaptor, 8);
1033 1033
  checkGraphEdgeList(adaptor, 4);
1034 1034
  checkGraphConArcList(adaptor, 8);
1035 1035
  checkGraphConEdgeList(adaptor, 4);
1036 1036

	
1037 1037
  checkGraphIncEdgeArcLists(adaptor, n1, 2);
1038 1038
  checkGraphIncEdgeArcLists(adaptor, n2, 2);
1039 1039
  checkGraphIncEdgeArcLists(adaptor, n3, 3);
1040 1040
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
1041 1041

	
1042 1042
  checkNodeIds(adaptor);
1043 1043
  checkArcIds(adaptor);
1044 1044
  checkEdgeIds(adaptor);
1045 1045

	
1046 1046
  checkGraphNodeMap(adaptor);
1047 1047
  checkGraphArcMap(adaptor);
1048 1048
  checkGraphEdgeMap(adaptor);
1049 1049

	
1050 1050
  // Hide a node
1051 1051
  adaptor.status(n1, false);
1052 1052
  adaptor.disable(n3);
1053 1053
  if (!adaptor.status(n3)) adaptor.enable(n3);
1054 1054

	
1055 1055
  checkGraphNodeList(adaptor, 3);
1056 1056
  checkGraphArcList(adaptor, 4);
1057 1057
  checkGraphEdgeList(adaptor, 2);
1058 1058
  checkGraphConArcList(adaptor, 4);
1059 1059
  checkGraphConEdgeList(adaptor, 2);
1060 1060

	
1061 1061
  checkGraphIncEdgeArcLists(adaptor, n2, 1);
1062 1062
  checkGraphIncEdgeArcLists(adaptor, n3, 2);
1063 1063
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
1064 1064

	
1065 1065
  checkNodeIds(adaptor);
1066 1066
  checkArcIds(adaptor);
1067 1067
  checkEdgeIds(adaptor);
1068 1068

	
1069 1069
  checkGraphNodeMap(adaptor);
1070 1070
  checkGraphArcMap(adaptor);
1071 1071
  checkGraphEdgeMap(adaptor);
1072 1072

	
1073 1073
  // Hide all nodes
1074 1074
  node_filter[n1] = node_filter[n2] = node_filter[n3] = node_filter[n4] = false;
1075 1075

	
1076 1076
  checkGraphNodeList(adaptor, 0);
1077 1077
  checkGraphArcList(adaptor, 0);
1078 1078
  checkGraphEdgeList(adaptor, 0);
1079 1079
  checkGraphConArcList(adaptor, 0);
1080 1080
  checkGraphConEdgeList(adaptor, 0);
1081 1081

	
1082 1082
  checkNodeIds(adaptor);
1083 1083
  checkArcIds(adaptor);
1084 1084
  checkEdgeIds(adaptor);
1085 1085

	
1086 1086
  checkGraphNodeMap(adaptor);
1087 1087
  checkGraphArcMap(adaptor);
1088 1088
  checkGraphEdgeMap(adaptor);
1089 1089

	
1090 1090
  // Check the conversion of nodes and edges
1091 1091
  Graph::Node ng = n3;
1092 1092
  ng = n4;
1093 1093
  Adaptor::Node na = n1;
1094 1094
  na = n2;
1095 1095
  Graph::Edge eg = e3;
1096 1096
  eg = e4;
1097 1097
  Adaptor::Edge ea = e1;
1098 1098
  ea = e2;
1099 1099
}
1100 1100

	
1101 1101
void checkFilterEdges() {
1102 1102
  // Check concepts
1103 1103
  checkConcept<concepts::Graph, FilterEdges<concepts::Graph> >();
1104 1104
  checkConcept<concepts::Graph, FilterEdges<ListGraph> >();
1105 1105
  checkConcept<concepts::AlterableGraphComponent<>,
1106 1106
               FilterEdges<ListGraph> >();
1107 1107
  checkConcept<concepts::ExtendableGraphComponent<>,
1108 1108
               FilterEdges<ListGraph> >();
1109 1109
  checkConcept<concepts::ErasableGraphComponent<>,
1110 1110
               FilterEdges<ListGraph> >();
1111 1111
  checkConcept<concepts::ClearableGraphComponent<>,
1112 1112
               FilterEdges<ListGraph> >();
1113 1113

	
1114 1114
  // Create a graph and an adaptor
1115 1115
  typedef ListGraph Graph;
1116 1116
  typedef Graph::EdgeMap<bool> EdgeFilter;
1117 1117
  typedef FilterEdges<Graph, EdgeFilter> Adaptor;
1118 1118

	
1119 1119
  Graph graph;
1120 1120
  EdgeFilter edge_filter(graph);
1121 1121
  Adaptor adaptor(graph, edge_filter);
1122 1122

	
1123 1123
  // Add nodes and edges to the original graph and the adaptor
1124 1124
  Graph::Node n1 = graph.addNode();
1125 1125
  Graph::Node n2 = graph.addNode();
1126 1126
  Adaptor::Node n3 = adaptor.addNode();
1127 1127
  Adaptor::Node n4 = adaptor.addNode();
1128 1128

	
1129 1129
  Graph::Edge e1 = graph.addEdge(n1, n2);
1130 1130
  Graph::Edge e2 = graph.addEdge(n1, n3);
1131 1131
  Adaptor::Edge e3 = adaptor.addEdge(n2, n3);
1132 1132
  Adaptor::Edge e4 = adaptor.addEdge(n3, n4);
1133 1133

	
1134 1134
  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = true;
1135 1135

	
1136 1136
  checkGraphNodeList(adaptor, 4);
1137 1137
  checkGraphArcList(adaptor, 8);
1138 1138
  checkGraphEdgeList(adaptor, 4);
1139 1139
  checkGraphConArcList(adaptor, 8);
1140 1140
  checkGraphConEdgeList(adaptor, 4);
1141 1141

	
1142 1142
  checkGraphIncEdgeArcLists(adaptor, n1, 2);
1143 1143
  checkGraphIncEdgeArcLists(adaptor, n2, 2);
1144 1144
  checkGraphIncEdgeArcLists(adaptor, n3, 3);
1145 1145
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
1146 1146

	
1147 1147
  checkNodeIds(adaptor);
1148 1148
  checkArcIds(adaptor);
1149 1149
  checkEdgeIds(adaptor);
1150 1150

	
1151 1151
  checkGraphNodeMap(adaptor);
1152 1152
  checkGraphArcMap(adaptor);
1153 1153
  checkGraphEdgeMap(adaptor);
1154 1154

	
1155 1155
  // Hide an edge
1156 1156
  adaptor.status(e2, false);
1157 1157
  adaptor.disable(e3);
1158 1158
  if (!adaptor.status(e3)) adaptor.enable(e3);
1159 1159

	
1160 1160
  checkGraphNodeList(adaptor, 4);
1161 1161
  checkGraphArcList(adaptor, 6);
1162 1162
  checkGraphEdgeList(adaptor, 3);
1163 1163
  checkGraphConArcList(adaptor, 6);
1164 1164
  checkGraphConEdgeList(adaptor, 3);
1165 1165

	
1166 1166
  checkGraphIncEdgeArcLists(adaptor, n1, 1);
1167 1167
  checkGraphIncEdgeArcLists(adaptor, n2, 2);
1168 1168
  checkGraphIncEdgeArcLists(adaptor, n3, 2);
1169 1169
  checkGraphIncEdgeArcLists(adaptor, n4, 1);
1170 1170

	
1171 1171
  checkNodeIds(adaptor);
1172 1172
  checkArcIds(adaptor);
1173 1173
  checkEdgeIds(adaptor);
1174 1174

	
1175 1175
  checkGraphNodeMap(adaptor);
1176 1176
  checkGraphArcMap(adaptor);
1177 1177
  checkGraphEdgeMap(adaptor);
1178 1178

	
1179 1179
  // Hide all edges
1180 1180
  edge_filter[e1] = edge_filter[e2] = edge_filter[e3] = edge_filter[e4] = false;
1181 1181

	
1182 1182
  checkGraphNodeList(adaptor, 4);
1183 1183
  checkGraphArcList(adaptor, 0);
1184 1184
  checkGraphEdgeList(adaptor, 0);
1185 1185
  checkGraphConArcList(adaptor, 0);
1186 1186
  checkGraphConEdgeList(adaptor, 0);
1187 1187

	
1188 1188
  checkNodeIds(adaptor);
1189 1189
  checkArcIds(adaptor);
1190 1190
  checkEdgeIds(adaptor);
1191 1191

	
1192 1192
  checkGraphNodeMap(adaptor);
1193 1193
  checkGraphArcMap(adaptor);
1194 1194
  checkGraphEdgeMap(adaptor);
1195 1195

	
1196 1196
  // Check the conversion of nodes and edges
1197 1197
  Graph::Node ng = n3;
1198 1198
  ng = n4;
1199 1199
  Adaptor::Node na = n1;
1200 1200
  na = n2;
1201 1201
  Graph::Edge eg = e3;
1202 1202
  eg = e4;
1203 1203
  Adaptor::Edge ea = e1;
1204 1204
  ea = e2;
1205 1205
}
1206 1206

	
1207 1207
void checkOrienter() {
1208 1208
  // Check concepts
1209 1209
  checkConcept<concepts::Digraph, Orienter<concepts::Graph> >();
1210 1210
  checkConcept<concepts::Digraph, Orienter<ListGraph> >();
1211 1211
  checkConcept<concepts::AlterableDigraphComponent<>,
1212 1212
               Orienter<ListGraph> >();
1213 1213
  checkConcept<concepts::ExtendableDigraphComponent<>,
1214 1214
               Orienter<ListGraph> >();
1215 1215
  checkConcept<concepts::ErasableDigraphComponent<>,
1216 1216
               Orienter<ListGraph> >();
1217 1217
  checkConcept<concepts::ClearableDigraphComponent<>,
1218 1218
               Orienter<ListGraph> >();
1219 1219

	
1220 1220
  // Create a graph and an adaptor
1221 1221
  typedef ListGraph Graph;
1222 1222
  typedef ListGraph::EdgeMap<bool> DirMap;
1223 1223
  typedef Orienter<Graph> Adaptor;
1224 1224

	
1225 1225
  Graph graph;
1226 1226
  DirMap dir(graph);
1227 1227
  Adaptor adaptor(graph, dir);
1228 1228

	
1229 1229
  // Add nodes and edges to the original graph and the adaptor
1230 1230
  Graph::Node n1 = graph.addNode();
1231 1231
  Graph::Node n2 = graph.addNode();
1232 1232
  Adaptor::Node n3 = adaptor.addNode();
1233 1233

	
1234 1234
  Graph::Edge e1 = graph.addEdge(n1, n2);
1235 1235
  Graph::Edge e2 = graph.addEdge(n1, n3);
1236 1236
  Adaptor::Arc e3 = adaptor.addArc(n2, n3);
1237 1237

	
1238 1238
  dir[e1] = dir[e2] = dir[e3] = true;
1239 1239

	
1240 1240
  // Check the original graph
1241 1241
  checkGraphNodeList(graph, 3);
1242 1242
  checkGraphArcList(graph, 6);
1243 1243
  checkGraphConArcList(graph, 6);
1244 1244
  checkGraphEdgeList(graph, 3);
1245 1245
  checkGraphConEdgeList(graph, 3);
1246 1246

	
1247 1247
  checkGraphIncEdgeArcLists(graph, n1, 2);
1248 1248
  checkGraphIncEdgeArcLists(graph, n2, 2);
1249 1249
  checkGraphIncEdgeArcLists(graph, n3, 2);
1250 1250

	
1251 1251
  checkNodeIds(graph);
1252 1252
  checkArcIds(graph);
1253 1253
  checkEdgeIds(graph);
1254 1254

	
1255 1255
  checkGraphNodeMap(graph);
1256 1256
  checkGraphArcMap(graph);
1257 1257
  checkGraphEdgeMap(graph);
1258 1258

	
1259 1259
  // Check the adaptor
1260 1260
  checkGraphNodeList(adaptor, 3);
1261 1261
  checkGraphArcList(adaptor, 3);
1262 1262
  checkGraphConArcList(adaptor, 3);
1263 1263

	
1264 1264
  checkGraphOutArcList(adaptor, n1, 2);
1265 1265
  checkGraphOutArcList(adaptor, n2, 1);
1266 1266
  checkGraphOutArcList(adaptor, n3, 0);
1267 1267

	
1268 1268
  checkGraphInArcList(adaptor, n1, 0);
1269 1269
  checkGraphInArcList(adaptor, n2, 1);
1270 1270
  checkGraphInArcList(adaptor, n3, 2);
1271 1271

	
1272 1272
  checkNodeIds(adaptor);
1273 1273
  checkArcIds(adaptor);
1274 1274

	
1275 1275
  checkGraphNodeMap(adaptor);
1276 1276
  checkGraphArcMap(adaptor);
1277 1277

	
1278 1278
  // Check direction changing
1279 1279
  {
1280 1280
    dir[e1] = true;
1281 1281
    Adaptor::Node u = adaptor.source(e1);
1282 1282
    Adaptor::Node v = adaptor.target(e1);
1283 1283

	
1284 1284
    dir[e1] = false;
1285 1285
    check (u == adaptor.target(e1), "Wrong dir");
1286 1286
    check (v == adaptor.source(e1), "Wrong dir");
1287 1287

	
1288 1288
    check ((u == n1 && v == n2) || (u == n2 && v == n1), "Wrong dir");
1289 1289
    dir[e1] = n1 == u;
1290 1290
  }
1291 1291

	
1292 1292
  {
1293 1293
    dir[e2] = true;
1294 1294
    Adaptor::Node u = adaptor.source(e2);
1295 1295
    Adaptor::Node v = adaptor.target(e2);
1296 1296

	
1297 1297
    dir[e2] = false;
1298 1298
    check (u == adaptor.target(e2), "Wrong dir");
1299 1299
    check (v == adaptor.source(e2), "Wrong dir");
1300 1300

	
1301 1301
    check ((u == n1 && v == n3) || (u == n3 && v == n1), "Wrong dir");
1302 1302
    dir[e2] = n3 == u;
1303 1303
  }
1304 1304

	
1305 1305
  {
1306 1306
    dir[e3] = true;
1307 1307
    Adaptor::Node u = adaptor.source(e3);
1308 1308
    Adaptor::Node v = adaptor.target(e3);
1309 1309

	
1310 1310
    dir[e3] = false;
1311 1311
    check (u == adaptor.target(e3), "Wrong dir");
1312 1312
    check (v == adaptor.source(e3), "Wrong dir");
1313 1313

	
1314 1314
    check ((u == n2 && v == n3) || (u == n3 && v == n2), "Wrong dir");
1315 1315
    dir[e3] = n2 == u;
1316 1316
  }
1317 1317

	
1318 1318
  // Check the adaptor again
1319 1319
  checkGraphNodeList(adaptor, 3);
1320 1320
  checkGraphArcList(adaptor, 3);
1321 1321
  checkGraphConArcList(adaptor, 3);
1322 1322

	
1323 1323
  checkGraphOutArcList(adaptor, n1, 1);
1324 1324
  checkGraphOutArcList(adaptor, n2, 1);
1325 1325
  checkGraphOutArcList(adaptor, n3, 1);
1326 1326

	
1327 1327
  checkGraphInArcList(adaptor, n1, 1);
1328 1328
  checkGraphInArcList(adaptor, n2, 1);
1329 1329
  checkGraphInArcList(adaptor, n3, 1);
1330 1330

	
1331 1331
  checkNodeIds(adaptor);
1332 1332
  checkArcIds(adaptor);
1333 1333

	
1334 1334
  checkGraphNodeMap(adaptor);
1335 1335
  checkGraphArcMap(adaptor);
1336 1336

	
1337 1337
  // Check reverseArc()
1338 1338
  adaptor.reverseArc(e2);
1339 1339
  adaptor.reverseArc(e3);
1340 1340
  adaptor.reverseArc(e2);
1341 1341

	
1342 1342
  checkGraphNodeList(adaptor, 3);
1343 1343
  checkGraphArcList(adaptor, 3);
1344 1344
  checkGraphConArcList(adaptor, 3);
1345 1345

	
1346 1346
  checkGraphOutArcList(adaptor, n1, 1);
1347 1347
  checkGraphOutArcList(adaptor, n2, 0);
1348 1348
  checkGraphOutArcList(adaptor, n3, 2);
1349 1349

	
1350 1350
  checkGraphInArcList(adaptor, n1, 1);
1351 1351
  checkGraphInArcList(adaptor, n2, 2);
1352 1352
  checkGraphInArcList(adaptor, n3, 0);
1353 1353

	
1354 1354
  // Check the conversion of nodes and arcs/edges
1355 1355
  Graph::Node ng = n3;
1356 1356
  ng = n3;
1357 1357
  Adaptor::Node na = n1;
1358 1358
  na = n2;
1359 1359
  Graph::Edge eg = e3;
1360 1360
  eg = e3;
1361 1361
  Adaptor::Arc aa = e1;
1362 1362
  aa = e2;
1363 1363
}
1364 1364

	
1365 1365
void checkCombiningAdaptors() {
1366 1366
  // Create a grid graph
1367 1367
  GridGraph graph(2,2);
1368 1368
  GridGraph::Node n1 = graph(0,0);
1369 1369
  GridGraph::Node n2 = graph(0,1);
1370 1370
  GridGraph::Node n3 = graph(1,0);
1371 1371
  GridGraph::Node n4 = graph(1,1);
1372 1372

	
1373 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;
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 1378

	
1379 1379
  // Apply several adaptors on the grid graph
1380
  typedef SplitNodes< ReverseDigraph< const Orienter<
1381
            const GridGraph, GridGraph::EdgeMap<bool> > > >
1382
    RevSplitGridGraph;
1383
  typedef ReverseDigraph<const RevSplitGridGraph> SplitGridGraph;
1380
  typedef SplitNodes<Orienter< const GridGraph, GridGraph::EdgeMap<bool> > >
1381
    SplitGridGraph;
1384 1382
  typedef Undirector<const SplitGridGraph> USplitGridGraph;
1385
  typedef Undirector<const USplitGridGraph> UUSplitGridGraph;
1386
  checkConcept<concepts::Digraph, RevSplitGridGraph>();
1387 1383
  checkConcept<concepts::Digraph, SplitGridGraph>();
1388 1384
  checkConcept<concepts::Graph, USplitGridGraph>();
1389
  checkConcept<concepts::Graph, UUSplitGridGraph>();
1390 1385

	
1391
  RevSplitGridGraph rev_adaptor =
1392
    splitNodes(reverseDigraph(orienter(graph, dir_map)));
1393
  SplitGridGraph adaptor = reverseDigraph(rev_adaptor);
1386
  SplitGridGraph adaptor = splitNodes(orienter(graph, dir_map));
1394 1387
  USplitGridGraph uadaptor = undirector(adaptor);
1395
  UUSplitGridGraph uuadaptor = undirector(uadaptor);
1396 1388

	
1397 1389
  // Check adaptor
1398 1390
  checkGraphNodeList(adaptor, 8);
1399 1391
  checkGraphArcList(adaptor, 8);
1400 1392
  checkGraphConArcList(adaptor, 8);
1401 1393

	
1402
  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n1), 1);
1403
  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n1), 1);
1404
  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n2), 2);
1405
  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n2), 1);
1406
  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n3), 1);
1407
  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n3), 1);
1408
  checkGraphOutArcList(adaptor, rev_adaptor.inNode(n4), 0);
1409
  checkGraphOutArcList(adaptor, rev_adaptor.outNode(n4), 1);
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);
1410 1402

	
1411
  checkGraphInArcList(adaptor, rev_adaptor.inNode(n1), 1);
1412
  checkGraphInArcList(adaptor, rev_adaptor.outNode(n1), 1);
1413
  checkGraphInArcList(adaptor, rev_adaptor.inNode(n2), 1);
1414
  checkGraphInArcList(adaptor, rev_adaptor.outNode(n2), 0);
1415
  checkGraphInArcList(adaptor, rev_adaptor.inNode(n3), 1);
1416
  checkGraphInArcList(adaptor, rev_adaptor.outNode(n3), 1);
1417
  checkGraphInArcList(adaptor, rev_adaptor.inNode(n4), 1);
1418
  checkGraphInArcList(adaptor, rev_adaptor.outNode(n4), 2);
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);
1419 1411

	
1420 1412
  checkNodeIds(adaptor);
1421 1413
  checkArcIds(adaptor);
1422 1414

	
1423 1415
  checkGraphNodeMap(adaptor);
1424 1416
  checkGraphArcMap(adaptor);
1425 1417

	
1426 1418
  // Check uadaptor
1427 1419
  checkGraphNodeList(uadaptor, 8);
1428 1420
  checkGraphEdgeList(uadaptor, 8);
1429 1421
  checkGraphArcList(uadaptor, 16);
1430 1422
  checkGraphConEdgeList(uadaptor, 8);
1431 1423
  checkGraphConArcList(uadaptor, 16);
1432 1424

	
1433 1425
  checkNodeIds(uadaptor);
1434 1426
  checkEdgeIds(uadaptor);
1435 1427
  checkArcIds(uadaptor);
1436 1428

	
1437 1429
  checkGraphNodeMap(uadaptor);
1438 1430
  checkGraphEdgeMap(uadaptor);
1439 1431
  checkGraphArcMap(uadaptor);
1440 1432

	
1441
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n1), 2);
1442
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n1), 2);
1443
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n2), 3);
1444
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n2), 1);
1445
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n3), 2);
1446
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n3), 2);
1447
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.inNode(n4), 1);
1448
  checkGraphIncEdgeArcLists(uadaptor, rev_adaptor.outNode(n4), 3);
1449

	
1450
  // Check uuadaptor
1451
  checkGraphNodeList(uuadaptor, 8);
1452
  checkGraphEdgeList(uuadaptor, 16);
1453
  checkGraphArcList(uuadaptor, 32);
1454
  checkGraphConEdgeList(uuadaptor, 16);
1455
  checkGraphConArcList(uuadaptor, 32);
1456

	
1457
  checkNodeIds(uuadaptor);
1458
  checkEdgeIds(uuadaptor);
1459
  checkArcIds(uuadaptor);
1460

	
1461
  checkGraphNodeMap(uuadaptor);
1462
  checkGraphEdgeMap(uuadaptor);
1463
  checkGraphArcMap(uuadaptor);
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);
1464 1441
}
1465 1442

	
1466 1443
int main(int, const char **) {
1467 1444
  // Check the digraph adaptors (using ListDigraph)
1468 1445
  checkReverseDigraph();
1469 1446
  checkSubDigraph();
1470 1447
  checkFilterNodes1();
1471 1448
  checkFilterArcs();
1472 1449
  checkUndirector();
1473 1450
  checkResidualDigraph();
1474 1451
  checkSplitNodes();
1475 1452

	
1476 1453
  // Check the graph adaptors (using ListGraph)
1477 1454
  checkSubGraph();
1478 1455
  checkFilterNodes2();
1479 1456
  checkFilterEdges();
1480 1457
  checkOrienter();
1481 1458

	
1482 1459
  // Combine adaptors (using GridGraph)
1483 1460
  checkCombiningAdaptors();
1484 1461

	
1485 1462
  return 0;
1486 1463
}
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-2009
5
 * Copyright (C) 2003-2010
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 61
  Node s, t, n;
62 62
  Arc e;
63 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 68
  concepts::ReadMap<Node,bool> nm;
69 69

	
70 70
  {
71 71
    BType bfs_test(G);
72 72
    const BType& const_bfs_test = bfs_test;
73 73

	
74 74
    bfs_test.run(s);
75 75
    bfs_test.run(s,t);
76 76
    bfs_test.run();
77 77

	
78 78
    bfs_test.init();
79 79
    bfs_test.addSource(s);
80 80
    n = bfs_test.processNextNode();
81 81
    n = bfs_test.processNextNode(t, b);
82 82
    n = bfs_test.processNextNode(nm, n);
83 83
    n = const_bfs_test.nextNode();
84 84
    b = const_bfs_test.emptyQueue();
85 85
    i = const_bfs_test.queueSize();
86
    
86

	
87 87
    bfs_test.start();
88 88
    bfs_test.start(t);
89 89
    bfs_test.start(nm);
90 90

	
91 91
    l  = const_bfs_test.dist(t);
92 92
    e  = const_bfs_test.predArc(t);
93 93
    s  = const_bfs_test.predNode(t);
94 94
    b  = const_bfs_test.reached(t);
95 95
    d  = const_bfs_test.distMap();
96 96
    p  = const_bfs_test.predMap();
97 97
    pp = const_bfs_test.path(t);
98 98
  }
99 99
  {
100 100
    BType
101 101
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
102 102
      ::SetDistMap<concepts::ReadWriteMap<Node,int> >
103 103
      ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
104 104
      ::SetStandardProcessedMap
105 105
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
106 106
      ::Create bfs_test(G);
107
      
107

	
108 108
    concepts::ReadWriteMap<Node,Arc> pred_map;
109 109
    concepts::ReadWriteMap<Node,int> dist_map;
110 110
    concepts::ReadWriteMap<Node,bool> reached_map;
111 111
    concepts::WriteMap<Node,bool> processed_map;
112
    
112

	
113 113
    bfs_test
114 114
      .predMap(pred_map)
115 115
      .distMap(dist_map)
116 116
      .reachedMap(reached_map)
117 117
      .processedMap(processed_map);
118 118

	
119 119
    bfs_test.run(s);
120 120
    bfs_test.run(s,t);
121 121
    bfs_test.run();
122
    
122

	
123 123
    bfs_test.init();
124 124
    bfs_test.addSource(s);
125 125
    n = bfs_test.processNextNode();
126 126
    n = bfs_test.processNextNode(t, b);
127 127
    n = bfs_test.processNextNode(nm, n);
128 128
    n = bfs_test.nextNode();
129 129
    b = bfs_test.emptyQueue();
130 130
    i = bfs_test.queueSize();
131
    
131

	
132 132
    bfs_test.start();
133 133
    bfs_test.start(t);
134 134
    bfs_test.start(nm);
135 135

	
136 136
    l  = bfs_test.dist(t);
137 137
    e  = bfs_test.predArc(t);
138 138
    s  = bfs_test.predNode(t);
139 139
    b  = bfs_test.reached(t);
140 140
    pp = bfs_test.path(t);
141 141
  }
142 142
}
143 143

	
144 144
void checkBfsFunctionCompile()
145 145
{
146 146
  typedef int VType;
147 147
  typedef concepts::Digraph Digraph;
148 148
  typedef Digraph::Arc Arc;
149 149
  typedef Digraph::Node Node;
150 150

	
151 151
  Digraph g;
152 152
  bool b;
153 153
  bfs(g).run(Node());
154 154
  b=bfs(g).run(Node(),Node());
155 155
  bfs(g).run();
156 156
  bfs(g)
157 157
    .predMap(concepts::ReadWriteMap<Node,Arc>())
158 158
    .distMap(concepts::ReadWriteMap<Node,VType>())
159 159
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
160 160
    .processedMap(concepts::WriteMap<Node,bool>())
161 161
    .run(Node());
162 162
  b=bfs(g)
163 163
    .predMap(concepts::ReadWriteMap<Node,Arc>())
164 164
    .distMap(concepts::ReadWriteMap<Node,VType>())
165 165
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
166 166
    .processedMap(concepts::WriteMap<Node,bool>())
167 167
    .path(concepts::Path<Digraph>())
168 168
    .dist(VType())
169 169
    .run(Node(),Node());
170 170
  bfs(g)
171 171
    .predMap(concepts::ReadWriteMap<Node,Arc>())
172 172
    .distMap(concepts::ReadWriteMap<Node,VType>())
173 173
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
174 174
    .processedMap(concepts::WriteMap<Node,bool>())
175 175
    .run();
176 176
}
177 177

	
178 178
template <class Digraph>
179 179
void checkBfs() {
180 180
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
181 181

	
182 182
  Digraph G;
183 183
  Node s, t;
184 184

	
185 185
  std::istringstream input(test_lgf);
186 186
  digraphReader(G, input).
187 187
    node("source", s).
188 188
    node("target", t).
189 189
    run();
190 190

	
191 191
  Bfs<Digraph> bfs_test(G);
192 192
  bfs_test.run(s);
193 193

	
194 194
  check(bfs_test.dist(t)==2,"Bfs found a wrong path.");
195 195

	
196 196
  Path<Digraph> p = bfs_test.path(t);
197 197
  check(p.length()==2,"path() found a wrong path.");
198 198
  check(checkPath(G, p),"path() found a wrong path.");
199 199
  check(pathSource(G, p) == s,"path() found a wrong path.");
200 200
  check(pathTarget(G, p) == t,"path() found a wrong path.");
201 201

	
202 202

	
203 203
  for(ArcIt a(G); a!=INVALID; ++a) {
204 204
    Node u=G.source(a);
205 205
    Node v=G.target(a);
206 206
    check( !bfs_test.reached(u) ||
207 207
           (bfs_test.dist(v) <= bfs_test.dist(u)+1),
208 208
           "Wrong output. " << G.id(u) << "->" << G.id(v));
209 209
  }
210 210

	
211 211
  for(NodeIt v(G); v!=INVALID; ++v) {
212 212
    if (bfs_test.reached(v)) {
213 213
      check(v==s || bfs_test.predArc(v)!=INVALID, "Wrong tree.");
214 214
      if (bfs_test.predArc(v)!=INVALID ) {
215 215
        Arc a=bfs_test.predArc(v);
216 216
        Node u=G.source(a);
217 217
        check(u==bfs_test.predNode(v),"Wrong tree.");
218 218
        check(bfs_test.dist(v) - bfs_test.dist(u) == 1,
219 219
              "Wrong distance. Difference: "
220 220
              << std::abs(bfs_test.dist(v) - bfs_test.dist(u) - 1));
221 221
      }
222 222
    }
223 223
  }
224 224

	
225 225
  {
226 226
    NullMap<Node,Arc> myPredMap;
227 227
    bfs(G).predMap(myPredMap).run(s);
228 228
  }
229 229
}
230 230

	
231 231
int main()
232 232
{
233 233
  checkBfs<ListDigraph>();
234 234
  checkBfs<SmartDigraph>();
235 235
  return 0;
236 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-2009
5
 * Copyright (C) 2003-2010
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 "test_tools.h"
22 22
#include <lemon/list_graph.h>
23 23
#include <lemon/circulation.h>
24 24
#include <lemon/lgf_reader.h>
25 25
#include <lemon/concepts/digraph.h>
26 26
#include <lemon/concepts/maps.h>
27 27

	
28 28
using namespace lemon;
29 29

	
30 30
char test_lgf[] =
31 31
  "@nodes\n"
32 32
  "label\n"
33 33
  "0\n"
34 34
  "1\n"
35 35
  "2\n"
36 36
  "3\n"
37 37
  "4\n"
38 38
  "5\n"
39 39
  "@arcs\n"
40 40
  "     lcap  ucap\n"
41 41
  "0 1  2  10\n"
42 42
  "0 2  2  6\n"
43 43
  "1 3  4  7\n"
44 44
  "1 4  0  5\n"
45 45
  "2 4  1  3\n"
46 46
  "3 5  3  8\n"
47 47
  "4 5  3  7\n"
48 48
  "@attributes\n"
49 49
  "source 0\n"
50 50
  "sink   5\n";
51 51

	
52 52
void checkCirculationCompile()
53 53
{
54 54
  typedef int VType;
55 55
  typedef concepts::Digraph Digraph;
56 56

	
57 57
  typedef Digraph::Node Node;
58 58
  typedef Digraph::Arc Arc;
59 59
  typedef concepts::ReadMap<Arc,VType> CapMap;
60 60
  typedef concepts::ReadMap<Node,VType> SupplyMap;
61 61
  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
62 62
  typedef concepts::WriteMap<Node,bool> BarrierMap;
63 63

	
64 64
  typedef Elevator<Digraph, Digraph::Node> Elev;
65 65
  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
66 66

	
67 67
  Digraph g;
68 68
  Node n;
69 69
  Arc a;
70 70
  CapMap lcap, ucap;
71 71
  SupplyMap supply;
72 72
  FlowMap flow;
73 73
  BarrierMap bar;
74 74
  VType v;
75 75
  bool b;
76 76

	
77 77
  typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
78 78
            ::SetFlowMap<FlowMap>
79 79
            ::SetElevator<Elev>
80 80
            ::SetStandardElevator<LinkedElev>
81 81
            ::Create CirculationType;
82 82
  CirculationType circ_test(g, lcap, ucap, supply);
83 83
  const CirculationType& const_circ_test = circ_test;
84
   
84

	
85 85
  circ_test
86 86
    .lowerMap(lcap)
87 87
    .upperMap(ucap)
88 88
    .supplyMap(supply)
89 89
    .flowMap(flow);
90 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

	
91 96
  circ_test.init();
92 97
  circ_test.greedyInit();
93 98
  circ_test.start();
94 99
  circ_test.run();
95 100

	
96 101
  v = const_circ_test.flow(a);
97 102
  const FlowMap& fm = const_circ_test.flowMap();
98 103
  b = const_circ_test.barrier(n);
99 104
  const_circ_test.barrierMap(bar);
100
  
105

	
101 106
  ignore_unused_variable_warning(fm);
102 107
}
103 108

	
104 109
template <class G, class LM, class UM, class DM>
105 110
void checkCirculation(const G& g, const LM& lm, const UM& um,
106 111
                      const DM& dm, bool find)
107 112
{
108 113
  Circulation<G, LM, UM, DM> circ(g, lm, um, dm);
109 114
  bool ret = circ.run();
110 115
  if (find) {
111 116
    check(ret, "A feasible solution should have been found.");
112 117
    check(circ.checkFlow(), "The found flow is corrupt.");
113 118
    check(!circ.checkBarrier(), "A barrier should not have been found.");
114 119
  } else {
115 120
    check(!ret, "A feasible solution should not have been found.");
116 121
    check(circ.checkBarrier(), "The found barrier is corrupt.");
117 122
  }
118 123
}
119 124

	
120 125
int main (int, char*[])
121 126
{
122 127
  typedef ListDigraph Digraph;
123 128
  DIGRAPH_TYPEDEFS(Digraph);
124 129

	
125 130
  Digraph g;
126 131
  IntArcMap lo(g), up(g);
127 132
  IntNodeMap delta(g, 0);
128 133
  Node s, t;
129 134

	
130 135
  std::istringstream input(test_lgf);
131 136
  DigraphReader<Digraph>(g,input).
132 137
    arcMap("lcap", lo).
133 138
    arcMap("ucap", up).
134 139
    node("source",s).
135 140
    node("sink",t).
136 141
    run();
137 142

	
138 143
  delta[s] = 7; delta[t] = -7;
139 144
  checkCirculation(g, lo, up, delta, true);
140 145

	
141 146
  delta[s] = 13; delta[t] = -13;
142 147
  checkCirculation(g, lo, up, delta, true);
143 148

	
144 149
  delta[s] = 6; delta[t] = -6;
145 150
  checkCirculation(g, lo, up, delta, false);
146 151

	
147 152
  delta[s] = 14; delta[t] = -14;
148 153
  checkCirculation(g, lo, up, delta, false);
149 154

	
150 155
  delta[s] = 7; delta[t] = -13;
151 156
  checkCirculation(g, lo, up, delta, true);
152 157

	
153 158
  delta[s] = 5; delta[t] = -15;
154 159
  checkCirculation(g, lo, up, delta, true);
155 160

	
156 161
  delta[s] = 10; delta[t] = -11;
157 162
  checkCirculation(g, lo, up, delta, true);
158 163

	
159 164
  delta[s] = 11; delta[t] = -10;
160 165
  checkCirculation(g, lo, up, delta, false);
161 166

	
162 167
  return 0;
163 168
}
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-2009
5
 * Copyright (C) 2003-2010
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/connectivity.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/adaptors.h>
22 22

	
23 23
#include "test_tools.h"
24 24

	
25 25
using namespace lemon;
26 26

	
27 27

	
28 28
int main()
29 29
{
30 30
  typedef ListDigraph Digraph;
31 31
  typedef Undirector<Digraph> Graph;
32
  
32

	
33 33
  {
34 34
    Digraph d;
35 35
    Digraph::NodeMap<int> order(d);
36 36
    Graph g(d);
37
    
37

	
38 38
    check(stronglyConnected(d), "The empty digraph is strongly connected");
39 39
    check(countStronglyConnectedComponents(d) == 0,
40 40
          "The empty digraph has 0 strongly connected component");
41 41
    check(connected(g), "The empty graph is connected");
42 42
    check(countConnectedComponents(g) == 0,
43 43
          "The empty graph has 0 connected component");
44 44

	
45 45
    check(biNodeConnected(g), "The empty graph is bi-node-connected");
46 46
    check(countBiNodeConnectedComponents(g) == 0,
47 47
          "The empty graph has 0 bi-node-connected component");
48 48
    check(biEdgeConnected(g), "The empty graph is bi-edge-connected");
49 49
    check(countBiEdgeConnectedComponents(g) == 0,
50 50
          "The empty graph has 0 bi-edge-connected component");
51
          
51

	
52 52
    check(dag(d), "The empty digraph is DAG.");
53 53
    check(checkedTopologicalSort(d, order), "The empty digraph is DAG.");
54 54
    check(loopFree(d), "The empty digraph is loop-free.");
55 55
    check(parallelFree(d), "The empty digraph is parallel-free.");
56 56
    check(simpleGraph(d), "The empty digraph is simple.");
57 57

	
58 58
    check(acyclic(g), "The empty graph is acyclic.");
59 59
    check(tree(g), "The empty graph is tree.");
60 60
    check(bipartite(g), "The empty graph is bipartite.");
61 61
    check(loopFree(g), "The empty graph is loop-free.");
62 62
    check(parallelFree(g), "The empty graph is parallel-free.");
63 63
    check(simpleGraph(g), "The empty graph is simple.");
64 64
  }
65 65

	
66 66
  {
67 67
    Digraph d;
68 68
    Digraph::NodeMap<int> order(d);
69 69
    Graph g(d);
70 70
    Digraph::Node n = d.addNode();
71 71

	
72 72
    check(stronglyConnected(d), "This digraph is strongly connected");
73 73
    check(countStronglyConnectedComponents(d) == 1,
74 74
          "This digraph has 1 strongly connected component");
75 75
    check(connected(g), "This graph is connected");
76 76
    check(countConnectedComponents(g) == 1,
77 77
          "This graph has 1 connected component");
78 78

	
79 79
    check(biNodeConnected(g), "This graph is bi-node-connected");
80 80
    check(countBiNodeConnectedComponents(g) == 0,
81 81
          "This graph has 0 bi-node-connected component");
82 82
    check(biEdgeConnected(g), "This graph is bi-edge-connected");
83 83
    check(countBiEdgeConnectedComponents(g) == 1,
84 84
          "This graph has 1 bi-edge-connected component");
85
          
85

	
86 86
    check(dag(d), "This digraph is DAG.");
87 87
    check(checkedTopologicalSort(d, order), "This digraph is DAG.");
88 88
    check(loopFree(d), "This digraph is loop-free.");
89 89
    check(parallelFree(d), "This digraph is parallel-free.");
90 90
    check(simpleGraph(d), "This digraph is simple.");
91 91

	
92 92
    check(acyclic(g), "This graph is acyclic.");
93 93
    check(tree(g), "This graph is tree.");
94 94
    check(bipartite(g), "This graph is bipartite.");
95 95
    check(loopFree(g), "This graph is loop-free.");
96 96
    check(parallelFree(g), "This graph is parallel-free.");
97 97
    check(simpleGraph(g), "This graph is simple.");
98 98
  }
99 99

	
100 100
  {
101 101
    Digraph d;
102 102
    Digraph::NodeMap<int> order(d);
103 103
    Graph g(d);
104
    
104

	
105 105
    Digraph::Node n1 = d.addNode();
106 106
    Digraph::Node n2 = d.addNode();
107 107
    Digraph::Node n3 = d.addNode();
108 108
    Digraph::Node n4 = d.addNode();
109 109
    Digraph::Node n5 = d.addNode();
110 110
    Digraph::Node n6 = d.addNode();
111
    
111

	
112 112
    d.addArc(n1, n3);
113 113
    d.addArc(n3, n2);
114 114
    d.addArc(n2, n1);
115 115
    d.addArc(n4, n2);
116 116
    d.addArc(n4, n3);
117 117
    d.addArc(n5, n6);
118 118
    d.addArc(n6, n5);
119 119

	
120 120
    check(!stronglyConnected(d), "This digraph is not strongly connected");
121 121
    check(countStronglyConnectedComponents(d) == 3,
122 122
          "This digraph has 3 strongly connected components");
123 123
    check(!connected(g), "This graph is not connected");
124 124
    check(countConnectedComponents(g) == 2,
125 125
          "This graph has 2 connected components");
126 126

	
127 127
    check(!dag(d), "This digraph is not DAG.");
128 128
    check(!checkedTopologicalSort(d, order), "This digraph is not DAG.");
129 129
    check(loopFree(d), "This digraph is loop-free.");
130 130
    check(parallelFree(d), "This digraph is parallel-free.");
131 131
    check(simpleGraph(d), "This digraph is simple.");
132 132

	
133 133
    check(!acyclic(g), "This graph is not acyclic.");
134 134
    check(!tree(g), "This graph is not tree.");
135 135
    check(!bipartite(g), "This graph is not bipartite.");
136 136
    check(loopFree(g), "This graph is loop-free.");
137 137
    check(!parallelFree(g), "This graph is not parallel-free.");
138 138
    check(!simpleGraph(g), "This graph is not simple.");
139
    
139

	
140 140
    d.addArc(n3, n3);
141
    
141

	
142 142
    check(!loopFree(d), "This digraph is not loop-free.");
143 143
    check(!loopFree(g), "This graph is not loop-free.");
144 144
    check(!simpleGraph(d), "This digraph is not simple.");
145
    
145

	
146 146
    d.addArc(n3, n2);
147
    
147

	
148 148
    check(!parallelFree(d), "This digraph is not parallel-free.");
149 149
  }
150
  
150

	
151 151
  {
152 152
    Digraph d;
153 153
    Digraph::ArcMap<bool> cutarcs(d, false);
154 154
    Graph g(d);
155
    
155

	
156 156
    Digraph::Node n1 = d.addNode();
157 157
    Digraph::Node n2 = d.addNode();
158 158
    Digraph::Node n3 = d.addNode();
159 159
    Digraph::Node n4 = d.addNode();
160 160
    Digraph::Node n5 = d.addNode();
161 161
    Digraph::Node n6 = d.addNode();
162 162
    Digraph::Node n7 = d.addNode();
163 163
    Digraph::Node n8 = d.addNode();
164 164

	
165 165
    d.addArc(n1, n2);
166 166
    d.addArc(n5, n1);
167 167
    d.addArc(n2, n8);
168 168
    d.addArc(n8, n5);
169 169
    d.addArc(n6, n4);
170 170
    d.addArc(n4, n6);
171 171
    d.addArc(n2, n5);
172 172
    d.addArc(n1, n8);
173 173
    d.addArc(n6, n7);
174 174
    d.addArc(n7, n6);
175
   
175

	
176 176
    check(!stronglyConnected(d), "This digraph is not strongly connected");
177 177
    check(countStronglyConnectedComponents(d) == 3,
178 178
          "This digraph has 3 strongly connected components");
179 179
    Digraph::NodeMap<int> scomp1(d);
180 180
    check(stronglyConnectedComponents(d, scomp1) == 3,
181 181
          "This digraph has 3 strongly connected components");
182 182
    check(scomp1[n1] != scomp1[n3] && scomp1[n1] != scomp1[n4] &&
183 183
          scomp1[n3] != scomp1[n4], "Wrong stronglyConnectedComponents()");
184 184
    check(scomp1[n1] == scomp1[n2] && scomp1[n1] == scomp1[n5] &&
185 185
          scomp1[n1] == scomp1[n8], "Wrong stronglyConnectedComponents()");
186 186
    check(scomp1[n4] == scomp1[n6] && scomp1[n4] == scomp1[n7],
187 187
          "Wrong stronglyConnectedComponents()");
188 188
    Digraph::ArcMap<bool> scut1(d, false);
189 189
    check(stronglyConnectedCutArcs(d, scut1) == 0,
190 190
          "This digraph has 0 strongly connected cut arc.");
191 191
    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
192 192
      check(!scut1[a], "Wrong stronglyConnectedCutArcs()");
193 193
    }
194 194

	
195 195
    check(!connected(g), "This graph is not connected");
196 196
    check(countConnectedComponents(g) == 3,
197 197
          "This graph has 3 connected components");
198 198
    Graph::NodeMap<int> comp(g);
199 199
    check(connectedComponents(g, comp) == 3,
200 200
          "This graph has 3 connected components");
201 201
    check(comp[n1] != comp[n3] && comp[n1] != comp[n4] &&
202 202
          comp[n3] != comp[n4], "Wrong connectedComponents()");
203 203
    check(comp[n1] == comp[n2] && comp[n1] == comp[n5] &&
204 204
          comp[n1] == comp[n8], "Wrong connectedComponents()");
205 205
    check(comp[n4] == comp[n6] && comp[n4] == comp[n7],
206 206
          "Wrong connectedComponents()");
207 207

	
208 208
    cutarcs[d.addArc(n3, n1)] = true;
209 209
    cutarcs[d.addArc(n3, n5)] = true;
210 210
    cutarcs[d.addArc(n3, n8)] = true;
211 211
    cutarcs[d.addArc(n8, n6)] = true;
212 212
    cutarcs[d.addArc(n8, n7)] = true;
213 213

	
214 214
    check(!stronglyConnected(d), "This digraph is not strongly connected");
215 215
    check(countStronglyConnectedComponents(d) == 3,
216 216
          "This digraph has 3 strongly connected components");
217 217
    Digraph::NodeMap<int> scomp2(d);
218 218
    check(stronglyConnectedComponents(d, scomp2) == 3,
219 219
          "This digraph has 3 strongly connected components");
220 220
    check(scomp2[n3] == 0, "Wrong stronglyConnectedComponents()");
221 221
    check(scomp2[n1] == 1 && scomp2[n2] == 1 && scomp2[n5] == 1 &&
222 222
          scomp2[n8] == 1, "Wrong stronglyConnectedComponents()");
223 223
    check(scomp2[n4] == 2 && scomp2[n6] == 2 && scomp2[n7] == 2,
224 224
          "Wrong stronglyConnectedComponents()");
225 225
    Digraph::ArcMap<bool> scut2(d, false);
226 226
    check(stronglyConnectedCutArcs(d, scut2) == 5,
227 227
          "This digraph has 5 strongly connected cut arcs.");
228 228
    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
229 229
      check(scut2[a] == cutarcs[a], "Wrong stronglyConnectedCutArcs()");
230 230
    }
231 231
  }
232 232

	
233 233
  {
234 234
    // DAG example for topological sort from the book New Algorithms
235 235
    // (T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein)
236 236
    Digraph d;
237 237
    Digraph::NodeMap<int> order(d);
238
    
238

	
239 239
    Digraph::Node belt = d.addNode();
240 240
    Digraph::Node trousers = d.addNode();
241 241
    Digraph::Node necktie = d.addNode();
242 242
    Digraph::Node coat = d.addNode();
243 243
    Digraph::Node socks = d.addNode();
244 244
    Digraph::Node shirt = d.addNode();
245 245
    Digraph::Node shoe = d.addNode();
246 246
    Digraph::Node watch = d.addNode();
247 247
    Digraph::Node pants = d.addNode();
248 248

	
249 249
    d.addArc(socks, shoe);
250 250
    d.addArc(pants, shoe);
251 251
    d.addArc(pants, trousers);
252 252
    d.addArc(trousers, shoe);
253 253
    d.addArc(trousers, belt);
254 254
    d.addArc(belt, coat);
255 255
    d.addArc(shirt, belt);
256 256
    d.addArc(shirt, necktie);
257 257
    d.addArc(necktie, coat);
258
    
258

	
259 259
    check(dag(d), "This digraph is DAG.");
260 260
    topologicalSort(d, order);
261 261
    for (Digraph::ArcIt a(d); a != INVALID; ++a) {
262 262
      check(order[d.source(a)] < order[d.target(a)],
263 263
            "Wrong topologicalSort()");
264 264
    }
265 265
  }
266 266

	
267 267
  {
268 268
    ListGraph g;
269 269
    ListGraph::NodeMap<bool> map(g);
270
    
270

	
271 271
    ListGraph::Node n1 = g.addNode();
272 272
    ListGraph::Node n2 = g.addNode();
273 273
    ListGraph::Node n3 = g.addNode();
274 274
    ListGraph::Node n4 = g.addNode();
275 275
    ListGraph::Node n5 = g.addNode();
276 276
    ListGraph::Node n6 = g.addNode();
277 277
    ListGraph::Node n7 = g.addNode();
278 278

	
279 279
    g.addEdge(n1, n3);
280 280
    g.addEdge(n1, n4);
281 281
    g.addEdge(n2, n5);
282 282
    g.addEdge(n3, n6);
283 283
    g.addEdge(n4, n6);
284 284
    g.addEdge(n4, n7);
285 285
    g.addEdge(n5, n7);
286
   
286

	
287 287
    check(bipartite(g), "This graph is bipartite");
288 288
    check(bipartitePartitions(g, map), "This graph is bipartite");
289
    
289

	
290 290
    check(map[n1] == map[n2] && map[n1] == map[n6] && map[n1] == map[n7],
291 291
          "Wrong bipartitePartitions()");
292 292
    check(map[n3] == map[n4] && map[n3] == map[n5],
293 293
          "Wrong bipartitePartitions()");
294 294
  }
295 295

	
296 296
  return 0;
297 297
}
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-2009
5
 * Copyright (C) 2003-2010
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
  "source1 6\n"
55 55
  "target1 3\n";
56 56

	
57 57

	
58 58
void checkDfsCompile()
59 59
{
60 60
  typedef concepts::Digraph Digraph;
61 61
  typedef Dfs<Digraph> DType;
62 62
  typedef Digraph::Node Node;
63 63
  typedef Digraph::Arc Arc;
64 64

	
65 65
  Digraph G;
66 66
  Node s, t;
67 67
  Arc e;
68 68
  int l, i;
69 69
  bool b;
70 70
  DType::DistMap d(G);
71 71
  DType::PredMap p(G);
72 72
  Path<Digraph> pp;
73 73
  concepts::ReadMap<Arc,bool> am;
74 74

	
75 75
  {
76 76
    DType dfs_test(G);
77 77
    const DType& const_dfs_test = dfs_test;
78 78

	
79 79
    dfs_test.run(s);
80 80
    dfs_test.run(s,t);
81 81
    dfs_test.run();
82 82

	
83 83
    dfs_test.init();
84 84
    dfs_test.addSource(s);
85 85
    e = dfs_test.processNextArc();
86 86
    e = const_dfs_test.nextArc();
87 87
    b = const_dfs_test.emptyQueue();
88 88
    i = const_dfs_test.queueSize();
89
    
89

	
90 90
    dfs_test.start();
91 91
    dfs_test.start(t);
92 92
    dfs_test.start(am);
93 93

	
94 94
    l  = const_dfs_test.dist(t);
95 95
    e  = const_dfs_test.predArc(t);
96 96
    s  = const_dfs_test.predNode(t);
97 97
    b  = const_dfs_test.reached(t);
98 98
    d  = const_dfs_test.distMap();
99 99
    p  = const_dfs_test.predMap();
100 100
    pp = const_dfs_test.path(t);
101 101
  }
102 102
  {
103 103
    DType
104 104
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
105 105
      ::SetDistMap<concepts::ReadWriteMap<Node,int> >
106 106
      ::SetReachedMap<concepts::ReadWriteMap<Node,bool> >
107 107
      ::SetStandardProcessedMap
108 108
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
109 109
      ::Create dfs_test(G);
110 110

	
111 111
    concepts::ReadWriteMap<Node,Arc> pred_map;
112 112
    concepts::ReadWriteMap<Node,int> dist_map;
113 113
    concepts::ReadWriteMap<Node,bool> reached_map;
114 114
    concepts::WriteMap<Node,bool> processed_map;
115
    
115

	
116 116
    dfs_test
117 117
      .predMap(pred_map)
118 118
      .distMap(dist_map)
119 119
      .reachedMap(reached_map)
120 120
      .processedMap(processed_map);
121 121

	
122 122
    dfs_test.run(s);
123 123
    dfs_test.run(s,t);
124 124
    dfs_test.run();
125 125
    dfs_test.init();
126 126

	
127 127
    dfs_test.addSource(s);
128 128
    e = dfs_test.processNextArc();
129 129
    e = dfs_test.nextArc();
130 130
    b = dfs_test.emptyQueue();
131 131
    i = dfs_test.queueSize();
132
    
132

	
133 133
    dfs_test.start();
134 134
    dfs_test.start(t);
135 135
    dfs_test.start(am);
136 136

	
137 137
    l  = dfs_test.dist(t);
138 138
    e  = dfs_test.predArc(t);
139 139
    s  = dfs_test.predNode(t);
140 140
    b  = dfs_test.reached(t);
141 141
    pp = dfs_test.path(t);
142 142
  }
143 143
}
144 144

	
145 145
void checkDfsFunctionCompile()
146 146
{
147 147
  typedef int VType;
148 148
  typedef concepts::Digraph Digraph;
149 149
  typedef Digraph::Arc Arc;
150 150
  typedef Digraph::Node Node;
151 151

	
152 152
  Digraph g;
153 153
  bool b;
154 154
  dfs(g).run(Node());
155 155
  b=dfs(g).run(Node(),Node());
156 156
  dfs(g).run();
157 157
  dfs(g)
158 158
    .predMap(concepts::ReadWriteMap<Node,Arc>())
159 159
    .distMap(concepts::ReadWriteMap<Node,VType>())
160 160
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
161 161
    .processedMap(concepts::WriteMap<Node,bool>())
162 162
    .run(Node());
163 163
  b=dfs(g)
164 164
    .predMap(concepts::ReadWriteMap<Node,Arc>())
165 165
    .distMap(concepts::ReadWriteMap<Node,VType>())
166 166
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
167 167
    .processedMap(concepts::WriteMap<Node,bool>())
168 168
    .path(concepts::Path<Digraph>())
169 169
    .dist(VType())
170 170
    .run(Node(),Node());
171 171
  dfs(g)
172 172
    .predMap(concepts::ReadWriteMap<Node,Arc>())
173 173
    .distMap(concepts::ReadWriteMap<Node,VType>())
174 174
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
175 175
    .processedMap(concepts::WriteMap<Node,bool>())
176 176
    .run();
177 177
}
178 178

	
179 179
template <class Digraph>
180 180
void checkDfs() {
181 181
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
182 182

	
183 183
  Digraph G;
184 184
  Node s, t;
185 185
  Node s1, t1;
186 186

	
187 187
  std::istringstream input(test_lgf);
188 188
  digraphReader(G, input).
189 189
    node("source", s).
190 190
    node("target", t).
191 191
    node("source1", s1).
192 192
    node("target1", t1).
193 193
    run();
194 194

	
195 195
  Dfs<Digraph> dfs_test(G);
196 196
  dfs_test.run(s);
197 197

	
198 198
  Path<Digraph> p = dfs_test.path(t);
199 199
  check(p.length() == dfs_test.dist(t),"path() found a wrong path.");
200 200
  check(checkPath(G, p),"path() found a wrong path.");
201 201
  check(pathSource(G, p) == s,"path() found a wrong path.");
202 202
  check(pathTarget(G, p) == t,"path() found a wrong path.");
203 203

	
204 204
  for(NodeIt v(G); v!=INVALID; ++v) {
205 205
    if (dfs_test.reached(v)) {
206 206
      check(v==s || dfs_test.predArc(v)!=INVALID, "Wrong tree.");
207 207
      if (dfs_test.predArc(v)!=INVALID ) {
208 208
        Arc e=dfs_test.predArc(v);
209 209
        Node u=G.source(e);
210 210
        check(u==dfs_test.predNode(v),"Wrong tree.");
211 211
        check(dfs_test.dist(v) - dfs_test.dist(u) == 1,
212 212
              "Wrong distance. (" << dfs_test.dist(u) << "->"
213 213
              << dfs_test.dist(v) << ")");
214 214
      }
215 215
    }
216 216
  }
217 217

	
218 218
  {
219 219
  Dfs<Digraph> dfs(G);
220 220
  check(dfs.run(s1,t1) && dfs.reached(t1),"Node 3 is reachable from Node 6.");
221 221
  }
222 222
  
223 223
  {
224 224
    NullMap<Node,Arc> myPredMap;
225 225
    dfs(G).predMap(myPredMap).run(s);
226 226
  }
227 227
}
228 228

	
229 229
int main()
230 230
{
231 231
  checkDfs<ListDigraph>();
232 232
  checkDfs<SmartDigraph>();
233 233
  return 0;
234 234
}
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-2009
5
 * Copyright (C) 2003-2010
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/static_graph.h>
22 23
#include <lemon/full_graph.h>
23 24

	
24 25
#include "test_tools.h"
25 26
#include "graph_test.h"
26 27

	
27 28
using namespace lemon;
28 29
using namespace lemon::concepts;
29 30

	
30 31
template <class Digraph>
31 32
void checkDigraphBuild() {
32 33
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
33 34
  Digraph G;
34 35

	
35 36
  checkGraphNodeList(G, 0);
36 37
  checkGraphArcList(G, 0);
37 38

	
39
  G.reserveNode(3);
40
  G.reserveArc(4);
41

	
38 42
  Node
39 43
    n1 = G.addNode(),
40 44
    n2 = G.addNode(),
41 45
    n3 = G.addNode();
42 46
  checkGraphNodeList(G, 3);
43 47
  checkGraphArcList(G, 0);
44 48

	
45 49
  Arc a1 = G.addArc(n1, n2);
46 50
  check(G.source(a1) == n1 && G.target(a1) == n2, "Wrong arc");
47 51
  checkGraphNodeList(G, 3);
48 52
  checkGraphArcList(G, 1);
49 53

	
50 54
  checkGraphOutArcList(G, n1, 1);
51 55
  checkGraphOutArcList(G, n2, 0);
52 56
  checkGraphOutArcList(G, n3, 0);
53 57

	
54 58
  checkGraphInArcList(G, n1, 0);
55 59
  checkGraphInArcList(G, n2, 1);
56 60
  checkGraphInArcList(G, n3, 0);
57 61

	
58 62
  checkGraphConArcList(G, 1);
59 63

	
60 64
  Arc a2 = G.addArc(n2, n1),
61 65
      a3 = G.addArc(n2, n3),
62 66
      a4 = G.addArc(n2, n3);
63 67

	
64 68
  checkGraphNodeList(G, 3);
65 69
  checkGraphArcList(G, 4);
66 70

	
67 71
  checkGraphOutArcList(G, n1, 1);
68 72
  checkGraphOutArcList(G, n2, 3);
69 73
  checkGraphOutArcList(G, n3, 0);
70 74

	
71 75
  checkGraphInArcList(G, n1, 1);
72 76
  checkGraphInArcList(G, n2, 1);
73 77
  checkGraphInArcList(G, n3, 2);
74 78

	
75 79
  checkGraphConArcList(G, 4);
76 80

	
77 81
  checkNodeIds(G);
78 82
  checkArcIds(G);
79 83
  checkGraphNodeMap(G);
80 84
  checkGraphArcMap(G);
81 85
}
82 86

	
83 87
template <class Digraph>
84 88
void checkDigraphSplit() {
85 89
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
86 90

	
87 91
  Digraph G;
88 92
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
89 93
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
90 94
      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
91 95

	
92 96
  Node n4 = G.split(n2);
93 97

	
94 98
  check(G.target(OutArcIt(G, n2)) == n4 &&
95 99
        G.source(InArcIt(G, n4)) == n2,
96 100
        "Wrong split.");
97 101

	
98 102
  checkGraphNodeList(G, 4);
99 103
  checkGraphArcList(G, 5);
100 104

	
101 105
  checkGraphOutArcList(G, n1, 1);
102 106
  checkGraphOutArcList(G, n2, 1);
103 107
  checkGraphOutArcList(G, n3, 0);
104 108
  checkGraphOutArcList(G, n4, 3);
105 109

	
106 110
  checkGraphInArcList(G, n1, 1);
107 111
  checkGraphInArcList(G, n2, 1);
108 112
  checkGraphInArcList(G, n3, 2);
109 113
  checkGraphInArcList(G, n4, 1);
110 114

	
111 115
  checkGraphConArcList(G, 5);
112 116
}
113 117

	
114 118
template <class Digraph>
115 119
void checkDigraphAlter() {
116 120
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
117 121

	
118 122
  Digraph G;
119 123
  Node n1 = G.addNode(), n2 = G.addNode(),
120 124
       n3 = G.addNode(), n4 = G.addNode();
121 125
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
122 126
      a3 = G.addArc(n4, n3), a4 = G.addArc(n4, n3),
123 127
      a5 = G.addArc(n2, n4);
124 128

	
125 129
  checkGraphNodeList(G, 4);
126 130
  checkGraphArcList(G, 5);
127 131

	
128 132
  // Check changeSource() and changeTarget()
129 133
  G.changeTarget(a4, n1);
130 134

	
131 135
  checkGraphNodeList(G, 4);
132 136
  checkGraphArcList(G, 5);
133 137

	
134 138
  checkGraphOutArcList(G, n1, 1);
135 139
  checkGraphOutArcList(G, n2, 1);
136 140
  checkGraphOutArcList(G, n3, 0);
137 141
  checkGraphOutArcList(G, n4, 3);
138 142

	
139 143
  checkGraphInArcList(G, n1, 2);
140 144
  checkGraphInArcList(G, n2, 1);
141 145
  checkGraphInArcList(G, n3, 1);
142 146
  checkGraphInArcList(G, n4, 1);
143 147

	
144 148
  checkGraphConArcList(G, 5);
145 149

	
146 150
  G.changeSource(a4, n3);
147 151

	
148 152
  checkGraphNodeList(G, 4);
149 153
  checkGraphArcList(G, 5);
150 154

	
151 155
  checkGraphOutArcList(G, n1, 1);
152 156
  checkGraphOutArcList(G, n2, 1);
153 157
  checkGraphOutArcList(G, n3, 1);
154 158
  checkGraphOutArcList(G, n4, 2);
155 159

	
156 160
  checkGraphInArcList(G, n1, 2);
157 161
  checkGraphInArcList(G, n2, 1);
158 162
  checkGraphInArcList(G, n3, 1);
159 163
  checkGraphInArcList(G, n4, 1);
160 164

	
161 165
  checkGraphConArcList(G, 5);
162 166

	
163 167
  // Check contract()
164 168
  G.contract(n2, n4, false);
165 169

	
166 170
  checkGraphNodeList(G, 3);
167 171
  checkGraphArcList(G, 5);
168 172

	
169 173
  checkGraphOutArcList(G, n1, 1);
170 174
  checkGraphOutArcList(G, n2, 3);
171 175
  checkGraphOutArcList(G, n3, 1);
172 176

	
173 177
  checkGraphInArcList(G, n1, 2);
174 178
  checkGraphInArcList(G, n2, 2);
175 179
  checkGraphInArcList(G, n3, 1);
176 180

	
177 181
  checkGraphConArcList(G, 5);
178 182

	
179 183
  G.contract(n2, n1);
180 184

	
181 185
  checkGraphNodeList(G, 2);
182 186
  checkGraphArcList(G, 3);
183 187

	
184 188
  checkGraphOutArcList(G, n2, 2);
185 189
  checkGraphOutArcList(G, n3, 1);
186 190

	
187 191
  checkGraphInArcList(G, n2, 2);
188 192
  checkGraphInArcList(G, n3, 1);
189 193

	
190 194
  checkGraphConArcList(G, 3);
191 195
}
192 196

	
193 197
template <class Digraph>
194 198
void checkDigraphErase() {
195 199
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
196 200

	
197 201
  Digraph G;
198 202
  Node n1 = G.addNode(), n2 = G.addNode(),
199 203
       n3 = G.addNode(), n4 = G.addNode();
200 204
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n4, n1),
201 205
      a3 = G.addArc(n4, n3), a4 = G.addArc(n3, n1),
202 206
      a5 = G.addArc(n2, n4);
203 207

	
204 208
  // Check arc deletion
205 209
  G.erase(a1);
206 210

	
207 211
  checkGraphNodeList(G, 4);
208 212
  checkGraphArcList(G, 4);
209 213

	
210 214
  checkGraphOutArcList(G, n1, 0);
211 215
  checkGraphOutArcList(G, n2, 1);
212 216
  checkGraphOutArcList(G, n3, 1);
213 217
  checkGraphOutArcList(G, n4, 2);
214 218

	
215 219
  checkGraphInArcList(G, n1, 2);
216 220
  checkGraphInArcList(G, n2, 0);
217 221
  checkGraphInArcList(G, n3, 1);
218 222
  checkGraphInArcList(G, n4, 1);
219 223

	
220 224
  checkGraphConArcList(G, 4);
221 225

	
222 226
  // Check node deletion
223 227
  G.erase(n4);
224 228

	
225 229
  checkGraphNodeList(G, 3);
226 230
  checkGraphArcList(G, 1);
227 231

	
228 232
  checkGraphOutArcList(G, n1, 0);
229 233
  checkGraphOutArcList(G, n2, 0);
230 234
  checkGraphOutArcList(G, n3, 1);
231 235
  checkGraphOutArcList(G, n4, 0);
232 236

	
233 237
  checkGraphInArcList(G, n1, 1);
234 238
  checkGraphInArcList(G, n2, 0);
235 239
  checkGraphInArcList(G, n3, 0);
236 240
  checkGraphInArcList(G, n4, 0);
237 241

	
238 242
  checkGraphConArcList(G, 1);
239 243
}
240 244

	
241 245

	
242 246
template <class Digraph>
243 247
void checkDigraphSnapshot() {
244 248
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
245 249

	
246 250
  Digraph G;
247 251
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
248 252
  Arc a1 = G.addArc(n1, n2), a2 = G.addArc(n2, n1),
249 253
      a3 = G.addArc(n2, n3), a4 = G.addArc(n2, n3);
250 254

	
251 255
  typename Digraph::Snapshot snapshot(G);
252 256

	
253 257
  Node n = G.addNode();
254 258
  G.addArc(n3, n);
255 259
  G.addArc(n, n3);
256 260

	
257 261
  checkGraphNodeList(G, 4);
258 262
  checkGraphArcList(G, 6);
259 263

	
260 264
  snapshot.restore();
261 265

	
262 266
  checkGraphNodeList(G, 3);
263 267
  checkGraphArcList(G, 4);
264 268

	
265 269
  checkGraphOutArcList(G, n1, 1);
266 270
  checkGraphOutArcList(G, n2, 3);
267 271
  checkGraphOutArcList(G, n3, 0);
268 272

	
269 273
  checkGraphInArcList(G, n1, 1);
270 274
  checkGraphInArcList(G, n2, 1);
271 275
  checkGraphInArcList(G, n3, 2);
272 276

	
273 277
  checkGraphConArcList(G, 4);
274 278

	
275 279
  checkNodeIds(G);
276 280
  checkArcIds(G);
277 281
  checkGraphNodeMap(G);
278 282
  checkGraphArcMap(G);
279 283

	
280 284
  G.addNode();
281 285
  snapshot.save(G);
282 286

	
283 287
  G.addArc(G.addNode(), G.addNode());
284 288

	
285 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();
286 298

	
287 299
  checkGraphNodeList(G, 4);
288 300
  checkGraphArcList(G, 4);
289 301
}
290 302

	
291 303
void checkConcepts() {
292 304
  { // Checking digraph components
293 305
    checkConcept<BaseDigraphComponent, BaseDigraphComponent >();
294 306

	
295 307
    checkConcept<IDableDigraphComponent<>,
296 308
      IDableDigraphComponent<> >();
297 309

	
298 310
    checkConcept<IterableDigraphComponent<>,
299 311
      IterableDigraphComponent<> >();
300 312

	
301 313
    checkConcept<MappableDigraphComponent<>,
302 314
      MappableDigraphComponent<> >();
303 315
  }
304 316
  { // Checking skeleton digraph
305 317
    checkConcept<Digraph, Digraph>();
306 318
  }
307 319
  { // Checking ListDigraph
308 320
    checkConcept<Digraph, ListDigraph>();
309 321
    checkConcept<AlterableDigraphComponent<>, ListDigraph>();
310 322
    checkConcept<ExtendableDigraphComponent<>, ListDigraph>();
311 323
    checkConcept<ClearableDigraphComponent<>, ListDigraph>();
312 324
    checkConcept<ErasableDigraphComponent<>, ListDigraph>();
313 325
  }
314 326
  { // Checking SmartDigraph
315 327
    checkConcept<Digraph, SmartDigraph>();
316 328
    checkConcept<AlterableDigraphComponent<>, SmartDigraph>();
317 329
    checkConcept<ExtendableDigraphComponent<>, SmartDigraph>();
318 330
    checkConcept<ClearableDigraphComponent<>, SmartDigraph>();
319 331
  }
332
  { // Checking StaticDigraph
333
    checkConcept<Digraph, StaticDigraph>();
334
    checkConcept<ClearableDigraphComponent<>, StaticDigraph>();
335
  }
320 336
  { // Checking FullDigraph
321 337
    checkConcept<Digraph, FullDigraph>();
322 338
  }
323 339
}
324 340

	
325 341
template <typename Digraph>
326 342
void checkDigraphValidity() {
327 343
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
328 344
  Digraph g;
329 345

	
330 346
  Node
331 347
    n1 = g.addNode(),
332 348
    n2 = g.addNode(),
333 349
    n3 = g.addNode();
334 350

	
335 351
  Arc
336 352
    e1 = g.addArc(n1, n2),
337 353
    e2 = g.addArc(n2, n3);
338 354

	
339 355
  check(g.valid(n1), "Wrong validity check");
340 356
  check(g.valid(e1), "Wrong validity check");
341 357

	
342 358
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
343 359
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
344 360
}
345 361

	
346 362
template <typename Digraph>
347 363
void checkDigraphValidityErase() {
348 364
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
349 365
  Digraph g;
350 366

	
351 367
  Node
352 368
    n1 = g.addNode(),
353 369
    n2 = g.addNode(),
354 370
    n3 = g.addNode();
355 371

	
356 372
  Arc
357 373
    e1 = g.addArc(n1, n2),
358 374
    e2 = g.addArc(n2, n3);
359 375

	
360 376
  check(g.valid(n1), "Wrong validity check");
361 377
  check(g.valid(e1), "Wrong validity check");
362 378

	
363 379
  g.erase(n1);
364 380

	
365 381
  check(!g.valid(n1), "Wrong validity check");
366 382
  check(g.valid(n2), "Wrong validity check");
367 383
  check(g.valid(n3), "Wrong validity check");
368 384
  check(!g.valid(e1), "Wrong validity check");
369 385
  check(g.valid(e2), "Wrong validity check");
370 386

	
371 387
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
372 388
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
373 389
}
374 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

	
375 498
void checkFullDigraph(int num) {
376 499
  typedef FullDigraph Digraph;
377 500
  DIGRAPH_TYPEDEFS(Digraph);
501

	
378 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");
379 507

	
380 508
  checkGraphNodeList(G, num);
381 509
  checkGraphArcList(G, num * num);
382 510

	
383 511
  for (NodeIt n(G); n != INVALID; ++n) {
384 512
    checkGraphOutArcList(G, n, num);
385 513
    checkGraphInArcList(G, n, num);
386 514
  }
387 515

	
388 516
  checkGraphConArcList(G, num * num);
389 517

	
390 518
  checkNodeIds(G);
391 519
  checkArcIds(G);
392 520
  checkGraphNodeMap(G);
393 521
  checkGraphArcMap(G);
394 522

	
395 523
  for (int i = 0; i < G.nodeNum(); ++i) {
396 524
    check(G.index(G(i)) == i, "Wrong index");
397 525
  }
398 526

	
399 527
  for (NodeIt s(G); s != INVALID; ++s) {
400 528
    for (NodeIt t(G); t != INVALID; ++t) {
401 529
      Arc a = G.arc(s, t);
402 530
      check(G.source(a) == s && G.target(a) == t, "Wrong arc lookup");
403 531
    }
404 532
  }
405 533
}
406 534

	
407 535
void checkDigraphs() {
408 536
  { // Checking ListDigraph
409 537
    checkDigraphBuild<ListDigraph>();
410 538
    checkDigraphSplit<ListDigraph>();
411 539
    checkDigraphAlter<ListDigraph>();
412 540
    checkDigraphErase<ListDigraph>();
413 541
    checkDigraphSnapshot<ListDigraph>();
414 542
    checkDigraphValidityErase<ListDigraph>();
415 543
  }
416 544
  { // Checking SmartDigraph
417 545
    checkDigraphBuild<SmartDigraph>();
418 546
    checkDigraphSplit<SmartDigraph>();
419 547
    checkDigraphSnapshot<SmartDigraph>();
420 548
    checkDigraphValidity<SmartDigraph>();
421 549
  }
550
  { // Checking StaticDigraph
551
    checkStaticDigraph();
552
  }
422 553
  { // Checking FullDigraph
423 554
    checkFullDigraph(8);
424 555
  }
425 556
}
426 557

	
427 558
int main() {
428 559
  checkDigraphs();
429 560
  checkConcepts();
430 561
  return 0;
431 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-2009
5
 * Copyright (C) 2003-2010
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/smart_graph.h>
21 21
#include <lemon/list_graph.h>
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/dijkstra.h>
24 24
#include <lemon/path.h>
25 25
#include <lemon/bin_heap.h>
26 26

	
27 27
#include "graph_test.h"
28 28
#include "test_tools.h"
29 29

	
30 30
using namespace lemon;
31 31

	
32 32
char test_lgf[] =
33 33
  "@nodes\n"
34 34
  "label\n"
35 35
  "0\n"
36 36
  "1\n"
37 37
  "2\n"
38 38
  "3\n"
39 39
  "4\n"
40 40
  "@arcs\n"
41 41
  "     label length\n"
42 42
  "0 1  0     1\n"
43 43
  "1 2  1     1\n"
44 44
  "2 3  2     1\n"
45 45
  "0 3  4     5\n"
46 46
  "0 3  5     10\n"
47 47
  "0 3  6     7\n"
48 48
  "4 2  7     1\n"
49 49
  "@attributes\n"
50 50
  "source 0\n"
51 51
  "target 3\n";
52 52

	
53 53
void checkDijkstraCompile()
54 54
{
55 55
  typedef int VType;
56 56
  typedef concepts::Digraph Digraph;
57 57
  typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
58 58
  typedef Dijkstra<Digraph, LengthMap> DType;
59 59
  typedef Digraph::Node Node;
60 60
  typedef Digraph::Arc Arc;
61 61

	
62 62
  Digraph G;
63 63
  Node s, t, n;
64 64
  Arc e;
65 65
  VType l;
66 66
  int i;
67 67
  bool b;
68 68
  DType::DistMap d(G);
69 69
  DType::PredMap p(G);
70 70
  LengthMap length;
71 71
  Path<Digraph> pp;
72 72
  concepts::ReadMap<Node,bool> nm;
73 73

	
74 74
  {
75 75
    DType dijkstra_test(G,length);
76 76
    const DType& const_dijkstra_test = dijkstra_test;
77 77

	
78 78
    dijkstra_test.run(s);
79 79
    dijkstra_test.run(s,t);
80 80

	
81 81
    dijkstra_test.init();
82 82
    dijkstra_test.addSource(s);
83 83
    dijkstra_test.addSource(s, 1);
84 84
    n = dijkstra_test.processNextNode();
85 85
    n = const_dijkstra_test.nextNode();
86 86
    b = const_dijkstra_test.emptyQueue();
87 87
    i = const_dijkstra_test.queueSize();
88
    
88

	
89 89
    dijkstra_test.start();
90 90
    dijkstra_test.start(t);
91 91
    dijkstra_test.start(nm);
92 92

	
93 93
    l  = const_dijkstra_test.dist(t);
94 94
    e  = const_dijkstra_test.predArc(t);
95 95
    s  = const_dijkstra_test.predNode(t);
96 96
    b  = const_dijkstra_test.reached(t);
97 97
    b  = const_dijkstra_test.processed(t);
98 98
    d  = const_dijkstra_test.distMap();
99 99
    p  = const_dijkstra_test.predMap();
100 100
    pp = const_dijkstra_test.path(t);
101 101
    l  = const_dijkstra_test.currentDist(t);
102 102
  }
103 103
  {
104 104
    DType
105 105
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
106 106
      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
107 107
      ::SetStandardProcessedMap
108 108
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
109 109
      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
110 110
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
111 111
      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
112
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >, 
112
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >,
113 113
                concepts::ReadWriteMap<Node,int> >
114 114
      ::Create dijkstra_test(G,length);
115 115

	
116 116
    LengthMap length_map;
117 117
    concepts::ReadWriteMap<Node,Arc> pred_map;
118 118
    concepts::ReadWriteMap<Node,VType> dist_map;
119 119
    concepts::WriteMap<Node,bool> processed_map;
120 120
    concepts::ReadWriteMap<Node,int> heap_cross_ref;
121 121
    BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
122
    
122

	
123 123
    dijkstra_test
124 124
      .lengthMap(length_map)
125 125
      .predMap(pred_map)
126 126
      .distMap(dist_map)
127 127
      .processedMap(processed_map)
128 128
      .heap(heap, heap_cross_ref);
129 129

	
130 130
    dijkstra_test.run(s);
131 131
    dijkstra_test.run(s,t);
132 132

	
133 133
    dijkstra_test.addSource(s);
134 134
    dijkstra_test.addSource(s, 1);
135 135
    n = dijkstra_test.processNextNode();
136 136
    n = dijkstra_test.nextNode();
137 137
    b = dijkstra_test.emptyQueue();
138 138
    i = dijkstra_test.queueSize();
139
    
139

	
140 140
    dijkstra_test.start();
141 141
    dijkstra_test.start(t);
142 142
    dijkstra_test.start(nm);
143 143

	
144 144
    l  = dijkstra_test.dist(t);
145 145
    e  = dijkstra_test.predArc(t);
146 146
    s  = dijkstra_test.predNode(t);
147 147
    b  = dijkstra_test.reached(t);
148 148
    b  = dijkstra_test.processed(t);
149 149
    pp = dijkstra_test.path(t);
150 150
    l  = dijkstra_test.currentDist(t);
151 151
  }
152 152

	
153 153
}
154 154

	
155 155
void checkDijkstraFunctionCompile()
156 156
{
157 157
  typedef int VType;
158 158
  typedef concepts::Digraph Digraph;
159 159
  typedef Digraph::Arc Arc;
160 160
  typedef Digraph::Node Node;
161 161
  typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
162 162

	
163 163
  Digraph g;
164 164
  bool b;
165 165
  dijkstra(g,LengthMap()).run(Node());
166 166
  b=dijkstra(g,LengthMap()).run(Node(),Node());
167 167
  dijkstra(g,LengthMap())
168 168
    .predMap(concepts::ReadWriteMap<Node,Arc>())
169 169
    .distMap(concepts::ReadWriteMap<Node,VType>())
170 170
    .processedMap(concepts::WriteMap<Node,bool>())
171 171
    .run(Node());
172 172
  b=dijkstra(g,LengthMap())
173 173
    .predMap(concepts::ReadWriteMap<Node,Arc>())
174 174
    .distMap(concepts::ReadWriteMap<Node,VType>())
175 175
    .processedMap(concepts::WriteMap<Node,bool>())
176 176
    .path(concepts::Path<Digraph>())
177 177
    .dist(VType())
178 178
    .run(Node(),Node());
179 179
}
180 180

	
181 181
template <class Digraph>
182 182
void checkDijkstra() {
183 183
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
184 184
  typedef typename Digraph::template ArcMap<int> LengthMap;
185 185

	
186 186
  Digraph G;
187 187
  Node s, t;
188 188
  LengthMap length(G);
189 189

	
190 190
  std::istringstream input(test_lgf);
191 191
  digraphReader(G, input).
192 192
    arcMap("length", length).
193 193
    node("source", s).
194 194
    node("target", t).
195 195
    run();
196 196

	
197 197
  Dijkstra<Digraph, LengthMap>
198 198
        dijkstra_test(G, length);
199 199
  dijkstra_test.run(s);
200 200

	
201 201
  check(dijkstra_test.dist(t)==3,"Dijkstra found a wrong path.");
202 202

	
203 203
  Path<Digraph> p = dijkstra_test.path(t);
204 204
  check(p.length()==3,"path() found a wrong path.");
205 205
  check(checkPath(G, p),"path() found a wrong path.");
206 206
  check(pathSource(G, p) == s,"path() found a wrong path.");
207 207
  check(pathTarget(G, p) == t,"path() found a wrong path.");
208 208

	
209 209
  for(ArcIt e(G); e!=INVALID; ++e) {
210 210
    Node u=G.source(e);
211 211
    Node v=G.target(e);
212 212
    check( !dijkstra_test.reached(u) ||
213 213
           (dijkstra_test.dist(v) - dijkstra_test.dist(u) <= length[e]),
214 214
           "Wrong output. dist(target)-dist(source)-arc_length=" <<
215 215
           dijkstra_test.dist(v) - dijkstra_test.dist(u) - length[e]);
216 216
  }
217 217

	
218 218
  for(NodeIt v(G); v!=INVALID; ++v) {
219 219
    if (dijkstra_test.reached(v)) {
220 220
      check(v==s || dijkstra_test.predArc(v)!=INVALID, "Wrong tree.");
221 221
      if (dijkstra_test.predArc(v)!=INVALID ) {
222 222
        Arc e=dijkstra_test.predArc(v);
223 223
        Node u=G.source(e);
224 224
        check(u==dijkstra_test.predNode(v),"Wrong tree.");
225 225
        check(dijkstra_test.dist(v) - dijkstra_test.dist(u) == length[e],
226 226
              "Wrong distance! Difference: " <<
227 227
              std::abs(dijkstra_test.dist(v)-dijkstra_test.dist(u)-length[e]));
228 228
      }
229 229
    }
230 230
  }
231 231

	
232 232
  {
233 233
    NullMap<Node,Arc> myPredMap;
234 234
    dijkstra(G,length).predMap(myPredMap).run(s);
235 235
  }
236 236
}
237 237

	
238 238
int main() {
239 239
  checkDijkstra<ListDigraph>();
240 240
  checkDijkstra<SmartDigraph>();
241 241
  return 0;
242 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-2010
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 <lemon/concepts/digraph.h>
23 23
#include <lemon/concepts/graph.h>
24 24
#include <lemon/concept_check.h>
25 25

	
26 26
#include <lemon/list_graph.h>
27 27

	
28 28
#include <lemon/edge_set.h>
29 29

	
30 30
#include "graph_test.h"
31 31
#include "test_tools.h"
32 32

	
33 33
using namespace lemon;
34 34

	
35 35
void checkSmartArcSet() {
36 36
  checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
37 37

	
38 38
  typedef ListDigraph Digraph;
39 39
  typedef SmartArcSet<Digraph> ArcSet;
40 40

	
41 41
  Digraph digraph;
42 42
  Digraph::Node
43 43
    n1 = digraph.addNode(),
44 44
    n2 = digraph.addNode();
45 45

	
46 46
  Digraph::Arc ga1 = digraph.addArc(n1, n2);
47 47

	
48 48
  ArcSet arc_set(digraph);
49 49

	
50 50
  Digraph::Arc ga2 = digraph.addArc(n2, n1);
51 51

	
52 52
  checkGraphNodeList(arc_set, 2);
53 53
  checkGraphArcList(arc_set, 0);
54 54

	
55 55
  Digraph::Node
56 56
    n3 = digraph.addNode();
57 57
  checkGraphNodeList(arc_set, 3);
58 58
  checkGraphArcList(arc_set, 0);
59 59

	
60 60
  ArcSet::Arc a1 = arc_set.addArc(n1, n2);
61 61
  check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
62 62
  checkGraphNodeList(arc_set, 3);
63 63
  checkGraphArcList(arc_set, 1);
64 64

	
65 65
  checkGraphOutArcList(arc_set, n1, 1);
66 66
  checkGraphOutArcList(arc_set, n2, 0);
67 67
  checkGraphOutArcList(arc_set, n3, 0);
68 68

	
69 69
  checkGraphInArcList(arc_set, n1, 0);
70 70
  checkGraphInArcList(arc_set, n2, 1);
71 71
  checkGraphInArcList(arc_set, n3, 0);
72 72

	
73 73
  checkGraphConArcList(arc_set, 1);
74 74

	
75 75
  ArcSet::Arc a2 = arc_set.addArc(n2, n1),
76 76
    a3 = arc_set.addArc(n2, n3),
77 77
    a4 = arc_set.addArc(n2, n3);
78 78
  checkGraphNodeList(arc_set, 3);
79 79
  checkGraphArcList(arc_set, 4);
80 80

	
81 81
  checkGraphOutArcList(arc_set, n1, 1);
82 82
  checkGraphOutArcList(arc_set, n2, 3);
83 83
  checkGraphOutArcList(arc_set, n3, 0);
84 84

	
85 85
  checkGraphInArcList(arc_set, n1, 1);
86 86
  checkGraphInArcList(arc_set, n2, 1);
87 87
  checkGraphInArcList(arc_set, n3, 2);
88 88

	
89 89
  checkGraphConArcList(arc_set, 4);
90 90

	
91 91
  checkNodeIds(arc_set);
92 92
  checkArcIds(arc_set);
93 93
  checkGraphNodeMap(arc_set);
94 94
  checkGraphArcMap(arc_set);
95 95

	
96 96
  check(arc_set.valid(), "Wrong validity");
97 97
  digraph.erase(n1);
98 98
  check(!arc_set.valid(), "Wrong validity");
99 99
}
100 100

	
101 101
void checkListArcSet() {
102 102
  checkConcept<concepts::Digraph, SmartArcSet<ListDigraph> >();
103 103

	
104 104
  typedef ListDigraph Digraph;
105 105
  typedef ListArcSet<Digraph> ArcSet;
106 106

	
107 107
  Digraph digraph;
108 108
  Digraph::Node
109 109
    n1 = digraph.addNode(),
110 110
    n2 = digraph.addNode();
111 111

	
112 112
  Digraph::Arc ga1 = digraph.addArc(n1, n2);
113 113

	
114 114
  ArcSet arc_set(digraph);
115 115

	
116 116
  Digraph::Arc ga2 = digraph.addArc(n2, n1);
117 117

	
118 118
  checkGraphNodeList(arc_set, 2);
119 119
  checkGraphArcList(arc_set, 0);
120 120

	
121 121
  Digraph::Node
122 122
    n3 = digraph.addNode();
123 123
  checkGraphNodeList(arc_set, 3);
124 124
  checkGraphArcList(arc_set, 0);
125 125

	
126 126
  ArcSet::Arc a1 = arc_set.addArc(n1, n2);
127 127
  check(arc_set.source(a1) == n1 && arc_set.target(a1) == n2, "Wrong arc");
128 128
  checkGraphNodeList(arc_set, 3);
129 129
  checkGraphArcList(arc_set, 1);
130 130

	
131 131
  checkGraphOutArcList(arc_set, n1, 1);
132 132
  checkGraphOutArcList(arc_set, n2, 0);
133 133
  checkGraphOutArcList(arc_set, n3, 0);
134 134

	
135 135
  checkGraphInArcList(arc_set, n1, 0);
136 136
  checkGraphInArcList(arc_set, n2, 1);
137 137
  checkGraphInArcList(arc_set, n3, 0);
138 138

	
139 139
  checkGraphConArcList(arc_set, 1);
140 140

	
141 141
  ArcSet::Arc a2 = arc_set.addArc(n2, n1),
142 142
    a3 = arc_set.addArc(n2, n3),
143 143
    a4 = arc_set.addArc(n2, n3);
144 144
  checkGraphNodeList(arc_set, 3);
145 145
  checkGraphArcList(arc_set, 4);
146 146

	
147 147
  checkGraphOutArcList(arc_set, n1, 1);
148 148
  checkGraphOutArcList(arc_set, n2, 3);
149 149
  checkGraphOutArcList(arc_set, n3, 0);
150 150

	
151 151
  checkGraphInArcList(arc_set, n1, 1);
152 152
  checkGraphInArcList(arc_set, n2, 1);
153 153
  checkGraphInArcList(arc_set, n3, 2);
154 154

	
155 155
  checkGraphConArcList(arc_set, 4);
156 156

	
157 157
  checkNodeIds(arc_set);
158 158
  checkArcIds(arc_set);
159 159
  checkGraphNodeMap(arc_set);
160 160
  checkGraphArcMap(arc_set);
161 161

	
162 162
  digraph.erase(n1);
163 163

	
164 164
  checkGraphNodeList(arc_set, 2);
165 165
  checkGraphArcList(arc_set, 2);
166 166

	
167 167
  checkGraphOutArcList(arc_set, n2, 2);
168 168
  checkGraphOutArcList(arc_set, n3, 0);
169 169

	
170 170
  checkGraphInArcList(arc_set, n2, 0);
171 171
  checkGraphInArcList(arc_set, n3, 2);
172 172

	
173 173
  checkNodeIds(arc_set);
174 174
  checkArcIds(arc_set);
175 175
  checkGraphNodeMap(arc_set);
176 176
  checkGraphArcMap(arc_set);
177 177

	
178 178
  checkGraphConArcList(arc_set, 2);
179 179
}
180 180

	
181 181
void checkSmartEdgeSet() {
182 182
  checkConcept<concepts::Digraph, SmartEdgeSet<ListDigraph> >();
183 183

	
184 184
  typedef ListDigraph Digraph;
185 185
  typedef SmartEdgeSet<Digraph> EdgeSet;
186 186

	
187 187
  Digraph digraph;
188 188
  Digraph::Node
189 189
    n1 = digraph.addNode(),
190 190
    n2 = digraph.addNode();
191 191

	
192 192
  Digraph::Arc ga1 = digraph.addArc(n1, n2);
193 193

	
194 194
  EdgeSet edge_set(digraph);
195 195

	
196 196
  Digraph::Arc ga2 = digraph.addArc(n2, n1);
197 197

	
198 198
  checkGraphNodeList(edge_set, 2);
199 199
  checkGraphArcList(edge_set, 0);
200 200
  checkGraphEdgeList(edge_set, 0);
201 201

	
202 202
  Digraph::Node
203 203
    n3 = digraph.addNode();
204 204
  checkGraphNodeList(edge_set, 3);
205 205
  checkGraphArcList(edge_set, 0);
206 206
  checkGraphEdgeList(edge_set, 0);
207 207

	
208 208
  EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
209 209
  check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
210 210
        (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
211 211
  checkGraphNodeList(edge_set, 3);
212 212
  checkGraphArcList(edge_set, 2);
213 213
  checkGraphEdgeList(edge_set, 1);
214 214

	
215 215
  checkGraphOutArcList(edge_set, n1, 1);
216 216
  checkGraphOutArcList(edge_set, n2, 1);
217 217
  checkGraphOutArcList(edge_set, n3, 0);
218 218

	
219 219
  checkGraphInArcList(edge_set, n1, 1);
220 220
  checkGraphInArcList(edge_set, n2, 1);
221 221
  checkGraphInArcList(edge_set, n3, 0);
222 222

	
223 223
  checkGraphIncEdgeList(edge_set, n1, 1);
224 224
  checkGraphIncEdgeList(edge_set, n2, 1);
225 225
  checkGraphIncEdgeList(edge_set, n3, 0);
226 226

	
227 227
  checkGraphConEdgeList(edge_set, 1);
228 228
  checkGraphConArcList(edge_set, 2);
229 229

	
230 230
  EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
231 231
    e3 = edge_set.addEdge(n2, n3),
232 232
    e4 = edge_set.addEdge(n2, n3);
233 233
  checkGraphNodeList(edge_set, 3);
234 234
  checkGraphEdgeList(edge_set, 4);
235 235

	
236 236
  checkGraphOutArcList(edge_set, n1, 2);
237 237
  checkGraphOutArcList(edge_set, n2, 4);
238 238
  checkGraphOutArcList(edge_set, n3, 2);
239 239

	
240 240
  checkGraphInArcList(edge_set, n1, 2);
241 241
  checkGraphInArcList(edge_set, n2, 4);
242 242
  checkGraphInArcList(edge_set, n3, 2);
243 243

	
244 244
  checkGraphIncEdgeList(edge_set, n1, 2);
245 245
  checkGraphIncEdgeList(edge_set, n2, 4);
246 246
  checkGraphIncEdgeList(edge_set, n3, 2);
247 247

	
248 248
  checkGraphConEdgeList(edge_set, 4);
249 249
  checkGraphConArcList(edge_set, 8);
250 250

	
251 251
  checkArcDirections(edge_set);
252 252

	
253 253
  checkNodeIds(edge_set);
254 254
  checkArcIds(edge_set);
255 255
  checkEdgeIds(edge_set);
256 256
  checkGraphNodeMap(edge_set);
257 257
  checkGraphArcMap(edge_set);
258 258
  checkGraphEdgeMap(edge_set);
259 259

	
260 260
  check(edge_set.valid(), "Wrong validity");
261 261
  digraph.erase(n1);
262 262
  check(!edge_set.valid(), "Wrong validity");
263 263
}
264 264

	
265 265
void checkListEdgeSet() {
266 266
  checkConcept<concepts::Digraph, ListEdgeSet<ListDigraph> >();
267 267

	
268 268
  typedef ListDigraph Digraph;
269 269
  typedef ListEdgeSet<Digraph> EdgeSet;
270 270

	
271 271
  Digraph digraph;
272 272
  Digraph::Node
273 273
    n1 = digraph.addNode(),
274 274
    n2 = digraph.addNode();
275 275

	
276 276
  Digraph::Arc ga1 = digraph.addArc(n1, n2);
277 277

	
278 278
  EdgeSet edge_set(digraph);
279 279

	
280 280
  Digraph::Arc ga2 = digraph.addArc(n2, n1);
281 281

	
282 282
  checkGraphNodeList(edge_set, 2);
283 283
  checkGraphArcList(edge_set, 0);
284 284
  checkGraphEdgeList(edge_set, 0);
285 285

	
286 286
  Digraph::Node
287 287
    n3 = digraph.addNode();
288 288
  checkGraphNodeList(edge_set, 3);
289 289
  checkGraphArcList(edge_set, 0);
290 290
  checkGraphEdgeList(edge_set, 0);
291 291

	
292 292
  EdgeSet::Edge e1 = edge_set.addEdge(n1, n2);
293 293
  check((edge_set.u(e1) == n1 && edge_set.v(e1) == n2) ||
294 294
        (edge_set.v(e1) == n1 && edge_set.u(e1) == n2), "Wrong edge");
295 295
  checkGraphNodeList(edge_set, 3);
296 296
  checkGraphArcList(edge_set, 2);
297 297
  checkGraphEdgeList(edge_set, 1);
298 298

	
299 299
  checkGraphOutArcList(edge_set, n1, 1);
300 300
  checkGraphOutArcList(edge_set, n2, 1);
301 301
  checkGraphOutArcList(edge_set, n3, 0);
302 302

	
303 303
  checkGraphInArcList(edge_set, n1, 1);
304 304
  checkGraphInArcList(edge_set, n2, 1);
305 305
  checkGraphInArcList(edge_set, n3, 0);
306 306

	
307 307
  checkGraphIncEdgeList(edge_set, n1, 1);
308 308
  checkGraphIncEdgeList(edge_set, n2, 1);
309 309
  checkGraphIncEdgeList(edge_set, n3, 0);
310 310

	
311 311
  checkGraphConEdgeList(edge_set, 1);
312 312
  checkGraphConArcList(edge_set, 2);
313 313

	
314 314
  EdgeSet::Edge e2 = edge_set.addEdge(n2, n1),
315 315
    e3 = edge_set.addEdge(n2, n3),
316 316
    e4 = edge_set.addEdge(n2, n3);
317 317
  checkGraphNodeList(edge_set, 3);
318 318
  checkGraphEdgeList(edge_set, 4);
319 319

	
320 320
  checkGraphOutArcList(edge_set, n1, 2);
321 321
  checkGraphOutArcList(edge_set, n2, 4);
322 322
  checkGraphOutArcList(edge_set, n3, 2);
323 323

	
324 324
  checkGraphInArcList(edge_set, n1, 2);
325 325
  checkGraphInArcList(edge_set, n2, 4);
326 326
  checkGraphInArcList(edge_set, n3, 2);
327 327

	
328 328
  checkGraphIncEdgeList(edge_set, n1, 2);
329 329
  checkGraphIncEdgeList(edge_set, n2, 4);
330 330
  checkGraphIncEdgeList(edge_set, n3, 2);
331 331

	
332 332
  checkGraphConEdgeList(edge_set, 4);
333 333
  checkGraphConArcList(edge_set, 8);
334 334

	
335 335
  checkArcDirections(edge_set);
336 336

	
337 337
  checkNodeIds(edge_set);
338 338
  checkArcIds(edge_set);
339 339
  checkEdgeIds(edge_set);
340 340
  checkGraphNodeMap(edge_set);
341 341
  checkGraphArcMap(edge_set);
342 342
  checkGraphEdgeMap(edge_set);
343 343

	
344 344
  digraph.erase(n1);
345 345

	
346 346
  checkGraphNodeList(edge_set, 2);
347 347
  checkGraphArcList(edge_set, 4);
348 348
  checkGraphEdgeList(edge_set, 2);
349 349

	
350 350
  checkGraphOutArcList(edge_set, n2, 2);
351 351
  checkGraphOutArcList(edge_set, n3, 2);
352 352

	
353 353
  checkGraphInArcList(edge_set, n2, 2);
354 354
  checkGraphInArcList(edge_set, n3, 2);
355 355

	
356 356
  checkGraphIncEdgeList(edge_set, n2, 2);
357 357
  checkGraphIncEdgeList(edge_set, n3, 2);
358 358

	
359 359
  checkNodeIds(edge_set);
360 360
  checkArcIds(edge_set);
361 361
  checkEdgeIds(edge_set);
362 362
  checkGraphNodeMap(edge_set);
363 363
  checkGraphArcMap(edge_set);
364 364
  checkGraphEdgeMap(edge_set);
365 365

	
366 366
  checkGraphConEdgeList(edge_set, 2);
367 367
  checkGraphConArcList(edge_set, 4);
368 368

	
369 369
}
370 370

	
371 371

	
372 372
int main() {
373 373

	
374 374
  checkSmartArcSet();
375 375
  checkListArcSet();
376 376
  checkSmartEdgeSet();
377 377
  checkListEdgeSet();
378 378

	
379 379
  return 0;
380 380
}
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-2009
5
 * Copyright (C) 2003-2010
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/euler.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/adaptors.h>
22 22
#include "test_tools.h"
23 23

	
24 24
using namespace lemon;
25 25

	
26 26
template <typename Digraph>
27 27
void checkDiEulerIt(const Digraph& g,
28 28
                    const typename Digraph::Node& start = INVALID)
29 29
{
30 30
  typename Digraph::template ArcMap<int> visitationNumber(g, 0);
31 31

	
32 32
  DiEulerIt<Digraph> e(g, start);
33 33
  if (e == INVALID) return;
34 34
  typename Digraph::Node firstNode = g.source(e);
35 35
  typename Digraph::Node lastNode = g.target(e);
36 36
  if (start != INVALID) {
37 37
    check(firstNode == start, "checkDiEulerIt: Wrong first node");
38 38
  }
39 39

	
40 40
  for (; e != INVALID; ++e) {
41 41
    if (e != INVALID) lastNode = g.target(e);
42 42
    ++visitationNumber[e];
43 43
  }
44 44

	
45 45
  check(firstNode == lastNode,
46 46
      "checkDiEulerIt: First and last nodes are not the same");
47 47

	
48 48
  for (typename Digraph::ArcIt a(g); a != INVALID; ++a)
49 49
  {
50 50
    check(visitationNumber[a] == 1,
51 51
        "checkDiEulerIt: Not visited or multiple times visited arc found");
52 52
  }
53 53
}
54 54

	
55 55
template <typename Graph>
56 56
void checkEulerIt(const Graph& g,
57 57
                  const typename Graph::Node& start = INVALID)
58 58
{
59 59
  typename Graph::template EdgeMap<int> visitationNumber(g, 0);
60 60

	
61 61
  EulerIt<Graph> e(g, start);
62 62
  if (e == INVALID) return;
63 63
  typename Graph::Node firstNode = g.source(typename Graph::Arc(e));
64 64
  typename Graph::Node lastNode = g.target(typename Graph::Arc(e));
65 65
  if (start != INVALID) {
66 66
    check(firstNode == start, "checkEulerIt: Wrong first node");
67 67
  }
68 68

	
69 69
  for (; e != INVALID; ++e) {
70 70
    if (e != INVALID) lastNode = g.target(typename Graph::Arc(e));
71 71
    ++visitationNumber[e];
72 72
  }
73 73

	
74 74
  check(firstNode == lastNode,
75 75
      "checkEulerIt: First and last nodes are not the same");
76 76

	
77 77
  for (typename Graph::EdgeIt e(g); e != INVALID; ++e)
78 78
  {
79 79
    check(visitationNumber[e] == 1,
80 80
        "checkEulerIt: Not visited or multiple times visited edge found");
81 81
  }
82 82
}
83 83

	
84 84
int main()
85 85
{
86 86
  typedef ListDigraph Digraph;
87 87
  typedef Undirector<Digraph> Graph;
88
  
88

	
89 89
  {
90 90
    Digraph d;
91 91
    Graph g(d);
92
    
92

	
93 93
    checkDiEulerIt(d);
94 94
    checkDiEulerIt(g);
95 95
    checkEulerIt(g);
96 96

	
97 97
    check(eulerian(d), "This graph is Eulerian");
98 98
    check(eulerian(g), "This graph is Eulerian");
99 99
  }
100 100
  {
101 101
    Digraph d;
102 102
    Graph g(d);
103 103
    Digraph::Node n = d.addNode();
104 104

	
105 105
    checkDiEulerIt(d);
106 106
    checkDiEulerIt(g);
107 107
    checkEulerIt(g);
108 108

	
109 109
    check(eulerian(d), "This graph is Eulerian");
110 110
    check(eulerian(g), "This graph is Eulerian");
111 111
  }
112 112
  {
113 113
    Digraph d;
114 114
    Graph g(d);
115 115
    Digraph::Node n = d.addNode();
116 116
    d.addArc(n, n);
117 117

	
118 118
    checkDiEulerIt(d);
119 119
    checkDiEulerIt(g);
120 120
    checkEulerIt(g);
121 121

	
122 122
    check(eulerian(d), "This graph is Eulerian");
123 123
    check(eulerian(g), "This graph is Eulerian");
124 124
  }
125 125
  {
126 126
    Digraph d;
127 127
    Graph g(d);
128 128
    Digraph::Node n1 = d.addNode();
129 129
    Digraph::Node n2 = d.addNode();
130 130
    Digraph::Node n3 = d.addNode();
131
    
131

	
132 132
    d.addArc(n1, n2);
133 133
    d.addArc(n2, n1);
134 134
    d.addArc(n2, n3);
135 135
    d.addArc(n3, n2);
136 136

	
137 137
    checkDiEulerIt(d);
138 138
    checkDiEulerIt(d, n2);
139 139
    checkDiEulerIt(g);
140 140
    checkDiEulerIt(g, n2);
141 141
    checkEulerIt(g);
142 142
    checkEulerIt(g, n2);
143 143

	
144 144
    check(eulerian(d), "This graph is Eulerian");
145 145
    check(eulerian(g), "This graph is Eulerian");
146 146
  }
147 147
  {
148 148
    Digraph d;
149 149
    Graph g(d);
150 150
    Digraph::Node n1 = d.addNode();
151 151
    Digraph::Node n2 = d.addNode();
152 152
    Digraph::Node n3 = d.addNode();
153 153
    Digraph::Node n4 = d.addNode();
154 154
    Digraph::Node n5 = d.addNode();
155 155
    Digraph::Node n6 = d.addNode();
156
    
156

	
157 157
    d.addArc(n1, n2);
158 158
    d.addArc(n2, n4);
159 159
    d.addArc(n1, n3);
160 160
    d.addArc(n3, n4);
161 161
    d.addArc(n4, n1);
162 162
    d.addArc(n3, n5);
163 163
    d.addArc(n5, n2);
164 164
    d.addArc(n4, n6);
165 165
    d.addArc(n2, n6);
166 166
    d.addArc(n6, n1);
167 167
    d.addArc(n6, n3);
168 168

	
169 169
    checkDiEulerIt(d);
170 170
    checkDiEulerIt(d, n1);
171 171
    checkDiEulerIt(d, n5);
172 172

	
173 173
    checkDiEulerIt(g);
174 174
    checkDiEulerIt(g, n1);
175 175
    checkDiEulerIt(g, n5);
176 176
    checkEulerIt(g);
177 177
    checkEulerIt(g, n1);
178 178
    checkEulerIt(g, n5);
179 179

	
180 180
    check(eulerian(d), "This graph is Eulerian");
181 181
    check(eulerian(g), "This graph is Eulerian");
182 182
  }
183 183
  {
184 184
    Digraph d;
185 185
    Graph g(d);
186 186
    Digraph::Node n0 = d.addNode();
187 187
    Digraph::Node n1 = d.addNode();
188 188
    Digraph::Node n2 = d.addNode();
189 189
    Digraph::Node n3 = d.addNode();
190 190
    Digraph::Node n4 = d.addNode();
191 191
    Digraph::Node n5 = d.addNode();
192
    
192

	
193 193
    d.addArc(n1, n2);
194 194
    d.addArc(n2, n3);
195 195
    d.addArc(n3, n1);
196 196

	
197 197
    checkDiEulerIt(d);
198 198
    checkDiEulerIt(d, n2);
199 199

	
200 200
    checkDiEulerIt(g);
201 201
    checkDiEulerIt(g, n2);
202 202
    checkEulerIt(g);
203 203
    checkEulerIt(g, n2);
204 204

	
205 205
    check(!eulerian(d), "This graph is not Eulerian");
206 206
    check(!eulerian(g), "This graph is not Eulerian");
207 207
  }
208 208
  {
209 209
    Digraph d;
210 210
    Graph g(d);
211 211
    Digraph::Node n1 = d.addNode();
212 212
    Digraph::Node n2 = d.addNode();
213 213
    Digraph::Node n3 = d.addNode();
214
    
214

	
215 215
    d.addArc(n1, n2);
216 216
    d.addArc(n2, n3);
217 217

	
218 218
    check(!eulerian(d), "This graph is not Eulerian");
219 219
    check(!eulerian(g), "This graph is not Eulerian");
220 220
  }
221 221

	
222 222
  return 0;
223 223
}
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-2010
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

	
1 19
#include <iostream>
2 20

	
3 21
#include "test_tools.h"
4 22
#include <lemon/smart_graph.h>
5 23
#include <lemon/concepts/graph.h>
6 24
#include <lemon/concepts/maps.h>
7 25
#include <lemon/lgf_reader.h>
8 26
#include <lemon/gomory_hu.h>
9 27
#include <cstdlib>
10 28

	
11 29
using namespace std;
12 30
using namespace lemon;
13 31

	
14 32
typedef SmartGraph Graph;
15 33

	
16 34
char test_lgf[] =
17 35
  "@nodes\n"
18 36
  "label\n"
19 37
  "0\n"
20 38
  "1\n"
21 39
  "2\n"
22 40
  "3\n"
23 41
  "4\n"
24 42
  "@arcs\n"
25 43
  "     label capacity\n"
26 44
  "0 1  0     1\n"
27 45
  "1 2  1     1\n"
28 46
  "2 3  2     1\n"
29 47
  "0 3  4     5\n"
30 48
  "0 3  5     10\n"
31 49
  "0 3  6     7\n"
32 50
  "4 2  7     1\n"
33 51
  "@attributes\n"
34 52
  "source 0\n"
35 53
  "target 3\n";
36
  
54

	
37 55
void checkGomoryHuCompile()
38 56
{
39 57
  typedef int Value;
40 58
  typedef concepts::Graph Graph;
41 59

	
42 60
  typedef Graph::Node Node;
43 61
  typedef Graph::Edge Edge;
44 62
  typedef concepts::ReadMap<Edge, Value> CapMap;
45 63
  typedef concepts::ReadWriteMap<Node, bool> CutMap;
46 64

	
47 65
  Graph g;
48 66
  Node n;
49 67
  CapMap cap;
50 68
  CutMap cut;
51 69
  Value v;
52 70
  int d;
53 71

	
54 72
  GomoryHu<Graph, CapMap> gh_test(g, cap);
55 73
  const GomoryHu<Graph, CapMap>&
56 74
    const_gh_test = gh_test;
57 75

	
58 76
  gh_test.run();
59 77

	
60 78
  n = const_gh_test.predNode(n);
61 79
  v = const_gh_test.predValue(n);
62 80
  d = const_gh_test.rootDist(n);
63 81
  v = const_gh_test.minCutValue(n, n);
64 82
  v = const_gh_test.minCutMap(n, n, cut);
65 83
}
66 84

	
67 85
GRAPH_TYPEDEFS(Graph);
68 86
typedef Graph::EdgeMap<int> IntEdgeMap;
69 87
typedef Graph::NodeMap<bool> BoolNodeMap;
70 88

	
71 89
int cutValue(const Graph& graph, const BoolNodeMap& cut,
72
	     const IntEdgeMap& capacity) {
90
             const IntEdgeMap& capacity) {
73 91

	
74 92
  int sum = 0;
75 93
  for (EdgeIt e(graph); e != INVALID; ++e) {
76 94
    Node s = graph.u(e);
77 95
    Node t = graph.v(e);
78 96

	
79 97
    if (cut[s] != cut[t]) {
80 98
      sum += capacity[e];
81 99
    }
82 100
  }
83 101
  return sum;
84 102
}
85 103

	
86 104

	
87 105
int main() {
88 106
  Graph graph;
89 107
  IntEdgeMap capacity(graph);
90 108

	
91 109
  std::istringstream input(test_lgf);
92 110
  GraphReader<Graph>(graph, input).
93 111
    edgeMap("capacity", capacity).run();
94 112

	
95 113
  GomoryHu<Graph> ght(graph, capacity);
96 114
  ght.run();
97 115

	
98 116
  for (NodeIt u(graph); u != INVALID; ++u) {
99 117
    for (NodeIt v(graph); v != u; ++v) {
100 118
      Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
101 119
      pf.runMinCut();
102 120
      BoolNodeMap cm(graph);
103 121
      ght.minCutMap(u, v, cm);
104 122
      check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
105 123
      check(cm[u] != cm[v], "Wrong cut 2");
106 124
      check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 3");
107 125

	
108 126
      int sum=0;
109 127
      for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
110
        sum+=capacity[a]; 
128
        sum+=capacity[a];
111 129
      check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
112 130

	
113 131
      sum=0;
114 132
      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n)
115 133
        sum++;
116 134
      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n)
117 135
        sum++;
118 136
      check(sum == countNodes(graph), "Problem with MinCutNodeIt");
119 137
    }
120 138
  }
121
  
139

	
122 140
  return 0;
123 141
}
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-2009
5
 * Copyright (C) 2003-2010
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 22
#include <lemon/full_graph.h>
23 23
#include <lemon/grid_graph.h>
24 24
#include <lemon/hypercube_graph.h>
25 25

	
26 26
#include "test_tools.h"
27 27
#include "graph_test.h"
28 28

	
29 29
using namespace lemon;
30 30
using namespace lemon::concepts;
31 31

	
32 32
template <class Graph>
33 33
void checkGraphBuild() {
34 34
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
35 35

	
36 36
  Graph G;
37 37
  checkGraphNodeList(G, 0);
38 38
  checkGraphEdgeList(G, 0);
39 39
  checkGraphArcList(G, 0);
40 40

	
41
  G.reserveNode(3);
42
  G.reserveEdge(3);
43

	
41 44
  Node
42 45
    n1 = G.addNode(),
43 46
    n2 = G.addNode(),
44 47
    n3 = G.addNode();
45 48
  checkGraphNodeList(G, 3);
46 49
  checkGraphEdgeList(G, 0);
47 50
  checkGraphArcList(G, 0);
48 51

	
49 52
  Edge e1 = G.addEdge(n1, n2);
50 53
  check((G.u(e1) == n1 && G.v(e1) == n2) || (G.u(e1) == n2 && G.v(e1) == n1),
51 54
        "Wrong edge");
52 55

	
53 56
  checkGraphNodeList(G, 3);
54 57
  checkGraphEdgeList(G, 1);
55 58
  checkGraphArcList(G, 2);
56 59

	
57 60
  checkGraphIncEdgeArcLists(G, n1, 1);
58 61
  checkGraphIncEdgeArcLists(G, n2, 1);
59 62
  checkGraphIncEdgeArcLists(G, n3, 0);
60 63

	
61 64
  checkGraphConEdgeList(G, 1);
62 65
  checkGraphConArcList(G, 2);
63 66

	
64 67
  Edge e2 = G.addEdge(n2, n1),
65 68
       e3 = G.addEdge(n2, n3);
66 69

	
67 70
  checkGraphNodeList(G, 3);
68 71
  checkGraphEdgeList(G, 3);
69 72
  checkGraphArcList(G, 6);
70 73

	
71 74
  checkGraphIncEdgeArcLists(G, n1, 2);
72 75
  checkGraphIncEdgeArcLists(G, n2, 3);
73 76
  checkGraphIncEdgeArcLists(G, n3, 1);
74 77

	
75 78
  checkGraphConEdgeList(G, 3);
76 79
  checkGraphConArcList(G, 6);
77 80

	
78 81
  checkArcDirections(G);
79 82

	
80 83
  checkNodeIds(G);
81 84
  checkArcIds(G);
82 85
  checkEdgeIds(G);
83 86
  checkGraphNodeMap(G);
84 87
  checkGraphArcMap(G);
85 88
  checkGraphEdgeMap(G);
86 89
}
87 90

	
88 91
template <class Graph>
89 92
void checkGraphAlter() {
90 93
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
91 94

	
92 95
  Graph G;
93 96
  Node n1 = G.addNode(), n2 = G.addNode(),
94 97
       n3 = G.addNode(), n4 = G.addNode();
95 98
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
96 99
       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
97 100
       e5 = G.addEdge(n4, n3);
98 101

	
99 102
  checkGraphNodeList(G, 4);
100 103
  checkGraphEdgeList(G, 5);
101 104
  checkGraphArcList(G, 10);
102 105

	
103 106
  // Check changeU() and changeV()
104 107
  if (G.u(e2) == n2) {
105 108
    G.changeU(e2, n3);
106 109
  } else {
107 110
    G.changeV(e2, n3);
108 111
  }
109 112

	
110 113
  checkGraphNodeList(G, 4);
111 114
  checkGraphEdgeList(G, 5);
112 115
  checkGraphArcList(G, 10);
113 116

	
114 117
  checkGraphIncEdgeArcLists(G, n1, 3);
115 118
  checkGraphIncEdgeArcLists(G, n2, 2);
116 119
  checkGraphIncEdgeArcLists(G, n3, 3);
117 120
  checkGraphIncEdgeArcLists(G, n4, 2);
118 121

	
119 122
  checkGraphConEdgeList(G, 5);
120 123
  checkGraphConArcList(G, 10);
121 124

	
122 125
  if (G.u(e2) == n1) {
123 126
    G.changeU(e2, n2);
124 127
  } else {
125 128
    G.changeV(e2, n2);
126 129
  }
127 130

	
128 131
  checkGraphNodeList(G, 4);
129 132
  checkGraphEdgeList(G, 5);
130 133
  checkGraphArcList(G, 10);
131 134

	
132 135
  checkGraphIncEdgeArcLists(G, n1, 2);
133 136
  checkGraphIncEdgeArcLists(G, n2, 3);
134 137
  checkGraphIncEdgeArcLists(G, n3, 3);
135 138
  checkGraphIncEdgeArcLists(G, n4, 2);
136 139

	
137 140
  checkGraphConEdgeList(G, 5);
138 141
  checkGraphConArcList(G, 10);
139 142

	
140 143
  // Check contract()
141 144
  G.contract(n1, n4, false);
142 145

	
143 146
  checkGraphNodeList(G, 3);
144 147
  checkGraphEdgeList(G, 5);
145 148
  checkGraphArcList(G, 10);
146 149

	
147 150
  checkGraphIncEdgeArcLists(G, n1, 4);
148 151
  checkGraphIncEdgeArcLists(G, n2, 3);
149 152
  checkGraphIncEdgeArcLists(G, n3, 3);
150 153

	
151 154
  checkGraphConEdgeList(G, 5);
152 155
  checkGraphConArcList(G, 10);
153 156

	
154 157
  G.contract(n2, n3);
155 158

	
156 159
  checkGraphNodeList(G, 2);
157 160
  checkGraphEdgeList(G, 3);
158 161
  checkGraphArcList(G, 6);
159 162

	
160 163
  checkGraphIncEdgeArcLists(G, n1, 4);
161 164
  checkGraphIncEdgeArcLists(G, n2, 2);
162 165

	
163 166
  checkGraphConEdgeList(G, 3);
164 167
  checkGraphConArcList(G, 6);
165 168
}
166 169

	
167 170
template <class Graph>
168 171
void checkGraphErase() {
169 172
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
170 173

	
171 174
  Graph G;
172 175
  Node n1 = G.addNode(), n2 = G.addNode(),
173 176
       n3 = G.addNode(), n4 = G.addNode();
174 177
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
175 178
       e3 = G.addEdge(n2, n3), e4 = G.addEdge(n1, n4),
176 179
       e5 = G.addEdge(n4, n3);
177 180

	
178 181
  // Check edge deletion
179 182
  G.erase(e2);
180 183

	
181 184
  checkGraphNodeList(G, 4);
182 185
  checkGraphEdgeList(G, 4);
183 186
  checkGraphArcList(G, 8);
184 187

	
185 188
  checkGraphIncEdgeArcLists(G, n1, 2);
186 189
  checkGraphIncEdgeArcLists(G, n2, 2);
187 190
  checkGraphIncEdgeArcLists(G, n3, 2);
188 191
  checkGraphIncEdgeArcLists(G, n4, 2);
189 192

	
190 193
  checkGraphConEdgeList(G, 4);
191 194
  checkGraphConArcList(G, 8);
192 195

	
193 196
  // Check node deletion
194 197
  G.erase(n3);
195 198

	
196 199
  checkGraphNodeList(G, 3);
197 200
  checkGraphEdgeList(G, 2);
198 201
  checkGraphArcList(G, 4);
199 202

	
200 203
  checkGraphIncEdgeArcLists(G, n1, 2);
201 204
  checkGraphIncEdgeArcLists(G, n2, 1);
202 205
  checkGraphIncEdgeArcLists(G, n4, 1);
203 206

	
204 207
  checkGraphConEdgeList(G, 2);
205 208
  checkGraphConArcList(G, 4);
206 209
}
207 210

	
208 211

	
209 212
template <class Graph>
210 213
void checkGraphSnapshot() {
211 214
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
212 215

	
213 216
  Graph G;
214 217
  Node n1 = G.addNode(), n2 = G.addNode(), n3 = G.addNode();
215 218
  Edge e1 = G.addEdge(n1, n2), e2 = G.addEdge(n2, n1),
216 219
       e3 = G.addEdge(n2, n3);
217 220

	
218 221
  checkGraphNodeList(G, 3);
219 222
  checkGraphEdgeList(G, 3);
220 223
  checkGraphArcList(G, 6);
221 224

	
222 225
  typename Graph::Snapshot snapshot(G);
223 226

	
224 227
  Node n = G.addNode();
225 228
  G.addEdge(n3, n);
226 229
  G.addEdge(n, n3);
227 230
  G.addEdge(n3, n2);
228 231

	
229 232
  checkGraphNodeList(G, 4);
230 233
  checkGraphEdgeList(G, 6);
231 234
  checkGraphArcList(G, 12);
232 235

	
233 236
  snapshot.restore();
234 237

	
235 238
  checkGraphNodeList(G, 3);
236 239
  checkGraphEdgeList(G, 3);
237 240
  checkGraphArcList(G, 6);
238 241

	
239 242
  checkGraphIncEdgeArcLists(G, n1, 2);
240 243
  checkGraphIncEdgeArcLists(G, n2, 3);
241 244
  checkGraphIncEdgeArcLists(G, n3, 1);
242 245

	
243 246
  checkGraphConEdgeList(G, 3);
244 247
  checkGraphConArcList(G, 6);
245 248

	
246 249
  checkNodeIds(G);
247 250
  checkEdgeIds(G);
248 251
  checkArcIds(G);
249 252
  checkGraphNodeMap(G);
250 253
  checkGraphEdgeMap(G);
251 254
  checkGraphArcMap(G);
252 255

	
253 256
  G.addNode();
254 257
  snapshot.save(G);
255 258

	
256 259
  G.addEdge(G.addNode(), G.addNode());
257 260

	
258 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();
259 271

	
260 272
  checkGraphNodeList(G, 4);
261 273
  checkGraphEdgeList(G, 3);
262 274
  checkGraphArcList(G, 6);
263 275
}
264 276

	
265 277
void checkFullGraph(int num) {
266 278
  typedef FullGraph Graph;
267 279
  GRAPH_TYPEDEFS(Graph);
268 280

	
269 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

	
270 289
  checkGraphNodeList(G, num);
271 290
  checkGraphEdgeList(G, num * (num - 1) / 2);
272 291

	
273 292
  for (NodeIt n(G); n != INVALID; ++n) {
274 293
    checkGraphOutArcList(G, n, num - 1);
275 294
    checkGraphInArcList(G, n, num - 1);
276 295
    checkGraphIncEdgeList(G, n, num - 1);
277 296
  }
278 297

	
279 298
  checkGraphConArcList(G, num * (num - 1));
280 299
  checkGraphConEdgeList(G, num * (num - 1) / 2);
281 300

	
282 301
  checkArcDirections(G);
283 302

	
284 303
  checkNodeIds(G);
285 304
  checkArcIds(G);
286 305
  checkEdgeIds(G);
287 306
  checkGraphNodeMap(G);
288 307
  checkGraphArcMap(G);
289 308
  checkGraphEdgeMap(G);
290 309

	
291 310

	
292 311
  for (int i = 0; i < G.nodeNum(); ++i) {
293 312
    check(G.index(G(i)) == i, "Wrong index");
294 313
  }
295 314

	
296 315
  for (NodeIt u(G); u != INVALID; ++u) {
297 316
    for (NodeIt v(G); v != INVALID; ++v) {
298 317
      Edge e = G.edge(u, v);
299 318
      Arc a = G.arc(u, v);
300 319
      if (u == v) {
301 320
        check(e == INVALID, "Wrong edge lookup");
302 321
        check(a == INVALID, "Wrong arc lookup");
303 322
      } else {
304 323
        check((G.u(e) == u && G.v(e) == v) ||
305 324
              (G.u(e) == v && G.v(e) == u), "Wrong edge lookup");
306 325
        check(G.source(a) == u && G.target(a) == v, "Wrong arc lookup");
307 326
      }
308 327
    }
309 328
  }
310 329
}
311 330

	
312 331
void checkConcepts() {
313 332
  { // Checking graph components
314 333
    checkConcept<BaseGraphComponent, BaseGraphComponent >();
315 334

	
316 335
    checkConcept<IDableGraphComponent<>,
317 336
      IDableGraphComponent<> >();
318 337

	
319 338
    checkConcept<IterableGraphComponent<>,
320 339
      IterableGraphComponent<> >();
321 340

	
322 341
    checkConcept<MappableGraphComponent<>,
323 342
      MappableGraphComponent<> >();
324 343
  }
325 344
  { // Checking skeleton graph
326 345
    checkConcept<Graph, Graph>();
327 346
  }
328 347
  { // Checking ListGraph
329 348
    checkConcept<Graph, ListGraph>();
330 349
    checkConcept<AlterableGraphComponent<>, ListGraph>();
331 350
    checkConcept<ExtendableGraphComponent<>, ListGraph>();
332 351
    checkConcept<ClearableGraphComponent<>, ListGraph>();
333 352
    checkConcept<ErasableGraphComponent<>, ListGraph>();
334 353
  }
335 354
  { // Checking SmartGraph
336 355
    checkConcept<Graph, SmartGraph>();
337 356
    checkConcept<AlterableGraphComponent<>, SmartGraph>();
338 357
    checkConcept<ExtendableGraphComponent<>, SmartGraph>();
339 358
    checkConcept<ClearableGraphComponent<>, SmartGraph>();
340 359
  }
341 360
  { // Checking FullGraph
342 361
    checkConcept<Graph, FullGraph>();
343 362
  }
344 363
  { // Checking GridGraph
345 364
    checkConcept<Graph, GridGraph>();
346 365
  }
347 366
  { // Checking HypercubeGraph
348 367
    checkConcept<Graph, HypercubeGraph>();
349 368
  }
350 369
}
351 370

	
352 371
template <typename Graph>
353 372
void checkGraphValidity() {
354 373
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
355 374
  Graph g;
356 375

	
357 376
  Node
358 377
    n1 = g.addNode(),
359 378
    n2 = g.addNode(),
360 379
    n3 = g.addNode();
361 380

	
362 381
  Edge
363 382
    e1 = g.addEdge(n1, n2),
364 383
    e2 = g.addEdge(n2, n3);
365 384

	
366 385
  check(g.valid(n1), "Wrong validity check");
367 386
  check(g.valid(e1), "Wrong validity check");
368 387
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
369 388

	
370 389
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
371 390
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
372 391
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
373 392
}
374 393

	
375 394
template <typename Graph>
376 395
void checkGraphValidityErase() {
377 396
  TEMPLATE_GRAPH_TYPEDEFS(Graph);
378 397
  Graph g;
379 398

	
380 399
  Node
381 400
    n1 = g.addNode(),
382 401
    n2 = g.addNode(),
383 402
    n3 = g.addNode();
384 403

	
385 404
  Edge
386 405
    e1 = g.addEdge(n1, n2),
387 406
    e2 = g.addEdge(n2, n3);
388 407

	
389 408
  check(g.valid(n1), "Wrong validity check");
390 409
  check(g.valid(e1), "Wrong validity check");
391 410
  check(g.valid(g.direct(e1, true)), "Wrong validity check");
392 411

	
393 412
  g.erase(n1);
394 413

	
395 414
  check(!g.valid(n1), "Wrong validity check");
396 415
  check(g.valid(n2), "Wrong validity check");
397 416
  check(g.valid(n3), "Wrong validity check");
398 417
  check(!g.valid(e1), "Wrong validity check");
399 418
  check(g.valid(e2), "Wrong validity check");
400 419

	
401 420
  check(!g.valid(g.nodeFromId(-1)), "Wrong validity check");
402 421
  check(!g.valid(g.edgeFromId(-1)), "Wrong validity check");
403 422
  check(!g.valid(g.arcFromId(-1)), "Wrong validity check");
404 423
}
405 424

	
406 425
void checkGridGraph(int width, int height) {
407 426
  typedef GridGraph Graph;
408 427
  GRAPH_TYPEDEFS(Graph);
409 428
  Graph G(width, height);
410 429

	
411 430
  check(G.width() == width, "Wrong column number");
412 431
  check(G.height() == height, "Wrong row number");
413 432

	
433
  G.resize(width, height);
434
  check(G.width() == width, "Wrong column number");
435
  check(G.height() == height, "Wrong row number");
436

	
414 437
  for (int i = 0; i < width; ++i) {
415 438
    for (int j = 0; j < height; ++j) {
416 439
      check(G.col(G(i, j)) == i, "Wrong column");
417 440
      check(G.row(G(i, j)) == j, "Wrong row");
418 441
      check(G.pos(G(i, j)).x == i, "Wrong column");
419 442
      check(G.pos(G(i, j)).y == j, "Wrong row");
420 443
    }
421 444
  }
422 445

	
423 446
  for (int j = 0; j < height; ++j) {
424 447
    for (int i = 0; i < width - 1; ++i) {
425 448
      check(G.source(G.right(G(i, j))) == G(i, j), "Wrong right");
426 449
      check(G.target(G.right(G(i, j))) == G(i + 1, j), "Wrong right");
427 450
    }
428 451
    check(G.right(G(width - 1, j)) == INVALID, "Wrong right");
429 452
  }
430 453

	
431 454
  for (int j = 0; j < height; ++j) {
432 455
    for (int i = 1; i < width; ++i) {
433 456
      check(G.source(G.left(G(i, j))) == G(i, j), "Wrong left");
434 457
      check(G.target(G.left(G(i, j))) == G(i - 1, j), "Wrong left");
435 458
    }
436 459
    check(G.left(G(0, j)) == INVALID, "Wrong left");
437 460
  }
438 461

	
439 462
  for (int i = 0; i < width; ++i) {
440 463
    for (int j = 0; j < height - 1; ++j) {
441 464
      check(G.source(G.up(G(i, j))) == G(i, j), "Wrong up");
442 465
      check(G.target(G.up(G(i, j))) == G(i, j + 1), "Wrong up");
443 466
    }
444 467
    check(G.up(G(i, height - 1)) == INVALID, "Wrong up");
445 468
  }
446 469

	
447 470
  for (int i = 0; i < width; ++i) {
448 471
    for (int j = 1; j < height; ++j) {
449 472
      check(G.source(G.down(G(i, j))) == G(i, j), "Wrong down");
450 473
      check(G.target(G.down(G(i, j))) == G(i, j - 1), "Wrong down");
451 474
    }
452 475
    check(G.down(G(i, 0)) == INVALID, "Wrong down");
453 476
  }
454 477

	
455 478
  checkGraphNodeList(G, width * height);
456 479
  checkGraphEdgeList(G, width * (height - 1) + (width - 1) * height);
457 480
  checkGraphArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
458 481

	
459 482
  for (NodeIt n(G); n != INVALID; ++n) {
460 483
    int nb = 4;
461 484
    if (G.col(n) == 0) --nb;
462 485
    if (G.col(n) == width - 1) --nb;
463 486
    if (G.row(n) == 0) --nb;
464 487
    if (G.row(n) == height - 1) --nb;
465 488

	
466 489
    checkGraphOutArcList(G, n, nb);
467 490
    checkGraphInArcList(G, n, nb);
468 491
    checkGraphIncEdgeList(G, n, nb);
469 492
  }
470 493

	
471 494
  checkArcDirections(G);
472 495

	
473 496
  checkGraphConArcList(G, 2 * (width * (height - 1) + (width - 1) * height));
474 497
  checkGraphConEdgeList(G, width * (height - 1) + (width - 1) * height);
475 498

	
476 499
  checkNodeIds(G);
477 500
  checkArcIds(G);
478 501
  checkEdgeIds(G);
479 502
  checkGraphNodeMap(G);
480 503
  checkGraphArcMap(G);
481 504
  checkGraphEdgeMap(G);
482 505

	
483 506
}
484 507

	
485 508
void checkHypercubeGraph(int dim) {
486 509
  GRAPH_TYPEDEFS(HypercubeGraph);
487 510

	
488 511
  HypercubeGraph G(dim);
512
  check(G.dimension() == dim, "Wrong dimension");
513

	
514
  G.resize(dim);
515
  check(G.dimension() == dim, "Wrong dimension");
516

	
489 517
  checkGraphNodeList(G, 1 << dim);
490 518
  checkGraphEdgeList(G, dim * (1 << (dim-1)));
491 519
  checkGraphArcList(G, dim * (1 << dim));
492 520

	
493 521
  Node n = G.nodeFromId(dim);
494 522

	
495 523
  for (NodeIt n(G); n != INVALID; ++n) {
496 524
    checkGraphIncEdgeList(G, n, dim);
497 525
    for (IncEdgeIt e(G, n); e != INVALID; ++e) {
498 526
      check( (G.u(e) == n &&
499 527
              G.id(G.v(e)) == (G.id(n) ^ (1 << G.dimension(e)))) ||
500 528
             (G.v(e) == n &&
501 529
              G.id(G.u(e)) == (G.id(n) ^ (1 << G.dimension(e)))),
502 530
             "Wrong edge or wrong dimension");
503 531
    }
504 532

	
505 533
    checkGraphOutArcList(G, n, dim);
506 534
    for (OutArcIt a(G, n); a != INVALID; ++a) {
507 535
      check(G.source(a) == n &&
508 536
            G.id(G.target(a)) == (G.id(n) ^ (1 << G.dimension(a))),
509 537
            "Wrong arc or wrong dimension");
510 538
    }
511 539

	
512 540
    checkGraphInArcList(G, n, dim);
513 541
    for (InArcIt a(G, n); a != INVALID; ++a) {
514 542
      check(G.target(a) == n &&
515 543
            G.id(G.source(a)) == (G.id(n) ^ (1 << G.dimension(a))),
516 544
            "Wrong arc or wrong dimension");
517 545
    }
518 546
  }
519 547

	
520 548
  checkGraphConArcList(G, (1 << dim) * dim);
521 549
  checkGraphConEdgeList(G, dim * (1 << (dim-1)));
522 550

	
523 551
  checkArcDirections(G);
524 552

	
525 553
  checkNodeIds(G);
526 554
  checkArcIds(G);
527 555
  checkEdgeIds(G);
528 556
  checkGraphNodeMap(G);
529 557
  checkGraphArcMap(G);
530 558
  checkGraphEdgeMap(G);
531 559
}
532 560

	
533 561
void checkGraphs() {
534 562
  { // Checking ListGraph
535 563
    checkGraphBuild<ListGraph>();
536 564
    checkGraphAlter<ListGraph>();
537 565
    checkGraphErase<ListGraph>();
538 566
    checkGraphSnapshot<ListGraph>();
539 567
    checkGraphValidityErase<ListGraph>();
540 568
  }
541 569
  { // Checking SmartGraph
542 570
    checkGraphBuild<SmartGraph>();
543 571
    checkGraphSnapshot<SmartGraph>();
544 572
    checkGraphValidity<SmartGraph>();
545 573
  }
546 574
  { // Checking FullGraph
547 575
    checkFullGraph(7);
548 576
    checkFullGraph(8);
549 577
  }
550 578
  { // Checking GridGraph
551 579
    checkGridGraph(5, 8);
552 580
    checkGridGraph(8, 5);
553 581
    checkGridGraph(5, 5);
554 582
    checkGridGraph(0, 0);
555 583
    checkGridGraph(1, 1);
556 584
  }
557 585
  { // Checking HypercubeGraph
558 586
    checkHypercubeGraph(1);
559 587
    checkHypercubeGraph(2);
560 588
    checkHypercubeGraph(3);
561 589
    checkHypercubeGraph(4);
562 590
  }
563 591
}
564 592

	
565 593
int main() {
566 594
  checkConcepts();
567 595
  checkGraphs();
568 596
  return 0;
569 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-2009
5
 * Copyright (C) 2003-2010
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 <sstream>
20 20

	
21 21
#include <lemon/smart_graph.h>
22 22
#include <lemon/adaptors.h>
23 23
#include <lemon/concepts/digraph.h>
24 24
#include <lemon/concepts/maps.h>
25 25
#include <lemon/lgf_reader.h>
26 26
#include <lemon/hao_orlin.h>
27 27

	
28 28
#include "test_tools.h"
29 29

	
30 30
using namespace lemon;
31 31
using namespace std;
32 32

	
33 33
const std::string lgf =
34 34
  "@nodes\n"
35 35
  "label\n"
36 36
  "0\n"
37 37
  "1\n"
38 38
  "2\n"
39 39
  "3\n"
40 40
  "4\n"
41 41
  "5\n"
42 42
  "@edges\n"
43 43
  "     cap1 cap2 cap3\n"
44 44
  "0 1  1    1    1   \n"
45 45
  "0 2  2    2    4   \n"
46 46
  "1 2  4    4    4   \n"
47 47
  "3 4  1    1    1   \n"
48 48
  "3 5  2    2    4   \n"
49 49
  "4 5  4    4    4   \n"
50 50
  "5 4  4    4    4   \n"
51 51
  "2 3  1    6    6   \n"
52 52
  "4 0  1    6    6   \n";
53 53

	
54 54
void checkHaoOrlinCompile()
55 55
{
56 56
  typedef int Value;
57 57
  typedef concepts::Digraph Digraph;
58 58

	
59 59
  typedef Digraph::Node Node;
60 60
  typedef Digraph::Arc Arc;
61 61
  typedef concepts::ReadMap<Arc, Value> CapMap;
62 62
  typedef concepts::WriteMap<Node, bool> CutMap;
63 63

	
64 64
  Digraph g;
65 65
  Node n;
66 66
  CapMap cap;
67 67
  CutMap cut;
68 68
  Value v;
69 69

	
70 70
  HaoOrlin<Digraph, CapMap> ho_test(g, cap);
71 71
  const HaoOrlin<Digraph, CapMap>&
72 72
    const_ho_test = ho_test;
73 73

	
74 74
  ho_test.init();
75 75
  ho_test.init(n);
76 76
  ho_test.calculateOut();
77 77
  ho_test.calculateIn();
78 78
  ho_test.run();
79 79
  ho_test.run(n);
80 80

	
81 81
  v = const_ho_test.minCutValue();
82 82
  v = const_ho_test.minCutMap(cut);
83 83
}
84 84

	
85 85
template <typename Graph, typename CapMap, typename CutMap>
86
typename CapMap::Value 
86
typename CapMap::Value
87 87
  cutValue(const Graph& graph, const CapMap& cap, const CutMap& cut)
88 88
{
89 89
  typename CapMap::Value sum = 0;
90 90
  for (typename Graph::ArcIt a(graph); a != INVALID; ++a) {
91 91
    if (cut[graph.source(a)] && !cut[graph.target(a)])
92 92
      sum += cap[a];
93 93
  }
94 94
  return sum;
95 95
}
96 96

	
97 97
int main() {
98 98
  SmartDigraph graph;
99 99
  SmartDigraph::ArcMap<int> cap1(graph), cap2(graph), cap3(graph);
100 100
  SmartDigraph::NodeMap<bool> cut(graph);
101 101

	
102 102
  istringstream input(lgf);
103 103
  digraphReader(graph, input)
104 104
    .arcMap("cap1", cap1)
105 105
    .arcMap("cap2", cap2)
106 106
    .arcMap("cap3", cap3)
107 107
    .run();
108 108

	
109 109
  {
110 110
    HaoOrlin<SmartDigraph> ho(graph, cap1);
111 111
    ho.run();
112 112
    ho.minCutMap(cut);
113
    
113

	
114 114
    check(ho.minCutValue() == 1, "Wrong cut value");
115 115
    check(ho.minCutValue() == cutValue(graph, cap1, cut), "Wrong cut value");
116 116
  }
117 117
  {
118 118
    HaoOrlin<SmartDigraph> ho(graph, cap2);
119 119
    ho.run();
120 120
    ho.minCutMap(cut);
121 121

	
122 122
    check(ho.minCutValue() == 1, "Wrong cut value");
123 123
    check(ho.minCutValue() == cutValue(graph, cap2, cut), "Wrong cut value");
124 124
  }
125 125
  {
126 126
    HaoOrlin<SmartDigraph> ho(graph, cap3);
127 127
    ho.run();
128 128
    ho.minCutMap(cut);
129
    
129

	
130 130
    check(ho.minCutValue() == 1, "Wrong cut value");
131 131
    check(ho.minCutValue() == cutValue(graph, cap3, cut), "Wrong cut value");
132 132
  }
133
  
133

	
134 134
  typedef Undirector<SmartDigraph> UGraph;
135 135
  UGraph ugraph(graph);
136
  
136

	
137 137
  {
138 138
    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap1);
139 139
    ho.run();
140 140
    ho.minCutMap(cut);
141
    
141

	
142 142
    check(ho.minCutValue() == 2, "Wrong cut value");
143 143
    check(ho.minCutValue() == cutValue(ugraph, cap1, cut), "Wrong cut value");
144 144
  }
145 145
  {
146 146
    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap2);
147 147
    ho.run();
148 148
    ho.minCutMap(cut);
149
    
149

	
150 150
    check(ho.minCutValue() == 5, "Wrong cut value");
151 151
    check(ho.minCutValue() == cutValue(ugraph, cap2, cut), "Wrong cut value");
152 152
  }
153 153
  {
154 154
    HaoOrlin<UGraph, SmartDigraph::ArcMap<int> > ho(ugraph, cap3);
155 155
    ho.run();
156 156
    ho.minCutMap(cut);
157
    
157

	
158 158
    check(ho.minCutValue() == 5, "Wrong cut value");
159 159
    check(ho.minCutValue() == cutValue(ugraph, cap3, cut), "Wrong cut value");
160 160
  }
161 161

	
162 162
  return 0;
163 163
}
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 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/quad_heap.h>
34
#include <lemon/dheap.h>
34 35
#include <lemon/fib_heap.h>
36
#include <lemon/pairing_heap.h>
35 37
#include <lemon/radix_heap.h>
38
#include <lemon/binomial_heap.h>
36 39
#include <lemon/bucket_heap.h>
37 40

	
38 41
#include "test_tools.h"
39 42

	
40 43
using namespace lemon;
41 44
using namespace lemon::concepts;
42 45

	
43 46
typedef ListDigraph Digraph;
44 47
DIGRAPH_TYPEDEFS(Digraph);
45 48

	
46 49
char test_lgf[] =
47 50
  "@nodes\n"
48 51
  "label\n"
49 52
  "0\n"
50 53
  "1\n"
51 54
  "2\n"
52 55
  "3\n"
53 56
  "4\n"
54 57
  "5\n"
55 58
  "6\n"
56 59
  "7\n"
57 60
  "8\n"
58 61
  "9\n"
59 62
  "@arcs\n"
60 63
  "                label   capacity\n"
61 64
  "0       5       0       94\n"
62 65
  "3       9       1       11\n"
63 66
  "8       7       2       83\n"
64 67
  "1       2       3       94\n"
65 68
  "5       7       4       35\n"
66 69
  "7       4       5       84\n"
67 70
  "9       5       6       38\n"
68 71
  "0       4       7       96\n"
69 72
  "6       7       8       6\n"
70 73
  "3       1       9       27\n"
71 74
  "5       2       10      77\n"
72 75
  "5       6       11      69\n"
73 76
  "6       5       12      41\n"
74 77
  "4       6       13      70\n"
75 78
  "3       2       14      45\n"
76 79
  "7       9       15      93\n"
77 80
  "5       9       16      50\n"
78 81
  "9       0       17      94\n"
79 82
  "9       6       18      67\n"
80 83
  "0       9       19      86\n"
81 84
  "@attributes\n"
82 85
  "source 3\n";
83 86

	
84 87
int test_seq[] = { 2, 28, 19, 27, 33, 25, 13, 41, 10, 26,  1,  9,  4, 34};
85 88
int test_inc[] = {20, 28, 34, 16,  0, 46, 44,  0, 42, 32, 14,  8,  6, 37};
86 89

	
87 90
int test_len = sizeof(test_seq) / sizeof(test_seq[0]);
88 91

	
89 92
template <typename Heap>
90 93
void heapSortTest() {
91 94
  RangeMap<int> map(test_len, -1);
92

	
93 95
  Heap heap(map);
94 96

	
95 97
  std::vector<int> v(test_len);
96

	
97 98
  for (int i = 0; i < test_len; ++i) {
98 99
    v[i] = test_seq[i];
99 100
    heap.push(i, v[i]);
100 101
  }
101 102
  std::sort(v.begin(), v.end());
102 103
  for (int i = 0; i < test_len; ++i) {
103
    check(v[i] == heap.prio() ,"Wrong order in heap sort.");
104
    check(v[i] == heap.prio(), "Wrong order in heap sort.");
104 105
    heap.pop();
105 106
  }
106 107
}
107 108

	
108 109
template <typename Heap>
109 110
void heapIncreaseTest() {
110 111
  RangeMap<int> map(test_len, -1);
111 112

	
112 113
  Heap heap(map);
113 114

	
114 115
  std::vector<int> v(test_len);
115

	
116 116
  for (int i = 0; i < test_len; ++i) {
117 117
    v[i] = test_seq[i];
118 118
    heap.push(i, v[i]);
119 119
  }
120 120
  for (int i = 0; i < test_len; ++i) {
121 121
    v[i] += test_inc[i];
122 122
    heap.increase(i, v[i]);
123 123
  }
124 124
  std::sort(v.begin(), v.end());
125 125
  for (int i = 0; i < test_len; ++i) {
126
    check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
126
    check(v[i] == heap.prio(), "Wrong order in heap increase test.");
127 127
    heap.pop();
128 128
  }
129 129
}
130 130

	
131

	
132

	
133 131
template <typename Heap>
134 132
void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
135 133
                      Node source) {
136 134

	
137 135
  typename Dijkstra<Digraph, IntArcMap>::template SetStandardHeap<Heap>::
138 136
    Create dijkstra(digraph, length);
139 137

	
140 138
  dijkstra.run(source);
141 139

	
142 140
  for(ArcIt a(digraph); a != INVALID; ++a) {
143 141
    Node s = digraph.source(a);
144 142
    Node t = digraph.target(a);
145 143
    if (dijkstra.reached(s)) {
146 144
      check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
147
             "Error in a shortest path tree!");
145
             "Error in shortest path tree.");
148 146
    }
149 147
  }
150 148

	
151 149
  for(NodeIt n(digraph); n != INVALID; ++n) {
152 150
    if ( dijkstra.reached(n) && dijkstra.predArc(n) != INVALID ) {
153 151
      Arc a = dijkstra.predArc(n);
154 152
      Node s = digraph.source(a);
155 153
      check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
156
             "Error in a shortest path tree!");
154
             "Error in shortest path tree.");
157 155
    }
158 156
  }
159 157

	
160 158
}
161 159

	
162 160
int main() {
163 161

	
164 162
  typedef int Item;
165 163
  typedef int Prio;
166 164
  typedef RangeMap<int> ItemIntMap;
167 165

	
168 166
  Digraph digraph;
169 167
  IntArcMap length(digraph);
170 168
  Node source;
171 169

	
172 170
  std::istringstream input(test_lgf);
173 171
  digraphReader(digraph, input).
174 172
    arcMap("capacity", length).
175 173
    node("source", source).
176 174
    run();
177 175

	
176
  // BinHeap
178 177
  {
179 178
    typedef BinHeap<Prio, ItemIntMap> IntHeap;
180 179
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
181 180
    heapSortTest<IntHeap>();
182 181
    heapIncreaseTest<IntHeap>();
183 182

	
184 183
    typedef BinHeap<Prio, IntNodeMap > NodeHeap;
185 184
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
186 185
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
187 186
  }
188 187

	
188
  // QuadHeap
189
  {
190
    typedef QuadHeap<Prio, ItemIntMap> IntHeap;
191
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
192
    heapSortTest<IntHeap>();
193
    heapIncreaseTest<IntHeap>();
194

	
195
    typedef QuadHeap<Prio, IntNodeMap > NodeHeap;
196
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
197
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
198
  }
199

	
200
  // DHeap
201
  {
202
    typedef DHeap<Prio, ItemIntMap> IntHeap;
203
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
204
    heapSortTest<IntHeap>();
205
    heapIncreaseTest<IntHeap>();
206

	
207
    typedef DHeap<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
  // BinomialHeap
249
  {
250
    typedef BinomialHeap<Prio, ItemIntMap> IntHeap;
251
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
252
    heapSortTest<IntHeap>();
253
    heapIncreaseTest<IntHeap>();
254

	
255
    typedef BinomialHeap<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

	
189 275
  {
190 276
    typedef FibHeap<Prio, ItemIntMap> IntHeap;
191 277
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
192 278
    heapSortTest<IntHeap>();
193 279
    heapIncreaseTest<IntHeap>();
194 280

	
195 281
    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
196 282
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
197 283
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
198 284
  }
199 285

	
200 286
  {
201 287
    typedef RadixHeap<ItemIntMap> IntHeap;
202 288
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
203 289
    heapSortTest<IntHeap>();
204 290
    heapIncreaseTest<IntHeap>();
205 291

	
206 292
    typedef RadixHeap<IntNodeMap > NodeHeap;
207 293
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
208 294
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
209 295
  }
210 296

	
211 297
  {
212 298
    typedef BucketHeap<ItemIntMap> IntHeap;
213 299
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
214 300
    heapSortTest<IntHeap>();
215 301
    heapIncreaseTest<IntHeap>();
216 302

	
217 303
    typedef BucketHeap<IntNodeMap > NodeHeap;
218 304
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
219 305
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
220 306
  }
221 307

	
222 308

	
223 309
  return 0;
224 310
}
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-2009
5
 * Copyright (C) 2003-2010
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <deque>
20 20
#include <set>
21 21

	
22 22
#include <lemon/concept_check.h>
23 23
#include <lemon/concepts/maps.h>
24 24
#include <lemon/maps.h>
25 25
#include <lemon/list_graph.h>
26
#include <lemon/smart_graph.h>
27
#include <lemon/adaptors.h>
28
#include <lemon/dfs.h>
29
#include <algorithm>
26 30

	
27 31
#include "test_tools.h"
28 32

	
29 33
using namespace lemon;
30 34
using namespace lemon::concepts;
31 35

	
32 36
struct A {};
33 37
inline bool operator<(A, A) { return true; }
34 38
struct B {};
35 39

	
36 40
class C {
37
  int x;
41
  int _x;
38 42
public:
39
  C(int _x) : x(_x) {}
43
  C(int x) : _x(x) {}
44
  int get() const { return _x; }
45
};
46
inline bool operator<(C c1, C c2) { return c1.get() < c2.get(); }
47
inline bool operator==(C c1, C c2) { return c1.get() == c2.get(); }
48

	
49
C createC(int x) { return C(x); }
50

	
51
template <typename T>
52
class Less {
53
  T _t;
54
public:
55
  Less(T t): _t(t) {}
56
  bool operator()(const T& t) const { return t < _t; }
40 57
};
41 58

	
42 59
class F {
43 60
public:
44 61
  typedef A argument_type;
45 62
  typedef B result_type;
46 63

	
47 64
  B operator()(const A&) const { return B(); }
48 65
private:
49 66
  F& operator=(const F&);
50 67
};
51 68

	
52 69
int func(A) { return 3; }
53 70

	
54 71
int binc(int a, B) { return a+1; }
55 72

	
73
template <typename T>
74
class Sum {
75
  T& _sum;
76
public:
77
  Sum(T& sum) : _sum(sum) {}
78
  void operator()(const T& t) { _sum += t; }
79
};
80

	
56 81
typedef ReadMap<A, double> DoubleMap;
57 82
typedef ReadWriteMap<A, double> DoubleWriteMap;
58 83
typedef ReferenceMap<A, double, double&, const double&> DoubleRefMap;
59 84

	
60 85
typedef ReadMap<A, bool> BoolMap;
61 86
typedef ReadWriteMap<A, bool> BoolWriteMap;
62 87
typedef ReferenceMap<A, bool, bool&, const bool&> BoolRefMap;
63 88

	
64 89
int main()
65 90
{
66 91
  // Map concepts
67 92
  checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
68 93
  checkConcept<ReadMap<A,C>, ReadMap<A,C> >();
69 94
  checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
70 95
  checkConcept<WriteMap<A,C>, WriteMap<A,C> >();
71 96
  checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
72 97
  checkConcept<ReadWriteMap<A,C>, ReadWriteMap<A,C> >();
73 98
  checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();
74 99
  checkConcept<ReferenceMap<A,C,C&,const C&>, ReferenceMap<A,C,C&,const C&> >();
75 100

	
76 101
  // NullMap
77 102
  {
78 103
    checkConcept<ReadWriteMap<A,B>, NullMap<A,B> >();
79 104
    NullMap<A,B> map1;
80 105
    NullMap<A,B> map2 = map1;
81 106
    map1 = nullMap<A,B>();
82 107
  }
83 108

	
84 109
  // ConstMap
85 110
  {
86 111
    checkConcept<ReadWriteMap<A,B>, ConstMap<A,B> >();
87 112
    checkConcept<ReadWriteMap<A,C>, ConstMap<A,C> >();
88 113
    ConstMap<A,B> map1;
89 114
    ConstMap<A,B> map2 = B();
90 115
    ConstMap<A,B> map3 = map1;
91 116
    map1 = constMap<A>(B());
92 117
    map1 = constMap<A,B>();
93 118
    map1.setAll(B());
94 119
    ConstMap<A,C> map4(C(1));
95 120
    ConstMap<A,C> map5 = map4;
96 121
    map4 = constMap<A>(C(2));
97 122
    map4.setAll(C(3));
98 123

	
99 124
    checkConcept<ReadWriteMap<A,int>, ConstMap<A,int> >();
100 125
    check(constMap<A>(10)[A()] == 10, "Something is wrong with ConstMap");
101 126

	
102 127
    checkConcept<ReadWriteMap<A,int>, ConstMap<A,Const<int,10> > >();
103 128
    ConstMap<A,Const<int,10> > map6;
104 129
    ConstMap<A,Const<int,10> > map7 = map6;
105 130
    map6 = constMap<A,int,10>();
106 131
    map7 = constMap<A,Const<int,10> >();
107 132
    check(map6[A()] == 10 && map7[A()] == 10,
108 133
          "Something is wrong with ConstMap");
109 134
  }
110 135

	
111 136
  // IdentityMap
112 137
  {
113 138
    checkConcept<ReadMap<A,A>, IdentityMap<A> >();
114 139
    IdentityMap<A> map1;
115 140
    IdentityMap<A> map2 = map1;
116 141
    map1 = identityMap<A>();
117 142

	
118 143
    checkConcept<ReadMap<double,double>, IdentityMap<double> >();
119 144
    check(identityMap<double>()[1.0] == 1.0 &&
120 145
          identityMap<double>()[3.14] == 3.14,
121 146
          "Something is wrong with IdentityMap");
122 147
  }
123 148

	
124 149
  // RangeMap
125 150
  {
126 151
    checkConcept<ReferenceMap<int,B,B&,const B&>, RangeMap<B> >();
127 152
    RangeMap<B> map1;
128 153
    RangeMap<B> map2(10);
129 154
    RangeMap<B> map3(10,B());
130 155
    RangeMap<B> map4 = map1;
131 156
    RangeMap<B> map5 = rangeMap<B>();
132 157
    RangeMap<B> map6 = rangeMap<B>(10);
133 158
    RangeMap<B> map7 = rangeMap(10,B());
134 159

	
135 160
    checkConcept< ReferenceMap<int, double, double&, const double&>,
136 161
                  RangeMap<double> >();
137 162
    std::vector<double> v(10, 0);
138 163
    v[5] = 100;
139 164
    RangeMap<double> map8(v);
140 165
    RangeMap<double> map9 = rangeMap(v);
141 166
    check(map9.size() == 10 && map9[2] == 0 && map9[5] == 100,
142 167
          "Something is wrong with RangeMap");
143 168
  }
144 169

	
145 170
  // SparseMap
146 171
  {
147 172
    checkConcept<ReferenceMap<A,B,B&,const B&>, SparseMap<A,B> >();
148 173
    SparseMap<A,B> map1;
149 174
    SparseMap<A,B> map2 = B();
150 175
    SparseMap<A,B> map3 = sparseMap<A,B>();
151 176
    SparseMap<A,B> map4 = sparseMap<A>(B());
152 177

	
153 178
    checkConcept< ReferenceMap<double, int, int&, const int&>,
154 179
                  SparseMap<double, int> >();
155 180
    std::map<double, int> m;
156 181
    SparseMap<double, int> map5(m);
157 182
    SparseMap<double, int> map6(m,10);
158 183
    SparseMap<double, int> map7 = sparseMap(m);
159 184
    SparseMap<double, int> map8 = sparseMap(m,10);
160 185

	
161 186
    check(map5[1.0] == 0 && map5[3.14] == 0 &&
162 187
          map6[1.0] == 10 && map6[3.14] == 10,
163 188
          "Something is wrong with SparseMap");
164 189
    map5[1.0] = map6[3.14] = 100;
165 190
    check(map5[1.0] == 100 && map5[3.14] == 0 &&
166 191
          map6[1.0] == 10 && map6[3.14] == 100,
167 192
          "Something is wrong with SparseMap");
168 193
  }
169 194

	
170 195
  // ComposeMap
171 196
  {
172 197
    typedef ComposeMap<DoubleMap, ReadMap<B,A> > CompMap;
173 198
    checkConcept<ReadMap<B,double>, CompMap>();
174 199
    CompMap map1 = CompMap(DoubleMap(),ReadMap<B,A>());
175 200
    CompMap map2 = composeMap(DoubleMap(), ReadMap<B,A>());
176 201

	
177 202
    SparseMap<double, bool> m1(false); m1[3.14] = true;
178 203
    RangeMap<double> m2(2); m2[0] = 3.0; m2[1] = 3.14;
179 204
    check(!composeMap(m1,m2)[0] && composeMap(m1,m2)[1],
180 205
          "Something is wrong with ComposeMap")
181 206
  }
182 207

	
183 208
  // CombineMap
184 209
  {
185 210
    typedef CombineMap<DoubleMap, DoubleMap, std::plus<double> > CombMap;
186 211
    checkConcept<ReadMap<A,double>, CombMap>();
187 212
    CombMap map1 = CombMap(DoubleMap(), DoubleMap());
188 213
    CombMap map2 = combineMap(DoubleMap(), DoubleMap(), std::plus<double>());
189 214

	
190 215
    check(combineMap(constMap<B,int,2>(), identityMap<B>(), &binc)[B()] == 3,
191 216
          "Something is wrong with CombineMap");
192 217
  }
193 218

	
194 219
  // FunctorToMap, MapToFunctor
195 220
  {
196 221
    checkConcept<ReadMap<A,B>, FunctorToMap<F,A,B> >();
197 222
    checkConcept<ReadMap<A,B>, FunctorToMap<F> >();
198 223
    FunctorToMap<F> map1;
199 224
    FunctorToMap<F> map2 = FunctorToMap<F>(F());
200 225
    B b = functorToMap(F())[A()];
201 226

	
202 227
    checkConcept<ReadMap<A,B>, MapToFunctor<ReadMap<A,B> > >();
203
    MapToFunctor<ReadMap<A,B> > map = MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
228
    MapToFunctor<ReadMap<A,B> > map =
229
      MapToFunctor<ReadMap<A,B> >(ReadMap<A,B>());
204 230

	
205 231
    check(functorToMap(&func)[A()] == 3,
206 232
          "Something is wrong with FunctorToMap");
207 233
    check(mapToFunctor(constMap<A,int>(2))(A()) == 2,
208 234
          "Something is wrong with MapToFunctor");
209 235
    check(mapToFunctor(functorToMap(&func))(A()) == 3 &&
210 236
          mapToFunctor(functorToMap(&func))[A()] == 3,
211 237
          "Something is wrong with FunctorToMap or MapToFunctor");
212 238
    check(functorToMap(mapToFunctor(constMap<A,int>(2)))[A()] == 2,
213 239
          "Something is wrong with FunctorToMap or MapToFunctor");
214 240
  }
215 241

	
216 242
  // ConvertMap
217 243
  {
218 244
    checkConcept<ReadMap<double,double>,
219 245
      ConvertMap<ReadMap<double, int>, double> >();
220 246
    ConvertMap<RangeMap<bool>, int> map1(rangeMap(1, true));
221 247
    ConvertMap<RangeMap<bool>, int> map2 = convertMap<int>(rangeMap(2, false));
222 248
  }
223 249

	
224 250
  // ForkMap
225 251
  {
226 252
    checkConcept<DoubleWriteMap, ForkMap<DoubleWriteMap, DoubleWriteMap> >();
227 253

	
228 254
    typedef RangeMap<double> RM;
229 255
    typedef SparseMap<int, double> SM;
230 256
    RM m1(10, -1);
231 257
    SM m2(-1);
232 258
    checkConcept<ReadWriteMap<int, double>, ForkMap<RM, SM> >();
233 259
    checkConcept<ReadWriteMap<int, double>, ForkMap<SM, RM> >();
234 260
    ForkMap<RM, SM> map1(m1,m2);
235 261
    ForkMap<SM, RM> map2 = forkMap(m2,m1);
236 262
    map2.set(5, 10);
237 263
    check(m1[1] == -1 && m1[5] == 10 && m2[1] == -1 &&
238 264
          m2[5] == 10 && map2[1] == -1 && map2[5] == 10,
239 265
          "Something is wrong with ForkMap");
240 266
  }
241 267

	
242 268
  // Arithmetic maps:
243 269
  // - AddMap, SubMap, MulMap, DivMap
244 270
  // - ShiftMap, ShiftWriteMap, ScaleMap, ScaleWriteMap
245 271
  // - NegMap, NegWriteMap, AbsMap
246 272
  {
247 273
    checkConcept<DoubleMap, AddMap<DoubleMap,DoubleMap> >();
248 274
    checkConcept<DoubleMap, SubMap<DoubleMap,DoubleMap> >();
249 275
    checkConcept<DoubleMap, MulMap<DoubleMap,DoubleMap> >();
250 276
    checkConcept<DoubleMap, DivMap<DoubleMap,DoubleMap> >();
251 277

	
252 278
    ConstMap<int, double> c1(1.0), c2(3.14);
253 279
    IdentityMap<int> im;
254 280
    ConvertMap<IdentityMap<int>, double> id(im);
255 281
    check(addMap(c1,id)[0] == 1.0  && addMap(c1,id)[10] == 11.0,
256 282
          "Something is wrong with AddMap");
257 283
    check(subMap(id,c1)[0] == -1.0 && subMap(id,c1)[10] == 9.0,
258 284
          "Something is wrong with SubMap");
259 285
    check(mulMap(id,c2)[0] == 0    && mulMap(id,c2)[2]  == 6.28,
260 286
          "Something is wrong with MulMap");
261 287
    check(divMap(c2,id)[1] == 3.14 && divMap(c2,id)[2]  == 1.57,
262 288
          "Something is wrong with DivMap");
263 289

	
264 290
    checkConcept<DoubleMap, ShiftMap<DoubleMap> >();
265 291
    checkConcept<DoubleWriteMap, ShiftWriteMap<DoubleWriteMap> >();
266 292
    checkConcept<DoubleMap, ScaleMap<DoubleMap> >();
267 293
    checkConcept<DoubleWriteMap, ScaleWriteMap<DoubleWriteMap> >();
268 294
    checkConcept<DoubleMap, NegMap<DoubleMap> >();
269 295
    checkConcept<DoubleWriteMap, NegWriteMap<DoubleWriteMap> >();
270 296
    checkConcept<DoubleMap, AbsMap<DoubleMap> >();
271 297

	
272 298
    check(shiftMap(id, 2.0)[1] == 3.0 && shiftMap(id, 2.0)[10] == 12.0,
273 299
          "Something is wrong with ShiftMap");
274 300
    check(shiftWriteMap(id, 2.0)[1] == 3.0 &&
275 301
          shiftWriteMap(id, 2.0)[10] == 12.0,
276 302
          "Something is wrong with ShiftWriteMap");
277 303
    check(scaleMap(id, 2.0)[1] == 2.0 && scaleMap(id, 2.0)[10] == 20.0,
278 304
          "Something is wrong with ScaleMap");
279 305
    check(scaleWriteMap(id, 2.0)[1] == 2.0 &&
280 306
          scaleWriteMap(id, 2.0)[10] == 20.0,
281 307
          "Something is wrong with ScaleWriteMap");
282 308
    check(negMap(id)[1] == -1.0 && negMap(id)[-10] == 10.0,
283 309
          "Something is wrong with NegMap");
284 310
    check(negWriteMap(id)[1] == -1.0 && negWriteMap(id)[-10] == 10.0,
285 311
          "Something is wrong with NegWriteMap");
286 312
    check(absMap(id)[1] == 1.0 && absMap(id)[-10] == 10.0,
287 313
          "Something is wrong with AbsMap");
288 314
  }
289 315

	
290 316
  // Logical maps:
291 317
  // - TrueMap, FalseMap
292 318
  // - AndMap, OrMap
293 319
  // - NotMap, NotWriteMap
294 320
  // - EqualMap, LessMap
295 321
  {
296 322
    checkConcept<BoolMap, TrueMap<A> >();
297 323
    checkConcept<BoolMap, FalseMap<A> >();
298 324
    checkConcept<BoolMap, AndMap<BoolMap,BoolMap> >();
299 325
    checkConcept<BoolMap, OrMap<BoolMap,BoolMap> >();
300 326
    checkConcept<BoolMap, NotMap<BoolMap> >();
301 327
    checkConcept<BoolWriteMap, NotWriteMap<BoolWriteMap> >();
302 328
    checkConcept<BoolMap, EqualMap<DoubleMap,DoubleMap> >();
303 329
    checkConcept<BoolMap, LessMap<DoubleMap,DoubleMap> >();
304 330

	
305 331
    TrueMap<int> tm;
306 332
    FalseMap<int> fm;
307 333
    RangeMap<bool> rm(2);
308 334
    rm[0] = true; rm[1] = false;
309 335
    check(andMap(tm,rm)[0] && !andMap(tm,rm)[1] &&
310 336
          !andMap(fm,rm)[0] && !andMap(fm,rm)[1],
311 337
          "Something is wrong with AndMap");
312 338
    check(orMap(tm,rm)[0] && orMap(tm,rm)[1] &&
313 339
          orMap(fm,rm)[0] && !orMap(fm,rm)[1],
314 340
          "Something is wrong with OrMap");
315 341
    check(!notMap(rm)[0] && notMap(rm)[1],
316 342
          "Something is wrong with NotMap");
317 343
    check(!notWriteMap(rm)[0] && notWriteMap(rm)[1],
318 344
          "Something is wrong with NotWriteMap");
319 345

	
320 346
    ConstMap<int, double> cm(2.0);
321 347
    IdentityMap<int> im;
322 348
    ConvertMap<IdentityMap<int>, double> id(im);
323 349
    check(lessMap(id,cm)[1] && !lessMap(id,cm)[2] && !lessMap(id,cm)[3],
324 350
          "Something is wrong with LessMap");
325 351
    check(!equalMap(id,cm)[1] && equalMap(id,cm)[2] && !equalMap(id,cm)[3],
326 352
          "Something is wrong with EqualMap");
327 353
  }
328 354

	
329 355
  // LoggerBoolMap
330 356
  {
331 357
    typedef std::vector<int> vec;
358
    checkConcept<WriteMap<int, bool>, LoggerBoolMap<vec::iterator> >();
359
    checkConcept<WriteMap<int, bool>,
360
                 LoggerBoolMap<std::back_insert_iterator<vec> > >();
361

	
332 362
    vec v1;
333 363
    vec v2(10);
334 364
    LoggerBoolMap<std::back_insert_iterator<vec> >
335 365
      map1(std::back_inserter(v1));
336 366
    LoggerBoolMap<vec::iterator> map2(v2.begin());
337 367
    map1.set(10, false);
338 368
    map1.set(20, true);   map2.set(20, true);
339 369
    map1.set(30, false);  map2.set(40, false);
340 370
    map1.set(50, true);   map2.set(50, true);
341 371
    map1.set(60, true);   map2.set(60, true);
342 372
    check(v1.size() == 3 && v2.size() == 10 &&
343 373
          v1[0]==20 && v1[1]==50 && v1[2]==60 &&
344 374
          v2[0]==20 && v2[1]==50 && v2[2]==60,
345 375
          "Something is wrong with LoggerBoolMap");
346 376

	
347 377
    int i = 0;
348 378
    for ( LoggerBoolMap<vec::iterator>::Iterator it = map2.begin();
349 379
          it != map2.end(); ++it )
350 380
      check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
381

	
382
    typedef ListDigraph Graph;
383
    DIGRAPH_TYPEDEFS(Graph);
384
    Graph gr;
385

	
386
    Node n0 = gr.addNode();
387
    Node n1 = gr.addNode();
388
    Node n2 = gr.addNode();
389
    Node n3 = gr.addNode();
390

	
391
    gr.addArc(n3, n0);
392
    gr.addArc(n3, n2);
393
    gr.addArc(n0, n2);
394
    gr.addArc(n2, n1);
395
    gr.addArc(n0, n1);
396

	
397
    {
398
      std::vector<Node> v;
399
      dfs(gr).processedMap(loggerBoolMap(std::back_inserter(v))).run();
400

	
401
      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
402
            "Something is wrong with LoggerBoolMap");
403
    }
404
    {
405
      std::vector<Node> v(countNodes(gr));
406
      dfs(gr).processedMap(loggerBoolMap(v.begin())).run();
407

	
408
      check(v.size()==4 && v[0]==n1 && v[1]==n2 && v[2]==n0 && v[3]==n3,
409
            "Something is wrong with LoggerBoolMap");
410
    }
351 411
  }
352
  
412

	
413
  // IdMap, RangeIdMap
414
  {
415
    typedef ListDigraph Graph;
416
    DIGRAPH_TYPEDEFS(Graph);
417

	
418
    checkConcept<ReadMap<Node, int>, IdMap<Graph, Node> >();
419
    checkConcept<ReadMap<Arc, int>, IdMap<Graph, Arc> >();
420
    checkConcept<ReadMap<Node, int>, RangeIdMap<Graph, Node> >();
421
    checkConcept<ReadMap<Arc, int>, RangeIdMap<Graph, Arc> >();
422

	
423
    Graph gr;
424
    IdMap<Graph, Node> nmap(gr);
425
    IdMap<Graph, Arc> amap(gr);
426
    RangeIdMap<Graph, Node> nrmap(gr);
427
    RangeIdMap<Graph, Arc> armap(gr);
428

	
429
    Node n0 = gr.addNode();
430
    Node n1 = gr.addNode();
431
    Node n2 = gr.addNode();
432

	
433
    Arc a0 = gr.addArc(n0, n1);
434
    Arc a1 = gr.addArc(n0, n2);
435
    Arc a2 = gr.addArc(n2, n1);
436
    Arc a3 = gr.addArc(n2, n0);
437

	
438
    check(nmap[n0] == gr.id(n0) && nmap(gr.id(n0)) == n0, "Wrong IdMap");
439
    check(nmap[n1] == gr.id(n1) && nmap(gr.id(n1)) == n1, "Wrong IdMap");
440
    check(nmap[n2] == gr.id(n2) && nmap(gr.id(n2)) == n2, "Wrong IdMap");
441

	
442
    check(amap[a0] == gr.id(a0) && amap(gr.id(a0)) == a0, "Wrong IdMap");
443
    check(amap[a1] == gr.id(a1) && amap(gr.id(a1)) == a1, "Wrong IdMap");
444
    check(amap[a2] == gr.id(a2) && amap(gr.id(a2)) == a2, "Wrong IdMap");
445
    check(amap[a3] == gr.id(a3) && amap(gr.id(a3)) == a3, "Wrong IdMap");
446

	
447
    check(nmap.inverse()[gr.id(n0)] == n0, "Wrong IdMap::InverseMap");
448
    check(amap.inverse()[gr.id(a0)] == a0, "Wrong IdMap::InverseMap");
449

	
450
    check(nrmap.size() == 3 && armap.size() == 4,
451
          "Wrong RangeIdMap::size()");
452

	
453
    check(nrmap[n0] == 0 && nrmap(0) == n0, "Wrong RangeIdMap");
454
    check(nrmap[n1] == 1 && nrmap(1) == n1, "Wrong RangeIdMap");
455
    check(nrmap[n2] == 2 && nrmap(2) == n2, "Wrong RangeIdMap");
456

	
457
    check(armap[a0] == 0 && armap(0) == a0, "Wrong RangeIdMap");
458
    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
459
    check(armap[a2] == 2 && armap(2) == a2, "Wrong RangeIdMap");
460
    check(armap[a3] == 3 && armap(3) == a3, "Wrong RangeIdMap");
461

	
462
    check(nrmap.inverse()[0] == n0, "Wrong RangeIdMap::InverseMap");
463
    check(armap.inverse()[0] == a0, "Wrong RangeIdMap::InverseMap");
464

	
465
    gr.erase(n1);
466

	
467
    if (nrmap[n0] == 1) nrmap.swap(n0, n2);
468
    nrmap.swap(n2, n0);
469
    if (armap[a1] == 1) armap.swap(a1, a3);
470
    armap.swap(a3, a1);
471

	
472
    check(nrmap.size() == 2 && armap.size() == 2,
473
          "Wrong RangeIdMap::size()");
474

	
475
    check(nrmap[n0] == 1 && nrmap(1) == n0, "Wrong RangeIdMap");
476
    check(nrmap[n2] == 0 && nrmap(0) == n2, "Wrong RangeIdMap");
477

	
478
    check(armap[a1] == 1 && armap(1) == a1, "Wrong RangeIdMap");
479
    check(armap[a3] == 0 && armap(0) == a3, "Wrong RangeIdMap");
480

	
481
    check(nrmap.inverse()[0] == n2, "Wrong RangeIdMap::InverseMap");
482
    check(armap.inverse()[0] == a3, "Wrong RangeIdMap::InverseMap");
483
  }
484

	
485
  // SourceMap, TargetMap, ForwardMap, BackwardMap, InDegMap, OutDegMap
486
  {
487
    typedef ListGraph Graph;
488
    GRAPH_TYPEDEFS(Graph);
489

	
490
    checkConcept<ReadMap<Arc, Node>, SourceMap<Graph> >();
491
    checkConcept<ReadMap<Arc, Node>, TargetMap<Graph> >();
492
    checkConcept<ReadMap<Edge, Arc>, ForwardMap<Graph> >();
493
    checkConcept<ReadMap<Edge, Arc>, BackwardMap<Graph> >();
494
    checkConcept<ReadMap<Node, int>, InDegMap<Graph> >();
495
    checkConcept<ReadMap<Node, int>, OutDegMap<Graph> >();
496

	
497
    Graph gr;
498
    Node n0 = gr.addNode();
499
    Node n1 = gr.addNode();
500
    Node n2 = gr.addNode();
501

	
502
    gr.addEdge(n0,n1);
503
    gr.addEdge(n1,n2);
504
    gr.addEdge(n0,n2);
505
    gr.addEdge(n2,n1);
506
    gr.addEdge(n1,n2);
507
    gr.addEdge(n0,n1);
508

	
509
    for (EdgeIt e(gr); e != INVALID; ++e) {
510
      check(forwardMap(gr)[e] == gr.direct(e, true), "Wrong ForwardMap");
511
      check(backwardMap(gr)[e] == gr.direct(e, false), "Wrong BackwardMap");
512
    }
513

	
514
    check(mapCompare(gr,
515
          sourceMap(orienter(gr, constMap<Edge, bool>(true))),
516
          targetMap(orienter(gr, constMap<Edge, bool>(false)))),
517
          "Wrong SourceMap or TargetMap");
518

	
519
    typedef Orienter<Graph, const ConstMap<Edge, bool> > Digraph;
520
    Digraph dgr(gr, constMap<Edge, bool>(true));
521
    OutDegMap<Digraph> odm(dgr);
522
    InDegMap<Digraph> idm(dgr);
523

	
524
    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 1, "Wrong OutDegMap");
525
    check(idm[n0] == 0 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
526

	
527
    gr.addEdge(n2, n0);
528

	
529
    check(odm[n0] == 3 && odm[n1] == 2 && odm[n2] == 2, "Wrong OutDegMap");
530
    check(idm[n0] == 1 && idm[n1] == 3 && idm[n2] == 3, "Wrong InDegMap");
531
  }
532

	
353 533
  // CrossRefMap
354 534
  {
355 535
    typedef ListDigraph Graph;
356 536
    DIGRAPH_TYPEDEFS(Graph);
357 537

	
358 538
    checkConcept<ReadWriteMap<Node, int>,
359 539
                 CrossRefMap<Graph, Node, int> >();
360
    
540
    checkConcept<ReadWriteMap<Node, bool>,
541
                 CrossRefMap<Graph, Node, bool> >();
542
    checkConcept<ReadWriteMap<Node, double>,
543
                 CrossRefMap<Graph, Node, double> >();
544

	
545
    Graph gr;
546
    typedef CrossRefMap<Graph, Node, char> CRMap;
547
    CRMap map(gr);
548

	
549
    Node n0 = gr.addNode();
550
    Node n1 = gr.addNode();
551
    Node n2 = gr.addNode();
552

	
553
    map.set(n0, 'A');
554
    map.set(n1, 'B');
555
    map.set(n2, 'C');
556

	
557
    check(map[n0] == 'A' && map('A') == n0 && map.inverse()['A'] == n0,
558
          "Wrong CrossRefMap");
559
    check(map[n1] == 'B' && map('B') == n1 && map.inverse()['B'] == n1,
560
          "Wrong CrossRefMap");
561
    check(map[n2] == 'C' && map('C') == n2 && map.inverse()['C'] == n2,
562
          "Wrong CrossRefMap");
563
    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
564
          "Wrong CrossRefMap::count()");
565

	
566
    CRMap::ValueIt it = map.beginValue();
567
    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
568
          it == map.endValue(), "Wrong value iterator");
569

	
570
    map.set(n2, 'A');
571

	
572
    check(map[n0] == 'A' && map[n1] == 'B' && map[n2] == 'A',
573
          "Wrong CrossRefMap");
574
    check(map('A') == n0 && map.inverse()['A'] == n0, "Wrong CrossRefMap");
575
    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
576
    check(map('C') == INVALID && map.inverse()['C'] == INVALID,
577
          "Wrong CrossRefMap");
578
    check(map.count('A') == 2 && map.count('B') == 1 && map.count('C') == 0,
579
          "Wrong CrossRefMap::count()");
580

	
581
    it = map.beginValue();
582
    check(*it++ == 'A' && *it++ == 'A' && *it++ == 'B' &&
583
          it == map.endValue(), "Wrong value iterator");
584

	
585
    map.set(n0, 'C');
586

	
587
    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
588
          "Wrong CrossRefMap");
589
    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
590
    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
591
    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
592
    check(map.count('A') == 1 && map.count('B') == 1 && map.count('C') == 1,
593
          "Wrong CrossRefMap::count()");
594

	
595
    it = map.beginValue();
596
    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
597
          it == map.endValue(), "Wrong value iterator");
598
  }
599

	
600
  // CrossRefMap
601
  {
602
    typedef SmartDigraph Graph;
603
    DIGRAPH_TYPEDEFS(Graph);
604

	
605
    checkConcept<ReadWriteMap<Node, int>,
606
                 CrossRefMap<Graph, Node, int> >();
607

	
361 608
    Graph gr;
362 609
    typedef CrossRefMap<Graph, Node, char> CRMap;
363 610
    typedef CRMap::ValueIterator ValueIt;
364 611
    CRMap map(gr);
365
    
612

	
366 613
    Node n0 = gr.addNode();
367 614
    Node n1 = gr.addNode();
368 615
    Node n2 = gr.addNode();
369
    
616

	
370 617
    map.set(n0, 'A');
371 618
    map.set(n1, 'B');
372 619
    map.set(n2, 'C');
373 620
    map.set(n2, 'A');
374 621
    map.set(n0, 'C');
375 622

	
376 623
    check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
377 624
          "Wrong CrossRefMap");
378 625
    check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
379 626
    check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
380 627
    check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
381 628

	
382 629
    ValueIt it = map.beginValue();
383 630
    check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
384 631
          it == map.endValue(), "Wrong value iterator");
385 632
  }
386 633

	
634
  // Iterable bool map
635
  {
636
    typedef SmartGraph Graph;
637
    typedef SmartGraph::Node Item;
638

	
639
    typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
640
    checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
641

	
642
    const int num = 10;
643
    Graph g;
644
    Ibm map0(g, true);
645
    std::vector<Item> items;
646
    for (int i = 0; i < num; ++i) {
647
      items.push_back(g.addNode());
648
    }
649

	
650
    Ibm map1(g, true);
651
    int n = 0;
652
    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
653
      check(map1[static_cast<Item>(it)], "Wrong TrueIt");
654
      ++n;
655
    }
656
    check(n == num, "Wrong number");
657

	
658
    n = 0;
659
    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
660
        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
661
        ++n;
662
    }
663
    check(n == num, "Wrong number");
664
    check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
665
    check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
666

	
667
    map1[items[5]] = true;
668

	
669
    n = 0;
670
    for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
671
        check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
672
        ++n;
673
    }
674
    check(n == num, "Wrong number");
675

	
676
    map1[items[num / 2]] = false;
677
    check(map1[items[num / 2]] == false, "Wrong map value");
678

	
679
    n = 0;
680
    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
681
        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
682
        ++n;
683
    }
684
    check(n == num - 1, "Wrong number");
685

	
686
    n = 0;
687
    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
688
        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
689
        ++n;
690
    }
691
    check(n == 1, "Wrong number");
692

	
693
    map1[items[0]] = false;
694
    check(map1[items[0]] == false, "Wrong map value");
695

	
696
    map1[items[num - 1]] = false;
697
    check(map1[items[num - 1]] == false, "Wrong map value");
698

	
699
    n = 0;
700
    for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
701
        check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
702
        ++n;
703
    }
704
    check(n == num - 3, "Wrong number");
705
    check(map1.trueNum() == num - 3, "Wrong number");
706

	
707
    n = 0;
708
    for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
709
        check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
710
        ++n;
711
    }
712
    check(n == 3, "Wrong number");
713
    check(map1.falseNum() == 3, "Wrong number");
714
  }
715

	
716
  // Iterable int map
717
  {
718
    typedef SmartGraph Graph;
719
    typedef SmartGraph::Node Item;
720
    typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
721

	
722
    checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
723

	
724
    const int num = 10;
725
    Graph g;
726
    Iim map0(g, 0);
727
    std::vector<Item> items;
728
    for (int i = 0; i < num; ++i) {
729
      items.push_back(g.addNode());
730
    }
731

	
732
    Iim map1(g);
733
    check(map1.size() == 0, "Wrong size");
734

	
735
    for (int i = 0; i < num; ++i) {
736
      map1[items[i]] = i;
737
    }
738
    check(map1.size() == num, "Wrong size");
739

	
740
    for (int i = 0; i < num; ++i) {
741
      Iim::ItemIt it(map1, i);
742
      check(static_cast<Item>(it) == items[i], "Wrong value");
743
      ++it;
744
      check(static_cast<Item>(it) == INVALID, "Wrong value");
745
    }
746

	
747
    for (int i = 0; i < num; ++i) {
748
      map1[items[i]] = i % 2;
749
    }
750
    check(map1.size() == 2, "Wrong size");
751

	
752
    int n = 0;
753
    for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
754
      check(map1[static_cast<Item>(it)] == 0, "Wrong value");
755
      ++n;
756
    }
757
    check(n == (num + 1) / 2, "Wrong number");
758

	
759
    for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
760
      check(map1[static_cast<Item>(it)] == 1, "Wrong value");
761
      ++n;
762
    }
763
    check(n == num, "Wrong number");
764

	
765
  }
766

	
767
  // Iterable value map
768
  {
769
    typedef SmartGraph Graph;
770
    typedef SmartGraph::Node Item;
771
    typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
772

	
773
    checkConcept<ReadWriteMap<Item, double>, Ivm>();
774

	
775
    const int num = 10;
776
    Graph g;
777
    Ivm map0(g, 0.0);
778
    std::vector<Item> items;
779
    for (int i = 0; i < num; ++i) {
780
      items.push_back(g.addNode());
781
    }
782

	
783
    Ivm map1(g, 0.0);
784
    check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
785
    check(*map1.beginValue() == 0.0, "Wrong value");
786

	
787
    for (int i = 0; i < num; ++i) {
788
      map1.set(items[i], static_cast<double>(i));
789
    }
790
    check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
791

	
792
    for (int i = 0; i < num; ++i) {
793
      Ivm::ItemIt it(map1, static_cast<double>(i));
794
      check(static_cast<Item>(it) == items[i], "Wrong value");
795
      ++it;
796
      check(static_cast<Item>(it) == INVALID, "Wrong value");
797
    }
798

	
799
    for (Ivm::ValueIt vit = map1.beginValue();
800
         vit != map1.endValue(); ++vit) {
801
      check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
802
            "Wrong ValueIt");
803
    }
804

	
805
    for (int i = 0; i < num; ++i) {
806
      map1.set(items[i], static_cast<double>(i % 2));
807
    }
808
    check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
809

	
810
    int n = 0;
811
    for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
812
      check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
813
      ++n;
814
    }
815
    check(n == (num + 1) / 2, "Wrong number");
816

	
817
    for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
818
      check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
819
      ++n;
820
    }
821
    check(n == num, "Wrong number");
822

	
823
  }
824

	
825
  // Graph map utilities:
826
  // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
827
  // mapFind(), mapFindIf(), mapCount(), mapCountIf()
828
  // mapCopy(), mapCompare(), mapFill()
829
  {
830
    DIGRAPH_TYPEDEFS(SmartDigraph);
831

	
832
    SmartDigraph g;
833
    Node n1 = g.addNode();
834
    Node n2 = g.addNode();
835
    Node n3 = g.addNode();
836

	
837
    SmartDigraph::NodeMap<int> map1(g);
838
    SmartDigraph::ArcMap<char> map2(g);
839
    ConstMap<Node, A> cmap1 = A();
840
    ConstMap<Arc, C> cmap2 = C(0);
841

	
842
    map1[n1] = 10;
843
    map1[n2] = 5;
844
    map1[n3] = 12;
845

	
846
    // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
847
    check(mapMin(g, map1) == n2, "Wrong mapMin()");
848
    check(mapMax(g, map1) == n3, "Wrong mapMax()");
849
    check(mapMin(g, map1, std::greater<int>()) == n3, "Wrong mapMin()");
850
    check(mapMax(g, map1, std::greater<int>()) == n2, "Wrong mapMax()");
851
    check(mapMinValue(g, map1) == 5, "Wrong mapMinValue()");
852
    check(mapMaxValue(g, map1) == 12, "Wrong mapMaxValue()");
853

	
854
    check(mapMin(g, map2) == INVALID, "Wrong mapMin()");
855
    check(mapMax(g, map2) == INVALID, "Wrong mapMax()");
856

	
857
    check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
858
    check(mapMax(g, cmap2) == INVALID, "Wrong mapMax()");
859

	
860
    Arc a1 = g.addArc(n1, n2);
861
    Arc a2 = g.addArc(n1, n3);
862
    Arc a3 = g.addArc(n2, n3);
863
    Arc a4 = g.addArc(n3, n1);
864

	
865
    map2[a1] = 'b';
866
    map2[a2] = 'a';
867
    map2[a3] = 'b';
868
    map2[a4] = 'c';
869

	
870
    // mapMin(), mapMax(), mapMinValue(), mapMaxValue()
871
    check(mapMin(g, map2) == a2, "Wrong mapMin()");
872
    check(mapMax(g, map2) == a4, "Wrong mapMax()");
873
    check(mapMin(g, map2, std::greater<int>()) == a4, "Wrong mapMin()");
874
    check(mapMax(g, map2, std::greater<int>()) == a2, "Wrong mapMax()");
875
    check(mapMinValue(g, map2, std::greater<int>()) == 'c',
876
          "Wrong mapMinValue()");
877
    check(mapMaxValue(g, map2, std::greater<int>()) == 'a',
878
          "Wrong mapMaxValue()");
879

	
880
    check(mapMin(g, cmap1) != INVALID, "Wrong mapMin()");
881
    check(mapMax(g, cmap2) != INVALID, "Wrong mapMax()");
882
    check(mapMaxValue(g, cmap2) == C(0), "Wrong mapMaxValue()");
883

	
884
    check(mapMin(g, composeMap(functorToMap(&createC), map2)) == a2,
885
          "Wrong mapMin()");
886
    check(mapMax(g, composeMap(functorToMap(&createC), map2)) == a4,
887
          "Wrong mapMax()");
888
    check(mapMinValue(g, composeMap(functorToMap(&createC), map2)) == C('a'),
889
          "Wrong mapMinValue()");
890
    check(mapMaxValue(g, composeMap(functorToMap(&createC), map2)) == C('c'),
891
          "Wrong mapMaxValue()");
892

	
893
    // mapFind(), mapFindIf()
894
    check(mapFind(g, map1, 5) == n2, "Wrong mapFind()");
895
    check(mapFind(g, map1, 6) == INVALID, "Wrong mapFind()");
896
    check(mapFind(g, map2, 'a') == a2, "Wrong mapFind()");
897
    check(mapFind(g, map2, 'e') == INVALID, "Wrong mapFind()");
898
    check(mapFind(g, cmap2, C(0)) == ArcIt(g), "Wrong mapFind()");
899
    check(mapFind(g, cmap2, C(1)) == INVALID, "Wrong mapFind()");
900

	
901
    check(mapFindIf(g, map1, Less<int>(7)) == n2,
902
          "Wrong mapFindIf()");
903
    check(mapFindIf(g, map1, Less<int>(5)) == INVALID,
904
          "Wrong mapFindIf()");
905
    check(mapFindIf(g, map2, Less<char>('d')) == ArcIt(g),
906
          "Wrong mapFindIf()");
907
    check(mapFindIf(g, map2, Less<char>('a')) == INVALID,
908
          "Wrong mapFindIf()");
909

	
910
    // mapCount(), mapCountIf()
911
    check(mapCount(g, map1, 5) == 1, "Wrong mapCount()");
912
    check(mapCount(g, map1, 6) == 0, "Wrong mapCount()");
913
    check(mapCount(g, map2, 'a') == 1, "Wrong mapCount()");
914
    check(mapCount(g, map2, 'b') == 2, "Wrong mapCount()");
915
    check(mapCount(g, map2, 'e') == 0, "Wrong mapCount()");
916
    check(mapCount(g, cmap2, C(0)) == 4, "Wrong mapCount()");
917
    check(mapCount(g, cmap2, C(1)) == 0, "Wrong mapCount()");
918

	
919
    check(mapCountIf(g, map1, Less<int>(11)) == 2,
920
          "Wrong mapCountIf()");
921
    check(mapCountIf(g, map1, Less<int>(13)) == 3,
922
          "Wrong mapCountIf()");
923
    check(mapCountIf(g, map1, Less<int>(5)) == 0,
924
          "Wrong mapCountIf()");
925
    check(mapCountIf(g, map2, Less<char>('d')) == 4,
926
          "Wrong mapCountIf()");
927
    check(mapCountIf(g, map2, Less<char>('c')) == 3,
928
          "Wrong mapCountIf()");
929
    check(mapCountIf(g, map2, Less<char>('a')) == 0,
930
          "Wrong mapCountIf()");
931

	
932
    // MapIt, ConstMapIt
933
/*
934
These tests can be used after applying bugfix #330
935
    typedef SmartDigraph::NodeMap<int>::MapIt MapIt;
936
    typedef SmartDigraph::NodeMap<int>::ConstMapIt ConstMapIt;
937
    check(*std::min_element(MapIt(map1), MapIt(INVALID)) == 5,
938
          "Wrong NodeMap<>::MapIt");
939
    check(*std::max_element(ConstMapIt(map1), ConstMapIt(INVALID)) == 12,
940
          "Wrong NodeMap<>::MapIt");
941

	
942
    int sum = 0;
943
    std::for_each(MapIt(map1), MapIt(INVALID), Sum<int>(sum));
944
    check(sum == 27, "Wrong NodeMap<>::MapIt");
945
    std::for_each(ConstMapIt(map1), ConstMapIt(INVALID), Sum<int>(sum));
946
    check(sum == 54, "Wrong NodeMap<>::ConstMapIt");
947
*/
948

	
949
    // mapCopy(), mapCompare(), mapFill()
950
    check(mapCompare(g, map1, map1), "Wrong mapCompare()");
951
    check(mapCompare(g, cmap2, cmap2), "Wrong mapCompare()");
952
    check(mapCompare(g, map1, shiftMap(map1, 0)), "Wrong mapCompare()");
953
    check(mapCompare(g, map2, scaleMap(map2, 1)), "Wrong mapCompare()");
954
    check(!mapCompare(g, map1, shiftMap(map1, 1)), "Wrong mapCompare()");
955

	
956
    SmartDigraph::NodeMap<int> map3(g, 0);
957
    SmartDigraph::ArcMap<char> map4(g, 'a');
958

	
959
    check(!mapCompare(g, map1, map3), "Wrong mapCompare()");
960
    check(!mapCompare(g, map2, map4), "Wrong mapCompare()");
961

	
962
    mapCopy(g, map1, map3);
963
    mapCopy(g, map2, map4);
964

	
965
    check(mapCompare(g, map1, map3), "Wrong mapCompare() or mapCopy()");
966
    check(mapCompare(g, map2, map4), "Wrong mapCompare() or mapCopy()");
967

	
968
    Undirector<SmartDigraph> ug(g);
969
    Undirector<SmartDigraph>::EdgeMap<char> umap1(ug, 'x');
970
    Undirector<SmartDigraph>::ArcMap<double> umap2(ug, 3.14);
971

	
972
    check(!mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
973
    check(!mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
974
    check(!mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
975
    check(!mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
976

	
977
    mapCopy(g, map2, umap1);
978

	
979
    check(mapCompare(g, map2, umap1), "Wrong mapCompare() or mapCopy()");
980
    check(mapCompare(g, umap1, map2), "Wrong mapCompare() or mapCopy()");
981
    check(mapCompare(ug, map2, umap1), "Wrong mapCompare() or mapCopy()");
982
    check(mapCompare(ug, umap1, map2), "Wrong mapCompare() or mapCopy()");
983

	
984
    mapCopy(g, map2, umap1);
985
    mapCopy(g, umap1, map2);
986
    mapCopy(ug, map2, umap1);
987
    mapCopy(ug, umap1, map2);
988

	
989
    check(!mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
990
    mapCopy(ug, umap1, umap2);
991
    check(mapCompare(ug, umap1, umap2), "Wrong mapCompare() or mapCopy()");
992

	
993
    check(!mapCompare(g, map1, constMap<Node>(2)), "Wrong mapCompare()");
994
    mapFill(g, map1, 2);
995
    check(mapCompare(g, constMap<Node>(2), map1), "Wrong mapFill()");
996

	
997
    check(!mapCompare(g, map2, constMap<Arc>('z')), "Wrong mapCompare()");
998
    mapCopy(g, constMap<Arc>('z'), map2);
999
    check(mapCompare(g, constMap<Arc>('z'), map2), "Wrong mapCopy()");
1000
  }
1001

	
387 1002
  return 0;
388 1003
}
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-2009
5
 * Copyright (C) 2003-2010
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 <sstream>
21 21
#include <vector>
22 22
#include <queue>
23 23
#include <cstdlib>
24 24

	
25 25
#include <lemon/matching.h>
26 26
#include <lemon/smart_graph.h>
27 27
#include <lemon/concepts/graph.h>
28 28
#include <lemon/concepts/maps.h>
29 29
#include <lemon/lgf_reader.h>
30 30
#include <lemon/math.h>
31 31

	
32 32
#include "test_tools.h"
33 33

	
34 34
using namespace std;
35 35
using namespace lemon;
36 36

	
37 37
GRAPH_TYPEDEFS(SmartGraph);
38 38

	
39 39

	
40 40
const int lgfn = 3;
41 41
const std::string lgf[lgfn] = {
42 42
  "@nodes\n"
43 43
  "label\n"
44 44
  "0\n"
45 45
  "1\n"
46 46
  "2\n"
47 47
  "3\n"
48 48
  "4\n"
49 49
  "5\n"
50 50
  "6\n"
51 51
  "7\n"
52 52
  "@edges\n"
53 53
  "     label  weight\n"
54 54
  "7 4  0      984\n"
55 55
  "0 7  1      73\n"
56 56
  "7 1  2      204\n"
57 57
  "2 3  3      583\n"
58 58
  "2 7  4      565\n"
59 59
  "2 1  5      582\n"
60 60
  "0 4  6      551\n"
61 61
  "2 5  7      385\n"
62 62
  "1 5  8      561\n"
63 63
  "5 3  9      484\n"
64 64
  "7 5  10     904\n"
65 65
  "3 6  11     47\n"
66 66
  "7 6  12     888\n"
67 67
  "3 0  13     747\n"
68 68
  "6 1  14     310\n",
69 69

	
70 70
  "@nodes\n"
71 71
  "label\n"
72 72
  "0\n"
73 73
  "1\n"
74 74
  "2\n"
75 75
  "3\n"
76 76
  "4\n"
77 77
  "5\n"
78 78
  "6\n"
79 79
  "7\n"
80 80
  "@edges\n"
81 81
  "     label  weight\n"
82 82
  "2 5  0      710\n"
83 83
  "0 5  1      241\n"
84 84
  "2 4  2      856\n"
85 85
  "2 6  3      762\n"
86 86
  "4 1  4      747\n"
87 87
  "6 1  5      962\n"
88 88
  "4 7  6      723\n"
89 89
  "1 7  7      661\n"
90 90
  "2 3  8      376\n"
91 91
  "1 0  9      416\n"
92 92
  "6 7  10     391\n",
93 93

	
94 94
  "@nodes\n"
95 95
  "label\n"
96 96
  "0\n"
97 97
  "1\n"
98 98
  "2\n"
99 99
  "3\n"
100 100
  "4\n"
101 101
  "5\n"
102 102
  "6\n"
103 103
  "7\n"
104 104
  "@edges\n"
105 105
  "     label  weight\n"
106 106
  "6 2  0      553\n"
107 107
  "0 7  1      653\n"
108 108
  "6 3  2      22\n"
109 109
  "4 7  3      846\n"
110 110
  "7 2  4      981\n"
111 111
  "7 6  5      250\n"
112 112
  "5 2  6      539\n",
113 113
};
114 114

	
115 115
void checkMaxMatchingCompile()
116 116
{
117 117
  typedef concepts::Graph Graph;
118 118
  typedef Graph::Node Node;
119 119
  typedef Graph::Edge Edge;
120 120
  typedef Graph::EdgeMap<bool> MatMap;
121 121

	
122 122
  Graph g;
123 123
  Node n;
124 124
  Edge e;
125 125
  MatMap mat(g);
126 126

	
127 127
  MaxMatching<Graph> mat_test(g);
128 128
  const MaxMatching<Graph>&
129 129
    const_mat_test = mat_test;
130 130

	
131 131
  mat_test.init();
132 132
  mat_test.greedyInit();
133 133
  mat_test.matchingInit(mat);
134 134
  mat_test.startSparse();
135 135
  mat_test.startDense();
136 136
  mat_test.run();
137
  
137

	
138 138
  const_mat_test.matchingSize();
139 139
  const_mat_test.matching(e);
140 140
  const_mat_test.matching(n);
141 141
  const MaxMatching<Graph>::MatchingMap& mmap =
142 142
    const_mat_test.matchingMap();
143 143
  e = mmap[n];
144 144
  const_mat_test.mate(n);
145 145

	
146
  MaxMatching<Graph>::Status stat = 
146
  MaxMatching<Graph>::Status stat =
147 147
    const_mat_test.status(n);
148 148
  const MaxMatching<Graph>::StatusMap& smap =
149 149
    const_mat_test.statusMap();
150 150
  stat = smap[n];
151 151
  const_mat_test.barrier(n);
152 152
}
153 153

	
154 154
void checkMaxWeightedMatchingCompile()
155 155
{
156 156
  typedef concepts::Graph Graph;
157 157
  typedef Graph::Node Node;
158 158
  typedef Graph::Edge Edge;
159 159
  typedef Graph::EdgeMap<int> WeightMap;
160 160

	
161 161
  Graph g;
162 162
  Node n;
163 163
  Edge e;
164 164
  WeightMap w(g);
165 165

	
166 166
  MaxWeightedMatching<Graph> mat_test(g, w);
167 167
  const MaxWeightedMatching<Graph>&
168 168
    const_mat_test = mat_test;
169 169

	
170 170
  mat_test.init();
171 171
  mat_test.start();
172 172
  mat_test.run();
173
  
173

	
174 174
  const_mat_test.matchingWeight();
175 175
  const_mat_test.matchingSize();
176 176
  const_mat_test.matching(e);
177 177
  const_mat_test.matching(n);
178 178
  const MaxWeightedMatching<Graph>::MatchingMap& mmap =
179 179
    const_mat_test.matchingMap();
180 180
  e = mmap[n];
181 181
  const_mat_test.mate(n);
182
  
182

	
183 183
  int k = 0;
184 184
  const_mat_test.dualValue();
185 185
  const_mat_test.nodeValue(n);
186 186
  const_mat_test.blossomNum();
187 187
  const_mat_test.blossomSize(k);
188 188
  const_mat_test.blossomValue(k);
189 189
}
190 190

	
191 191
void checkMaxWeightedPerfectMatchingCompile()
192 192
{
193 193
  typedef concepts::Graph Graph;
194 194
  typedef Graph::Node Node;
195 195
  typedef Graph::Edge Edge;
196 196
  typedef Graph::EdgeMap<int> WeightMap;
197 197

	
198 198
  Graph g;
199 199
  Node n;
200 200
  Edge e;
201 201
  WeightMap w(g);
202 202

	
203 203
  MaxWeightedPerfectMatching<Graph> mat_test(g, w);
204 204
  const MaxWeightedPerfectMatching<Graph>&
205 205
    const_mat_test = mat_test;
206 206

	
207 207
  mat_test.init();
208 208
  mat_test.start();
209 209
  mat_test.run();
210
  
210

	
211 211
  const_mat_test.matchingWeight();
212 212
  const_mat_test.matching(e);
213 213
  const_mat_test.matching(n);
214 214
  const MaxWeightedPerfectMatching<Graph>::MatchingMap& mmap =
215 215
    const_mat_test.matchingMap();
216 216
  e = mmap[n];
217 217
  const_mat_test.mate(n);
218
  
218

	
219 219
  int k = 0;
220 220
  const_mat_test.dualValue();
221 221
  const_mat_test.nodeValue(n);
222 222
  const_mat_test.blossomNum();
223 223
  const_mat_test.blossomSize(k);
224 224
  const_mat_test.blossomValue(k);
225 225
}
226 226

	
227 227
void checkMatching(const SmartGraph& graph,
228 228
                   const MaxMatching<SmartGraph>& mm) {
229 229
  int num = 0;
230 230

	
231 231
  IntNodeMap comp_index(graph);
232 232
  UnionFind<IntNodeMap> comp(comp_index);
233 233

	
234 234
  int barrier_num = 0;
235 235

	
236 236
  for (NodeIt n(graph); n != INVALID; ++n) {
237 237
    check(mm.status(n) == MaxMatching<SmartGraph>::EVEN ||
238 238
          mm.matching(n) != INVALID, "Wrong Gallai-Edmonds decomposition");
239 239
    if (mm.status(n) == MaxMatching<SmartGraph>::ODD) {
240 240
      ++barrier_num;
241 241
    } else {
242 242
      comp.insert(n);
243 243
    }
244 244
  }
245 245

	
246 246
  for (EdgeIt e(graph); e != INVALID; ++e) {
247 247
    if (mm.matching(e)) {
248 248
      check(e == mm.matching(graph.u(e)), "Wrong matching");
249 249
      check(e == mm.matching(graph.v(e)), "Wrong matching");
250 250
      ++num;
251 251
    }
252 252
    check(mm.status(graph.u(e)) != MaxMatching<SmartGraph>::EVEN ||
253 253
          mm.status(graph.v(e)) != MaxMatching<SmartGraph>::MATCHED,
254 254
          "Wrong Gallai-Edmonds decomposition");
255 255

	
256 256
    check(mm.status(graph.v(e)) != MaxMatching<SmartGraph>::EVEN ||
257 257
          mm.status(graph.u(e)) != MaxMatching<SmartGraph>::MATCHED,
258 258
          "Wrong Gallai-Edmonds decomposition");
259 259

	
260 260
    if (mm.status(graph.u(e)) != MaxMatching<SmartGraph>::ODD &&
261 261
        mm.status(graph.v(e)) != MaxMatching<SmartGraph>::ODD) {
262 262
      comp.join(graph.u(e), graph.v(e));
263 263
    }
264 264
  }
265 265

	
266 266
  std::set<int> comp_root;
267 267
  int odd_comp_num = 0;
268 268
  for (NodeIt n(graph); n != INVALID; ++n) {
269 269
    if (mm.status(n) != MaxMatching<SmartGraph>::ODD) {
270 270
      int root = comp.find(n);
271 271
      if (comp_root.find(root) == comp_root.end()) {
272 272
        comp_root.insert(root);
273 273
        if (comp.size(n) % 2 == 1) {
274 274
          ++odd_comp_num;
275 275
        }
276 276
      }
277 277
    }
278 278
  }
279 279

	
280 280
  check(mm.matchingSize() == num, "Wrong matching");
281 281
  check(2 * num == countNodes(graph) - (odd_comp_num - barrier_num),
282 282
         "Wrong matching");
283 283
  return;
284 284
}
285 285

	
286 286
void checkWeightedMatching(const SmartGraph& graph,
287 287
                   const SmartGraph::EdgeMap<int>& weight,
288 288
                   const MaxWeightedMatching<SmartGraph>& mwm) {
289 289
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
290 290
    if (graph.u(e) == graph.v(e)) continue;
291 291
    int rw = mwm.nodeValue(graph.u(e)) + mwm.nodeValue(graph.v(e));
292 292

	
293 293
    for (int i = 0; i < mwm.blossomNum(); ++i) {
294 294
      bool s = false, t = false;
295 295
      for (MaxWeightedMatching<SmartGraph>::BlossomIt n(mwm, i);
296 296
           n != INVALID; ++n) {
297 297
        if (graph.u(e) == n) s = true;
298 298
        if (graph.v(e) == n) t = true;
299 299
      }
300 300
      if (s == true && t == true) {
301 301
        rw += mwm.blossomValue(i);
302 302
      }
303 303
    }
304 304
    rw -= weight[e] * mwm.dualScale;
305 305

	
306 306
    check(rw >= 0, "Negative reduced weight");
307 307
    check(rw == 0 || !mwm.matching(e),
308 308
          "Non-zero reduced weight on matching edge");
309 309
  }
310 310

	
311 311
  int pv = 0;
312 312
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
313 313
    if (mwm.matching(n) != INVALID) {
314 314
      check(mwm.nodeValue(n) >= 0, "Invalid node value");
315 315
      pv += weight[mwm.matching(n)];
316 316
      SmartGraph::Node o = graph.target(mwm.matching(n));
317 317
      check(mwm.mate(n) == o, "Invalid matching");
318 318
      check(mwm.matching(n) == graph.oppositeArc(mwm.matching(o)),
319 319
            "Invalid matching");
320 320
    } else {
321 321
      check(mwm.mate(n) == INVALID, "Invalid matching");
322 322
      check(mwm.nodeValue(n) == 0, "Invalid matching");
323 323
    }
324 324
  }
325 325

	
326 326
  int dv = 0;
327 327
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
328 328
    dv += mwm.nodeValue(n);
329 329
  }
330 330

	
331 331
  for (int i = 0; i < mwm.blossomNum(); ++i) {
332 332
    check(mwm.blossomValue(i) >= 0, "Invalid blossom value");
333 333
    check(mwm.blossomSize(i) % 2 == 1, "Even blossom size");
334 334
    dv += mwm.blossomValue(i) * ((mwm.blossomSize(i) - 1) / 2);
335 335
  }
336 336

	
337 337
  check(pv * mwm.dualScale == dv * 2, "Wrong duality");
338 338

	
339 339
  return;
340 340
}
341 341

	
342 342
void checkWeightedPerfectMatching(const SmartGraph& graph,
343 343
                          const SmartGraph::EdgeMap<int>& weight,
344 344
                          const MaxWeightedPerfectMatching<SmartGraph>& mwpm) {
345 345
  for (SmartGraph::EdgeIt e(graph); e != INVALID; ++e) {
346 346
    if (graph.u(e) == graph.v(e)) continue;
347 347
    int rw = mwpm.nodeValue(graph.u(e)) + mwpm.nodeValue(graph.v(e));
348 348

	
349 349
    for (int i = 0; i < mwpm.blossomNum(); ++i) {
350 350
      bool s = false, t = false;
351 351
      for (MaxWeightedPerfectMatching<SmartGraph>::BlossomIt n(mwpm, i);
352 352
           n != INVALID; ++n) {
353 353
        if (graph.u(e) == n) s = true;
354 354
        if (graph.v(e) == n) t = true;
355 355
      }
356 356
      if (s == true && t == true) {
357 357
        rw += mwpm.blossomValue(i);
358 358
      }
359 359
    }
360 360
    rw -= weight[e] * mwpm.dualScale;
361 361

	
362 362
    check(rw >= 0, "Negative reduced weight");
363 363
    check(rw == 0 || !mwpm.matching(e),
364 364
          "Non-zero reduced weight on matching edge");
365 365
  }
366 366

	
367 367
  int pv = 0;
368 368
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
369 369
    check(mwpm.matching(n) != INVALID, "Non perfect");
370 370
    pv += weight[mwpm.matching(n)];
371 371
    SmartGraph::Node o = graph.target(mwpm.matching(n));
372 372
    check(mwpm.mate(n) == o, "Invalid matching");
373 373
    check(mwpm.matching(n) == graph.oppositeArc(mwpm.matching(o)),
374 374
          "Invalid matching");
375 375
  }
376 376

	
377 377
  int dv = 0;
378 378
  for (SmartGraph::NodeIt n(graph); n != INVALID; ++n) {
379 379
    dv += mwpm.nodeValue(n);
380 380
  }
381 381

	
382 382
  for (int i = 0; i < mwpm.blossomNum(); ++i) {
383 383
    check(mwpm.blossomValue(i) >= 0, "Invalid blossom value");
384 384
    check(mwpm.blossomSize(i) % 2 == 1, "Even blossom size");
385 385
    dv += mwpm.blossomValue(i) * ((mwpm.blossomSize(i) - 1) / 2);
386 386
  }
387 387

	
388 388
  check(pv * mwpm.dualScale == dv * 2, "Wrong duality");
389 389

	
390 390
  return;
391 391
}
392 392

	
393 393

	
394 394
int main() {
395 395

	
396 396
  for (int i = 0; i < lgfn; ++i) {
397 397
    SmartGraph graph;
398 398
    SmartGraph::EdgeMap<int> weight(graph);
399 399

	
400 400
    istringstream lgfs(lgf[i]);
401 401
    graphReader(graph, lgfs).
402 402
      edgeMap("weight", weight).run();
403 403

	
404
    MaxMatching<SmartGraph> mm(graph);
405
    mm.run();
406
    checkMatching(graph, mm);
404
    bool perfect;
405
    {
406
      MaxMatching<SmartGraph> mm(graph);
407
      mm.run();
408
      checkMatching(graph, mm);
409
      perfect = 2 * mm.matchingSize() == countNodes(graph);
410
    }
407 411

	
408
    MaxWeightedMatching<SmartGraph> mwm(graph, weight);
409
    mwm.run();
410
    checkWeightedMatching(graph, weight, mwm);
412
    {
413
      MaxWeightedMatching<SmartGraph> mwm(graph, weight);
414
      mwm.run();
415
      checkWeightedMatching(graph, weight, mwm);
416
    }
411 417

	
412
    MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
413
    bool perfect = mwpm.run();
418
    {
419
      MaxWeightedMatching<SmartGraph> mwm(graph, weight);
420
      mwm.init();
421
      mwm.start();
422
      checkWeightedMatching(graph, weight, mwm);
423
    }
414 424

	
415
    check(perfect == (mm.matchingSize() * 2 == countNodes(graph)),
416
          "Perfect matching found");
425
    {
426
      MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
427
      bool result = mwpm.run();
417 428

	
418
    if (perfect) {
419
      checkWeightedPerfectMatching(graph, weight, mwpm);
429
      check(result == perfect, "Perfect matching found");
430
      if (perfect) {
431
        checkWeightedPerfectMatching(graph, weight, mwpm);
432
      }
433
    }
434

	
435
    {
436
      MaxWeightedPerfectMatching<SmartGraph> mwpm(graph, weight);
437
      mwpm.init();
438
      bool result = mwpm.start();
439

	
440
      check(result == perfect, "Perfect matching found");
441
      if (perfect) {
442
        checkWeightedPerfectMatching(graph, weight, mwpm);
443
      }
420 444
    }
421 445
  }
422 446

	
423 447
  return 0;
424 448
}
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-2010
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 <set>
21 21
#include <vector>
22 22
#include <iterator>
23 23

	
24 24
#include <lemon/smart_graph.h>
25 25
#include <lemon/min_cost_arborescence.h>
26 26
#include <lemon/lgf_reader.h>
27 27
#include <lemon/concepts/digraph.h>
28 28

	
29 29
#include "test_tools.h"
30 30

	
31 31
using namespace lemon;
32 32
using namespace std;
33 33

	
34 34
const char test_lgf[] =
35 35
  "@nodes\n"
36 36
  "label\n"
37 37
  "0\n"
38 38
  "1\n"
39 39
  "2\n"
40 40
  "3\n"
41 41
  "4\n"
42 42
  "5\n"
43 43
  "6\n"
44 44
  "7\n"
45 45
  "8\n"
46 46
  "9\n"
47 47
  "@arcs\n"
48 48
  "     label  cost\n"
49 49
  "1 8  0      107\n"
50 50
  "0 3  1      70\n"
51 51
  "2 1  2      46\n"
52 52
  "4 1  3      28\n"
53 53
  "4 4  4      91\n"
54 54
  "3 9  5      76\n"
55 55
  "9 8  6      61\n"
56 56
  "8 1  7      39\n"
57 57
  "9 8  8      74\n"
58 58
  "8 0  9      39\n"
59 59
  "4 3  10     45\n"
60 60
  "2 2  11     34\n"
61 61
  "0 1  12     100\n"
62 62
  "6 3  13     95\n"
63 63
  "4 1  14     22\n"
64 64
  "1 1  15     31\n"
65 65
  "7 2  16     51\n"
66 66
  "2 6  17     29\n"
67 67
  "8 3  18     115\n"
68 68
  "6 9  19     32\n"
69 69
  "1 1  20     60\n"
70 70
  "0 3  21     40\n"
71 71
  "@attributes\n"
72 72
  "source 0\n";
73 73

	
74 74

	
75 75
void checkMinCostArborescenceCompile()
76 76
{
77 77
  typedef double VType;
78 78
  typedef concepts::Digraph Digraph;
79 79
  typedef concepts::ReadMap<Digraph::Arc, VType> CostMap;
80 80
  typedef Digraph::Node Node;
81 81
  typedef Digraph::Arc Arc;
82 82
  typedef concepts::WriteMap<Digraph::Arc, bool> ArbMap;
83 83
  typedef concepts::ReadWriteMap<Digraph::Node, Digraph::Arc> PredMap;
84 84

	
85 85
  typedef MinCostArborescence<Digraph, CostMap>::
86 86
            SetArborescenceMap<ArbMap>::
87 87
            SetPredMap<PredMap>::Create MinCostArbType;
88 88

	
89 89
  Digraph g;
90 90
  Node s, n;
91 91
  Arc e;
92 92
  VType c;
93 93
  bool b;
94 94
  int i;
95 95
  CostMap cost;
96 96
  ArbMap arb;
97 97
  PredMap pred;
98 98

	
99 99
  MinCostArbType mcarb_test(g, cost);
100 100
  const MinCostArbType& const_mcarb_test = mcarb_test;
101 101

	
102 102
  mcarb_test
103 103
    .arborescenceMap(arb)
104 104
    .predMap(pred)
105 105
    .run(s);
106 106

	
107 107
  mcarb_test.init();
108 108
  mcarb_test.addSource(s);
109 109
  mcarb_test.start();
110 110
  n = mcarb_test.processNextNode();
111 111
  b = const_mcarb_test.emptyQueue();
112 112
  i = const_mcarb_test.queueSize();
113
  
113

	
114 114
  c = const_mcarb_test.arborescenceCost();
115 115
  b = const_mcarb_test.arborescence(e);
116 116
  e = const_mcarb_test.pred(n);
117 117
  const MinCostArbType::ArborescenceMap &am =
118 118
    const_mcarb_test.arborescenceMap();
119 119
  const MinCostArbType::PredMap &pm =
120 120
    const_mcarb_test.predMap();
121 121
  b = const_mcarb_test.reached(n);
122 122
  b = const_mcarb_test.processed(n);
123
  
123

	
124 124
  i = const_mcarb_test.dualNum();
125 125
  c = const_mcarb_test.dualValue();
126 126
  i = const_mcarb_test.dualSize(i);
127 127
  c = const_mcarb_test.dualValue(i);
128
  
128

	
129 129
  ignore_unused_variable_warning(am);
130 130
  ignore_unused_variable_warning(pm);
131 131
}
132 132

	
133 133
int main() {
134 134
  typedef SmartDigraph Digraph;
135 135
  DIGRAPH_TYPEDEFS(Digraph);
136 136

	
137 137
  typedef Digraph::ArcMap<double> CostMap;
138 138

	
139 139
  Digraph digraph;
140 140
  CostMap cost(digraph);
141 141
  Node source;
142 142

	
143 143
  std::istringstream is(test_lgf);
144 144
  digraphReader(digraph, is).
145 145
    arcMap("cost", cost).
146 146
    node("source", source).run();
147 147

	
148 148
  MinCostArborescence<Digraph, CostMap> mca(digraph, cost);
149 149
  mca.run(source);
150 150

	
151 151
  vector<pair<double, set<Node> > > dualSolution(mca.dualNum());
152 152

	
153 153
  for (int i = 0; i < mca.dualNum(); ++i) {
154 154
    dualSolution[i].first = mca.dualValue(i);
155 155
    for (MinCostArborescence<Digraph, CostMap>::DualIt it(mca, i);
156 156
         it != INVALID; ++it) {
157 157
      dualSolution[i].second.insert(it);
158 158
    }
159 159
  }
160 160

	
161 161
  for (ArcIt it(digraph); it != INVALID; ++it) {
162 162
    if (mca.reached(digraph.source(it))) {
163 163
      double sum = 0.0;
164 164
      for (int i = 0; i < int(dualSolution.size()); ++i) {
165 165
        if (dualSolution[i].second.find(digraph.target(it))
166 166
            != dualSolution[i].second.end() &&
167 167
            dualSolution[i].second.find(digraph.source(it))
168 168
            == dualSolution[i].second.end()) {
169 169
          sum += dualSolution[i].first;
170 170
        }
171 171
      }
172 172
      if (mca.arborescence(it)) {
173 173
        check(sum == cost[it], "Invalid dual solution");
174 174
      }
175 175
      check(sum <= cost[it], "Invalid dual solution");
176 176
    }
177 177
  }
178 178

	
179 179

	
180 180
  check(mca.dualValue() == mca.arborescenceCost(), "Invalid dual solution");
181 181

	
182 182
  check(mca.reached(source), "Invalid arborescence");
183 183
  for (ArcIt a(digraph); a != INVALID; ++a) {
184 184
    check(!mca.reached(digraph.source(a)) ||
185 185
          mca.reached(digraph.target(a)), "Invalid arborescence");
186 186
  }
187 187

	
188 188
  for (NodeIt n(digraph); n != INVALID; ++n) {
189 189
    if (!mca.reached(n)) continue;
190 190
    int cnt = 0;
191 191
    for (InArcIt a(digraph, n); a != INVALID; ++a) {
192 192
      if (mca.arborescence(a)) {
193 193
        check(mca.pred(n) == a, "Invalid arborescence");
194 194
        ++cnt;
195 195
      }
196 196
    }
197 197
    check((n == source ? cnt == 0 : cnt == 1), "Invalid arborescence");
198 198
  }
199 199

	
200 200
  Digraph::ArcMap<bool> arborescence(digraph);
201 201
  check(mca.arborescenceCost() ==
202 202
        minCostArborescence(digraph, cost, source, arborescence),
203 203
        "Wrong result of the function interface");
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-2009
5
 * Copyright (C) 2003-2010
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 <limits>
22 22

	
23 23
#include <lemon/list_graph.h>
24 24
#include <lemon/lgf_reader.h>
25 25

	
26 26
#include <lemon/network_simplex.h>
27
#include <lemon/capacity_scaling.h>
28
#include <lemon/cost_scaling.h>
29
#include <lemon/cycle_canceling.h>
27 30

	
28 31
#include <lemon/concepts/digraph.h>
32
#include <lemon/concepts/heap.h>
29 33
#include <lemon/concept_check.h>
30 34

	
31 35
#include "test_tools.h"
32 36

	
33 37
using namespace lemon;
34 38

	
39
// Test networks
35 40
char test_lgf[] =
36 41
  "@nodes\n"
37 42
  "label  sup1 sup2 sup3 sup4 sup5 sup6\n"
38 43
  "    1    20   27    0   30   20   30\n"
39 44
  "    2    -4    0    0    0   -8   -3\n"
40 45
  "    3     0    0    0    0    0    0\n"
41 46
  "    4     0    0    0    0    0    0\n"
42 47
  "    5     9    0    0    0    6   11\n"
43 48
  "    6    -6    0    0    0   -5   -6\n"
44 49
  "    7     0    0    0    0    0    0\n"
45 50
  "    8     0    0    0    0    0    3\n"
46 51
  "    9     3    0    0    0    0    0\n"
47 52
  "   10    -2    0    0    0   -7   -2\n"
48 53
  "   11     0    0    0    0  -10    0\n"
49 54
  "   12   -20  -27    0  -30  -30  -20\n"
50
  "\n"                
55
  "\n"
51 56
  "@arcs\n"
52 57
  "       cost  cap low1 low2 low3\n"
53 58
  " 1  2    70   11    0    8    8\n"
54 59
  " 1  3   150    3    0    1    0\n"
55 60
  " 1  4    80   15    0    2    2\n"
56 61
  " 2  8    80   12    0    0    0\n"
57 62
  " 3  5   140    5    0    3    1\n"
58 63
  " 4  6    60   10    0    1    0\n"
59 64
  " 4  7    80    2    0    0    0\n"
60 65
  " 4  8   110    3    0    0    0\n"
61 66
  " 5  7    60   14    0    0    0\n"
62 67
  " 5 11   120   12    0    0    0\n"
63 68
  " 6  3     0    3    0    0    0\n"
64 69
  " 6  9   140    4    0    0    0\n"
65 70
  " 6 10    90    8    0    0    0\n"
66 71
  " 7  1    30    5    0    0   -5\n"
67 72
  " 8 12    60   16    0    4    3\n"
68 73
  " 9 12    50    6    0    0    0\n"
69 74
  "10 12    70   13    0    5    2\n"
70 75
  "10  2   100    7    0    0    0\n"
71 76
  "10  7    60   10    0    0   -3\n"
72 77
  "11 10    20   14    0    6  -20\n"
73 78
  "12 11    30   10    0    0  -10\n"
74 79
  "\n"
75 80
  "@attributes\n"
76 81
  "source 1\n"
77 82
  "target 12\n";
78 83

	
84
char test_neg1_lgf[] =
85
  "@nodes\n"
86
  "label   sup\n"
87
  "    1   100\n"
88
  "    2     0\n"
89
  "    3     0\n"
90
  "    4  -100\n"
91
  "    5     0\n"
92
  "    6     0\n"
93
  "    7     0\n"
94
  "@arcs\n"
95
  "      cost   low1   low2\n"
96
  "1 2    100      0      0\n"
97
  "1 3     30      0      0\n"
98
  "2 4     20      0      0\n"
99
  "3 4     80      0      0\n"
100
  "3 2     50      0      0\n"
101
  "5 3     10      0      0\n"
102
  "5 6     80      0   1000\n"
103
  "6 7     30      0  -1000\n"
104
  "7 5   -120      0      0\n";
105

	
106
char test_neg2_lgf[] =
107
  "@nodes\n"
108
  "label   sup\n"
109
  "    1   100\n"
110
  "    2  -300\n"
111
  "@arcs\n"
112
  "      cost\n"
113
  "1 2     -1\n";
114

	
115

	
116
// Test data
117
typedef ListDigraph Digraph;
118
DIGRAPH_TYPEDEFS(ListDigraph);
119

	
120
Digraph gr;
121
Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
122
Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
123
ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
124
Node v, w;
125

	
126
Digraph neg1_gr;
127
Digraph::ArcMap<int> neg1_c(neg1_gr), neg1_l1(neg1_gr), neg1_l2(neg1_gr);
128
ConstMap<Arc, int> neg1_u1(std::numeric_limits<int>::max()), neg1_u2(5000);
129
Digraph::NodeMap<int> neg1_s(neg1_gr);
130

	
131
Digraph neg2_gr;
132
Digraph::ArcMap<int> neg2_c(neg2_gr);
133
ConstMap<Arc, int> neg2_l(0), neg2_u(1000);
134
Digraph::NodeMap<int> neg2_s(neg2_gr);
135

	
79 136

	
80 137
enum SupplyType {
81 138
  EQ,
82 139
  GEQ,
83 140
  LEQ
84 141
};
85 142

	
143

	
86 144
// Check the interface of an MCF algorithm
87 145
template <typename GR, typename Value, typename Cost>
88 146
class McfClassConcept
89 147
{
90 148
public:
91 149

	
92 150
  template <typename MCF>
93 151
  struct Constraints {
94 152
    void constraints() {
95 153
      checkConcept<concepts::Digraph, GR>();
96
      
154

	
97 155
      const Constraints& me = *this;
98 156

	
99 157
      MCF mcf(me.g);
100 158
      const MCF& const_mcf = mcf;
101 159

	
102
      b = mcf.reset()
160
      b = mcf.reset().resetParams()
103 161
             .lowerMap(me.lower)
104 162
             .upperMap(me.upper)
105 163
             .costMap(me.cost)
106 164
             .supplyMap(me.sup)
107 165
             .stSupply(me.n, me.n, me.k)
108 166
             .run();
109 167

	
110 168
      c = const_mcf.totalCost();
111 169
      x = const_mcf.template totalCost<double>();
112 170
      v = const_mcf.flow(me.a);
113 171
      c = const_mcf.potential(me.n);
114 172
      const_mcf.flowMap(fm);
115 173
      const_mcf.potentialMap(pm);
116 174
    }
117 175

	
118 176
    typedef typename GR::Node Node;
119 177
    typedef typename GR::Arc Arc;
120 178
    typedef concepts::ReadMap<Node, Value> NM;
121 179
    typedef concepts::ReadMap<Arc, Value> VAM;
122 180
    typedef concepts::ReadMap<Arc, Cost> CAM;
123 181
    typedef concepts::WriteMap<Arc, Value> FlowMap;
124 182
    typedef concepts::WriteMap<Node, Cost> PotMap;
125
  
183

	
126 184
    GR g;
127 185
    VAM lower;
128 186
    VAM upper;
129 187
    CAM cost;
130 188
    NM sup;
131 189
    Node n;
132 190
    Arc a;
133 191
    Value k;
134 192

	
135 193
    FlowMap fm;
136 194
    PotMap pm;
137 195
    bool b;
138 196
    double x;
139 197
    typename MCF::Value v;
140 198
    typename MCF::Cost c;
141 199
  };
142 200

	
143 201
};
144 202

	
145 203

	
146 204
// Check the feasibility of the given flow (primal soluiton)
147 205
template < typename GR, typename LM, typename UM,
148 206
           typename SM, typename FM >
149 207
bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
150 208
                const SM& supply, const FM& flow,
151 209
                SupplyType type = EQ )
152 210
{
153 211
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
154 212

	
155 213
  for (ArcIt e(gr); e != INVALID; ++e) {
156 214
    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
157 215
  }
158 216

	
159 217
  for (NodeIt n(gr); n != INVALID; ++n) {
160 218
    typename SM::Value sum = 0;
161 219
    for (OutArcIt e(gr, n); e != INVALID; ++e)
162 220
      sum += flow[e];
163 221
    for (InArcIt e(gr, n); e != INVALID; ++e)
164 222
      sum -= flow[e];
165 223
    bool b = (type ==  EQ && sum == supply[n]) ||
166 224
             (type == GEQ && sum >= supply[n]) ||
167 225
             (type == LEQ && sum <= supply[n]);
168 226
    if (!b) return false;
169 227
  }
170 228

	
171 229
  return true;
172 230
}
173 231

	
174 232
// Check the feasibility of the given potentials (dual soluiton)
175 233
// using the "Complementary Slackness" optimality condition
176 234
template < typename GR, typename LM, typename UM,
177 235
           typename CM, typename SM, typename FM, typename PM >
178 236
bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
179
                     const CM& cost, const SM& supply, const FM& flow, 
237
                     const CM& cost, const SM& supply, const FM& flow,
180 238
                     const PM& pi, SupplyType type )
181 239
{
182 240
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
183 241

	
184 242
  bool opt = true;
185 243
  for (ArcIt e(gr); opt && e != INVALID; ++e) {
186 244
    typename CM::Value red_cost =
187 245
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
188 246
    opt = red_cost == 0 ||
189 247
          (red_cost > 0 && flow[e] == lower[e]) ||
190 248
          (red_cost < 0 && flow[e] == upper[e]);
191 249
  }
192
  
250

	
193 251
  for (NodeIt n(gr); opt && n != INVALID; ++n) {
194 252
    typename SM::Value sum = 0;
195 253
    for (OutArcIt e(gr, n); e != INVALID; ++e)
196 254
      sum += flow[e];
197 255
    for (InArcIt e(gr, n); e != INVALID; ++e)
198 256
      sum -= flow[e];
199 257
    if (type != LEQ) {
200 258
      opt = (pi[n] <= 0) && (sum == supply[n] || pi[n] == 0);
201 259
    } else {
202 260
      opt = (pi[n] >= 0) && (sum == supply[n] || pi[n] == 0);
203 261
    }
204 262
  }
205
  
263

	
206 264
  return opt;
207 265
}
208 266

	
209 267
// Check whether the dual cost is equal to the primal cost
210 268
template < typename GR, typename LM, typename UM,
211 269
           typename CM, typename SM, typename PM >
212 270
bool checkDualCost( const GR& gr, const LM& lower, const UM& upper,
213 271
                    const CM& cost, const SM& supply, const PM& pi,
214 272
                    typename CM::Value total )
215 273
{
216 274
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
217 275

	
218 276
  typename CM::Value dual_cost = 0;
219 277
  SM red_supply(gr);
220 278
  for (NodeIt n(gr); n != INVALID; ++n) {
221 279
    red_supply[n] = supply[n];
222 280
  }
223 281
  for (ArcIt a(gr); a != INVALID; ++a) {
224 282
    if (lower[a] != 0) {
225 283
      dual_cost += lower[a] * cost[a];
226 284
      red_supply[gr.source(a)] -= lower[a];
227 285
      red_supply[gr.target(a)] += lower[a];
228 286
    }
229 287
  }
230
  
288

	
231 289
  for (NodeIt n(gr); n != INVALID; ++n) {
232 290
    dual_cost -= red_supply[n] * pi[n];
233 291
  }
234 292
  for (ArcIt a(gr); a != INVALID; ++a) {
235 293
    typename CM::Value red_cost =
236 294
      cost[a] + pi[gr.source(a)] - pi[gr.target(a)];
237 295
    dual_cost -= (upper[a] - lower[a]) * std::max(-red_cost, 0);
238 296
  }
239
  
297

	
240 298
  return dual_cost == total;
241 299
}
242 300

	
243 301
// Run a minimum cost flow algorithm and check the results
244 302
template < typename MCF, typename GR,
245 303
           typename LM, typename UM,
246 304
           typename CM, typename SM,
247 305
           typename PT >
248 306
void checkMcf( const MCF& mcf, PT mcf_result,
249 307
               const GR& gr, const LM& lower, const UM& upper,
250 308
               const CM& cost, const SM& supply,
251 309
               PT result, bool optimal, typename CM::Value total,
252 310
               const std::string &test_id = "",
253 311
               SupplyType type = EQ )
254 312
{
255 313
  check(mcf_result == result, "Wrong result " + test_id);
256 314
  if (optimal) {
257 315
    typename GR::template ArcMap<typename SM::Value> flow(gr);
258 316
    typename GR::template NodeMap<typename CM::Value> pi(gr);
259 317
    mcf.flowMap(flow);
260 318
    mcf.potentialMap(pi);
261 319
    check(checkFlow(gr, lower, upper, supply, flow, type),
262 320
          "The flow is not feasible " + test_id);
263 321
    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
264 322
    check(checkPotential(gr, lower, upper, cost, supply, flow, pi, type),
265 323
          "Wrong potentials " + test_id);
266 324
    check(checkDualCost(gr, lower, upper, cost, supply, pi, total),
267 325
          "Wrong dual cost " + test_id);
268 326
  }
269 327
}
270 328

	
329
template < typename MCF, typename Param >
330
void runMcfGeqTests( Param param,
331
                     const std::string &test_str = "",
332
                     bool full_neg_cost_support = false )
333
{
334
  MCF mcf1(gr), mcf2(neg1_gr), mcf3(neg2_gr);
335

	
336
  // Basic tests
337
  mcf1.upperMap(u).costMap(c).supplyMap(s1);
338
  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s1,
339
           mcf1.OPTIMAL, true,     5240, test_str + "-1");
340
  mcf1.stSupply(v, w, 27);
341
  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s2,
342
           mcf1.OPTIMAL, true,     7620, test_str + "-2");
343
  mcf1.lowerMap(l2).supplyMap(s1);
344
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s1,
345
           mcf1.OPTIMAL, true,     5970, test_str + "-3");
346
  mcf1.stSupply(v, w, 27);
347
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s2,
348
           mcf1.OPTIMAL, true,     8010, test_str + "-4");
349
  mcf1.resetParams().supplyMap(s1);
350
  checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s1,
351
           mcf1.OPTIMAL, true,       74, test_str + "-5");
352
  mcf1.lowerMap(l2).stSupply(v, w, 27);
353
  checkMcf(mcf1, mcf1.run(param), gr, l2, cu, cc, s2,
354
           mcf1.OPTIMAL, true,       94, test_str + "-6");
355
  mcf1.reset();
356
  checkMcf(mcf1, mcf1.run(param), gr, l1, cu, cc, s3,
357
           mcf1.OPTIMAL, true,        0, test_str + "-7");
358
  mcf1.lowerMap(l2).upperMap(u);
359
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, cc, s3,
360
           mcf1.INFEASIBLE, false,    0, test_str + "-8");
361
  mcf1.lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
362
  checkMcf(mcf1, mcf1.run(param), gr, l3, u, c, s4,
363
           mcf1.OPTIMAL, true,     6360, test_str + "-9");
364

	
365
  // Tests for the GEQ form
366
  mcf1.resetParams().upperMap(u).costMap(c).supplyMap(s5);
367
  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s5,
368
           mcf1.OPTIMAL, true,     3530, test_str + "-10", GEQ);
369
  mcf1.lowerMap(l2);
370
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
371
           mcf1.OPTIMAL, true,     4540, test_str + "-11", GEQ);
372
  mcf1.supplyMap(s6);
373
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
374
           mcf1.INFEASIBLE, false,    0, test_str + "-12", GEQ);
375

	
376
  // Tests with negative costs
377
  mcf2.lowerMap(neg1_l1).costMap(neg1_c).supplyMap(neg1_s);
378
  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u1, neg1_c, neg1_s,
379
           mcf2.UNBOUNDED, false,     0, test_str + "-13");
380
  mcf2.upperMap(neg1_u2);
381
  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l1, neg1_u2, neg1_c, neg1_s,
382
           mcf2.OPTIMAL, true,   -40000, test_str + "-14");
383
  mcf2.resetParams().lowerMap(neg1_l2).costMap(neg1_c).supplyMap(neg1_s);
384
  checkMcf(mcf2, mcf2.run(param), neg1_gr, neg1_l2, neg1_u1, neg1_c, neg1_s,
385
           mcf2.UNBOUNDED, false,     0, test_str + "-15");
386

	
387
  mcf3.costMap(neg2_c).supplyMap(neg2_s);
388
  if (full_neg_cost_support) {
389
    checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
390
             mcf3.OPTIMAL, true,   -300, test_str + "-16", GEQ);
391
  } else {
392
    checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
393
             mcf3.UNBOUNDED, false,   0, test_str + "-17", GEQ);
394
  }
395
  mcf3.upperMap(neg2_u);
396
  checkMcf(mcf3, mcf3.run(param), neg2_gr, neg2_l, neg2_u, neg2_c, neg2_s,
397
           mcf3.OPTIMAL, true,     -300, test_str + "-18", GEQ);
398
}
399

	
400
template < typename MCF, typename Param >
401
void runMcfLeqTests( Param param,
402
                     const std::string &test_str = "" )
403
{
404
  // Tests for the LEQ form
405
  MCF mcf1(gr);
406
  mcf1.supplyType(mcf1.LEQ);
407
  mcf1.upperMap(u).costMap(c).supplyMap(s6);
408
  checkMcf(mcf1, mcf1.run(param), gr, l1, u, c, s6,
409
           mcf1.OPTIMAL, true,   5080, test_str + "-19", LEQ);
410
  mcf1.lowerMap(l2);
411
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s6,
412
           mcf1.OPTIMAL, true,   5930, test_str + "-20", LEQ);
413
  mcf1.supplyMap(s5);
414
  checkMcf(mcf1, mcf1.run(param), gr, l2, u, c, s5,
415
           mcf1.INFEASIBLE, false,  0, test_str + "-21", LEQ);
416
}
417

	
418

	
271 419
int main()
272 420
{
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

	
421
  // Read the test networks
295 422
  std::istringstream input(test_lgf);
296 423
  DigraphReader<Digraph>(gr, input)
297 424
    .arcMap("cost", c)
298 425
    .arcMap("cap", u)
299 426
    .arcMap("low1", l1)
300 427
    .arcMap("low2", l2)
301 428
    .arcMap("low3", l3)
302 429
    .nodeMap("sup1", s1)
303 430
    .nodeMap("sup2", s2)
304 431
    .nodeMap("sup3", s3)
305 432
    .nodeMap("sup4", s4)
306 433
    .nodeMap("sup5", s5)
307 434
    .nodeMap("sup6", s6)
308 435
    .node("source", v)
309 436
    .node("target", w)
310 437
    .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 438

	
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;
439
  std::istringstream neg_inp1(test_neg1_lgf);
440
  DigraphReader<Digraph>(neg1_gr, neg_inp1)
441
    .arcMap("cost", neg1_c)
442
    .arcMap("low1", neg1_l1)
443
    .arcMap("low2", neg1_l2)
444
    .nodeMap("sup", neg1_s)
445
    .run();
361 446

	
447
  std::istringstream neg_inp2(test_neg2_lgf);
448
  DigraphReader<Digraph>(neg2_gr, neg_inp2)
449
    .arcMap("cost", neg2_c)
450
    .nodeMap("sup", neg2_s)
451
    .run();
362 452

	
363
  // A. Test NetworkSimplex with the default pivot rule
453
  // Check the interface of NetworkSimplex
364 454
  {
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);
455
    typedef concepts::Digraph GR;
456
    checkConcept< McfClassConcept<GR, int, int>,
457
                  NetworkSimplex<GR> >();
458
    checkConcept< McfClassConcept<GR, double, double>,
459
                  NetworkSimplex<GR, double> >();
460
    checkConcept< McfClassConcept<GR, int, double>,
461
                  NetworkSimplex<GR, int, double> >();
430 462
  }
431 463

	
432
  // B. Test NetworkSimplex with each pivot rule
464
  // Check the interface of CapacityScaling
433 465
  {
434
    NetworkSimplex<Digraph> mcf(gr);
435
    mcf.supplyMap(s1).costMap(c).upperMap(u).lowerMap(l2);
466
    typedef concepts::Digraph GR;
467
    checkConcept< McfClassConcept<GR, int, int>,
468
                  CapacityScaling<GR> >();
469
    checkConcept< McfClassConcept<GR, double, double>,
470
                  CapacityScaling<GR, double> >();
471
    checkConcept< McfClassConcept<GR, int, double>,
472
                  CapacityScaling<GR, int, double> >();
473
    typedef CapacityScaling<GR>::
474
      SetHeap<concepts::Heap<int, RangeMap<int> > >::Create CAS;
475
    checkConcept< McfClassConcept<GR, int, int>, CAS >();
476
  }
436 477

	
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");
478
  // Check the interface of CostScaling
479
  {
480
    typedef concepts::Digraph GR;
481
    checkConcept< McfClassConcept<GR, int, int>,
482
                  CostScaling<GR> >();
483
    checkConcept< McfClassConcept<GR, double, double>,
484
                  CostScaling<GR, double> >();
485
    checkConcept< McfClassConcept<GR, int, double>,
486
                  CostScaling<GR, int, double> >();
487
    typedef CostScaling<GR>::
488
      SetLargeCost<double>::Create COS;
489
    checkConcept< McfClassConcept<GR, int, int>, COS >();
490
  }
491

	
492
  // Check the interface of CycleCanceling
493
  {
494
    typedef concepts::Digraph GR;
495
    checkConcept< McfClassConcept<GR, int, int>,
496
                  CycleCanceling<GR> >();
497
    checkConcept< McfClassConcept<GR, double, double>,
498
                  CycleCanceling<GR, double> >();
499
    checkConcept< McfClassConcept<GR, int, double>,
500
                  CycleCanceling<GR, int, double> >();
501
  }
502

	
503
  // Test NetworkSimplex
504
  {
505
    typedef NetworkSimplex<Digraph> MCF;
506
    runMcfGeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE", true);
507
    runMcfLeqTests<MCF>(MCF::FIRST_ELIGIBLE, "NS-FE");
508
    runMcfGeqTests<MCF>(MCF::BEST_ELIGIBLE,  "NS-BE", true);
509
    runMcfLeqTests<MCF>(MCF::BEST_ELIGIBLE,  "NS-BE");
510
    runMcfGeqTests<MCF>(MCF::BLOCK_SEARCH,   "NS-BS", true);
511
    runMcfLeqTests<MCF>(MCF::BLOCK_SEARCH,   "NS-BS");
512
    runMcfGeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL", true);
513
    runMcfLeqTests<MCF>(MCF::CANDIDATE_LIST, "NS-CL");
514
    runMcfGeqTests<MCF>(MCF::ALTERING_LIST,  "NS-AL", true);
515
    runMcfLeqTests<MCF>(MCF::ALTERING_LIST,  "NS-AL");
516
  }
517

	
518
  // Test CapacityScaling
519
  {
520
    typedef CapacityScaling<Digraph> MCF;
521
    runMcfGeqTests<MCF>(0, "SSP");
522
    runMcfGeqTests<MCF>(2, "CAS");
523
  }
524

	
525
  // Test CostScaling
526
  {
527
    typedef CostScaling<Digraph> MCF;
528
    runMcfGeqTests<MCF>(MCF::PUSH, "COS-PR");
529
    runMcfGeqTests<MCF>(MCF::AUGMENT, "COS-AR");
530
    runMcfGeqTests<MCF>(MCF::PARTIAL_AUGMENT, "COS-PAR");
531
  }
532

	
533
  // Test CycleCanceling
534
  {
535
    typedef CycleCanceling<Digraph> MCF;
536
    runMcfGeqTests<MCF>(MCF::SIMPLE_CYCLE_CANCELING, "SCC");
537
    runMcfGeqTests<MCF>(MCF::MINIMUM_MEAN_CYCLE_CANCELING, "MMCC");
538
    runMcfGeqTests<MCF>(MCF::CANCEL_AND_TIGHTEN, "CAT");
447 539
  }
448 540

	
449 541
  return 0;
450 542
}
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-2009
5
 * Copyright (C) 2003-2010
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 "test_tools.h"
22 22
#include <lemon/smart_graph.h>
23 23
#include <lemon/preflow.h>
24 24
#include <lemon/concepts/digraph.h>
25 25
#include <lemon/concepts/maps.h>
26 26
#include <lemon/lgf_reader.h>
27 27
#include <lemon/elevator.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
  "7\n"
42 42
  "8\n"
43 43
  "9\n"
44 44
  "@arcs\n"
45 45
  "    label capacity\n"
46 46
  "0 1 0     20\n"
47 47
  "0 2 1     0\n"
48 48
  "1 1 2     3\n"
49 49
  "1 2 3     8\n"
50 50
  "1 3 4     8\n"
51 51
  "2 5 5     5\n"
52 52
  "3 2 6     5\n"
53 53
  "3 5 7     5\n"
54 54
  "3 6 8     5\n"
55 55
  "4 3 9     3\n"
56 56
  "5 7 10    3\n"
57 57
  "5 6 11    10\n"
58 58
  "5 8 12    10\n"
59 59
  "6 8 13    8\n"
60 60
  "8 9 14    20\n"
61 61
  "8 1 15    5\n"
62 62
  "9 5 16    5\n"
63 63
  "@attributes\n"
64 64
  "source 1\n"
65 65
  "target 8\n";
66 66

	
67 67
void checkPreflowCompile()
68 68
{
69 69
  typedef int VType;
70 70
  typedef concepts::Digraph Digraph;
71 71

	
72 72
  typedef Digraph::Node Node;
73 73
  typedef Digraph::Arc Arc;
74 74
  typedef concepts::ReadMap<Arc,VType> CapMap;
75 75
  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
76 76
  typedef concepts::WriteMap<Node,bool> CutMap;
77 77

	
78 78
  typedef Elevator<Digraph, Digraph::Node> Elev;
79 79
  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
80 80

	
81 81
  Digraph g;
82 82
  Node n;
83 83
  Arc e;
84 84
  CapMap cap;
85 85
  FlowMap flow;
86 86
  CutMap cut;
87 87
  VType v;
88 88
  bool b;
89 89

	
90 90
  typedef Preflow<Digraph, CapMap>
91 91
            ::SetFlowMap<FlowMap>
92 92
            ::SetElevator<Elev>
93 93
            ::SetStandardElevator<LinkedElev>
94 94
            ::Create PreflowType;
95 95
  PreflowType preflow_test(g, cap, n, n);
96 96
  const PreflowType& const_preflow_test = preflow_test;
97 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

	
98 103
  preflow_test
99 104
    .capacityMap(cap)
100 105
    .flowMap(flow)
101 106
    .source(n)
102 107
    .target(n);
103 108

	
104 109
  preflow_test.init();
105 110
  preflow_test.init(cap);
106 111
  preflow_test.startFirstPhase();
107 112
  preflow_test.startSecondPhase();
108 113
  preflow_test.run();
109 114
  preflow_test.runMinCut();
110 115

	
111 116
  v = const_preflow_test.flowValue();
112 117
  v = const_preflow_test.flow(e);
113 118
  const FlowMap& fm = const_preflow_test.flowMap();
114 119
  b = const_preflow_test.minCut(n);
115 120
  const_preflow_test.minCutMap(cut);
116
  
121

	
117 122
  ignore_unused_variable_warning(fm);
118 123
}
119 124

	
120 125
int cutValue (const SmartDigraph& g,
121 126
              const SmartDigraph::NodeMap<bool>& cut,
122 127
              const SmartDigraph::ArcMap<int>& cap) {
123 128

	
124 129
  int c=0;
125 130
  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
126 131
    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
127 132
  }
128 133
  return c;
129 134
}
130 135

	
131 136
bool checkFlow(const SmartDigraph& g,
132 137
               const SmartDigraph::ArcMap<int>& flow,
133 138
               const SmartDigraph::ArcMap<int>& cap,
134 139
               SmartDigraph::Node s, SmartDigraph::Node t) {
135 140

	
136 141
  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
137 142
    if (flow[e] < 0 || flow[e] > cap[e]) return false;
138 143
  }
139 144

	
140 145
  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
141 146
    if (n == s || n == t) continue;
142 147
    int sum = 0;
143 148
    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
144 149
      sum += flow[e];
145 150
    }
146 151
    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
147 152
      sum -= flow[e];
148 153
    }
149 154
    if (sum != 0) return false;
150 155
  }
151 156
  return true;
152 157
}
153 158

	
154 159
void initFlowTest()
155 160
{
156 161
  DIGRAPH_TYPEDEFS(SmartDigraph);
157 162
  
158 163
  SmartDigraph g;
159 164
  SmartDigraph::ArcMap<int> cap(g),iflow(g);
160 165
  Node s=g.addNode(); Node t=g.addNode();
161 166
  Node n1=g.addNode(); Node n2=g.addNode();
162 167
  Arc a;
163 168
  a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
164 169
  a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
165 170
  a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
166 171

	
167 172
  Preflow<SmartDigraph> pre(g,cap,s,t);
168 173
  pre.init(iflow);
169 174
  pre.startFirstPhase();
170 175
  check(pre.flowValue() == 10, "The incorrect max flow value.");
171 176
  check(pre.minCut(s), "Wrong min cut (Node s).");
172 177
  check(pre.minCut(n1), "Wrong min cut (Node n1).");
173 178
  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
174 179
  check(!pre.minCut(t), "Wrong min cut (Node t).");
175 180
}
176 181

	
177 182

	
178 183
int main() {
179 184

	
180 185
  typedef SmartDigraph Digraph;
181 186

	
182 187
  typedef Digraph::Node Node;
183 188
  typedef Digraph::NodeIt NodeIt;
184 189
  typedef Digraph::ArcIt ArcIt;
185 190
  typedef Digraph::ArcMap<int> CapMap;
186 191
  typedef Digraph::ArcMap<int> FlowMap;
187 192
  typedef Digraph::NodeMap<bool> CutMap;
188 193

	
189 194
  typedef Preflow<Digraph, CapMap> PType;
190 195

	
191 196
  Digraph g;
192 197
  Node s, t;
193 198
  CapMap cap(g);
194 199
  std::istringstream input(test_lgf);
195 200
  DigraphReader<Digraph>(g,input).
196 201
    arcMap("capacity", cap).
197 202
    node("source",s).
198 203
    node("target",t).
199 204
    run();
200 205

	
201 206
  PType preflow_test(g, cap, s, t);
202 207
  preflow_test.run();
203 208

	
204 209
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
205 210
        "The flow is not feasible.");
206 211

	
207 212
  CutMap min_cut(g);
208 213
  preflow_test.minCutMap(min_cut);
209 214
  int min_cut_value=cutValue(g,min_cut,cap);
210 215

	
211 216
  check(preflow_test.flowValue() == min_cut_value,
212 217
        "The max flow value is not equal to the three min cut values.");
213 218

	
214 219
  FlowMap flow(g);
215 220
  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
216 221

	
217 222
  int flow_value=preflow_test.flowValue();
218 223

	
219 224
  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
220 225
  preflow_test.init(flow);
221 226
  preflow_test.startFirstPhase();
222 227

	
223 228
  CutMap min_cut1(g);
224 229
  preflow_test.minCutMap(min_cut1);
225 230
  min_cut_value=cutValue(g,min_cut1,cap);
226 231

	
227 232
  check(preflow_test.flowValue() == min_cut_value &&
228 233
        min_cut_value == 2*flow_value,
229 234
        "The max flow value or the min cut value is wrong.");
230 235

	
231 236
  preflow_test.startSecondPhase();
232 237

	
233 238
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
234 239
        "The flow is not feasible.");
235 240

	
236 241
  CutMap min_cut2(g);
237 242
  preflow_test.minCutMap(min_cut2);
238 243
  min_cut_value=cutValue(g,min_cut2,cap);
239 244

	
240 245
  check(preflow_test.flowValue() == min_cut_value &&
241 246
        min_cut_value == 2*flow_value,
242 247
        "The max flow value or the three min cut values were not doubled");
243 248

	
244 249

	
245 250
  preflow_test.flowMap(flow);
246 251

	
247 252
  NodeIt tmp1(g,s);
248 253
  ++tmp1;
249 254
  if ( tmp1 != INVALID ) s=tmp1;
250 255

	
251 256
  NodeIt tmp2(g,t);
252 257
  ++tmp2;
253 258
  if ( tmp2 != INVALID ) t=tmp2;
254 259

	
255 260
  preflow_test.source(s);
256 261
  preflow_test.target(t);
257 262

	
258 263
  preflow_test.run();
259 264

	
260 265
  CutMap min_cut3(g);
261 266
  preflow_test.minCutMap(min_cut3);
262 267
  min_cut_value=cutValue(g,min_cut3,cap);
263 268

	
264 269

	
265 270
  check(preflow_test.flowValue() == min_cut_value,
266 271
        "The max flow value or the three min cut values are incorrect.");
267 272

	
268 273
  initFlowTest();
269 274
  
270 275
  return 0;
271 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-2009
5
 * Copyright (C) 2003-2010
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/list_graph.h>
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/path.h>
24 24
#include <lemon/suurballe.h>
25 25
#include <lemon/concepts/digraph.h>
26
#include <lemon/concepts/heap.h>
26 27

	
27 28
#include "test_tools.h"
28 29

	
29 30
using namespace lemon;
30 31

	
31 32
char test_lgf[] =
32 33
  "@nodes\n"
33 34
  "label\n"
34 35
  "1\n"
35 36
  "2\n"
36 37
  "3\n"
37 38
  "4\n"
38 39
  "5\n"
39 40
  "6\n"
40 41
  "7\n"
41 42
  "8\n"
42 43
  "9\n"
43 44
  "10\n"
44 45
  "11\n"
45 46
  "12\n"
46 47
  "@arcs\n"
47 48
  "      length\n"
48 49
  " 1  2  70\n"
49 50
  " 1  3 150\n"
50 51
  " 1  4  80\n"
51 52
  " 2  8  80\n"
52 53
  " 3  5 140\n"
53 54
  " 4  6  60\n"
54 55
  " 4  7  80\n"
55 56
  " 4  8 110\n"
56 57
  " 5  7  60\n"
57 58
  " 5 11 120\n"
58 59
  " 6  3   0\n"
59 60
  " 6  9 140\n"
60 61
  " 6 10  90\n"
61 62
  " 7  1  30\n"
62 63
  " 8 12  60\n"
63 64
  " 9 12  50\n"
64 65
  "10 12  70\n"
65 66
  "10  2 100\n"
66 67
  "10  7  60\n"
67 68
  "11 10  20\n"
68 69
  "12 11  30\n"
69 70
  "@attributes\n"
70 71
  "source  1\n"
71 72
  "target 12\n"
72 73
  "@end\n";
73 74

	
74 75
// Check the interface of Suurballe
75 76
void checkSuurballeCompile()
76 77
{
77 78
  typedef int VType;
78 79
  typedef concepts::Digraph Digraph;
79 80

	
80 81
  typedef Digraph::Node Node;
81 82
  typedef Digraph::Arc Arc;
82 83
  typedef concepts::ReadMap<Arc, VType> LengthMap;
83
  
84
  typedef Suurballe<Digraph, LengthMap> SuurballeType;
84

	
85
  typedef Suurballe<Digraph, LengthMap> ST;
86
  typedef Suurballe<Digraph, LengthMap>
87
    ::SetFlowMap<ST::FlowMap>
88
    ::SetPotentialMap<ST::PotentialMap>
89
    ::SetPath<SimplePath<Digraph> >
90
    ::SetHeap<concepts::Heap<VType, Digraph::NodeMap<int> > >
91
    ::Create SuurballeType;
85 92

	
86 93
  Digraph g;
87 94
  Node n;
88 95
  Arc e;
89 96
  LengthMap len;
90 97
  SuurballeType::FlowMap flow(g);
91 98
  SuurballeType::PotentialMap pi(g);
92 99

	
93 100
  SuurballeType suurb_test(g, len);
94 101
  const SuurballeType& const_suurb_test = suurb_test;
95 102

	
96 103
  suurb_test
97 104
    .flowMap(flow)
98 105
    .potentialMap(pi);
99 106

	
100 107
  int k;
101 108
  k = suurb_test.run(n, n);
102 109
  k = suurb_test.run(n, n, k);
103 110
  suurb_test.init(n);
111
  suurb_test.fullInit(n);
112
  suurb_test.start(n);
113
  suurb_test.start(n, k);
104 114
  k = suurb_test.findFlow(n);
105 115
  k = suurb_test.findFlow(n, k);
106 116
  suurb_test.findPaths();
107
  
117

	
108 118
  int f;
109 119
  VType c;
110 120
  c = const_suurb_test.totalLength();
111 121
  f = const_suurb_test.flow(e);
112 122
  const SuurballeType::FlowMap& fm =
113 123
    const_suurb_test.flowMap();
114 124
  c = const_suurb_test.potential(n);
115 125
  const SuurballeType::PotentialMap& pm =
116 126
    const_suurb_test.potentialMap();
117 127
  k = const_suurb_test.pathNum();
118 128
  Path<Digraph> p = const_suurb_test.path(k);
119
  
129

	
120 130
  ignore_unused_variable_warning(fm);
121 131
  ignore_unused_variable_warning(pm);
122 132
}
123 133

	
124 134
// Check the feasibility of the flow
125 135
template <typename Digraph, typename FlowMap>
126 136
bool checkFlow( const Digraph& gr, const FlowMap& flow,
127 137
                typename Digraph::Node s, typename Digraph::Node t,
128 138
                int value )
129 139
{
130 140
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
131 141
  for (ArcIt e(gr); e != INVALID; ++e)
132 142
    if (!(flow[e] == 0 || flow[e] == 1)) return false;
133 143

	
134 144
  for (NodeIt n(gr); n != INVALID; ++n) {
135 145
    int sum = 0;
136 146
    for (OutArcIt e(gr, n); e != INVALID; ++e)
137 147
      sum += flow[e];
138 148
    for (InArcIt e(gr, n); e != INVALID; ++e)
139 149
      sum -= flow[e];
140 150
    if (n == s && sum != value) return false;
141 151
    if (n == t && sum != -value) return false;
142 152
    if (n != s && n != t && sum != 0) return false;
143 153
  }
144 154

	
145 155
  return true;
146 156
}
147 157

	
148 158
// Check the optimalitiy of the flow
149 159
template < typename Digraph, typename CostMap,
150 160
           typename FlowMap, typename PotentialMap >
151 161
bool checkOptimality( const Digraph& gr, const CostMap& cost,
152 162
                      const FlowMap& flow, const PotentialMap& pi )
153 163
{
154 164
  // Check the "Complementary Slackness" optimality condition
155 165
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
156 166
  bool opt = true;
157 167
  for (ArcIt e(gr); e != INVALID; ++e) {
158 168
    typename CostMap::Value red_cost =
159 169
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
160 170
    opt = (flow[e] == 0 && red_cost >= 0) ||
161 171
          (flow[e] == 1 && red_cost <= 0);
162 172
    if (!opt) break;
163 173
  }
164 174
  return opt;
165 175
}
166 176

	
167 177
// Check a path
168 178
template <typename Digraph, typename Path>
169 179
bool checkPath( const Digraph& gr, const Path& path,
170 180
                typename Digraph::Node s, typename Digraph::Node t)
171 181
{
172 182
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
173 183
  Node n = s;
174 184
  for (int i = 0; i < path.length(); ++i) {
175 185
    if (gr.source(path.nth(i)) != n) return false;
176 186
    n = gr.target(path.nth(i));
177 187
  }
178 188
  return n == t;
179 189
}
180 190

	
181 191

	
182 192
int main()
183 193
{
184 194
  DIGRAPH_TYPEDEFS(ListDigraph);
185 195

	
186 196
  // Read the test digraph
187 197
  ListDigraph digraph;
188 198
  ListDigraph::ArcMap<int> length(digraph);
189 199
  Node s, t;
190 200

	
191 201
  std::istringstream input(test_lgf);
192 202
  DigraphReader<ListDigraph>(digraph, input).
193 203
    arcMap("length", length).
194 204
    node("source", s).
195 205
    node("target", t).
196 206
    run();
197 207

	
198
  // Find 2 paths
208
  // Check run()
199 209
  {
200 210
    Suurballe<ListDigraph> suurballe(digraph, length);
211

	
212
    // Find 2 paths
201 213
    check(suurballe.run(s, t) == 2, "Wrong number of paths");
202 214
    check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
203 215
          "The flow is not feasible");
204 216
    check(suurballe.totalLength() == 510, "The flow is not optimal");
205 217
    check(checkOptimality(digraph, length, suurballe.flowMap(),
206 218
                          suurballe.potentialMap()),
207 219
          "Wrong potentials");
208 220
    for (int i = 0; i < suurballe.pathNum(); ++i)
209 221
      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
210
  }
211 222

	
212
  // Find 3 paths
213
  {
214
    Suurballe<ListDigraph> suurballe(digraph, length);
223
    // Find 3 paths
215 224
    check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
216 225
    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
217 226
          "The flow is not feasible");
218 227
    check(suurballe.totalLength() == 1040, "The flow is not optimal");
219 228
    check(checkOptimality(digraph, length, suurballe.flowMap(),
220 229
                          suurballe.potentialMap()),
221 230
          "Wrong potentials");
222 231
    for (int i = 0; i < suurballe.pathNum(); ++i)
223 232
      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
224
  }
225 233

	
226
  // Find 5 paths (only 3 can be found)
227
  {
228
    Suurballe<ListDigraph> suurballe(digraph, length);
234
    // Find 5 paths (only 3 can be found)
229 235
    check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
230 236
    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
231 237
          "The flow is not feasible");
232 238
    check(suurballe.totalLength() == 1040, "The flow is not optimal");
233 239
    check(checkOptimality(digraph, length, suurballe.flowMap(),
234 240
                          suurballe.potentialMap()),
235 241
          "Wrong potentials");
236 242
    for (int i = 0; i < suurballe.pathNum(); ++i)
237 243
      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
238 244
  }
239 245

	
246
  // Check fullInit() + start()
247
  {
248
    Suurballe<ListDigraph> suurballe(digraph, length);
249
    suurballe.fullInit(s);
250

	
251
    // Find 2 paths
252
    check(suurballe.start(t) == 2, "Wrong number of paths");
253
    check(suurballe.totalLength() == 510, "The flow is not optimal");
254

	
255
    // Find 3 paths
256
    check(suurballe.start(t, 3) == 3, "Wrong number of paths");
257
    check(suurballe.totalLength() == 1040, "The flow is not optimal");
258

	
259
    // Find 5 paths (only 3 can be found)
260
    check(suurballe.start(t, 5) == 3, "Wrong number of paths");
261
    check(suurballe.totalLength() == 1040, "The flow is not optimal");
262
  }
263

	
240 264
  return 0;
241 265
}
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-2009
5
 * Copyright (C) 2003-2010
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-2009
5
 * Copyright (C) 2003-2010
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 tools
20 20
///\file
21 21
///\brief DIMACS problem solver.
22 22
///
23 23
/// This program solves various problems given in DIMACS format.
24 24
///
25 25
/// See
26 26
/// \code
27 27
///   dimacs-solver --help
28 28
/// \endcode
29 29
/// for more info on usage.
30 30

	
31 31
#include <iostream>
32 32
#include <fstream>
33 33
#include <cstring>
34 34

	
35 35
#include <lemon/smart_graph.h>
36 36
#include <lemon/dimacs.h>
37 37
#include <lemon/lgf_writer.h>
38 38
#include <lemon/time_measure.h>
39 39

	
40 40
#include <lemon/arg_parser.h>
41 41
#include <lemon/error.h>
42 42

	
43 43
#include <lemon/dijkstra.h>
44 44
#include <lemon/preflow.h>
45 45
#include <lemon/matching.h>
46 46
#include <lemon/network_simplex.h>
47 47

	
48 48
using namespace lemon;
49 49
typedef SmartDigraph Digraph;
50 50
DIGRAPH_TYPEDEFS(Digraph);
51 51
typedef SmartGraph Graph;
52 52

	
53 53
template<class Value>
54 54
void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
55 55
              DimacsDescriptor &desc)
56 56
{
57 57
  bool report = !ap.given("q");
58 58
  Digraph g;
59 59
  Node s;
60 60
  Digraph::ArcMap<Value> len(g);
61 61
  Timer t;
62 62
  t.restart();
63 63
  readDimacsSp(is, g, len, s, desc);
64 64
  if(report) std::cerr << "Read the file: " << t << '\n';
65 65
  t.restart();
66 66
  Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
67 67
  if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
68 68
  t.restart();
69 69
  dij.run(s);
70 70
  if(report) std::cerr << "Run Dijkstra: " << t << '\n';
71 71
}
72 72

	
73 73
template<class Value>
74 74
void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
75 75
               Value infty, DimacsDescriptor &desc)
76 76
{
77 77
  bool report = !ap.given("q");
78 78
  Digraph g;
79 79
  Node s,t;
80 80
  Digraph::ArcMap<Value> cap(g);
81 81
  Timer ti;
82 82
  ti.restart();
83 83
  readDimacsMax(is, g, cap, s, t, infty, desc);
84 84
  if(report) std::cerr << "Read the file: " << ti << '\n';
85 85
  ti.restart();
86 86
  Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
87 87
  if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
88 88
  ti.restart();
89 89
  pre.run();
90 90
  if(report) std::cerr << "Run Preflow: " << ti << '\n';
91
  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';  
91
  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';
92 92
}
93 93

	
94
template<class Value>
94
template<class Value, class LargeValue>
95 95
void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
96 96
               Value infty, DimacsDescriptor &desc)
97 97
{
98 98
  bool report = !ap.given("q");
99 99
  Digraph g;
100 100
  Digraph::ArcMap<Value> lower(g), cap(g), cost(g);
101 101
  Digraph::NodeMap<Value> sup(g);
102 102
  Timer ti;
103 103

	
104 104
  ti.restart();
105 105
  readDimacsMin(is, g, lower, cap, cost, sup, infty, desc);
106 106
  ti.stop();
107 107
  Value sum_sup = 0;
108 108
  for (Digraph::NodeIt n(g); n != INVALID; ++n) {
109 109
    sum_sup += sup[n];
110 110
  }
111 111
  if (report) {
112 112
    std::cerr << "Sum of supply values: " << sum_sup << "\n";
113 113
    if (sum_sup <= 0)
114 114
      std::cerr << "GEQ supply contraints are used for NetworkSimplex\n\n";
115 115
    else
116 116
      std::cerr << "LEQ supply contraints are used for NetworkSimplex\n\n";
117 117
  }
118 118
  if (report) std::cerr << "Read the file: " << ti << '\n';
119 119

	
120 120
  ti.restart();
121 121
  NetworkSimplex<Digraph, Value> ns(g);
122 122
  ns.lowerMap(lower).upperMap(cap).costMap(cost).supplyMap(sup);
123 123
  if (sum_sup > 0) ns.supplyType(ns.LEQ);
124 124
  if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n';
125 125
  ti.restart();
126 126
  bool res = ns.run();
127 127
  if (report) {
128 128
    std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
129 129
    std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n';
130
    if (res) std::cerr << "Min flow cost: " << ns.totalCost() << '\n';
130
    if (res) std::cerr << "Min flow cost: "
131
                       << ns.template totalCost<LargeValue>() << '\n';
131 132
  }
132 133
}
133 134

	
134 135
void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
135 136
              DimacsDescriptor &desc)
136 137
{
137 138
  bool report = !ap.given("q");
138 139
  Graph g;
139 140
  Timer ti;
140 141
  ti.restart();
141 142
  readDimacsMat(is, g, desc);
142 143
  if(report) std::cerr << "Read the file: " << ti << '\n';
143 144
  ti.restart();
144 145
  MaxMatching<Graph> mat(g);
145 146
  if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
146 147
  ti.restart();
147 148
  mat.run();
148 149
  if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
149 150
  if(report) std::cerr << "\nCardinality of max matching: "
150
                       << mat.matchingSize() << '\n';  
151
                       << mat.matchingSize() << '\n';
151 152
}
152 153

	
153 154

	
154
template<class Value>
155
template<class Value, class LargeValue>
155 156
void solve(ArgParser &ap, std::istream &is, std::ostream &os,
156 157
           DimacsDescriptor &desc)
157 158
{
158 159
  std::stringstream iss(static_cast<std::string>(ap["infcap"]));
159 160
  Value infty;
160 161
  iss >> infty;
161 162
  if(iss.fail())
162 163
    {
163 164
      std::cerr << "Cannot interpret '"
164 165
                << static_cast<std::string>(ap["infcap"]) << "' as infinite"
165 166
                << std::endl;
166 167
      exit(1);
167 168
    }
168
  
169

	
169 170
  switch(desc.type)
170 171
    {
171 172
    case DimacsDescriptor::MIN:
172
      solve_min<Value>(ap,is,os,infty,desc);
173
      solve_min<Value, LargeValue>(ap,is,os,infty,desc);
173 174
      break;
174 175
    case DimacsDescriptor::MAX:
175 176
      solve_max<Value>(ap,is,os,infty,desc);
176 177
      break;
177 178
    case DimacsDescriptor::SP:
178 179
      solve_sp<Value>(ap,is,os,desc);
179 180
      break;
180 181
    case DimacsDescriptor::MAT:
181 182
      solve_mat(ap,is,os,desc);
182 183
      break;
183 184
    default:
184 185
      break;
185 186
    }
186 187
}
187 188

	
188 189
int main(int argc, const char *argv[]) {
189 190
  typedef SmartDigraph Digraph;
190 191

	
191 192
  typedef Digraph::Arc Arc;
192 193

	
193 194
  std::string inputName;
194 195
  std::string outputName;
195 196

	
196 197
  ArgParser ap(argc, argv);
197 198
  ap.other("[INFILE [OUTFILE]]",
198 199
           "If either the INFILE or OUTFILE file is missing the standard\n"
199 200
           "     input/output will be used instead.")
200 201
    .boolOption("q", "Do not print any report")
201 202
    .boolOption("int","Use 'int' for capacities, costs etc. (default)")
202 203
    .optionGroup("datatype","int")
203 204
#ifdef LEMON_HAVE_LONG_LONG
204 205
    .boolOption("long","Use 'long long' for capacities, costs etc.")
205 206
    .optionGroup("datatype","long")
206 207
#endif
207 208
    .boolOption("double","Use 'double' for capacities, costs etc.")
208 209
    .optionGroup("datatype","double")
209 210
    .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
210 211
    .optionGroup("datatype","ldouble")
211 212
    .onlyOneGroup("datatype")
212 213
    .stringOption("infcap","Value used for 'very high' capacities","0")
213 214
    .run();
214 215

	
215 216
  std::ifstream input;
216 217
  std::ofstream output;
217 218

	
218 219
  switch(ap.files().size())
219 220
    {
220 221
    case 2:
221 222
      output.open(ap.files()[1].c_str());
222 223
      if (!output) {
223 224
        throw IoError("Cannot open the file for writing", ap.files()[1]);
224 225
      }
225 226
    case 1:
226 227
      input.open(ap.files()[0].c_str());
227 228
      if (!input) {
228 229
        throw IoError("File cannot be found", ap.files()[0]);
229 230
      }
230 231
    case 0:
231 232
      break;
232 233
    default:
233 234
      std::cerr << ap.commandName() << ": too many arguments\n";
234 235
      return 1;
235 236
    }
236 237
  std::istream& is = (ap.files().size()<1 ? std::cin : input);
237 238
  std::ostream& os = (ap.files().size()<2 ? std::cout : output);
238 239

	
239 240
  DimacsDescriptor desc = dimacsType(is);
240
  
241

	
241 242
  if(!ap.given("q"))
242 243
    {
243 244
      std::cout << "Problem type: ";
244 245
      switch(desc.type)
245 246
        {
246 247
        case DimacsDescriptor::MIN:
247 248
          std::cout << "min";
248 249
          break;
249 250
        case DimacsDescriptor::MAX:
250 251
          std::cout << "max";
251 252
          break;
252 253
        case DimacsDescriptor::SP:
253 254
          std::cout << "sp";
254 255
        case DimacsDescriptor::MAT:
255 256
          std::cout << "mat";
256 257
          break;
257 258
        default:
258 259
          exit(1);
259 260
          break;
260 261
        }
261 262
      std::cout << "\nNum of nodes: " << desc.nodeNum;
262 263
      std::cout << "\nNum of arcs:  " << desc.edgeNum;
263 264
      std::cout << "\n\n";
264 265
    }
265
    
266

	
266 267
  if(ap.given("double"))
267
    solve<double>(ap,is,os,desc);
268
    solve<double, double>(ap,is,os,desc);
268 269
  else if(ap.given("ldouble"))
269
    solve<long double>(ap,is,os,desc);
270
    solve<long double, long double>(ap,is,os,desc);
270 271
#ifdef LEMON_HAVE_LONG_LONG
271 272
  else if(ap.given("long"))
272
    solve<long long>(ap,is,os,desc);
273
    solve<long long, long long>(ap,is,os,desc);
274
  else solve<int, long long>(ap,is,os,desc);
275
#else
276
  else solve<int, long>(ap,is,os,desc);
273 277
#endif
274
  else solve<int>(ap,is,os,desc);
275 278

	
276 279
  return 0;
277 280
}
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 6
    echo "Usage:"
7 7
    echo "  $0 source-file(s)"
8 8
    exit
9 9
fi
10 10

	
11 11
for i in $@
12 12
do
13 13
    echo Update $i...
14 14
    TMP=`mktemp`
15 15
    sed -e "s/\<undirected graph\>/_gr_aph_label_/g"\
16 16
        -e "s/\<undirected graphs\>/_gr_aph_label_s/g"\
17 17
        -e "s/\<undirected edge\>/_ed_ge_label_/g"\
18 18
        -e "s/\<undirected edges\>/_ed_ge_label_s/g"\
19 19
        -e "s/\<directed graph\>/_digr_aph_label_/g"\
20 20
        -e "s/\<directed graphs\>/_digr_aph_label_s/g"\
21 21
        -e "s/\<directed edge\>/_ar_c_label_/g"\
22 22
        -e "s/\<directed edges\>/_ar_c_label_s/g"\
23 23
        -e "s/UGraph/_Gr_aph_label_/g"\
24 24
        -e "s/u[Gg]raph/_gr_aph_label_/g"\
25 25
        -e "s/Graph\>/_Digr_aph_label_/g"\
26 26
        -e "s/\<graph\>/_digr_aph_label_/g"\
27 27
        -e "s/Graphs\>/_Digr_aph_label_s/g"\
28 28
        -e "s/\<graphs\>/_digr_aph_label_s/g"\
29 29
        -e "s/\([Gg]\)raph\([a-z]\)/_\1r_aph_label_\2/g"\
30 30
        -e "s/\([a-z_]\)graph/\1_gr_aph_label_/g"\
31 31
        -e "s/Graph/_Digr_aph_label_/g"\
32 32
        -e "s/graph/_digr_aph_label_/g"\
33 33
        -e "s/UEdge/_Ed_ge_label_/g"\
34 34
        -e "s/u[Ee]dge/_ed_ge_label_/g"\
35 35
        -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
36 36
        -e "s/Edge\>/_Ar_c_label_/g"\
37 37
        -e "s/\<edge\>/_ar_c_label_/g"\
38
        -e "s/_edge\>/_ar_c_label_/g"\
38
        -e "s/_edge\>/__ar_c_label_/g"\
39 39
        -e "s/Edges\>/_Ar_c_label_s/g"\
40 40
        -e "s/\<edges\>/_ar_c_label_s/g"\
41
        -e "s/_edges\>/_ar_c_label_s/g"\
41
        -e "s/_edges\>/__ar_c_label_s/g"\
42 42
        -e "s/\([Ee]\)dge\([a-z]\)/_\1d_ge_label_\2/g"\
43 43
        -e "s/\([a-z]\)edge/\1_ed_ge_label_/g"\
44 44
        -e "s/Edge/_Ar_c_label_/g"\
45 45
        -e "s/edge/_ar_c_label_/g"\
46 46
        -e "s/A[Nn]ode/_Re_d_label_/g"\
47 47
        -e "s/B[Nn]ode/_Blu_e_label_/g"\
48 48
        -e "s/A-[Nn]ode/_Re_d_label_/g"\
49 49
        -e "s/B-[Nn]ode/_Blu_e_label_/g"\
50 50
        -e "s/a[Nn]ode/_re_d_label_/g"\
51 51
        -e "s/b[Nn]ode/_blu_e_label_/g"\
52 52
        -e "s/\<UGRAPH_TYPEDEFS\([ \t]*([ \t]*\)typename[ \t]/TEMPLATE__GR_APH_TY_PEDE_FS_label_\1/g"\
53 53
        -e "s/\<GRAPH_TYPEDEFS\([ \t]*([ \t]*\)typename[ \t]/TEMPLATE__DIGR_APH_TY_PEDE_FS_label_\1/g"\
54 54
        -e "s/\<UGRAPH_TYPEDEFS\>/_GR_APH_TY_PEDE_FS_label_/g"\
55 55
        -e "s/\<GRAPH_TYPEDEFS\>/_DIGR_APH_TY_PEDE_FS_label_/g"\
56 56
        -e "s/_Digr_aph_label_/Digraph/g"\
57 57
        -e "s/_digr_aph_label_/digraph/g"\
58 58
        -e "s/_Gr_aph_label_/Graph/g"\
59 59
        -e "s/_gr_aph_label_/graph/g"\
60 60
        -e "s/_Ar_c_label_/Arc/g"\
61 61
        -e "s/_ar_c_label_/arc/g"\
62 62
        -e "s/_Ed_ge_label_/Edge/g"\
63 63
        -e "s/_ed_ge_label_/edge/g"\
64 64
        -e "s/_In_cEd_geIt_label_/IncEdgeIt/g"\
65 65
        -e "s/_Re_d_label_/Red/g"\
66 66
        -e "s/_Blu_e_label_/Blue/g"\
67 67
        -e "s/_re_d_label_/red/g"\
68 68
        -e "s/_blu_e_label_/blue/g"\
69 69
        -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\
70 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"\
71 76
        -e "s/DigraphToEps/GraphToEps/g"\
72 77
        -e "s/digraphToEps/graphToEps/g"\
73 78
        -e "s/\<DefPredMap\>/SetPredMap/g"\
74 79
        -e "s/\<DefDistMap\>/SetDistMap/g"\
75 80
        -e "s/\<DefReachedMap\>/SetReachedMap/g"\
76 81
        -e "s/\<DefProcessedMap\>/SetProcessedMap/g"\
77 82
        -e "s/\<DefHeap\>/SetHeap/g"\
78 83
        -e "s/\<DefStandardHeap\>/SetStandradHeap/g"\
79 84
        -e "s/\<DefOperationTraits\>/SetOperationTraits/g"\
80 85
        -e "s/\<DefProcessedMapToBeDefaultMap\>/SetStandardProcessedMap/g"\
81 86
        -e "s/\<copyGraph\>/graphCopy/g"\
82 87
        -e "s/\<copyDigraph\>/digraphCopy/g"\
83 88
        -e "s/\<HyperCubeDigraph\>/HypercubeGraph/g"\
84 89
        -e "s/\<IntegerMap\>/RangeMap/g"\
85 90
        -e "s/\<integerMap\>/rangeMap/g"\
86 91
        -e "s/\<\([sS]\)tdMap\>/\1parseMap/g"\
87 92
        -e "s/\<\([Ff]\)unctorMap\>/\1unctorToMap/g"\
88 93
        -e "s/\<\([Mm]\)apFunctor\>/\1apToFunctor/g"\
89 94
        -e "s/\<\([Ff]\)orkWriteMap\>/\1orkMap/g"\
90 95
        -e "s/\<StoreBoolMap\>/LoggerBoolMap/g"\
91 96
        -e "s/\<storeBoolMap\>/loggerBoolMap/g"\
92 97
        -e "s/\<InvertableMap\>/CrossRefMap/g"\
93 98
        -e "s/\<invertableMap\>/crossRefMap/g"\
94 99
        -e "s/\<DescriptorMap\>/RangeIdMap/g"\
95 100
        -e "s/\<descriptorMap\>/rangeIdMap/g"\
96 101
        -e "s/\<BoundingBox\>/Box/g"\
97 102
        -e "s/\<readNauty\>/readNautyGraph/g"\
98 103
        -e "s/\<RevDigraphAdaptor\>/ReverseDigraph/g"\
99 104
        -e "s/\<revDigraphAdaptor\>/reverseDigraph/g"\
100 105
        -e "s/\<SubDigraphAdaptor\>/SubDigraph/g"\
101 106
        -e "s/\<subDigraphAdaptor\>/subDigraph/g"\
102 107
        -e "s/\<SubGraphAdaptor\>/SubGraph/g"\
103 108
        -e "s/\<subGraphAdaptor\>/subGraph/g"\
104 109
        -e "s/\<NodeSubDigraphAdaptor\>/FilterNodes/g"\
105 110
        -e "s/\<nodeSubDigraphAdaptor\>/filterNodes/g"\
106 111
        -e "s/\<ArcSubDigraphAdaptor\>/FilterArcs/g"\
107 112
        -e "s/\<arcSubDigraphAdaptor\>/filterArcs/g"\
108 113
        -e "s/\<UndirDigraphAdaptor\>/Undirector/g"\
109 114
        -e "s/\<undirDigraphAdaptor\>/undirector/g"\
110 115
        -e "s/\<ResDigraphAdaptor\>/ResidualDigraph/g"\
111 116
        -e "s/\<resDigraphAdaptor\>/residualDigraph/g"\
112 117
        -e "s/\<SplitDigraphAdaptor\>/SplitNodes/g"\
113 118
        -e "s/\<splitDigraphAdaptor\>/splitNodes/g"\
114 119
        -e "s/\<SubGraphAdaptor\>/SubGraph/g"\
115 120
        -e "s/\<subGraphAdaptor\>/subGraph/g"\
116 121
        -e "s/\<NodeSubGraphAdaptor\>/FilterNodes/g"\
117 122
        -e "s/\<nodeSubGraphAdaptor\>/filterNodes/g"\
118 123
        -e "s/\<ArcSubGraphAdaptor\>/FilterEdges/g"\
119 124
        -e "s/\<arcSubGraphAdaptor\>/filterEdges/g"\
120 125
        -e "s/\<DirGraphAdaptor\>/Orienter/g"\
121 126
        -e "s/\<dirGraphAdaptor\>/orienter/g"\
122 127
        -e "s/\<LpCplex\>/CplexLp/g"\
123 128
        -e "s/\<MipCplex\>/CplexMip/g"\
124 129
        -e "s/\<LpGlpk\>/GlpkLp/g"\
125 130
        -e "s/\<MipGlpk\>/GlpkMip/g"\
126 131
        -e "s/\<LpSoplex\>/SoplexLp/g"\
127 132
    <$i > $TMP
128 133
    mv $TMP $i
129 134
done
0 comments (0 inline)