gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 10 0
merge default
1 file changed with 26 insertions and 26 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
1 1
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
2 2

	
3 3
#EXECUTE_PROCESS(
4 4
#  COMMAND hg id -i
5 5
#  OUTPUT_VARIABLE HG_REVISION
6 6
#  OUTPUT_STRIP_TRAILING_WHITESPACE)
7 7

	
8
SET(PROJECT_NAME "Lemon")
8
SET(PROJECT_NAME "LEMON")
9 9
SET(PROJECT_VERSION_MAJOR "0")
10 10
SET(PROJECT_VERSION_MINOR "99")
11 11
SET(PROJECT_VERSION_PATCH "0")
12 12
SET(PROJECT_VERSION
13 13
  "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
14 14

	
15 15
PROJECT(${PROJECT_NAME})
16 16

	
17 17
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
18 18

	
19 19
INCLUDE(FindDoxygen)
20 20
INCLUDE(FindGhostscript)
21 21

	
22 22
ENABLE_TESTING()
23 23

	
24 24
ADD_SUBDIRECTORY(lemon)
25 25
ADD_SUBDIRECTORY(demo)
26 26
ADD_SUBDIRECTORY(doc)
27 27
ADD_SUBDIRECTORY(test)
28 28

	
29 29
IF(WIN32)
30 30
  INSTALL(FILES ${CMAKE_SOURCE_DIR}/cmake/nsis/lemon.ico
31 31
    DESTINATION bin)
32 32
ENDIF(WIN32)
33 33

	
34 34
IF(WIN32)
35 35
  SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
36 36
  SET(CPACK_PACKAGE_VENDOR
37 37
    "EGRES - Egervary Research Group on Combinatorial Optimization")
38 38
  SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
39
    "Lemon - Library of Efficient Models and Optimization in Networks")
39
    "LEMON - Library of Efficient Models and Optimization in Networks")
40 40
  SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
41 41

	
42 42
  SET(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
43 43
  SET(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
44 44
  SET(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
45 45
  SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
46 46

	
47 47
  SET(CPACK_PACKAGE_INSTALL_DIRECTORY
48 48
    "${PROJECT_NAME} ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
49 49
  SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
50 50
    "${PROJECT_NAME} ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
51 51

	
52 52
  # Variables to generate a component-based installer.
53 53
  #SET(CPACK_COMPONENTS_ALL headers library html_documentation)
54 54

	
55 55
  #SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
56 56
  #SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Static library")
57 57
  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
58 58

	
59 59
  #SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
60
  #  "C++ header files for use with the Lemon library")
60
  #  "C++ header files for use with the LEMON library")
61 61
  #SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
62
  #  "Static library used to build programs with Lemon")
62
  #  "Static library used to build programs with LEMON")
63 63
  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
64 64
  #  "Doxygen generated documentation")
65 65

	
66 66
  #SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
67 67

	
68 68
  #SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
69 69
  #SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
70 70
  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
71 71

	
72 72
  #SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
73
  #  "Components needed to develop software using Lemon")
73
  #  "Components needed to develop software using LEMON")
74 74
  #SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
75
  #  "Documentation of Lemon")
75
  #  "Documentation of LEMON")
76 76

	
77 77
  #SET(CPACK_ALL_INSTALL_TYPES Full Developer)
78 78

	
79 79
  #SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
80 80
  #SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
81 81
  #SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
82 82

	
83 83
  SET(CPACK_GENERATOR "NSIS")
84 84
  SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/lemon.ico")
85 85
  SET(CPACK_NSIS_MUI_UNIICON "${CMAKE_SOURCE_DIR}/cmake/nsis/uninstall.ico")
86 86
  #SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
87 87
  SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
88 88
  SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
89 89
  SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
90 90
  SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lemon.cs.elte.hu")
91 91
  SET(CPACK_NSIS_CONTACT "lemon-user@lemon.cs.elte.hu")
92 92
  SET(CPACK_NSIS_CREATE_ICONS_EXTRA "
93 93
    CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\doc\\\\index.html\\\"
94 94
    ")
95 95
  SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
96 96
    !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
97 97
    Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Documentation.lnk\\\"
98 98
    ")
99 99

	
100 100
  INCLUDE(CPack)
101 101
ENDIF(WIN32)
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_define([lemon_hg_revision], [m4_normalize(esyscmd([hg id -i]))])
6 6
m4_define([lemon_version], [ifelse(lemon_version_number(), [], [lemon_hg_revision()], [lemon_version_number()])])
7 7

	
8 8
AC_PREREQ([2.59])
9
AC_INIT([Lemon], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
9
AC_INIT([LEMON], [lemon_version()], [lemon-user@lemon.cs.elte.hu], [lemon])
10 10
AC_CONFIG_AUX_DIR([build-aux])
11 11
AC_CONFIG_MACRO_DIR([m4])
12 12
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects nostdinc])
13 13
AC_CONFIG_SRCDIR([lemon/list_graph.h])
14 14
AC_CONFIG_HEADERS([config.h lemon/config.h])
15 15

	
16 16
lx_cmdline_cxxflags_set=${CXXFLAGS+set}
17 17

	
18 18
dnl Checks for programs.
19 19
AC_PROG_CXX
20 20
AC_PROG_CXXCPP
21 21
AC_PROG_INSTALL
22 22
AC_DISABLE_SHARED
23 23
AC_PROG_LIBTOOL
24 24

	
25 25
AC_CHECK_PROG([doxygen_found],[doxygen],[yes],[no])
26 26
AC_CHECK_PROG([gs_found],[gs],[yes],[no])
27 27

	
28 28
dnl Set custom compiler flags when using g++.
29 29
if test x"$lx_cmdline_cxxflags_set" != x"set" -a "$GXX" = yes; then
30 30
  CXXFLAGS="$CXXFLAGS -Wall -W -Wall -W -Wunused -Wformat=2 -Wctor-dtor-privacy -Wnon-virtual-dtor -Wno-char-subscripts -Wwrite-strings -Wno-char-subscripts -Wreturn-type -Wcast-qual -Wcast-align -Wsign-promo -Woverloaded-virtual -Woverloaded-virtual -ansi -fno-strict-aliasing -Wold-style-cast -Wno-unknown-pragmas"
31 31
fi
32 32

	
33 33
dnl Checks for libraries.
34 34
LX_CHECK_GLPK
35 35
LX_CHECK_CPLEX
36 36
LX_CHECK_SOPLEX
37 37

	
38 38
dnl Disable/enable building the demo programs.
39 39
AC_ARG_ENABLE([demo],
40 40
AS_HELP_STRING([--enable-demo], [build the demo programs])
41 41
AS_HELP_STRING([--disable-demo], [do not build the demo programs @<:@default@:>@]),
42 42
              [], [enable_demo=no])
43 43
AC_MSG_CHECKING([whether to build the demo programs])
44 44
if test x"$enable_demo" != x"no"; then
45 45
  AC_MSG_RESULT([yes])
46 46
else
47 47
  AC_MSG_RESULT([no])
48 48
fi
49 49
AM_CONDITIONAL([WANT_DEMO], [test x"$enable_demo" != x"no"])
50 50

	
51 51
dnl Disable/enable building the binary tools.
52 52
AC_ARG_ENABLE([tools],
53 53
AS_HELP_STRING([--enable-tools], [build additional tools @<:@default@:>@])
54 54
AS_HELP_STRING([--disable-tools], [do not build additional tools]),
55 55
              [], [enable_tools=yes])
56 56
AC_MSG_CHECKING([whether to build the additional tools])
57 57
if test x"$enable_tools" != x"no"; then
58 58
  AC_MSG_RESULT([yes])
59 59
else
60 60
  AC_MSG_RESULT([no])
61 61
fi
62 62
AM_CONDITIONAL([WANT_TOOLS], [test x"$enable_tools" != x"no"])
63 63

	
64 64
dnl Disable/enable building the benchmarks.
65 65
AC_ARG_ENABLE([benchmark],
66 66
AS_HELP_STRING([--enable-benchmark], [build the benchmarks])
67 67
AS_HELP_STRING([--disable-benchmark], [do not build the benchmarks @<:@default@:>@]),
68 68
              [], [enable_benchmark=no])
69 69
AC_MSG_CHECKING([whether to build the benchmarks])
70 70
if test x"$enable_benchmark" != x"no"; then
71 71
  AC_MSG_RESULT([yes])
72 72
else
73 73
  AC_MSG_RESULT([no])
74 74
fi
75 75
AM_CONDITIONAL([WANT_BENCHMARK], [test x"$enable_benchmark" != x"no"])
76 76

	
77 77
dnl Checks for header files.
78 78
AC_CHECK_HEADERS(limits.h sys/time.h sys/times.h unistd.h)
79 79

	
80 80
dnl Checks for typedefs, structures, and compiler characteristics.
81 81
AC_C_CONST
82 82
AC_C_INLINE
83 83
AC_TYPE_SIZE_T
84 84
AC_HEADER_TIME
85 85
AC_STRUCT_TM
86 86

	
87 87
dnl Checks for library functions.
88 88
AC_HEADER_STDC
89 89
AC_CHECK_FUNCS(gettimeofday times ctime_r)
90 90

	
91 91
dnl Add dependencies on files generated by configure.
92 92
AC_SUBST([CONFIG_STATUS_DEPENDENCIES],
93 93
  ['$(top_srcdir)/doc/Doxyfile.in $(top_srcdir)/lemon/lemon.pc.in'])
94 94

	
95 95
AC_CONFIG_FILES([
96 96
Makefile
97 97
doc/Doxyfile
98 98
lemon/lemon.pc
99 99
])
100 100

	
101 101
AC_OUTPUT
102 102

	
103 103
echo
104 104
echo '****************************** SUMMARY ******************************'
105 105
echo
106 106
echo Package version............... : $PACKAGE-$VERSION
107 107
echo
108 108
echo C++ compiler.................. : $CXX
109 109
echo C++ compiles flags............ : $CXXFLAGS
110 110
echo
111 111
echo GLPK support.................. : $lx_glpk_found
112 112
echo CPLEX support................. : $lx_cplex_found
113 113
echo SOPLEX support................ : $lx_soplex_found
114 114
echo
115 115
echo Build benchmarks.............. : $enable_benchmark
116 116
echo Build demo programs........... : $enable_demo
117 117
echo Build additional tools........ : $enable_tools
118 118
echo
119 119
echo The packace will be installed in
120 120
echo -n '  '
121 121
echo $prefix.
122 122
echo
123 123
echo '*********************************************************************'
124 124

	
125 125
echo
126 126
echo Configure complete, now type \'make\' and then \'make install\'.
127 127
echo
Ignore white space 6 line context
... ...
@@ -72,492 +72,492 @@
72 72
@ingroup datas
73 73
\brief Map structures implemented in LEMON.
74 74

	
75 75
This group describes the map structures implemented in LEMON.
76 76

	
77 77
LEMON provides several special purpose maps that e.g. combine
78 78
new maps from existing ones.
79 79
*/
80 80

	
81 81
/**
82 82
@defgroup graph_maps Graph Maps
83 83
@ingroup maps
84 84
\brief Special graph-related maps.
85 85

	
86 86
This group describes maps that are specifically designed to assign
87 87
values to the nodes and arcs of graphs.
88 88
*/
89 89

	
90 90

	
91 91
/**
92 92
\defgroup map_adaptors Map Adaptors
93 93
\ingroup maps
94 94
\brief Tools to create new maps from existing ones
95 95

	
96 96
This group describes map adaptors that are used to create "implicit"
97 97
maps from other maps.
98 98

	
99 99
Most of them are \ref lemon::concepts::ReadMap "read-only maps".
100 100
They can make arithmetic and logical operations between one or two maps
101 101
(negation, shifting, addition, multiplication, logical 'and', 'or',
102 102
'not' etc.) or e.g. convert a map to another one of different Value type.
103 103

	
104 104
The typical usage of this classes is passing implicit maps to
105 105
algorithms.  If a function type algorithm is called then the function
106 106
type map adaptors can be used comfortable. For example let's see the
107 107
usage of map adaptors with the \c digraphToEps() function.
108 108
\code
109 109
  Color nodeColor(int deg) {
110 110
    if (deg >= 2) {
111 111
      return Color(0.5, 0.0, 0.5);
112 112
    } else if (deg == 1) {
113 113
      return Color(1.0, 0.5, 1.0);
114 114
    } else {
115 115
      return Color(0.0, 0.0, 0.0);
116 116
    }
117 117
  }
118 118

	
119 119
  Digraph::NodeMap<int> degree_map(graph);
120 120

	
121 121
  digraphToEps(graph, "graph.eps")
122 122
    .coords(coords).scaleToA4().undirected()
123 123
    .nodeColors(composeMap(functorToMap(nodeColor), degree_map))
124 124
    .run();
125 125
\endcode
126 126
The \c functorToMap() function makes an \c int to \c Color map from the
127 127
\e nodeColor() function. The \c composeMap() compose the \e degree_map
128 128
and the previously created map. The composed map is a proper function to
129 129
get the color of each node.
130 130

	
131 131
The usage with class type algorithms is little bit harder. In this
132 132
case the function type map adaptors can not be used, because the
133 133
function map adaptors give back temporary objects.
134 134
\code
135 135
  Digraph graph;
136 136

	
137 137
  typedef Digraph::ArcMap<double> DoubleArcMap;
138 138
  DoubleArcMap length(graph);
139 139
  DoubleArcMap speed(graph);
140 140

	
141 141
  typedef DivMap<DoubleArcMap, DoubleArcMap> TimeMap;
142 142
  TimeMap time(length, speed);
143 143

	
144 144
  Dijkstra<Digraph, TimeMap> dijkstra(graph, time);
145 145
  dijkstra.run(source, target);
146 146
\endcode
147 147
We have a length map and a maximum speed map on the arcs of a digraph.
148 148
The minimum time to pass the arc can be calculated as the division of
149 149
the two maps which can be done implicitly with the \c DivMap template
150 150
class. We use the implicit minimum time map as the length map of the
151 151
\c Dijkstra algorithm.
152 152
*/
153 153

	
154 154
/**
155 155
@defgroup matrices Matrices
156 156
@ingroup datas
157 157
\brief Two dimensional data storages implemented in LEMON.
158 158

	
159 159
This group describes two dimensional data storages implemented in LEMON.
160 160
*/
161 161

	
162 162
/**
163 163
@defgroup paths Path Structures
164 164
@ingroup datas
165 165
\brief Path structures implemented in LEMON.
166 166

	
167 167
This group describes the path structures implemented in LEMON.
168 168

	
169 169
LEMON provides flexible data structures to work with paths.
170 170
All of them have similar interfaces and they can be copied easily with
171 171
assignment operators and copy constructors. This makes it easy and
172 172
efficient to have e.g. the Dijkstra algorithm to store its result in
173 173
any kind of path structure.
174 174

	
175 175
\sa lemon::concepts::Path
176 176

	
177 177
*/
178 178

	
179 179
/**
180 180
@defgroup auxdat Auxiliary Data Structures
181 181
@ingroup datas
182 182
\brief Auxiliary data structures implemented in LEMON.
183 183

	
184 184
This group describes some data structures implemented in LEMON in
185 185
order to make it easier to implement combinatorial algorithms.
186 186
*/
187 187

	
188 188

	
189 189
/**
190 190
@defgroup algs Algorithms
191 191
\brief This group describes the several algorithms
192 192
implemented in LEMON.
193 193

	
194 194
This group describes the several algorithms
195 195
implemented in LEMON.
196 196
*/
197 197

	
198 198
/**
199 199
@defgroup search Graph Search
200 200
@ingroup algs
201 201
\brief Common graph search algorithms.
202 202

	
203 203
This group describes the common graph search algorithms like
204 204
Breadth-first search (Bfs) and Depth-first search (Dfs).
205 205
*/
206 206

	
207 207
/**
208 208
@defgroup shortest_path Shortest Path algorithms
209 209
@ingroup algs
210 210
\brief Algorithms for finding shortest paths.
211 211

	
212 212
This group describes the algorithms for finding shortest paths in graphs.
213 213
*/
214 214

	
215 215
/**
216 216
@defgroup max_flow Maximum Flow algorithms
217 217
@ingroup algs
218 218
\brief Algorithms for finding maximum flows.
219 219

	
220 220
This group describes the algorithms for finding maximum flows and
221 221
feasible circulations.
222 222

	
223 223
The maximum flow problem is to find a flow between a single source and
224 224
a single target that is maximum. Formally, there is a \f$G=(V,A)\f$
225 225
directed graph, an \f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity
226 226
function and given \f$s, t \in V\f$ source and target node. The
227 227
maximum flow is the \f$f_a\f$ solution of the next optimization problem:
228 228

	
229 229
\f[ 0 \le f_a \le c_a \f]
230 230
\f[ \sum_{v\in\delta^{-}(u)}f_{vu}=\sum_{v\in\delta^{+}(u)}f_{uv}
231 231
\qquad \forall u \in V \setminus \{s,t\}\f]
232 232
\f[ \max \sum_{v\in\delta^{+}(s)}f_{uv} - \sum_{v\in\delta^{-}(s)}f_{vu}\f]
233 233

	
234 234
LEMON contains several algorithms for solving maximum flow problems:
235 235
- \ref lemon::EdmondsKarp "Edmonds-Karp"
236 236
- \ref lemon::Preflow "Goldberg's Preflow algorithm"
237 237
- \ref lemon::DinitzSleatorTarjan "Dinitz's blocking flow algorithm with dynamic trees"
238 238
- \ref lemon::GoldbergTarjan "Preflow algorithm with dynamic trees"
239 239

	
240 240
In most cases the \ref lemon::Preflow "Preflow" algorithm provides the
241 241
fastest method to compute the maximum flow. All impelementations
242 242
provides functions to query the minimum cut, which is the dual linear
243 243
programming problem of the maximum flow.
244 244

	
245 245
*/
246 246

	
247 247
/**
248 248
@defgroup min_cost_flow Minimum Cost Flow algorithms
249 249
@ingroup algs
250 250

	
251 251
\brief Algorithms for finding minimum cost flows and circulations.
252 252

	
253 253
This group describes the algorithms for finding minimum cost flows and
254 254
circulations.
255 255
*/
256 256

	
257 257
/**
258 258
@defgroup min_cut Minimum Cut algorithms
259 259
@ingroup algs
260 260

	
261 261
\brief Algorithms for finding minimum cut in graphs.
262 262

	
263 263
This group describes the algorithms for finding minimum cut in graphs.
264 264

	
265 265
The minimum cut problem is to find a non-empty and non-complete
266 266
\f$X\f$ subset of the vertices with minimum overall capacity on
267 267
outgoing arcs. Formally, there is \f$G=(V,A)\f$ directed graph, an
268 268
\f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
269 269
cut is the \f$X\f$ solution of the next optimization problem:
270 270

	
271 271
\f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
272 272
\sum_{uv\in A, u\in X, v\not\in X}c_{uv}\f]
273 273

	
274 274
LEMON contains several algorithms related to minimum cut problems:
275 275

	
276 276
- \ref lemon::HaoOrlin "Hao-Orlin algorithm" to calculate minimum cut
277 277
  in directed graphs
278 278
- \ref lemon::NagamochiIbaraki "Nagamochi-Ibaraki algorithm" to
279 279
  calculate minimum cut in undirected graphs
280 280
- \ref lemon::GomoryHuTree "Gomory-Hu tree computation" to calculate all
281 281
  pairs minimum cut in undirected graphs
282 282

	
283 283
If you want to find minimum cut just between two distinict nodes,
284 284
please see the \ref max_flow "Maximum Flow page".
285 285

	
286 286
*/
287 287

	
288 288
/**
289 289
@defgroup graph_prop Connectivity and other graph properties
290 290
@ingroup algs
291 291
\brief Algorithms for discovering the graph properties
292 292

	
293 293
This group describes the algorithms for discovering the graph properties
294 294
like connectivity, bipartiteness, euler property, simplicity etc.
295 295

	
296 296
\image html edge_biconnected_components.png
297 297
\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
298 298
*/
299 299

	
300 300
/**
301 301
@defgroup planar Planarity embedding and drawing
302 302
@ingroup algs
303 303
\brief Algorithms for planarity checking, embedding and drawing
304 304

	
305 305
This group describes the algorithms for planarity checking,
306 306
embedding and drawing.
307 307

	
308 308
\image html planar.png
309 309
\image latex planar.eps "Plane graph" width=\textwidth
310 310
*/
311 311

	
312 312
/**
313 313
@defgroup matching Matching algorithms
314 314
@ingroup algs
315 315
\brief Algorithms for finding matchings in graphs and bipartite graphs.
316 316

	
317 317
This group contains algorithm objects and functions to calculate
318 318
matchings in graphs and bipartite graphs. The general matching problem is
319 319
finding a subset of the arcs which does not shares common endpoints.
320 320

	
321 321
There are several different algorithms for calculate matchings in
322 322
graphs.  The matching problems in bipartite graphs are generally
323 323
easier than in general graphs. The goal of the matching optimization
324 324
can be the finding maximum cardinality, maximum weight or minimum cost
325 325
matching. The search can be constrained to find perfect or
326 326
maximum cardinality matching.
327 327

	
328
Lemon contains the next algorithms:
328
LEMON contains the next algorithms:
329 329
- \ref lemon::MaxBipartiteMatching "MaxBipartiteMatching" Hopcroft-Karp
330 330
  augmenting path algorithm for calculate maximum cardinality matching in
331 331
  bipartite graphs
332 332
- \ref lemon::PrBipartiteMatching "PrBipartiteMatching" Push-Relabel
333 333
  algorithm for calculate maximum cardinality matching in bipartite graphs
334 334
- \ref lemon::MaxWeightedBipartiteMatching "MaxWeightedBipartiteMatching"
335 335
  Successive shortest path algorithm for calculate maximum weighted matching
336 336
  and maximum weighted bipartite matching in bipartite graph
337 337
- \ref lemon::MinCostMaxBipartiteMatching "MinCostMaxBipartiteMatching"
338 338
  Successive shortest path algorithm for calculate minimum cost maximum
339 339
  matching in bipartite graph
340 340
- \ref lemon::MaxMatching "MaxMatching" Edmond's blossom shrinking algorithm
341 341
  for calculate maximum cardinality matching in general graph
342 342
- \ref lemon::MaxWeightedMatching "MaxWeightedMatching" Edmond's blossom
343 343
  shrinking algorithm for calculate maximum weighted matching in general
344 344
  graph
345 345
- \ref lemon::MaxWeightedPerfectMatching "MaxWeightedPerfectMatching"
346 346
  Edmond's blossom shrinking algorithm for calculate maximum weighted
347 347
  perfect matching in general graph
348 348

	
349 349
\image html bipartite_matching.png
350 350
\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
351 351

	
352 352
*/
353 353

	
354 354
/**
355 355
@defgroup spantree Minimum Spanning Tree algorithms
356 356
@ingroup algs
357 357
\brief Algorithms for finding a minimum cost spanning tree in a graph.
358 358

	
359 359
This group describes the algorithms for finding a minimum cost spanning
360 360
tree in a graph
361 361
*/
362 362

	
363 363

	
364 364
/**
365 365
@defgroup auxalg Auxiliary algorithms
366 366
@ingroup algs
367 367
\brief Auxiliary algorithms implemented in LEMON.
368 368

	
369 369
This group describes some algorithms implemented in LEMON
370 370
in order to make it easier to implement complex algorithms.
371 371
*/
372 372

	
373 373
/**
374 374
@defgroup approx Approximation algorithms
375 375
\brief Approximation algorithms.
376 376

	
377 377
This group describes the approximation and heuristic algorithms
378 378
implemented in LEMON.
379 379
*/
380 380

	
381 381
/**
382 382
@defgroup gen_opt_group General Optimization Tools
383 383
\brief This group describes some general optimization frameworks
384 384
implemented in LEMON.
385 385

	
386 386
This group describes some general optimization frameworks
387 387
implemented in LEMON.
388 388

	
389 389
*/
390 390

	
391 391
/**
392 392
@defgroup lp_group Lp and Mip solvers
393 393
@ingroup gen_opt_group
394 394
\brief Lp and Mip solver interfaces for LEMON.
395 395

	
396 396
This group describes Lp and Mip solver interfaces for LEMON. The
397 397
various LP solvers could be used in the same manner with this
398 398
interface.
399 399

	
400 400
*/
401 401

	
402 402
/**
403 403
@defgroup lp_utils Tools for Lp and Mip solvers
404 404
@ingroup lp_group
405 405
\brief Helper tools to the Lp and Mip solvers.
406 406

	
407 407
This group adds some helper tools to general optimization framework
408 408
implemented in LEMON.
409 409
*/
410 410

	
411 411
/**
412 412
@defgroup metah Metaheuristics
413 413
@ingroup gen_opt_group
414 414
\brief Metaheuristics for LEMON library.
415 415

	
416 416
This group describes some metaheuristic optimization tools.
417 417
*/
418 418

	
419 419
/**
420 420
@defgroup utils Tools and Utilities
421 421
\brief Tools and utilities for programming in LEMON
422 422

	
423 423
Tools and utilities for programming in LEMON.
424 424
*/
425 425

	
426 426
/**
427 427
@defgroup gutils Basic Graph Utilities
428 428
@ingroup utils
429 429
\brief Simple basic graph utilities.
430 430

	
431 431
This group describes some simple basic graph utilities.
432 432
*/
433 433

	
434 434
/**
435 435
@defgroup misc Miscellaneous Tools
436 436
@ingroup utils
437 437
\brief Tools for development, debugging and testing.
438 438

	
439 439
This group describes several useful tools for development,
440 440
debugging and testing.
441 441
*/
442 442

	
443 443
/**
444 444
@defgroup timecount Time measuring and Counting
445 445
@ingroup misc
446 446
\brief Simple tools for measuring the performance of algorithms.
447 447

	
448 448
This group describes simple tools for measuring the performance
449 449
of algorithms.
450 450
*/
451 451

	
452 452
/**
453 453
@defgroup graphbits Tools for Graph Implementation
454 454
@ingroup utils
455 455
\brief Tools to make it easier to create graphs.
456 456

	
457 457
This group describes the tools that makes it easier to create graphs and
458 458
the maps that dynamically update with the graph changes.
459 459
*/
460 460

	
461 461
/**
462 462
@defgroup exceptions Exceptions
463 463
@ingroup utils
464 464
\brief Exceptions defined in LEMON.
465 465

	
466 466
This group describes the exceptions defined in LEMON.
467 467
*/
468 468

	
469 469
/**
470 470
@defgroup io_group Input-Output
471 471
\brief Graph Input-Output methods
472 472

	
473 473
This group describes the tools for importing and exporting graphs
474 474
and graph related data. Now it supports the LEMON format, the
475 475
\c DIMACS format and the encapsulated postscript (EPS) format.
476 476
*/
477 477

	
478 478
/**
479
@defgroup lemon_io Lemon Input-Output
479
@defgroup lemon_io LEMON Input-Output
480 480
@ingroup io_group
481
\brief Reading and writing \ref lgf-format "Lemon Graph Format".
481
\brief Reading and writing \ref lgf-format "LEMON Graph Format".
482 482

	
483 483
This group describes methods for reading and writing
484
\ref lgf-format "Lemon Graph Format".
484
\ref lgf-format "LEMON Graph Format".
485 485
*/
486 486

	
487 487
/**
488 488
@defgroup eps_io Postscript exporting
489 489
@ingroup io_group
490 490
\brief General \c EPS drawer and graph exporter
491 491

	
492 492
This group describes general \c EPS drawing methods and special
493 493
graph exporting tools.
494 494
*/
495 495

	
496 496

	
497 497
/**
498 498
@defgroup concept Concepts
499 499
\brief Skeleton classes and concept checking classes
500 500

	
501 501
This group describes the data/algorithm skeletons and concept checking
502 502
classes implemented in LEMON.
503 503

	
504 504
The purpose of the classes in this group is fourfold.
505 505

	
506 506
- These classes contain the documentations of the concepts. In order
507 507
  to avoid document multiplications, an implementation of a concept
508 508
  simply refers to the corresponding concept class.
509 509

	
510 510
- These classes declare every functions, <tt>typedef</tt>s etc. an
511 511
  implementation of the concepts should provide, however completely
512 512
  without implementations and real data structures behind the
513 513
  interface. On the other hand they should provide nothing else. All
514 514
  the algorithms working on a data structure meeting a certain concept
515 515
  should compile with these classes. (Though it will not run properly,
516 516
  of course.) In this way it is easily to check if an algorithm
517 517
  doesn't use any extra feature of a certain implementation.
518 518

	
519 519
- The concept descriptor classes also provide a <em>checker class</em>
520 520
  that makes it possible to check whether a certain implementation of a
521 521
  concept indeed provides all the required features.
522 522

	
523 523
- Finally, They can serve as a skeleton of a new implementation of a concept.
524 524

	
525 525
*/
526 526

	
527 527

	
528 528
/**
529 529
@defgroup graph_concepts Graph Structure Concepts
530 530
@ingroup concept
531 531
\brief Skeleton and concept checking classes for graph structures
532 532

	
533 533
This group describes the skeletons and concept checking classes of LEMON's
534 534
graph structures and helper classes used to implement these.
535 535
*/
536 536

	
537 537
/* --- Unused group
538 538
@defgroup experimental Experimental Structures and Algorithms
539 539
This group describes some Experimental structures and algorithms.
540 540
The stuff here is subject to change.
541 541
*/
542 542

	
543 543
/**
544 544
\anchor demoprograms
545 545

	
546 546
@defgroup demos Demo programs
547 547

	
548 548
Some demo programs are listed here. Their full source codes can be found in
549 549
the \c demo subdirectory of the source tree.
550 550

	
551 551
It order to compile them, use <tt>--enable-demo</tt> configure option when
552 552
build the library.
553 553
*/
554 554

	
555 555
/**
556 556
@defgroup tools Standalone utility applications
557 557

	
558 558
Some utility applications are listed here.
559 559

	
560 560
The standard compilation procedure (<tt>./configure;make</tt>) will compile
561 561
them, as well.
562 562
*/
563 563

	
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-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
namespace lemon {
20 20
/*!
21 21

	
22 22

	
23 23

	
24
\page lgf-format Lemon Graph Format (LGF)
24
\page lgf-format LEMON Graph Format (LGF)
25 25

	
26 26
The \e LGF is a <em>column oriented</em>
27 27
file format for storing graphs and associated data like
28 28
node and edge maps.
29 29

	
30 30
Each line with \c '#' first non-whitespace
31 31
character is considered as a comment line.
32 32

	
33 33
Otherwise the file consists of sections starting with
34 34
a header line. The header lines starts with an \c '@' character followed by the
35 35
type of section. The standard section types are \c \@nodes, \c
36 36
\@arcs and \c \@edges
37 37
and \@attributes. Each header line may also have an optional
38 38
\e name, which can be use to distinguish the sections of the same
39 39
type.
40 40

	
41 41
The standard sections are column oriented, each line consists of
42 42
<em>token</em>s separated by whitespaces. A token can be \e plain or
43 43
\e quoted. A plain token is just a sequence of non-whitespace characters,
44 44
while a quoted token is a
45 45
character sequence surrounded by double quotes, and it can also
46 46
contain whitespaces and escape sequences.
47 47

	
48 48
The \c \@nodes section describes a set of nodes and associated
49 49
maps. The first is a header line, its columns are the names of the
50 50
maps appearing in the following lines.
51 51
One of the maps must be called \c
52 52
"label", which plays special role in the file.
53 53
The following
54 54
non-empty lines until the next section describes nodes of the
55 55
graph. Each line contains the values of the node maps
56 56
associated to the current node.
57 57

	
58 58
\code
59 59
 @nodes
60 60
 label  coordinates  size    title
61 61
 1      (10,20)      10      "First node"
62 62
 2      (80,80)      8       "Second node"
63 63
 3      (40,10)      10      "Third node"
64 64
\endcode
65 65

	
66 66
The \c \@arcs section is very similar to the \c \@nodes section,
67 67
it again starts with a header line describing the names of the maps,
68 68
but the \c "label" map is not obligatory here. The following lines
69 69
describe the arcs. The first two tokens of each line are
70 70
the source and the target node of the arc, respectively, then come the map
71 71
values. The source and target tokens must be node labels.
72 72

	
73 73
\code
74 74
 @arcs
75 75
         capacity
76 76
 1   2   16
77 77
 1   3   12
78 78
 2   3   18
79 79
\endcode
80 80

	
81 81
The \c \@edges is just a synonym of \c \@arcs. The @arcs section can
82 82
also store the edge set of an undirected graph. In such case there is
83 83
a conventional method for store arc maps in the file, if two columns
84 84
has the same caption with \c '+' and \c '-' prefix, then these columns
85 85
can be regarded as the values of an arc map.
86 86

	
87 87
The \c \@attributes section contains key-value pairs, each line
88 88
consists of two tokens, an attribute name, and then an attribute
89 89
value. The value of the attribute could be also a label value of a
90 90
node or an edge, or even an edge label prefixed with \c '+' or \c '-',
91 91
which regards to the forward or backward directed arc of the
92 92
corresponding edge.
93 93

	
94 94
\code
95 95
 @attributes
96 96
 source 1
97 97
 target 3
98 98
 caption "LEMON test digraph"
99 99
\endcode
100 100

	
101 101
The \e LGF can contain extra sections, but there is no restriction on
102 102
the format of such sections.
103 103

	
104 104
*/
105 105
}
106 106

	
107 107
//  LocalWords:  whitespace whitespaces
Ignore white space 512 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-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_BITS_ALTERATION_NOTIFIER_H
20 20
#define LEMON_BITS_ALTERATION_NOTIFIER_H
21 21

	
22 22
#include <vector>
23 23
#include <list>
24 24

	
25 25
#include <lemon/core.h>
26 26

	
27 27
///\ingroup graphbits
28 28
///\file
29 29
///\brief Observer notifier for graph alteration observers.
30 30

	
31 31
namespace lemon {
32 32

	
33 33
  /// \ingroup graphbits
34 34
  ///
35 35
  /// \brief Notifier class to notify observes about alterations in
36 36
  /// a container.
37 37
  ///
38 38
  /// The simple graph's can be refered as two containers, one node container
39 39
  /// and one edge container. But they are not standard containers they
40 40
  /// does not store values directly they are just key continars for more
41 41
  /// value containers which are the node and edge maps.
42 42
  ///
43 43
  /// The graph's node and edge sets can be changed as we add or erase
44
  /// nodes and edges in the graph. Lemon would like to handle easily
44
  /// nodes and edges in the graph. LEMON would like to handle easily
45 45
  /// that the node and edge maps should contain values for all nodes or
46 46
  /// edges. If we want to check on every indicing if the map contains
47 47
  /// the current indicing key that cause a drawback in the performance
48 48
  /// in the library. We use another solution we notify all maps about
49 49
  /// an alteration in the graph, which cause only drawback on the
50 50
  /// alteration of the graph.
51 51
  ///
52 52
  /// This class provides an interface to the container. The \e first() and \e
53 53
  /// next() member functions make possible to iterate on the keys of the
54 54
  /// container. The \e id() function returns an integer id for each key.
55 55
  /// The \e maxId() function gives back an upper bound of the ids.
56 56
  ///
57 57
  /// For the proper functonality of this class, we should notify it
58 58
  /// about each alteration in the container. The alterations have four type
59 59
  /// as \e add(), \e erase(), \e build() and \e clear(). The \e add() and
60 60
  /// \e erase() signals that only one or few items added or erased to or
61 61
  /// from the graph. If all items are erased from the graph or from an empty
62 62
  /// graph a new graph is builded then it can be signaled with the
63 63
  /// clear() and build() members. Important rule that if we erase items
64 64
  /// from graph we should first signal the alteration and after that erase
65 65
  /// them from the container, on the other way on item addition we should
66 66
  /// first extend the container and just after that signal the alteration.
67 67
  ///
68 68
  /// The alteration can be observed with a class inherited from the
69 69
  /// \e ObserverBase nested class. The signals can be handled with
70 70
  /// overriding the virtual functions defined in the base class.  The
71 71
  /// observer base can be attached to the notifier with the
72 72
  /// \e attach() member and can be detached with detach() function. The
73 73
  /// alteration handlers should not call any function which signals
74 74
  /// an other alteration in the same notifier and should not
75 75
  /// detach any observer from the notifier.
76 76
  ///
77 77
  /// Alteration observers try to be exception safe. If an \e add() or
78 78
  /// a \e clear() function throws an exception then the remaining
79 79
  /// observeres will not be notified and the fulfilled additions will
80 80
  /// be rolled back by calling the \e erase() or \e clear()
81 81
  /// functions. Thence the \e erase() and \e clear() should not throw
82 82
  /// exception. Actullay, it can be throw only
83 83
  /// \ref AlterationObserver::ImmediateDetach ImmediateDetach
84 84
  /// exception which detach the observer from the notifier.
85 85
  ///
86 86
  /// There are some place when the alteration observing is not completly
87 87
  /// reliable. If we want to carry out the node degree in the graph
88 88
  /// as in the \ref InDegMap and we use the reverseEdge that cause
89 89
  /// unreliable functionality. Because the alteration observing signals
90 90
  /// only erasing and adding but not the reversing it will stores bad
91 91
  /// degrees. The sub graph adaptors cannot signal the alterations because
92 92
  /// just a setting in the filter map can modify the graph and this cannot
93 93
  /// be watched in any way.
94 94
  ///
95 95
  /// \param _Container The container which is observed.
96 96
  /// \param _Item The item type which is obserbved.
97 97

	
98 98
  template <typename _Container, typename _Item>
99 99
  class AlterationNotifier {
100 100
  public:
101 101

	
102 102
    typedef True Notifier;
103 103

	
104 104
    typedef _Container Container;
105 105
    typedef _Item Item;
106 106

	
107 107
    /// \brief Exception which can be called from \e clear() and
108 108
    /// \e erase().
109 109
    ///
110 110
    /// From the \e clear() and \e erase() function only this
111 111
    /// exception is allowed to throw. The exception immediatly
112 112
    /// detaches the current observer from the notifier. Because the
113 113
    /// \e clear() and \e erase() should not throw other exceptions
114 114
    /// it can be used to invalidate the observer.
115 115
    struct ImmediateDetach {};
116 116

	
117 117
    /// \brief ObserverBase is the base class for the observers.
118 118
    ///
119 119
    /// ObserverBase is the abstract base class for the observers.
120 120
    /// It will be notified about an item was inserted into or
121 121
    /// erased from the graph.
122 122
    ///
123 123
    /// The observer interface contains some pure virtual functions
124 124
    /// to override. The add() and erase() functions are
125 125
    /// to notify the oberver when one item is added or
126 126
    /// erased.
127 127
    ///
128 128
    /// The build() and clear() members are to notify the observer
129 129
    /// about the container is built from an empty container or
130 130
    /// is cleared to an empty container.
131 131

	
132 132
    class ObserverBase {
133 133
    protected:
134 134
      typedef AlterationNotifier Notifier;
135 135

	
136 136
      friend class AlterationNotifier;
137 137

	
138 138
      /// \brief Default constructor.
139 139
      ///
140 140
      /// Default constructor for ObserverBase.
141 141
      ///
142 142
      ObserverBase() : _notifier(0) {}
143 143

	
144 144
      /// \brief Constructor which attach the observer into notifier.
145 145
      ///
146 146
      /// Constructor which attach the observer into notifier.
147 147
      ObserverBase(AlterationNotifier& nf) {
148 148
        attach(nf);
149 149
      }
150 150

	
151 151
      /// \brief Constructor which attach the obserever to the same notifier.
152 152
      ///
153 153
      /// Constructor which attach the obserever to the same notifier as
154 154
      /// the other observer is attached to.
155 155
      ObserverBase(const ObserverBase& copy) {
156 156
        if (copy.attached()) {
157 157
          attach(*copy.notifier());
158 158
        }
159 159
      }
160 160

	
161 161
      /// \brief Destructor
162 162
      virtual ~ObserverBase() {
163 163
        if (attached()) {
164 164
          detach();
165 165
        }
166 166
      }
167 167

	
168 168
      /// \brief Attaches the observer into an AlterationNotifier.
169 169
      ///
170 170
      /// This member attaches the observer into an AlterationNotifier.
171 171
      ///
172 172
      void attach(AlterationNotifier& nf) {
173 173
        nf.attach(*this);
174 174
      }
175 175

	
176 176
      /// \brief Detaches the observer into an AlterationNotifier.
177 177
      ///
178 178
      /// This member detaches the observer from an AlterationNotifier.
179 179
      ///
180 180
      void detach() {
181 181
        _notifier->detach(*this);
182 182
      }
183 183

	
184 184
      /// \brief Gives back a pointer to the notifier which the map
185 185
      /// attached into.
186 186
      ///
187 187
      /// This function gives back a pointer to the notifier which the map
188 188
      /// attached into.
189 189
      ///
190 190
      Notifier* notifier() const { return const_cast<Notifier*>(_notifier); }
191 191

	
192 192
      /// Gives back true when the observer is attached into a notifier.
193 193
      bool attached() const { return _notifier != 0; }
194 194

	
195 195
    private:
196 196

	
197 197
      ObserverBase& operator=(const ObserverBase& copy);
198 198

	
199 199
    protected:
200 200

	
201 201
      Notifier* _notifier;
202 202
      typename std::list<ObserverBase*>::iterator _index;
203 203

	
204 204
      /// \brief The member function to notificate the observer about an
205 205
      /// item is added to the container.
206 206
      ///
207 207
      /// The add() member function notificates the observer about an item
208 208
      /// is added to the container. It have to be overrided in the
209 209
      /// subclasses.
210 210
      virtual void add(const Item&) = 0;
211 211

	
212 212
      /// \brief The member function to notificate the observer about
213 213
      /// more item is added to the container.
214 214
      ///
215 215
      /// The add() member function notificates the observer about more item
216 216
      /// is added to the container. It have to be overrided in the
217 217
      /// subclasses.
218 218
      virtual void add(const std::vector<Item>& items) = 0;
219 219

	
220 220
      /// \brief The member function to notificate the observer about an
221 221
      /// item is erased from the container.
222 222
      ///
223 223
      /// The erase() member function notificates the observer about an
224 224
      /// item is erased from the container. It have to be overrided in
225 225
      /// the subclasses.
226 226
      virtual void erase(const Item&) = 0;
227 227

	
228 228
      /// \brief The member function to notificate the observer about
229 229
      /// more item is erased from the container.
230 230
      ///
231 231
      /// The erase() member function notificates the observer about more item
232 232
      /// is erased from the container. It have to be overrided in the
233 233
      /// subclasses.
234 234
      virtual void erase(const std::vector<Item>& items) = 0;
235 235

	
236 236
      /// \brief The member function to notificate the observer about the
237 237
      /// container is built.
238 238
      ///
239 239
      /// The build() member function notificates the observer about the
240 240
      /// container is built from an empty container. It have to be
241 241
      /// overrided in the subclasses.
242 242

	
243 243
      virtual void build() = 0;
244 244

	
245 245
      /// \brief The member function to notificate the observer about all
246 246
      /// items are erased from the container.
247 247
      ///
248 248
      /// The clear() member function notificates the observer about all
249 249
      /// items are erased from the container. It have to be overrided in
250 250
      /// the subclasses.
251 251
      virtual void clear() = 0;
252 252

	
253 253
    };
254 254

	
255 255
  protected:
256 256

	
257 257
    const Container* container;
258 258

	
259 259
    typedef std::list<ObserverBase*> Observers;
260 260
    Observers _observers;
261 261

	
262 262

	
263 263
  public:
264 264

	
265 265
    /// \brief Default constructor.
266 266
    ///
267 267
    /// The default constructor of the AlterationNotifier.
268 268
    /// It creates an empty notifier.
269 269
    AlterationNotifier()
270 270
      : container(0) {}
271 271

	
272 272
    /// \brief Constructor.
273 273
    ///
274 274
    /// Constructor with the observed container parameter.
275 275
    AlterationNotifier(const Container& _container)
276 276
      : container(&_container) {}
277 277

	
278 278
    /// \brief Copy Constructor of the AlterationNotifier.
279 279
    ///
280 280
    /// Copy constructor of the AlterationNotifier.
281 281
    /// It creates only an empty notifier because the copiable
282 282
    /// notifier's observers have to be registered still into that notifier.
283 283
    AlterationNotifier(const AlterationNotifier& _notifier)
284 284
      : container(_notifier.container) {}
285 285

	
286 286
    /// \brief Destructor.
287 287
    ///
288 288
    /// Destructor of the AlterationNotifier.
289 289
    ///
290 290
    ~AlterationNotifier() {
291 291
      typename Observers::iterator it;
292 292
      for (it = _observers.begin(); it != _observers.end(); ++it) {
293 293
        (*it)->_notifier = 0;
294 294
      }
295 295
    }
296 296

	
297 297
    /// \brief Sets the container.
298 298
    ///
299 299
    /// Sets the container.
300 300
    void setContainer(const Container& _container) {
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-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\ingroup concept
20 20
///\file
21 21
///\brief Classes for representing paths in digraphs.
22 22
///
23 23
///\todo Iterators have obsolete style
24 24

	
25 25
#ifndef LEMON_CONCEPT_PATH_H
26 26
#define LEMON_CONCEPT_PATH_H
27 27

	
28 28
#include <lemon/core.h>
29 29
#include <lemon/concept_check.h>
30 30

	
31 31
namespace lemon {
32 32
  namespace concepts {
33 33

	
34 34
    /// \addtogroup concept
35 35
    /// @{
36 36

	
37 37
    /// \brief A skeleton structure for representing directed paths in
38 38
    /// a digraph.
39 39
    ///
40 40
    /// A skeleton structure for representing directed paths in a
41 41
    /// digraph.
42 42
    /// \tparam _Digraph The digraph type in which the path is.
43 43
    ///
44 44
    /// In a sense, the path can be treated as a list of arcs. The
45 45
    /// lemon path type stores just this list. As a consequence it
46 46
    /// cannot enumerate the nodes in the path and the zero length
47 47
    /// paths cannot store the source.
48 48
    ///
49 49
    template <typename _Digraph>
50 50
    class Path {
51 51
    public:
52 52

	
53 53
      /// Type of the underlying digraph.
54 54
      typedef _Digraph Digraph;
55 55
      /// Arc type of the underlying digraph.
56 56
      typedef typename Digraph::Arc Arc;
57 57

	
58 58
      class ArcIt;
59 59

	
60 60
      /// \brief Default constructor
61 61
      Path() {}
62 62

	
63 63
      /// \brief Template constructor
64 64
      template <typename CPath>
65 65
      Path(const CPath& cpath) {}
66 66

	
67 67
      /// \brief Template assigment
68 68
      template <typename CPath>
69 69
      Path& operator=(const CPath& cpath) {}
70 70

	
71 71
      /// Length of the path ie. the number of arcs in the path.
72 72
      int length() const { return 0;}
73 73

	
74 74
      /// Returns whether the path is empty.
75 75
      bool empty() const { return true;}
76 76

	
77 77
      /// Resets the path to an empty path.
78 78
      void clear() {}
79 79

	
80
      /// \brief Lemon style iterator for path arcs
80
      /// \brief LEMON style iterator for path arcs
81 81
      ///
82 82
      /// This class is used to iterate on the arcs of the paths.
83 83
      class ArcIt {
84 84
      public:
85 85
        /// Default constructor
86 86
        ArcIt() {}
87 87
        /// Invalid constructor
88 88
        ArcIt(Invalid) {}
89 89
        /// Constructor for first arc
90 90
        ArcIt(const Path &) {}
91 91

	
92 92
        /// Conversion to Arc
93 93
        operator Arc() const { return INVALID; }
94 94

	
95 95
        /// Next arc
96 96
        ArcIt& operator++() {return *this;}
97 97

	
98 98
        /// Comparison operator
99 99
        bool operator==(const ArcIt&) const {return true;}
100 100
        /// Comparison operator
101 101
        bool operator!=(const ArcIt&) const {return true;}
102 102
        /// Comparison operator
103 103
        bool operator<(const ArcIt&) const {return false;}
104 104

	
105 105
      };
106 106

	
107 107
      template <typename _Path>
108 108
      struct Constraints {
109 109
        void constraints() {
110 110
          Path<Digraph> pc;
111 111
          _Path p, pp(pc);
112 112
          int l = p.length();
113 113
          int e = p.empty();
114 114
          p.clear();
115 115

	
116 116
          p = pc;
117 117

	
118 118
          typename _Path::ArcIt id, ii(INVALID), i(p);
119 119

	
120 120
          ++i;
121 121
          typename Digraph::Arc ed = i;
122 122

	
123 123
          e = (i == ii);
124 124
          e = (i != ii);
125 125
          e = (i < ii);
126 126

	
127 127
          ignore_unused_variable_warning(l);
128 128
          ignore_unused_variable_warning(pp);
129 129
          ignore_unused_variable_warning(e);
130 130
          ignore_unused_variable_warning(id);
131 131
          ignore_unused_variable_warning(ii);
132 132
          ignore_unused_variable_warning(ed);
133 133
        }
134 134
      };
135 135

	
136 136
    };
137 137

	
138 138
    namespace _path_bits {
139 139

	
140 140
      template <typename _Digraph, typename _Path, typename RevPathTag = void>
141 141
      struct PathDumperConstraints {
142 142
        void constraints() {
143 143
          int l = p.length();
144 144
          int e = p.empty();
145 145

	
146 146
          typename _Path::ArcIt id, i(p);
147 147

	
148 148
          ++i;
149 149
          typename _Digraph::Arc ed = i;
150 150

	
151 151
          e = (i == INVALID);
152 152
          e = (i != INVALID);
153 153

	
154 154
          ignore_unused_variable_warning(l);
155 155
          ignore_unused_variable_warning(e);
156 156
          ignore_unused_variable_warning(id);
157 157
          ignore_unused_variable_warning(ed);
158 158
        }
159 159
        _Path& p;
160 160
      };
161 161

	
162 162
      template <typename _Digraph, typename _Path>
163 163
      struct PathDumperConstraints<
164 164
        _Digraph, _Path,
165 165
        typename enable_if<typename _Path::RevPathTag, void>::type
166 166
      > {
167 167
        void constraints() {
168 168
          int l = p.length();
169 169
          int e = p.empty();
170 170

	
171 171
          typename _Path::RevArcIt id, i(p);
172 172

	
173 173
          ++i;
174 174
          typename _Digraph::Arc ed = i;
175 175

	
176 176
          e = (i == INVALID);
177 177
          e = (i != INVALID);
178 178

	
179 179
          ignore_unused_variable_warning(l);
180 180
          ignore_unused_variable_warning(e);
181 181
          ignore_unused_variable_warning(id);
182 182
          ignore_unused_variable_warning(ed);
183 183
        }
184 184
        _Path& p;
185 185
      };
186 186

	
187 187
    }
188 188

	
189 189

	
190 190
    /// \brief A skeleton structure for path dumpers.
191 191
    ///
192 192
    /// A skeleton structure for path dumpers. The path dumpers are
193 193
    /// the generalization of the paths. The path dumpers can
194 194
    /// enumerate the arcs of the path wheter in forward or in
195 195
    /// backward order.  In most time these classes are not used
196 196
    /// directly rather it used to assign a dumped class to a real
197 197
    /// path type.
198 198
    ///
199 199
    /// The main purpose of this concept is that the shortest path
200 200
    /// algorithms can enumerate easily the arcs in reverse order.
201 201
    /// If we would like to give back a real path from these
202 202
    /// algorithms then we should create a temporarly path object. In
203
    /// Lemon such algorithms gives back a path dumper what can
203
    /// LEMON such algorithms gives back a path dumper what can
204 204
    /// assigned to a real path and the dumpers can be implemented as
205 205
    /// an adaptor class to the predecessor map.
206 206

	
207 207
    /// \tparam _Digraph  The digraph type in which the path is.
208 208
    ///
209 209
    /// The paths can be constructed from any path type by a
210 210
    /// template constructor or a template assignment operator.
211 211
    ///
212 212
    template <typename _Digraph>
213 213
    class PathDumper {
214 214
    public:
215 215

	
216 216
      /// Type of the underlying digraph.
217 217
      typedef _Digraph Digraph;
218 218
      /// Arc type of the underlying digraph.
219 219
      typedef typename Digraph::Arc Arc;
220 220

	
221 221
      /// Length of the path ie. the number of arcs in the path.
222 222
      int length() const { return 0;}
223 223

	
224 224
      /// Returns whether the path is empty.
225 225
      bool empty() const { return true;}
226 226

	
227 227
      /// \brief Forward or reverse dumping
228 228
      ///
229 229
      /// If the RevPathTag is defined and true then reverse dumping
230 230
      /// is provided in the path dumper. In this case instead of the
231 231
      /// ArcIt the RevArcIt iterator should be implemented in the
232 232
      /// dumper.
233 233
      typedef False RevPathTag;
234 234

	
235
      /// \brief Lemon style iterator for path arcs
235
      /// \brief LEMON style iterator for path arcs
236 236
      ///
237 237
      /// This class is used to iterate on the arcs of the paths.
238 238
      class ArcIt {
239 239
      public:
240 240
        /// Default constructor
241 241
        ArcIt() {}
242 242
        /// Invalid constructor
243 243
        ArcIt(Invalid) {}
244 244
        /// Constructor for first arc
245 245
        ArcIt(const PathDumper&) {}
246 246

	
247 247
        /// Conversion to Arc
248 248
        operator Arc() const { return INVALID; }
249 249

	
250 250
        /// Next arc
251 251
        ArcIt& operator++() {return *this;}
252 252

	
253 253
        /// Comparison operator
254 254
        bool operator==(const ArcIt&) const {return true;}
255 255
        /// Comparison operator
256 256
        bool operator!=(const ArcIt&) const {return true;}
257 257
        /// Comparison operator
258 258
        bool operator<(const ArcIt&) const {return false;}
259 259

	
260 260
      };
261 261

	
262
      /// \brief Lemon style iterator for path arcs
262
      /// \brief LEMON style iterator for path arcs
263 263
      ///
264 264
      /// This class is used to iterate on the arcs of the paths in
265 265
      /// reverse direction.
266 266
      class RevArcIt {
267 267
      public:
268 268
        /// Default constructor
269 269
        RevArcIt() {}
270 270
        /// Invalid constructor
271 271
        RevArcIt(Invalid) {}
272 272
        /// Constructor for first arc
273 273
        RevArcIt(const PathDumper &) {}
274 274

	
275 275
        /// Conversion to Arc
276 276
        operator Arc() const { return INVALID; }
277 277

	
278 278
        /// Next arc
279 279
        RevArcIt& operator++() {return *this;}
280 280

	
281 281
        /// Comparison operator
282 282
        bool operator==(const RevArcIt&) const {return true;}
283 283
        /// Comparison operator
284 284
        bool operator!=(const RevArcIt&) const {return true;}
285 285
        /// Comparison operator
286 286
        bool operator<(const RevArcIt&) const {return false;}
287 287

	
288 288
      };
289 289

	
290 290
      template <typename _Path>
291 291
      struct Constraints {
292 292
        void constraints() {
293 293
          function_requires<_path_bits::
294 294
            PathDumperConstraints<Digraph, _Path> >();
295 295
        }
296 296
      };
297 297

	
298 298
    };
299 299

	
300 300

	
301 301
    ///@}
302 302
  }
303 303

	
304 304
} // namespace lemon
305 305

	
306 306
#endif // LEMON_CONCEPT_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 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\ingroup lemon_io
20 20
///\file
21
///\brief \ref lgf-format "Lemon Graph Format" reader.
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/assert.h>
35 35
#include <lemon/core.h>
36 36

	
37 37
#include <lemon/lgf_writer.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 _reader_bits {
45 45

	
46 46
    template <typename Value>
47 47
    struct DefaultConverter {
48 48
      Value operator()(const std::string& str) {
49 49
        std::istringstream is(str);
50 50
        Value value;
51 51
        is >> value;
52 52

	
53 53
        char c;
54 54
        if (is >> std::ws >> c) {
55 55
          throw DataFormatError("Remaining characters in token");
56 56
        }
57 57
        return value;
58 58
      }
59 59
    };
60 60

	
61 61
    template <>
62 62
    struct DefaultConverter<std::string> {
63 63
      std::string operator()(const std::string& str) {
64 64
        return str;
65 65
      }
66 66
    };
67 67

	
68 68
    template <typename _Item>
69 69
    class MapStorageBase {
70 70
    public:
71 71
      typedef _Item Item;
72 72

	
73 73
    public:
74 74
      MapStorageBase() {}
75 75
      virtual ~MapStorageBase() {}
76 76

	
77 77
      virtual void set(const Item& item, const std::string& value) = 0;
78 78

	
79 79
    };
80 80

	
81 81
    template <typename _Item, typename _Map,
82 82
              typename _Converter = DefaultConverter<typename _Map::Value> >
83 83
    class MapStorage : public MapStorageBase<_Item> {
84 84
    public:
85 85
      typedef _Map Map;
86 86
      typedef _Converter Converter;
87 87
      typedef _Item Item;
88 88

	
89 89
    private:
90 90
      Map& _map;
91 91
      Converter _converter;
92 92

	
93 93
    public:
94 94
      MapStorage(Map& map, const Converter& converter = Converter())
95 95
        : _map(map), _converter(converter) {}
96 96
      virtual ~MapStorage() {}
97 97

	
98 98
      virtual void set(const Item& item ,const std::string& value) {
99 99
        _map.set(item, _converter(value));
100 100
      }
101 101
    };
102 102

	
103 103
    template <typename _Graph, bool _dir, typename _Map,
104 104
              typename _Converter = DefaultConverter<typename _Map::Value> >
105 105
    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
106 106
    public:
107 107
      typedef _Map Map;
108 108
      typedef _Converter Converter;
109 109
      typedef _Graph Graph;
110 110
      typedef typename Graph::Edge Item;
111 111
      static const bool dir = _dir;
112 112

	
113 113
    private:
114 114
      const Graph& _graph;
115 115
      Map& _map;
116 116
      Converter _converter;
117 117

	
118 118
    public:
119 119
      GraphArcMapStorage(const Graph& graph, Map& map,
120 120
                         const Converter& converter = Converter())
121 121
        : _graph(graph), _map(map), _converter(converter) {}
122 122
      virtual ~GraphArcMapStorage() {}
123 123

	
124 124
      virtual void set(const Item& item ,const std::string& value) {
125 125
        _map.set(_graph.direct(item, dir), _converter(value));
126 126
      }
127 127
    };
128 128

	
129 129
    class ValueStorageBase {
130 130
    public:
131 131
      ValueStorageBase() {}
132 132
      virtual ~ValueStorageBase() {}
133 133

	
134 134
      virtual void set(const std::string&) = 0;
135 135
    };
136 136

	
137 137
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
138 138
    class ValueStorage : public ValueStorageBase {
139 139
    public:
140 140
      typedef _Value Value;
141 141
      typedef _Converter Converter;
142 142

	
143 143
    private:
144 144
      Value& _value;
145 145
      Converter _converter;
146 146

	
147 147
    public:
148 148
      ValueStorage(Value& value, const Converter& converter = Converter())
149 149
        : _value(value), _converter(converter) {}
150 150

	
151 151
      virtual void set(const std::string& value) {
152 152
        _value = _converter(value);
153 153
      }
154 154
    };
155 155

	
156 156
    template <typename Value>
157 157
    struct MapLookUpConverter {
158 158
      const std::map<std::string, Value>& _map;
159 159

	
160 160
      MapLookUpConverter(const std::map<std::string, Value>& map)
161 161
        : _map(map) {}
162 162

	
163 163
      Value operator()(const std::string& str) {
164 164
        typename std::map<std::string, Value>::const_iterator it =
165 165
          _map.find(str);
166 166
        if (it == _map.end()) {
167 167
          std::ostringstream msg;
168 168
          msg << "Item not found: " << str;
169 169
          throw DataFormatError(msg.str().c_str());
170 170
        }
171 171
        return it->second;
172 172
      }
173 173
    };
174 174

	
175 175
    template <typename Graph>
176 176
    struct GraphArcLookUpConverter {
177 177
      const Graph& _graph;
178 178
      const std::map<std::string, typename Graph::Edge>& _map;
179 179

	
180 180
      GraphArcLookUpConverter(const Graph& graph,
181 181
                              const std::map<std::string,
182 182
                                             typename Graph::Edge>& map)
183 183
        : _graph(graph), _map(map) {}
184 184

	
185 185
      typename Graph::Arc operator()(const std::string& str) {
186 186
        if (str.empty() || (str[0] != '+' && str[0] != '-')) {
187 187
          throw DataFormatError("Item must start with '+' or '-'");
188 188
        }
189 189
        typename std::map<std::string, typename Graph::Edge>
190 190
          ::const_iterator it = _map.find(str.substr(1));
191 191
        if (it == _map.end()) {
192 192
          throw DataFormatError("Item not found");
193 193
        }
194 194
        return _graph.direct(it->second, str[0] == '+');
195 195
      }
196 196
    };
197 197

	
198 198
    inline bool isWhiteSpace(char c) {
199 199
      return c == ' ' || c == '\t' || c == '\v' ||
200 200
        c == '\n' || c == '\r' || c == '\f';
201 201
    }
202 202

	
203 203
    inline bool isOct(char c) {
204 204
      return '0' <= c && c <='7';
205 205
    }
206 206

	
207 207
    inline int valueOct(char c) {
208 208
      LEMON_ASSERT(isOct(c), "The character is not octal.");
209 209
      return c - '0';
210 210
    }
211 211

	
212 212
    inline bool isHex(char c) {
213 213
      return ('0' <= c && c <= '9') ||
214 214
        ('a' <= c && c <= 'z') ||
215 215
        ('A' <= c && c <= 'Z');
216 216
    }
217 217

	
218 218
    inline int valueHex(char c) {
219 219
      LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
220 220
      if ('0' <= c && c <= '9') return c - '0';
221 221
      if ('a' <= c && c <= 'z') return c - 'a' + 10;
222 222
      return c - 'A' + 10;
223 223
    }
224 224

	
225 225
    inline bool isIdentifierFirstChar(char c) {
226 226
      return ('a' <= c && c <= 'z') ||
227 227
        ('A' <= c && c <= 'Z') || c == '_';
228 228
    }
229 229

	
230 230
    inline bool isIdentifierChar(char c) {
231 231
      return isIdentifierFirstChar(c) ||
232 232
        ('0' <= c && c <= '9');
233 233
    }
234 234

	
235 235
    inline char readEscape(std::istream& is) {
236 236
      char c;
237 237
      if (!is.get(c))
238 238
        throw DataFormatError("Escape format error");
239 239

	
240 240
      switch (c) {
241 241
      case '\\':
242 242
        return '\\';
243 243
      case '\"':
244 244
        return '\"';
245 245
      case '\'':
246 246
        return '\'';
247 247
      case '\?':
248 248
        return '\?';
249 249
      case 'a':
250 250
        return '\a';
251 251
      case 'b':
252 252
        return '\b';
253 253
      case 'f':
254 254
        return '\f';
255 255
      case 'n':
256 256
        return '\n';
257 257
      case 'r':
258 258
        return '\r';
259 259
      case 't':
260 260
        return '\t';
261 261
      case 'v':
262 262
        return '\v';
263 263
      case 'x':
264 264
        {
265 265
          int code;
266 266
          if (!is.get(c) || !isHex(c))
267 267
            throw DataFormatError("Escape format error");
268 268
          else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
269 269
          else code = code * 16 + valueHex(c);
270 270
          return code;
271 271
        }
272 272
      default:
273 273
        {
274 274
          int code;
275 275
          if (!isOct(c))
276 276
            throw DataFormatError("Escape format error");
277 277
          else if (code = valueOct(c), !is.get(c) || !isOct(c))
... ...
@@ -2048,513 +2048,513 @@
2048 2048
  /// with two different functions. With the \c sectionLines() function a
2049 2049
  /// functor can process the section line-by-line, while with the \c
2050 2050
  /// sectionStream() member the section can be read from an input
2051 2051
  /// stream.
2052 2052
  class SectionReader {
2053 2053
  private:
2054 2054

	
2055 2055
    std::istream* _is;
2056 2056
    bool local_is;
2057 2057

	
2058 2058
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2059 2059
    Sections _sections;
2060 2060

	
2061 2061
    int line_num;
2062 2062
    std::istringstream line;
2063 2063

	
2064 2064
  public:
2065 2065

	
2066 2066
    /// \brief Constructor
2067 2067
    ///
2068 2068
    /// Construct a section reader, which reads from the given input
2069 2069
    /// stream.
2070 2070
    SectionReader(std::istream& is)
2071 2071
      : _is(&is), local_is(false) {}
2072 2072

	
2073 2073
    /// \brief Constructor
2074 2074
    ///
2075 2075
    /// Construct a section reader, which reads from the given file.
2076 2076
    SectionReader(const std::string& fn)
2077 2077
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2078 2078

	
2079 2079
    /// \brief Constructor
2080 2080
    ///
2081 2081
    /// Construct a section reader, which reads from the given file.
2082 2082
    SectionReader(const char* fn)
2083 2083
      : _is(new std::ifstream(fn)), local_is(true) {}
2084 2084

	
2085 2085
    /// \brief Destructor
2086 2086
    ~SectionReader() {
2087 2087
      for (Sections::iterator it = _sections.begin();
2088 2088
           it != _sections.end(); ++it) {
2089 2089
        delete it->second;
2090 2090
      }
2091 2091

	
2092 2092
      if (local_is) {
2093 2093
        delete _is;
2094 2094
      }
2095 2095

	
2096 2096
    }
2097 2097

	
2098 2098
  private:
2099 2099

	
2100 2100
    friend SectionReader sectionReader(std::istream& is);
2101 2101
    friend SectionReader sectionReader(const std::string& fn);
2102 2102
    friend SectionReader sectionReader(const char* fn);
2103 2103

	
2104 2104
    SectionReader(SectionReader& other)
2105 2105
      : _is(other._is), local_is(other.local_is) {
2106 2106

	
2107 2107
      other._is = 0;
2108 2108
      other.local_is = false;
2109 2109

	
2110 2110
      _sections.swap(other._sections);
2111 2111
    }
2112 2112

	
2113 2113
    SectionReader& operator=(const SectionReader&);
2114 2114

	
2115 2115
  public:
2116 2116

	
2117 2117
    /// \name Section readers
2118 2118
    /// @{
2119 2119

	
2120 2120
    /// \brief Add a section processor with line oriented reading
2121 2121
    ///
2122 2122
    /// The first parameter is the type descriptor of the section, the
2123 2123
    /// second is a functor, which takes just one \c std::string
2124 2124
    /// parameter. At the reading process, each line of the section
2125 2125
    /// will be given to the functor object. However, the empty lines
2126 2126
    /// and the comment lines are filtered out, and the leading
2127 2127
    /// whitespaces are trimmed from each processed string.
2128 2128
    ///
2129 2129
    /// For example let's see a section, which contain several
2130 2130
    /// integers, which should be inserted into a vector.
2131 2131
    ///\code
2132 2132
    ///  @numbers
2133 2133
    ///  12 45 23
2134 2134
    ///  4
2135 2135
    ///  23 6
2136 2136
    ///\endcode
2137 2137
    ///
2138 2138
    /// The functor is implemented as a struct:
2139 2139
    ///\code
2140 2140
    ///  struct NumberSection {
2141 2141
    ///    std::vector<int>& _data;
2142 2142
    ///    NumberSection(std::vector<int>& data) : _data(data) {}
2143 2143
    ///    void operator()(const std::string& line) {
2144 2144
    ///      std::istringstream ls(line);
2145 2145
    ///      int value;
2146 2146
    ///      while (ls >> value) _data.push_back(value);
2147 2147
    ///    }
2148 2148
    ///  };
2149 2149
    ///
2150 2150
    ///  // ...
2151 2151
    ///
2152 2152
    ///  reader.sectionLines("numbers", NumberSection(vec));
2153 2153
    ///\endcode
2154 2154
    template <typename Functor>
2155 2155
    SectionReader& sectionLines(const std::string& type, Functor functor) {
2156 2156
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2157 2157
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2158 2158
                   "Multiple reading of section.");
2159 2159
      _sections.insert(std::make_pair(type,
2160 2160
        new _reader_bits::LineSection<Functor>(functor)));
2161 2161
      return *this;
2162 2162
    }
2163 2163

	
2164 2164

	
2165 2165
    /// \brief Add a section processor with stream oriented reading
2166 2166
    ///
2167 2167
    /// The first parameter is the type of the section, the second is
2168 2168
    /// a functor, which takes an \c std::istream& and an \c int&
2169 2169
    /// parameter, the latter regard to the line number of stream. The
2170 2170
    /// functor can read the input while the section go on, and the
2171 2171
    /// line number should be modified accordingly.
2172 2172
    template <typename Functor>
2173 2173
    SectionReader& sectionStream(const std::string& type, Functor functor) {
2174 2174
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2175 2175
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2176 2176
                   "Multiple reading of section.");
2177 2177
      _sections.insert(std::make_pair(type,
2178 2178
         new _reader_bits::StreamSection<Functor>(functor)));
2179 2179
      return *this;
2180 2180
    }
2181 2181

	
2182 2182
    /// @}
2183 2183

	
2184 2184
  private:
2185 2185

	
2186 2186
    bool readLine() {
2187 2187
      std::string str;
2188 2188
      while(++line_num, std::getline(*_is, str)) {
2189 2189
        line.clear(); line.str(str);
2190 2190
        char c;
2191 2191
        if (line >> std::ws >> c && c != '#') {
2192 2192
          line.putback(c);
2193 2193
          return true;
2194 2194
        }
2195 2195
      }
2196 2196
      return false;
2197 2197
    }
2198 2198

	
2199 2199
    bool readSuccess() {
2200 2200
      return static_cast<bool>(*_is);
2201 2201
    }
2202 2202

	
2203 2203
    void skipSection() {
2204 2204
      char c;
2205 2205
      while (readSuccess() && line >> c && c != '@') {
2206 2206
        readLine();
2207 2207
      }
2208 2208
      line.putback(c);
2209 2209
    }
2210 2210

	
2211 2211
  public:
2212 2212

	
2213 2213

	
2214 2214
    /// \name Execution of the reader
2215 2215
    /// @{
2216 2216

	
2217 2217
    /// \brief Start the batch processing
2218 2218
    ///
2219 2219
    /// This function starts the batch processing.
2220 2220
    void run() {
2221 2221

	
2222 2222
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2223 2223

	
2224 2224
      std::set<std::string> extra_sections;
2225 2225

	
2226 2226
      line_num = 0;
2227 2227
      readLine();
2228 2228
      skipSection();
2229 2229

	
2230 2230
      while (readSuccess()) {
2231 2231
        try {
2232 2232
          char c;
2233 2233
          std::string section, caption;
2234 2234
          line >> c;
2235 2235
          _reader_bits::readToken(line, section);
2236 2236
          _reader_bits::readToken(line, caption);
2237 2237

	
2238 2238
          if (line >> c)
2239 2239
            throw DataFormatError("Extra character on the end of line");
2240 2240

	
2241 2241
          if (extra_sections.find(section) != extra_sections.end()) {
2242 2242
            std::ostringstream msg;
2243 2243
            msg << "Multiple occurence of section " << section;
2244 2244
            throw DataFormatError(msg.str().c_str());
2245 2245
          }
2246 2246
          Sections::iterator it = _sections.find(section);
2247 2247
          if (it != _sections.end()) {
2248 2248
            extra_sections.insert(section);
2249 2249
            it->second->process(*_is, line_num);
2250 2250
          }
2251 2251
          readLine();
2252 2252
          skipSection();
2253 2253
        } catch (DataFormatError& error) {
2254 2254
          error.line(line_num);
2255 2255
          throw;
2256 2256
        }
2257 2257
      }
2258 2258
      for (Sections::iterator it = _sections.begin();
2259 2259
           it != _sections.end(); ++it) {
2260 2260
        if (extra_sections.find(it->first) == extra_sections.end()) {
2261 2261
          std::ostringstream os;
2262 2262
          os << "Cannot find section: " << it->first;
2263 2263
          throw DataFormatError(os.str().c_str());
2264 2264
        }
2265 2265
      }
2266 2266
    }
2267 2267

	
2268 2268
    /// @}
2269 2269

	
2270 2270
  };
2271 2271

	
2272 2272
  /// \brief Return a \ref SectionReader class
2273 2273
  ///
2274 2274
  /// This function just returns a \ref SectionReader class.
2275 2275
  /// \relates SectionReader
2276 2276
  inline SectionReader sectionReader(std::istream& is) {
2277 2277
    SectionReader tmp(is);
2278 2278
    return tmp;
2279 2279
  }
2280 2280

	
2281 2281
  /// \brief Return a \ref SectionReader class
2282 2282
  ///
2283 2283
  /// This function just returns a \ref SectionReader class.
2284 2284
  /// \relates SectionReader
2285 2285
  inline SectionReader sectionReader(const std::string& fn) {
2286 2286
    SectionReader tmp(fn);
2287 2287
    return tmp;
2288 2288
  }
2289 2289

	
2290 2290
  /// \brief Return a \ref SectionReader class
2291 2291
  ///
2292 2292
  /// This function just returns a \ref SectionReader class.
2293 2293
  /// \relates SectionReader
2294 2294
  inline SectionReader sectionReader(const char* fn) {
2295 2295
    SectionReader tmp(fn);
2296 2296
    return tmp;
2297 2297
  }
2298 2298

	
2299 2299
  /// \ingroup lemon_io
2300 2300
  ///
2301 2301
  /// \brief Reader for the contents of the \ref lgf-format "LGF" file
2302 2302
  ///
2303 2303
  /// This class can be used to read the sections, the map names and
2304
  /// the attributes from a file. Usually, the Lemon programs know
2304
  /// the attributes from a file. Usually, the LEMON programs know
2305 2305
  /// that, which type of graph, which maps and which attributes
2306 2306
  /// should be read from a file, but in general tools (like glemon)
2307 2307
  /// the contents of an LGF file should be guessed somehow. This class
2308 2308
  /// reads the graph and stores the appropriate information for
2309 2309
  /// reading the graph.
2310 2310
  ///
2311 2311
  ///\code
2312 2312
  /// LgfContents contents("graph.lgf");
2313 2313
  /// contents.run();
2314 2314
  ///
2315 2315
  /// // Does it contain any node section and arc section?
2316 2316
  /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
2317 2317
  ///   std::cerr << "Failure, cannot find graph." << std::endl;
2318 2318
  ///   return -1;
2319 2319
  /// }
2320 2320
  /// std::cout << "The name of the default node section: "
2321 2321
  ///           << contents.nodeSection(0) << std::endl;
2322 2322
  /// std::cout << "The number of the arc maps: "
2323 2323
  ///           << contents.arcMaps(0).size() << std::endl;
2324 2324
  /// std::cout << "The name of second arc map: "
2325 2325
  ///           << contents.arcMaps(0)[1] << std::endl;
2326 2326
  ///\endcode
2327 2327
  class LgfContents {
2328 2328
  private:
2329 2329

	
2330 2330
    std::istream* _is;
2331 2331
    bool local_is;
2332 2332

	
2333 2333
    std::vector<std::string> _node_sections;
2334 2334
    std::vector<std::string> _edge_sections;
2335 2335
    std::vector<std::string> _attribute_sections;
2336 2336
    std::vector<std::string> _extra_sections;
2337 2337

	
2338 2338
    std::vector<bool> _arc_sections;
2339 2339

	
2340 2340
    std::vector<std::vector<std::string> > _node_maps;
2341 2341
    std::vector<std::vector<std::string> > _edge_maps;
2342 2342

	
2343 2343
    std::vector<std::vector<std::string> > _attributes;
2344 2344

	
2345 2345

	
2346 2346
    int line_num;
2347 2347
    std::istringstream line;
2348 2348

	
2349 2349
  public:
2350 2350

	
2351 2351
    /// \brief Constructor
2352 2352
    ///
2353 2353
    /// Construct an \e LGF contents reader, which reads from the given
2354 2354
    /// input stream.
2355 2355
    LgfContents(std::istream& is)
2356 2356
      : _is(&is), local_is(false) {}
2357 2357

	
2358 2358
    /// \brief Constructor
2359 2359
    ///
2360 2360
    /// Construct an \e LGF contents reader, which reads from the given
2361 2361
    /// file.
2362 2362
    LgfContents(const std::string& fn)
2363 2363
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2364 2364

	
2365 2365
    /// \brief Constructor
2366 2366
    ///
2367 2367
    /// Construct an \e LGF contents reader, which reads from the given
2368 2368
    /// file.
2369 2369
    LgfContents(const char* fn)
2370 2370
      : _is(new std::ifstream(fn)), local_is(true) {}
2371 2371

	
2372 2372
    /// \brief Destructor
2373 2373
    ~LgfContents() {
2374 2374
      if (local_is) delete _is;
2375 2375
    }
2376 2376

	
2377 2377
  private:
2378 2378

	
2379 2379
    LgfContents(const LgfContents&);
2380 2380
    LgfContents& operator=(const LgfContents&);
2381 2381

	
2382 2382
  public:
2383 2383

	
2384 2384

	
2385 2385
    /// \name Node sections
2386 2386
    /// @{
2387 2387

	
2388 2388
    /// \brief Gives back the number of node sections in the file.
2389 2389
    ///
2390 2390
    /// Gives back the number of node sections in the file.
2391 2391
    int nodeSectionNum() const {
2392 2392
      return _node_sections.size();
2393 2393
    }
2394 2394

	
2395 2395
    /// \brief Returns the node section name at the given position.
2396 2396
    ///
2397 2397
    /// Returns the node section name at the given position.
2398 2398
    const std::string& nodeSection(int i) const {
2399 2399
      return _node_sections[i];
2400 2400
    }
2401 2401

	
2402 2402
    /// \brief Gives back the node maps for the given section.
2403 2403
    ///
2404 2404
    /// Gives back the node maps for the given section.
2405 2405
    const std::vector<std::string>& nodeMapNames(int i) const {
2406 2406
      return _node_maps[i];
2407 2407
    }
2408 2408

	
2409 2409
    /// @}
2410 2410

	
2411 2411
    /// \name Arc/Edge sections
2412 2412
    /// @{
2413 2413

	
2414 2414
    /// \brief Gives back the number of arc/edge sections in the file.
2415 2415
    ///
2416 2416
    /// Gives back the number of arc/edge sections in the file.
2417 2417
    /// \note It is synonym of \c edgeSectionNum().
2418 2418
    int arcSectionNum() const {
2419 2419
      return _edge_sections.size();
2420 2420
    }
2421 2421

	
2422 2422
    /// \brief Returns the arc/edge section name at the given position.
2423 2423
    ///
2424 2424
    /// Returns the arc/edge section name at the given position.
2425 2425
    /// \note It is synonym of \c edgeSection().
2426 2426
    const std::string& arcSection(int i) const {
2427 2427
      return _edge_sections[i];
2428 2428
    }
2429 2429

	
2430 2430
    /// \brief Gives back the arc/edge maps for the given section.
2431 2431
    ///
2432 2432
    /// Gives back the arc/edge maps for the given section.
2433 2433
    /// \note It is synonym of \c edgeMapNames().
2434 2434
    const std::vector<std::string>& arcMapNames(int i) const {
2435 2435
      return _edge_maps[i];
2436 2436
    }
2437 2437

	
2438 2438
    /// @}
2439 2439

	
2440 2440
    /// \name Synonyms
2441 2441
    /// @{
2442 2442

	
2443 2443
    /// \brief Gives back the number of arc/edge sections in the file.
2444 2444
    ///
2445 2445
    /// Gives back the number of arc/edge sections in the file.
2446 2446
    /// \note It is synonym of \c arcSectionNum().
2447 2447
    int edgeSectionNum() const {
2448 2448
      return _edge_sections.size();
2449 2449
    }
2450 2450

	
2451 2451
    /// \brief Returns the section name at the given position.
2452 2452
    ///
2453 2453
    /// Returns the section name at the given position.
2454 2454
    /// \note It is synonym of \c arcSection().
2455 2455
    const std::string& edgeSection(int i) const {
2456 2456
      return _edge_sections[i];
2457 2457
    }
2458 2458

	
2459 2459
    /// \brief Gives back the edge maps for the given section.
2460 2460
    ///
2461 2461
    /// Gives back the edge maps for the given section.
2462 2462
    /// \note It is synonym of \c arcMapNames().
2463 2463
    const std::vector<std::string>& edgeMapNames(int i) const {
2464 2464
      return _edge_maps[i];
2465 2465
    }
2466 2466

	
2467 2467
    /// @}
2468 2468

	
2469 2469
    /// \name Attribute sections
2470 2470
    /// @{
2471 2471

	
2472 2472
    /// \brief Gives back the number of attribute sections in the file.
2473 2473
    ///
2474 2474
    /// Gives back the number of attribute sections in the file.
2475 2475
    int attributeSectionNum() const {
2476 2476
      return _attribute_sections.size();
2477 2477
    }
2478 2478

	
2479 2479
    /// \brief Returns the attribute section name at the given position.
2480 2480
    ///
2481 2481
    /// Returns the attribute section name at the given position.
2482 2482
    const std::string& attributeSectionNames(int i) const {
2483 2483
      return _attribute_sections[i];
2484 2484
    }
2485 2485

	
2486 2486
    /// \brief Gives back the attributes for the given section.
2487 2487
    ///
2488 2488
    /// Gives back the attributes for the given section.
2489 2489
    const std::vector<std::string>& attributes(int i) const {
2490 2490
      return _attributes[i];
2491 2491
    }
2492 2492

	
2493 2493
    /// @}
2494 2494

	
2495 2495
    /// \name Extra sections
2496 2496
    /// @{
2497 2497

	
2498 2498
    /// \brief Gives back the number of extra sections in the file.
2499 2499
    ///
2500 2500
    /// Gives back the number of extra sections in the file.
2501 2501
    int extraSectionNum() const {
2502 2502
      return _extra_sections.size();
2503 2503
    }
2504 2504

	
2505 2505
    /// \brief Returns the extra section type at the given position.
2506 2506
    ///
2507 2507
    /// Returns the section type at the given position.
2508 2508
    const std::string& extraSection(int i) const {
2509 2509
      return _extra_sections[i];
2510 2510
    }
2511 2511

	
2512 2512
    /// @}
2513 2513

	
2514 2514
  private:
2515 2515

	
2516 2516
    bool readLine() {
2517 2517
      std::string str;
2518 2518
      while(++line_num, std::getline(*_is, str)) {
2519 2519
        line.clear(); line.str(str);
2520 2520
        char c;
2521 2521
        if (line >> std::ws >> c && c != '#') {
2522 2522
          line.putback(c);
2523 2523
          return true;
2524 2524
        }
2525 2525
      }
2526 2526
      return false;
2527 2527
    }
2528 2528

	
2529 2529
    bool readSuccess() {
2530 2530
      return static_cast<bool>(*_is);
2531 2531
    }
2532 2532

	
2533 2533
    void skipSection() {
2534 2534
      char c;
2535 2535
      while (readSuccess() && line >> c && c != '@') {
2536 2536
        readLine();
2537 2537
      }
2538 2538
      line.putback(c);
2539 2539
    }
2540 2540

	
2541 2541
    void readMaps(std::vector<std::string>& maps) {
2542 2542
      char c;
2543 2543
      if (!readLine() || !(line >> c) || c == '@') {
2544 2544
        if (readSuccess() && line) line.putback(c);
2545 2545
        return;
2546 2546
      }
2547 2547
      line.putback(c);
2548 2548
      std::string map;
2549 2549
      while (_reader_bits::readToken(line, map)) {
2550 2550
        maps.push_back(map);
2551 2551
      }
2552 2552
    }
2553 2553

	
2554 2554
    void readAttributes(std::vector<std::string>& attrs) {
2555 2555
      readLine();
2556 2556
      char c;
2557 2557
      while (readSuccess() && line >> c && c != '@') {
2558 2558
        line.putback(c);
2559 2559
        std::string attr;
2560 2560
        _reader_bits::readToken(line, attr);
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-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\ingroup lemon_io
20 20
///\file
21
///\brief \ref lgf-format "Lemon Graph Format" writer.
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/assert.h>
37 37
#include <lemon/core.h>
38 38
#include <lemon/maps.h>
39 39

	
40 40
namespace lemon {
41 41

	
42 42
  namespace _writer_bits {
43 43

	
44 44
    template <typename Value>
45 45
    struct DefaultConverter {
46 46
      std::string operator()(const Value& value) {
47 47
        std::ostringstream os;
48 48
        os << value;
49 49
        return os.str();
50 50
      }
51 51
    };
52 52

	
53 53
    template <typename T>
54 54
    bool operator<(const T&, const T&) {
55 55
      throw DataFormatError("Label map is not comparable");
56 56
    }
57 57

	
58 58
    template <typename _Map>
59 59
    class MapLess {
60 60
    public:
61 61
      typedef _Map Map;
62 62
      typedef typename Map::Key Item;
63 63

	
64 64
    private:
65 65
      const Map& _map;
66 66

	
67 67
    public:
68 68
      MapLess(const Map& map) : _map(map) {}
69 69

	
70 70
      bool operator()(const Item& left, const Item& right) {
71 71
        return _map[left] < _map[right];
72 72
      }
73 73
    };
74 74

	
75 75
    template <typename _Graph, bool _dir, typename _Map>
76 76
    class GraphArcMapLess {
77 77
    public:
78 78
      typedef _Map Map;
79 79
      typedef _Graph Graph;
80 80
      typedef typename Graph::Edge Item;
81 81

	
82 82
    private:
83 83
      const Graph& _graph;
84 84
      const Map& _map;
85 85

	
86 86
    public:
87 87
      GraphArcMapLess(const Graph& graph, const Map& map)
88 88
        : _graph(graph), _map(map) {}
89 89

	
90 90
      bool operator()(const Item& left, const Item& right) {
91 91
        return _map[_graph.direct(left, _dir)] <
92 92
          _map[_graph.direct(right, _dir)];
93 93
      }
94 94
    };
95 95

	
96 96
    template <typename _Item>
97 97
    class MapStorageBase {
98 98
    public:
99 99
      typedef _Item Item;
100 100

	
101 101
    public:
102 102
      MapStorageBase() {}
103 103
      virtual ~MapStorageBase() {}
104 104

	
105 105
      virtual std::string get(const Item& item) = 0;
106 106
      virtual void sort(std::vector<Item>&) = 0;
107 107
    };
108 108

	
109 109
    template <typename _Item, typename _Map,
110 110
              typename _Converter = DefaultConverter<typename _Map::Value> >
111 111
    class MapStorage : public MapStorageBase<_Item> {
112 112
    public:
113 113
      typedef _Map Map;
114 114
      typedef _Converter Converter;
115 115
      typedef _Item Item;
116 116

	
117 117
    private:
118 118
      const Map& _map;
119 119
      Converter _converter;
120 120

	
121 121
    public:
122 122
      MapStorage(const Map& map, const Converter& converter = Converter())
123 123
        : _map(map), _converter(converter) {}
124 124
      virtual ~MapStorage() {}
125 125

	
126 126
      virtual std::string get(const Item& item) {
127 127
        return _converter(_map[item]);
128 128
      }
129 129
      virtual void sort(std::vector<Item>& items) {
130 130
        MapLess<Map> less(_map);
131 131
        std::sort(items.begin(), items.end(), less);
132 132
      }
133 133
    };
134 134

	
135 135
    template <typename _Graph, bool _dir, typename _Map,
136 136
              typename _Converter = DefaultConverter<typename _Map::Value> >
137 137
    class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
138 138
    public:
139 139
      typedef _Map Map;
140 140
      typedef _Converter Converter;
141 141
      typedef _Graph Graph;
142 142
      typedef typename Graph::Edge Item;
143 143
      static const bool dir = _dir;
144 144

	
145 145
    private:
146 146
      const Graph& _graph;
147 147
      const Map& _map;
148 148
      Converter _converter;
149 149

	
150 150
    public:
151 151
      GraphArcMapStorage(const Graph& graph, const Map& map,
152 152
                         const Converter& converter = Converter())
153 153
        : _graph(graph), _map(map), _converter(converter) {}
154 154
      virtual ~GraphArcMapStorage() {}
155 155

	
156 156
      virtual std::string get(const Item& item) {
157 157
        return _converter(_map[_graph.direct(item, dir)]);
158 158
      }
159 159
      virtual void sort(std::vector<Item>& items) {
160 160
        GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
161 161
        std::sort(items.begin(), items.end(), less);
162 162
      }
163 163
    };
164 164

	
165 165
    class ValueStorageBase {
166 166
    public:
167 167
      ValueStorageBase() {}
168 168
      virtual ~ValueStorageBase() {}
169 169

	
170 170
      virtual std::string get() = 0;
171 171
    };
172 172

	
173 173
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
174 174
    class ValueStorage : public ValueStorageBase {
175 175
    public:
176 176
      typedef _Value Value;
177 177
      typedef _Converter Converter;
178 178

	
179 179
    private:
180 180
      const Value& _value;
181 181
      Converter _converter;
182 182

	
183 183
    public:
184 184
      ValueStorage(const Value& value, const Converter& converter = Converter())
185 185
        : _value(value), _converter(converter) {}
186 186

	
187 187
      virtual std::string get() {
188 188
        return _converter(_value);
189 189
      }
190 190
    };
191 191

	
192 192
    template <typename Value>
193 193
    struct MapLookUpConverter {
194 194
      const std::map<Value, std::string>& _map;
195 195

	
196 196
      MapLookUpConverter(const std::map<Value, std::string>& map)
197 197
        : _map(map) {}
198 198

	
199 199
      std::string operator()(const Value& str) {
200 200
        typename std::map<Value, std::string>::const_iterator it =
201 201
          _map.find(str);
202 202
        if (it == _map.end()) {
203 203
          throw DataFormatError("Item not found");
204 204
        }
205 205
        return it->second;
206 206
      }
207 207
    };
208 208

	
209 209
    template <typename Graph>
210 210
    struct GraphArcLookUpConverter {
211 211
      const Graph& _graph;
212 212
      const std::map<typename Graph::Edge, std::string>& _map;
213 213

	
214 214
      GraphArcLookUpConverter(const Graph& graph,
215 215
                              const std::map<typename Graph::Edge,
216 216
                                             std::string>& map)
217 217
        : _graph(graph), _map(map) {}
218 218

	
219 219
      std::string operator()(const typename Graph::Arc& val) {
220 220
        typename std::map<typename Graph::Edge, std::string>
221 221
          ::const_iterator it = _map.find(val);
222 222
        if (it == _map.end()) {
223 223
          throw DataFormatError("Item not found");
224 224
        }
225 225
        return (_graph.direction(val) ? '+' : '-') + it->second;
226 226
      }
227 227
    };
228 228

	
229 229
    inline bool isWhiteSpace(char c) {
230 230
      return c == ' ' || c == '\t' || c == '\v' ||
231 231
        c == '\n' || c == '\r' || c == '\f';
232 232
    }
233 233

	
234 234
    inline bool isEscaped(char c) {
235 235
      return c == '\\' || c == '\"' || c == '\'' ||
236 236
        c == '\a' || c == '\b';
237 237
    }
238 238

	
239 239
    inline static void writeEscape(std::ostream& os, char c) {
240 240
      switch (c) {
241 241
      case '\\':
242 242
        os << "\\\\";
243 243
        return;
244 244
      case '\"':
245 245
        os << "\\\"";
246 246
        return;
247 247
      case '\a':
248 248
        os << "\\a";
249 249
        return;
250 250
      case '\b':
251 251
        os << "\\b";
252 252
        return;
253 253
      case '\f':
254 254
        os << "\\f";
255 255
        return;
256 256
      case '\r':
257 257
        os << "\\r";
258 258
        return;
259 259
      case '\n':
260 260
        os << "\\n";
261 261
        return;
262 262
      case '\t':
263 263
        os << "\\t";
264 264
        return;
265 265
      case '\v':
266 266
        os << "\\v";
267 267
        return;
268 268
      default:
269 269
        if (c < 0x20) {
270 270
          std::ios::fmtflags flags = os.flags();
271 271
          os << '\\' << std::oct << static_cast<int>(c);
272 272
          os.flags(flags);
273 273
        } else {
274 274
          os << c;
275 275
        }
276 276
        return;
277 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 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\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 _Digraph 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 _Digraph>
56 56
  class Path {
57 57
  public:
58 58

	
59 59
    typedef _Digraph 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
      copyPath(*this, cpath);
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
      copyPath(*this, cpath);
82 82
      return *this;
83 83
    }
84 84

	
85
    /// \brief Lemon style iterator for path arcs
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 n is in the [0..length() - 1] 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 n is in the [0..length() - 1] 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 _Digraph 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 _Digraph>
244 244
  class SimplePath {
245 245
  public:
246 246

	
247 247
    typedef _Digraph 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
      copyPath(*this, cpath);
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
      copyPath(*this, cpath);
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 n is in the [0..length() - 1] 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

	
Ignore white space 6 line context
... ...
@@ -244,875 +244,875 @@
244 244
        int next = items[idx].parent;
245 245
        const_cast<int&>(items[idx].parent) = k;
246 246
        idx = next;
247 247
      }
248 248
      return k;
249 249
    }
250 250

	
251 251
    int classIndex(int idx) const {
252 252
      return ~(items[repIndex(idx)].parent);
253 253
    }
254 254

	
255 255
    void singletonItem(int idx) {
256 256
      items[idx].next = idx;
257 257
      items[idx].prev = idx;
258 258
    }
259 259

	
260 260
    void laceItem(int idx, int rdx) {
261 261
      items[idx].prev = rdx;
262 262
      items[idx].next = items[rdx].next;
263 263
      items[items[rdx].next].prev = idx;
264 264
      items[rdx].next = idx;
265 265
    }
266 266

	
267 267
    void unlaceItem(int idx) {
268 268
      items[items[idx].prev].next = items[idx].next;
269 269
      items[items[idx].next].prev = items[idx].prev;
270 270

	
271 271
      items[idx].next = firstFreeItem;
272 272
      firstFreeItem = idx;
273 273
    }
274 274

	
275 275
    void spliceItems(int ak, int bk) {
276 276
      items[items[ak].prev].next = bk;
277 277
      items[items[bk].prev].next = ak;
278 278
      int tmp = items[ak].prev;
279 279
      items[ak].prev = items[bk].prev;
280 280
      items[bk].prev = tmp;
281 281

	
282 282
    }
283 283

	
284 284
    void laceClass(int cls) {
285 285
      if (firstClass != -1) {
286 286
        classes[firstClass].prev = cls;
287 287
      }
288 288
      classes[cls].next = firstClass;
289 289
      classes[cls].prev = -1;
290 290
      firstClass = cls;
291 291
    }
292 292

	
293 293
    void unlaceClass(int cls) {
294 294
      if (classes[cls].prev != -1) {
295 295
        classes[classes[cls].prev].next = classes[cls].next;
296 296
      } else {
297 297
        firstClass = classes[cls].next;
298 298
      }
299 299
      if (classes[cls].next != -1) {
300 300
        classes[classes[cls].next].prev = classes[cls].prev;
301 301
      }
302 302

	
303 303
      classes[cls].next = firstFreeClass;
304 304
      firstFreeClass = cls;
305 305
    }
306 306

	
307 307
  public:
308 308

	
309 309
    UnionFindEnum(ItemIntMap& _index)
310 310
      : index(_index), items(), firstFreeItem(-1),
311 311
        firstClass(-1), firstFreeClass(-1) {}
312 312

	
313 313
    /// \brief Inserts the given element into a new component.
314 314
    ///
315 315
    /// This method creates a new component consisting only of the
316 316
    /// given element.
317 317
    ///
318 318
    int insert(const Item& item) {
319 319
      int idx = newItem();
320 320

	
321 321
      index.set(item, idx);
322 322

	
323 323
      singletonItem(idx);
324 324
      items[idx].item = item;
325 325

	
326 326
      int cdx = newClass();
327 327

	
328 328
      items[idx].parent = ~cdx;
329 329

	
330 330
      laceClass(cdx);
331 331
      classes[cdx].size = 1;
332 332
      classes[cdx].firstItem = idx;
333 333

	
334 334
      firstClass = cdx;
335 335

	
336 336
      return cdx;
337 337
    }
338 338

	
339 339
    /// \brief Inserts the given element into the component of the others.
340 340
    ///
341 341
    /// This methods inserts the element \e a into the component of the
342 342
    /// element \e comp.
343 343
    void insert(const Item& item, int cls) {
344 344
      int rdx = classes[cls].firstItem;
345 345
      int idx = newItem();
346 346

	
347 347
      index.set(item, idx);
348 348

	
349 349
      laceItem(idx, rdx);
350 350

	
351 351
      items[idx].item = item;
352 352
      items[idx].parent = rdx;
353 353

	
354 354
      ++classes[~(items[rdx].parent)].size;
355 355
    }
356 356

	
357 357
    /// \brief Clears the union-find data structure
358 358
    ///
359 359
    /// Erase each item from the data structure.
360 360
    void clear() {
361 361
      items.clear();
362 362
      firstClass = -1;
363 363
      firstFreeItem = -1;
364 364
    }
365 365

	
366 366
    /// \brief Finds the component of the given element.
367 367
    ///
368 368
    /// The method returns the component id of the given element.
369 369
    int find(const Item &item) const {
370 370
      return ~(items[repIndex(index[item])].parent);
371 371
    }
372 372

	
373 373
    /// \brief Joining the component of element \e a and element \e b.
374 374
    ///
375 375
    /// This is the \e union operation of the Union-Find structure.
376 376
    /// Joins the component of element \e a and component of
377 377
    /// element \e b. If \e a and \e b are in the same component then
378 378
    /// returns -1 else returns the remaining class.
379 379
    int join(const Item& a, const Item& b) {
380 380

	
381 381
      int ak = repIndex(index[a]);
382 382
      int bk = repIndex(index[b]);
383 383

	
384 384
      if (ak == bk) {
385 385
        return -1;
386 386
      }
387 387

	
388 388
      int acx = ~(items[ak].parent);
389 389
      int bcx = ~(items[bk].parent);
390 390

	
391 391
      int rcx;
392 392

	
393 393
      if (classes[acx].size > classes[bcx].size) {
394 394
        classes[acx].size += classes[bcx].size;
395 395
        items[bk].parent = ak;
396 396
        unlaceClass(bcx);
397 397
        rcx = acx;
398 398
      } else {
399 399
        classes[bcx].size += classes[acx].size;
400 400
        items[ak].parent = bk;
401 401
        unlaceClass(acx);
402 402
        rcx = bcx;
403 403
      }
404 404
      spliceItems(ak, bk);
405 405

	
406 406
      return rcx;
407 407
    }
408 408

	
409 409
    /// \brief Returns the size of the class.
410 410
    ///
411 411
    /// Returns the size of the class.
412 412
    int size(int cls) const {
413 413
      return classes[cls].size;
414 414
    }
415 415

	
416 416
    /// \brief Splits up the component.
417 417
    ///
418 418
    /// Splitting the component into singleton components (component
419 419
    /// of size one).
420 420
    void split(int cls) {
421 421
      int fdx = classes[cls].firstItem;
422 422
      int idx = items[fdx].next;
423 423
      while (idx != fdx) {
424 424
        int next = items[idx].next;
425 425

	
426 426
        singletonItem(idx);
427 427

	
428 428
        int cdx = newClass();
429 429
        items[idx].parent = ~cdx;
430 430

	
431 431
        laceClass(cdx);
432 432
        classes[cdx].size = 1;
433 433
        classes[cdx].firstItem = idx;
434 434

	
435 435
        idx = next;
436 436
      }
437 437

	
438 438
      items[idx].prev = idx;
439 439
      items[idx].next = idx;
440 440

	
441 441
      classes[~(items[idx].parent)].size = 1;
442 442

	
443 443
    }
444 444

	
445 445
    /// \brief Removes the given element from the structure.
446 446
    ///
447 447
    /// Removes the element from its component and if the component becomes
448 448
    /// empty then removes that component from the component list.
449 449
    ///
450 450
    /// \warning It is an error to remove an element which is not in
451 451
    /// the structure.
452 452
    /// \warning This running time of this operation is proportional to the
453 453
    /// number of the items in this class.
454 454
    void erase(const Item& item) {
455 455
      int idx = index[item];
456 456
      int fdx = items[idx].next;
457 457

	
458 458
      int cdx = classIndex(idx);
459 459
      if (idx == fdx) {
460 460
        unlaceClass(cdx);
461 461
        items[idx].next = firstFreeItem;
462 462
        firstFreeItem = idx;
463 463
        return;
464 464
      } else {
465 465
        classes[cdx].firstItem = fdx;
466 466
        --classes[cdx].size;
467 467
        items[fdx].parent = ~cdx;
468 468

	
469 469
        unlaceItem(idx);
470 470
        idx = items[fdx].next;
471 471
        while (idx != fdx) {
472 472
          items[idx].parent = fdx;
473 473
          idx = items[idx].next;
474 474
        }
475 475

	
476 476
      }
477 477

	
478 478
    }
479 479

	
480 480
    /// \brief Gives back a representant item of the component.
481 481
    ///
482 482
    /// Gives back a representant item of the component.
483 483
    Item item(int cls) const {
484 484
      return items[classes[cls].firstItem].item;
485 485
    }
486 486

	
487 487
    /// \brief Removes the component of the given element from the structure.
488 488
    ///
489 489
    /// Removes the component of the given element from the structure.
490 490
    ///
491 491
    /// \warning It is an error to give an element which is not in the
492 492
    /// structure.
493 493
    void eraseClass(int cls) {
494 494
      int fdx = classes[cls].firstItem;
495 495
      unlaceClass(cls);
496 496
      items[items[fdx].prev].next = firstFreeItem;
497 497
      firstFreeItem = fdx;
498 498
    }
499 499

	
500
    /// \brief Lemon style iterator for the representant items.
500
    /// \brief LEMON style iterator for the representant items.
501 501
    ///
502 502
    /// ClassIt is a lemon style iterator for the components. It iterates
503 503
    /// on the ids of the classes.
504 504
    class ClassIt {
505 505
    public:
506 506
      /// \brief Constructor of the iterator
507 507
      ///
508 508
      /// Constructor of the iterator
509 509
      ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) {
510 510
        cdx = unionFind->firstClass;
511 511
      }
512 512

	
513 513
      /// \brief Constructor to get invalid iterator
514 514
      ///
515 515
      /// Constructor to get invalid iterator
516 516
      ClassIt(Invalid) : unionFind(0), cdx(-1) {}
517 517

	
518 518
      /// \brief Increment operator
519 519
      ///
520 520
      /// It steps to the next representant item.
521 521
      ClassIt& operator++() {
522 522
        cdx = unionFind->classes[cdx].next;
523 523
        return *this;
524 524
      }
525 525

	
526 526
      /// \brief Conversion operator
527 527
      ///
528 528
      /// It converts the iterator to the current representant item.
529 529
      operator int() const {
530 530
        return cdx;
531 531
      }
532 532

	
533 533
      /// \brief Equality operator
534 534
      ///
535 535
      /// Equality operator
536 536
      bool operator==(const ClassIt& i) {
537 537
        return i.cdx == cdx;
538 538
      }
539 539

	
540 540
      /// \brief Inequality operator
541 541
      ///
542 542
      /// Inequality operator
543 543
      bool operator!=(const ClassIt& i) {
544 544
        return i.cdx != cdx;
545 545
      }
546 546

	
547 547
    private:
548 548
      const UnionFindEnum* unionFind;
549 549
      int cdx;
550 550
    };
551 551

	
552
    /// \brief Lemon style iterator for the items of a component.
552
    /// \brief LEMON style iterator for the items of a component.
553 553
    ///
554 554
    /// ClassIt is a lemon style iterator for the components. It iterates
555 555
    /// on the items of a class. By example if you want to iterate on
556 556
    /// each items of each classes then you may write the next code.
557 557
    ///\code
558 558
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
559 559
    ///   std::cout << "Class: ";
560 560
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
561 561
    ///     std::cout << toString(iit) << ' ' << std::endl;
562 562
    ///   }
563 563
    ///   std::cout << std::endl;
564 564
    /// }
565 565
    ///\endcode
566 566
    class ItemIt {
567 567
    public:
568 568
      /// \brief Constructor of the iterator
569 569
      ///
570 570
      /// Constructor of the iterator. The iterator iterates
571 571
      /// on the class of the \c item.
572 572
      ItemIt(const UnionFindEnum& ufe, int cls) : unionFind(&ufe) {
573 573
        fdx = idx = unionFind->classes[cls].firstItem;
574 574
      }
575 575

	
576 576
      /// \brief Constructor to get invalid iterator
577 577
      ///
578 578
      /// Constructor to get invalid iterator
579 579
      ItemIt(Invalid) : unionFind(0), idx(-1) {}
580 580

	
581 581
      /// \brief Increment operator
582 582
      ///
583 583
      /// It steps to the next item in the class.
584 584
      ItemIt& operator++() {
585 585
        idx = unionFind->items[idx].next;
586 586
        if (idx == fdx) idx = -1;
587 587
        return *this;
588 588
      }
589 589

	
590 590
      /// \brief Conversion operator
591 591
      ///
592 592
      /// It converts the iterator to the current item.
593 593
      operator const Item&() const {
594 594
        return unionFind->items[idx].item;
595 595
      }
596 596

	
597 597
      /// \brief Equality operator
598 598
      ///
599 599
      /// Equality operator
600 600
      bool operator==(const ItemIt& i) {
601 601
        return i.idx == idx;
602 602
      }
603 603

	
604 604
      /// \brief Inequality operator
605 605
      ///
606 606
      /// Inequality operator
607 607
      bool operator!=(const ItemIt& i) {
608 608
        return i.idx != idx;
609 609
      }
610 610

	
611 611
    private:
612 612
      const UnionFindEnum* unionFind;
613 613
      int idx, fdx;
614 614
    };
615 615

	
616 616
  };
617 617

	
618 618
  /// \ingroup auxdat
619 619
  ///
620 620
  /// \brief A \e Extend-Find data structure implementation which
621 621
  /// is able to enumerate the components.
622 622
  ///
623 623
  /// The class implements an \e Extend-Find data structure which is
624 624
  /// able to enumerate the components and the items in a
625 625
  /// component. The data structure is a simplification of the
626 626
  /// Union-Find structure, and it does not allow to merge two components.
627 627
  ///
628 628
  /// \pre You need to add all the elements by the \ref insert()
629 629
  /// method.
630 630
  template <typename _ItemIntMap>
631 631
  class ExtendFindEnum {
632 632
  public:
633 633

	
634 634
    typedef _ItemIntMap ItemIntMap;
635 635
    typedef typename ItemIntMap::Key Item;
636 636

	
637 637
  private:
638 638

	
639 639
    ItemIntMap& index;
640 640

	
641 641
    struct ItemT {
642 642
      int cls;
643 643
      Item item;
644 644
      int next, prev;
645 645
    };
646 646

	
647 647
    std::vector<ItemT> items;
648 648
    int firstFreeItem;
649 649

	
650 650
    struct ClassT {
651 651
      int firstItem;
652 652
      int next, prev;
653 653
    };
654 654

	
655 655
    std::vector<ClassT> classes;
656 656

	
657 657
    int firstClass, firstFreeClass;
658 658

	
659 659
    int newClass() {
660 660
      if (firstFreeClass != -1) {
661 661
        int cdx = firstFreeClass;
662 662
        firstFreeClass = classes[cdx].next;
663 663
        return cdx;
664 664
      } else {
665 665
        classes.push_back(ClassT());
666 666
        return classes.size() - 1;
667 667
      }
668 668
    }
669 669

	
670 670
    int newItem() {
671 671
      if (firstFreeItem != -1) {
672 672
        int idx = firstFreeItem;
673 673
        firstFreeItem = items[idx].next;
674 674
        return idx;
675 675
      } else {
676 676
        items.push_back(ItemT());
677 677
        return items.size() - 1;
678 678
      }
679 679
    }
680 680

	
681 681
  public:
682 682

	
683 683
    /// \brief Constructor
684 684
    ExtendFindEnum(ItemIntMap& _index)
685 685
      : index(_index), items(), firstFreeItem(-1),
686 686
        classes(), firstClass(-1), firstFreeClass(-1) {}
687 687

	
688 688
    /// \brief Inserts the given element into a new component.
689 689
    ///
690 690
    /// This method creates a new component consisting only of the
691 691
    /// given element.
692 692
    int insert(const Item& item) {
693 693
      int cdx = newClass();
694 694
      classes[cdx].prev = -1;
695 695
      classes[cdx].next = firstClass;
696 696
      if (firstClass != -1) {
697 697
        classes[firstClass].prev = cdx;
698 698
      }
699 699
      firstClass = cdx;
700 700

	
701 701
      int idx = newItem();
702 702
      items[idx].item = item;
703 703
      items[idx].cls = cdx;
704 704
      items[idx].prev = idx;
705 705
      items[idx].next = idx;
706 706

	
707 707
      classes[cdx].firstItem = idx;
708 708

	
709 709
      index.set(item, idx);
710 710

	
711 711
      return cdx;
712 712
    }
713 713

	
714 714
    /// \brief Inserts the given element into the given component.
715 715
    ///
716 716
    /// This methods inserts the element \e item a into the \e cls class.
717 717
    void insert(const Item& item, int cls) {
718 718
      int idx = newItem();
719 719
      int rdx = classes[cls].firstItem;
720 720
      items[idx].item = item;
721 721
      items[idx].cls = cls;
722 722

	
723 723
      items[idx].prev = rdx;
724 724
      items[idx].next = items[rdx].next;
725 725
      items[items[rdx].next].prev = idx;
726 726
      items[rdx].next = idx;
727 727

	
728 728
      index.set(item, idx);
729 729
    }
730 730

	
731 731
    /// \brief Clears the union-find data structure
732 732
    ///
733 733
    /// Erase each item from the data structure.
734 734
    void clear() {
735 735
      items.clear();
736 736
      classes.clear;
737 737
      firstClass = firstFreeClass = firstFreeItem = -1;
738 738
    }
739 739

	
740 740
    /// \brief Gives back the class of the \e item.
741 741
    ///
742 742
    /// Gives back the class of the \e item.
743 743
    int find(const Item &item) const {
744 744
      return items[index[item]].cls;
745 745
    }
746 746

	
747 747
    /// \brief Gives back a representant item of the component.
748 748
    ///
749 749
    /// Gives back a representant item of the component.
750 750
    Item item(int cls) const {
751 751
      return items[classes[cls].firstItem].item;
752 752
    }
753 753

	
754 754
    /// \brief Removes the given element from the structure.
755 755
    ///
756 756
    /// Removes the element from its component and if the component becomes
757 757
    /// empty then removes that component from the component list.
758 758
    ///
759 759
    /// \warning It is an error to remove an element which is not in
760 760
    /// the structure.
761 761
    void erase(const Item &item) {
762 762
      int idx = index[item];
763 763
      int cdx = items[idx].cls;
764 764

	
765 765
      if (idx == items[idx].next) {
766 766
        if (classes[cdx].prev != -1) {
767 767
          classes[classes[cdx].prev].next = classes[cdx].next;
768 768
        } else {
769 769
          firstClass = classes[cdx].next;
770 770
        }
771 771
        if (classes[cdx].next != -1) {
772 772
          classes[classes[cdx].next].prev = classes[cdx].prev;
773 773
        }
774 774
        classes[cdx].next = firstFreeClass;
775 775
        firstFreeClass = cdx;
776 776
      } else {
777 777
        classes[cdx].firstItem = items[idx].next;
778 778
        items[items[idx].next].prev = items[idx].prev;
779 779
        items[items[idx].prev].next = items[idx].next;
780 780
      }
781 781
      items[idx].next = firstFreeItem;
782 782
      firstFreeItem = idx;
783 783

	
784 784
    }
785 785

	
786 786

	
787 787
    /// \brief Removes the component of the given element from the structure.
788 788
    ///
789 789
    /// Removes the component of the given element from the structure.
790 790
    ///
791 791
    /// \warning It is an error to give an element which is not in the
792 792
    /// structure.
793 793
    void eraseClass(int cdx) {
794 794
      int idx = classes[cdx].firstItem;
795 795
      items[items[idx].prev].next = firstFreeItem;
796 796
      firstFreeItem = idx;
797 797

	
798 798
      if (classes[cdx].prev != -1) {
799 799
        classes[classes[cdx].prev].next = classes[cdx].next;
800 800
      } else {
801 801
        firstClass = classes[cdx].next;
802 802
      }
803 803
      if (classes[cdx].next != -1) {
804 804
        classes[classes[cdx].next].prev = classes[cdx].prev;
805 805
      }
806 806
      classes[cdx].next = firstFreeClass;
807 807
      firstFreeClass = cdx;
808 808
    }
809 809

	
810
    /// \brief Lemon style iterator for the classes.
810
    /// \brief LEMON style iterator for the classes.
811 811
    ///
812 812
    /// ClassIt is a lemon style iterator for the components. It iterates
813 813
    /// on the ids of classes.
814 814
    class ClassIt {
815 815
    public:
816 816
      /// \brief Constructor of the iterator
817 817
      ///
818 818
      /// Constructor of the iterator
819 819
      ClassIt(const ExtendFindEnum& ufe) : extendFind(&ufe) {
820 820
        cdx = extendFind->firstClass;
821 821
      }
822 822

	
823 823
      /// \brief Constructor to get invalid iterator
824 824
      ///
825 825
      /// Constructor to get invalid iterator
826 826
      ClassIt(Invalid) : extendFind(0), cdx(-1) {}
827 827

	
828 828
      /// \brief Increment operator
829 829
      ///
830 830
      /// It steps to the next representant item.
831 831
      ClassIt& operator++() {
832 832
        cdx = extendFind->classes[cdx].next;
833 833
        return *this;
834 834
      }
835 835

	
836 836
      /// \brief Conversion operator
837 837
      ///
838 838
      /// It converts the iterator to the current class id.
839 839
      operator int() const {
840 840
        return cdx;
841 841
      }
842 842

	
843 843
      /// \brief Equality operator
844 844
      ///
845 845
      /// Equality operator
846 846
      bool operator==(const ClassIt& i) {
847 847
        return i.cdx == cdx;
848 848
      }
849 849

	
850 850
      /// \brief Inequality operator
851 851
      ///
852 852
      /// Inequality operator
853 853
      bool operator!=(const ClassIt& i) {
854 854
        return i.cdx != cdx;
855 855
      }
856 856

	
857 857
    private:
858 858
      const ExtendFindEnum* extendFind;
859 859
      int cdx;
860 860
    };
861 861

	
862
    /// \brief Lemon style iterator for the items of a component.
862
    /// \brief LEMON style iterator for the items of a component.
863 863
    ///
864 864
    /// ClassIt is a lemon style iterator for the components. It iterates
865 865
    /// on the items of a class. By example if you want to iterate on
866 866
    /// each items of each classes then you may write the next code.
867 867
    ///\code
868 868
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
869 869
    ///   std::cout << "Class: ";
870 870
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
871 871
    ///     std::cout << toString(iit) << ' ' << std::endl;
872 872
    ///   }
873 873
    ///   std::cout << std::endl;
874 874
    /// }
875 875
    ///\endcode
876 876
    class ItemIt {
877 877
    public:
878 878
      /// \brief Constructor of the iterator
879 879
      ///
880 880
      /// Constructor of the iterator. The iterator iterates
881 881
      /// on the class of the \c item.
882 882
      ItemIt(const ExtendFindEnum& ufe, int cls) : extendFind(&ufe) {
883 883
        fdx = idx = extendFind->classes[cls].firstItem;
884 884
      }
885 885

	
886 886
      /// \brief Constructor to get invalid iterator
887 887
      ///
888 888
      /// Constructor to get invalid iterator
889 889
      ItemIt(Invalid) : extendFind(0), idx(-1) {}
890 890

	
891 891
      /// \brief Increment operator
892 892
      ///
893 893
      /// It steps to the next item in the class.
894 894
      ItemIt& operator++() {
895 895
        idx = extendFind->items[idx].next;
896 896
        if (fdx == idx) idx = -1;
897 897
        return *this;
898 898
      }
899 899

	
900 900
      /// \brief Conversion operator
901 901
      ///
902 902
      /// It converts the iterator to the current item.
903 903
      operator const Item&() const {
904 904
        return extendFind->items[idx].item;
905 905
      }
906 906

	
907 907
      /// \brief Equality operator
908 908
      ///
909 909
      /// Equality operator
910 910
      bool operator==(const ItemIt& i) {
911 911
        return i.idx == idx;
912 912
      }
913 913

	
914 914
      /// \brief Inequality operator
915 915
      ///
916 916
      /// Inequality operator
917 917
      bool operator!=(const ItemIt& i) {
918 918
        return i.idx != idx;
919 919
      }
920 920

	
921 921
    private:
922 922
      const ExtendFindEnum* extendFind;
923 923
      int idx, fdx;
924 924
    };
925 925

	
926 926
  };
927 927

	
928 928
  /// \ingroup auxdat
929 929
  ///
930 930
  /// \brief A \e Union-Find data structure implementation which
931 931
  /// is able to store a priority for each item and retrieve the minimum of
932 932
  /// each class.
933 933
  ///
934 934
  /// A \e Union-Find data structure implementation which is able to
935 935
  /// store a priority for each item and retrieve the minimum of each
936 936
  /// class. In addition, it supports the joining and splitting the
937 937
  /// components. If you don't need this feature then you makes
938 938
  /// better to use the \ref UnionFind class which is more efficient.
939 939
  ///
940 940
  /// The union-find data strcuture based on a (2, 16)-tree with a
941 941
  /// tournament minimum selection on the internal nodes. The insert
942 942
  /// operation takes O(1), the find, set, decrease and increase takes
943 943
  /// O(log(n)), where n is the number of nodes in the current
944 944
  /// component.  The complexity of join and split is O(log(n)*k),
945 945
  /// where n is the sum of the number of the nodes and k is the
946 946
  /// number of joined components or the number of the components
947 947
  /// after the split.
948 948
  ///
949 949
  /// \pre You need to add all the elements by the \ref insert()
950 950
  /// method.
951 951
  ///
952 952
  template <typename _Value, typename _ItemIntMap,
953 953
            typename _Comp = std::less<_Value> >
954 954
  class HeapUnionFind {
955 955
  public:
956 956

	
957 957
    typedef _Value Value;
958 958
    typedef typename _ItemIntMap::Key Item;
959 959

	
960 960
    typedef _ItemIntMap ItemIntMap;
961 961

	
962 962
    typedef _Comp Comp;
963 963

	
964 964
  private:
965 965

	
966 966
    static const int cmax = 16;
967 967

	
968 968
    ItemIntMap& index;
969 969

	
970 970
    struct ClassNode {
971 971
      int parent;
972 972
      int depth;
973 973

	
974 974
      int left, right;
975 975
      int next, prev;
976 976
    };
977 977

	
978 978
    int first_class;
979 979
    int first_free_class;
980 980
    std::vector<ClassNode> classes;
981 981

	
982 982
    int newClass() {
983 983
      if (first_free_class < 0) {
984 984
        int id = classes.size();
985 985
        classes.push_back(ClassNode());
986 986
        return id;
987 987
      } else {
988 988
        int id = first_free_class;
989 989
        first_free_class = classes[id].next;
990 990
        return id;
991 991
      }
992 992
    }
993 993

	
994 994
    void deleteClass(int id) {
995 995
      classes[id].next = first_free_class;
996 996
      first_free_class = id;
997 997
    }
998 998

	
999 999
    struct ItemNode {
1000 1000
      int parent;
1001 1001
      Item item;
1002 1002
      Value prio;
1003 1003
      int next, prev;
1004 1004
      int left, right;
1005 1005
      int size;
1006 1006
    };
1007 1007

	
1008 1008
    int first_free_node;
1009 1009
    std::vector<ItemNode> nodes;
1010 1010

	
1011 1011
    int newNode() {
1012 1012
      if (first_free_node < 0) {
1013 1013
        int id = nodes.size();
1014 1014
        nodes.push_back(ItemNode());
1015 1015
        return id;
1016 1016
      } else {
1017 1017
        int id = first_free_node;
1018 1018
        first_free_node = nodes[id].next;
1019 1019
        return id;
1020 1020
      }
1021 1021
    }
1022 1022

	
1023 1023
    void deleteNode(int id) {
1024 1024
      nodes[id].next = first_free_node;
1025 1025
      first_free_node = id;
1026 1026
    }
1027 1027

	
1028 1028
    Comp comp;
1029 1029

	
1030 1030
    int findClass(int id) const {
1031 1031
      int kd = id;
1032 1032
      while (kd >= 0) {
1033 1033
        kd = nodes[kd].parent;
1034 1034
      }
1035 1035
      return ~kd;
1036 1036
    }
1037 1037

	
1038 1038
    int leftNode(int id) const {
1039 1039
      int kd = ~(classes[id].parent);
1040 1040
      for (int i = 0; i < classes[id].depth; ++i) {
1041 1041
        kd = nodes[kd].left;
1042 1042
      }
1043 1043
      return kd;
1044 1044
    }
1045 1045

	
1046 1046
    int nextNode(int id) const {
1047 1047
      int depth = 0;
1048 1048
      while (id >= 0 && nodes[id].next == -1) {
1049 1049
        id = nodes[id].parent;
1050 1050
        ++depth;
1051 1051
      }
1052 1052
      if (id < 0) {
1053 1053
        return -1;
1054 1054
      }
1055 1055
      id = nodes[id].next;
1056 1056
      while (depth--) {
1057 1057
        id = nodes[id].left;
1058 1058
      }
1059 1059
      return id;
1060 1060
    }
1061 1061

	
1062 1062

	
1063 1063
    void setPrio(int id) {
1064 1064
      int jd = nodes[id].left;
1065 1065
      nodes[id].prio = nodes[jd].prio;
1066 1066
      nodes[id].item = nodes[jd].item;
1067 1067
      jd = nodes[jd].next;
1068 1068
      while (jd != -1) {
1069 1069
        if (comp(nodes[jd].prio, nodes[id].prio)) {
1070 1070
          nodes[id].prio = nodes[jd].prio;
1071 1071
          nodes[id].item = nodes[jd].item;
1072 1072
        }
1073 1073
        jd = nodes[jd].next;
1074 1074
      }
1075 1075
    }
1076 1076

	
1077 1077
    void push(int id, int jd) {
1078 1078
      nodes[id].size = 1;
1079 1079
      nodes[id].left = nodes[id].right = jd;
1080 1080
      nodes[jd].next = nodes[jd].prev = -1;
1081 1081
      nodes[jd].parent = id;
1082 1082
    }
1083 1083

	
1084 1084
    void pushAfter(int id, int jd) {
1085 1085
      int kd = nodes[id].parent;
1086 1086
      if (nodes[id].next != -1) {
1087 1087
        nodes[nodes[id].next].prev = jd;
1088 1088
        if (kd >= 0) {
1089 1089
          nodes[kd].size += 1;
1090 1090
        }
1091 1091
      } else {
1092 1092
        if (kd >= 0) {
1093 1093
          nodes[kd].right = jd;
1094 1094
          nodes[kd].size += 1;
1095 1095
        }
1096 1096
      }
1097 1097
      nodes[jd].next = nodes[id].next;
1098 1098
      nodes[jd].prev = id;
1099 1099
      nodes[id].next = jd;
1100 1100
      nodes[jd].parent = kd;
1101 1101
    }
1102 1102

	
1103 1103
    void pushRight(int id, int jd) {
1104 1104
      nodes[id].size += 1;
1105 1105
      nodes[jd].prev = nodes[id].right;
1106 1106
      nodes[jd].next = -1;
1107 1107
      nodes[nodes[id].right].next = jd;
1108 1108
      nodes[id].right = jd;
1109 1109
      nodes[jd].parent = id;
1110 1110
    }
1111 1111

	
1112 1112
    void popRight(int id) {
1113 1113
      nodes[id].size -= 1;
1114 1114
      int jd = nodes[id].right;
1115 1115
      nodes[nodes[jd].prev].next = -1;
1116 1116
      nodes[id].right = nodes[jd].prev;
1117 1117
    }
1118 1118

	
... ...
@@ -1402,395 +1402,395 @@
1402 1402
              pushRight(new_id, ~(classes[r].parent));
1403 1403
              setPrio(new_id);
1404 1404

	
1405 1405
              id = nodes[id].parent;
1406 1406
              classes[r].parent = ~new_id;
1407 1407
            }
1408 1408
            if (id < 0) {
1409 1409
              int new_parent = newNode();
1410 1410
              nodes[new_parent].next = -1;
1411 1411
              nodes[new_parent].prev = -1;
1412 1412
              nodes[new_parent].parent = ~l;
1413 1413

	
1414 1414
              push(new_parent, ~(classes[l].parent));
1415 1415
              pushRight(new_parent, ~(classes[r].parent));
1416 1416
              setPrio(new_parent);
1417 1417

	
1418 1418
              classes[l].parent = ~new_parent;
1419 1419
              classes[l].depth += 1;
1420 1420
            } else {
1421 1421
              pushRight(id, ~(classes[r].parent));
1422 1422
              while (id >= 0 && less(~(classes[r].parent), id)) {
1423 1423
                nodes[id].prio = nodes[~(classes[r].parent)].prio;
1424 1424
                nodes[id].item = nodes[~(classes[r].parent)].item;
1425 1425
                id = nodes[id].parent;
1426 1426
              }
1427 1427
            }
1428 1428
          } else if (classes[r].depth > classes[l].depth) {
1429 1429
            int id = ~(classes[r].parent);
1430 1430
            for (int i = classes[l].depth + 1; i < classes[r].depth; ++i) {
1431 1431
              id = nodes[id].left;
1432 1432
            }
1433 1433
            while (id >= 0 && nodes[id].size == cmax) {
1434 1434
              int new_id = newNode();
1435 1435
              int left_id = nodes[id].left;
1436 1436

	
1437 1437
              popLeft(id);
1438 1438
              if (nodes[id].prio == nodes[left_id].prio) {
1439 1439
                setPrio(id);
1440 1440
              }
1441 1441
              push(new_id, left_id);
1442 1442
              pushLeft(new_id, ~(classes[l].parent));
1443 1443
              setPrio(new_id);
1444 1444

	
1445 1445
              id = nodes[id].parent;
1446 1446
              classes[l].parent = ~new_id;
1447 1447

	
1448 1448
            }
1449 1449
            if (id < 0) {
1450 1450
              int new_parent = newNode();
1451 1451
              nodes[new_parent].next = -1;
1452 1452
              nodes[new_parent].prev = -1;
1453 1453
              nodes[new_parent].parent = ~l;
1454 1454

	
1455 1455
              push(new_parent, ~(classes[r].parent));
1456 1456
              pushLeft(new_parent, ~(classes[l].parent));
1457 1457
              setPrio(new_parent);
1458 1458

	
1459 1459
              classes[r].parent = ~new_parent;
1460 1460
              classes[r].depth += 1;
1461 1461
            } else {
1462 1462
              pushLeft(id, ~(classes[l].parent));
1463 1463
              while (id >= 0 && less(~(classes[l].parent), id)) {
1464 1464
                nodes[id].prio = nodes[~(classes[l].parent)].prio;
1465 1465
                nodes[id].item = nodes[~(classes[l].parent)].item;
1466 1466
                id = nodes[id].parent;
1467 1467
              }
1468 1468
            }
1469 1469
            nodes[~(classes[r].parent)].parent = ~l;
1470 1470
            classes[l].parent = classes[r].parent;
1471 1471
            classes[l].depth = classes[r].depth;
1472 1472
          } else {
1473 1473
            if (classes[l].depth != 0 &&
1474 1474
                nodes[~(classes[l].parent)].size +
1475 1475
                nodes[~(classes[r].parent)].size <= cmax) {
1476 1476
              splice(~(classes[l].parent), ~(classes[r].parent));
1477 1477
              deleteNode(~(classes[r].parent));
1478 1478
              if (less(~(classes[r].parent), ~(classes[l].parent))) {
1479 1479
                nodes[~(classes[l].parent)].prio =
1480 1480
                  nodes[~(classes[r].parent)].prio;
1481 1481
                nodes[~(classes[l].parent)].item =
1482 1482
                  nodes[~(classes[r].parent)].item;
1483 1483
              }
1484 1484
            } else {
1485 1485
              int new_parent = newNode();
1486 1486
              nodes[new_parent].next = nodes[new_parent].prev = -1;
1487 1487
              push(new_parent, ~(classes[l].parent));
1488 1488
              pushRight(new_parent, ~(classes[r].parent));
1489 1489
              setPrio(new_parent);
1490 1490

	
1491 1491
              classes[l].parent = ~new_parent;
1492 1492
              classes[l].depth += 1;
1493 1493
              nodes[new_parent].parent = ~l;
1494 1494
            }
1495 1495
          }
1496 1496
          if (classes[r].next != -1) {
1497 1497
            classes[classes[r].next].prev = classes[r].prev;
1498 1498
          }
1499 1499
          classes[classes[r].prev].next = classes[r].next;
1500 1500

	
1501 1501
          classes[r].prev = classes[l].right;
1502 1502
          classes[classes[l].right].next = r;
1503 1503
          classes[l].right = r;
1504 1504
          classes[r].parent = l;
1505 1505

	
1506 1506
          classes[r].next = -1;
1507 1507
          classes[r].depth = rln;
1508 1508
        }
1509 1509
      }
1510 1510
      return class_id;
1511 1511
    }
1512 1512

	
1513 1513
    /// \brief Split the class to subclasses.
1514 1514
    ///
1515 1515
    /// The current function splits the given class. The join, which
1516 1516
    /// made the current class, stored a reference to the
1517 1517
    /// subclasses. The \c splitClass() member restores the classes
1518 1518
    /// and creates the heaps. The parameter is an STL output iterator
1519 1519
    /// which will be filled with the subclass ids. The time
1520 1520
    /// complexity is O(log(n)*k) where n is the overall number of
1521 1521
    /// nodes in the splitted classes and k is the number of the
1522 1522
    /// classes.
1523 1523
    template <typename Iterator>
1524 1524
    void split(int cls, Iterator out) {
1525 1525
      std::vector<int> cs;
1526 1526
      { // splitting union-find
1527 1527
        int id = cls;
1528 1528
        int l = classes[id].left;
1529 1529

	
1530 1530
        classes[l].parent = classes[id].parent;
1531 1531
        classes[l].depth = classes[id].depth;
1532 1532

	
1533 1533
        nodes[~(classes[l].parent)].parent = ~l;
1534 1534

	
1535 1535
        *out++ = l;
1536 1536

	
1537 1537
        while (l != -1) {
1538 1538
          cs.push_back(l);
1539 1539
          l = classes[l].next;
1540 1540
        }
1541 1541

	
1542 1542
        classes[classes[id].right].next = first_class;
1543 1543
        classes[first_class].prev = classes[id].right;
1544 1544
        first_class = classes[id].left;
1545 1545

	
1546 1546
        if (classes[id].next != -1) {
1547 1547
          classes[classes[id].next].prev = classes[id].prev;
1548 1548
        }
1549 1549
        classes[classes[id].prev].next = classes[id].next;
1550 1550

	
1551 1551
        deleteClass(id);
1552 1552
      }
1553 1553

	
1554 1554
      {
1555 1555
        for (int i = 1; i < int(cs.size()); ++i) {
1556 1556
          int l = classes[cs[i]].depth;
1557 1557
          while (nodes[nodes[l].parent].left == l) {
1558 1558
            l = nodes[l].parent;
1559 1559
          }
1560 1560
          int r = l;
1561 1561
          while (nodes[l].parent >= 0) {
1562 1562
            l = nodes[l].parent;
1563 1563
            int new_node = newNode();
1564 1564

	
1565 1565
            nodes[new_node].prev = -1;
1566 1566
            nodes[new_node].next = -1;
1567 1567

	
1568 1568
            split(r, new_node);
1569 1569
            pushAfter(l, new_node);
1570 1570
            setPrio(l);
1571 1571
            setPrio(new_node);
1572 1572
            r = new_node;
1573 1573
          }
1574 1574
          classes[cs[i]].parent = ~r;
1575 1575
          classes[cs[i]].depth = classes[~(nodes[l].parent)].depth;
1576 1576
          nodes[r].parent = ~cs[i];
1577 1577

	
1578 1578
          nodes[l].next = -1;
1579 1579
          nodes[r].prev = -1;
1580 1580

	
1581 1581
          repairRight(~(nodes[l].parent));
1582 1582
          repairLeft(cs[i]);
1583 1583

	
1584 1584
          *out++ = cs[i];
1585 1585
        }
1586 1586
      }
1587 1587
    }
1588 1588

	
1589 1589
    /// \brief Gives back the priority of the current item.
1590 1590
    ///
1591 1591
    /// \return Gives back the priority of the current item.
1592 1592
    const Value& operator[](const Item& item) const {
1593 1593
      return nodes[index[item]].prio;
1594 1594
    }
1595 1595

	
1596 1596
    /// \brief Sets the priority of the current item.
1597 1597
    ///
1598 1598
    /// Sets the priority of the current item.
1599 1599
    void set(const Item& item, const Value& prio) {
1600 1600
      if (comp(prio, nodes[index[item]].prio)) {
1601 1601
        decrease(item, prio);
1602 1602
      } else if (!comp(prio, nodes[index[item]].prio)) {
1603 1603
        increase(item, prio);
1604 1604
      }
1605 1605
    }
1606 1606

	
1607 1607
    /// \brief Increase the priority of the current item.
1608 1608
    ///
1609 1609
    /// Increase the priority of the current item.
1610 1610
    void increase(const Item& item, const Value& prio) {
1611 1611
      int id = index[item];
1612 1612
      int kd = nodes[id].parent;
1613 1613
      nodes[id].prio = prio;
1614 1614
      while (kd >= 0 && nodes[kd].item == item) {
1615 1615
        setPrio(kd);
1616 1616
        kd = nodes[kd].parent;
1617 1617
      }
1618 1618
    }
1619 1619

	
1620 1620
    /// \brief Increase the priority of the current item.
1621 1621
    ///
1622 1622
    /// Increase the priority of the current item.
1623 1623
    void decrease(const Item& item, const Value& prio) {
1624 1624
      int id = index[item];
1625 1625
      int kd = nodes[id].parent;
1626 1626
      nodes[id].prio = prio;
1627 1627
      while (kd >= 0 && less(id, kd)) {
1628 1628
        nodes[kd].prio = prio;
1629 1629
        nodes[kd].item = item;
1630 1630
        kd = nodes[kd].parent;
1631 1631
      }
1632 1632
    }
1633 1633

	
1634 1634
    /// \brief Gives back the minimum priority of the class.
1635 1635
    ///
1636 1636
    /// \return Gives back the minimum priority of the class.
1637 1637
    const Value& classPrio(int cls) const {
1638 1638
      return nodes[~(classes[cls].parent)].prio;
1639 1639
    }
1640 1640

	
1641 1641
    /// \brief Gives back the minimum priority item of the class.
1642 1642
    ///
1643 1643
    /// \return Gives back the minimum priority item of the class.
1644 1644
    const Item& classTop(int cls) const {
1645 1645
      return nodes[~(classes[cls].parent)].item;
1646 1646
    }
1647 1647

	
1648 1648
    /// \brief Gives back a representant item of the class.
1649 1649
    ///
1650 1650
    /// The representant is indpendent from the priorities of the
1651 1651
    /// items.
1652 1652
    /// \return Gives back a representant item of the class.
1653 1653
    const Item& classRep(int id) const {
1654 1654
      int parent = classes[id].parent;
1655 1655
      return nodes[parent >= 0 ? classes[id].depth : leftNode(id)].item;
1656 1656
    }
1657 1657

	
1658
    /// \brief Lemon style iterator for the items of a class.
1658
    /// \brief LEMON style iterator for the items of a class.
1659 1659
    ///
1660 1660
    /// ClassIt is a lemon style iterator for the components. It iterates
1661 1661
    /// on the items of a class. By example if you want to iterate on
1662 1662
    /// each items of each classes then you may write the next code.
1663 1663
    ///\code
1664 1664
    /// for (ClassIt cit(huf); cit != INVALID; ++cit) {
1665 1665
    ///   std::cout << "Class: ";
1666 1666
    ///   for (ItemIt iit(huf, cit); iit != INVALID; ++iit) {
1667 1667
    ///     std::cout << toString(iit) << ' ' << std::endl;
1668 1668
    ///   }
1669 1669
    ///   std::cout << std::endl;
1670 1670
    /// }
1671 1671
    ///\endcode
1672 1672
    class ItemIt {
1673 1673
    private:
1674 1674

	
1675 1675
      const HeapUnionFind* _huf;
1676 1676
      int _id, _lid;
1677 1677

	
1678 1678
    public:
1679 1679

	
1680 1680
      /// \brief Default constructor
1681 1681
      ///
1682 1682
      /// Default constructor
1683 1683
      ItemIt() {}
1684 1684

	
1685 1685
      ItemIt(const HeapUnionFind& huf, int cls) : _huf(&huf) {
1686 1686
        int id = cls;
1687 1687
        int parent = _huf->classes[id].parent;
1688 1688
        if (parent >= 0) {
1689 1689
          _id = _huf->classes[id].depth;
1690 1690
          if (_huf->classes[id].next != -1) {
1691 1691
            _lid = _huf->classes[_huf->classes[id].next].depth;
1692 1692
          } else {
1693 1693
            _lid = -1;
1694 1694
          }
1695 1695
        } else {
1696 1696
          _id = _huf->leftNode(id);
1697 1697
          _lid = -1;
1698 1698
        }
1699 1699
      }
1700 1700

	
1701 1701
      /// \brief Increment operator
1702 1702
      ///
1703 1703
      /// It steps to the next item in the class.
1704 1704
      ItemIt& operator++() {
1705 1705
        _id = _huf->nextNode(_id);
1706 1706
        return *this;
1707 1707
      }
1708 1708

	
1709 1709
      /// \brief Conversion operator
1710 1710
      ///
1711 1711
      /// It converts the iterator to the current item.
1712 1712
      operator const Item&() const {
1713 1713
        return _huf->nodes[_id].item;
1714 1714
      }
1715 1715

	
1716 1716
      /// \brief Equality operator
1717 1717
      ///
1718 1718
      /// Equality operator
1719 1719
      bool operator==(const ItemIt& i) {
1720 1720
        return i._id == _id;
1721 1721
      }
1722 1722

	
1723 1723
      /// \brief Inequality operator
1724 1724
      ///
1725 1725
      /// Inequality operator
1726 1726
      bool operator!=(const ItemIt& i) {
1727 1727
        return i._id != _id;
1728 1728
      }
1729 1729

	
1730 1730
      /// \brief Equality operator
1731 1731
      ///
1732 1732
      /// Equality operator
1733 1733
      bool operator==(Invalid) {
1734 1734
        return _id == _lid;
1735 1735
      }
1736 1736

	
1737 1737
      /// \brief Inequality operator
1738 1738
      ///
1739 1739
      /// Inequality operator
1740 1740
      bool operator!=(Invalid) {
1741 1741
        return _id != _lid;
1742 1742
      }
1743 1743

	
1744 1744
    };
1745 1745

	
1746 1746
    /// \brief Class iterator
1747 1747
    ///
1748 1748
    /// The iterator stores
1749 1749
    class ClassIt {
1750 1750
    private:
1751 1751

	
1752 1752
      const HeapUnionFind* _huf;
1753 1753
      int _id;
1754 1754

	
1755 1755
    public:
1756 1756

	
1757 1757
      ClassIt(const HeapUnionFind& huf)
1758 1758
        : _huf(&huf), _id(huf.first_class) {}
1759 1759

	
1760 1760
      ClassIt(const HeapUnionFind& huf, int cls)
1761 1761
        : _huf(&huf), _id(huf.classes[cls].left) {}
1762 1762

	
1763 1763
      ClassIt(Invalid) : _huf(0), _id(-1) {}
1764 1764

	
1765 1765
      const ClassIt& operator++() {
1766 1766
        _id = _huf->classes[_id].next;
1767 1767
        return *this;
1768 1768
      }
1769 1769

	
1770 1770
      /// \brief Equality operator
1771 1771
      ///
1772 1772
      /// Equality operator
1773 1773
      bool operator==(const ClassIt& i) {
1774 1774
        return i._id == _id;
1775 1775
      }
1776 1776

	
1777 1777
      /// \brief Inequality operator
1778 1778
      ///
1779 1779
      /// Inequality operator
1780 1780
      bool operator!=(const ClassIt& i) {
1781 1781
        return i._id != _id;
1782 1782
      }
1783 1783

	
1784 1784
      operator int() const {
1785 1785
        return _id;
1786 1786
      }
1787 1787

	
1788 1788
    };
1789 1789

	
1790 1790
  };
1791 1791

	
1792 1792
  //! @}
1793 1793

	
1794 1794
} //namespace lemon
1795 1795

	
1796 1796
#endif //LEMON_UNION_FIND_H
0 comments (0 inline)